Support rfxtrx smoke detectors, motion sensors as binary_sensors (#38000)

* Add binary sensor support to motion sensors and smoke detectors

* Add support for new sensor events as binary sensors

Adds a default device_class for motion sensors and smoke detector

* Use device type instead of event to set class

* Add some additional binary values
This commit is contained in:
Joakim Plate 2020-07-24 17:16:41 +02:00 committed by GitHub
parent 84df0efb5e
commit 632a36d819
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 160 additions and 62 deletions

View file

@ -3,7 +3,11 @@ import logging
import RFXtrx as rfxtrxmod
from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.components.binary_sensor import (
DEVICE_CLASS_MOTION,
DEVICE_CLASS_SMOKE,
BinarySensorEntity,
)
from homeassistant.const import (
CONF_COMMAND_OFF,
CONF_COMMAND_ON,
@ -34,6 +38,33 @@ from .const import (
_LOGGER = logging.getLogger(__name__)
SENSOR_STATUS_ON = [
"Panic",
"Motion",
"Motion Tamper",
"Light Detected",
"Alarm",
"Alarm Tamper",
]
SENSOR_STATUS_OFF = [
"End Panic",
"No Motion",
"No Motion Tamper",
"Dark Detected",
"Normal",
"Normal Tamper",
]
DEVICE_TYPE_DEVICE_CLASS = {
"X10 Security Motion Detector": DEVICE_CLASS_MOTION,
"KD101 Smoke Detector": DEVICE_CLASS_SMOKE,
"Visonic Powercode Motion Detector": DEVICE_CLASS_MOTION,
"Alecto SA30 Smoke Detector": DEVICE_CLASS_SMOKE,
"RM174RF Smoke Detector": DEVICE_CLASS_SMOKE,
}
async def async_setup_entry(
hass, config_entry, async_add_entities,
):
@ -46,7 +77,14 @@ async def async_setup_entry(
discovery_info = config_entry.data
def supported(event):
return isinstance(event, rfxtrxmod.ControlEvent)
if isinstance(event, rfxtrxmod.ControlEvent):
return True
if isinstance(event, rfxtrxmod.SensorEvent):
return event.values.get("Sensor Status") in [
*SENSOR_STATUS_ON,
*SENSOR_STATUS_OFF,
]
return False
for packet_id, entity_info in discovery_info[CONF_DEVICES].items():
event = get_rfx_object(packet_id)
@ -70,7 +108,10 @@ async def async_setup_entry(
device = RfxtrxBinarySensor(
event.device,
device_id,
entity_info.get(CONF_DEVICE_CLASS),
entity_info.get(
CONF_DEVICE_CLASS,
DEVICE_TYPE_DEVICE_CLASS.get(event.device.type_string),
),
entity_info.get(CONF_OFF_DELAY),
entity_info.get(CONF_DATA_BITS),
entity_info.get(CONF_COMMAND_ON),
@ -97,7 +138,12 @@ async def async_setup_entry(
event.device.subtype,
"".join(f"{x:02x}" for x in event.data),
)
sensor = RfxtrxBinarySensor(event.device, device_id, event=event)
sensor = RfxtrxBinarySensor(
event.device,
device_id,
event=event,
device_class=DEVICE_TYPE_DEVICE_CLASS.get(event.device.type_string),
)
async_add_entities([sensor])
# Subscribe to main RFXtrx events
@ -170,9 +216,13 @@ class RfxtrxBinarySensor(RfxtrxEntity, BinarySensorEntity):
self._state = True
def _apply_event_standard(self, event):
if event.values["Command"] in COMMAND_ON_LIST:
if event.values.get("Command") in COMMAND_ON_LIST:
self._state = True
elif event.values["Command"] in COMMAND_OFF_LIST:
elif event.values.get("Command") in COMMAND_OFF_LIST:
self._state = False
elif event.values.get("Sensor Status") in SENSOR_STATUS_ON:
self._state = True
elif event.values.get("Sensor Status") in SENSOR_STATUS_OFF:
self._state = False
def _apply_event(self, event):
@ -200,7 +250,11 @@ class RfxtrxBinarySensor(RfxtrxEntity, BinarySensorEntity):
self.async_write_ha_state()
if self.is_on and self._off_delay is not None and self._delay_listener is None:
if self._delay_listener:
self._delay_listener()
self._delay_listener = None
if self.is_on and self._off_delay is not None:
@callback
def off_delay_listener(now):