Make sure command entities restore from state (#38038)

pull/38041/head^2
Joakim Plate 2020-07-22 00:01:31 +02:00 committed by GitHub
parent ad5d7ee615
commit 945acb4e29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 182 additions and 11 deletions

View File

@ -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(

View File

@ -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."""

View File

@ -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."""

View File

@ -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."""

View File

@ -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."""

View File

@ -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)

View File

@ -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(

View File

@ -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(

View File

@ -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(

View File

@ -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(

View File

@ -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(