Skip to content

Commit b4f03a4

Browse files
committed
refactor: export and define all simulator state default constants at package level
1 parent 0a23de7 commit b4f03a4

4 files changed

Lines changed: 113 additions & 80 deletions

File tree

roborock/testing/__init__.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,25 @@ async def test_start_vacuum_service():
6666
from roborock.testing.channel import FakeChannel
6767
from roborock.testing.cloud import FakeRoborockCloud, FakeUserState, FakeWebApiClient
6868
from roborock.testing.simulator import RoborockDeviceSimulator
69-
from roborock.testing.v1_simulator import V1VacuumSimulator
69+
from roborock.testing.v1_simulator import (
70+
DEFAULT_APP_INIT,
71+
DEFAULT_CLEAN_SUMMARY,
72+
DEFAULT_CONSUMABLE,
73+
DEFAULT_DND_TIMER,
74+
DEFAULT_LAST_CLEAN_RECORD,
75+
DEFAULT_NETWORK_INFO,
76+
DEFAULT_STATUS,
77+
V1VacuumSimulator,
78+
)
7079

7180
__all__ = [
81+
"DEFAULT_APP_INIT",
82+
"DEFAULT_CLEAN_SUMMARY",
83+
"DEFAULT_CONSUMABLE",
84+
"DEFAULT_DND_TIMER",
85+
"DEFAULT_LAST_CLEAN_RECORD",
86+
"DEFAULT_NETWORK_INFO",
87+
"DEFAULT_STATUS",
7288
"FakeChannel",
7389
"FakeRoborockCloud",
7490
"FakeUserState",

roborock/testing/v1_simulator.py

Lines changed: 67 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,57 @@ def _serialize_dataclass(obj: Any) -> dict[str, Any]:
113113
new_feature_info_2=8192,
114114
)
115115

116+
DEFAULT_NETWORK_INFO = NetworkInfo(
117+
ip="1.1.1.1",
118+
ssid="test_wifi",
119+
mac="aa:bb:cc:dd:ee:ff",
120+
bssid="aa:bb:cc:dd:ee:ff",
121+
rssi=-50,
122+
)
123+
124+
DEFAULT_CONSUMABLE = Consumable(
125+
main_brush_work_time=74382,
126+
side_brush_work_time=74383,
127+
filter_work_time=74384,
128+
filter_element_work_time=0,
129+
sensor_dirty_time=74385,
130+
strainer_work_times=65,
131+
dust_collection_work_times=25,
132+
cleaning_brush_work_times=66,
133+
)
134+
135+
DEFAULT_DND_TIMER = DnDTimer(
136+
start_hour=22,
137+
start_minute=0,
138+
end_hour=7,
139+
end_minute=0,
140+
enabled=1,
141+
)
142+
143+
DEFAULT_CLEAN_SUMMARY = CleanSummary(
144+
clean_time=74382,
145+
clean_area=1159182500,
146+
clean_count=31,
147+
dust_collection_count=25,
148+
records=[1672543330, 1672458041],
149+
)
150+
151+
DEFAULT_LAST_CLEAN_RECORD = CleanRecord(
152+
begin=1672543330,
153+
end=1672544638,
154+
duration=1176,
155+
area=20965000,
156+
error=0,
157+
complete=1,
158+
start_type=RoborockStartType.app,
159+
clean_type=RoborockCleanType.select_zone,
160+
finish_reason=RoborockFinishReason.finished_cleaning_4,
161+
dust_collection_status=1,
162+
avoid_count=19,
163+
wash_count=2,
164+
map_flag=0,
165+
)
166+
116167

117168
class V1VacuumSimulator(RoborockDeviceSimulator):
118169
"""Firmware simulator for a V1/L01 vacuum device.
@@ -129,84 +180,29 @@ class V1VacuumSimulator(RoborockDeviceSimulator):
129180
def __init__(
130181
self,
131182
duid: str = "fake_duid",
132-
battery: int = 100,
133-
state: RoborockStateCode | int = RoborockStateCode.charging,
134-
fan_power: int = 102, # balanced
135-
dnd_enabled: int = 0,
136-
mop_mode: int = 300,
137-
water_box_mode: int = 200,
183+
status: StatusV2 | None = None,
184+
app_init: AppInitStatus | None = None,
185+
network_info: NetworkInfo | None = None,
186+
consumables: Consumable | None = None,
187+
dnd_timer: DnDTimer | None = None,
188+
clean_summary: CleanSummary | None = None,
189+
last_clean_record: CleanRecord | None = None,
138190
custom_handlers: dict[str, Callable[[list[Any]], Any]] | None = None,
139191
device_info: HomeDataDevice | None = None,
140192
product: HomeDataProduct | None = None,
141-
dss: int = 169,
142-
dock_type: RoborockDockTypeCode | int = 3,
143193
):
144194
super().__init__(duid=duid, device_info=device_info, product=product)
145-
self.status = replace(DEFAULT_STATUS)
146-
self.app_init = replace(DEFAULT_APP_INIT)
147-
self.app_init.local_info = replace(DEFAULT_APP_INIT.local_info)
148-
149-
self.status.battery = battery
150-
self.status.state = RoborockStateCode(state)
151-
self.status.fan_power = fan_power
152-
self.status.dnd_enabled = dnd_enabled
153-
self.status.mop_mode = mop_mode
154-
self.status.water_box_mode = water_box_mode
155-
self.status.dss = dss
156-
self.status.dock_type = RoborockDockTypeCode(dock_type)
195+
self.status = status or replace(DEFAULT_STATUS)
196+
self.app_init = app_init or replace(DEFAULT_APP_INIT)
197+
if app_init is None:
198+
self.app_init.local_info = replace(DEFAULT_APP_INIT.local_info)
199+
self.network_info = network_info or replace(DEFAULT_NETWORK_INFO)
200+
self.consumables = consumables or replace(DEFAULT_CONSUMABLE)
201+
self.dnd_timer = dnd_timer or replace(DEFAULT_DND_TIMER)
202+
self.clean_summary = clean_summary or replace(DEFAULT_CLEAN_SUMMARY)
203+
self.last_clean_record = last_clean_record or replace(DEFAULT_LAST_CLEAN_RECORD)
157204
self.custom_handlers = custom_handlers or {}
158205

159-
self.network_info = NetworkInfo(
160-
ip="1.1.1.1",
161-
ssid="test_wifi",
162-
mac="aa:bb:cc:dd:ee:ff",
163-
bssid="aa:bb:cc:dd:ee:ff",
164-
rssi=-50,
165-
)
166-
167-
self.consumables = Consumable(
168-
main_brush_work_time=74382,
169-
side_brush_work_time=74383,
170-
filter_work_time=74384,
171-
filter_element_work_time=0,
172-
sensor_dirty_time=74385,
173-
strainer_work_times=65,
174-
dust_collection_work_times=25,
175-
cleaning_brush_work_times=66,
176-
)
177-
178-
self.dnd_timer = DnDTimer(
179-
start_hour=22,
180-
start_minute=0,
181-
end_hour=7,
182-
end_minute=0,
183-
enabled=1,
184-
)
185-
186-
self.clean_summary = CleanSummary(
187-
clean_time=74382,
188-
clean_area=1159182500,
189-
clean_count=31,
190-
dust_collection_count=25,
191-
records=[1672543330, 1672458041],
192-
)
193-
194-
self.last_clean_record = CleanRecord(
195-
begin=1672543330,
196-
end=1672544638,
197-
duration=1176,
198-
area=20965000,
199-
error=0,
200-
complete=1,
201-
start_type=RoborockStartType.app,
202-
clean_type=RoborockCleanType.select_zone,
203-
finish_reason=RoborockFinishReason.finished_cleaning_4,
204-
dust_collection_status=1,
205-
avoid_count=19,
206-
wash_count=2,
207-
map_flag=0,
208-
)
209-
210206
# Set up default handlers dictionary
211207
self.default_handlers: dict[str, Callable[[Any], Any]] = {
212208
"get_status": lambda params: [self.get_status_dict()],

tests/testing/test_cloud.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
from dataclasses import replace
2+
13
import pytest
24

35
from roborock.data import HomeDataDevice, HomeDataProduct, RoborockCategory, UserData
46
from roborock.data.v1 import RoborockStateCode
57
from roborock.devices.cache import InMemoryCache
68
from roborock.devices.device_manager import UserParams, create_device_manager
79
from roborock.exceptions import RoborockException
8-
from roborock.testing import FakeRoborockCloud, V1VacuumSimulator
10+
from roborock.testing import DEFAULT_STATUS, FakeRoborockCloud, V1VacuumSimulator
911
from roborock.web_api import RoborockApiClient
1012
from tests import mock_data
1113

@@ -15,7 +17,10 @@
1517
async def test_fake_roborock_cloud():
1618
"""Verify that FakeRoborockCloud can discover devices via fake HTTP requests and connect them."""
1719
cloud = FakeRoborockCloud()
18-
fake_device = V1VacuumSimulator(duid="living_room_s7", battery=99, state=RoborockStateCode.charging)
20+
fake_device = V1VacuumSimulator(
21+
duid="living_room_s7",
22+
status=replace(DEFAULT_STATUS, battery=99, state=RoborockStateCode.charging),
23+
)
1924
cloud.add_device(fake_device)
2025

2126
with cloud.patch_device_manager():
@@ -81,7 +86,10 @@ async def test_cloud_dynamic_device_addition():
8186
cloud = FakeRoborockCloud()
8287

8388
with cloud.patch_device_manager():
84-
fake_device = V1VacuumSimulator(duid="dynamic_s7", battery=42)
89+
fake_device = V1VacuumSimulator(
90+
duid="dynamic_s7",
91+
status=replace(DEFAULT_STATUS, battery=42),
92+
)
8593
cloud.add_device(fake_device)
8694

8795
manager = await create_device_manager(

tests/testing/test_v1_simulator.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from dataclasses import replace
2+
13
import pytest
24

35
from roborock.data import UserData
@@ -7,7 +9,7 @@
79
from roborock.devices.device_manager import UserParams, create_device_manager
810
from roborock.devices.traits.v1.consumeable import ConsumableAttribute
911
from roborock.exceptions import RoborockException
10-
from roborock.testing import FakeRoborockCloud, V1VacuumSimulator
12+
from roborock.testing import DEFAULT_STATUS, FakeRoborockCloud, V1VacuumSimulator
1113
from tests import mock_data
1214

1315
USER_DATA = UserData.from_dict(mock_data.USER_DATA)
@@ -71,7 +73,7 @@ async def test_trait_dnd_refresh():
7173
async def test_trait_fan_speed_change():
7274
"""Verify that sending set_custom_mode updates the simulator fan speed and the trait reflects it."""
7375
cloud = FakeRoborockCloud()
74-
fake_device = V1VacuumSimulator(duid="s7_fan", fan_power=102)
76+
fake_device = V1VacuumSimulator(duid="s7_fan", status=replace(DEFAULT_STATUS, fan_power=102))
7577
device = await _create_connected_device(cloud, fake_device)
7678

7779
await device.v1_properties.status.refresh()
@@ -100,7 +102,7 @@ async def test_trait_clean_summary_refresh():
100102
async def test_trait_multiple_state_transitions():
101103
"""Verify a sequence of state transitions through trait commands."""
102104
cloud = FakeRoborockCloud()
103-
fake_device = V1VacuumSimulator(duid="s7_transitions", state=RoborockStateCode.charging)
105+
fake_device = V1VacuumSimulator(duid="s7_transitions")
104106
device = await _create_connected_device(cloud, fake_device)
105107

106108
# Start cleaning
@@ -123,7 +125,10 @@ async def test_trait_multiple_state_transitions():
123125
async def test_trait_push_update_propagation():
124126
"""Verify that unsolicited push updates propagate to client traits without refresh."""
125127
cloud = FakeRoborockCloud()
126-
fake_device = V1VacuumSimulator(duid="s7_push", battery=99, state=RoborockStateCode.charging)
128+
fake_device = V1VacuumSimulator(
129+
duid="s7_push",
130+
status=replace(DEFAULT_STATUS, battery=99, state=RoborockStateCode.charging),
131+
)
127132
device = await _create_connected_device(cloud, fake_device)
128133

129134
await device.v1_properties.status.refresh()
@@ -160,7 +165,15 @@ def custom_get_status(params):
160165

161166
async def test_trait_properties_and_dss_config():
162167
"""Verify that properties, dss config, and dock_type config are correctly exposed on the simulator."""
163-
fake_device = V1VacuumSimulator(duid="s7_properties", state=RoborockStateCode.cleaning, dss=42, dock_type=5)
168+
fake_device = V1VacuumSimulator(
169+
duid="s7_properties",
170+
status=replace(
171+
DEFAULT_STATUS,
172+
state=RoborockStateCode.cleaning,
173+
dss=42,
174+
dock_type=RoborockDockTypeCode(5),
175+
),
176+
)
164177
assert fake_device.in_cleaning == RoborockInCleaning.global_clean_not_complete
165178
assert fake_device.in_returning == 0
166179
assert fake_device.charge_status == RoborockChargeStatus.charge_waiting

0 commit comments

Comments
 (0)