@homebridge-plugins/homebridge-govee 11.32.2-beta.2 → 11.32.2-beta.21

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 (73) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/config.schema.json +1 -1
  3. package/lib/connection/ble.js +26 -1
  4. package/lib/connection/openapi.js +18 -0
  5. package/lib/device/appliance-basic.js +377 -0
  6. package/lib/device/dehumidifier-H7150.js +9 -3
  7. package/lib/device/diffuser-H7161.js +7 -1
  8. package/lib/device/fan-H1370.js +7 -1
  9. package/lib/device/fan-H7100.js +36 -4
  10. package/lib/device/fan-H7105.js +7 -1
  11. package/lib/device/fan-H7107.js +7 -1
  12. package/lib/device/heater1a.js +52 -12
  13. package/lib/device/heater1b.js +14 -3
  14. package/lib/device/heater2.js +7 -1
  15. package/lib/device/humidifier-H7140.js +7 -1
  16. package/lib/device/humidifier-H7141.js +7 -1
  17. package/lib/device/humidifier-H7142.js +7 -1
  18. package/lib/device/humidifier-H7143.js +7 -1
  19. package/lib/device/humidifier-H7160.js +7 -1
  20. package/lib/device/ice-maker-H7172.js +19 -7
  21. package/lib/device/index.js +44 -51
  22. package/lib/device/kettle.js +7 -1
  23. package/lib/device/outlet-single.js +7 -1
  24. package/lib/device/purifier-H7120.js +14 -25
  25. package/lib/device/purifier-H7122.js +7 -1
  26. package/lib/device/purifier-H7123.js +9 -3
  27. package/lib/device/purifier-H7126.js +7 -1
  28. package/lib/device/{sensor-button.js → sensor-basic.js} +14 -2
  29. package/lib/device/sensor-presence.js +7 -1
  30. package/lib/device/sensor-thermo4.js +13 -2
  31. package/lib/device/switch-double.js +34 -15
  32. package/lib/device/switch-triple.js +36 -17
  33. package/lib/device/template.js +15 -2
  34. package/lib/platform.js +83 -799
  35. package/lib/utils/capabilities.js +220 -0
  36. package/lib/utils/command-builder.js +6 -4
  37. package/lib/utils/config-parser.js +280 -0
  38. package/lib/utils/constants.js +120 -8
  39. package/lib/utils/decode.js +4 -1
  40. package/lib/utils/device-capabilities.js +77 -3
  41. package/lib/utils/device-context.js +179 -0
  42. package/lib/utils/device-merge.js +251 -0
  43. package/lib/utils/dispatch.js +159 -0
  44. package/lib/utils/functions.js +9 -0
  45. package/lib/utils/lang-en.js +0 -2
  46. package/lib/utils/report-unknown.js +156 -0
  47. package/package.json +1 -1
  48. package/lib/device/dehumidifier-H7151.js +0 -189
  49. package/lib/device/dehumidifier-H7152.js +0 -180
  50. package/lib/device/diffuser-H7162.js +0 -123
  51. package/lib/device/fan-H1310.js +0 -284
  52. package/lib/device/fan-H7101.js +0 -340
  53. package/lib/device/fan-H7102.js +0 -284
  54. package/lib/device/fan-H7106.js +0 -284
  55. package/lib/device/fan-H7111.js +0 -345
  56. package/lib/device/humidifier-H7145.js +0 -187
  57. package/lib/device/humidifier-H7147.js +0 -187
  58. package/lib/device/humidifier-H7148.js +0 -187
  59. package/lib/device/humidifier-H7149.js +0 -187
  60. package/lib/device/humidifier-H714E.js +0 -187
  61. package/lib/device/ice-maker-H717D.js +0 -218
  62. package/lib/device/ice-maker-H8120.js +0 -218
  63. package/lib/device/outlet-double.js +0 -188
  64. package/lib/device/outlet-triple.js +0 -160
  65. package/lib/device/purifier-H7121.js +0 -406
  66. package/lib/device/purifier-H7124.js +0 -504
  67. package/lib/device/purifier-H7127.js +0 -359
  68. package/lib/device/purifier-H7128.js +0 -359
  69. package/lib/device/purifier-H7129.js +0 -359
  70. package/lib/device/purifier-H712C.js +0 -359
  71. package/lib/device/sensor-contact.js +0 -22
  72. package/lib/utils/ble-timeouts.test.js +0 -44
  73. package/lib/utils/functions.test.js +0 -292
@@ -1,345 +0,0 @@
1
- import {
2
- base64ToHex,
3
- fanSpeedToHkPercent,
4
- getTwoItemPosition,
5
- hexToTwoItems,
6
- hkPercentToFanSpeed,
7
- parseError,
8
- } from '../utils/functions.js'
9
- import platformLang from '../utils/lang-en.js'
10
-
11
- /*
12
-
13
- H7111
14
- {
15
- "mode": {
16
- "options": [
17
- {
18
- "name": "Custom",
19
- "value": 2
20
- },
21
- {
22
- "name": "Auto",
23
- "value": 3
24
- },
25
- {
26
- "name": "Sleep",
27
- "value": 5
28
- },
29
- {
30
- "name": "Nature",
31
- "value": 6
32
- },
33
- {
34
- "name": "Turbo",
35
- "value": 7
36
- }
37
- ]
38
- },
39
- "gear": {
40
- "options": [
41
- {
42
- "name": "gear",
43
- "value": [
44
- 1,
45
- 2,
46
- 3,
47
- 4,
48
- 5,
49
- 6,
50
- 7,
51
- 8
52
- ]
53
- }
54
- ]
55
- }
56
- }
57
-
58
- // NOTES
59
- H7111 -> Sleep, Nature, Custom, Auto
60
-
61
- sleep
62
- [31/10/2022, 20:52:08] [Govee] [Device1] [AWS] receiving update {"source":"AWS","result":1,"commands":["qgUFAAAAAAAAAAAAAAAAAAAAAKo=","qgUABQAAAAAAAAAAAAAAAAAAAKo="]}.
63
- [31/10/2022, 20:52:08] [Govee] [Device1] new scene code: [qgUFAAAAAAAAAAAAAAAAAAAAAKo=] [aa050500000000000000000000000000000000aa].
64
- [31/10/2022, 20:52:08] [Govee] [Device1] new scene code: [qgUABQAAAAAAAAAAAAAAAAAAAKo=] [aa050005000000000000000000000000000000aa].
65
-
66
- nature
67
- [31/10/2022, 20:52:43] [Govee] [Device1] [AWS] receiving update {"source":"AWS","result":1,"commands":["qgUGAAAAAAAAAAAAAAAAAAAAAKk=","qgUABgAAAAAAAAAAAAAAAAAAAKk="]}.
68
- [31/10/2022, 20:52:43] [Govee] [Device1] new scene code: [qgUGAAAAAAAAAAAAAAAAAAAAAKk=] [aa050600000000000000000000000000000000a9].
69
- [31/10/2022, 20:52:43] [Govee] [Device1] new scene code: [qgUABgAAAAAAAAAAAAAAAAAAAKk=] [aa050006000000000000000000000000000000a9].
70
- */
71
-
72
- export default class {
73
- constructor(platform, accessory) {
74
- // Set up variables from the platform
75
- this.hapChar = platform.api.hap.Characteristic
76
- this.hapErr = platform.api.hap.HapStatusError
77
- this.hapServ = platform.api.hap.Service
78
- this.platform = platform
79
-
80
- // Set up variables from the accessory
81
- this.accessory = accessory
82
-
83
- // Codes etc
84
- this.speedCodes = {
85
- 1: 'MwUBAQAAAAAAAAAAAAAAAAAAADY=',
86
- 2: 'MwUBAgAAAAAAAAAAAAAAAAAAADU=',
87
- 3: 'MwUBAwAAAAAAAAAAAAAAAAAAADQ=',
88
- 4: 'MwUBBAAAAAAAAAAAAAAAAAAAADM=',
89
- 5: 'MwUBBQAAAAAAAAAAAAAAAAAAADI=',
90
- 6: 'MwUBBgAAAAAAAAAAAAAAAAAAADE=',
91
- 7: 'MwUBBwAAAAAAAAAAAAAAAAAAADA=',
92
- 8: 'MwUBCAAAAAAAAAAAAAAAAAAAAD8=',
93
- 9: 'MwUAAwAAAAAAAAAAAAAAAAAAADU=', // auto mode
94
- }
95
- this.autoSpeed = 9
96
- // Real speed steps, excluding auto - HomeKit percentages map onto these
97
- this.speedSteps = 8
98
-
99
- // Remove any old original Fan services
100
- if (this.accessory.getService(this.hapServ.Fan)) {
101
- this.accessory.removeService(this.accessory.getService(this.hapServ.Fan))
102
- }
103
-
104
- // Rebuild the fan service if it was cached under an older speed scale, as
105
- // HomeKit keeps the old props until the service itself is replaced
106
- const existingService = this.accessory.getService(this.hapServ.Fanv2)
107
- if (existingService) {
108
- const { props } = existingService.getCharacteristic(this.hapChar.RotationSpeed)
109
- if (props.unit === 'percentage' || props.maxValue !== 100) {
110
- this.accessory.removeService(existingService)
111
- }
112
- }
113
-
114
- // Add the fan service for the fan if it doesn't already exist
115
- this.service = this.accessory.getService(this.hapServ.Fanv2) || this.accessory.addService(this.hapServ.Fanv2)
116
-
117
- // Add the set handler to the fan on/off characteristic
118
- this.service
119
- .getCharacteristic(this.hapChar.Active)
120
- .onSet(async value => this.internalStateUpdate(value))
121
- this.cacheState = this.service.getCharacteristic(this.hapChar.Active).value ? 'on' : 'off'
122
-
123
- // Add the set handler to the fan rotation speed characteristic
124
- this.service
125
- .getCharacteristic(this.hapChar.RotationSpeed)
126
- .setProps({
127
- maxValue: 100,
128
- minStep: 1,
129
- minValue: 0,
130
- unit: 'unitless',
131
- })
132
- .onSet(async value => this.internalSpeedUpdate(value))
133
- this.cacheSpeed = this.service.getCharacteristic(this.hapChar.RotationSpeed).value
134
-
135
- // Add the set handler to the fan swing mode
136
- this.service
137
- .getCharacteristic(this.hapChar.SwingMode)
138
- .onSet(async value => this.internalSwingUpdate(value))
139
- this.cacheSwing = this.service.getCharacteristic(this.hapChar.SwingMode).value === 1 ? 'on' : 'off'
140
-
141
- // Output the customised options to the log
142
- const opts = JSON.stringify({})
143
- platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
144
- }
145
-
146
- async internalStateUpdate(value) {
147
- try {
148
- const newValue = value ? 'on' : 'off'
149
-
150
- // Don't continue if the new value is the same as before
151
- if (this.cacheState === newValue) {
152
- return
153
- }
154
-
155
- // Send the request to the platform sender function
156
- await this.platform.sendDeviceUpdate(this.accessory, {
157
- cmd: 'ptReal',
158
- value: value ? 'MwEBAAAAAAAAAAAAAAAAAAAAADM=' : 'MwEAAAAAAAAAAAAAAAAAAAAAADI=',
159
- })
160
-
161
- // Cache the new state and log if appropriate
162
- if (this.cacheState !== newValue) {
163
- this.cacheState = newValue
164
- this.accessory.log(`${platformLang.curState} [${newValue}]`)
165
- }
166
- } catch (err) {
167
- // Catch any errors during the process
168
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
169
-
170
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
171
- setTimeout(() => {
172
- this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on' ? 1 : 0)
173
- }, 2000)
174
- throw new this.hapErr(-70402)
175
- }
176
- }
177
-
178
- async internalSpeedUpdate(value) {
179
- try {
180
- // Don't continue if the value is 0
181
- if (value === 0) {
182
- return
183
- }
184
-
185
- // HomeKit sends a percentage - map it onto this model's real speed steps
186
- value = hkPercentToFanSpeed(value, this.speedSteps)
187
-
188
- // Don't continue if the new value is the same as before
189
- if (this.cacheSpeed === value) {
190
- return
191
- }
192
-
193
- const codeToSend = this.speedCodes[value]
194
-
195
- const isAuto = value === this.autoSpeed
196
- await this.platform.sendDeviceUpdate(this.accessory, {
197
- cmd: 'ptReal',
198
- value: codeToSend,
199
- openApi: this.accessory.context.openApiCapabilities?.workMode
200
- ? { instance: 'workMode', capabilityType: 'devices.capabilities.work_mode', value: isAuto ? { workMode: 3 } : { workMode: 1, modeValue: value } }
201
- : undefined,
202
- })
203
-
204
- // Cache the new state and log if appropriate
205
- if (this.cacheSpeed !== value) {
206
- this.cacheSpeed = value
207
- this.accessory.log(`${platformLang.curSpeed} [${value}]`)
208
- }
209
- } catch (err) {
210
- // Catch any errors during the process
211
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
212
-
213
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
214
- setTimeout(() => {
215
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, fanSpeedToHkPercent(this.cacheSpeed, this.speedSteps, this.autoSpeed))
216
- }, 2000)
217
- throw new this.hapErr(-70402)
218
- }
219
- }
220
-
221
- async internalSwingUpdate(value) {
222
- try {
223
- const newValue = value ? 'on' : 'off'
224
- // Don't continue if the new value is the same as before
225
- if (this.cacheSwing === value) {
226
- return
227
- }
228
-
229
- await this.platform.sendDeviceUpdate(this.accessory, {
230
- cmd: 'ptReal',
231
- value: value ? 'Mx8BAQAAAAAAAAAAAAAAAAAAACw=' : 'Mx8BAAAAAAAAAAAAAAAAAAAAAC0=',
232
- openApi: this.accessory.context.openApiCapabilities?.oscillationToggle
233
- ? { instance: 'oscillationToggle', capabilityType: 'devices.capabilities.toggle', value: value ? 1 : 0 }
234
- : undefined,
235
- })
236
-
237
- // Cache the new state and log if appropriate
238
- if (this.cacheSwing !== newValue) {
239
- this.cacheSwing = newValue
240
- this.accessory.log(`${platformLang.curSwing} [${newValue}]`)
241
- }
242
- } catch (err) {
243
- // Catch any errors during the process
244
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
245
-
246
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
247
- setTimeout(() => {
248
- this.service.updateCharacteristic(this.hapChar.SwingMode, this.cacheSwing === 'on' ? 1 : 0)
249
- }, 2000)
250
- throw new this.hapErr(-70402)
251
- }
252
- }
253
-
254
- externalUpdate(params) {
255
- // Update the active characteristic
256
- if (params.state && params.state !== this.cacheState) {
257
- this.cacheState = params.state
258
- this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on' ? 1 : 0)
259
- this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
260
- }
261
-
262
- // Handle OpenAPI workMode (speed or auto)
263
- if (params.workMode) {
264
- let newSpeed
265
- if (params.workMode.workMode === 3) {
266
- newSpeed = this.autoSpeed
267
- } else {
268
- newSpeed = params.workMode.modeValue
269
- }
270
- if (Number.isFinite(newSpeed) && newSpeed >= 1 && newSpeed <= this.autoSpeed && this.cacheSpeed !== newSpeed) {
271
- this.cacheSpeed = newSpeed
272
- const hkSpeed = fanSpeedToHkPercent(newSpeed, this.speedSteps, this.autoSpeed)
273
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, hkSpeed)
274
- this.accessory.log(`${platformLang.curSpeed} [${newSpeed} -> ${hkSpeed}%]`)
275
- }
276
- }
277
-
278
- // Handle OpenAPI toggles
279
- if (params.toggles?.oscillationToggle !== undefined) {
280
- const newSwing = params.toggles.oscillationToggle ? 'on' : 'off'
281
- if (this.cacheSwing !== newSwing) {
282
- this.cacheSwing = newSwing
283
- this.service.updateCharacteristic(this.hapChar.SwingMode, this.cacheSwing === 'on' ? 1 : 0)
284
- this.accessory.log(`${platformLang.curSwing} [${this.cacheSwing}]`)
285
- }
286
- }
287
-
288
- // Check for some other scene/mode change
289
- ;(params.commands || []).forEach((command) => {
290
- const hexString = base64ToHex(command)
291
- const hexParts = hexToTwoItems(hexString)
292
-
293
- // Return now if not a device query update code
294
- if (getTwoItemPosition(hexParts, 1) !== 'aa') {
295
- return
296
- }
297
-
298
- if (getTwoItemPosition(hexParts, 2) === '08') {
299
- // Sensor Attached?
300
- const dev = hexString.substring(4, hexString.length - 24)
301
- this.accessory.context.sensorAttached = dev !== '000000000000'
302
- return
303
- }
304
-
305
- const deviceFunction = `${getTwoItemPosition(hexParts, 2)}${getTwoItemPosition(hexParts, 3)}`
306
-
307
- switch (deviceFunction) {
308
- case '0501': {
309
- // Fan speed
310
- const newSpeed = Number.parseInt(getTwoItemPosition(hexParts, 4), 16)
311
- if (newSpeed >= 1 && newSpeed <= this.speedSteps && this.cacheSpeed !== newSpeed) {
312
- this.cacheSpeed = newSpeed
313
- const hkSpeed = fanSpeedToHkPercent(newSpeed, this.speedSteps, this.autoSpeed)
314
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, hkSpeed)
315
- this.accessory.log(`${platformLang.curSpeed} [${newSpeed} -> ${hkSpeed}%]`)
316
- }
317
- break
318
- }
319
- case '0500': {
320
- // Mode change (auto = 0x03)
321
- if (getTwoItemPosition(hexParts, 4) === '03' && this.cacheSpeed !== this.autoSpeed) {
322
- // Cache auto so we can tell it apart from "user asked for max speed"
323
- this.cacheSpeed = this.autoSpeed
324
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, 100)
325
- this.accessory.log(`${platformLang.curSpeed} [auto -> 100%]`)
326
- }
327
- break
328
- }
329
- case '1f01': {
330
- // Swing Mode
331
- const newSwing = getTwoItemPosition(hexParts, 4) === '01' ? 'on' : 'off'
332
- if (this.cacheSwing !== newSwing) {
333
- this.cacheSwing = newSwing
334
- this.service.updateCharacteristic(this.hapChar.SwingMode, this.cacheSwing === 'on' ? 1 : 0)
335
- this.accessory.log(`${platformLang.curSwing} [${this.cacheSwing}]`)
336
- }
337
- break
338
- }
339
- default:
340
- this.accessory.logDebugWarn(`${platformLang.newScene}: [${command}] [${hexString}]`)
341
- break
342
- }
343
- })
344
- }
345
- }
@@ -1,187 +0,0 @@
1
- import {
2
- base64ToHex,
3
- getTwoItemPosition,
4
- hexToTwoItems,
5
- parseError,
6
- } from '../utils/functions.js'
7
- import platformLang from '../utils/lang-en.js'
8
-
9
- export default class {
10
- constructor(platform, accessory) {
11
- // Set up variables from the platform
12
- this.hapChar = platform.api.hap.Characteristic
13
- this.hapErr = platform.api.hap.HapStatusError
14
- this.hapServ = platform.api.hap.Service
15
- this.platform = platform
16
-
17
- // Set up variables from the accessory
18
- this.accessory = accessory
19
-
20
- // Speed codes
21
- this.value2Code = {
22
- 1: 'MwUBAQAAAAAAAAAAAAAAAAAAADY=',
23
- 2: 'MwUBAgAAAAAAAAAAAAAAAAAAADU=',
24
- 3: 'MwUBAwAAAAAAAAAAAAAAAAAAADQ=',
25
- 4: 'MwUBBAAAAAAAAAAAAAAAAAAAADM=',
26
- 5: 'MwUBBQAAAAAAAAAAAAAAAAAAADI=',
27
- 6: 'MwUBBgAAAAAAAAAAAAAAAAAAADE=',
28
- 7: 'MwUBBwAAAAAAAAAAAAAAAAAAADA=',
29
- 8: 'MwUBCAAAAAAAAAAAAAAAAAAAAD8=',
30
- }
31
-
32
- // Migrate old %-rotation speed to unitless
33
- const existingFanService = this.accessory.getService(this.hapServ.Fan)
34
- if (existingFanService) {
35
- if (existingFanService.getCharacteristic(this.hapChar.RotationSpeed).props.unit === 'percentage') {
36
- this.accessory.removeService(existingFanService)
37
- }
38
- }
39
-
40
- // Add the fan service if it doesn't already exist
41
- this.service = this.accessory.getService(this.hapServ.Fan) || this.accessory.addService(this.hapServ.Fan)
42
-
43
- // Add the set handler to the fan on/off characteristic
44
- this.service
45
- .getCharacteristic(this.hapChar.On)
46
- .onSet(async value => this.internalStateUpdate(value))
47
- this.cacheState = this.service.getCharacteristic(this.hapChar.On).value ? 'on' : 'off'
48
-
49
- // Add the set handler to the fan rotation speed characteristic
50
- this.service
51
- .getCharacteristic(this.hapChar.RotationSpeed)
52
- .setProps({
53
- maxValue: 8,
54
- minStep: 1,
55
- minValue: 0,
56
- unit: 'unitless',
57
- })
58
- .onSet(async value => this.internalSpeedUpdate(value))
59
- this.cacheSpeed = this.service.getCharacteristic(this.hapChar.RotationSpeed).value
60
-
61
- // Output the customised options to the log
62
- const opts = JSON.stringify({})
63
- platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
64
- }
65
-
66
- async internalStateUpdate(value) {
67
- try {
68
- const newValue = value ? 'on' : 'off'
69
-
70
- // Don't continue if the new value is the same as before
71
- if (this.cacheState === newValue) {
72
- return
73
- }
74
-
75
- // Send the request to the platform sender function
76
- await this.platform.sendDeviceUpdate(this.accessory, {
77
- cmd: 'stateHumi',
78
- value: value ? 1 : 0,
79
- })
80
-
81
- // Cache the new state and log if appropriate
82
- this.cacheState = newValue
83
- this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
84
- } catch (err) {
85
- // Catch any errors during the process
86
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
87
-
88
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
89
- setTimeout(() => {
90
- this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
91
- }, 2000)
92
- throw new this.hapErr(-70402)
93
- }
94
- }
95
-
96
- async internalSpeedUpdate(value) {
97
- try {
98
- // Don't continue if the speed is 0
99
- if (value === 0) {
100
- return
101
- }
102
-
103
- // Don't continue if the speed value won't have effect
104
- if (value === this.cacheSpeed) {
105
- return
106
- }
107
-
108
- // Get the scene code for this value
109
- const newCode = this.value2Code[value]
110
-
111
- // Send the request to the platform sender function
112
- await this.platform.sendDeviceUpdate(this.accessory, {
113
- cmd: 'ptReal',
114
- value: newCode,
115
- openApi: this.accessory.context.openApiCapabilities?.workMode
116
- ? { instance: 'workMode', capabilityType: 'devices.capabilities.work_mode', value: { workMode: 1, modeValue: value } }
117
- : undefined,
118
- })
119
-
120
- // Cache the new state and log if appropriate
121
- this.cacheSpeed = value
122
- this.accessory.log(`${platformLang.curSpeed} [${value}]`)
123
- } catch (err) {
124
- // Catch any errors during the process
125
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
126
-
127
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
128
- setTimeout(() => {
129
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
130
- }, 2000)
131
- throw new this.hapErr(-70402)
132
- }
133
- }
134
-
135
- externalUpdate(params) {
136
- // Check for an ON/OFF change
137
- if (params.state && params.state !== this.cacheState) {
138
- this.cacheState = params.state
139
- this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
140
-
141
- // Log the change
142
- this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
143
- }
144
-
145
- // Handle OpenAPI workMode (speed)
146
- if (params.workMode) {
147
- const speed = params.workMode.modeValue
148
- if (speed >= 1 && speed <= 8) {
149
- this.cacheSpeed = speed
150
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
151
- }
152
- }
153
-
154
- // Check for some other scene/mode change
155
- (params.commands || []).forEach((command) => {
156
- const hexString = base64ToHex(command)
157
- const hexParts = hexToTwoItems(hexString)
158
-
159
- // Return now if not a device query update code
160
- if (getTwoItemPosition(hexParts, 1) !== 'aa') {
161
- return
162
- }
163
-
164
- const deviceFunction = `${getTwoItemPosition(hexParts, 2)}${getTwoItemPosition(hexParts, 3)}`
165
-
166
- switch (deviceFunction) {
167
- case '0501':
168
- case '0502': {
169
- // Speed update
170
- const newSpeedRaw = getTwoItemPosition(hexParts, 4)
171
- const newSpeedValue = Number.parseInt(newSpeedRaw, 16)
172
- if (newSpeedValue >= 1 && newSpeedValue <= 8) {
173
- if (newSpeedValue !== this.cacheSpeed) {
174
- this.cacheSpeed = newSpeedValue
175
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
176
- this.accessory.log(`${platformLang.curSpeed} [${this.cacheSpeed}]`)
177
- }
178
- }
179
- break
180
- }
181
- default:
182
- this.accessory.logDebugWarn(`${platformLang.newScene}: [${command}] [${hexString}]`)
183
- break
184
- }
185
- })
186
- }
187
- }