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:
parent
84df0efb5e
commit
632a36d819
7 changed files with 160 additions and 62 deletions
|
@ -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):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue