Adopt new runtime entry data model for AlarmDecoder (#117856)

* Adopt new runtime entity data model for AlarmDecoder

Transition the AlarmDecoder integration to the new runtime entity model.

* Apply change suggestions by epenet

Tested & applied the suggestions from epenet.
This commit is contained in:
Chris 2024-05-22 01:47:37 -07:00 committed by GitHub
parent b898c86c89
commit b4d0562063
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 50 additions and 50 deletions

View File

@ -1,5 +1,7 @@
"""Support for AlarmDecoder devices.""" """Support for AlarmDecoder devices."""
from collections.abc import Callable
from dataclasses import dataclass
from datetime import timedelta from datetime import timedelta
import logging import logging
@ -22,11 +24,6 @@ from homeassistant.helpers.event import async_call_later
from .const import ( from .const import (
CONF_DEVICE_BAUD, CONF_DEVICE_BAUD,
CONF_DEVICE_PATH, CONF_DEVICE_PATH,
DATA_AD,
DATA_REMOVE_STOP_LISTENER,
DATA_REMOVE_UPDATE_LISTENER,
DATA_RESTART,
DOMAIN,
PROTOCOL_SERIAL, PROTOCOL_SERIAL,
PROTOCOL_SOCKET, PROTOCOL_SOCKET,
SIGNAL_PANEL_MESSAGE, SIGNAL_PANEL_MESSAGE,
@ -44,8 +41,22 @@ PLATFORMS = [
Platform.SENSOR, Platform.SENSOR,
] ]
type AlarmDecoderConfigEntry = ConfigEntry[AlarmDecoderData]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
@dataclass
class AlarmDecoderData:
"""Runtime data for the AlarmDecoder class."""
client: AdExt
remove_update_listener: Callable[[], None]
remove_stop_listener: Callable[[], None]
restart: bool
async def async_setup_entry(
hass: HomeAssistant, entry: AlarmDecoderConfigEntry
) -> bool:
"""Set up AlarmDecoder config flow.""" """Set up AlarmDecoder config flow."""
undo_listener = entry.add_update_listener(_update_listener) undo_listener = entry.add_update_listener(_update_listener)
@ -54,10 +65,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
def stop_alarmdecoder(event): def stop_alarmdecoder(event):
"""Handle the shutdown of AlarmDecoder.""" """Handle the shutdown of AlarmDecoder."""
if not hass.data.get(DOMAIN): if not entry.runtime_data:
return return
_LOGGER.debug("Shutting down alarmdecoder") _LOGGER.debug("Shutting down alarmdecoder")
hass.data[DOMAIN][entry.entry_id][DATA_RESTART] = False entry.runtime_data.restart = False
controller.close() controller.close()
async def open_connection(now=None): async def open_connection(now=None):
@ -69,13 +80,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async_call_later(hass, timedelta(seconds=5), open_connection) async_call_later(hass, timedelta(seconds=5), open_connection)
return return
_LOGGER.debug("Established a connection with the alarmdecoder") _LOGGER.debug("Established a connection with the alarmdecoder")
hass.data[DOMAIN][entry.entry_id][DATA_RESTART] = True entry.runtime_data.restart = True
def handle_closed_connection(event): def handle_closed_connection(event):
"""Restart after unexpected loss of connection.""" """Restart after unexpected loss of connection."""
if not hass.data[DOMAIN][entry.entry_id][DATA_RESTART]: if not entry.runtime_data.restart:
return return
hass.data[DOMAIN][entry.entry_id][DATA_RESTART] = False entry.runtime_data.restart = False
_LOGGER.warning("AlarmDecoder unexpectedly lost connection") _LOGGER.warning("AlarmDecoder unexpectedly lost connection")
hass.add_job(open_connection) hass.add_job(open_connection)
@ -119,13 +130,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
EVENT_HOMEASSISTANT_STOP, stop_alarmdecoder EVENT_HOMEASSISTANT_STOP, stop_alarmdecoder
) )
hass.data.setdefault(DOMAIN, {}) entry.runtime_data = AlarmDecoderData(
hass.data[DOMAIN][entry.entry_id] = { controller, undo_listener, remove_stop_listener, False
DATA_AD: controller, )
DATA_REMOVE_UPDATE_LISTENER: undo_listener,
DATA_REMOVE_STOP_LISTENER: remove_stop_listener,
DATA_RESTART: False,
}
await open_connection() await open_connection()
@ -136,28 +143,26 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return True return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_unload_entry(
hass: HomeAssistant, entry: AlarmDecoderConfigEntry
) -> bool:
"""Unload a AlarmDecoder entry.""" """Unload a AlarmDecoder entry."""
hass.data[DOMAIN][entry.entry_id][DATA_RESTART] = False data = entry.runtime_data
data.restart = False
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if not unload_ok: if not unload_ok:
return False return False
hass.data[DOMAIN][entry.entry_id][DATA_REMOVE_UPDATE_LISTENER]() data.remove_update_listener()
hass.data[DOMAIN][entry.entry_id][DATA_REMOVE_STOP_LISTENER]() data.remove_stop_listener()
await hass.async_add_executor_job(hass.data[DOMAIN][entry.entry_id][DATA_AD].close) await hass.async_add_executor_job(data.client.close)
if hass.data[DOMAIN][entry.entry_id]:
hass.data[DOMAIN].pop(entry.entry_id)
if not hass.data[DOMAIN]:
hass.data.pop(DOMAIN)
return True return True
async def _update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None: async def _update_listener(hass: HomeAssistant, entry: AlarmDecoderConfigEntry) -> None:
"""Handle options update.""" """Handle options update."""
_LOGGER.debug("AlarmDecoder options updated: %s", entry.as_dict()["options"]) _LOGGER.debug("AlarmDecoder options updated: %s", entry.as_dict()["options"])
await hass.config_entries.async_reload(entry.entry_id) await hass.config_entries.async_reload(entry.entry_id)

View File

@ -9,7 +9,6 @@ from homeassistant.components.alarm_control_panel import (
AlarmControlPanelEntityFeature, AlarmControlPanelEntityFeature,
CodeFormat, CodeFormat,
) )
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
ATTR_CODE, ATTR_CODE,
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_AWAY,
@ -24,13 +23,12 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AlarmDecoderConfigEntry
from .const import ( from .const import (
CONF_ALT_NIGHT_MODE, CONF_ALT_NIGHT_MODE,
CONF_AUTO_BYPASS, CONF_AUTO_BYPASS,
CONF_CODE_ARM_REQUIRED, CONF_CODE_ARM_REQUIRED,
DATA_AD,
DEFAULT_ARM_OPTIONS, DEFAULT_ARM_OPTIONS,
DOMAIN,
OPTIONS_ARM, OPTIONS_ARM,
SIGNAL_PANEL_MESSAGE, SIGNAL_PANEL_MESSAGE,
) )
@ -43,15 +41,16 @@ ATTR_KEYPRESS = "keypress"
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant,
entry: AlarmDecoderConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up for AlarmDecoder alarm panels.""" """Set up for AlarmDecoder alarm panels."""
options = entry.options options = entry.options
arm_options = options.get(OPTIONS_ARM, DEFAULT_ARM_OPTIONS) arm_options = options.get(OPTIONS_ARM, DEFAULT_ARM_OPTIONS)
client = hass.data[DOMAIN][entry.entry_id][DATA_AD]
entity = AlarmDecoderAlarmPanel( entity = AlarmDecoderAlarmPanel(
client=client, client=entry.runtime_data.client,
auto_bypass=arm_options[CONF_AUTO_BYPASS], auto_bypass=arm_options[CONF_AUTO_BYPASS],
code_arm_required=arm_options[CONF_CODE_ARM_REQUIRED], code_arm_required=arm_options[CONF_CODE_ARM_REQUIRED],
alt_night_mode=arm_options[CONF_ALT_NIGHT_MODE], alt_night_mode=arm_options[CONF_ALT_NIGHT_MODE],

View File

@ -3,11 +3,11 @@
import logging import logging
from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AlarmDecoderConfigEntry
from .const import ( from .const import (
CONF_RELAY_ADDR, CONF_RELAY_ADDR,
CONF_RELAY_CHAN, CONF_RELAY_CHAN,
@ -16,9 +16,7 @@ from .const import (
CONF_ZONE_NUMBER, CONF_ZONE_NUMBER,
CONF_ZONE_RFID, CONF_ZONE_RFID,
CONF_ZONE_TYPE, CONF_ZONE_TYPE,
DATA_AD,
DEFAULT_ZONE_OPTIONS, DEFAULT_ZONE_OPTIONS,
DOMAIN,
OPTIONS_ZONES, OPTIONS_ZONES,
SIGNAL_REL_MESSAGE, SIGNAL_REL_MESSAGE,
SIGNAL_RFX_MESSAGE, SIGNAL_RFX_MESSAGE,
@ -40,11 +38,13 @@ ATTR_RF_LOOP1 = "rf_loop1"
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant,
entry: AlarmDecoderConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up for AlarmDecoder sensor.""" """Set up for AlarmDecoder sensor."""
client = hass.data[DOMAIN][entry.entry_id][DATA_AD] client = entry.runtime_data.client
zones = entry.options.get(OPTIONS_ZONES, DEFAULT_ZONE_OPTIONS) zones = entry.options.get(OPTIONS_ZONES, DEFAULT_ZONE_OPTIONS)
entities = [] entities = []

View File

@ -13,11 +13,6 @@ CONF_ZONE_NUMBER = "zone_number"
CONF_ZONE_RFID = "zone_rfid" CONF_ZONE_RFID = "zone_rfid"
CONF_ZONE_TYPE = "zone_type" CONF_ZONE_TYPE = "zone_type"
DATA_AD = "alarmdecoder"
DATA_REMOVE_STOP_LISTENER = "rm_stop_listener"
DATA_REMOVE_UPDATE_LISTENER = "rm_update_listener"
DATA_RESTART = "restart"
DEFAULT_ALT_NIGHT_MODE = False DEFAULT_ALT_NIGHT_MODE = False
DEFAULT_AUTO_BYPASS = False DEFAULT_AUTO_BYPASS = False
DEFAULT_CODE_ARM_REQUIRED = True DEFAULT_CODE_ARM_REQUIRED = True

View File

@ -1,22 +1,23 @@
"""Support for AlarmDecoder sensors (Shows Panel Display).""" """Support for AlarmDecoder sensors (Shows Panel Display)."""
from homeassistant.components.sensor import SensorEntity from homeassistant.components.sensor import SensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DATA_AD, DOMAIN, SIGNAL_PANEL_MESSAGE from . import AlarmDecoderConfigEntry
from .const import SIGNAL_PANEL_MESSAGE
from .entity import AlarmDecoderEntity from .entity import AlarmDecoderEntity
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant,
entry: AlarmDecoderConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up for AlarmDecoder sensor.""" """Set up for AlarmDecoder sensor."""
client = hass.data[DOMAIN][entry.entry_id][DATA_AD] entity = AlarmDecoderSensor(client=entry.runtime_data.client)
entity = AlarmDecoderSensor(client=client)
async_add_entities([entity]) async_add_entities([entity])