@homebridge-plugins/homebridge-ewelink 12.3.3

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.
Files changed (113) hide show
  1. package/CHANGELOG.md +1363 -0
  2. package/LICENSE +21 -0
  3. package/README.md +68 -0
  4. package/config.schema.json +1757 -0
  5. package/eslint.config.js +15 -0
  6. package/lib/connection/api.js +508 -0
  7. package/lib/connection/http.js +304 -0
  8. package/lib/connection/lan.js +318 -0
  9. package/lib/connection/ws.js +414 -0
  10. package/lib/device/curtain.js +324 -0
  11. package/lib/device/diffuser.js +473 -0
  12. package/lib/device/fan.js +349 -0
  13. package/lib/device/group.js +106 -0
  14. package/lib/device/humidifier.js +199 -0
  15. package/lib/device/index.js +61 -0
  16. package/lib/device/light-cct.js +333 -0
  17. package/lib/device/light-dimmer.js +257 -0
  18. package/lib/device/light-rgb-cct.js +809 -0
  19. package/lib/device/light-rgb.js +272 -0
  20. package/lib/device/motor.js +363 -0
  21. package/lib/device/outlet-multi.js +417 -0
  22. package/lib/device/outlet-single-inched.js +409 -0
  23. package/lib/device/outlet-single.js +384 -0
  24. package/lib/device/panel.js +382 -0
  25. package/lib/device/rf-bridge.js +321 -0
  26. package/lib/device/rf-button.js +125 -0
  27. package/lib/device/rf-sensor.js +173 -0
  28. package/lib/device/sensor-ambient.js +311 -0
  29. package/lib/device/sensor-contact.js +140 -0
  30. package/lib/device/sensor-temp-humi.js +182 -0
  31. package/lib/device/simulation/blind.js +253 -0
  32. package/lib/device/simulation/cooler.js +312 -0
  33. package/lib/device/simulation/door.js +253 -0
  34. package/lib/device/simulation/doorbell.js +190 -0
  35. package/lib/device/simulation/garage-eachen.js +235 -0
  36. package/lib/device/simulation/garage-four.js +176 -0
  37. package/lib/device/simulation/garage-od-switch.js +36 -0
  38. package/lib/device/simulation/garage-one.js +395 -0
  39. package/lib/device/simulation/garage-two.js +394 -0
  40. package/lib/device/simulation/gate-one.js +327 -0
  41. package/lib/device/simulation/heater.js +389 -0
  42. package/lib/device/simulation/index.js +75 -0
  43. package/lib/device/simulation/light-fan.js +258 -0
  44. package/lib/device/simulation/lock-eachen.js +163 -0
  45. package/lib/device/simulation/lock-one.js +366 -0
  46. package/lib/device/simulation/p-button.js +223 -0
  47. package/lib/device/simulation/purifier.js +289 -0
  48. package/lib/device/simulation/rf-blind.js +192 -0
  49. package/lib/device/simulation/rf-door.js +180 -0
  50. package/lib/device/simulation/rf-window.js +180 -0
  51. package/lib/device/simulation/sensor-hidden.js +105 -0
  52. package/lib/device/simulation/sensor-leak.js +123 -0
  53. package/lib/device/simulation/sensor-visible.js +231 -0
  54. package/lib/device/simulation/sensor.js +300 -0
  55. package/lib/device/simulation/switch-valve.js +351 -0
  56. package/lib/device/simulation/tap-one.js +283 -0
  57. package/lib/device/simulation/tap-two.js +266 -0
  58. package/lib/device/simulation/th-cooler.js +443 -0
  59. package/lib/device/simulation/th-dehumidifier.js +424 -0
  60. package/lib/device/simulation/th-heater.js +449 -0
  61. package/lib/device/simulation/th-humidifier.js +424 -0
  62. package/lib/device/simulation/th-thermostat.js +611 -0
  63. package/lib/device/simulation/tv.js +252 -0
  64. package/lib/device/simulation/valve-four.js +232 -0
  65. package/lib/device/simulation/valve-one.js +345 -0
  66. package/lib/device/simulation/valve-two.js +340 -0
  67. package/lib/device/simulation/window.js +253 -0
  68. package/lib/device/switch-man.js +106 -0
  69. package/lib/device/switch-mate.js +82 -0
  70. package/lib/device/switch-multi.js +411 -0
  71. package/lib/device/switch-single-inched.js +332 -0
  72. package/lib/device/switch-single.js +307 -0
  73. package/lib/device/template.js +43 -0
  74. package/lib/device/thermostat.js +286 -0
  75. package/lib/device/zigbee/index.js +27 -0
  76. package/lib/device/zigbee/light-cct.js +263 -0
  77. package/lib/device/zigbee/light-dimmer.js +148 -0
  78. package/lib/device/zigbee/light-rgb-cct.js +400 -0
  79. package/lib/device/zigbee/motor.js +301 -0
  80. package/lib/device/zigbee/sensor-ambient.js +177 -0
  81. package/lib/device/zigbee/sensor-contact.js +137 -0
  82. package/lib/device/zigbee/sensor-leak.js +119 -0
  83. package/lib/device/zigbee/sensor-motion.js +119 -0
  84. package/lib/device/zigbee/sensor-occupancy.js +119 -0
  85. package/lib/device/zigbee/sensor-smoke.js +96 -0
  86. package/lib/device/zigbee/switch-stateless.js +104 -0
  87. package/lib/device/zigbee/thermostat.js +323 -0
  88. package/lib/fakegato/LICENSE +21 -0
  89. package/lib/fakegato/fakegato-history.js +813 -0
  90. package/lib/fakegato/fakegato-storage.js +108 -0
  91. package/lib/fakegato/fakegato-timer.js +125 -0
  92. package/lib/fakegato/uuid.js +27 -0
  93. package/lib/homebridge-ui/public/index.html +365 -0
  94. package/lib/homebridge-ui/server.js +46 -0
  95. package/lib/index.js +7 -0
  96. package/lib/node-dns-sd/LICENSE +21 -0
  97. package/lib/node-dns-sd/README.md +613 -0
  98. package/lib/node-dns-sd/lib/dns-sd-classes.json +6 -0
  99. package/lib/node-dns-sd/lib/dns-sd-composer.js +83 -0
  100. package/lib/node-dns-sd/lib/dns-sd-parser.js +344 -0
  101. package/lib/node-dns-sd/lib/dns-sd-types.json +52 -0
  102. package/lib/node-dns-sd/lib/dns-sd.js +580 -0
  103. package/lib/platform.js +2156 -0
  104. package/lib/utils/colour.js +552 -0
  105. package/lib/utils/constants.js +589 -0
  106. package/lib/utils/custom-chars.js +33 -0
  107. package/lib/utils/eve-chars.js +130 -0
  108. package/lib/utils/functions.js +42 -0
  109. package/lib/utils/lang-en.js +160 -0
  110. package/lib/utils/lang-fr.js +163 -0
  111. package/lib/utils/lang-th.js +160 -0
  112. package/lib/utils/lang.js +5 -0
  113. package/package.json +75 -0
@@ -0,0 +1,253 @@
1
+ import platformConsts from '../../utils/constants.js'
2
+ import { generateRandomString, hasProperty, sleep } from '../../utils/functions.js'
3
+
4
+ export default class {
5
+ constructor(platform, accessory) {
6
+ // Set up variables from the platform
7
+ this.eveChar = platform.eveChar
8
+ this.hapChar = platform.api.hap.Characteristic
9
+ this.hapErr = platform.api.hap.HapStatusError
10
+ this.hapServ = platform.api.hap.Service
11
+ this.lang = platform.lang
12
+ this.log = platform.log
13
+ this.platform = platform
14
+
15
+ // Set up variables from the accessory
16
+ this.name = accessory.displayName
17
+ this.accessory = accessory
18
+
19
+ // Initially set the online flag as true (to be then updated as false if necessary)
20
+ this.isOnline = true
21
+
22
+ // Set up custom variables for this device type
23
+ const deviceConf = platform.deviceConf[accessory.context.eweDeviceId] || {}
24
+ this.operationTimeUp = deviceConf.operationTime || platformConsts.defaultValues.operationTime
25
+ this.operationTimeDown = deviceConf.operationTimeDown || this.operationTimeUp
26
+
27
+ // Set the correct logging variables for this accessory
28
+ switch (deviceConf.overrideLogging) {
29
+ case 'standard':
30
+ this.enableLogging = true
31
+ this.enableDebugLogging = false
32
+ break
33
+ case 'debug':
34
+ this.enableLogging = true
35
+ this.enableDebugLogging = true
36
+ break
37
+ case 'disable':
38
+ this.enableLogging = false
39
+ this.enableDebugLogging = false
40
+ break
41
+ default:
42
+ this.enableLogging = !platform.config.disableDeviceLogging
43
+ this.enableDebugLogging = platform.config.debug
44
+ break
45
+ }
46
+
47
+ // Set up the accessory with default positions when added the first time
48
+ if (!hasProperty(this.accessory.context, 'cacheCurrentPosition')) {
49
+ this.accessory.context.cacheCurrentPosition = 0
50
+ this.accessory.context.cachePositionState = 2
51
+ this.accessory.context.cacheTargetPosition = 0
52
+ }
53
+
54
+ // Add the window service if it doesn't already exist
55
+ this.service = this.accessory.getService(this.hapServ.Window)
56
+ if (!this.service) {
57
+ this.service = this.accessory.addService(this.hapServ.Window)
58
+ this.service.updateCharacteristic(this.hapChar.CurrentPosition, 0)
59
+ this.service.updateCharacteristic(this.hapChar.TargetPosition, 0)
60
+ this.service.updateCharacteristic(this.hapChar.PositionState, 2)
61
+ }
62
+
63
+ // Certain devices give power readings
64
+ if (platformConsts.devices.switchMultiPower.includes(this.accessory.context.eweUIID)) {
65
+ // Add Eve power characteristics
66
+ this.powerReadings = true
67
+ if (!this.service.testCharacteristic(this.eveChar.CurrentConsumption)) {
68
+ this.service.addCharacteristic(this.eveChar.CurrentConsumption)
69
+ }
70
+ if (!this.service.testCharacteristic(this.eveChar.ElectricCurrent)) {
71
+ this.service.addCharacteristic(this.eveChar.ElectricCurrent)
72
+ }
73
+ if (!this.service.testCharacteristic(this.eveChar.Voltage)) {
74
+ this.service.addCharacteristic(this.eveChar.Voltage)
75
+ }
76
+ }
77
+
78
+ // Add the set handler to the target position characteristic
79
+ this.service.getCharacteristic(this.hapChar.TargetPosition).onSet((value) => {
80
+ // We don't use await as we want the callback to be run straight away
81
+ this.internalPositionUpdate(value)
82
+ })
83
+
84
+ // Add the get handlers only if the user hasn't disabled the disableNoResponse setting
85
+ if (!platform.config.disableNoResponse) {
86
+ this.service.getCharacteristic(this.hapChar.CurrentPosition).onGet(() => {
87
+ if (!this.isOnline) {
88
+ throw new this.hapErr(-70402)
89
+ }
90
+ return this.service.getCharacteristic(this.hapChar.CurrentPosition).value
91
+ })
92
+ this.service.getCharacteristic(this.hapChar.TargetPosition).onGet(() => {
93
+ if (!this.isOnline) {
94
+ throw new this.hapErr(-70402)
95
+ }
96
+ return this.service.getCharacteristic(this.hapChar.TargetPosition).value
97
+ })
98
+ }
99
+
100
+ // Set up an interval to get eWeLink to send power updates
101
+ if (this.powerReadings && platform.config.mode !== 'lan') {
102
+ setTimeout(() => {
103
+ this.internalUIUpdate()
104
+ this.intervalPoll = setInterval(() => this.internalUIUpdate(), 120000)
105
+ }, 5000)
106
+
107
+ // Stop the intervals on Homebridge shutdown
108
+ platform.api.on('shutdown', () => clearInterval(this.intervalPoll))
109
+ }
110
+
111
+ // Output the customised options to the log
112
+ const normalLogging = this.enableLogging ? 'standard' : 'disable'
113
+ const opts = JSON.stringify({
114
+ logging: this.enableDebugLogging ? 'debug' : normalLogging,
115
+ operationTimeDown: this.operationTimeDown,
116
+ operationTimeUp: this.operationTimeUp,
117
+ showAs: 'window',
118
+ })
119
+ this.log('[%s] %s %s.', this.name, this.lang.devInitOpts, opts)
120
+ }
121
+
122
+ async internalPositionUpdate(value) {
123
+ try {
124
+ let prevPosition = this.accessory.context.cacheCurrentPosition
125
+ if (value === prevPosition) {
126
+ return
127
+ }
128
+ const params = {
129
+ switches: [],
130
+ }
131
+ const prevState = this.accessory.context.cachePositionState
132
+ const percentStepUpPerDS = this.operationTimeUp / 100
133
+ const percentStepDownPerDS = this.operationTimeDown / 100
134
+ const updateKey = generateRandomString(5)
135
+ this.updateKey = updateKey
136
+ if (prevState !== 2) {
137
+ params.switches.push({ switch: 'off', outlet: 0 })
138
+ params.switches.push({ switch: 'off', outlet: 1 })
139
+ await this.platform.sendDeviceUpdate(this.accessory, params)
140
+ params.switches = []
141
+ const posPercentChange = Math.floor(Date.now() / 100) - this.accessory.context.cacheLastStartTime
142
+ const posPercentChangeUp = Math.floor(percentStepUpPerDS * posPercentChange)
143
+ const posPercentChangeDown = Math.floor(percentStepDownPerDS * posPercentChange)
144
+ if (prevState === 0) {
145
+ // Was going down
146
+ prevPosition -= posPercentChangeDown
147
+ } else {
148
+ // Was going up
149
+ prevPosition += posPercentChangeUp
150
+ }
151
+ prevPosition = Math.min(Math.max(prevPosition, 0), 100)
152
+ this.service.updateCharacteristic(this.hapChar.CurrentPosition, prevPosition)
153
+ this.accessory.context.cacheCurrentPosition = prevPosition
154
+ }
155
+ const diffPosition = value - prevPosition
156
+ const setToMoveUp = diffPosition > 0
157
+ let decisecondsToMove
158
+ if (setToMoveUp) {
159
+ decisecondsToMove = Math.round(Math.abs(diffPosition) * percentStepUpPerDS)
160
+ params.switches.push({ switch: 'on', outlet: 0 })
161
+ } else {
162
+ decisecondsToMove = Math.round(Math.abs(diffPosition) * percentStepDownPerDS)
163
+ params.switches.push({ switch: 'on', outlet: 1 })
164
+ }
165
+ await this.platform.sendDeviceUpdate(this.accessory, params)
166
+ params.switches = []
167
+ this.accessory.context.cacheTargetPosition = value
168
+ this.accessory.context.cachePositionState = setToMoveUp ? 1 : 0
169
+ this.accessory.context.cacheLastStartTime = Math.floor(Date.now() / 100)
170
+ await sleep(decisecondsToMove * 100)
171
+ if (this.updateKey !== updateKey) {
172
+ return
173
+ }
174
+ params.switches.push({
175
+ switch: 'off',
176
+ outlet: setToMoveUp ? 0 : 1,
177
+ })
178
+ await this.platform.sendDeviceUpdate(this.accessory, params)
179
+ this.service.updateCharacteristic(this.hapChar.PositionState, 2)
180
+ this.service.updateCharacteristic(this.hapChar.CurrentPosition, value)
181
+ this.accessory.context.cachePositionState = 2
182
+ this.accessory.context.cacheCurrentPosition = value
183
+ if (this.enableLogging) {
184
+ this.log('[%s] %s [%s%]', this.name, this.lang.curPos, value)
185
+ }
186
+ } catch (err) {
187
+ this.platform.deviceUpdateError(this.accessory, err, true)
188
+ setTimeout(() => {
189
+ this.service.updateCharacteristic(
190
+ this.hapChar.TargetPosition,
191
+ this.accessory.context.cacheTargetPosition,
192
+ )
193
+ }, 2000)
194
+ this.service.updateCharacteristic(this.hapChar.TargetPosition, new this.hapErr(-70402))
195
+ }
196
+ }
197
+
198
+ async internalUIUpdate() {
199
+ try {
200
+ // Skip polling if device isn't online
201
+ if (!this.isOnline) {
202
+ return
203
+ }
204
+
205
+ // Send the params to request the updates
206
+ await this.platform.sendDeviceUpdate(this.accessory, { uiActive: { outlet: 0, time: 120 } })
207
+ } catch (err) {
208
+ // Suppress errors here
209
+ }
210
+ }
211
+
212
+ async externalUpdate(params) {
213
+ try {
214
+ if (!this.powerReadings) {
215
+ return
216
+ }
217
+ let logger = false
218
+ let power
219
+ let voltage
220
+ let current
221
+ if (hasProperty(params, 'actPow_00')) {
222
+ power = Number.parseInt(params.actPow_00, 10) / 100
223
+ this.service.updateCharacteristic(this.eveChar.CurrentConsumption, power)
224
+ logger = true
225
+ }
226
+ if (hasProperty(params, 'voltage_00')) {
227
+ voltage = Number.parseInt(params.voltage_00, 10) / 100
228
+ this.service.updateCharacteristic(this.eveChar.Voltage, voltage)
229
+ logger = true
230
+ }
231
+ if (hasProperty(params, 'current_00')) {
232
+ current = Number.parseInt(params.current_00, 10) / 100
233
+ this.service.updateCharacteristic(this.eveChar.ElectricCurrent, current)
234
+ logger = true
235
+ }
236
+ if (params.updateSource && logger && this.enableLogging) {
237
+ this.log(
238
+ '[%s] %s%s%s.',
239
+ this.name,
240
+ power !== undefined ? `${this.lang.curPower} [${power}W]` : '',
241
+ voltage !== undefined ? ` ${this.lang.curVolt} [${voltage}V]` : '',
242
+ current !== undefined ? ` ${this.lang.curCurr} [${current}A]` : '',
243
+ )
244
+ }
245
+ } catch (err) {
246
+ this.platform.deviceUpdateError(this.accessory, err, false)
247
+ }
248
+ }
249
+
250
+ markStatus(isOnline) {
251
+ this.isOnline = isOnline
252
+ }
253
+ }
@@ -0,0 +1,106 @@
1
+ import { hasProperty } from '../utils/functions.js'
2
+
3
+ export default class {
4
+ constructor(platform, accessory) {
5
+ // Set up variables from the platform
6
+ this.hapChar = platform.api.hap.Characteristic
7
+ this.hapServ = platform.api.hap.Service
8
+ this.lang = platform.lang
9
+ this.log = platform.log
10
+ this.platform = platform
11
+
12
+ // Set up variables from the accessory
13
+ this.name = accessory.displayName
14
+ this.accessory = accessory
15
+
16
+ // Set up custom variables for this device type
17
+ const deviceConf = platform.deviceConf[accessory.context.eweDeviceId] || {}
18
+
19
+ // Set the correct logging variables for this accessory
20
+ switch (deviceConf.overrideLogging) {
21
+ case 'standard':
22
+ this.enableLogging = true
23
+ this.enableDebugLogging = false
24
+ break
25
+ case 'debug':
26
+ this.enableLogging = true
27
+ this.enableDebugLogging = true
28
+ break
29
+ case 'disable':
30
+ this.enableLogging = false
31
+ this.enableDebugLogging = false
32
+ break
33
+ default:
34
+ this.enableLogging = !platform.config.disableDeviceLogging
35
+ this.enableDebugLogging = platform.config.debug
36
+ break
37
+ }
38
+ this.timeouts = {};
39
+
40
+ // Add the stateless switch services if they don't already exist
41
+ [1, 2, 3, 4, 5, 6].forEach((label) => {
42
+ this[`service${label}`] = this.accessory.getService(`Channel ${label}`)
43
+ if (!this[`service${label}`]) {
44
+ this[`service${label}`] = this.accessory.addService(
45
+ this.hapServ.StatelessProgrammableSwitch,
46
+ `Channel ${label}`,
47
+ `channel${label}`,
48
+ )
49
+
50
+ // Add the ConfiguredName characteristic
51
+ this[`service${label}`].addCharacteristic(this.hapChar.ConfiguredName)
52
+ this[`service${label}`].updateCharacteristic(this.hapChar.ConfiguredName, `Channel ${label}`)
53
+
54
+ // Add the ServiceLabelIndex characteristic
55
+ this[`service${label}`].addCharacteristic(this.hapChar.ServiceLabelIndex)
56
+ this[`service${label}`].updateCharacteristic(this.hapChar.ServiceLabelIndex, label)
57
+ }
58
+
59
+ this.timeouts[label] = false
60
+ })
61
+
62
+ // Output the customised options to the log
63
+ const normalLogging = this.enableLogging ? 'standard' : 'disable'
64
+ const opts = JSON.stringify({
65
+ logging: this.enableDebugLogging ? 'debug' : normalLogging,
66
+ })
67
+ this.log('[%s] %s %s.', this.name, this.lang.devInitOpts, opts)
68
+ }
69
+
70
+ async externalUpdate(params) {
71
+ try {
72
+ if (
73
+ hasProperty(params, 'outlet')
74
+ && [0, 1, 2, 3, 4, 5].includes(params.outlet)
75
+ && params.actionTime
76
+ && !this.timeouts[params.outlet + 1]
77
+ ) {
78
+ const label = params.outlet + 1
79
+ this.timeouts[label] = true
80
+ setTimeout(() => {
81
+ this.timeouts[label] = false
82
+ }, 1000)
83
+ const timeDiff = (new Date().getTime() - Date.parse(params.actionTime)) / 1000
84
+ if (timeDiff < 5) {
85
+ const service = this[`service${label}`]
86
+ service.updateCharacteristic(this.hapChar.ProgrammableSwitchEvent, params.key)
87
+ if (params.updateSource && this.enableLogging) {
88
+ const doubleLong = params.key === 1 ? this.lang.buttonDouble : this.lang.buttonLong
89
+ const textLabel = params.key === 0 ? this.lang.buttonSingle : doubleLong
90
+ if (this.enableLogging) {
91
+ this.log(
92
+ '[%s] [%s] %s [%s].',
93
+ this.name,
94
+ service.getCharacteristic(this.hapChar.ConfiguredName),
95
+ this.lang.curState,
96
+ textLabel,
97
+ )
98
+ }
99
+ }
100
+ }
101
+ }
102
+ } catch (err) {
103
+ this.platform.deviceUpdateError(this.accessory, err, false)
104
+ }
105
+ }
106
+ }
@@ -0,0 +1,82 @@
1
+ import { hasProperty } from '../utils/functions.js'
2
+
3
+ export default class {
4
+ constructor(platform, accessory) {
5
+ // Set up variables from the platform
6
+ this.hapChar = platform.api.hap.Characteristic
7
+ this.hapServ = platform.api.hap.Service
8
+ this.lang = platform.lang
9
+ this.log = platform.log
10
+ this.platform = platform
11
+
12
+ // Set up variables from the accessory
13
+ this.name = accessory.displayName
14
+ this.accessory = accessory
15
+
16
+ // Set up custom variables for this device type
17
+ const deviceConf = platform.deviceConf[accessory.context.eweDeviceId] || {}
18
+
19
+ // Set the correct logging variables for this accessory
20
+ switch (deviceConf.overrideLogging) {
21
+ case 'standard':
22
+ this.enableLogging = true
23
+ this.enableDebugLogging = false
24
+ break
25
+ case 'debug':
26
+ this.enableLogging = true
27
+ this.enableDebugLogging = true
28
+ break
29
+ case 'disable':
30
+ this.enableLogging = false
31
+ this.enableDebugLogging = false
32
+ break
33
+ default:
34
+ this.enableLogging = !platform.config.disableDeviceLogging
35
+ this.enableDebugLogging = platform.config.debug
36
+ break
37
+ }
38
+ this.timeouts = {
39
+ 0: false,
40
+ 1: false,
41
+ 2: false,
42
+ }
43
+
44
+ // Add the stateless switch service if it doesn't already exist
45
+ this.service = this.accessory.getService(this.hapServ.StatelessProgrammableSwitch)
46
+ || this.accessory.addService(this.hapServ.StatelessProgrammableSwitch)
47
+
48
+ // Output the customised options to the log
49
+ const normalLogging = this.enableLogging ? 'standard' : 'disable'
50
+ const opts = JSON.stringify({
51
+ logging: this.enableDebugLogging ? 'debug' : normalLogging,
52
+ })
53
+ this.log('[%s] %s %s.', this.name, this.lang.devInitOpts, opts)
54
+ }
55
+
56
+ async externalUpdate(params) {
57
+ try {
58
+ if (
59
+ hasProperty(params, 'outlet')
60
+ && [0, 1, 2].includes(params.outlet)
61
+ && params.actionTime
62
+ && !this.timeouts[params.outlet]
63
+ ) {
64
+ this.timeouts[params.outlet] = true
65
+ setTimeout(() => {
66
+ this.timeouts[params.outlet] = false
67
+ }, 1000)
68
+ const timeDiff = (new Date().getTime() - Date.parse(params.actionTime)) / 1000
69
+ if (timeDiff < 5) {
70
+ this.service.updateCharacteristic(this.hapChar.ProgrammableSwitchEvent, params.outlet)
71
+ if (params.updateSource && this.enableLogging) {
72
+ const doubleLong = params.outlet === 1 ? this.lang.buttonDouble : this.lang.buttonLong
73
+ const textLabel = params.outlet === 0 ? this.lang.buttonSingle : doubleLong
74
+ this.log('[%s] %s [%s].', this.name, this.lang.curState, textLabel)
75
+ }
76
+ }
77
+ }
78
+ } catch (err) {
79
+ this.platform.deviceUpdateError(this.accessory, err, false)
80
+ }
81
+ }
82
+ }