rivian-python-client 2.2.0b1__tar.gz → 2.2.0b2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/PKG-INFO +1 -1
  2. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/pyproject.toml +8 -0
  3. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/__version__.py +1 -1
  4. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/body.py +70 -46
  5. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/charging.py +37 -37
  6. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/comfort.py +54 -45
  7. rivian_python_client-2.2.0b2/src/rivian/parallax/device_table.py +99 -0
  8. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/dynamics.py +34 -34
  9. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/energy.py +6 -6
  10. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/gearguard_streaming.py +9 -9
  11. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/geofence.py +11 -5
  12. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/holiday_celebration.py +46 -6
  13. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/ota.py +24 -18
  14. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/body.proto +86 -27
  15. rivian_python_client-2.2.0b2/src/rivian/parallax/proto/body_pb2.py +72 -0
  16. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/body_pb2.pyi +154 -40
  17. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/comfort.proto +33 -26
  18. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/comfort_pb2.py +24 -24
  19. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/comfort_pb2.pyi +57 -43
  20. rivian_python_client-2.2.0b2/src/rivian/parallax/proto/device_table.proto +64 -0
  21. rivian_python_client-2.2.0b2/src/rivian/parallax/proto/device_table_pb2.py +50 -0
  22. rivian_python_client-2.2.0b2/src/rivian/parallax/proto/device_table_pb2.pyi +92 -0
  23. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/geofence.proto +9 -2
  24. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/geofence_pb2.py +5 -3
  25. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/geofence_pb2.pyi +16 -4
  26. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/holiday_celebration.proto +24 -13
  27. rivian_python_client-2.2.0b2/src/rivian/parallax/proto/holiday_celebration_pb2.py +50 -0
  28. rivian_python_client-2.2.0b2/src/rivian/parallax/proto/holiday_celebration_pb2.pyi +92 -0
  29. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/ota.proto +17 -10
  30. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/ota_pb2.py +17 -15
  31. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/ota_pb2.pyi +26 -19
  32. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/vehicle.proto +5 -5
  33. rivian_python_client-2.2.0b2/src/rivian/parallax/proto/vehicle_access.proto +19 -0
  34. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/vehicle_access_pb2.py +5 -3
  35. rivian_python_client-2.2.0b2/src/rivian/parallax/proto/vehicle_access_pb2.pyi +25 -0
  36. rivian_python_client-2.2.0b2/src/rivian/parallax/proto/vehicle_pb2.py +62 -0
  37. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/vehicle_pb2.pyi +20 -20
  38. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/security.py +37 -37
  39. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/vehicle.py +29 -23
  40. rivian_python_client-2.2.0b2/src/rivian/parallax/vehicle_access.py +39 -0
  41. rivian_python_client-2.2.0b1/src/rivian/parallax/device_table.py +0 -59
  42. rivian_python_client-2.2.0b1/src/rivian/parallax/proto/body_pb2.py +0 -64
  43. rivian_python_client-2.2.0b1/src/rivian/parallax/proto/device_table.proto +0 -44
  44. rivian_python_client-2.2.0b1/src/rivian/parallax/proto/device_table_pb2.py +0 -46
  45. rivian_python_client-2.2.0b1/src/rivian/parallax/proto/device_table_pb2.pyi +0 -61
  46. rivian_python_client-2.2.0b1/src/rivian/parallax/proto/holiday_celebration_pb2.py +0 -44
  47. rivian_python_client-2.2.0b1/src/rivian/parallax/proto/holiday_celebration_pb2.pyi +0 -73
  48. rivian_python_client-2.2.0b1/src/rivian/parallax/proto/vehicle_access.proto +0 -8
  49. rivian_python_client-2.2.0b1/src/rivian/parallax/proto/vehicle_access_pb2.pyi +0 -9
  50. rivian_python_client-2.2.0b1/src/rivian/parallax/proto/vehicle_pb2.py +0 -62
  51. rivian_python_client-2.2.0b1/src/rivian/parallax/vehicle_access.py +0 -18
  52. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/.gitignore +0 -0
  53. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/README.md +0 -0
  54. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/__init__.py +0 -0
  55. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/ble.py +0 -0
  56. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/const.py +0 -0
  57. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/exceptions.py +0 -0
  58. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/__init__.py +0 -0
  59. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/core.py +0 -0
  60. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/departure.py +0 -0
  61. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/energy_edge_compute.py +0 -0
  62. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/navigation.py +0 -0
  63. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/parallax.py +0 -0
  64. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/__init__.py +0 -0
  65. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/charging.proto +0 -0
  66. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/charging_pb2.py +0 -0
  67. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/charging_pb2.pyi +0 -0
  68. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/departure.proto +0 -0
  69. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/departure_pb2.py +0 -0
  70. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/departure_pb2.pyi +0 -0
  71. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/dynamics.proto +0 -0
  72. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/dynamics_pb2.py +0 -0
  73. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/dynamics_pb2.pyi +0 -0
  74. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/energy.proto +0 -0
  75. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/energy_edge_compute.proto +0 -0
  76. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/energy_edge_compute_pb2.py +0 -0
  77. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/energy_edge_compute_pb2.pyi +0 -0
  78. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/energy_pb2.py +0 -0
  79. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/energy_pb2.pyi +0 -0
  80. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/gearguard_streaming.proto +0 -0
  81. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/gearguard_streaming_pb2.py +0 -0
  82. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/gearguard_streaming_pb2.pyi +0 -0
  83. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/navigation.proto +0 -0
  84. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/navigation_pb2.py +0 -0
  85. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/navigation_pb2.pyi +0 -0
  86. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/parallax.proto +0 -0
  87. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/parallax_pb2.py +0 -0
  88. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/parallax_pb2.pyi +0 -0
  89. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/secure_file_transfer.proto +0 -0
  90. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/secure_file_transfer_pb2.py +0 -0
  91. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/secure_file_transfer_pb2.pyi +0 -0
  92. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/security.proto +0 -0
  93. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/security_pb2.py +0 -0
  94. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/security_pb2.pyi +0 -0
  95. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/user_passcodes.proto +0 -0
  96. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/user_passcodes_pb2.py +0 -0
  97. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/proto/user_passcodes_pb2.pyi +0 -0
  98. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/secure_file_transfer.py +0 -0
  99. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/parallax/user_passcodes.py +0 -0
  100. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/py.typed +0 -0
  101. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/rivian.py +0 -0
  102. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/schemas/charging.graphql +0 -0
  103. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/schemas/gateway.graphql +0 -0
  104. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/schemas/orders.graphql +0 -0
  105. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/utils.py +0 -0
  106. {rivian_python_client-2.2.0b1 → rivian_python_client-2.2.0b2}/src/rivian/ws_monitor.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: rivian-python-client
3
- Version: 2.2.0b1
3
+ Version: 2.2.0b2
4
4
  Summary: Rivian API Client (Unofficial)
5
5
  Author-email: Brian Retterer <bretterer@gmail.com>, "J.R. Gutierrez" <jrgutier@gmail.com>, Nathan Spencer <natekspencer@gmail.com>, Trevor Mack <drummer8001@gmail.com>
6
6
  License-Expression: MIT
@@ -36,8 +36,16 @@ dev = [
36
36
  "pre-commit>=4.6.1,<5",
37
37
  "types-protobuf>=7.35.1.20260906",
38
38
  "grpcio-tools==1.84.0",
39
+ "pytest-cov>=7.0,<8",
39
40
  ]
40
41
 
42
+ [tool.coverage.run]
43
+ source = ["rivian"]
44
+ omit = ["*_pb2.py"]
45
+
46
+ [tool.coverage.report]
47
+ exclude_also = ["if TYPE_CHECKING:"]
48
+
41
49
  [tool.hatch.build.hooks.version]
42
50
  path = "src/rivian/__version__.py"
43
51
 
@@ -1,4 +1,4 @@
1
1
  # This file is auto-generated by Hatchling. As such, do not:
2
2
  # - modify
3
3
  # - track in version control e.g. be sure to add to .gitignore
4
- __version__ = VERSION = '2.2.0b1'
4
+ __version__ = VERSION = '2.2.0b2'
@@ -8,28 +8,30 @@ from .core import _LOGGER, RVMDecoder, _enum, _present
8
8
  from .proto import body_pb2
9
9
 
10
10
  _CLOSURE_MAP: Final[dict[int, str]] = {
11
- 1: "doorFrontLeftClosed",
12
- 2: "doorFrontRightClosed",
13
- 3: "doorRearLeftClosed",
14
- 4: "doorRearRightClosed",
15
- 5: "closureFrunkClosed",
16
- 6: "closureTailgateClosed",
17
- 7: "closureLiftgateClosed",
18
- 8: "closureSideBinLeftClosed",
19
- 9: "closureSideBinRightClosed",
20
- 10: "chargePortState",
21
- 11: "closureTonneauClosed",
22
- 12: "windowFrontLeftClosed",
23
- 13: "windowFrontRightClosed",
24
- 14: "windowRearLeftClosed",
25
- 15: "windowRearRightClosed",
11
+ body_pb2.DOOR_FRONT_LEFT: "doorFrontLeftClosed",
12
+ body_pb2.DOOR_FRONT_RIGHT: "doorFrontRightClosed",
13
+ body_pb2.DOOR_REAR_LEFT: "doorRearLeftClosed",
14
+ body_pb2.DOOR_REAR_RIGHT: "doorRearRightClosed",
15
+ body_pb2.FRUNK: "closureFrunkClosed",
16
+ body_pb2.TAILGATE: "closureTailgateClosed",
17
+ body_pb2.LIFTGATE: "closureLiftgateClosed",
18
+ body_pb2.SIDE_BIN_LEFT: "closureSideBinLeftClosed",
19
+ body_pb2.SIDE_BIN_RIGHT: "closureSideBinRightClosed",
20
+ body_pb2.CHARGE_PORT: "chargePortState",
21
+ body_pb2.TONNEAU: "closureTonneauClosed",
22
+ body_pb2.WINDOW_FRONT_LEFT: "windowFrontLeftClosed",
23
+ body_pb2.WINDOW_FRONT_RIGHT: "windowFrontRightClosed",
24
+ body_pb2.WINDOW_REAR_LEFT: "windowRearLeftClosed",
25
+ body_pb2.WINDOW_REAR_RIGHT: "windowRearRightClosed",
26
+ body_pb2.WINDOW_REAR: "windowRearClosed",
26
27
  }
27
28
 
28
29
  _CLOSURE_STATE_MAP: Final[dict[int, str]] = {
29
- 1: "open",
30
- 2: "closed",
31
- 4: "opening",
32
- 5: "closing",
30
+ body_pb2.CLOSURE_STATE_OPEN: "open",
31
+ body_pb2.CLOSURE_STATE_CLOSED: "closed",
32
+ body_pb2.CLOSURE_STATE_AJAR: "ajar",
33
+ body_pb2.CLOSURE_STATE_OPENING: "opening",
34
+ body_pb2.CLOSURE_STATE_CLOSING: "closing",
33
35
  }
34
36
 
35
37
 
@@ -41,11 +43,7 @@ def _enum_names(enum: Any, prefix: str) -> dict[int, str]:
41
43
  }
42
44
 
43
45
 
44
- # Other side-bin values are unconfirmed, so they pass through as raw ints.
45
- _SIDE_BIN_NEXT_ACTIONS: Final[dict[int, str]] = {
46
- body_pb2.SIDE_BIN_SNA: "sna",
47
- body_pb2.SIDE_BIN_OPEN_ALLOWED: "open_allowed",
48
- }
46
+ _SIDE_BIN_NEXT_ACTIONS: Final = _enum_names(body_pb2.SideBinNextAction, "SIDE_BIN_")
49
47
 
50
48
  # Closure id -> (next-action field, result key, value names).
51
49
  _NEXT_ACTIONS: Final[dict[int, tuple[str, str, dict[int, str]]]] = {
@@ -54,6 +52,11 @@ _NEXT_ACTIONS: Final[dict[int, tuple[str, str, dict[int, str]]]] = {
54
52
  "closureFrunkNextAction",
55
53
  _enum_names(body_pb2.FrunkNextAction, "FRUNK_"),
56
54
  ),
55
+ body_pb2.LIFTGATE: (
56
+ "liftgate_next_action",
57
+ "closureLiftgateNextAction",
58
+ _enum_names(body_pb2.LiftgateNextAction, "LIFTGATE_"),
59
+ ),
57
60
  body_pb2.SIDE_BIN_LEFT: (
58
61
  "side_bin_next_action",
59
62
  "closureSideBinLeftNextAction",
@@ -74,26 +77,42 @@ _NEXT_ACTIONS: Final[dict[int, tuple[str, str, dict[int, str]]]] = {
74
77
  "closureChargePortDoorNextAction",
75
78
  _enum_names(body_pb2.ChargePortDoorNextAction, "CHARGE_PORT_DOOR_"),
76
79
  ),
80
+ body_pb2.GROUP_WINDOWS: (
81
+ "windows_next_action",
82
+ "windowsNextAction",
83
+ _enum_names(body_pb2.WindowsNextAction, "WINDOWS_"),
84
+ ),
77
85
  }
78
86
 
79
87
  _LOCK_MAP: Final[dict[int, str]] = {
80
- 1: "doorFrontLeftLocked",
81
- 2: "doorFrontRightLocked",
82
- 3: "doorRearLeftLocked",
83
- 4: "doorRearRightLocked",
84
- 5: "closureFrunkLocked",
85
- 6: "closureTailgateLocked",
86
- 7: "closureLiftgateLocked",
87
- 8: "closureSideBinLeftLocked",
88
- 9: "closureSideBinRightLocked",
89
- 15: "closureTonneauLocked",
88
+ body_pb2.LOCK_DOOR_FRONT_LEFT: "doorFrontLeftLocked",
89
+ body_pb2.LOCK_DOOR_FRONT_RIGHT: "doorFrontRightLocked",
90
+ body_pb2.LOCK_DOOR_REAR_LEFT: "doorRearLeftLocked",
91
+ body_pb2.LOCK_DOOR_REAR_RIGHT: "doorRearRightLocked",
92
+ body_pb2.LOCK_FRUNK: "closureFrunkLocked",
93
+ body_pb2.LOCK_TAILGATE: "closureTailgateLocked",
94
+ body_pb2.LOCK_LIFTGATE: "closureLiftgateLocked",
95
+ body_pb2.LOCK_SIDE_BIN_LEFT: "closureSideBinLeftLocked",
96
+ body_pb2.LOCK_SIDE_BIN_RIGHT: "closureSideBinRightLocked",
97
+ body_pb2.LOCK_CHARGE_PORT: "closureChargePortLocked",
98
+ body_pb2.LOCK_TRUNK_SECURITY: "closureTrunkSecurityLocked",
99
+ body_pb2.LOCK_CENTER_CONSOLE: "closureCenterConsoleLocked",
100
+ body_pb2.LOCK_GLOVE_BOX: "closureGloveBoxLocked",
101
+ body_pb2.LOCK_GEAR_GUARD: "gearGuardLocked",
102
+ body_pb2.LOCK_TONNEAU: "closureTonneauLocked",
103
+ }
104
+
105
+ _LOCK_STATE_MAP: Final[dict[int, str]] = {
106
+ body_pb2.LOCK_STATE_LOCKED: "locked",
107
+ body_pb2.LOCK_STATE_UNLOCKED: "unlocked",
108
+ body_pb2.LOCK_STATE_PARTIALLY_UNLOCKED: "partially_unlocked",
90
109
  }
91
110
 
92
111
  _TRAILER_PRESENCE_MAP: Final[dict[int, str]] = {
93
- 1: "trailer_not_present",
94
- 2: "trailer_present",
95
- 3: "trailer_present_with_brakes",
96
- 4: "trailer_invalid",
112
+ body_pb2.TRAILER_NOT_PRESENT: "trailer_not_present",
113
+ body_pb2.TRAILER_PRESENT: "trailer_present",
114
+ body_pb2.TRAILER_PRESENT_WITH_BRAKES: "trailer_present_with_brakes",
115
+ body_pb2.TRAILER_INVALID: "trailer_invalid",
97
116
  }
98
117
 
99
118
 
@@ -103,10 +122,11 @@ def decode_closures(m: body_pb2.ClosuresState) -> dict[str, Any]:
103
122
 
104
123
  Fields:
105
124
  doorFrontLeftClosed, closureFrunkClosed, etc.: str
106
- ("open" | "closed" | "opening" | "closing")
107
- closureFrunkNextAction, closureTailgateNextAction,
108
- closureSideBinLeftNextAction, closureSideBinRightNextAction,
109
- closureChargePortDoorNextAction: str — e.g. "open_allowed" (shut),
125
+ ("open" | "closed" | "ajar" | "opening" | "closing")
126
+ closureFrunkNextAction, closureLiftgateNextAction,
127
+ closureTailgateNextAction, closureSideBinLeftNextAction,
128
+ closureSideBinRightNextAction, closureChargePortDoorNextAction,
129
+ windowsNextAction: str — e.g. "open_allowed" (shut),
110
130
  "close_allowed" (open); for the charge port,
111
131
  "close_not_available" means plugged in
112
132
 
@@ -122,7 +142,7 @@ def decode_closures(m: body_pb2.ClosuresState) -> dict[str, Any]:
122
142
  result[_CLOSURE_MAP[cid]] = _enum(
123
143
  _CLOSURE_STATE_MAP, state_val, what="closure state"
124
144
  )
125
- else:
145
+ elif cid != body_pb2.GROUP_WINDOWS:
126
146
  _LOGGER.debug("Unknown closure id %s (state %s)", cid, state_val)
127
147
  if cid in _NEXT_ACTIONS:
128
148
  field, key, names = _NEXT_ACTIONS[cid]
@@ -133,10 +153,12 @@ def decode_closures(m: body_pb2.ClosuresState) -> dict[str, Any]:
133
153
 
134
154
  @RVMDecoder.register("body.locks.states", body_pb2.LocksState)
135
155
  def decode_locks(m: body_pb2.LocksState) -> dict[str, Any]:
136
- """body.locks.states — lock state of every lockable closure.
156
+ """body.locks.states — lock state of every lock.
137
157
 
138
158
  Fields:
139
- doorFrontLeftLocked, closureFrunkLocked, etc.: str ("locked" | "unlocked")
159
+ doorFrontLeftLocked, closureFrunkLocked, gearGuardLocked (the Gear
160
+ Guard cable), etc.: str ("locked" | "unlocked" |
161
+ "partially_unlocked")
140
162
  """
141
163
  result: dict[str, Any] = {}
142
164
  for s in m.lock:
@@ -145,7 +167,9 @@ def decode_locks(m: body_pb2.LocksState) -> dict[str, Any]:
145
167
  if state_val is None:
146
168
  continue
147
169
  if lid in _LOCK_MAP:
148
- result[_LOCK_MAP[lid]] = "locked" if state_val == 1 else "unlocked"
170
+ result[_LOCK_MAP[lid]] = _enum(
171
+ _LOCK_STATE_MAP, state_val, what="lock state"
172
+ )
149
173
  else:
150
174
  _LOGGER.debug("Unknown lock id %s (state %s)", lid, state_val)
151
175
  return result
@@ -8,13 +8,13 @@ from .core import RVMDecoder, _enum, _present
8
8
  from .proto import charging_pb2
9
9
 
10
10
  _DAY_OF_WEEK_MAP: Final[dict[int, str]] = {
11
- 1: "sunday",
12
- 2: "monday",
13
- 3: "tuesday",
14
- 4: "wednesday",
15
- 5: "thursday",
16
- 6: "friday",
17
- 7: "saturday",
11
+ charging_pb2.ScheduleTimeWindow.SUNDAY: "sunday",
12
+ charging_pb2.ScheduleTimeWindow.MONDAY: "monday",
13
+ charging_pb2.ScheduleTimeWindow.TUESDAY: "tuesday",
14
+ charging_pb2.ScheduleTimeWindow.WEDNESDAY: "wednesday",
15
+ charging_pb2.ScheduleTimeWindow.THURSDAY: "thursday",
16
+ charging_pb2.ScheduleTimeWindow.FRIDAY: "friday",
17
+ charging_pb2.ScheduleTimeWindow.SATURDAY: "saturday",
18
18
  }
19
19
 
20
20
 
@@ -65,8 +65,8 @@ def decode_session_notification(m: charging_pb2.SessionNotification) -> dict[str
65
65
 
66
66
 
67
67
  _REMOTE_COMMAND_MAP: Final[dict[int, str]] = {
68
- 1: "start",
69
- 2: "stop",
68
+ charging_pb2.REMOTE_COMMAND_START: "start",
69
+ charging_pb2.REMOTE_COMMAND_STOP: "stop",
70
70
  }
71
71
 
72
72
 
@@ -144,34 +144,34 @@ def decode_weighted_charging_forecast(
144
144
 
145
145
 
146
146
  _CONNECTION_STATE_MAP: Final[dict[int, str]] = {
147
- 1: "disconnected",
148
- 2: "connected",
147
+ charging_pb2.CONNECTION_STATE_DISCONNECTED: "disconnected",
148
+ charging_pb2.CONNECTION_STATE_CONNECTED: "connected",
149
149
  }
150
150
 
151
151
  _CHARGING_STATE_MAP: Final[dict[int, str]] = {
152
- 1: "charging_ready",
153
- 2: "charging_connecting",
154
- 3: "charging_active",
155
- 4: "charging_complete",
156
- 5: "charging_scheduled",
157
- 6: "charging_vehicle_error",
158
- 7: "charging_station_error",
159
- 8: "charging_stopped_by_user",
160
- 9: "charging_stopped_by_station",
161
- 10: "charging_payment_error",
162
- 11: "charging_cert_error",
163
- 12: "charging_tls_error",
164
- 13: "charging_error_ac_adapter_used_on_dc",
165
- 14: "charging_error_dc_adapter_used_on_ac",
166
- 15: "charging_error_incompatible_charger",
167
- 16: "charging_sd_compensation",
168
- 17: "waiting_on_charger",
169
- 18: "charging_error_not_ready_or_incompatible_charger",
170
- 19: "charging_vehicle_stopped",
171
- 20: "charging_payment_error_start_rivian_app",
172
- 21: "charging_tls_error_unknown_charger",
173
- 22: "charging_tls_error_unexpected_fail",
174
- 23: "charging_tls_error_start_rivian_app",
152
+ charging_pb2.CHARGING_READY: "charging_ready",
153
+ charging_pb2.CHARGING_CONNECTING: "charging_connecting",
154
+ charging_pb2.CHARGING_ACTIVE: "charging_active",
155
+ charging_pb2.CHARGING_COMPLETE: "charging_complete",
156
+ charging_pb2.CHARGING_SCHEDULED: "charging_scheduled",
157
+ charging_pb2.CHARGING_VEHICLE_ERROR: "charging_vehicle_error",
158
+ charging_pb2.CHARGING_STATION_ERROR: "charging_station_error",
159
+ charging_pb2.CHARGING_USER_STOPPED: "charging_stopped_by_user",
160
+ charging_pb2.CHARGING_STATION_STOPPED: "charging_stopped_by_station",
161
+ charging_pb2.CHARGING_PAYMENT_ERROR: "charging_payment_error",
162
+ charging_pb2.CHARGING_CERT_ERROR: "charging_cert_error",
163
+ charging_pb2.CHARGING_TLS_ERROR: "charging_tls_error",
164
+ charging_pb2.CHARGING_ERROR_AC_ADAPTER_USED_ON_DC: "charging_error_ac_adapter_used_on_dc",
165
+ charging_pb2.CHARGING_ERROR_DC_ADAPTER_USED_ON_AC: "charging_error_dc_adapter_used_on_ac",
166
+ charging_pb2.CHARGING_ERROR_INCOMPATIBLE_CHARGER: "charging_error_incompatible_charger",
167
+ charging_pb2.CHARGING_SD_COMPENSATION: "charging_sd_compensation",
168
+ charging_pb2.WAITING_ON_CHARGER: "waiting_on_charger",
169
+ charging_pb2.CHARGER_NOT_READY_OR_INCOMPATIBLE: "charging_error_not_ready_or_incompatible_charger",
170
+ charging_pb2.CHARGING_VEHICLE_STOPPED: "charging_vehicle_stopped",
171
+ charging_pb2.CHARGING_PAYMENT_ERROR_START_RIVIAN_APP: "charging_payment_error_start_rivian_app",
172
+ charging_pb2.CHARGING_TLS_ERROR_UNKNOWN_CHARGER: "charging_tls_error_unknown_charger",
173
+ charging_pb2.CHARGING_TLS_ERROR_UNEXPECTED_FAIL: "charging_tls_error_unexpected_fail",
174
+ charging_pb2.CHARGING_TLS_ERROR_START_RIVIAN_APP: "charging_tls_error_start_rivian_app",
175
175
  }
176
176
 
177
177
 
@@ -211,9 +211,9 @@ def decode_time_estimation(m: charging_pb2.TimeEstimation) -> dict[str, Any]:
211
211
 
212
212
 
213
213
  _CHARGER_STATUS_MAP: Final[dict[int, str]] = {
214
- 1: "chrgr_sts_not_connected",
215
- 2: "chrgr_sts_connected_no_chrg",
216
- 3: "chrgr_sts_connected_charging",
214
+ charging_pb2.CHARGER_STATUS_NOT_CONNECTED: "chrgr_sts_not_connected",
215
+ charging_pb2.CHARGER_STATUS_CONNECTED_NO_CHARGE: "chrgr_sts_connected_no_chrg",
216
+ charging_pb2.CHARGER_STATUS_CONNECTED_CHARGING: "chrgr_sts_connected_charging",
217
217
  }
218
218
 
219
219
 
@@ -34,60 +34,69 @@ def decode_user_modes_state(m: comfort_pb2.UserModesState) -> dict[str, Any]:
34
34
 
35
35
 
36
36
  _CLIMATE_HOLD_AVAILABILITY_MAP: Final[dict[int, str]] = {
37
- 0: "unspecified",
38
- 1: "available",
39
- 2: "controllable",
40
- 3: "unavailable",
37
+ comfort_pb2.CLIMATE_HOLD_AVAILABILITY_UNSPECIFIED: "unspecified",
38
+ comfort_pb2.CLIMATE_HOLD_AVAILABLE: "available",
39
+ comfort_pb2.CLIMATE_HOLD_CONTROLLABLE: "controllable",
40
+ comfort_pb2.CLIMATE_HOLD_UNAVAILABLE: "unavailable",
41
41
  }
42
42
 
43
43
  _CLIMATE_HOLD_STATUS_MAP: Final[dict[int, str]] = {
44
- 0: "unspecified",
45
- 1: "unavailable",
46
- 2: "off",
47
- 3: "on",
48
- 4: "fault",
44
+ comfort_pb2.CLIMATE_HOLD_STATUS_UNSPECIFIED: "unspecified",
45
+ comfort_pb2.CLIMATE_HOLD_STATUS_UNAVAILABLE: "unavailable",
46
+ comfort_pb2.CLIMATE_HOLD_STATUS_OFF: "off",
47
+ comfort_pb2.CLIMATE_HOLD_STATUS_ON: "on",
48
+ comfort_pb2.CLIMATE_HOLD_STATUS_FAULT: "fault",
49
49
  }
50
50
 
51
51
  _CLIMATE_HOLD_UNAVAILABILITY_REASON_MAP: Final[dict[int, str]] = {
52
- 0: "unspecified",
53
- 1: "unknown",
54
- 2: "low_soc",
52
+ comfort_pb2.CLIMATE_HOLD_UNAVAILABILITY_UNSPECIFIED: "unspecified",
53
+ comfort_pb2.CLIMATE_HOLD_UNAVAILABILITY_UNKNOWN: "unknown",
54
+ comfort_pb2.CLIMATE_HOLD_UNAVAILABILITY_LOW_SOC: "low_soc",
55
55
  }
56
56
 
57
57
  _PET_MODE_STATE_MAP: Final[dict[int, str]] = {
58
- 0: "off",
59
- 1: "on",
60
- 2: "disabled",
61
- 3: "faulty",
58
+ comfort_pb2.PET_MODE_OFF: "off",
59
+ comfort_pb2.PET_MODE_ON: "on",
60
+ comfort_pb2.PET_MODE_DISABLED: "disabled",
61
+ comfort_pb2.PET_MODE_FAULTY: "faulty",
62
62
  }
63
63
 
64
64
  _PET_MODE_TEMPERATURE_MAP: Final[dict[int, str]] = {
65
- 0: "default",
66
- 1: "cold",
67
- 2: "hot",
68
- 3: "faulty",
65
+ comfort_pb2.PET_MODE_TEMPERATURE_DEFAULT: "default",
66
+ comfort_pb2.PET_MODE_TEMPERATURE_COLD: "cold",
67
+ comfort_pb2.PET_MODE_TEMPERATURE_HOT: "hot",
68
+ comfort_pb2.PET_MODE_TEMPERATURE_FAULTY: "faulty",
69
69
  }
70
70
 
71
- _SEAT_CONDITIONING_MAP: Final[dict[int, str]] = {
72
- 1: "steeringWheel",
73
- 5: "seatFrontLeft",
74
- 7: "seatFrontRight", # inferred
75
- 8: "seatRearLeft",
76
- 10: "seatRearRight",
77
- 11: "seatThirdRowLeft", # R1S
78
- 13: "seatThirdRowRight", # R1S
71
+ # Seat keys use the GraphQL names: row 1 is "Front", row 2 "Rear", row 3
72
+ # "ThirdRow".
73
+ _CABIN_SURFACE_MAP: Final[dict[int, str]] = {
74
+ comfort_pb2.STEERING_WHEEL: "steeringWheel",
75
+ comfort_pb2.REAR_GLASS: "rearGlass",
76
+ comfort_pb2.FRONT_GLASS: "frontGlass",
77
+ comfort_pb2.SIDEVIEW_MIRRORS: "sideviewMirrors",
78
+ comfort_pb2.SEAT_ROW_1_LEFT: "seatFrontLeft",
79
+ comfort_pb2.SEAT_ROW_1_MIDDLE: "seatFrontMiddle",
80
+ comfort_pb2.SEAT_ROW_1_RIGHT: "seatFrontRight",
81
+ comfort_pb2.SEAT_ROW_2_LEFT: "seatRearLeft",
82
+ comfort_pb2.SEAT_ROW_2_MIDDLE: "seatRearMiddle",
83
+ comfort_pb2.SEAT_ROW_2_RIGHT: "seatRearRight",
84
+ comfort_pb2.SEAT_ROW_3_LEFT: "seatThirdRowLeft",
85
+ comfort_pb2.SEAT_ROW_3_MIDDLE: "seatThirdRowMiddle",
86
+ comfort_pb2.SEAT_ROW_3_RIGHT: "seatThirdRowRight",
87
+ comfort_pb2.WIPER_AREA: "wiperArea",
79
88
  }
80
89
 
81
- _SEAT_CONDITIONING_STATUS_MAP: Final[dict[int | None, str]] = {
90
+ _CONDITIONING_LEVEL_MAP: Final[dict[int | None, str]] = {
82
91
  None: "Off",
83
- 1: "Level_1",
84
- 2: "Level_2",
85
- 3: "Level_3",
92
+ comfort_pb2.CONDITIONING_LEVEL_1: "Level_1",
93
+ comfort_pb2.CONDITIONING_LEVEL_2: "Level_2",
94
+ comfort_pb2.CONDITIONING_LEVEL_3: "Level_3",
86
95
  }
87
96
 
88
- _SEAT_CONDITIONING_TYPE_MAP: Final[dict[int, str]] = {
89
- 1: "Heat",
90
- 2: "Vent",
97
+ _CONDITIONING_TYPE_MAP: Final[dict[int, str]] = {
98
+ comfort_pb2.CONDITIONING_HEAT: "Heat",
99
+ comfort_pb2.CONDITIONING_VENT: "Vent",
91
100
  }
92
101
 
93
102
 
@@ -247,23 +256,23 @@ def decode_seat_conditioning(m: comfort_pb2.SeatConditioningStatus) -> dict[str,
247
256
  seatThirdRowLeftHeat, seatThirdRowRightHeat: str
248
257
  ("Off" | "Level_1" | "Level_2" | "Level_3")
249
258
  steeringWheelHeat: str ("Off" | "Level_1")
259
+ plus <surface>Heat/Vent for any other surface sent (middle seats,
260
+ rearGlass, frontGlass, sideviewMirrors, wiperArea)
250
261
 
251
262
  Entries without a state are skipped.
252
263
  """
253
264
  result: dict[str, Any] = {}
254
- for s in m.seat:
255
- cid, hvac_type = s.id, s.type
256
- if (state_val := _present(s, "state")) is None:
265
+ for surface in m.surface:
266
+ surface_id, hvac_type = surface.id, surface.type
267
+ if (state_val := _present(surface, "state")) is None:
257
268
  continue
258
- if cid in _SEAT_CONDITIONING_MAP and hvac_type in _SEAT_CONDITIONING_TYPE_MAP:
259
- key = (
260
- f"{_SEAT_CONDITIONING_MAP[cid]}{_SEAT_CONDITIONING_TYPE_MAP[hvac_type]}"
261
- )
262
- result[key] = _SEAT_CONDITIONING_STATUS_MAP.get(state_val, state_val)
269
+ if surface_id in _CABIN_SURFACE_MAP and hvac_type in _CONDITIONING_TYPE_MAP:
270
+ key = f"{_CABIN_SURFACE_MAP[surface_id]}{_CONDITIONING_TYPE_MAP[hvac_type]}"
271
+ result[key] = _CONDITIONING_LEVEL_MAP.get(state_val, state_val)
263
272
  else:
264
273
  _LOGGER.debug(
265
- "Unknown seat conditioning status id %s (hvac_type %s; state %s)",
266
- cid,
274
+ "Unknown cabin surface %s (hvac_type %s; state %s)",
275
+ surface_id,
267
276
  hvac_type,
268
277
  state_val,
269
278
  )
@@ -0,0 +1,99 @@
1
+ """Decoders for `device_table.*` RVM topics."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import uuid
6
+ from typing import Any, Final
7
+
8
+ from .core import RVMDecoder, _enum, _present
9
+ from .proto import device_table_pb2
10
+
11
+ _Devices = device_table_pb2.VasKeyperDevices
12
+ _KEY_STATUS_MAP: Final[dict[int, str]] = {
13
+ _Devices.KEY_STATUS_ACTIVE: "active",
14
+ _Devices.KEY_STATUS_INACTIVE: "inactive",
15
+ _Devices.KEY_STATUS_WAITING_TO_PAIR: "waiting_to_pair",
16
+ _Devices.KEY_STATUS_PAIRING: "pairing",
17
+ }
18
+
19
+ _KEY_TYPE_MAP: Final[dict[int, str]] = {
20
+ _Devices.KEY_TYPE_PHONE: "phone",
21
+ _Devices.KEY_TYPE_KEY_CARD: "key_card",
22
+ _Devices.KEY_TYPE_KEY_FOB: "key_fob",
23
+ }
24
+
25
+
26
+ @RVMDecoder.register(
27
+ "device_table.vas_keyper.devices", device_table_pb2.VasKeyperDevices
28
+ )
29
+ def decode_vas_keyper_devices(m: device_table_pb2.VasKeyperDevices) -> dict[str, Any]:
30
+ """device_table.vas_keyper.devices — a key (phone, key card or fob).
31
+
32
+ Covers every driver's keys. A deleted key isn't removed; it's resent
33
+ as inactive.
34
+
35
+ Fields (partial updates, so each only when sent):
36
+ deviceName: str — phone keys, e.g. the phone's name
37
+ keyType: str ("phone" | "key_card" | "key_fob"; key_fob inferred)
38
+ mappedIdentityId: str — the GraphQL device's `mappedIdentityId`
39
+ hrid: str — short human-readable id (key card)
40
+ profileId: str — the driver profile the key belongs to
41
+ publicKey: str — hex; phone keys
42
+ keyRevision: int — key table revision when the entry was last written
43
+ keyStatus: str ("active" | "inactive" | "waiting_to_pair" |
44
+ "pairing"); inactive covers unpaired, no longer paired and
45
+ deleted keys
46
+ infoC: int — 1 while active, 2147483647 while inactive, else the
47
+ pairing attempt number
48
+ infoA, infoB: int — unknown; always equal
49
+ deviceId: str — hex; for a key card, the GraphQL `devices[].id`
50
+ phoneId: str — the phone's UUID; phone keys
51
+ credentialHex: str — hex; likely key material
52
+ active: bool
53
+ """
54
+ result: dict[str, Any] = {}
55
+ if m.HasField("label"):
56
+ if (v := _present(m.label, "name")) is not None:
57
+ result["deviceName"] = v
58
+ if (v := _present(m.label, "key_type")) is not None:
59
+ result["keyType"] = _enum(_KEY_TYPE_MAP, v, what="key type")
60
+ if m.HasField("device"):
61
+ for field, key in (
62
+ ("mapped_identity_id", "mappedIdentityId"),
63
+ ("hrid", "hrid"),
64
+ ("profile_id", "profileId"),
65
+ ("public_key", "publicKey"),
66
+ ("revision", "keyRevision"),
67
+ ):
68
+ if (v := _present(m.device, field)) is not None:
69
+ result[key] = v
70
+
71
+ if not m.HasField("credentials"):
72
+ return result
73
+ credentials = m.credentials
74
+ if credentials.HasField("info"):
75
+ for field, key in (
76
+ ("a", "infoA"),
77
+ ("c", "infoC"),
78
+ ("b", "infoB"),
79
+ ):
80
+ if (v := _present(credentials.info, field)) is not None:
81
+ result[key] = v
82
+ if (v := _present(credentials.info, "status")) is not None:
83
+ result["keyStatus"] = _enum(_KEY_STATUS_MAP, v, what="key status")
84
+ for field in ("card", "fob", "phone"):
85
+ if not credentials.HasField(field):
86
+ continue
87
+ material = getattr(credentials, field)
88
+ if (ident := _present(material, "id")) is not None:
89
+ if field == "phone" and len(ident) == 16:
90
+ result["phoneId"] = str(uuid.UUID(bytes=ident))
91
+ else:
92
+ result["deviceId"] = ident.hex()
93
+ if (cred := _present(material, "credential")) is not None:
94
+ result["credentialHex"] = cred.hex()
95
+ if (v := _present(credentials, "key_type")) is not None:
96
+ result["keyType"] = _enum(_KEY_TYPE_MAP, v, what="key type")
97
+ if (v := _present(credentials, "active")) is not None:
98
+ result["active"] = v
99
+ return result
@@ -9,55 +9,55 @@ from .core import _LOGGER, RVMDecoder, _enum, _present
9
9
  from .proto import dynamics_pb2
10
10
 
11
11
  _DRIVE_MODE_MAP: Final[dict[int, str]] = {
12
- 1: "init_mode",
13
- 2: "everyday",
14
- 3: "off_road_snow_ice",
15
- 4: "off_road_sport_auto",
16
- 5: "off_road_sport_drift",
17
- 6: "sport_launch",
18
- 7: "fault",
19
- 8: "sport",
20
- 9: "distance",
21
- 10: "towing",
22
- 11: "off_road_auto",
23
- 12: "off_road_sand",
24
- 13: "off_road_rocks",
25
- 14: "off_road_mud",
26
- 15: "winter",
12
+ dynamics_pb2.DRIVE_MODE_INIT: "init_mode",
13
+ dynamics_pb2.DRIVE_MODE_EVERYDAY: "everyday",
14
+ dynamics_pb2.DRIVE_MODE_OFF_ROAD_SNOW_ICE: "off_road_snow_ice",
15
+ dynamics_pb2.DRIVE_MODE_OFF_ROAD_SPORT_AUTO: "off_road_sport_auto",
16
+ dynamics_pb2.DRIVE_MODE_OFF_ROAD_SPORT_DRIFT: "off_road_sport_drift",
17
+ dynamics_pb2.DRIVE_MODE_SPORT_LAUNCH: "sport_launch",
18
+ dynamics_pb2.DRIVE_MODE_FAULT: "fault",
19
+ dynamics_pb2.DRIVE_MODE_SPORT: "sport",
20
+ dynamics_pb2.DRIVE_MODE_DISTANCE: "distance",
21
+ dynamics_pb2.DRIVE_MODE_TOWING: "towing",
22
+ dynamics_pb2.DRIVE_MODE_OFF_ROAD_AUTO: "off_road_auto",
23
+ dynamics_pb2.DRIVE_MODE_OFF_ROAD_SAND: "off_road_sand",
24
+ dynamics_pb2.DRIVE_MODE_OFF_ROAD_ROCKS: "off_road_rocks",
25
+ dynamics_pb2.DRIVE_MODE_OFF_ROAD_MUD: "off_road_mud",
26
+ dynamics_pb2.DRIVE_MODE_WINTER: "winter",
27
27
  }
28
28
 
29
29
  _GEAR_MAP: Final[dict[int, str]] = {
30
- 0: "not_defined",
31
- 1: "park",
32
- 2: "reverse",
33
- 3: "neutral",
34
- 4: "drive",
30
+ dynamics_pb2.GEAR_NOT_DEFINED: "not_defined",
31
+ dynamics_pb2.GEAR_PARK: "park",
32
+ dynamics_pb2.GEAR_REVERSE: "reverse",
33
+ dynamics_pb2.GEAR_NEUTRAL: "neutral",
34
+ dynamics_pb2.GEAR_DRIVE: "drive",
35
35
  }
36
36
 
37
37
  _KNOWN_LOCATION_MAP: Final[dict[int, str]] = {
38
- 1: "unknown",
39
- 2: "home",
40
- 3: "work",
38
+ dynamics_pb2.KNOWN_LOCATION_UNKNOWN: "unknown",
39
+ dynamics_pb2.KNOWN_LOCATION_HOME: "home",
40
+ dynamics_pb2.KNOWN_LOCATION_WORK: "work",
41
41
  }
42
42
 
43
43
  _RANGE_THRESHOLD_MAP: Final[dict[int, str]] = {
44
- 1: "normal",
45
- 2: "low",
46
- 3: "red",
47
- 4: "critically_low",
44
+ dynamics_pb2.RANGE_NORMAL: "normal",
45
+ dynamics_pb2.RANGE_LOW: "low",
46
+ dynamics_pb2.RANGE_RED: "red",
47
+ dynamics_pb2.RANGE_CRITICALLY_LOW: "critically_low",
48
48
  }
49
49
 
50
50
  _TEMPERATURE_IMPACT_MAP: Final[dict[int, str]] = {
51
- 1: "normal_range",
52
- 2: "cold_may_impact",
53
- 3: "cold_impact",
51
+ dynamics_pb2.TEMPERATURE_NORMAL_RANGE: "normal_range",
52
+ dynamics_pb2.TEMPERATURE_COLD_MAY_IMPACT: "cold_may_impact",
53
+ dynamics_pb2.TEMPERATURE_COLD_IMPACT: "cold_impact",
54
54
  }
55
55
 
56
56
  _TIRE_POSITION_MAP: Final[dict[int, str]] = {
57
- 1: "FrontLeft",
58
- 2: "FrontRight",
59
- 3: "RearLeft",
60
- 4: "RearRight",
57
+ dynamics_pb2.TIRE_FRONT_LEFT: "FrontLeft",
58
+ dynamics_pb2.TIRE_FRONT_RIGHT: "FrontRight",
59
+ dynamics_pb2.TIRE_REAR_LEFT: "RearLeft",
60
+ dynamics_pb2.TIRE_REAR_RIGHT: "RearRight",
61
61
  }
62
62
 
63
63