|
55 | 55 | ) |
56 | 56 | from pymammotion.http.model.http import ErrorInfo, Response |
57 | 57 | from pymammotion.mammotion.commands.mammotion_command import MammotionCommand |
58 | | -from pymammotion.proto import SystemUpdateBufMsg |
| 58 | +from pymammotion.proto import MulSex, SystemUpdateBufMsg |
59 | 59 | from pymammotion.state.device_state import DeviceSnapshot |
60 | 60 | from pymammotion.transport.base import ( |
61 | 61 | AuthError, |
|
92 | 92 |
|
93 | 93 | MAINTENANCE_INTERVAL = timedelta(minutes=60) |
94 | 94 | DEFAULT_INTERVAL = timedelta(minutes=30) |
95 | | -REPORT_INTERVAL = timedelta(minutes=30) |
| 95 | +REPORT_INTERVAL = timedelta(minutes=5) |
96 | 96 | DEVICE_VERSION_INTERVAL = timedelta(weeks=1) |
97 | 97 | MAP_INTERVAL = timedelta(minutes=60) |
98 | 98 | RTK_INTERVAL = timedelta(hours=5) |
@@ -232,6 +232,22 @@ def get_stream_data(self) -> Response[StreamSubscriptionResponse]: |
232 | 232 | """Return stream data.""" |
233 | 233 | return self._stream_data |
234 | 234 |
|
| 235 | + async def join_webrtc_channel(self) -> None: |
| 236 | + """Start stream command.""" |
| 237 | + handle = self.manager.mower(self.device_name) |
| 238 | + if handle is None: |
| 239 | + return |
| 240 | + command = self.commands.device_agora_join_channel_with_position(enter_state=1) |
| 241 | + await self.async_send_cloud_command(handle.iot_id, command) |
| 242 | + |
| 243 | + async def leave_webrtc_channel(self) -> None: |
| 244 | + """End stream command.""" |
| 245 | + handle = self.manager.mower(self.device_name) |
| 246 | + if handle is None: |
| 247 | + return |
| 248 | + command = self.commands.device_agora_join_channel_with_position(enter_state=0) |
| 249 | + await self.async_send_cloud_command(handle.iot_id, command) |
| 250 | + |
235 | 251 | async def set_scheduled_updates(self, enabled: bool) -> None: |
236 | 252 | """Enable or disable scheduled polling updates for this device.""" |
237 | 253 | device = self.manager.get_device_by_name(self.device_name) |
@@ -493,6 +509,22 @@ async def async_sync_schedule(self) -> None: |
493 | 509 | if self.update_failures < 5: |
494 | 510 | await self.async_sync_schedule() |
495 | 511 |
|
| 512 | + async def async_fetch_audio_config(self) -> None: |
| 513 | + """Request current audio config (volume, language, gender) from device.""" |
| 514 | + await self.async_send_command("get_car_audio_cfg") |
| 515 | + |
| 516 | + async def async_set_voice_volume(self, volume: float) -> None: |
| 517 | + """Set robot voice volume (0–100).""" |
| 518 | + await self.async_send_command("set_car_volume", volume=int(volume)) |
| 519 | + |
| 520 | + async def async_set_voice_on_off(self, on: bool) -> None: |
| 521 | + """Turn robot voice on (restores 50%) or off (sets volume to 0).""" |
| 522 | + await self.async_send_command("set_car_volume", volume=50 if on else 0) |
| 523 | + |
| 524 | + async def async_set_voice_gender(self, sex: str) -> None: |
| 525 | + """Set robot voice gender (MAN or WOMAN).""" |
| 526 | + await self.async_send_command("set_car_volume_sex", sex=MulSex[sex]) |
| 527 | + |
496 | 528 | async def async_start_stop_blades( |
497 | 529 | self, start_stop: bool, blade_height: int = 60 |
498 | 530 | ) -> None: |
@@ -1191,6 +1223,11 @@ async def _async_update_data(self) -> MowingDevice: |
1191 | 1223 | ) |
1192 | 1224 | ) |
1193 | 1225 |
|
| 1226 | + if handle := self.manager.mower(self.device_name): |
| 1227 | + if ble := handle.get_transport(TransportType.BLE): |
| 1228 | + if ble.is_usable and not ble.is_connected: |
| 1229 | + await ble.connect() |
| 1230 | + |
1194 | 1231 | return device |
1195 | 1232 |
|
1196 | 1233 | async def _async_update_notification(self, res: tuple[str, Any | None]) -> None: |
|
0 commit comments