Deduplicate light data with deCONZ websocket fixture (#122421)

This commit is contained in:
Robert Svensson 2024-07-23 08:40:30 +02:00 committed by GitHub
parent 0039f1bb49
commit 4ee256633b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 32 additions and 131 deletions

View file

@ -269,6 +269,19 @@ def fixture_websocket_data(_mock_websocket: _WebsocketMock) -> WebsocketDataType
return change_websocket_data
@pytest.fixture(name="light_ws_data")
def fixture_light_websocket_data(
mock_websocket_data: WebsocketDataType,
) -> WebsocketDataType:
"""Fixture to send light data over websocket."""
async def send_light_data(data: dict[str, Any]) -> None:
"""Send light data on the websocket."""
await mock_websocket_data({"r": "lights"} | data)
return send_light_data
@pytest.fixture(name="sensor_ws_data")
def fixture_sensor_websocket_data(
mock_websocket_data: WebsocketDataType,

View file

@ -111,15 +111,11 @@ async def test_alarm_control_panel(
# Event signals alarm control panel armed away
await sensor_ws_data({"state": {"panel": AncillaryControlPanel.ARMED_AWAY}})
await hass.async_block_till_done()
assert hass.states.get("alarm_control_panel.keypad").state == STATE_ALARM_ARMED_AWAY
# Event signals alarm control panel armed night
await sensor_ws_data({"state": {"panel": AncillaryControlPanel.ARMED_NIGHT}})
await hass.async_block_till_done()
assert (
hass.states.get("alarm_control_panel.keypad").state == STATE_ALARM_ARMED_NIGHT
)
@ -127,15 +123,11 @@ async def test_alarm_control_panel(
# Event signals alarm control panel armed home
await sensor_ws_data({"state": {"panel": AncillaryControlPanel.ARMED_STAY}})
await hass.async_block_till_done()
assert hass.states.get("alarm_control_panel.keypad").state == STATE_ALARM_ARMED_HOME
# Event signals alarm control panel disarmed
await sensor_ws_data({"state": {"panel": AncillaryControlPanel.DISARMED}})
await hass.async_block_till_done()
assert hass.states.get("alarm_control_panel.keypad").state == STATE_ALARM_DISARMED
# Event signals alarm control panel arming
@ -146,8 +138,6 @@ async def test_alarm_control_panel(
AncillaryControlPanel.ARMING_STAY,
):
await sensor_ws_data({"state": {"panel": arming_event}})
await hass.async_block_till_done()
assert hass.states.get("alarm_control_panel.keypad").state == STATE_ALARM_ARMING
# Event signals alarm control panel pending
@ -157,8 +147,6 @@ async def test_alarm_control_panel(
AncillaryControlPanel.EXIT_DELAY,
):
await sensor_ws_data({"state": {"panel": pending_event}})
await hass.async_block_till_done()
assert (
hass.states.get("alarm_control_panel.keypad").state == STATE_ALARM_PENDING
)
@ -166,15 +154,11 @@ async def test_alarm_control_panel(
# Event signals alarm control panel triggered
await sensor_ws_data({"state": {"panel": AncillaryControlPanel.IN_ALARM}})
await hass.async_block_till_done()
assert hass.states.get("alarm_control_panel.keypad").state == STATE_ALARM_TRIGGERED
# Event signals alarm control panel unknown state keeps previous state
await sensor_ws_data({"state": {"panel": AncillaryControlPanel.NOT_READY}})
await hass.async_block_till_done()
assert hass.states.get("alarm_control_panel.keypad").state == STATE_ALARM_TRIGGERED
# Verify service calls

View file

@ -493,7 +493,6 @@ async def test_binary_sensors(
# Change state
await sensor_ws_data({"state": expected["websocket_event"]})
await hass.async_block_till_done()
assert hass.states.get(expected["entity_id"]).state == expected["next_state"]
# Unload entry
@ -611,8 +610,6 @@ async def test_add_new_binary_sensor(
},
}
await sensor_ws_data(event_added_sensor)
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 1
assert hass.states.get("binary_sensor.presence_sensor").state == STATE_OFF
@ -640,8 +637,6 @@ async def test_add_new_binary_sensor_ignored_load_entities_on_service_call(
assert len(hass.states.async_all()) == 0
await sensor_ws_data({"e": "added", "sensor": sensor})
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 0
assert not hass.states.get("binary_sensor.presence_sensor")
@ -687,8 +682,6 @@ async def test_add_new_binary_sensor_ignored_load_entities_on_options_change(
assert len(hass.states.async_all()) == 0
await sensor_ws_data({"e": "added", "sensor": sensor})
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 0
assert not hass.states.get("binary_sensor.presence_sensor")

View file

@ -111,8 +111,6 @@ async def test_simple_climate_device(
# Event signals thermostat configured off
await sensor_ws_data({"state": {"on": False}})
await hass.async_block_till_done()
assert hass.states.get("climate.thermostat").state == STATE_OFF
assert (
hass.states.get("climate.thermostat").attributes["hvac_action"]
@ -122,8 +120,6 @@ async def test_simple_climate_device(
# Event signals thermostat state on
await sensor_ws_data({"state": {"on": True}})
await hass.async_block_till_done()
assert hass.states.get("climate.thermostat").state == HVACMode.HEAT
assert (
hass.states.get("climate.thermostat").attributes["hvac_action"]
@ -212,8 +208,6 @@ async def test_climate_device_without_cooling_support(
# Event signals thermostat configured off
await sensor_ws_data({"config": {"mode": "off"}})
await hass.async_block_till_done()
assert hass.states.get("climate.thermostat").state == STATE_OFF
assert (
hass.states.get("climate.thermostat").attributes["hvac_action"]
@ -223,8 +217,6 @@ async def test_climate_device_without_cooling_support(
# Event signals thermostat state on
await sensor_ws_data({"config": {"mode": "other"}, "state": {"on": True}})
await hass.async_block_till_done()
assert hass.states.get("climate.thermostat").state == HVACMode.HEAT
assert (
hass.states.get("climate.thermostat").attributes["hvac_action"]
@ -234,8 +226,6 @@ async def test_climate_device_without_cooling_support(
# Event signals thermostat state off
await sensor_ws_data({"state": {"on": False}})
await hass.async_block_till_done()
assert hass.states.get("climate.thermostat").state == STATE_OFF
assert (
hass.states.get("climate.thermostat").attributes["hvac_action"]
@ -378,9 +368,6 @@ async def test_climate_device_with_cooling_support(
# Event signals thermostat mode cool
await sensor_ws_data({"config": {"mode": "cool"}})
await hass.async_block_till_done()
await hass.async_block_till_done()
assert hass.states.get("climate.zen_01").state == HVACMode.COOL
assert hass.states.get("climate.zen_01").attributes["temperature"] == 11.1
assert (
@ -390,8 +377,6 @@ async def test_climate_device_with_cooling_support(
# Event signals thermostat state on
await sensor_ws_data({"state": {"on": True}})
await hass.async_block_till_done()
assert hass.states.get("climate.zen_01").state == HVACMode.COOL
assert (
hass.states.get("climate.zen_01").attributes["hvac_action"]
@ -470,8 +455,6 @@ async def test_climate_device_with_fan_support(
# Event signals fan mode defaults to off
await sensor_ws_data({"config": {"fanmode": "unsupported"}})
await hass.async_block_till_done()
assert hass.states.get("climate.zen_01").attributes["fan_mode"] == FAN_OFF
assert (
hass.states.get("climate.zen_01").attributes["hvac_action"] == HVACAction.IDLE
@ -480,8 +463,6 @@ async def test_climate_device_with_fan_support(
# Event signals unsupported fan mode
await sensor_ws_data({"config": {"fanmode": "unsupported"}, "state": {"on": True}})
await hass.async_block_till_done()
assert hass.states.get("climate.zen_01").attributes["fan_mode"] == FAN_ON
assert (
hass.states.get("climate.zen_01").attributes["hvac_action"]
@ -491,8 +472,6 @@ async def test_climate_device_with_fan_support(
# Event signals unsupported fan mode
await sensor_ws_data({"config": {"fanmode": "unsupported"}})
await hass.async_block_till_done()
assert hass.states.get("climate.zen_01").attributes["fan_mode"] == FAN_ON
assert (
hass.states.get("climate.zen_01").attributes["hvac_action"]
@ -595,8 +574,6 @@ async def test_climate_device_with_preset(
# Event signals deCONZ preset
await sensor_ws_data({"config": {"preset": "manual"}})
await hass.async_block_till_done()
assert (
hass.states.get("climate.zen_01").attributes["preset_mode"]
== DECONZ_PRESET_MANUAL
@ -605,8 +582,6 @@ async def test_climate_device_with_preset(
# Event signals unknown preset
await sensor_ws_data({"config": {"preset": "unsupported"}})
await hass.async_block_till_done()
assert hass.states.get("climate.zen_01").attributes["preset_mode"] is None
# Verify service calls
@ -739,8 +714,6 @@ async def test_verify_state_update(
)
await sensor_ws_data({"state": {"on": False}})
await hass.async_block_till_done()
assert hass.states.get("climate.thermostat").state == HVACMode.AUTO
assert (
hass.states.get("climate.thermostat").attributes["hvac_action"]
@ -775,7 +748,6 @@ async def test_add_new_climate_device(
assert len(hass.states.async_all()) == 0
await sensor_ws_data(event_added_sensor)
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 2
assert hass.states.get("climate.thermostat").state == HVACMode.AUTO
@ -898,7 +870,6 @@ async def test_boost_mode(
# Event signals thermostat preset boost and valve 100 (real data)
await sensor_ws_data({"config": {"preset": "boost"}, "state": {"valve": 100}})
await hass.async_block_till_done()
climate_thermostat = hass.states.get("climate.thermostat")
assert climate_thermostat.attributes["preset_mode"] is PRESET_BOOST

View file

@ -57,7 +57,7 @@ async def test_cover(
hass: HomeAssistant,
config_entry_setup: ConfigEntry,
mock_put_request: Callable[[str, str], AiohttpClientMocker],
mock_websocket_data: WebsocketDataType,
light_ws_data: WebsocketDataType,
) -> None:
"""Test that all supported cover entities are created."""
assert len(hass.states.async_all()) == 2
@ -68,9 +68,7 @@ async def test_cover(
# Event signals cover is open
await mock_websocket_data({"r": "lights", "state": {"lift": 0, "open": True}})
await hass.async_block_till_done()
await light_ws_data({"state": {"lift": 0, "open": True}})
cover = hass.states.get("cover.window_covering_device")
assert cover.state == STATE_OPEN
assert cover.attributes[ATTR_CURRENT_POSITION] == 100

View file

@ -99,7 +99,6 @@ async def test_deconz_events(
captured_events = async_capture_events(hass, CONF_DECONZ_EVENT)
await sensor_ws_data({"id": "1", "state": {"buttonevent": 2000}})
await hass.async_block_till_done()
device = device_registry.async_get_device(
identifiers={(DECONZ_DOMAIN, "00:00:00:00:00:00:00:01")}
@ -114,7 +113,6 @@ async def test_deconz_events(
}
await sensor_ws_data({"id": "3", "state": {"buttonevent": 2000}})
await hass.async_block_till_done()
device = device_registry.async_get_device(
identifiers={(DECONZ_DOMAIN, "00:00:00:00:00:00:00:03")}
@ -130,7 +128,6 @@ async def test_deconz_events(
}
await sensor_ws_data({"id": "4", "state": {"gesture": 0}})
await hass.async_block_till_done()
device = device_registry.async_get_device(
identifiers={(DECONZ_DOMAIN, "00:00:00:00:00:00:00:04")}
@ -150,7 +147,6 @@ async def test_deconz_events(
"state": {"buttonevent": 6002, "angle": 110, "xy": [0.5982, 0.3897]},
}
await sensor_ws_data(event_changed_sensor)
await hass.async_block_till_done()
device = device_registry.async_get_device(
identifiers={(DECONZ_DOMAIN, "00:00:00:00:00:00:00:05")}
@ -169,8 +165,6 @@ async def test_deconz_events(
# Unsupported event
await sensor_ws_data({"id": "1", "name": "other name"})
await hass.async_block_till_done()
assert len(captured_events) == 4
await hass.config_entries.async_unload(config_entry_setup.entry_id)
@ -272,7 +266,6 @@ async def test_deconz_alarm_events(
# Emergency event
await sensor_ws_data({"state": {"action": AncillaryControlAction.EMERGENCY}})
await hass.async_block_till_done()
device = device_registry.async_get_device(
identifiers={(DECONZ_DOMAIN, "00:00:00:00:00:00:00:01")}
@ -289,7 +282,6 @@ async def test_deconz_alarm_events(
# Fire event
await sensor_ws_data({"state": {"action": AncillaryControlAction.FIRE}})
await hass.async_block_till_done()
device = device_registry.async_get_device(
identifiers={(DECONZ_DOMAIN, "00:00:00:00:00:00:00:01")}
@ -306,7 +298,6 @@ async def test_deconz_alarm_events(
# Invalid code event
await sensor_ws_data({"state": {"action": AncillaryControlAction.INVALID_CODE}})
await hass.async_block_till_done()
device = device_registry.async_get_device(
identifiers={(DECONZ_DOMAIN, "00:00:00:00:00:00:00:01")}
@ -323,7 +314,6 @@ async def test_deconz_alarm_events(
# Panic event
await sensor_ws_data({"state": {"action": AncillaryControlAction.PANIC}})
await hass.async_block_till_done()
device = device_registry.async_get_device(
identifiers={(DECONZ_DOMAIN, "00:00:00:00:00:00:00:01")}
@ -340,15 +330,11 @@ async def test_deconz_alarm_events(
# Only care for changes to specific action events
await sensor_ws_data({"state": {"action": AncillaryControlAction.ARMED_AWAY}})
await hass.async_block_till_done()
assert len(captured_events) == 4
# Only care for action events
await sensor_ws_data({"state": {"panel": AncillaryControlPanel.ARMED_AWAY}})
await hass.async_block_till_done()
assert len(captured_events) == 4
await hass.config_entries.async_unload(config_entry_setup.entry_id)
@ -425,7 +411,6 @@ async def test_deconz_presence_events(
PresenceStatePresenceEvent.RIGHT_LEAVE,
):
await sensor_ws_data({"state": {"presenceevent": presence_event}})
await hass.async_block_till_done()
assert len(captured_events) == 1
assert captured_events[0].data == {
@ -439,8 +424,6 @@ async def test_deconz_presence_events(
# Unsupported presence event
await sensor_ws_data({"state": {"presenceevent": PresenceStatePresenceEvent.NINE}})
await hass.async_block_till_done()
assert len(captured_events) == 0
await hass.config_entries.async_unload(config_entry_setup.entry_id)
@ -514,7 +497,6 @@ async def test_deconz_relative_rotary_events(
}
}
await sensor_ws_data(event_changed_sensor)
await hass.async_block_till_done()
assert len(captured_events) == 1
assert captured_events[0].data == {
@ -530,8 +512,6 @@ async def test_deconz_relative_rotary_events(
# Unsupported relative rotary event
await sensor_ws_data({"name": "123"})
await hass.async_block_till_done()
assert len(captured_events) == 0
await hass.config_entries.async_unload(config_entry_setup.entry_id)

View file

@ -344,8 +344,6 @@ async def test_functional_device_trigger(
assert len(hass.states.async_entity_ids(AUTOMATION_DOMAIN)) == 1
await sensor_ws_data({"state": {"buttonevent": 1002}})
await hass.async_block_till_done()
assert len(service_calls) == 1
assert service_calls[0].data["some"] == "test_trigger_button_press"

View file

@ -47,7 +47,7 @@ async def test_fans(
aioclient_mock: AiohttpClientMocker,
config_entry_setup: ConfigEntry,
mock_put_request: Callable[[str, str], AiohttpClientMocker],
mock_websocket_data: WebsocketDataType,
light_ws_data: WebsocketDataType,
) -> None:
"""Test that all supported fan entities are created."""
assert len(hass.states.async_all()) == 2 # Light and fan
@ -56,33 +56,23 @@ async def test_fans(
# Test states
await mock_websocket_data({"r": "lights", "state": {"speed": 1}})
await hass.async_block_till_done()
await light_ws_data({"state": {"speed": 1}})
assert hass.states.get("fan.ceiling_fan").state == STATE_ON
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 25
await mock_websocket_data({"r": "lights", "state": {"speed": 2}})
await hass.async_block_till_done()
await light_ws_data({"state": {"speed": 2}})
assert hass.states.get("fan.ceiling_fan").state == STATE_ON
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 50
await mock_websocket_data({"r": "lights", "state": {"speed": 3}})
await hass.async_block_till_done()
await light_ws_data({"state": {"speed": 3}})
assert hass.states.get("fan.ceiling_fan").state == STATE_ON
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 75
await mock_websocket_data({"r": "lights", "state": {"speed": 4}})
await hass.async_block_till_done()
await light_ws_data({"state": {"speed": 4}})
assert hass.states.get("fan.ceiling_fan").state == STATE_ON
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 100
await mock_websocket_data({"r": "lights", "state": {"speed": 0}})
await hass.async_block_till_done()
await light_ws_data({"state": {"speed": 0}})
assert hass.states.get("fan.ceiling_fan").state == STATE_OFF
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 0
@ -172,9 +162,7 @@ async def test_fans(
# Events with an unsupported speed does not get converted
await mock_websocket_data({"r": "lights", "state": {"speed": 5}})
await hass.async_block_till_done()
await light_ws_data({"state": {"speed": 5}})
assert hass.states.get("fan.ceiling_fan").state == STATE_ON
assert not hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE]

View file

@ -471,14 +471,12 @@ async def test_lights(
@pytest.mark.usefixtures("config_entry_setup")
async def test_light_state_change(
hass: HomeAssistant,
mock_websocket_data: WebsocketDataType,
light_ws_data: WebsocketDataType,
) -> None:
"""Verify light can change state on websocket event."""
assert hass.states.get("light.hue_go").state == STATE_ON
await mock_websocket_data({"r": "lights", "state": {"on": False}})
await hass.async_block_till_done()
await light_ws_data({"state": {"on": False}})
assert hass.states.get("light.hue_go").state == STATE_OFF
@ -1280,7 +1278,7 @@ async def test_disable_light_groups(
@pytest.mark.usefixtures("config_entry_setup")
async def test_non_color_light_reports_color(
hass: HomeAssistant,
mock_websocket_data: WebsocketDataType,
light_ws_data: WebsocketDataType,
) -> None:
"""Verify hs_color does not crash when a group gets updated with a bad color value.
@ -1303,7 +1301,6 @@ async def test_non_color_light_reports_color(
# for a non-color light causing an exception in hs_color
event_changed_light = {
"id": "1",
"r": "lights",
"state": {
"alert": None,
"bri": 216,
@ -1314,9 +1311,7 @@ async def test_non_color_light_reports_color(
},
"uniqueid": "ec:1b:bd:ff:fe:ee:ed:dd-01",
}
await mock_websocket_data(event_changed_light)
await hass.async_block_till_done()
await light_ws_data(event_changed_light)
group = hass.states.get("light.group")
assert group.attributes[ATTR_COLOR_MODE] == ColorMode.XY
assert group.attributes[ATTR_HS_COLOR] == (40.571, 41.176)

View file

@ -45,15 +45,13 @@ async def test_lock_from_light(
hass: HomeAssistant,
config_entry_setup: ConfigEntry,
mock_put_request: Callable[[str, str], AiohttpClientMocker],
mock_websocket_data: WebsocketDataType,
light_ws_data: WebsocketDataType,
) -> None:
"""Test that all supported lock entities based on lights are created."""
assert len(hass.states.async_all()) == 1
assert hass.states.get("lock.door_lock").state == STATE_UNLOCKED
await mock_websocket_data({"r": "lights", "state": {"on": True}})
await hass.async_block_till_done()
await light_ws_data({"state": {"on": True}})
assert hass.states.get("lock.door_lock").state == STATE_LOCKED
# Verify service calls
@ -129,8 +127,6 @@ async def test_lock_from_sensor(
assert hass.states.get("lock.door_lock").state == STATE_UNLOCKED
await sensor_ws_data({"state": {"lockstate": "locked"}})
await hass.async_block_till_done()
assert hass.states.get("lock.door_lock").state == STATE_LOCKED
# Verify service calls

View file

@ -135,7 +135,6 @@ async def test_number_entities(
# Change state
await sensor_ws_data(expected["websocket_event"])
await hass.async_block_till_done()
assert hass.states.get(expected["entity_id"]).state == expected["next_state"]
# Verify service calls

View file

@ -131,6 +131,4 @@ async def test_only_new_scenes_are_created(
"scenes": [{"id": "1", "name": "Scene"}],
}
await mock_websocket_data(event_changed_group)
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 2

View file

@ -953,7 +953,6 @@ async def test_sensors(
# Change state
await sensor_ws_data(expected["websocket_event"])
await hass.async_block_till_done()
assert hass.states.get(expected["entity_id"]).state == expected["next_state"]
# Unload entry
@ -1073,8 +1072,6 @@ async def test_add_new_sensor(
assert len(hass.states.async_all()) == 0
await sensor_ws_data(event_added_sensor)
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 2
assert hass.states.get("sensor.light_level_sensor").state == "999.8"
@ -1172,15 +1169,10 @@ async def test_add_battery_later(
assert len(hass.states.async_all()) == 0
await sensor_ws_data({"id": "2", "config": {"battery": 50}})
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 0
await sensor_ws_data({"id": "1", "config": {"battery": 50}})
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 1
assert hass.states.get("sensor.switch_1_battery").state == "50"

View file

@ -35,16 +35,14 @@ from tests.test_util.aiohttp import AiohttpClientMocker
async def test_sirens(
hass: HomeAssistant,
config_entry_setup: ConfigEntry,
mock_websocket_data: WebsocketDataType,
light_ws_data: WebsocketDataType,
mock_put_request: Callable[[str, str], AiohttpClientMocker],
) -> None:
"""Test that siren entities are created."""
assert len(hass.states.async_all()) == 1
assert hass.states.get("siren.warning_device").state == STATE_ON
await mock_websocket_data({"r": "lights", "state": {"alert": None}})
await hass.async_block_till_done()
await light_ws_data({"state": {"alert": None}})
assert hass.states.get("siren.warning_device").state == STATE_OFF
# Verify service calls

View file

@ -56,7 +56,7 @@ async def test_power_plugs(
hass: HomeAssistant,
config_entry_setup: ConfigEntry,
mock_put_request: Callable[[str, str], AiohttpClientMocker],
mock_websocket_data: WebsocketDataType,
light_ws_data: WebsocketDataType,
) -> None:
"""Test that all supported switch entities are created."""
assert len(hass.states.async_all()) == 4
@ -65,9 +65,7 @@ async def test_power_plugs(
assert hass.states.get("switch.on_off_relay").state == STATE_ON
assert hass.states.get("switch.unsupported_switch") is None
await mock_websocket_data({"r": "lights", "state": {"on": False}})
await hass.async_block_till_done()
await light_ws_data({"state": {"on": False}})
assert hass.states.get("switch.on_off_switch").state == STATE_OFF
# Verify service calls