From aa719b5c7e582217bf88e78723458f0d8e7fba75 Mon Sep 17 00:00:00 2001 From: ufozone Date: Sat, 4 May 2024 23:45:31 +0200 Subject: [PATCH 1/4] Move getting location history to coordinator --- custom_components/zcsmower/coordinator.py | 37 +++++++++++++++++++ custom_components/zcsmower/device_tracker.py | 38 +++----------------- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/custom_components/zcsmower/coordinator.py b/custom_components/zcsmower/coordinator.py index 206ac81..2db1ff7 100644 --- a/custom_components/zcsmower/coordinator.py +++ b/custom_components/zcsmower/coordinator.py @@ -19,8 +19,11 @@ ATTR_MANUFACTURER, ATTR_MODEL, ATTR_SW_VERSION, + STATE_UNAVAILABLE, + STATE_UNKNOWN, ) from homeassistant.config_entries import ConfigEntry +from homeassistant.components.recorder import history from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.update_coordinator import ( DataUpdateCoordinator, @@ -74,6 +77,7 @@ UPDATE_INTERVAL_WORKING_DEFAULT, UPDATE_INTERVAL_STANDBY_DEFAULT, UPDATE_INTERVAL_IDLING_DEFAULT, + LOCATION_HISTORY_DAYS_DEFAULT, LOCATION_HISTORY_ITEMS_DEFAULT, MANUFACTURER_DEFAULT, MANUFACTURER_MAP, @@ -232,6 +236,39 @@ def init_location_history( if self.data[imei][ATTR_LOCATION_HISTORY] is None: self.data[imei][ATTR_LOCATION_HISTORY] = [] + def get_location_history( + self, + entity_id: str, + imei: str, + ) -> None: + """Get location history for lawn mower.""" + # Getting history with history.get_last_state_changes can cause instability + # because it has to scan the table to find the last number_of_states states + # because the metadata_id_last_updated_ts index is in ascending order. + history_list = history.state_changes_during_period( + self.hass, + start_time=self._get_datetime_now() - timedelta(days=LOCATION_HISTORY_DAYS_DEFAULT), + entity_id=entity_id, + no_attributes=False, + include_start_time_state=True, + ) + self.init_location_history( + imei=imei, + ) + for state in history_list.get(entity_id, []): + if state.state not in (STATE_UNKNOWN, STATE_UNAVAILABLE, None): + latitude = state.attributes.get(ATTR_LATITUDE, None) + longitude = state.attributes.get(ATTR_LONGITUDE, None) + if latitude and longitude: + self.add_location_history( + imei=imei, + location=(latitude, longitude), + ) + # Always update HA states after getting location history. + #self.hass.async_create_task( + # self._async_update_listeners() + #) + def add_location_history( self, imei: str, diff --git a/custom_components/zcsmower/device_tracker.py b/custom_components/zcsmower/device_tracker.py index cb86872..b667d25 100644 --- a/custom_components/zcsmower/device_tracker.py +++ b/custom_components/zcsmower/device_tracker.py @@ -16,10 +16,7 @@ SourceType, TrackerEntity, ) -from homeassistant.components.recorder import ( - get_instance, - history, -) +from homeassistant.components.recorder import get_instance from homeassistant.helpers.entity import ( Entity, EntityDescription, @@ -28,7 +25,6 @@ from .const import ( DOMAIN, - LOCATION_HISTORY_DAYS_DEFAULT, ) from .coordinator import ZcsMowerDataUpdateCoordinator from .entity import ZcsMowerEntity @@ -94,35 +90,9 @@ async def async_added_to_hass(self) -> None: # Load Recorder after loading entity await get_instance(self.hass).async_add_executor_job( - self._get_location_history, - ) - - def _get_location_history(self) -> None: - # Getting history with history.get_last_state_changes can cause instability - # because it has to scan the table to find the last number_of_states states - # because the metadata_id_last_updated_ts index is in ascending order. - history_list = history.state_changes_during_period( - self.hass, - start_time=dt_util.now() - timedelta(days=LOCATION_HISTORY_DAYS_DEFAULT), - entity_id=self.entity_id, - no_attributes=False, - include_start_time_state=True, - ) - self.coordinator.init_location_history( - imei=self._imei, - ) - for state in history_list.get(self.entity_id, []): - if state.state not in (STATE_UNKNOWN, STATE_UNAVAILABLE, None): - latitude = state.attributes.get(ATTR_LATITUDE, None) - longitude = state.attributes.get(ATTR_LONGITUDE, None) - if latitude and longitude: - self.coordinator.add_location_history( - imei=self._imei, - location=(latitude, longitude), - ) - # Always update HA states after getting location history. - self.hass.async_create_task( - self.coordinator._async_update_listeners() + self.coordinator.get_location_history, + self.entity_id, + self._imei, ) @property From f435228740b3bda227ff9ab182463d30e05b5666 Mon Sep 17 00:00:00 2001 From: ufozone Date: Sat, 4 May 2024 23:49:12 +0200 Subject: [PATCH 2/4] Fix RUFF warnings #128 --- custom_components/zcsmower/device_tracker.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/custom_components/zcsmower/device_tracker.py b/custom_components/zcsmower/device_tracker.py index b667d25..2d1f1d1 100644 --- a/custom_components/zcsmower/device_tracker.py +++ b/custom_components/zcsmower/device_tracker.py @@ -1,15 +1,11 @@ """ZCS Lawn Mower Robot sensor platform.""" from __future__ import annotations -from datetime import timedelta - from homeassistant.core import HomeAssistant from homeassistant.const import ( ATTR_LOCATION, ATTR_LATITUDE, ATTR_LONGITUDE, - STATE_UNAVAILABLE, - STATE_UNKNOWN, ) from homeassistant.config_entries import ConfigEntry from homeassistant.components.device_tracker import ( @@ -21,7 +17,6 @@ Entity, EntityDescription, ) -import homeassistant.util.dt as dt_util from .const import ( DOMAIN, From 3b6c73d4e9cb6c159231a4b3693fc51121c76c9d Mon Sep 17 00:00:00 2001 From: ufozone Date: Sun, 5 May 2024 00:08:29 +0200 Subject: [PATCH 3/4] Improve getting location history to coordinator --- custom_components/zcsmower/coordinator.py | 30 +++++++++++++------- custom_components/zcsmower/device_tracker.py | 7 ++--- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/custom_components/zcsmower/coordinator.py b/custom_components/zcsmower/coordinator.py index 2db1ff7..da64795 100644 --- a/custom_components/zcsmower/coordinator.py +++ b/custom_components/zcsmower/coordinator.py @@ -23,7 +23,10 @@ STATE_UNKNOWN, ) from homeassistant.config_entries import ConfigEntry -from homeassistant.components.recorder import history +from homeassistant.components.recorder import ( + get_instance, + history, +) from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.update_coordinator import ( DataUpdateCoordinator, @@ -228,13 +231,22 @@ def get_mower_attributes( """Get attributes of an given lawn mower.""" return self.data.get(imei, None) - def init_location_history( + async def init_location_history( self, + entity_id: str, imei: str, ) -> None: """Initiate location history for lawn mower.""" - if self.data[imei][ATTR_LOCATION_HISTORY] is None: - self.data[imei][ATTR_LOCATION_HISTORY] = [] + # Load Recorder after loading entity + await get_instance(self.hass).async_add_executor_job( + self.get_location_history, + entity_id, + imei, + ) + # Always update HA states after getting location history. + self.hass.async_create_task( + self._async_update_listeners() + ) def get_location_history( self, @@ -242,6 +254,9 @@ def get_location_history( imei: str, ) -> None: """Get location history for lawn mower.""" + if self.data[imei][ATTR_LOCATION_HISTORY] is None: + self.data[imei][ATTR_LOCATION_HISTORY] = [] + # Getting history with history.get_last_state_changes can cause instability # because it has to scan the table to find the last number_of_states states # because the metadata_id_last_updated_ts index is in ascending order. @@ -252,9 +267,6 @@ def get_location_history( no_attributes=False, include_start_time_state=True, ) - self.init_location_history( - imei=imei, - ) for state in history_list.get(entity_id, []): if state.state not in (STATE_UNKNOWN, STATE_UNAVAILABLE, None): latitude = state.attributes.get(ATTR_LATITUDE, None) @@ -264,10 +276,6 @@ def get_location_history( imei=imei, location=(latitude, longitude), ) - # Always update HA states after getting location history. - #self.hass.async_create_task( - # self._async_update_listeners() - #) def add_location_history( self, diff --git a/custom_components/zcsmower/device_tracker.py b/custom_components/zcsmower/device_tracker.py index 2d1f1d1..12f4732 100644 --- a/custom_components/zcsmower/device_tracker.py +++ b/custom_components/zcsmower/device_tracker.py @@ -84,10 +84,9 @@ async def async_added_to_hass(self) -> None: await super().async_added_to_hass() # Load Recorder after loading entity - await get_instance(self.hass).async_add_executor_job( - self.coordinator.get_location_history, - self.entity_id, - self._imei, + await self.coordinator.init_location_history( + entity_id=self.entity_id, + imei=self._imei, ) @property From ce0ebd77dbdf93c2a57472dec4fe47ade383c14d Mon Sep 17 00:00:00 2001 From: ufozone Date: Sun, 5 May 2024 00:11:11 +0200 Subject: [PATCH 4/4] Fix RUFF warnings #128 --- custom_components/zcsmower/device_tracker.py | 1 - 1 file changed, 1 deletion(-) diff --git a/custom_components/zcsmower/device_tracker.py b/custom_components/zcsmower/device_tracker.py index 12f4732..757547f 100644 --- a/custom_components/zcsmower/device_tracker.py +++ b/custom_components/zcsmower/device_tracker.py @@ -12,7 +12,6 @@ SourceType, TrackerEntity, ) -from homeassistant.components.recorder import get_instance from homeassistant.helpers.entity import ( Entity, EntityDescription,