homebridge-deconz 0.0.10 → 0.0.13
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.
- package/README.md +3 -6
- package/cli/deconz.js +12 -0
- package/config.schema.json +1 -0
- package/homebridge-ui/public/index.html +26 -0
- package/homebridge-ui/public/style.css +0 -0
- package/homebridge-ui/server.js +43 -0
- package/lib/Deconz/ApiClient.js +34 -1
- package/lib/Deconz/ApiResponse.js +1 -1
- package/lib/Deconz/Device.js +0 -7
- package/lib/Deconz/Resource.js +751 -25
- package/lib/DeconzAccessory/Contact.js +54 -0
- package/lib/DeconzAccessory/Gateway.js +102 -66
- package/lib/DeconzAccessory/Light.js +42 -37
- package/lib/DeconzAccessory/Motion.js +51 -0
- package/lib/DeconzAccessory/Sensor.js +35 -0
- package/lib/DeconzAccessory/Temperature.js +63 -0
- package/lib/DeconzAccessory/Thermostat.js +50 -0
- package/lib/DeconzAccessory/WarningDevice.js +56 -0
- package/lib/DeconzAccessory/WindowCovering.js +47 -0
- package/lib/DeconzAccessory/index.js +144 -2
- package/lib/DeconzPlatform.js +5 -2
- package/lib/DeconzService/AirPressure.js +43 -0
- package/lib/DeconzService/AirQuality.js +20 -11
- package/lib/DeconzService/Alarm.js +13 -9
- package/lib/DeconzService/Battery.js +53 -0
- package/lib/DeconzService/Button.js +9 -2
- package/lib/DeconzService/CarbonMonoxide.js +38 -0
- package/lib/DeconzService/Consumption.js +65 -0
- package/lib/DeconzService/Contact.js +60 -0
- package/lib/DeconzService/Daylight.js +132 -0
- package/lib/DeconzService/DeviceSettings.js +11 -0
- package/lib/DeconzService/Flag.js +52 -0
- package/lib/DeconzService/Humidity.js +37 -0
- package/lib/DeconzService/Leak.js +38 -0
- package/lib/DeconzService/Light.js +122 -172
- package/lib/DeconzService/LightLevel.js +54 -0
- package/lib/DeconzService/LightsResource.js +112 -0
- package/lib/DeconzService/Motion.js +101 -0
- package/lib/DeconzService/Outlet.js +76 -0
- package/lib/DeconzService/Power.js +83 -0
- package/lib/DeconzService/SensorsResource.js +96 -0
- package/lib/DeconzService/Smoke.js +38 -0
- package/lib/DeconzService/Status.js +53 -0
- package/lib/DeconzService/Switch.js +93 -0
- package/lib/DeconzService/Temperature.js +63 -0
- package/lib/DeconzService/Thermostat.js +175 -0
- package/lib/DeconzService/WarningDevice.js +68 -0
- package/lib/DeconzService/WindowCovering.js +162 -0
- package/lib/DeconzService/index.js +79 -25
- package/package.json +6 -5
- package/lib/Client/ApiError.js +0 -42
- package/lib/DeconzAccessory/Device.js +0 -69
- package/lib/DeconzService/Sensor.js +0 -61
package/lib/Deconz/Resource.js
CHANGED
@@ -6,24 +6,21 @@
|
|
6
6
|
'use strict'
|
7
7
|
|
8
8
|
const homebridgeLib = require('homebridge-lib')
|
9
|
+
const Deconz = require('../Deconz')
|
10
|
+
const DeconzAccessory = require('../DeconzAccessory')
|
11
|
+
const DeconzService = require('../DeconzService')
|
9
12
|
|
10
13
|
const { toInstance, toInt, toObject, toString } = homebridgeLib.OptionParser
|
11
14
|
const { defaultGamut } = homebridgeLib.Colour
|
12
|
-
|
13
|
-
const
|
14
|
-
|
15
|
+
const { buttonEvent } = Deconz.ApiClient
|
16
|
+
const { SINGLE, DOUBLE, LONG } = DeconzService.Button
|
15
17
|
const rtypes = ['lights', 'sensors', 'groups']
|
16
18
|
|
17
19
|
// From low to high.
|
18
20
|
const sensorsPrios = [
|
19
21
|
'Power',
|
20
22
|
'Consumption',
|
21
|
-
'Switch',
|
22
|
-
'AirQuality',
|
23
|
-
'Pressure',
|
24
|
-
'Humidiy',
|
25
23
|
'Temperature',
|
26
|
-
'LightLevel',
|
27
24
|
'Presence',
|
28
25
|
'OpenClose',
|
29
26
|
'Thermostat'
|
@@ -76,6 +73,17 @@ const hueGamutTypeByModel = {
|
|
76
73
|
LST002: 'C' // Hue LightStrips Plus
|
77
74
|
}
|
78
75
|
|
76
|
+
const hueTapMap = {
|
77
|
+
34: 1002, // press 1
|
78
|
+
16: 2002, // press 2
|
79
|
+
17: 3002, // press 3
|
80
|
+
18: 4002, // press 4
|
81
|
+
100: 5002, // press 1 and 2
|
82
|
+
101: 0, // release 1 and 2
|
83
|
+
98: 6002, // press 3 and 4
|
84
|
+
99: 0 // release 3 and 4
|
85
|
+
}
|
86
|
+
|
79
87
|
/** Delegate class for a resource on a deCONZ gateway.
|
80
88
|
*
|
81
89
|
* @memberof Deconz
|
@@ -153,6 +161,11 @@ class Resource {
|
|
153
161
|
*/
|
154
162
|
this.subtype = endpoint + (cluster == null ? '' : '-' + cluster)
|
155
163
|
|
164
|
+
/** Zigbee endpoint.
|
165
|
+
* @type {string}
|
166
|
+
*/
|
167
|
+
this.endpoint = endpoint
|
168
|
+
|
156
169
|
/** Zigbee device vs virtual device.
|
157
170
|
*
|
158
171
|
* Derived from the resource type and, for `sensors`, on the `type` in the
|
@@ -242,7 +255,7 @@ class Resource {
|
|
242
255
|
*/
|
243
256
|
get prio () {
|
244
257
|
if (this.rtype === 'groups') return -1
|
245
|
-
if (this.rtype === 'lights') return this.
|
258
|
+
if (this.rtype === 'lights') return this.endpoint
|
246
259
|
return sensorsPrios.indexOf(this.type)
|
247
260
|
}
|
248
261
|
|
@@ -306,7 +319,7 @@ class Resource {
|
|
306
319
|
// case 'CLIPDoorLock': return null
|
307
320
|
case 'Daylight': return 'Daylight'
|
308
321
|
case 'ZHAFire':
|
309
|
-
case 'CLIPFire': return '
|
322
|
+
case 'CLIPFire': return 'Smoke'
|
310
323
|
case 'CLIPGenericFlag': return 'Flag'
|
311
324
|
case 'CLIPGenericStatus': return 'Status'
|
312
325
|
case 'ZHAHumidity':
|
@@ -316,17 +329,17 @@ class Resource {
|
|
316
329
|
// case 'ZHAMoisture':
|
317
330
|
// case 'CLIPMoisture': return null
|
318
331
|
case 'ZHAOpenClose':
|
319
|
-
case 'CLIPOpenClose': return '
|
332
|
+
case 'CLIPOpenClose': return 'Contact'
|
320
333
|
case 'ZHAPower':
|
321
334
|
case 'CLIPPower': return 'Power'
|
322
335
|
case 'ZHAPresence':
|
323
|
-
case 'CLIPPresence': return '
|
336
|
+
case 'CLIPPresence': return 'Motion'
|
324
337
|
case 'ZHAPressure':
|
325
|
-
case 'CLIPPressure': return '
|
338
|
+
case 'CLIPPressure': return 'AirPressure'
|
326
339
|
case 'ZHASpectral': return ''
|
327
340
|
case 'ZGPSwitch':
|
328
|
-
case 'ZHASwitch':
|
329
|
-
case 'CLIPSwitch': return ''
|
341
|
+
case 'ZHASwitch':
|
342
|
+
case 'CLIPSwitch': return 'Switch'
|
330
343
|
case 'ZHATemperature':
|
331
344
|
case 'CLIPTemperature': return 'Temperature'
|
332
345
|
case 'ZHAThermostat':
|
@@ -334,9 +347,9 @@ class Resource {
|
|
334
347
|
case 'ZHATime':
|
335
348
|
case 'CLIPTime': return ''
|
336
349
|
case 'ZHAVibration':
|
337
|
-
case 'CLIPVibration': return '
|
350
|
+
case 'CLIPVibration': return 'Motion'
|
338
351
|
case 'ZHAWater':
|
339
|
-
case 'CLIPWater': return '
|
352
|
+
case 'CLIPWater': return 'Leak'
|
340
353
|
default: return null
|
341
354
|
}
|
342
355
|
}
|
@@ -353,7 +366,7 @@ class Resource {
|
|
353
366
|
this.model === 'RM01' && // 6715 U-500 with 6736-84.
|
354
367
|
this.capabilities.bri && this.body.type === 'On/Off light' // Issue #241
|
355
368
|
) {
|
356
|
-
gateway.
|
369
|
+
gateway.vdebug(
|
357
370
|
'%s: ignoring state.bri for %s', this.rpath, this.body.type
|
358
371
|
)
|
359
372
|
this.capabilities.bri = false
|
@@ -377,32 +390,32 @@ class Resource {
|
|
377
390
|
}
|
378
391
|
if (this.model === 'GLEDOPTO') { // Issue #244
|
379
392
|
if (
|
380
|
-
this.
|
393
|
+
this.endpoint === '0A' &&
|
381
394
|
this.body.type === 'Dimmable light' &&
|
382
395
|
this.firmware === '1.0.2'
|
383
396
|
) {
|
384
397
|
this.model = 'RGBW'
|
385
398
|
} else if (
|
386
|
-
this.
|
399
|
+
this.endpoint === '0B' &&
|
387
400
|
this.body.type === 'Color temperature light' &&
|
388
401
|
this.firmware === '1.3.002'
|
389
402
|
) {
|
390
403
|
this.model = 'WW/CW'
|
391
404
|
} else if (
|
392
|
-
this.
|
405
|
+
this.endpoint === '0B' &&
|
393
406
|
this.body.type === 'Extended color light' &&
|
394
407
|
this.firmware === '1.0.2'
|
395
408
|
) {
|
396
409
|
this.model = 'RGB+CCT'
|
397
|
-
const device = gateway.
|
398
|
-
if (device != null
|
410
|
+
const device = gateway.deviceById[this.id]
|
411
|
+
if (device != null) {
|
399
412
|
this.model = 'RGBW'
|
400
413
|
this.capabilities.ct = false
|
401
414
|
}
|
402
415
|
} else {
|
403
416
|
return
|
404
417
|
}
|
405
|
-
gateway.
|
418
|
+
gateway.vdebug('%s: set model to %j', this.rpath, this.model)
|
406
419
|
}
|
407
420
|
break
|
408
421
|
case 'IKEA of Sweden':
|
@@ -449,7 +462,7 @@ class Resource {
|
|
449
462
|
g: [0.11, 0.82],
|
450
463
|
b: [0.13, 0.04]
|
451
464
|
}
|
452
|
-
if (this.capabilities.
|
465
|
+
if (this.capabilities.colorLoop) {
|
453
466
|
this.capabilities.effects = [
|
454
467
|
'Sunset', 'Party', 'Worklight', 'Campfire', 'Romance', 'Nightlight'
|
455
468
|
]
|
@@ -476,6 +489,719 @@ class Resource {
|
|
476
489
|
break
|
477
490
|
}
|
478
491
|
}
|
492
|
+
|
493
|
+
/** Patch a resource corresponding to a `Flag` service.
|
494
|
+
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
495
|
+
*/
|
496
|
+
patchFlag (gateway) {
|
497
|
+
if (
|
498
|
+
this.body.manufacturername === 'homebridge-hue' &&
|
499
|
+
this.body.modelid === 'CLIPGenericFlag' &&
|
500
|
+
this.body.swversion === '0'
|
501
|
+
) {
|
502
|
+
this.capabilities.readonly = true
|
503
|
+
}
|
504
|
+
}
|
505
|
+
|
506
|
+
/** Patch a resource corresponding to a `Flag` service.
|
507
|
+
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
508
|
+
*/
|
509
|
+
patchStatus (gateway) {
|
510
|
+
if (
|
511
|
+
this.body.manufacturername === 'homebridge-hue' &&
|
512
|
+
this.body.modelid === 'CLIPGenericStatus'
|
513
|
+
) {
|
514
|
+
const a = this.body.swversion.split(',')
|
515
|
+
const min = parseInt(a[0])
|
516
|
+
const max = parseInt(a[1])
|
517
|
+
const step = parseInt(a[2])
|
518
|
+
// Eve 3.1 displays the following controls, depending on the properties:
|
519
|
+
// 1. {minValue: 0, maxValue: 1, minStep: 1} switch
|
520
|
+
// 2. {minValue: a, maxValue: b, minStep: 1}, 1 < b - a <= 20 down|up
|
521
|
+
// 3. {minValue: a, maxValue: b}, (a, b) != (0, 1) slider
|
522
|
+
// 4. {minValue: a, maxValue: b, minStep: 1}, b - a > 20 slider
|
523
|
+
// Avoid the following bugs:
|
524
|
+
// 5. {minValue: 0, maxValue: 1} nothing
|
525
|
+
// 6. {minValue: a, maxValue: b, minStep: 1}, b - a = 1 switch*
|
526
|
+
// *) switch sends values 0 and 1 instead of a and b;
|
527
|
+
if (min === 0 && max === 0) {
|
528
|
+
this.capabilities.readonly = true
|
529
|
+
} else if (min >= -127 && max <= 127 && min < max) {
|
530
|
+
if (min === 0 && max === 1) {
|
531
|
+
// Workaround Eve bug (case 5 above).
|
532
|
+
this.capabilities.props = { minValue: min, maxValue: max, minStep: 1 }
|
533
|
+
} else if (max - min === 1) {
|
534
|
+
// Workaround Eve bug (case 6 above).
|
535
|
+
this.capabilities.props = { minValue: min, maxValue: max }
|
536
|
+
} else if (step !== 1) {
|
537
|
+
// Default to slider for backwards compatibility.
|
538
|
+
this.capabilities.props = { minValue: min, maxValue: max }
|
539
|
+
} else {
|
540
|
+
this.capabilities.props = { minValue: min, maxValue: max, minStep: 1 }
|
541
|
+
}
|
542
|
+
}
|
543
|
+
}
|
544
|
+
}
|
545
|
+
|
546
|
+
/** Patch a resource corresponding to a `Switch` service.
|
547
|
+
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
548
|
+
*/
|
549
|
+
patchSwitch (gateway) {
|
550
|
+
const buttons = []
|
551
|
+
let dots = false
|
552
|
+
switch (this.manufacturer) {
|
553
|
+
case 'Bitron Home':
|
554
|
+
switch (this.model) {
|
555
|
+
case '902010/23': // Bitron remote, see #639.
|
556
|
+
dots = true
|
557
|
+
buttons.push([1, 'Dim Up', SINGLE])
|
558
|
+
buttons.push([2, 'On', SINGLE])
|
559
|
+
buttons.push([3, 'Off', SINGLE])
|
560
|
+
buttons.push([4, 'Dim Down', SINGLE])
|
561
|
+
break
|
562
|
+
default:
|
563
|
+
break
|
564
|
+
}
|
565
|
+
break
|
566
|
+
case 'Busch-Jaeger':
|
567
|
+
switch (this.model) {
|
568
|
+
case 'RM01': // Busch-Jaeger Light Link control element (mains-powered)
|
569
|
+
case 'RB01': // Busch-Jaeger Light Link wall-mounted transmitter
|
570
|
+
if (this.endpoint === '0A') {
|
571
|
+
buttons.push([1, 'Button 1', SINGLE | LONG])
|
572
|
+
buttons.push([2, 'Button 2', SINGLE | LONG])
|
573
|
+
} else if (this.endpoint === '0B') {
|
574
|
+
buttons.push([3, 'Button 3', SINGLE | LONG])
|
575
|
+
buttons.push([4, 'Button 4', SINGLE | LONG])
|
576
|
+
} else if (this.endpoint === '0C') {
|
577
|
+
buttons.push([5, 'Button 5', SINGLE | LONG])
|
578
|
+
buttons.push([6, 'Button 6', SINGLE | LONG])
|
579
|
+
} else if (this.endpoint === '0D') {
|
580
|
+
buttons.push([7, 'Button 7', SINGLE | LONG])
|
581
|
+
buttons.push([8, 'Button 8', SINGLE | LONG])
|
582
|
+
}
|
583
|
+
break
|
584
|
+
default:
|
585
|
+
break
|
586
|
+
}
|
587
|
+
break
|
588
|
+
case 'Echostar':
|
589
|
+
switch (this.model) {
|
590
|
+
case 'Bell':
|
591
|
+
buttons.push([1, 'Front Doorbell', SINGLE])
|
592
|
+
buttons.push([2, 'Rear Doorbell', SINGLE])
|
593
|
+
break
|
594
|
+
default:
|
595
|
+
break
|
596
|
+
}
|
597
|
+
break
|
598
|
+
case 'ELKO':
|
599
|
+
switch (this.model) {
|
600
|
+
case 'ElkoDimmerRemoteZHA': // ELKO ESH 316 Endevender RF, see #922.
|
601
|
+
buttons.push([1, 'Press', SINGLE])
|
602
|
+
buttons.push([2, 'Dim Up', SINGLE])
|
603
|
+
buttons.push([3, 'Dim Down', SINGLE])
|
604
|
+
break
|
605
|
+
default:
|
606
|
+
break
|
607
|
+
}
|
608
|
+
break
|
609
|
+
case 'Heiman':
|
610
|
+
switch (this.model) {
|
611
|
+
case 'RC-EF-3.0':
|
612
|
+
dots = true
|
613
|
+
buttons.push([1, 'HomeMode', SINGLE])
|
614
|
+
buttons.push([2, 'Disarm', SINGLE])
|
615
|
+
buttons.push([3, 'SOS', SINGLE])
|
616
|
+
buttons.push([4, 'Arm', SINGLE])
|
617
|
+
break
|
618
|
+
default:
|
619
|
+
break
|
620
|
+
}
|
621
|
+
break
|
622
|
+
case 'IKEA of Sweden':
|
623
|
+
switch (this.model) {
|
624
|
+
case 'Remote Control N2':
|
625
|
+
buttons.push([1, 'Dim Up', SINGLE | LONG])
|
626
|
+
buttons.push([2, 'Dim Down', SINGLE | LONG])
|
627
|
+
buttons.push([3, 'Previous', SINGLE | LONG])
|
628
|
+
buttons.push([4, 'Next', SINGLE | LONG])
|
629
|
+
break
|
630
|
+
case 'SYMFONISK Sound Controller':
|
631
|
+
buttons.push([1, 'Button', SINGLE | DOUBLE | LONG])
|
632
|
+
if (this.body.mode === 1) {
|
633
|
+
buttons.push([2, 'Turn Right', LONG])
|
634
|
+
buttons.push([3, 'Turn Left', LONG])
|
635
|
+
} else {
|
636
|
+
buttons.push([2, 'Turn Right', SINGLE])
|
637
|
+
buttons.push([3, 'Turn Left', SINGLE])
|
638
|
+
}
|
639
|
+
break
|
640
|
+
case 'TRADFRI SHORTCUT Button':
|
641
|
+
buttons.push([1, 'Button', SINGLE | LONG])
|
642
|
+
break
|
643
|
+
case 'TRADFRI on/off switch':
|
644
|
+
buttons.push([1, 'On', SINGLE | LONG])
|
645
|
+
buttons.push([2, 'Off', SINGLE | LONG])
|
646
|
+
break
|
647
|
+
case 'TRADFRI open/close remote':
|
648
|
+
buttons.push([1, 'Open', SINGLE | LONG])
|
649
|
+
buttons.push([2, 'Close', SINGLE | LONG])
|
650
|
+
break
|
651
|
+
case 'TRADFRI remote control':
|
652
|
+
buttons.push([1, 'On/Off', SINGLE])
|
653
|
+
buttons.push([2, 'Dim Up', SINGLE | LONG])
|
654
|
+
buttons.push([3, 'Dim Down', SINGLE | LONG])
|
655
|
+
buttons.push([4, 'Previous', SINGLE | LONG])
|
656
|
+
buttons.push([5, 'Next', SINGLE | LONG])
|
657
|
+
break
|
658
|
+
case 'TRADFRI wireless dimmer':
|
659
|
+
if (this.obj.mode === 1) {
|
660
|
+
buttons.push([1, 'Turn Right', SINGLE | LONG])
|
661
|
+
buttons.push([2, 'Turn Left', SINGLE | LONG])
|
662
|
+
} else {
|
663
|
+
buttons.push([1, 'On', SINGLE])
|
664
|
+
buttons.push([2, 'Dim Up', SINGLE])
|
665
|
+
buttons.push([3, 'Dim Down', SINGLE])
|
666
|
+
buttons.push([4, 'Off', SINGLE])
|
667
|
+
}
|
668
|
+
break
|
669
|
+
default:
|
670
|
+
break
|
671
|
+
}
|
672
|
+
break
|
673
|
+
case 'Insta':
|
674
|
+
switch (this.model) {
|
675
|
+
case 'HS_4f_GJ_1': // Gira/Jung Light Link hand transmitter
|
676
|
+
case 'WS_3f_G_1': // Gira Light Link wall transmitter
|
677
|
+
case 'WS_4f_J_1': // Jung Light Link wall transmitter
|
678
|
+
buttons.push([1, 'Off', SINGLE | DOUBLE | LONG])
|
679
|
+
buttons.push([2, 'On', SINGLE | DOUBLE | LONG])
|
680
|
+
buttons.push([3, 'Scene 1', SINGLE])
|
681
|
+
buttons.push([4, 'Scene 2', SINGLE])
|
682
|
+
buttons.push([5, 'Scene 3', SINGLE])
|
683
|
+
buttons.push([6, 'Scene 4', SINGLE])
|
684
|
+
if (this.model !== 'WS_3f_G_1') {
|
685
|
+
buttons.push([7, 'Scene 5', SINGLE])
|
686
|
+
buttons.push([8, 'Scene 6', SINGLE])
|
687
|
+
}
|
688
|
+
break
|
689
|
+
default:
|
690
|
+
break
|
691
|
+
}
|
692
|
+
break
|
693
|
+
case 'LDS':
|
694
|
+
switch (this.model) {
|
695
|
+
case 'ZBT-DIMController-D0800':
|
696
|
+
buttons.push([1, 'On/Off', SINGLE])
|
697
|
+
buttons.push([2, 'Dim Up', SINGLE | LONG])
|
698
|
+
buttons.push([3, 'Dim Down', SINGLE | LONG])
|
699
|
+
buttons.push([4, 'Scene', SINGLE | LONG])
|
700
|
+
break
|
701
|
+
default:
|
702
|
+
break
|
703
|
+
}
|
704
|
+
break
|
705
|
+
case 'LIDL Livarno Lux':
|
706
|
+
switch (this.model) {
|
707
|
+
case 'HG06323':
|
708
|
+
buttons.push([1, 'On', SINGLE | DOUBLE | LONG])
|
709
|
+
buttons.push([2, 'Dim Up', SINGLE | LONG])
|
710
|
+
buttons.push([3, 'Dim Down', SINGLE | LONG])
|
711
|
+
buttons.push([4, 'Off', SINGLE])
|
712
|
+
break
|
713
|
+
default:
|
714
|
+
break
|
715
|
+
}
|
716
|
+
break
|
717
|
+
case 'LUMI':
|
718
|
+
switch (this.model) {
|
719
|
+
case 'lumi.ctrl_neutral1':
|
720
|
+
buttons.push([1, 'Button', SINGLE])
|
721
|
+
break
|
722
|
+
case 'lumi.ctrl_neutral2':
|
723
|
+
buttons.push([1, 'Left', SINGLE])
|
724
|
+
buttons.push([2, 'Right', SINGLE])
|
725
|
+
buttons.push([3, 'Both', SINGLE])
|
726
|
+
break
|
727
|
+
case 'lumi.remote.b1acn01':
|
728
|
+
case 'lumi.remote.b186acn01':
|
729
|
+
case 'lumi.remote.b186acn02':
|
730
|
+
buttons.push([1, 'Button', SINGLE | DOUBLE | LONG])
|
731
|
+
break
|
732
|
+
case 'lumi.remote.b28ac1':
|
733
|
+
case 'lumi.remote.b286acn01':
|
734
|
+
case 'lumi.remote.b286acn02':
|
735
|
+
buttons.push([1, 'Left', SINGLE | DOUBLE | LONG])
|
736
|
+
buttons.push([2, 'Right', SINGLE | DOUBLE | LONG])
|
737
|
+
buttons.push([3, 'Both', SINGLE | DOUBLE | LONG])
|
738
|
+
break
|
739
|
+
case 'lumi.remote.b286opcn01': // Xiaomi Aqara Opple, see #637.
|
740
|
+
case 'lumi.remote.b486opcn01': // Xiaomi Aqara Opple, see #637.
|
741
|
+
case 'lumi.remote.b686opcn01': // Xiaomi Aqara Opple, see #637.
|
742
|
+
buttons.push([1, '1', SINGLE | DOUBLE | LONG])
|
743
|
+
buttons.push([2, '2', SINGLE | DOUBLE | LONG])
|
744
|
+
if (this.model !== 'lumi.remote.b286opcn01') {
|
745
|
+
buttons.push([3, '3', SINGLE | DOUBLE | LONG])
|
746
|
+
buttons.push([4, '4', SINGLE | DOUBLE | LONG])
|
747
|
+
if (this.model === 'lumi.remote.b686opcn01') {
|
748
|
+
buttons.push([5, '5', SINGLE | DOUBLE | LONG])
|
749
|
+
buttons.push([6, '6', SINGLE | DOUBLE | LONG])
|
750
|
+
}
|
751
|
+
}
|
752
|
+
break
|
753
|
+
case 'lumi.sensor_86sw1': // Xiaomi wall switch (single button)
|
754
|
+
case 'lumi.ctrl_ln1.aq1':
|
755
|
+
buttons.push([1, 'Button', SINGLE | DOUBLE])
|
756
|
+
break
|
757
|
+
case 'lumi.sensor_86sw2': // Xiaomi wall switch (two buttons)
|
758
|
+
case 'lumi.ctrl_ln2.aq1':
|
759
|
+
buttons.push([1, 'Left', SINGLE | DOUBLE])
|
760
|
+
buttons.push([2, 'Right', SINGLE | DOUBLE])
|
761
|
+
buttons.push([3, 'Both', SINGLE | DOUBLE])
|
762
|
+
break
|
763
|
+
case 'lumi.sensor_cube':
|
764
|
+
case 'lumi.sensor_cube.aqgl01':
|
765
|
+
if (this.endpoint === '02') {
|
766
|
+
buttons.push([1, 'Side 1', SINGLE | DOUBLE | LONG])
|
767
|
+
buttons.push([2, 'Side 2', SINGLE | DOUBLE | LONG])
|
768
|
+
buttons.push([3, 'Side 3', SINGLE | DOUBLE | LONG])
|
769
|
+
buttons.push([4, 'Side 4', SINGLE | DOUBLE | LONG])
|
770
|
+
buttons.push([5, 'Side 5', SINGLE | DOUBLE | LONG])
|
771
|
+
buttons.push([6, 'Side 6', SINGLE | DOUBLE | LONG])
|
772
|
+
buttons.push([7, 'Cube', SINGLE | DOUBLE | LONG])
|
773
|
+
this.capabilities.toButtonEvent = (v) => {
|
774
|
+
const button = Math.floor(v / 1000)
|
775
|
+
let event = v % 1000
|
776
|
+
if (v === 7000) { // Wakeup
|
777
|
+
event = buttonEvent.SHORT_RELEASE
|
778
|
+
} else if (v === 7007 || v === 7008) { // Shake, Drop
|
779
|
+
} else if (event === 0) { // Push
|
780
|
+
event = buttonEvent.LONG_RELEASE
|
781
|
+
} else if (event === button) { // Double tap
|
782
|
+
event = buttonEvent.DOUBLE_PRESS
|
783
|
+
} else { // Flip
|
784
|
+
event = buttonEvent.SHORT_RELEASE
|
785
|
+
}
|
786
|
+
return button * 1000 + event
|
787
|
+
}
|
788
|
+
} else if (this.endpoint === '03') {
|
789
|
+
buttons.push([8, 'Turn Right', SINGLE | DOUBLE | LONG])
|
790
|
+
buttons.push([9, 'Turn Left', SINGLE | DOUBLE | LONG])
|
791
|
+
this.capabilities.toButtonEvent = (v) => {
|
792
|
+
const button = v > 0 ? 8 : 9
|
793
|
+
const event = Math.abs(v) < 4500
|
794
|
+
? buttonEvent.SHORT_RELEASE
|
795
|
+
: Math.abs(v) < 9000
|
796
|
+
? buttonEvent.DOUBLE_PRESS
|
797
|
+
: buttonEvent.LONG_RELEASE
|
798
|
+
return button * 1000 + event
|
799
|
+
}
|
800
|
+
}
|
801
|
+
break
|
802
|
+
case 'lumi.sensor_switch': // Xiaomi Mi wireless switch
|
803
|
+
case 'lumi.sensor_switch.aq2': // Xiaomi Aqara smart wireless switch
|
804
|
+
case 'lumi.sensor_switch.aq3': // Xiaomi Aqara smart wireless switch with gyro
|
805
|
+
buttons.push([1, 'Button', SINGLE | DOUBLE | LONG])
|
806
|
+
break
|
807
|
+
default:
|
808
|
+
break
|
809
|
+
}
|
810
|
+
break
|
811
|
+
case 'Lutron':
|
812
|
+
switch (this.model) {
|
813
|
+
case 'LZL4BWHL01 Remote': // Lutron Pico, see 102.
|
814
|
+
buttons.push([1, 'On', SINGLE])
|
815
|
+
buttons.push([2, 'Dim Up', LONG])
|
816
|
+
buttons.push([3, 'Dim Down', LONG])
|
817
|
+
buttons.push([4, 'Off', SINGLE])
|
818
|
+
break
|
819
|
+
case 'Z3-1BRL': // Lutron Aurora, see #522.
|
820
|
+
buttons.push([1, 'Button', SINGLE])
|
821
|
+
buttons.push([2, 'Turn Right', SINGLE])
|
822
|
+
buttons.push([3, 'Turn Left', SINGLE])
|
823
|
+
break
|
824
|
+
default:
|
825
|
+
break
|
826
|
+
}
|
827
|
+
break
|
828
|
+
case 'MLI':
|
829
|
+
switch (this.model) {
|
830
|
+
case 'ZBT-Remote-ALL-RGBW': // Tint remote control by Müller-Licht see deconz-rest-plugin#1209
|
831
|
+
buttons.push([1, 'On/Off', SINGLE])
|
832
|
+
buttons.push([2, 'Dim Up', SINGLE | LONG])
|
833
|
+
buttons.push([3, 'Dim Down', SINGLE | LONG])
|
834
|
+
buttons.push([4, 'Warm', SINGLE])
|
835
|
+
buttons.push([5, 'Cool', SINGLE])
|
836
|
+
buttons.push([6, 'Colour Wheel', SINGLE])
|
837
|
+
buttons.push([7, 'Work Light', SINGLE])
|
838
|
+
buttons.push([8, 'Sunset', SINGLE])
|
839
|
+
buttons.push([9, 'Party', SINGLE])
|
840
|
+
buttons.push([10, 'Night Light', SINGLE])
|
841
|
+
buttons.push([11, 'Campfire', SINGLE])
|
842
|
+
buttons.push([12, 'Romance', SINGLE])
|
843
|
+
break
|
844
|
+
default:
|
845
|
+
break
|
846
|
+
}
|
847
|
+
break
|
848
|
+
case 'OSRAM':
|
849
|
+
switch (this.model) {
|
850
|
+
case 'Lightify Switch Mini':
|
851
|
+
buttons.push([1, 'Up', SINGLE | LONG])
|
852
|
+
buttons.push([2, 'Down', SINGLE | LONG])
|
853
|
+
buttons.push([3, 'Middle', SINGLE | LONG])
|
854
|
+
break
|
855
|
+
default:
|
856
|
+
break
|
857
|
+
}
|
858
|
+
break
|
859
|
+
case 'Philips':
|
860
|
+
case 'Signify Netherlands B.V.':
|
861
|
+
switch (this.model) {
|
862
|
+
case 'RDM001': // Hue wall switch module
|
863
|
+
switch (this.body.config.devicemode) {
|
864
|
+
case 'singlerocker':
|
865
|
+
buttons.push([1, 'Rocker 1', SINGLE])
|
866
|
+
break
|
867
|
+
case 'singlepushbutton':
|
868
|
+
buttons.push([1, 'Push Button 1', SINGLE | LONG, true])
|
869
|
+
break
|
870
|
+
case 'dualrocker':
|
871
|
+
buttons.push([1, 'Rocker 1', SINGLE])
|
872
|
+
buttons.push([2, 'Rocker 2', SINGLE])
|
873
|
+
break
|
874
|
+
case 'dualpushbutton':
|
875
|
+
buttons.push([1, 'Push Button 1', SINGLE | LONG, true])
|
876
|
+
buttons.push([2, 'Push Button 2', SINGLE | LONG, true])
|
877
|
+
break
|
878
|
+
default:
|
879
|
+
break
|
880
|
+
}
|
881
|
+
break
|
882
|
+
case 'ROM001': // Hue smart button
|
883
|
+
buttons.push([1, 'Button', SINGLE | LONG, true])
|
884
|
+
break
|
885
|
+
case 'RWL020':
|
886
|
+
case 'RWL021': // Hue dimmer switch
|
887
|
+
buttons.push([1, 'On', SINGLE | LONG])
|
888
|
+
buttons.push([2, 'Dim Up', SINGLE | LONG, true])
|
889
|
+
buttons.push([3, 'Dim Down', SINGLE | LONG, true])
|
890
|
+
buttons.push([4, 'Off', SINGLE | LONG])
|
891
|
+
break
|
892
|
+
case 'RWL022': // Hue dimmer switch (2021)
|
893
|
+
buttons.push([1, 'On/Off', SINGLE | LONG])
|
894
|
+
buttons.push([2, 'Dim Up', SINGLE | LONG, true])
|
895
|
+
buttons.push([3, 'Dim Down', SINGLE | LONG, true])
|
896
|
+
buttons.push([4, 'Hue', SINGLE | LONG])
|
897
|
+
break
|
898
|
+
case 'ZGPSWITCH': // Hue tap
|
899
|
+
dots = true
|
900
|
+
buttons.push([1, '1', SINGLE])
|
901
|
+
buttons.push([2, '2', SINGLE])
|
902
|
+
buttons.push([3, '3', SINGLE])
|
903
|
+
buttons.push([4, '4', SINGLE])
|
904
|
+
buttons.push([5, '1 and 2', SINGLE])
|
905
|
+
buttons.push([6, '3 and 4', SINGLE])
|
906
|
+
this.capabilities.toButtonEvent = (v) => {
|
907
|
+
return hueTapMap[v]
|
908
|
+
}
|
909
|
+
break
|
910
|
+
default:
|
911
|
+
break
|
912
|
+
}
|
913
|
+
break
|
914
|
+
case 'PhilipsFoH':
|
915
|
+
if (this.model === 'FOHSWITCH') { // Friends-of-Hue switch
|
916
|
+
buttons.push([1, 'Top Left', SINGLE | LONG])
|
917
|
+
buttons.push([2, 'Bottom Left', SINGLE | LONG])
|
918
|
+
buttons.push([3, 'Top Right', SINGLE | LONG])
|
919
|
+
buttons.push([4, 'Bottom Right', SINGLE | LONG])
|
920
|
+
buttons.push([5, 'Top Both', SINGLE | LONG])
|
921
|
+
buttons.push([6, 'Bottom Both', SINGLE | LONG])
|
922
|
+
}
|
923
|
+
break
|
924
|
+
case 'Samjin':
|
925
|
+
switch (this.model) {
|
926
|
+
case 'button':
|
927
|
+
buttons.push([1, 'Button', SINGLE | DOUBLE | LONG])
|
928
|
+
break
|
929
|
+
default:
|
930
|
+
break
|
931
|
+
}
|
932
|
+
break
|
933
|
+
case 'Sunricher':
|
934
|
+
switch (this.model) {
|
935
|
+
case 'ZG2833K8_EU05': // Sunricher 8-button remote, see #529.
|
936
|
+
if (this.endpoint === '01') {
|
937
|
+
buttons.push([1, 'On 1', SINGLE | LONG])
|
938
|
+
buttons.push([2, 'Off 1', SINGLE | LONG])
|
939
|
+
} else if (this.endpoint === '02') {
|
940
|
+
buttons.push([3, 'On 2', SINGLE | LONG])
|
941
|
+
buttons.push([4, 'Off 2', SINGLE | LONG])
|
942
|
+
} else if (this.endpoint === '03') {
|
943
|
+
buttons.push([5, 'On 3', SINGLE | LONG])
|
944
|
+
buttons.push([6, 'Off 3', SINGLE | LONG])
|
945
|
+
} else if (this.endpoint === '04') {
|
946
|
+
buttons.push([7, 'On 4', SINGLE | LONG])
|
947
|
+
buttons.push([8, 'Off 4', SINGLE | LONG])
|
948
|
+
}
|
949
|
+
break
|
950
|
+
case 'ZG2833PAC': // Sunricher C4
|
951
|
+
buttons.push([1, 'Rocker 1', SINGLE])
|
952
|
+
buttons.push([2, 'Rocker 2', SINGLE])
|
953
|
+
buttons.push([3, 'Rocker 3', SINGLE])
|
954
|
+
buttons.push([4, 'Rocker 4', SINGLE])
|
955
|
+
break
|
956
|
+
case 'ZGRC-KEY-002': // Sunricher CCT remote, see #529.
|
957
|
+
buttons.push([1, 'On', SINGLE])
|
958
|
+
buttons.push([2, 'Off', SINGLE])
|
959
|
+
buttons.push([3, 'Dim', LONG])
|
960
|
+
buttons.push([4, 'C/W', SINGLE | LONG])
|
961
|
+
break
|
962
|
+
default:
|
963
|
+
break
|
964
|
+
}
|
965
|
+
break
|
966
|
+
case '_TZ3000_arfwfgoa':
|
967
|
+
switch (this.model) {
|
968
|
+
case 'TS0042': // Tuys 2-button switch, single endpoint
|
969
|
+
buttons.push([1, 'Left', SINGLE | DOUBLE | LONG])
|
970
|
+
buttons.push([2, 'Right', SINGLE | DOUBLE | LONG])
|
971
|
+
break
|
972
|
+
default:
|
973
|
+
break
|
974
|
+
}
|
975
|
+
break
|
976
|
+
case '_TZ3000_dfgbtub0':
|
977
|
+
case '_TZ3000_i3rjdrwu':
|
978
|
+
switch (this.model) {
|
979
|
+
case 'TS0042': // Tuya 2-button switch, see #1060.
|
980
|
+
if (this.endpoint === '01') {
|
981
|
+
buttons.push([1, 'Button 1', SINGLE | DOUBLE | LONG])
|
982
|
+
} else if (this.endpoint === '02') {
|
983
|
+
buttons.push([2, 'Button 2', SINGLE | DOUBLE | LONG])
|
984
|
+
}
|
985
|
+
break
|
986
|
+
default:
|
987
|
+
break
|
988
|
+
}
|
989
|
+
break
|
990
|
+
case '_TZ3000_pzui3skt':
|
991
|
+
switch (this.model) {
|
992
|
+
case 'TS0041': // Tuya 1-button switch
|
993
|
+
buttons.push([1, 'Button', SINGLE | DOUBLE | LONG])
|
994
|
+
break
|
995
|
+
default:
|
996
|
+
break
|
997
|
+
}
|
998
|
+
break
|
999
|
+
case '_TZ3000_rrjr1q0u':
|
1000
|
+
switch (this.model) {
|
1001
|
+
case 'TS0043': // Tuya 3-button switch
|
1002
|
+
buttons.push([1, 'Left', SINGLE | DOUBLE | LONG])
|
1003
|
+
buttons.push([2, 'Middle', SINGLE | DOUBLE | LONG])
|
1004
|
+
buttons.push([3, 'Right', SINGLE | DOUBLE | LONG])
|
1005
|
+
break
|
1006
|
+
default:
|
1007
|
+
break
|
1008
|
+
}
|
1009
|
+
break
|
1010
|
+
case '_TZ3000_vp6clf9d':
|
1011
|
+
switch (this.model) {
|
1012
|
+
case 'TS0044':
|
1013
|
+
buttons.push([1, 'Bottom Left', SINGLE | DOUBLE | LONG])
|
1014
|
+
buttons.push([2, 'Bottom Right', SINGLE | DOUBLE | LONG])
|
1015
|
+
buttons.push([3, 'Top Right', SINGLE | DOUBLE | LONG])
|
1016
|
+
buttons.push([4, 'Top Left', SINGLE | DOUBLE | LONG])
|
1017
|
+
break
|
1018
|
+
default:
|
1019
|
+
break
|
1020
|
+
}
|
1021
|
+
break
|
1022
|
+
case '_TZ3000_xabckq1v':
|
1023
|
+
switch (this.model) {
|
1024
|
+
case 'TS004F': // Tuya 4-button switch, single press only
|
1025
|
+
buttons.push([1, 'Top Left', SINGLE])
|
1026
|
+
buttons.push([2, 'Bottom Left', SINGLE])
|
1027
|
+
buttons.push([3, 'Top Right', SINGLE])
|
1028
|
+
buttons.push([4, 'Bottom Right', SINGLE])
|
1029
|
+
break
|
1030
|
+
default:
|
1031
|
+
break
|
1032
|
+
}
|
1033
|
+
break
|
1034
|
+
case 'dresden elektronik':
|
1035
|
+
switch (this.model) {
|
1036
|
+
case 'Kobold':
|
1037
|
+
buttons.push([1, 'Button', SINGLE | LONG])
|
1038
|
+
break
|
1039
|
+
case 'Lighting Switch':
|
1040
|
+
if (this.endpoint === '01') {
|
1041
|
+
if (this.body.mode !== 2) {
|
1042
|
+
gateway.vdebug(
|
1043
|
+
'%s: Lighting Switch mode %d instead of 2',
|
1044
|
+
this.rpath, this.body.mode
|
1045
|
+
)
|
1046
|
+
}
|
1047
|
+
buttons.push([1, 'Top Left', SINGLE | LONG])
|
1048
|
+
buttons.push([2, 'Bottom Left', SINGLE | LONG])
|
1049
|
+
buttons.push([3, 'Top Right', SINGLE | LONG])
|
1050
|
+
buttons.push([4, 'Bottom Right', SINGLE | LONG])
|
1051
|
+
}
|
1052
|
+
break
|
1053
|
+
case 'Scene Switch':
|
1054
|
+
buttons.push([1, 'On', SINGLE | LONG])
|
1055
|
+
buttons.push([2, 'Off', SINGLE | LONG])
|
1056
|
+
buttons.push([3, 'Scene 1', SINGLE])
|
1057
|
+
buttons.push([4, 'Scene 2', SINGLE])
|
1058
|
+
buttons.push([5, 'Scene 3', SINGLE])
|
1059
|
+
buttons.push([6, 'Scene 4', SINGLE])
|
1060
|
+
break
|
1061
|
+
default:
|
1062
|
+
break
|
1063
|
+
}
|
1064
|
+
break
|
1065
|
+
case 'eWeLink':
|
1066
|
+
switch (this.model) {
|
1067
|
+
case 'WB01':
|
1068
|
+
buttons.push([1, 'Press', SINGLE | DOUBLE | LONG])
|
1069
|
+
break
|
1070
|
+
default:
|
1071
|
+
break
|
1072
|
+
}
|
1073
|
+
break
|
1074
|
+
case 'icasa':
|
1075
|
+
switch (this.model) {
|
1076
|
+
case 'ICZB-KPD12':
|
1077
|
+
case 'ICZB-KPD14S':
|
1078
|
+
case 'ICZB-KPD18S':
|
1079
|
+
buttons.push([1, 'Off', SINGLE | LONG])
|
1080
|
+
buttons.push([2, 'On', SINGLE | LONG])
|
1081
|
+
if (this.model !== 'ICZB-KPD12') {
|
1082
|
+
buttons.push([3, 'S1', SINGLE])
|
1083
|
+
buttons.push([4, 'S2', SINGLE])
|
1084
|
+
if (this.model === 'ICZB-KPD18S') {
|
1085
|
+
buttons.push([5, 'S3', SINGLE])
|
1086
|
+
buttons.push([6, 'S4', SINGLE])
|
1087
|
+
buttons.push([7, 'S5', SINGLE])
|
1088
|
+
buttons.push([8, 'S6', SINGLE])
|
1089
|
+
}
|
1090
|
+
}
|
1091
|
+
break
|
1092
|
+
case 'ICZB-RM11S':
|
1093
|
+
buttons.push([1, '1 Off', SINGLE | LONG])
|
1094
|
+
buttons.push([2, '1 On', SINGLE | LONG])
|
1095
|
+
buttons.push([3, '2 Off', SINGLE | LONG])
|
1096
|
+
buttons.push([4, '2 On', SINGLE | LONG])
|
1097
|
+
buttons.push([5, '3 Off', SINGLE | LONG])
|
1098
|
+
buttons.push([6, '3 On', SINGLE | LONG])
|
1099
|
+
buttons.push([7, '4 Off', SINGLE | LONG])
|
1100
|
+
buttons.push([8, '4 On', SINGLE | LONG])
|
1101
|
+
buttons.push([9, 'S1', SINGLE])
|
1102
|
+
buttons.push([10, 'S2', SINGLE])
|
1103
|
+
break
|
1104
|
+
default:
|
1105
|
+
break
|
1106
|
+
}
|
1107
|
+
break
|
1108
|
+
case 'innr':
|
1109
|
+
switch (this.model) {
|
1110
|
+
case 'RC 110':
|
1111
|
+
if (this.endpoint === '01') {
|
1112
|
+
buttons.push([1, 'On/Off', SINGLE])
|
1113
|
+
buttons.push([2, 'Dim Up', SINGLE | LONG])
|
1114
|
+
buttons.push([3, 'Dim Down', SINGLE | LONG])
|
1115
|
+
buttons.push([4, '1', SINGLE])
|
1116
|
+
buttons.push([5, '2', SINGLE])
|
1117
|
+
buttons.push([6, '3', SINGLE])
|
1118
|
+
buttons.push([7, '4', SINGLE])
|
1119
|
+
buttons.push([8, '5', SINGLE])
|
1120
|
+
buttons.push([9, '6', SINGLE])
|
1121
|
+
for (let i = 1; i <= 6; i++) {
|
1122
|
+
const button = 7 + i * 3
|
1123
|
+
buttons.push([button, `On/Off ${i}`, SINGLE])
|
1124
|
+
buttons.push([button + 1, `Dim Up ${i}`, SINGLE | LONG])
|
1125
|
+
buttons.push([button + 2, `Dim Down ${i}`, SINGLE | LONG])
|
1126
|
+
}
|
1127
|
+
}
|
1128
|
+
break
|
1129
|
+
default:
|
1130
|
+
break
|
1131
|
+
}
|
1132
|
+
break
|
1133
|
+
case 'lk':
|
1134
|
+
switch (this.model) {
|
1135
|
+
case 'ZBT-DIMSwitch-D0001': // Linkind 1-Key Remote Control, see #949.
|
1136
|
+
buttons.push([1, 'Button', SINGLE | LONG])
|
1137
|
+
this.capabilities.homekitValue = (v) => { return 1 }
|
1138
|
+
break
|
1139
|
+
default:
|
1140
|
+
break
|
1141
|
+
}
|
1142
|
+
break
|
1143
|
+
case 'ubisys':
|
1144
|
+
switch (this.model) {
|
1145
|
+
case 'C4 (5504)':
|
1146
|
+
case 'C4-R (5604)':
|
1147
|
+
buttons.push([1, '1', SINGLE | LONG])
|
1148
|
+
buttons.push([2, '2', SINGLE | LONG])
|
1149
|
+
buttons.push([3, '3', SINGLE | LONG])
|
1150
|
+
buttons.push([4, '4', SINGLE | LONG])
|
1151
|
+
break
|
1152
|
+
case 'D1 (5503)':
|
1153
|
+
case 'D1-R (5603)':
|
1154
|
+
case 'S1-R (5601)':
|
1155
|
+
case 'S2 (5502)':
|
1156
|
+
case 'S2-R (5602)':
|
1157
|
+
buttons.push([1, '1', SINGLE | LONG])
|
1158
|
+
buttons.push([2, '2', SINGLE | LONG])
|
1159
|
+
break
|
1160
|
+
case 'S1 (5501)':
|
1161
|
+
buttons.push([1, '1', SINGLE | LONG])
|
1162
|
+
break
|
1163
|
+
default:
|
1164
|
+
break
|
1165
|
+
}
|
1166
|
+
break
|
1167
|
+
default:
|
1168
|
+
break
|
1169
|
+
}
|
1170
|
+
if (buttons.length > 0) {
|
1171
|
+
this.capabilities.buttons = {}
|
1172
|
+
for (const button of buttons) {
|
1173
|
+
this.capabilities.buttons[button[0]] = {
|
1174
|
+
label: button[1],
|
1175
|
+
events: button[2],
|
1176
|
+
hasRepeat: button[3]
|
1177
|
+
}
|
1178
|
+
}
|
1179
|
+
this.capabilities.namespace = dots
|
1180
|
+
? gateway.Characteristics.hap.ServiceLabelNamespace.DOTS
|
1181
|
+
: gateway.Characteristics.hap.ServiceLabelNamespace.ARABIC_NUMERALS
|
1182
|
+
}
|
1183
|
+
}
|
1184
|
+
|
1185
|
+
/** Patch a resource corresponding to a `Thermostat` service.
|
1186
|
+
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
1187
|
+
*/
|
1188
|
+
patchThermostat (gateway) {
|
1189
|
+
if (this.manufacturer === 'ELKO' && this.model === 'Super TR') {
|
1190
|
+
this.capabilities.heatValue = 'heat'
|
1191
|
+
} else {
|
1192
|
+
this.capabilities.heatValue = 'auto'
|
1193
|
+
}
|
1194
|
+
}
|
1195
|
+
|
1196
|
+
/** Patch a resource corresponding to a `WindowCovering` service.
|
1197
|
+
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
1198
|
+
*/
|
1199
|
+
patchWindowCovering (gateway) {
|
1200
|
+
if (this.manufacturer === 'LUMI' && this.model === 'lumi.curtain.acn002') {
|
1201
|
+
this.capabilities.maxSpeed = 2
|
1202
|
+
this.capabilities.positionChange = true
|
1203
|
+
}
|
1204
|
+
}
|
479
1205
|
}
|
480
1206
|
|
481
1207
|
module.exports = Resource
|