98 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Python
		
	
	
"""Support for Envisalink zone states- represented as binary sensors."""
 | 
						|
import datetime
 | 
						|
import logging
 | 
						|
 | 
						|
from homeassistant.components.binary_sensor import BinarySensorEntity
 | 
						|
from homeassistant.const import ATTR_LAST_TRIP_TIME
 | 
						|
from homeassistant.core import callback
 | 
						|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
 | 
						|
from homeassistant.util import dt as dt_util
 | 
						|
 | 
						|
from . import (
 | 
						|
    CONF_ZONENAME,
 | 
						|
    CONF_ZONETYPE,
 | 
						|
    DATA_EVL,
 | 
						|
    SIGNAL_ZONE_UPDATE,
 | 
						|
    ZONE_SCHEMA,
 | 
						|
    EnvisalinkDevice,
 | 
						|
)
 | 
						|
 | 
						|
_LOGGER = logging.getLogger(__name__)
 | 
						|
 | 
						|
 | 
						|
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
 | 
						|
    """Set up the Envisalink binary sensor devices."""
 | 
						|
    configured_zones = discovery_info["zones"]
 | 
						|
 | 
						|
    devices = []
 | 
						|
    for zone_num in configured_zones:
 | 
						|
        device_config_data = ZONE_SCHEMA(configured_zones[zone_num])
 | 
						|
        device = EnvisalinkBinarySensor(
 | 
						|
            hass,
 | 
						|
            zone_num,
 | 
						|
            device_config_data[CONF_ZONENAME],
 | 
						|
            device_config_data[CONF_ZONETYPE],
 | 
						|
            hass.data[DATA_EVL].alarm_state["zone"][zone_num],
 | 
						|
            hass.data[DATA_EVL],
 | 
						|
        )
 | 
						|
        devices.append(device)
 | 
						|
 | 
						|
    async_add_entities(devices)
 | 
						|
 | 
						|
 | 
						|
class EnvisalinkBinarySensor(EnvisalinkDevice, BinarySensorEntity):
 | 
						|
    """Representation of an Envisalink binary sensor."""
 | 
						|
 | 
						|
    def __init__(self, hass, zone_number, zone_name, zone_type, info, controller):
 | 
						|
        """Initialize the binary_sensor."""
 | 
						|
        self._zone_type = zone_type
 | 
						|
        self._zone_number = zone_number
 | 
						|
 | 
						|
        _LOGGER.debug("Setting up zone: %s", zone_name)
 | 
						|
        super().__init__(zone_name, info, controller)
 | 
						|
 | 
						|
    async def async_added_to_hass(self):
 | 
						|
        """Register callbacks."""
 | 
						|
        async_dispatcher_connect(self.hass, SIGNAL_ZONE_UPDATE, self._update_callback)
 | 
						|
 | 
						|
    @property
 | 
						|
    def extra_state_attributes(self):
 | 
						|
        """Return the state attributes."""
 | 
						|
        attr = {}
 | 
						|
 | 
						|
        # The Envisalink library returns a "last_fault" value that's the
 | 
						|
        # number of seconds since the last fault, up to a maximum of 327680
 | 
						|
        # seconds (65536 5-second ticks).
 | 
						|
        #
 | 
						|
        # We don't want the HA event log to fill up with a bunch of no-op
 | 
						|
        # "state changes" that are just that number ticking up once per poll
 | 
						|
        # interval, so we subtract it from the current second-accurate time
 | 
						|
        # unless it is already at the maximum value, in which case we set it
 | 
						|
        # to None since we can't determine the actual value.
 | 
						|
        seconds_ago = self._info["last_fault"]
 | 
						|
        if seconds_ago < 65536 * 5:
 | 
						|
            now = dt_util.now().replace(microsecond=0)
 | 
						|
            delta = datetime.timedelta(seconds=seconds_ago)
 | 
						|
            last_trip_time = (now - delta).isoformat()
 | 
						|
        else:
 | 
						|
            last_trip_time = None
 | 
						|
 | 
						|
        attr[ATTR_LAST_TRIP_TIME] = last_trip_time
 | 
						|
        return attr
 | 
						|
 | 
						|
    @property
 | 
						|
    def is_on(self):
 | 
						|
        """Return true if sensor is on."""
 | 
						|
        return self._info["status"]["open"]
 | 
						|
 | 
						|
    @property
 | 
						|
    def device_class(self):
 | 
						|
        """Return the class of this sensor, from DEVICE_CLASSES."""
 | 
						|
        return self._zone_type
 | 
						|
 | 
						|
    @callback
 | 
						|
    def _update_callback(self, zone):
 | 
						|
        """Update the zone's state, if needed."""
 | 
						|
        if zone is None or int(zone) == self._zone_number:
 | 
						|
            self.async_write_ha_state()
 |