#Can you share your code?
1 messages · Page 1 of 1 (latest)
Coordinator: (it just polls every 30 seconds starting at a specified time until it gets some data from the api or it reaches the specified end time)
class SmartTagCoordinator(DataUpdateCoordinator[Optional[ActivityItem]]):
def __init__(self, hass: HomeAssistant, api_client: SmartTagApiClient, am_timing: PollTimingData):
super().__init__(hass, _LOGGER, name = f"SMART Tag Coordinator")
self.api_client = api_client
self.am_timing = am_timing
self.hass = hass
self.unsub_start_am = async_track_time_change(self.hass, self.on_am_start_embark, self.am_timing.embark_start.hour, self.am_timing.embark_start.minute, self.am_timing.embark_start.second)
self.unsub_interval_poll = None
async def _async_update_data(self) -> ActivityItem | None:
try:
async with async_timeout.timeout(10):
return await self.api_client.get_last_activity()
except AuthError as err:
raise ConfigEntryAuthFailed from err
@callback
async def on_am_start_embark(self, t: datetime):
# Weekends
time = datetime.now()
if time.weekday() == 5 or time.weekday() == 6:
return
self.unsub_interval_poll = async_track_time_interval(self.hass, self.on_interval, timedelta(seconds = 30))
await self.on_interval(t)
def unsub_interval(self):
if self.unsub_interval_poll is not None:
self.unsub_interval_poll()
self.unsub_interval_poll = None
async def on_interval(self, _t):
await self.async_refresh()
t = datetime.now()
if self.last_update_success:
if self.data is not None:
# Stop polling
self.unsub_interval()
else:
# Error occured
self.unsub_interval()
if t.time() > self.am_timing.embark_end:
self.unsub_interval()
Entity: (just applies a value fn from the description to the coordinator data)
class SmartTagSensor(CoordinatorEntity[SmartTagCoordinator], Entity):
_attr_has_entity_name = True
entity_description: SmartTagEntityDescription
def __init__(self, coordinator: SmartTagCoordinator, description: SmartTagEntityDescription, device_info: DeviceInfo, entry_id: str):
super().__init__(coordinator)
self._attr_unique_id = f"{entry_id}-{description.key}"
self._attr_device_info = device_info
self.entity_id = f"sensor.smart_tag_{description.key}"
self.entity_description = description
self._state = description.value_fn(coordinator.data)
@property
def state(self) -> StateType:
return self._state
@callback
def _handle_coordinator_update(self) -> None:
new_state = self.entity_description.value_fn(self.coordinator.data)
if new_state is not None:
self._state = new_state
self.async_write_ha_state()
it sounds like all the callbacks for automations are getting processed before the next state change is made
this could just be a timing issue
yeah that's what I thought too
I added a 1 second delay to the automation and it worked
is that the best solution in this case? should I change the order that the entities are created in?
this is the code in async_setup_entry if that's relevant:
sensors = [SmartTagSensor(
coordinator,
description,
device_info,
entry.entry_id
) for description in AVAILABLE_ENTITIES]
async_add_entities(sensors, False)
"entity A" (in my original question) is the first element in AVAILABLE_ENTITIES so it would make sense that automations based on it would get processed first
also I have another question - in my on_interval fn above I have to manually get the time because the param passed in by hass seems to be inconsistent
when it's triggered by async_track_time_change it's in local time but when it's from async_track_time_interval it's utc
Likely yes as the order entities are created should not be relevant
why do you have to get the time manually? I see what you mean about inconsistent from a timezone perspective but you can change the timezone without retrieving the time again
homeassistant.util.dt has functions to help with that
also, are there any proper api docs for the hass object and the homeassistant module? the links on the developer documentation seem to be broken