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
|
|
|
|
|
|
|
|
from homeassistant.components.binary_sensor import BinarySensorDevice
|
2017-12-16 23:52:59 +00:00
|
|
|
from homeassistant.components.alarmdecoder import (
|
|
|
|
ZONE_SCHEMA, CONF_ZONES, CONF_ZONE_NAME, CONF_ZONE_TYPE,
|
2018-12-11 10:34:03 +00:00
|
|
|
CONF_ZONE_RFID, CONF_ZONE_LOOP, SIGNAL_ZONE_FAULT, SIGNAL_ZONE_RESTORE,
|
2018-07-21 15:31:07 +00:00
|
|
|
SIGNAL_RFX_MESSAGE, SIGNAL_REL_MESSAGE, CONF_RELAY_ADDR,
|
|
|
|
CONF_RELAY_CHAN)
|
2017-04-12 09:35:35 +00:00
|
|
|
|
|
|
|
DEPENDENCIES = ['alarmdecoder']
|
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
2017-12-25 09:52:33 +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-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(
|
2018-12-11 10:34:03 +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
|
|
|
|
|
|
|
|
|
|
|
|
class AlarmDecoderBinarySensor(BinarySensorDevice):
|
|
|
|
"""Representation of an AlarmDecoder binary sensor."""
|
|
|
|
|
2018-12-11 10:34:03 +00:00
|
|
|
def __init__(self, zone_number, zone_name, zone_type, zone_rfid, zone_loop,
|
2018-07-21 15:31:07 +00:00
|
|
|
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."""
|
2017-12-16 23:52:59 +00:00
|
|
|
self.hass.helpers.dispatcher.async_dispatcher_connect(
|
|
|
|
SIGNAL_ZONE_FAULT, self._fault_callback)
|
2017-04-12 09:35:35 +00:00
|
|
|
|
2017-12-16 23:52:59 +00:00
|
|
|
self.hass.helpers.dispatcher.async_dispatcher_connect(
|
|
|
|
SIGNAL_ZONE_RESTORE, self._restore_callback)
|
2017-04-12 09:35:35 +00:00
|
|
|
|
2017-12-25 09:52:33 +00:00
|
|
|
self.hass.helpers.dispatcher.async_dispatcher_connect(
|
|
|
|
SIGNAL_RFX_MESSAGE, self._rfx_message_callback)
|
|
|
|
|
2018-07-21 15:31:07 +00:00
|
|
|
self.hass.helpers.dispatcher.async_dispatcher_connect(
|
|
|
|
SIGNAL_REL_MESSAGE, self._rel_message_callback)
|
|
|
|
|
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."""
|
|
|
|
if zone is None or int(zone) == self._zone_number:
|
|
|
|
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):
|
|
|
|
"""Update relay state."""
|
|
|
|
if (self._relay_addr == message.address and
|
|
|
|
self._relay_chan == message.channel):
|
|
|
|
_LOGGER.debug("Relay %d:%d value:%d", message.address,
|
|
|
|
message.channel, message.value)
|
|
|
|
self._state = message.value
|
|
|
|
self.schedule_update_ha_state()
|