2019-02-13 20:21:14 +00:00
|
|
|
"""Support for AlarmDecoder zone states- represented as binary sensors."""
|
2017-04-12 09:35:35 +00:00
|
|
|
import logging
|
|
|
|
|
2020-04-23 19:57:07 +00:00
|
|
|
from homeassistant.components.binary_sensor import BinarySensorEntity
|
2019-03-21 05:56:46 +00:00
|
|
|
|
|
|
|
from . import (
|
2019-07-31 19:25:30 +00:00
|
|
|
CONF_RELAY_ADDR,
|
|
|
|
CONF_RELAY_CHAN,
|
|
|
|
CONF_ZONE_LOOP,
|
|
|
|
CONF_ZONE_NAME,
|
|
|
|
CONF_ZONE_RFID,
|
|
|
|
CONF_ZONE_TYPE,
|
|
|
|
CONF_ZONES,
|
|
|
|
SIGNAL_REL_MESSAGE,
|
|
|
|
SIGNAL_RFX_MESSAGE,
|
|
|
|
SIGNAL_ZONE_FAULT,
|
|
|
|
SIGNAL_ZONE_RESTORE,
|
|
|
|
ZONE_SCHEMA,
|
|
|
|
)
|
2017-04-12 09:35:35 +00:00
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
ATTR_RF_BIT0 = "rf_bit0"
|
|
|
|
ATTR_RF_LOW_BAT = "rf_low_battery"
|
|
|
|
ATTR_RF_SUPERVISED = "rf_supervised"
|
|
|
|
ATTR_RF_BIT3 = "rf_bit3"
|
|
|
|
ATTR_RF_LOOP3 = "rf_loop3"
|
|
|
|
ATTR_RF_LOOP2 = "rf_loop2"
|
|
|
|
ATTR_RF_LOOP4 = "rf_loop4"
|
|
|
|
ATTR_RF_LOOP1 = "rf_loop1"
|
2017-12-25 09:52:33 +00:00
|
|
|
|
2017-04-12 09:35:35 +00:00
|
|
|
|
2018-08-24 14:37:30 +00:00
|
|
|
def setup_platform(hass, config, add_entities, discovery_info=None):
|
2017-04-30 05:04:49 +00:00
|
|
|
"""Set up the AlarmDecoder binary sensor devices."""
|
2017-04-12 09:35:35 +00:00
|
|
|
configured_zones = discovery_info[CONF_ZONES]
|
|
|
|
|
|
|
|
devices = []
|
|
|
|
for zone_num in configured_zones:
|
|
|
|
device_config_data = ZONE_SCHEMA(configured_zones[zone_num])
|
|
|
|
zone_type = device_config_data[CONF_ZONE_TYPE]
|
|
|
|
zone_name = device_config_data[CONF_ZONE_NAME]
|
2017-12-25 09:52:33 +00:00
|
|
|
zone_rfid = device_config_data.get(CONF_ZONE_RFID)
|
2018-12-11 10:34:03 +00:00
|
|
|
zone_loop = device_config_data.get(CONF_ZONE_LOOP)
|
2018-07-21 15:31:07 +00:00
|
|
|
relay_addr = device_config_data.get(CONF_RELAY_ADDR)
|
|
|
|
relay_chan = device_config_data.get(CONF_RELAY_CHAN)
|
2017-12-25 09:52:33 +00:00
|
|
|
device = AlarmDecoderBinarySensor(
|
2019-07-31 19:25:30 +00:00
|
|
|
zone_num, zone_name, zone_type, zone_rfid, zone_loop, relay_addr, relay_chan
|
|
|
|
)
|
2017-04-12 09:35:35 +00:00
|
|
|
devices.append(device)
|
|
|
|
|
2018-08-24 14:37:30 +00:00
|
|
|
add_entities(devices)
|
2017-04-12 09:35:35 +00:00
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
2020-04-23 19:57:07 +00:00
|
|
|
class AlarmDecoderBinarySensor(BinarySensorEntity):
|
2017-04-12 09:35:35 +00:00
|
|
|
"""Representation of an AlarmDecoder binary sensor."""
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
zone_number,
|
|
|
|
zone_name,
|
|
|
|
zone_type,
|
|
|
|
zone_rfid,
|
|
|
|
zone_loop,
|
|
|
|
relay_addr,
|
|
|
|
relay_chan,
|
|
|
|
):
|
2017-04-12 09:35:35 +00:00
|
|
|
"""Initialize the binary_sensor."""
|
|
|
|
self._zone_number = zone_number
|
|
|
|
self._zone_type = zone_type
|
2017-12-25 09:52:33 +00:00
|
|
|
self._state = None
|
2017-04-12 09:35:35 +00:00
|
|
|
self._name = zone_name
|
2017-12-25 09:52:33 +00:00
|
|
|
self._rfid = zone_rfid
|
2018-12-11 10:34:03 +00:00
|
|
|
self._loop = zone_loop
|
2017-12-25 09:52:33 +00:00
|
|
|
self._rfstate = None
|
2018-07-21 15:31:07 +00:00
|
|
|
self._relay_addr = relay_addr
|
|
|
|
self._relay_chan = relay_chan
|
2017-04-12 09:35:35 +00:00
|
|
|
|
2018-10-01 06:49:19 +00:00
|
|
|
async def async_added_to_hass(self):
|
2017-04-12 09:35:35 +00:00
|
|
|
"""Register callbacks."""
|
2020-04-02 16:25:33 +00:00
|
|
|
self.async_on_remove(
|
|
|
|
self.hass.helpers.dispatcher.async_dispatcher_connect(
|
|
|
|
SIGNAL_ZONE_FAULT, self._fault_callback
|
|
|
|
)
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
2017-04-12 09:35:35 +00:00
|
|
|
|
2020-04-02 16:25:33 +00:00
|
|
|
self.async_on_remove(
|
|
|
|
self.hass.helpers.dispatcher.async_dispatcher_connect(
|
|
|
|
SIGNAL_ZONE_RESTORE, self._restore_callback
|
|
|
|
)
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
2017-04-12 09:35:35 +00:00
|
|
|
|
2020-04-02 16:25:33 +00:00
|
|
|
self.async_on_remove(
|
|
|
|
self.hass.helpers.dispatcher.async_dispatcher_connect(
|
|
|
|
SIGNAL_RFX_MESSAGE, self._rfx_message_callback
|
|
|
|
)
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
2017-12-25 09:52:33 +00:00
|
|
|
|
2020-04-02 16:25:33 +00:00
|
|
|
self.async_on_remove(
|
|
|
|
self.hass.helpers.dispatcher.async_dispatcher_connect(
|
|
|
|
SIGNAL_REL_MESSAGE, self._rel_message_callback
|
|
|
|
)
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
2018-07-21 15:31:07 +00:00
|
|
|
|
2017-04-12 09:35:35 +00:00
|
|
|
@property
|
|
|
|
def name(self):
|
|
|
|
"""Return the name of the entity."""
|
|
|
|
return self._name
|
|
|
|
|
|
|
|
@property
|
|
|
|
def should_poll(self):
|
|
|
|
"""No polling needed."""
|
|
|
|
return False
|
|
|
|
|
2017-12-25 09:52:33 +00:00
|
|
|
@property
|
|
|
|
def device_state_attributes(self):
|
|
|
|
"""Return the state attributes."""
|
|
|
|
attr = {}
|
|
|
|
if self._rfid and self._rfstate is not None:
|
2018-12-06 10:54:44 +00:00
|
|
|
attr[ATTR_RF_BIT0] = bool(self._rfstate & 0x01)
|
|
|
|
attr[ATTR_RF_LOW_BAT] = bool(self._rfstate & 0x02)
|
|
|
|
attr[ATTR_RF_SUPERVISED] = bool(self._rfstate & 0x04)
|
|
|
|
attr[ATTR_RF_BIT3] = bool(self._rfstate & 0x08)
|
|
|
|
attr[ATTR_RF_LOOP3] = bool(self._rfstate & 0x10)
|
|
|
|
attr[ATTR_RF_LOOP2] = bool(self._rfstate & 0x20)
|
|
|
|
attr[ATTR_RF_LOOP4] = bool(self._rfstate & 0x40)
|
|
|
|
attr[ATTR_RF_LOOP1] = bool(self._rfstate & 0x80)
|
2017-12-25 09:52:33 +00:00
|
|
|
return attr
|
|
|
|
|
2017-04-12 09:35:35 +00:00
|
|
|
@property
|
|
|
|
def is_on(self):
|
|
|
|
"""Return true if sensor is on."""
|
|
|
|
return self._state == 1
|
|
|
|
|
|
|
|
@property
|
|
|
|
def device_class(self):
|
|
|
|
"""Return the class of this sensor, from DEVICE_CLASSES."""
|
|
|
|
return self._zone_type
|
|
|
|
|
|
|
|
def _fault_callback(self, zone):
|
|
|
|
"""Update the zone's state, if needed."""
|
|
|
|
if zone is None or int(zone) == self._zone_number:
|
|
|
|
self._state = 1
|
2017-12-16 23:52:59 +00:00
|
|
|
self.schedule_update_ha_state()
|
2017-04-12 09:35:35 +00:00
|
|
|
|
|
|
|
def _restore_callback(self, zone):
|
|
|
|
"""Update the zone's state, if needed."""
|
2020-02-08 13:32:52 +00:00
|
|
|
if zone is None or (int(zone) == self._zone_number and not self._loop):
|
2017-04-12 09:35:35 +00:00
|
|
|
self._state = 0
|
2017-12-16 23:52:59 +00:00
|
|
|
self.schedule_update_ha_state()
|
2017-12-25 09:52:33 +00:00
|
|
|
|
|
|
|
def _rfx_message_callback(self, message):
|
|
|
|
"""Update RF state."""
|
|
|
|
if self._rfid and message and message.serial_number == self._rfid:
|
|
|
|
self._rfstate = message.value
|
2018-12-11 10:34:03 +00:00
|
|
|
if self._loop:
|
|
|
|
self._state = 1 if message.loop[self._loop - 1] else 0
|
2017-12-25 09:52:33 +00:00
|
|
|
self.schedule_update_ha_state()
|
2018-07-21 15:31:07 +00:00
|
|
|
|
|
|
|
def _rel_message_callback(self, message):
|
2019-10-04 01:01:06 +00:00
|
|
|
"""Update relay / expander state."""
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
if self._relay_addr == message.address and self._relay_chan == message.channel:
|
|
|
|
_LOGGER.debug(
|
2019-10-04 01:01:06 +00:00
|
|
|
"%s %d:%d value:%d",
|
|
|
|
"Relay" if message.type == message.RELAY else "ZoneExpander",
|
|
|
|
message.address,
|
|
|
|
message.channel,
|
|
|
|
message.value,
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
2018-07-21 15:31:07 +00:00
|
|
|
self._state = message.value
|
|
|
|
self.schedule_update_ha_state()
|