Notify users when zwave device gets reset (#101362)
* Notify users when zwave device gets reset * review comments
This commit is contained in:
parent
cd175f679f
commit
d3c5b9777b
3 changed files with 99 additions and 14 deletions
|
@ -113,6 +113,7 @@ from .helpers import (
|
|||
async_enable_statistics,
|
||||
get_device_id,
|
||||
get_device_id_ext,
|
||||
get_network_identifier_for_notification,
|
||||
get_unique_id,
|
||||
get_valueless_base_unique_id,
|
||||
)
|
||||
|
@ -448,6 +449,28 @@ class ControllerEvents:
|
|||
"remove_entity"
|
||||
),
|
||||
)
|
||||
elif reason == RemoveNodeReason.RESET:
|
||||
device_name = device.name_by_user or device.name or f"Node {node.node_id}"
|
||||
identifier = get_network_identifier_for_notification(
|
||||
self.hass, self.config_entry, self.driver_events.driver.controller
|
||||
)
|
||||
notification_msg = (
|
||||
f"`{device_name}` has been factory reset "
|
||||
"and removed from the Z-Wave network"
|
||||
)
|
||||
if identifier:
|
||||
# Remove trailing comma if it's there
|
||||
if identifier[-1] == ",":
|
||||
identifier = identifier[:-1]
|
||||
notification_msg = f"{notification_msg} {identifier}."
|
||||
else:
|
||||
notification_msg = f"{notification_msg}."
|
||||
async_create(
|
||||
self.hass,
|
||||
notification_msg,
|
||||
"Device Was Factory Reset!",
|
||||
f"{DOMAIN}.node_reset_and_removed.{dev_id[1]}",
|
||||
)
|
||||
else:
|
||||
self.remove_device(device)
|
||||
|
||||
|
@ -459,26 +482,17 @@ class ControllerEvents:
|
|||
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
|
||||
device_name = device.name_by_user or device.name or f"Node {node.node_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}`, "
|
||||
identifier = get_network_identifier_for_notification(
|
||||
self.hass, self.config_entry, self.driver_events.driver.controller
|
||||
)
|
||||
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 "
|
||||
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."
|
||||
),
|
||||
|
|
|
@ -14,6 +14,7 @@ from zwave_js_server.const import (
|
|||
ConfigurationValueType,
|
||||
LogLevel,
|
||||
)
|
||||
from zwave_js_server.model.controller import Controller
|
||||
from zwave_js_server.model.driver import Driver
|
||||
from zwave_js_server.model.log_config import LogConfig
|
||||
from zwave_js_server.model.node import Node as ZwaveNode
|
||||
|
@ -512,3 +513,15 @@ def get_device_info(driver: Driver, node: ZwaveNode) -> DeviceInfo:
|
|||
manufacturer=node.device_config.manufacturer,
|
||||
suggested_area=node.location if node.location else None,
|
||||
)
|
||||
|
||||
|
||||
def get_network_identifier_for_notification(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry, controller: Controller
|
||||
) -> str:
|
||||
"""Return the network identifier string for persistent notifications."""
|
||||
home_id = str(controller.home_id)
|
||||
if len(hass.config_entries.async_entries(DOMAIN)) > 1:
|
||||
if str(home_id) != config_entry.title:
|
||||
return f"`{config_entry.title}`, with the home ID `{home_id}`,"
|
||||
return f"with the home ID `{home_id}`"
|
||||
return ""
|
||||
|
|
|
@ -1644,3 +1644,61 @@ async def test_server_logging(hass: HomeAssistant, client) -> None:
|
|||
assert len(client.async_send_command.call_args_list) == 0
|
||||
assert not client.enable_server_logging.called
|
||||
assert not client.disable_server_logging.called
|
||||
|
||||
|
||||
async def test_factory_reset_node(
|
||||
hass: HomeAssistant, client, multisensor_6, multisensor_6_state, integration
|
||||
) -> None:
|
||||
"""Test when a node is removed because it was reset."""
|
||||
# One config entry scenario
|
||||
remove_event = Event(
|
||||
type="node removed",
|
||||
data={
|
||||
"source": "controller",
|
||||
"event": "node removed",
|
||||
"reason": 5,
|
||||
"node": deepcopy(multisensor_6_state),
|
||||
},
|
||||
)
|
||||
dev_id = get_device_id(client.driver, multisensor_6)
|
||||
msg_id = f"{DOMAIN}.node_reset_and_removed.{dev_id[1]}"
|
||||
|
||||
client.driver.controller.receive_event(remove_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)
|
||||
|
||||
# Re-add the node then remove it again
|
||||
client.driver.controller.nodes[multisensor_6_state["nodeId"]] = Node(
|
||||
client, deepcopy(multisensor_6_state)
|
||||
)
|
||||
remove_event.data["node"] = deepcopy(multisensor_6_state)
|
||||
client.driver.controller.receive_event(remove_event)
|
||||
# Test case where config entry title and home ID don't match
|
||||
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.nodes[multisensor_6_state["nodeId"]] = Node(
|
||||
client, deepcopy(multisensor_6_state)
|
||||
)
|
||||
remove_event.data["node"] = deepcopy(multisensor_6_state)
|
||||
client.driver.controller.receive_event(remove_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"]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue