diff --git a/homeassistant/components/rfxtrx/__init__.py b/homeassistant/components/rfxtrx/__init__.py index 66d4235ffdb..44e1d537408 100644 --- a/homeassistant/components/rfxtrx/__init__.py +++ b/homeassistant/components/rfxtrx/__init__.py @@ -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 diff --git a/homeassistant/components/rfxtrx/binary_sensor.py b/homeassistant/components/rfxtrx/binary_sensor.py index 78eb49740d5..9e3d24cdb6a 100644 --- a/homeassistant/components/rfxtrx/binary_sensor.py +++ b/homeassistant/components/rfxtrx/binary_sensor.py @@ -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( diff --git a/homeassistant/components/rfxtrx/const.py b/homeassistant/components/rfxtrx/const.py index 1f36b00e184..d457435f85c 100644 --- a/homeassistant/components/rfxtrx/const.py +++ b/homeassistant/components/rfxtrx/const.py @@ -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" diff --git a/homeassistant/components/rfxtrx/switch.py b/homeassistant/components/rfxtrx/switch.py index 96c066d5f3e..60ddb9a4d16 100644 --- a/homeassistant/components/rfxtrx/switch.py +++ b/homeassistant/components/rfxtrx/switch.py @@ -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): diff --git a/tests/components/rfxtrx/test_binary_sensor.py b/tests/components/rfxtrx/test_binary_sensor.py index a52b390395a..5b76c6287a3 100644 --- a/tests/components/rfxtrx/test_binary_sensor.py +++ b/tests/components/rfxtrx/test_binary_sensor.py @@ -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): diff --git a/tests/components/rfxtrx/test_switch.py b/tests/components/rfxtrx/test_switch.py index 12064911bb6..94adf4a980e 100644 --- a/tests/components/rfxtrx/test_switch.py +++ b/tests/components/rfxtrx/test_switch.py @@ -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