Compare commits

...
39 Commits
Author SHA1 Message Date
Koen Kanters 94751abaac chore(dev): release 2.10.1 (#31831) 2026-05-07 19:44:19 +02:00
Koen Kanters cc8456617a fix(ignore): update zigbee-herdsman-converters to 26.46.0 (#31937) 2026-05-07 17:36:55 +00:00
Koen Kanters 8727abdefc fix(ignore): update zigbee-herdsman-converters to 26.45.0 (#31925) 2026-05-06 20:05:18 +00:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 24e90273c9 fix(ignore): bump express-static-gzip from 3.0.0 to 3.0.1 in the minor-patch group (#31924)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-06 21:59:24 +02:00
Koen Kanters 845bdb7dba fix(ignore): update zigbee-herdsman-converters to 26.44.0 (#31900) 2026-05-05 18:57:33 +00:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 55f12ff520 fix(ignore): bump @biomejs/biome from 2.4.13 to 2.4.14 in the minor-patch group across 1 directory (#31881)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 20:30:06 +02:00
Koen Kanters 19eb05a0e0 fix(ignore): update zigbee-herdsman-converters to 26.43.0 (#31878) 2026-05-05 05:29:59 +00:00
Nerivec 9f7ea9b7c7 fix: Replace deprecated url.parse (#31845) 2026-05-04 20:29:24 +02:00
github-actions[bot] 0d7b8f189c chore: promote to dev 2026-05-01 17:40:55 +00:00
Koen Kanters 4639243cf9 chore(dev): release 2.10.0 (#31572) 2026-05-01 19:28:02 +02:00
Koen Kanters df26459b46 fix(ignore): update zigbee-herdsman-converters to 26.42.0 (#31830) 2026-05-01 15:30:23 +00:00
Koen Kanters c58162344f fix(ignore): update zigbee-herdsman-converters to 26.41.0 (#31820) 2026-04-30 19:56:07 +00:00
Andy 5974286445 fix: Improve transmit power description (#31735) 2026-04-28 22:13:25 +02:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 4e527bbce8 fix(deps): bump googleapis/release-please-action from 4 to 5 (#31805)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-28 22:11:58 +02:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> b3983b35de fix(ignore): bump the minor-patch group with 3 updates (#31806)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-28 22:11:47 +02:00
Koen KantersandMikhail Samin 429c5aea58 fix(ignore): update zigbee-herdsman-converters to 26.40.0 (#31800)
Co-authored-by: Mikhail Samin <i@mishasamin.xyz>
2026-04-26 20:05:21 +00:00
Koen Kanters e71507835b fix(ignore): update zigbee-herdsman-converters to 26.39.1 (#31783) 2026-04-23 19:24:07 +00:00
Koen Kanters 3bb3d56c05 fix(ignore): update zigbee-herdsman-converters to 26.38.1 (#31777) 2026-04-22 19:19:16 +00:00
Koen Kanters 305b7bcafa fix(ignore): update zigbee-herdsman-converters to 26.38.0 (#31768) 2026-04-21 19:39:41 +00:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 7ba232e27d fix(ignore): bump the minor-patch group with 2 updates (#31758)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 20:44:01 +02:00
Koen Kanters 78f440bada fix(ignore): update zigbee-herdsman-converters to 26.37.0 (#31749) 2026-04-19 19:39:12 +00:00
Koen Kanters a54775dea1 fix(ignore): update zigbee-herdsman-converters to 26.36.0 (#31737) 2026-04-17 18:01:27 +00:00
hoellenandKoen Kanters 041972669a feat: Home Assistant: add group entities in discovery config (#31663)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2026-04-17 19:14:54 +02:00
Koen Kanters 0a7dfcef59 fix(ignore): update zigbee-herdsman-converters to 26.35.0 (#31713) 2026-04-14 19:09:08 +00:00
Koen Kanters 55d8d1f4d0 fix(ignore): update zigbee-herdsman-converters to 26.34.0 (#31702) 2026-04-13 19:19:40 +00:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> cdd7357522 fix(ignore): bump @biomejs/biome from 2.4.10 to 2.4.11 in the minor-patch group (#31699)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 21:00:46 +02:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 4294512486 chore(deps): bump actions/github-script from 8 to 9 (#31697)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 21:00:32 +02:00
Koen Kanters 0c9ec722db fix(ignore): update zigbee-herdsman-converters to 26.33.1 (#31674) 2026-04-11 12:19:45 +00:00
Koen Kanters a0204ad3f0 fix(ignore): update zigbee-herdsman to 10.0.7 (#31673) 2026-04-11 11:32:03 +00:00
toastedcornflakes 4a63e65981 fix: Clarify units of pause_on_backoff_gt (#31668) 2026-04-11 12:47:09 +02:00
Koen Kanters 4818cc4163 fix(ignore): update zigbee-herdsman-converters to 26.32.0 (#31653) 2026-04-09 19:18:29 +00:00
dependabot[bot]dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Koen Kanters
9e27181b64 fix(ignore): bump typescript from 5.9.3 to 6.0.2 (#31560)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2026-04-08 20:28:59 +02:00
Koen Kanters a50065cbb4 fix(ignore): update zigbee-herdsman-converters to 26.31.0 (#31637) 2026-04-07 19:14:49 +00:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> e6dd5c73bc fix(ignore): bump @types/node from 24.12.0 to 24.12.2 in the minor-patch group across 1 directory (#31628)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-07 20:55:57 +02:00
Koen Kanters aef3242319 fix(ignore): update zigbee-herdsman to 10.0.6 (#31636) 2026-04-07 18:31:15 +00:00
Koen Kanters 6b567c1286 fix(ignore): update zigbee-herdsman-converters to 26.30.0 (#31608) 2026-04-05 06:07:21 +00:00
Koen Kanters 23f9847994 fix(ignore): update zigbee-herdsman-converters to 26.29.0 (#31586) 2026-04-02 18:14:41 +00:00
Koen Kanters 08e4e9edeb fix(ignore): update zigbee-herdsman-converters to 26.28.0 (#31574) 2026-04-01 20:08:13 +00:00
github-actions[bot] 673d81f51a chore: promote to dev 2026-04-01 19:40:05 +00:00
15 changed files with 401 additions and 220 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
steps:
- name: Delete untagged images
uses: actions/github-script@v8
uses: actions/github-script@v9
with:
github-token: ${{ secrets.GH_TOKEN }}
script: |
+1 -1
View File
@@ -31,7 +31,7 @@ jobs:
path: zhc
- name: Comment on new device support/external converter issue
uses: actions/github-script@v8
uses: actions/github-script@v9
with:
script: |
const {newDeviceSupport} = await import("${{ github.workspace }}/z2m/scripts/issueBot.mjs")
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
with:
node-version: 24
- uses: googleapis/release-please-action@v4
- uses: googleapis/release-please-action@v5
id: release
with:
target-branch: dev
+1 -1
View File
@@ -1,3 +1,3 @@
{
".": "2.9.2"
".": "2.10.1"
}
+50
View File
@@ -1,5 +1,55 @@
# Changelog
## [2.10.1](https://github.com/Koenkk/zigbee2mqtt/compare/2.10.0...2.10.1) (2026-05-07)
### Bug Fixes
* **ignore:** bump @biomejs/biome from 2.4.13 to 2.4.14 in the minor-patch group across 1 directory ([#31881](https://github.com/Koenkk/zigbee2mqtt/issues/31881)) ([55f12ff](https://github.com/Koenkk/zigbee2mqtt/commit/55f12ff52063d576be0fe82891678c52181f3b8e))
* **ignore:** bump express-static-gzip from 3.0.0 to 3.0.1 in the minor-patch group ([#31924](https://github.com/Koenkk/zigbee2mqtt/issues/31924)) ([24e9027](https://github.com/Koenkk/zigbee2mqtt/commit/24e90273c9e712e122887e74ccf8208a8b42e762))
* **ignore:** update zigbee-herdsman-converters to 26.43.0 ([#31878](https://github.com/Koenkk/zigbee2mqtt/issues/31878)) ([19eb05a](https://github.com/Koenkk/zigbee2mqtt/commit/19eb05a0e023c7e2e8639c1dcda18399e96ae74d))
* **ignore:** update zigbee-herdsman-converters to 26.44.0 ([#31900](https://github.com/Koenkk/zigbee2mqtt/issues/31900)) ([845bdb7](https://github.com/Koenkk/zigbee2mqtt/commit/845bdb7dba5fe0f5e67e1b92c68872da0f3abf6a))
* **ignore:** update zigbee-herdsman-converters to 26.45.0 ([#31925](https://github.com/Koenkk/zigbee2mqtt/issues/31925)) ([8727abd](https://github.com/Koenkk/zigbee2mqtt/commit/8727abdefc9114a5e2e1036d764271c90065e0a1))
* **ignore:** update zigbee-herdsman-converters to 26.46.0 ([#31937](https://github.com/Koenkk/zigbee2mqtt/issues/31937)) ([cc84566](https://github.com/Koenkk/zigbee2mqtt/commit/cc8456617a4a389e7297e380901bfd6bb0223b32))
* Replace deprecated `url.parse` ([#31845](https://github.com/Koenkk/zigbee2mqtt/issues/31845)) ([9f7ea9b](https://github.com/Koenkk/zigbee2mqtt/commit/9f7ea9b7c79db7a781b431fbe43568e15647f8e5))
## [2.10.0](https://github.com/Koenkk/zigbee2mqtt/compare/2.9.2...2.10.0) (2026-05-01)
### Features
* Home Assistant: add group entities in discovery config ([#31663](https://github.com/Koenkk/zigbee2mqtt/issues/31663)) ([0419726](https://github.com/Koenkk/zigbee2mqtt/commit/041972669a6a8108e8fee1a0fffb555292371285))
### Bug Fixes
* Clarify units of pause_on_backoff_gt ([#31668](https://github.com/Koenkk/zigbee2mqtt/issues/31668)) ([4a63e65](https://github.com/Koenkk/zigbee2mqtt/commit/4a63e65981b6bbd746a730e7ca2291aba7a6c975))
* **deps:** bump googleapis/release-please-action from 4 to 5 ([#31805](https://github.com/Koenkk/zigbee2mqtt/issues/31805)) ([4e527bb](https://github.com/Koenkk/zigbee2mqtt/commit/4e527bbce8612c85fd636a1c493059af9793991f))
* **ignore:** bump @biomejs/biome from 2.4.10 to 2.4.11 in the minor-patch group ([#31699](https://github.com/Koenkk/zigbee2mqtt/issues/31699)) ([cdd7357](https://github.com/Koenkk/zigbee2mqtt/commit/cdd73575227527ae7eca5732d96687a30cea8538))
* **ignore:** bump @types/node from 24.12.0 to 24.12.2 in the minor-patch group across 1 directory ([#31628](https://github.com/Koenkk/zigbee2mqtt/issues/31628)) ([e6dd5c7](https://github.com/Koenkk/zigbee2mqtt/commit/e6dd5c73bc2d76b32c45ef19633626dbcdde8379))
* **ignore:** bump the minor-patch group with 2 updates ([#31758](https://github.com/Koenkk/zigbee2mqtt/issues/31758)) ([7ba232e](https://github.com/Koenkk/zigbee2mqtt/commit/7ba232e27d973119530119ca136aaab3e8e22ab6))
* **ignore:** bump the minor-patch group with 3 updates ([#31806](https://github.com/Koenkk/zigbee2mqtt/issues/31806)) ([b3983b3](https://github.com/Koenkk/zigbee2mqtt/commit/b3983b35de0b6242d8e4d01f0d1d1e535e2d0b60))
* **ignore:** bump typescript from 5.9.3 to 6.0.2 ([#31560](https://github.com/Koenkk/zigbee2mqtt/issues/31560)) ([9e27181](https://github.com/Koenkk/zigbee2mqtt/commit/9e27181b64b771250db283b5a4b1da7835470ee6))
* **ignore:** update zigbee-herdsman to 10.0.6 ([#31636](https://github.com/Koenkk/zigbee2mqtt/issues/31636)) ([aef3242](https://github.com/Koenkk/zigbee2mqtt/commit/aef32423195914aa9ef08875d4fe6de36df71f11))
* **ignore:** update zigbee-herdsman to 10.0.7 ([#31673](https://github.com/Koenkk/zigbee2mqtt/issues/31673)) ([a0204ad](https://github.com/Koenkk/zigbee2mqtt/commit/a0204ad3f00ed366e4c41455ae4189bd31870a95))
* **ignore:** update zigbee-herdsman-converters to 26.28.0 ([#31574](https://github.com/Koenkk/zigbee2mqtt/issues/31574)) ([08e4e9e](https://github.com/Koenkk/zigbee2mqtt/commit/08e4e9edeb048a07f89d6283e5bea04274a3fb47))
* **ignore:** update zigbee-herdsman-converters to 26.29.0 ([#31586](https://github.com/Koenkk/zigbee2mqtt/issues/31586)) ([23f9847](https://github.com/Koenkk/zigbee2mqtt/commit/23f9847994da94fa8b38ba823a8e55418b006e7c))
* **ignore:** update zigbee-herdsman-converters to 26.30.0 ([#31608](https://github.com/Koenkk/zigbee2mqtt/issues/31608)) ([6b567c1](https://github.com/Koenkk/zigbee2mqtt/commit/6b567c1286201aa9fef4744f7378798bc852c9ff))
* **ignore:** update zigbee-herdsman-converters to 26.31.0 ([#31637](https://github.com/Koenkk/zigbee2mqtt/issues/31637)) ([a50065c](https://github.com/Koenkk/zigbee2mqtt/commit/a50065cbb40bb149a87046bb83a7602a5587b3b0))
* **ignore:** update zigbee-herdsman-converters to 26.32.0 ([#31653](https://github.com/Koenkk/zigbee2mqtt/issues/31653)) ([4818cc4](https://github.com/Koenkk/zigbee2mqtt/commit/4818cc4163d578990339daf6c5e725bb40a08216))
* **ignore:** update zigbee-herdsman-converters to 26.33.1 ([#31674](https://github.com/Koenkk/zigbee2mqtt/issues/31674)) ([0c9ec72](https://github.com/Koenkk/zigbee2mqtt/commit/0c9ec722db3f53c57870de7f09de9971d69cbda8))
* **ignore:** update zigbee-herdsman-converters to 26.34.0 ([#31702](https://github.com/Koenkk/zigbee2mqtt/issues/31702)) ([55d8d1f](https://github.com/Koenkk/zigbee2mqtt/commit/55d8d1f4d0a5895ce146dbec98630d82adcd4e22))
* **ignore:** update zigbee-herdsman-converters to 26.35.0 ([#31713](https://github.com/Koenkk/zigbee2mqtt/issues/31713)) ([0a7dfce](https://github.com/Koenkk/zigbee2mqtt/commit/0a7dfcef596c3201f9f0cd81960c0e4ad8add0c4))
* **ignore:** update zigbee-herdsman-converters to 26.36.0 ([#31737](https://github.com/Koenkk/zigbee2mqtt/issues/31737)) ([a54775d](https://github.com/Koenkk/zigbee2mqtt/commit/a54775dea10a14b6d2f25ebb3c79a8a9d979e970))
* **ignore:** update zigbee-herdsman-converters to 26.37.0 ([#31749](https://github.com/Koenkk/zigbee2mqtt/issues/31749)) ([78f440b](https://github.com/Koenkk/zigbee2mqtt/commit/78f440bada9a14abb1d84af12fc77b1af7d250ea))
* **ignore:** update zigbee-herdsman-converters to 26.38.0 ([#31768](https://github.com/Koenkk/zigbee2mqtt/issues/31768)) ([305b7bc](https://github.com/Koenkk/zigbee2mqtt/commit/305b7bcafab59250173eddb9c08cb2fed0d966a0))
* **ignore:** update zigbee-herdsman-converters to 26.38.1 ([#31777](https://github.com/Koenkk/zigbee2mqtt/issues/31777)) ([3bb3d56](https://github.com/Koenkk/zigbee2mqtt/commit/3bb3d56c05b92e349d2b117973df6cf9414b8450))
* **ignore:** update zigbee-herdsman-converters to 26.39.1 ([#31783](https://github.com/Koenkk/zigbee2mqtt/issues/31783)) ([e715078](https://github.com/Koenkk/zigbee2mqtt/commit/e71507835b2c0673ec0df488e9d1db39a7b64a05))
* **ignore:** update zigbee-herdsman-converters to 26.40.0 ([#31800](https://github.com/Koenkk/zigbee2mqtt/issues/31800)) ([429c5ae](https://github.com/Koenkk/zigbee2mqtt/commit/429c5aea585da1525347adc13712bc556b4ea2ae))
* **ignore:** update zigbee-herdsman-converters to 26.41.0 ([#31820](https://github.com/Koenkk/zigbee2mqtt/issues/31820)) ([c581623](https://github.com/Koenkk/zigbee2mqtt/commit/c58162344fddc1cdb49027f6dcc9f1f35030bc61))
* **ignore:** update zigbee-herdsman-converters to 26.42.0 ([#31830](https://github.com/Koenkk/zigbee2mqtt/issues/31830)) ([df26459](https://github.com/Koenkk/zigbee2mqtt/commit/df26459b46e67f4f3b1079eb6fa6a439bf1979af))
* Improve transmit power description ([#31735](https://github.com/Koenkk/zigbee2mqtt/issues/31735)) ([5974286](https://github.com/Koenkk/zigbee2mqtt/commit/59742864457a9e29783363ebde8ede0e0aca5ea2))
## [2.9.2](https://github.com/Koenkk/zigbee2mqtt/compare/2.9.1...2.9.2) (2026-03-31)
+2 -3
View File
@@ -5,7 +5,6 @@ import {createServer} from "node:http";
import {createServer as createSecureServer} from "node:https";
import type {Socket} from "node:net";
import {posix} from "node:path";
import {parse} from "node:url";
import bind from "bind-decorator";
import expressStaticGzip from "express-static-gzip";
import finalhandler from "finalhandler";
@@ -157,10 +156,10 @@ export class Frontend extends Extension {
@bind private onUpgrade(request: IncomingMessage, socket: Socket, head: Buffer): void {
this.wss.handleUpgrade(request, socket, head, (ws) => {
// biome-ignore lint/style/noNonNullAssertion: `Only valid for request obtained from Server`
const {query} = parse(request.url!, true);
const {searchParams} = new URL(request.url!, "http://localhost"); // dummy base, may not be absolute
const authToken = settings.get().frontend.auth_token;
if (!authToken || authToken === query.token) {
if (!authToken || authToken === searchParams.get("token")) {
this.wss.emit("connection", ws, request);
} else {
ws.close(4401, "Unauthorized");
+98 -68
View File
@@ -2,7 +2,7 @@ import assert from "node:assert";
import bind from "bind-decorator";
import stringify from "json-stable-stringify-without-jsonify";
import type * as zhc from "zigbee-herdsman-converters";
import type {Zh} from "zigbee-herdsman-converters/lib/types";
import logger from "../util/logger";
import * as settings from "../util/settings";
import utils, {assertBinaryExpose, assertEnumExpose, assertNumericExpose, isBinaryExpose, isEnumExpose, isNumericExpose} from "../util/utils";
@@ -18,6 +18,7 @@ interface DiscoveryEntry {
type: string;
object_id: string;
discovery_payload: KeyValue;
endpoint?: Zh.Endpoint;
}
interface Discovered {
@@ -384,6 +385,7 @@ export class HomeAssistant extends Extension {
private discoveryTopic: string;
private discoveryRegex: RegExp;
private discoveryRegexWoTopic = /(.*)\/(.*)\/(.*)\/config/;
private groupMemberLookup = new Map<string, string>();
private statusTopic: string;
private legacyActionSensor: boolean;
private experimentalEventEntities: boolean;
@@ -459,10 +461,15 @@ export class HomeAssistant extends Extension {
const discoverWait = 5;
// Discover with `published = false`, this will populate `this.discovered` without publishing the discoveries.
// This is needed for clearing outdated entries in `this.onMQTTMessage()`
// Discover devices before groups to populate `this.groupMemberLookup` for group discovery.
await this.discover(this.bridge, false);
for (const e of this.zigbee.devicesAndGroupsIterator(utils.deviceNotCoordinator)) {
await this.discover(e, false);
for (const device of this.zigbee.devicesIterator(utils.deviceNotCoordinator)) {
await this.discover(device, false);
}
for (const group of this.zigbee.groupsIterator()) {
await this.discover(group, false);
}
logger.debug(`Discovering entities to Home Assistant in ${discoverWait}s`);
@@ -487,21 +494,16 @@ export class HomeAssistant extends Extension {
return this.discovered[ID];
}
private exposeToConfig(
exposes: zhc.Expose[],
entityType: "device" | "group",
allExposes: zhc.Expose[],
definition?: zhc.Definition,
): DiscoveryEntry[] {
private exposeToConfig(exposes: zhc.Expose[], entity: Device | Group, allExposes: zhc.Expose[]): DiscoveryEntry[] {
// For groups an array of exposes (of the same type) is passed, this is to determine e.g. what features
// to use for a bulb (e.g. color_xy/color_temp)
assert(entityType === "group" || exposes.length === 1, "Multiple exposes for device not allowed");
assert(entity.isGroup() || exposes.length === 1, "Multiple exposes for device not allowed");
const firstExpose = exposes[0];
assert(entityType === "device" || GROUP_SUPPORTED_TYPES.includes(firstExpose.type), `Unsupported expose type ${firstExpose.type} for group`);
assert(entity.isDevice() || GROUP_SUPPORTED_TYPES.includes(firstExpose.type), `Unsupported expose type ${firstExpose.type} for group`);
const discoveryEntries: DiscoveryEntry[] = [];
const endpoint = entityType === "device" ? exposes[0].endpoint : undefined;
const getProperty = (feature: zhc.Feature): string => (entityType === "group" ? featurePropertyWithoutEndpoint(feature) : feature.property);
const endpointName = entity.isDevice() ? exposes[0].endpoint : undefined;
const getProperty = (feature: zhc.Feature): string => (entity.isGroup() ? featurePropertyWithoutEndpoint(feature) : feature.property);
switch (firstExpose.type) {
case "light": {
@@ -520,16 +522,16 @@ export class HomeAssistant extends Extension {
const discoveryEntry: DiscoveryEntry = {
type: "light",
object_id: endpoint ? `light_${endpoint}` : "light",
object_id: endpointName ? `light_${endpointName}` : "light",
mockProperties: [{property: state.property, value: null}],
discovery_payload: {
name: endpoint ? utils.capitalize(endpoint) : null,
name: endpointName ? utils.capitalize(endpointName) : null,
brightness: !!hasBrightness,
schema: "json",
command_topic: true,
brightness_scale: 254,
command_topic_prefix: endpoint,
state_topic_postfix: endpoint,
command_topic_prefix: endpointName,
state_topic_postfix: endpointName,
},
};
@@ -582,15 +584,15 @@ export class HomeAssistant extends Extension {
const property = getProperty(state);
const discoveryEntry: DiscoveryEntry = {
type: "switch",
object_id: endpoint ? `switch_${endpoint}` : "switch",
object_id: endpointName ? `switch_${endpointName}` : "switch",
mockProperties: [{property: property, value: null}],
discovery_payload: {
name: endpoint ? utils.capitalize(endpoint) : null,
name: endpointName ? utils.capitalize(endpointName) : null,
payload_off: state.value_off,
payload_on: state.value_on,
value_template: `{{ value_json.${property} }}`,
command_topic: true,
command_topic_prefix: endpoint,
command_topic_prefix: endpointName,
},
};
@@ -621,10 +623,10 @@ export class HomeAssistant extends Extension {
const discoveryEntry: DiscoveryEntry = {
type: "climate",
object_id: endpoint ? `climate_${endpoint}` : "climate",
object_id: endpointName ? `climate_${endpointName}` : "climate",
mockProperties: [],
discovery_payload: {
name: endpoint ? utils.capitalize(endpoint) : null,
name: endpointName ? utils.capitalize(endpointName) : null,
// Static
state_topic: false,
temperature_unit: "C",
@@ -635,7 +637,7 @@ export class HomeAssistant extends Extension {
// Temperature
current_temperature_topic: true,
current_temperature_template: `{{ value_json.${temperature.property} }}`,
command_topic_prefix: endpoint,
command_topic_prefix: endpointName,
},
};
@@ -704,13 +706,13 @@ export class HomeAssistant extends Extension {
if (tempCalibration) {
const discoveryEntry: DiscoveryEntry = {
type: "number",
object_id: endpoint ? `${tempCalibration.name}_${endpoint}` : `${tempCalibration.name}`,
object_id: endpointName ? `${tempCalibration.name}_${endpointName}` : `${tempCalibration.name}`,
mockProperties: [{property: tempCalibration.property, value: null}],
discovery_payload: {
name: endpoint ? `${tempCalibration.label} ${endpoint}` : tempCalibration.label,
name: endpointName ? `${tempCalibration.label} ${endpointName}` : tempCalibration.label,
value_template: `{{ value_json.${tempCalibration.property} }}`,
command_topic: true,
command_topic_prefix: endpoint,
command_topic_prefix: endpointName,
command_topic_postfix: tempCalibration.property,
device_class: "temperature_delta",
entity_category: "config",
@@ -729,10 +731,10 @@ export class HomeAssistant extends Extension {
const piHeatingDemand = (firstExpose as zhc.Climate).features.filter(isNumericExpose).find((f) => f.name === "pi_heating_demand");
if (piHeatingDemand) {
const discoveryEntry: Partial<DiscoveryEntry> = {
object_id: endpoint ? `${piHeatingDemand.name}_${endpoint}` : `${piHeatingDemand.name}`,
object_id: endpointName ? `${piHeatingDemand.name}_${endpointName}` : `${piHeatingDemand.name}`,
mockProperties: [{property: piHeatingDemand.property, value: null}],
discovery_payload: {
name: endpoint ? `${piHeatingDemand.label} ${endpoint}` : piHeatingDemand.label,
name: endpointName ? `${piHeatingDemand.label} ${endpointName}` : piHeatingDemand.label,
value_template: `{{ value_json.${piHeatingDemand.property} }}`,
...(piHeatingDemand.unit && {unit_of_measurement: piHeatingDemand.unit}),
icon: "mdi:radiator",
@@ -744,7 +746,7 @@ export class HomeAssistant extends Extension {
if (piHeatingDemand.access & ACCESS_SET) {
discoveryEntry.type = "number";
discoveryEntry.discovery_payload.command_topic = true;
discoveryEntry.discovery_payload.command_topic_prefix = endpoint;
discoveryEntry.discovery_payload.command_topic_prefix = endpointName;
discoveryEntry.discovery_payload.command_topic_postfix = piHeatingDemand.property;
discoveryEntry.discovery_payload.min = piHeatingDemand.value_min;
discoveryEntry.discovery_payload.max = piHeatingDemand.value_max;
@@ -760,10 +762,10 @@ export class HomeAssistant extends Extension {
if (piCoolingDemand) {
const discoveryEntry: DiscoveryEntry = {
type: "sensor",
object_id: endpoint ? /* v8 ignore next */ `${piCoolingDemand.name}_${endpoint}` : `${piCoolingDemand.name}`,
object_id: endpointName ? /* v8 ignore next */ `${piCoolingDemand.name}_${endpointName}` : `${piCoolingDemand.name}`,
mockProperties: [{property: piCoolingDemand.property, value: null}],
discovery_payload: {
name: endpoint ? /* v8 ignore next */ `${piCoolingDemand.label} ${endpoint}` : piCoolingDemand.label,
name: endpointName ? /* v8 ignore next */ `${piCoolingDemand.label} ${endpointName}` : piCoolingDemand.label,
value_template: `{{ value_json.${piCoolingDemand.property} }}`,
...(piCoolingDemand.unit && {unit_of_measurement: piCoolingDemand.unit}),
entity_category: "diagnostic",
@@ -782,10 +784,10 @@ export class HomeAssistant extends Extension {
if (localTemperature && !temperatureSensor && !localTemperatureSensor) {
const discoveryEntry: DiscoveryEntry = {
type: "sensor",
object_id: endpoint ? `${localTemperature.name}_${endpoint}` : `${localTemperature.name}`,
object_id: endpointName ? `${localTemperature.name}_${endpointName}` : `${localTemperature.name}`,
mockProperties: [{property: localTemperature.property, value: null}],
discovery_payload: {
name: endpoint ? `${localTemperature.label} ${endpoint}` : localTemperature.label,
name: endpointName ? `${localTemperature.label} ${endpointName}` : localTemperature.label,
value_template: `{{ value_json.${localTemperature.property} }}`,
...(localTemperature.unit && {unit_of_measurement: localTemperature.unit}),
device_class: "temperature",
@@ -811,18 +813,18 @@ export class HomeAssistant extends Extension {
const discoveryEntry: DiscoveryEntry = {
type: "lock",
/* v8 ignore next */
object_id: endpoint ? `lock_${endpoint}` : "lock",
object_id: endpointName ? `lock_${endpointName}` : "lock",
mockProperties: [{property: state.property, value: null}],
discovery_payload: {
/* v8 ignore next */
name: endpoint ? utils.capitalize(endpoint) : null,
command_topic_prefix: endpoint,
name: endpointName ? utils.capitalize(endpointName) : null,
command_topic_prefix: endpointName,
command_topic: true,
value_template: `{{ value_json.${state.property} }}`,
state_locked: state.value_on,
state_unlocked: state.value_off,
/* v8 ignore next */
command_topic_postfix: endpoint ? state.property : null,
command_topic_postfix: endpointName ? state.property : null,
},
};
discoveryEntries.push(discoveryEntry);
@@ -847,13 +849,13 @@ export class HomeAssistant extends Extension {
const discoveryEntry: DiscoveryEntry = {
type: "cover",
mockProperties: [{property: state.property, value: null}],
object_id: endpoint ? `cover_${endpoint}` : "cover",
object_id: endpointName ? `cover_${endpointName}` : "cover",
discovery_payload: {
name: endpoint ? utils.capitalize(endpoint) : null,
command_topic_prefix: endpoint,
name: endpointName ? utils.capitalize(endpointName) : null,
command_topic_prefix: endpointName,
command_topic: true,
state_topic: true,
state_topic_postfix: endpoint,
state_topic_postfix: endpointName,
},
};
@@ -916,7 +918,7 @@ export class HomeAssistant extends Extension {
break;
}
case "fan": {
assert(!endpoint, "Endpoint not supported for fan type");
assert(!endpointName, "Endpoint not supported for fan type");
const discoveryEntry: DiscoveryEntry = {
type: "fan",
object_id: "fan",
@@ -952,7 +954,7 @@ export class HomeAssistant extends Extension {
);
let presets = ["on", "auto", "smart"].filter((s) => modeEmulatedSpeed.values.includes(s));
if (definition?.model === "99432") {
if (entity.isDevice() && entity.definition?.model === "99432") {
// The Hampton Bay 99432 fan implements 4 speeds using the ZCL
// hvacFanCtrl values `low`, `medium`, `high`, and `on`, and
// 1 preset called "Comfort Breeze" using the ZCL value `smart`.
@@ -1014,9 +1016,9 @@ export class HomeAssistant extends Extension {
const discoveryEntry: DiscoveryEntry = {
type: "switch",
mockProperties: [{property: firstExpose.property, value: null}],
object_id: endpoint ? `switch_${firstExpose.name}_${endpoint}` : `switch_${firstExpose.name}`,
object_id: endpointName ? `switch_${firstExpose.name}_${endpointName}` : `switch_${firstExpose.name}`,
discovery_payload: {
name: endpoint ? /* v8 ignore next */ `${firstExpose.label} ${endpoint}` : firstExpose.label,
name: endpointName ? /* v8 ignore next */ `${firstExpose.label} ${endpointName}` : firstExpose.label,
value_template:
typeof firstExpose.value_on === "boolean"
? `{% if value_json.${firstExpose.property} %}true{% else %}false{% endif %}`
@@ -1024,7 +1026,7 @@ export class HomeAssistant extends Extension {
payload_on: firstExpose.value_on.toString(),
payload_off: firstExpose.value_off.toString(),
command_topic: true,
command_topic_prefix: endpoint,
command_topic_prefix: endpointName,
command_topic_postfix: firstExpose.property,
...(BINARY_DISCOVERY_LOOKUP[firstExpose.name] || {}),
},
@@ -1034,10 +1036,10 @@ export class HomeAssistant extends Extension {
} else {
const discoveryEntry: DiscoveryEntry = {
type: "binary_sensor",
object_id: endpoint ? `${firstExpose.name}_${endpoint}` : `${firstExpose.name}`,
object_id: endpointName ? `${firstExpose.name}_${endpointName}` : `${firstExpose.name}`,
mockProperties: [{property: firstExpose.property, value: null}],
discovery_payload: {
name: endpoint ? /* v8 ignore next */ `${firstExpose.label} ${endpoint}` : firstExpose.label,
name: endpointName ? /* v8 ignore next */ `${firstExpose.label} ${endpointName}` : firstExpose.label,
value_template: `{{ value_json.${firstExpose.property} }}`,
payload_on: firstExpose.value_on,
payload_off: firstExpose.value_off,
@@ -1059,13 +1061,13 @@ export class HomeAssistant extends Extension {
if (allowsSet) {
const discoveryEntry: DiscoveryEntry = {
type: "number",
object_id: endpoint ? `${firstExpose.name}_${endpoint}` : `${firstExpose.name}`,
object_id: endpointName ? `${firstExpose.name}_${endpointName}` : `${firstExpose.name}`,
mockProperties: [{property: firstExpose.property, value: null}],
discovery_payload: {
name: endpoint ? `${firstExpose.label} ${endpoint}` : firstExpose.label,
name: endpointName ? `${firstExpose.label} ${endpointName}` : firstExpose.label,
value_template: `{{ value_json.${firstExpose.property} }}`,
command_topic: true,
command_topic_prefix: endpoint,
command_topic_prefix: endpointName,
command_topic_postfix: firstExpose.property,
...(firstExpose.unit && {unit_of_measurement: firstExpose.unit}),
...(firstExpose.value_step && {step: firstExpose.value_step}),
@@ -1110,10 +1112,10 @@ export class HomeAssistant extends Extension {
const discoveryEntry: DiscoveryEntry = {
type: "sensor",
object_id: endpoint ? `${firstExpose.name}_${endpoint}` : `${firstExpose.name}`,
object_id: endpointName ? `${firstExpose.name}_${endpointName}` : `${firstExpose.name}`,
mockProperties: [{property: firstExpose.property, value: null}],
discovery_payload: {
name: endpoint ? `${firstExpose.label} ${endpoint}` : firstExpose.label,
name: endpointName ? `${firstExpose.label} ${endpointName}` : firstExpose.label,
value_template: `{{ value_json.${firstExpose.property} }}`,
enabled_by_default: !allowsSet,
...(firstExpose.unit && {unit_of_measurement: firstExpose.unit}),
@@ -1155,7 +1157,7 @@ export class HomeAssistant extends Extension {
object_id: firstExpose.property,
mockProperties: [],
discovery_payload: {
name: endpoint ? /* v8 ignore next */ `${firstExpose.label} ${endpoint}` : firstExpose.label,
name: endpointName ? /* v8 ignore next */ `${firstExpose.label} ${endpointName}` : firstExpose.label,
state_topic: true,
event_types: this.prepareActionEventTypes(firstExpose.values),
value_template: this.actionValueTemplate,
@@ -1179,9 +1181,9 @@ export class HomeAssistant extends Extension {
object_id: firstExpose.property,
mockProperties: [{property: firstExpose.property, value: null}],
discovery_payload: {
name: endpoint ? /* v8 ignore next */ `${firstExpose.label} ${endpoint}` : firstExpose.label,
name: endpointName ? /* v8 ignore next */ `${firstExpose.label} ${endpointName}` : firstExpose.label,
state_topic: false,
command_topic_prefix: endpoint,
command_topic_prefix: endpointName,
command_topic: true,
command_topic_postfix: firstExpose.property,
payload_press: firstExpose.values[0].toString(),
@@ -1200,10 +1202,10 @@ export class HomeAssistant extends Extension {
object_id: firstExpose.property,
mockProperties: [{property: firstExpose.property, value: null}],
discovery_payload: {
name: endpoint ? `${firstExpose.label} ${endpoint}` : firstExpose.label,
name: endpointName ? `${firstExpose.label} ${endpointName}` : firstExpose.label,
value_template: valueTemplate,
state_topic: !!(firstExpose.access & ACCESS_STATE),
command_topic_prefix: endpoint,
command_topic_prefix: endpointName,
command_topic: true,
command_topic_postfix: firstExpose.property,
options: firstExpose.values.map((v) => v.toString()),
@@ -1222,7 +1224,7 @@ export class HomeAssistant extends Extension {
object_id: firstExpose.property,
mockProperties: [{property: firstExpose.property, value: null}],
discovery_payload: {
name: endpoint ? `${firstExpose.label} ${endpoint}` : firstExpose.label,
name: endpointName ? `${firstExpose.label} ${endpointName}` : firstExpose.label,
value_template: valueTemplate,
...ENUM_DISCOVERY_LOOKUP[firstExpose.name],
},
@@ -1244,12 +1246,12 @@ export class HomeAssistant extends Extension {
const discoveryEntry: DiscoveryEntry = {
type: "siren",
object_id: endpoint ? /* v8 ignore next */ `siren_${endpoint}` : "siren",
object_id: endpointName ? /* v8 ignore next */ `siren_${endpointName}` : "siren",
mockProperties: [{property: warningExpose.property, value: null}],
discovery_payload: {
name: endpoint ? /* v8 ignore next */ utils.capitalize(endpoint) : null,
name: endpointName ? /* v8 ignore next */ utils.capitalize(endpointName) : null,
command_topic: true,
command_topic_prefix: endpoint,
command_topic_prefix: endpointName,
state_topic: false,
optimistic: true,
},
@@ -1295,10 +1297,10 @@ export class HomeAssistant extends Extension {
object_id: firstExposeTyped.property,
mockProperties: [{property: firstExposeTyped.property, value: null}],
discovery_payload: {
name: endpoint ? `${firstExposeTyped.label} ${endpoint}` : firstExposeTyped.label,
name: endpointName ? `${firstExposeTyped.label} ${endpointName}` : firstExposeTyped.label,
state_topic: firstExposeTyped.access & ACCESS_STATE,
value_template: `{{ value_json.${firstExposeTyped.property} }}`,
command_topic_prefix: endpoint,
command_topic_prefix: endpointName,
command_topic: true,
command_topic_postfix: firstExposeTyped.property,
...LIST_DISCOVERY_LOOKUP[firstExposeTyped.name],
@@ -1312,7 +1314,7 @@ export class HomeAssistant extends Extension {
object_id: firstExposeTyped.property,
mockProperties: [{property: firstExposeTyped.property, value: null}],
discovery_payload: {
name: endpoint ? `${firstExposeTyped.label} ${endpoint}` : firstExposeTyped.label,
name: endpointName ? `${firstExposeTyped.label} ${endpointName}` : firstExposeTyped.label,
// Truncate text if it's too long
// https://github.com/Koenkk/zigbee2mqtt/issues/23199
value_template: `{{ value_json.${firstExposeTyped.property} | default('',True) | string | truncate(254, True, '', 0) }}`,
@@ -1349,6 +1351,8 @@ export class HomeAssistant extends Extension {
if (entry.discovery_payload.device_class) {
delete entry.discovery_payload.name;
}
entry.endpoint = entity.isDevice() ? entity.endpoint(endpointName) : undefined;
}
return discoveryEntries;
@@ -1474,7 +1478,7 @@ export class HomeAssistant extends Extension {
if (isDevice) {
const exposes = entity.exposes(); // avoid calling it hundred of times/s
for (const expose of exposes) {
configs.push(...this.exposeToConfig([expose], "device", exposes, entity.definition));
configs.push(...this.exposeToConfig([expose], entity, exposes));
}
} else if (isGroup) {
// group
@@ -1503,7 +1507,7 @@ export class HomeAssistant extends Extension {
}
configs = ([] as DiscoveryEntry[]).concat(
...Object.values(exposesByType).map((exposes) => this.exposeToConfig(exposes, "group", allExposes)),
...Object.values(exposesByType).map((exposes) => this.exposeToConfig(exposes, entity, allExposes)),
);
} else {
// Discover bridge config.
@@ -1656,7 +1660,33 @@ export class HomeAssistant extends Extension {
payload.default_entity_id = `${config.type}.${payload.object_id}`;
// Set unique_id
payload.unique_id = `${entity.options.ID}_${config.object_id}_${settings.get().mqtt.base_topic}`;
const uniqueId = `${entity.options.ID}_${config.object_id}_${settings.get().mqtt.base_topic}`;
payload.unique_id = uniqueId;
if (config.endpoint) {
assert(entity.isDevice());
const memberKey = `${config.endpoint.deviceIeeeAddress}_${config.endpoint.ID}_${config.type}`;
this.groupMemberLookup.set(memberKey, uniqueId);
}
// Add group member unique_ids for Home Assistant entity grouping
// This assumes that `discover()` already has been called for all devices, since it depends on the
// `groupMemberLookup` being populated.
// https://www.home-assistant.io/integrations/mqtt#grouping-entities
if (isGroup) {
const memberIds: string[] = [];
for (const endpoint of entity.zh.members) {
const memberKey = `${endpoint.deviceIeeeAddress}_${endpoint.ID}_${config.type}`;
const memberUniqueId = this.groupMemberLookup.get(memberKey);
if (memberUniqueId) {
memberIds.push(memberUniqueId);
}
}
if (memberIds.length > 0) {
payload.group = memberIds;
}
}
// Attributes for device registry and origin
payload.device = devicePayload;
+2 -2
View File
@@ -88,7 +88,7 @@
"title": "Pause on backoff greater than",
"default": 0,
"minimum": 0,
"description": "Pause availability pings when backoff reaches over this limit until a new Zigbee message is received from the device. A value of zero disables pausing."
"description": "Pause availability pings when the backoff multiplier reaches over this limit until a new Zigbee message is received from the device. A value of zero disables pausing."
}
},
"required": ["timeout"]
@@ -800,7 +800,7 @@
"requiresRestart": true,
"minimum": -128,
"maximum": 127,
"description": "Transmit power of adapter, only available for Z-Stack (CC253*/CC2652/CC1352) adapters, CC2652 = 5dbm, CC1352 max is = 20dbm (5dbm default)"
"description": "Transmit power of adapter, in dBm (max is often 20, refer to chip specifications)"
},
"output": {
"type": "string",
+10 -10
View File
@@ -1,6 +1,6 @@
{
"name": "zigbee2mqtt",
"version": "2.9.2",
"version": "2.10.1",
"description": "Zigbee to MQTT bridge using Zigbee-herdsman",
"main": "index.js",
"types": "dist/types/api.d.ts",
@@ -42,10 +42,10 @@
},
"homepage": "https://koenkk.github.io/zigbee2mqtt",
"dependencies": {
"ajv": "^8.18.0",
"ajv": "^8.20.0",
"bind-decorator": "^1.0.11",
"debounce": "^3.0.0",
"express-static-gzip": "^3.0.0",
"express-static-gzip": "^3.0.1",
"fast-deep-equal": "^3.1.3",
"finalhandler": "^2.1.1",
"humanize-duration": "^3.33.2",
@@ -62,24 +62,24 @@
"winston-syslog": "^2.7.1",
"winston-transport": "^4.9.0",
"ws": "^8.20.0",
"zigbee-herdsman": "10.0.5",
"zigbee-herdsman-converters": "26.27.0",
"zigbee-herdsman": "10.0.7",
"zigbee-herdsman-converters": "26.46.0",
"zigbee2mqtt-frontend": "0.9.21",
"zigbee2mqtt-windfront": "2.11.1"
"zigbee2mqtt-windfront": "2.11.2"
},
"devDependencies": {
"@biomejs/biome": "^2.4.10",
"@biomejs/biome": "^2.4.14",
"@types/finalhandler": "^1.2.3",
"@types/humanize-duration": "^3.27.4",
"@types/js-yaml": "^4.0.9",
"@types/node": "^24.12.0",
"@types/node": "^24.12.2",
"@types/object-assign-deep": "^0.4.3",
"@types/readable-stream": "4.0.23",
"@types/serve-static": "^2.2.0",
"@types/ws": "8.18.1",
"@vitest/coverage-v8": "^3.1.1",
"tmp": "^0.2.5",
"typescript": "^5.9.3",
"typescript": "^6.0.3",
"vitest": "^3.1.1"
},
"pnpm": {
@@ -99,4 +99,4 @@
"optionalDependencies": {
"unix-dgram": "^2.0.7"
}
}
}
+112 -118
View File
@@ -5,15 +5,15 @@ settings:
excludeLinksFromLockfile: false
overrides:
zigbee-herdsman: 10.0.5
zigbee-herdsman: 10.0.7
importers:
.:
dependencies:
ajv:
specifier: ^8.18.0
version: 8.18.0
specifier: ^8.20.0
version: 8.20.0
bind-decorator:
specifier: ^1.0.11
version: 1.0.11
@@ -21,8 +21,8 @@ importers:
specifier: ^3.0.0
version: 3.0.0
express-static-gzip:
specifier: ^3.0.0
version: 3.0.0
specifier: ^3.0.1
version: 3.0.1
fast-deep-equal:
specifier: ^3.1.3
version: 3.1.3
@@ -72,21 +72,21 @@ importers:
specifier: ^8.20.0
version: 8.20.0
zigbee-herdsman:
specifier: 10.0.5
version: 10.0.5
specifier: 10.0.7
version: 10.0.7
zigbee-herdsman-converters:
specifier: 26.27.0
version: 26.27.0
specifier: 26.46.0
version: 26.46.0
zigbee2mqtt-frontend:
specifier: 0.9.21
version: 0.9.21
zigbee2mqtt-windfront:
specifier: 2.11.1
version: 2.11.1
specifier: 2.11.2
version: 2.11.2
devDependencies:
'@biomejs/biome':
specifier: ^2.4.10
version: 2.4.10
specifier: ^2.4.14
version: 2.4.14
'@types/finalhandler':
specifier: ^1.2.3
version: 1.2.4
@@ -97,8 +97,8 @@ importers:
specifier: ^4.0.9
version: 4.0.9
'@types/node':
specifier: ^24.12.0
version: 24.12.0
specifier: ^24.12.2
version: 24.12.2
'@types/object-assign-deep':
specifier: ^0.4.3
version: 0.4.3
@@ -113,16 +113,16 @@ importers:
version: 8.18.1
'@vitest/coverage-v8':
specifier: ^3.1.1
version: 3.2.4(vitest@3.2.4(@types/node@24.12.0))
version: 3.2.4(vitest@3.2.4(@types/node@24.12.2))
tmp:
specifier: ^0.2.5
version: 0.2.5
typescript:
specifier: ^5.9.3
version: 5.9.3
specifier: ^6.0.3
version: 6.0.3
vitest:
specifier: ^3.1.1
version: 3.2.4(@types/node@24.12.0)
version: 3.2.4(@types/node@24.12.2)
optionalDependencies:
unix-dgram:
specifier: ^2.0.7
@@ -159,55 +159,55 @@ packages:
resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==}
engines: {node: '>=18'}
'@biomejs/biome@2.4.10':
resolution: {integrity: sha512-xxA3AphFQ1geij4JTHXv4EeSTda1IFn22ye9LdyVPoJU19fNVl0uzfEuhsfQ4Yue/0FaLs2/ccVi4UDiE7R30w==}
'@biomejs/biome@2.4.14':
resolution: {integrity: sha512-TmAvxOEgrpLypzVGJ8FulIZnlyA9TxrO1hyqYrCz9r+bwma9xXxuLA5IuYnj55XQneFx460KjRbx6SWGLkg3bQ==}
engines: {node: '>=14.21.3'}
hasBin: true
'@biomejs/cli-darwin-arm64@2.4.10':
resolution: {integrity: sha512-vuzzI1cWqDVzOMIkYyHbKqp+AkQq4K7k+UCXWpkYcY/HDn1UxdsbsfgtVpa40shem8Kax4TLDLlx8kMAecgqiw==}
'@biomejs/cli-darwin-arm64@2.4.14':
resolution: {integrity: sha512-XvgoE9XOawUOQPdmvs4J7wPhi/DLwSCGks3AlPJDmh34O0awRTqCED1HRcRDdpf1Zrp4us4MGOOdIxNpbqNF5Q==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [darwin]
'@biomejs/cli-darwin-x64@2.4.10':
resolution: {integrity: sha512-14fzASRo+BPotwp7nWULy2W5xeUyFnTaq1V13Etrrxkrih+ez/2QfgFm5Ehtf5vSjtgx/IJycMMpn5kPd5ZNaA==}
'@biomejs/cli-darwin-x64@2.4.14':
resolution: {integrity: sha512-jE7hKBCFhOx3uUh+ZkWBfOHxAcILPfhFplNkuID/eZeSTLHzfZzoZxW8fbqY9xXRnPi7jGNAf1iPVR+0yWsM/Q==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [darwin]
'@biomejs/cli-linux-arm64-musl@2.4.10':
resolution: {integrity: sha512-WrJY6UuiSD/Dh+nwK2qOTu8kdMDlLV3dLMmychIghHPAysWFq1/DGC1pVZx8POE3ZkzKR3PUUnVrtZfMfaJjyQ==}
'@biomejs/cli-linux-arm64-musl@2.4.14':
resolution: {integrity: sha512-/z+6gqAqqUQTHazwStxSXKHg9b8UvqBmDFRp+c4wYbq2KXhELQDon9EoC9RpmQ8JWkqQx/lIUy/cs+MhzDZp6A==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
'@biomejs/cli-linux-arm64@2.4.10':
resolution: {integrity: sha512-7MH1CMW5uuxQ/s7FLST63qF8B3Hgu2HRdZ7tA1X1+mk+St4JOuIrqdhIBnnyqeyWJNI+Bww7Es5QZ0wIc1Cmkw==}
'@biomejs/cli-linux-arm64@2.4.14':
resolution: {integrity: sha512-2TELhZnW5RSLL063l9rc5xLpA0ZIw0Ccwy/0q384rvNAgFw3yI76bd59547yxowdQr5MNPET/xDLrLuvgSeeWQ==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
'@biomejs/cli-linux-x64-musl@2.4.10':
resolution: {integrity: sha512-kDTi3pI6PBN6CiczsWYOyP2zk0IJI08EWEQyDMQWW221rPaaEz6FvjLhnU07KMzLv8q3qSuoB93ua6inSQ55Tw==}
'@biomejs/cli-linux-x64-musl@2.4.14':
resolution: {integrity: sha512-R6BWgJdQOwW9ulJatuTVrQkjnODjqHZkKNOqb1sz++3Noe5LYd0i3PchnOBUCYAPHoPWHhjJqbdZlHEu0hpjdA==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
'@biomejs/cli-linux-x64@2.4.10':
resolution: {integrity: sha512-tZLvEEi2u9Xu1zAqRjTcpIDGVtldigVvzug2fTuPG0ME/g8/mXpRPcNgLB22bGn6FvLJpHHnqLnwliOu8xjYrg==}
'@biomejs/cli-linux-x64@2.4.14':
resolution: {integrity: sha512-zHrlQZDBDUz4OLAraYpWKcnLS6HOewBFWYOzY91d1ZjdqZwibOyb6BEu6WuWLugyo0P3riCmsbV9UqV1cSXwQg==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
'@biomejs/cli-win32-arm64@2.4.10':
resolution: {integrity: sha512-umwQU6qPzH+ISTf/eHyJ/QoQnJs3V9Vpjz2OjZXe9MVBZ7prgGafMy7yYeRGnlmDAn87AKTF3Q6weLoMGpeqdQ==}
'@biomejs/cli-win32-arm64@2.4.14':
resolution: {integrity: sha512-M3EH5hqOI/F/FUA2u4xcLoUgmxd218mvuj/6JL7Hv2toQvr2/AdOvKSpGkoRuWFCtQPVa+ZqkEV3Q5xBA9+XSA==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [win32]
'@biomejs/cli-win32-x64@2.4.10':
resolution: {integrity: sha512-aW/JU5GuyH4uxMrNYpoC2kjaHlyJGLgIa3XkhPEZI0uKhZhJZU8BuEyJmvgzSPQNGozBwWjC972RaNdcJ9KyJg==}
'@biomejs/cli-win32-x64@2.4.14':
resolution: {integrity: sha512-WL0EG5qE+EAKomGXbf2g6VnSKJhTL3tXC0QRzWRwA5VpjxNYa6H4P7ZWfymbGE4IhZZQi1KXQ2R0YjwInmz2fA==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [win32]
@@ -553,8 +553,8 @@ packages:
'@types/js-yaml@4.0.9':
resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==}
'@types/node@24.12.0':
resolution: {integrity: sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==}
'@types/node@24.12.2':
resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==}
'@types/object-assign-deep@0.4.3':
resolution: {integrity: sha512-d9Gxaj5j1hzrxJ61EFEg13B4g4FgrT/DYtcDWFXPehR8DF2SUZbVMFtZIs8exkVRiqrqBpdTc/lUUZjncsPpMw==}
@@ -613,8 +613,8 @@ packages:
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
engines: {node: '>=6.5'}
ajv@8.18.0:
resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==}
ajv@8.20.0:
resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==}
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
@@ -824,8 +824,8 @@ packages:
resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==}
engines: {node: '>=12.0.0'}
express-static-gzip@3.0.0:
resolution: {integrity: sha512-36O10S0asHl3QojOBQQ0ZjXNtElmhgPS6erSUCCZymXkB/CK1mnGqOj4BTJN+FYRDIzVFnzo3wLFCZJvAk6rQQ==}
express-static-gzip@3.0.1:
resolution: {integrity: sha512-LMeU/3YjFlFUa4vrPX+RoMMRW5mIpF4Iysgs6gX7A59WCY4BzyF3O28mBr4eMlWuW4DU9wVAVuVcfx29ln1N6g==}
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
@@ -894,8 +894,8 @@ packages:
html-escaper@2.0.2:
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
http-errors@2.0.0:
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
http-errors@2.0.1:
resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==}
engines: {node: '>= 0.8'}
humanize-duration@3.33.2:
@@ -1008,9 +1008,9 @@ packages:
resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
engines: {node: '>= 0.6'}
mime-types@3.0.1:
resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==}
engines: {node: '>= 0.6'}
mime-types@3.0.2:
resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==}
engines: {node: '>=18'}
minimatch@10.2.0:
resolution: {integrity: sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==}
@@ -1169,12 +1169,12 @@ packages:
engines: {node: '>=10'}
hasBin: true
send@1.2.0:
resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==}
send@1.2.1:
resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==}
engines: {node: '>= 18'}
serve-static@2.2.0:
resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==}
serve-static@2.2.1:
resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==}
engines: {node: '>= 18'}
setimmediate@1.0.5:
@@ -1230,10 +1230,6 @@ packages:
stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
statuses@2.0.1:
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
engines: {node: '>= 0.8'}
statuses@2.0.2:
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
engines: {node: '>= 0.8'}
@@ -1324,8 +1320,8 @@ packages:
typedarray@0.0.6:
resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
typescript@5.9.3:
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
typescript@6.0.3:
resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==}
engines: {node: '>=14.17'}
hasBin: true
@@ -1472,12 +1468,12 @@ packages:
utf-8-validate:
optional: true
zigbee-herdsman-converters@26.27.0:
resolution: {integrity: sha512-l0Tc/TBRML5lO298NRxr2CtKcQ5YxA96FINJuifyGGG62mANSa+UmAcvl0P/fnPo8r7q8wdCYxXrb/7lYILZKA==}
zigbee-herdsman-converters@26.46.0:
resolution: {integrity: sha512-RFRQQoxGrz8si/wsFOPMdFXF1ppO0mQxU9cyRvzT98HV4bL3dnUKEWIdo6caCllLn6izA5kdob9vtxXqruU/SQ==}
engines: {node: '>=20.15.0'}
zigbee-herdsman@10.0.5:
resolution: {integrity: sha512-zCXpvzTxQ9pkuYpMV6PVb6gX8AUGpl99ut80Q96bWCqXKHNnkbn1wwrpdaXuvGhoWVB8En9hp8ZnipbF9sODEw==}
zigbee-herdsman@10.0.7:
resolution: {integrity: sha512-QqKJaJryWf7IUuVNV6Dc1/qNPrs2dJANPJhRTG74nZBAsyIDn/vSyCP7g19fuEM7Cphr/0ZgCJZkHP2wKvNPMw==}
zigbee-on-host@0.2.4:
resolution: {integrity: sha512-NIG6CWp+Yfn7PjqEIRvenHqpwT1U7rSkyimnFOUIFpnmxQOJKrmcwWDfn6WjbU/YIYYWSQPlj+g13icu1xwlyg==}
@@ -1487,8 +1483,8 @@ packages:
resolution: {integrity: sha512-ClHYlG7g0v/tnIsD6kycNCi1ZEKIbQuU7lGJR3WqYcDmuqEMVcHDGbRiRwYRQcZGMxkqCf7guxNsXiKnC10+kg==}
engines: {node: '>=20.11'}
zigbee2mqtt-windfront@2.11.1:
resolution: {integrity: sha512-2xM01JnuCWZlb1xYkIBVFAGJ6mkuAq/DRi8kfmB8KlA77LzHuX+f85pdgDotF9WGWb4+TqxmnpifYri1Nc3K2A==}
zigbee2mqtt-windfront@2.11.2:
resolution: {integrity: sha512-NzuPB8VHZsuumb3euxX73fXtM+neLCgabhBUM1UoVHubF//w9afe6Wuws2e1W59yOSd03lAn9/Bkmt6sgDgjwQ==}
engines: {node: '>=22.12.0'}
snapshots:
@@ -1515,39 +1511,39 @@ snapshots:
'@bcoe/v8-coverage@1.0.2': {}
'@biomejs/biome@2.4.10':
'@biomejs/biome@2.4.14':
optionalDependencies:
'@biomejs/cli-darwin-arm64': 2.4.10
'@biomejs/cli-darwin-x64': 2.4.10
'@biomejs/cli-linux-arm64': 2.4.10
'@biomejs/cli-linux-arm64-musl': 2.4.10
'@biomejs/cli-linux-x64': 2.4.10
'@biomejs/cli-linux-x64-musl': 2.4.10
'@biomejs/cli-win32-arm64': 2.4.10
'@biomejs/cli-win32-x64': 2.4.10
'@biomejs/cli-darwin-arm64': 2.4.14
'@biomejs/cli-darwin-x64': 2.4.14
'@biomejs/cli-linux-arm64': 2.4.14
'@biomejs/cli-linux-arm64-musl': 2.4.14
'@biomejs/cli-linux-x64': 2.4.14
'@biomejs/cli-linux-x64-musl': 2.4.14
'@biomejs/cli-win32-arm64': 2.4.14
'@biomejs/cli-win32-x64': 2.4.14
'@biomejs/cli-darwin-arm64@2.4.10':
'@biomejs/cli-darwin-arm64@2.4.14':
optional: true
'@biomejs/cli-darwin-x64@2.4.10':
'@biomejs/cli-darwin-x64@2.4.14':
optional: true
'@biomejs/cli-linux-arm64-musl@2.4.10':
'@biomejs/cli-linux-arm64-musl@2.4.14':
optional: true
'@biomejs/cli-linux-arm64@2.4.10':
'@biomejs/cli-linux-arm64@2.4.14':
optional: true
'@biomejs/cli-linux-x64-musl@2.4.10':
'@biomejs/cli-linux-x64-musl@2.4.14':
optional: true
'@biomejs/cli-linux-x64@2.4.10':
'@biomejs/cli-linux-x64@2.4.14':
optional: true
'@biomejs/cli-win32-arm64@2.4.10':
'@biomejs/cli-win32-arm64@2.4.14':
optional: true
'@biomejs/cli-win32-x64@2.4.10':
'@biomejs/cli-win32-x64@2.4.14':
optional: true
'@colors/colors@1.6.0': {}
@@ -1770,7 +1766,7 @@ snapshots:
'@types/finalhandler@1.2.4':
dependencies:
'@types/node': 24.12.0
'@types/node': 24.12.2
'@types/http-errors@2.0.5': {}
@@ -1778,7 +1774,7 @@ snapshots:
'@types/js-yaml@4.0.9': {}
'@types/node@24.12.0':
'@types/node@24.12.2':
dependencies:
undici-types: 7.16.0
@@ -1786,20 +1782,20 @@ snapshots:
'@types/readable-stream@4.0.23':
dependencies:
'@types/node': 24.12.0
'@types/node': 24.12.2
'@types/serve-static@2.2.0':
dependencies:
'@types/http-errors': 2.0.5
'@types/node': 24.12.0
'@types/node': 24.12.2
'@types/triple-beam@1.3.5': {}
'@types/ws@8.18.1':
dependencies:
'@types/node': 24.12.0
'@types/node': 24.12.2
'@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/node@24.12.0))':
'@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/node@24.12.2))':
dependencies:
'@ampproject/remapping': 2.3.0
'@bcoe/v8-coverage': 1.0.2
@@ -1814,7 +1810,7 @@ snapshots:
std-env: 3.9.0
test-exclude: 7.0.1
tinyrainbow: 2.0.0
vitest: 3.2.4(@types/node@24.12.0)
vitest: 3.2.4(@types/node@24.12.2)
transitivePeerDependencies:
- supports-color
@@ -1826,13 +1822,13 @@ snapshots:
chai: 5.2.0
tinyrainbow: 2.0.0
'@vitest/mocker@3.2.4(vite@6.3.5(@types/node@24.12.0))':
'@vitest/mocker@3.2.4(vite@6.3.5(@types/node@24.12.2))':
dependencies:
'@vitest/spy': 3.2.4
estree-walker: 3.0.3
magic-string: 0.30.17
optionalDependencies:
vite: 6.3.5(@types/node@24.12.0)
vite: 6.3.5(@types/node@24.12.2)
'@vitest/pretty-format@3.2.4':
dependencies:
@@ -1864,7 +1860,7 @@ snapshots:
dependencies:
event-target-shim: 5.0.1
ajv@8.18.0:
ajv@8.20.0:
dependencies:
fast-deep-equal: 3.1.3
fast-uri: 3.1.0
@@ -2070,11 +2066,11 @@ snapshots:
expect-type@1.2.1: {}
express-static-gzip@3.0.0:
express-static-gzip@3.0.1:
dependencies:
mime-types: 3.0.1
mime-types: 3.0.2
parseurl: 1.3.3
serve-static: 2.2.0
serve-static: 2.2.1
transitivePeerDependencies:
- supports-color
@@ -2142,12 +2138,12 @@ snapshots:
html-escaper@2.0.2: {}
http-errors@2.0.0:
http-errors@2.0.1:
dependencies:
depd: 2.0.0
inherits: 2.0.4
setprototypeof: 1.2.0
statuses: 2.0.1
statuses: 2.0.2
toidentifier: 1.0.1
humanize-duration@3.33.2: {}
@@ -2259,7 +2255,7 @@ snapshots:
mime-db@1.54.0: {}
mime-types@3.0.1:
mime-types@3.0.2:
dependencies:
mime-db: 1.54.0
@@ -2446,15 +2442,15 @@ snapshots:
semver@7.7.4: {}
send@1.2.0:
send@1.2.1:
dependencies:
debug: 4.4.3
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
fresh: 2.0.0
http-errors: 2.0.0
mime-types: 3.0.1
http-errors: 2.0.1
mime-types: 3.0.2
ms: 2.1.3
on-finished: 2.4.1
range-parser: 1.2.1
@@ -2462,12 +2458,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
serve-static@2.2.0:
serve-static@2.2.1:
dependencies:
encodeurl: 2.0.0
escape-html: 1.0.3
parseurl: 1.3.3
send: 1.2.0
send: 1.2.1
transitivePeerDependencies:
- supports-color
@@ -2509,8 +2505,6 @@ snapshots:
stackback@0.0.2: {}
statuses@2.0.1: {}
statuses@2.0.2: {}
std-env@3.9.0: {}
@@ -2588,7 +2582,7 @@ snapshots:
typedarray@0.0.6: {}
typescript@5.9.3: {}
typescript@6.0.3: {}
undici-types@7.16.0: {}
@@ -2606,13 +2600,13 @@ snapshots:
util-deprecate@1.0.2: {}
vite-node@3.2.4(@types/node@24.12.0):
vite-node@3.2.4(@types/node@24.12.2):
dependencies:
cac: 6.7.14
debug: 4.4.3
es-module-lexer: 1.7.0
pathe: 2.0.3
vite: 6.3.5(@types/node@24.12.0)
vite: 6.3.5(@types/node@24.12.2)
transitivePeerDependencies:
- '@types/node'
- jiti
@@ -2627,7 +2621,7 @@ snapshots:
- tsx
- yaml
vite@6.3.5(@types/node@24.12.0):
vite@6.3.5(@types/node@24.12.2):
dependencies:
esbuild: 0.25.5
fdir: 6.4.6(picomatch@4.0.2)
@@ -2636,14 +2630,14 @@ snapshots:
rollup: 4.44.0
tinyglobby: 0.2.14
optionalDependencies:
'@types/node': 24.12.0
'@types/node': 24.12.2
fsevents: 2.3.3
vitest@3.2.4(@types/node@24.12.0):
vitest@3.2.4(@types/node@24.12.2):
dependencies:
'@types/chai': 5.2.2
'@vitest/expect': 3.2.4
'@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@24.12.0))
'@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@24.12.2))
'@vitest/pretty-format': 3.2.4
'@vitest/runner': 3.2.4
'@vitest/snapshot': 3.2.4
@@ -2661,11 +2655,11 @@ snapshots:
tinyglobby: 0.2.14
tinypool: 1.1.1
tinyrainbow: 2.0.0
vite: 6.3.5(@types/node@24.12.0)
vite-node: 3.2.4(@types/node@24.12.0)
vite: 6.3.5(@types/node@24.12.2)
vite-node: 3.2.4(@types/node@24.12.2)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 24.12.0
'@types/node': 24.12.2
transitivePeerDependencies:
- jiti
- less
@@ -2759,15 +2753,15 @@ snapshots:
ws@8.20.0: {}
zigbee-herdsman-converters@26.27.0:
zigbee-herdsman-converters@26.46.0:
dependencies:
iconv-lite: 0.7.2
semver: 7.7.4
zigbee-herdsman: 10.0.5
zigbee-herdsman: 10.0.7
transitivePeerDependencies:
- supports-color
zigbee-herdsman@10.0.5:
zigbee-herdsman@10.0.7:
dependencies:
'@date-fns/tz': 1.4.1
'@serialport/bindings-cpp': 13.0.1
@@ -2785,4 +2779,4 @@ snapshots:
zigbee2mqtt-frontend@0.9.21: {}
zigbee2mqtt-windfront@2.11.1: {}
zigbee2mqtt-windfront@2.11.2: {}
+61 -10
View File
@@ -735,7 +735,7 @@ describe("Extension: Bridge", () => {
values: ["off", "on", "toggle", "previous"],
},
{
access: 2,
access: 3,
label: "Effect",
name: "effect",
property: "effect",
@@ -748,11 +748,41 @@ describe("Extension: Bridge", () => {
"candle",
"fireplace",
"colorloop",
"sunset",
"sunrise",
"sparkle",
"opal",
"glisten",
"underwater",
"cosmos",
"sunbeam",
"enchant",
"none",
"finish_effect",
"stop_effect",
"stop_hue_effect",
],
},
{
access: 3,
description: "Animation speed for the active effect (0=slowest, 1=fastest)",
label: "Effect speed",
name: "effect_speed",
property: "effect_speed",
type: "numeric",
value_max: 1,
value_min: 0,
value_step: 0.01,
},
{
access: 2,
description:
'Set the base color of the active effect without stopping it (hex e.g. #FF4400, or JSON {"x":0.6,"y":0.3})',
label: "Effect color",
name: "effect_color",
property: "effect_color",
type: "text",
},
{
access: 1,
category: "diagnostic",
@@ -768,6 +798,27 @@ describe("Extension: Bridge", () => {
],
model: "7146060PH",
options: [
{
access: 2,
description:
"Control this light using a Philips-specific protocol instead of standard Zigbee commands. When enabled, on/off, brightness, color, and color temperature are combined into single atomic commands. This is required to use the Effect color update mode. When disabled (default), standard Zigbee commands are used, which preserves the usual behavior, including simulating on/off transitions.",
label: "Hue native control",
name: "hue_native_control",
property: "hue_native_control",
type: "binary",
value_off: false,
value_on: true,
},
{
access: 2,
description:
"Controls what happens when color is changed while an effect is active (requires Hue native control). 'stop' (default): color change stops the effect (Hue app behavior). 'update': color change re-sends the effect with the new color.",
label: "Effect color mode",
name: "effect_color_mode",
property: "effect_color_mode",
type: "enum",
values: ["stop", "update"],
},
{
access: 2,
description:
@@ -781,21 +832,21 @@ describe("Extension: Bridge", () => {
},
{
access: 2,
description:
"When enabled colors will be synced, e.g. if the light supports both color x/y and color temperature a conversion from color x/y to color temperature will be done when setting the x/y color (default true).",
label: "Color sync",
name: "color_sync",
property: "color_sync",
description: "State actions will also be published as 'action' when true (default false).",
label: "State action",
name: "state_action",
property: "state_action",
type: "binary",
value_off: false,
value_on: true,
},
{
access: 2,
description: "State actions will also be published as 'action' when true (default false).",
label: "State action",
name: "state_action",
property: "state_action",
description:
"When enabled colors will be synced, e.g. if the light supports both color x/y and color temperature a conversion from color x/y to color temperature will be done when setting the x/y color (default true).",
label: "Color sync",
name: "color_sync",
property: "color_sync",
type: "binary",
value_off: false,
value_on: true,
+6
View File
@@ -245,6 +245,8 @@ describe("Extension: Frontend", () => {
stringify({
state: "ON",
effect: null,
effect_color: null,
effect_speed: null,
power_on_behavior: null,
linkquality: 20,
update: {state: null, installed_version: -1, latest_version: -1},
@@ -269,6 +271,8 @@ describe("Extension: Frontend", () => {
state: "ON",
power_on_behavior: null,
effect: null,
effect_color: null,
effect_speed: null,
linkquality: 20,
update: {state: null, installed_version: -1, latest_version: -1},
},
@@ -296,6 +300,8 @@ describe("Extension: Frontend", () => {
brightness: 90,
power_on_behavior: null,
effect: null,
effect_color: null,
effect_speed: null,
linkquality: 20,
update: {state: null, installed_version: -1, latest_version: -1},
},
+53 -1
View File
@@ -103,6 +103,7 @@ describe("Extension: HomeAssistant", () => {
definition: d,
isDevice: (): boolean => true,
isGroup: (): boolean => false,
endpoint: () => undefined,
options: {},
exposes: (): unknown[] => exposes,
zh: {endpoints: []},
@@ -124,7 +125,7 @@ describe("Extension: HomeAssistant", () => {
}
}
expect(duplicated).toHaveLength(0);
expect(duplicated).toStrictEqual([]);
});
it("Should discover devices and groups", async () => {
@@ -163,6 +164,16 @@ describe("Extension: HomeAssistant", () => {
"candle",
"fireplace",
"colorloop",
"sunset",
"sunrise",
"sparkle",
"opal",
"glisten",
"underwater",
"cosmos",
"sunbeam",
"enchant",
"none",
"finish_effect",
"stop_effect",
"stop_hue_effect",
@@ -170,6 +181,7 @@ describe("Extension: HomeAssistant", () => {
object_id: "ha_discovery_group",
default_entity_id: "light.ha_discovery_group",
unique_id: "9_light_zigbee2mqtt",
group: ["0x000b57fffec6a5b4_light_zigbee2mqtt", "0x000b57fffec6a5b7_light_zigbee2mqtt"],
origin: origin,
};
@@ -225,6 +237,7 @@ describe("Extension: HomeAssistant", () => {
object_id: "ha_discovery_group",
default_entity_id: "switch.ha_discovery_group",
unique_id: "9_switch_zigbee2mqtt",
group: ["0x0017880104e45542_switch_right_zigbee2mqtt"],
origin: origin,
value_template: "{{ value_json.state }}",
};
@@ -1558,6 +1571,8 @@ describe("Extension: HomeAssistant", () => {
color: {hue: 0, saturation: 100, h: 0, s: 100},
color_mode: "hs",
effect: null,
effect_color: null,
effect_speed: null,
linkquality: null,
state: null,
power_on_behavior: null,
@@ -1581,6 +1596,8 @@ describe("Extension: HomeAssistant", () => {
color: {x: 0.4576, y: 0.41},
color_mode: "xy",
effect: null,
effect_color: null,
effect_speed: null,
linkquality: null,
state: null,
power_on_behavior: null,
@@ -1603,6 +1620,8 @@ describe("Extension: HomeAssistant", () => {
stringify({
linkquality: null,
effect: null,
effect_color: null,
effect_speed: null,
state: "ON",
power_on_behavior: null,
update: {state: null, installed_version: -1, latest_version: -1},
@@ -1965,6 +1984,16 @@ describe("Extension: HomeAssistant", () => {
"candle",
"fireplace",
"colorloop",
"sunset",
"sunrise",
"sparkle",
"opal",
"glisten",
"underwater",
"cosmos",
"sunbeam",
"enchant",
"none",
"finish_effect",
"stop_effect",
"stop_hue_effect",
@@ -1972,6 +2001,7 @@ describe("Extension: HomeAssistant", () => {
object_id: "ha_discovery_group_new",
default_entity_id: "light.ha_discovery_group_new",
unique_id: "9_light_zigbee2mqtt",
group: ["0x000b57fffec6a5b4_light_zigbee2mqtt", "0x000b57fffec6a5b7_light_zigbee2mqtt"],
origin: origin,
};
@@ -2434,6 +2464,16 @@ describe("Extension: HomeAssistant", () => {
"candle",
"fireplace",
"colorloop",
"sunset",
"sunrise",
"sparkle",
"opal",
"glisten",
"underwater",
"cosmos",
"sunbeam",
"enchant",
"none",
"finish_effect",
"stop_effect",
"stop_hue_effect",
@@ -2441,6 +2481,7 @@ describe("Extension: HomeAssistant", () => {
object_id: "ha_discovery_group",
default_entity_id: "light.ha_discovery_group",
unique_id: "9_light_zigbee2mqtt",
group: ["0x000b57fffec6a5b4_light_zigbee2mqtt", "0x000b57fffec6a5b7_light_zigbee2mqtt"],
origin: origin,
};
@@ -2479,6 +2520,16 @@ describe("Extension: HomeAssistant", () => {
"candle",
"fireplace",
"colorloop",
"sunset",
"sunrise",
"sparkle",
"opal",
"glisten",
"underwater",
"cosmos",
"sunbeam",
"enchant",
"none",
"finish_effect",
"stop_effect",
"stop_hue_effect",
@@ -2486,6 +2537,7 @@ describe("Extension: HomeAssistant", () => {
object_id: "ha_discovery_group",
default_entity_id: "light.ha_discovery_group",
unique_id: "9_light_zigbee2mqtt",
group: ["0x000b57fffec6a5b4_light_zigbee2mqtt", "0x000b57fffec6a5b7_light_zigbee2mqtt"],
origin: origin,
};
+3 -3
View File
@@ -286,7 +286,7 @@ describe("Extension: NetworkMap", () => {
description: "Hue Go",
model: "7146060PH",
supports:
"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, linkquality",
"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, effect_speed, effect_color, linkquality",
vendor: "Philips",
},
failed: [],
@@ -616,7 +616,7 @@ describe("Extension: NetworkMap", () => {
description: "Hue Go",
model: "7146060PH",
supports:
"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, linkquality",
"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, effect_speed, effect_color, linkquality",
vendor: "Philips",
},
failed: [],
@@ -785,7 +785,7 @@ describe("Extension: NetworkMap", () => {
description: "Hue Go",
model: "7146060PH",
supports:
"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, linkquality",
"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, effect_speed, effect_color, linkquality",
vendor: "Philips",
},
failed: [],
-1
View File
@@ -11,7 +11,6 @@
"declaration": true,
"declarationMap": true,
"outDir": "dist",
"baseUrl": ".",
"rootDir": "lib",
"inlineSourceMap": true,
"resolveJsonModule": true,