rivian-python-client 2.3.1__py3-none-any.whl → 2.4.0__py3-none-any.whl
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.
- rivian/__version__.py +1 -1
- rivian/ble.py +2 -2
- rivian/const.py +2 -2
- rivian/parallax/__init__.py +18 -2
- rivian/parallax/body.py +13 -0
- rivian/parallax/command.py +168 -0
- rivian/parallax/core.py +11 -6
- rivian/parallax/proto/body.proto +11 -0
- rivian/parallax/proto/body_pb2.py +39 -35
- rivian/parallax/proto/body_pb2.pyi +12 -0
- rivian/parallax/proto/command.proto +108 -0
- rivian/parallax/proto/command_pb2.py +62 -0
- rivian/parallax/proto/command_pb2.pyi +151 -0
- rivian/rivian.py +129 -11
- rivian/utils.py +32 -3
- rivian/ws_monitor.py +16 -3
- {rivian_python_client-2.3.1.dist-info → rivian_python_client-2.4.0.dist-info}/METADATA +42 -1
- {rivian_python_client-2.3.1.dist-info → rivian_python_client-2.4.0.dist-info}/RECORD +19 -15
- {rivian_python_client-2.3.1.dist-info → rivian_python_client-2.4.0.dist-info}/WHEEL +1 -1
rivian/__version__.py
CHANGED
rivian/ble.py
CHANGED
|
@@ -7,7 +7,7 @@ import logging
|
|
|
7
7
|
import platform
|
|
8
8
|
import secrets
|
|
9
9
|
|
|
10
|
-
from .utils import
|
|
10
|
+
from .utils import generate_command_hmac
|
|
11
11
|
|
|
12
12
|
_LOGGER = logging.getLogger(__name__)
|
|
13
13
|
|
|
@@ -96,7 +96,7 @@ async def pair_phone(
|
|
|
96
96
|
|
|
97
97
|
_LOGGER.debug("Exchanging nonce")
|
|
98
98
|
phone_nonce = secrets.token_bytes(16)
|
|
99
|
-
hmac =
|
|
99
|
+
hmac = generate_command_hmac(phone_nonce, vehicle_key, private_key)
|
|
100
100
|
await client.write_gatt_char(
|
|
101
101
|
PHONE_NONCE_VEHICLE_NONCE_UUID, phone_nonce + hmac
|
|
102
102
|
)
|
rivian/const.py
CHANGED
|
@@ -185,8 +185,8 @@ class VehicleCommand(StrEnum):
|
|
|
185
185
|
VEHICLE_CABIN_PRECONDITION_DISABLE = "VEHICLE_CABIN_PRECONDITION_DISABLE"
|
|
186
186
|
VEHICLE_CABIN_PRECONDITION_ENABLE = "VEHICLE_CABIN_PRECONDITION_ENABLE"
|
|
187
187
|
# Gen2 HVAC Controls
|
|
188
|
-
|
|
189
|
-
|
|
188
|
+
CABIN_HVAC_3RD_ROW_REAR_LEFT_SEAT_HEAT = "CABIN_HVAC_3RD_ROW_REAR_LEFT_SEAT_HEAT"
|
|
189
|
+
CABIN_HVAC_3RD_ROW_REAR_RIGHT_SEAT_HEAT = "CABIN_HVAC_3RD_ROW_REAR_RIGHT_SEAT_HEAT"
|
|
190
190
|
|
|
191
191
|
# Closures
|
|
192
192
|
LOCK_ALL_CLOSURES_FEEDBACK = "LOCK_ALL_CLOSURES_FEEDBACK"
|
rivian/parallax/__init__.py
CHANGED
|
@@ -10,10 +10,18 @@ Public API:
|
|
|
10
10
|
encode_vehicle_operation(rvm, payload=b"", ...) -> str
|
|
11
11
|
Builds a `send_vehicle_operation` request; an empty payload reads
|
|
12
12
|
the RVM, anything else (e.g. `encode_climate_hold_setting`) writes it.
|
|
13
|
+
encode_command(vehicle_id, rvm, payload, ...) -> str
|
|
14
|
+
Builds and signs a `send_parallax_command` request, with a payload
|
|
15
|
+
such as `encode_unlock()`.
|
|
16
|
+
LOCK_RVM / encode_lock(), UNLOCK_RVM / encode_unlock()
|
|
17
|
+
The RVM and payload of a signed lock or unlock command.
|
|
18
|
+
decode_command_state_message(data) -> dict | None
|
|
19
|
+
Reads a raw `subscribe_for_parallax_command_state` message.
|
|
13
20
|
|
|
14
21
|
Layout:
|
|
15
|
-
core.py
|
|
16
|
-
|
|
22
|
+
core.py - registry, payload parsing and shared helpers
|
|
23
|
+
command.py - signed remote commands and their state messages
|
|
24
|
+
proto/ - .proto schemas and their generated *_pb2 modules
|
|
17
25
|
<topic prefix>.py - one module per RVM topic prefix (body.*, etc.)
|
|
18
26
|
|
|
19
27
|
To add a decoder, decorate it with
|
|
@@ -44,11 +52,13 @@ from . import ( # noqa: F401 (imported to register their decoders)
|
|
|
44
52
|
vehicle,
|
|
45
53
|
vehicle_access,
|
|
46
54
|
)
|
|
55
|
+
from .body import LOCK_RVM, UNLOCK_RVM, encode_lock, encode_unlock
|
|
47
56
|
from .comfort import (
|
|
48
57
|
CLIMATE_HOLD_SETTING_RVM,
|
|
49
58
|
CLIMATE_HOLD_STATUS_RVM,
|
|
50
59
|
encode_climate_hold_setting,
|
|
51
60
|
)
|
|
61
|
+
from .command import decode_command_state_message, encode_command
|
|
52
62
|
from .core import (
|
|
53
63
|
RVMDecoder,
|
|
54
64
|
decode_parallax_message,
|
|
@@ -75,9 +85,15 @@ __all__ = [
|
|
|
75
85
|
"CHARGING_RVMS",
|
|
76
86
|
"CLIMATE_HOLD_SETTING_RVM",
|
|
77
87
|
"CLIMATE_HOLD_STATUS_RVM",
|
|
88
|
+
"LOCK_RVM",
|
|
78
89
|
"PARALLAX_RVMS",
|
|
90
|
+
"UNLOCK_RVM",
|
|
91
|
+
"decode_command_state_message",
|
|
79
92
|
"decode_parallax_message",
|
|
80
93
|
"decode_parallax_subscription_message",
|
|
81
94
|
"encode_climate_hold_setting",
|
|
95
|
+
"encode_command",
|
|
96
|
+
"encode_lock",
|
|
97
|
+
"encode_unlock",
|
|
82
98
|
"encode_vehicle_operation",
|
|
83
99
|
]
|
rivian/parallax/body.py
CHANGED
|
@@ -7,6 +7,9 @@ from typing import Any, Final
|
|
|
7
7
|
from .core import _LOGGER, RVMDecoder, _enum, _present
|
|
8
8
|
from .proto import body_pb2
|
|
9
9
|
|
|
10
|
+
LOCK_RVM: Final = "body.locks.lock"
|
|
11
|
+
UNLOCK_RVM: Final = "body.locks.unlock"
|
|
12
|
+
|
|
10
13
|
_CLOSURE_MAP: Final[dict[int, str]] = {
|
|
11
14
|
body_pb2.DOOR_FRONT_LEFT: "doorFrontLeftClosed",
|
|
12
15
|
body_pb2.DOOR_FRONT_RIGHT: "doorFrontRightClosed",
|
|
@@ -173,6 +176,16 @@ def decode_closures(m: body_pb2.ClosuresState) -> dict[str, Any]:
|
|
|
173
176
|
return result
|
|
174
177
|
|
|
175
178
|
|
|
179
|
+
def encode_lock() -> bytes:
|
|
180
|
+
"""Encode a body.locks.lock payload, which has no fields."""
|
|
181
|
+
return body_pb2.LockCommand().SerializeToString()
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def encode_unlock() -> bytes:
|
|
185
|
+
"""Encode a body.locks.unlock payload that unlocks everything."""
|
|
186
|
+
return body_pb2.UnlockCommand(all=True).SerializeToString()
|
|
187
|
+
|
|
188
|
+
|
|
176
189
|
@RVMDecoder.register("body.locks.states", body_pb2.LocksState)
|
|
177
190
|
def decode_locks(m: body_pb2.LocksState) -> dict[str, Any]:
|
|
178
191
|
"""body.locks.states — lock state of every lock.
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""Encoder and decoder for signed Parallax remote commands.
|
|
2
|
+
|
|
3
|
+
A command such as `body.locks.unlock` is sent with the `sendParallaxPayload`
|
|
4
|
+
mutation (`Rivian.send_parallax_command`). Its payload is an `Operation` in an
|
|
5
|
+
`Envelope`, signed with the secret that `Rivian.send_vehicle_command` derives from
|
|
6
|
+
the phone's key and the vehicle's, but over the operation's bytes. In testing,
|
|
7
|
+
Rivian woke a sleeping vehicle for it.
|
|
8
|
+
|
|
9
|
+
The `vehicleCommandStatePx` subscription
|
|
10
|
+
(`Rivian.subscribe_for_parallax_command_state`) reports on the command as it
|
|
11
|
+
goes: the vehicle waking up, validating and executing it, then the result.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import base64
|
|
17
|
+
import time
|
|
18
|
+
import uuid
|
|
19
|
+
from typing import Any, Final
|
|
20
|
+
|
|
21
|
+
from google.protobuf.message import DecodeError
|
|
22
|
+
|
|
23
|
+
from ..utils import generate_command_hmac
|
|
24
|
+
from .core import _LOGGER, _debug_message, _enum, _present
|
|
25
|
+
from .proto import command_pb2
|
|
26
|
+
|
|
27
|
+
_PROGRESS_MAP: Final[dict[int, str]] = {
|
|
28
|
+
command_pb2.VEHICLE_MODEL_OP_PROGRESS_UNSPECIFIED: "unspecified",
|
|
29
|
+
command_pb2.VEHICLE_MODEL_OP_PROGRESS_VEHICLE_WAKING_UP: "waking_up",
|
|
30
|
+
command_pb2.VEHICLE_MODEL_OP_PROGRESS_VEHICLE_VALIDATING: "validating",
|
|
31
|
+
command_pb2.VEHICLE_MODEL_OP_PROGRESS_VEHICLE_EXECUTING: "executing",
|
|
32
|
+
command_pb2.VEHICLE_MODEL_OP_PROGRESS_VEHICLE_COMPLETE: "complete",
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
_STATUS_MAP: Final[dict[int, str]] = {
|
|
36
|
+
command_pb2.RESPONSE_STATUS_UNDEFINED: "undefined",
|
|
37
|
+
command_pb2.RESPONSE_STATUS_SUCCESS: "success",
|
|
38
|
+
command_pb2.RESPONSE_STATUS_FAIL: "failed",
|
|
39
|
+
command_pb2.RESPONSE_STATUS_INVALID_REQUEST: "invalid_request",
|
|
40
|
+
command_pb2.RESPONSE_STATUS_NOT_SUPPORTED: "not_supported",
|
|
41
|
+
command_pb2.RESPONSE_STATUS_TIMEOUT: "timeout",
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def encode_command(
|
|
46
|
+
vehicle_id: str,
|
|
47
|
+
rvm: str,
|
|
48
|
+
payload: bytes,
|
|
49
|
+
*,
|
|
50
|
+
identity_id: str,
|
|
51
|
+
vehicle_key: str,
|
|
52
|
+
private_key: str,
|
|
53
|
+
command_id: str | None = None,
|
|
54
|
+
timestamp: float | None = None,
|
|
55
|
+
) -> str:
|
|
56
|
+
"""Encode and sign a command, as the payload of `sendParallaxPayload`.
|
|
57
|
+
|
|
58
|
+
`payload` is the RVM's message, e.g. `encode_unlock()` for `UNLOCK_RVM`;
|
|
59
|
+
nothing checks that they go together. `identity_id`, `vehicle_key` and
|
|
60
|
+
`private_key` are the ones `send_vehicle_command` takes. The command id, a
|
|
61
|
+
UUID, is a new one unless `command_id` is given (`ValueError` if it isn't
|
|
62
|
+
one); `timestamp` is epoch milliseconds, now unless given.
|
|
63
|
+
|
|
64
|
+
The result is signed and can be replayed until the vehicle rejects its
|
|
65
|
+
timestamp, so treat it as a secret.
|
|
66
|
+
"""
|
|
67
|
+
command_id_bytes = (
|
|
68
|
+
uuid.uuid4().bytes if command_id is None else uuid.UUID(command_id).bytes
|
|
69
|
+
)
|
|
70
|
+
timestamp_ms = int(time.time() * 1000 if timestamp is None else timestamp)
|
|
71
|
+
stamp = command_pb2.Timestamp(
|
|
72
|
+
seconds=timestamp_ms // 1000, nanos=timestamp_ms % 1000 * 1_000_000
|
|
73
|
+
)
|
|
74
|
+
operation = command_pb2.Operation(
|
|
75
|
+
rvm=rvm,
|
|
76
|
+
type=command_pb2.PARALLAX_OPERATION_REQUEST,
|
|
77
|
+
command_id=command_id_bytes,
|
|
78
|
+
payload=payload,
|
|
79
|
+
created_at=stamp,
|
|
80
|
+
vehicle_id=vehicle_id,
|
|
81
|
+
).SerializeToString()
|
|
82
|
+
envelope = command_pb2.Envelope(
|
|
83
|
+
composite=command_pb2.Composite(bytes_val=operation),
|
|
84
|
+
last_update=stamp,
|
|
85
|
+
correlation_id=command_id_bytes,
|
|
86
|
+
security_info=command_pb2.SecurityInfo(
|
|
87
|
+
signature=command_pb2.Signature(
|
|
88
|
+
type=command_pb2.DATA_SIGNATURE_TYPE_HMAC_SHA256,
|
|
89
|
+
# The raw HMAC-SHA256 of the data, as BLE commands use too
|
|
90
|
+
value=generate_command_hmac(operation, vehicle_key, private_key),
|
|
91
|
+
),
|
|
92
|
+
mapped_identity=identity_id,
|
|
93
|
+
),
|
|
94
|
+
)
|
|
95
|
+
return base64.b64encode(envelope.SerializeToString()).decode("utf-8")
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def decode_command_state(payload: str) -> dict[str, Any] | None:
|
|
99
|
+
"""Decode the payload of a `vehicleCommandStatePx` message.
|
|
100
|
+
|
|
101
|
+
Returns None if the payload is empty or can't be read.
|
|
102
|
+
|
|
103
|
+
Fields:
|
|
104
|
+
commandId: str | None — the command's UUID
|
|
105
|
+
rvm: str
|
|
106
|
+
progress: str | int — "unspecified" | "waking_up" | "validating" |
|
|
107
|
+
"executing" | "complete". Any of the ones before "complete" can be
|
|
108
|
+
skipped, and "waking_up" has come more than once for one command.
|
|
109
|
+
status: str | int | None — how the vehicle answered ("undefined" |
|
|
110
|
+
"success" | "failed" | "invalid_request" | "not_supported" |
|
|
111
|
+
"timeout"); None if the message has no result
|
|
112
|
+
error: dict | None — {"code": int, "message": str}, from the result or,
|
|
113
|
+
if the whole operation failed, from the operation error (which has
|
|
114
|
+
no status)
|
|
115
|
+
|
|
116
|
+
A value this library doesn't know comes back as the number it was sent as.
|
|
117
|
+
|
|
118
|
+
The vehicle has done the command when the progress is "complete", the status
|
|
119
|
+
"success" and there is no error. "failed", "invalid_request" and
|
|
120
|
+
"not_supported" mean it has not. With "timeout" or "undefined", or if no
|
|
121
|
+
"complete" message comes at all, it isn't known, and the vehicle may do it
|
|
122
|
+
later.
|
|
123
|
+
"""
|
|
124
|
+
try:
|
|
125
|
+
data = base64.b64decode(payload)
|
|
126
|
+
message = command_pb2.CommandState.FromString(data)
|
|
127
|
+
except (TypeError, ValueError, DecodeError):
|
|
128
|
+
_LOGGER.debug("Failed to decode command state", exc_info=True)
|
|
129
|
+
return None
|
|
130
|
+
if not data:
|
|
131
|
+
return None
|
|
132
|
+
_debug_message("command state", message)
|
|
133
|
+
|
|
134
|
+
status: str | int | None = None
|
|
135
|
+
error: dict[str, Any] | None = None
|
|
136
|
+
if (result := _present(message, "data")) is not None:
|
|
137
|
+
status = _enum(_STATUS_MAP, result.response_status, what="command status")
|
|
138
|
+
if (result_error := _present(result, "error")) is not None:
|
|
139
|
+
error = {"code": result_error.code, "message": result_error.message}
|
|
140
|
+
elif (operation_error := _present(message, "operation_error")) is not None:
|
|
141
|
+
error = {"code": operation_error.error, "message": operation_error.message}
|
|
142
|
+
return {
|
|
143
|
+
"commandId": (
|
|
144
|
+
str(uuid.UUID(bytes=message.command_id))
|
|
145
|
+
if len(message.command_id) == 16
|
|
146
|
+
else None
|
|
147
|
+
),
|
|
148
|
+
"rvm": message.rvm,
|
|
149
|
+
"progress": _enum(_PROGRESS_MAP, message.progress, what="command progress"),
|
|
150
|
+
"status": status,
|
|
151
|
+
"error": error,
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def decode_command_state_message(data: dict[str, Any]) -> dict[str, Any] | None:
|
|
156
|
+
"""Decode a raw `subscribe_for_parallax_command_state` message.
|
|
157
|
+
|
|
158
|
+
Unwraps `payload.data.vehicleCommandStatePx.payload` for
|
|
159
|
+
`decode_command_state`; returns None if it's missing or can't be read. That
|
|
160
|
+
includes a message that carries GraphQL errors (`data["payload"]["errors"]`)
|
|
161
|
+
instead of a state.
|
|
162
|
+
"""
|
|
163
|
+
payload: Any = data
|
|
164
|
+
for key in ("payload", "data", "vehicleCommandStatePx", "payload"):
|
|
165
|
+
if not isinstance(payload, dict):
|
|
166
|
+
return None
|
|
167
|
+
payload = payload.get(key)
|
|
168
|
+
return decode_command_state(payload)
|
rivian/parallax/core.py
CHANGED
|
@@ -76,6 +76,16 @@ def _describe_unknowns(message: Message, path: str = "") -> list[str]:
|
|
|
76
76
|
return found
|
|
77
77
|
|
|
78
78
|
|
|
79
|
+
def _debug_message(label: str, message: Message) -> None:
|
|
80
|
+
"""Debug-log a parsed `message` and anything its schema doesn't define."""
|
|
81
|
+
if _LOGGER.isEnabledFor(logging.DEBUG):
|
|
82
|
+
_LOGGER.debug(
|
|
83
|
+
"%s: %s", label, text_format.MessageToString(message, as_one_line=True)
|
|
84
|
+
)
|
|
85
|
+
for unknown in _describe_unknowns(message):
|
|
86
|
+
_LOGGER.debug("%s: %s", label, unknown)
|
|
87
|
+
|
|
88
|
+
|
|
79
89
|
class RVMDecoder:
|
|
80
90
|
"""Registry of RVM topic -> (message class, decoder).
|
|
81
91
|
|
|
@@ -124,12 +134,7 @@ def _decode_rvm_payload(payload: str | None, rvm: str) -> dict[str, Any]:
|
|
|
124
134
|
except Exception:
|
|
125
135
|
_LOGGER.debug("Failed to decode %s payload", rvm, exc_info=True)
|
|
126
136
|
return {}
|
|
127
|
-
|
|
128
|
-
_LOGGER.debug(
|
|
129
|
-
"%s: %s", rvm, text_format.MessageToString(message, as_one_line=True)
|
|
130
|
-
)
|
|
131
|
-
for unknown in _describe_unknowns(message):
|
|
132
|
-
_LOGGER.debug("%s: %s", rvm, unknown)
|
|
137
|
+
_debug_message(rvm, message)
|
|
133
138
|
return result
|
|
134
139
|
|
|
135
140
|
|
rivian/parallax/proto/body.proto
CHANGED
|
@@ -266,3 +266,14 @@ enum WiperFluidState {
|
|
|
266
266
|
WIPER_FLUID_STATE_LOW = 2;
|
|
267
267
|
WIPER_FLUID_STATE_EMPTY = 3;
|
|
268
268
|
}
|
|
269
|
+
|
|
270
|
+
// body.locks.unlock, the payload of a signed command (see ../command.py)
|
|
271
|
+
message UnlockCommand {
|
|
272
|
+
oneof target {
|
|
273
|
+
bool all = 1; // the app always sets this
|
|
274
|
+
bool user_preference = 2; // in the app's schema; its button never sends it
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// body.locks.lock, the payload of a signed command. It has no fields.
|
|
279
|
+
message LockCommand {}
|
|
@@ -24,47 +24,47 @@ _sym_db = _symbol_database.Default()
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n rivian/parallax/proto/body.proto\x12\x14rivian.parallax.body\"\x89\x06\n\rClosuresState\x12<\n\x07\x63losure\x18\x01 \x03(\x0b\x32+.rivian.parallax.body.ClosuresState.Closure\x1a\xb9\x05\n\x07\x43losure\x12+\n\x02id\x18\x01 \x01(\x0e\x32\x1f.rivian.parallax.body.ClosureId\x12\x36\n\x05state\x18\x02 \x01(\x0e\x32\".rivian.parallax.body.ClosureStateH\x01\x88\x01\x01\x12\x1d\n\x15open_position_percent\x18\x03 \x01(\x05\x12\x31\n\x05\x66\x61ult\x18\x04 \x01(\x0e\x32\".rivian.parallax.body.ClosureFault\x12\x46\n\x13windows_next_action\x18\x05 \x01(\x0e\x32\'.rivian.parallax.body.WindowsNextActionH\x00\x12\x42\n\x11\x66runk_next_action\x18\x06 \x01(\x0e\x32%.rivian.parallax.body.FrunkNextActionH\x00\x12H\n\x14liftgate_next_action\x18\x07 \x01(\x0e\x32(.rivian.parallax.body.LiftgateNextActionH\x00\x12G\n\x14side_bin_next_action\x18\x08 \x01(\x0e\x32\'.rivian.parallax.body.SideBinNextActionH\x00\x12H\n\x14tailgate_next_action\x18\t \x01(\x0e\x32(.rivian.parallax.body.TailgateNextActionH\x00\x12V\n\x1c\x63harge_port_door_next_action\x18\n \x01(\x0e\x32..rivian.parallax.body.ChargePortDoorNextActionH\x00\x12\x1d\n\x13tonneau_next_action\x18\x0b \x01(\x05H\x00\x42\r\n\x0bnext_actionB\x08\n\x06_state\"\xe3\x01\n\nLocksState\x12\x33\n\x04lock\x18\x01 \x03(\x0b\x32%.rivian.parallax.body.LocksState.Lock\x1a\x9f\x01\n\x04Lock\x12(\n\x02id\x18\x01 \x01(\x0e\x32\x1c.rivian.parallax.body.LockId\x12\x33\n\x05state\x18\x02 \x01(\x0e\x32\x1f.rivian.parallax.body.LockStateH\x00\x88\x01\x01\x12.\n\x05\x66\x61ult\x18\x03 \x01(\x0e\x32\x1f.rivian.parallax.body.LockFaultB\x08\n\x06_state\"\xd1\x01\n\x0cWindowsState\x12\x39\n\x06window\x18\x01 \x03(\x0b\x32).rivian.parallax.body.WindowsState.Window\x1a\x85\x01\n\x06Window\x12\x36\n\x08instance\x18\x01 \x01(\x0e\x32$.rivian.parallax.body.WindowInstance\x12\x43\n\x12\x63\x61libration_status\x18\x02 \x01(\x0e\x32\'.rivian.parallax.body.CalibrationStatus\"\x9b\x01\n\x0cTrailerState\x12<\n\x08presence\x18\x01 \x01(\x0e\x32%.rivian.parallax.body.TrailerPresenceH\x00\x88\x01\x01\x12@\n\x11rear_hitch_status\x18\x02 \x01(\x0e\x32%.rivian.parallax.body.RearHitchStatusB\x0b\n\t_presence\"G\n\x0fWiperFluidLevel\x12\x34\n\x05state\x18\x02 \x01(\x0e\x32%.rivian.parallax.body.WiperFluidState*\xe8\x02\n\tClosureId\x12\x1a\n\x16\x43LOSURE_ID_UNSPECIFIED\x10\x00\x12\x13\n\x0f\x44OOR_FRONT_LEFT\x10\x01\x12\x14\n\x10\x44OOR_FRONT_RIGHT\x10\x02\x12\x12\n\x0e\x44OOR_REAR_LEFT\x10\x03\x12\x13\n\x0f\x44OOR_REAR_RIGHT\x10\x04\x12\t\n\x05\x46RUNK\x10\x05\x12\x0c\n\x08TAILGATE\x10\x06\x12\x0c\n\x08LIFTGATE\x10\x07\x12\x11\n\rSIDE_BIN_LEFT\x10\x08\x12\x12\n\x0eSIDE_BIN_RIGHT\x10\t\x12\x0f\n\x0b\x43HARGE_PORT\x10\n\x12\x0b\n\x07TONNEAU\x10\x0b\x12\x15\n\x11WINDOW_FRONT_LEFT\x10\x0c\x12\x16\n\x12WINDOW_FRONT_RIGHT\x10\r\x12\x14\n\x10WINDOW_REAR_LEFT\x10\x0e\x12\x15\n\x11WINDOW_REAR_RIGHT\x10\x0f\x12\x0f\n\x0bWINDOW_REAR\x10\x10\x12\x12\n\rGROUP_WINDOWS\x10\x90N*\xad\x01\n\x0c\x43losureState\x12\x1d\n\x19\x43LOSURE_STATE_UNSPECIFIED\x10\x00\x12\x16\n\x12\x43LOSURE_STATE_OPEN\x10\x01\x12\x18\n\x14\x43LOSURE_STATE_CLOSED\x10\x02\x12\x16\n\x12\x43LOSURE_STATE_AJAR\x10\x03\x12\x19\n\x15\x43LOSURE_STATE_OPENING\x10\x04\x12\x19\n\x15\x43LOSURE_STATE_CLOSING\x10\x05*\xf3\x02\n\x06LockId\x12\x17\n\x13LOCK_ID_UNSPECIFIED\x10\x00\x12\x18\n\x14LOCK_DOOR_FRONT_LEFT\x10\x01\x12\x19\n\x15LOCK_DOOR_FRONT_RIGHT\x10\x02\x12\x17\n\x13LOCK_DOOR_REAR_LEFT\x10\x03\x12\x18\n\x14LOCK_DOOR_REAR_RIGHT\x10\x04\x12\x0e\n\nLOCK_FRUNK\x10\x05\x12\x11\n\rLOCK_TAILGATE\x10\x06\x12\x11\n\rLOCK_LIFTGATE\x10\x07\x12\x16\n\x12LOCK_SIDE_BIN_LEFT\x10\x08\x12\x17\n\x13LOCK_SIDE_BIN_RIGHT\x10\t\x12\x14\n\x10LOCK_CHARGE_PORT\x10\n\x12\x17\n\x13LOCK_TRUNK_SECURITY\x10\x0b\x12\x17\n\x13LOCK_CENTER_CONSOLE\x10\x0c\x12\x12\n\x0eLOCK_GLOVE_BOX\x10\r\x12\x13\n\x0fLOCK_GEAR_GUARD\x10\x0e\x12\x10\n\x0cLOCK_TONNEAU\x10\x0f*z\n\tLockState\x12\x1a\n\x16LOCK_STATE_UNSPECIFIED\x10\x00\x12\x15\n\x11LOCK_STATE_LOCKED\x10\x01\x12\x17\n\x13LOCK_STATE_UNLOCKED\x10\x02\x12!\n\x1dLOCK_STATE_PARTIALLY_UNLOCKED\x10\x03*?\n\tLockFault\x12\x1a\n\x16LOCK_FAULT_UNSPECIFIED\x10\x00\x12\x16\n\x12LOCK_FAULT_FAULTED\x10\x01*\xcb\x01\n\x0eWindowInstance\x12\x1f\n\x1bWINDOW_INSTANCE_UNSPECIFIED\x10\x00\x12\x1e\n\x1aWINDOW_INSTANCE_FRONT_LEFT\x10\x01\x12\x1f\n\x1bWINDOW_INSTANCE_FRONT_RIGHT\x10\x02\x12\x1d\n\x19WINDOW_INSTANCE_REAR_LEFT\x10\x03\x12\x1e\n\x1aWINDOW_INSTANCE_REAR_RIGHT\x10\x04\x12\x18\n\x14WINDOW_INSTANCE_REAR\x10\x05*\x81\x01\n\x11\x43\x61librationStatus\x12\"\n\x1e\x43\x41LIBRATION_STATUS_UNSPECIFIED\x10\x00\x12!\n\x1d\x43\x41LIBRATION_STATUS_CALIBRATED\x10\x01\x12%\n!CALIBRATION_STATUS_NOT_CALIBRATED\x10\x02*\xd8\x01\n\x0fRearHitchStatus\x12!\n\x1dREAR_HITCH_STATUS_UNSPECIFIED\x10\x00\x12!\n\x1dREAR_HITCH_STATUS_NOT_PRESENT\x10\x01\x12\x1f\n\x1bREAR_HITCH_STATUS_ACCESSORY\x10\x02\x12\x1e\n\x1aREAR_HITCH_STATUS_TRAILER1\x10\x03\x12\x1e\n\x1aREAR_HITCH_STATUS_TRAILER2\x10\x04\x12\x1e\n\x1aREAR_HITCH_STATUS_TRAILER3\x10\x05*\xaa\x01\n\x0c\x43losureFault\x12\x1d\n\x19\x43LOSURE_FAULT_UNSPECIFIED\x10\x00\x12\x1a\n\x16\x43LOSURE_FAULT_NO_FAULT\x10\x01\x12\x19\n\x15\x43LOSURE_FAULT_GENERAL\x10\x02\x12&\n\"CLOSURE_FAULT_NO_POWERED_OPERATION\x10\x03\x12\x1c\n\x18\x43LOSURE_FAULT_OBSTRUCTED\x10\x04*\x97\x01\n\x0fTrailerPresence\x12 \n\x1cTRAILER_PRESENCE_UNSPECIFIED\x10\x00\x12\x17\n\x13TRAILER_NOT_PRESENT\x10\x01\x12\x13\n\x0fTRAILER_PRESENT\x10\x02\x12\x1f\n\x1bTRAILER_PRESENT_WITH_BRAKES\x10\x03\x12\x13\n\x0fTRAILER_INVALID\x10\x04*\x9f\x04\n\x18\x43hargePortDoorNextAction\x12\x18\n\x14\x43HARGE_PORT_DOOR_SNA\x10\x00\x12!\n\x1d\x43HARGE_PORT_DOOR_OPEN_ALLOWED\x10\x01\x12\'\n#CHARGE_PORT_DOOR_OPEN_NOT_AVAILABLE\x10\x02\x12-\n)CHARGE_PORT_DOOR_OPEN_NOT_ALLOWED_FAULTED\x10\x03\x12\x1c\n\x18\x43HARGE_PORT_DOOR_OPENING\x10\x04\x12\"\n\x1e\x43HARGE_PORT_DOOR_CLOSE_ALLOWED\x10\x05\x12;\n7CHARGE_PORT_DOOR_OBSTRUCTED_WHILE_OPENING_CLOSE_ALLOWED\x10\x06\x12:\n6CHARGE_PORT_DOOR_OBSTRUCTED_WHILE_OPENING_OPEN_ALLOWED\x10\x07\x12;\n7CHARGE_PORT_DOOR_OBSTRUCTED_WHILE_CLOSING_CLOSE_ALLOWED\x10\x08\x12(\n$CHARGE_PORT_DOOR_CLOSE_NOT_AVAILABLE\x10\t\x12.\n*CHARGE_PORT_DOOR_CLOSE_NOT_ALLOWED_FAULTED\x10\n\x12\x1c\n\x18\x43HARGE_PORT_DOOR_CLOSING\x10\x0b*\xb0\x03\n\x0f\x46runkNextAction\x12\r\n\tFRUNK_SNA\x10\x00\x12\x16\n\x12\x46RUNK_OPEN_ALLOWED\x10\x01\x12\x17\n\x13\x46RUNK_CLOSE_ALLOWED\x10\x02\x12\x11\n\rFRUNK_OPENING\x10\x03\x12\x11\n\rFRUNK_CLOSING\x10\x04\x12\x1c\n\x18\x46RUNK_OPEN_NOT_AVAILABLE\x10\x05\x12\x1d\n\x19\x46RUNK_CLOSE_NOT_AVAILABLE\x10\x06\x12\"\n\x1e\x46RUNK_OPEN_NOT_ALLOWED_FAULTED\x10\x07\x12#\n\x1f\x46RUNK_CLOSE_NOT_ALLOWED_FAULTED\x10\x08\x12)\n%FRUNK_OPEN_ALLOWED_NO_POWER_OPERATION\x10\t\x12.\n*FRUNK_CLOSE_NOT_ALLOWED_NO_POWER_OPERATION\x10\n\x12*\n&FRUNK_OBSTRUCTED_OPENING_CLOSE_ALLOWED\x10\x0b\x12*\n&FRUNK_OBSTRUCTED_CLOSING_CLOSE_ALLOWED\x10\x0c*\xa7\x06\n\x12LiftgateNextAction\x12\x10\n\x0cLIFTGATE_SNA\x10\x00\x12\x19\n\x15LIFTGATE_OPEN_ALLOWED\x10\x01\x12\x1a\n\x16LIFTGATE_CLOSE_ALLOWED\x10\x02\x12\x14\n\x10LIFTGATE_OPENING\x10\x03\x12\x14\n\x10LIFTGATE_CLOSING\x10\x04\x12\x1f\n\x1bLIFTGATE_OPEN_NOT_AVAILABLE\x10\x05\x12 \n\x1cLIFTGATE_CLOSE_NOT_AVAILABLE\x10\x06\x12%\n!LIFTGATE_OPEN_NOT_ALLOWED_FAULTED\x10\x07\x12&\n\"LIFTGATE_CLOSE_NOT_ALLOWED_FAULTED\x10\x08\x12,\n(LIFTGATE_OPEN_ALLOWED_NO_POWER_OPERATION\x10\t\x12\x31\n-LIFTGATE_CLOSE_NOT_ALLOWED_NO_POWER_OPERATION\x10\n\x12-\n)LIFTGATE_OBSTRUCTED_OPENING_CLOSE_ALLOWED\x10\x0b\x12-\n)LIFTGATE_OBSTRUCTED_CLOSING_CLOSE_ALLOWED\x10\x0c\x12.\n*LIFTGATE_LOWER_GATE_OPEN_CLOSE_NOT_ALLOWED\x10\r\x12&\n\"LIFTGATE_OPENING_PAUSE_NOT_ALLOWED\x10\x0e\x12&\n\"LIFTGATE_CLOSING_PAUSE_NOT_ALLOWED\x10\x0f\x12+\n\'LIFTGATE_OPEN_ALLOWED_OBSTACLE_DETECTED\x10\x10\x12*\n&LIFTGATE_OPEN_ALLOWED_TRAILER_DETECTED\x10\x11\x12,\n(LIFTGATE_CLOSE_ALLOWED_OBSTACLE_DETECTED\x10\x12\x12+\n\'LIFTGATE_CLOSE_ALLOWED_TRAILER_DETECTED\x10\x13\x12\x17\n\x13LIFTGATE_PROCESSING\x10\x14*\xb2\x02\n\x11SideBinNextAction\x12\x10\n\x0cSIDE_BIN_SNA\x10\x00\x12\x19\n\x15SIDE_BIN_OPEN_ALLOWED\x10\x01\x12\x14\n\x10SIDE_BIN_OPENING\x10\x02\x12\x1f\n\x1bSIDE_BIN_OPEN_NOT_AVAILABLE\x10\x03\x12%\n!SIDE_BIN_OPEN_NOT_ALLOWED_FAULTED\x10\x04\x12\x32\n.SIDE_BIN_STUCK_AJAR_WHILE_OPENING_OPEN_ALLOWED\x10\x05\x12-\n)SIDE_BIN_OPEN_ALREADY_NO_ACTION_AVAILABLE\x10\x06\x12/\n+SIDE_BIN_OPEN_ALLOWED_CONFIRM_VEHICLE_ANGLE\x10\x07*\x8c\x03\n\x12TailgateNextAction\x12\x10\n\x0cTAILGATE_SNA\x10\x00\x12\x19\n\x15TAILGATE_OPEN_ALLOWED\x10\x01\x12\x14\n\x10TAILGATE_OPENING\x10\x02\x12\x1f\n\x1bTAILGATE_OPEN_NOT_AVAILABLE\x10\x03\x12%\n!TAILGATE_OPEN_NOT_ALLOWED_FAULTED\x10\x04\x12\x32\n.TAILGATE_STUCK_AJAR_WHILE_OPENING_OPEN_ALLOWED\x10\x05\x12-\n)TAILGATE_OPEN_ALREADY_NO_ACTION_AVAILABLE\x10\x06\x12/\n+TAILGATE_OPEN_ALLOWED_CONFIRM_VEHICLE_ANGLE\x10\x07\x12+\n\'TAILGATE_OPEN_ALLOWED_OBSTACLE_DETECTED\x10\x08\x12*\n&TAILGATE_OPEN_ALLOWED_TRAILER_DETECTED\x10\t*\xb0\x03\n\x11WindowsNextAction\x12\x0f\n\x0bWINDOWS_SNA\x10\x00\x12\x18\n\x14WINDOWS_OPEN_ALLOWED\x10\x01\x12\x19\n\x15WINDOWS_CLOSE_ALLOWED\x10\x02\x12\x13\n\x0fWINDOWS_OPENING\x10\x03\x12\x13\n\x0fWINDOWS_CLOSING\x10\x04\x12\x12\n\x0eWINDOWS_MOVING\x10\x05\x12\x1e\n\x1aWINDOWS_OPEN_NOT_AVAILABLE\x10\x06\x12\x1f\n\x1bWINDOWS_CLOSE_NOT_AVAILABLE\x10\x07\x12$\n WINDOWS_OPEN_NOT_ALLOWED_FAULTED\x10\x08\x12%\n!WINDOWS_CLOSE_NOT_ALLOWED_FAULTED\x10\t\x12\x32\n.WINDOWS_OBSTRUCTED_WHILE_CLOSING_CLOSE_ALLOWED\x10\n\x12*\n&WINDOWS_CLOSE_NOT_ALLOWED_UNCALIBRATED\x10\x0b\x12)\n%WINDOWS_OPEN_NOT_ALLOWED_UNCALIBRATED\x10\x0c*\x8a\x01\n\x0fWiperFluidState\x12!\n\x1dWIPER_FLUID_STATE_UNSPECIFIED\x10\x00\x12\x1c\n\x18WIPER_FLUID_STATE_NORMAL\x10\x01\x12\x19\n\x15WIPER_FLUID_STATE_LOW\x10\x02\x12\x1b\n\x17WIPER_FLUID_STATE_EMPTY\x10\x03\x62\x06proto3')
|
|
27
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n rivian/parallax/proto/body.proto\x12\x14rivian.parallax.body\"\x89\x06\n\rClosuresState\x12<\n\x07\x63losure\x18\x01 \x03(\x0b\x32+.rivian.parallax.body.ClosuresState.Closure\x1a\xb9\x05\n\x07\x43losure\x12+\n\x02id\x18\x01 \x01(\x0e\x32\x1f.rivian.parallax.body.ClosureId\x12\x36\n\x05state\x18\x02 \x01(\x0e\x32\".rivian.parallax.body.ClosureStateH\x01\x88\x01\x01\x12\x1d\n\x15open_position_percent\x18\x03 \x01(\x05\x12\x31\n\x05\x66\x61ult\x18\x04 \x01(\x0e\x32\".rivian.parallax.body.ClosureFault\x12\x46\n\x13windows_next_action\x18\x05 \x01(\x0e\x32\'.rivian.parallax.body.WindowsNextActionH\x00\x12\x42\n\x11\x66runk_next_action\x18\x06 \x01(\x0e\x32%.rivian.parallax.body.FrunkNextActionH\x00\x12H\n\x14liftgate_next_action\x18\x07 \x01(\x0e\x32(.rivian.parallax.body.LiftgateNextActionH\x00\x12G\n\x14side_bin_next_action\x18\x08 \x01(\x0e\x32\'.rivian.parallax.body.SideBinNextActionH\x00\x12H\n\x14tailgate_next_action\x18\t \x01(\x0e\x32(.rivian.parallax.body.TailgateNextActionH\x00\x12V\n\x1c\x63harge_port_door_next_action\x18\n \x01(\x0e\x32..rivian.parallax.body.ChargePortDoorNextActionH\x00\x12\x1d\n\x13tonneau_next_action\x18\x0b \x01(\x05H\x00\x42\r\n\x0bnext_actionB\x08\n\x06_state\"\xe3\x01\n\nLocksState\x12\x33\n\x04lock\x18\x01 \x03(\x0b\x32%.rivian.parallax.body.LocksState.Lock\x1a\x9f\x01\n\x04Lock\x12(\n\x02id\x18\x01 \x01(\x0e\x32\x1c.rivian.parallax.body.LockId\x12\x33\n\x05state\x18\x02 \x01(\x0e\x32\x1f.rivian.parallax.body.LockStateH\x00\x88\x01\x01\x12.\n\x05\x66\x61ult\x18\x03 \x01(\x0e\x32\x1f.rivian.parallax.body.LockFaultB\x08\n\x06_state\"\xd1\x01\n\x0cWindowsState\x12\x39\n\x06window\x18\x01 \x03(\x0b\x32).rivian.parallax.body.WindowsState.Window\x1a\x85\x01\n\x06Window\x12\x36\n\x08instance\x18\x01 \x01(\x0e\x32$.rivian.parallax.body.WindowInstance\x12\x43\n\x12\x63\x61libration_status\x18\x02 \x01(\x0e\x32\'.rivian.parallax.body.CalibrationStatus\"\x9b\x01\n\x0cTrailerState\x12<\n\x08presence\x18\x01 \x01(\x0e\x32%.rivian.parallax.body.TrailerPresenceH\x00\x88\x01\x01\x12@\n\x11rear_hitch_status\x18\x02 \x01(\x0e\x32%.rivian.parallax.body.RearHitchStatusB\x0b\n\t_presence\"G\n\x0fWiperFluidLevel\x12\x34\n\x05state\x18\x02 \x01(\x0e\x32%.rivian.parallax.body.WiperFluidState\"C\n\rUnlockCommand\x12\r\n\x03\x61ll\x18\x01 \x01(\x08H\x00\x12\x19\n\x0fuser_preference\x18\x02 \x01(\x08H\x00\x42\x08\n\x06target\"\r\n\x0bLockCommand*\xe8\x02\n\tClosureId\x12\x1a\n\x16\x43LOSURE_ID_UNSPECIFIED\x10\x00\x12\x13\n\x0f\x44OOR_FRONT_LEFT\x10\x01\x12\x14\n\x10\x44OOR_FRONT_RIGHT\x10\x02\x12\x12\n\x0e\x44OOR_REAR_LEFT\x10\x03\x12\x13\n\x0f\x44OOR_REAR_RIGHT\x10\x04\x12\t\n\x05\x46RUNK\x10\x05\x12\x0c\n\x08TAILGATE\x10\x06\x12\x0c\n\x08LIFTGATE\x10\x07\x12\x11\n\rSIDE_BIN_LEFT\x10\x08\x12\x12\n\x0eSIDE_BIN_RIGHT\x10\t\x12\x0f\n\x0b\x43HARGE_PORT\x10\n\x12\x0b\n\x07TONNEAU\x10\x0b\x12\x15\n\x11WINDOW_FRONT_LEFT\x10\x0c\x12\x16\n\x12WINDOW_FRONT_RIGHT\x10\r\x12\x14\n\x10WINDOW_REAR_LEFT\x10\x0e\x12\x15\n\x11WINDOW_REAR_RIGHT\x10\x0f\x12\x0f\n\x0bWINDOW_REAR\x10\x10\x12\x12\n\rGROUP_WINDOWS\x10\x90N*\xad\x01\n\x0c\x43losureState\x12\x1d\n\x19\x43LOSURE_STATE_UNSPECIFIED\x10\x00\x12\x16\n\x12\x43LOSURE_STATE_OPEN\x10\x01\x12\x18\n\x14\x43LOSURE_STATE_CLOSED\x10\x02\x12\x16\n\x12\x43LOSURE_STATE_AJAR\x10\x03\x12\x19\n\x15\x43LOSURE_STATE_OPENING\x10\x04\x12\x19\n\x15\x43LOSURE_STATE_CLOSING\x10\x05*\xf3\x02\n\x06LockId\x12\x17\n\x13LOCK_ID_UNSPECIFIED\x10\x00\x12\x18\n\x14LOCK_DOOR_FRONT_LEFT\x10\x01\x12\x19\n\x15LOCK_DOOR_FRONT_RIGHT\x10\x02\x12\x17\n\x13LOCK_DOOR_REAR_LEFT\x10\x03\x12\x18\n\x14LOCK_DOOR_REAR_RIGHT\x10\x04\x12\x0e\n\nLOCK_FRUNK\x10\x05\x12\x11\n\rLOCK_TAILGATE\x10\x06\x12\x11\n\rLOCK_LIFTGATE\x10\x07\x12\x16\n\x12LOCK_SIDE_BIN_LEFT\x10\x08\x12\x17\n\x13LOCK_SIDE_BIN_RIGHT\x10\t\x12\x14\n\x10LOCK_CHARGE_PORT\x10\n\x12\x17\n\x13LOCK_TRUNK_SECURITY\x10\x0b\x12\x17\n\x13LOCK_CENTER_CONSOLE\x10\x0c\x12\x12\n\x0eLOCK_GLOVE_BOX\x10\r\x12\x13\n\x0fLOCK_GEAR_GUARD\x10\x0e\x12\x10\n\x0cLOCK_TONNEAU\x10\x0f*z\n\tLockState\x12\x1a\n\x16LOCK_STATE_UNSPECIFIED\x10\x00\x12\x15\n\x11LOCK_STATE_LOCKED\x10\x01\x12\x17\n\x13LOCK_STATE_UNLOCKED\x10\x02\x12!\n\x1dLOCK_STATE_PARTIALLY_UNLOCKED\x10\x03*?\n\tLockFault\x12\x1a\n\x16LOCK_FAULT_UNSPECIFIED\x10\x00\x12\x16\n\x12LOCK_FAULT_FAULTED\x10\x01*\xcb\x01\n\x0eWindowInstance\x12\x1f\n\x1bWINDOW_INSTANCE_UNSPECIFIED\x10\x00\x12\x1e\n\x1aWINDOW_INSTANCE_FRONT_LEFT\x10\x01\x12\x1f\n\x1bWINDOW_INSTANCE_FRONT_RIGHT\x10\x02\x12\x1d\n\x19WINDOW_INSTANCE_REAR_LEFT\x10\x03\x12\x1e\n\x1aWINDOW_INSTANCE_REAR_RIGHT\x10\x04\x12\x18\n\x14WINDOW_INSTANCE_REAR\x10\x05*\x81\x01\n\x11\x43\x61librationStatus\x12\"\n\x1e\x43\x41LIBRATION_STATUS_UNSPECIFIED\x10\x00\x12!\n\x1d\x43\x41LIBRATION_STATUS_CALIBRATED\x10\x01\x12%\n!CALIBRATION_STATUS_NOT_CALIBRATED\x10\x02*\xd8\x01\n\x0fRearHitchStatus\x12!\n\x1dREAR_HITCH_STATUS_UNSPECIFIED\x10\x00\x12!\n\x1dREAR_HITCH_STATUS_NOT_PRESENT\x10\x01\x12\x1f\n\x1bREAR_HITCH_STATUS_ACCESSORY\x10\x02\x12\x1e\n\x1aREAR_HITCH_STATUS_TRAILER1\x10\x03\x12\x1e\n\x1aREAR_HITCH_STATUS_TRAILER2\x10\x04\x12\x1e\n\x1aREAR_HITCH_STATUS_TRAILER3\x10\x05*\xaa\x01\n\x0c\x43losureFault\x12\x1d\n\x19\x43LOSURE_FAULT_UNSPECIFIED\x10\x00\x12\x1a\n\x16\x43LOSURE_FAULT_NO_FAULT\x10\x01\x12\x19\n\x15\x43LOSURE_FAULT_GENERAL\x10\x02\x12&\n\"CLOSURE_FAULT_NO_POWERED_OPERATION\x10\x03\x12\x1c\n\x18\x43LOSURE_FAULT_OBSTRUCTED\x10\x04*\x97\x01\n\x0fTrailerPresence\x12 \n\x1cTRAILER_PRESENCE_UNSPECIFIED\x10\x00\x12\x17\n\x13TRAILER_NOT_PRESENT\x10\x01\x12\x13\n\x0fTRAILER_PRESENT\x10\x02\x12\x1f\n\x1bTRAILER_PRESENT_WITH_BRAKES\x10\x03\x12\x13\n\x0fTRAILER_INVALID\x10\x04*\x9f\x04\n\x18\x43hargePortDoorNextAction\x12\x18\n\x14\x43HARGE_PORT_DOOR_SNA\x10\x00\x12!\n\x1d\x43HARGE_PORT_DOOR_OPEN_ALLOWED\x10\x01\x12\'\n#CHARGE_PORT_DOOR_OPEN_NOT_AVAILABLE\x10\x02\x12-\n)CHARGE_PORT_DOOR_OPEN_NOT_ALLOWED_FAULTED\x10\x03\x12\x1c\n\x18\x43HARGE_PORT_DOOR_OPENING\x10\x04\x12\"\n\x1e\x43HARGE_PORT_DOOR_CLOSE_ALLOWED\x10\x05\x12;\n7CHARGE_PORT_DOOR_OBSTRUCTED_WHILE_OPENING_CLOSE_ALLOWED\x10\x06\x12:\n6CHARGE_PORT_DOOR_OBSTRUCTED_WHILE_OPENING_OPEN_ALLOWED\x10\x07\x12;\n7CHARGE_PORT_DOOR_OBSTRUCTED_WHILE_CLOSING_CLOSE_ALLOWED\x10\x08\x12(\n$CHARGE_PORT_DOOR_CLOSE_NOT_AVAILABLE\x10\t\x12.\n*CHARGE_PORT_DOOR_CLOSE_NOT_ALLOWED_FAULTED\x10\n\x12\x1c\n\x18\x43HARGE_PORT_DOOR_CLOSING\x10\x0b*\xb0\x03\n\x0f\x46runkNextAction\x12\r\n\tFRUNK_SNA\x10\x00\x12\x16\n\x12\x46RUNK_OPEN_ALLOWED\x10\x01\x12\x17\n\x13\x46RUNK_CLOSE_ALLOWED\x10\x02\x12\x11\n\rFRUNK_OPENING\x10\x03\x12\x11\n\rFRUNK_CLOSING\x10\x04\x12\x1c\n\x18\x46RUNK_OPEN_NOT_AVAILABLE\x10\x05\x12\x1d\n\x19\x46RUNK_CLOSE_NOT_AVAILABLE\x10\x06\x12\"\n\x1e\x46RUNK_OPEN_NOT_ALLOWED_FAULTED\x10\x07\x12#\n\x1f\x46RUNK_CLOSE_NOT_ALLOWED_FAULTED\x10\x08\x12)\n%FRUNK_OPEN_ALLOWED_NO_POWER_OPERATION\x10\t\x12.\n*FRUNK_CLOSE_NOT_ALLOWED_NO_POWER_OPERATION\x10\n\x12*\n&FRUNK_OBSTRUCTED_OPENING_CLOSE_ALLOWED\x10\x0b\x12*\n&FRUNK_OBSTRUCTED_CLOSING_CLOSE_ALLOWED\x10\x0c*\xa7\x06\n\x12LiftgateNextAction\x12\x10\n\x0cLIFTGATE_SNA\x10\x00\x12\x19\n\x15LIFTGATE_OPEN_ALLOWED\x10\x01\x12\x1a\n\x16LIFTGATE_CLOSE_ALLOWED\x10\x02\x12\x14\n\x10LIFTGATE_OPENING\x10\x03\x12\x14\n\x10LIFTGATE_CLOSING\x10\x04\x12\x1f\n\x1bLIFTGATE_OPEN_NOT_AVAILABLE\x10\x05\x12 \n\x1cLIFTGATE_CLOSE_NOT_AVAILABLE\x10\x06\x12%\n!LIFTGATE_OPEN_NOT_ALLOWED_FAULTED\x10\x07\x12&\n\"LIFTGATE_CLOSE_NOT_ALLOWED_FAULTED\x10\x08\x12,\n(LIFTGATE_OPEN_ALLOWED_NO_POWER_OPERATION\x10\t\x12\x31\n-LIFTGATE_CLOSE_NOT_ALLOWED_NO_POWER_OPERATION\x10\n\x12-\n)LIFTGATE_OBSTRUCTED_OPENING_CLOSE_ALLOWED\x10\x0b\x12-\n)LIFTGATE_OBSTRUCTED_CLOSING_CLOSE_ALLOWED\x10\x0c\x12.\n*LIFTGATE_LOWER_GATE_OPEN_CLOSE_NOT_ALLOWED\x10\r\x12&\n\"LIFTGATE_OPENING_PAUSE_NOT_ALLOWED\x10\x0e\x12&\n\"LIFTGATE_CLOSING_PAUSE_NOT_ALLOWED\x10\x0f\x12+\n\'LIFTGATE_OPEN_ALLOWED_OBSTACLE_DETECTED\x10\x10\x12*\n&LIFTGATE_OPEN_ALLOWED_TRAILER_DETECTED\x10\x11\x12,\n(LIFTGATE_CLOSE_ALLOWED_OBSTACLE_DETECTED\x10\x12\x12+\n\'LIFTGATE_CLOSE_ALLOWED_TRAILER_DETECTED\x10\x13\x12\x17\n\x13LIFTGATE_PROCESSING\x10\x14*\xb2\x02\n\x11SideBinNextAction\x12\x10\n\x0cSIDE_BIN_SNA\x10\x00\x12\x19\n\x15SIDE_BIN_OPEN_ALLOWED\x10\x01\x12\x14\n\x10SIDE_BIN_OPENING\x10\x02\x12\x1f\n\x1bSIDE_BIN_OPEN_NOT_AVAILABLE\x10\x03\x12%\n!SIDE_BIN_OPEN_NOT_ALLOWED_FAULTED\x10\x04\x12\x32\n.SIDE_BIN_STUCK_AJAR_WHILE_OPENING_OPEN_ALLOWED\x10\x05\x12-\n)SIDE_BIN_OPEN_ALREADY_NO_ACTION_AVAILABLE\x10\x06\x12/\n+SIDE_BIN_OPEN_ALLOWED_CONFIRM_VEHICLE_ANGLE\x10\x07*\x8c\x03\n\x12TailgateNextAction\x12\x10\n\x0cTAILGATE_SNA\x10\x00\x12\x19\n\x15TAILGATE_OPEN_ALLOWED\x10\x01\x12\x14\n\x10TAILGATE_OPENING\x10\x02\x12\x1f\n\x1bTAILGATE_OPEN_NOT_AVAILABLE\x10\x03\x12%\n!TAILGATE_OPEN_NOT_ALLOWED_FAULTED\x10\x04\x12\x32\n.TAILGATE_STUCK_AJAR_WHILE_OPENING_OPEN_ALLOWED\x10\x05\x12-\n)TAILGATE_OPEN_ALREADY_NO_ACTION_AVAILABLE\x10\x06\x12/\n+TAILGATE_OPEN_ALLOWED_CONFIRM_VEHICLE_ANGLE\x10\x07\x12+\n\'TAILGATE_OPEN_ALLOWED_OBSTACLE_DETECTED\x10\x08\x12*\n&TAILGATE_OPEN_ALLOWED_TRAILER_DETECTED\x10\t*\xb0\x03\n\x11WindowsNextAction\x12\x0f\n\x0bWINDOWS_SNA\x10\x00\x12\x18\n\x14WINDOWS_OPEN_ALLOWED\x10\x01\x12\x19\n\x15WINDOWS_CLOSE_ALLOWED\x10\x02\x12\x13\n\x0fWINDOWS_OPENING\x10\x03\x12\x13\n\x0fWINDOWS_CLOSING\x10\x04\x12\x12\n\x0eWINDOWS_MOVING\x10\x05\x12\x1e\n\x1aWINDOWS_OPEN_NOT_AVAILABLE\x10\x06\x12\x1f\n\x1bWINDOWS_CLOSE_NOT_AVAILABLE\x10\x07\x12$\n WINDOWS_OPEN_NOT_ALLOWED_FAULTED\x10\x08\x12%\n!WINDOWS_CLOSE_NOT_ALLOWED_FAULTED\x10\t\x12\x32\n.WINDOWS_OBSTRUCTED_WHILE_CLOSING_CLOSE_ALLOWED\x10\n\x12*\n&WINDOWS_CLOSE_NOT_ALLOWED_UNCALIBRATED\x10\x0b\x12)\n%WINDOWS_OPEN_NOT_ALLOWED_UNCALIBRATED\x10\x0c*\x8a\x01\n\x0fWiperFluidState\x12!\n\x1dWIPER_FLUID_STATE_UNSPECIFIED\x10\x00\x12\x1c\n\x18WIPER_FLUID_STATE_NORMAL\x10\x01\x12\x19\n\x15WIPER_FLUID_STATE_LOW\x10\x02\x12\x1b\n\x17WIPER_FLUID_STATE_EMPTY\x10\x03\x62\x06proto3')
|
|
28
28
|
|
|
29
29
|
_globals = globals()
|
|
30
30
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
31
31
|
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'rivian.parallax.proto.body_pb2', _globals)
|
|
32
32
|
if not _descriptor._USE_C_DESCRIPTORS:
|
|
33
33
|
DESCRIPTOR._loaded_options = None
|
|
34
|
-
_globals['_CLOSUREID']._serialized_start=
|
|
35
|
-
_globals['_CLOSUREID']._serialized_end=
|
|
36
|
-
_globals['_CLOSURESTATE']._serialized_start=
|
|
37
|
-
_globals['_CLOSURESTATE']._serialized_end=
|
|
38
|
-
_globals['_LOCKID']._serialized_start=
|
|
39
|
-
_globals['_LOCKID']._serialized_end=
|
|
40
|
-
_globals['_LOCKSTATE']._serialized_start=
|
|
41
|
-
_globals['_LOCKSTATE']._serialized_end=
|
|
42
|
-
_globals['_LOCKFAULT']._serialized_start=
|
|
43
|
-
_globals['_LOCKFAULT']._serialized_end=
|
|
44
|
-
_globals['_WINDOWINSTANCE']._serialized_start=
|
|
45
|
-
_globals['_WINDOWINSTANCE']._serialized_end=
|
|
46
|
-
_globals['_CALIBRATIONSTATUS']._serialized_start=
|
|
47
|
-
_globals['_CALIBRATIONSTATUS']._serialized_end=
|
|
48
|
-
_globals['_REARHITCHSTATUS']._serialized_start=
|
|
49
|
-
_globals['_REARHITCHSTATUS']._serialized_end=
|
|
50
|
-
_globals['_CLOSUREFAULT']._serialized_start=
|
|
51
|
-
_globals['_CLOSUREFAULT']._serialized_end=
|
|
52
|
-
_globals['_TRAILERPRESENCE']._serialized_start=
|
|
53
|
-
_globals['_TRAILERPRESENCE']._serialized_end=
|
|
54
|
-
_globals['_CHARGEPORTDOORNEXTACTION']._serialized_start=
|
|
55
|
-
_globals['_CHARGEPORTDOORNEXTACTION']._serialized_end=
|
|
56
|
-
_globals['_FRUNKNEXTACTION']._serialized_start=
|
|
57
|
-
_globals['_FRUNKNEXTACTION']._serialized_end=
|
|
58
|
-
_globals['_LIFTGATENEXTACTION']._serialized_start=
|
|
59
|
-
_globals['_LIFTGATENEXTACTION']._serialized_end=
|
|
60
|
-
_globals['_SIDEBINNEXTACTION']._serialized_start=
|
|
61
|
-
_globals['_SIDEBINNEXTACTION']._serialized_end=
|
|
62
|
-
_globals['_TAILGATENEXTACTION']._serialized_start=
|
|
63
|
-
_globals['_TAILGATENEXTACTION']._serialized_end=
|
|
64
|
-
_globals['_WINDOWSNEXTACTION']._serialized_start=
|
|
65
|
-
_globals['_WINDOWSNEXTACTION']._serialized_end=
|
|
66
|
-
_globals['_WIPERFLUIDSTATE']._serialized_start=
|
|
67
|
-
_globals['_WIPERFLUIDSTATE']._serialized_end=
|
|
34
|
+
_globals['_CLOSUREID']._serialized_start=1596
|
|
35
|
+
_globals['_CLOSUREID']._serialized_end=1956
|
|
36
|
+
_globals['_CLOSURESTATE']._serialized_start=1959
|
|
37
|
+
_globals['_CLOSURESTATE']._serialized_end=2132
|
|
38
|
+
_globals['_LOCKID']._serialized_start=2135
|
|
39
|
+
_globals['_LOCKID']._serialized_end=2506
|
|
40
|
+
_globals['_LOCKSTATE']._serialized_start=2508
|
|
41
|
+
_globals['_LOCKSTATE']._serialized_end=2630
|
|
42
|
+
_globals['_LOCKFAULT']._serialized_start=2632
|
|
43
|
+
_globals['_LOCKFAULT']._serialized_end=2695
|
|
44
|
+
_globals['_WINDOWINSTANCE']._serialized_start=2698
|
|
45
|
+
_globals['_WINDOWINSTANCE']._serialized_end=2901
|
|
46
|
+
_globals['_CALIBRATIONSTATUS']._serialized_start=2904
|
|
47
|
+
_globals['_CALIBRATIONSTATUS']._serialized_end=3033
|
|
48
|
+
_globals['_REARHITCHSTATUS']._serialized_start=3036
|
|
49
|
+
_globals['_REARHITCHSTATUS']._serialized_end=3252
|
|
50
|
+
_globals['_CLOSUREFAULT']._serialized_start=3255
|
|
51
|
+
_globals['_CLOSUREFAULT']._serialized_end=3425
|
|
52
|
+
_globals['_TRAILERPRESENCE']._serialized_start=3428
|
|
53
|
+
_globals['_TRAILERPRESENCE']._serialized_end=3579
|
|
54
|
+
_globals['_CHARGEPORTDOORNEXTACTION']._serialized_start=3582
|
|
55
|
+
_globals['_CHARGEPORTDOORNEXTACTION']._serialized_end=4125
|
|
56
|
+
_globals['_FRUNKNEXTACTION']._serialized_start=4128
|
|
57
|
+
_globals['_FRUNKNEXTACTION']._serialized_end=4560
|
|
58
|
+
_globals['_LIFTGATENEXTACTION']._serialized_start=4563
|
|
59
|
+
_globals['_LIFTGATENEXTACTION']._serialized_end=5370
|
|
60
|
+
_globals['_SIDEBINNEXTACTION']._serialized_start=5373
|
|
61
|
+
_globals['_SIDEBINNEXTACTION']._serialized_end=5679
|
|
62
|
+
_globals['_TAILGATENEXTACTION']._serialized_start=5682
|
|
63
|
+
_globals['_TAILGATENEXTACTION']._serialized_end=6078
|
|
64
|
+
_globals['_WINDOWSNEXTACTION']._serialized_start=6081
|
|
65
|
+
_globals['_WINDOWSNEXTACTION']._serialized_end=6513
|
|
66
|
+
_globals['_WIPERFLUIDSTATE']._serialized_start=6516
|
|
67
|
+
_globals['_WIPERFLUIDSTATE']._serialized_end=6654
|
|
68
68
|
_globals['_CLOSURESSTATE']._serialized_start=59
|
|
69
69
|
_globals['_CLOSURESSTATE']._serialized_end=836
|
|
70
70
|
_globals['_CLOSURESSTATE_CLOSURE']._serialized_start=139
|
|
@@ -81,4 +81,8 @@ if not _descriptor._USE_C_DESCRIPTORS:
|
|
|
81
81
|
_globals['_TRAILERSTATE']._serialized_end=1436
|
|
82
82
|
_globals['_WIPERFLUIDLEVEL']._serialized_start=1438
|
|
83
83
|
_globals['_WIPERFLUIDLEVEL']._serialized_end=1509
|
|
84
|
+
_globals['_UNLOCKCOMMAND']._serialized_start=1511
|
|
85
|
+
_globals['_UNLOCKCOMMAND']._serialized_end=1578
|
|
86
|
+
_globals['_LOCKCOMMAND']._serialized_start=1580
|
|
87
|
+
_globals['_LOCKCOMMAND']._serialized_end=1593
|
|
84
88
|
# @@protoc_insertion_point(module_scope)
|
|
@@ -434,3 +434,15 @@ class WiperFluidLevel(_message.Message):
|
|
|
434
434
|
STATE_FIELD_NUMBER: _ClassVar[int]
|
|
435
435
|
state: WiperFluidState
|
|
436
436
|
def __init__(self, state: _Optional[_Union[WiperFluidState, str]] = ...) -> None: ...
|
|
437
|
+
|
|
438
|
+
class UnlockCommand(_message.Message):
|
|
439
|
+
__slots__ = ("all", "user_preference")
|
|
440
|
+
ALL_FIELD_NUMBER: _ClassVar[int]
|
|
441
|
+
USER_PREFERENCE_FIELD_NUMBER: _ClassVar[int]
|
|
442
|
+
all: bool
|
|
443
|
+
user_preference: bool
|
|
444
|
+
def __init__(self, all: bool = ..., user_preference: bool = ...) -> None: ...
|
|
445
|
+
|
|
446
|
+
class LockCommand(_message.Message):
|
|
447
|
+
__slots__ = ()
|
|
448
|
+
def __init__(self) -> None: ...
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package rivian.parallax.command;
|
|
4
|
+
|
|
5
|
+
// Reverse-engineered `sendParallaxPayload` request for a signed remote command,
|
|
6
|
+
// and the `vehicleCommandStatePx` message that reports on it; see ../command.py.
|
|
7
|
+
// Only the field numbers matter on the wire. Enum values are named as the app
|
|
8
|
+
// names them, except ResponseStatus, which the app names without a prefix. Unlike
|
|
9
|
+
// operation.proto's Operation, this one goes to the vehicle inside a signed
|
|
10
|
+
// Envelope.
|
|
11
|
+
|
|
12
|
+
// Wraps an Operation. Field 17 is what makes it a signed command.
|
|
13
|
+
message Envelope {
|
|
14
|
+
// The app's envelope can hold other kinds of value; a command only uses this
|
|
15
|
+
oneof value {
|
|
16
|
+
Composite composite = 10;
|
|
17
|
+
}
|
|
18
|
+
Timestamp last_update = 12;
|
|
19
|
+
bytes correlation_id = 16; // the command id: 16 bytes of a UUID
|
|
20
|
+
SecurityInfo security_info = 17;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
message Composite {
|
|
24
|
+
bytes bytes_val = 2; // a serialized Operation
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
message Operation {
|
|
28
|
+
string rvm = 1;
|
|
29
|
+
OperationType type = 2;
|
|
30
|
+
bytes command_id = 3; // the same 16 bytes as the envelope's correlation_id
|
|
31
|
+
bytes payload = 4; // the RVM's message; absent when empty
|
|
32
|
+
Timestamp created_at = 5;
|
|
33
|
+
// 6 is never set by the app
|
|
34
|
+
string vehicle_id = 7;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
enum OperationType {
|
|
38
|
+
PARALLAX_OPERATION_UNSPECIFIED = 0;
|
|
39
|
+
PARALLAX_OPERATION_PUBLISH = 1;
|
|
40
|
+
PARALLAX_OPERATION_SUBSCRIBE = 2;
|
|
41
|
+
PARALLAX_OPERATION_REQUEST = 3; // the only one a command uses
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
message SecurityInfo {
|
|
45
|
+
Signature signature = 1;
|
|
46
|
+
string mapped_identity = 2; // the enrolled phone's identityId for the vehicle
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
message Signature {
|
|
50
|
+
SignatureType type = 1;
|
|
51
|
+
bytes value = 2; // 32 raw bytes of the HMAC-SHA256, not hex
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
enum SignatureType {
|
|
55
|
+
DATA_SIGNATURE_TYPE_UNSPECIFIED = 0;
|
|
56
|
+
DATA_SIGNATURE_TYPE_HMAC_SHA256 = 1;
|
|
57
|
+
DATA_SIGNATURE_TYPE_RCS = 2;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
message Timestamp {
|
|
61
|
+
int64 seconds = 1; // epoch seconds
|
|
62
|
+
int32 nanos = 2;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// What `vehicleCommandStatePx` sends, base64 encoded, as the command goes on.
|
|
66
|
+
message CommandState {
|
|
67
|
+
bytes command_id = 1; // 16 bytes of a UUID
|
|
68
|
+
string rvm = 2;
|
|
69
|
+
Progress progress = 3;
|
|
70
|
+
oneof result {
|
|
71
|
+
OperationError operation_error = 4;
|
|
72
|
+
// The app declares this as bytes holding a CommandResult, which is the
|
|
73
|
+
// same on the wire. Present, but empty, for an undefined status.
|
|
74
|
+
CommandResult data = 5;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
enum Progress {
|
|
79
|
+
VEHICLE_MODEL_OP_PROGRESS_UNSPECIFIED = 0;
|
|
80
|
+
VEHICLE_MODEL_OP_PROGRESS_VEHICLE_WAKING_UP = 1; // seen twice for one command
|
|
81
|
+
VEHICLE_MODEL_OP_PROGRESS_VEHICLE_VALIDATING = 2;
|
|
82
|
+
VEHICLE_MODEL_OP_PROGRESS_VEHICLE_EXECUTING = 3;
|
|
83
|
+
VEHICLE_MODEL_OP_PROGRESS_VEHICLE_COMPLETE = 4; // the last message
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
message CommandResult {
|
|
87
|
+
ResponseStatus response_status = 1;
|
|
88
|
+
Error error = 2;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
enum ResponseStatus {
|
|
92
|
+
RESPONSE_STATUS_UNDEFINED = 0;
|
|
93
|
+
RESPONSE_STATUS_SUCCESS = 1;
|
|
94
|
+
RESPONSE_STATUS_FAIL = 2;
|
|
95
|
+
RESPONSE_STATUS_INVALID_REQUEST = 3;
|
|
96
|
+
RESPONSE_STATUS_NOT_SUPPORTED = 4;
|
|
97
|
+
RESPONSE_STATUS_TIMEOUT = 5;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
message Error {
|
|
101
|
+
int32 code = 1;
|
|
102
|
+
string message = 2;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
message OperationError {
|
|
106
|
+
int32 error = 1; // an enum in the app, whose values were not decompiled
|
|
107
|
+
string message = 2;
|
|
108
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
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/command.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/command.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/command.proto\x12\x17rivian.parallax.command\"\xdb\x01\n\x08\x45nvelope\x12\x37\n\tcomposite\x18\n \x01(\x0b\x32\".rivian.parallax.command.CompositeH\x00\x12\x37\n\x0blast_update\x18\x0c \x01(\x0b\x32\".rivian.parallax.command.Timestamp\x12\x16\n\x0e\x63orrelation_id\x18\x10 \x01(\x0c\x12<\n\rsecurity_info\x18\x11 \x01(\x0b\x32%.rivian.parallax.command.SecurityInfoB\x07\n\x05value\"\x1e\n\tComposite\x12\x11\n\tbytes_val\x18\x02 \x01(\x0c\"\xbf\x01\n\tOperation\x12\x0b\n\x03rvm\x18\x01 \x01(\t\x12\x34\n\x04type\x18\x02 \x01(\x0e\x32&.rivian.parallax.command.OperationType\x12\x12\n\ncommand_id\x18\x03 \x01(\x0c\x12\x0f\n\x07payload\x18\x04 \x01(\x0c\x12\x36\n\ncreated_at\x18\x05 \x01(\x0b\x32\".rivian.parallax.command.Timestamp\x12\x12\n\nvehicle_id\x18\x07 \x01(\t\"^\n\x0cSecurityInfo\x12\x35\n\tsignature\x18\x01 \x01(\x0b\x32\".rivian.parallax.command.Signature\x12\x17\n\x0fmapped_identity\x18\x02 \x01(\t\"P\n\tSignature\x12\x34\n\x04type\x18\x01 \x01(\x0e\x32&.rivian.parallax.command.SignatureType\x12\r\n\x05value\x18\x02 \x01(\x0c\"+\n\tTimestamp\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\"\xea\x01\n\x0c\x43ommandState\x12\x12\n\ncommand_id\x18\x01 \x01(\x0c\x12\x0b\n\x03rvm\x18\x02 \x01(\t\x12\x33\n\x08progress\x18\x03 \x01(\x0e\x32!.rivian.parallax.command.Progress\x12\x42\n\x0foperation_error\x18\x04 \x01(\x0b\x32\'.rivian.parallax.command.OperationErrorH\x00\x12\x36\n\x04\x64\x61ta\x18\x05 \x01(\x0b\x32&.rivian.parallax.command.CommandResultH\x00\x42\x08\n\x06result\"\x80\x01\n\rCommandResult\x12@\n\x0fresponse_status\x18\x01 \x01(\x0e\x32\'.rivian.parallax.command.ResponseStatus\x12-\n\x05\x65rror\x18\x02 \x01(\x0b\x32\x1e.rivian.parallax.command.Error\"&\n\x05\x45rror\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0f\n\x07message\x18\x02 \x01(\t\"0\n\x0eOperationError\x12\r\n\x05\x65rror\x18\x01 \x01(\x05\x12\x0f\n\x07message\x18\x02 \x01(\t*\x95\x01\n\rOperationType\x12\"\n\x1ePARALLAX_OPERATION_UNSPECIFIED\x10\x00\x12\x1e\n\x1aPARALLAX_OPERATION_PUBLISH\x10\x01\x12 \n\x1cPARALLAX_OPERATION_SUBSCRIBE\x10\x02\x12\x1e\n\x1aPARALLAX_OPERATION_REQUEST\x10\x03*v\n\rSignatureType\x12#\n\x1f\x44\x41TA_SIGNATURE_TYPE_UNSPECIFIED\x10\x00\x12#\n\x1f\x44\x41TA_SIGNATURE_TYPE_HMAC_SHA256\x10\x01\x12\x1b\n\x17\x44\x41TA_SIGNATURE_TYPE_RCS\x10\x02*\xf9\x01\n\x08Progress\x12)\n%VEHICLE_MODEL_OP_PROGRESS_UNSPECIFIED\x10\x00\x12/\n+VEHICLE_MODEL_OP_PROGRESS_VEHICLE_WAKING_UP\x10\x01\x12\x30\n,VEHICLE_MODEL_OP_PROGRESS_VEHICLE_VALIDATING\x10\x02\x12/\n+VEHICLE_MODEL_OP_PROGRESS_VEHICLE_EXECUTING\x10\x03\x12.\n*VEHICLE_MODEL_OP_PROGRESS_VEHICLE_COMPLETE\x10\x04*\xcb\x01\n\x0eResponseStatus\x12\x1d\n\x19RESPONSE_STATUS_UNDEFINED\x10\x00\x12\x1b\n\x17RESPONSE_STATUS_SUCCESS\x10\x01\x12\x18\n\x14RESPONSE_STATUS_FAIL\x10\x02\x12#\n\x1fRESPONSE_STATUS_INVALID_REQUEST\x10\x03\x12!\n\x1dRESPONSE_STATUS_NOT_SUPPORTED\x10\x04\x12\x1b\n\x17RESPONSE_STATUS_TIMEOUT\x10\x05\x62\x06proto3')
|
|
28
|
+
|
|
29
|
+
_globals = globals()
|
|
30
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
31
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'rivian.parallax.proto.command_pb2', _globals)
|
|
32
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
|
33
|
+
DESCRIPTOR._loaded_options = None
|
|
34
|
+
_globals['_OPERATIONTYPE']._serialized_start=1194
|
|
35
|
+
_globals['_OPERATIONTYPE']._serialized_end=1343
|
|
36
|
+
_globals['_SIGNATURETYPE']._serialized_start=1345
|
|
37
|
+
_globals['_SIGNATURETYPE']._serialized_end=1463
|
|
38
|
+
_globals['_PROGRESS']._serialized_start=1466
|
|
39
|
+
_globals['_PROGRESS']._serialized_end=1715
|
|
40
|
+
_globals['_RESPONSESTATUS']._serialized_start=1718
|
|
41
|
+
_globals['_RESPONSESTATUS']._serialized_end=1921
|
|
42
|
+
_globals['_ENVELOPE']._serialized_start=65
|
|
43
|
+
_globals['_ENVELOPE']._serialized_end=284
|
|
44
|
+
_globals['_COMPOSITE']._serialized_start=286
|
|
45
|
+
_globals['_COMPOSITE']._serialized_end=316
|
|
46
|
+
_globals['_OPERATION']._serialized_start=319
|
|
47
|
+
_globals['_OPERATION']._serialized_end=510
|
|
48
|
+
_globals['_SECURITYINFO']._serialized_start=512
|
|
49
|
+
_globals['_SECURITYINFO']._serialized_end=606
|
|
50
|
+
_globals['_SIGNATURE']._serialized_start=608
|
|
51
|
+
_globals['_SIGNATURE']._serialized_end=688
|
|
52
|
+
_globals['_TIMESTAMP']._serialized_start=690
|
|
53
|
+
_globals['_TIMESTAMP']._serialized_end=733
|
|
54
|
+
_globals['_COMMANDSTATE']._serialized_start=736
|
|
55
|
+
_globals['_COMMANDSTATE']._serialized_end=970
|
|
56
|
+
_globals['_COMMANDRESULT']._serialized_start=973
|
|
57
|
+
_globals['_COMMANDRESULT']._serialized_end=1101
|
|
58
|
+
_globals['_ERROR']._serialized_start=1103
|
|
59
|
+
_globals['_ERROR']._serialized_end=1141
|
|
60
|
+
_globals['_OPERATIONERROR']._serialized_start=1143
|
|
61
|
+
_globals['_OPERATIONERROR']._serialized_end=1191
|
|
62
|
+
# @@protoc_insertion_point(module_scope)
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
|
2
|
+
from google.protobuf import descriptor as _descriptor
|
|
3
|
+
from google.protobuf import message as _message
|
|
4
|
+
from collections.abc import Mapping as _Mapping
|
|
5
|
+
from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
|
|
6
|
+
|
|
7
|
+
DESCRIPTOR: _descriptor.FileDescriptor
|
|
8
|
+
|
|
9
|
+
class OperationType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
10
|
+
__slots__ = ()
|
|
11
|
+
PARALLAX_OPERATION_UNSPECIFIED: _ClassVar[OperationType]
|
|
12
|
+
PARALLAX_OPERATION_PUBLISH: _ClassVar[OperationType]
|
|
13
|
+
PARALLAX_OPERATION_SUBSCRIBE: _ClassVar[OperationType]
|
|
14
|
+
PARALLAX_OPERATION_REQUEST: _ClassVar[OperationType]
|
|
15
|
+
|
|
16
|
+
class SignatureType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
17
|
+
__slots__ = ()
|
|
18
|
+
DATA_SIGNATURE_TYPE_UNSPECIFIED: _ClassVar[SignatureType]
|
|
19
|
+
DATA_SIGNATURE_TYPE_HMAC_SHA256: _ClassVar[SignatureType]
|
|
20
|
+
DATA_SIGNATURE_TYPE_RCS: _ClassVar[SignatureType]
|
|
21
|
+
|
|
22
|
+
class Progress(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
23
|
+
__slots__ = ()
|
|
24
|
+
VEHICLE_MODEL_OP_PROGRESS_UNSPECIFIED: _ClassVar[Progress]
|
|
25
|
+
VEHICLE_MODEL_OP_PROGRESS_VEHICLE_WAKING_UP: _ClassVar[Progress]
|
|
26
|
+
VEHICLE_MODEL_OP_PROGRESS_VEHICLE_VALIDATING: _ClassVar[Progress]
|
|
27
|
+
VEHICLE_MODEL_OP_PROGRESS_VEHICLE_EXECUTING: _ClassVar[Progress]
|
|
28
|
+
VEHICLE_MODEL_OP_PROGRESS_VEHICLE_COMPLETE: _ClassVar[Progress]
|
|
29
|
+
|
|
30
|
+
class ResponseStatus(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
31
|
+
__slots__ = ()
|
|
32
|
+
RESPONSE_STATUS_UNDEFINED: _ClassVar[ResponseStatus]
|
|
33
|
+
RESPONSE_STATUS_SUCCESS: _ClassVar[ResponseStatus]
|
|
34
|
+
RESPONSE_STATUS_FAIL: _ClassVar[ResponseStatus]
|
|
35
|
+
RESPONSE_STATUS_INVALID_REQUEST: _ClassVar[ResponseStatus]
|
|
36
|
+
RESPONSE_STATUS_NOT_SUPPORTED: _ClassVar[ResponseStatus]
|
|
37
|
+
RESPONSE_STATUS_TIMEOUT: _ClassVar[ResponseStatus]
|
|
38
|
+
PARALLAX_OPERATION_UNSPECIFIED: OperationType
|
|
39
|
+
PARALLAX_OPERATION_PUBLISH: OperationType
|
|
40
|
+
PARALLAX_OPERATION_SUBSCRIBE: OperationType
|
|
41
|
+
PARALLAX_OPERATION_REQUEST: OperationType
|
|
42
|
+
DATA_SIGNATURE_TYPE_UNSPECIFIED: SignatureType
|
|
43
|
+
DATA_SIGNATURE_TYPE_HMAC_SHA256: SignatureType
|
|
44
|
+
DATA_SIGNATURE_TYPE_RCS: SignatureType
|
|
45
|
+
VEHICLE_MODEL_OP_PROGRESS_UNSPECIFIED: Progress
|
|
46
|
+
VEHICLE_MODEL_OP_PROGRESS_VEHICLE_WAKING_UP: Progress
|
|
47
|
+
VEHICLE_MODEL_OP_PROGRESS_VEHICLE_VALIDATING: Progress
|
|
48
|
+
VEHICLE_MODEL_OP_PROGRESS_VEHICLE_EXECUTING: Progress
|
|
49
|
+
VEHICLE_MODEL_OP_PROGRESS_VEHICLE_COMPLETE: Progress
|
|
50
|
+
RESPONSE_STATUS_UNDEFINED: ResponseStatus
|
|
51
|
+
RESPONSE_STATUS_SUCCESS: ResponseStatus
|
|
52
|
+
RESPONSE_STATUS_FAIL: ResponseStatus
|
|
53
|
+
RESPONSE_STATUS_INVALID_REQUEST: ResponseStatus
|
|
54
|
+
RESPONSE_STATUS_NOT_SUPPORTED: ResponseStatus
|
|
55
|
+
RESPONSE_STATUS_TIMEOUT: ResponseStatus
|
|
56
|
+
|
|
57
|
+
class Envelope(_message.Message):
|
|
58
|
+
__slots__ = ("composite", "last_update", "correlation_id", "security_info")
|
|
59
|
+
COMPOSITE_FIELD_NUMBER: _ClassVar[int]
|
|
60
|
+
LAST_UPDATE_FIELD_NUMBER: _ClassVar[int]
|
|
61
|
+
CORRELATION_ID_FIELD_NUMBER: _ClassVar[int]
|
|
62
|
+
SECURITY_INFO_FIELD_NUMBER: _ClassVar[int]
|
|
63
|
+
composite: Composite
|
|
64
|
+
last_update: Timestamp
|
|
65
|
+
correlation_id: bytes
|
|
66
|
+
security_info: SecurityInfo
|
|
67
|
+
def __init__(self, composite: _Optional[_Union[Composite, _Mapping]] = ..., last_update: _Optional[_Union[Timestamp, _Mapping]] = ..., correlation_id: _Optional[bytes] = ..., security_info: _Optional[_Union[SecurityInfo, _Mapping]] = ...) -> None: ...
|
|
68
|
+
|
|
69
|
+
class Composite(_message.Message):
|
|
70
|
+
__slots__ = ("bytes_val",)
|
|
71
|
+
BYTES_VAL_FIELD_NUMBER: _ClassVar[int]
|
|
72
|
+
bytes_val: bytes
|
|
73
|
+
def __init__(self, bytes_val: _Optional[bytes] = ...) -> None: ...
|
|
74
|
+
|
|
75
|
+
class Operation(_message.Message):
|
|
76
|
+
__slots__ = ("rvm", "type", "command_id", "payload", "created_at", "vehicle_id")
|
|
77
|
+
RVM_FIELD_NUMBER: _ClassVar[int]
|
|
78
|
+
TYPE_FIELD_NUMBER: _ClassVar[int]
|
|
79
|
+
COMMAND_ID_FIELD_NUMBER: _ClassVar[int]
|
|
80
|
+
PAYLOAD_FIELD_NUMBER: _ClassVar[int]
|
|
81
|
+
CREATED_AT_FIELD_NUMBER: _ClassVar[int]
|
|
82
|
+
VEHICLE_ID_FIELD_NUMBER: _ClassVar[int]
|
|
83
|
+
rvm: str
|
|
84
|
+
type: OperationType
|
|
85
|
+
command_id: bytes
|
|
86
|
+
payload: bytes
|
|
87
|
+
created_at: Timestamp
|
|
88
|
+
vehicle_id: str
|
|
89
|
+
def __init__(self, rvm: _Optional[str] = ..., type: _Optional[_Union[OperationType, str]] = ..., command_id: _Optional[bytes] = ..., payload: _Optional[bytes] = ..., created_at: _Optional[_Union[Timestamp, _Mapping]] = ..., vehicle_id: _Optional[str] = ...) -> None: ...
|
|
90
|
+
|
|
91
|
+
class SecurityInfo(_message.Message):
|
|
92
|
+
__slots__ = ("signature", "mapped_identity")
|
|
93
|
+
SIGNATURE_FIELD_NUMBER: _ClassVar[int]
|
|
94
|
+
MAPPED_IDENTITY_FIELD_NUMBER: _ClassVar[int]
|
|
95
|
+
signature: Signature
|
|
96
|
+
mapped_identity: str
|
|
97
|
+
def __init__(self, signature: _Optional[_Union[Signature, _Mapping]] = ..., mapped_identity: _Optional[str] = ...) -> None: ...
|
|
98
|
+
|
|
99
|
+
class Signature(_message.Message):
|
|
100
|
+
__slots__ = ("type", "value")
|
|
101
|
+
TYPE_FIELD_NUMBER: _ClassVar[int]
|
|
102
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
103
|
+
type: SignatureType
|
|
104
|
+
value: bytes
|
|
105
|
+
def __init__(self, type: _Optional[_Union[SignatureType, str]] = ..., value: _Optional[bytes] = ...) -> None: ...
|
|
106
|
+
|
|
107
|
+
class Timestamp(_message.Message):
|
|
108
|
+
__slots__ = ("seconds", "nanos")
|
|
109
|
+
SECONDS_FIELD_NUMBER: _ClassVar[int]
|
|
110
|
+
NANOS_FIELD_NUMBER: _ClassVar[int]
|
|
111
|
+
seconds: int
|
|
112
|
+
nanos: int
|
|
113
|
+
def __init__(self, seconds: _Optional[int] = ..., nanos: _Optional[int] = ...) -> None: ...
|
|
114
|
+
|
|
115
|
+
class CommandState(_message.Message):
|
|
116
|
+
__slots__ = ("command_id", "rvm", "progress", "operation_error", "data")
|
|
117
|
+
COMMAND_ID_FIELD_NUMBER: _ClassVar[int]
|
|
118
|
+
RVM_FIELD_NUMBER: _ClassVar[int]
|
|
119
|
+
PROGRESS_FIELD_NUMBER: _ClassVar[int]
|
|
120
|
+
OPERATION_ERROR_FIELD_NUMBER: _ClassVar[int]
|
|
121
|
+
DATA_FIELD_NUMBER: _ClassVar[int]
|
|
122
|
+
command_id: bytes
|
|
123
|
+
rvm: str
|
|
124
|
+
progress: Progress
|
|
125
|
+
operation_error: OperationError
|
|
126
|
+
data: CommandResult
|
|
127
|
+
def __init__(self, command_id: _Optional[bytes] = ..., rvm: _Optional[str] = ..., progress: _Optional[_Union[Progress, str]] = ..., operation_error: _Optional[_Union[OperationError, _Mapping]] = ..., data: _Optional[_Union[CommandResult, _Mapping]] = ...) -> None: ...
|
|
128
|
+
|
|
129
|
+
class CommandResult(_message.Message):
|
|
130
|
+
__slots__ = ("response_status", "error")
|
|
131
|
+
RESPONSE_STATUS_FIELD_NUMBER: _ClassVar[int]
|
|
132
|
+
ERROR_FIELD_NUMBER: _ClassVar[int]
|
|
133
|
+
response_status: ResponseStatus
|
|
134
|
+
error: Error
|
|
135
|
+
def __init__(self, response_status: _Optional[_Union[ResponseStatus, str]] = ..., error: _Optional[_Union[Error, _Mapping]] = ...) -> None: ...
|
|
136
|
+
|
|
137
|
+
class Error(_message.Message):
|
|
138
|
+
__slots__ = ("code", "message")
|
|
139
|
+
CODE_FIELD_NUMBER: _ClassVar[int]
|
|
140
|
+
MESSAGE_FIELD_NUMBER: _ClassVar[int]
|
|
141
|
+
code: int
|
|
142
|
+
message: str
|
|
143
|
+
def __init__(self, code: _Optional[int] = ..., message: _Optional[str] = ...) -> None: ...
|
|
144
|
+
|
|
145
|
+
class OperationError(_message.Message):
|
|
146
|
+
__slots__ = ("error", "message")
|
|
147
|
+
ERROR_FIELD_NUMBER: _ClassVar[int]
|
|
148
|
+
MESSAGE_FIELD_NUMBER: _ClassVar[int]
|
|
149
|
+
error: int
|
|
150
|
+
message: str
|
|
151
|
+
def __init__(self, error: _Optional[int] = ..., message: _Optional[str] = ...) -> None: ...
|
rivian/rivian.py
CHANGED
|
@@ -10,7 +10,6 @@ import uuid
|
|
|
10
10
|
from collections.abc import Awaitable, Callable
|
|
11
11
|
from datetime import date
|
|
12
12
|
from typing import Any, Self
|
|
13
|
-
from warnings import warn
|
|
14
13
|
|
|
15
14
|
import aiohttp
|
|
16
15
|
from aiohttp import ClientResponse, ClientWebSocketResponse
|
|
@@ -36,9 +35,10 @@ from .parallax import (
|
|
|
36
35
|
CLIMATE_HOLD_SETTING_RVM,
|
|
37
36
|
CLIMATE_HOLD_STATUS_RVM,
|
|
38
37
|
encode_climate_hold_setting,
|
|
38
|
+
encode_command,
|
|
39
39
|
encode_vehicle_operation,
|
|
40
40
|
)
|
|
41
|
-
from .utils import generate_vehicle_command_hmac
|
|
41
|
+
from .utils import generate_vehicle_command_hmac, send_deprecation_warning
|
|
42
42
|
from .ws_monitor import WebSocketMonitor
|
|
43
43
|
|
|
44
44
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -91,15 +91,14 @@ def _iso_date(value: date | str) -> str:
|
|
|
91
91
|
return value if isinstance(value, str) else value.strftime("%Y-%m-%d")
|
|
92
92
|
|
|
93
93
|
|
|
94
|
-
def
|
|
95
|
-
"""
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
_LOGGER.warning(message)
|
|
94
|
+
def _command_id(command_id: str | None = None) -> str:
|
|
95
|
+
"""Return a Parallax command id as a canonical UUID string, or a new one."""
|
|
96
|
+
if command_id is None:
|
|
97
|
+
return str(uuid.uuid4())
|
|
98
|
+
try:
|
|
99
|
+
return str(uuid.UUID(str(command_id)))
|
|
100
|
+
except ValueError as err:
|
|
101
|
+
raise RivianBadRequestError("A command id must be a UUID") from err
|
|
103
102
|
|
|
104
103
|
|
|
105
104
|
class Rivian:
|
|
@@ -645,6 +644,27 @@ class Rivian:
|
|
|
645
644
|
}
|
|
646
645
|
return await self.__graphql_query(headers, url, graphql_json)
|
|
647
646
|
|
|
647
|
+
async def send_location_to_vehicle(
|
|
648
|
+
self, vehicle_id: str, location: str
|
|
649
|
+
) -> ClientResponse:
|
|
650
|
+
"""Send a destination to a vehicle's navigation.
|
|
651
|
+
|
|
652
|
+
`location` is an address, a place, or coordinates as "lat,lng", and Rivian
|
|
653
|
+
parses it. A `publishResponse.result` of 0 means the request was accepted.
|
|
654
|
+
"""
|
|
655
|
+
url = GRAPHQL_GATEWAY
|
|
656
|
+
headers = BASE_HEADERS | {
|
|
657
|
+
"Csrf-Token": self._csrf_token,
|
|
658
|
+
"A-Sess": self._app_session_token,
|
|
659
|
+
"U-Sess": self._user_session_token,
|
|
660
|
+
}
|
|
661
|
+
graphql_json = {
|
|
662
|
+
"operationName": "parseAndShareLocationToVehicle",
|
|
663
|
+
"query": "mutation parseAndShareLocationToVehicle($str: String!, $vehicleId: String!) { parseAndShareLocationToVehicle(str: $str, vehicleId: $vehicleId) { __typename publishResponse { __typename result } } }",
|
|
664
|
+
"variables": {"str": location, "vehicleId": vehicle_id},
|
|
665
|
+
}
|
|
666
|
+
return await self.__graphql_query(headers, url, graphql_json)
|
|
667
|
+
|
|
648
668
|
async def get_vehicle_ota_update_details(self, vehicle_id: str) -> ClientResponse:
|
|
649
669
|
"""Get vehicle OTA update details."""
|
|
650
670
|
url = GRAPHQL_GATEWAY
|
|
@@ -684,6 +704,8 @@ class Rivian:
|
|
|
684
704
|
VehicleCommand.CABIN_HVAC_RIGHT_SEAT_HEAT,
|
|
685
705
|
VehicleCommand.CABIN_HVAC_RIGHT_SEAT_VENT,
|
|
686
706
|
VehicleCommand.CABIN_HVAC_STEERING_HEAT,
|
|
707
|
+
VehicleCommand.CABIN_HVAC_3RD_ROW_REAR_LEFT_SEAT_HEAT,
|
|
708
|
+
VehicleCommand.CABIN_HVAC_3RD_ROW_REAR_RIGHT_SEAT_HEAT,
|
|
687
709
|
) and not (
|
|
688
710
|
params
|
|
689
711
|
and isinstance((level := params.get("level")), int)
|
|
@@ -762,6 +784,72 @@ class Rivian:
|
|
|
762
784
|
return status.get("id")
|
|
763
785
|
return None
|
|
764
786
|
|
|
787
|
+
async def send_parallax_command(
|
|
788
|
+
self,
|
|
789
|
+
vehicle_id: str,
|
|
790
|
+
rvm: str,
|
|
791
|
+
payload: bytes,
|
|
792
|
+
*,
|
|
793
|
+
identity_id: str,
|
|
794
|
+
vehicle_key: str,
|
|
795
|
+
private_key: str,
|
|
796
|
+
command_id: str | None = None,
|
|
797
|
+
) -> str | None:
|
|
798
|
+
"""Send a signed Parallax command to the vehicle, e.g. to unlock it.
|
|
799
|
+
|
|
800
|
+
`rvm` and `payload` go together, e.g. `UNLOCK_RVM` and `encode_unlock()`
|
|
801
|
+
from `rivian.parallax`. The keys are those of `send_vehicle_command`: a
|
|
802
|
+
phone key enrolled with `enroll_phone`. In testing, a sleeping vehicle
|
|
803
|
+
was woken by the request, so `WAKE_VEHICLE` wasn't needed first. The app
|
|
804
|
+
sends body commands this way only to vehicles that list `PVS_BD_CMD` as
|
|
805
|
+
available; how others respond is untested.
|
|
806
|
+
|
|
807
|
+
Returns the command's id, a UUID (the given `command_id`, if any), once
|
|
808
|
+
Rivian has accepted the command, or None if it didn't. That isn't the
|
|
809
|
+
command done: follow it with `subscribe_for_parallax_command_state`.
|
|
810
|
+
|
|
811
|
+
Raises `RivianBadRequestError` for a missing id or a `command_id` that
|
|
812
|
+
isn't a UUID, and the usual `RivianApiException` if the request fails,
|
|
813
|
+
which can be after Rivian has the command. Bad keys raise `ValueError`
|
|
814
|
+
or a `cryptography` error before anything is sent.
|
|
815
|
+
"""
|
|
816
|
+
if not (vehicle_id and rvm and identity_id):
|
|
817
|
+
raise RivianBadRequestError(
|
|
818
|
+
"A Parallax command needs a vehicle id, an RVM and an identity id"
|
|
819
|
+
)
|
|
820
|
+
command_id = _command_id(command_id)
|
|
821
|
+
url = GRAPHQL_GATEWAY
|
|
822
|
+
headers = BASE_HEADERS | {
|
|
823
|
+
"Csrf-Token": self._csrf_token,
|
|
824
|
+
"A-Sess": self._app_session_token,
|
|
825
|
+
"U-Sess": self._user_session_token,
|
|
826
|
+
}
|
|
827
|
+
graphql_json = {
|
|
828
|
+
"operationName": "SendRemoteCommand",
|
|
829
|
+
"variables": {
|
|
830
|
+
"vehicleId": vehicle_id,
|
|
831
|
+
"model": rvm,
|
|
832
|
+
"parallaxPayloadB64": encode_command(
|
|
833
|
+
vehicle_id,
|
|
834
|
+
rvm,
|
|
835
|
+
payload,
|
|
836
|
+
identity_id=identity_id,
|
|
837
|
+
vehicle_key=vehicle_key,
|
|
838
|
+
private_key=private_key,
|
|
839
|
+
command_id=command_id,
|
|
840
|
+
),
|
|
841
|
+
},
|
|
842
|
+
"query": "mutation SendRemoteCommand($vehicleId: String!, $model: String!, $parallaxPayloadB64: String!) { sendParallaxPayload(payload: $parallaxPayloadB64, meta: { vehicleId: $vehicleId model: $model isVehicleModelOp: true requiresWakeup: true } ) { success sequenceNumber } }",
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
response = await self.__graphql_query(headers, url, graphql_json)
|
|
846
|
+
if response.status == 200:
|
|
847
|
+
data = await response.json()
|
|
848
|
+
sent = (data.get("data") or {}).get("sendParallaxPayload") or {}
|
|
849
|
+
if sent.get("success"):
|
|
850
|
+
return command_id
|
|
851
|
+
return None
|
|
852
|
+
|
|
765
853
|
async def send_vehicle_operation(
|
|
766
854
|
self,
|
|
767
855
|
vehicle_id: str,
|
|
@@ -889,6 +977,36 @@ class Rivian:
|
|
|
889
977
|
payload, callback, f"{vehicle_id} {topics}"
|
|
890
978
|
)
|
|
891
979
|
|
|
980
|
+
async def subscribe_for_parallax_command_state(
|
|
981
|
+
self,
|
|
982
|
+
vehicle_id: str,
|
|
983
|
+
command_id: str,
|
|
984
|
+
callback: Callable[[dict[str, Any]], None],
|
|
985
|
+
) -> Callable[[], Awaitable[None]] | None:
|
|
986
|
+
"""Open a web socket connection to follow a `send_parallax_command`.
|
|
987
|
+
|
|
988
|
+
The messages report the command's progress, up to its result; decode them
|
|
989
|
+
with `parallax.decode_command_state_message`. Subscribe before sending the
|
|
990
|
+
command: Rivian doesn't acknowledge a subscription, and states from before
|
|
991
|
+
it may not be replayed.
|
|
992
|
+
|
|
993
|
+
The last message has the progress "complete", but none comes if the
|
|
994
|
+
vehicle can't be reached, so keep a timeout of your own. The subscription
|
|
995
|
+
is kept, and resubscribed after a quiet minute or a reconnect (so a message
|
|
996
|
+
may come more than once), until the returned function is awaited. Returns
|
|
997
|
+
None if it couldn't subscribe, and raises `RivianBadRequestError` if
|
|
998
|
+
`command_id` isn't a UUID.
|
|
999
|
+
"""
|
|
1000
|
+
command_id = _command_id(command_id)
|
|
1001
|
+
payload = {
|
|
1002
|
+
"operationName": "vehicleCommandStatePx",
|
|
1003
|
+
"query": "subscription vehicleCommandStatePx($vehicleId: String!, $commandId: String!) { vehicleCommandStatePx(vehicleId: $vehicleId, commandId: $commandId) { payload } }",
|
|
1004
|
+
"variables": {"vehicleId": vehicle_id, "commandId": command_id},
|
|
1005
|
+
}
|
|
1006
|
+
return await self._start_subscription(
|
|
1007
|
+
payload, callback, f"{vehicle_id} command {command_id}"
|
|
1008
|
+
)
|
|
1009
|
+
|
|
892
1010
|
async def _start_subscription(
|
|
893
1011
|
self,
|
|
894
1012
|
payload: dict[str, Any],
|
rivian/utils.py
CHANGED
|
@@ -4,14 +4,30 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import hashlib
|
|
6
6
|
import hmac
|
|
7
|
+
import logging
|
|
7
8
|
from base64 import b64decode, b64encode
|
|
8
9
|
from datetime import UTC, datetime
|
|
9
10
|
from typing import cast
|
|
11
|
+
from warnings import warn
|
|
10
12
|
|
|
11
13
|
from cryptography.hazmat.primitives import hashes, serialization
|
|
12
14
|
from cryptography.hazmat.primitives.asymmetric import ec
|
|
13
15
|
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
|
|
14
16
|
|
|
17
|
+
_LOGGER = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def send_deprecation_warning(old_name: str, new_name: str) -> None:
|
|
21
|
+
"""Send a deprecation warning."""
|
|
22
|
+
message = f"{old_name} has been deprecated in favor of {new_name}, the alias will be removed in the future"
|
|
23
|
+
warn(
|
|
24
|
+
message,
|
|
25
|
+
DeprecationWarning,
|
|
26
|
+
# Point at the code that called the deprecated function
|
|
27
|
+
stacklevel=3,
|
|
28
|
+
)
|
|
29
|
+
_LOGGER.warning(message)
|
|
30
|
+
|
|
15
31
|
|
|
16
32
|
def base64_encode(data: bytes) -> str:
|
|
17
33
|
"""Encode bytes to Base64 string"""
|
|
@@ -69,12 +85,25 @@ def generate_key_pair() -> tuple[str, str]:
|
|
|
69
85
|
return (public_key_str, private_key_str)
|
|
70
86
|
|
|
71
87
|
|
|
88
|
+
def generate_command_hmac(data: bytes, vehicle_key: str, private_key: str) -> bytes:
|
|
89
|
+
"""Return the raw HMAC-SHA256 of `data`, keyed by the phone and vehicle keys.
|
|
90
|
+
|
|
91
|
+
Signs BLE commands and signed Parallax commands alike.
|
|
92
|
+
"""
|
|
93
|
+
secret_key = get_secret_key(private_key, vehicle_key)
|
|
94
|
+
return bytes.fromhex(get_message_signature(secret_key, data))
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# TODO: Remove around 2027-05, six months after its deprecation in 2026-11
|
|
72
98
|
def generate_ble_command_hmac(
|
|
73
99
|
hmac_data: bytes, vehicle_key: str, private_key: str
|
|
74
100
|
) -> bytes:
|
|
75
|
-
"""Generate ble command hmac.
|
|
76
|
-
|
|
77
|
-
|
|
101
|
+
"""Generate ble command hmac.
|
|
102
|
+
|
|
103
|
+
Deprecated: use `generate_command_hmac`.
|
|
104
|
+
"""
|
|
105
|
+
send_deprecation_warning("generate_ble_command_hmac", "generate_command_hmac")
|
|
106
|
+
return generate_command_hmac(hmac_data, vehicle_key, private_key)
|
|
78
107
|
|
|
79
108
|
|
|
80
109
|
def generate_vehicle_command_hmac(
|
rivian/ws_monitor.py
CHANGED
|
@@ -24,6 +24,8 @@ _LOGGER = logging.getLogger(__name__)
|
|
|
24
24
|
|
|
25
25
|
RATE_LIMITED = "Rate limited"
|
|
26
26
|
UNAUTHENTICATED = "Unauthenticated"
|
|
27
|
+
# Close code with which the server refuses a connection
|
|
28
|
+
FORBIDDEN = 4403
|
|
27
29
|
RATE_LIMIT_BACKOFF_MIN = 30
|
|
28
30
|
RATE_LIMIT_BACKOFF_MAX = 900
|
|
29
31
|
|
|
@@ -85,6 +87,8 @@ class WebSocketMonitor:
|
|
|
85
87
|
self._backoff_reason: str | None = None
|
|
86
88
|
# The server's reason for closing the current connection, if it gave one
|
|
87
89
|
self._close_message: str | None = None
|
|
90
|
+
# Whether the server refused the current connection (4403) before its ack
|
|
91
|
+
self._forbidden = False
|
|
88
92
|
self._backoff_state = (
|
|
89
93
|
_Backoff()
|
|
90
94
|
if backoff_key is None
|
|
@@ -145,8 +149,12 @@ class WebSocketMonitor:
|
|
|
145
149
|
|
|
146
150
|
@property
|
|
147
151
|
def unauthenticated(self) -> bool:
|
|
148
|
-
"""Return `True` if the server closed the latest connection as unauthenticated.
|
|
149
|
-
|
|
152
|
+
"""Return `True` if the server closed the latest connection as unauthenticated.
|
|
153
|
+
|
|
154
|
+
That is, with the reason "Unauthenticated" or as forbidden (4403) before
|
|
155
|
+
the connection was acknowledged.
|
|
156
|
+
"""
|
|
157
|
+
return self._close_message == UNAUTHENTICATED or self._forbidden
|
|
150
158
|
|
|
151
159
|
@property
|
|
152
160
|
def backoff_remaining(self) -> float:
|
|
@@ -164,6 +172,7 @@ class WebSocketMonitor:
|
|
|
164
172
|
self._disconnect = False
|
|
165
173
|
self._backoff_reason = None
|
|
166
174
|
self._close_message = None
|
|
175
|
+
self._forbidden = False
|
|
167
176
|
self._connection_ack.clear()
|
|
168
177
|
# pylint: disable=protected-access
|
|
169
178
|
assert self._account._session
|
|
@@ -270,7 +279,11 @@ class WebSocketMonitor:
|
|
|
270
279
|
if msg.type in (WSMsgType.CLOSE, WSMsgType.CLOSING, WSMsgType.CLOSED):
|
|
271
280
|
self._log_message(msg)
|
|
272
281
|
self._close_message = msg.extra or None
|
|
273
|
-
|
|
282
|
+
# After the ack a 4403 may be transient, so reconnect instead
|
|
283
|
+
self._forbidden = (
|
|
284
|
+
not acknowledged and websocket.close_code == FORBIDDEN
|
|
285
|
+
)
|
|
286
|
+
if self.unauthenticated:
|
|
274
287
|
self._disconnect = True
|
|
275
288
|
elif msg.extra == RATE_LIMITED:
|
|
276
289
|
self._start_backoff(BACKOFF_RATE_LIMITED)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: rivian-python-client
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
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
|
|
@@ -65,3 +65,44 @@ editing one, regenerate its `*_pb2` modules (don't edit those by hand):
|
|
|
65
65
|
uv run python -m grpc_tools.protoc --proto_path=src --python_out=src \
|
|
66
66
|
--pyi_out=src src/rivian/parallax/proto/*.proto
|
|
67
67
|
```
|
|
68
|
+
|
|
69
|
+
### Commands
|
|
70
|
+
|
|
71
|
+
`send_parallax_command` sends a signed command, such as unlocking
|
|
72
|
+
(`parallax.UNLOCK_RVM` with `parallax.encode_unlock()`; `LOCK_RVM` and
|
|
73
|
+
`encode_lock()` to lock), and `subscribe_for_parallax_command_state` follows it.
|
|
74
|
+
Subscribe first, then send:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
import uuid
|
|
78
|
+
|
|
79
|
+
from rivian import parallax
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def on_state(data):
|
|
83
|
+
if state := parallax.decode_command_state_message(data):
|
|
84
|
+
print(state["progress"], state["status"], state["error"])
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
command_id = str(uuid.uuid4())
|
|
88
|
+
unsubscribe = await rivian.subscribe_for_parallax_command_state(
|
|
89
|
+
vehicle_id, command_id, on_state
|
|
90
|
+
)
|
|
91
|
+
if unsubscribe:
|
|
92
|
+
await rivian.send_parallax_command(
|
|
93
|
+
vehicle_id,
|
|
94
|
+
parallax.UNLOCK_RVM,
|
|
95
|
+
parallax.encode_unlock(),
|
|
96
|
+
identity_id=identity_id,
|
|
97
|
+
vehicle_key=vehicle_key,
|
|
98
|
+
private_key=private_key,
|
|
99
|
+
command_id=command_id,
|
|
100
|
+
)
|
|
101
|
+
... # wait for the progress "complete", or give up
|
|
102
|
+
await unsubscribe()
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The keys are those of `send_vehicle_command`. The command is done when the progress
|
|
106
|
+
is `complete`, the status `success` and there is no `error`. If you never see that,
|
|
107
|
+
check the vehicle before sending it again. This unlocks a real vehicle, so keep the
|
|
108
|
+
keys secret.
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
rivian/__init__.py,sha256=m1arAfL3-WG5NQDkraIni2h-tGr-2nmltIabQetCFw8,207
|
|
2
|
-
rivian/__version__.py,sha256=
|
|
3
|
-
rivian/ble.py,sha256=
|
|
4
|
-
rivian/const.py,sha256=
|
|
2
|
+
rivian/__version__.py,sha256=dR-oduO2bwSixGaYt6Y_HUAhG5f_sK-djy4s6GUfu-Y,171
|
|
3
|
+
rivian/ble.py,sha256=ko-PBco51wqt-eJeILbXyJWOdZf87xh2uR-d3ls-4qc,5872
|
|
4
|
+
rivian/const.py,sha256=rl9-Dmj0E74xviYhZ9-jcv-nJ_JYrwINOygYX35ol1w,7134
|
|
5
5
|
rivian/exceptions.py,sha256=JVSOTzbfbIp4pobx9mFQm12m_qgVNV2p-Zp34m590Uw,969
|
|
6
6
|
rivian/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
rivian/rivian.py,sha256=
|
|
8
|
-
rivian/utils.py,sha256=
|
|
9
|
-
rivian/ws_monitor.py,sha256=
|
|
10
|
-
rivian/parallax/__init__.py,sha256=
|
|
11
|
-
rivian/parallax/body.py,sha256=
|
|
7
|
+
rivian/rivian.py,sha256=H8ZH95FJU5f78MsEICw9Xt-oBbmwSWOuGAW-e85vZRU,49821
|
|
8
|
+
rivian/utils.py,sha256=rQ1X8ttQ5BkbfLjqE1q7teu6Lw8Gya7Xd4bb6aAwlhs,4894
|
|
9
|
+
rivian/ws_monitor.py,sha256=o3Cqa8b0qJj7VWnGqnebQEvtAR8xk5yS8RFld1F0u8s,16096
|
|
10
|
+
rivian/parallax/__init__.py,sha256=GS_hkC0FW4_Bf-xpGPUw0Y6Nd62glI2XH4JSURcxdyo,3302
|
|
11
|
+
rivian/parallax/body.py,sha256=F56wnpTgJO5-uXVXbtg2W-Z-XT7OPHmgxnnkwqfubqs,9996
|
|
12
12
|
rivian/parallax/charging.py,sha256=pB_RtqiK9yMF3qGJdCjoqSSX3t8RMizU4mHGV6f2Y5E,17370
|
|
13
13
|
rivian/parallax/comfort.py,sha256=AhRl8Hz43EQWIT6kSgWQxgZ6MEE3Yi8BpZquIPZl4yw,12682
|
|
14
|
-
rivian/parallax/
|
|
14
|
+
rivian/parallax/command.py,sha256=6XAvYB5D3BsB4B5JyTEo05eAkJIGW0FkF9EzKe6BCIM,6840
|
|
15
|
+
rivian/parallax/core.py,sha256=VAt78QoGt8iGTzFOwWG0cTnYYyXBvPGrND1anFrLuIw,5913
|
|
15
16
|
rivian/parallax/departure.py,sha256=SzgcYPG74TrkE7m4DhrspIlx2pcl7EcKowTJT7y0iDw,4244
|
|
16
17
|
rivian/parallax/device_table.py,sha256=eTn3Ld-tLbil8VurrPfRWx6kwugKZ0YQPrWI6NdWi4Y,5757
|
|
17
18
|
rivian/parallax/dynamics.py,sha256=F554PzA70_j32uG-8DBxsy3Lcc9QcVtTQ3N2eZbKG78,10480
|
|
@@ -30,15 +31,18 @@ rivian/parallax/user_passcodes.py,sha256=VFCCF5IwxchK1XNohk-axiDfjz5KoETzYhYqSD7
|
|
|
30
31
|
rivian/parallax/vehicle.py,sha256=somEeK3vTC2dLiVkdXQzAC3SsVMKBU0WYTJcyL35eGM,8668
|
|
31
32
|
rivian/parallax/vehicle_access.py,sha256=ZbttRDm7SdUk9rwZ2pghvhy6OTOZDbaIH0x7KjYfj48,2284
|
|
32
33
|
rivian/parallax/proto/__init__.py,sha256=zK8ZbnfFPlrZtz4ehFVqCYig4fPsSO-AQ-cPo7LB3LA,331
|
|
33
|
-
rivian/parallax/proto/body.proto,sha256=
|
|
34
|
-
rivian/parallax/proto/body_pb2.py,sha256=
|
|
35
|
-
rivian/parallax/proto/body_pb2.pyi,sha256=
|
|
34
|
+
rivian/parallax/proto/body.proto,sha256=sYYKDU1_tucYysXD--O5yzvIhoxgrqd9HpqUjO__i8c,7863
|
|
35
|
+
rivian/parallax/proto/body_pb2.py,sha256=hKy8rRpSY0CkMsB5gNBOpi0boqyeWYPHDTTjiqJVBeI,13795
|
|
36
|
+
rivian/parallax/proto/body_pb2.pyi,sha256=iJlK0jQ_ebplV5HZxQPCMUkq8XbZl8fMNGS2mSFwY50,22074
|
|
36
37
|
rivian/parallax/proto/charging.proto,sha256=uoIcBet_ApAyDe9JFFJyLRoC3q7rxFP4t0ZRg6GrCLw,7336
|
|
37
38
|
rivian/parallax/proto/charging_pb2.py,sha256=9WmzG9ns43uJfISlmDl_K67At4RIOdhn3k4jPGET_iM,12411
|
|
38
39
|
rivian/parallax/proto/charging_pb2.pyi,sha256=lSDCDP4o1obDnCUXq2KYGCvPY-Oq1Pzo6qUHSzjcpxw,18820
|
|
39
40
|
rivian/parallax/proto/comfort.proto,sha256=I6Lxh0FH0tkFFMeo5iV49NZfbiKViaaCb-1eTfSHJ8Y,4789
|
|
40
41
|
rivian/parallax/proto/comfort_pb2.py,sha256=_RW6pCjZdWuhKQCRT4DBj-a_YNVd7d4oex_pbMDR36k,10203
|
|
41
42
|
rivian/parallax/proto/comfort_pb2.pyi,sha256=BXChLWZlv3d6slTIk99pdFMtM-5Xmc8vH1ov6AnwsPg,14342
|
|
43
|
+
rivian/parallax/proto/command.proto,sha256=tjUvm1NQGlXfIITB9XUPQ5IVUp9q_VcFfJVoEAEjTpw,3080
|
|
44
|
+
rivian/parallax/proto/command_pb2.py,sha256=IJtwu6ESWSzNFcTJi62hYSlhxRqumdQ9VosFosETi_I,5450
|
|
45
|
+
rivian/parallax/proto/command_pb2.pyi,sha256=RXy_IHwOmgCN2YOJvbqQe8STIfcNuKBKhctGrSdFU7o,6863
|
|
42
46
|
rivian/parallax/proto/departure.proto,sha256=bjt6kSNIGvW0vlMSyQVchP0jGJhSmez8E4d2orVrWww,2224
|
|
43
47
|
rivian/parallax/proto/departure_pb2.py,sha256=eKBiWihlUWx3gvCTGpiuG8CepwWcSxEMJGpjC541hyw,5952
|
|
44
48
|
rivian/parallax/proto/departure_pb2.pyi,sha256=Jw8vfV8PtnsK-sDbpJmiJBNiK4xgDi2TuKBTAoTeJEE,7502
|
|
@@ -93,6 +97,6 @@ rivian/parallax/proto/vehicle_pb2.pyi,sha256=uM5JxmmlviPjtUq1FFqyZ_i-ih28A46KIYU
|
|
|
93
97
|
rivian/schemas/charging.graphql,sha256=YkaQbGtCDPtxGzmgNxOUHgYZKNDDtW7IipoaAFdGmGo,3061
|
|
94
98
|
rivian/schemas/gateway.graphql,sha256=0ZJX5_bKHqLmk3rtpp9to9GwrdCxyTasMhxAPwEhsqI,17865
|
|
95
99
|
rivian/schemas/orders.graphql,sha256=goM4x7gbkFHvpMf7XUv2cTkTKMaIicrT4JbIi07F_Do,4290
|
|
96
|
-
rivian_python_client-2.
|
|
97
|
-
rivian_python_client-2.
|
|
98
|
-
rivian_python_client-2.
|
|
100
|
+
rivian_python_client-2.4.0.dist-info/METADATA,sha256=knlFQc4KJGFXkrjIXcszPc3-F5psaq7LDbCgWywnWo0,2981
|
|
101
|
+
rivian_python_client-2.4.0.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
|
|
102
|
+
rivian_python_client-2.4.0.dist-info/RECORD,,
|