rivian-python-client 2.2.0b12__tar.gz → 2.3.1__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 (104) hide show
  1. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/PKG-INFO +28 -4
  2. rivian_python_client-2.3.1/README.md +52 -0
  3. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/pyproject.toml +1 -3
  4. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/__version__.py +1 -1
  5. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/const.py +1 -27
  6. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/__init__.py +13 -0
  7. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/charging.py +3 -1
  8. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/comfort.py +10 -4
  9. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/departure.py +16 -6
  10. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/holiday_celebration.py +29 -7
  11. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/navigation.py +7 -3
  12. rivian_python_client-2.3.1/src/rivian/parallax/operation.py +39 -0
  13. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/charging.proto +3 -0
  14. rivian_python_client-2.3.1/src/rivian/parallax/proto/charging_pb2.py +86 -0
  15. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/charging_pb2.pyi +4 -2
  16. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/departure.proto +12 -0
  17. rivian_python_client-2.3.1/src/rivian/parallax/proto/departure_pb2.py +58 -0
  18. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/departure_pb2.pyi +16 -2
  19. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/holiday_celebration.proto +9 -5
  20. rivian_python_client-2.3.1/src/rivian/parallax/proto/holiday_celebration_pb2.py +56 -0
  21. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/holiday_celebration_pb2.pyi +6 -2
  22. rivian_python_client-2.3.1/src/rivian/parallax/proto/operation.proto +31 -0
  23. rivian_python_client-2.3.1/src/rivian/parallax/proto/operation_pb2.py +44 -0
  24. rivian_python_client-2.3.1/src/rivian/parallax/proto/operation_pb2.pyi +45 -0
  25. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/rivian.py +345 -103
  26. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/schemas/charging.graphql +0 -21
  27. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/utils.py +2 -2
  28. rivian_python_client-2.3.1/src/rivian/ws_monitor.py +395 -0
  29. rivian_python_client-2.2.0b12/README.md +0 -26
  30. rivian_python_client-2.2.0b12/src/rivian/parallax/proto/charging_pb2.py +0 -86
  31. rivian_python_client-2.2.0b12/src/rivian/parallax/proto/departure_pb2.py +0 -54
  32. rivian_python_client-2.2.0b12/src/rivian/parallax/proto/holiday_celebration_pb2.py +0 -56
  33. rivian_python_client-2.2.0b12/src/rivian/ws_monitor.py +0 -247
  34. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/.gitignore +0 -0
  35. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/__init__.py +0 -0
  36. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/ble.py +0 -0
  37. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/exceptions.py +0 -0
  38. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/body.py +0 -0
  39. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/core.py +0 -0
  40. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/device_table.py +0 -0
  41. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/dynamics.py +0 -0
  42. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/energy.py +0 -0
  43. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/energy_edge_compute.py +0 -0
  44. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/gearguard_streaming.py +0 -0
  45. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/geofence.py +0 -0
  46. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/ota.py +0 -0
  47. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/parallax.py +0 -0
  48. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/__init__.py +0 -0
  49. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/body.proto +0 -0
  50. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/body_pb2.py +0 -0
  51. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/body_pb2.pyi +0 -0
  52. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/comfort.proto +0 -0
  53. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/comfort_pb2.py +0 -0
  54. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/comfort_pb2.pyi +0 -0
  55. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/device_table.proto +0 -0
  56. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/device_table_pb2.py +0 -0
  57. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/device_table_pb2.pyi +0 -0
  58. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/dynamics.proto +0 -0
  59. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/dynamics_pb2.py +0 -0
  60. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/dynamics_pb2.pyi +0 -0
  61. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/energy.proto +0 -0
  62. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/energy_edge_compute.proto +0 -0
  63. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/energy_edge_compute_pb2.py +0 -0
  64. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/energy_edge_compute_pb2.pyi +0 -0
  65. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/energy_pb2.py +0 -0
  66. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/energy_pb2.pyi +0 -0
  67. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/gearguard_streaming.proto +0 -0
  68. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/gearguard_streaming_pb2.py +0 -0
  69. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/gearguard_streaming_pb2.pyi +0 -0
  70. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/geofence.proto +0 -0
  71. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/geofence_pb2.py +0 -0
  72. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/geofence_pb2.pyi +0 -0
  73. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/navigation.proto +0 -0
  74. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/navigation_pb2.py +0 -0
  75. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/navigation_pb2.pyi +0 -0
  76. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/ota.proto +0 -0
  77. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/ota_pb2.py +0 -0
  78. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/ota_pb2.pyi +0 -0
  79. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/parallax.proto +0 -0
  80. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/parallax_pb2.py +0 -0
  81. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/parallax_pb2.pyi +0 -0
  82. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/secure_file_transfer.proto +0 -0
  83. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/secure_file_transfer_pb2.py +0 -0
  84. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/secure_file_transfer_pb2.pyi +0 -0
  85. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/security.proto +0 -0
  86. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/security_pb2.py +0 -0
  87. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/security_pb2.pyi +0 -0
  88. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/user_passcodes.proto +0 -0
  89. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/user_passcodes_pb2.py +0 -0
  90. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/user_passcodes_pb2.pyi +0 -0
  91. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/vehicle.proto +0 -0
  92. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/vehicle_access.proto +0 -0
  93. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/vehicle_access_pb2.py +0 -0
  94. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/vehicle_access_pb2.pyi +0 -0
  95. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/vehicle_pb2.py +0 -0
  96. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/proto/vehicle_pb2.pyi +0 -0
  97. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/secure_file_transfer.py +0 -0
  98. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/security.py +0 -0
  99. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/user_passcodes.py +0 -0
  100. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/vehicle.py +0 -0
  101. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/parallax/vehicle_access.py +0 -0
  102. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/py.typed +0 -0
  103. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/schemas/gateway.graphql +0 -0
  104. {rivian_python_client-2.2.0b12 → rivian_python_client-2.3.1}/src/rivian/schemas/orders.graphql +0 -0
@@ -1,15 +1,13 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: rivian-python-client
3
- Version: 2.2.0b12
3
+ Version: 2.3.1
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
7
- Requires-Python: >=3.10
7
+ Requires-Python: >=3.11
8
8
  Requires-Dist: aiohttp>=3.0.0
9
- Requires-Dist: backports-strenum>=1.2.4; python_version < '3.11'
10
9
  Requires-Dist: cryptography>=41.0.1
11
10
  Requires-Dist: protobuf<8,>=6.31.1
12
- Requires-Dist: typing-extensions>=4.14.1; python_version < '3.11'
13
11
  Provides-Extra: ble
14
12
  Requires-Dist: bleak>=0.21; extra == 'ble'
15
13
  Requires-Dist: dbus-fast>=2.11.0; (sys_platform == 'linux') and extra == 'ble'
@@ -41,3 +39,29 @@ pre-commit install
41
39
  ```
42
40
  uv run pytest
43
41
  ```
42
+
43
+ ## Parallax
44
+
45
+ `subscribe_for_parallax_messages` streams the vehicle's Parallax RVM topics,
46
+ whose payloads are protobuf. `rivian.parallax` decodes them into dicts keyed
47
+ like the GraphQL vehicle state where a matching property exists:
48
+
49
+ ```python
50
+ from rivian import parallax
51
+
52
+
53
+ def on_message(data):
54
+ if decoded := parallax.decode_parallax_subscription_message(data):
55
+ print(decoded)
56
+ ```
57
+
58
+ `parallax.PARALLAX_RVMS` lists every topic with a decoder, and
59
+ `parallax.CHARGING_RVMS` the ones relevant to a charging session.
60
+
61
+ The schemas in `src/rivian/parallax/proto/*.proto` are reverse-engineered. After
62
+ editing one, regenerate its `*_pb2` modules (don't edit those by hand):
63
+
64
+ ```
65
+ uv run python -m grpc_tools.protoc --proto_path=src --python_out=src \
66
+ --pyi_out=src src/rivian/parallax/proto/*.proto
67
+ ```
@@ -0,0 +1,52 @@
1
+ # Python: Rivian API Client
2
+
3
+ Currently a Work In Progress
4
+
5
+ ## Dependencies
6
+
7
+ [uv](https://docs.astral.sh/uv/)
8
+
9
+ ```
10
+ curl -LsSf https://astral.sh/uv/install.sh | sh
11
+ ```
12
+
13
+ ## Setup
14
+
15
+ Install project dependencies into the uv virtual environment and run pre-commit
16
+
17
+ ```
18
+ uv sync --all-extras
19
+ pre-commit install
20
+ ```
21
+
22
+ ## Run Tests
23
+
24
+ ```
25
+ uv run pytest
26
+ ```
27
+
28
+ ## Parallax
29
+
30
+ `subscribe_for_parallax_messages` streams the vehicle's Parallax RVM topics,
31
+ whose payloads are protobuf. `rivian.parallax` decodes them into dicts keyed
32
+ like the GraphQL vehicle state where a matching property exists:
33
+
34
+ ```python
35
+ from rivian import parallax
36
+
37
+
38
+ def on_message(data):
39
+ if decoded := parallax.decode_parallax_subscription_message(data):
40
+ print(decoded)
41
+ ```
42
+
43
+ `parallax.PARALLAX_RVMS` lists every topic with a decoder, and
44
+ `parallax.CHARGING_RVMS` the ones relevant to a charging session.
45
+
46
+ The schemas in `src/rivian/parallax/proto/*.proto` are reverse-engineered. After
47
+ editing one, regenerate its `*_pb2` modules (don't edit those by hand):
48
+
49
+ ```
50
+ uv run python -m grpc_tools.protoc --proto_path=src --python_out=src \
51
+ --pyi_out=src src/rivian/parallax/proto/*.proto
52
+ ```
@@ -7,14 +7,12 @@ authors = [
7
7
  { name = "Nathan Spencer", email = "natekspencer@gmail.com" },
8
8
  { name = "Trevor Mack", email = "drummer8001@gmail.com" },
9
9
  ]
10
- requires-python = ">=3.10"
10
+ requires-python = ">=3.11"
11
11
  readme = "README.md"
12
12
  license = "MIT"
13
13
  dependencies = [
14
14
  "aiohttp (>=3.0.0)",
15
15
  "cryptography (>=41.0.1)",
16
- "backports-strenum (>=1.2.4) ; python_version < '3.11'",
17
- "typing_extensions (>=4.14.1) ; python_version < '3.11'",
18
16
  "protobuf>=6.31.1,<8",
19
17
  ]
20
18
  dynamic = ["version"]
@@ -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.0b12'
4
+ __version__ = VERSION = '2.3.1'
@@ -2,34 +2,9 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- import sys
5
+ from enum import StrEnum
6
6
  from typing import Final
7
7
 
8
- if sys.version_info >= (3, 11):
9
- from enum import StrEnum
10
- else:
11
- from backports.strenum import StrEnum
12
-
13
- LIVE_SESSION_PROPERTIES: Final[set[str]] = {
14
- "chargerId",
15
- "current",
16
- "currentCurrency",
17
- "currentMiles",
18
- "currentPrice",
19
- "isFreeSession",
20
- "isRivianCharger",
21
- "kilometersChargedPerHour",
22
- "locationId",
23
- "power",
24
- "rangeAddedThisSession",
25
- "soc",
26
- "startTime",
27
- "timeElapsed",
28
- "timeRemaining",
29
- "totalChargedEnergy",
30
- "vehicleChargerState",
31
- }
32
-
33
8
  VEHICLE_STATE_PROPERTIES: Final[set[str]] = {
34
9
  # VehicleCloudConnection
35
10
  "cloudConnection",
@@ -38,7 +13,6 @@ VEHICLE_STATE_PROPERTIES: Final[set[str]] = {
38
13
  "gnssLocation",
39
14
  "gnssError",
40
15
  # TimeStamped(String|[Nullable]Float|Int)
41
- "activeDriverName",
42
16
  "alarmSoundStatus",
43
17
  "batteryCapacity",
44
18
  "batteryCellType",
@@ -7,6 +7,9 @@ Public API:
7
7
  Same, for a raw `subscribe_for_parallax_messages` message.
8
8
  PARALLAX_RVMS: list[str] — every RVM with a registered decoder
9
9
  CHARGING_RVMS: list[str] — the subset relevant to a charging session
10
+ encode_vehicle_operation(rvm, payload=b"", ...) -> str
11
+ Builds a `send_vehicle_operation` request; an empty payload reads
12
+ the RVM, anything else (e.g. `encode_climate_hold_setting`) writes it.
10
13
 
11
14
  Layout:
12
15
  core.py - registry, payload parsing and shared helpers
@@ -41,11 +44,17 @@ from . import ( # noqa: F401 (imported to register their decoders)
41
44
  vehicle,
42
45
  vehicle_access,
43
46
  )
47
+ from .comfort import (
48
+ CLIMATE_HOLD_SETTING_RVM,
49
+ CLIMATE_HOLD_STATUS_RVM,
50
+ encode_climate_hold_setting,
51
+ )
44
52
  from .core import (
45
53
  RVMDecoder,
46
54
  decode_parallax_message,
47
55
  decode_parallax_subscription_message,
48
56
  )
57
+ from .operation import encode_vehicle_operation
49
58
 
50
59
  PARALLAX_RVMS: list[str] = list(RVMDecoder.decoders)
51
60
 
@@ -64,7 +73,11 @@ CHARGING_RVMS: list[str] = [
64
73
 
65
74
  __all__ = [
66
75
  "CHARGING_RVMS",
76
+ "CLIMATE_HOLD_SETTING_RVM",
77
+ "CLIMATE_HOLD_STATUS_RVM",
67
78
  "PARALLAX_RVMS",
68
79
  "decode_parallax_message",
69
80
  "decode_parallax_subscription_message",
81
+ "encode_climate_hold_setting",
82
+ "encode_vehicle_operation",
70
83
  ]
@@ -374,7 +374,7 @@ def decode_energy_state(m: charging_pb2.EnergyState) -> dict[str, Any]:
374
374
  energyChargerState, energyConnectionState: str — as
375
375
  charging.session.status's chargerState / connectionState, which
376
376
  these can lag
377
- _field3: int — raw
377
+ _field3, _field8: int — raw
378
378
  """
379
379
  result: dict[str, Any] = {}
380
380
  if (v := _present(m, "charging_state")) is not None:
@@ -389,6 +389,8 @@ def decode_energy_state(m: charging_pb2.EnergyState) -> dict[str, Any]:
389
389
  result["chargerStatus"] = _enum(_CHARGER_STATUS_MAP, v, what="charger status")
390
390
  if (v := _present(m, "field_3")) is not None:
391
391
  result["_field3"] = v
392
+ if (v := _present(m, "field_8")) is not None:
393
+ result["_field8"] = v
392
394
  return result
393
395
 
394
396
 
@@ -7,6 +7,9 @@ from typing import Any, Final
7
7
  from .core import _LOGGER, RVMDecoder, _enum, _present
8
8
  from .proto import comfort_pb2
9
9
 
10
+ CLIMATE_HOLD_SETTING_RVM: Final = "comfort.cabin.climate_hold_setting"
11
+ CLIMATE_HOLD_STATUS_RVM: Final = "comfort.cabin.climate_hold_status"
12
+
10
13
 
11
14
  @RVMDecoder.register(
12
15
  "comfort.cabin.hvac_settings_status", comfort_pb2.HvacSettingsStatus
@@ -200,9 +203,12 @@ def decode_cabin_ventilation(m: comfort_pb2.CabinVentilationSetting) -> dict[str
200
203
  return {"cabinVentilationEnabled": m.auto_cabin_ventilation_enabled}
201
204
 
202
205
 
203
- @RVMDecoder.register(
204
- "comfort.cabin.climate_hold_setting", comfort_pb2.ClimateHoldSetting
205
- )
206
+ def encode_climate_hold_setting(duration_seconds: int) -> bytes:
207
+ """Encode a comfort.cabin.climate_hold_setting payload."""
208
+ return comfort_pb2.ClimateHoldSetting(duration=duration_seconds).SerializeToString()
209
+
210
+
211
+ @RVMDecoder.register(CLIMATE_HOLD_SETTING_RVM, comfort_pb2.ClimateHoldSetting)
206
212
  def decode_climate_hold_setting(m: comfort_pb2.ClimateHoldSetting) -> dict[str, Any]:
207
213
  """comfort.cabin.climate_hold_setting — configured climate-hold duration.
208
214
 
@@ -212,7 +218,7 @@ def decode_climate_hold_setting(m: comfort_pb2.ClimateHoldSetting) -> dict[str,
212
218
  return {"climateHoldDuration": m.duration}
213
219
 
214
220
 
215
- @RVMDecoder.register("comfort.cabin.climate_hold_status", comfort_pb2.ClimateHoldStatus)
221
+ @RVMDecoder.register(CLIMATE_HOLD_STATUS_RVM, comfort_pb2.ClimateHoldStatus)
216
222
  def decode_climate_hold_status(m: comfort_pb2.ClimateHoldStatus) -> dict[str, Any]:
217
223
  """comfort.cabin.climate_hold_status — current climate-hold status.
218
224
 
@@ -53,11 +53,19 @@ def _decode_schedule(schedule: _Schedules.Schedule) -> dict[str, Any]:
53
53
  entry["name"] = v
54
54
  entry["isEnabled"] = schedule.is_enabled
55
55
 
56
- occurrence = schedule.occurrence
57
- entry["occurrence"] = {
58
- "days": [day for field, day in _WEEKDAYS if getattr(occurrence.days, field)],
59
- "startsAtMin": occurrence.starts_at,
60
- }
56
+ if schedule.HasField("single_occurrence"):
57
+ starts_at = schedule.single_occurrence.starts_at
58
+ entry["occurrence"] = {
59
+ "startsAt": from_epoch(starts_at.seconds + starts_at.nanos / 1e9)
60
+ }
61
+ else:
62
+ occurrence = schedule.occurrence
63
+ entry["occurrence"] = {
64
+ "days": [
65
+ day for field, day in _WEEKDAYS if getattr(occurrence.days, field)
66
+ ],
67
+ "startsAtMin": occurrence.starts_at,
68
+ }
61
69
 
62
70
  settings = schedule.departure_settings
63
71
  comfort = settings.comfort_settings
@@ -87,7 +95,9 @@ def decode_departure_schedules(m: departure_pb2.DepartureSchedules) -> dict[str,
87
95
  departureSchedules: list[dict] — the gateway's DepartureSchedule shape:
88
96
  id: str, name: str, isEnabled: bool
89
97
  occurrence: {"days": list[str] ("monday" ... "sunday"; order
90
- inferred), "startsAtMin": int (minutes after local midnight)}
98
+ inferred), "startsAtMin": int (minutes after local midnight)},
99
+ or {"startsAt": datetime} for the one-off "s-" schedule a
100
+ departNow adds (departing 10 minutes after the call)
91
101
  departureSettings: {"shouldOverrideChargeSchedule": bool,
92
102
  "comfortSettings": {"cabinTempCelsius": float,
93
103
  "frontDefogDefrost": "off" | "defog" | "defrost",
@@ -14,10 +14,27 @@ from .proto import holiday_celebration_pb2
14
14
  holiday_celebration_pb2.HolidayCelebrationEnabled,
15
15
  )
16
16
  def decode_holiday_celebration_enabled(
17
- _m: holiday_celebration_pb2.HolidayCelebrationEnabled,
17
+ m: holiday_celebration_pb2.HolidayCelebrationEnabled,
18
18
  ) -> dict[str, Any]:
19
- """holiday_celebration.car_costume.holiday_celebration_enabled — unmapped."""
20
- return {}
19
+ """holiday_celebration.car_costume.holiday_celebration_enabled.
20
+
21
+ The names are inferred; the app has no class for this topic.
22
+
23
+ Fields:
24
+ holidayCelebrationAvailable: bool — the (seasonal) feature is offered
25
+ holidayCelebrationEnabled: bool — the user's on/off switch
26
+ """
27
+ return {
28
+ "holidayCelebrationAvailable": m.available,
29
+ "holidayCelebrationEnabled": m.enabled,
30
+ }
31
+
32
+
33
+ # Best guess; 2 hasn't been seen.
34
+ _CAR_COSTUME_AVAILABILITY_MAP: Final[dict[int, str]] = {
35
+ 1: "available",
36
+ 3: "unavailable",
37
+ }
21
38
 
22
39
 
23
40
  _COSTUME_THEME_MAP: Final[dict[int, str]] = {
@@ -51,7 +68,7 @@ def decode_car_costume_settings(
51
68
  costumeInteriorLightShowEnabled: bool
52
69
  costumeInteriorOverheadLightsEnabled: bool
53
70
  costumeLightsColor: int
54
- costumeEffect: int
71
+ costumeEffect: int (1 none, 3 the display show; inferred)
55
72
  costumeEffectTrigger: str ("manual" | "motion"), None when unset
56
73
  """
57
74
  return {
@@ -86,15 +103,20 @@ def decode_car_costume_state(
86
103
  Names come from the app; the int values are unmapped enums.
87
104
 
88
105
  Fields:
89
- carCostumeAvailability: int
106
+ carCostumeAvailability: str | int ("available" | "unavailable"; a
107
+ best guess), the raw int when unmapped
90
108
  costumeTheme: str | None ("none" | "ghostbusters" |
91
109
  "ghostbusters_display"; inferred), None when unset
92
110
  costumeMotionTriggerDetected: bool
93
- activeCostumeEffect: int
111
+ activeCostumeEffect: int (1 none, 3 the display show; inferred)
94
112
  costumeStartTime: datetime, only when sent
95
113
  """
96
114
  result: dict[str, Any] = {
97
- "carCostumeAvailability": m.car_costume_availability,
115
+ "carCostumeAvailability": _enum(
116
+ _CAR_COSTUME_AVAILABILITY_MAP,
117
+ m.car_costume_availability,
118
+ what="car costume availability",
119
+ ),
98
120
  "costumeTheme": (
99
121
  _enum(_COSTUME_THEME_MAP, m.costume_theme, what="costume theme")
100
122
  if m.costume_theme
@@ -310,7 +310,9 @@ def decode_trip_info(m: navigation_pb2.TripInfo) -> dict[str, Any]:
310
310
  and incidents ({firstIndex, lastIndex, type})
311
311
  overviewPolyline: str — Google-encoded, whole trip
312
312
  nextWaypointDepartureTime: datetime — the next stop's departure if
313
- it's a charging stop, else its arrival
313
+ it's a charging stop, else its arrival. It stops updating once
314
+ the first stop is reached, keeping that stop's time for the
315
+ rest of the trip; use waypoints[0] instead
314
316
  finalStateOfCharge, finalRangeRemaining: float — the last
315
317
  waypoint's (percent, meters)
316
318
  socIsBelowLimit: bool
@@ -346,9 +348,11 @@ def decode_trip_progress(m: navigation_pb2.TripProgress) -> dict[str, Any]:
346
348
  """navigation.navigation_service.trip_progress — live progress on the active trip.
347
349
 
348
350
  Fields:
349
- nextWaypointArrivalTime: datetime — live ETA
351
+ nextWaypointArrivalTime: datetime — live ETA, to the minute
350
352
  finalDestinationArrivalTime: datetime — live ETA for the last
351
- waypoint; missing for one message after the waypoints change
353
+ waypoint, to the minute; missing while the route is
354
+ recalculating and on the stale progress the vehicle keeps
355
+ resending after navigation ends
352
356
  nextStopIndex: int
353
357
  distanceRemaining, durationRemaining: float — to the next waypoint
354
358
  (meters, seconds)
@@ -0,0 +1,39 @@
1
+ """Encoder for `sendVehicleOperation` requests."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import base64
6
+ import uuid
7
+
8
+ from .proto import operation_pb2
9
+
10
+ _Request = operation_pb2.VehicleOperationRequest
11
+
12
+
13
+ def encode_vehicle_operation(
14
+ rvm: str,
15
+ payload: bytes = b"",
16
+ phone_id: bytes = bytes(16),
17
+ request_id: str | None = None,
18
+ ) -> str:
19
+ """Encode a `sendVehicleOperation` request as a base64 string.
20
+
21
+ An empty payload asks the vehicle to publish the current value of the RVM,
22
+ anything else writes it. The vehicle accepts an all-zero phone id.
23
+ """
24
+ request = _Request(
25
+ metadata=_Request.Metadata(
26
+ phone_info=_Request.Metadata.PhoneInfo(field_1=1, phone_id=phone_id),
27
+ request_id=request_id or str(uuid.uuid4()),
28
+ ),
29
+ operation=_Request.Operation(
30
+ rvm=rvm,
31
+ type=(
32
+ operation_pb2.OPERATION_WRITE
33
+ if payload
34
+ else operation_pb2.OPERATION_READ
35
+ ),
36
+ payload=payload,
37
+ ),
38
+ )
39
+ return base64.b64encode(request.SerializeToString()).decode("utf-8")
@@ -219,6 +219,9 @@ message EnergyState {
219
219
  optional ChargerStatus charger_status = 2; // inferred
220
220
  optional int32 field_3 = 3; // unknown
221
221
  float power = 4; // kW; same as charging.session.power
222
+ // Unknown; sent with remote_command's start_available as the vehicle sleeps
223
+ // with a user-stopped session.
224
+ optional int32 field_8 = 8;
222
225
  string field_10 = 10; // unknown
223
226
  optional ConnectionState connection_state = 11;
224
227
  }
@@ -0,0 +1,86 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: rivian/parallax/proto/charging.proto
5
+ # Protobuf Python Version: 6.31.1
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 6,
15
+ 31,
16
+ 1,
17
+ '',
18
+ 'rivian/parallax/proto/charging.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+
26
+
27
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$rivian/parallax/proto/charging.proto\x12\x18rivian.parallax.charging\"\xe8\x04\n\x12ScheduleTimeWindow\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x43\n\x06window\x18\x02 \x01(\x0b\x32\x33.rivian.parallax.charging.ScheduleTimeWindow.Window\x1a\xbe\x02\n\x06Window\x12\x12\n\nstart_time\x18\x01 \x01(\x05\x12\x10\n\x08\x65nd_time\x18\x02 \x01(\x05\x12\x10\n\x08\x64uration\x18\x03 \x01(\x05\x12\x11\n\x04\x61mps\x18\x04 \x01(\x05H\x00\x88\x01\x01\x12L\n\x08location\x18\x05 \x01(\x0b\x32:.rivian.parallax.charging.ScheduleTimeWindow.GeoCoordinate\x12I\n\tstart_day\x18\x06 \x01(\x0e\x32\x36.rivian.parallax.charging.ScheduleTimeWindow.DayOfWeek\x12G\n\x07\x65nd_day\x18\x07 \x01(\x0e\x32\x36.rivian.parallax.charging.ScheduleTimeWindow.DayOfWeekB\x07\n\x05_amps\x1a\x34\n\rGeoCoordinate\x12\x10\n\x08latitude\x18\x01 \x01(\x01\x12\x11\n\tlongitude\x18\x02 \x01(\x01\"\x84\x01\n\tDayOfWeek\x12\x1b\n\x17\x44\x41Y_OF_WEEK_UNSPECIFIED\x10\x00\x12\n\n\x06SUNDAY\x10\x01\x12\n\n\x06MONDAY\x10\x02\x12\x0b\n\x07TUESDAY\x10\x03\x12\r\n\tWEDNESDAY\x10\x04\x12\x0c\n\x08THURSDAY\x10\x05\x12\n\n\x06\x46RIDAY\x10\x06\x12\x0c\n\x08SATURDAY\x10\x07\"\xb6\x01\n\x13SessionNotification\x12\x1e\n\x16unexpected_stop_reason\x18\x01 \x01(\x05\x12\x44\n\rderate_status\x18\x02 \x01(\x0e\x32-.rivian.parallax.charging.ChargerDerateStatus\x12\x39\n\x0b\x66\x61ult_chime\x18\x03 \x01(\x0e\x32$.rivian.parallax.charging.FaultChime\"\\\n\x14SessionRemoteCommand\x12\x44\n\x0fstart_available\x18\x01 \x01(\x0e\x32+.rivian.parallax.charging.StartAvailability\"1\n\tSocSlider\x12\x16\n\tsoc_limit\x18\x01 \x01(\x05H\x00\x88\x01\x01\x42\x0c\n\n_soc_limit\"\x1f\n\nTripTarget\x12\x11\n\tsoc_limit\x18\x02 \x01(\x05\"\xf3\x01\n\x15SmartChargingSettings\x12S\n\x0eready_by_times\x18\x01 \x03(\x0b\x32;.rivian.parallax.charging.SmartChargingSettings.ReadyByTime\x12\x1c\n\x14\x63lean_energy_enabled\x18\x02 \x01(\x08\x1ag\n\x0bReadyByTime\x12\r\n\x05hours\x18\x01 \x01(\x05\x12\x0f\n\x07minutes\x18\x02 \x01(\x05\x12\x38\n\x04\x64\x61ys\x18\x03 \x03(\x0e\x32*.rivian.parallax.charging.SmartChargingDay\"\xf0\x01\n\x11SmartChargingInfo\x12K\n\x0bresume_time\x18\x01 \x01(\x0b\x32\x36.rivian.parallax.charging.SmartChargingInfo.ResumeTime\x12I\n\x0cnotification\x18\x02 \x01(\x0e\x32\x33.rivian.parallax.charging.SmartChargingNotification\x12\x15\n\rschedule_type\x18\x03 \x01(\x05\x1a,\n\nResumeTime\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\"\x1a\n\x18WeightedChargingForecast\"\xda\x01\n\rSessionStatus\x12H\n\x10\x63onnection_state\x18\x01 \x01(\x0e\x32).rivian.parallax.charging.ConnectionStateH\x00\x88\x01\x01\x12\x44\n\x0e\x63harging_state\x18\x02 \x01(\x0e\x32\'.rivian.parallax.charging.ChargingStateH\x01\x88\x01\x01\x12\x11\n\tevse_type\x18\x03 \x01(\x05\x42\x13\n\x11_connection_stateB\x11\n\x0f_charging_state\"v\n\x0eTimeEstimation\x12\x42\n\x08validity\x18\x01 \x01(\x0e\x32\x30.rivian.parallax.charging.TimeEstimationValidity\x12 \n\x18\x65stimated_time_remaining\x18\x02 \x01(\x05\"\x83\x03\n\x0b\x45nergyState\x12\x44\n\x0e\x63harging_state\x18\x01 \x01(\x0e\x32\'.rivian.parallax.charging.ChargingStateH\x00\x88\x01\x01\x12\x44\n\x0e\x63harger_status\x18\x02 \x01(\x0e\x32\'.rivian.parallax.charging.ChargerStatusH\x01\x88\x01\x01\x12\x14\n\x07\x66ield_3\x18\x03 \x01(\x05H\x02\x88\x01\x01\x12\r\n\x05power\x18\x04 \x01(\x02\x12\x14\n\x07\x66ield_8\x18\x08 \x01(\x05H\x03\x88\x01\x01\x12\x10\n\x08\x66ield_10\x18\n \x01(\t\x12H\n\x10\x63onnection_state\x18\x0b \x01(\x0e\x32).rivian.parallax.charging.ConnectionStateH\x04\x88\x01\x01\x42\x11\n\x0f_charging_stateB\x11\n\x0f_charger_statusB\n\n\x08_field_3B\n\n\x08_field_8B\x13\n\x11_connection_state\"\x1d\n\x0cSessionPower\x12\r\n\x05power\x18\x01 \x01(\x02*\xb2\x05\n\x13\x43hargerDerateStatus\x12\x16\n\x12\x44\x45RATE_STATUS_NONE\x10\x00\x12\x1e\n\x1a\x44\x45RATE_STATUS_WARM_ADAPTER\x10\x01\x12\x1e\n\x1a\x44\x45RATE_STATUS_DC_WARM_PLUG\x10\x02\x12\x1e\n\x1a\x44\x45RATE_STATUS_AC_WARM_PLUG\x10\x03\x12\x1f\n\x1b\x44\x45RATE_STATUS_EVSE_DERATING\x10\x04\x12\x1d\n\x19\x44\x45RATE_STATUS_NEARING_TOC\x10\x05\x12/\n+DERATE_STATUS_NEAR_TOC_LFP_BATT_CALIBRATING\x10\x06\x12\"\n\x1e\x44\x45RATE_STATUS_HVAC_PRIORITIZED\x10\x07\x12!\n\x1d\x44\x45RATE_STATUS_BATTERY_HEATING\x10\x08\x12!\n\x1d\x44\x45RATE_STATUS_BATTERY_COOLING\x10\t\x12\x32\n.DERATE_STATUS_CELL_THERMAL_LIM_COLD_NO_CURRENT\x10\n\x12\x31\n-DERATE_STATUS_CELL_THERMAL_LIM_HOT_NO_CURRENT\x10\x0b\x12\'\n#DERATE_STATUS_CELL_THERMAL_LIM_COLD\x10\x0c\x12&\n\"DERATE_STATUS_CELL_THERMAL_LIM_HOT\x10\r\x12+\n\'DERATE_STATUS_PACK_HARDWARE_THERMAL_LIM\x10\x0e\x12 \n\x1c\x44\x45RATE_STATUS_HIGH_SOC_SIGMA\x10\x0f\x12\"\n\x1e\x44\x45RATE_STATUS_HV_BATTERY_FAULT\x10\x10\x12\x1d\n\x19\x44\x45RATE_STATUS_DCAC_EXPORT\x10\x11*\xdb\x03\n\nFaultChime\x12\x14\n\x10\x46\x41ULT_CHIME_NONE\x10\x00\x12%\n!FAULT_CHIME_CHARGING_DISABLED_ALL\x10\x01\x12$\n FAULT_CHIME_CHARGING_DISABLED_DC\x10\x02\x12-\n)FAULT_CHIME_CHARGING_DISABLED_PIN_TEMP_DC\x10\x03\x12\x36\n2FAULT_CHIME_CHARGING_DISABLED_PIN_TEMP_GRADIENT_DC\x10\x04\x12$\n FAULT_CHIME_CHARGING_DEGRADED_DC\x10\x05\x12$\n FAULT_CHIME_CHARGING_DISABLED_AC\x10\x06\x12-\n)FAULT_CHIME_CHARGING_DISABLED_PIN_TEMP_AC\x10\x07\x12$\n FAULT_CHIME_CHARGING_DEGRADED_AC\x10\x08\x12\x34\n0FAULT_CHIME_CHARGING_DISABLED_PARTIAL_CONNECTION\x10\t\x12,\n(FAULT_CHIME_CHARGING_DISABLED_NOT_PARKED\x10\n*j\n\x11StartAvailability\x12\x1a\n\x16START_AVAILABILITY_SNA\x10\x00\x12\x1c\n\x18START_AVAILABILITY_FALSE\x10\x01\x12\x1b\n\x17START_AVAILABILITY_TRUE\x10\x02*\x97\x02\n\x10SmartChargingDay\x12\"\n\x1eSMART_CHARGING_DAY_UNSPECIFIED\x10\x00\x12\x1d\n\x19SMART_CHARGING_DAY_MONDAY\x10\x01\x12\x1e\n\x1aSMART_CHARGING_DAY_TUESDAY\x10\x02\x12 \n\x1cSMART_CHARGING_DAY_WEDNESDAY\x10\x03\x12\x1f\n\x1bSMART_CHARGING_DAY_THURSDAY\x10\x04\x12\x1d\n\x19SMART_CHARGING_DAY_FRIDAY\x10\x05\x12\x1f\n\x1bSMART_CHARGING_DAY_SATURDAY\x10\x06\x12\x1d\n\x19SMART_CHARGING_DAY_SUNDAY\x10\x07*\xbc\x02\n\x19SmartChargingNotification\x12#\n\x1fSMART_CHARGING_NOTIFICATION_SNA\x10\x00\x12:\n6SMART_CHARGING_NOTIFICATION_CHARGING_WITH_CLEAN_ENERGY\x10\x01\x12/\n+SMART_CHARGING_NOTIFICATION_CHARGING_PAUSED\x10\x02\x12<\n8SMART_CHARGING_NOTIFICATION_CLEAN_ENERGY_NOT_ENOUGH_TIME\x10\x03\x12O\nKSMART_CHARGING_NOTIFICATION_CLEAN_ENERGY_FORECAST_UNAVAILABLE_OR_INCOMPLETE\x10\x04*\xaf\x01\n\x0f\x43onnectionState\x12\x19\n\x15\x43ONNECTION_STATE_INIT\x10\x00\x12!\n\x1d\x43ONNECTION_STATE_DISCONNECTED\x10\x01\x12\x1e\n\x1a\x43ONNECTION_STATE_CONNECTED\x10\x02\x12\x1a\n\x16\x43ONNECTION_STATE_ERROR\x10\x03\x12\"\n\x1e\x43ONNECTION_STATE_V2L_CONNECTED\x10\x04*\xc4\x06\n\rChargingState\x12\x1e\n\x1a\x43HARGING_STATE_UNSPECIFIED\x10\x00\x12\x12\n\x0e\x43HARGING_READY\x10\x01\x12\x17\n\x13\x43HARGING_CONNECTING\x10\x02\x12\x13\n\x0f\x43HARGING_ACTIVE\x10\x03\x12\x15\n\x11\x43HARGING_COMPLETE\x10\x04\x12\x16\n\x12\x43HARGING_SCHEDULED\x10\x05\x12\x1a\n\x16\x43HARGING_VEHICLE_ERROR\x10\x06\x12\x1a\n\x16\x43HARGING_STATION_ERROR\x10\x07\x12\x19\n\x15\x43HARGING_USER_STOPPED\x10\x08\x12\x1c\n\x18\x43HARGING_STATION_STOPPED\x10\t\x12\x1a\n\x16\x43HARGING_PAYMENT_ERROR\x10\n\x12\x17\n\x13\x43HARGING_CERT_ERROR\x10\x0b\x12\x16\n\x12\x43HARGING_TLS_ERROR\x10\x0c\x12(\n$CHARGING_ERROR_AC_ADAPTER_USED_ON_DC\x10\r\x12(\n$CHARGING_ERROR_DC_ADAPTER_USED_ON_AC\x10\x0e\x12\'\n#CHARGING_ERROR_INCOMPATIBLE_CHARGER\x10\x0f\x12\x1c\n\x18\x43HARGING_SD_COMPENSATION\x10\x10\x12\x16\n\x12WAITING_ON_CHARGER\x10\x11\x12%\n!CHARGER_NOT_READY_OR_INCOMPATIBLE\x10\x12\x12\x1c\n\x18\x43HARGING_VEHICLE_STOPPED\x10\x13\x12+\n\'CHARGING_PAYMENT_ERROR_START_RIVIAN_APP\x10\x14\x12&\n\"CHARGING_TLS_ERROR_UNKNOWN_CHARGER\x10\x15\x12&\n\"CHARGING_TLS_ERROR_UNEXPECTED_FAIL\x10\x16\x12\'\n#CHARGING_TLS_ERROR_START_RIVIAN_APP\x10\x17\x12\"\n\x1e\x43HARGING_SMART_CHARGING_PAUSED\x10\x18\x12\"\n\x1e\x43HARGING_SMART_CHARGING_ACTIVE\x10\x19*\xb4\x01\n\x16TimeEstimationValidity\x12!\n\x1dTIME_ESTIMATION_VALIDITY_NONE\x10\x00\x12\"\n\x1eTIME_ESTIMATION_VALIDITY_VALID\x10\x01\x12$\n TIME_ESTIMATION_VALIDITY_INVALID\x10\x02\x12-\n)TIME_ESTIMATION_VALIDITY_PACK_DISCHARGING\x10\x03*\xa0\x01\n\rChargerStatus\x12\x1e\n\x1a\x43HARGER_STATUS_UNSPECIFIED\x10\x00\x12 \n\x1c\x43HARGER_STATUS_NOT_CONNECTED\x10\x01\x12&\n\"CHARGER_STATUS_CONNECTED_NO_CHARGE\x10\x02\x12%\n!CHARGER_STATUS_CONNECTED_CHARGING\x10\x03\x62\x06proto3')
28
+
29
+ _globals = globals()
30
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
31
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'rivian.parallax.proto.charging_pb2', _globals)
32
+ if not _descriptor._USE_C_DESCRIPTORS:
33
+ DESCRIPTOR._loaded_options = None
34
+ _globals['_CHARGERDERATESTATUS']._serialized_start=2328
35
+ _globals['_CHARGERDERATESTATUS']._serialized_end=3018
36
+ _globals['_FAULTCHIME']._serialized_start=3021
37
+ _globals['_FAULTCHIME']._serialized_end=3496
38
+ _globals['_STARTAVAILABILITY']._serialized_start=3498
39
+ _globals['_STARTAVAILABILITY']._serialized_end=3604
40
+ _globals['_SMARTCHARGINGDAY']._serialized_start=3607
41
+ _globals['_SMARTCHARGINGDAY']._serialized_end=3886
42
+ _globals['_SMARTCHARGINGNOTIFICATION']._serialized_start=3889
43
+ _globals['_SMARTCHARGINGNOTIFICATION']._serialized_end=4205
44
+ _globals['_CONNECTIONSTATE']._serialized_start=4208
45
+ _globals['_CONNECTIONSTATE']._serialized_end=4383
46
+ _globals['_CHARGINGSTATE']._serialized_start=4386
47
+ _globals['_CHARGINGSTATE']._serialized_end=5222
48
+ _globals['_TIMEESTIMATIONVALIDITY']._serialized_start=5225
49
+ _globals['_TIMEESTIMATIONVALIDITY']._serialized_end=5405
50
+ _globals['_CHARGERSTATUS']._serialized_start=5408
51
+ _globals['_CHARGERSTATUS']._serialized_end=5568
52
+ _globals['_SCHEDULETIMEWINDOW']._serialized_start=67
53
+ _globals['_SCHEDULETIMEWINDOW']._serialized_end=683
54
+ _globals['_SCHEDULETIMEWINDOW_WINDOW']._serialized_start=176
55
+ _globals['_SCHEDULETIMEWINDOW_WINDOW']._serialized_end=494
56
+ _globals['_SCHEDULETIMEWINDOW_GEOCOORDINATE']._serialized_start=496
57
+ _globals['_SCHEDULETIMEWINDOW_GEOCOORDINATE']._serialized_end=548
58
+ _globals['_SCHEDULETIMEWINDOW_DAYOFWEEK']._serialized_start=551
59
+ _globals['_SCHEDULETIMEWINDOW_DAYOFWEEK']._serialized_end=683
60
+ _globals['_SESSIONNOTIFICATION']._serialized_start=686
61
+ _globals['_SESSIONNOTIFICATION']._serialized_end=868
62
+ _globals['_SESSIONREMOTECOMMAND']._serialized_start=870
63
+ _globals['_SESSIONREMOTECOMMAND']._serialized_end=962
64
+ _globals['_SOCSLIDER']._serialized_start=964
65
+ _globals['_SOCSLIDER']._serialized_end=1013
66
+ _globals['_TRIPTARGET']._serialized_start=1015
67
+ _globals['_TRIPTARGET']._serialized_end=1046
68
+ _globals['_SMARTCHARGINGSETTINGS']._serialized_start=1049
69
+ _globals['_SMARTCHARGINGSETTINGS']._serialized_end=1292
70
+ _globals['_SMARTCHARGINGSETTINGS_READYBYTIME']._serialized_start=1189
71
+ _globals['_SMARTCHARGINGSETTINGS_READYBYTIME']._serialized_end=1292
72
+ _globals['_SMARTCHARGINGINFO']._serialized_start=1295
73
+ _globals['_SMARTCHARGINGINFO']._serialized_end=1535
74
+ _globals['_SMARTCHARGINGINFO_RESUMETIME']._serialized_start=1491
75
+ _globals['_SMARTCHARGINGINFO_RESUMETIME']._serialized_end=1535
76
+ _globals['_WEIGHTEDCHARGINGFORECAST']._serialized_start=1537
77
+ _globals['_WEIGHTEDCHARGINGFORECAST']._serialized_end=1563
78
+ _globals['_SESSIONSTATUS']._serialized_start=1566
79
+ _globals['_SESSIONSTATUS']._serialized_end=1784
80
+ _globals['_TIMEESTIMATION']._serialized_start=1786
81
+ _globals['_TIMEESTIMATION']._serialized_end=1904
82
+ _globals['_ENERGYSTATE']._serialized_start=1907
83
+ _globals['_ENERGYSTATE']._serialized_end=2294
84
+ _globals['_SESSIONPOWER']._serialized_start=2296
85
+ _globals['_SESSIONPOWER']._serialized_end=2325
86
+ # @@protoc_insertion_point(module_scope)
@@ -337,20 +337,22 @@ class TimeEstimation(_message.Message):
337
337
  def __init__(self, validity: _Optional[_Union[TimeEstimationValidity, str]] = ..., estimated_time_remaining: _Optional[int] = ...) -> None: ...
338
338
 
339
339
  class EnergyState(_message.Message):
340
- __slots__ = ("charging_state", "charger_status", "field_3", "power", "field_10", "connection_state")
340
+ __slots__ = ("charging_state", "charger_status", "field_3", "power", "field_8", "field_10", "connection_state")
341
341
  CHARGING_STATE_FIELD_NUMBER: _ClassVar[int]
342
342
  CHARGER_STATUS_FIELD_NUMBER: _ClassVar[int]
343
343
  FIELD_3_FIELD_NUMBER: _ClassVar[int]
344
344
  POWER_FIELD_NUMBER: _ClassVar[int]
345
+ FIELD_8_FIELD_NUMBER: _ClassVar[int]
345
346
  FIELD_10_FIELD_NUMBER: _ClassVar[int]
346
347
  CONNECTION_STATE_FIELD_NUMBER: _ClassVar[int]
347
348
  charging_state: ChargingState
348
349
  charger_status: ChargerStatus
349
350
  field_3: int
350
351
  power: float
352
+ field_8: int
351
353
  field_10: str
352
354
  connection_state: ConnectionState
353
- def __init__(self, charging_state: _Optional[_Union[ChargingState, str]] = ..., charger_status: _Optional[_Union[ChargerStatus, str]] = ..., field_3: _Optional[int] = ..., power: _Optional[float] = ..., field_10: _Optional[str] = ..., connection_state: _Optional[_Union[ConnectionState, str]] = ...) -> None: ...
355
+ def __init__(self, charging_state: _Optional[_Union[ChargingState, str]] = ..., charger_status: _Optional[_Union[ChargerStatus, str]] = ..., field_3: _Optional[int] = ..., power: _Optional[float] = ..., field_8: _Optional[int] = ..., field_10: _Optional[str] = ..., connection_state: _Optional[_Union[ConnectionState, str]] = ...) -> None: ...
354
356
 
355
357
  class SessionPower(_message.Message):
356
358
  __slots__ = ("power",)
@@ -15,9 +15,21 @@ message DepartureSchedules {
15
15
  optional string name = 2;
16
16
  bool is_enabled = 3;
17
17
  Occurrence occurrence = 4;
18
+ // Set instead of occurrence on the one-off "s-" schedule a departNow
19
+ // adds; the gateway leaves that schedule out.
20
+ SingleOccurrence single_occurrence = 5;
18
21
  DepartureSettings departure_settings = 6;
19
22
  }
20
23
 
24
+ message SingleOccurrence {
25
+ StartsAt starts_at = 1;
26
+
27
+ message StartsAt {
28
+ int64 seconds = 1; // epoch seconds
29
+ int32 nanos = 2;
30
+ }
31
+ }
32
+
21
33
  message Occurrence {
22
34
  Days days = 1;
23
35
  optional int32 starts_at = 2; // minutes after local midnight
@@ -0,0 +1,58 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: rivian/parallax/proto/departure.proto
5
+ # Protobuf Python Version: 6.31.1
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 6,
15
+ 31,
16
+ 1,
17
+ '',
18
+ 'rivian/parallax/proto/departure.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+
26
+
27
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%rivian/parallax/proto/departure.proto\x12\x19rivian.parallax.departure\"\xca\r\n\x12\x44\x65partureSchedules\x12H\n\x08schedule\x18\x01 \x03(\x0b\x32\x36.rivian.parallax.departure.DepartureSchedules.Schedule\x12K\n\nupdated_at\x18\x02 \x01(\x0b\x32\x37.rivian.parallax.departure.DepartureSchedules.UpdatedAt\x1a\xd8\x02\n\x08Schedule\x12\x0f\n\x02id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x11\n\x04name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x12\n\nis_enabled\x18\x03 \x01(\x08\x12L\n\noccurrence\x18\x04 \x01(\x0b\x32\x38.rivian.parallax.departure.DepartureSchedules.Occurrence\x12Y\n\x11single_occurrence\x18\x05 \x01(\x0b\x32>.rivian.parallax.departure.DepartureSchedules.SingleOccurrence\x12[\n\x12\x64\x65parture_settings\x18\x06 \x01(\x0b\x32?.rivian.parallax.departure.DepartureSchedules.DepartureSettingsB\x05\n\x03_idB\x07\n\x05_name\x1a\x9a\x01\n\x10SingleOccurrence\x12Z\n\tstarts_at\x18\x01 \x01(\x0b\x32G.rivian.parallax.departure.DepartureSchedules.SingleOccurrence.StartsAt\x1a*\n\x08StartsAt\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\x1at\n\nOccurrence\x12@\n\x04\x64\x61ys\x18\x01 \x01(\x0b\x32\x32.rivian.parallax.departure.DepartureSchedules.Days\x12\x16\n\tstarts_at\x18\x02 \x01(\x05H\x00\x88\x01\x01\x42\x0c\n\n_starts_at\x1a~\n\x04\x44\x61ys\x12\x0e\n\x06monday\x18\x01 \x01(\x08\x12\x0f\n\x07tuesday\x18\x02 \x01(\x08\x12\x11\n\twednesday\x18\x03 \x01(\x08\x12\x10\n\x08thursday\x18\x04 \x01(\x08\x12\x0e\n\x06\x66riday\x18\x05 \x01(\x08\x12\x10\n\x08saturday\x18\x06 \x01(\x08\x12\x0e\n\x06sunday\x18\x07 \x01(\x08\x1a\x95\x01\n\x11\x44\x65partureSettings\x12W\n\x10\x63omfort_settings\x18\x01 \x01(\x0b\x32=.rivian.parallax.departure.DepartureSchedules.ComfortSettings\x12\'\n\x1fshould_override_charge_schedule\x18\x02 \x01(\x08\x1a\xde\x01\n\x0f\x43omfortSettings\x12\x19\n\x11\x63\x61\x62in_temperature\x18\x01 \x01(\x02\x12I\n\x13\x66ront_defog_defrost\x18\x02 \x01(\x0e\x32,.rivian.parallax.departure.DefogDefrostLevel\x12\x65\n\x18surface_heat_vent_levels\x18\x03 \x01(\x0b\x32\x43.rivian.parallax.departure.DepartureSchedules.SurfaceHeatVentLevels\x1a\x88\x03\n\x15SurfaceHeatVentLevels\x12H\n\x0f\x66ront_left_seat\x18\x01 \x01(\x0e\x32/.rivian.parallax.departure.SurfaceHeatVentLevel\x12I\n\x10\x66ront_right_seat\x18\x02 \x01(\x0e\x32/.rivian.parallax.departure.SurfaceHeatVentLevel\x12G\n\x0erear_left_seat\x18\x03 \x01(\x0e\x32/.rivian.parallax.departure.SurfaceHeatVentLevel\x12H\n\x0frear_right_seat\x18\x04 \x01(\x0e\x32/.rivian.parallax.departure.SurfaceHeatVentLevel\x12G\n\x0esteering_wheel\x18\x05 \x01(\x0e\x32/.rivian.parallax.departure.SurfaceHeatVentLevel\x1a+\n\tUpdatedAt\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05*^\n\x11\x44\x65\x66ogDefrostLevel\x12\x15\n\x11\x44\x45\x46OG_DEFROST_OFF\x10\x00\x12\x17\n\x13\x44\x45\x46OG_DEFROST_DEFOG\x10\x01\x12\x19\n\x15\x44\x45\x46OG_DEFROST_DEFROST\x10\x02*\x9f\x01\n\x14SurfaceHeatVentLevel\x12\x0f\n\x0bSURFACE_OFF\x10\x00\x12\x12\n\x0eSURFACE_HEAT_1\x10\x01\x12\x12\n\x0eSURFACE_HEAT_2\x10\x02\x12\x12\n\x0eSURFACE_HEAT_3\x10\x03\x12\x12\n\x0eSURFACE_VENT_1\x10\x04\x12\x12\n\x0eSURFACE_VENT_2\x10\x05\x12\x12\n\x0eSURFACE_VENT_3\x10\x06\x62\x06proto3')
28
+
29
+ _globals = globals()
30
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
31
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'rivian.parallax.proto.departure_pb2', _globals)
32
+ if not _descriptor._USE_C_DESCRIPTORS:
33
+ DESCRIPTOR._loaded_options = None
34
+ _globals['_DEFOGDEFROSTLEVEL']._serialized_start=1809
35
+ _globals['_DEFOGDEFROSTLEVEL']._serialized_end=1903
36
+ _globals['_SURFACEHEATVENTLEVEL']._serialized_start=1906
37
+ _globals['_SURFACEHEATVENTLEVEL']._serialized_end=2065
38
+ _globals['_DEPARTURESCHEDULES']._serialized_start=69
39
+ _globals['_DEPARTURESCHEDULES']._serialized_end=1807
40
+ _globals['_DEPARTURESCHEDULES_SCHEDULE']._serialized_start=243
41
+ _globals['_DEPARTURESCHEDULES_SCHEDULE']._serialized_end=587
42
+ _globals['_DEPARTURESCHEDULES_SINGLEOCCURRENCE']._serialized_start=590
43
+ _globals['_DEPARTURESCHEDULES_SINGLEOCCURRENCE']._serialized_end=744
44
+ _globals['_DEPARTURESCHEDULES_SINGLEOCCURRENCE_STARTSAT']._serialized_start=702
45
+ _globals['_DEPARTURESCHEDULES_SINGLEOCCURRENCE_STARTSAT']._serialized_end=744
46
+ _globals['_DEPARTURESCHEDULES_OCCURRENCE']._serialized_start=746
47
+ _globals['_DEPARTURESCHEDULES_OCCURRENCE']._serialized_end=862
48
+ _globals['_DEPARTURESCHEDULES_DAYS']._serialized_start=864
49
+ _globals['_DEPARTURESCHEDULES_DAYS']._serialized_end=990
50
+ _globals['_DEPARTURESCHEDULES_DEPARTURESETTINGS']._serialized_start=993
51
+ _globals['_DEPARTURESCHEDULES_DEPARTURESETTINGS']._serialized_end=1142
52
+ _globals['_DEPARTURESCHEDULES_COMFORTSETTINGS']._serialized_start=1145
53
+ _globals['_DEPARTURESCHEDULES_COMFORTSETTINGS']._serialized_end=1367
54
+ _globals['_DEPARTURESCHEDULES_SURFACEHEATVENTLEVELS']._serialized_start=1370
55
+ _globals['_DEPARTURESCHEDULES_SURFACEHEATVENTLEVELS']._serialized_end=1762
56
+ _globals['_DEPARTURESCHEDULES_UPDATEDAT']._serialized_start=1764
57
+ _globals['_DEPARTURESCHEDULES_UPDATEDAT']._serialized_end=1807
58
+ # @@protoc_insertion_point(module_scope)