diff --git a/custom_components/zcsmower/coordinator.py b/custom_components/zcsmower/coordinator.py index 206ac81..da64795 100644 --- a/custom_components/zcsmower/coordinator.py +++ b/custom_components/zcsmower/coordinator.py @@ -19,8 +19,14 @@ ATTR_MANUFACTURER, ATTR_MODEL, ATTR_SW_VERSION, + STATE_UNAVAILABLE, + STATE_UNKNOWN, ) from homeassistant.config_entries import ConfigEntry +from homeassistant.components.recorder import ( + get_instance, + history, +) from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.update_coordinator import ( DataUpdateCoordinator, @@ -74,6 +80,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, @@ -224,14 +231,52 @@ 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.""" + # 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, + entity_id: str, + 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. + 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, + ) + 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), + ) + 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..757547f 100644 --- a/custom_components/zcsmower/device_tracker.py +++ b/custom_components/zcsmower/device_tracker.py @@ -1,34 +1,24 @@ """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 ( SourceType, TrackerEntity, ) -from homeassistant.components.recorder import ( - get_instance, - history, -) from homeassistant.helpers.entity import ( Entity, EntityDescription, ) -import homeassistant.util.dt as dt_util from .const import ( DOMAIN, - LOCATION_HISTORY_DAYS_DEFAULT, ) from .coordinator import ZcsMowerDataUpdateCoordinator from .entity import ZcsMowerEntity @@ -93,37 +83,10 @@ 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._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), + await self.coordinator.init_location_history( 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() - ) @property def location_accuracy(self):