mirror of
https://github.com/home-assistant/core
synced 2024-10-04 20:02:40 +00:00
Elk types 4 (#70305)
This commit is contained in:
parent
a1f33a093c
commit
1492ea1fe3
|
@ -91,6 +91,7 @@ homeassistant.components.dunehd.*
|
|||
homeassistant.components.efergy.*
|
||||
homeassistant.components.elgato.*
|
||||
homeassistant.components.elkm1.__init__
|
||||
homeassistant.components.elkm1.alarm_control_panel
|
||||
homeassistant.components.elkm1.climate
|
||||
homeassistant.components.elkm1.discovery
|
||||
homeassistant.components.elkm1.light
|
||||
|
|
|
@ -486,7 +486,7 @@ class ElkEntity(Entity):
|
|||
"""Is the entity available to be updated."""
|
||||
return self._elk.is_connected()
|
||||
|
||||
def initial_attrs(self) -> dict[str, int]:
|
||||
def initial_attrs(self) -> dict[str, Any]:
|
||||
"""Return the underlying element's attributes as a dict."""
|
||||
attrs = {}
|
||||
attrs["index"] = self._element.index + 1
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
"""Each ElkM1 area will be created as a separate alarm_control_panel."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from elkm1_lib.areas import Area
|
||||
from elkm1_lib.const import AlarmState, ArmedStatus, ArmLevel, ArmUpState
|
||||
from elkm1_lib.elements import Element
|
||||
from elkm1_lib.elk import Elk
|
||||
from elkm1_lib.keypads import Keypad
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.alarm_control_panel import (
|
||||
|
@ -107,18 +113,19 @@ class ElkArea(ElkAttachedEntity, AlarmControlPanelEntity, RestoreEntity):
|
|||
| AlarmControlPanelEntityFeature.ARM_AWAY
|
||||
| AlarmControlPanelEntityFeature.ARM_NIGHT
|
||||
)
|
||||
_element: Area
|
||||
|
||||
def __init__(self, element, elk, elk_data):
|
||||
def __init__(self, element: Element, elk: Elk, elk_data: dict[str, Any]) -> None:
|
||||
"""Initialize Area as Alarm Control Panel."""
|
||||
super().__init__(element, elk, elk_data)
|
||||
self._elk = elk
|
||||
self._changed_by_keypad = None
|
||||
self._changed_by_time = None
|
||||
self._changed_by_id = None
|
||||
self._changed_by = None
|
||||
self._state = None
|
||||
self._changed_by_keypad: str | None = None
|
||||
self._changed_by_time: str | None = None
|
||||
self._changed_by_id: int | None = None
|
||||
self._changed_by: str | None = None
|
||||
self._state: str | None = None
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Register callback for ElkM1 changes."""
|
||||
await super().async_added_to_hass()
|
||||
if len(self._elk.areas.elements) == 1:
|
||||
|
@ -139,7 +146,8 @@ class ElkArea(ElkAttachedEntity, AlarmControlPanelEntity, RestoreEntity):
|
|||
if ATTR_CHANGED_BY in last_state.attributes:
|
||||
self._changed_by = last_state.attributes[ATTR_CHANGED_BY]
|
||||
|
||||
def _watch_keypad(self, keypad, changeset):
|
||||
def _watch_keypad(self, keypad: Element, changeset: dict[str, Any]) -> None:
|
||||
assert isinstance(keypad, Keypad)
|
||||
if keypad.area != self._element.index:
|
||||
return
|
||||
if changeset.get("last_user") is not None:
|
||||
|
@ -149,30 +157,30 @@ class ElkArea(ElkAttachedEntity, AlarmControlPanelEntity, RestoreEntity):
|
|||
self._changed_by = self._elk.users.username(keypad.last_user)
|
||||
self.async_write_ha_state()
|
||||
|
||||
def _watch_area(self, area, changeset):
|
||||
def _watch_area(self, area: Element, changeset: dict[str, Any]) -> None:
|
||||
if not (last_log := changeset.get("last_log")):
|
||||
return
|
||||
# user_number only set for arm/disarm logs
|
||||
if not last_log.get("user_number"):
|
||||
if (user_number := last_log.get("user_number")) is None:
|
||||
return
|
||||
self._changed_by_keypad = None
|
||||
self._changed_by_id = last_log["user_number"]
|
||||
self._changed_by = self._elk.users.username(self._changed_by_id - 1)
|
||||
self._changed_by_id = user_number
|
||||
self._changed_by = self._elk.users.username(user_number - 1)
|
||||
self._changed_by_time = last_log["timestamp"]
|
||||
self.async_write_ha_state()
|
||||
|
||||
@property
|
||||
def code_format(self):
|
||||
def code_format(self) -> CodeFormat | None:
|
||||
"""Return the alarm code format."""
|
||||
return CodeFormat.NUMBER
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def state(self) -> str | None:
|
||||
"""Return the state of the element."""
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Attributes of the area."""
|
||||
attrs = self.initial_attrs()
|
||||
elmt = self._element
|
||||
|
@ -191,11 +199,11 @@ class ElkArea(ElkAttachedEntity, AlarmControlPanelEntity, RestoreEntity):
|
|||
return attrs
|
||||
|
||||
@property
|
||||
def changed_by(self):
|
||||
def changed_by(self) -> str | None:
|
||||
"""Last change triggered by."""
|
||||
return self._changed_by
|
||||
|
||||
def _element_changed(self, element, changeset):
|
||||
def _element_changed(self, element: Element, changeset: dict[str, Any]) -> None:
|
||||
elk_state_to_hass_state = {
|
||||
ArmedStatus.DISARMED.value: STATE_ALARM_DISARMED,
|
||||
ArmedStatus.ARMED_AWAY.value: STATE_ALARM_ARMED_AWAY,
|
||||
|
@ -208,57 +216,68 @@ class ElkArea(ElkAttachedEntity, AlarmControlPanelEntity, RestoreEntity):
|
|||
|
||||
if self._element.alarm_state is None:
|
||||
self._state = None
|
||||
elif self._area_is_in_alarm_state():
|
||||
elif self._element.alarm_state >= AlarmState.FIRE_ALARM.value:
|
||||
# Area is in alarm state
|
||||
self._state = STATE_ALARM_TRIGGERED
|
||||
elif self._entry_exit_timer_is_running():
|
||||
self._state = (
|
||||
STATE_ALARM_ARMING if self._element.is_exit else STATE_ALARM_PENDING
|
||||
)
|
||||
else:
|
||||
elif self._element.armed_status is not None:
|
||||
self._state = elk_state_to_hass_state[self._element.armed_status]
|
||||
else:
|
||||
self._state = None
|
||||
|
||||
def _entry_exit_timer_is_running(self):
|
||||
def _entry_exit_timer_is_running(self) -> bool:
|
||||
return self._element.timer1 > 0 or self._element.timer2 > 0
|
||||
|
||||
def _area_is_in_alarm_state(self):
|
||||
return self._element.alarm_state >= AlarmState.FIRE_ALARM.value
|
||||
|
||||
async def async_alarm_disarm(self, code=None):
|
||||
async def async_alarm_disarm(self, code: str | None = None) -> None:
|
||||
"""Send disarm command."""
|
||||
self._element.disarm(int(code))
|
||||
if code is not None:
|
||||
self._element.disarm(int(code))
|
||||
|
||||
async def async_alarm_arm_home(self, code=None):
|
||||
async def async_alarm_arm_home(self, code: str | None = None) -> None:
|
||||
"""Send arm home command."""
|
||||
self._element.arm(ArmLevel.ARMED_STAY.value, int(code))
|
||||
if code is not None:
|
||||
self._element.arm(ArmLevel.ARMED_STAY.value, int(code))
|
||||
|
||||
async def async_alarm_arm_away(self, code=None):
|
||||
async def async_alarm_arm_away(self, code: str | None = None) -> None:
|
||||
"""Send arm away command."""
|
||||
self._element.arm(ArmLevel.ARMED_AWAY.value, int(code))
|
||||
if code is not None:
|
||||
self._element.arm(ArmLevel.ARMED_AWAY.value, int(code))
|
||||
|
||||
async def async_alarm_arm_night(self, code=None):
|
||||
async def async_alarm_arm_night(self, code: str | None = None) -> None:
|
||||
"""Send arm night command."""
|
||||
self._element.arm(ArmLevel.ARMED_NIGHT.value, int(code))
|
||||
if code is not None:
|
||||
self._element.arm(ArmLevel.ARMED_NIGHT.value, int(code))
|
||||
|
||||
async def async_alarm_arm_home_instant(self, code=None):
|
||||
async def async_alarm_arm_home_instant(self, code: str | None = None) -> None:
|
||||
"""Send arm stay instant command."""
|
||||
self._element.arm(ArmLevel.ARMED_STAY_INSTANT.value, int(code))
|
||||
if code is not None:
|
||||
self._element.arm(ArmLevel.ARMED_STAY_INSTANT.value, int(code))
|
||||
|
||||
async def async_alarm_arm_night_instant(self, code=None):
|
||||
async def async_alarm_arm_night_instant(self, code: str | None = None) -> None:
|
||||
"""Send arm night instant command."""
|
||||
self._element.arm(ArmLevel.ARMED_NIGHT_INSTANT.value, int(code))
|
||||
if code is not None:
|
||||
self._element.arm(ArmLevel.ARMED_NIGHT_INSTANT.value, int(code))
|
||||
|
||||
async def async_alarm_arm_vacation(self, code=None):
|
||||
async def async_alarm_arm_vacation(self, code: str | None = None) -> None:
|
||||
"""Send arm vacation command."""
|
||||
self._element.arm(ArmLevel.ARMED_VACATION.value, int(code))
|
||||
if code is not None:
|
||||
self._element.arm(ArmLevel.ARMED_VACATION.value, int(code))
|
||||
|
||||
async def async_display_message(self, clear, beep, timeout, line1, line2):
|
||||
async def async_display_message(
|
||||
self, clear: int, beep: bool, timeout: int, line1: str, line2: str
|
||||
) -> None:
|
||||
"""Display a message on all keypads for the area."""
|
||||
self._element.display_message(clear, beep, timeout, line1, line2)
|
||||
|
||||
async def async_bypass(self, code=None):
|
||||
async def async_bypass(self, code: str | None = None) -> None:
|
||||
"""Bypass all zones in area."""
|
||||
self._element.bypass(code)
|
||||
if code is not None:
|
||||
self._element.bypass(int(code))
|
||||
|
||||
async def async_clear_bypass(self, code=None):
|
||||
async def async_clear_bypass(self, code: str | None = None) -> None:
|
||||
"""Clear bypass for all zones in area."""
|
||||
self._element.clear_bypass(code)
|
||||
if code is not None:
|
||||
self._element.clear_bypass(int(code))
|
||||
|
|
11
mypy.ini
11
mypy.ini
|
@ -803,6 +803,17 @@ no_implicit_optional = true
|
|||
warn_return_any = true
|
||||
warn_unreachable = true
|
||||
|
||||
[mypy-homeassistant.components.elkm1.alarm_control_panel]
|
||||
check_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
disallow_subclassing_any = true
|
||||
disallow_untyped_calls = true
|
||||
disallow_untyped_decorators = true
|
||||
disallow_untyped_defs = true
|
||||
no_implicit_optional = true
|
||||
warn_return_any = true
|
||||
warn_unreachable = true
|
||||
|
||||
[mypy-homeassistant.components.elkm1.climate]
|
||||
check_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
|
|
Loading…
Reference in a new issue