mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 12:17:07 +00:00
ElkM1 integration updates for new version of base library (#71508)
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
19168227eb
commit
a03a4b0d13
@ -205,18 +205,18 @@ class ElkArea(ElkAttachedEntity, AlarmControlPanelEntity, RestoreEntity):
|
||||
|
||||
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,
|
||||
ArmedStatus.ARMED_STAY.value: STATE_ALARM_ARMED_HOME,
|
||||
ArmedStatus.ARMED_STAY_INSTANT.value: STATE_ALARM_ARMED_HOME,
|
||||
ArmedStatus.ARMED_TO_NIGHT.value: STATE_ALARM_ARMED_NIGHT,
|
||||
ArmedStatus.ARMED_TO_NIGHT_INSTANT.value: STATE_ALARM_ARMED_NIGHT,
|
||||
ArmedStatus.ARMED_TO_VACATION.value: STATE_ALARM_ARMED_AWAY,
|
||||
ArmedStatus.DISARMED: STATE_ALARM_DISARMED,
|
||||
ArmedStatus.ARMED_AWAY: STATE_ALARM_ARMED_AWAY,
|
||||
ArmedStatus.ARMED_STAY: STATE_ALARM_ARMED_HOME,
|
||||
ArmedStatus.ARMED_STAY_INSTANT: STATE_ALARM_ARMED_HOME,
|
||||
ArmedStatus.ARMED_TO_NIGHT: STATE_ALARM_ARMED_NIGHT,
|
||||
ArmedStatus.ARMED_TO_NIGHT_INSTANT: STATE_ALARM_ARMED_NIGHT,
|
||||
ArmedStatus.ARMED_TO_VACATION: STATE_ALARM_ARMED_AWAY,
|
||||
}
|
||||
|
||||
if self._element.alarm_state is None:
|
||||
self._state = None
|
||||
elif self._element.alarm_state >= AlarmState.FIRE_ALARM.value:
|
||||
elif self._element.in_alarm_state():
|
||||
# Area is in alarm state
|
||||
self._state = STATE_ALARM_TRIGGERED
|
||||
elif self._entry_exit_timer_is_running():
|
||||
@ -239,32 +239,32 @@ class ElkArea(ElkAttachedEntity, AlarmControlPanelEntity, RestoreEntity):
|
||||
async def async_alarm_arm_home(self, code: str | None = None) -> None:
|
||||
"""Send arm home command."""
|
||||
if code is not None:
|
||||
self._element.arm(ArmLevel.ARMED_STAY.value, int(code))
|
||||
self._element.arm(ArmLevel.ARMED_STAY, int(code))
|
||||
|
||||
async def async_alarm_arm_away(self, code: str | None = None) -> None:
|
||||
"""Send arm away command."""
|
||||
if code is not None:
|
||||
self._element.arm(ArmLevel.ARMED_AWAY.value, int(code))
|
||||
self._element.arm(ArmLevel.ARMED_AWAY, int(code))
|
||||
|
||||
async def async_alarm_arm_night(self, code: str | None = None) -> None:
|
||||
"""Send arm night command."""
|
||||
if code is not None:
|
||||
self._element.arm(ArmLevel.ARMED_NIGHT.value, int(code))
|
||||
self._element.arm(ArmLevel.ARMED_NIGHT, int(code))
|
||||
|
||||
async def async_alarm_arm_home_instant(self, code: str | None = None) -> None:
|
||||
"""Send arm stay instant command."""
|
||||
if code is not None:
|
||||
self._element.arm(ArmLevel.ARMED_STAY_INSTANT.value, int(code))
|
||||
self._element.arm(ArmLevel.ARMED_STAY_INSTANT, int(code))
|
||||
|
||||
async def async_alarm_arm_night_instant(self, code: str | None = None) -> None:
|
||||
"""Send arm night instant command."""
|
||||
if code is not None:
|
||||
self._element.arm(ArmLevel.ARMED_NIGHT_INSTANT.value, int(code))
|
||||
self._element.arm(ArmLevel.ARMED_NIGHT_INSTANT, int(code))
|
||||
|
||||
async def async_alarm_arm_vacation(self, code: str | None = None) -> None:
|
||||
"""Send arm vacation command."""
|
||||
if code is not None:
|
||||
self._element.arm(ArmLevel.ARMED_VACATION.value, int(code))
|
||||
self._element.arm(ArmLevel.ARMED_VACATION, int(code))
|
||||
|
||||
async def async_display_message(
|
||||
self, clear: int, beep: bool, timeout: int, line1: str, line2: str
|
||||
|
@ -33,26 +33,26 @@ SUPPORT_HVAC = [
|
||||
HVACMode.FAN_ONLY,
|
||||
]
|
||||
HASS_TO_ELK_HVAC_MODES = {
|
||||
HVACMode.OFF: (ThermostatMode.OFF.value, ThermostatFan.AUTO.value),
|
||||
HVACMode.HEAT: (ThermostatMode.HEAT.value, None),
|
||||
HVACMode.COOL: (ThermostatMode.COOL.value, None),
|
||||
HVACMode.HEAT_COOL: (ThermostatMode.AUTO.value, None),
|
||||
HVACMode.FAN_ONLY: (ThermostatMode.OFF.value, ThermostatFan.ON.value),
|
||||
HVACMode.OFF: (ThermostatMode.OFF, ThermostatFan.AUTO),
|
||||
HVACMode.HEAT: (ThermostatMode.HEAT, None),
|
||||
HVACMode.COOL: (ThermostatMode.COOL, None),
|
||||
HVACMode.HEAT_COOL: (ThermostatMode.AUTO, None),
|
||||
HVACMode.FAN_ONLY: (ThermostatMode.OFF, ThermostatFan.ON),
|
||||
}
|
||||
ELK_TO_HASS_HVAC_MODES = {
|
||||
ThermostatMode.OFF.value: HVACMode.OFF,
|
||||
ThermostatMode.COOL.value: HVACMode.COOL,
|
||||
ThermostatMode.HEAT.value: HVACMode.HEAT,
|
||||
ThermostatMode.EMERGENCY_HEAT.value: HVACMode.HEAT,
|
||||
ThermostatMode.AUTO.value: HVACMode.HEAT_COOL,
|
||||
ThermostatMode.OFF: HVACMode.OFF,
|
||||
ThermostatMode.COOL: HVACMode.COOL,
|
||||
ThermostatMode.HEAT: HVACMode.HEAT,
|
||||
ThermostatMode.EMERGENCY_HEAT: HVACMode.HEAT,
|
||||
ThermostatMode.AUTO: HVACMode.HEAT_COOL,
|
||||
}
|
||||
HASS_TO_ELK_FAN_MODES = {
|
||||
FAN_AUTO: (None, ThermostatFan.AUTO.value),
|
||||
FAN_ON: (None, ThermostatFan.ON.value),
|
||||
FAN_AUTO: (None, ThermostatFan.AUTO),
|
||||
FAN_ON: (None, ThermostatFan.ON),
|
||||
}
|
||||
ELK_TO_HASS_FAN_MODES = {
|
||||
ThermostatFan.AUTO.value: FAN_AUTO,
|
||||
ThermostatFan.ON.value: FAN_ON,
|
||||
ThermostatFan.AUTO: FAN_AUTO,
|
||||
ThermostatFan.ON: FAN_ON,
|
||||
}
|
||||
|
||||
|
||||
@ -84,7 +84,7 @@ class ElkThermostat(ElkEntity, ClimateEntity):
|
||||
def __init__(self, element: Element, elk: Elk, elk_data: dict[str, Any]) -> None:
|
||||
"""Initialize climate entity."""
|
||||
super().__init__(element, elk, elk_data)
|
||||
self._state: str = HVACMode.OFF
|
||||
self._state: str | None = None
|
||||
|
||||
@property
|
||||
def temperature_unit(self) -> str:
|
||||
@ -100,11 +100,11 @@ class ElkThermostat(ElkEntity, ClimateEntity):
|
||||
def target_temperature(self) -> float | None:
|
||||
"""Return the temperature we are trying to reach."""
|
||||
if self._element.mode in (
|
||||
ThermostatMode.HEAT.value,
|
||||
ThermostatMode.EMERGENCY_HEAT.value,
|
||||
ThermostatMode.HEAT,
|
||||
ThermostatMode.EMERGENCY_HEAT,
|
||||
):
|
||||
return self._element.heat_setpoint
|
||||
if self._element.mode == ThermostatMode.COOL.value:
|
||||
if self._element.mode == ThermostatMode.COOL:
|
||||
return self._element.cool_setpoint
|
||||
return None
|
||||
|
||||
@ -129,7 +129,7 @@ class ElkThermostat(ElkEntity, ClimateEntity):
|
||||
return self._element.humidity
|
||||
|
||||
@property
|
||||
def hvac_mode(self) -> str:
|
||||
def hvac_mode(self) -> str | None:
|
||||
"""Return current operation ie. heat, cool, idle."""
|
||||
return self._state
|
||||
|
||||
@ -146,7 +146,7 @@ class ElkThermostat(ElkEntity, ClimateEntity):
|
||||
@property
|
||||
def is_aux_heat(self) -> bool:
|
||||
"""Return if aux heater is on."""
|
||||
return self._element.mode == ThermostatMode.EMERGENCY_HEAT.value
|
||||
return self._element.mode == ThermostatMode.EMERGENCY_HEAT
|
||||
|
||||
@property
|
||||
def min_temp(self) -> float:
|
||||
@ -159,15 +159,17 @@ class ElkThermostat(ElkEntity, ClimateEntity):
|
||||
return 99
|
||||
|
||||
@property
|
||||
def fan_mode(self) -> str:
|
||||
def fan_mode(self) -> str | None:
|
||||
"""Return the fan setting."""
|
||||
if self._element.fan is None:
|
||||
return None
|
||||
return ELK_TO_HASS_FAN_MODES[self._element.fan]
|
||||
|
||||
def _elk_set(self, mode: int | None, fan: int | None) -> None:
|
||||
def _elk_set(self, mode: ThermostatMode | None, fan: ThermostatFan | None) -> None:
|
||||
if mode is not None:
|
||||
self._element.set(ThermostatSetting.MODE.value, mode)
|
||||
self._element.set(ThermostatSetting.MODE, mode)
|
||||
if fan is not None:
|
||||
self._element.set(ThermostatSetting.FAN.value, fan)
|
||||
self._element.set(ThermostatSetting.FAN, fan)
|
||||
|
||||
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||
"""Set thermostat operation mode."""
|
||||
@ -176,11 +178,11 @@ class ElkThermostat(ElkEntity, ClimateEntity):
|
||||
|
||||
async def async_turn_aux_heat_on(self) -> None:
|
||||
"""Turn auxiliary heater on."""
|
||||
self._elk_set(ThermostatMode.EMERGENCY_HEAT.value, None)
|
||||
self._elk_set(ThermostatMode.EMERGENCY_HEAT, None)
|
||||
|
||||
async def async_turn_aux_heat_off(self) -> None:
|
||||
"""Turn auxiliary heater off."""
|
||||
self._elk_set(ThermostatMode.HEAT.value, None)
|
||||
self._elk_set(ThermostatMode.HEAT, None)
|
||||
|
||||
@property
|
||||
def fan_modes(self) -> list[str]:
|
||||
@ -197,11 +199,14 @@ class ElkThermostat(ElkEntity, ClimateEntity):
|
||||
low_temp = kwargs.get(ATTR_TARGET_TEMP_LOW)
|
||||
high_temp = kwargs.get(ATTR_TARGET_TEMP_HIGH)
|
||||
if low_temp is not None:
|
||||
self._element.set(ThermostatSetting.HEAT_SETPOINT.value, round(low_temp))
|
||||
self._element.set(ThermostatSetting.HEAT_SETPOINT, round(low_temp))
|
||||
if high_temp is not None:
|
||||
self._element.set(ThermostatSetting.COOL_SETPOINT.value, round(high_temp))
|
||||
self._element.set(ThermostatSetting.COOL_SETPOINT, round(high_temp))
|
||||
|
||||
def _element_changed(self, element: Element, changeset: Any) -> None:
|
||||
if self._element.mode is None:
|
||||
self._state = None
|
||||
else:
|
||||
self._state = ELK_TO_HASS_HVAC_MODES[self._element.mode]
|
||||
if self._state == HVACMode.OFF and self._element.fan == ThermostatFan.ON.value:
|
||||
if self._state == HVACMode.OFF and self._element.fan == ThermostatFan.ON:
|
||||
self._state = HVACMode.FAN_ONLY
|
||||
|
@ -2,7 +2,7 @@
|
||||
"domain": "elkm1",
|
||||
"name": "Elk-M1 Control",
|
||||
"documentation": "https://www.home-assistant.io/integrations/elkm1",
|
||||
"requirements": ["elkm1-lib==1.3.5"],
|
||||
"requirements": ["elkm1-lib==2.0.0"],
|
||||
"dhcp": [{ "registered_devices": true }, { "macaddress": "00409D*" }],
|
||||
"codeowners": ["@gwww", "@bdraco"],
|
||||
"dependencies": ["network"],
|
||||
|
@ -3,12 +3,7 @@ from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from elkm1_lib.const import (
|
||||
SettingFormat,
|
||||
ZoneLogicalStatus,
|
||||
ZonePhysicalStatus,
|
||||
ZoneType,
|
||||
)
|
||||
from elkm1_lib.const import SettingFormat, ZoneType
|
||||
from elkm1_lib.counters import Counter
|
||||
from elkm1_lib.elements import Element
|
||||
from elkm1_lib.elk import Elk
|
||||
@ -237,25 +232,25 @@ class ElkZone(ElkSensor):
|
||||
def icon(self) -> str:
|
||||
"""Icon to use in the frontend."""
|
||||
zone_icons = {
|
||||
ZoneType.FIRE_ALARM.value: "fire",
|
||||
ZoneType.FIRE_VERIFIED.value: "fire",
|
||||
ZoneType.FIRE_SUPERVISORY.value: "fire",
|
||||
ZoneType.KEYFOB.value: "key",
|
||||
ZoneType.NON_ALARM.value: "alarm-off",
|
||||
ZoneType.MEDICAL_ALARM.value: "medical-bag",
|
||||
ZoneType.POLICE_ALARM.value: "alarm-light",
|
||||
ZoneType.POLICE_NO_INDICATION.value: "alarm-light",
|
||||
ZoneType.KEY_MOMENTARY_ARM_DISARM.value: "power",
|
||||
ZoneType.KEY_MOMENTARY_ARM_AWAY.value: "power",
|
||||
ZoneType.KEY_MOMENTARY_ARM_STAY.value: "power",
|
||||
ZoneType.KEY_MOMENTARY_DISARM.value: "power",
|
||||
ZoneType.KEY_ON_OFF.value: "toggle-switch",
|
||||
ZoneType.MUTE_AUDIBLES.value: "volume-mute",
|
||||
ZoneType.POWER_SUPERVISORY.value: "power-plug",
|
||||
ZoneType.TEMPERATURE.value: "thermometer-lines",
|
||||
ZoneType.ANALOG_ZONE.value: "speedometer",
|
||||
ZoneType.PHONE_KEY.value: "phone-classic",
|
||||
ZoneType.INTERCOM_KEY.value: "deskphone",
|
||||
ZoneType.FIRE_ALARM: "fire",
|
||||
ZoneType.FIRE_VERIFIED: "fire",
|
||||
ZoneType.FIRE_SUPERVISORY: "fire",
|
||||
ZoneType.KEYFOB: "key",
|
||||
ZoneType.NON_ALARM: "alarm-off",
|
||||
ZoneType.MEDICAL_ALARM: "medical-bag",
|
||||
ZoneType.POLICE_ALARM: "alarm-light",
|
||||
ZoneType.POLICE_NO_INDICATION: "alarm-light",
|
||||
ZoneType.KEY_MOMENTARY_ARM_DISARM: "power",
|
||||
ZoneType.KEY_MOMENTARY_ARM_AWAY: "power",
|
||||
ZoneType.KEY_MOMENTARY_ARM_STAY: "power",
|
||||
ZoneType.KEY_MOMENTARY_DISARM: "power",
|
||||
ZoneType.KEY_ON_OFF: "toggle-switch",
|
||||
ZoneType.MUTE_AUDIBLES: "volume-mute",
|
||||
ZoneType.POWER_SUPERVISORY: "power-plug",
|
||||
ZoneType.TEMPERATURE: "thermometer-lines",
|
||||
ZoneType.ANALOG_ZONE: "speedometer",
|
||||
ZoneType.PHONE_KEY: "phone-classic",
|
||||
ZoneType.INTERCOM_KEY: "deskphone",
|
||||
}
|
||||
return f"mdi:{zone_icons.get(self._element.definition, 'alarm-bell')}"
|
||||
|
||||
@ -263,13 +258,9 @@ class ElkZone(ElkSensor):
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Attributes of the sensor."""
|
||||
attrs: dict[str, Any] = self.initial_attrs()
|
||||
attrs["physical_status"] = ZonePhysicalStatus(
|
||||
self._element.physical_status
|
||||
).name.lower()
|
||||
attrs["logical_status"] = ZoneLogicalStatus(
|
||||
self._element.logical_status
|
||||
).name.lower()
|
||||
attrs["definition"] = ZoneType(self._element.definition).name.lower()
|
||||
attrs["physical_status"] = self._element.physical_status.name.lower()
|
||||
attrs["logical_status"] = self._element.logical_status.name.lower()
|
||||
attrs["definition"] = self._element.definition.name.lower()
|
||||
attrs["area"] = self._element.area + 1
|
||||
attrs["triggered_alarm"] = self._element.triggered_alarm
|
||||
return attrs
|
||||
@ -277,27 +268,25 @@ class ElkZone(ElkSensor):
|
||||
@property
|
||||
def temperature_unit(self) -> str | None:
|
||||
"""Return the temperature unit."""
|
||||
if self._element.definition == ZoneType.TEMPERATURE.value:
|
||||
if self._element.definition == ZoneType.TEMPERATURE:
|
||||
return self._temperature_unit
|
||||
return None
|
||||
|
||||
@property
|
||||
def native_unit_of_measurement(self) -> str | None:
|
||||
"""Return the unit of measurement."""
|
||||
if self._element.definition == ZoneType.TEMPERATURE.value:
|
||||
if self._element.definition == ZoneType.TEMPERATURE:
|
||||
return self._temperature_unit
|
||||
if self._element.definition == ZoneType.ANALOG_ZONE.value:
|
||||
if self._element.definition == ZoneType.ANALOG_ZONE:
|
||||
return ELECTRIC_POTENTIAL_VOLT
|
||||
return None
|
||||
|
||||
def _element_changed(self, _: Element, changeset: Any) -> None:
|
||||
if self._element.definition == ZoneType.TEMPERATURE.value:
|
||||
if self._element.definition == ZoneType.TEMPERATURE:
|
||||
self._state = temperature_to_state(
|
||||
self._element.temperature, UNDEFINED_TEMPERATURE
|
||||
)
|
||||
elif self._element.definition == ZoneType.ANALOG_ZONE.value:
|
||||
elif self._element.definition == ZoneType.ANALOG_ZONE:
|
||||
self._state = f"{self._element.voltage}"
|
||||
else:
|
||||
self._state = pretty_const(
|
||||
ZoneLogicalStatus(self._element.logical_status).name
|
||||
)
|
||||
self._state = pretty_const(self._element.logical_status.name)
|
||||
|
@ -584,7 +584,7 @@ elgato==3.0.0
|
||||
eliqonline==1.2.2
|
||||
|
||||
# homeassistant.components.elkm1
|
||||
elkm1-lib==1.3.5
|
||||
elkm1-lib==2.0.0
|
||||
|
||||
# homeassistant.components.elmax
|
||||
elmax_api==0.0.2
|
||||
|
@ -418,7 +418,7 @@ dynalite_devices==0.1.46
|
||||
elgato==3.0.0
|
||||
|
||||
# homeassistant.components.elkm1
|
||||
elkm1-lib==1.3.5
|
||||
elkm1-lib==2.0.0
|
||||
|
||||
# homeassistant.components.elmax
|
||||
elmax_api==0.0.2
|
||||
|
Loading…
x
Reference in New Issue
Block a user