From f3ea44cd92cdc912cfaace92e07cd820fba8c38e Mon Sep 17 00:00:00 2001
From: Charles Garwood <cgarwood@gmail.com>
Date: Mon, 4 Nov 2019 10:17:32 -0500
Subject: [PATCH] Cleanup Device Registry on Z-Wave Node Removal (#28240)

* Remove device from device registry on node removal

* Make async_get_registry from entity registry more concise

* Lower log level to debug
---
 homeassistant/components/zwave/__init__.py | 26 +++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/homeassistant/components/zwave/__init__.py b/homeassistant/components/zwave/__init__.py
index 841b283a98d..97a904c5d99 100644
--- a/homeassistant/components/zwave/__init__.py
+++ b/homeassistant/components/zwave/__init__.py
@@ -13,7 +13,12 @@ from homeassistant.helpers import discovery
 from homeassistant.helpers.entity import generate_entity_id
 from homeassistant.helpers.entity_component import DEFAULT_SCAN_INTERVAL
 from homeassistant.helpers.entity_platform import EntityPlatform
-from homeassistant.helpers.entity_registry import async_get_registry
+from homeassistant.helpers.entity_registry import (
+    async_get_registry as async_get_entity_registry,
+)
+from homeassistant.helpers.device_registry import (
+    async_get_registry as async_get_device_registry,
+)
 from homeassistant.const import (
     ATTR_ENTITY_ID,
     EVENT_HOMEASSISTANT_START,
@@ -376,7 +381,7 @@ async def async_setup_entry(hass, config_entry):
     hass.data[DATA_DEVICES] = {}
     hass.data[DATA_ENTITY_VALUES] = []
 
-    registry = await async_get_registry(hass)
+    registry = await async_get_entity_registry(hass)
 
     wsapi.async_load_websocket_api(hass)
 
@@ -479,13 +484,14 @@ async def async_setup_entry(hass, config_entry):
     def node_removed(node):
         node_id = node.node_id
         node_key = f"node-{node_id}"
-        _LOGGER.info("Node Removed: %s", hass.data[DATA_DEVICES][node_key])
         for key in list(hass.data[DATA_DEVICES]):
+            if key is None:
+                continue
             if not key.startswith(f"{node_id}-"):
                 continue
 
             entity = hass.data[DATA_DEVICES][key]
-            _LOGGER.info(
+            _LOGGER.debug(
                 "Removing Entity - value: %s - entity_id: %s", key, entity.entity_id
             )
             hass.add_job(entity.node_removed())
@@ -495,6 +501,16 @@ async def async_setup_entry(hass, config_entry):
         hass.add_job(entity.node_removed())
         del hass.data[DATA_DEVICES][node_key]
 
+        hass.add_job(_remove_device(node))
+
+    async def _remove_device(node):
+        dev_reg = await async_get_device_registry(hass)
+        identifier, name = node_device_id_and_name(node)
+        device = dev_reg.async_get_device(identifiers={identifier}, connections=set())
+        if device is not None:
+            _LOGGER.debug("Removing Device - %s - %s", device.id, name)
+            dev_reg.async_remove_device(device.id)
+
     def network_ready():
         """Handle the query of all awake nodes."""
         _LOGGER.info(
@@ -1208,7 +1224,7 @@ class ZWaveDeviceEntity(ZWaveBaseEntity):
         self._name = _value_name(self.values.primary)
         if update_ids:
             # Update entity ID.
-            ent_reg = await async_get_registry(self.hass)
+            ent_reg = await async_get_entity_registry(self.hass)
             new_entity_id = ent_reg.async_generate_entity_id(
                 self.platform.domain,
                 self._name,
-- 
GitLab