92 lines
2.8 KiB
Python
92 lines
2.8 KiB
Python
"""Support for Balboa events."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime, timedelta
|
|
|
|
from pybalboa import EVENT_UPDATE, SpaClient
|
|
|
|
from homeassistant.components.event import EventEntity
|
|
from homeassistant.core import HomeAssistant, callback
|
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|
from homeassistant.helpers.event import async_track_time_interval
|
|
|
|
from . import BalboaConfigEntry
|
|
from .entity import BalboaEntity
|
|
|
|
FAULT = "fault"
|
|
FAULT_DATE = "fault_date"
|
|
REQUEST_FAULT_LOG_INTERVAL = timedelta(minutes=5)
|
|
|
|
FAULT_MESSAGE_CODE_MAP: dict[int, str] = {
|
|
15: "sensor_out_of_sync",
|
|
16: "low_flow",
|
|
17: "flow_failed",
|
|
18: "settings_reset",
|
|
19: "priming_mode",
|
|
20: "clock_failed",
|
|
21: "settings_reset",
|
|
22: "memory_failure",
|
|
26: "service_sensor_sync",
|
|
27: "heater_dry",
|
|
28: "heater_may_be_dry",
|
|
29: "water_too_hot",
|
|
30: "heater_too_hot",
|
|
31: "sensor_a_fault",
|
|
32: "sensor_b_fault",
|
|
34: "pump_stuck",
|
|
35: "hot_fault",
|
|
36: "gfci_test_failed",
|
|
37: "standby_mode",
|
|
}
|
|
FAULT_EVENT_TYPES = sorted(set(FAULT_MESSAGE_CODE_MAP.values()))
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
entry: BalboaConfigEntry,
|
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
|
) -> None:
|
|
"""Set up the spa's events."""
|
|
async_add_entities([BalboaEventEntity(entry.runtime_data)])
|
|
|
|
|
|
class BalboaEventEntity(BalboaEntity, EventEntity):
|
|
"""Representation of a Balboa event entity."""
|
|
|
|
_attr_event_types = FAULT_EVENT_TYPES
|
|
_attr_translation_key = FAULT
|
|
|
|
def __init__(self, spa: SpaClient) -> None:
|
|
"""Initialize a Balboa event entity."""
|
|
super().__init__(spa, FAULT)
|
|
|
|
@callback
|
|
def _async_handle_event(self) -> None:
|
|
"""Handle the fault event."""
|
|
if not (fault := self._client.fault):
|
|
return
|
|
fault_date = fault.fault_datetime.isoformat()
|
|
if self.state_attributes.get(FAULT_DATE) != fault_date:
|
|
self._trigger_event(
|
|
FAULT_MESSAGE_CODE_MAP.get(fault.message_code, fault.message),
|
|
{FAULT_DATE: fault_date, "code": fault.message_code},
|
|
)
|
|
self.async_write_ha_state()
|
|
|
|
async def async_added_to_hass(self) -> None:
|
|
"""Run when entity about to be added to hass."""
|
|
await super().async_added_to_hass()
|
|
self.async_on_remove(self._client.on(EVENT_UPDATE, self._async_handle_event))
|
|
|
|
async def request_fault_log(now: datetime | None = None) -> None:
|
|
"""Request the most recent fault log."""
|
|
await self._client.request_fault_log()
|
|
|
|
await request_fault_log()
|
|
self.async_on_remove(
|
|
async_track_time_interval(
|
|
self.hass, request_fault_log, REQUEST_FAULT_LOG_INTERVAL
|
|
)
|
|
)
|