From 66e490e55fb4d3e4beeaf97f828afc6ad588cd02 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Wed, 22 Jul 2020 15:27:04 +0200 Subject: [PATCH] Rfxtrx fixup restore (#38039) --- homeassistant/components/rfxtrx/__init__.py | 46 +++++---- .../components/rfxtrx/binary_sensor.py | 96 +++---------------- homeassistant/components/rfxtrx/cover.py | 23 ++--- homeassistant/components/rfxtrx/light.py | 23 +++-- homeassistant/components/rfxtrx/sensor.py | 56 +---------- homeassistant/components/rfxtrx/switch.py | 23 +++-- tests/components/rfxtrx/test_binary_sensor.py | 27 +++++- tests/components/rfxtrx/test_cover.py | 23 +++++ tests/components/rfxtrx/test_light.py | 25 +++++ tests/components/rfxtrx/test_sensor.py | 27 ++++++ tests/components/rfxtrx/test_switch.py | 21 ++++ 11 files changed, 204 insertions(+), 186 deletions(-) diff --git a/homeassistant/components/rfxtrx/__init__.py b/homeassistant/components/rfxtrx/__init__.py index 54863f86332..1f4655aedc7 100644 --- a/homeassistant/components/rfxtrx/__init__.py +++ b/homeassistant/components/rfxtrx/__init__.py @@ -23,6 +23,7 @@ from homeassistant.const import ( UNIT_PERCENTAGE, UV_INDEX, ) +from homeassistant.core import callback import homeassistant.helpers.config_validation as cv from homeassistant.helpers.restore_state import RestoreEntity @@ -343,35 +344,30 @@ def get_device_id(device, data_bits=None): return (f"{device.packettype:x}", f"{device.subtype:x}", id_string) -class RfxtrxDevice(RestoreEntity): +class RfxtrxEntity(RestoreEntity): """Represents a Rfxtrx device. Contains the common logic for Rfxtrx lights and switches. """ - def __init__(self, device, device_id, signal_repetitions, event=None): + def __init__(self, device, device_id, event=None): """Initialize the device.""" - self.signal_repetitions = signal_repetitions self._name = f"{device.type_string} {device.id_string}" self._device = device - self._event = None - self._state = None + self._event = event self._device_id = device_id self._unique_id = "_".join(x for x in self._device_id) - if event: - self._apply_event(event) - async def async_added_to_hass(self): """Restore RFXtrx device state (ON/OFF).""" if self._event: - return + self._apply_event(self._event) - old_state = await self.async_get_last_state() - if old_state is not None: - event = old_state.attributes.get(ATTR_EVENT) - if event: - self._apply_event(get_rfx_object(event)) + self.async_on_remove( + self.hass.helpers.dispatcher.async_dispatcher_connect( + SIGNAL_EVENT, self._handle_event + ) + ) @property def should_poll(self): @@ -390,11 +386,6 @@ class RfxtrxDevice(RestoreEntity): return None return {ATTR_EVENT: "".join(f"{x:02x}" for x in self._event.data)} - @property - def is_on(self): - """Return true if device is on.""" - return self._state - @property def assumed_state(self): """Return true if unable to access real state of entity.""" @@ -418,6 +409,23 @@ class RfxtrxDevice(RestoreEntity): """Apply a received event.""" self._event = event + @callback + def _handle_event(self, event, device_id): + """Handle a reception of data, overridden by other classes.""" + + +class RfxtrxCommandEntity(RfxtrxEntity): + """Represents a Rfxtrx device. + + Contains the common logic for Rfxtrx lights and switches. + """ + + def __init__(self, device, device_id, signal_repetitions=1, event=None): + """Initialzie a switch or light device.""" + super().__init__(device, device_id, event=event) + self.signal_repetitions = signal_repetitions + self._state = None + def _send_command(self, command, brightness=0): rfx_object = self.hass.data[DATA_RFXOBJECT] diff --git a/homeassistant/components/rfxtrx/binary_sensor.py b/homeassistant/components/rfxtrx/binary_sensor.py index 5f6e32437c4..3f0010b139e 100644 --- a/homeassistant/components/rfxtrx/binary_sensor.py +++ b/homeassistant/components/rfxtrx/binary_sensor.py @@ -12,14 +12,13 @@ from homeassistant.const import ( ) from homeassistant.core import callback from homeassistant.helpers import event as evt -from homeassistant.helpers.restore_state import RestoreEntity from . import ( CONF_AUTOMATIC_ADD, CONF_DATA_BITS, CONF_OFF_DELAY, - DOMAIN, SIGNAL_EVENT, + RfxtrxEntity, find_possible_pt2262_device, get_device_id, get_pt2262_cmd, @@ -107,7 +106,7 @@ async def async_setup_entry( ) -class RfxtrxBinarySensor(BinarySensorEntity, RestoreEntity): +class RfxtrxBinarySensor(RfxtrxEntity, BinarySensorEntity): """A representation of a RFXtrx binary sensor.""" def __init__( @@ -122,25 +121,17 @@ class RfxtrxBinarySensor(BinarySensorEntity, RestoreEntity): event=None, ): """Initialize the RFXtrx sensor.""" - self._event = None - self._device = device - self._name = f"{device.type_string} {device.id_string}" + super().__init__(device, device_id, event=event) self._device_class = device_class self._data_bits = data_bits self._off_delay = off_delay - self._state = False - self.delay_listener = None + self._state = None + self._delay_listener = None self._cmd_on = cmd_on self._cmd_off = cmd_off - self._device_id = device_id - self._unique_id = "_".join(x for x in self._device_id) - - if event: - self._apply_event(event) - async def async_added_to_hass(self): - """Restore RFXtrx switch device state (ON/OFF).""" + """Restore device state.""" await super().async_added_to_hass() if self._event is None: @@ -150,44 +141,6 @@ class RfxtrxBinarySensor(BinarySensorEntity, RestoreEntity): if event: self._apply_event(get_rfx_object(event)) - self.async_on_remove( - self.hass.helpers.dispatcher.async_dispatcher_connect( - SIGNAL_EVENT, self._handle_event - ) - ) - - @property - def name(self): - """Return the device name.""" - return self._name - - @property - def device_state_attributes(self): - """Return the device state attributes.""" - if not self._event: - return None - return {ATTR_EVENT: "".join(f"{x:02x}" for x in self._event.data)} - - @property - def data_bits(self): - """Return the number of data bits.""" - return self._data_bits - - @property - def cmd_on(self): - """Return the value of the 'On' command.""" - return self._cmd_on - - @property - def cmd_off(self): - """Return the value of the 'Off' command.""" - return self._cmd_off - - @property - def should_poll(self): - """No polling needed.""" - return False - @property def force_update(self) -> bool: """We should force updates. Repeated states have meaning.""" @@ -198,38 +151,19 @@ class RfxtrxBinarySensor(BinarySensorEntity, RestoreEntity): """Return the sensor class.""" return self._device_class - @property - def off_delay(self): - """Return the off_delay attribute value.""" - return self._off_delay - @property def is_on(self): """Return true if the sensor state is True.""" return self._state - @property - def unique_id(self): - """Return unique identifier of remote device.""" - return self._unique_id - - @property - def device_info(self): - """Return the device info.""" - return { - "identifiers": {(DOMAIN, *self._device_id)}, - "name": f"{self._device.type_string} {self._device.id_string}", - "model": self._device.type_string, - } - def _apply_event_lighting4(self, event): """Apply event for a lighting 4 device.""" - if self.data_bits is not None: - cmd = get_pt2262_cmd(event.device.id_string, self.data_bits) + if self._data_bits is not None: + cmd = get_pt2262_cmd(event.device.id_string, self._data_bits) cmd = int(cmd, 16) - if cmd == self.cmd_on: + if cmd == self._cmd_on: self._state = True - elif cmd == self.cmd_off: + elif cmd == self._cmd_off: self._state = False else: self._state = True @@ -242,7 +176,7 @@ class RfxtrxBinarySensor(BinarySensorEntity, RestoreEntity): def _apply_event(self, event): """Apply command from rfxtrx.""" - self._event = event + super()._apply_event(event) if event.device.packettype == DEVICE_PACKET_TYPE_LIGHTING4: self._apply_event_lighting4(event) else: @@ -265,15 +199,15 @@ class RfxtrxBinarySensor(BinarySensorEntity, RestoreEntity): self.async_write_ha_state() - if self.is_on and self.off_delay is not None and self.delay_listener is None: + if self.is_on and self._off_delay is not None and self._delay_listener is None: @callback def off_delay_listener(now): """Switch device off after a delay.""" - self.delay_listener = None + self._delay_listener = None self._state = False self.async_write_ha_state() - self.delay_listener = evt.async_call_later( - self.hass, self.off_delay.total_seconds(), off_delay_listener + self._delay_listener = evt.async_call_later( + self.hass, self._off_delay.total_seconds(), off_delay_listener ) diff --git a/homeassistant/components/rfxtrx/cover.py b/homeassistant/components/rfxtrx/cover.py index a3cefb42cb7..af5c48810ee 100644 --- a/homeassistant/components/rfxtrx/cover.py +++ b/homeassistant/components/rfxtrx/cover.py @@ -2,16 +2,15 @@ import logging from homeassistant.components.cover import CoverEntity -from homeassistant.const import CONF_DEVICES +from homeassistant.const import CONF_DEVICES, STATE_OPEN from homeassistant.core import callback -from homeassistant.helpers.restore_state import RestoreEntity from . import ( CONF_AUTOMATIC_ADD, CONF_SIGNAL_REPETITIONS, DEFAULT_SIGNAL_REPETITIONS, SIGNAL_EVENT, - RfxtrxDevice, + RfxtrxCommandEntity, get_device_id, get_rfx_object, ) @@ -79,23 +78,17 @@ async def async_setup_entry( hass.helpers.dispatcher.async_dispatcher_connect(SIGNAL_EVENT, cover_update) -class RfxtrxCover(RfxtrxDevice, CoverEntity, RestoreEntity): +class RfxtrxCover(RfxtrxCommandEntity, CoverEntity): """Representation of a RFXtrx cover.""" async def async_added_to_hass(self): - """Restore RFXtrx cover device state (OPEN/CLOSE).""" + """Restore device state.""" await super().async_added_to_hass() - self.async_on_remove( - self.hass.helpers.dispatcher.async_dispatcher_connect( - SIGNAL_EVENT, self._handle_event - ) - ) - - @property - def should_poll(self): - """Return the polling state. No polling available in RFXtrx cover.""" - return False + if self._event is None: + old_state = await self.async_get_last_state() + if old_state is not None: + self._state = old_state.state == STATE_OPEN @property def is_closed(self): diff --git a/homeassistant/components/rfxtrx/light.py b/homeassistant/components/rfxtrx/light.py index 649be7be3fe..71bf54d3d50 100644 --- a/homeassistant/components/rfxtrx/light.py +++ b/homeassistant/components/rfxtrx/light.py @@ -8,7 +8,7 @@ from homeassistant.components.light import ( SUPPORT_BRIGHTNESS, LightEntity, ) -from homeassistant.const import CONF_DEVICES +from homeassistant.const import CONF_DEVICES, STATE_ON from homeassistant.core import callback from . import ( @@ -16,7 +16,7 @@ from . import ( CONF_SIGNAL_REPETITIONS, DEFAULT_SIGNAL_REPETITIONS, SIGNAL_EVENT, - RfxtrxDevice, + RfxtrxCommandEntity, get_device_id, get_rfx_object, ) @@ -48,7 +48,7 @@ async def async_setup_entry( _LOGGER.error("Invalid device: %s", packet_id) continue if not supported(event): - return + continue device_id = get_device_id(event.device) if device_id in device_ids: @@ -92,7 +92,7 @@ async def async_setup_entry( hass.helpers.dispatcher.async_dispatcher_connect(SIGNAL_EVENT, light_update) -class RfxtrxLight(RfxtrxDevice, LightEntity): +class RfxtrxLight(RfxtrxCommandEntity, LightEntity): """Representation of a RFXtrx light.""" _brightness = 0 @@ -101,11 +101,11 @@ class RfxtrxLight(RfxtrxDevice, LightEntity): """Restore RFXtrx device state (ON/OFF).""" await super().async_added_to_hass() - self.async_on_remove( - self.hass.helpers.dispatcher.async_dispatcher_connect( - SIGNAL_EVENT, self._handle_event - ) - ) + if self._event is None: + old_state = await self.async_get_last_state() + if old_state is not None: + self._state = old_state.state == STATE_ON + self._brightness = old_state.attributes.get(ATTR_BRIGHTNESS) @property def brightness(self): @@ -117,6 +117,11 @@ class RfxtrxLight(RfxtrxDevice, LightEntity): """Flag supported features.""" return SUPPORT_RFXTRX + @property + def is_on(self): + """Return true if device is on.""" + return self._state + def turn_on(self, **kwargs): """Turn the light on.""" brightness = kwargs.get(ATTR_BRIGHTNESS) diff --git a/homeassistant/components/rfxtrx/sensor.py b/homeassistant/components/rfxtrx/sensor.py index de341307551..537fabd7aa7 100644 --- a/homeassistant/components/rfxtrx/sensor.py +++ b/homeassistant/components/rfxtrx/sensor.py @@ -11,13 +11,12 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import CONF_DEVICES from homeassistant.core import callback -from homeassistant.helpers.restore_state import RestoreEntity from . import ( CONF_AUTOMATIC_ADD, DATA_TYPES, - DOMAIN, SIGNAL_EVENT, + RfxtrxEntity, get_device_id, get_rfx_object, ) @@ -113,27 +112,22 @@ async def async_setup_entry( hass.helpers.dispatcher.async_dispatcher_connect(SIGNAL_EVENT, sensor_update) -class RfxtrxSensor(RestoreEntity): +class RfxtrxSensor(RfxtrxEntity): """Representation of a RFXtrx sensor.""" def __init__(self, device, device_id, data_type, event=None): """Initialize the sensor.""" - self._event = None - self._device = device - self._name = f"{device.type_string} {device.id_string} {data_type}" + super().__init__(device, device_id, event=event) self.data_type = data_type self._unit_of_measurement = DATA_TYPES.get(data_type, "") - self._device_id = device_id + self._name = f"{device.type_string} {device.id_string} {data_type}" self._unique_id = "_".join(x for x in (*self._device_id, data_type)) self._device_class = DEVICE_CLASSES.get(data_type) self._convert_fun = CONVERT_FUNCTIONS.get(data_type, lambda x: x) - if event: - self._apply_event(event) - async def async_added_to_hass(self): - """Restore RFXtrx switch device state (ON/OFF).""" + """Restore device state.""" await super().async_added_to_hass() if self._event is None: @@ -143,16 +137,6 @@ class RfxtrxSensor(RestoreEntity): if event: self._apply_event(get_rfx_object(event)) - self.async_on_remove( - self.hass.helpers.dispatcher.async_dispatcher_connect( - SIGNAL_EVENT, self._handle_event - ) - ) - - def __str__(self): - """Return the name of the sensor.""" - return self._name - @property def state(self): """Return the state of the sensor.""" @@ -161,18 +145,6 @@ class RfxtrxSensor(RestoreEntity): value = self._event.values.get(self.data_type) return self._convert_fun(value) - @property - def name(self): - """Get the name of the sensor.""" - return self._name - - @property - def device_state_attributes(self): - """Return the device state attributes.""" - if not self._event: - return None - return {ATTR_EVENT: "".join(f"{x:02x}" for x in self._event.data)} - @property def unit_of_measurement(self): """Return the unit this state is expressed in.""" @@ -193,24 +165,6 @@ class RfxtrxSensor(RestoreEntity): """Return a device class for sensor.""" return self._device_class - @property - def unique_id(self): - """Return unique identifier of remote device.""" - return self._unique_id - - @property - def device_info(self): - """Return the device info.""" - return { - "identifiers": {(DOMAIN, *self._device_id)}, - "name": f"{self._device.type_string} {self._device.id_string}", - "model": self._device.type_string, - } - - def _apply_event(self, event): - """Apply command from rfxtrx.""" - self._event = event - @callback def _handle_event(self, event, device_id): """Check if event applies to me and update.""" diff --git a/homeassistant/components/rfxtrx/switch.py b/homeassistant/components/rfxtrx/switch.py index 7b2a23c1624..e5c96215c83 100644 --- a/homeassistant/components/rfxtrx/switch.py +++ b/homeassistant/components/rfxtrx/switch.py @@ -4,9 +4,8 @@ import logging import RFXtrx as rfxtrxmod from homeassistant.components.switch import SwitchEntity -from homeassistant.const import CONF_DEVICES +from homeassistant.const import CONF_DEVICES, STATE_ON from homeassistant.core import callback -from homeassistant.helpers.restore_state import RestoreEntity from . import ( CONF_AUTOMATIC_ADD, @@ -14,7 +13,7 @@ from . import ( DEFAULT_SIGNAL_REPETITIONS, DOMAIN, SIGNAL_EVENT, - RfxtrxDevice, + RfxtrxCommandEntity, get_device_id, get_rfx_object, ) @@ -89,18 +88,17 @@ async def async_setup_entry( hass.helpers.dispatcher.async_dispatcher_connect(SIGNAL_EVENT, switch_update) -class RfxtrxSwitch(RfxtrxDevice, SwitchEntity, RestoreEntity): +class RfxtrxSwitch(RfxtrxCommandEntity, SwitchEntity): """Representation of a RFXtrx switch.""" async def async_added_to_hass(self): - """Restore RFXtrx switch device state (ON/OFF).""" + """Restore device state.""" await super().async_added_to_hass() - self.async_on_remove( - self.hass.helpers.dispatcher.async_dispatcher_connect( - SIGNAL_EVENT, self._handle_event - ) - ) + if self._event is None: + old_state = await self.async_get_last_state() + if old_state is not None: + self._state = old_state.state == STATE_ON def _apply_event(self, event): """Apply command from rfxtrx.""" @@ -120,6 +118,11 @@ class RfxtrxSwitch(RfxtrxDevice, SwitchEntity, RestoreEntity): self.async_write_ha_state() + @property + def is_on(self): + """Return true if device is on.""" + return self._state + def turn_on(self, **kwargs): """Turn the device on.""" self._send_command("turn_on") diff --git a/tests/components/rfxtrx/test_binary_sensor.py b/tests/components/rfxtrx/test_binary_sensor.py index d694dcb34cf..ad04a0763f2 100644 --- a/tests/components/rfxtrx/test_binary_sensor.py +++ b/tests/components/rfxtrx/test_binary_sensor.py @@ -1,12 +1,16 @@ """The tests for the Rfxtrx sensor platform.""" from datetime import timedelta +import pytest + +from homeassistant.components.rfxtrx.const import ATTR_EVENT +from homeassistant.core import State from homeassistant.setup import async_setup_component from homeassistant.util.dt import utcnow from . import _signal_event -from tests.common import async_fire_time_changed +from tests.common import async_fire_time_changed, mock_restore_cache async def test_one(hass, rfxtrx): @@ -59,6 +63,27 @@ async def test_one_pt2262(hass, rfxtrx): assert state.state == "off" +@pytest.mark.parametrize( + "state,event", + [["on", "0b1100cd0213c7f230010f71"], ["off", "0b1100cd0213c7f230000f71"]], +) +async def test_state_restore(hass, rfxtrx, state, event): + """State restoration.""" + + entity_id = "binary_sensor.ac_213c7f2_48" + + mock_restore_cache(hass, [State(entity_id, state, attributes={ATTR_EVENT: event})]) + + assert await async_setup_component( + hass, + "rfxtrx", + {"rfxtrx": {"device": "abcd", "devices": {"0b1100cd0213c7f230010f71": {}}}}, + ) + await hass.async_block_till_done() + + assert hass.states.get(entity_id).state == state + + async def test_several(hass, rfxtrx): """Test with 3.""" assert await async_setup_component( diff --git a/tests/components/rfxtrx/test_cover.py b/tests/components/rfxtrx/test_cover.py index 9a9b37f4e36..73c3cb9cc27 100644 --- a/tests/components/rfxtrx/test_cover.py +++ b/tests/components/rfxtrx/test_cover.py @@ -1,10 +1,15 @@ """The tests for the Rfxtrx cover platform.""" from unittest.mock import call +import pytest + +from homeassistant.core import State from homeassistant.setup import async_setup_component from . import _signal_event +from tests.common import mock_restore_cache + async def test_one_cover(hass, rfxtrx): """Test with 1 cover.""" @@ -46,6 +51,24 @@ async def test_one_cover(hass, rfxtrx): ] +@pytest.mark.parametrize("state", ["open", "closed"]) +async def test_state_restore(hass, rfxtrx, state): + """State restoration.""" + + entity_id = "cover.lightwaverf_siemens_0213c7_242" + + mock_restore_cache(hass, [State(entity_id, state)]) + + assert await async_setup_component( + hass, + "rfxtrx", + {"rfxtrx": {"device": "abcd", "devices": {"0b1400cd0213c7f20d010f51": {}}}}, + ) + await hass.async_block_till_done() + + assert hass.states.get(entity_id).state == state + + async def test_several_covers(hass, rfxtrx): """Test with 3 covers.""" assert await async_setup_component( diff --git a/tests/components/rfxtrx/test_light.py b/tests/components/rfxtrx/test_light.py index 53ddf8bc48c..b96dec95e6e 100644 --- a/tests/components/rfxtrx/test_light.py +++ b/tests/components/rfxtrx/test_light.py @@ -3,10 +3,14 @@ from unittest.mock import call import pytest +from homeassistant.components.light import ATTR_BRIGHTNESS +from homeassistant.core import State from homeassistant.setup import async_setup_component from . import _signal_event +from tests.common import mock_restore_cache + async def test_one_light(hass, rfxtrx): """Test with 1 light.""" @@ -83,6 +87,27 @@ async def test_one_light(hass, rfxtrx): ] +@pytest.mark.parametrize("state,brightness", [["on", 100], ["on", 50], ["off", None]]) +async def test_state_restore(hass, rfxtrx, state, brightness): + """State restoration.""" + + entity_id = "light.ac_213c7f2_16" + + mock_restore_cache( + hass, [State(entity_id, state, attributes={ATTR_BRIGHTNESS: brightness})] + ) + + assert await async_setup_component( + hass, + "rfxtrx", + {"rfxtrx": {"device": "abcd", "devices": {"0b1100cd0213c7f210020f51": {}}}}, + ) + await hass.async_block_till_done() + + assert hass.states.get(entity_id).state == state + assert hass.states.get(entity_id).attributes.get(ATTR_BRIGHTNESS) == brightness + + async def test_several_lights(hass, rfxtrx): """Test with 3 lights.""" assert await async_setup_component( diff --git a/tests/components/rfxtrx/test_sensor.py b/tests/components/rfxtrx/test_sensor.py index 91e010f9e54..3a797f4168d 100644 --- a/tests/components/rfxtrx/test_sensor.py +++ b/tests/components/rfxtrx/test_sensor.py @@ -1,9 +1,15 @@ """The tests for the Rfxtrx sensor platform.""" +import pytest + +from homeassistant.components.rfxtrx.const import ATTR_EVENT from homeassistant.const import TEMP_CELSIUS, UNIT_PERCENTAGE +from homeassistant.core import State from homeassistant.setup import async_setup_component from . import _signal_event +from tests.common import mock_restore_cache + async def test_default_config(hass, rfxtrx): """Test with 0 sensor.""" @@ -34,6 +40,27 @@ async def test_one_sensor(hass, rfxtrx): assert state.attributes.get("unit_of_measurement") == TEMP_CELSIUS +@pytest.mark.parametrize( + "state,event", + [["18.4", "0a520801070100b81b0279"], ["17.9", "0a52085e070100b31b0279"]], +) +async def test_state_restore(hass, rfxtrx, state, event): + """State restoration.""" + + entity_id = "sensor.wt260_wt260h_wt440h_wt450_wt450h_07_01_temperature" + + mock_restore_cache(hass, [State(entity_id, state, attributes={ATTR_EVENT: event})]) + + assert await async_setup_component( + hass, + "rfxtrx", + {"rfxtrx": {"device": "abcd", "devices": {"0a520801070100b81b0279": {}}}}, + ) + await hass.async_block_till_done() + + assert hass.states.get(entity_id).state == state + + async def test_one_sensor_no_datatype(hass, rfxtrx): """Test with 1 sensor.""" assert await async_setup_component( diff --git a/tests/components/rfxtrx/test_switch.py b/tests/components/rfxtrx/test_switch.py index 24d1cbbcdf0..22f7a73c77c 100644 --- a/tests/components/rfxtrx/test_switch.py +++ b/tests/components/rfxtrx/test_switch.py @@ -3,10 +3,13 @@ from unittest.mock import call import pytest +from homeassistant.core import State from homeassistant.setup import async_setup_component from . import _signal_event +from tests.common import mock_restore_cache + async def test_one_switch(hass, rfxtrx): """Test with 1 switch.""" @@ -42,6 +45,24 @@ async def test_one_switch(hass, rfxtrx): ] +@pytest.mark.parametrize("state", ["on", "off"]) +async def test_state_restore(hass, rfxtrx, state): + """State restoration.""" + + entity_id = "switch.ac_213c7f2_16" + + mock_restore_cache(hass, [State(entity_id, state)]) + + assert await async_setup_component( + hass, + "rfxtrx", + {"rfxtrx": {"device": "abcd", "devices": {"0b1100cd0213c7f210010f51": {}}}}, + ) + await hass.async_block_till_done() + + assert hass.states.get(entity_id).state == state + + async def test_several_switches(hass, rfxtrx): """Test with 3 switches.""" assert await async_setup_component(