@switchbot/homebridge-switchbot 5.0.0-beta.93 → 5.0.0-beta.95

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -764,14 +764,44 @@ export class HumidifierDevice extends GenericDevice {
764
764
  return {
765
765
  services: [
766
766
  {
767
- type: 'HumiditySensor',
767
+ type: 'HumidifierDehumidifier',
768
768
  characteristics: {
769
+ Active: {
770
+ get: async () => {
771
+ const s = await this.getState()
772
+ return s && s.on ? 1 : 0
773
+ },
774
+ set: async (v: any) => {
775
+ await this.setState({ on: v === 1 })
776
+ },
777
+ },
778
+ CurrentHumidifierDehumidifierState: {
779
+ get: async () => {
780
+ const s = await this.getState()
781
+ return s && s.on ? 2 : 0 // 0 = Inactive, 2 = Humidifying
782
+ },
783
+ },
784
+ TargetHumidifierDehumidifierState: {
785
+ get: async () => 1, // 1 = Humidifier
786
+ set: async (v: any) => {
787
+ // Support humidifier mode
788
+ },
789
+ },
769
790
  CurrentRelativeHumidity: {
770
791
  get: async () => {
771
792
  const s = await this.getState()
772
793
  return typeof s.humidity === 'number' ? s.humidity : 0
773
794
  },
774
795
  },
796
+ RelativeHumidityHumidifierThreshold: {
797
+ get: async () => {
798
+ const s = await this.getState()
799
+ return typeof s.targetHumidity === 'number' ? s.targetHumidity : 50
800
+ },
801
+ set: async (v: any) => {
802
+ await this.setState({ humidity: Number(v) })
803
+ },
804
+ },
775
805
  },
776
806
  },
777
807
  ],
package/src/platform.ts CHANGED
@@ -6,37 +6,224 @@ import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js'
6
6
  import { SwitchBotClient } from './switchbotClient.js'
7
7
 
8
8
  // Which device types should prefer Matter if available
9
+ // Based on HAP service mappings: device implementations use specific HomeKit services
10
+ // that map to corresponding Matter clusters when Matter is enabled
9
11
  const DEVICE_MATTER_SUPPORTED: Record<string, boolean> = {
10
- bot: false,
11
- curtain: true,
12
- fan: true,
13
- light: true,
14
- lightstrip: true,
15
- motion: true,
16
- contact: true,
17
- vacuum: true,
18
- lock: true,
19
- humidifier: true,
20
- temperature: true,
21
- wosweeper: true,
22
- wosweepermini: true,
23
- wosweeperminipro: true,
12
+ // Core devices
13
+ 'bot': true, // Switch → OnOff
14
+ 'curtain': true, // WindowCovering → WindowCovering
15
+ 'fan': true, // Fan → FanControl
16
+ 'light': true, // Lightbulb → OnOff + LevelControl
17
+ 'lightstrip': true, // Lightbulb (color) → OnOff + LevelControl + ColorControl
18
+ 'motion': true, // MotionSensor → OccupancySensing
19
+ 'contact': true, // ContactSensor → BooleanState
20
+ 'vacuum': true, // Switch → RobotVacuumCleaner
21
+ 'lock': true, // LockMechanism → DoorLock
22
+ 'humidifier': true, // Fan + Humidity → OnOff + FanControl + RelativeHumidityMeasurement
23
+ 'temperature': true, // TemperatureSensor → TemperatureMeasurement
24
+
25
+ // Switch devices
26
+ 'relay': true, // Switch → OnOff
27
+ 'relay switch 1': true, // Switch → OnOff
28
+ 'relay switch 1pm': true, // Switch → OnOff
29
+ 'plug': true, // Outlet → OnOff
30
+ 'plug mini (jp)': true, // Outlet → OnOff
31
+ 'plug mini (us)': true, // Outlet → OnOff
32
+
33
+ // Window covering variants
34
+ 'blindtilt': true, // WindowCovering → WindowCovering
35
+ 'blind tilt': true, // WindowCovering → WindowCovering
36
+ 'curtain3': true, // WindowCovering → WindowCovering
37
+ 'rollershade': true, // WindowCovering → WindowCovering
38
+ 'roller shade': true, // WindowCovering → WindowCovering
39
+ 'worollershade': true, // WindowCovering → WindowCovering
40
+ 'wo rollershade': true, // WindowCovering → WindowCovering
41
+
42
+ // Vacuum variants (normalized to 'vacuum' before lookup)
43
+ 'wosweeper': true, // VacuumDevice → RobotVacuumCleaner
44
+ 'wosweepermini': true, // VacuumDevice → RobotVacuumCleaner
45
+ 'wosweeperminipro': true, // VacuumDevice → RobotVacuumCleaner
46
+ 'k10+': true, // VacuumDevice → RobotVacuumCleaner
47
+ 'k10+ pro': true, // VacuumDevice → RobotVacuumCleaner
48
+
49
+ // Sensors
50
+ 'meter': true, // TemperatureSensor + HumiditySensor → TemperatureMeasurement + RelativeHumidityMeasurement
51
+ 'meterplus': true, // TemperatureSensor + HumiditySensor → TemperatureMeasurement + RelativeHumidityMeasurement
52
+ 'meter plus (jp)': true, // TemperatureSensor + HumiditySensor → TemperatureMeasurement + RelativeHumidityMeasurement
53
+ 'meterpro': true, // TemperatureSensor + HumiditySensor → TemperatureMeasurement + RelativeHumidityMeasurement
54
+ 'meterpro(co2)': true, // TemperatureSensor + HumiditySensor → TemperatureMeasurement + RelativeHumidityMeasurement
55
+ 'waterdetector': true, // LeakSensor → BooleanState
56
+ 'water detector': true, // LeakSensor → BooleanState
57
+
58
+ // Other devices
59
+ 'smart fan': true, // Fan → FanControl
60
+ 'strip light': true, // Lightbulb (color) → OnOff + LevelControl + ColorControl
61
+ 'hub 2': false, // Hub device - not exposed as accessory
62
+ 'walletfinder': false, // Button device - Matter support TBD
24
63
  }
25
64
 
26
65
  // Default Matter cluster configurations by device type
27
- // Note: wosweeper variants are normalized to 'vacuum' before cluster lookup
66
+ // Maps device types to their Matter cluster states (used when device doesn't provide clusters)
67
+ // Note: wosweeper/curtain/plug variants are normalized before cluster lookup (see loadDevices)
28
68
  const DEVICE_MATTER_CLUSTERS: Record<string, any> = {
29
- bot: { onOff: { onOff: false } },
30
- vacuum: { robotVacuumCleaner: { operationalState: 0, runMode: 0 }, operationalState: { operationalState: 0 } },
31
- curtain: { windowCovering: { currentPositionLiftPercent100ths: 0, targetPositionLiftPercent100ths: 0 } },
32
- fan: { fanControl: { fanMode: 0, percentCurrent: 0, percentSetting: 0 } },
33
- light: { onOff: { onOff: false }, levelControl: { currentLevel: 0, minLevel: 0, maxLevel: 254 } },
34
- lightstrip: { onOff: { onOff: false }, levelControl: { currentLevel: 0, minLevel: 0, maxLevel: 254 }, colorControl: { currentHue: 0, currentSaturation: 0 } },
35
- lock: { doorLock: { lockState: 0, lockType: 0, actuatorEnabled: true } },
36
- motion: { occupancySensing: { occupancy: 0 } },
37
- contact: { booleanState: { stateValue: false } },
38
- humidifier: { onOff: { onOff: false }, fanControl: { fanMode: 0, percentCurrent: 0 }, relativeHumidityMeasurement: { measuredValue: 0 } },
39
- temperature: { temperatureMeasurement: { measuredValue: 0 } },
69
+ // Core devices - aligned with HAP service implementations
70
+ bot: { onOff: { onOff: false } }, // Switch OnOff
71
+ vacuum: {
72
+ robotVacuumCleaner: { operationalState: 0, runMode: 0 },
73
+ operationalState: { operationalState: 0 },
74
+ }, // Switch in HAP, RobotVacuumCleaner in Matter
75
+ curtain: {
76
+ windowCovering: {
77
+ currentPositionLiftPercent100ths: 0,
78
+ targetPositionLiftPercent100ths: 0,
79
+ operationalStatus: 0,
80
+ },
81
+ }, // WindowCovering → WindowCovering (includes curtain3, rollershade variants via normalization)
82
+ blindtilt: {
83
+ windowCovering: {
84
+ currentPositionLiftPercent100ths: 0,
85
+ targetPositionLiftPercent100ths: 0,
86
+ currentPositionTiltPercent100ths: 0,
87
+ targetPositionTiltPercent100ths: 0,
88
+ operationalStatus: 0,
89
+ },
90
+ }, // WindowCovering with tilt → WindowCovering
91
+ fan: {
92
+ onOff: { onOff: false },
93
+ fanControl: {
94
+ fanMode: 0,
95
+ percentCurrent: 0,
96
+ percentSetting: 0,
97
+ speedCurrent: 0,
98
+ speedMax: 100,
99
+ },
100
+ }, // Fan → OnOff + FanControl
101
+ light: {
102
+ onOff: { onOff: false },
103
+ levelControl: {
104
+ currentLevel: 0,
105
+ minLevel: 0,
106
+ maxLevel: 254,
107
+ },
108
+ }, // Lightbulb → OnOff + LevelControl
109
+ lightstrip: {
110
+ onOff: { onOff: false },
111
+ levelControl: {
112
+ currentLevel: 0,
113
+ minLevel: 0,
114
+ maxLevel: 254,
115
+ },
116
+ colorControl: {
117
+ currentHue: 0,
118
+ currentSaturation: 0,
119
+ colorTemperatureMireds: 400,
120
+ colorMode: 0,
121
+ },
122
+ }, // Lightbulb with color → OnOff + LevelControl + ColorControl
123
+ lock: {
124
+ doorLock: {
125
+ lockState: 0,
126
+ lockType: 0,
127
+ actuatorEnabled: true,
128
+ operatingMode: 0,
129
+ },
130
+ }, // LockMechanism → DoorLock
131
+ motion: {
132
+ occupancySensing: {
133
+ occupancy: 0,
134
+ occupancySensorType: 0,
135
+ },
136
+ }, // MotionSensor → OccupancySensing
137
+ contact: {
138
+ booleanState: {
139
+ stateValue: false,
140
+ },
141
+ }, // ContactSensor → BooleanState
142
+ humidifier: {
143
+ onOff: { onOff: false },
144
+ fanControl: {
145
+ fanMode: 0,
146
+ percentCurrent: 0,
147
+ },
148
+ relativeHumidityMeasurement: {
149
+ measuredValue: 0,
150
+ minMeasuredValue: 0,
151
+ maxMeasuredValue: 100,
152
+ },
153
+ }, // HumidifierDehumidifier → OnOff + FanControl + RelativeHumidityMeasurement
154
+ temperature: {
155
+ temperatureMeasurement: {
156
+ measuredValue: 0,
157
+ minMeasuredValue: -27315,
158
+ maxMeasuredValue: 32767,
159
+ },
160
+ }, // TemperatureSensor → TemperatureMeasurement
161
+
162
+ // Switch/Outlet devices
163
+ relay: { onOff: { onOff: false } }, // Switch → OnOff
164
+ plug: {
165
+ onOff: { onOff: false },
166
+ electricalMeasurement: {
167
+ activePower: 0,
168
+ rmsCurrent: 0,
169
+ rmsVoltage: 0,
170
+ },
171
+ }, // Outlet → OnOff + ElectricalMeasurement (for PM models)
172
+
173
+ // Sensors
174
+ meter: {
175
+ temperatureMeasurement: {
176
+ measuredValue: 0,
177
+ minMeasuredValue: -27315,
178
+ maxMeasuredValue: 32767,
179
+ },
180
+ relativeHumidityMeasurement: {
181
+ measuredValue: 0,
182
+ minMeasuredValue: 0,
183
+ maxMeasuredValue: 100,
184
+ },
185
+ }, // TemperatureSensor + HumiditySensor → TemperatureMeasurement + RelativeHumidityMeasurement
186
+ waterdetector: {
187
+ booleanState: {
188
+ stateValue: false,
189
+ },
190
+ }, // LeakSensor → BooleanState
191
+ }
192
+
193
+ const DEVICE_MATTER_DEVICE_TYPE_KEYS: Record<string, string> = {
194
+ bot: 'OnOffSwitch',
195
+ vacuum: 'RoboticVacuumCleaner',
196
+ curtain: 'WindowCovering',
197
+ blindtilt: 'WindowCovering',
198
+ fan: 'Fan',
199
+ light: 'DimmableLight',
200
+ lightstrip: 'ExtendedColorLight',
201
+ lock: 'DoorLock',
202
+ motion: 'MotionSensor',
203
+ contact: 'ContactSensor',
204
+ humidifier: 'Fan',
205
+ temperature: 'TemperatureSensor',
206
+ relay: 'OnOffSwitch',
207
+ plug: 'OnOffOutlet',
208
+ meter: 'TemperatureSensor',
209
+ waterdetector: 'LeakSensor',
210
+ }
211
+
212
+ function resolveMatterDeviceType(matterApi: any, type: string, createdDeviceType?: any, clusters?: any): any {
213
+ if (createdDeviceType && typeof createdDeviceType === 'object' && typeof createdDeviceType.with === 'function') {
214
+ return createdDeviceType
215
+ }
216
+
217
+ const lowerType = (typeof createdDeviceType === 'string' && createdDeviceType) ? createdDeviceType.toLowerCase() : (type || '').toLowerCase()
218
+
219
+ // Cluster-based upgrade for color lights if descriptor omitted device type.
220
+ const hasColorControl = !!clusters?.colorControl
221
+ const inferredType = hasColorControl && lowerType === 'light'
222
+ ? 'lightstrip'
223
+ : lowerType
224
+
225
+ const mappedKey = DEVICE_MATTER_DEVICE_TYPE_KEYS[inferredType] || 'OnOffSwitch'
226
+ return matterApi?.deviceTypes?.[mappedKey] || matterApi?.deviceTypes?.OnOffSwitch
40
227
  }
41
228
 
42
229
  export class SwitchBotHAPPlatform {
@@ -125,10 +312,40 @@ export class SwitchBotHAPPlatform {
125
312
  }
126
313
 
127
314
  let type: string = d.type
128
- // Normalize wosweeper variants to vacuum
129
- if (['wosweeper', 'wosweepermini', 'wosweeperminipro'].includes((type || '').toLowerCase())) {
315
+ // Normalize device type variants for consistent Matter cluster lookup
316
+ // Vacuum variants
317
+ if (['wosweeper', 'wosweepermini', 'wosweeperminipro', 'k10+', 'k10+ pro'].includes((type || '').toLowerCase())) {
130
318
  type = 'vacuum'
131
319
  }
320
+ // Window covering variants
321
+ if (['blindtilt', 'blind tilt', 'curtain3', 'rollershade', 'roller shade', 'worollershade', 'wo rollershade'].includes((type || '').toLowerCase())) {
322
+ type = 'curtain'
323
+ }
324
+ // Plug variants
325
+ if (['plug mini (jp)', 'plug mini (us)'].includes((type || '').toLowerCase())) {
326
+ type = 'plug'
327
+ }
328
+ // Meter variants
329
+ if (['meterplus', 'meter plus (jp)', 'meterpro', 'meterpro(co2)'].includes((type || '').toLowerCase())) {
330
+ type = 'meter'
331
+ }
332
+ // Relay switch variants
333
+ if (['relay switch 1', 'relay switch 1pm'].includes((type || '').toLowerCase())) {
334
+ type = 'relay'
335
+ }
336
+ // Water detector variants
337
+ if (['water detector'].includes((type || '').toLowerCase())) {
338
+ type = 'waterdetector'
339
+ }
340
+ // Fan variants
341
+ if (['smart fan'].includes((type || '').toLowerCase())) {
342
+ type = 'fan'
343
+ }
344
+ // Light variants
345
+ if (['strip light'].includes((type || '').toLowerCase())) {
346
+ type = 'lightstrip'
347
+ }
348
+
132
349
  const matterSupported = !!DEVICE_MATTER_SUPPORTED[(type || '').toLowerCase()]
133
350
  // Auto-detect Matter from Homebridge API, allow manual override via config
134
351
  const matterAvailable = !!(this.api?.isMatterAvailable?.() && this.api?.isMatterEnabled?.())
@@ -149,17 +366,19 @@ export class SwitchBotHAPPlatform {
149
366
  const createdDesc = created.createAccessory?.(this.api) || { id: d.id, name: d.name || type }
150
367
  const uuid = matterApi.uuid.generate(`${d.id}`)
151
368
  const defaultClusters = DEVICE_MATTER_CLUSTERS[type.toLowerCase()] || { onOff: { onOff: false } }
369
+ const clusters = createdDesc.clusters || defaultClusters
370
+ const deviceType = resolveMatterDeviceType(matterApi, type, createdDesc.deviceType, clusters)
152
371
  const accessory: any = {
153
372
  UUID: uuid,
154
373
  displayName: createdDesc.name || d.name || type,
155
- deviceType: createdDesc.deviceType || type,
374
+ deviceType,
156
375
  manufacturer: createdDesc.manufacturer || 'SwitchBot',
157
376
  model: createdDesc.model || type,
158
377
  serialNumber: createdDesc.serialNumber || d.id,
159
378
  reachable: createdDesc.reachable !== false,
160
379
  firmwareRevision: createdDesc.firmwareRevision || '1.0.0',
161
380
  hardwareRevision: createdDesc.hardwareRevision || '',
162
- clusters: createdDesc.clusters || defaultClusters,
381
+ clusters,
163
382
  context: { deviceId: d.id, type, _created: true },
164
383
  }
165
384
  try {
@@ -369,10 +588,40 @@ export class SwitchBotMatterPlatform {
369
588
  }
370
589
 
371
590
  let type: string = d.type
372
- // Normalize wosweeper variants to vacuum
373
- if (['wosweeper', 'wosweepermini', 'wosweeperminipro'].includes((type || '').toLowerCase())) {
591
+ // Normalize device type variants for consistent Matter cluster lookup
592
+ // Vacuum variants
593
+ if (['wosweeper', 'wosweepermini', 'wosweeperminipro', 'k10+', 'k10+ pro'].includes((type || '').toLowerCase())) {
374
594
  type = 'vacuum'
375
595
  }
596
+ // Window covering variants
597
+ if (['blindtilt', 'blind tilt', 'curtain3', 'rollershade', 'roller shade', 'worollershade', 'wo rollershade'].includes((type || '').toLowerCase())) {
598
+ type = 'curtain'
599
+ }
600
+ // Plug variants
601
+ if (['plug mini (jp)', 'plug mini (us)'].includes((type || '').toLowerCase())) {
602
+ type = 'plug'
603
+ }
604
+ // Meter variants
605
+ if (['meterplus', 'meter plus (jp)', 'meterpro', 'meterpro(co2)'].includes((type || '').toLowerCase())) {
606
+ type = 'meter'
607
+ }
608
+ // Relay switch variants
609
+ if (['relay switch 1', 'relay switch 1pm'].includes((type || '').toLowerCase())) {
610
+ type = 'relay'
611
+ }
612
+ // Water detector variants
613
+ if (['water detector'].includes((type || '').toLowerCase())) {
614
+ type = 'waterdetector'
615
+ }
616
+ // Fan variants
617
+ if (['smart fan'].includes((type || '').toLowerCase())) {
618
+ type = 'fan'
619
+ }
620
+ // Light variants
621
+ if (['strip light'].includes((type || '').toLowerCase())) {
622
+ type = 'lightstrip'
623
+ }
624
+
376
625
  const matterSupported = !!DEVICE_MATTER_SUPPORTED[(type || '').toLowerCase()]
377
626
  // Auto-detect Matter from Homebridge API, allow manual override via config
378
627
  const matterAvailable = this.api?.isMatterAvailable?.() && this.api?.isMatterEnabled?.()
@@ -471,10 +720,40 @@ export class SwitchBotMatterPlatform {
471
720
  }
472
721
 
473
722
  let type: string = d.type
474
- // Normalize wosweeper variants to vacuum
475
- if (['wosweeper', 'wosweepermini', 'wosweeperminipro'].includes((type || '').toLowerCase())) {
723
+ // Normalize device type variants for consistent Matter cluster lookup
724
+ // Vacuum variants
725
+ if (['wosweeper', 'wosweepermini', 'wosweeperminipro', 'k10+', 'k10+ pro'].includes((type || '').toLowerCase())) {
476
726
  type = 'vacuum'
477
727
  }
728
+ // Window covering variants
729
+ if (['blindtilt', 'blind tilt', 'curtain3', 'rollershade', 'roller shade', 'worollershade', 'wo rollershade'].includes((type || '').toLowerCase())) {
730
+ type = 'curtain'
731
+ }
732
+ // Plug variants
733
+ if (['plug mini (jp)', 'plug mini (us)'].includes((type || '').toLowerCase())) {
734
+ type = 'plug'
735
+ }
736
+ // Meter variants
737
+ if (['meterplus', 'meter plus (jp)', 'meterpro', 'meterpro(co2)'].includes((type || '').toLowerCase())) {
738
+ type = 'meter'
739
+ }
740
+ // Relay switch variants
741
+ if (['relay switch 1', 'relay switch 1pm'].includes((type || '').toLowerCase())) {
742
+ type = 'relay'
743
+ }
744
+ // Water detector variants
745
+ if (['water detector'].includes((type || '').toLowerCase())) {
746
+ type = 'waterdetector'
747
+ }
748
+ // Fan variants
749
+ if (['smart fan'].includes((type || '').toLowerCase())) {
750
+ type = 'fan'
751
+ }
752
+ // Light variants
753
+ if (['strip light'].includes((type || '').toLowerCase())) {
754
+ type = 'lightstrip'
755
+ }
756
+
478
757
  const matterSupported = !!DEVICE_MATTER_SUPPORTED[(type || '').toLowerCase()]
479
758
  const useMatter = matterEnabled && matterSupported
480
759
  if (!useMatter) {
@@ -501,34 +780,38 @@ export class SwitchBotMatterPlatform {
501
780
  if (existing) {
502
781
  // Ensure context and displayName are up to date
503
782
  const defaultClusters = DEVICE_MATTER_CLUSTERS[type.toLowerCase()] || { onOff: { onOff: false } }
783
+ const clusters = existing.clusters || createdDesc.clusters || defaultClusters
784
+ const deviceType = resolveMatterDeviceType(matterApi, type, existing.deviceType || createdDesc.deviceType, clusters)
504
785
  existing.context = existing.context || {}
505
786
  existing.context.deviceId = existing.context.deviceId || d.id
506
787
  existing.context.type = existing.context.type || type
507
- existing.deviceType = existing.deviceType || createdDesc.deviceType || type
788
+ existing.deviceType = deviceType
508
789
  existing.manufacturer = existing.manufacturer || createdDesc.manufacturer || 'SwitchBot'
509
790
  existing.model = existing.model || createdDesc.model || type
510
791
  existing.serialNumber = existing.serialNumber || createdDesc.serialNumber || d.id
511
792
  existing.reachable = existing.reachable !== false
512
793
  existing.firmwareRevision = existing.firmwareRevision || createdDesc.firmwareRevision || '1.0.0'
513
794
  existing.hardwareRevision = existing.hardwareRevision || createdDesc.hardwareRevision || ''
514
- existing.clusters = existing.clusters || createdDesc.clusters || defaultClusters
795
+ existing.clusters = clusters
515
796
  existing.displayName = createdDesc.name || d.name || type
516
797
  existing.UUID = existing.UUID || existing.uuid || uuid
517
798
  accessoriesToRegister.push(existing)
518
799
  this.accessories.set(existing.UUID || uuid, existing)
519
800
  } else {
520
801
  const defaultClusters = DEVICE_MATTER_CLUSTERS[type.toLowerCase()] || { onOff: { onOff: false } }
802
+ const clusters = createdDesc.clusters || defaultClusters
803
+ const deviceType = resolveMatterDeviceType(matterApi, type, createdDesc.deviceType, clusters)
521
804
  const serialized: any = {
522
805
  UUID: uuid,
523
806
  displayName: createdDesc.name || d.name || type,
524
- deviceType: createdDesc.deviceType || type,
807
+ deviceType,
525
808
  manufacturer: createdDesc.manufacturer || 'SwitchBot',
526
809
  model: createdDesc.model || type,
527
810
  serialNumber: createdDesc.serialNumber || d.id,
528
811
  reachable: createdDesc.reachable !== false,
529
812
  firmwareRevision: createdDesc.firmwareRevision || '1.0.0',
530
813
  hardwareRevision: createdDesc.hardwareRevision || '',
531
- clusters: createdDesc.clusters || defaultClusters,
814
+ clusters,
532
815
  context: { deviceId: d.id, type, created: true },
533
816
  }
534
817
  accessoriesToRegister.push(serialized)