Skip to content

Commit 91d3492

Browse files
committed
Add Q10 VacuumTrait test scripts
- test_q10_simple.py: Interactive test script with detailed debug info - test_q10_vacuum.py: Basic test script for Q10 vacuum commands These scripts test the VacuumTrait functionality added in PR #754
1 parent 9719cac commit 91d3492

File tree

2 files changed

+283
-0
lines changed

2 files changed

+283
-0
lines changed

test_q10_simple.py

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
#!/usr/bin/env python3
2+
"""Simple test script for Q10 VacuumTrait functionality."""
3+
4+
import asyncio
5+
import pathlib
6+
7+
from roborock.devices.device_manager import UserParams, create_device_manager
8+
from roborock.devices.file_cache import FileCache, load_value, store_value
9+
from roborock.web_api import RoborockApiClient
10+
11+
# Cache paths
12+
USER_PARAMS_PATH = pathlib.Path.home() / ".cache" / "roborock-user-params.pkl"
13+
CACHE_PATH = pathlib.Path.home() / ".cache" / "roborock-cache-data.pkl"
14+
15+
16+
async def login_flow() -> UserParams:
17+
"""Perform the login flow to obtain UserData from the web API."""
18+
username = input("📧 Email: ")
19+
web_api = RoborockApiClient(username=username)
20+
print("📨 Requesting login code sent to email...")
21+
await web_api.request_code()
22+
code = input("🔑 Code: ")
23+
user_data = await web_api.code_login(code)
24+
base_url = await web_api.base_url
25+
return UserParams(
26+
username=username,
27+
user_data=user_data,
28+
base_url=base_url,
29+
)
30+
31+
32+
async def get_or_create_session() -> UserParams:
33+
"""Initialize the session by logging in if necessary."""
34+
user_params = await load_value(USER_PARAMS_PATH)
35+
if user_params is None:
36+
print("No cached login data found, please login.")
37+
user_params = await login_flow()
38+
print("✅ Login successful, caching login data...")
39+
await store_value(USER_PARAMS_PATH, user_params)
40+
return user_params
41+
42+
43+
async def main():
44+
"""Test Q10 vacuum commands."""
45+
print("🔄 Initializing...")
46+
47+
try:
48+
user_params = await get_or_create_session()
49+
cache = FileCache(CACHE_PATH)
50+
51+
print("🔄 Creating device manager...")
52+
device_manager = await create_device_manager(user_params, cache=cache)
53+
54+
print("🔄 Getting devices...")
55+
devices = await device_manager.get_devices()
56+
57+
print(f"\n📱 Found {len(devices)} device(s)")
58+
59+
# List all devices with their properties
60+
for idx, device in enumerate(devices, 1):
61+
print(f"\n Device {idx}: {device.name}")
62+
print(f" Product: {device.product.name} ({device.product.model})")
63+
print(f" Has v1_properties: {device.v1_properties is not None}")
64+
print(f" Has b01_q10_properties: {device.b01_q10_properties is not None}")
65+
66+
# Check what attributes the device has
67+
attrs = [attr for attr in dir(device) if not attr.startswith('_') and 'properties' in attr.lower()]
68+
print(f" Available property APIs: {attrs}")
69+
70+
# Select device
71+
if len(devices) == 1:
72+
device = devices[0]
73+
print(f"\n✅ Using device: {device.name}")
74+
else:
75+
device_idx = int(input("\nSelect device number: ")) - 1
76+
device = devices[device_idx]
77+
print(f"\n✅ Selected device: {device.name}")
78+
79+
# Check if it's a Q10 device
80+
if device.b01_q10_properties is None:
81+
print("\n❌ This device doesn't have Q10 properties")
82+
print(f" Product: {device.product.name} ({device.product.model})")
83+
print("\n💡 Available properties:")
84+
if device.v1_properties:
85+
print(" - v1_properties (V1 API)")
86+
if hasattr(device, 'b01_q7_properties') and device.b01_q7_properties:
87+
print(" - b01_q7_properties (Q7 API)")
88+
await cache.flush()
89+
return
90+
91+
print(f"\n✅ Device has Q10 properties!")
92+
93+
# Check if vacuum trait exists
94+
if not hasattr(device.b01_q10_properties, 'vacuum'):
95+
print("\n❌ Q10 properties don't have 'vacuum' trait")
96+
print(f" Available traits: {[attr for attr in dir(device.b01_q10_properties) if not attr.startswith('_')]}")
97+
await cache.flush()
98+
return
99+
100+
vacuum = device.b01_q10_properties.vacuum
101+
print(f"✅ Vacuum trait found: {vacuum}")
102+
103+
print("\n🤖 Q10 Vacuum Trait Test Menu")
104+
print("=" * 50)
105+
print("1. Start cleaning")
106+
print("2. Pause cleaning")
107+
print("3. Resume cleaning")
108+
print("4. Stop cleaning")
109+
print("5. Return to dock")
110+
print("0. Exit")
111+
print("=" * 50)
112+
113+
while True:
114+
try:
115+
choice = input("\nEnter your choice (0-5): ").strip()
116+
117+
if choice == "0":
118+
print("👋 Exiting...")
119+
break
120+
elif choice == "1":
121+
print("▶️ Starting cleaning...")
122+
await vacuum.start_clean()
123+
print("✅ Start cleaning command sent!")
124+
elif choice == "2":
125+
print("⏸️ Pausing cleaning...")
126+
await vacuum.pause_clean()
127+
print("✅ Pause command sent!")
128+
elif choice == "3":
129+
print("▶️ Resuming cleaning...")
130+
await vacuum.resume_clean()
131+
print("✅ Resume command sent!")
132+
elif choice == "4":
133+
print("⏹️ Stopping cleaning...")
134+
await vacuum.stop_clean()
135+
print("✅ Stop command sent!")
136+
elif choice == "5":
137+
print("🏠 Returning to dock...")
138+
await vacuum.return_to_dock()
139+
print("✅ Return to dock command sent!")
140+
else:
141+
print("❌ Invalid choice, please try again")
142+
except KeyboardInterrupt:
143+
print("\n👋 Exiting...")
144+
break
145+
except Exception as e:
146+
print(f"❌ Error: {e}")
147+
import traceback
148+
traceback.print_exc()
149+
150+
await cache.flush()
151+
152+
except Exception as e:
153+
print(f"\n❌ Fatal error: {e}")
154+
import traceback
155+
traceback.print_exc()
156+
157+
158+
if __name__ == "__main__":
159+
asyncio.run(main())

test_q10_vacuum.py

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#!/usr/bin/env python3
2+
"""Test script for Q10 VacuumTrait functionality."""
3+
4+
import asyncio
5+
import pathlib
6+
7+
from roborock.devices.device_manager import UserParams, create_device_manager
8+
from roborock.devices.file_cache import FileCache, load_value, store_value
9+
from roborock.web_api import RoborockApiClient
10+
11+
# Cache paths
12+
USER_PARAMS_PATH = pathlib.Path.home() / ".cache" / "roborock-user-params.pkl"
13+
CACHE_PATH = pathlib.Path.home() / ".cache" / "roborock-cache-data.pkl"
14+
15+
16+
async def login_flow() -> UserParams:
17+
"""Perform the login flow to obtain UserData from the web API."""
18+
username = input("📧 Email: ")
19+
web_api = RoborockApiClient(username=username)
20+
print("📨 Requesting login code sent to email...")
21+
await web_api.request_code()
22+
code = input("🔑 Code: ")
23+
user_data = await web_api.code_login(code)
24+
base_url = await web_api.base_url
25+
return UserParams(
26+
username=username,
27+
user_data=user_data,
28+
base_url=base_url,
29+
)
30+
31+
32+
async def get_or_create_session() -> UserParams:
33+
"""Initialize the session by logging in if necessary."""
34+
user_params = await load_value(USER_PARAMS_PATH)
35+
if user_params is None:
36+
print("No cached login data found, please login.")
37+
user_params = await login_flow()
38+
print("✅ Login successful, caching login data...")
39+
await store_value(USER_PARAMS_PATH, user_params)
40+
return user_params
41+
42+
43+
async def main():
44+
"""Test Q10 vacuum commands."""
45+
user_params = await get_or_create_session()
46+
cache = FileCache(CACHE_PATH)
47+
48+
# Create device manager and get devices
49+
device_manager = await create_device_manager(user_params, cache=cache)
50+
devices = await device_manager.get_devices()
51+
52+
print(f"\n📱 Found {len(devices)} device(s)")
53+
54+
# List all devices
55+
for idx, device in enumerate(devices, 1):
56+
print(f" {idx}. {device.name} ({device.model})")
57+
58+
# Select device
59+
if len(devices) == 1:
60+
device = devices[0]
61+
print(f"\n✅ Using device: {device.name}")
62+
else:
63+
device_idx = int(input("\nSelect device number: ")) - 1
64+
device = devices[device_idx]
65+
66+
# Check if it's a Q10 device with the vacuum trait
67+
if not hasattr(device, 'b01_q10_properties') or device.b01_q10_properties is None:
68+
print("\n❌ This device doesn't support Q10 properties (not a Q10 device?)")
69+
print(f" Device type: {device.model}")
70+
return
71+
72+
vacuum = device.b01_q10_properties.vacuum
73+
74+
print("\n🤖 Q10 Vacuum Trait Test Menu")
75+
print("=" * 50)
76+
print("1. Start cleaning")
77+
print("2. Pause cleaning")
78+
print("3. Resume cleaning")
79+
print("4. Stop cleaning")
80+
print("5. Return to dock")
81+
print("0. Exit")
82+
print("=" * 50)
83+
84+
while True:
85+
try:
86+
choice = input("\nEnter your choice (0-5): ").strip()
87+
88+
if choice == "0":
89+
print("👋 Exiting...")
90+
break
91+
elif choice == "1":
92+
print("▶️ Starting cleaning...")
93+
await vacuum.start_clean()
94+
print("✅ Start cleaning command sent!")
95+
elif choice == "2":
96+
print("⏸️ Pausing cleaning...")
97+
await vacuum.pause_clean()
98+
print("✅ Pause command sent!")
99+
elif choice == "3":
100+
print("▶️ Resuming cleaning...")
101+
await vacuum.resume_clean()
102+
print("✅ Resume command sent!")
103+
elif choice == "4":
104+
print("⏹️ Stopping cleaning...")
105+
await vacuum.stop_clean()
106+
print("✅ Stop command sent!")
107+
elif choice == "5":
108+
print("🏠 Returning to dock...")
109+
await vacuum.return_to_dock()
110+
print("✅ Return to dock command sent!")
111+
else:
112+
print("❌ Invalid choice, please try again")
113+
except KeyboardInterrupt:
114+
print("\n👋 Exiting...")
115+
break
116+
except Exception as e:
117+
print(f"❌ Error: {e}")
118+
import traceback
119+
traceback.print_exc()
120+
121+
await cache.flush()
122+
123+
if __name__ == "__main__":
124+
asyncio.run(main())

0 commit comments

Comments
 (0)