@@ -283,16 +283,25 @@ async def async_refresh_login(self, exc: Exception | None = None) -> None:
283283 raise ConfigEntryAuthFailed (
284284 f"Login failed for Mammotion account: { exc .reason } "
285285 ) from exc
286- if (
287- isinstance (exc , SessionExpiredError )
288- and self .manager .token_manager is not None
289- ):
290- await self .manager .token_manager .refresh_aliyun_credentials ()
291- elif isinstance (exc , AuthError ) and self .manager .token_manager is not None :
292- await self .manager .token_manager .refresh_mqtt_credentials ()
293- else :
294- await self .manager .refresh_login (self .account )
295- self .store_cloud_credentials ()
286+ try :
287+ if (
288+ isinstance (exc , SessionExpiredError )
289+ and self .manager .token_manager is not None
290+ ):
291+ await self .manager .token_manager .refresh_aliyun_credentials ()
292+ elif isinstance (exc , AuthError ) and self .manager .token_manager is not None :
293+ await self .manager .token_manager .refresh_mqtt_credentials ()
294+ else :
295+ await self .manager .refresh_login (self .account )
296+ self .store_cloud_credentials ()
297+ except ReLoginRequiredError :
298+ try :
299+ await self .manager .refresh_login (self .account )
300+ self .store_cloud_credentials ()
301+ except LoginFailedError as err :
302+ raise ConfigEntryAuthFailed (
303+ f"Login failed for Mammotion account: { err .reason } "
304+ ) from err
296305
297306 async def async_send_and_wait (
298307 self ,
@@ -982,13 +991,7 @@ async def async_shutdown(self) -> None:
982991 await super ().async_shutdown ()
983992
984993 async def _on_state_changed (self , snapshot : Any ) -> None :
985- """Push updated device data to HA without triggering a full refresh.
986-
987- Triggering async_request_refresh() here caused a feedback loop: every
988- incoming report mutates state, which would trigger a refresh, which
989- sends another get_report_cfg, producing more reports. Pushing the
990- data update directly keeps entities in sync without re-issuing commands.
991- """
994+ """Push updated device data to HA."""
992995 device = self .manager .get_device_by_name (self .device_name )
993996 if device is not None :
994997 self .async_set_updated_data (self .get_coordinator_data (device ))
@@ -1535,26 +1538,51 @@ async def _async_update_data(self) -> MowingDevice:
15351538 if data := await super ()._async_update_data ():
15361539 return data
15371540 device = self .manager .get_device_by_name (self .device_name )
1538- try :
1541+ if device .report_data .dev .sys_status in (
1542+ WorkMode .MODE_WORKING ,
1543+ WorkMode .MODE_RETURNING ,
1544+ WorkMode .MODE_LOCK ,
1545+ ):
1546+ try :
1547+ await self .async_send_and_wait (
1548+ "read_write_device" , "bidire_comm_cmd" , rw_id = 5 , rw = 1 , context = 2
1549+ )
1550+ await self .async_send_and_wait (
1551+ "read_write_device" , "bidire_comm_cmd" , rw_id = 5 , rw = 1 , context = 3
1552+ )
1553+ if not device .errors .error_codes :
1554+ http = self .manager .mammotion_http
1555+ if http is not None :
1556+ device .errors .error_codes = await http .get_all_error_codes ()
1557+ except DeviceOfflineException :
1558+ return device
1559+
1560+ return device
1561+
1562+ async def _on_sys_status_changed (self , sys_status : WorkMode ) -> None :
1563+ """Handle sys status changed."""
1564+ if sys_status in (
1565+ WorkMode .MODE_WORKING ,
1566+ WorkMode .MODE_RETURNING ,
1567+ WorkMode .MODE_LOCK ,
1568+ WorkMode .MODE_PAUSE ,
1569+ ):
15391570 await self .async_send_and_wait (
15401571 "read_write_device" , "bidire_comm_cmd" , rw_id = 5 , rw = 1 , context = 2
15411572 )
15421573 await self .async_send_and_wait (
15431574 "read_write_device" , "bidire_comm_cmd" , rw_id = 5 , rw = 1 , context = 3
15441575 )
1545- if not device .errors .error_codes :
1546- http = self .manager .mammotion_http
1547- if http is not None :
1548- device .errors .error_codes = await http .get_all_error_codes ()
1549- except DeviceOfflineException :
1550- return device
1551-
1552- return device
15531576
15541577 async def _async_setup (self ) -> None :
15551578 """Setup device version coordinator."""
15561579 await super ()._async_setup ()
15571580 device = self .manager .get_device_by_name (self .device_name )
1581+ if handle := self .manager .mower (self .device_name ):
1582+ handle .watch_field (
1583+ lambda s : s .raw .report_data .dev .sys_status ,
1584+ self ._on_sys_status_changed ,
1585+ )
15581586
15591587 try :
15601588 await self .async_send_and_wait (
0 commit comments