From 41d5256533ec6ef1c102af0a43c7b7f26b8e06fb Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 6 Dec 2022 22:56:33 -0500 Subject: [PATCH] Add via_device support to zwave_js (#83219) Co-authored-by: Paulus Schoutsen --- homeassistant/components/zwave_js/__init__.py | 31 +++- .../components/zwave_js/device_action.py | 3 + .../components/zwave_js/device_condition.py | 5 +- .../components/zwave_js/device_trigger.py | 9 +- tests/components/zwave_js/conftest.py | 14 +- tests/components/zwave_js/test_button.py | 1 - .../components/zwave_js/test_device_action.py | 17 +- .../zwave_js/test_device_condition.py | 73 ++++++--- .../zwave_js/test_device_trigger.py | 151 ++++++++++++++---- tests/components/zwave_js/test_init.py | 8 +- tests/components/zwave_js/test_sensor.py | 4 +- tests/components/zwave_js/test_services.py | 13 +- tests/components/zwave_js/test_trigger.py | 21 ++- tests/components/zwave_js/test_update.py | 1 - 14 files changed, 251 insertions(+), 100 deletions(-) diff --git a/homeassistant/components/zwave_js/__init__.py b/homeassistant/components/zwave_js/__init__.py index e7b17b30b03..2d6e7350899 100644 --- a/homeassistant/components/zwave_js/__init__.py +++ b/homeassistant/components/zwave_js/__init__.py @@ -230,6 +230,7 @@ class DriverEvents: async def setup(self, driver: Driver) -> None: """Set up devices using the ready driver.""" self.driver = driver + controller = driver.controller # If opt in preference hasn't been specified yet, we do nothing, otherwise # we apply the preference @@ -244,7 +245,7 @@ class DriverEvents: ) known_devices = [ self.dev_reg.async_get_device({get_device_id(driver, node)}) - for node in driver.controller.nodes.values() + for node in controller.nodes.values() ] # Devices that are in the device registry that are not known by the controller can be removed @@ -252,17 +253,24 @@ class DriverEvents: if device not in known_devices: self.dev_reg.async_remove_device(device.id) - # run discovery on all ready nodes + # run discovery on controller node + c_node_id = controller.own_node_id + controller_node = controller.nodes.get(c_node_id) if c_node_id else None + if controller_node: + await self.controller_events.async_on_node_added(controller_node) + + # run discovery on all other ready nodes await asyncio.gather( *( self.controller_events.async_on_node_added(node) - for node in driver.controller.nodes.values() + for node in controller.nodes.values() + if controller_node is None or node != controller_node ) ) # listen for new nodes being added to the mesh self.config_entry.async_on_unload( - driver.controller.on( + controller.on( "node added", lambda event: self.hass.async_create_task( self.controller_events.async_on_node_added(event["node"]) @@ -272,9 +280,7 @@ class DriverEvents: # listen for nodes being removed from the mesh # NOTE: This will not remove nodes that were removed when HA was not running self.config_entry.async_on_unload( - driver.controller.on( - "node removed", self.controller_events.async_on_node_removed - ) + controller.on("node removed", self.controller_events.async_on_node_removed) ) async def async_setup_platform(self, platform: Platform) -> None: @@ -383,6 +389,16 @@ class ControllerEvents: device_id = get_device_id(driver, node) device_id_ext = get_device_id_ext(driver, node) device = self.dev_reg.async_get_device({device_id}) + via_device_id = None + controller = driver.controller + # Get the controller node device ID if this node is not the controller + if ( + controller.own_node_id is not None + and controller.own_node_id != node.node_id + ): + via_device_id = get_device_id( + driver, controller.nodes[controller.own_node_id] + ) # Replace the device if it can be determined that this node is not the # same product as it was previously. @@ -408,6 +424,7 @@ class ControllerEvents: model=node.device_config.label, manufacturer=node.device_config.manufacturer, suggested_area=node.location if node.location else UNDEFINED, + via_device=via_device_id, ) async_dispatcher_send(self.hass, EVENT_DEVICE_ADDED_TO_REGISTRY, device) diff --git a/homeassistant/components/zwave_js/device_action.py b/homeassistant/components/zwave_js/device_action.py index 004e4cc2aae..54dd17b7b83 100644 --- a/homeassistant/components/zwave_js/device_action.py +++ b/homeassistant/components/zwave_js/device_action.py @@ -150,6 +150,9 @@ async def async_get_actions( node = async_get_node_from_device_id(hass, device_id) + if node.client.driver and node.client.driver.controller.own_node_id == node.node_id: + return actions + base_action = { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DOMAIN, diff --git a/homeassistant/components/zwave_js/device_condition.py b/homeassistant/components/zwave_js/device_condition.py index c42b5af71c4..87967c21dd5 100644 --- a/homeassistant/components/zwave_js/device_condition.py +++ b/homeassistant/components/zwave_js/device_condition.py @@ -126,7 +126,7 @@ async def async_get_conditions( hass: HomeAssistant, device_id: str ) -> list[dict[str, str]]: """List device conditions for Z-Wave JS devices.""" - conditions = [] + conditions: list[dict] = [] base_condition = { CONF_CONDITION: "device", CONF_DEVICE_ID: device_id, @@ -134,6 +134,9 @@ async def async_get_conditions( } node = async_get_node_from_device_id(hass, device_id) + if node.client.driver and node.client.driver.controller.own_node_id == node.node_id: + return conditions + # Any value's value condition conditions.append({**base_condition, CONF_TYPE: VALUE_TYPE}) diff --git a/homeassistant/components/zwave_js/device_trigger.py b/homeassistant/components/zwave_js/device_trigger.py index 76a7f134d17..348346680d7 100644 --- a/homeassistant/components/zwave_js/device_trigger.py +++ b/homeassistant/components/zwave_js/device_trigger.py @@ -248,9 +248,6 @@ async def async_get_triggers( hass: HomeAssistant, device_id: str ) -> list[dict[str, Any]]: """List device triggers for Z-Wave JS devices.""" - dev_reg = device_registry.async_get(hass) - node = async_get_node_from_device_id(hass, device_id, dev_reg) - triggers: list[dict] = [] base_trigger = { CONF_PLATFORM: "device", @@ -258,6 +255,12 @@ async def async_get_triggers( CONF_DOMAIN: DOMAIN, } + dev_reg = device_registry.async_get(hass) + node = async_get_node_from_device_id(hass, device_id, dev_reg) + + if node.client.driver and node.client.driver.controller.own_node_id == node.node_id: + return triggers + # We can add a node status trigger if the node status sensor is enabled ent_reg = entity_registry.async_get(hass) entity_id = async_get_node_status_sensor_entity_id( diff --git a/tests/components/zwave_js/conftest.py b/tests/components/zwave_js/conftest.py index e5a759ba0a0..ba97cfe4c36 100644 --- a/tests/components/zwave_js/conftest.py +++ b/tests/components/zwave_js/conftest.py @@ -583,7 +583,9 @@ def lock_home_connect_620_state_fixture(): @pytest.fixture(name="client") -def mock_client_fixture(controller_state, version_state, log_config_state): +def mock_client_fixture( + controller_state, controller_node_state, version_state, log_config_state +): """Mock a client.""" with patch( @@ -608,6 +610,8 @@ def mock_client_fixture(controller_state, version_state, log_config_state): client.listen = AsyncMock(side_effect=listen) client.disconnect = AsyncMock(side_effect=disconnect) client.driver = Driver(client, controller_state, log_config_state) + node = Node(client, copy.deepcopy(controller_node_state)) + client.driver.controller.nodes[node.node_id] = node client.version = VersionInfo.from_message(version_state) client.ws_server_url = "ws://test:3000/zjs" @@ -615,14 +619,6 @@ def mock_client_fixture(controller_state, version_state, log_config_state): yield client -@pytest.fixture(name="controller_node") -def controller_node_fixture(client, controller_node_state): - """Mock a controller node.""" - node = Node(client, copy.deepcopy(controller_node_state)) - client.driver.controller.nodes[node.node_id] = node - return node - - @pytest.fixture(name="multisensor_6") def multisensor_6_fixture(client, multisensor_6_state): """Mock a multisensor 6 node.""" diff --git a/tests/components/zwave_js/test_button.py b/tests/components/zwave_js/test_button.py index 336d3688988..27bd41b3142 100644 --- a/tests/components/zwave_js/test_button.py +++ b/tests/components/zwave_js/test_button.py @@ -10,7 +10,6 @@ async def test_ping_entity( hass, client, climate_radio_thermostat_ct100_plus_different_endpoints, - controller_node, integration, caplog, ): diff --git a/tests/components/zwave_js/test_device_action.py b/tests/components/zwave_js/test_device_action.py index ad9d61b3f33..a60f10761b6 100644 --- a/tests/components/zwave_js/test_device_action.py +++ b/tests/components/zwave_js/test_device_action.py @@ -91,6 +91,16 @@ async def test_get_actions( for action in expected_actions: assert action in actions + # Test that we don't return actions for a controller node + device = dev_reg.async_get_device( + {get_device_id(driver, client.driver.controller.nodes[1])} + ) + assert device + assert ( + await async_get_device_automations(hass, DeviceAutomationType.ACTION, device.id) + == [] + ) + async def test_get_actions_meter( hass: HomeAssistant, @@ -408,9 +418,10 @@ async def test_get_action_capabilities( ): """Test we get the expected action capabilities.""" dev_reg = device_registry.async_get(hass) - device = device_registry.async_entries_for_config_entry( - dev_reg, integration.entry_id - )[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, climate_radio_thermostat_ct100_plus)} + ) + assert device # Test refresh_value capabilities = await device_action.async_get_action_capabilities( diff --git a/tests/components/zwave_js/test_device_condition.py b/tests/components/zwave_js/test_device_condition.py index 8b538a3c48b..b42573f3aa9 100644 --- a/tests/components/zwave_js/test_device_condition.py +++ b/tests/components/zwave_js/test_device_condition.py @@ -15,7 +15,10 @@ from homeassistant.components.device_automation.exceptions import ( InvalidDeviceAutomationConfig, ) from homeassistant.components.zwave_js import DOMAIN, device_condition -from homeassistant.components.zwave_js.helpers import get_zwave_value_from_config +from homeassistant.components.zwave_js.helpers import ( + get_device_id, + get_zwave_value_from_config, +) from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, device_registry from homeassistant.setup import async_setup_component @@ -32,9 +35,10 @@ def calls(hass): async def test_get_conditions(hass, client, lock_schlage_be469, integration) -> None: """Test we get the expected onditions from a zwave_js.""" dev_reg = device_registry.async_get(hass) - device = device_registry.async_entries_for_config_entry( - dev_reg, integration.entry_id - )[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device config_value = list(lock_schlage_be469.get_configuration_values().values())[0] value_id = config_value.value_id name = config_value.property_name @@ -70,15 +74,28 @@ async def test_get_conditions(hass, client, lock_schlage_be469, integration) -> for condition in expected_conditions: assert condition in conditions + # Test that we don't return actions for a controller node + device = dev_reg.async_get_device( + {get_device_id(client.driver, client.driver.controller.nodes[1])} + ) + assert device + assert ( + await async_get_device_automations( + hass, DeviceAutomationType.CONDITION, device.id + ) + == [] + ) + async def test_node_status_state( hass, client, lock_schlage_be469, integration, calls ) -> None: """Test for node_status conditions.""" dev_reg = device_registry.async_get(hass) - device = device_registry.async_entries_for_config_entry( - dev_reg, integration.entry_id - )[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device assert await async_setup_component( hass, @@ -224,9 +241,10 @@ async def test_config_parameter_state( ) -> None: """Test for config_parameter conditions.""" dev_reg = device_registry.async_get(hass) - device = device_registry.async_entries_for_config_entry( - dev_reg, integration.entry_id - )[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device assert await async_setup_component( hass, @@ -333,9 +351,10 @@ async def test_value_state( ) -> None: """Test for value conditions.""" dev_reg = device_registry.async_get(hass) - device = device_registry.async_entries_for_config_entry( - dev_reg, integration.entry_id - )[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device assert await async_setup_component( hass, @@ -377,9 +396,10 @@ async def test_get_condition_capabilities_node_status( ): """Test we don't get capabilities from a node_status condition.""" dev_reg = device_registry.async_get(hass) - device = device_registry.async_entries_for_config_entry( - dev_reg, integration.entry_id - )[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device capabilities = await device_condition.async_get_condition_capabilities( hass, @@ -413,9 +433,10 @@ async def test_get_condition_capabilities_value( ): """Test we get the expected capabilities from a value condition.""" dev_reg = device_registry.async_get(hass) - device = device_registry.async_entries_for_config_entry( - dev_reg, integration.entry_id - )[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device capabilities = await device_condition.async_get_condition_capabilities( hass, @@ -462,9 +483,10 @@ async def test_get_condition_capabilities_config_parameter( """Test we get the expected capabilities from a config_parameter condition.""" node = climate_radio_thermostat_ct100_plus dev_reg = device_registry.async_get(hass) - device = device_registry.async_entries_for_config_entry( - dev_reg, integration.entry_id - )[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, climate_radio_thermostat_ct100_plus)} + ) + assert device # Test enumerated type param capabilities = await device_condition.async_get_condition_capabilities( @@ -541,9 +563,10 @@ async def test_get_condition_capabilities_config_parameter( async def test_failure_scenarios(hass, client, hank_binary_switch, integration): """Test failure scenarios.""" dev_reg = device_registry.async_get(hass) - device = device_registry.async_entries_for_config_entry( - dev_reg, integration.entry_id - )[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, hank_binary_switch)} + ) + assert device with pytest.raises(HomeAssistantError): await device_condition.async_condition_from_config( diff --git a/tests/components/zwave_js/test_device_trigger.py b/tests/components/zwave_js/test_device_trigger.py index 84d87efed63..e9bc319fe4d 100644 --- a/tests/components/zwave_js/test_device_trigger.py +++ b/tests/components/zwave_js/test_device_trigger.py @@ -15,13 +15,11 @@ from homeassistant.components.device_automation.exceptions import ( from homeassistant.components.zwave_js import DOMAIN, device_trigger from homeassistant.components.zwave_js.helpers import ( async_get_node_status_sensor_entity_id, + get_device_id, ) from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.device_registry import ( - async_entries_for_config_entry, - async_get as async_get_dev_reg, -) +from homeassistant.helpers.device_registry import async_get as async_get_dev_reg from homeassistant.helpers.entity_registry import async_get as async_get_ent_reg from homeassistant.setup import async_setup_component @@ -38,12 +36,30 @@ def calls(hass): return async_mock_service(hass, "test", "automation") +async def test_no_controller_triggers(hass, client, integration): + """Test that we do not get triggers for the controller.""" + dev_reg = async_get_dev_reg(hass) + device = dev_reg.async_get_device( + {get_device_id(client.driver, client.driver.controller.nodes[1])} + ) + assert device + assert ( + await async_get_device_automations( + hass, DeviceAutomationType.TRIGGER, device.id + ) + == [] + ) + + async def test_get_notification_notification_triggers( hass, client, lock_schlage_be469, integration ): """Test we get the expected triggers from a zwave_js device with the Notification CC.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device expected_trigger = { "platform": "device", "domain": DOMAIN, @@ -64,7 +80,10 @@ async def test_if_notification_notification_fires( """Test for event.notification.notification trigger firing.""" node: Node = lock_schlage_be469 dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device assert await async_setup_component( hass, @@ -157,7 +176,10 @@ async def test_get_trigger_capabilities_notification_notification( ): """Test we get the expected capabilities from a notification.notification trigger.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device capabilities = await device_trigger.async_get_trigger_capabilities( hass, { @@ -189,7 +211,10 @@ async def test_if_entry_control_notification_fires( """Test for notification.entry_control trigger firing.""" node: Node = lock_schlage_be469 dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device assert await async_setup_component( hass, @@ -281,7 +306,10 @@ async def test_get_trigger_capabilities_entry_control_notification( ): """Test we get the expected capabilities from a notification.entry_control trigger.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device capabilities = await device_trigger.async_get_trigger_capabilities( hass, { @@ -308,7 +336,10 @@ async def test_get_trigger_capabilities_entry_control_notification( async def test_get_node_status_triggers(hass, client, lock_schlage_be469, integration): """Test we get the expected triggers from a device with node status sensor enabled.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device ent_reg = async_get_ent_reg(hass) entity_id = async_get_node_status_sensor_entity_id( hass, device.id, ent_reg, dev_reg @@ -337,7 +368,10 @@ async def test_if_node_status_change_fires( """Test for node_status trigger firing.""" node: Node = lock_schlage_be469 dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device ent_reg = async_get_ent_reg(hass) entity_id = async_get_node_status_sensor_entity_id( hass, device.id, ent_reg, dev_reg @@ -412,7 +446,10 @@ async def test_get_trigger_capabilities_node_status( ): """Test we get the expected capabilities from a node_status trigger.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device ent_reg = async_get_ent_reg(hass) entity_id = async_get_node_status_sensor_entity_id( hass, device.id, ent_reg, dev_reg @@ -467,7 +504,10 @@ async def test_get_basic_value_notification_triggers( ): """Test we get the expected triggers from a zwave_js device with the Basic CC.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, ge_in_wall_dimmer_switch)} + ) + assert device expected_trigger = { "platform": "device", "domain": DOMAIN, @@ -492,7 +532,10 @@ async def test_if_basic_value_notification_fires( """Test for event.value_notification.basic trigger firing.""" node: Node = ge_in_wall_dimmer_switch dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, ge_in_wall_dimmer_switch)} + ) + assert device assert await async_setup_component( hass, @@ -600,7 +643,10 @@ async def test_get_trigger_capabilities_basic_value_notification( ): """Test we get the expected capabilities from a value_notification.basic trigger.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, ge_in_wall_dimmer_switch)} + ) + assert device capabilities = await device_trigger.async_get_trigger_capabilities( hass, { @@ -635,7 +681,10 @@ async def test_get_central_scene_value_notification_triggers( ): """Test we get the expected triggers from a zwave_js device with the Central Scene CC.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, wallmote_central_scene)} + ) + assert device expected_trigger = { "platform": "device", "domain": DOMAIN, @@ -660,7 +709,10 @@ async def test_if_central_scene_value_notification_fires( """Test for event.value_notification.central_scene trigger firing.""" node: Node = wallmote_central_scene dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, wallmote_central_scene)} + ) + assert device assert await async_setup_component( hass, @@ -775,7 +827,10 @@ async def test_get_trigger_capabilities_central_scene_value_notification( ): """Test we get the expected capabilities from a value_notification.central_scene trigger.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, wallmote_central_scene)} + ) + assert device capabilities = await device_trigger.async_get_trigger_capabilities( hass, { @@ -809,7 +864,10 @@ async def test_get_scene_activation_value_notification_triggers( ): """Test we get the expected triggers from a zwave_js device with the SceneActivation CC.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, hank_binary_switch)} + ) + assert device expected_trigger = { "platform": "device", "domain": DOMAIN, @@ -834,7 +892,10 @@ async def test_if_scene_activation_value_notification_fires( """Test for event.value_notification.scene_activation trigger firing.""" node: Node = hank_binary_switch dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, hank_binary_switch)} + ) + assert device assert await async_setup_component( hass, @@ -942,7 +1003,10 @@ async def test_get_trigger_capabilities_scene_activation_value_notification( ): """Test we get the expected capabilities from a value_notification.scene_activation trigger.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, hank_binary_switch)} + ) + assert device capabilities = await device_trigger.async_get_trigger_capabilities( hass, { @@ -977,7 +1041,10 @@ async def test_get_value_updated_value_triggers( ): """Test we get the zwave_js.value_updated.value trigger from a zwave_js device.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device expected_trigger = { "platform": "device", "domain": DOMAIN, @@ -997,7 +1064,10 @@ async def test_if_value_updated_value_fires( """Test for zwave_js.value_updated.value trigger firing.""" node: Node = lock_schlage_be469 dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device assert await async_setup_component( hass, @@ -1086,7 +1156,10 @@ async def test_value_updated_value_no_driver( """Test zwave_js.value_updated.value trigger with missing driver.""" node: Node = lock_schlage_be469 dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device driver = client.driver client.driver = None @@ -1153,7 +1226,10 @@ async def test_get_trigger_capabilities_value_updated_value( ): """Test we get the expected capabilities from a zwave_js.value_updated.value trigger.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device capabilities = await device_trigger.async_get_trigger_capabilities( hass, { @@ -1201,7 +1277,10 @@ async def test_get_value_updated_config_parameter_triggers( ): """Test we get the zwave_js.value_updated.config_parameter trigger from a zwave_js device.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device expected_trigger = { "platform": "device", "domain": DOMAIN, @@ -1226,7 +1305,10 @@ async def test_if_value_updated_config_parameter_fires( """Test for zwave_js.value_updated.config_parameter trigger firing.""" node: Node = lock_schlage_be469 dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device assert await async_setup_component( hass, @@ -1293,7 +1375,10 @@ async def test_get_trigger_capabilities_value_updated_config_parameter_range( ): """Test we get the expected capabilities from a range zwave_js.value_updated.config_parameter trigger.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device capabilities = await device_trigger.async_get_trigger_capabilities( hass, { @@ -1335,7 +1420,10 @@ async def test_get_trigger_capabilities_value_updated_config_parameter_enumerate ): """Test we get the expected capabilities from an enumerated zwave_js.value_updated.config_parameter trigger.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device capabilities = await device_trigger.async_get_trigger_capabilities( hass, { @@ -1386,7 +1474,10 @@ async def test_failure_scenarios(hass, client, hank_binary_switch, integration): ) dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, hank_binary_switch)} + ) + assert device with pytest.raises(HomeAssistantError): await device_trigger.async_attach_trigger( diff --git a/tests/components/zwave_js/test_init.py b/tests/components/zwave_js/test_init.py index 4f58c87febb..0d22484bea6 100644 --- a/tests/components/zwave_js/test_init.py +++ b/tests/components/zwave_js/test_init.py @@ -199,7 +199,7 @@ async def test_on_node_added_not_ready( device_id = f"{client.driver.controller.home_id}-{zp3111_not_ready_state['nodeId']}" assert len(hass.states.async_all()) == 0 - assert not dev_reg.devices + assert len(dev_reg.devices) == 1 node_state = deepcopy(zp3111_not_ready_state) node_state["isSecure"] = False @@ -911,12 +911,12 @@ async def test_removed_device( driver = client.driver assert driver # Verify how many nodes are available - assert len(driver.controller.nodes) == 2 + assert len(driver.controller.nodes) == 3 # Make sure there are the same number of devices dev_reg = dr.async_get(hass) device_entries = dr.async_entries_for_config_entry(dev_reg, integration.entry_id) - assert len(device_entries) == 2 + assert len(device_entries) == 3 # Check how many entities there are ent_reg = er.async_get(hass) @@ -931,7 +931,7 @@ async def test_removed_device( # Assert that the node and all of it's entities were removed from the device and # entity registry device_entries = dr.async_entries_for_config_entry(dev_reg, integration.entry_id) - assert len(device_entries) == 1 + assert len(device_entries) == 2 entity_entries = er.async_entries_for_config_entry(ent_reg, integration.entry_id) assert len(entity_entries) == 18 assert dev_reg.async_get_device({get_device_id(driver, old_node)}) is None diff --git a/tests/components/zwave_js/test_sensor.py b/tests/components/zwave_js/test_sensor.py index 848c4d7b0e5..a32537b1d0d 100644 --- a/tests/components/zwave_js/test_sensor.py +++ b/tests/components/zwave_js/test_sensor.py @@ -156,9 +156,7 @@ async def test_config_parameter_sensor(hass, lock_id_lock_as_id150, integration) assert entity_entry.disabled -async def test_node_status_sensor( - hass, client, controller_node, lock_id_lock_as_id150, integration -): +async def test_node_status_sensor(hass, client, lock_id_lock_as_id150, integration): """Test node status sensor is created and gets updated on node state changes.""" NODE_STATUS_ENTITY = "sensor.z_wave_module_for_id_lock_150_and_101_node_status" node = lock_id_lock_as_id150 diff --git a/tests/components/zwave_js/test_services.py b/tests/components/zwave_js/test_services.py index 6e425bff042..710892c4741 100644 --- a/tests/components/zwave_js/test_services.py +++ b/tests/components/zwave_js/test_services.py @@ -34,10 +34,7 @@ from homeassistant.components.zwave_js.helpers import get_device_id from homeassistant.const import ATTR_AREA_ID, ATTR_DEVICE_ID, ATTR_ENTITY_ID from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.area_registry import async_get as async_get_area_reg -from homeassistant.helpers.device_registry import ( - async_entries_for_config_entry, - async_get as async_get_dev_reg, -) +from homeassistant.helpers.device_registry import async_get as async_get_dev_reg from homeassistant.helpers.entity_registry import async_get as async_get_ent_reg from homeassistant.setup import async_setup_component @@ -408,7 +405,8 @@ async def test_set_config_parameter_gather( async def test_bulk_set_config_parameters(hass, client, multisensor_6, integration): """Test the bulk_set_partial_config_parameters service.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device({get_device_id(client.driver, multisensor_6)}) + assert device # Test setting config parameter by property and property_key await hass.services.async_call( DOMAIN, @@ -736,7 +734,10 @@ async def test_refresh_value( async def test_set_value(hass, client, climate_danfoss_lc_13, integration): """Test set_value service.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, climate_danfoss_lc_13)} + ) + assert device await hass.services.async_call( DOMAIN, diff --git a/tests/components/zwave_js/test_trigger.py b/tests/components/zwave_js/test_trigger.py index b3b6910e5f5..56a8e63b439 100644 --- a/tests/components/zwave_js/test_trigger.py +++ b/tests/components/zwave_js/test_trigger.py @@ -9,15 +9,13 @@ from zwave_js_server.model.node import Node from homeassistant.components import automation from homeassistant.components.zwave_js import DOMAIN +from homeassistant.components.zwave_js.helpers import get_device_id from homeassistant.components.zwave_js.trigger import async_validate_trigger_config from homeassistant.components.zwave_js.triggers.trigger_helpers import ( async_bypass_dynamic_config_validation, ) from homeassistant.const import SERVICE_RELOAD -from homeassistant.helpers.device_registry import ( - async_entries_for_config_entry, - async_get as async_get_dev_reg, -) +from homeassistant.helpers.device_registry import async_get as async_get_dev_reg from homeassistant.setup import async_setup_component from .common import SCHLAGE_BE469_LOCK_ENTITY @@ -30,7 +28,10 @@ async def test_zwave_js_value_updated(hass, client, lock_schlage_be469, integrat trigger_type = f"{DOMAIN}.value_updated" node: Node = lock_schlage_be469 dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device no_value_filter = async_capture_events(hass, "no_value_filter") single_from_value_filter = async_capture_events(hass, "single_from_value_filter") @@ -449,7 +450,10 @@ async def test_zwave_js_event(hass, client, lock_schlage_be469, integration): trigger_type = f"{DOMAIN}.event" node: Node = lock_schlage_be469 dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device node_no_event_data_filter = async_capture_events(hass, "node_no_event_data_filter") node_event_data_filter = async_capture_events(hass, "node_event_data_filter") @@ -992,7 +996,10 @@ async def test_zwave_js_trigger_config_entry_unloaded( ): """Test zwave_js triggers bypass dynamic validation when needed.""" dev_reg = async_get_dev_reg(hass) - device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] + device = dev_reg.async_get_device( + {get_device_id(client.driver, lock_schlage_be469)} + ) + assert device # Test bypass check is False assert not async_bypass_dynamic_config_validation( diff --git a/tests/components/zwave_js/test_update.py b/tests/components/zwave_js/test_update.py index 4c00c1c9a3a..1650b7e8edd 100644 --- a/tests/components/zwave_js/test_update.py +++ b/tests/components/zwave_js/test_update.py @@ -72,7 +72,6 @@ async def test_update_entity_states( hass, client, climate_radio_thermostat_ct100_plus_different_endpoints, - controller_node, integration, caplog, hass_ws_client,