From b441091f6fd51dbd77f0c75d17064ea19adc8dd8 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 28 Aug 2026 21:12:23 +0300 Subject: [PATCH] fix: Warn when setting unsupported device option (#32928) --- lib/extension/bridge.ts | 14 ++++++++++++++ test/extensions/bridge.test.ts | 30 ++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/lib/extension/bridge.ts b/lib/extension/bridge.ts index 8a2d4b7bd..5e5eae906 100644 --- a/lib/extension/bridge.ts +++ b/lib/extension/bridge.ts @@ -466,6 +466,20 @@ export default class Bridge extends Extension { const ID = message.id; const entity = this.getEntity(entityType, ID); + + if (entity instanceof Device) { + const supportedOptions = new Set(Object.keys(settings.schemaJson.definitions.device.properties)); + for (const option of entity.definition?.options ?? []) { + supportedOptions.add(option.property); + } + + for (const option of Object.keys(message.options)) { + if (!supportedOptions.has(option)) { + logger.warning(`Device '${ID}' does not support option '${option}'`); + } + } + } + const oldOptions = objectAssignDeep({}, cleanup(entity.options)); if (message.options.icon) { diff --git a/test/extensions/bridge.test.ts b/test/extensions/bridge.test.ts index e26ad1e3f..120ff586b 100644 --- a/test/extensions/bridge.test.ts +++ b/test/extensions/bridge.test.ts @@ -3624,6 +3624,36 @@ describe("Extension: Bridge", () => { ); }); + it("Should warn on unsupported device option", async () => { + mockMQTTPublishAsync.mockClear(); + mockLogger.warning.mockClear(); + + const device = controller.zigbee.resolveEntity(devices.bulb.ieeeAddr); + assert(device && "definition" in device); + const definitionOptions = device.definition?.options; + device.definition!.options = undefined; + + mockMQTTEvents.message("zigbee2mqtt/bridge/request/device/options", stringify({options: {unsupported: true}, id: "bulb"})); + await flushPromises(); + device.definition!.options = definitionOptions; + + expect(settings.getDevice("bulb")).toHaveProperty("unsupported"); + expect(mockLogger.warning).toHaveBeenCalledWith("Device 'bulb' does not support option 'unsupported'"); + expect(mockMQTTPublishAsync).toHaveBeenCalledWith( + "zigbee2mqtt/bridge/response/device/options", + stringify({ + data: { + from: {retain: true, description: "this is my bulb"}, + to: {retain: true, description: "this is my bulb", unsupported: true}, + id: "bulb", + restart_required: false, + }, + status: "ok", + }), + {}, + ); + }); + it("Should allow to add group by string", async () => { mockMQTTPublishAsync.mockClear(); mockMQTTEvents.message("zigbee2mqtt/bridge/request/group/add", "group_193");