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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions src/saic_ismart_client_ng/api/vehicle/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,17 @@ class RvcParamsId(Enum):
UNK_6 = 6
LOCK_ID = 7
WINDOW_SUNROOF = 8
# The door windows follow the status model (driverWindow, passengerWindow,
# rearLeftWindow, rearRightWindow). The front pair is named by role, the
# rear pair by side. The WINDOW_2/3/4 names are the original ones, kept as
# aliases.
WINDOW_DRIVER = 9
WINDOW_2 = 10
WINDOW_3 = 11
WINDOW_4 = 12
WINDOW_PASSENGER = 10
WINDOW_REAR_LEFT = 11
WINDOW_REAR_RIGHT = 12
WINDOW_2 = 10 # noqa: PIE796 - alias of WINDOW_PASSENGER
WINDOW_3 = 11 # noqa: PIE796 - alias of WINDOW_REAR_LEFT
WINDOW_4 = 12 # noqa: PIE796 - alias of WINDOW_REAR_RIGHT
WINDOW_OPEN_CLOSE = 13
HEATED_SEAT_DRIVER = 17
HEATED_SEAT_PASSENGER = 18
Expand Down
12 changes: 6 additions & 6 deletions src/saic_ismart_client_ng/api/vehicle/windows/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ async def control_windows(
for i in [
VehicleWindowId.SUNROOF,
VehicleWindowId.DRIVER,
VehicleWindowId.WINDOW_2,
VehicleWindowId.WINDOW_3,
VehicleWindowId.WINDOW_4,
VehicleWindowId.PASSENGER,
VehicleWindowId.REAR_LEFT,
VehicleWindowId.REAR_RIGHT,
]:
if i.value.value in requested_windows:
rcv_params.append(RvcParams(i.value, b"\x01"))
Expand Down Expand Up @@ -78,9 +78,9 @@ async def control_door_windows(
rvc_params = [
RvcParams(RvcParamsId.WINDOW_SUNROOF, b"\x00"),
RvcParams(RvcParamsId.WINDOW_DRIVER, b"\x01"),
RvcParams(RvcParamsId.WINDOW_2, b"\x01"),
RvcParams(RvcParamsId.WINDOW_3, b"\x01"),
RvcParams(RvcParamsId.WINDOW_4, b"\x01"),
RvcParams(RvcParamsId.WINDOW_PASSENGER, b"\x01"),
RvcParams(RvcParamsId.WINDOW_REAR_LEFT, b"\x01"),
RvcParams(RvcParamsId.WINDOW_REAR_RIGHT, b"\x01"),
RvcParams(RvcParamsId.WINDOW_OPEN_CLOSE, action.value.to_bytes(1, "big")),
]
request = VehicleControlReq(
Expand Down
10 changes: 7 additions & 3 deletions src/saic_ismart_client_ng/api/vehicle/windows/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
class VehicleWindowId(Enum):
SUNROOF = RvcParamsId.WINDOW_SUNROOF
DRIVER = RvcParamsId.WINDOW_DRIVER
WINDOW_2 = RvcParamsId.WINDOW_2
WINDOW_3 = RvcParamsId.WINDOW_3
WINDOW_4 = RvcParamsId.WINDOW_4
PASSENGER = RvcParamsId.WINDOW_PASSENGER
REAR_LEFT = RvcParamsId.WINDOW_REAR_LEFT
REAR_RIGHT = RvcParamsId.WINDOW_REAR_RIGHT
# The original names, kept as aliases.
WINDOW_2 = RvcParamsId.WINDOW_2 # alias of PASSENGER
WINDOW_3 = RvcParamsId.WINDOW_3 # alias of REAR_LEFT
WINDOW_4 = RvcParamsId.WINDOW_4 # alias of REAR_RIGHT


class DoorWindowsAction(Enum):
Expand Down
59 changes: 59 additions & 0 deletions tests/test_door_window_names.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""Door windows are named after the status model, the old names are aliases.

The parameters sent to the car don't change.
"""

from __future__ import annotations

import base64
from typing import Any
import unittest

from saic_ismart_client_ng import SaicApi
from saic_ismart_client_ng.api.vehicle import RvcParamsId
from saic_ismart_client_ng.api.vehicle.windows import VehicleWindowId
from saic_ismart_client_ng.model import SaicApiConfiguration


class TestDoorWindowNames(unittest.IsolatedAsyncioTestCase):
def test_new_names_keep_the_param_ids(self) -> None:
assert RvcParamsId.WINDOW_DRIVER.value == 9
assert RvcParamsId.WINDOW_PASSENGER.value == 10
assert RvcParamsId.WINDOW_REAR_LEFT.value == 11
assert RvcParamsId.WINDOW_REAR_RIGHT.value == 12

def test_old_names_still_work(self) -> None:
# Looked up by name: mypy doesn't know enum aliases share a member.
assert RvcParamsId["WINDOW_2"] is RvcParamsId.WINDOW_PASSENGER
assert RvcParamsId["WINDOW_3"] is RvcParamsId.WINDOW_REAR_LEFT
assert RvcParamsId["WINDOW_4"] is RvcParamsId.WINDOW_REAR_RIGHT
assert VehicleWindowId["WINDOW_2"] is VehicleWindowId.PASSENGER
assert VehicleWindowId["WINDOW_3"] is VehicleWindowId.REAR_LEFT
assert VehicleWindowId["WINDOW_4"] is VehicleWindowId.REAR_RIGHT

async def test_control_windows_command_unchanged(self) -> None:
api = SaicApi(SaicApiConfiguration(username="user", password="pass")) # noqa: S106
captured: dict[str, Any] = {}

async def capture(body: Any, _vin: str) -> None:
captured["body"] = body

api.send_vehicle_control_command = capture # type: ignore[method-assign,assignment]
await api.control_windows(
"OFFLINE0000000000",
should_open=False,
windows=[VehicleWindowId.PASSENGER],
)
await api.close()
params = [
(p.paramId, base64.b64decode(p.paramValue))
for p in captured["body"].rvcParams
]
assert params == [
(8, b"\x00"),
(9, b"\x00"),
(10, b"\x01"),
(11, b"\x00"),
(12, b"\x00"),
(13, b"\x00"),
]
Loading