Support group events for AC switches and binary sensors. Fixes #53065. (#53384)

* Support group events for AC switches and binary sensors. Fixes #53065.

* Review comments
This commit is contained in:
Børge Nordli 2021-07-23 18:45:31 +02:00 committed by GitHub
parent 952cb964c8
commit 87165d6133
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 93 additions and 9 deletions

View file

@ -44,6 +44,7 @@ from homeassistant.helpers.restore_state import RestoreEntity
from .const import (
ATTR_EVENT,
COMMAND_GROUP_LIST,
CONF_AUTOMATIC_ADD,
CONF_DATA_BITS,
CONF_DEBUG,
@ -465,6 +466,9 @@ class RfxtrxEntity(RestoreEntity):
self._event = event
self._device_id = device_id
self._unique_id = "_".join(x for x in self._device_id)
# If id_string is 213c7f2:1, the group_id is 213c7f2, and the device will respond to
# group events regardless of their group indices.
(self._group_id, _, _) = device.id_string.partition(":")
async def async_added_to_hass(self):
"""Restore RFXtrx device state (ON/OFF)."""
@ -520,6 +524,15 @@ class RfxtrxEntity(RestoreEntity):
"model": self._device.type_string,
}
def _event_applies(self, event, device_id):
"""Check if event applies to me."""
if "Command" in event.values and event.values["Command"] in COMMAND_GROUP_LIST:
(group_id, _, _) = event.device.id_string.partition(":")
return group_id == self._group_id
# Otherwise, the event only applies to the matching device.
return device_id == self._device_id
def _apply_event(self, event):
"""Apply a received event."""
self._event = event

View file

@ -233,7 +233,7 @@ class RfxtrxBinarySensor(RfxtrxEntity, BinarySensorEntity):
@callback
def _handle_event(self, event, device_id):
"""Check if event applies to me and update."""
if device_id != self._device_id:
if not self._event_applies(event, device_id):
return
_LOGGER.debug(

View file

@ -19,6 +19,7 @@ COMMAND_ON_LIST = [
"On",
"Up",
"Stop",
"Group on",
"Open (inline relay)",
"Stop (inline relay)",
"Enable sun automation",
@ -26,11 +27,17 @@ COMMAND_ON_LIST = [
COMMAND_OFF_LIST = [
"Off",
"Group off",
"Down",
"Close (inline relay)",
"Disable sun automation",
]
COMMAND_GROUP_LIST = [
"Group on",
"Group off",
]
ATTR_EVENT = "event"
SERVICE_SEND = "send"

View file

@ -117,12 +117,10 @@ class RfxtrxSwitch(RfxtrxCommandEntity, SwitchEntity):
@callback
def _handle_event(self, event, device_id):
"""Check if event applies to me and update."""
if device_id != self._device_id:
return
if self._event_applies(event, device_id):
self._apply_event(event)
self._apply_event(event)
self.async_write_ha_state()
self.async_write_ha_state()
@property
def is_on(self):

View file

@ -121,7 +121,7 @@ async def test_several(hass, rfxtrx):
devices={
"0b1100cd0213c7f230010f71": {},
"0b1100100118cdea02010f70": {},
"0b1100101118cdea02010f70": {},
"0b1100100118cdea03010f70": {},
}
)
mock_entry = MockConfigEntry(domain="rfxtrx", unique_id=DOMAIN, data=entry_data)
@ -141,10 +141,20 @@ async def test_several(hass, rfxtrx):
assert state.state == "off"
assert state.attributes.get("friendly_name") == "AC 118cdea:2"
state = hass.states.get("binary_sensor.ac_1118cdea_2")
state = hass.states.get("binary_sensor.ac_118cdea_3")
assert state
assert state.state == "off"
assert state.attributes.get("friendly_name") == "AC 1118cdea:2"
assert state.attributes.get("friendly_name") == "AC 118cdea:3"
# "2: Group on"
await rfxtrx.signal("0b1100100118cdea03040f70")
assert hass.states.get("binary_sensor.ac_118cdea_2").state == "on"
assert hass.states.get("binary_sensor.ac_118cdea_3").state == "on"
# "2: Group off"
await rfxtrx.signal("0b1100100118cdea03030f70")
assert hass.states.get("binary_sensor.ac_118cdea_2").state == "off"
assert hass.states.get("binary_sensor.ac_118cdea_3").state == "off"
async def test_discover(hass, rfxtrx_automatic):

View file

@ -125,6 +125,62 @@ async def test_repetitions(hass, rfxtrx, repetitions):
assert rfxtrx.transport.send.call_count == repetitions
async def test_switch_events(hass, rfxtrx):
"""Event test with 2 switches."""
entry_data = create_rfx_test_cfg(
devices={
"0b1100cd0213c7f205010f51": {"signal_repetitions": 1},
"0b1100cd0213c7f210010f51": {"signal_repetitions": 1},
}
)
mock_entry = MockConfigEntry(domain="rfxtrx", unique_id=DOMAIN, data=entry_data)
mock_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
state = hass.states.get("switch.ac_213c7f2_16")
assert state
assert state.state == "off"
assert state.attributes.get("friendly_name") == "AC 213c7f2:16"
state = hass.states.get("switch.ac_213c7f2_5")
assert state
assert state.state == "off"
assert state.attributes.get("friendly_name") == "AC 213c7f2:5"
# "16: On"
await rfxtrx.signal("0b1100100213c7f210010f70")
assert hass.states.get("switch.ac_213c7f2_5").state == "off"
assert hass.states.get("switch.ac_213c7f2_16").state == "on"
# "16: Off"
await rfxtrx.signal("0b1100100213c7f210000f70")
assert hass.states.get("switch.ac_213c7f2_5").state == "off"
assert hass.states.get("switch.ac_213c7f2_16").state == "off"
# "5: On"
await rfxtrx.signal("0b1100100213c7f205010f70")
assert hass.states.get("switch.ac_213c7f2_5").state == "on"
assert hass.states.get("switch.ac_213c7f2_16").state == "off"
# "5: Off"
await rfxtrx.signal("0b1100100213c7f205000f70")
assert hass.states.get("switch.ac_213c7f2_5").state == "off"
assert hass.states.get("switch.ac_213c7f2_16").state == "off"
# "16: Group on"
await rfxtrx.signal("0b1100100213c7f210040f70")
assert hass.states.get("switch.ac_213c7f2_5").state == "on"
assert hass.states.get("switch.ac_213c7f2_16").state == "on"
# "16: Group off"
await rfxtrx.signal("0b1100100213c7f210030f70")
assert hass.states.get("switch.ac_213c7f2_5").state == "off"
assert hass.states.get("switch.ac_213c7f2_16").state == "off"
async def test_discover_switch(hass, rfxtrx_automatic):
"""Test with discovery of switches."""
rfxtrx = rfxtrx_automatic