fix: Fix bind/unbind by coordinator ieeeAddr not working (#27333)

Co-authored-by: bo0tzz <git@bo0tzz.me>
This commit is contained in:
Koen Kanters
2025-05-07 21:15:05 +02:00
committed by GitHub
co-authored by bo0tzz
parent 7a4f2869b9
commit d8855b8e6f
5 changed files with 33 additions and 9 deletions
+5 -2
View File
@@ -198,7 +198,7 @@ interface ParsedMQTTMessage {
type: "bind" | "unbind";
sourceKey?: string;
sourceEndpointKey?: string | number;
targetKey?: string;
targetKey?: string | number;
targetEndpointKey?: string | number;
clusters?: string[];
skipDisableReporting: boolean;
@@ -242,7 +242,10 @@ export default class Bind extends Extension {
return [message, {type, skipDisableReporting}, `Source device '${message.from}' does not exist`];
}
const resolvedTarget = message.to === DEFAULT_BIND_GROUP.name ? DEFAULT_BIND_GROUP : this.zigbee.resolveEntity(message.to);
const resolvedTarget =
message.to === DEFAULT_BIND_GROUP.name || message.to === DEFAULT_BIND_GROUP.ID
? DEFAULT_BIND_GROUP
: this.zigbee.resolveEntity(message.to);
if (!resolvedTarget) {
return [message, {type, skipDisableReporting}, `Target device or group '${message.to}' does not exist`];
+4 -4
View File
@@ -474,7 +474,7 @@ export interface Zigbee2MQTTAPI {
"bridge/request/device/bind": {
from: string;
from_endpoint: string | number | "default";
to: string;
to: string | number;
to_endpoint?: string | number;
clusters?: string[];
skip_disable_reporting?: boolean;
@@ -483,7 +483,7 @@ export interface Zigbee2MQTTAPI {
"bridge/response/device/bind": {
from: string;
from_endpoint: string | number;
to: string;
to: string | number;
to_endpoint: string | number | undefined;
clusters: string[];
failed: string[];
@@ -492,7 +492,7 @@ export interface Zigbee2MQTTAPI {
"bridge/request/device/unbind": {
from: string;
from_endpoint: string | number | "default";
to: string;
to: string | number;
to_endpoint?: string | number;
clusters?: string[];
skip_disable_reporting?: boolean;
@@ -501,7 +501,7 @@ export interface Zigbee2MQTTAPI {
"bridge/response/device/unbind": {
from: string;
from_endpoint: string | number;
to: string;
to: string | number;
to_endpoint: string | number | undefined;
clusters: string[];
failed: string[];
+4 -2
View File
@@ -23,6 +23,7 @@ export default class Zigbee {
private eventBus: EventBus;
private groupLookup = new Map<number /* group ID */, Group>();
private deviceLookup = new Map<string /* IEEE address */, Device>();
private coordinatorIeeeAddr!: string;
constructor(eventBus: EventBus) {
this.eventBus = eventBus;
@@ -73,6 +74,7 @@ export default class Zigbee {
throw error;
}
this.coordinatorIeeeAddr = this.herdsman.getDevicesByType("Coordinator")[0].ieeeAddr;
await this.resolveDevicesDefinitions();
this.herdsman.on("adapterDisconnected", () => this.eventBus.emitAdapterDisconnected());
@@ -280,8 +282,8 @@ export default class Zigbee {
return this.resolveDevice(key.ieeeAddr);
}
if (typeof key === "string" && key.toLowerCase() === "coordinator") {
return this.resolveDevice(this.herdsman.getDevicesByType("Coordinator")[0].ieeeAddr);
if (typeof key === "string" && (key.toLowerCase() === "coordinator" || key === this.coordinatorIeeeAddr)) {
return this.resolveDevice(this.coordinatorIeeeAddr);
}
const settingsDevice = settings.getDevice(key.toString());
+19
View File
@@ -281,6 +281,25 @@ describe("Extension: Bind", () => {
);
});
it("Should allow to bind to coordinator by ieeeAddr", async () => {
const device = devices.remote;
const target = devices.coordinator.getEndpoint(1)!;
const endpoint = device.getEndpoint(1)!;
mockClear(device);
mockMQTTEvents.message(
"zigbee2mqtt/bridge/request/device/bind",
stringify({from: "remote", to: devices.coordinator.ieeeAddr, clusters: ["genOnOff"]}),
);
await flushPromises();
expect(endpoint.bind).toHaveBeenCalledTimes(1);
expect(endpoint.bind).toHaveBeenCalledWith("genOnOff", target);
expect(mockMQTTPublishAsync).toHaveBeenCalledWith(
"zigbee2mqtt/bridge/response/device/bind",
stringify({data: {from: "remote", from_endpoint: "default", to: "0x00124b00120144ae", clusters: ["genOnOff"], failed: []}, status: "ok"}),
{},
);
});
it("Should log error when there is nothing to bind", async () => {
const device = devices.bulb_color;
const endpoint = device.getEndpoint(1)!;
+1 -1
View File
@@ -18,7 +18,7 @@ import * as settings from "../../lib/util/settings";
const mocksClear = [mockMQTTPublishAsync, mockLogger.warning, mockLogger.debug];
returnDevices.push(devices.bulb.ieeeAddr, devices.LIVOLO.ieeeAddr);
returnDevices.push(devices.bulb.ieeeAddr, devices.LIVOLO.ieeeAddr, devices.coordinator.ieeeAddr);
describe("Extension: OnEvent", () => {
let controller: Controller;