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."""
from collections.abc import Callable
from dataclasses import dataclass
from datetime import timedelta
import logging
@ -22,11 +24,6 @@ from homeassistant.helpers.event import async_call_later
from .const import (
CONF_DEVICE_BAUD,
CONF_DEVICE_PATH,
DATA_AD,
DATA_REMOVE_STOP_LISTENER,
DATA_REMOVE_UPDATE_LISTENER,
DATA_RESTART,
DOMAIN,
PROTOCOL_SERIAL,
PROTOCOL_SOCKET,
SIGNAL_PANEL_MESSAGE,
@ -44,8 +41,22 @@ PLATFORMS = [
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."""
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):
"""Handle the shutdown of AlarmDecoder."""
if not hass.data.get(DOMAIN):
if not entry.runtime_data:
return
_LOGGER.debug("Shutting down alarmdecoder")
hass.data[DOMAIN][entry.entry_id][DATA_RESTART] = False
entry.runtime_data.restart = False
controller.close()
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)
return
_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):
"""Restart after unexpected loss of connection."""
if not hass.data[DOMAIN][entry.entry_id][DATA_RESTART]:
if not entry.runtime_data.restart:
return
hass.data[DOMAIN][entry.entry_id][DATA_RESTART] = False
entry.runtime_data.restart = False
_LOGGER.warning("AlarmDecoder unexpectedly lost 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
)
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.entry_id] = {
DATA_AD: controller,
DATA_REMOVE_UPDATE_LISTENER: undo_listener,
DATA_REMOVE_STOP_LISTENER: remove_stop_listener,
DATA_RESTART: False,
}
entry.runtime_data = AlarmDecoderData(
controller, undo_listener, remove_stop_listener, False
)
await open_connection()
@ -136,28 +143,26 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
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."""
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)
if not unload_ok:
return False
hass.data[DOMAIN][entry.entry_id][DATA_REMOVE_UPDATE_LISTENER]()
hass.data[DOMAIN][entry.entry_id][DATA_REMOVE_STOP_LISTENER]()
await hass.async_add_executor_job(hass.data[DOMAIN][entry.entry_id][DATA_AD].close)
if hass.data[DOMAIN][entry.entry_id]:
hass.data[DOMAIN].pop(entry.entry_id)
if not hass.data[DOMAIN]:
hass.data.pop(DOMAIN)
data.remove_update_listener()
data.remove_stop_listener()
await hass.async_add_executor_job(data.client.close)
return True
async def _update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None:
async def _update_listener(hass: HomeAssistant, entry: AlarmDecoderConfigEntry) -> None:
"""Handle options update."""
_LOGGER.debug("AlarmDecoder options updated: %s", entry.as_dict()["options"])
await hass.config_entries.async_reload(entry.entry_id)

View File

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

View File

@ -3,11 +3,11 @@
import logging
from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AlarmDecoderConfigEntry
from .const import (
CONF_RELAY_ADDR,
CONF_RELAY_CHAN,
@ -16,9 +16,7 @@ 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,
@ -40,11 +38,13 @@ ATTR_RF_LOOP1 = "rf_loop1"
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
hass: HomeAssistant,
entry: AlarmDecoderConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""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)
entities = []

View File

@ -13,11 +13,6 @@ CONF_ZONE_NUMBER = "zone_number"
CONF_ZONE_RFID = "zone_rfid"
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_AUTO_BYPASS = False
DEFAULT_CODE_ARM_REQUIRED = True

View File

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