1 """Support for AlarmDecoder devices."""
3 from collections.abc
import Callable
4 from dataclasses
import dataclass
5 from datetime
import timedelta
8 from adext
import AdExt
9 from alarmdecoder.devices
import SerialDevice, SocketDevice
10 from alarmdecoder.util
import NoDeviceError
17 EVENT_HOMEASSISTANT_STOP,
36 _LOGGER = logging.getLogger(__name__)
39 Platform.ALARM_CONTROL_PANEL,
40 Platform.BINARY_SENSOR,
44 type AlarmDecoderConfigEntry = ConfigEntry[AlarmDecoderData]
49 """Runtime data for the AlarmDecoder class."""
52 remove_update_listener: Callable[[],
None]
53 remove_stop_listener: Callable[[],
None]
58 hass: HomeAssistant, entry: AlarmDecoderConfigEntry
60 """Set up AlarmDecoder config flow."""
61 undo_listener = entry.add_update_listener(_update_listener)
63 ad_connection = entry.data
64 protocol = ad_connection[CONF_PROTOCOL]
66 def stop_alarmdecoder(event):
67 """Handle the shutdown of AlarmDecoder."""
68 if not entry.runtime_data:
70 _LOGGER.debug(
"Shutting down alarmdecoder")
71 entry.runtime_data.restart =
False
74 async
def open_connection(now=None):
75 """Open a connection to AlarmDecoder."""
77 await hass.async_add_executor_job(controller.open, baud)
79 _LOGGER.debug(
"Failed to connect. Retrying in 5 seconds")
82 _LOGGER.debug(
"Established a connection with the alarmdecoder")
83 entry.runtime_data.restart =
True
85 def handle_closed_connection(event):
86 """Restart after unexpected loss of connection."""
87 if not entry.runtime_data.restart:
89 entry.runtime_data.restart =
False
90 _LOGGER.warning(
"AlarmDecoder unexpectedly lost connection")
91 hass.add_job(open_connection)
93 def handle_message(sender, message):
94 """Handle message from AlarmDecoder."""
97 def handle_rfx_message(sender, message):
98 """Handle RFX message from AlarmDecoder."""
101 def zone_fault_callback(sender, zone):
102 """Handle zone fault from AlarmDecoder."""
105 def zone_restore_callback(sender, zone):
106 """Handle zone restore from AlarmDecoder."""
109 def handle_rel_message(sender, message):
110 """Handle relay or zone expander message from AlarmDecoder."""
113 baud = ad_connection.get(CONF_DEVICE_BAUD)
114 if protocol == PROTOCOL_SOCKET:
115 host = ad_connection[CONF_HOST]
116 port = ad_connection[CONF_PORT]
117 controller = AdExt(SocketDevice(interface=(host, port)))
118 if protocol == PROTOCOL_SERIAL:
119 path = ad_connection[CONF_DEVICE_PATH]
120 controller = AdExt(SerialDevice(interface=path))
122 controller.on_message += handle_message
123 controller.on_rfx_message += handle_rfx_message
124 controller.on_zone_fault += zone_fault_callback
125 controller.on_zone_restore += zone_restore_callback
126 controller.on_close += handle_closed_connection
127 controller.on_expander_message += handle_rel_message
129 remove_stop_listener = hass.bus.async_listen_once(
130 EVENT_HOMEASSISTANT_STOP, stop_alarmdecoder
134 controller, undo_listener, remove_stop_listener,
False
137 await open_connection()
139 await controller.is_init()
141 await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
147 hass: HomeAssistant, entry: AlarmDecoderConfigEntry
149 """Unload a AlarmDecoder entry."""
150 data = entry.runtime_data
153 unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
158 data.remove_update_listener()
159 data.remove_stop_listener()
160 await hass.async_add_executor_job(data.client.close)
166 """Handle options update."""
167 _LOGGER.debug(
"AlarmDecoder options updated: %s", entry.as_dict()[
"options"])
168 await hass.config_entries.async_reload(entry.entry_id)
None _update_listener(HomeAssistant hass, AlarmDecoderConfigEntry entry)
bool async_setup_entry(HomeAssistant hass, AlarmDecoderConfigEntry entry)
bool async_unload_entry(HomeAssistant hass, AlarmDecoderConfigEntry entry)
None dispatcher_send(HomeAssistant hass, str signal, *Any args)
CALLBACK_TYPE async_call_later(HomeAssistant hass, float|timedelta delay, HassJob[[datetime], Coroutine[Any, Any, None]|None]|Callable[[datetime], Coroutine[Any, Any, None]|None] action)