Просмотр исходного кода

Add manage locks option flow step; improve frontend registration logging

Options flow now includes a "Manage locks" step to add/remove Z-Wave lock
entities without deleting and re-adding the config entry. Groups that
reference only removed locks are pruned automatically.

Frontend registration now logs success at debug level and failures at
error level with manual registration instructions.
ZiB 4 месяцев назад
Родитель
Сommit
92f599a0c1

+ 9 - 6
custom_components/zlock_slots/__init__.py

@@ -62,14 +62,17 @@ async def _async_register_frontend(hass: HomeAssistant) -> None:
     await hass.http.async_register_static_paths([
       StaticPathConfig(_CARD_URL, str(_CARD_PATH), cache_headers=False)
     ])
-  except Exception:
-    _LOGGER.debug("Static path %s already registered", _CARD_URL)
+  except Exception as err:
+    _LOGGER.debug("Static path %s already registered: %s", _CARD_URL, err)
 
   try:
     from homeassistant.components.frontend import async_register_extra_module_url
     async_register_extra_module_url(hass, _CARD_URL)
-  except Exception:
-    _LOGGER.warning(
-      "Could not auto-register Lovelace card. Add manually via Settings → Dashboard → Resources: %s",
-      _CARD_URL,
+    _LOGGER.debug("Registered Lovelace module: %s", _CARD_URL)
+  except Exception as err:
+    _LOGGER.error(
+      "Failed to register Lovelace card module %s: %s. "
+      "Add it manually: Settings → Dashboards → ⋮ → Resources → Add Resource, "
+      "URL: %s, Resource type: JavaScript module.",
+      _CARD_URL, err, _CARD_URL,
     )

+ 37 - 1
custom_components/zlock_slots/config_flow.py

@@ -62,9 +62,45 @@ class ZLockSlotsOptionsFlow(OptionsFlow):
   async def async_step_init(self, user_input=None) -> ConfigFlowResult:
     return self.async_show_menu(
       step_id="init",
-      menu_options=["add_group", "remove_group", "finish"],
+      menu_options=["manage_locks", "add_group", "remove_group", "finish"],
     )
 
+  async def async_step_manage_locks(self, user_input=None) -> ConfigFlowResult:
+    errors: dict[str, str] = {}
+    current_lock_ids: list[str] = self._entry.data.get(CONF_LOCK_ENTITY_IDS, [])
+
+    if user_input is not None:
+      new_lock_ids: list[str] = user_input.get(CONF_LOCK_ENTITY_IDS, [])
+      if not new_lock_ids:
+        errors[CONF_LOCK_ENTITY_IDS] = "no_locks_selected"
+      else:
+        removed = set(current_lock_ids) - set(new_lock_ids)
+        if removed:
+          self._groups = [
+            g for g in self._groups
+            if not all(lid in removed for lid in g.get(CONF_LOCK_ENTITY_IDS, []))
+          ]
+          for g in self._groups:
+            g[CONF_LOCK_ENTITY_IDS] = [
+              lid for lid in g.get(CONF_LOCK_ENTITY_IDS, []) if lid not in removed
+            ]
+          self._groups = [g for g in self._groups if g.get(CONF_LOCK_ENTITY_IDS)]
+        self.hass.config_entries.async_update_entry(
+          self._entry, data={CONF_LOCK_ENTITY_IDS: new_lock_ids}
+        )
+        return await self.async_step_init()
+
+    schema = vol.Schema({
+      vol.Required(CONF_LOCK_ENTITY_IDS, default=current_lock_ids): selector.EntitySelector(
+        selector.EntitySelectorConfig(
+          domain="lock",
+          integration="zwave_js",
+          multiple=True,
+        )
+      ),
+    })
+    return self.async_show_form(step_id="manage_locks", data_schema=schema, errors=errors)
+
   async def async_step_add_group(self, user_input=None) -> ConfigFlowResult:
     errors: dict[str, str] = {}
     lock_ids: list[str] = self._entry.data[CONF_LOCK_ENTITY_IDS]

+ 9 - 1
custom_components/zlock_slots/strings.json

@@ -19,13 +19,21 @@
   "options": {
     "step": {
       "init": {
-        "title": "Manage Lock Groups",
+        "title": "Z-Lock Slots Options",
         "menu_options": {
+          "manage_locks": "Manage locks",
           "add_group": "Add group",
           "remove_group": "Remove group",
           "finish": "Save and close"
         }
       },
+      "manage_locks": {
+        "title": "Manage Locks",
+        "description": "Add or remove Z-Wave locks. Groups referencing only removed locks will also be removed.",
+        "data": {
+          "lock_entity_ids": "Lock(s)"
+        }
+      },
       "add_group": {
         "title": "Add Lock Group",
         "description": "Create a group of locks that publishes a shared last-action and last-user sensor.",

+ 9 - 1
custom_components/zlock_slots/translations/en.json

@@ -19,13 +19,21 @@
   "options": {
     "step": {
       "init": {
-        "title": "Manage Lock Groups",
+        "title": "Z-Lock Slots Options",
         "menu_options": {
+          "manage_locks": "Manage locks",
           "add_group": "Add group",
           "remove_group": "Remove group",
           "finish": "Save and close"
         }
       },
+      "manage_locks": {
+        "title": "Manage Locks",
+        "description": "Add or remove Z-Wave locks. Groups referencing only removed locks will also be removed.",
+        "data": {
+          "lock_entity_ids": "Lock(s)"
+        }
+      },
       "add_group": {
         "title": "Add Lock Group",
         "description": "Create a group of locks that publishes a shared last-action and last-user sensor.",