From 75a030eed68cbfeb5e414b8c97811262d23aa55e Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 1 Nov 2026 13:40:31 +0000 Subject: [PATCH] feat: resolve the Lock Ultra and Permanent Outdoor Lights OpenAPI device types SwitchBotAPI documents two deviceType strings that did not resolve to a class: - "Lock Ultra": the deviceType the Lock Ultra status response reports (the device list says "Smart Lock Ultra", already mapped). Maps to WoSmartLockPro. - "Permanent Outdoor Lights": same commands as the RGBICWW Strip Light (turnOn/turnOff/toggle, setBrightness, setColor, setColorTemperature). Maps to WoRGBICWWStripLight. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01LzktUt9rqfrSfRydbWruTR --- src/settings.ts | 3 +++ test/devices/openapi-commands.test.ts | 25 +++++++++++++++++++++++ test/types/device-type-resolution.test.ts | 2 ++ 3 files changed, 30 insertions(+) diff --git a/src/settings.ts b/src/settings.ts index dd37e004..901dbf9a 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -316,6 +316,7 @@ export const DEVICE_CLASS_MAP: Record = { 'Smart Lock Pro': 'WoSmartLockPro', 'Smart Lock Pro Wifi': 'WoSmartLockProWiFi', 'Smart Lock Ultra': 'WoSmartLockPro', + 'Lock Ultra': 'WoSmartLockPro', // deviceType in the Lock Ultra status response 'Lock Vision': 'WoSmartLockVision', 'Lock Vision Pro': 'WoSmartLockVisionPro', 'Keypad': 'WoKeypad', @@ -337,6 +338,8 @@ export const DEVICE_CLASS_MAP: Record = { 'SwitchBot Floor Lamp': 'WoFloorLamp', 'RGBICWW Strip Light': 'WoRGBICWWStripLight', 'SwitchBot RGBICWW Strip Light': 'WoRGBICWWStripLight', + // Same OpenAPI commands as the RGBICWW Strip Light: turnOn/turnOff/toggle, setBrightness, setColor, setColorTemperature + 'Permanent Outdoor Lights': 'WoRGBICWWStripLight', 'RGBICWW Floor Lamp': 'WoRGBICWWFloorLamp', 'SwitchBot RGBICWW Floor Lamp': 'WoRGBICWWFloorLamp', 'Art Frame': 'WoArtFrame', diff --git a/test/devices/openapi-commands.test.ts b/test/devices/openapi-commands.test.ts index f2a1a06e..d5ccaf37 100644 --- a/test/devices/openapi-commands.test.ts +++ b/test/devices/openapi-commands.test.ts @@ -73,6 +73,31 @@ describe('openAPI commands', () => { expect(calls()).toEqual([['setColor', '255:128:0']]) }) + // devices/lighting/permanent-outdoor-lights.md + it('permanent Outdoor Lights send the documented light commands', async () => { + const { device, calls } = await apiDevice('Permanent Outdoor Lights') + await device.turnOn() + await device.turnOff() + await device.setBrightness(40) + await device.setColorTemperature(2700) + await device.setColor(255, 128, 0) + expect(calls()).toEqual([ + ['turnOn', undefined], + ['turnOff', undefined], + ['setBrightness', 40], + ['setColorTemperature', 2700], + ['setColor', '255:128:0'], + ]) + }) + + // devices/locks-security/lock-ultra.md: the status response reports deviceType "Lock Ultra" + it('lock Ultra sends lock and unlock', async () => { + const { device, calls } = await apiDevice('Lock Ultra') + await device.lock() + await device.unlock() + expect(calls()).toEqual([['lock', undefined], ['unlock', undefined]]) + }) + it('color Bulb sends setColorTemperature in kelvin', async () => { const { device, calls } = await apiDevice('Color Bulb') await device.setColorTemp(2700, 6500, 4000) diff --git a/test/types/device-type-resolution.test.ts b/test/types/device-type-resolution.test.ts index 27849402..78cd9cad 100644 --- a/test/types/device-type-resolution.test.ts +++ b/test/types/device-type-resolution.test.ts @@ -62,6 +62,8 @@ describe('openAPI deviceType names', () => { ['Smart Lock Pro', 'WoSmartLockPro'], ['Smart Lock Pro Wifi', 'WoSmartLockProWiFi'], ['Smart Lock Ultra', 'WoSmartLockPro'], + ['Lock Ultra', 'WoSmartLockPro'], + ['Permanent Outdoor Lights', 'WoRGBICWWStripLight'], ['Air Purifier VOC', 'WoAirPurifier'], ['Air Purifier Table PM2.5', 'WoAirPurifierTable'], ['Air Purifier Table VOC', 'WoAirPurifierTable'],