Skip to content

Commit

Permalink
Merge pull request #128 from ufozone/127-error-adding-entity-device_t…
Browse files Browse the repository at this point in the history
…racker

Move getting location history to coordinator
  • Loading branch information
ufozone authored May 4, 2024
2 parents 917d136 + ce0ebd7 commit d29666a
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 39 deletions.
47 changes: 46 additions & 1 deletion custom_components/zcsmower/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
39 changes: 1 addition & 38 deletions custom_components/zcsmower/device_tracker.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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):
Expand Down

0 comments on commit d29666a

Please sign in to comment.