diff --git a/src/geckolib/__init__.py b/src/geckolib/__init__.py index cbe28aa..252feba 100644 --- a/src/geckolib/__init__.py +++ b/src/geckolib/__init__.py @@ -19,6 +19,7 @@ GeckoBinarySensor, GeckoSwitch, GeckoWaterCare, + GeckoReminders, ) from .async_locator import GeckoAsyncLocator from .async_spa_descriptor import GeckoAsyncSpaDescriptor @@ -42,6 +43,7 @@ GeckoWatercareProtocolHandler, GeckoUpdateFirmwareProtocolHandler, GeckoRemindersProtocolHandler, + GeckoReminderType, GeckoPackCommandProtocolHandler, # GeckoStructure, @@ -79,6 +81,7 @@ "GeckoBinarySensor", "GeckoSwitch", "GeckoWaterCare", + "GeckoReminders", # From constants "GeckoConstants", # From facade @@ -107,6 +110,7 @@ "GeckoWatercareProtocolHandler", "GeckoUpdateFirmwareProtocolHandler", "GeckoRemindersProtocolHandler", + "GeckoReminderType", "GeckoPackCommandProtocolHandler", # "GeckoStructure", diff --git a/src/geckolib/automation/__init__.py b/src/geckolib/automation/__init__.py index 73added..641b9d2 100644 --- a/src/geckolib/automation/__init__.py +++ b/src/geckolib/automation/__init__.py @@ -30,4 +30,4 @@ "GeckoSwitch", "GeckoWaterCare", "GeckoReminders", -] \ No newline at end of file +] diff --git a/src/geckolib/automation/async_facade.py b/src/geckolib/automation/async_facade.py index ccf394a..7b24c18 100644 --- a/src/geckolib/automation/async_facade.py +++ b/src/geckolib/automation/async_facade.py @@ -59,6 +59,7 @@ def __init__(self, spa: GeckoAsyncSpa, taskman: AsyncTasks, **kwargs: str) -> No device.watch(self._on_change) self._taskman.add_task(self._facade_update(), "Facade update", "FACADE") + self._ready = False async def _facade_update(self) -> None: _LOGGER.debug("Facade update task started") @@ -76,6 +77,9 @@ async def _facade_update(self) -> None: await self._spa.async_get_reminders() ) + # After we've been round here at least once, we're ready + self._ready = True + finally: wait_time = ( GeckoConstants.FACADE_UPDATE_FREQUENCY_IN_SECONDS @@ -88,6 +92,10 @@ async def _facade_update(self) -> None: _LOGGER.debug("Facade update loop cancelled") raise + async def wait_for_one_update(self): + while not self._ready: + await asyncio.sleep(0) + def _scan_outputs(self) -> None: """Scan the spa outputs to decide what user options are available""" diff --git a/src/geckolib/automation/reminders.py b/src/geckolib/automation/reminders.py index 5fdca19..555e8c3 100644 --- a/src/geckolib/automation/reminders.py +++ b/src/geckolib/automation/reminders.py @@ -1,4 +1,5 @@ """ Gecko Reminders """ +from __future__ import annotations import logging from datetime import datetime @@ -53,6 +54,15 @@ def reminders(self): """return all reminders""" return self._active_reminders + def get_reminder( + self, reminder_type: GeckoReminderType + ) -> Optional[GeckoReminders.Reminder]: + """Get the reminder of the specified type, or None if not found""" + for reminder in self.reminders: + if reminder.type == reminder_type: + return reminder + return None + @property def last_update(self) -> Optional[datetime]: """Time of last reminder update""" diff --git a/src/geckolib/spa_state.py b/src/geckolib/spa_state.py index 5286777..1b3dd23 100644 --- a/src/geckolib/spa_state.py +++ b/src/geckolib/spa_state.py @@ -47,7 +47,7 @@ def to_string(state: GeckoSpaState) -> str: elif state == GeckoSpaState.ERROR_NEEDS_ATTENTION: return "Needs attention, check logs" elif state == GeckoSpaState.LOCATING_SPAS: - return "Searching for spas" + return "Searching for spas..." elif state == GeckoSpaState.LOCATED_SPAS: return "Choose spa" elif state == GeckoSpaState.ERROR_SPA_NOT_FOUND: