Split handling and application of event (#37665)

This way _handle_event can contain things available
when entity has been added to home assistant,
and _apply event can remain internal and used on init.
pull/37690/head
Joakim Plate 2020-07-09 11:40:37 +02:00 committed by GitHub
parent 155a5f7c26
commit a3310330f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 127 additions and 123 deletions

View File

@ -270,7 +270,9 @@ def get_devices_from_config(config, device):
fire_event = entity_info[ATTR_FIRE_EVENT]
datas = {ATTR_STATE: False, ATTR_FIRE_EVENT: fire_event}
new_device = device(entity_info[ATTR_NAME], event, datas, signal_repetitions)
new_device = device(
entity_info[ATTR_NAME], event.device, datas, signal_repetitions
)
RFX_DEVICES[device_id] = new_device
devices.append(new_device)
return devices
@ -295,7 +297,7 @@ def get_new_device(event, config, device):
)
datas = {ATTR_STATE: False, ATTR_FIRE_EVENT: False}
signal_repetitions = config[CONF_SIGNAL_REPETITIONS]
new_device = device(pkt_id, event, datas, signal_repetitions)
new_device = device(pkt_id, event.device, datas, signal_repetitions, event=event)
RFX_DEVICES[device_id] = new_device
return new_device
@ -321,14 +323,17 @@ class RfxtrxDevice(Entity):
Contains the common logic for Rfxtrx lights and switches.
"""
def __init__(self, name, event, datas, signal_repetitions):
def __init__(self, name, device, datas, signal_repetitions, event=None):
"""Initialize the device."""
self.signal_repetitions = signal_repetitions
self._name = name
self._event = event
self._device = device
self._state = datas[ATTR_STATE]
self._should_fire_event = datas[ATTR_FIRE_EVENT]
self._unique_id = f"{event.device.packettype:x}_{event.device.subtype:x}_{event.device.id_string}"
self._unique_id = f"{device.packettype:x}_{device.subtype:x}_{device.id_string}"
if event:
self._apply_event(event)
@property
def should_poll(self):
@ -364,38 +369,36 @@ class RfxtrxDevice(Entity):
"""Apply a received event."""
def _send_command(self, command, brightness=0):
if not self._event:
return
rfx_object = self.hass.data[DATA_RFXOBJECT]
if command == "turn_on":
for _ in range(self.signal_repetitions):
self._event.device.send_on(rfx_object.transport)
self._device.send_on(rfx_object.transport)
self._state = True
elif command == "dim":
for _ in range(self.signal_repetitions):
self._event.device.send_dim(rfx_object.transport, brightness)
self._device.send_dim(rfx_object.transport, brightness)
self._state = True
elif command == "turn_off":
for _ in range(self.signal_repetitions):
self._event.device.send_off(rfx_object.transport)
self._device.send_off(rfx_object.transport)
self._state = False
elif command == "roll_up":
for _ in range(self.signal_repetitions):
self._event.device.send_open(rfx_object.transport)
self._device.send_open(rfx_object.transport)
self._state = True
elif command == "roll_down":
for _ in range(self.signal_repetitions):
self._event.device.send_close(rfx_object.transport)
self._device.send_close(rfx_object.transport)
self._state = False
elif command == "stop_roll":
for _ in range(self.signal_repetitions):
self._event.device.send_stop(rfx_object.transport)
self._device.send_stop(rfx_object.transport)
self._state = True
if self.hass:

View File

@ -85,7 +85,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
)
device = RfxtrxBinarySensor(
event,
event.device,
entity.get(CONF_NAME),
entity.get(CONF_DEVICE_CLASS),
entity[CONF_FIRE_EVENT],
@ -120,8 +120,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
_LOGGER.debug("Found possible matching device ID: %s", poss_id)
pkt_id = "".join(f"{x:02x}" for x in event.data)
sensor = RfxtrxBinarySensor(event, pkt_id)
sensor.apply_event(event)
sensor = RfxtrxBinarySensor(event.device, pkt_id, event=event)
RFX_DEVICES[device_id] = sensor
add_entities([sensor])
_LOGGER.info(
@ -141,7 +140,7 @@ class RfxtrxBinarySensor(BinarySensorEntity):
def __init__(
self,
event,
device,
name,
device_class=None,
should_fire=False,
@ -149,55 +148,43 @@ class RfxtrxBinarySensor(BinarySensorEntity):
data_bits=None,
cmd_on=None,
cmd_off=None,
event=None,
):
"""Initialize the RFXtrx sensor."""
self.event = event
self.event = None
self._device = device
self._name = name
self._should_fire_event = should_fire
self._device_class = device_class
self._off_delay = off_delay
self._state = False
self.is_lighting4 = event.device.packettype == 0x13
self.is_lighting4 = device.packettype == 0x13
self.delay_listener = None
self._data_bits = data_bits
self._cmd_on = cmd_on
self._cmd_off = cmd_off
if data_bits is not None:
self._masked_id = get_pt2262_deviceid(
event.device.id_string.lower(), data_bits
self._masked_id = get_pt2262_deviceid(device.id_string.lower(), data_bits)
self._unique_id = (
f"{device.packettype:x}_{device.subtype:x}_{self._masked_id}"
)
self._unique_id = f"{event.device.packettype:x}_{event.device.subtype:x}_{self._masked_id}"
else:
self._masked_id = None
self._unique_id = f"{event.device.packettype:x}_{event.device.subtype:x}_{event.device.id_string}"
self._unique_id = (
f"{device.packettype:x}_{device.subtype:x}_{device.id_string}"
)
if event:
self._apply_event(event)
async def async_added_to_hass(self):
"""Restore RFXtrx switch device state (ON/OFF)."""
await super().async_added_to_hass()
def _handle_event(event):
"""Check if event applies to me and update."""
if self._masked_id:
masked_id = get_pt2262_deviceid(event.device.id_string, self._data_bits)
if masked_id != self._masked_id:
return
else:
if event.device.id_string != self.event.device.id_string:
return
_LOGGER.debug(
"Binary sensor update (Device ID: %s Class: %s Sub: %s)",
event.device.id_string,
event.device.__class__.__name__,
event.device.subtype,
)
self.apply_event(event)
self.async_on_remove(
self.hass.helpers.dispatcher.async_dispatcher_connect(
SIGNAL_EVENT, _handle_event
SIGNAL_EVENT, self._handle_event
)
)
@ -274,17 +261,35 @@ class RfxtrxBinarySensor(BinarySensorEntity):
elif event.values["Command"] in COMMAND_OFF_LIST:
self._state = False
def apply_event(self, event):
def _apply_event(self, event):
"""Apply command from rfxtrx."""
if self.is_lighting4:
self._apply_event_lighting4(event)
else:
self._apply_event_standard(event)
if self.hass:
self.schedule_update_ha_state()
if self.should_fire_event:
fire_command_event(self.hass, self.entity_id, event.values["Command"])
def _handle_event(self, event):
"""Check if event applies to me and update."""
if self._masked_id:
masked_id = get_pt2262_deviceid(event.device.id_string, self._data_bits)
if masked_id != self._masked_id:
return
else:
if event.device.id_string != self._device.id_string:
return
_LOGGER.debug(
"Binary sensor update (Device ID: %s Class: %s Sub: %s)",
event.device.id_string,
event.device.__class__.__name__,
event.device.subtype,
)
self._apply_event(event)
self.schedule_update_ha_state()
if self.should_fire_event:
fire_command_event(self.hass, self.entity_id, event.values["Command"])
if self.is_on and self.off_delay is not None and self.delay_listener is None:
@ -292,8 +297,7 @@ class RfxtrxBinarySensor(BinarySensorEntity):
"""Switch device off after a delay."""
self.delay_listener = None
self._state = False
if self.hass:
self.schedule_update_ha_state()
self.schedule_update_ha_state()
self.delay_listener = evt.call_later(
self.hass, self.off_delay.total_seconds(), off_delay_listener

View File

@ -55,7 +55,6 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
new_device = get_new_device(event, config, RfxtrxCover)
if new_device:
new_device.apply_event(event)
add_entities([new_device])
# Subscribe to main RFXtrx events
@ -73,16 +72,9 @@ class RfxtrxCover(RfxtrxDevice, CoverEntity, RestoreEntity):
if old_state is not None:
self._state = old_state.state == STATE_OPEN
def _handle_event(event):
"""Check if event applies to me and update."""
if event.device.id_string != self._event.device.id_string:
return
self.apply_event(event)
self.async_on_remove(
self.hass.helpers.dispatcher.async_dispatcher_connect(
SIGNAL_EVENT, _handle_event
SIGNAL_EVENT, self._handle_event
)
)
@ -108,14 +100,20 @@ class RfxtrxCover(RfxtrxDevice, CoverEntity, RestoreEntity):
"""Stop the cover."""
self._send_command("stop_roll")
def apply_event(self, event):
def _apply_event(self, event):
"""Apply command from rfxtrx."""
if event.values["Command"] in COMMAND_ON_LIST:
self._state = True
elif event.values["Command"] in COMMAND_OFF_LIST:
self._state = False
if self.hass:
self.schedule_update_ha_state()
if self.should_fire_event:
fire_command_event(self.hass, self.entity_id, event.values["Command"])
def _handle_event(self, event):
"""Check if event applies to me and update."""
if event.device.id_string != self._device.id_string:
return
self._apply_event(event)
self.schedule_update_ha_state()
if self.should_fire_event:
fire_command_event(self.hass, self.entity_id, event.values["Command"])

View File

@ -65,7 +65,6 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
new_device = get_new_device(event, config, RfxtrxLight)
if new_device:
new_device.apply_event(event)
add_entities([new_device])
# Subscribe to main RFXtrx events
@ -92,16 +91,9 @@ class RfxtrxLight(RfxtrxDevice, LightEntity, RestoreEntity):
):
self._brightness = int(old_state.attributes[ATTR_BRIGHTNESS])
def _handle_event(event):
"""Check if event applies to me and update."""
if event.device.id_string != self._event.device.id_string:
return
self.apply_event(event)
self.async_on_remove(
self.hass.helpers.dispatcher.async_dispatcher_connect(
SIGNAL_EVENT, _handle_event
SIGNAL_EVENT, self._handle_event
)
)
@ -131,7 +123,7 @@ class RfxtrxLight(RfxtrxDevice, LightEntity, RestoreEntity):
self._brightness = 0
self._send_command("turn_off")
def apply_event(self, event):
def _apply_event(self, event):
"""Apply command from rfxtrx."""
if event.values["Command"] in COMMAND_ON_LIST:
self._state = True
@ -141,7 +133,13 @@ class RfxtrxLight(RfxtrxDevice, LightEntity, RestoreEntity):
self._brightness = event.values["Dim level"] * 255 // 100
self._state = self._brightness > 0
if self.hass:
self.schedule_update_ha_state()
if self.should_fire_event:
fire_command_event(self.hass, self.entity_id, event.values["Command"])
def _handle_event(self, event):
"""Check if event applies to me and update."""
if event.device.id_string != self._device.id_string:
return
self._apply_event(event)
self.schedule_update_ha_state()
if self.should_fire_event:
fire_command_event(self.hass, self.entity_id, event.values["Command"])

View File

@ -64,7 +64,6 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
break
for _data_type in data_types:
new_sensor = RfxtrxSensor(
None,
event.device,
entity_info[ATTR_NAME],
_data_type,
@ -97,8 +96,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
if _data_type in event.values:
data_type = _data_type
break
new_sensor = RfxtrxSensor(event, event.device, pkt_id, data_type)
new_sensor.apply_event(event)
new_sensor = RfxtrxSensor(event.device, pkt_id, data_type, event=event)
sub_sensors = {}
sub_sensors[new_sensor.data_type] = new_sensor
RFX_DEVICES[device_id] = sub_sensors
@ -111,9 +109,9 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
class RfxtrxSensor(Entity):
"""Representation of a RFXtrx sensor."""
def __init__(self, event, device, name, data_type, should_fire_event=False):
def __init__(self, device, name, data_type, should_fire_event=False, event=None):
"""Initialize the sensor."""
self.event = event
self.event = None
self._device = device
self._name = name
self.should_fire_event = should_fire_event
@ -123,33 +121,16 @@ class RfxtrxSensor(Entity):
f"{device.packettype:x}_{device.subtype:x}_{device.id_string}_{data_type}"
)
if event:
self._apply_event(event)
async def async_added_to_hass(self):
"""Restore RFXtrx switch device state (ON/OFF)."""
await super().async_added_to_hass()
def _handle_event(event):
"""Check if event applies to me and update."""
if not isinstance(event, SensorEvent):
return
if event.device.id_string != self._device.id_string:
return
if self.data_type not in event.values:
return
_LOGGER.debug(
"Sensor update (Device ID: %s Class: %s Sub: %s)",
event.device.id_string,
event.device.__class__.__name__,
event.device.subtype,
)
self.apply_event(event)
self.async_on_remove(
self.hass.helpers.dispatcher.async_dispatcher_connect(
SIGNAL_EVENT, _handle_event
SIGNAL_EVENT, self._handle_event
)
)
@ -186,10 +167,30 @@ class RfxtrxSensor(Entity):
"""Return unique identifier of remote device."""
return self._unique_id
def apply_event(self, event):
def _apply_event(self, event):
"""Apply command from rfxtrx."""
self.event = event
if self.hass:
self.schedule_update_ha_state()
if self.should_fire_event:
self.hass.bus.fire("signal_received", {ATTR_ENTITY_ID: self.entity_id})
def _handle_event(self, event):
"""Check if event applies to me and update."""
if not isinstance(event, SensorEvent):
return
if event.device.id_string != self._device.id_string:
return
if self.data_type not in event.values:
return
_LOGGER.debug(
"Sensor update (Device ID: %s Class: %s Sub: %s)",
event.device.id_string,
event.device.__class__.__name__,
event.device.subtype,
)
self._apply_event(event)
self.schedule_update_ha_state()
if self.should_fire_event:
self.hass.bus.fire("signal_received", {ATTR_ENTITY_ID: self.entity_id})

View File

@ -60,7 +60,6 @@ def setup_platform(hass, config, add_entities_callback, discovery_info=None):
new_device = get_new_device(event, config, RfxtrxSwitch)
if new_device:
new_device.apply_event(event)
add_entities_callback([new_device])
# Subscribe to main RFXtrx events
@ -78,35 +77,36 @@ class RfxtrxSwitch(RfxtrxDevice, SwitchEntity, RestoreEntity):
if old_state is not None:
self._state = old_state.state == STATE_ON
def _handle_event(event):
"""Check if event applies to me and update."""
if event.device.id_string != self._event.device.id_string:
return
self.apply_event(event)
self.async_on_remove(
self.hass.helpers.dispatcher.async_dispatcher_connect(
SIGNAL_EVENT, _handle_event
SIGNAL_EVENT, self._handle_event
)
)
def apply_event(self, event):
def _apply_event(self, event):
"""Apply command from rfxtrx."""
if event.values["Command"] in COMMAND_ON_LIST:
self._state = True
elif event.values["Command"] in COMMAND_OFF_LIST:
self._state = False
if self.hass:
self.schedule_update_ha_state()
if self.should_fire_event:
fire_command_event(self.hass, self.entity_id, event.values["Command"])
def _handle_event(self, event):
"""Check if event applies to me and update."""
if event.device.id_string != self._device.id_string:
return
self._apply_event(event)
self.schedule_update_ha_state()
if self.should_fire_event:
fire_command_event(self.hass, self.entity_id, event.values["Command"])
def turn_on(self, **kwargs):
"""Turn the device on."""
self._send_command("turn_on")
self.schedule_update_ha_state()
def turn_off(self, **kwargs):
"""Turn the device off."""
self._send_command("turn_off")
self.schedule_update_ha_state()