diff --git a/homeassistant/components/rfxtrx/__init__.py b/homeassistant/components/rfxtrx/__init__.py index 9cef384cc01..0fdab9f1bf5 100644 --- a/homeassistant/components/rfxtrx/__init__.py +++ b/homeassistant/components/rfxtrx/__init__.py @@ -398,12 +398,6 @@ class RfxtrxEntity(RestoreEntity): """Restore RFXtrx device state (ON/OFF).""" if self._event: self._apply_event(self._event) - else: - 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( diff --git a/homeassistant/components/rfxtrx/binary_sensor.py b/homeassistant/components/rfxtrx/binary_sensor.py index 82e8765fb49..0c2cd728afc 100644 --- a/homeassistant/components/rfxtrx/binary_sensor.py +++ b/homeassistant/components/rfxtrx/binary_sensor.py @@ -24,7 +24,12 @@ from . import ( get_pt2262_cmd, get_rfx_object, ) -from .const import COMMAND_OFF_LIST, COMMAND_ON_LIST, DEVICE_PACKET_TYPE_LIGHTING4 +from .const import ( + ATTR_EVENT, + COMMAND_OFF_LIST, + COMMAND_ON_LIST, + DEVICE_PACKET_TYPE_LIGHTING4, +) _LOGGER = logging.getLogger(__name__) @@ -124,6 +129,17 @@ class RfxtrxBinarySensor(RfxtrxEntity, BinarySensorEntity): self._cmd_on = cmd_on self._cmd_off = cmd_off + async def async_added_to_hass(self): + """Restore device state.""" + await super().async_added_to_hass() + + if self._event is None: + 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)) + @property def force_update(self) -> bool: """We should force updates. Repeated states have meaning.""" diff --git a/homeassistant/components/rfxtrx/cover.py b/homeassistant/components/rfxtrx/cover.py index db3f5d38131..047f7c67a21 100644 --- a/homeassistant/components/rfxtrx/cover.py +++ b/homeassistant/components/rfxtrx/cover.py @@ -2,7 +2,7 @@ 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 . import ( @@ -81,6 +81,15 @@ async def async_setup_entry( class RfxtrxCover(RfxtrxCommandEntity, CoverEntity): """Representation of a RFXtrx cover.""" + async def async_added_to_hass(self): + """Restore device state.""" + await super().async_added_to_hass() + + 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): """Return if the cover is closed.""" diff --git a/homeassistant/components/rfxtrx/light.py b/homeassistant/components/rfxtrx/light.py index 81633f847c4..cd57bb99c40 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 ( @@ -97,6 +97,16 @@ class RfxtrxLight(RfxtrxCommandEntity, LightEntity): _brightness = 0 + async def async_added_to_hass(self): + """Restore RFXtrx device state (ON/OFF).""" + await super().async_added_to_hass() + + 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): """Return the brightness of this light between 0..255.""" diff --git a/homeassistant/components/rfxtrx/sensor.py b/homeassistant/components/rfxtrx/sensor.py index 337af41940f..34e6dc1b310 100644 --- a/homeassistant/components/rfxtrx/sensor.py +++ b/homeassistant/components/rfxtrx/sensor.py @@ -20,6 +20,7 @@ from . import ( get_device_id, get_rfx_object, ) +from .const import ATTR_EVENT _LOGGER = logging.getLogger(__name__) @@ -125,6 +126,17 @@ class RfxtrxSensor(RfxtrxEntity): self._device_class = DEVICE_CLASSES.get(data_type) self._convert_fun = CONVERT_FUNCTIONS.get(data_type, lambda x: x) + async def async_added_to_hass(self): + """Restore device state.""" + await super().async_added_to_hass() + + if self._event is None: + 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)) + @property def state(self): """Return the state of the sensor.""" diff --git a/homeassistant/components/rfxtrx/switch.py b/homeassistant/components/rfxtrx/switch.py index 4b5c6919910..cf8c26edecb 100644 --- a/homeassistant/components/rfxtrx/switch.py +++ b/homeassistant/components/rfxtrx/switch.py @@ -4,7 +4,7 @@ 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 . import ( @@ -91,6 +91,15 @@ async def async_setup_entry( class RfxtrxSwitch(RfxtrxCommandEntity, SwitchEntity): """Representation of a RFXtrx switch.""" + async def async_added_to_hass(self): + """Restore device state.""" + await super().async_added_to_hass() + + 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.""" super()._apply_event(event) 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(