Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ All exceptions inherit from `TeslaFleetError(BaseException)`.

### Protobuf

Generated protobuf files live in `tesla/vehicle/proto/` and are excluded from ruff and pyright. Do not edit these directly — regenerate them with `tools/regenerate_protos.sh` (needs `protoc` on `PATH`).
Source protobuf definitions live in `proto/`; generated Python files live in `tesla_fleet_api/tesla/vehicle/proto/` and are excluded from ruff and pyright. Do not edit generated `*_pb2.py`/`*_pb2.pyi` files directly — update the source `.proto`, add new files to the `PROTOS` list and import-rewrite set in `tools/regenerate_protos.sh`, then regenerate (needs `protoc` on `PATH`). If a new generated module is added, also update the hand-maintained `tesla_fleet_api/tesla/vehicle/proto/__init__.pyi` export stub.

**Runtime-version pin (Home Assistant compatibility).** The gencode stamps a `ValidateProtobufRuntimeVersion(major, minor, patch, …)` call, and protobuf refuses to load gencode that is *newer* than the installed runtime (`gencode X > runtime` → `VersionError`). Home Assistant core pins `protobuf==6.32.0`, so the gencode must be stamped **≤ 6.32.0** or it breaks in HA. The generator version is the `protoc` version: under unified protobuf versioning, `protoc vX.Y` (`libprotoc X.Y`) stamps Python gencode `6.X.Y`. So to target runtime 6.32.0, regenerate with **protoc v32.0** (`protoc-32.0-linux-x86_64.zip` from the protobuf GitHub releases). The `protobuf>=6.32.0` floor in `pyproject.toml` must match the gencode version — never set it below the stamped version, or installs that resolve an older protobuf will hit `VersionError` at import.

Expand Down
11 changes: 11 additions & 0 deletions proto/session.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
syntax = "proto3";
import "google/protobuf/timestamp.proto";

package Session;

message SessionStore {
bytes public_key = 1;
bytes epoch = 2;
uint32 delta = 3;
optional google.protobuf.Timestamp lock = 4;
}
3 changes: 3 additions & 0 deletions proto/universal_message.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ enum Domain {
DOMAIN_BROADCAST = 0;
DOMAIN_VEHICLE_SECURITY = 2;
DOMAIN_INFOTAINMENT = 3;
DOMAIN_AUTHD = 5;
DOMAIN_ENERGY_DEVICE = 7;
DOMAIN_ENERGY_DEVICE_AUTH = 8;
}

message Destination {
Expand Down
1 change: 1 addition & 0 deletions tesla_fleet_api/tesla/vehicle/proto/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ from . import common_pb2
from . import errors_pb2
from . import keys_pb2
from . import managed_charging_pb2
from . import session_pb2
from . import signatures_pb2
from . import universal_message_pb2
from . import vcsec_pb2
Expand Down
37 changes: 37 additions & 0 deletions tesla_fleet_api/tesla/vehicle/proto/session_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions tesla_fleet_api/tesla/vehicle/proto/session_pb2.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import datetime

from google.protobuf import timestamp_pb2 as _timestamp_pb2
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from collections.abc import Mapping as _Mapping
from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union

DESCRIPTOR: _descriptor.FileDescriptor

class SessionStore(_message.Message):
__slots__ = ("public_key", "epoch", "delta", "lock")
PUBLIC_KEY_FIELD_NUMBER: _ClassVar[int]
EPOCH_FIELD_NUMBER: _ClassVar[int]
DELTA_FIELD_NUMBER: _ClassVar[int]
LOCK_FIELD_NUMBER: _ClassVar[int]
public_key: bytes
epoch: bytes
delta: int
lock: _timestamp_pb2.Timestamp
def __init__(self, public_key: _Optional[bytes] = ..., epoch: _Optional[bytes] = ..., delta: _Optional[int] = ..., lock: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ...
18 changes: 9 additions & 9 deletions tesla_fleet_api/tesla/vehicle/proto/universal_message_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions tesla_fleet_api/tesla/vehicle/proto/universal_message_pb2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ class Domain(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
DOMAIN_BROADCAST: _ClassVar[Domain]
DOMAIN_VEHICLE_SECURITY: _ClassVar[Domain]
DOMAIN_INFOTAINMENT: _ClassVar[Domain]
DOMAIN_AUTHD: _ClassVar[Domain]
DOMAIN_ENERGY_DEVICE: _ClassVar[Domain]
DOMAIN_ENERGY_DEVICE_AUTH: _ClassVar[Domain]

class OperationStatus_E(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = ()
Expand Down Expand Up @@ -58,6 +61,9 @@ class Flags(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
DOMAIN_BROADCAST: Domain
DOMAIN_VEHICLE_SECURITY: Domain
DOMAIN_INFOTAINMENT: Domain
DOMAIN_AUTHD: Domain
DOMAIN_ENERGY_DEVICE: Domain
DOMAIN_ENERGY_DEVICE_AUTH: Domain
OPERATIONSTATUS_OK: OperationStatus_E
OPERATIONSTATUS_WAIT: OperationStatus_E
OPERATIONSTATUS_ERROR: OperationStatus_E
Expand Down
3 changes: 2 additions & 1 deletion tools/regenerate_protos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ PROTOS=(
vehicle.proto
car_server.proto
universal_message.proto
session.proto
)

# Copy the top-level .proto files into proto/tesla/, rewriting imports of our
Expand All @@ -50,7 +51,7 @@ import re, sys
src, dst = sys.argv[1], sys.argv[2]
own = {"common.proto","errors.proto","keys.proto","signatures.proto",
"managed_charging.proto","vcsec.proto","vehicle.proto",
"car_server.proto","universal_message.proto"}
"car_server.proto","universal_message.proto","session.proto"}
text = open(src).read()
def repl(m):
name = m.group(1)
Expand Down
Loading