@homebridge-plugins/homebridge-govee 11.32.2-beta.14 → 11.32.2-beta.15

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/CHANGELOG.md CHANGED
@@ -30,6 +30,8 @@ All notable changes to `@homebridge-plugins/homebridge-govee` will be documented
30
30
  - refactor: point the H7151 and H7111 at the handlers they were byte-for-byte copies of
31
31
  - refactor: build the ice maker size codes from the model rather than writing both orderings out by hand
32
32
  - refactor: build the switch and outlet tiles of a multi-socket device from one handler instead of two copies of it
33
+ - fix: move the H7152 dehumidifier's speed slider when it reports a new speed, which until now only the H7150 and H7151 did
34
+ - refactor: point the H7101 and H7111 fans at the H7100 handler they matched command for command
33
35
 
34
36
  ## v11.32.1 (2026-08-02)
35
37
 
@@ -8,7 +8,7 @@ import platformLang from '../utils/lang-en.js'
8
8
  import { logUnknownData } from '../utils/report-unknown.js'
9
9
 
10
10
  /*
11
- H7150 and H7151
11
+ H7150, H7151 and H7152
12
12
  {
13
13
  "mode": {
14
14
  "options": [
@@ -10,6 +10,16 @@ import {
10
10
  import platformLang from '../utils/lang-en.js'
11
11
  import { logUnknownData } from '../utils/report-unknown.js'
12
12
 
13
+ /*
14
+ The models on this handler and the modes each offers:
15
+
16
+ H7100, H7102, H7106 -> Sleep, Nature, Custom, Auto
17
+ H7101 -> Sleep, Nature, Turbo, Custom, Auto
18
+ H7111 -> Sleep, Nature, Custom, Auto
19
+ H1310, R1310 -> as the H7100, but its oscillation status message has
20
+ never been confirmed, so it is not read back
21
+ */
22
+
13
23
  export default class GoveeFanH7100 {
14
24
  constructor(platform, accessory) {
15
25
  // Set up variables from the platform
@@ -267,7 +277,7 @@ export default class GoveeFanH7100 {
267
277
  this.cacheSpeed = this.autoSpeed
268
278
  // Cache auto so we can tell it apart from "user asked for max speed"
269
279
  this.service.updateCharacteristic(this.hapChar.RotationSpeed, 100)
270
- this.accessory.log(`${platformLang.curSpeed} [auto]`)
280
+ this.accessory.log(`${platformLang.curSpeed} [auto -> 100%]`)
271
281
  }
272
282
  break
273
283
  }
@@ -7,11 +7,9 @@ import {
7
7
  } from './appliance-basic.js'
8
8
  import deviceCoolerSingle from './cooler-single.js'
9
9
  import deviceDehumidifierH7150 from './dehumidifier-H7150.js'
10
- import deviceDehumidifierH7152 from './dehumidifier-H7152.js'
11
10
  import deviceDiffuserH7161 from './diffuser-H7161.js'
12
11
  import deviceFanH1370 from './fan-H1370.js'
13
12
  import deviceFanH7100 from './fan-H7100.js'
14
- import deviceFanH7101 from './fan-H7101.js'
15
13
  import deviceFanH7105 from './fan-H7105.js'
16
14
  import deviceFanH7107 from './fan-H7107.js'
17
15
  import deviceHeater1A from './heater1a.js'
@@ -53,7 +51,7 @@ export default {
53
51
  deviceCoolerSingle,
54
52
  deviceDehumidifierH7150,
55
53
  deviceDehumidifierH7151: deviceDehumidifierH7150, // identical to the H7150
56
- deviceDehumidifierH7152,
54
+ deviceDehumidifierH7152: deviceDehumidifierH7150, // same device, and this gives it proper speed feedback
57
55
  deviceDiffuserH7161,
58
56
  deviceDiffuserH7162: deviceDiffuserH7161, // identical to the H7161
59
57
  deviceDehumidifierBasic,
@@ -64,10 +62,10 @@ export default {
64
62
  deviceFanH7100,
65
63
  deviceFanH7102: deviceFanH7100, // identical to the H7100
66
64
  deviceFanH7106: deviceFanH7100, // identical to the H7100
67
- deviceFanH7101,
65
+ deviceFanH7101: deviceFanH7100, // identical to the H7100, with a turbo mode it is never sent
68
66
  deviceFanH7105,
69
67
  deviceFanH7107,
70
- deviceFanH7111: deviceFanH7101, // same fan without the turbo mode, which is not sent
68
+ deviceFanH7111: deviceFanH7100, // same fan without the turbo mode, which is not sent
71
69
  deviceHeaterSingle,
72
70
  deviceHeater1A,
73
71
  deviceHeater1B,
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@homebridge-plugins/homebridge-govee",
3
3
  "alias": "Govee",
4
4
  "type": "module",
5
- "version": "11.32.2-beta.14",
5
+ "version": "11.32.2-beta.15",
6
6
  "description": "Homebridge plugin to integrate Govee devices into HomeKit.",
7
7
  "author": {
8
8
  "name": "bwp91",
@@ -1,186 +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
- import { logUnknownData } from '../utils/report-unknown.js'
9
-
10
- export default class {
11
- constructor(platform, accessory) {
12
- // Set up variables from the platform
13
- this.hapChar = platform.api.hap.Characteristic
14
- this.hapErr = platform.api.hap.HapStatusError
15
- this.hapServ = platform.api.hap.Service
16
- this.platform = platform
17
-
18
- // Set up variables from the accessory
19
- this.accessory = accessory
20
-
21
- // Speed codes
22
- this.value2Code = {
23
- 1: 'MwUBAQAAAAAAAAAAAAAAAAAAADY=',
24
- 2: 'MwUBAgAAAAAAAAAAAAAAAAAAADU=',
25
- 3: 'MwUBAwAAAAAAAAAAAAAAAAAAADQ=',
26
- 4: 'MwUBBAAAAAAAAAAAAAAAAAAAADM=',
27
- 5: 'MwUBBQAAAAAAAAAAAAAAAAAAADI=',
28
- 6: 'MwUBBgAAAAAAAAAAAAAAAAAAADE=',
29
- 7: 'MwUBBwAAAAAAAAAAAAAAAAAAADA=',
30
- 8: 'MwUBCAAAAAAAAAAAAAAAAAAAAD8=',
31
- }
32
-
33
- // Migrate old %-rotation speed to unitless
34
- const existingFanService = this.accessory.getService(this.hapServ.Fan)
35
- if (existingFanService) {
36
- if (existingFanService.getCharacteristic(this.hapChar.RotationSpeed).props.unit === 'percentage') {
37
- this.accessory.removeService(existingFanService)
38
- }
39
- }
40
-
41
- // Add the fan service if it doesn't already exist
42
- this.service = this.accessory.getService(this.hapServ.Fan) || this.accessory.addService(this.hapServ.Fan)
43
-
44
- // Add the set handler to the fan on/off characteristic
45
- this.service
46
- .getCharacteristic(this.hapChar.On)
47
- .onSet(async value => this.internalStateUpdate(value))
48
- this.cacheState = this.service.getCharacteristic(this.hapChar.On).value ? 'on' : 'off'
49
-
50
- // Add the set handler to the fan rotation speed characteristic
51
- this.service
52
- .getCharacteristic(this.hapChar.RotationSpeed)
53
- .setProps({
54
- maxValue: 8,
55
- minStep: 1,
56
- minValue: 0,
57
- unit: 'unitless',
58
- })
59
- .onSet(async value => this.internalSpeedUpdate(value))
60
- this.cacheSpeed = this.service.getCharacteristic(this.hapChar.RotationSpeed).value
61
-
62
- // Output the customised options to the log
63
- const opts = JSON.stringify({})
64
- platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
65
- }
66
-
67
- async internalStateUpdate(value) {
68
- try {
69
- const newValue = value ? 'on' : 'off'
70
-
71
- // Don't continue if the new value is the same as before
72
- if (this.cacheState === newValue) {
73
- return
74
- }
75
-
76
- // Send the request to the platform sender function
77
- await this.platform.sendDeviceUpdate(this.accessory, {
78
- cmd: 'stateHumi',
79
- value: value ? 1 : 0,
80
- })
81
-
82
- // Cache the new state and log if appropriate
83
- this.cacheState = newValue
84
- this.accessory.log(`${platformLang.curState} [${newValue}]`)
85
- } catch (err) {
86
- // Catch any errors during the process
87
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
88
-
89
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
90
- setTimeout(() => {
91
- this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
92
- }, 2000)
93
- throw new this.hapErr(-70402)
94
- }
95
- }
96
-
97
- async internalSpeedUpdate(value) {
98
- try {
99
- // Don't continue if the speed is 0
100
- if (value === 0) {
101
- return
102
- }
103
-
104
- // Don't continue if the speed value won't have effect
105
- if (value === this.cacheSpeed) {
106
- return
107
- }
108
-
109
- // Get the scene code for this value
110
- const newCode = this.value2Code[value]
111
-
112
- // Send the request to the platform sender function
113
- await this.platform.sendDeviceUpdate(this.accessory, {
114
- cmd: 'ptReal',
115
- value: newCode,
116
- })
117
-
118
- // Cache the new state and log if appropriate
119
- this.cacheSpeed = value
120
- this.accessory.log(`${platformLang.curSpeed} [${value}]`)
121
- } catch (err) {
122
- // Catch any errors during the process
123
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
124
-
125
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
126
- setTimeout(() => {
127
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
128
- }, 2000)
129
- throw new this.hapErr(-70402)
130
- }
131
- }
132
-
133
- externalUpdate(params) {
134
- // Check for an ON/OFF change
135
- if (params.state && params.state !== this.cacheState) {
136
- this.cacheState = params.state
137
- this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
138
-
139
- // Log the change
140
- this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
141
- }
142
-
143
- // Handle OpenAPI workMode
144
- if (params.workMode) {
145
- const mode = params.workMode.modeValue
146
- this.accessory.log(`${platformLang.curMode} [${mode}]`)
147
- }
148
-
149
- // Check for some other scene/mode change
150
- (params.commands || []).forEach((command) => {
151
- const hexString = base64ToHex(command)
152
- const hexParts = hexToTwoItems(hexString)
153
-
154
- // Return now if not a device query update code
155
- if (getTwoItemPosition(hexParts, 1) !== 'aa') {
156
- return
157
- }
158
-
159
- const deviceFunction = `${getTwoItemPosition(hexParts, 2)}${getTwoItemPosition(hexParts, 3)}`
160
-
161
- switch (deviceFunction) {
162
- case '0501':
163
- case '0502': {
164
- // Speed update
165
- const newSpeedValue = Number.parseInt(getTwoItemPosition(hexParts, 4), 16)
166
- if (newSpeedValue >= 1 && newSpeedValue <= 8) {
167
- if (newSpeedValue !== this.cacheSpeed) {
168
- this.cacheSpeed = newSpeedValue
169
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
170
- this.accessory.log(`${platformLang.curSpeed} [${this.cacheSpeed}]`)
171
- }
172
- }
173
- break
174
- }
175
- default:
176
- logUnknownData(this.accessory, {
177
- kind: 'scene',
178
- source: params.source,
179
- raw: command,
180
- hex: hexString,
181
- })
182
- break
183
- }
184
- })
185
- }
186
- }
@@ -1,347 +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
- import { logUnknownData } from '../utils/report-unknown.js'
11
-
12
- /*
13
- H7101 and 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
- },
35
- "gear": {
36
- "options": [
37
- {
38
- "name": "gear",
39
- "value": [
40
- 1,
41
- 2,
42
- 3,
43
- 4,
44
- 5,
45
- 6,
46
- 7,
47
- 8
48
- ]
49
- }
50
- ]
51
- }
52
- }
53
-
54
- // NOTES
55
- H7101 -> Sleep, Nature, Turbo, Custom, Auto
56
- H7111 -> Sleep, Nature, Custom, Auto (no turbo)
57
-
58
- sleep
59
- [31/10/2022, 20:52:08] [Govee] [Device1] [AWS] receiving update {"source":"AWS","result":1,"commands":["qgUFAAAAAAAAAAAAAAAAAAAAAKo=","qgUABQAAAAAAAAAAAAAAAAAAAKo="]}.
60
- [31/10/2022, 20:52:08] [Govee] [Device1] new scene code: [qgUFAAAAAAAAAAAAAAAAAAAAAKo=] [aa050500000000000000000000000000000000aa].
61
- [31/10/2022, 20:52:08] [Govee] [Device1] new scene code: [qgUABQAAAAAAAAAAAAAAAAAAAKo=] [aa050005000000000000000000000000000000aa].
62
-
63
- nature
64
- [31/10/2022, 20:52:43] [Govee] [Device1] [AWS] receiving update {"source":"AWS","result":1,"commands":["qgUGAAAAAAAAAAAAAAAAAAAAAKk=","qgUABgAAAAAAAAAAAAAAAAAAAKk="]}.
65
- [31/10/2022, 20:52:43] [Govee] [Device1] new scene code: [qgUGAAAAAAAAAAAAAAAAAAAAAKk=] [aa050600000000000000000000000000000000a9].
66
- [31/10/2022, 20:52:43] [Govee] [Device1] new scene code: [qgUABgAAAAAAAAAAAAAAAAAAAKk=] [aa050006000000000000000000000000000000a9].
67
- */
68
-
69
- export default class GoveeFanH7101 {
70
- constructor(platform, accessory) {
71
- // Set up variables from the platform
72
- this.hapChar = platform.api.hap.Characteristic
73
- this.hapErr = platform.api.hap.HapStatusError
74
- this.hapServ = platform.api.hap.Service
75
- this.platform = platform
76
-
77
- // Set up variables from the accessory
78
- this.accessory = accessory
79
-
80
- // Codes etc
81
- this.speedCodes = {
82
- 1: 'MwUBAQAAAAAAAAAAAAAAAAAAADY=',
83
- 2: 'MwUBAgAAAAAAAAAAAAAAAAAAADU=',
84
- 3: 'MwUBAwAAAAAAAAAAAAAAAAAAADQ=',
85
- 4: 'MwUBBAAAAAAAAAAAAAAAAAAAADM=',
86
- 5: 'MwUBBQAAAAAAAAAAAAAAAAAAADI=',
87
- 6: 'MwUBBgAAAAAAAAAAAAAAAAAAADE=',
88
- 7: 'MwUBBwAAAAAAAAAAAAAAAAAAADA=',
89
- 8: 'MwUBCAAAAAAAAAAAAAAAAAAAAD8=',
90
- 9: 'MwUAAwAAAAAAAAAAAAAAAAAAADU=', // auto mode
91
- }
92
- this.autoSpeed = 9
93
- // Real speed steps, excluding auto - HomeKit percentages map onto these
94
- this.speedSteps = 8
95
-
96
- // Remove any old original Fan services
97
- if (this.accessory.getService(this.hapServ.Fan)) {
98
- this.accessory.removeService(this.accessory.getService(this.hapServ.Fan))
99
- }
100
-
101
- // Rebuild the fan service if it was cached under an older speed scale, as
102
- // HomeKit keeps the old props until the service itself is replaced
103
- const existingService = this.accessory.getService(this.hapServ.Fanv2)
104
- if (existingService) {
105
- const { props } = existingService.getCharacteristic(this.hapChar.RotationSpeed)
106
- if (props.unit === 'percentage' || props.maxValue !== 100) {
107
- this.accessory.removeService(existingService)
108
- }
109
- }
110
-
111
- // Add the fan service for the fan if it doesn't already exist
112
- this.service = this.accessory.getService(this.hapServ.Fanv2) || this.accessory.addService(this.hapServ.Fanv2)
113
-
114
- // Add the set handler to the fan on/off characteristic
115
- this.service
116
- .getCharacteristic(this.hapChar.Active)
117
- .onSet(async value => this.internalStateUpdate(value))
118
- this.cacheState = this.service.getCharacteristic(this.hapChar.Active).value ? 'on' : 'off'
119
-
120
- // Add the set handler to the fan rotation speed characteristic
121
- this.service
122
- .getCharacteristic(this.hapChar.RotationSpeed)
123
- .setProps({
124
- maxValue: 100,
125
- minStep: 1,
126
- minValue: 0,
127
- unit: 'unitless',
128
- })
129
- .onSet(async value => this.internalSpeedUpdate(value))
130
- this.cacheSpeed = this.service.getCharacteristic(this.hapChar.RotationSpeed).value
131
-
132
- // Add the set handler to the fan swing mode
133
- this.service
134
- .getCharacteristic(this.hapChar.SwingMode)
135
- .onSet(async value => this.internalSwingUpdate(value))
136
- this.cacheSwing = this.service.getCharacteristic(this.hapChar.SwingMode).value === 1 ? 'on' : 'off'
137
-
138
- // Output the customised options to the log
139
- const opts = JSON.stringify({})
140
- platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
141
- }
142
-
143
- async internalStateUpdate(value) {
144
- try {
145
- const newValue = value ? 'on' : 'off'
146
-
147
- // Don't continue if the new value is the same as before
148
- if (this.cacheState === newValue) {
149
- return
150
- }
151
-
152
- // Send the request to the platform sender function
153
- await this.platform.sendDeviceUpdate(this.accessory, {
154
- cmd: 'ptReal',
155
- value: value ? 'MwEBAAAAAAAAAAAAAAAAAAAAADM=' : 'MwEAAAAAAAAAAAAAAAAAAAAAADI=',
156
- })
157
-
158
- // Cache the new state and log if appropriate
159
- if (this.cacheState !== newValue) {
160
- this.cacheState = newValue
161
- this.accessory.log(`${platformLang.curState} [${newValue}]`)
162
- }
163
- } catch (err) {
164
- // Catch any errors during the process
165
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
166
-
167
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
168
- setTimeout(() => {
169
- this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on' ? 1 : 0)
170
- }, 2000)
171
- throw new this.hapErr(-70402)
172
- }
173
- }
174
-
175
- async internalSpeedUpdate(value) {
176
- try {
177
- // Don't continue if the value is 0
178
- if (value === 0) {
179
- return
180
- }
181
-
182
- // HomeKit sends a percentage - map it onto this model's real speed steps
183
- value = hkPercentToFanSpeed(value, this.speedSteps)
184
-
185
- // Don't continue if the new value is the same as before
186
- if (this.cacheSpeed === value) {
187
- return
188
- }
189
-
190
- const codeToSend = this.speedCodes[value]
191
-
192
- const isAuto = value === this.autoSpeed
193
- await this.platform.sendDeviceUpdate(this.accessory, {
194
- cmd: 'ptReal',
195
- value: codeToSend,
196
- openApi: this.accessory.context.openApiCapabilities?.workMode
197
- ? { instance: 'workMode', capabilityType: 'devices.capabilities.work_mode', value: isAuto ? { workMode: 3 } : { workMode: 1, modeValue: value } }
198
- : undefined,
199
- })
200
-
201
- // Cache the new state and log if appropriate
202
- if (this.cacheSpeed !== value) {
203
- this.cacheSpeed = value
204
- this.accessory.log(`${platformLang.curSpeed} [${value}]`)
205
- }
206
- } catch (err) {
207
- // Catch any errors during the process
208
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
209
-
210
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
211
- setTimeout(() => {
212
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, fanSpeedToHkPercent(this.cacheSpeed, this.speedSteps, this.autoSpeed))
213
- }, 2000)
214
- throw new this.hapErr(-70402)
215
- }
216
- }
217
-
218
- async internalSwingUpdate(value) {
219
- try {
220
- const newValue = value ? 'on' : 'off'
221
- // Don't continue if the new value is the same as before
222
- if (this.cacheSwing === value) {
223
- return
224
- }
225
-
226
- await this.platform.sendDeviceUpdate(this.accessory, {
227
- cmd: 'ptReal',
228
- value: value ? 'Mx8BAQAAAAAAAAAAAAAAAAAAACw=' : 'Mx8BAAAAAAAAAAAAAAAAAAAAAC0=',
229
- openApi: this.accessory.context.openApiCapabilities?.oscillationToggle
230
- ? { instance: 'oscillationToggle', capabilityType: 'devices.capabilities.toggle', value: value ? 1 : 0 }
231
- : undefined,
232
- })
233
-
234
- // Cache the new state and log if appropriate
235
- if (this.cacheSwing !== newValue) {
236
- this.cacheSwing = newValue
237
- this.accessory.log(`${platformLang.curSwing} [${newValue}]`)
238
- }
239
- } catch (err) {
240
- // Catch any errors during the process
241
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
242
-
243
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
244
- setTimeout(() => {
245
- this.service.updateCharacteristic(this.hapChar.SwingMode, this.cacheSwing === 'on' ? 1 : 0)
246
- }, 2000)
247
- throw new this.hapErr(-70402)
248
- }
249
- }
250
-
251
- externalUpdate(params) {
252
- // Update the active characteristic
253
- if (params.state && params.state !== this.cacheState) {
254
- this.cacheState = params.state
255
- this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on' ? 1 : 0)
256
- this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
257
- }
258
-
259
- // Handle OpenAPI workMode (speed or auto)
260
- if (params.workMode) {
261
- let newSpeed
262
- if (params.workMode.workMode === 3) {
263
- newSpeed = this.autoSpeed
264
- } else {
265
- newSpeed = params.workMode.modeValue
266
- }
267
- if (Number.isFinite(newSpeed) && newSpeed >= 1 && newSpeed <= this.autoSpeed && this.cacheSpeed !== newSpeed) {
268
- this.cacheSpeed = newSpeed
269
- const hkSpeed = fanSpeedToHkPercent(newSpeed, this.speedSteps, this.autoSpeed)
270
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, hkSpeed)
271
- this.accessory.log(`${platformLang.curSpeed} [${newSpeed} -> ${hkSpeed}%]`)
272
- }
273
- }
274
-
275
- // Handle OpenAPI toggles
276
- if (params.toggles?.oscillationToggle !== undefined) {
277
- const newSwing = params.toggles.oscillationToggle ? 'on' : 'off'
278
- if (this.cacheSwing !== newSwing) {
279
- this.cacheSwing = newSwing
280
- this.service.updateCharacteristic(this.hapChar.SwingMode, this.cacheSwing === 'on' ? 1 : 0)
281
- this.accessory.log(`${platformLang.curSwing} [${this.cacheSwing}]`)
282
- }
283
- }
284
-
285
- // Check for some other scene/mode change
286
- (params.commands || []).forEach((command) => {
287
- const hexString = base64ToHex(command)
288
- const hexParts = hexToTwoItems(hexString)
289
-
290
- // Return now if not a device query update code
291
- if (getTwoItemPosition(hexParts, 1) !== 'aa') {
292
- return
293
- }
294
-
295
- if (getTwoItemPosition(hexParts, 2) === '08') {
296
- // Sensor Attached?
297
- const dev = hexString.substring(4, hexString.length - 24)
298
- this.accessory.context.sensorAttached = dev !== '000000000000'
299
- return
300
- }
301
-
302
- const deviceFunction = `${getTwoItemPosition(hexParts, 2)}${getTwoItemPosition(hexParts, 3)}`
303
-
304
- switch (deviceFunction) {
305
- case '0501': {
306
- // Fan speed
307
- const newSpeed = Number.parseInt(getTwoItemPosition(hexParts, 4), 16)
308
- if (newSpeed >= 1 && newSpeed <= this.speedSteps && this.cacheSpeed !== newSpeed) {
309
- this.cacheSpeed = newSpeed
310
- const hkSpeed = fanSpeedToHkPercent(newSpeed, this.speedSteps, this.autoSpeed)
311
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, hkSpeed)
312
- this.accessory.log(`${platformLang.curSpeed} [${newSpeed} -> ${hkSpeed}%]`)
313
- }
314
- break
315
- }
316
- case '0500': {
317
- // Mode change (auto = 0x03)
318
- if (getTwoItemPosition(hexParts, 4) === '03' && this.cacheSpeed !== this.autoSpeed) {
319
- this.cacheSpeed = this.autoSpeed
320
- // Cache auto so we can tell it apart from "user asked for max speed"
321
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, 100)
322
- this.accessory.log(`${platformLang.curSpeed} [auto -> 100%]`)
323
- }
324
- break
325
- }
326
- case '1f01': {
327
- // Swing Mode
328
- const newSwing = getTwoItemPosition(hexParts, 4) === '01' ? 'on' : 'off'
329
- if (this.cacheSwing !== newSwing) {
330
- this.cacheSwing = newSwing
331
- this.service.updateCharacteristic(this.hapChar.SwingMode, this.cacheSwing === 'on' ? 1 : 0)
332
- this.accessory.log(`${platformLang.curSwing} [${this.cacheSwing}]`)
333
- }
334
- break
335
- }
336
- default:
337
- logUnknownData(this.accessory, {
338
- kind: 'scene',
339
- source: params.source,
340
- raw: command,
341
- hex: hexString,
342
- })
343
- break
344
- }
345
- })
346
- }
347
- }