Add AlarmDecoder device info (#117357)

* Update AlarmDecoder component to newer model

This commit makes AlarmDecoder operate as a proper device entity following the new model introduced a few years ago.

Code also has an internal dependency on a newer version of adext (>= 0.4.3) which has been updated correspondingly.

* Created AlarmDecoder entity

Added an alarmdecoder entity so the device_info can be re-used across the integration

* Move _attr_has_entity_name to base entity

As per code review suggestion, clean up the object model.

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

* Missed one suggestion with the prior commit

Moves _attr_has_entity_name to base entity

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

* Address some ruff issues

* Apply additional ruff cleanups

Ran ruff again to clean up a few files tat weren't picked up last time

* Apply suggestions from code review

Some additional cleanup of style & removal of unnecessary code

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

* Properly generated the integration file

generation had to happen twice for this to work.  Now that it's generated, I'm including the missing update.

* Apply suggestions from code review

Use local client variable instead of self._client

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

* Sort the manifest

documentation was added, but it wasn't sorted properly in the key/value pairs

* Add alarmdecoder entity file to coverage ignore file

Added the alarmdecoder entity file so it is ignored for coverage

---------

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
pull/117655/head
Christopher Tremblay 2024-05-17 23:59:44 -07:00 committed by GitHub
parent 2b195cab72
commit b015dbfccb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 57 additions and 8 deletions

View File

@ -61,6 +61,7 @@ omit =
homeassistant/components/alarmdecoder/__init__.py
homeassistant/components/alarmdecoder/alarm_control_panel.py
homeassistant/components/alarmdecoder/binary_sensor.py
homeassistant/components/alarmdecoder/entity.py
homeassistant/components/alarmdecoder/sensor.py
homeassistant/components/alpha_vantage/sensor.py
homeassistant/components/amazon_polly/*

View File

@ -129,6 +129,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
await open_connection()
await controller.is_init()
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True

View File

@ -34,6 +34,7 @@ from .const import (
OPTIONS_ARM,
SIGNAL_PANEL_MESSAGE,
)
from .entity import AlarmDecoderEntity
SERVICE_ALARM_TOGGLE_CHIME = "alarm_toggle_chime"
@ -75,7 +76,7 @@ async def async_setup_entry(
)
class AlarmDecoderAlarmPanel(AlarmControlPanelEntity):
class AlarmDecoderAlarmPanel(AlarmDecoderEntity, AlarmControlPanelEntity):
"""Representation of an AlarmDecoder-based alarm panel."""
_attr_name = "Alarm Panel"
@ -89,7 +90,8 @@ class AlarmDecoderAlarmPanel(AlarmControlPanelEntity):
def __init__(self, client, auto_bypass, code_arm_required, alt_night_mode):
"""Initialize the alarm panel."""
self._client = client
super().__init__(client)
self._attr_unique_id = f"{client.serial_number}-panel"
self._auto_bypass = auto_bypass
self._attr_code_arm_required = code_arm_required
self._alt_night_mode = alt_night_mode

View File

@ -16,13 +16,16 @@ from .const import (
CONF_ZONE_NUMBER,
CONF_ZONE_RFID,
CONF_ZONE_TYPE,
DATA_AD,
DEFAULT_ZONE_OPTIONS,
DOMAIN,
OPTIONS_ZONES,
SIGNAL_REL_MESSAGE,
SIGNAL_RFX_MESSAGE,
SIGNAL_ZONE_FAULT,
SIGNAL_ZONE_RESTORE,
)
from .entity import AlarmDecoderEntity
_LOGGER = logging.getLogger(__name__)
@ -41,6 +44,7 @@ async def async_setup_entry(
) -> None:
"""Set up for AlarmDecoder sensor."""
client = hass.data[DOMAIN][entry.entry_id][DATA_AD]
zones = entry.options.get(OPTIONS_ZONES, DEFAULT_ZONE_OPTIONS)
entities = []
@ -53,20 +57,28 @@ async def async_setup_entry(
relay_addr = zone_info.get(CONF_RELAY_ADDR)
relay_chan = zone_info.get(CONF_RELAY_CHAN)
entity = AlarmDecoderBinarySensor(
zone_num, zone_name, zone_type, zone_rfid, zone_loop, relay_addr, relay_chan
client,
zone_num,
zone_name,
zone_type,
zone_rfid,
zone_loop,
relay_addr,
relay_chan,
)
entities.append(entity)
async_add_entities(entities)
class AlarmDecoderBinarySensor(BinarySensorEntity):
class AlarmDecoderBinarySensor(AlarmDecoderEntity, BinarySensorEntity):
"""Representation of an AlarmDecoder binary sensor."""
_attr_should_poll = False
def __init__(
self,
client,
zone_number,
zone_name,
zone_type,
@ -76,6 +88,8 @@ class AlarmDecoderBinarySensor(BinarySensorEntity):
relay_chan,
):
"""Initialize the binary_sensor."""
super().__init__(client)
self._attr_unique_id = f"{client.serial_number}-zone-{zone_number}"
self._zone_number = int(zone_number)
self._zone_type = zone_type
self._attr_name = zone_name

View File

@ -0,0 +1,22 @@
"""Support for AlarmDecoder-based alarm control panels entity."""
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import Entity
from .const import DOMAIN
class AlarmDecoderEntity(Entity):
"""Define a base AlarmDecoder entity."""
_attr_has_entity_name = True
def __init__(self, client):
"""Initialize the alarm decoder entity."""
self._client = client
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, client.serial_number)},
manufacturer="NuTech",
serial_number=client.serial_number,
sw_version=client.version_number,
)

View File

@ -4,6 +4,7 @@
"codeowners": [],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/alarmdecoder",
"integration_type": "device",
"iot_class": "local_push",
"loggers": ["adext", "alarmdecoder"],
"requirements": ["adext==0.4.3"]

View File

@ -6,7 +6,8 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import SIGNAL_PANEL_MESSAGE
from .const import DATA_AD, DOMAIN, SIGNAL_PANEL_MESSAGE
from .entity import AlarmDecoderEntity
async def async_setup_entry(
@ -14,17 +15,23 @@ async def async_setup_entry(
) -> None:
"""Set up for AlarmDecoder sensor."""
entity = AlarmDecoderSensor()
client = hass.data[DOMAIN][entry.entry_id][DATA_AD]
entity = AlarmDecoderSensor(client=client)
async_add_entities([entity])
class AlarmDecoderSensor(SensorEntity):
class AlarmDecoderSensor(AlarmDecoderEntity, SensorEntity):
"""Representation of an AlarmDecoder keypad."""
_attr_translation_key = "alarm_panel_display"
_attr_name = "Alarm Panel Display"
_attr_should_poll = False
def __init__(self, client):
"""Initialize the alarm decoder sensor."""
super().__init__(client)
self._attr_unique_id = f"{client.serial_number}-display"
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
self.async_on_remove(

View File

@ -188,7 +188,7 @@
},
"alarmdecoder": {
"name": "AlarmDecoder",
"integration_type": "hub",
"integration_type": "device",
"config_flow": true,
"iot_class": "local_push"
},