def async_remove_addons_from_dev_reg( dev_reg: DeviceRegistry, addons: list[dict[str, Any]] ) -> None: """Remove addons from the device registry.""" for addon_slug in addons: if dev := dev_reg.async_get_device({(DOMAIN, addon_slug)}): dev_reg.async_remove_device(dev.id)
async def test_action(hass, device_reg: DeviceRegistry, rfxtrx: RFXtrx.Connect, device, config, expected): """Test for actions.""" await setup_entry(hass, {device.code: {"signal_repetitions": 1}}) device_entry = device_reg.async_get_device(device.device_identifiers, set()) assert device_entry assert await async_setup_component( hass, automation.DOMAIN, { automation.DOMAIN: [ { "trigger": { "platform": "event", "event_type": "test_event", }, "action": { "domain": DOMAIN, "device_id": device_entry.id, **config, }, }, ] }, ) hass.bus.async_fire("test_event") await hass.async_block_till_done() rfxtrx.transport.send.assert_called_once_with(bytearray.fromhex(expected))
def async_host_input_received( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, device_registry: dr.DeviceRegistry, inp: pypck.inputs.Input, ) -> None: """Process received input object (command) from LCN bus.""" if not isinstance(inp, pypck.inputs.ModInput): return lcn_connection = hass.data[DOMAIN][config_entry.entry_id][CONNECTION] logical_address = lcn_connection.physical_to_logical( inp.physical_source_addr) address = ( logical_address.seg_id, logical_address.addr_id, logical_address.is_group, ) identifiers = {(DOMAIN, generate_unique_id(config_entry.entry_id, address))} device = device_registry.async_get_device(identifiers, set()) if device is None: return if isinstance(inp, pypck.inputs.ModStatusAccessControl): _async_fire_access_control_event(hass, device, address, inp) elif isinstance(inp, pypck.inputs.ModSendKeysHost): _async_fire_send_keys_event(hass, device, address, inp)
def _get_device_long_name( device_registry: DeviceRegistry, current_device: str ) -> str: device = device_registry.async_get_device({(DOMAIN, current_device)}) if device and device.name_by_user: return f"{device.name_by_user} ({current_device})" return current_device
def register_node_in_dev_reg( hass: HomeAssistant, entry: ConfigEntry, dev_reg: device_registry.DeviceRegistry, client: ZwaveClient, node: ZwaveNode, remove_device_func: Callable[[device_registry.DeviceEntry], None], ) -> device_registry.DeviceEntry: """Register node in dev reg.""" device_id = get_device_id(client, node) # If a device already exists but it doesn't match the new node, it means the node # was replaced with a different device and the device needs to be removeed so the # new device can be created. Otherwise if the device exists and the node is the same, # the node was replaced with the same device model and we can reuse the device. if (device := dev_reg.async_get_device({ device_id })) and (device.model != node.device_config.label or device.manufacturer != node.device_config.manufacturer): remove_device_func(device)
def _async_remove_old_device_identifiers( config_entry_id: str, device_registry: dr.DeviceRegistry, hub: BondHub ) -> None: """Remove the non-unique device registry entries.""" for device in hub.devices: dev = device_registry.async_get_device(identifiers={(DOMAIN, device.device_id)}) if dev is None: continue if config_entry_id in dev.config_entries: device_registry.async_remove_device(dev.id)
def check_device_registry( device_registry: DeviceRegistry, expected_devices: list[MappingProxyType] ) -> None: """Ensure that the expected_devices are correctly registered.""" for expected_device in expected_devices: registry_entry = device_registry.async_get_device( expected_device[ATTR_IDENTIFIERS] ) assert registry_entry is not None assert registry_entry.identifiers == expected_device[ATTR_IDENTIFIERS] assert registry_entry.manufacturer == expected_device[ATTR_MANUFACTURER] assert registry_entry.name == expected_device[ATTR_NAME] assert registry_entry.model == expected_device[ATTR_MODEL] if expected_via_device := expected_device.get(ATTR_VIA_DEVICE): assert registry_entry.via_device_id is not None parent_entry = device_registry.async_get_device({expected_via_device}) assert parent_entry is not None assert registry_entry.via_device_id == parent_entry.id else: assert registry_entry.via_device_id is None
def check_device_registry( device_registry: DeviceRegistry, expected_device: dict[str, Any] ) -> None: """Ensure that the expected_device is correctly registered.""" assert len(device_registry.devices) == 1 registry_entry = device_registry.async_get_device(expected_device[ATTR_IDENTIFIERS]) assert registry_entry is not None assert registry_entry.identifiers == expected_device[ATTR_IDENTIFIERS] assert registry_entry.manufacturer == expected_device[ATTR_MANUFACTURER] assert registry_entry.name == expected_device[ATTR_NAME] assert registry_entry.model == expected_device[ATTR_MODEL] assert registry_entry.sw_version == expected_device[ATTR_SW_VERSION]
async def test_get_actions(hass, device_reg: DeviceRegistry, device, expected): """Test we get the expected actions from a rfxtrx.""" await setup_entry(hass, {device.code: {"signal_repetitions": 1}}) device_entry = device_reg.async_get_device(device.device_identifiers, set()) assert device_entry actions = await async_get_device_automations(hass, "action", device_entry.id) actions = [action for action in actions if action["domain"] == DOMAIN] expected_actions = [ {"domain": DOMAIN, "device_id": device_entry.id, **action_type} for action_type in expected ] assert_lists_same(actions, expected_actions)
def _remove_device( hass: HomeAssistant, config_entry: ConfigEntry, mac: str, tasmota_mqtt: TasmotaMQTTClient, device_registry: DeviceRegistry, ) -> None: """Remove device from device registry.""" device = device_registry.async_get_device(set(), {(CONNECTION_NETWORK_MAC, mac)}) if device is None: return _LOGGER.debug("Removing tasmota device %s", mac) device_registry.async_remove_device(device.id) clear_discovery_topic(mac, config_entry.data[CONF_DISCOVERY_PREFIX], tasmota_mqtt)
async def _remove_device( hass: HomeAssistant, config_entry: ConfigEntry, mac: str, tasmota_mqtt: TasmotaMQTTClient, device_registry: DeviceRegistry, ) -> None: """Remove a discovered Tasmota device.""" device = device_registry.async_get_device(set(), {(CONNECTION_NETWORK_MAC, mac)}) if device is None or config_entry.entry_id not in device.config_entries: return _LOGGER.debug("Removing tasmota from device %s", mac) device_registry.async_update_device( device.id, remove_config_entry_id=config_entry.entry_id)
def register_node_in_dev_reg( hass: HomeAssistant, entry: ConfigEntry, dev_reg: device_registry.DeviceRegistry, client: ZwaveClient, node: ZwaveNode, remove_device_func: Callable[[device_registry.DeviceEntry], None], ) -> device_registry.DeviceEntry: """Register node in dev reg.""" device_id = get_device_id(client, node) device_id_ext = get_device_id_ext(client, node) device = dev_reg.async_get_device({device_id}) # Replace the device if it can be determined that this node is not the # same product as it was previously. if ( device_id_ext and device and len(device.identifiers) == 2 and device_id_ext not in device.identifiers ): remove_device_func(device) device = None if device_id_ext: ids = {device_id, device_id_ext} else: ids = {device_id} params = { ATTR_IDENTIFIERS: ids, ATTR_SW_VERSION: node.firmware_version, ATTR_NAME: node.name or node.device_config.description or f"Node {node.node_id}", ATTR_MODEL: node.device_config.label, ATTR_MANUFACTURER: node.device_config.manufacturer, } if node.location: params[ATTR_SUGGESTED_AREA] = node.location device = dev_reg.async_get_or_create(config_entry_id=entry.entry_id, **params) async_dispatcher_send(hass, EVENT_DEVICE_ADDED_TO_REGISTRY, device) return device
async def test_invalid_trigger(hass, device_reg: DeviceRegistry): """Test for invalid actions.""" event = EVENT_LIGHTING_1 notification_calls = async_mock_service(hass, "persistent_notification", "create") await setup_entry( hass, {event.code: { "fire_event": True, "signal_repetitions": 1 }}) device_identifers: Any = event.device_identifiers device_entry = device_reg.async_get_device(device_identifers, set()) assert device_entry assert await async_setup_component( hass, automation.DOMAIN, { automation.DOMAIN: [ { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": device_entry.id, "type": event.type, "subtype": "invalid", }, "action": { "service": "test.automation", "data_template": { "some": ("{{trigger.platform}}") }, }, }, ] }, ) await hass.async_block_till_done() assert len(notification_calls) == 1 assert ("The following integrations and platforms could not be set up" in notification_calls[0].data["message"])
async def test_firing_event(hass, device_reg: DeviceRegistry, rfxtrx, event): """Test for turn_on and turn_off triggers firing.""" await setup_entry( hass, {event.code: { "fire_event": True, "signal_repetitions": 1 }}) device_entry = device_reg.async_get_device(event.device_identifiers, set()) assert device_entry calls = async_mock_service(hass, "test", "automation") assert await async_setup_component( hass, automation.DOMAIN, { automation.DOMAIN: [ { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": device_entry.id, "type": event.type, "subtype": event.subtype, }, "action": { "service": "test.automation", "data_template": { "some": ("{{trigger.platform}}") }, }, }, ] }, ) await hass.async_block_till_done() await rfxtrx.signal(event.code) assert len(calls) == 1 assert calls[0].data["some"] == "device"
def register_node_in_dev_reg( hass: HomeAssistant, entry: ConfigEntry, dev_reg: device_registry.DeviceRegistry, driver: Driver, node: ZwaveNode, remove_device_func: Callable[[device_registry.DeviceEntry], None], ) -> device_registry.DeviceEntry: """Register node in dev reg.""" device_id = get_device_id(driver, node) device_id_ext = get_device_id_ext(driver, node) device = dev_reg.async_get_device({device_id}) # Replace the device if it can be determined that this node is not the # same product as it was previously. if ( device_id_ext and device and len(device.identifiers) == 2 and device_id_ext not in device.identifiers ): remove_device_func(device) device = None if device_id_ext: ids = {device_id, device_id_ext} else: ids = {device_id} device = dev_reg.async_get_or_create( config_entry_id=entry.entry_id, identifiers=ids, sw_version=node.firmware_version, name=node.name or node.device_config.description or f"Node {node.node_id}", model=node.device_config.label, manufacturer=node.device_config.manufacturer, suggested_area=node.location if node.location else UNDEFINED, ) async_dispatcher_send(hass, EVENT_DEVICE_ADDED_TO_REGISTRY, device) return device
async def test_invalid_action(hass, device_reg: DeviceRegistry): """Test for invalid actions.""" device = DEVICE_LIGHTING_1 await setup_entry(hass, {device.code: {"signal_repetitions": 1}}) device_identifers: Any = device.device_identifiers device_entry = device_reg.async_get_device(device_identifers, set()) assert device_entry assert await async_setup_component( hass, automation.DOMAIN, { automation.DOMAIN: [ { "trigger": { "platform": "event", "event_type": "test_event", }, "action": { "domain": DOMAIN, "device_id": device_entry.id, "type": "send_command", "subtype": "invalid", }, }, ] }, ) await hass.async_block_till_done() assert len( notifications := hass.states.async_all("persistent_notification")) == 1 assert ("The following integrations and platforms could not be set up" in notifications[0].attributes["message"])