Complete strict typing for ElkM1 integration (#70334)
This commit is contained in:
parent
64381acbaf
commit
2abe551eef
3 changed files with 55 additions and 119 deletions
|
@ -1,13 +1,22 @@
|
|||
"""Support for control of ElkM1 sensors."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from elkm1_lib.const import (
|
||||
SettingFormat,
|
||||
ZoneLogicalStatus,
|
||||
ZonePhysicalStatus,
|
||||
ZoneType,
|
||||
)
|
||||
from elkm1_lib.counters import Counter
|
||||
from elkm1_lib.elements import Element
|
||||
from elkm1_lib.elk import Elk
|
||||
from elkm1_lib.keypads import Keypad
|
||||
from elkm1_lib.panel import Panel
|
||||
from elkm1_lib.settings import Setting
|
||||
from elkm1_lib.util import pretty_const
|
||||
from elkm1_lib.zones import Zone
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.sensor import SensorEntity
|
||||
|
@ -73,43 +82,45 @@ async def async_setup_entry(
|
|||
)
|
||||
|
||||
|
||||
def temperature_to_state(temperature, undefined_temperature):
|
||||
def temperature_to_state(temperature: int, undefined_temperature: int) -> str | None:
|
||||
"""Convert temperature to a state."""
|
||||
return temperature if temperature > undefined_temperature else None
|
||||
return f"{temperature}" if temperature > undefined_temperature else None
|
||||
|
||||
|
||||
class ElkSensor(ElkAttachedEntity, SensorEntity):
|
||||
"""Base representation of Elk-M1 sensor."""
|
||||
|
||||
def __init__(self, element, elk, elk_data):
|
||||
def __init__(self, element: Element, elk: Elk, elk_data: dict[str, Any]) -> None:
|
||||
"""Initialize the base of all Elk sensors."""
|
||||
super().__init__(element, elk, elk_data)
|
||||
self._state = None
|
||||
self._state: str | None = None
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
def native_value(self) -> str | None:
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
async def async_counter_refresh(self):
|
||||
async def async_counter_refresh(self) -> None:
|
||||
"""Refresh the value of a counter from the panel."""
|
||||
if not isinstance(self, ElkCounter):
|
||||
raise HomeAssistantError("supported only on ElkM1 Counter sensors")
|
||||
self._element.get()
|
||||
|
||||
async def async_counter_set(self, value=None):
|
||||
async def async_counter_set(self, value: int | None = None) -> None:
|
||||
"""Set the value of a counter on the panel."""
|
||||
if not isinstance(self, ElkCounter):
|
||||
raise HomeAssistantError("supported only on ElkM1 Counter sensors")
|
||||
self._element.set(value)
|
||||
if value is not None:
|
||||
self._element.set(value)
|
||||
|
||||
async def async_zone_bypass(self, code=None):
|
||||
async def async_zone_bypass(self, code: int | None = None) -> None:
|
||||
"""Bypass zone."""
|
||||
if not isinstance(self, ElkZone):
|
||||
raise HomeAssistantError("supported only on ElkM1 Zone sensors")
|
||||
self._element.bypass(code)
|
||||
if code is not None:
|
||||
self._element.bypass(code)
|
||||
|
||||
async def async_zone_trigger(self):
|
||||
async def async_zone_trigger(self) -> None:
|
||||
"""Trigger zone."""
|
||||
if not isinstance(self, ElkZone):
|
||||
raise HomeAssistantError("supported only on ElkM1 Zone sensors")
|
||||
|
@ -119,37 +130,41 @@ class ElkSensor(ElkAttachedEntity, SensorEntity):
|
|||
class ElkCounter(ElkSensor):
|
||||
"""Representation of an Elk-M1 Counter."""
|
||||
|
||||
_element: Counter
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
def icon(self) -> str:
|
||||
"""Icon to use in the frontend."""
|
||||
return "mdi:numeric"
|
||||
|
||||
def _element_changed(self, element, changeset):
|
||||
def _element_changed(self, _: Element, changeset: Any) -> None:
|
||||
self._state = self._element.value
|
||||
|
||||
|
||||
class ElkKeypad(ElkSensor):
|
||||
"""Representation of an Elk-M1 Keypad."""
|
||||
|
||||
_element: Keypad
|
||||
|
||||
@property
|
||||
def temperature_unit(self):
|
||||
def temperature_unit(self) -> str:
|
||||
"""Return the temperature unit."""
|
||||
return self._temperature_unit
|
||||
|
||||
@property
|
||||
def native_unit_of_measurement(self):
|
||||
def native_unit_of_measurement(self) -> str:
|
||||
"""Return the unit of measurement."""
|
||||
return self._temperature_unit
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
def icon(self) -> str:
|
||||
"""Icon to use in the frontend."""
|
||||
return "mdi:thermometer-lines"
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Attributes of the sensor."""
|
||||
attrs = self.initial_attrs()
|
||||
attrs: dict[str, Any] = self.initial_attrs()
|
||||
attrs["area"] = self._element.area + 1
|
||||
attrs["temperature"] = self._state
|
||||
attrs["last_user_time"] = self._element.last_user_time.isoformat()
|
||||
|
@ -159,7 +174,7 @@ class ElkKeypad(ElkSensor):
|
|||
attrs["last_keypress"] = self._element.last_keypress
|
||||
return attrs
|
||||
|
||||
def _element_changed(self, element, changeset):
|
||||
def _element_changed(self, _: Element, changeset: Any) -> None:
|
||||
self._state = temperature_to_state(
|
||||
self._element.temperature, UNDEFINED_TEMPERATURE
|
||||
)
|
||||
|
@ -169,20 +184,21 @@ class ElkPanel(ElkSensor):
|
|||
"""Representation of an Elk-M1 Panel."""
|
||||
|
||||
_attr_entity_category = EntityCategory.DIAGNOSTIC
|
||||
_element: Panel
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
def icon(self) -> str:
|
||||
"""Icon to use in the frontend."""
|
||||
return "mdi:home"
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Attributes of the sensor."""
|
||||
attrs = self.initial_attrs()
|
||||
attrs["system_trouble_status"] = self._element.system_trouble_status
|
||||
return attrs
|
||||
|
||||
def _element_changed(self, element, changeset):
|
||||
def _element_changed(self, _: Element, changeset: Any) -> None:
|
||||
if self._elk.is_connected():
|
||||
self._state = (
|
||||
"Paused" if self._element.remote_programming_status else "Connected"
|
||||
|
@ -194,18 +210,20 @@ class ElkPanel(ElkSensor):
|
|||
class ElkSetting(ElkSensor):
|
||||
"""Representation of an Elk-M1 Setting."""
|
||||
|
||||
_element: Setting
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
def icon(self) -> str:
|
||||
"""Icon to use in the frontend."""
|
||||
return "mdi:numeric"
|
||||
|
||||
def _element_changed(self, element, changeset):
|
||||
def _element_changed(self, _: Element, changeset: Any) -> None:
|
||||
self._state = self._element.value
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Attributes of the sensor."""
|
||||
attrs = self.initial_attrs()
|
||||
attrs: dict[str, Any] = self.initial_attrs()
|
||||
attrs["value_format"] = SettingFormat(self._element.value_format).name.lower()
|
||||
return attrs
|
||||
|
||||
|
@ -213,8 +231,10 @@ class ElkSetting(ElkSensor):
|
|||
class ElkZone(ElkSensor):
|
||||
"""Representation of an Elk-M1 Zone."""
|
||||
|
||||
_element: Zone
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
def icon(self) -> str:
|
||||
"""Icon to use in the frontend."""
|
||||
zone_icons = {
|
||||
ZoneType.FIRE_ALARM.value: "fire",
|
||||
|
@ -240,9 +260,9 @@ class ElkZone(ElkSensor):
|
|||
return f"mdi:{zone_icons.get(self._element.definition, 'alarm-bell')}"
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Attributes of the sensor."""
|
||||
attrs = self.initial_attrs()
|
||||
attrs: dict[str, Any] = self.initial_attrs()
|
||||
attrs["physical_status"] = ZonePhysicalStatus(
|
||||
self._element.physical_status
|
||||
).name.lower()
|
||||
|
@ -255,14 +275,14 @@ class ElkZone(ElkSensor):
|
|||
return attrs
|
||||
|
||||
@property
|
||||
def temperature_unit(self):
|
||||
def temperature_unit(self) -> str | None:
|
||||
"""Return the temperature unit."""
|
||||
if self._element.definition == ZoneType.TEMPERATURE.value:
|
||||
return self._temperature_unit
|
||||
return None
|
||||
|
||||
@property
|
||||
def native_unit_of_measurement(self):
|
||||
def native_unit_of_measurement(self) -> str | None:
|
||||
"""Return the unit of measurement."""
|
||||
if self._element.definition == ZoneType.TEMPERATURE.value:
|
||||
return self._temperature_unit
|
||||
|
@ -270,13 +290,13 @@ class ElkZone(ElkSensor):
|
|||
return ELECTRIC_POTENTIAL_VOLT
|
||||
return None
|
||||
|
||||
def _element_changed(self, element, changeset):
|
||||
def _element_changed(self, _: Element, changeset: Any) -> None:
|
||||
if self._element.definition == ZoneType.TEMPERATURE.value:
|
||||
self._state = temperature_to_state(
|
||||
self._element.temperature, UNDEFINED_TEMPERATURE
|
||||
)
|
||||
elif self._element.definition == ZoneType.ANALOG_ZONE.value:
|
||||
self._state = self._element.voltage
|
||||
self._state = f"{self._element.voltage}"
|
||||
else:
|
||||
self._state = pretty_const(
|
||||
ZoneLogicalStatus(self._element.logical_status).name
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue