async def test_device_diagnostics_error(hass, integration): """Test the device diagnostics raises exception when an invalid device is used.""" dev_reg = async_get_dev_reg(hass) device = dev_reg.async_get_or_create(config_entry_id=integration.entry_id, identifiers={("test", "test")}) with pytest.raises(ValueError): await async_get_device_diagnostics(hass, integration, device)
def async_get_node_status_sensor_entity_id( hass: HomeAssistant, device_id: str, ent_reg: EntityRegistry | None = None, dev_reg: DeviceRegistry | None = None, ) -> str: """Get the node status sensor entity ID for a given Z-Wave JS device.""" if not ent_reg: ent_reg = async_get_ent_reg(hass) if not dev_reg: dev_reg = async_get_dev_reg(hass) device = dev_reg.async_get(device_id) if not device: raise HomeAssistantError("Invalid Device ID provided") entry_id = next(entry_id for entry_id in device.config_entries) client = hass.data[DOMAIN][entry_id][DATA_CLIENT] node = async_get_node_from_device_id(hass, device_id, dev_reg) entity_id = ent_reg.async_get_entity_id( SENSOR_DOMAIN, DOMAIN, f"{client.driver.controller.home_id}.{node.node_id}.node_status", ) if not entity_id: raise HomeAssistantError( "Node status sensor entity not found. Device may not be a zwave_js device" ) return entity_id
async def test_get_trigger_capabilities_central_scene_value_notification( hass, client, wallmote_central_scene, integration ): """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] capabilities = await device_trigger.async_get_trigger_capabilities( hass, { "platform": "device", "domain": DOMAIN, "type": "event.value_notification.central_scene", "device_id": device.id, "command_class": CommandClass.CENTRAL_SCENE.value, "property": "scene", "property_key": "001", "endpoint": 0, "subtype": "Endpoint 0 Scene 001", }, ) assert capabilities and "extra_fields" in capabilities assert voluptuous_serialize.convert( capabilities["extra_fields"], custom_serializer=cv.custom_serializer ) == [ { "name": "value", "optional": True, "type": "select", "options": [(0, "KeyPressed"), (1, "KeyReleased"), (2, "KeyHeldDown")], }, ]
async def test_get_trigger_capabilities_scene_activation_value_notification( hass, client, hank_binary_switch, integration ): """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] capabilities = await device_trigger.async_get_trigger_capabilities( hass, { "platform": "device", "domain": DOMAIN, "type": "event.value_notification.scene_activation", "device_id": device.id, "command_class": CommandClass.SCENE_ACTIVATION.value, "property": "sceneId", "property_key": None, "endpoint": 0, "subtype": "Endpoint 0", }, ) assert capabilities and "extra_fields" in capabilities assert voluptuous_serialize.convert( capabilities["extra_fields"], custom_serializer=cv.custom_serializer ) == [ { "name": "value", "optional": True, "type": "integer", "valueMin": 1, "valueMax": 255, } ]
async def test_get_trigger_capabilities_entry_control_notification( hass, client, lock_schlage_be469, integration ): """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] capabilities = await device_trigger.async_get_trigger_capabilities( hass, { "platform": "device", "domain": DOMAIN, "device_id": device.id, "type": "event.notification.entry_control", "command_class": CommandClass.ENTRY_CONTROL.value, }, ) assert capabilities and "extra_fields" in capabilities assert_lists_same( voluptuous_serialize.convert( capabilities["extra_fields"], custom_serializer=cv.custom_serializer ), [ {"name": "event_type", "optional": True, "type": "string"}, {"name": "data_type", "optional": True, "type": "string"}, ], )
async def test_device_diagnostics( hass, client, multisensor_6, integration, hass_client, version_state, ): """Test the device level diagnostics data dump.""" dev_reg = async_get_dev_reg(hass) device = dev_reg.async_get_device( {get_device_id(client.driver, multisensor_6)}) assert device # Update a value and ensure it is reflected in the node state event = Event( type="value updated", data={ "source": "node", "event": "value updated", "nodeId": multisensor_6.node_id, "args": { "commandClassName": "Multilevel Sensor", "commandClass": 49, "endpoint": 0, "property": PROPERTY_ULTRAVIOLET, "newValue": 1, "prevValue": 0, "propertyName": PROPERTY_ULTRAVIOLET, }, }, ) multisensor_6.receive_event(event) diagnostics_data = await get_diagnostics_for_device( hass, hass_client, integration, device) assert diagnostics_data["versionInfo"] == { "driverVersion": version_state["driverVersion"], "serverVersion": version_state["serverVersion"], "minSchemaVersion": 0, "maxSchemaVersion": 0, } # Assert that we only have the entities that were discovered for this device # Entities that are created outside of discovery (e.g. node status sensor and # ping button) should not be in dump. assert len(diagnostics_data["entities"]) == len( list( async_discover_node_values(multisensor_6, device, {device.id: set()}))) assert diagnostics_data["state"] == { **multisensor_6.data, "statistics": { "commandsDroppedRX": 0, "commandsDroppedTX": 0, "commandsRX": 0, "commandsTX": 0, "timeoutResponse": 0, }, }
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback) -> None: """Set up the Tibber sensor.""" tibber_connection = hass.data[TIBBER_DOMAIN] entity_registry = async_get_entity_reg(hass) device_registry = async_get_dev_reg(hass) coordinator: TibberDataCoordinator | None = None entities: list[TibberSensor] = [] for home in tibber_connection.get_homes(only_active=False): try: await home.update_info() except asyncio.TimeoutError as err: _LOGGER.error("Timeout connecting to Tibber home: %s ", err) raise PlatformNotReady() from err except aiohttp.ClientError as err: _LOGGER.error("Error connecting to Tibber home: %s ", err) raise PlatformNotReady() from err if home.has_active_subscription: entities.append(TibberSensorElPrice(home)) if coordinator is None: coordinator = TibberDataCoordinator(hass, tibber_connection) for entity_description in SENSORS: entities.append( TibberDataSensor(home, coordinator, entity_description)) if home.has_real_time_consumption: await home.rt_subscribe( TibberRtDataCoordinator(async_add_entities, home, hass).async_set_updated_data) # migrate old_id = home.info["viewer"]["home"]["meteringPointData"][ "consumptionEan"] if old_id is None: continue # migrate to new device ids old_entity_id = entity_registry.async_get_entity_id( "sensor", TIBBER_DOMAIN, old_id) if old_entity_id is not None: entity_registry.async_update_entity(old_entity_id, new_unique_id=home.home_id) # migrate to new device ids device_entry = device_registry.async_get_device({(TIBBER_DOMAIN, old_id)}) if device_entry and entry.entry_id in device_entry.config_entries: device_registry.async_update_device(device_entry.id, new_identifiers={ (TIBBER_DOMAIN, home.home_id) }) async_add_entities(entities, True)
async def test_failure_scenarios(hass, client, hank_binary_switch, integration): """Test failure scenarios.""" with pytest.raises(HomeAssistantError): await async_attach_trigger(hass, { "type": "failed.test", "device_id": "invalid_device_id" }, None, {}) with pytest.raises(HomeAssistantError): await async_attach_trigger( hass, { "type": "event.failed_type", "device_id": "invalid_device_id" }, None, {}, ) dev_reg = async_get_dev_reg(hass) device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] with pytest.raises(HomeAssistantError): await async_attach_trigger(hass, { "type": "failed.test", "device_id": device.id }, None, {}) with pytest.raises(HomeAssistantError): await async_attach_trigger( hass, { "type": "event.failed_type", "device_id": device.id }, None, {}, ) with patch( "homeassistant.components.zwave_js.device_trigger.async_get_node_from_device_id", return_value=None, ), patch( "homeassistant.components.zwave_js.helpers.get_zwave_value_from_config", return_value=None, ): assert (await async_get_trigger_capabilities(hass, { "type": "failed.test", "device_id": "invalid_device_id" }) == {}) with pytest.raises(HomeAssistantError): async_get_node_status_sensor_entity_id(hass, "invalid_device_id")
def async_get_node_from_device_id( hass: HomeAssistant, device_id: str, dev_reg: DeviceRegistry | None = None ) -> ZwaveNode: """ Get node from a device ID. Raises ValueError if device is invalid or node can't be found. """ if not dev_reg: dev_reg = async_get_dev_reg(hass) device_entry = dev_reg.async_get(device_id) if not device_entry: raise ValueError(f"Device ID {device_id} is not valid") # Use device config entry ID's to validate that this is a valid zwave_js device # and to get the client config_entry_ids = device_entry.config_entries config_entry_id = next( ( config_entry_id for config_entry_id in config_entry_ids if cast( ConfigEntry, hass.config_entries.async_get_entry(config_entry_id), ).domain == DOMAIN ), None, ) if config_entry_id is None or config_entry_id not in hass.data[DOMAIN]: raise ValueError( f"Device {device_id} is not from an existing zwave_js config entry" ) client = hass.data[DOMAIN][config_entry_id][DATA_CLIENT] # Get node ID from device identifier, perform some validation, and then get the # node identifier = next( ( get_home_and_node_id_from_device_id(identifier) for identifier in device_entry.identifiers if identifier[0] == DOMAIN ), None, ) node_id = int(identifier[1]) if identifier is not None else None if node_id is None or node_id not in client.driver.controller.nodes: raise ValueError(f"Node for device {device_id} can't be found") return client.driver.controller.nodes[node_id]
async def test_get_trigger_capabilities_node_status( hass, client, lock_schlage_be469, integration ): """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] ent_reg = async_get_ent_reg(hass) entity_id = async_get_node_status_sensor_entity_id( hass, device.id, ent_reg, dev_reg ) ent_reg.async_update_entity(entity_id, **{"disabled_by": None}) await hass.config_entries.async_reload(integration.entry_id) await hass.async_block_till_done() capabilities = await device_trigger.async_get_trigger_capabilities( hass, { "platform": "device", "domain": DOMAIN, "device_id": device.id, "entity_id": entity_id, "type": "state.node_status", }, ) assert capabilities and "extra_fields" in capabilities assert voluptuous_serialize.convert( capabilities["extra_fields"], custom_serializer=cv.custom_serializer ) == [ { "name": "from", "optional": True, "options": [ ("asleep", "asleep"), ("awake", "awake"), ("dead", "dead"), ("alive", "alive"), ], "type": "select", }, { "name": "to", "optional": True, "options": [ ("asleep", "asleep"), ("awake", "awake"), ("dead", "dead"), ("alive", "alive"), ], "type": "select", }, {"name": "for", "optional": True, "type": "positive_time_period_dict"}, ]
async def test_get_value_updated_value_triggers(hass, client, lock_schlage_be469, integration): """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] expected_trigger = { "platform": "device", "domain": DOMAIN, "type": "zwave_js.value_updated.value", "device_id": device.id, } triggers = await async_get_device_automations(hass, "trigger", device.id) assert expected_trigger in triggers
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] expected_trigger = { "platform": "device", "domain": DOMAIN, "type": "event.notification.notification", "device_id": device.id, "command_class": CommandClass.NOTIFICATION, } triggers = await async_get_device_automations(hass, "trigger", device.id) assert expected_trigger in triggers
async def test_get_trigger_capabilities_value_updated_value( hass, client, lock_schlage_be469, integration ): """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] capabilities = await device_trigger.async_get_trigger_capabilities( hass, { "platform": "device", "domain": DOMAIN, "device_id": device.id, "type": "zwave_js.value_updated.value", "command_class": CommandClass.DOOR_LOCK.value, "property": "latchStatus", "property_key": None, "endpoint": None, }, ) assert capabilities and "extra_fields" in capabilities assert voluptuous_serialize.convert( capabilities["extra_fields"], custom_serializer=cv.custom_serializer ) == [ { "name": "command_class", "required": True, "type": "select", "options": [ (133, "Association"), (128, "Battery"), (98, "Door Lock"), (122, "Firmware Update Meta Data"), (114, "Manufacturer Specific"), (113, "Notification"), (152, "Security"), (99, "User Code"), (134, "Version"), ], }, {"name": "property", "required": True, "type": "string"}, {"name": "property_key", "optional": True, "type": "string"}, {"name": "endpoint", "optional": True, "type": "string"}, {"name": "from", "optional": True, "type": "string"}, {"name": "to", "optional": True, "type": "string"}, ]
async def test_get_central_scene_value_notification_triggers( hass, client, wallmote_central_scene, integration): """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] expected_trigger = { "platform": "device", "domain": DOMAIN, "type": "event.value_notification.central_scene", "device_id": device.id, "command_class": CommandClass.CENTRAL_SCENE, "property": "scene", "property_key": "001", "endpoint": 0, "subtype": "Endpoint 0 Scene 001", } triggers = await async_get_device_automations(hass, "trigger", device.id) assert expected_trigger in triggers
async def test_get_scene_activation_value_notification_triggers( hass, client, hank_binary_switch, integration): """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] expected_trigger = { "platform": "device", "domain": DOMAIN, "type": "event.value_notification.scene_activation", "device_id": device.id, "command_class": CommandClass.SCENE_ACTIVATION.value, "property": "sceneId", "property_key": None, "endpoint": 0, "subtype": "Endpoint 0", } triggers = await async_get_device_automations(hass, "trigger", device.id) assert expected_trigger in triggers
async def test_get_value_updated_config_parameter_triggers( hass, client, lock_schlage_be469, integration): """Test we get the zwave_js.value_updated.config_parameter trigger from a zwave_js device.""" node = lock_schlage_be469 dev_reg = async_get_dev_reg(hass) device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] expected_trigger = { "platform": "device", "domain": DOMAIN, "type": "zwave_js.value_updated.config_parameter", "device_id": device.id, "property": 3, "property_key": None, "endpoint": 0, "command_class": CommandClass.CONFIGURATION.value, "subtype": f"{node.node_id}-112-0-3 (Beeper)", } triggers = await async_get_device_automations(hass, "trigger", device.id) assert expected_trigger in triggers
async def test_get_basic_value_notification_triggers(hass, client, ge_in_wall_dimmer_switch, integration): """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] expected_trigger = { "platform": "device", "domain": DOMAIN, "type": "event.value_notification.basic", "device_id": device.id, "command_class": CommandClass.BASIC, "property": "event", "property_key": None, "endpoint": 0, "subtype": "Endpoint 0", } triggers = await async_get_device_automations(hass, "trigger", device.id) assert expected_trigger in triggers
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] ent_reg = async_get_ent_reg(hass) entity_id = async_get_node_status_sensor_entity_id(hass, device.id, ent_reg, dev_reg) ent_reg.async_update_entity(entity_id, **{"disabled_by": None}) await hass.config_entries.async_reload(integration.entry_id) await hass.async_block_till_done() expected_trigger = { "platform": "device", "domain": DOMAIN, "type": "state.node_status", "device_id": device.id, "entity_id": entity_id, } triggers = await async_get_device_automations(hass, "trigger", device.id) assert expected_trigger in triggers
async def test_get_trigger_capabilities_value_updated_config_parameter_range( hass, client, lock_schlage_be469, integration ): """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] capabilities = await device_trigger.async_get_trigger_capabilities( hass, { "platform": "device", "domain": DOMAIN, "device_id": device.id, "type": "zwave_js.value_updated.config_parameter", "property": 6, "property_key": None, "endpoint": 0, "command_class": CommandClass.CONFIGURATION.value, "subtype": "6 (User Slot Status)", }, ) assert capabilities and "extra_fields" in capabilities assert voluptuous_serialize.convert( capabilities["extra_fields"], custom_serializer=cv.custom_serializer ) == [ { "name": "from", "optional": True, "valueMin": 0, "valueMax": 255, "type": "integer", }, { "name": "to", "optional": True, "valueMin": 0, "valueMax": 255, "type": "integer", }, ]
async def test_get_trigger_capabilities_value_updated_config_parameter_enumerated( hass, client, lock_schlage_be469, integration): """Test we get the expected capabilities from an enumerated zwave_js.value_updated.config_parameter trigger.""" node = lock_schlage_be469 dev_reg = async_get_dev_reg(hass) device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] capabilities = await device_trigger.async_get_trigger_capabilities( hass, { "platform": "device", "domain": DOMAIN, "device_id": device.id, "type": "zwave_js.value_updated.config_parameter", "property": 3, "property_key": None, "endpoint": 0, "command_class": CommandClass.CONFIGURATION.value, "subtype": f"{node.node_id}-112-0-3 (Beeper)", }, ) assert capabilities and "extra_fields" in capabilities assert voluptuous_serialize.convert( capabilities["extra_fields"], custom_serializer=cv.custom_serializer) == [ { "name": "from", "optional": True, "options": [(0, "Disable Beeper"), (255, "Enable Beeper")], "type": "select", }, { "name": "to", "optional": True, "options": [(0, "Disable Beeper"), (255, "Enable Beeper")], "type": "select", }, ]
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] await hass.services.async_call( DOMAIN, SERVICE_SET_VALUE, { ATTR_ENTITY_ID: CLIMATE_DANFOSS_LC13_ENTITY, ATTR_COMMAND_CLASS: 117, ATTR_PROPERTY: "local", ATTR_VALUE: 2, }, blocking=True, ) assert len(client.async_send_command_no_wait.call_args_list) == 1 args = client.async_send_command_no_wait.call_args[0][0] assert args["command"] == "node.set_value" assert args["nodeId"] == 5 assert args["valueId"] == { "commandClassName": "Protection", "commandClass": 117, "endpoint": 0, "property": "local", "propertyName": "local", "ccVersion": 2, "metadata": { "type": "number", "readable": True, "writeable": True, "label": "Local protection state", "states": {"0": "Unprotected", "2": "NoOperationPossible"}, }, "value": 0, } assert args["value"] == 2 client.async_send_command_no_wait.reset_mock() # Test bitmask as value and non bool as bool await hass.services.async_call( DOMAIN, SERVICE_SET_VALUE, { ATTR_ENTITY_ID: CLIMATE_DANFOSS_LC13_ENTITY, ATTR_COMMAND_CLASS: 117, ATTR_PROPERTY: "local", ATTR_VALUE: "0x2", ATTR_WAIT_FOR_RESULT: 1, }, blocking=True, ) assert len(client.async_send_command.call_args_list) == 1 args = client.async_send_command.call_args[0][0] assert args["command"] == "node.set_value" assert args["nodeId"] == 5 assert args["valueId"] == { "commandClassName": "Protection", "commandClass": 117, "endpoint": 0, "property": "local", "propertyName": "local", "ccVersion": 2, "metadata": { "type": "number", "readable": True, "writeable": True, "label": "Local protection state", "states": {"0": "Unprotected", "2": "NoOperationPossible"}, }, "value": 0, } assert args["value"] == 2 client.async_send_command.reset_mock() # Test that when a command fails we raise an exception client.async_send_command.return_value = {"success": False} with pytest.raises(SetValueFailed): await hass.services.async_call( DOMAIN, SERVICE_SET_VALUE, { ATTR_DEVICE_ID: device.id, ATTR_COMMAND_CLASS: 117, ATTR_PROPERTY: "local", ATTR_VALUE: 2, ATTR_WAIT_FOR_RESULT: True, }, blocking=True, ) assert len(client.async_send_command.call_args_list) == 1 args = client.async_send_command.call_args[0][0] assert args["command"] == "node.set_value" assert args["nodeId"] == 5 assert args["valueId"] == { "commandClassName": "Protection", "commandClass": 117, "endpoint": 0, "property": "local", "propertyName": "local", "ccVersion": 2, "metadata": { "type": "number", "readable": True, "writeable": True, "label": "Local protection state", "states": {"0": "Unprotected", "2": "NoOperationPossible"}, }, "value": 0, } assert args["value"] == 2 # Test missing device and entities keys with pytest.raises(vol.MultipleInvalid): await hass.services.async_call( DOMAIN, SERVICE_SET_VALUE, { ATTR_COMMAND_CLASS: 117, ATTR_PROPERTY: "local", ATTR_VALUE: 2, ATTR_WAIT_FOR_RESULT: True, }, blocking=True, )
async def test_set_config_parameter(hass, client, multisensor_6, integration): """Test the set_config_parameter service.""" dev_reg = async_get_dev_reg(hass) ent_reg = async_get_ent_reg(hass) entity_entry = ent_reg.async_get(AIR_TEMPERATURE_SENSOR) # Test setting config parameter by property and property_key await hass.services.async_call( DOMAIN, SERVICE_SET_CONFIG_PARAMETER, { ATTR_ENTITY_ID: AIR_TEMPERATURE_SENSOR, ATTR_CONFIG_PARAMETER: 102, ATTR_CONFIG_PARAMETER_BITMASK: 1, ATTR_CONFIG_VALUE: 1, }, blocking=True, ) assert len(client.async_send_command_no_wait.call_args_list) == 1 args = client.async_send_command_no_wait.call_args[0][0] assert args["command"] == "node.set_value" assert args["nodeId"] == 52 assert args["valueId"] == { "commandClassName": "Configuration", "commandClass": 112, "endpoint": 0, "property": 102, "propertyName": "Group 2: Send battery reports", "propertyKey": 1, "metadata": { "type": "number", "readable": True, "writeable": True, "valueSize": 4, "min": 0, "max": 1, "default": 1, "format": 0, "allowManualEntry": True, "label": "Group 2: Send battery reports", "description": "Include battery information in periodic reports to Group 2", "isFromConfig": True, }, "value": 0, } assert args["value"] == 1 client.async_send_command_no_wait.reset_mock() # Test setting config parameter value in hex await hass.services.async_call( DOMAIN, SERVICE_SET_CONFIG_PARAMETER, { ATTR_ENTITY_ID: AIR_TEMPERATURE_SENSOR, ATTR_CONFIG_PARAMETER: 102, ATTR_CONFIG_PARAMETER_BITMASK: 1, ATTR_CONFIG_VALUE: "0x1", }, blocking=True, ) assert len(client.async_send_command_no_wait.call_args_list) == 1 args = client.async_send_command_no_wait.call_args[0][0] assert args["command"] == "node.set_value" assert args["nodeId"] == 52 assert args["valueId"] == { "commandClassName": "Configuration", "commandClass": 112, "endpoint": 0, "property": 102, "propertyName": "Group 2: Send battery reports", "propertyKey": 1, "metadata": { "type": "number", "readable": True, "writeable": True, "valueSize": 4, "min": 0, "max": 1, "default": 1, "format": 0, "allowManualEntry": True, "label": "Group 2: Send battery reports", "description": "Include battery information in periodic reports to Group 2", "isFromConfig": True, }, "value": 0, } assert args["value"] == 1 client.async_send_command_no_wait.reset_mock() # Test setting parameter by property name await hass.services.async_call( DOMAIN, SERVICE_SET_CONFIG_PARAMETER, { ATTR_ENTITY_ID: AIR_TEMPERATURE_SENSOR, ATTR_CONFIG_PARAMETER: "Group 2: Send battery reports", ATTR_CONFIG_VALUE: 1, }, blocking=True, ) assert len(client.async_send_command_no_wait.call_args_list) == 1 args = client.async_send_command_no_wait.call_args[0][0] assert args["command"] == "node.set_value" assert args["nodeId"] == 52 assert args["valueId"] == { "commandClassName": "Configuration", "commandClass": 112, "endpoint": 0, "property": 102, "propertyName": "Group 2: Send battery reports", "propertyKey": 1, "metadata": { "type": "number", "readable": True, "writeable": True, "valueSize": 4, "min": 0, "max": 1, "default": 1, "format": 0, "allowManualEntry": True, "label": "Group 2: Send battery reports", "description": "Include battery information in periodic reports to Group 2", "isFromConfig": True, }, "value": 0, } assert args["value"] == 1 client.async_send_command_no_wait.reset_mock() # Test setting parameter by property name and state label await hass.services.async_call( DOMAIN, SERVICE_SET_CONFIG_PARAMETER, { ATTR_DEVICE_ID: entity_entry.device_id, ATTR_CONFIG_PARAMETER: "Temperature Threshold (Unit)", ATTR_CONFIG_VALUE: "Fahrenheit", }, blocking=True, ) assert len(client.async_send_command_no_wait.call_args_list) == 1 args = client.async_send_command_no_wait.call_args[0][0] assert args["command"] == "node.set_value" assert args["nodeId"] == 52 assert args["valueId"] == { "commandClassName": "Configuration", "commandClass": 112, "endpoint": 0, "property": 41, "propertyName": "Temperature Threshold (Unit)", "propertyKey": 15, "metadata": { "type": "number", "readable": True, "writeable": True, "valueSize": 3, "min": 1, "max": 2, "default": 1, "format": 0, "allowManualEntry": False, "states": {"1": "Celsius", "2": "Fahrenheit"}, "label": "Temperature Threshold (Unit)", "isFromConfig": True, }, "value": 0, } assert args["value"] == 2 client.async_send_command_no_wait.reset_mock() # Test setting parameter by property and bitmask await hass.services.async_call( DOMAIN, SERVICE_SET_CONFIG_PARAMETER, { ATTR_ENTITY_ID: AIR_TEMPERATURE_SENSOR, ATTR_CONFIG_PARAMETER: 102, ATTR_CONFIG_PARAMETER_BITMASK: "0x01", ATTR_CONFIG_VALUE: 1, }, blocking=True, ) assert len(client.async_send_command_no_wait.call_args_list) == 1 args = client.async_send_command_no_wait.call_args[0][0] assert args["command"] == "node.set_value" assert args["nodeId"] == 52 assert args["valueId"] == { "commandClassName": "Configuration", "commandClass": 112, "endpoint": 0, "property": 102, "propertyName": "Group 2: Send battery reports", "propertyKey": 1, "metadata": { "type": "number", "readable": True, "writeable": True, "valueSize": 4, "min": 0, "max": 1, "default": 1, "format": 0, "allowManualEntry": True, "label": "Group 2: Send battery reports", "description": "Include battery information in periodic reports to Group 2", "isFromConfig": True, }, "value": 0, } assert args["value"] == 1 # Test that an invalid entity ID raises a MultipleInvalid with pytest.raises(vol.MultipleInvalid): await hass.services.async_call( DOMAIN, SERVICE_SET_CONFIG_PARAMETER, { ATTR_ENTITY_ID: "sensor.fake_entity", ATTR_CONFIG_PARAMETER: "Temperature Threshold (Unit)", ATTR_CONFIG_VALUE: "Fahrenheit", }, blocking=True, ) # Test that an invalid device ID raises a MultipleInvalid with pytest.raises(vol.MultipleInvalid): await hass.services.async_call( DOMAIN, SERVICE_SET_CONFIG_PARAMETER, { ATTR_DEVICE_ID: "fake_device_id", ATTR_CONFIG_PARAMETER: "Temperature Threshold (Unit)", ATTR_CONFIG_VALUE: "Fahrenheit", }, blocking=True, ) # Test that we can't include a bitmask value if parameter is a string with pytest.raises(vol.Invalid): await hass.services.async_call( DOMAIN, SERVICE_SET_CONFIG_PARAMETER, { ATTR_DEVICE_ID: entity_entry.device_id, ATTR_CONFIG_PARAMETER: "Temperature Threshold (Unit)", ATTR_CONFIG_PARAMETER_BITMASK: 1, ATTR_CONFIG_VALUE: "Fahrenheit", }, blocking=True, ) non_zwave_js_config_entry = MockConfigEntry(entry_id="fake_entry_id") non_zwave_js_config_entry.add_to_hass(hass) non_zwave_js_device = dev_reg.async_get_or_create( config_entry_id=non_zwave_js_config_entry.entry_id, identifiers={("test", "test")}, ) # Test that a non Z-Wave JS device raises a MultipleInvalid with pytest.raises(vol.MultipleInvalid): await hass.services.async_call( DOMAIN, SERVICE_SET_CONFIG_PARAMETER, { ATTR_DEVICE_ID: non_zwave_js_device.id, ATTR_CONFIG_PARAMETER: "Temperature Threshold (Unit)", ATTR_CONFIG_VALUE: "Fahrenheit", }, blocking=True, ) zwave_js_device_with_invalid_node_id = dev_reg.async_get_or_create( config_entry_id=integration.entry_id, identifiers={(DOMAIN, "500-500")} ) # Test that a Z-Wave JS device with an invalid node ID raises a MultipleInvalid with pytest.raises(vol.MultipleInvalid): await hass.services.async_call( DOMAIN, SERVICE_SET_CONFIG_PARAMETER, { ATTR_DEVICE_ID: zwave_js_device_with_invalid_node_id.id, ATTR_CONFIG_PARAMETER: "Temperature Threshold (Unit)", ATTR_CONFIG_VALUE: "Fahrenheit", }, blocking=True, ) non_zwave_js_entity = ent_reg.async_get_or_create( "test", "sensor", "test_sensor", suggested_object_id="test_sensor", config_entry=non_zwave_js_config_entry, ) # Test that a non Z-Wave JS entity raises a MultipleInvalid with pytest.raises(vol.MultipleInvalid): await hass.services.async_call( DOMAIN, SERVICE_SET_CONFIG_PARAMETER, { ATTR_ENTITY_ID: non_zwave_js_entity.entity_id, ATTR_CONFIG_PARAMETER: "Temperature Threshold (Unit)", ATTR_CONFIG_VALUE: "Fahrenheit", }, blocking=True, ) # Test that when a device is awake, we call async_send_command instead of # async_send_command_no_wait multisensor_6.handle_wake_up(None) await hass.services.async_call( DOMAIN, SERVICE_SET_CONFIG_PARAMETER, { ATTR_ENTITY_ID: AIR_TEMPERATURE_SENSOR, ATTR_CONFIG_PARAMETER: 102, ATTR_CONFIG_PARAMETER_BITMASK: 1, ATTR_CONFIG_VALUE: 1, }, blocking=True, ) assert len(client.async_send_command.call_args_list) == 1 args = client.async_send_command.call_args[0][0] assert args["command"] == "node.set_value" assert args["nodeId"] == 52 assert args["valueId"] == { "commandClassName": "Configuration", "commandClass": 112, "endpoint": 0, "property": 102, "propertyName": "Group 2: Send battery reports", "propertyKey": 1, "metadata": { "type": "number", "readable": True, "writeable": True, "valueSize": 4, "min": 0, "max": 1, "default": 1, "format": 0, "allowManualEntry": True, "label": "Group 2: Send battery reports", "description": "Include battery information in periodic reports to Group 2", "isFromConfig": True, }, "value": 0, } assert args["value"] == 1 client.async_send_command.reset_mock()
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] # Test setting config parameter by property and property_key await hass.services.async_call( DOMAIN, SERVICE_BULK_SET_PARTIAL_CONFIG_PARAMETERS, { ATTR_DEVICE_ID: device.id, ATTR_CONFIG_PARAMETER: 102, ATTR_CONFIG_VALUE: 241, }, blocking=True, ) assert len(client.async_send_command_no_wait.call_args_list) == 1 args = client.async_send_command_no_wait.call_args[0][0] assert args["command"] == "node.set_value" assert args["nodeId"] == 52 assert args["valueId"] == { "commandClass": 112, "property": 102, } assert args["value"] == 241 client.async_send_command_no_wait.reset_mock() await hass.services.async_call( DOMAIN, SERVICE_BULK_SET_PARTIAL_CONFIG_PARAMETERS, { ATTR_ENTITY_ID: AIR_TEMPERATURE_SENSOR, ATTR_CONFIG_PARAMETER: 102, ATTR_CONFIG_VALUE: { 1: 1, 16: 1, 32: 1, 64: 1, 128: 1, }, }, blocking=True, ) assert len(client.async_send_command_no_wait.call_args_list) == 1 args = client.async_send_command_no_wait.call_args[0][0] assert args["command"] == "node.set_value" assert args["nodeId"] == 52 assert args["valueId"] == { "commandClass": 112, "property": 102, } assert args["value"] == 241 client.async_send_command_no_wait.reset_mock() # Test using hex values for config parameter values await hass.services.async_call( DOMAIN, SERVICE_BULK_SET_PARTIAL_CONFIG_PARAMETERS, { ATTR_ENTITY_ID: AIR_TEMPERATURE_SENSOR, ATTR_CONFIG_PARAMETER: 102, ATTR_CONFIG_VALUE: { 1: "0x1", 16: "0x1", 32: "0x1", 64: "0x1", 128: "0x1", }, }, blocking=True, ) assert len(client.async_send_command_no_wait.call_args_list) == 1 args = client.async_send_command_no_wait.call_args[0][0] assert args["command"] == "node.set_value" assert args["nodeId"] == 52 assert args["valueId"] == { "commandClass": 112, "property": 102, } assert args["value"] == 241 client.async_send_command_no_wait.reset_mock() await hass.services.async_call( DOMAIN, SERVICE_BULK_SET_PARTIAL_CONFIG_PARAMETERS, { ATTR_ENTITY_ID: AIR_TEMPERATURE_SENSOR, ATTR_CONFIG_PARAMETER: 102, ATTR_CONFIG_VALUE: { "0x1": 1, "0x10": 1, "0x20": 1, "0x40": 1, "0x80": 1, }, }, blocking=True, ) assert len(client.async_send_command_no_wait.call_args_list) == 1 args = client.async_send_command_no_wait.call_args[0][0] assert args["command"] == "node.set_value" assert args["nodeId"] == 52 assert args["valueId"] == { "commandClass": 112, "property": 102, } assert args["value"] == 241 client.async_send_command_no_wait.reset_mock() # Test that when a device is awake, we call async_send_command instead of # async_send_command_no_wait multisensor_6.handle_wake_up(None) await hass.services.async_call( DOMAIN, SERVICE_BULK_SET_PARTIAL_CONFIG_PARAMETERS, { ATTR_ENTITY_ID: AIR_TEMPERATURE_SENSOR, ATTR_CONFIG_PARAMETER: 102, ATTR_CONFIG_VALUE: { 1: 1, 16: 1, 32: 1, 64: 1, 128: 1, }, }, blocking=True, ) assert len(client.async_send_command.call_args_list) == 1 args = client.async_send_command.call_args[0][0] assert args["command"] == "node.set_value" assert args["nodeId"] == 52 assert args["valueId"] == { "commandClass": 112, "property": 102, } assert args["value"] == 241 client.async_send_command.reset_mock()
async def test_if_value_updated_value_fires( hass, client, lock_schlage_be469, integration, calls ): """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] assert await async_setup_component( hass, automation.DOMAIN, { automation.DOMAIN: [ { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": device.id, "type": "zwave_js.value_updated.value", "command_class": CommandClass.DOOR_LOCK.value, "property": "latchStatus", "property_key": None, "endpoint": None, "from": "open", }, "action": { "service": "test.automation", "data_template": { "some": ( "zwave_js.value_updated.value - " "{{ trigger.platform}} - " "{{ trigger.previous_value }}" ) }, }, }, ] }, ) # Publish fake value update that shouldn't trigger event = Event( type="value updated", data={ "source": "node", "event": "value updated", "nodeId": node.node_id, "args": { "commandClassName": "Door Lock", "commandClass": 98, "endpoint": 0, "property": "insideHandlesCanOpenDoor", "newValue": [True, False, False, False], "prevValue": [False, False, False, False], "propertyName": "insideHandlesCanOpenDoor", }, }, ) node.receive_event(event) await hass.async_block_till_done() assert len(calls) == 0 # Publish fake value update that should trigger event = Event( type="value updated", data={ "source": "node", "event": "value updated", "nodeId": node.node_id, "args": { "commandClassName": "Door Lock", "commandClass": 98, "endpoint": 0, "property": "latchStatus", "newValue": "closed", "prevValue": "open", "propertyName": "latchStatus", }, }, ) node.receive_event(event) await hass.async_block_till_done() assert len(calls) == 1 assert ( calls[0].data["some"] == "zwave_js.value_updated.value - zwave_js.value_updated - open" )
async def test_if_scene_activation_value_notification_fires( hass, client, hank_binary_switch, integration, calls ): """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] assert await async_setup_component( hass, automation.DOMAIN, { automation.DOMAIN: [ # value { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": device.id, "type": "event.value_notification.scene_activation", "command_class": CommandClass.SCENE_ACTIVATION.value, "property": "sceneId", "property_key": None, "endpoint": 0, "subtype": "Endpoint 0", "value": 1, }, "action": { "service": "test.automation", "data_template": { "some": ( "event.value_notification.scene_activation - " "{{ trigger.platform}} - " "{{ trigger.event.event_type}} - " "{{ trigger.event.data.command_class }}" ) }, }, }, # No value { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": device.id, "type": "event.value_notification.scene_activation", "command_class": CommandClass.SCENE_ACTIVATION.value, "property": "sceneId", "property_key": None, "endpoint": 0, "subtype": "Endpoint 0", }, "action": { "service": "test.automation", "data_template": { "some": ( "event.value_notification.scene_activation2 - " "{{ trigger.platform}} - " "{{ trigger.event.event_type}} - " "{{ trigger.event.data.command_class }}" ) }, }, }, ] }, ) # Publish fake Scene Activation CC value notification event = Event( type="value notification", data={ "source": "node", "event": "value notification", "nodeId": node.node_id, "args": { "commandClassName": "Scene Activation", "commandClass": 43, "endpoint": 0, "property": "sceneId", "propertyName": "sceneId", "value": 1, "metadata": { "type": "number", "readable": True, "writeable": True, "min": 1, "max": 255, "label": "Scene ID", }, "ccVersion": 1, }, }, ) node.receive_event(event) await hass.async_block_till_done() assert len(calls) == 2 assert calls[0].data[ "some" ] == "event.value_notification.scene_activation - device - zwave_js_value_notification - {}".format( CommandClass.SCENE_ACTIVATION ) assert calls[1].data[ "some" ] == "event.value_notification.scene_activation2 - device - zwave_js_value_notification - {}".format( CommandClass.SCENE_ACTIVATION )
async def test_failure_scenarios(hass, client, hank_binary_switch, integration): """Test failure scenarios.""" with pytest.raises(HomeAssistantError): await device_trigger.async_attach_trigger( hass, {"type": "failed.test", "device_id": "invalid_device_id"}, None, {} ) with pytest.raises(HomeAssistantError): await device_trigger.async_attach_trigger( hass, {"type": "event.failed_type", "device_id": "invalid_device_id"}, None, {}, ) dev_reg = async_get_dev_reg(hass) device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0] with pytest.raises(HomeAssistantError): await device_trigger.async_attach_trigger( hass, {"type": "failed.test", "device_id": device.id}, None, {} ) with pytest.raises(HomeAssistantError): await device_trigger.async_attach_trigger( hass, {"type": "event.failed_type", "device_id": device.id}, None, {}, ) with pytest.raises(HomeAssistantError): await device_trigger.async_attach_trigger( hass, {"type": "state.failed_type", "device_id": device.id}, None, {}, ) with patch( "homeassistant.components.zwave_js.device_trigger.async_get_node_from_device_id", return_value=None, ), patch( "homeassistant.components.zwave_js.helpers.get_zwave_value_from_config", return_value=None, ): assert ( await device_trigger.async_get_trigger_capabilities( hass, {"type": "failed.test", "device_id": "invalid_device_id"} ) == {} ) with pytest.raises(HomeAssistantError): async_get_node_status_sensor_entity_id(hass, "invalid_device_id") INVALID_CONFIG = { "platform": "device", "domain": DOMAIN, "device_id": device.id, "type": "zwave_js.value_updated.value", "command_class": CommandClass.DOOR_LOCK.value, "property": 9999, "property_key": 9999, "endpoint": 9999, } # Test that invalid config raises exception with pytest.raises(InvalidDeviceAutomationConfig): await device_trigger.async_validate_trigger_config(hass, INVALID_CONFIG) # Unload entry so we can verify that validation will pass on an invalid config # since we return early await hass.config_entries.async_unload(integration.entry_id) assert ( await device_trigger.async_validate_trigger_config(hass, INVALID_CONFIG) == INVALID_CONFIG ) # Test invalid device ID fails validation with pytest.raises(InvalidDeviceAutomationConfig): await device_trigger.async_validate_trigger_config( hass, { "platform": "device", "domain": DOMAIN, "device_id": "invalid_device_id", "type": "zwave_js.value_updated.value", "command_class": CommandClass.DOOR_LOCK.value, "property": 9999, "property_key": 9999, "endpoint": 9999, }, )
async def test_if_central_scene_value_notification_fires( hass, client, wallmote_central_scene, integration, calls ): """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] assert await async_setup_component( hass, automation.DOMAIN, { automation.DOMAIN: [ # value { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": device.id, "type": "event.value_notification.central_scene", "command_class": CommandClass.CENTRAL_SCENE.value, "property": "scene", "property_key": "001", "endpoint": 0, "subtype": "Endpoint 0 Scene 001", "value": 0, }, "action": { "service": "test.automation", "data_template": { "some": ( "event.value_notification.central_scene - " "{{ trigger.platform}} - " "{{ trigger.event.event_type}} - " "{{ trigger.event.data.command_class }}" ) }, }, }, # no value { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": device.id, "type": "event.value_notification.central_scene", "command_class": CommandClass.CENTRAL_SCENE.value, "property": "scene", "property_key": "001", "endpoint": 0, "subtype": "Endpoint 0 Scene 001", }, "action": { "service": "test.automation", "data_template": { "some": ( "event.value_notification.central_scene2 - " "{{ trigger.platform}} - " "{{ trigger.event.event_type}} - " "{{ trigger.event.data.command_class }}" ) }, }, }, ] }, ) # Publish fake Central Scene CC value notification event = Event( type="value notification", data={ "source": "node", "event": "value notification", "nodeId": node.node_id, "args": { "commandClassName": "Central Scene", "commandClass": 91, "endpoint": 0, "property": "scene", "propertyName": "scene", "propertyKey": "001", "propertyKey": "001", "value": 0, "metadata": { "type": "number", "readable": True, "writeable": False, "min": 0, "max": 255, "label": "Scene 004", "states": { "0": "KeyPressed", "1": "KeyReleased", "2": "KeyHeldDown", }, }, "ccVersion": 1, }, }, ) node.receive_event(event) await hass.async_block_till_done() assert len(calls) == 2 assert calls[0].data[ "some" ] == "event.value_notification.central_scene - device - zwave_js_value_notification - {}".format( CommandClass.CENTRAL_SCENE ) assert calls[1].data[ "some" ] == "event.value_notification.central_scene2 - device - zwave_js_value_notification - {}".format( CommandClass.CENTRAL_SCENE )
async def test_if_notification_notification_fires( hass, client, lock_schlage_be469, integration, calls ): """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] assert await async_setup_component( hass, automation.DOMAIN, { automation.DOMAIN: [ # event, type, label { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": device.id, "type": "event.notification.notification", "command_class": CommandClass.NOTIFICATION.value, "type.": 6, "event": 5, "label": "Access Control", }, "action": { "service": "test.automation", "data_template": { "some": ( "event.notification.notification - " "{{ trigger.platform}} - " "{{ trigger.event.event_type}} - " "{{ trigger.event.data.command_class }}" ) }, }, }, # no type, event, label { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": device.id, "type": "event.notification.notification", "command_class": CommandClass.NOTIFICATION.value, }, "action": { "service": "test.automation", "data_template": { "some": ( "event.notification.notification2 - " "{{ trigger.platform}} - " "{{ trigger.event.event_type}} - " "{{ trigger.event.data.command_class }}" ) }, }, }, ] }, ) # Publish fake Notification CC notification event = Event( type="notification", data={ "source": "node", "event": "notification", "nodeId": node.node_id, "ccId": 113, "args": { "type": 6, "event": 5, "label": "Access Control", "eventLabel": "Keypad lock operation", "parameters": {"userId": 1}, }, }, ) node.receive_event(event) await hass.async_block_till_done() assert len(calls) == 2 assert calls[0].data[ "some" ] == "event.notification.notification - device - zwave_js_notification - {}".format( CommandClass.NOTIFICATION ) assert calls[1].data[ "some" ] == "event.notification.notification2 - device - zwave_js_notification - {}".format( CommandClass.NOTIFICATION )
async def test_if_entry_control_notification_fires( hass, client, lock_schlage_be469, integration, calls ): """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] assert await async_setup_component( hass, automation.DOMAIN, { automation.DOMAIN: [ # event_type and data_type { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": device.id, "type": "event.notification.entry_control", "command_class": CommandClass.ENTRY_CONTROL.value, "event_type": 5, "data_type": 2, }, "action": { "service": "test.automation", "data_template": { "some": ( "event.notification.notification - " "{{ trigger.platform}} - " "{{ trigger.event.event_type}} - " "{{ trigger.event.data.command_class }}" ) }, }, }, # no event_type and data_type { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": device.id, "type": "event.notification.entry_control", "command_class": CommandClass.ENTRY_CONTROL.value, }, "action": { "service": "test.automation", "data_template": { "some": ( "event.notification.notification2 - " "{{ trigger.platform}} - " "{{ trigger.event.event_type}} - " "{{ trigger.event.data.command_class }}" ) }, }, }, ] }, ) # Publish fake Entry Control CC notification event = Event( type="notification", data={ "source": "node", "event": "notification", "nodeId": node.node_id, "ccId": 111, "args": {"eventType": 5, "dataType": 2, "eventData": "555"}, }, ) node.receive_event(event) await hass.async_block_till_done() assert len(calls) == 2 assert calls[0].data[ "some" ] == "event.notification.notification - device - zwave_js_notification - {}".format( CommandClass.ENTRY_CONTROL ) assert calls[1].data[ "some" ] == "event.notification.notification2 - device - zwave_js_notification - {}".format( CommandClass.ENTRY_CONTROL )
async def test_if_node_status_change_fires( hass, client, lock_schlage_be469, integration, calls ): """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] ent_reg = async_get_ent_reg(hass) entity_id = async_get_node_status_sensor_entity_id( hass, device.id, ent_reg, dev_reg ) ent_reg.async_update_entity(entity_id, **{"disabled_by": None}) await hass.config_entries.async_reload(integration.entry_id) await hass.async_block_till_done() assert await async_setup_component( hass, automation.DOMAIN, { automation.DOMAIN: [ # from { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": device.id, "entity_id": entity_id, "type": "state.node_status", "from": "alive", }, "action": { "service": "test.automation", "data_template": { "some": ( "state.node_status - " "{{ trigger.platform}} - " "{{ trigger.from_state.state }}" ) }, }, }, # no from or to { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": device.id, "entity_id": entity_id, "type": "state.node_status", }, "action": { "service": "test.automation", "data_template": { "some": ( "state.node_status2 - " "{{ trigger.platform}} - " "{{ trigger.from_state.state }}" ) }, }, }, ] }, ) # Test status change event = Event( "dead", data={"source": "node", "event": "dead", "nodeId": node.node_id} ) node.receive_event(event) await hass.async_block_till_done() assert len(calls) == 2 assert calls[0].data["some"] == "state.node_status - device - alive" assert calls[1].data["some"] == "state.node_status2 - device - alive"