@homebridge-plugins/homebridge-govee 11.32.2-beta.8 → 11.32.2

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 (77) hide show
  1. package/CHANGELOG.md +32 -2
  2. package/README.md +1 -1
  3. package/lib/connection/ble.js +156 -19
  4. package/lib/connection/openapi.js +18 -0
  5. package/lib/device/appliance-basic.js +116 -24
  6. package/lib/device/base.js +80 -0
  7. package/lib/device/cooler-single.js +7 -22
  8. package/lib/device/dehumidifier-H7150.js +8 -26
  9. package/lib/device/diffuser-H7161.js +5 -18
  10. package/lib/device/fan-H1370.js +13 -46
  11. package/lib/device/fan-H7100.js +36 -33
  12. package/lib/device/fan-H7105.js +15 -53
  13. package/lib/device/fan-H7107.js +15 -53
  14. package/lib/device/heater-single.js +7 -22
  15. package/lib/device/heater1a.js +21 -42
  16. package/lib/device/heater1b.js +17 -61
  17. package/lib/device/heater2.js +23 -81
  18. package/lib/device/humidifier-H7140.js +9 -32
  19. package/lib/device/humidifier-H7141.js +7 -25
  20. package/lib/device/humidifier-H7142.js +13 -46
  21. package/lib/device/humidifier-H7143.js +7 -25
  22. package/lib/device/humidifier-H7160.js +13 -46
  23. package/lib/device/ice-maker-H7172.js +18 -29
  24. package/lib/device/index.js +22 -29
  25. package/lib/device/kettle.js +5 -16
  26. package/lib/device/light-switch.js +5 -18
  27. package/lib/device/light.js +14 -41
  28. package/lib/device/outlet-single.js +8 -18
  29. package/lib/device/purifier-H7120.js +20 -68
  30. package/lib/device/purifier-H7122.js +14 -45
  31. package/lib/device/purifier-H7123.js +15 -46
  32. package/lib/device/purifier-H7126.js +12 -38
  33. package/lib/device/purifier-single.js +7 -19
  34. package/lib/device/sensor-basic.js +25 -0
  35. package/lib/device/sensor-co2.js +5 -11
  36. package/lib/device/sensor-leak.js +4 -9
  37. package/lib/device/sensor-monitor.js +3 -10
  38. package/lib/device/sensor-presence.js +3 -10
  39. package/lib/device/sensor-probe.js +52 -0
  40. package/lib/device/sensor-thermo-switch.js +4 -9
  41. package/lib/device/sensor-thermo.js +4 -9
  42. package/lib/device/switch-double.js +39 -32
  43. package/lib/device/switch-single.js +6 -19
  44. package/lib/device/switch-triple.js +41 -35
  45. package/lib/device/tap-single.js +7 -19
  46. package/lib/device/template.js +3 -10
  47. package/lib/device/tv-single.js +6 -18
  48. package/lib/device/valve-single.js +7 -19
  49. package/lib/platform.js +107 -813
  50. package/lib/utils/ble-crypto.js +130 -0
  51. package/lib/utils/ble-protocol.js +8 -0
  52. package/lib/utils/capabilities.js +221 -0
  53. package/lib/utils/command-builder.js +2 -0
  54. package/lib/utils/config-parser.js +280 -0
  55. package/lib/utils/constants.js +28 -6
  56. package/lib/utils/device-capabilities.js +34 -1
  57. package/lib/utils/device-context.js +179 -0
  58. package/lib/utils/device-merge.js +251 -0
  59. package/lib/utils/dispatch.js +161 -0
  60. package/lib/utils/functions.js +9 -0
  61. package/package.json +1 -1
  62. package/CONTRIBUTING-STRUCTURE.md +0 -66
  63. package/lib/device/dehumidifier-H7151.js +0 -195
  64. package/lib/device/dehumidifier-H7152.js +0 -186
  65. package/lib/device/fan-H1310.js +0 -290
  66. package/lib/device/fan-H7101.js +0 -346
  67. package/lib/device/fan-H7111.js +0 -351
  68. package/lib/device/ice-maker-H8121.js +0 -228
  69. package/lib/device/ice-maker-H8122.js +0 -228
  70. package/lib/device/outlet-double.js +0 -188
  71. package/lib/device/outlet-triple.js +0 -160
  72. package/lib/device/purifier-H7121.js +0 -412
  73. package/lib/device/purifier-H7124.js +0 -510
  74. package/lib/device/sensor-button.js +0 -27
  75. package/lib/device/sensor-contact.js +0 -27
  76. package/lib/device/sensor-thermo4.js +0 -66
  77. package/lib/utils/appliance-capabilities.js +0 -45
@@ -1,16 +1,11 @@
1
1
  import { generateRandomString, hasProperty, parseError } from '../utils/functions.js'
2
2
  import platformLang from '../utils/lang-en.js'
3
+ import GoveeDevice from './base.js'
3
4
 
4
- export default class {
5
+ export default class extends GoveeDevice {
5
6
  constructor(platform, accessory) {
6
- // Set up variables from the platform
7
- this.hapChar = platform.api.hap.Characteristic
8
- this.hapErr = platform.api.hap.HapStatusError
9
- this.hapServ = platform.api.hap.Service
10
- this.platform = platform
11
-
7
+ super(platform, accessory)
12
8
  // Set up variables from the accessory
13
- this.accessory = accessory
14
9
  this.temperatureSource = accessory.context.temperatureSource;
15
10
 
16
11
  // Remove any old services from simulations
@@ -149,14 +144,9 @@ export default class {
149
144
  value === 1 ? newOnState : 0,
150
145
  )
151
146
  } catch (err) {
152
- // Catch any errors during the process
153
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
154
-
155
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
156
- setTimeout(() => {
147
+ this.failUpdate(err, () => {
157
148
  this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on' ? 1 : 0)
158
- }, 2000)
159
- throw new this.hapErr(-70402)
149
+ })
160
150
  }
161
151
  }
162
152
 
@@ -211,17 +201,12 @@ export default class {
211
201
  this.cacheCool === 'on' ? 3 : 1,
212
202
  )
213
203
  } catch (err) {
214
- // Catch any errors during the process
215
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
216
-
217
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
218
- setTimeout(() => {
204
+ this.failUpdate(err, () => {
219
205
  this.service.updateCharacteristic(
220
206
  this.hapChar.CoolingThresholdTemperature,
221
207
  this.accessory.context.cacheTarget,
222
208
  )
223
- }, 2000)
224
- throw new this.hapErr(-70402)
209
+ })
225
210
  }
226
211
  }
227
212
 
@@ -2,13 +2,13 @@ import {
2
2
  base64ToHex,
3
3
  getTwoItemPosition,
4
4
  hexToTwoItems,
5
- parseError,
6
5
  } from '../utils/functions.js'
7
6
  import platformLang from '../utils/lang-en.js'
8
7
  import { logUnknownData } from '../utils/report-unknown.js'
8
+ import GoveeDevice from './base.js'
9
9
 
10
10
  /*
11
- H7150
11
+ H7150, H7151 and H7152
12
12
  {
13
13
  "mode": {
14
14
  "options": [
@@ -32,17 +32,9 @@ import { logUnknownData } from '../utils/report-unknown.js'
32
32
  }
33
33
  }
34
34
  */
35
- export default class {
35
+ export default class GoveeDehumidifierH7150 extends GoveeDevice {
36
36
  constructor(platform, accessory) {
37
- // Set up variables from the platform
38
- this.hapChar = platform.api.hap.Characteristic
39
- this.hapErr = platform.api.hap.HapStatusError
40
- this.hapServ = platform.api.hap.Service
41
- this.platform = platform
42
-
43
- // Set up variables from the accessory
44
- this.accessory = accessory
45
-
37
+ super(platform, accessory)
46
38
  // Speed codes
47
39
  this.value2Code = {
48
40
  1: 'MwUBAQAAAAAAAAAAAAAAAAAAADY=',
@@ -108,14 +100,9 @@ export default class {
108
100
  this.cacheState = newValue
109
101
  this.accessory.log(`${platformLang.curState} [${newValue}]`)
110
102
  } catch (err) {
111
- // Catch any errors during the process
112
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
113
-
114
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
115
- setTimeout(() => {
103
+ this.failUpdate(err, () => {
116
104
  this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
117
- }, 2000)
118
- throw new this.hapErr(-70402)
105
+ })
119
106
  }
120
107
  }
121
108
 
@@ -147,14 +134,9 @@ export default class {
147
134
  this.cacheSpeed = value
148
135
  this.accessory.log(`${platformLang.curSpeed} [${value}]`)
149
136
  } catch (err) {
150
- // Catch any errors during the process
151
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
152
-
153
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
154
- setTimeout(() => {
137
+ this.failUpdate(err, () => {
155
138
  this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
156
- }, 2000)
157
- throw new this.hapErr(-70402)
139
+ })
158
140
  }
159
141
  }
160
142
 
@@ -2,22 +2,14 @@ import {
2
2
  base64ToHex,
3
3
  getTwoItemPosition,
4
4
  hexToTwoItems,
5
- parseError,
6
5
  } from '../utils/functions.js'
7
6
  import platformLang from '../utils/lang-en.js'
8
7
  import { logUnknownData } from '../utils/report-unknown.js'
8
+ import GoveeDevice from './base.js'
9
9
 
10
- export default class {
10
+ export default class extends GoveeDevice {
11
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
-
12
+ super(platform, accessory)
21
13
  // Remove fan service if exists
22
14
  if (this.accessory.getService(this.hapServ.Fan)) {
23
15
  this.accessory.removeService(this.accessory.getService(this.hapServ.Fan))
@@ -71,14 +63,9 @@ export default class {
71
63
 
72
64
  this.service.updateCharacteristic(this.hapChar.CurrentAirPurifierState, value === 1 ? 2 : 0)
73
65
  } catch (err) {
74
- // Catch any errors during the process
75
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
76
-
77
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
78
- setTimeout(() => {
66
+ this.failUpdate(err, () => {
79
67
  this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on' ? 1 : 0)
80
- }, 2000)
81
- throw new this.hapErr(-70402)
68
+ })
82
69
  }
83
70
  }
84
71
 
@@ -6,11 +6,11 @@ import {
6
6
  getTwoItemPosition,
7
7
  hexToTwoItems,
8
8
  hkPercentToFanSpeed,
9
- parseError,
10
9
  sleep,
11
10
  } from '../utils/functions.js'
12
11
  import platformLang from '../utils/lang-en.js'
13
12
  import { logUnknownData } from '../utils/report-unknown.js'
13
+ import GoveeDevice from './base.js'
14
14
 
15
15
  /*
16
16
  Codes below were decoded from a real device's AWS status reports in
@@ -20,17 +20,9 @@ import { logUnknownData } from '../utils/report-unknown.js'
20
20
  The light reports through the standard state/brightness/kelvin fields
21
21
  (colour temperature only, 2700-6500K)
22
22
  */
23
- export default class {
23
+ export default class extends GoveeDevice {
24
24
  constructor(platform, accessory) {
25
- // Set up variables from the platform
26
- this.hapChar = platform.api.hap.Characteristic
27
- this.hapErr = platform.api.hap.HapStatusError
28
- this.hapServ = platform.api.hap.Service
29
- this.platform = platform
30
-
31
- // Set up variables from the accessory
32
- this.accessory = accessory
33
-
25
+ super(platform, accessory)
34
26
  // Set up custom variables for this device type
35
27
  const deviceConf = platform.deviceConf[accessory.context.gvDeviceId]
36
28
  this.hideLight = deviceConf && deviceConf.hideLight
@@ -138,14 +130,9 @@ export default class {
138
130
  this.accessory.log(`${platformLang.curState} [${newValue}]`)
139
131
  }
140
132
  } catch (err) {
141
- // Catch any errors during the process
142
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
143
-
144
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
145
- setTimeout(() => {
133
+ this.failUpdate(err, () => {
146
134
  this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on' ? 1 : 0)
147
- }, 2000)
148
- throw new this.hapErr(-70402)
135
+ })
149
136
  }
150
137
  }
151
138
 
@@ -176,14 +163,9 @@ export default class {
176
163
  this.accessory.log(`${platformLang.curSpeed} [${value}]`)
177
164
  }
178
165
  } catch (err) {
179
- // Catch any errors during the process
180
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
181
-
182
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
183
- setTimeout(() => {
166
+ this.failUpdate(err, () => {
184
167
  this.service.updateCharacteristic(this.hapChar.RotationSpeed, fanSpeedToHkPercent(this.cacheSpeed, this.speedSteps))
185
- }, 2000)
186
- throw new this.hapErr(-70402)
168
+ })
187
169
  }
188
170
  }
189
171
 
@@ -208,14 +190,9 @@ export default class {
208
190
  this.accessory.log(`${platformLang.curLight} [${newValue}]`)
209
191
  }
210
192
  } catch (err) {
211
- // Catch any errors during the process
212
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
213
-
214
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
215
- setTimeout(() => {
193
+ this.failUpdate(err, () => {
216
194
  this.lightService.updateCharacteristic(this.hapChar.On, this.cacheLightState === 'on')
217
- }, 2000)
218
- throw new this.hapErr(-70402)
195
+ })
219
196
  }
220
197
  }
221
198
 
@@ -246,14 +223,9 @@ export default class {
246
223
  this.accessory.log(`${platformLang.curBright} [${value}%]`)
247
224
  }
248
225
  } catch (err) {
249
- // Catch any errors during the process
250
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
251
-
252
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
253
- setTimeout(() => {
226
+ this.failUpdate(err, () => {
254
227
  this.lightService.updateCharacteristic(this.hapChar.Brightness, this.cacheBright)
255
- }, 2000)
256
- throw new this.hapErr(-70402)
228
+ })
257
229
  }
258
230
  }
259
231
 
@@ -287,14 +259,9 @@ export default class {
287
259
  this.cacheKelvin = k
288
260
  this.accessory.log(`${platformLang.curColour} [${k}K]`)
289
261
  } catch (err) {
290
- // Catch any errors during the process
291
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
292
-
293
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
294
- setTimeout(() => {
262
+ this.failUpdate(err, () => {
295
263
  this.lightService.updateCharacteristic(this.hapChar.ColorTemperature, this.cacheMired)
296
- }, 2000)
297
- throw new this.hapErr(-70402)
264
+ })
298
265
  }
299
266
  }
300
267
 
@@ -1,24 +1,31 @@
1
+ import { getDeviceCapabilities } from '../utils/device-capabilities.js'
1
2
  import {
2
3
  base64ToHex,
3
4
  fanSpeedToHkPercent,
4
5
  getTwoItemPosition,
5
6
  hexToTwoItems,
6
7
  hkPercentToFanSpeed,
7
- parseError,
8
8
  } from '../utils/functions.js'
9
9
  import platformLang from '../utils/lang-en.js'
10
10
  import { logUnknownData } from '../utils/report-unknown.js'
11
+ import GoveeDevice from './base.js'
11
12
 
12
- export default class {
13
- constructor(platform, accessory) {
14
- // Set up variables from the platform
15
- this.hapChar = platform.api.hap.Characteristic
16
- this.hapErr = platform.api.hap.HapStatusError
17
- this.hapServ = platform.api.hap.Service
18
- this.platform = platform
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
+ */
19
22
 
20
- // Set up variables from the accessory
21
- this.accessory = accessory
23
+ export default class GoveeFanH7100 extends GoveeDevice {
24
+ constructor(platform, accessory) {
25
+ super(platform, accessory)
26
+ // Which of the models on this handler have a confirmed meaning for the
27
+ // oscillation status message
28
+ this.readsSwingStatus = getDeviceCapabilities(accessory.context.gvModel).readsSwingStatus
22
29
 
23
30
  // Codes etc
24
31
  this.speedCodes = {
@@ -104,14 +111,9 @@ export default class {
104
111
  this.accessory.log(`${platformLang.curState} [${newValue}]`)
105
112
  }
106
113
  } catch (err) {
107
- // Catch any errors during the process
108
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
109
-
110
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
111
- setTimeout(() => {
114
+ this.failUpdate(err, () => {
112
115
  this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on' ? 1 : 0)
113
- }, 2000)
114
- throw new this.hapErr(-70402)
116
+ })
115
117
  }
116
118
  }
117
119
 
@@ -147,14 +149,9 @@ export default class {
147
149
  this.accessory.log(`${platformLang.curSpeed} [${value}]`)
148
150
  }
149
151
  } catch (err) {
150
- // Catch any errors during the process
151
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
152
-
153
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
154
- setTimeout(() => {
152
+ this.failUpdate(err, () => {
155
153
  this.service.updateCharacteristic(this.hapChar.RotationSpeed, fanSpeedToHkPercent(this.cacheSpeed, this.speedSteps, this.autoSpeed))
156
- }, 2000)
157
- throw new this.hapErr(-70402)
154
+ })
158
155
  }
159
156
  }
160
157
 
@@ -180,14 +177,9 @@ export default class {
180
177
  this.accessory.log(`${platformLang.curSwing} [${newValue}]`)
181
178
  }
182
179
  } catch (err) {
183
- // Catch any errors during the process
184
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
185
-
186
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
187
- setTimeout(() => {
180
+ this.failUpdate(err, () => {
188
181
  this.service.updateCharacteristic(this.hapChar.SwingMode, this.cacheSwing === 'on' ? 1 : 0)
189
- }, 2000)
190
- throw new this.hapErr(-70402)
182
+ })
191
183
  }
192
184
  }
193
185
 
@@ -262,12 +254,23 @@ export default class {
262
254
  this.cacheSpeed = this.autoSpeed
263
255
  // Cache auto so we can tell it apart from "user asked for max speed"
264
256
  this.service.updateCharacteristic(this.hapChar.RotationSpeed, 100)
265
- this.accessory.log(`${platformLang.curSpeed} [auto]`)
257
+ this.accessory.log(`${platformLang.curSpeed} [auto -> 100%]`)
266
258
  }
267
259
  break
268
260
  }
269
261
  case '1f01': {
270
- // Swing Mode
262
+ // Not every model on this handler is known to mean oscillation by
263
+ // this message, so one that has not been confirmed falls through and
264
+ // reports it instead - which is how it gets confirmed
265
+ if (!this.readsSwingStatus) {
266
+ logUnknownData(this.accessory, {
267
+ kind: 'scene',
268
+ source: params.source,
269
+ raw: command,
270
+ hex: hexString,
271
+ })
272
+ break
273
+ }
271
274
  const newSwing = getTwoItemPosition(hexParts, 4) === '01' ? 'on' : 'off'
272
275
  if (this.cacheSwing !== newSwing) {
273
276
  this.cacheSwing = newSwing
@@ -8,23 +8,15 @@ import {
8
8
  hexToDecimal,
9
9
  hexToTwoItems,
10
10
  hkPercentToFanSpeed,
11
- parseError,
12
11
  sleep,
13
12
  } from '../utils/functions.js'
14
13
  import platformLang from '../utils/lang-en.js'
15
14
  import { logUnknownData } from '../utils/report-unknown.js'
15
+ import GoveeDevice from './base.js'
16
16
 
17
- export default class {
17
+ export default class extends GoveeDevice {
18
18
  constructor(platform, accessory) {
19
- // Set up variables from the platform
20
- this.hapChar = platform.api.hap.Characteristic
21
- this.hapErr = platform.api.hap.HapStatusError
22
- this.hapServ = platform.api.hap.Service
23
- this.platform = platform
24
-
25
- // Set up variables from the accessory
26
- this.accessory = accessory
27
-
19
+ super(platform, accessory)
28
20
  // Set up custom variables for this device type
29
21
  const deviceConf = platform.deviceConf[accessory.context.gvDeviceId]
30
22
  this.hideLight = deviceConf && deviceConf.hideLight
@@ -151,14 +143,9 @@ export default class {
151
143
  this.accessory.log(`${platformLang.curState} [${newValue}]`)
152
144
  }
153
145
  } catch (err) {
154
- // Catch any errors during the process
155
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
156
-
157
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
158
- setTimeout(() => {
146
+ this.failUpdate(err, () => {
159
147
  this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on' ? 1 : 0)
160
- }, 2000)
161
- throw new this.hapErr(-70402)
148
+ })
162
149
  }
163
150
  }
164
151
 
@@ -192,14 +179,9 @@ export default class {
192
179
  this.accessory.log(`${platformLang.curSpeed} [${value}]`)
193
180
  }
194
181
  } catch (err) {
195
- // Catch any errors during the process
196
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
197
-
198
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
199
- setTimeout(() => {
182
+ this.failUpdate(err, () => {
200
183
  this.service.updateCharacteristic(this.hapChar.RotationSpeed, fanSpeedToHkPercent(this.cacheSpeed, this.speedSteps, this.autoSpeed))
201
- }, 2000)
202
- throw new this.hapErr(-70402)
184
+ })
203
185
  }
204
186
  }
205
187
 
@@ -233,14 +215,9 @@ export default class {
233
215
  // this.accessory.log(`${platformLang.curSwing} [${newValue}]`)
234
216
  // }
235
217
  } catch (err) {
236
- // Catch any errors during the process
237
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
238
-
239
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
240
- setTimeout(() => {
218
+ this.failUpdate(err, () => {
241
219
  this.service.updateCharacteristic(this.hapChar.SwingMode, this.cacheSwing === 'on' ? 1 : 0)
242
- }, 2000)
243
- throw new this.hapErr(-70402)
220
+ })
244
221
  }
245
222
  }
246
223
 
@@ -268,14 +245,9 @@ export default class {
268
245
  this.accessory.log(`${platformLang.curLight} [${newValue}]`)
269
246
  }
270
247
  } catch (err) {
271
- // Catch any errors during the process
272
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
273
-
274
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
275
- setTimeout(() => {
248
+ this.failUpdate(err, () => {
276
249
  this.lightService.updateCharacteristic(this.hapChar.On, this.cacheLightState === 'on')
277
- }, 2000)
278
- throw new this.hapErr(-70402)
250
+ })
279
251
  }
280
252
  }
281
253
 
@@ -322,14 +294,9 @@ export default class {
322
294
  this.accessory.log(`${platformLang.curBright} [${value}%]`)
323
295
  }
324
296
  } catch (err) {
325
- // Catch any errors during the process
326
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
327
-
328
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
329
- setTimeout(() => {
297
+ this.failUpdate(err, () => {
330
298
  this.lightService.updateCharacteristic(this.hapChar.Brightness, this.cacheBright)
331
- }, 2000)
332
- throw new this.hapErr(-70402)
299
+ })
333
300
  }
334
301
  }
335
302
 
@@ -366,14 +333,9 @@ export default class {
366
333
  this.accessory.log(`${platformLang.curColour} [rgb ${newRGB.join(' ')}]`)
367
334
  }
368
335
  } catch (err) {
369
- // Catch any errors during the process
370
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
371
-
372
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
373
- setTimeout(() => {
336
+ this.failUpdate(err, () => {
374
337
  this.lightService.updateCharacteristic(this.hapChar.Hue, this.cacheHue)
375
- }, 2000)
376
- throw new this.hapErr(-70402)
338
+ })
377
339
  }
378
340
  }
379
341
 
@@ -8,23 +8,15 @@ import {
8
8
  hexToDecimal,
9
9
  hexToTwoItems,
10
10
  hkPercentToFanSpeed,
11
- parseError,
12
11
  sleep,
13
12
  } from '../utils/functions.js'
14
13
  import platformLang from '../utils/lang-en.js'
15
14
  import { logUnknownData } from '../utils/report-unknown.js'
15
+ import GoveeDevice from './base.js'
16
16
 
17
- export default class {
17
+ export default class extends GoveeDevice {
18
18
  constructor(platform, accessory) {
19
- // Set up variables from the platform
20
- this.hapChar = platform.api.hap.Characteristic
21
- this.hapErr = platform.api.hap.HapStatusError
22
- this.hapServ = platform.api.hap.Service
23
- this.platform = platform
24
-
25
- // Set up variables from the accessory
26
- this.accessory = accessory
27
-
19
+ super(platform, accessory)
28
20
  // Set up custom variables for this device type
29
21
  const deviceConf = platform.deviceConf[accessory.context.gvDeviceId]
30
22
  this.hideLight = deviceConf && deviceConf.hideLight
@@ -151,14 +143,9 @@ export default class {
151
143
  this.accessory.log(`${platformLang.curState} [${newValue}]`)
152
144
  }
153
145
  } catch (err) {
154
- // Catch any errors during the process
155
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
156
-
157
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
158
- setTimeout(() => {
146
+ this.failUpdate(err, () => {
159
147
  this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on' ? 1 : 0)
160
- }, 2000)
161
- throw new this.hapErr(-70402)
148
+ })
162
149
  }
163
150
  }
164
151
 
@@ -192,14 +179,9 @@ export default class {
192
179
  this.accessory.log(`${platformLang.curSpeed} [${value}]`)
193
180
  }
194
181
  } catch (err) {
195
- // Catch any errors during the process
196
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
197
-
198
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
199
- setTimeout(() => {
182
+ this.failUpdate(err, () => {
200
183
  this.service.updateCharacteristic(this.hapChar.RotationSpeed, fanSpeedToHkPercent(this.cacheSpeed, this.speedSteps, this.autoSpeed))
201
- }, 2000)
202
- throw new this.hapErr(-70402)
184
+ })
203
185
  }
204
186
  }
205
187
 
@@ -246,14 +228,9 @@ export default class {
246
228
  this.accessory.log(`${platformLang.curSwing} [${newValue}]`)
247
229
  }
248
230
  } catch (err) {
249
- // Catch any errors during the process
250
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
251
-
252
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
253
- setTimeout(() => {
231
+ this.failUpdate(err, () => {
254
232
  this.service.updateCharacteristic(this.hapChar.SwingMode, this.cacheSwing === 'on' ? 1 : 0)
255
- }, 2000)
256
- throw new this.hapErr(-70402)
233
+ })
257
234
  }
258
235
  }
259
236
 
@@ -281,14 +258,9 @@ export default class {
281
258
  this.accessory.log(`${platformLang.curLight} [${newValue}]`)
282
259
  }
283
260
  } catch (err) {
284
- // Catch any errors during the process
285
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
286
-
287
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
288
- setTimeout(() => {
261
+ this.failUpdate(err, () => {
289
262
  this.lightService.updateCharacteristic(this.hapChar.On, this.cacheLightState === 'on')
290
- }, 2000)
291
- throw new this.hapErr(-70402)
263
+ })
292
264
  }
293
265
  }
294
266
 
@@ -335,14 +307,9 @@ export default class {
335
307
  this.accessory.log(`${platformLang.curBright} [${value}%]`)
336
308
  }
337
309
  } catch (err) {
338
- // Catch any errors during the process
339
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
340
-
341
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
342
- setTimeout(() => {
310
+ this.failUpdate(err, () => {
343
311
  this.lightService.updateCharacteristic(this.hapChar.Brightness, this.cacheBright)
344
- }, 2000)
345
- throw new this.hapErr(-70402)
312
+ })
346
313
  }
347
314
  }
348
315
 
@@ -379,14 +346,9 @@ export default class {
379
346
  this.accessory.log(`${platformLang.curColour} [rgb ${newRGB.join(' ')}]`)
380
347
  }
381
348
  } catch (err) {
382
- // Catch any errors during the process
383
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
384
-
385
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
386
- setTimeout(() => {
349
+ this.failUpdate(err, () => {
387
350
  this.lightService.updateCharacteristic(this.hapChar.Hue, this.cacheHue)
388
- }, 2000)
389
- throw new this.hapErr(-70402)
351
+ })
390
352
  }
391
353
  }
392
354