From 6079cc44807df285459a5cf3e9b0a5abf2d9846e Mon Sep 17 00:00:00 2001 From: Luligu Date: Fri, 7 Feb 2025 17:12:40 +0100 Subject: [PATCH] Release 0.0.9 --- CHANGELOG.md | 20 + README.md | 20 +- matterbridge-hass.schema.json | 4 +- mock/homeassistant.json | 1872 +++++++++++++++++++++++++++------ package-lock.json | 140 +-- package.json | 8 +- src/converters.ts | 5 +- src/homeAssistant.ts | 18 +- src/index.test.ts | 5 +- src/platform.test.ts | 70 +- src/platform.ts | 66 +- 11 files changed, 1766 insertions(+), 462 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9967d25..b885c22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file. If you like this project and find it useful, please consider giving it a star on GitHub at https://github.com/Luligu/matterbridge-hass and sponsoring it. +## [0.0.9] - 2025-02-07 + +### Added + +- [hass]: Added support for helpers with domain input_boolean. +- [plugin]: Added check for duplicated device and individual entity names. + +### Changed + +- [package]: Updated dependencies. +- [package]: Requires matterbridge 2.1.4. + +### Fixed + +- [cover]: Fixed state closed on domain cover. + + + Buy me a coffee + + ## [0.0.8] - 2025-02-02 ### Added diff --git a/README.md b/README.md index 5543763..d36438c 100644 --- a/README.md +++ b/README.md @@ -12,13 +12,13 @@ --- -This plugin allows you to expose the Home Assistant devices to Matter. +This plugin allows you to expose the Home Assistant devices and entities to Matter. It is the ideal companion of the official [Matterbridge Home Assistant Add-on](https://github.com/Luligu/matterbridge-home-assistant-addon/blob/main/README.md). Features: -- The plugin can run with Matterbridge running in the Matterbridge Official Add-on or outside Home Assistant. +- The plugin can be used with Matterbridge running in the Matterbridge Official Add-on or outside Home Assistant. - The connection with Home Assistant is made throught WebSocket: so Matterbridge can be also in another network if the Home Assistant host is reachable. - It is possible to select from a list the devices to include in the device white or black list. - It is possible to select from a list the entities to include in the entity white or black list. @@ -34,7 +34,7 @@ Supported devices: - fan (with state on/off and attributes percentage/preset_mode) -- cover (with state open/close/opening/closing and attribute current_position) +- cover (with state open/closed/opening/closing and attribute current_position) - climate (with state off/heat/cool/heat_cool and attribute temperature/current_temperature/target_temp_low/target_temp_high) @@ -48,7 +48,9 @@ Supported individual entities: - script -These entities are exposed as on/off outlets. When the outlet is turned on, it triggers the associated automation, scene, or script. After triggering, the outlet automatically switches back to the off state. +- helpers of domain input_boolean + +These entities are exposed as on/off outlets. When the outlet is turned on, it triggers the associated automation, scene, or script. After triggering, the outlet automatically switches back to the off state. The helpers of domain input_boolean maintain the on / off state. > **Warning:** Since this plugin takes the devices from Home Assistant, it cannot be paired back to Home Assistant. This would lead to duplicate devices! If you run Matterbridge like a Home Assistant Add-on and also use other plugins to expose their devices to Home Assistant, then change to child bridge mode and pair the other plugins to Home Assistant and this plugin wherever you need it. @@ -108,11 +110,11 @@ There are 2 different source of Matter devices coming from matterbridge-hass plu - Regular devices with their entities that use the main whiteList, blackList, entityBlackList and deviceEntityBlackList. -You see them in Home Assistant at http://localhost:8123/config/devices/dashboard. +You find them in Home Assistant at http://localhost:8123/config/devices/dashboard. -- Individual entities with domain scenes, scripts, automations that use individualEntityWhiteList and individualEntityBlackList. +- Individual entities with domain scene, script, automation and input_boolean that use individualEntityWhiteList and individualEntityBlackList. -You see these special entities in Home Assistant at http://localhost:8123/config/automation/dashboard, http://localhost:8123/config/scene/dashboard and http://localhost:8123/config/script/dashboard. +You find these special entities in Home Assistant at http://localhost:8123/config/automation/dashboard, http://localhost:8123/config/scene/dashboard, http://localhost:8123/config/script/dashboard and http://localhost:8123/config/helpers. You may need to set some config values in the frontend (wait that the plugin has been configured before changing the config): @@ -130,7 +132,7 @@ Home Assistant long term token used to connect to Home Assistant with WebSocket. ### individualEntityWhiteList -White list of individual entities without associated device to be exposed. It allows to expose scenes, scripts, automations. +White list of individual entities without associated device to be exposed. It allows to expose scenes, scripts, automations and input_boolean. Enter the entity_id (i.e. automation.turn_off_all_switches) or the entity name (i.e. Turn off all switches). ### individualEntityBlackList @@ -148,7 +150,7 @@ If the blackList is defined the devices included will not be exposed to Matter. ### entityBlackList -The entities in the list will not be exposed for all devices. Use the entity name. +The entities in the list will not be exposed for all devices. Use the entity name. This doesn't concern the individual entities. ### deviceEntityBlackList diff --git a/matterbridge-hass.schema.json b/matterbridge-hass.schema.json index 7dac33b..87ee52d 100644 --- a/matterbridge-hass.schema.json +++ b/matterbridge-hass.schema.json @@ -29,7 +29,7 @@ "default": 60 }, "individualEntityWhiteList": { - "description": "White list of individual entities without associated device to be exposed. It allows to select scenes, scripts, automations. Enter the entity_id (i.e. automation.turn_off_all_switches) or the entity name (i.e. Turn off all switched).", + "description": "White list of individual entities without associated device to be exposed. It allows to select scenes, scripts, automations and input_boolean. Enter the entity_id (i.e. automation.turn_off_all_switches) or the entity name (i.e. Turn off all switched).", "type": "array", "items": { "type": "string" @@ -38,7 +38,7 @@ "selectEntityFrom": "name" }, "individualEntityBlackList": { - "description": "Black list of individual entities without associated device to not be exposed. It allows to select scenes, scripts, automations. Enter the entity_id (i.e. automation.turn_off_all_switches) or the entity name (i.e. Turn off all switched).", + "description": "Black list of individual entities without associated device to not be exposed. It allows to select scenes, scripts, automations and input_boolean. Enter the entity_id (i.e. automation.turn_off_all_switches) or the entity name (i.e. Turn off all switched).", "type": "array", "items": { "type": "string" diff --git a/mock/homeassistant.json b/mock/homeassistant.json index 1a95459..1b8ed54 100644 --- a/mock/homeassistant.json +++ b/mock/homeassistant.json @@ -3,14 +3,21 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J50BAHZ8AKHB79K34M3MXC"], + "config_entries": [ + "01J6J50BAHZ8AKHB79K34M3MXC" + ], "connections": [], "created_at": 1725038603.61461, "disabled_by": null, "entry_type": "service", "hw_version": null, "id": "fbaee7a0f13380a642201889e2906e8c", - "identifiers": [["sun", "01J6J50BAHZ8AKHB79K34M3MXC"]], + "identifiers": [ + [ + "sun", + "01J6J50BAHZ8AKHB79K34M3MXC" + ] + ], "labels": [], "manufacturer": null, "model": null, @@ -26,14 +33,21 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J50C9GRRNRZWNH189GDHBT"], + "config_entries": [ + "01J6J50C9GRRNRZWNH189GDHBT" + ], "connections": [], "created_at": 1725038604.726252, "disabled_by": null, "entry_type": "service", "hw_version": null, "id": "3ccdb9024997eab91c68e3ac74fa7893", - "identifiers": [["hassio", "core"]], + "identifiers": [ + [ + "hassio", + "core" + ] + ], "labels": [], "manufacturer": "Home Assistant", "model": "Home Assistant Core", @@ -49,14 +63,21 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J50C9GRRNRZWNH189GDHBT"], + "config_entries": [ + "01J6J50C9GRRNRZWNH189GDHBT" + ], "connections": [], "created_at": 1725038604.726873, "disabled_by": null, "entry_type": "service", "hw_version": null, "id": "069662c6234ec6170619ae3e98cdf51e", - "identifiers": [["hassio", "supervisor"]], + "identifiers": [ + [ + "hassio", + "supervisor" + ] + ], "labels": [], "manufacturer": "Home Assistant", "model": "Home Assistant Supervisor", @@ -72,14 +93,21 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J50C9GRRNRZWNH189GDHBT"], + "config_entries": [ + "01J6J50C9GRRNRZWNH189GDHBT" + ], "connections": [], "created_at": 1725038604.727217, "disabled_by": null, "entry_type": "service", "hw_version": null, "id": "4f42c80bdc9f665956b498deb4c9dbfd", - "identifiers": [["hassio", "host"]], + "identifiers": [ + [ + "hassio", + "host" + ] + ], "labels": [], "manufacturer": "Home Assistant", "model": "Home Assistant Host", @@ -95,14 +123,21 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J50C9GRRNRZWNH189GDHBT"], + "config_entries": [ + "01J6J50C9GRRNRZWNH189GDHBT" + ], "connections": [], "created_at": 1725038604.727483, "disabled_by": null, "entry_type": "service", "hw_version": null, "id": "73259c15f1251065e0191ab0e79f6613", - "identifiers": [["hassio", "OS"]], + "identifiers": [ + [ + "hassio", + "OS" + ] + ], "labels": [], "manufacturer": "Home Assistant", "model": "Home Assistant Operating System", @@ -118,14 +153,21 @@ { "area_id": null, "configuration_url": "https://www.met.no/en", - "config_entries": ["01J6J6BH25M5MMJVEJ04FADJV5"], + "config_entries": [ + "01J6J6BH25M5MMJVEJ04FADJV5" + ], "connections": [], "created_at": 1725040018.889964, "disabled_by": null, "entry_type": "service", "hw_version": null, "id": "34ddaedf22e5c61e23fc8cbfc27db4b0", - "identifiers": [["met", "01J6J6BH25M5MMJVEJ04FADJV5"]], + "identifiers": [ + [ + "met", + "01J6J6BH25M5MMJVEJ04FADJV5" + ] + ], "labels": [], "manufacturer": "Met.no", "model": "Forecast", @@ -141,14 +183,21 @@ { "area_id": null, "configuration_url": "homeassistant://hassio/addon/core_matter_server", - "config_entries": ["01J6J50C9GRRNRZWNH189GDHBT"], + "config_entries": [ + "01J6J50C9GRRNRZWNH189GDHBT" + ], "connections": [], "created_at": 1725041204.129441, "disabled_by": null, "entry_type": "service", "hw_version": null, "id": "2c7ef5f366331c562dbff21df659613a", - "identifiers": [["hassio", "core_matter_server"]], + "identifiers": [ + [ + "hassio", + "core_matter_server" + ] + ], "labels": [], "manufacturer": "Official add-ons", "model": "Home Assistant Add-on", @@ -164,14 +213,22 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J7NJAF02T3BSC3WTWTJ4YVT1", "01J7JMMF9DP1S0422TP2EBA4W6"], + "config_entries": [ + "01J7NJAF02T3BSC3WTWTJ4YVT1", + "01J7JMMF9DP1S0422TP2EBA4W6" + ], "connections": [], "created_at": 1725120289.599289, "disabled_by": null, "entry_type": null, "hw_version": null, "id": "e19544471e06a2fc73da46bec34b3f13", - "identifiers": [["mobile_app", "85EA0E37-6F8E-4292-9D69-F2DD757F2672"]], + "identifiers": [ + [ + "mobile_app", + "85EA0E37-6F8E-4292-9D69-F2DD757F2672" + ] + ], "labels": [], "manufacturer": "Apple", "model": "iPhone16,1", @@ -187,14 +244,21 @@ { "area_id": null, "configuration_url": "homeassistant://hassio/addon/core_samba", - "config_entries": ["01J6J50C9GRRNRZWNH189GDHBT"], + "config_entries": [ + "01J6J50C9GRRNRZWNH189GDHBT" + ], "connections": [], "created_at": 1725620177.379212, "disabled_by": null, "entry_type": "service", "hw_version": null, "id": "ff327eaee438df4701fe201c0645096f", - "identifiers": [["hassio", "core_samba"]], + "identifiers": [ + [ + "hassio", + "core_samba" + ] + ], "labels": [], "manufacturer": "Official add-ons", "model": "Home Assistant Add-on", @@ -210,14 +274,21 @@ { "area_id": null, "configuration_url": "homeassistant://hassio/addon/core_ssh", - "config_entries": ["01J6J50C9GRRNRZWNH189GDHBT"], + "config_entries": [ + "01J6J50C9GRRNRZWNH189GDHBT" + ], "connections": [], "created_at": 1725624710.188691, "disabled_by": null, "entry_type": "service", "hw_version": null, "id": "0a8e282e657d2154dfbf56553cd0616f", - "identifiers": [["hassio", "core_ssh"]], + "identifiers": [ + [ + "hassio", + "core_ssh" + ] + ], "labels": [], "manufacturer": "Official add-ons", "model": "Home Assistant Add-on", @@ -233,8 +304,15 @@ { "area_id": null, "configuration_url": "http://192.168.1.150:80", - "config_entries": ["01J7RFH4C1RWTMZ1Z2EBY2WZ4B"], - "connections": [["mac", "cc:7b:5c:0a:b6:24"]], + "config_entries": [ + "01J7RFH4C1RWTMZ1Z2EBY2WZ4B" + ], + "connections": [ + [ + "mac", + "cc:7b:5c:0a:b6:24" + ] + ], "created_at": 1726324707.846316, "disabled_by": null, "entry_type": null, @@ -256,8 +334,15 @@ { "area_id": null, "configuration_url": "http://192.168.1.156:80", - "config_entries": ["01J85DN3ARHRZJ3X2Y3C0ZSNMY"], - "connections": [["mac", "34:98:7a:49:57:c4"]], + "config_entries": [ + "01J85DN3ARHRZJ3X2Y3C0ZSNMY" + ], + "connections": [ + [ + "mac", + "34:98:7a:49:57:c4" + ] + ], "created_at": 1726758948.372638, "disabled_by": null, "entry_type": null, @@ -279,14 +364,21 @@ { "area_id": null, "configuration_url": "homeassistant://hassio/addon/local_matterbridge", - "config_entries": ["01J6J50C9GRRNRZWNH189GDHBT"], + "config_entries": [ + "01J6J50C9GRRNRZWNH189GDHBT" + ], "connections": [], "created_at": 1725862540.40383, "disabled_by": null, "entry_type": "service", "hw_version": null, "id": "1a96bdc13db15a236b1774953b8cf0fc", - "identifiers": [["hassio", "local_matterbridge"]], + "identifiers": [ + [ + "hassio", + "local_matterbridge" + ] + ], "labels": [], "manufacturer": "Local add-ons", "model": "Home Assistant Add-on", @@ -302,8 +394,15 @@ { "area_id": null, "configuration_url": "http://SLZB-06P10-II.local", - "config_entries": ["01J8FCM8B3N3GR21GMAXAGMPMF"], - "connections": [["mac", "e4:65:b8:d9:0f:e8"]], + "config_entries": [ + "01J8FCM8B3N3GR21GMAXAGMPMF" + ], + "connections": [ + [ + "mac", + "e4:65:b8:d9:0f:e8" + ] + ], "created_at": 1727093416.537993, "disabled_by": null, "entry_type": null, @@ -325,8 +424,15 @@ { "area_id": null, "configuration_url": "http://SLZB-06P10-I.local", - "config_entries": ["01J97K5KZJVWW0XYC4MVWW8JAN"], - "connections": [["mac", "e4:65:b8:d9:0d:64"]], + "config_entries": [ + "01J97K5KZJVWW0XYC4MVWW8JAN" + ], + "connections": [ + [ + "mac", + "e4:65:b8:d9:0d:64" + ] + ], "created_at": 1727905583.814959, "disabled_by": null, "entry_type": null, @@ -348,7 +454,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1728717123.913952, "disabled_by": null, @@ -356,8 +464,14 @@ "hw_version": "10.0.22631", "id": "842c0f96d437045d9aa915e4109f9316", "identifiers": [ - ["matter", "deviceid_CAD2FA0F285B2850-0000000000000031-MatterNodeDevice"], - ["matter", "serial_CS43d1dcfdf8effb88"] + [ + "matter", + "deviceid_CAD2FA0F285B2850-0000000000000031-MatterNodeDevice" + ], + [ + "matter", + "serial_CS43d1dcfdf8effb88" + ] ], "labels": [], "manufacturer": "Matterbridge", @@ -374,7 +488,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1728717006.912548, "disabled_by": null, @@ -382,8 +498,14 @@ "hw_version": "6.6.54-haos", "id": "d4a13a20b1b1f2c2962f84f3ffe29df4", "identifiers": [ - ["matter", "serial_CSd4c8dab75767f50a"], - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-MatterNodeDevice"] + [ + "matter", + "serial_CSd4c8dab75767f50a" + ], + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-MatterNodeDevice" + ] ], "labels": [], "manufacturer": "Matterbridge", @@ -400,8 +522,15 @@ { "area_id": null, "configuration_url": "http://192.168.1.155:80", - "config_entries": ["01JBQC74E6XF74HAY9FPZ3DC9K"], - "connections": [["mac", "48:55:19:ee:12:a7"]], + "config_entries": [ + "01JBQC74E6XF74HAY9FPZ3DC9K" + ], + "connections": [ + [ + "mac", + "48:55:19:ee:12:a7" + ] + ], "created_at": 1730582647.361794, "disabled_by": null, "entry_type": null, @@ -423,7 +552,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1725376976.61836, "disabled_by": null, @@ -431,8 +562,14 @@ "hw_version": "1.0.0", "id": "054236775dbec1a5e3bf809a854d5d5e", "identifiers": [ - ["matter", "serial_0x2342375564"], - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-3"] + [ + "matter", + "serial_0x2342375564" + ], + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-3" + ] ], "labels": [], "manufacturer": "Luligu", @@ -449,7 +586,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1725397907.162919, "disabled_by": null, @@ -457,8 +596,14 @@ "hw_version": "1.0.0", "id": "0e7d878fb0cee030e67c2bb806f5094b", "identifiers": [ - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-21"], - ["matter", "serial_serial_987484318322"] + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-21" + ], + [ + "matter", + "serial_serial_987484318322" + ] ], "labels": [], "manufacturer": "Luligu", @@ -475,7 +620,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1725285447.665569, "disabled_by": null, @@ -483,8 +630,14 @@ "hw_version": "1.0.0", "id": "e7a5676bcfa4a5a57bf2cdd4d7020448", "identifiers": [ - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-6"], - ["matter", "serial_0x25097564"] + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-6" + ], + [ + "matter", + "serial_0x25097564" + ] ], "labels": [], "manufacturer": "Luligu", @@ -501,7 +654,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1725378185.32515, "disabled_by": null, @@ -509,8 +664,14 @@ "hw_version": "1.0.0", "id": "a7fac3ec781275f3872d089e4f82307e", "identifiers": [ - ["matter", "serial_0x234554564"], - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-4"] + [ + "matter", + "serial_0x234554564" + ], + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-4" + ] ], "labels": [], "manufacturer": "Luligu", @@ -527,7 +688,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1725288864.247281, "disabled_by": null, @@ -535,8 +698,14 @@ "hw_version": "1.0.0", "id": "1adb7198570f7bf0662d99618def644e", "identifiers": [ - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-16"], - ["matter", "serial_serial_980545631228"] + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-16" + ], + [ + "matter", + "serial_serial_980545631228" + ] ], "labels": [], "manufacturer": "Luligu", @@ -553,7 +722,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1725287568.537371, "disabled_by": null, @@ -561,8 +732,14 @@ "hw_version": "1.0.0", "id": "66aa9045b11c8e5e2c90b06175fae0f0", "identifiers": [ - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-8"], - ["matter", "serial_0x23480749"] + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-8" + ], + [ + "matter", + "serial_0x23480749" + ] ], "labels": [], "manufacturer": "Luligu", @@ -579,7 +756,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1725284669.248506, "disabled_by": null, @@ -587,8 +766,14 @@ "hw_version": "1.0.0", "id": "de09532666dba9db586d93b4b2699062", "identifiers": [ - ["matter", "serial_0x23497564"], - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-7"] + [ + "matter", + "serial_0x23497564" + ], + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-7" + ] ], "labels": [], "manufacturer": "Luligu", @@ -605,7 +790,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1730641626.471183, "disabled_by": null, @@ -613,8 +800,14 @@ "hw_version": "1.0.0", "id": "3898c5aa5d1c14b05406b7007d8d347f", "identifiers": [ - ["matter", "serial_0x96382164"], - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-12"] + [ + "matter", + "serial_0x96382164" + ], + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-12" + ] ], "labels": [], "manufacturer": "Luligu", @@ -631,7 +824,59 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], + "connections": [], + "created_at": 1734336741.468888, + "disabled_by": null, + "entry_type": null, + "hw_version": "2.1.4-dev.2", + "id": "dc0b13b9f9d848b90201f926ab7a5c96", + "identifiers": [ + [ + "matter", + "deviceid_CAD2FA0F285B2850-0000000000000035-65" + ], + [ + "matter", + "serial_0x96382164H" + ], + [ + "matter", + "deviceid_CAD2FA0F285B2850-0000000000000035-41" + ], + [ + "matter", + "deviceid_CAD2FA0F285B2850-0000000000000037-20" + ], + [ + "matter", + "deviceid_CAD2FA0F285B2850-0000000000000035-28" + ], + [ + "matter", + "deviceid_CAD2FA0F285B2850-0000000000000037-51" + ] + ], + "labels": [], + "manufacturer": "Matterbridge", + "model": "Thermostat (Heat)", + "model_id": null, + "modified_at": 1738860465.130394, + "name_by_user": null, + "name": "Thermostat (Heat)", + "primary_config_entry": "01J6J7D7EADB8KNX8XBDYDNB1B", + "serial_number": "0x96382164H", + "sw_version": "1.1.6", + "via_device_id": "3e46fbb7d8bacc7e353aaaed0c3f9c8f" + }, + { + "area_id": null, + "configuration_url": null, + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1730641626.550536, "disabled_by": null, @@ -639,8 +884,14 @@ "hw_version": "1.0.0", "id": "6af9352ad295b876bfcfc1d90d11f4ce", "identifiers": [ - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-19"], - ["matter", "serial_serial_98745631224"] + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-19" + ], + [ + "matter", + "serial_serial_98745631224" + ] ], "labels": [], "manufacturer": "Luligu", @@ -657,7 +908,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1725044472.645806, "disabled_by": null, @@ -665,8 +918,14 @@ "hw_version": "1.0.0", "id": "2aa3364c58e0e2b7f343629a26ea7d13", "identifiers": [ - ["matter", "serial_0x23480564"], - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-5"] + [ + "matter", + "serial_0x23480564" + ], + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-5" + ] ], "labels": [], "manufacturer": "Luligu", @@ -683,7 +942,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1730641626.696591, "disabled_by": null, @@ -691,8 +952,14 @@ "hw_version": "1.0.0", "id": "85476b52c919e7d58a779155c476fdb0", "identifiers": [ - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-2"], - ["matter", "serial_0x23452164"] + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-2" + ], + [ + "matter", + "serial_0x23452164" + ] ], "labels": [], "manufacturer": "Luligu", @@ -709,7 +976,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1730641626.757749, "disabled_by": null, @@ -717,8 +986,14 @@ "hw_version": "1.0.0", "id": "198113096bd13a9aaec18871780962cb", "identifiers": [ - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-18"], - ["matter", "serial_serial_98745631223"] + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-18" + ], + [ + "matter", + "serial_serial_98745631223" + ] ], "labels": [], "manufacturer": "Luligu", @@ -735,7 +1010,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1725044472.69598, "disabled_by": null, @@ -743,8 +1020,14 @@ "hw_version": "1.0.0", "id": "7b5c275b2e7c3844caf7a7c438ce77ac", "identifiers": [ - ["matter", "serial_0x96352164"], - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-11"] + [ + "matter", + "serial_0x96352164" + ], + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-11" + ] ], "labels": [], "manufacturer": "Luligu", @@ -761,7 +1044,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1730641626.859755, "disabled_by": null, @@ -769,8 +1054,14 @@ "hw_version": "1.0.0", "id": "df128ee16983a0166879f2e3484a6f7e", "identifiers": [ - ["matter", "serial_serial_94745631225"], - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-20"] + [ + "matter", + "serial_serial_94745631225" + ], + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-20" + ] ], "labels": [], "manufacturer": "Luligu", @@ -787,7 +1078,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1730641626.961021, "disabled_by": null, @@ -795,8 +1088,14 @@ "hw_version": "1.0.0", "id": "96efad8d87e1b740cd6713e41cb78446", "identifiers": [ - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-17"], - ["matter", "serial_serial_98745631222"] + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-17" + ], + [ + "matter", + "serial_serial_98745631222" + ] ], "labels": [], "manufacturer": "Luligu", @@ -813,7 +1112,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1725044472.678494, "disabled_by": null, @@ -821,8 +1122,14 @@ "hw_version": "1.0.0", "id": "b684c54436937eea8bfd0884cf4b4547", "identifiers": [ - ["matter", "serial_0x01020564"], - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-10"] + [ + "matter", + "serial_0x01020564" + ], + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-10" + ] ], "labels": [], "manufacturer": "Luligu", @@ -839,7 +1146,9 @@ { "area_id": null, "configuration_url": null, - "config_entries": ["01J6J7D7EADB8KNX8XBDYDNB1B"], + "config_entries": [ + "01J6J7D7EADB8KNX8XBDYDNB1B" + ], "connections": [], "created_at": 1730641627.022424, "disabled_by": null, @@ -847,8 +1156,14 @@ "hw_version": "1.0.0", "id": "9b9ca0dbe87c6305334e5ef0afb4f6c5", "identifiers": [ - ["matter", "deviceid_CAD2FA0F285B2850-000000000000001F-9"], - ["matter", "serial_0x29252164"] + [ + "matter", + "deviceid_CAD2FA0F285B2850-000000000000001F-9" + ], + [ + "matter", + "serial_0x29252164" + ] ], "labels": [], "manufacturer": "Luligu", @@ -864,6 +1179,84 @@ } ], "entities": [ + { + "area_id": null, + "categories": {}, + "config_entry_id": "01J6J7D7EADB8KNX8XBDYDNB1B", + "created_at": 1737993627.221181, + "device_id": "dc0b13b9f9d848b90201f926ab7a5c96", + "disabled_by": null, + "entity_category": null, + "entity_id": "climate.thermostat_heat", + "has_entity_name": true, + "hidden_by": null, + "icon": null, + "id": "1a52873ff26d42e6977ebdfb3bda8264", + "labels": [], + "modified_at": 1737993627.223207, + "name": null, + "options": { + "conversation": { + "should_expose": true + } + }, + "original_name": null, + "platform": "matter", + "translation_key": null, + "unique_id": "CAD2FA0F285B2850-0000000000000035-65-65-MatterThermostat-513-0" + }, + { + "area_id": null, + "categories": {}, + "config_entry_id": "01J6J7D7EADB8KNX8XBDYDNB1B", + "created_at": 1738101364.058462, + "device_id": "dc0b13b9f9d848b90201f926ab7a5c96", + "disabled_by": null, + "entity_category": null, + "entity_id": "sensor.thermostat_heat_temperature", + "has_entity_name": true, + "hidden_by": null, + "icon": null, + "id": "2cfc3a3e85d236af8cec42ccfc1506b4", + "labels": [], + "modified_at": 1738101368.155283, + "name": null, + "options": { + "conversation": { + "should_expose": true + } + }, + "original_name": "Temperature", + "platform": "matter", + "translation_key": null, + "unique_id": "CAD2FA0F285B2850-0000000000000035-65-66-TemperatureSensor-1026-0" + }, + { + "area_id": null, + "categories": {}, + "config_entry_id": "01J6J7D7EADB8KNX8XBDYDNB1B", + "created_at": 1738101364.068124, + "device_id": "dc0b13b9f9d848b90201f926ab7a5c96", + "disabled_by": null, + "entity_category": null, + "entity_id": "sensor.thermostat_heat_temperature_2", + "has_entity_name": true, + "hidden_by": null, + "icon": null, + "id": "134a4a757f4e9e7dbcbea2b6a44e8e08", + "labels": [], + "modified_at": 1738101368.156542, + "name": null, + "options": { + "conversation": { + "should_expose": true + } + }, + "original_name": "Temperature", + "platform": "matter", + "translation_key": null, + "unique_id": "CAD2FA0F285B2850-0000000000000035-65-67-TemperatureSensor-1026-0" + }, { "area_id": null, "categories": {}, @@ -7361,13 +7754,129 @@ } ], "states": [ + { + "entity_id": "climate.thermostat_heat", + "state": "heat", + "attributes": { + "hvac_modes": [ + "off", + "heat" + ], + "min_temp": 5, + "max_temp": 35, + "current_temperature": 21, + "temperature": 22.5, + "friendly_name": "Thermostat (Heat)", + "supported_features": 385 + }, + "last_changed": "2025-02-06T16:47:44.891622+00:00", + "last_reported": "2025-02-07T10:27:39.289281+00:00", + "last_updated": "2025-02-07T10:27:39.289281+00:00", + "context": { + "id": "01JKFZ6TMSW9FHGAE9H0MQQ54W", + "parent_id": null, + "user_id": null + } + }, + { + "entity_id": "sensor.thermostat_heat_battery", + "state": "70", + "attributes": { + "state_class": "measurement", + "unit_of_measurement": "%", + "device_class": "battery", + "friendly_name": "Thermostat (Heat) Battery" + }, + "last_changed": "2025-02-06T16:47:44.892724+00:00", + "last_reported": "2025-02-06T16:47:44.892724+00:00", + "last_updated": "2025-02-06T16:47:44.892724+00:00", + "context": { + "id": "01JKE2J2QW3K77Y8F7SMDEPV4T", + "parent_id": null, + "user_id": null + } + }, + { + "entity_id": "sensor.thermostat_heat_voltage", + "state": "1.500", + "attributes": { + "state_class": "measurement", + "unit_of_measurement": "V", + "device_class": "voltage", + "friendly_name": "Thermostat (Heat) Voltage" + }, + "last_changed": "2025-02-06T16:47:44.912773+00:00", + "last_reported": "2025-02-06T16:47:44.912773+00:00", + "last_updated": "2025-02-06T16:47:44.912773+00:00", + "context": { + "id": "01JKE2J2RGH0MR1CYE11PTM3ZD", + "parent_id": null, + "user_id": null + } + }, + { + "entity_id": "sensor.thermostat_heat_temperature_3", + "state": "21.0", + "attributes": { + "state_class": "measurement", + "unit_of_measurement": "°C", + "device_class": "temperature", + "friendly_name": "Thermostat (Heat) Temperature" + }, + "last_changed": "2025-02-07T10:27:39.290444+00:00", + "last_reported": "2025-02-07T10:27:39.290444+00:00", + "last_updated": "2025-02-07T10:27:39.290444+00:00", + "context": { + "id": "01JKFZ6TMTHZ6M2PXPF0EG7XYK", + "parent_id": null, + "user_id": null + } + }, + { + "entity_id": "sensor.thermostat_heat_temperature", + "state": "20.5", + "attributes": { + "state_class": "measurement", + "unit_of_measurement": "°C", + "device_class": "temperature", + "friendly_name": "Thermostat (Heat) Temperature" + }, + "last_changed": "2025-02-07T10:27:39.264170+00:00", + "last_reported": "2025-02-07T10:27:39.264170+00:00", + "last_updated": "2025-02-07T10:27:39.264170+00:00", + "context": { + "id": "01JKFZ6TM0G52WD12QVKNNTB1H", + "parent_id": null, + "user_id": null + } + }, + { + "entity_id": "sensor.thermostat_heat_temperature_2", + "state": "17.0", + "attributes": { + "state_class": "measurement", + "unit_of_measurement": "°C", + "device_class": "temperature", + "friendly_name": "Thermostat (Heat) Temperature" + }, + "last_changed": "2025-02-07T10:27:39.267680+00:00", + "last_reported": "2025-02-07T10:27:39.267680+00:00", + "last_updated": "2025-02-07T10:27:39.267680+00:00", + "context": { + "id": "01JKFZ6TM3WAQ530NC1RYSDE3F", + "parent_id": null, + "user_id": null + } + }, { "entity_id": "person.luca", "state": "not_home", "attributes": { "editable": true, "id": "luca", - "device_trackers": ["device_tracker.lucas_iphone"], + "device_trackers": [ + "device_tracker.lucas_iphone" + ], "latitude": 43.73546856841873, "longitude": 7.414291906426737, "gps_accuracy": 14, @@ -8054,7 +8563,9 @@ "state": "Stationary", "attributes": { "Confidence": "High", - "Types": ["Stationary"], + "Types": [ + "Stationary" + ], "icon": "mdi:human-male", "friendly_name": "Luca’s iPhone Activity" }, @@ -8227,7 +8738,10 @@ "Inland Water": "N/A", "ISO Country Code": "MC", "Locality": "Monaco", - "Location": [43.73546856841873, 7.414291906426737], + "Location": [ + 43.73546856841873, + 7.414291906426737 + ], "Name": "25B Avenue Hector Otto", "Ocean": "N/A", "Postal Code": "98000", @@ -8318,7 +8832,9 @@ "state": "Stationary", "attributes": { "Confidence": "High", - "Types": ["Stationary"], + "Types": [ + "Stationary" + ], "icon": "mdi:human-male", "friendly_name": "Luca’s iPhone Activity" }, @@ -8624,7 +9140,10 @@ "Inland Water": "N/A", "ISO Country Code": "MC", "Locality": "Monaco", - "Location": [43.73546856841873, 7.414291906426737], + "Location": [ + 43.73546856841873, + 7.414291906426737 + ], "Name": "25B Avenue Hector Otto", "Ocean": "N/A", "Postal Code": "98000", @@ -8698,7 +9217,11 @@ "entity_id": "sensor.slzb_06p10_i_connection_mode", "state": "usb", "attributes": { - "options": ["eth", "wifi", "usb"], + "options": [ + "eth", + "wifi", + "usb" + ], "device_class": "enum", "friendly_name": "SLZB-06p10 I Connection mode" }, @@ -8715,7 +9238,10 @@ "entity_id": "sensor.slzb_06p10_i_firmware_channel", "state": "release", "attributes": { - "options": ["dev", "release"], + "options": [ + "dev", + "release" + ], "device_class": "enum", "friendly_name": "SLZB-06p10 I Firmware channel" }, @@ -8732,7 +9258,11 @@ "entity_id": "sensor.slzb_06p10_i_zigbee_type", "state": "coordinator", "attributes": { - "options": ["coordinator", "router", "thread"], + "options": [ + "coordinator", + "router", + "thread" + ], "device_class": "enum", "friendly_name": "SLZB-06p10 I Zigbee type" }, @@ -8933,7 +9463,11 @@ "entity_id": "sensor.slzb_06p10_ii_connection_mode", "state": "usb", "attributes": { - "options": ["eth", "wifi", "usb"], + "options": [ + "eth", + "wifi", + "usb" + ], "device_class": "enum", "friendly_name": "SLZB-06p10 II Connection mode" }, @@ -8950,7 +9484,10 @@ "entity_id": "sensor.slzb_06p10_ii_firmware_channel", "state": "release", "attributes": { - "options": ["dev", "release"], + "options": [ + "dev", + "release" + ], "device_class": "enum", "friendly_name": "SLZB-06p10 II Firmware channel" }, @@ -8967,7 +9504,11 @@ "entity_id": "sensor.slzb_06p10_ii_zigbee_type", "state": "coordinator", "attributes": { - "options": ["coordinator", "router", "thread"], + "options": [ + "coordinator", + "router", + "thread" + ], "device_class": "enum", "friendly_name": "SLZB-06p10 II Zigbee type" }, @@ -9445,16 +9986,34 @@ "max_color_temp_kelvin": 6500, "min_mireds": 153, "max_mireds": 333, - "effect_list": ["Off", "Meteor Shower", "Gradual Change", "Flash"], - "supported_color_modes": ["color_temp", "rgb"], + "effect_list": [ + "Off", + "Meteor Shower", + "Gradual Change", + "Flash" + ], + "supported_color_modes": [ + "color_temp", + "rgb" + ], "effect": "Off", "color_mode": "rgb", "brightness": 255, "color_temp_kelvin": null, "color_temp": null, - "hs_color": [306.048, 98.413], - "rgb_color": [252, 4, 227], - "xy_color": [0.419, 0.17], + "hs_color": [ + 306.048, + 98.413 + ], + "rgb_color": [ + 252, + 4, + 227 + ], + "xy_color": [ + 0.419, + 0.17 + ], "friendly_name": "Bulb Gen1", "supported_features": 36 }, @@ -9487,7 +10046,14 @@ "entity_id": "event.my_shelly_dimmer_1pm_pro_input_0", "state": "unknown", "attributes": { - "event_types": ["single_push", "btn_down", "double_push", "long_push", "btn_up", "triple_push"], + "event_types": [ + "single_push", + "btn_down", + "double_push", + "long_push", + "btn_up", + "triple_push" + ], "event_type": null, "device_class": "button", "friendly_name": "Dimmer 1PM Pro Input 0" @@ -9505,7 +10071,14 @@ "entity_id": "event.my_shelly_dimmer_1pm_pro_input_1", "state": "unknown", "attributes": { - "event_types": ["single_push", "btn_down", "double_push", "long_push", "btn_up", "triple_push"], + "event_types": [ + "single_push", + "btn_down", + "double_push", + "long_push", + "btn_up", + "triple_push" + ], "event_type": null, "device_class": "button", "friendly_name": "Dimmer 1PM Pro Input 1" @@ -9523,7 +10096,9 @@ "entity_id": "light.my_shelly_dimmer_1pm_pro_light_0", "state": "on", "attributes": { - "supported_color_modes": ["brightness"], + "supported_color_modes": [ + "brightness" + ], "color_mode": "brightness", "brightness": 255, "friendly_name": "Dimmer 1PM Pro", @@ -9692,7 +10267,9 @@ "entity_id": "light.light_on_off_light", "state": "on", "attributes": { - "supported_color_modes": ["onoff"], + "supported_color_modes": [ + "onoff" + ], "color_mode": "onoff", "friendly_name": "Light (on/off) Light", "supported_features": 0 @@ -9852,7 +10429,14 @@ "entity_id": "sensor.air_quality_sensor_air_quality", "state": "poor", "attributes": { - "options": ["extremely_poor", "very_poor", "poor", "fair", "good", "moderate"], + "options": [ + "extremely_poor", + "very_poor", + "poor", + "fair", + "good", + "moderate" + ], "device_class": "enum", "friendly_name": "Air quality sensor Air quality" }, @@ -9939,12 +10523,24 @@ "entity_id": "light.light_hs_light", "state": "on", "attributes": { - "supported_color_modes": ["hs"], + "supported_color_modes": [ + "hs" + ], "color_mode": "hs", "brightness": 221, - "hs_color": [0, 50.394], - "rgb_color": [255, 126, 126], - "xy_color": [0.528, 0.313], + "hs_color": [ + 0, + 50.394 + ], + "rgb_color": [ + 255, + 126, + 126 + ], + "xy_color": [ + 0.528, + 0.313 + ], "friendly_name": "Light (HS) Light", "supported_features": 32 }, @@ -9996,7 +10592,9 @@ "entity_id": "light.dimmer_light", "state": "on", "attributes": { - "supported_color_modes": ["brightness"], + "supported_color_modes": [ + "brightness" + ], "color_mode": "brightness", "brightness": 221, "friendly_name": "Dimmer Light", @@ -10086,7 +10684,12 @@ "entity_id": "fan.fan_fan", "state": "on", "attributes": { - "preset_modes": ["low", "medium", "high", "auto"], + "preset_modes": [ + "low", + "medium", + "high", + "auto" + ], "percentage": 30, "percentage_step": 1, "preset_mode": "auto", @@ -10106,7 +10709,12 @@ "entity_id": "fan.fan_fan", "state": "on", "attributes": { - "preset_modes": ["low", "medium", "high", "auto"], + "preset_modes": [ + "low", + "medium", + "high", + "auto" + ], "percentage": 30, "percentage_step": 1, "preset_mode": "a", @@ -10126,7 +10734,12 @@ "entity_id": "fan.fan_fan", "state": "on", "attributes": { - "preset_modes": ["low", "medium", "high", "auto"], + "preset_modes": [ + "low", + "medium", + "high", + "auto" + ], "percentage": 30, "percentage_step": 1, "preset_mode": "abcd", @@ -10166,14 +10779,26 @@ "max_color_temp_kelvin": 6802, "min_mireds": 147, "max_mireds": 500, - "supported_color_modes": ["color_temp"], + "supported_color_modes": [ + "color_temp" + ], "color_mode": "color_temp", "brightness": 221, "color_temp_kelvin": 4000, "color_temp": 250, - "hs_color": [26.812, 34.87], - "rgb_color": [255, 205, 166], - "xy_color": [0.421, 0.364], + "hs_color": [ + 26.812, + 34.87 + ], + "rgb_color": [ + 255, + 205, + 166 + ], + "xy_color": [ + 0.421, + 0.364 + ], "friendly_name": "Light (CT) Light", "supported_features": 32 }, @@ -10261,12 +10886,24 @@ "entity_id": "light.light_xy_light", "state": "on", "attributes": { - "supported_color_modes": ["xy"], + "supported_color_modes": [ + "xy" + ], "color_mode": "xy", "brightness": 221, - "hs_color": [0, 100], - "rgb_color": [255, 0, 0], - "xy_color": [0.700592, 0.299286], + "hs_color": [ + 0, + 100 + ], + "rgb_color": [ + 255, + 0, + 0 + ], + "xy_color": [ + 0.700592, + 0.299286 + ], "friendly_name": "Light (XY) Light", "supported_features": 32 }, @@ -10318,7 +10955,12 @@ "entity_id": "climate.thermostat_thermostat", "state": "heat_cool", "attributes": { - "hvac_modes": ["off", "heat", "cool", "heat_cool"], + "hvac_modes": [ + "off", + "heat", + "cool", + "heat_cool" + ], "min_temp": 7, "max_temp": 50, "current_temperature": 19, @@ -10341,7 +10983,12 @@ "entity_id": "climate.thermostat_thermostat", "state": "heat", "attributes": { - "hvac_modes": ["off", "heat", "cool", "heat_cool"], + "hvac_modes": [ + "off", + "heat", + "cool", + "heat_cool" + ], "min_temp": 7, "max_temp": 50, "current_temperature": 20, @@ -10364,7 +11011,12 @@ "entity_id": "climate.thermostat_thermostat", "state": "cool", "attributes": { - "hvac_modes": ["off", "heat", "cool", "heat_cool"], + "hvac_modes": [ + "off", + "heat", + "cool", + "heat_cool" + ], "min_temp": 7, "max_temp": 50, "current_temperature": 20, @@ -10387,7 +11039,12 @@ "entity_id": "climate.thermostat_thermostat", "state": "heat_cool", "attributes": { - "hvac_modes": ["off", "heat", "cool", "heat_cool"], + "hvac_modes": [ + "off", + "heat", + "cool", + "heat_cool" + ], "min_temp": 7, "max_temp": 50, "current_temperature": 20, @@ -10498,14 +11155,28 @@ "max_color_temp_kelvin": 6802, "min_mireds": 147, "max_mireds": 500, - "supported_color_modes": ["color_temp", "hs", "xy"], + "supported_color_modes": [ + "color_temp", + "hs", + "xy" + ], "color_mode": "hs", "brightness": 221, "color_temp_kelvin": null, "color_temp": null, - "hs_color": [0, 50.394], - "rgb_color": [255, 126, 126], - "xy_color": [0.528, 0.313], + "hs_color": [ + 0, + 50.394 + ], + "rgb_color": [ + 255, + 126, + 126 + ], + "xy_color": [ + 0.528, + 0.313 + ], "friendly_name": "Light (XY, HS and CT) Light", "supported_features": 32 }, @@ -11300,8 +11971,14 @@ "scene" ], "config_dir": "/config", - "whitelist_external_dirs": ["/media", "/config/www"], - "allowlist_external_dirs": ["/media", "/config/www"], + "whitelist_external_dirs": [ + "/media", + "/config/www" + ], + "allowlist_external_dirs": [ + "/media", + "/config/www" + ], "allowlist_external_urls": [], "version": "2024.10.4", "config_source": "storage", @@ -11381,7 +12058,9 @@ "description": "Generic action to turn devices off under any domain.", "fields": {}, "target": { - "entity": [{}] + "entity": [ + {} + ] } }, "turn_on": { @@ -11389,7 +12068,9 @@ "description": "Generic action to turn devices on under any domain.", "fields": {}, "target": { - "entity": [{}] + "entity": [ + {} + ] } }, "toggle": { @@ -11397,7 +12078,9 @@ "description": "Generic action to toggle devices on/off under any domain.", "fields": {}, "target": { - "entity": [{}] + "entity": [ + {} + ] } }, "stop": { @@ -11503,8 +12186,12 @@ } }, "target": { - "entity": [{}], - "device": [{}] + "entity": [ + {} + ], + "device": [ + {} + ] } }, "reload_all": { @@ -11521,7 +12208,14 @@ "level": { "selector": { "select": { - "options": ["debug", "info", "warning", "error", "fatal", "critical"], + "options": [ + "debug", + "info", + "warning", + "error", + "fatal", + "critical" + ], "translation_key": "level" } }, @@ -11559,7 +12253,13 @@ "default": "error", "selector": { "select": { - "options": ["debug", "info", "warning", "error", "critical"], + "options": [ + "debug", + "info", + "warning", + "error", + "critical" + ], "translation_key": "level" } }, @@ -11604,7 +12304,10 @@ "default": "light", "selector": { "select": { - "options": ["dark", "light"], + "options": [ + "dark", + "light" + ], "translation_key": "mode" } }, @@ -11862,7 +12565,11 @@ "description": "Exclude the Home Assistant database file from backup" }, "addons": { - "example": ["core_ssh", "core_samba", "core_mosquitto"], + "example": [ + "core_ssh", + "core_samba", + "core_mosquitto" + ], "selector": { "object": null }, @@ -11870,7 +12577,10 @@ "description": "List of add-ons to include in the backup. Use the name slug of the add-on." }, "folders": { - "example": ["homeassistant", "share"], + "example": [ + "homeassistant", + "share" + ], "selector": { "object": null }, @@ -11953,7 +12663,10 @@ "description": "Restores Home Assistant." }, "folders": { - "example": ["homeassistant", "share"], + "example": [ + "homeassistant", + "share" + ], "selector": { "object": null }, @@ -11961,7 +12674,11 @@ "description": "List of directories to include in the backup." }, "addons": { - "example": ["core_ssh", "core_samba", "core_mosquitto"], + "example": [ + "core_ssh", + "core_samba", + "core_mosquitto" + ], "selector": { "object": null }, @@ -12005,7 +12722,9 @@ "target": { "entity": [ { - "domain": ["update"] + "domain": [ + "update" + ] } ] } @@ -12017,7 +12736,9 @@ "target": { "entity": [ { - "domain": ["update"] + "domain": [ + "update" + ] } ] } @@ -12029,7 +12750,9 @@ "target": { "entity": [ { - "domain": ["update"] + "domain": [ + "update" + ] } ] } @@ -12150,7 +12873,9 @@ "target": { "entity": [ { - "domain": ["tts"] + "domain": [ + "tts" + ] } ] } @@ -12275,7 +13000,9 @@ "entity": [ { "integration": "homeassistant", - "domain": ["scene"] + "domain": [ + "scene" + ] } ] } @@ -12299,7 +13026,9 @@ "target": { "entity": [ { - "domain": ["scene"] + "domain": [ + "scene" + ] } ] } @@ -12332,7 +13061,9 @@ "target": { "entity": [ { - "domain": ["input_number"] + "domain": [ + "input_number" + ] } ] } @@ -12344,7 +13075,9 @@ "target": { "entity": [ { - "domain": ["input_number"] + "domain": [ + "input_number" + ] } ] } @@ -12356,7 +13089,9 @@ "target": { "entity": [ { - "domain": ["input_number"] + "domain": [ + "input_number" + ] } ] } @@ -12375,7 +13110,9 @@ "target": { "entity": [ { - "domain": ["input_boolean"] + "domain": [ + "input_boolean" + ] } ] } @@ -12387,7 +13124,9 @@ "target": { "entity": [ { - "domain": ["input_boolean"] + "domain": [ + "input_boolean" + ] } ] } @@ -12399,7 +13138,9 @@ "target": { "entity": [ { - "domain": ["input_boolean"] + "domain": [ + "input_boolean" + ] } ] } @@ -12418,7 +13159,9 @@ "target": { "entity": [ { - "domain": ["input_select"] + "domain": [ + "input_select" + ] } ] } @@ -12430,7 +13173,9 @@ "target": { "entity": [ { - "domain": ["input_select"] + "domain": [ + "input_select" + ] } ] } @@ -12451,7 +13196,9 @@ "target": { "entity": [ { - "domain": ["input_select"] + "domain": [ + "input_select" + ] } ] } @@ -12473,7 +13220,9 @@ "target": { "entity": [ { - "domain": ["input_select"] + "domain": [ + "input_select" + ] } ] } @@ -12494,7 +13243,9 @@ "target": { "entity": [ { - "domain": ["input_select"] + "domain": [ + "input_select" + ] } ] } @@ -12518,7 +13269,9 @@ "target": { "entity": [ { - "domain": ["input_select"] + "domain": [ + "input_select" + ] } ] } @@ -12541,7 +13294,9 @@ "target": { "entity": [ { - "domain": ["automation"] + "domain": [ + "automation" + ] } ] } @@ -12553,7 +13308,9 @@ "target": { "entity": [ { - "domain": ["automation"] + "domain": [ + "automation" + ] } ] } @@ -12565,7 +13322,9 @@ "target": { "entity": [ { - "domain": ["automation"] + "domain": [ + "automation" + ] } ] } @@ -12586,7 +13345,9 @@ "target": { "entity": [ { - "domain": ["automation"] + "domain": [ + "automation" + ] } ] } @@ -12619,7 +13380,9 @@ "target": { "entity": [ { - "domain": ["timer"] + "domain": [ + "timer" + ] } ] } @@ -12631,7 +13394,9 @@ "target": { "entity": [ { - "domain": ["timer"] + "domain": [ + "timer" + ] } ] } @@ -12643,7 +13408,9 @@ "target": { "entity": [ { - "domain": ["timer"] + "domain": [ + "timer" + ] } ] } @@ -12655,7 +13422,9 @@ "target": { "entity": [ { - "domain": ["timer"] + "domain": [ + "timer" + ] } ] } @@ -12678,7 +13447,9 @@ "target": { "entity": [ { - "domain": ["timer"] + "domain": [ + "timer" + ] } ] } @@ -12704,7 +13475,9 @@ "target": { "entity": [ { - "domain": ["script"] + "domain": [ + "script" + ] } ] } @@ -12716,7 +13489,9 @@ "target": { "entity": [ { - "domain": ["script"] + "domain": [ + "script" + ] } ] } @@ -12728,7 +13503,9 @@ "target": { "entity": [ { - "domain": ["script"] + "domain": [ + "script" + ] } ] } @@ -12747,7 +13524,9 @@ "target": { "entity": [ { - "domain": ["input_button"] + "domain": [ + "input_button" + ] } ] } @@ -12909,7 +13688,9 @@ "target": { "entity": [ { - "domain": ["input_datetime"] + "domain": [ + "input_datetime" + ] } ] } @@ -13021,7 +13802,9 @@ "target": { "entity": [ { - "domain": ["counter"] + "domain": [ + "counter" + ] } ] } @@ -13033,7 +13816,9 @@ "target": { "entity": [ { - "domain": ["counter"] + "domain": [ + "counter" + ] } ] } @@ -13045,7 +13830,9 @@ "target": { "entity": [ { - "domain": ["counter"] + "domain": [ + "counter" + ] } ] } @@ -13070,7 +13857,9 @@ "target": { "entity": [ { - "domain": ["counter"] + "domain": [ + "counter" + ] } ] } @@ -13084,7 +13873,9 @@ "target": { "entity": [ { - "domain": ["button"] + "domain": [ + "button" + ] } ] } @@ -13098,8 +13889,12 @@ "target": { "entity": [ { - "domain": ["climate"], - "supported_features": [256] + "domain": [ + "climate" + ], + "supported_features": [ + 256 + ] } ] } @@ -13111,8 +13906,12 @@ "target": { "entity": [ { - "domain": ["climate"], - "supported_features": [128] + "domain": [ + "climate" + ], + "supported_features": [ + 128 + ] } ] } @@ -13124,8 +13923,13 @@ "target": { "entity": [ { - "domain": ["climate"], - "supported_features": [128, 256] + "domain": [ + "climate" + ], + "supported_features": [ + 128, + 256 + ] } ] } @@ -13137,7 +13941,15 @@ "hvac_mode": { "selector": { "select": { - "options": ["off", "auto", "cool", "dry", "fan_only", "heat_cool", "heat"], + "options": [ + "off", + "auto", + "cool", + "dry", + "fan_only", + "heat_cool", + "heat" + ], "translation_key": "hvac_mode" } }, @@ -13148,7 +13960,9 @@ "target": { "entity": [ { - "domain": ["climate"] + "domain": [ + "climate" + ] } ] } @@ -13170,8 +13984,12 @@ "target": { "entity": [ { - "domain": ["climate"], - "supported_features": [16] + "domain": [ + "climate" + ], + "supported_features": [ + 16 + ] } ] } @@ -13192,8 +14010,12 @@ "target": { "entity": [ { - "domain": ["climate"], - "supported_features": [64] + "domain": [ + "climate" + ], + "supported_features": [ + 64 + ] } ] } @@ -13204,7 +14026,9 @@ "fields": { "temperature": { "filter": { - "supported_features": [1] + "supported_features": [ + 1 + ] }, "selector": { "number": { @@ -13219,7 +14043,9 @@ }, "target_temp_high": { "filter": { - "supported_features": [2] + "supported_features": [ + 2 + ] }, "advanced": true, "selector": { @@ -13235,7 +14061,9 @@ }, "target_temp_low": { "filter": { - "supported_features": [2] + "supported_features": [ + 2 + ] }, "advanced": true, "selector": { @@ -13252,7 +14080,15 @@ "hvac_mode": { "selector": { "select": { - "options": ["off", "auto", "cool", "dry", "fan_only", "heat_cool", "heat"], + "options": [ + "off", + "auto", + "cool", + "dry", + "fan_only", + "heat_cool", + "heat" + ], "translation_key": "hvac_mode" } }, @@ -13263,8 +14099,13 @@ "target": { "entity": [ { - "domain": ["climate"], - "supported_features": [1, 2] + "domain": [ + "climate" + ], + "supported_features": [ + 1, + 2 + ] } ] } @@ -13289,8 +14130,12 @@ "target": { "entity": [ { - "domain": ["climate"], - "supported_features": [4] + "domain": [ + "climate" + ], + "supported_features": [ + 4 + ] } ] } @@ -13312,8 +14157,12 @@ "target": { "entity": [ { - "domain": ["climate"], - "supported_features": [8] + "domain": [ + "climate" + ], + "supported_features": [ + 8 + ] } ] } @@ -13335,8 +14184,12 @@ "target": { "entity": [ { - "domain": ["climate"], - "supported_features": [32] + "domain": [ + "climate" + ], + "supported_features": [ + 32 + ] } ] } @@ -13350,8 +14203,12 @@ "target": { "entity": [ { - "domain": ["cover"], - "supported_features": [1] + "domain": [ + "cover" + ], + "supported_features": [ + 1 + ] } ] } @@ -13363,8 +14220,12 @@ "target": { "entity": [ { - "domain": ["cover"], - "supported_features": [2] + "domain": [ + "cover" + ], + "supported_features": [ + 2 + ] } ] } @@ -13389,8 +14250,12 @@ "target": { "entity": [ { - "domain": ["cover"], - "supported_features": [4] + "domain": [ + "cover" + ], + "supported_features": [ + 4 + ] } ] } @@ -13402,8 +14267,12 @@ "target": { "entity": [ { - "domain": ["cover"], - "supported_features": [8] + "domain": [ + "cover" + ], + "supported_features": [ + 8 + ] } ] } @@ -13415,8 +14284,12 @@ "target": { "entity": [ { - "domain": ["cover"], - "supported_features": [3] + "domain": [ + "cover" + ], + "supported_features": [ + 3 + ] } ] } @@ -13428,8 +14301,12 @@ "target": { "entity": [ { - "domain": ["cover"], - "supported_features": [16] + "domain": [ + "cover" + ], + "supported_features": [ + 16 + ] } ] } @@ -13441,8 +14318,12 @@ "target": { "entity": [ { - "domain": ["cover"], - "supported_features": [32] + "domain": [ + "cover" + ], + "supported_features": [ + 32 + ] } ] } @@ -13454,8 +14335,12 @@ "target": { "entity": [ { - "domain": ["cover"], - "supported_features": [64] + "domain": [ + "cover" + ], + "supported_features": [ + 64 + ] } ] } @@ -13480,8 +14365,12 @@ "target": { "entity": [ { - "domain": ["cover"], - "supported_features": [128] + "domain": [ + "cover" + ], + "supported_features": [ + 128 + ] } ] } @@ -13493,8 +14382,12 @@ "target": { "entity": [ { - "domain": ["cover"], - "supported_features": [48] + "domain": [ + "cover" + ], + "supported_features": [ + 48 + ] } ] } @@ -13507,7 +14400,9 @@ "fields": { "percentage": { "filter": { - "supported_features": [1] + "supported_features": [ + 1 + ] }, "selector": { "number": { @@ -13522,7 +14417,9 @@ "preset_mode": { "example": "auto", "filter": { - "supported_features": [8] + "supported_features": [ + 8 + ] }, "selector": { "text": null @@ -13534,8 +14431,12 @@ "target": { "entity": [ { - "domain": ["fan"], - "supported_features": [32] + "domain": [ + "fan" + ], + "supported_features": [ + 32 + ] } ] } @@ -13547,8 +14448,12 @@ "target": { "entity": [ { - "domain": ["fan"], - "supported_features": [16] + "domain": [ + "fan" + ], + "supported_features": [ + 16 + ] } ] } @@ -13560,7 +14465,9 @@ "target": { "entity": [ { - "domain": ["fan"] + "domain": [ + "fan" + ] } ] } @@ -13586,8 +14493,12 @@ "target": { "entity": [ { - "domain": ["fan"], - "supported_features": [1] + "domain": [ + "fan" + ], + "supported_features": [ + 1 + ] } ] } @@ -13613,8 +14524,12 @@ "target": { "entity": [ { - "domain": ["fan"], - "supported_features": [1] + "domain": [ + "fan" + ], + "supported_features": [ + 1 + ] } ] } @@ -13635,8 +14550,12 @@ "target": { "entity": [ { - "domain": ["fan"], - "supported_features": [2] + "domain": [ + "fan" + ], + "supported_features": [ + 2 + ] } ] } @@ -13649,7 +14568,10 @@ "required": true, "selector": { "select": { - "options": ["forward", "reverse"], + "options": [ + "forward", + "reverse" + ], "translation_key": "direction" } }, @@ -13660,8 +14582,12 @@ "target": { "entity": [ { - "domain": ["fan"], - "supported_features": [4] + "domain": [ + "fan" + ], + "supported_features": [ + 4 + ] } ] } @@ -13686,8 +14612,12 @@ "target": { "entity": [ { - "domain": ["fan"], - "supported_features": [1] + "domain": [ + "fan" + ], + "supported_features": [ + 1 + ] } ] } @@ -13709,8 +14639,12 @@ "target": { "entity": [ { - "domain": ["fan"], - "supported_features": [8] + "domain": [ + "fan" + ], + "supported_features": [ + 8 + ] } ] } @@ -13723,7 +14657,9 @@ "fields": { "transition": { "filter": { - "supported_features": [32] + "supported_features": [ + 32 + ] }, "selector": { "number": { @@ -13738,7 +14674,13 @@ "rgb_color": { "filter": { "attribute": { - "supported_color_modes": ["hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "example": "[255, 100, 100]", @@ -13751,7 +14693,14 @@ "kelvin": { "filter": { "attribute": { - "supported_color_modes": ["color_temp", "hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "color_temp", + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "selector": { @@ -13767,7 +14716,15 @@ "brightness_pct": { "filter": { "attribute": { - "supported_color_modes": ["brightness", "color_temp", "hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "brightness", + "color_temp", + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "selector": { @@ -13783,7 +14740,15 @@ "brightness_step_pct": { "filter": { "attribute": { - "supported_color_modes": ["brightness", "color_temp", "hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "brightness", + "color_temp", + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "selector": { @@ -13798,7 +14763,9 @@ }, "effect": { "filter": { - "supported_features": [4] + "supported_features": [ + 4 + ] }, "selector": { "text": null @@ -13812,7 +14779,13 @@ "rgbw_color": { "filter": { "attribute": { - "supported_color_modes": ["hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "example": "[255, 100, 100, 50]", @@ -13823,7 +14796,13 @@ "rgbww_color": { "filter": { "attribute": { - "supported_color_modes": ["hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "example": "[255, 100, 100, 50, 70]", @@ -13834,7 +14813,13 @@ "color_name": { "filter": { "attribute": { - "supported_color_modes": ["hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "selector": { @@ -13996,7 +14981,13 @@ "hs_color": { "filter": { "attribute": { - "supported_color_modes": ["hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "example": "[300, 70]", @@ -14007,7 +14998,13 @@ "xy_color": { "filter": { "attribute": { - "supported_color_modes": ["hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "example": "[0.52, 0.43]", @@ -14018,7 +15015,14 @@ "color_temp": { "filter": { "attribute": { - "supported_color_modes": ["color_temp", "hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "color_temp", + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "selector": { @@ -14032,7 +15036,15 @@ "brightness": { "filter": { "attribute": { - "supported_color_modes": ["brightness", "color_temp", "hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "brightness", + "color_temp", + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "selector": { @@ -14045,7 +15057,15 @@ "brightness_step": { "filter": { "attribute": { - "supported_color_modes": ["brightness", "color_temp", "hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "brightness", + "color_temp", + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "selector": { @@ -14058,7 +15078,9 @@ "white": { "filter": { "attribute": { - "supported_color_modes": ["white"] + "supported_color_modes": [ + "white" + ] } }, "selector": { @@ -14076,7 +15098,9 @@ }, "flash": { "filter": { - "supported_features": [8] + "supported_features": [ + 8 + ] }, "selector": { "select": { @@ -14099,7 +15123,9 @@ "target": { "entity": [ { - "domain": ["light"] + "domain": [ + "light" + ] } ] } @@ -14110,7 +15136,9 @@ "fields": { "transition": { "filter": { - "supported_features": [32] + "supported_features": [ + 32 + ] }, "selector": { "number": { @@ -14127,7 +15155,9 @@ "fields": { "flash": { "filter": { - "supported_features": [8] + "supported_features": [ + 8 + ] }, "selector": { "select": { @@ -14150,7 +15180,9 @@ "target": { "entity": [ { - "domain": ["light"] + "domain": [ + "light" + ] } ] } @@ -14161,7 +15193,9 @@ "fields": { "transition": { "filter": { - "supported_features": [32] + "supported_features": [ + 32 + ] }, "selector": { "number": { @@ -14176,7 +15210,13 @@ "rgb_color": { "filter": { "attribute": { - "supported_color_modes": ["hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "example": "[255, 100, 100]", @@ -14189,7 +15229,14 @@ "kelvin": { "filter": { "attribute": { - "supported_color_modes": ["color_temp", "hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "color_temp", + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "selector": { @@ -14205,7 +15252,15 @@ "brightness_pct": { "filter": { "attribute": { - "supported_color_modes": ["brightness", "color_temp", "hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "brightness", + "color_temp", + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "selector": { @@ -14220,7 +15275,9 @@ }, "effect": { "filter": { - "supported_features": [4] + "supported_features": [ + 4 + ] }, "selector": { "text": null @@ -14234,7 +15291,13 @@ "rgbw_color": { "filter": { "attribute": { - "supported_color_modes": ["hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "example": "[255, 100, 100, 50]", @@ -14245,7 +15308,13 @@ "rgbww_color": { "filter": { "attribute": { - "supported_color_modes": ["hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "example": "[255, 100, 100, 50, 70]", @@ -14256,7 +15325,13 @@ "color_name": { "filter": { "attribute": { - "supported_color_modes": ["hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "selector": { @@ -14418,7 +15493,13 @@ "hs_color": { "filter": { "attribute": { - "supported_color_modes": ["hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "example": "[300, 70]", @@ -14429,7 +15510,13 @@ "xy_color": { "filter": { "attribute": { - "supported_color_modes": ["hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "example": "[0.52, 0.43]", @@ -14440,7 +15527,14 @@ "color_temp": { "filter": { "attribute": { - "supported_color_modes": ["color_temp", "hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "color_temp", + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "selector": { @@ -14454,7 +15548,15 @@ "brightness": { "filter": { "attribute": { - "supported_color_modes": ["brightness", "color_temp", "hs", "xy", "rgb", "rgbw", "rgbww"] + "supported_color_modes": [ + "brightness", + "color_temp", + "hs", + "xy", + "rgb", + "rgbw", + "rgbww" + ] } }, "selector": { @@ -14467,7 +15569,9 @@ "white": { "filter": { "attribute": { - "supported_color_modes": ["white"] + "supported_color_modes": [ + "white" + ] } }, "selector": { @@ -14485,7 +15589,9 @@ }, "flash": { "filter": { - "supported_features": [8] + "supported_features": [ + 8 + ] }, "selector": { "select": { @@ -14508,7 +15614,9 @@ "target": { "entity": [ { - "domain": ["light"] + "domain": [ + "light" + ] } ] } @@ -14531,7 +15639,9 @@ "target": { "entity": [ { - "domain": ["lock"] + "domain": [ + "lock" + ] } ] } @@ -14552,7 +15662,9 @@ "target": { "entity": [ { - "domain": ["lock"] + "domain": [ + "lock" + ] } ] } @@ -14573,8 +15685,12 @@ "target": { "entity": [ { - "domain": ["lock"], - "supported_features": [1] + "domain": [ + "lock" + ], + "supported_features": [ + 1 + ] } ] } @@ -14597,7 +15713,9 @@ "target": { "entity": [ { - "domain": ["number"] + "domain": [ + "number" + ] } ] } @@ -14611,7 +15729,9 @@ "target": { "entity": [ { - "domain": ["select"] + "domain": [ + "select" + ] } ] } @@ -14623,7 +15743,9 @@ "target": { "entity": [ { - "domain": ["select"] + "domain": [ + "select" + ] } ] } @@ -14644,7 +15766,9 @@ "target": { "entity": [ { - "domain": ["select"] + "domain": [ + "select" + ] } ] } @@ -14666,7 +15790,9 @@ "target": { "entity": [ { - "domain": ["select"] + "domain": [ + "select" + ] } ] } @@ -14687,7 +15813,9 @@ "target": { "entity": [ { - "domain": ["select"] + "domain": [ + "select" + ] } ] } @@ -14701,7 +15829,9 @@ "target": { "entity": [ { - "domain": ["switch"] + "domain": [ + "switch" + ] } ] } @@ -14713,7 +15843,9 @@ "target": { "entity": [ { - "domain": ["switch"] + "domain": [ + "switch" + ] } ] } @@ -14725,7 +15857,9 @@ "target": { "entity": [ { - "domain": ["switch"] + "domain": [ + "switch" + ] } ] } @@ -14739,8 +15873,12 @@ "target": { "entity": [ { - "domain": ["valve"], - "supported_features": [1] + "domain": [ + "valve" + ], + "supported_features": [ + 1 + ] } ] } @@ -14752,8 +15890,12 @@ "target": { "entity": [ { - "domain": ["valve"], - "supported_features": [2] + "domain": [ + "valve" + ], + "supported_features": [ + 2 + ] } ] } @@ -14778,8 +15920,12 @@ "target": { "entity": [ { - "domain": ["valve"], - "supported_features": [4] + "domain": [ + "valve" + ], + "supported_features": [ + 4 + ] } ] } @@ -14791,8 +15937,12 @@ "target": { "entity": [ { - "domain": ["valve"], - "supported_features": [8] + "domain": [ + "valve" + ], + "supported_features": [ + 8 + ] } ] } @@ -14804,8 +15954,12 @@ "target": { "entity": [ { - "domain": ["valve"], - "supported_features": [3] + "domain": [ + "valve" + ], + "supported_features": [ + 3 + ] } ] } @@ -14834,7 +15988,9 @@ "target": { "entity": [ { - "domain": ["input_text"] + "domain": [ + "input_text" + ] } ] } @@ -14856,7 +16012,9 @@ }, "due_date": { "filter": { - "supported_features": [16] + "supported_features": [ + 16 + ] }, "example": "2023-11-17", "selector": { @@ -14867,7 +16025,9 @@ }, "due_datetime": { "filter": { - "supported_features": [32] + "supported_features": [ + 32 + ] }, "example": "2023-11-17 13:30:00", "selector": { @@ -14878,7 +16038,9 @@ }, "description": { "filter": { - "supported_features": [64] + "supported_features": [ + 64 + ] }, "example": "A more complete description of the to-do item than that provided by the summary.", "selector": { @@ -14891,8 +16053,12 @@ "target": { "entity": [ { - "domain": ["todo"], - "supported_features": [1] + "domain": [ + "todo" + ], + "supported_features": [ + 1 + ] } ] } @@ -14923,7 +16089,10 @@ "selector": { "select": { "translation_key": "status", - "options": ["needs_action", "completed"] + "options": [ + "needs_action", + "completed" + ] } }, "name": "Set status", @@ -14931,7 +16100,9 @@ }, "due_date": { "filter": { - "supported_features": [16] + "supported_features": [ + 16 + ] }, "example": "2023-11-17", "selector": { @@ -14942,7 +16113,9 @@ }, "due_datetime": { "filter": { - "supported_features": [32] + "supported_features": [ + 32 + ] }, "example": "2023-11-17 13:30:00", "selector": { @@ -14953,7 +16126,9 @@ }, "description": { "filter": { - "supported_features": [64] + "supported_features": [ + 64 + ] }, "example": "A more complete description of the to-do item than that provided by the summary.", "selector": { @@ -14966,8 +16141,12 @@ "target": { "entity": [ { - "domain": ["todo"], - "supported_features": [4] + "domain": [ + "todo" + ], + "supported_features": [ + 4 + ] } ] } @@ -14988,8 +16167,12 @@ "target": { "entity": [ { - "domain": ["todo"], - "supported_features": [2] + "domain": [ + "todo" + ], + "supported_features": [ + 2 + ] } ] } @@ -15004,7 +16187,10 @@ "selector": { "select": { "translation_key": "status", - "options": ["needs_action", "completed"], + "options": [ + "needs_action", + "completed" + ], "multiple": true } }, @@ -15015,7 +16201,9 @@ "target": { "entity": [ { - "domain": ["todo"] + "domain": [ + "todo" + ] } ] }, @@ -15030,8 +16218,12 @@ "target": { "entity": [ { - "domain": ["todo"], - "supported_features": [2] + "domain": [ + "todo" + ], + "supported_features": [ + 2 + ] } ] } @@ -15056,7 +16248,9 @@ "text": null }, "filter": { - "supported_features": [1] + "supported_features": [ + 1 + ] }, "name": "Title", "description": "Title for your notification message." @@ -15065,7 +16259,9 @@ "target": { "entity": [ { - "domain": ["notify"] + "domain": [ + "notify" + ] } ] } @@ -15243,7 +16439,11 @@ "required": true, "selector": { "select": { - "options": ["daily", "hourly", "twice_daily"], + "options": [ + "daily", + "hourly", + "twice_daily" + ], "translation_key": "forecast_type" } }, @@ -15254,8 +16454,14 @@ "target": { "entity": [ { - "domain": ["weather"], - "supported_features": [1, 2, 4] + "domain": [ + "weather" + ], + "supported_features": [ + 1, + 2, + 4 + ] } ] }, @@ -15282,11 +16488,13 @@ "target": { "entity": [ { - "domain": ["text"] + "domain": [ + "text" + ] } ] } } } } -} +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index fcb8c72..e4375fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "matterbridge-hass", - "version": "0.0.8", + "version": "0.0.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "matterbridge-hass", - "version": "0.0.8", + "version": "0.0.9", "license": "Apache-2.0", "dependencies": { "node-ansi-logger": "3.0.0", @@ -17,7 +17,7 @@ "@eslint/js": "^9.19.0", "@types/eslint__js": "^8.42.3", "@types/jest": "^29.5.14", - "@types/node": "^22.13.0", + "@types/node": "^22.13.1", "@types/ws": "^8.5.14", "eslint": "^9.19.0", "eslint-config-prettier": "^10.0.1", @@ -27,7 +27,7 @@ "prettier": "^3.4.2", "ts-jest": "^29.2.5", "typescript": "^5.7.3", - "typescript-eslint": "^8.22.0" + "typescript-eslint": "^8.23.0" }, "engines": { "node": ">=18.0.0 <19.0.0 || >=20.0.0 <21.0.0 || >=22.0.0 <23.0.0" @@ -1430,9 +1430,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.13.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.0.tgz", - "integrity": "sha512-ClIbNe36lawluuvq3+YYhnIN2CELi+6q8NpnM7PYp4hBn/TatfboPgVSm2rwKRfnV2M+Ty9GWDFI64KEe+kysA==", + "version": "22.13.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz", + "integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==", "dev": true, "license": "MIT", "dependencies": { @@ -1474,21 +1474,21 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.22.0.tgz", - "integrity": "sha512-4Uta6REnz/xEJMvwf72wdUnC3rr4jAQf5jnTkeRQ9b6soxLxhDEbS/pfMPoJLDfFPNVRdryqWUIV/2GZzDJFZw==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.23.0.tgz", + "integrity": "sha512-vBz65tJgRrA1Q5gWlRfvoH+w943dq9K1p1yDBY2pc+a1nbBLZp7fB9+Hk8DaALUbzjqlMfgaqlVPT1REJdkt/w==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.22.0", - "@typescript-eslint/type-utils": "8.22.0", - "@typescript-eslint/utils": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0", + "@typescript-eslint/scope-manager": "8.23.0", + "@typescript-eslint/type-utils": "8.23.0", + "@typescript-eslint/utils": "8.23.0", + "@typescript-eslint/visitor-keys": "8.23.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.0.0" + "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1504,16 +1504,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.22.0.tgz", - "integrity": "sha512-MqtmbdNEdoNxTPzpWiWnqNac54h8JDAmkWtJExBVVnSrSmi9z+sZUt0LfKqk9rjqmKOIeRhO4fHHJ1nQIjduIQ==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.23.0.tgz", + "integrity": "sha512-h2lUByouOXFAlMec2mILeELUbME5SZRN/7R9Cw2RD2lRQQY08MWMM+PmVVKKJNK1aIwqTo9t/0CvOxwPbRIE2Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.22.0", - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/typescript-estree": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0", + "@typescript-eslint/scope-manager": "8.23.0", + "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/typescript-estree": "8.23.0", + "@typescript-eslint/visitor-keys": "8.23.0", "debug": "^4.3.4" }, "engines": { @@ -1529,14 +1529,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.22.0.tgz", - "integrity": "sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.23.0.tgz", + "integrity": "sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0" + "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/visitor-keys": "8.23.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1547,16 +1547,16 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.22.0.tgz", - "integrity": "sha512-NzE3aB62fDEaGjaAYZE4LH7I1MUwHooQ98Byq0G0y3kkibPJQIXVUspzlFOmOfHhiDLwKzMlWxaNv+/qcZurJA==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.23.0.tgz", + "integrity": "sha512-iIuLdYpQWZKbiH+RkCGc6iu+VwscP5rCtQ1lyQ7TYuKLrcZoeJVpcLiG8DliXVkUxirW/PWlmS+d6yD51L9jvA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.22.0", - "@typescript-eslint/utils": "8.22.0", + "@typescript-eslint/typescript-estree": "8.23.0", + "@typescript-eslint/utils": "8.23.0", "debug": "^4.3.4", - "ts-api-utils": "^2.0.0" + "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1571,9 +1571,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz", - "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.23.0.tgz", + "integrity": "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==", "dev": true, "license": "MIT", "engines": { @@ -1585,20 +1585,20 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz", - "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.23.0.tgz", + "integrity": "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0", + "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/visitor-keys": "8.23.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^2.0.0" + "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1638,16 +1638,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.22.0.tgz", - "integrity": "sha512-T8oc1MbF8L+Bk2msAvCUzjxVB2Z2f+vXYfcucE2wOmYs7ZUwco5Ep0fYZw8quNwOiw9K8GYVL+Kgc2pETNTLOg==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.23.0.tgz", + "integrity": "sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.22.0", - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/typescript-estree": "8.22.0" + "@typescript-eslint/scope-manager": "8.23.0", + "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/typescript-estree": "8.23.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1662,13 +1662,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.22.0.tgz", - "integrity": "sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz", + "integrity": "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/types": "8.23.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -2030,9 +2030,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001696", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001696.tgz", - "integrity": "sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ==", + "version": "1.0.30001698", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001698.tgz", + "integrity": "sha512-xJ3km2oiG/MbNU8G6zIq6XRZ6HtAOVXsbOrP/blGazi52kc5Yy7b6sDA5O+FbROzRrV7BSTllLHuNvmawYUJjw==", "dev": true, "funding": [ { @@ -2291,9 +2291,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.90", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.90.tgz", - "integrity": "sha512-C3PN4aydfW91Natdyd449Kw+BzhLmof6tzy5W1pFC5SpQxVXT+oyiyOG9AgYYSN9OdA/ik3YkCrpwqI8ug5Tug==", + "version": "1.5.96", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.96.tgz", + "integrity": "sha512-8AJUW6dh75Fm/ny8+kZKJzI1pgoE8bKLZlzDU2W1ENd+DXKJrx7I7l9hb8UWR4ojlnb5OlixMt00QWiYJoVw1w==", "dev": true, "license": "ISC" }, @@ -3001,9 +3001,9 @@ } }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4678,9 +4678,9 @@ } }, "node_modules/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "dev": true, "license": "ISC", "bin": { @@ -5061,15 +5061,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.22.0.tgz", - "integrity": "sha512-Y2rj210FW1Wb6TWXzQc5+P+EWI9/zdS57hLEc0gnyuvdzWo8+Y8brKlbj0muejonhMI/xAZCnZZwjbIfv1CkOw==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.23.0.tgz", + "integrity": "sha512-/LBRo3HrXr5LxmrdYSOCvoAMm7p2jNizNfbIpCgvG4HMsnoprRUOce/+8VJ9BDYWW68rqIENE/haVLWPeFZBVQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.22.0", - "@typescript-eslint/parser": "8.22.0", - "@typescript-eslint/utils": "8.22.0" + "@typescript-eslint/eslint-plugin": "8.23.0", + "@typescript-eslint/parser": "8.23.0", + "@typescript-eslint/utils": "8.23.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" diff --git a/package.json b/package.json index 8f58dc1..c63ca90 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matterbridge-hass", - "version": "0.0.8", + "version": "0.0.9", "description": "Matterbridge hass plugin", "author": "https://github.com/Luligu", "license": "Apache-2.0", @@ -99,7 +99,7 @@ "@eslint/js": "^9.19.0", "@types/eslint__js": "^8.42.3", "@types/jest": "^29.5.14", - "@types/node": "^22.13.0", + "@types/node": "^22.13.1", "@types/ws": "^8.5.14", "eslint": "^9.19.0", "eslint-config-prettier": "^10.0.1", @@ -109,6 +109,6 @@ "prettier": "^3.4.2", "ts-jest": "^29.2.5", "typescript": "^5.7.3", - "typescript-eslint": "^8.22.0" + "typescript-eslint": "^8.23.0" } -} \ No newline at end of file +} diff --git a/src/converters.ts b/src/converters.ts index 2169238..da1fdb9 100644 --- a/src/converters.ts +++ b/src/converters.ts @@ -72,13 +72,16 @@ export const hassUpdateStateConverter: { domain: string; state: string; clusterI { domain: 'cover', state: 'opening', clusterId: WindowCovering.Cluster.id, attribute: 'operationalStatus', value: { global: WindowCovering.MovementStatus.Opening, lift: WindowCovering.MovementStatus.Opening, tilt: 0 } }, { domain: 'cover', state: 'open', clusterId: WindowCovering.Cluster.id, attribute: 'operationalStatus', value: { global: WindowCovering.MovementStatus.Stopped, lift: WindowCovering.MovementStatus.Stopped, tilt: 0 } }, - { domain: 'cover', state: 'close', clusterId: WindowCovering.Cluster.id, attribute: 'operationalStatus', value: { global: WindowCovering.MovementStatus.Stopped, lift: WindowCovering.MovementStatus.Stopped, tilt: 0 } }, + { domain: 'cover', state: 'closed', clusterId: WindowCovering.Cluster.id, attribute: 'operationalStatus', value: { global: WindowCovering.MovementStatus.Stopped, lift: WindowCovering.MovementStatus.Stopped, tilt: 0 } }, { domain: 'cover', state: 'closing', clusterId: WindowCovering.Cluster.id, attribute: 'operationalStatus', value: { global: WindowCovering.MovementStatus.Closing, lift: WindowCovering.MovementStatus.Closing, tilt: 0 } }, { domain: 'climate', state: 'off', clusterId: Thermostat.Cluster.id, attribute: 'systemMode', value: Thermostat.SystemMode.Off }, { domain: 'climate', state: 'heat', clusterId: Thermostat.Cluster.id, attribute: 'systemMode', value: Thermostat.SystemMode.Heat }, { domain: 'climate', state: 'cool', clusterId: Thermostat.Cluster.id, attribute: 'systemMode', value: Thermostat.SystemMode.Cool }, { domain: 'climate', state: 'heat_cool', clusterId: Thermostat.Cluster.id, attribute: 'systemMode', value: Thermostat.SystemMode.Auto }, + + { domain: 'input_boolean', state: 'on', clusterId: OnOff.Cluster.id, attribute: 'onOff', value: true }, + { domain: 'input_boolean', state: 'off', clusterId: OnOff.Cluster.id, attribute: 'onOff', value: false }, ]; // Update Home Assistant attributes to Matterbridge device attributes diff --git a/src/homeAssistant.ts b/src/homeAssistant.ts index f4f552b..bdd5503 100644 --- a/src/homeAssistant.ts +++ b/src/homeAssistant.ts @@ -61,7 +61,7 @@ export interface HassEntity { categories: object; // Categories of the entity config_entry_id: string; // The config entry this entity belongs to created_at: string; // Timestamp of when the entity was created - device_id: string; // The ID of the device this entity is associated with + device_id: string | null; // The ID of the device this entity is associated with disabled_by: string | null; // Whether the entity is disabled and by whom entity_category: string | null; // The category of the entity entity_id: string; // Unique ID of the entity (e.g., "light.living_room") @@ -108,8 +108,8 @@ export interface HassState { */ export interface HassDataEvent { entity_id: string; - old_state: HassState; - new_state: HassState; + old_state: HassState | null; + new_state: HassState | null; } /** @@ -179,7 +179,7 @@ interface HomeAssistantEventEmitter { error: [error: { code: string; message: string } | WebSocket.ErrorEvent | undefined]; devices: [devices: HassDevice[]]; entities: [entities: HassEntity[]]; - event: [deviceId: string, entityId: string, old_state: HassState, new_state: HassState]; + event: [deviceId: string | null, entityId: string, old_state: HassState, new_state: HassState]; call_service: []; pong: []; } @@ -376,18 +376,16 @@ export class HomeAssistant extends EventEmitter { return; } if (response.id === this.eventsSubscribeId && response.event && response.event.event_type === 'state_changed') { + // this.log.debug(`Event ${CYAN}${response.event.event_type}${db} received id ${CYAN}${response.id}${db}`); const entity = this.hassEntities.get(response.event.data.entity_id); if (!entity) { this.log.debug(`Entity id ${CYAN}${response.event.data.entity_id}${db} not found processing event`); return; } - const device = this.hassDevices.get(entity.device_id); - if (!device) { - this.log.debug(`Device id ${CYAN}${entity.device_id}${db} not found processing event:`); - return; + if (response.event.data.old_state && response.event.data.new_state) { + this.hassStates.set(response.event.data.new_state.entity_id, response.event.data.new_state); + this.emit('event', entity.device_id, entity.entity_id, response.event.data.old_state, response.event.data.new_state); } - this.hassStates.set(response.event.data.new_state.entity_id, response.event.data.new_state); - this.emit('event', device.id, entity.entity_id, response.event.data.old_state, response.event.data.new_state); } else if (response.id === this.eventsSubscribeId && response.event && response.event.event_type === 'call_service') { this.log.debug(`Event ${CYAN}${response.event.event_type}${db} received id ${CYAN}${response.id}${db}`); this.emit('call_service'); diff --git a/src/index.test.ts b/src/index.test.ts index 60ccc3d..51e09a1 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -32,7 +32,7 @@ describe('initializePlugin', () => { matterbridgeDirectory: './jest/matterbridge', matterbridgePluginDirectory: './jest/plugins', systemInformation: { ipv4Address: undefined, ipv6Address: undefined, osRelease: 'xx.xx.xx.xx.xx.xx', nodeVersion: '22.1.10' }, - matterbridgeVersion: '2.1.0', + matterbridgeVersion: '2.1.4', edge: true, log: mockLog, getDevices: jest.fn(() => { @@ -75,9 +75,10 @@ describe('initializePlugin', () => { // console.error('Mocked console.log', args); }); - it('should return an instance of HomeAssistantPlatform', () => { + it('should return an instance of HomeAssistantPlatform', async () => { const platform = initializePlugin(mockMatterbridge, mockLog, mockConfig); expect(platform).toBeInstanceOf(HomeAssistantPlatform); platform.onShutdown(); + await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait for ha.close() to complete }); }); diff --git a/src/platform.test.ts b/src/platform.test.ts index 705a1d7..74f2b34 100644 --- a/src/platform.test.ts +++ b/src/platform.test.ts @@ -50,7 +50,7 @@ describe('HassPlatform', () => { matterbridgeDirectory: './jest/matterbridge', matterbridgePluginDirectory: './jest/plugins', systemInformation: { ipv4Address: undefined, ipv6Address: undefined, osRelease: 'xx.xx.xx.xx.xx.xx', nodeVersion: '22.1.10' }, - matterbridgeVersion: '2.1.0', + matterbridgeVersion: '2.1.4', edge: true, log: mockLog, getDevices: jest.fn(() => { @@ -204,7 +204,7 @@ describe('HassPlatform', () => { it('should not initialize platform with wrong version', () => { mockMatterbridge.matterbridgeVersion = '1.5.5'; expect(() => new HomeAssistantPlatform(mockMatterbridge, mockLog, mockConfig)).toThrow(); - mockMatterbridge.matterbridgeVersion = '2.1.0'; + mockMatterbridge.matterbridgeVersion = '2.1.4'; }); it('should validate with white and black list', () => { @@ -804,7 +804,7 @@ describe('HassPlatform', () => { let device: HassDevice | undefined; (mockData.devices as HassDevice[]).forEach((d) => { - if (d.name === 'Thermostat') device = d; + if (d.name === 'Thermostat (Heat)') device = d; }); expect(device).toBeDefined(); if (!device) return; @@ -816,7 +816,7 @@ describe('HassPlatform', () => { expect(mockLog.info).toHaveBeenCalledWith(`Starting platform ${idn}${mockConfig.name}${rs}${nf}: Test reason`); expect(mockLog.info).toHaveBeenCalledWith(`Creating device ${idn}${device.name}${rs}${nf} id ${CYAN}${device.id}${nf}`); - expect(mockLog.debug).toHaveBeenCalledWith(`- subscribe: ${CYAN}Thermostat${db}:${CYAN}systemMode${db} check ${CYAN}true${db}`); + // expect(mockLog.debug).toHaveBeenCalledWith(`- subscribe: ${CYAN}Thermostat (Heat)${db}:${CYAN}systemMode${db} check ${CYAN}true${db}`); expect(mockLog.debug).toHaveBeenCalledWith(`Registering device ${dn}${device.name}${db}...`); expect(mockMatterbridge.addBridgedEndpoint).toHaveBeenCalled(); @@ -874,7 +874,7 @@ describe('HassPlatform', () => { expect(mockLog.info).toHaveBeenCalledWith(`Starting platform ${idn}${mockConfig.name}${rs}${nf}: Test reason`); expect(mockLog.info).toHaveBeenCalledWith(`Creating device ${idn}${switchDevice.name}${rs}${nf} id ${CYAN}${switchDevice.id}${nf}`); expect(mockLog.debug).toHaveBeenCalledWith(`Registering device ${dn}${switchDevice.name}${db}...`); - expect(mockMatterbridge.addBridgedEndpoint).toHaveBeenCalled(); + expect(mockMatterbridge.addBridgedEndpoint).toHaveBeenCalled(); // Duplicated device name }); it('should not register a switch device from ha without states', async () => { @@ -885,10 +885,25 @@ describe('HassPlatform', () => { await haPlatform.onStart('Test reason'); expect(mockLog.info).toHaveBeenCalledWith(`Starting platform ${idn}${mockConfig.name}${rs}${nf}: Test reason`); - expect(mockLog.debug).toHaveBeenCalledWith(`Lookup device ${CYAN}${switchDevice.name}${db} entity ${CYAN}${switchDeviceEntity.entity_id}${db}: state not found`); + // expect(mockLog.debug).toHaveBeenCalledWith(`Lookup device ${CYAN}${switchDevice.name}${db} entity ${CYAN}${switchDeviceEntity.entity_id}${db}: state not found`); expect(mockLog.debug).not.toHaveBeenCalledWith(`Registering device ${dn}${switchDevice.name}${db}...`); }); + it('should register a thermo auto device from ha', async () => { + expect(haPlatform).toBeDefined(); + + haPlatform.ha.hassDevices.set(autoDevice.id, autoDevice as unknown as HassDevice); + haPlatform.ha.hassEntities.set(autoDeviceEntity.entity_id, autoDeviceEntity as unknown as HassEntity); + haPlatform.ha.hassStates.set(autoDeviceEntityState.entity_id, autoDeviceEntityState as unknown as HassState); + + await haPlatform.onStart('Test reason'); + + expect(mockLog.info).toHaveBeenCalledWith(`Starting platform ${idn}${mockConfig.name}${rs}${nf}: Test reason`); + expect(mockLog.info).toHaveBeenCalledWith(`Creating device ${idn}${autoDevice.name}${rs}${nf} id ${CYAN}${autoDevice.id}${nf}`); + expect(mockLog.debug).toHaveBeenCalledWith(`Registering device ${dn}${autoDevice.name}${db}...`); + expect(mockMatterbridge.addBridgedEndpoint).toHaveBeenCalled(); + }); + it('should register a thermo heat device from ha', async () => { expect(haPlatform).toBeDefined(); @@ -916,7 +931,7 @@ describe('HassPlatform', () => { expect(mockLog.info).toHaveBeenCalledWith(`Starting platform ${idn}${mockConfig.name}${rs}${nf}: Test reason`); expect(mockLog.info).toHaveBeenCalledWith(`Creating device ${idn}${coolDevice.name}${rs}${nf} id ${CYAN}${coolDevice.id}${nf}`); expect(mockLog.debug).toHaveBeenCalledWith(`Registering device ${dn}${coolDevice.name}${db}...`); - expect(mockMatterbridge.addBridgedEndpoint).toHaveBeenCalled(); + expect(mockMatterbridge.addBridgedEndpoint).toHaveBeenCalled(); // Duplicated device name }); it('should call onConfigure', async () => { @@ -977,7 +992,7 @@ const switchDevice = { model_id: null, modified_at: 1726500210.074452, name_by_user: null, - name: 'Switch', + name: 'Switch mock', primary_config_entry: '01J6J7D7EADB8KNX8XBDYDNB1B', serial_number: '0x23452164', sw_version: '1.0.0', @@ -1017,6 +1032,41 @@ const switchDeviceEntityState = { context: { id: '01J83564ER52RJF78N4S96YHG8', parent_id: null, user_id: null }, }; +const autoDevice = { + area_id: null, + id: 'd80898f83188759ed7329e97df00ee6f', + labels: [], + manufacturer: 'Luligu', + model: 'Matterbridge Switch', + model_id: null, + name_by_user: null, + name: 'Thermo auto', + serial_number: '0x23452164', +}; + +const autoDeviceEntity = { + area_id: null, + device_id: 'd80898f83188759ed7329e97df00ee6f', + entity_id: 'climate.thermo-auto', + id: '0b25a337cb83edefb1d310450ad2b0aa', + name: null, +}; + +const autoDeviceEntityState = { + entity_id: 'climate.thermo-auto', + state: 'heat', + attributes: { + hvac_modes: ['off', 'heat', 'cool', 'auto'], + min_temp: 7, + max_temp: 50, + current_temperature: 19, + temperature: 20, + target_temp_high: null, + target_temp_low: null, + friendly_name: 'Thermostat', + }, +}; + const heatDevice = { area_id: null, id: 'd80898f83188759ed7329e97df00ee6a', @@ -1025,7 +1075,7 @@ const heatDevice = { model: 'Matterbridge Switch', model_id: null, name_by_user: null, - name: 'Thermo', + name: 'Thermo heat', serial_number: '0x23452164', }; @@ -1060,7 +1110,7 @@ const coolDevice = { model: 'Matterbridge Switch', model_id: null, name_by_user: null, - name: 'Thermo', + name: 'Thermo cool', serial_number: '0x23452164', }; diff --git a/src/platform.ts b/src/platform.ts index bc7ba7f..76de866 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -64,7 +64,7 @@ export class HomeAssistantPlatform extends MatterbridgeDynamicPlatform { ha: HomeAssistant; // Matterbridge devices - matterbridgeDevices = new Map(); + matterbridgeDevices = new Map(); // Without the postfix bridgedHassDevices = new Map(); // Only the bridged devices from Home Assistant bridgedHassEntities = new Map(); // Only the bridged individual entities from Home Assistant @@ -72,9 +72,9 @@ export class HomeAssistantPlatform extends MatterbridgeDynamicPlatform { super(matterbridge, log, config); // Verify that Matterbridge is the correct version - if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('2.1.0')) { + if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('2.1.4')) { throw new Error( - `This plugin requires Matterbridge version >= "2.1.0". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend."`, + `This plugin requires Matterbridge version >= "2.1.4". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend."`, ); } @@ -165,15 +165,13 @@ export class HomeAssistantPlatform extends MatterbridgeDynamicPlatform { this.log.error('Error writing payload to file:', error); }); - // Scan individual entities and create Matterbridge devices + // Scan individual entities (domain automation, scene, script and helpers input_boolean) and create Matterbridge devices for (const entity of Array.from(this.ha.hassEntities.values())) { const [domain, name] = entity.entity_id.split('.'); - if (!['automation', 'scene', 'script'].includes(domain)) continue; + if (!['automation', 'scene', 'script', 'input_boolean'].includes(domain)) continue; const entityName = entity.name ?? entity.original_name; - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - if (entityName && this.selectEntity) this.selectEntity.set(entity.id, { name: entity.entity_id, description: entityName, icon: 'hub' }); if (!isValidString(entityName)) continue; + if (entityName && this.selectEntity) this.selectEntity.set(entity.id, { name: entity.entity_id, description: entityName, icon: 'hub' }); if ( isValidArray(this.config.individualEntityWhiteList, 1) && !this.config.individualEntityWhiteList.includes(entityName) && @@ -185,6 +183,10 @@ export class HomeAssistantPlatform extends MatterbridgeDynamicPlatform { (this.config.individualEntityBlackList.includes(entityName) || this.config.individualEntityBlackList.includes(entity.entity_id)) ) continue; + if (this.hasDeviceName(entityName)) { + this.log.warn(`Entity ${CYAN}${entityName}${nf} already exists as a registered device. Please change the name in Home Assistant`); + continue; + } this.log.info(`Creating device for individual entity ${idn}${entityName}${rs}${nf} domain ${CYAN}${domain}${nf} name ${CYAN}${name}${nf}`); // Create a Mutable device with bridgedNode and the BridgedDeviceBasicInformationCluster @@ -199,7 +201,10 @@ export class HomeAssistantPlatform extends MatterbridgeDynamicPlatform { mutableDevice.addDeviceTypes('', bridgedNode); mutableDevice.composedType = 'HomeAssistant'; const matterbridgeDevice = await mutableDevice.createMainEndpoint(); - matterbridgeDevice.configUrl = `${(this.config.host as string | undefined)?.replace('ws://', 'http://')}/config/entities/entity/${entity.id}`; + if (domain === 'automation') matterbridgeDevice.configUrl = `${(this.config.host as string | undefined)?.replace('ws://', 'http://')}/config/automation/dashboard`; + else if (domain === 'scene') matterbridgeDevice.configUrl = `${(this.config.host as string | undefined)?.replace('ws://', 'http://')}/config/scene/dashboard`; + else if (domain === 'script') matterbridgeDevice.configUrl = `${(this.config.host as string | undefined)?.replace('ws://', 'http://')}/config/script/dashboard`; + else if (domain === 'input_boolean') matterbridgeDevice.configUrl = `${(this.config.host as string | undefined)?.replace('ws://', 'http://')}/config/helpers`; await mutableDevice.createClusters(''); // Create the child endpoint with onOffOutlet and the OnOffCluster @@ -208,14 +213,19 @@ export class HomeAssistantPlatform extends MatterbridgeDynamicPlatform { const child = await mutableDevice.createChildEndpoint(entity.entity_id); await mutableDevice.createClusters(entity.entity_id); child.addCommandHandler('on', async () => { + // child.setAttribute(OnOff.Cluster.id, 'onOff', true, child.log); // No need with behavior await this.ha.callServiceAsync(domain, domain === 'automation' ? 'trigger' : 'turn_on', entity.entity_id); - child.setAttribute(OnOff.Cluster.id, 'onOff', true, child.log); - setTimeout(() => { - child.setAttribute(OnOff.Cluster.id, 'onOff', false, child.log); - }, 500); + if (domain !== 'input_boolean') { + // We revert the state after 500ms except for input_boolean + setTimeout(() => { + child.setAttribute(OnOff.Cluster.id, 'onOff', false, child.log); + }, 500); + } }); child.addCommandHandler('off', async () => { - child.setAttribute(OnOff.Cluster.id, 'onOff', false, child.log); + // child.setAttribute(OnOff.Cluster.id, 'onOff', false, child.log); // No need with behavior + // We update hass only for input_boolean + if (domain === 'input_boolean') await this.ha.callServiceAsync(domain, 'turn_off', entity.entity_id); }); this.log.debug(`Registering device ${dn}${entityName}${db}...`); @@ -227,17 +237,21 @@ export class HomeAssistantPlatform extends MatterbridgeDynamicPlatform { // Scan devices and entities and create Matterbridge devices for (const device of Array.from(this.ha.hassDevices.values())) { - const name = device.name_by_user ?? device.name; + const deviceName = device.name_by_user ?? device.name; const entitiesCount = Array.from(this.ha.hassEntities.values()).filter((e) => e.device_id === device.id).length; - if (name && entitiesCount > 0 && this.selectDevice) this.selectDevice.set(device.id, { serial: device.id, name, icon: 'hub' }); - if (!isValidString(name) || !this.validateDeviceWhiteBlackList([name, device.id], true)) continue; + if (deviceName && entitiesCount > 0 && this.selectDevice) this.selectDevice.set(device.id, { serial: device.id, name: deviceName, icon: 'hub' }); + if (!isValidString(deviceName) || !this.validateDevice([deviceName, device.id], true)) continue; + if (this.hasDeviceName(deviceName)) { + this.log.warn(`Device ${CYAN}${deviceName}${nf} already exists as a registered device. Please change the name in Home Assistant`); + continue; + } this.log.info(`Creating device ${idn}${device.name}${rs}${nf} id ${CYAN}${device.id}${nf}`); // this.log.debug(`Lookup device ${CYAN}${device.name}${db} id ${CYAN}${device.id}${db}`); // Create a Mutable device const mutableDevice = new MutableDevice( this.matterbridge, - name + (isValidString(this.config.namePostfix, 1, 3) ? ' ' + this.config.namePostfix : ''), + deviceName + (isValidString(this.config.namePostfix, 1, 3) ? ' ' + this.config.namePostfix : ''), isValidString(this.config.serialPostfix, 1, 3) ? device.id.slice(0, 29) + this.config.serialPostfix : device.id, 0xfff1, 'HomeAssistant', @@ -251,7 +265,7 @@ export class HomeAssistantPlatform extends MatterbridgeDynamicPlatform { // Scan entities for supported domains and services and add them to the Matterbridge device for (const entity of Array.from(this.ha.hassEntities.values()).filter((e) => e.device_id === device.id)) { this.log.debug(`Lookup device ${CYAN}${device.name}${db} entity ${CYAN}${entity.entity_id}${db}`); - if (!this.validateEntityBlackList(name, entity.entity_id, true)) continue; + if (!this.validateEntity(deviceName, entity.entity_id, true)) continue; const domain = entity.entity_id.split('.')[0]; // Get the device state @@ -522,8 +536,13 @@ export class HomeAssistantPlatform extends MatterbridgeDynamicPlatform { this.log.info(`Shutting down platform ${idn}${this.config.name}${rs}${nf}: ${reason ?? ''}`); this.ha.close(); + this.ha.removeAllListeners(); if (this.config.unregisterOnShutdown === true) await this.unregisterAllDevices(); + + this.matterbridgeDevices.clear(); + this.bridgedHassDevices.clear(); + this.bridgedHassEntities.clear(); } async commandHandler(mbDevice: MatterbridgeEndpoint | undefined, endpoint: MatterbridgeEndpoint, request: any, attributes: any, command: string) { @@ -562,8 +581,8 @@ export class HomeAssistantPlatform extends MatterbridgeDynamicPlatform { } */ - async updateHandler(deviceId: string, entityId: string, old_state: HassState, new_state: HassState) { - const matterbridgeDevice = this.matterbridgeDevices.get(deviceId); + async updateHandler(deviceId: string | null, entityId: string, old_state: HassState, new_state: HassState) { + const matterbridgeDevice = this.matterbridgeDevices.get(deviceId ?? entityId); if (!matterbridgeDevice) return; const endpoint = matterbridgeDevice.getChildEndpointByName(entityId) || matterbridgeDevice.getChildEndpointByName(entityId.replaceAll('.', '')); if (!endpoint) return; @@ -572,7 +591,10 @@ export class HomeAssistantPlatform extends MatterbridgeDynamicPlatform { `from ${YELLOW}${old_state.state}${db} with ${debugStringify(old_state.attributes)}${db} to ${YELLOW}${new_state.state}${db} with ${debugStringify(new_state.attributes)}`, ); const domain = entityId.split('.')[0]; - if (domain === 'sensor') { + if (['automation', 'scene', 'script'].includes(domain)) { + // No update for individual entities (automation, scene, script) only for input_boolean that maintains the state + return; + } else if (domain === 'sensor') { // Update sensors of the device const hassSensorConverter = hassDomainSensorsConverter.find( (s) => s.domain === domain && s.withStateClass === new_state.attributes['state_class'] && s.withDeviceClass === new_state.attributes['device_class'],