Add zwave_js controller identify event (#99254)

This commit is contained in:
Raman Gupta 2023-08-30 05:32:41 -04:00 committed by GitHub
parent 56b99d2bc6
commit 40748a6c34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 91 additions and 1 deletions

View File

@ -21,6 +21,7 @@ from zwave_js_server.model.notification import (
from zwave_js_server.model.value import Value, ValueNotification
from homeassistant.components.hassio import AddonError, AddonManager, AddonState
from homeassistant.components.persistent_notification import async_create
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_DEVICE_ID,
@ -290,6 +291,11 @@ class DriverEvents:
controller.on("node removed", self.controller_events.async_on_node_removed)
)
# listen for identify events for the controller
self.config_entry.async_on_unload(
controller.on("identify", self.controller_events.async_on_identify)
)
async def async_setup_platform(self, platform: Platform) -> None:
"""Set up platform if needed."""
if platform not in self.platform_setup_tasks:
@ -417,6 +423,41 @@ class ControllerEvents:
else:
self.remove_device(device)
@callback
def async_on_identify(self, event: dict) -> None:
"""Handle identify event."""
# Get node device
node: ZwaveNode = event["node"]
dev_id = get_device_id(self.driver_events.driver, node)
device = self.dev_reg.async_get_device(identifiers={dev_id})
assert device
device_name = device.name_by_user or device.name
home_id = self.driver_events.driver.controller.home_id
# We do this because we know at this point the controller has its home ID as
# as it is part of the device ID
assert home_id
# In case the user has multiple networks, we should give them more information
# about the network for the controller being identified.
identifier = ""
if len(self.hass.config_entries.async_entries(DOMAIN)) > 1:
if str(home_id) != self.config_entry.title:
identifier = (
f"`{self.config_entry.title}`, with the home ID `{home_id}`, "
)
else:
identifier = f"with the home ID `{home_id}` "
async_create(
self.hass,
(
f"`{device_name}` has just requested the controller for your Z-Wave "
f"network {identifier}to identify itself. No action is needed from "
"you other than to note the source of the request, and you can safely "
"dismiss this notification when ready."
),
"New Z-Wave Identify Controller Request",
f"{DOMAIN}.identify_controller.{dev_id[1]}",
)
@callback
def register_node_in_dev_reg(self, node: ZwaveNode) -> dr.DeviceEntry:
"""Register node in dev reg."""

View File

@ -11,6 +11,7 @@ from zwave_js_server.model.node import Node
from zwave_js_server.model.version import VersionInfo
from homeassistant.components.hassio.handler import HassioAPIError
from homeassistant.components.persistent_notification import async_dismiss
from homeassistant.components.zwave_js import DOMAIN
from homeassistant.components.zwave_js.helpers import get_device_id
from homeassistant.config_entries import ConfigEntryDisabler, ConfigEntryState
@ -25,7 +26,7 @@ from homeassistant.helpers import (
from .common import AIR_TEMPERATURE_SENSOR, EATON_RF9640_ENTITY
from tests.common import MockConfigEntry
from tests.common import MockConfigEntry, async_get_persistent_notifications
@pytest.fixture(name="connect_timeout")
@ -1501,3 +1502,51 @@ async def test_disabled_entity_on_value_removed(
}
== new_unavailable_entities
)
async def test_identify_event(
hass: HomeAssistant, client, multisensor_6, integration
) -> None:
"""Test controller identify event."""
# One config entry scenario
event = Event(
type="identify",
data={
"source": "controller",
"event": "identify",
"nodeId": multisensor_6.node_id,
},
)
dev_id = get_device_id(client.driver, multisensor_6)
msg_id = f"{DOMAIN}.identify_controller.{dev_id[1]}"
client.driver.controller.receive_event(event)
notifications = async_get_persistent_notifications(hass)
assert len(notifications) == 1
assert list(notifications)[0] == msg_id
assert notifications[msg_id]["message"].startswith("`Multisensor 6`")
assert "with the home ID" not in notifications[msg_id]["message"]
async_dismiss(hass, msg_id)
# Add mock config entry to simulate having multiple entries
new_entry = MockConfigEntry(domain=DOMAIN)
new_entry.add_to_hass(hass)
# Test case where config entry title and home ID don't match
client.driver.controller.receive_event(event)
notifications = async_get_persistent_notifications(hass)
assert len(notifications) == 1
assert list(notifications)[0] == msg_id
assert (
"network `Mock Title`, with the home ID `3245146787`"
in notifications[msg_id]["message"]
)
async_dismiss(hass, msg_id)
# Test case where config entry title and home ID do match
hass.config_entries.async_update_entry(integration, title="3245146787")
client.driver.controller.receive_event(event)
notifications = async_get_persistent_notifications(hass)
assert len(notifications) == 1
assert list(notifications)[0] == msg_id
assert "network with the home ID `3245146787`" in notifications[msg_id]["message"]