@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.
- package/CHANGELOG.md +31 -0
- package/config.schema.json +1 -1
- package/lib/connection/ble.js +26 -1
- package/lib/connection/openapi.js +18 -0
- package/lib/device/appliance-basic.js +377 -0
- package/lib/device/dehumidifier-H7150.js +9 -3
- package/lib/device/diffuser-H7161.js +7 -1
- package/lib/device/fan-H1370.js +7 -1
- package/lib/device/fan-H7100.js +36 -4
- package/lib/device/fan-H7105.js +7 -1
- package/lib/device/fan-H7107.js +7 -1
- package/lib/device/heater1a.js +52 -12
- package/lib/device/heater1b.js +14 -3
- package/lib/device/heater2.js +7 -1
- package/lib/device/humidifier-H7140.js +7 -1
- package/lib/device/humidifier-H7141.js +7 -1
- package/lib/device/humidifier-H7142.js +7 -1
- package/lib/device/humidifier-H7143.js +7 -1
- package/lib/device/humidifier-H7160.js +7 -1
- package/lib/device/ice-maker-H7172.js +19 -7
- package/lib/device/index.js +44 -51
- package/lib/device/kettle.js +7 -1
- package/lib/device/outlet-single.js +7 -1
- package/lib/device/purifier-H7120.js +14 -25
- package/lib/device/purifier-H7122.js +7 -1
- package/lib/device/purifier-H7123.js +9 -3
- package/lib/device/purifier-H7126.js +7 -1
- package/lib/device/{sensor-button.js → sensor-basic.js} +14 -2
- package/lib/device/sensor-presence.js +7 -1
- package/lib/device/sensor-thermo4.js +13 -2
- package/lib/device/switch-double.js +34 -15
- package/lib/device/switch-triple.js +36 -17
- package/lib/device/template.js +15 -2
- package/lib/platform.js +83 -799
- package/lib/utils/capabilities.js +220 -0
- package/lib/utils/command-builder.js +6 -4
- package/lib/utils/config-parser.js +280 -0
- package/lib/utils/constants.js +120 -8
- package/lib/utils/decode.js +4 -1
- package/lib/utils/device-capabilities.js +77 -3
- package/lib/utils/device-context.js +179 -0
- package/lib/utils/device-merge.js +251 -0
- package/lib/utils/dispatch.js +159 -0
- package/lib/utils/functions.js +9 -0
- package/lib/utils/lang-en.js +0 -2
- package/lib/utils/report-unknown.js +156 -0
- package/package.json +1 -1
- package/lib/device/dehumidifier-H7151.js +0 -189
- package/lib/device/dehumidifier-H7152.js +0 -180
- package/lib/device/diffuser-H7162.js +0 -123
- package/lib/device/fan-H1310.js +0 -284
- package/lib/device/fan-H7101.js +0 -340
- package/lib/device/fan-H7102.js +0 -284
- package/lib/device/fan-H7106.js +0 -284
- package/lib/device/fan-H7111.js +0 -345
- package/lib/device/humidifier-H7145.js +0 -187
- package/lib/device/humidifier-H7147.js +0 -187
- package/lib/device/humidifier-H7148.js +0 -187
- package/lib/device/humidifier-H7149.js +0 -187
- package/lib/device/humidifier-H714E.js +0 -187
- package/lib/device/ice-maker-H717D.js +0 -218
- package/lib/device/ice-maker-H8120.js +0 -218
- package/lib/device/outlet-double.js +0 -188
- package/lib/device/outlet-triple.js +0 -160
- package/lib/device/purifier-H7121.js +0 -406
- package/lib/device/purifier-H7124.js +0 -504
- package/lib/device/purifier-H7127.js +0 -359
- package/lib/device/purifier-H7128.js +0 -359
- package/lib/device/purifier-H7129.js +0 -359
- package/lib/device/purifier-H712C.js +0 -359
- package/lib/device/sensor-contact.js +0 -22
- package/lib/utils/ble-timeouts.test.js +0 -44
- package/lib/utils/functions.test.js +0 -292
|
@@ -7,9 +7,10 @@ import {
|
|
|
7
7
|
statusToActionCode,
|
|
8
8
|
} from '../utils/functions.js'
|
|
9
9
|
import platformLang from '../utils/lang-en.js'
|
|
10
|
+
import { logUnknownData } from '../utils/report-unknown.js'
|
|
10
11
|
|
|
11
12
|
/*
|
|
12
|
-
H7123
|
|
13
|
+
H7123 and H7124
|
|
13
14
|
{
|
|
14
15
|
"mode": {
|
|
15
16
|
"options": [
|
|
@@ -38,7 +39,7 @@ import platformLang from '../utils/lang-en.js'
|
|
|
38
39
|
}
|
|
39
40
|
*/
|
|
40
41
|
|
|
41
|
-
export default class {
|
|
42
|
+
export default class GoveePurifierH7123 {
|
|
42
43
|
constructor(platform, accessory) {
|
|
43
44
|
// Set up variables from the platform
|
|
44
45
|
this.cusChar = platform.cusChar
|
|
@@ -497,7 +498,12 @@ export default class {
|
|
|
497
498
|
break
|
|
498
499
|
}
|
|
499
500
|
default:
|
|
500
|
-
this.accessory
|
|
501
|
+
logUnknownData(this.accessory, {
|
|
502
|
+
kind: 'scene',
|
|
503
|
+
source: params.source,
|
|
504
|
+
raw: command,
|
|
505
|
+
hex: hexString,
|
|
506
|
+
})
|
|
501
507
|
break
|
|
502
508
|
}
|
|
503
509
|
})
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
parseError,
|
|
6
6
|
} from '../utils/functions.js'
|
|
7
7
|
import platformLang from '../utils/lang-en.js'
|
|
8
|
+
import { logUnknownData } from '../utils/report-unknown.js'
|
|
8
9
|
|
|
9
10
|
export default class {
|
|
10
11
|
constructor(platform, accessory) {
|
|
@@ -351,7 +352,12 @@ export default class {
|
|
|
351
352
|
break
|
|
352
353
|
}
|
|
353
354
|
default:
|
|
354
|
-
this.accessory
|
|
355
|
+
logUnknownData(this.accessory, {
|
|
356
|
+
kind: 'scene',
|
|
357
|
+
source: params.source,
|
|
358
|
+
raw: command,
|
|
359
|
+
hex: hexString,
|
|
360
|
+
})
|
|
355
361
|
break
|
|
356
362
|
}
|
|
357
363
|
})
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import platformLang from '../utils/lang-en.js'
|
|
2
|
+
import { logUnknownData } from '../utils/report-unknown.js'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
/**
|
|
5
|
+
* A sensor whose broadcasts are not decoded yet.
|
|
6
|
+
*
|
|
7
|
+
* It offers no tile, because a tile that never updates is worse than none. What
|
|
8
|
+
* it does is report every message it receives in one copy-paste line, so an
|
|
9
|
+
* owner can send in exactly what is needed to finish the model off.
|
|
10
|
+
*/
|
|
11
|
+
export default class GoveeSensorBasic {
|
|
4
12
|
constructor(platform, accessory) {
|
|
5
13
|
// Set up variables from the platform
|
|
6
14
|
this.hapChar = platform.api.hap.Characteristic
|
|
@@ -17,6 +25,10 @@ export default class {
|
|
|
17
25
|
}
|
|
18
26
|
|
|
19
27
|
externalUpdate(params) {
|
|
20
|
-
this.accessory
|
|
28
|
+
logUnknownData(this.accessory, {
|
|
29
|
+
kind: 'scene',
|
|
30
|
+
source: params.source,
|
|
31
|
+
raw: params.scene,
|
|
32
|
+
})
|
|
21
33
|
}
|
|
22
34
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { base64ToHex, getTwoItemPosition, hexToTwoItems } from '../utils/functions.js'
|
|
2
2
|
import platformLang from '../utils/lang-en.js'
|
|
3
|
+
import { logUnknownData } from '../utils/report-unknown.js'
|
|
3
4
|
|
|
4
5
|
export default class {
|
|
5
6
|
constructor(platform, accessory) {
|
|
@@ -45,7 +46,12 @@ export default class {
|
|
|
45
46
|
break
|
|
46
47
|
}
|
|
47
48
|
default:
|
|
48
|
-
this.accessory
|
|
49
|
+
logUnknownData(this.accessory, {
|
|
50
|
+
kind: 'scene',
|
|
51
|
+
source: params.source,
|
|
52
|
+
raw: command,
|
|
53
|
+
hex: hexString,
|
|
54
|
+
})
|
|
49
55
|
break
|
|
50
56
|
}
|
|
51
57
|
})
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { base64ToHex, getTwoItemPosition, hexToTwoItems } from '../utils/functions.js'
|
|
2
2
|
import platformLang from '../utils/lang-en.js'
|
|
3
|
+
import { logUnknownData } from '../utils/report-unknown.js'
|
|
3
4
|
|
|
4
5
|
export default class {
|
|
5
6
|
constructor(platform, accessory) {
|
|
@@ -36,7 +37,12 @@ export default class {
|
|
|
36
37
|
const hexString = base64ToHex(command)
|
|
37
38
|
const hexParts = hexToTwoItems(hexString)
|
|
38
39
|
|
|
39
|
-
this.accessory
|
|
40
|
+
logUnknownData(this.accessory, {
|
|
41
|
+
kind: 'scene',
|
|
42
|
+
source: params.source,
|
|
43
|
+
raw: command,
|
|
44
|
+
hex: hexString,
|
|
45
|
+
})
|
|
40
46
|
|
|
41
47
|
// Return now if not a device query update code
|
|
42
48
|
if (getTwoItemPosition(hexParts, 1) !== 'aa') {
|
|
@@ -47,7 +53,12 @@ export default class {
|
|
|
47
53
|
|
|
48
54
|
switch (deviceFunction) {
|
|
49
55
|
default:
|
|
50
|
-
this.accessory
|
|
56
|
+
logUnknownData(this.accessory, {
|
|
57
|
+
kind: 'scene',
|
|
58
|
+
source: params.source,
|
|
59
|
+
raw: command,
|
|
60
|
+
hex: hexString,
|
|
61
|
+
})
|
|
51
62
|
break
|
|
52
63
|
}
|
|
53
64
|
})
|
|
@@ -8,8 +8,8 @@ import platformLang from '../utils/lang-en.js'
|
|
|
8
8
|
// outright rather than accepted and silently dropped (#1323).
|
|
9
9
|
const nightLightModels = ['H5089']
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
constructor(platform, accessory) {
|
|
11
|
+
class MultiSwitchDouble {
|
|
12
|
+
constructor(platform, accessory, config) {
|
|
13
13
|
// Set up variables from the platform
|
|
14
14
|
this.hapChar = platform.api.hap.Characteristic
|
|
15
15
|
this.hapErr = platform.api.hap.HapStatusError
|
|
@@ -19,12 +19,13 @@ export default class {
|
|
|
19
19
|
// Set up variables from the accessory
|
|
20
20
|
this.accessory = accessory
|
|
21
21
|
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
// Drop the tiles of the other kind, left behind if this device has been
|
|
23
|
+
// shown as the other one before
|
|
24
|
+
if (this.accessory.getService(`${config.other} 1`)) {
|
|
25
|
+
this.accessory.removeService(this.accessory.getService(`${config.other} 1`))
|
|
25
26
|
}
|
|
26
|
-
if (this.accessory.getService(
|
|
27
|
-
this.accessory.removeService(this.accessory.getService(
|
|
27
|
+
if (this.accessory.getService(`${config.other} 2`)) {
|
|
28
|
+
this.accessory.removeService(this.accessory.getService(`${config.other} 2`))
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
// A model that used to be treated as a single switch or outlet leaves an
|
|
@@ -35,15 +36,15 @@ export default class {
|
|
|
35
36
|
&& [this.hapServ.Switch.UUID, this.hapServ.Outlet.UUID].includes(service.UUID))
|
|
36
37
|
.forEach(service => this.accessory.removeService(service))
|
|
37
38
|
|
|
38
|
-
// Add
|
|
39
|
-
this.service1 = this.accessory.getService(
|
|
40
|
-
|| this.accessory.addService(this.hapServ.
|
|
41
|
-
this.service2 = this.accessory.getService(
|
|
42
|
-
|| this.accessory.addService(this.hapServ.
|
|
39
|
+
// Add this device's tiles if they are not there already
|
|
40
|
+
this.service1 = this.accessory.getService(`${config.label} 1`)
|
|
41
|
+
|| this.accessory.addService(this.hapServ[config.label], `${config.label} 1`, `${config.subtype}1`)
|
|
42
|
+
this.service2 = this.accessory.getService(`${config.label} 2`)
|
|
43
|
+
|| this.accessory.addService(this.hapServ[config.label], `${config.label} 2`, `${config.subtype}2`)
|
|
43
44
|
|
|
44
45
|
if (!this.service1.testCharacteristic(this.hapChar.ConfiguredName)) {
|
|
45
46
|
this.service1.addCharacteristic(this.hapChar.ConfiguredName)
|
|
46
|
-
this.service1.updateCharacteristic(this.hapChar.ConfiguredName,
|
|
47
|
+
this.service1.updateCharacteristic(this.hapChar.ConfiguredName, `${config.label} 1`)
|
|
47
48
|
}
|
|
48
49
|
if (!this.service1.testCharacteristic(this.hapChar.ServiceLabelIndex)) {
|
|
49
50
|
this.service1.addCharacteristic(this.hapChar.ServiceLabelIndex)
|
|
@@ -51,7 +52,7 @@ export default class {
|
|
|
51
52
|
}
|
|
52
53
|
if (!this.service2.testCharacteristic(this.hapChar.ConfiguredName)) {
|
|
53
54
|
this.service2.addCharacteristic(this.hapChar.ConfiguredName)
|
|
54
|
-
this.service2.updateCharacteristic(this.hapChar.ConfiguredName,
|
|
55
|
+
this.service2.updateCharacteristic(this.hapChar.ConfiguredName, `${config.label} 2`)
|
|
55
56
|
}
|
|
56
57
|
if (!this.service2.testCharacteristic(this.hapChar.ServiceLabelIndex)) {
|
|
57
58
|
this.service2.addCharacteristic(this.hapChar.ServiceLabelIndex)
|
|
@@ -86,7 +87,7 @@ export default class {
|
|
|
86
87
|
|
|
87
88
|
// Output the customised options to the log
|
|
88
89
|
const opts = JSON.stringify({
|
|
89
|
-
showAs:
|
|
90
|
+
showAs: config.showAs,
|
|
90
91
|
})
|
|
91
92
|
platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
|
|
92
93
|
|
|
@@ -186,3 +187,21 @@ export default class {
|
|
|
186
187
|
}
|
|
187
188
|
}
|
|
188
189
|
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* A double switch and a double outlet are the same device with a different tile
|
|
193
|
+
* in the Home app, chosen by the owner's `showAs` setting. Only the service
|
|
194
|
+
* type, the tile names and the logged option differ, so they share this and are
|
|
195
|
+
* built from it rather than from a copy of it.
|
|
196
|
+
*/
|
|
197
|
+
function make(config) {
|
|
198
|
+
return class extends MultiSwitchDouble {
|
|
199
|
+
constructor(platform, accessory) {
|
|
200
|
+
super(platform, accessory, config)
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export default make({ label: 'Switch', subtype: 'switch', other: 'Outlet', showAs: 'switch' })
|
|
206
|
+
|
|
207
|
+
export const asOutlet = make({ label: 'Outlet', subtype: 'outlet', other: 'Switch', showAs: 'outlet' })
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { parseError } from '../utils/functions.js'
|
|
2
2
|
import platformLang from '../utils/lang-en.js'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
constructor(platform, accessory) {
|
|
4
|
+
class MultiSwitchTriple {
|
|
5
|
+
constructor(platform, accessory, config) {
|
|
6
6
|
// Set up variables from the platform
|
|
7
7
|
this.hapChar = platform.api.hap.Characteristic
|
|
8
8
|
this.hapErr = platform.api.hap.HapStatusError
|
|
@@ -12,24 +12,25 @@ export default class {
|
|
|
12
12
|
// Set up variables from the accessory
|
|
13
13
|
this.accessory = accessory
|
|
14
14
|
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
// Drop the tiles of the other kind, left behind if this device has been
|
|
16
|
+
// shown as the other one before
|
|
17
|
+
if (this.accessory.getService(`${config.other} 1`)) {
|
|
18
|
+
this.accessory.removeService(this.accessory.getService(`${config.other} 1`))
|
|
18
19
|
}
|
|
19
|
-
if (this.accessory.getService(
|
|
20
|
-
this.accessory.removeService(this.accessory.getService(
|
|
20
|
+
if (this.accessory.getService(`${config.other} 2`)) {
|
|
21
|
+
this.accessory.removeService(this.accessory.getService(`${config.other} 2`))
|
|
21
22
|
}
|
|
22
|
-
if (this.accessory.getService(
|
|
23
|
-
this.accessory.removeService(this.accessory.getService(
|
|
23
|
+
if (this.accessory.getService(`${config.other} 3`)) {
|
|
24
|
+
this.accessory.removeService(this.accessory.getService(`${config.other} 3`))
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
// Add
|
|
27
|
-
this.service1 = this.accessory.getService(
|
|
28
|
-
|| this.accessory.addService(this.hapServ.
|
|
29
|
-
this.service2 = this.accessory.getService(
|
|
30
|
-
|| this.accessory.addService(this.hapServ.
|
|
31
|
-
this.service3 = this.accessory.getService(
|
|
32
|
-
|| this.accessory.addService(this.hapServ.
|
|
27
|
+
// Add this device's tiles if they are not there already
|
|
28
|
+
this.service1 = this.accessory.getService(`${config.label} 1`)
|
|
29
|
+
|| this.accessory.addService(this.hapServ[config.label], `${config.label} 1`, `${config.subtype}1`)
|
|
30
|
+
this.service2 = this.accessory.getService(`${config.label} 2`)
|
|
31
|
+
|| this.accessory.addService(this.hapServ[config.label], `${config.label} 2`, `${config.subtype}2`)
|
|
32
|
+
this.service3 = this.accessory.getService(`${config.label} 3`)
|
|
33
|
+
|| this.accessory.addService(this.hapServ[config.label], `${config.label} 3`, `${config.subtype}3`)
|
|
33
34
|
|
|
34
35
|
// Add the set handler to the switch on/off characteristic
|
|
35
36
|
this.service1.getCharacteristic(this.hapChar.On).onSet(async (value) => {
|
|
@@ -47,7 +48,7 @@ export default class {
|
|
|
47
48
|
|
|
48
49
|
// Output the customised options to the log
|
|
49
50
|
const opts = JSON.stringify({
|
|
50
|
-
showAs:
|
|
51
|
+
showAs: config.showAs,
|
|
51
52
|
})
|
|
52
53
|
platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
|
|
53
54
|
|
|
@@ -158,3 +159,21 @@ export default class {
|
|
|
158
159
|
}
|
|
159
160
|
}
|
|
160
161
|
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* A triple switch and a triple outlet are the same device with a different tile
|
|
165
|
+
* in the Home app, chosen by the owner's `showAs` setting. Only the service
|
|
166
|
+
* type, the tile names and the logged option differ, so they share this and are
|
|
167
|
+
* built from it rather than from a copy of it.
|
|
168
|
+
*/
|
|
169
|
+
function make(config) {
|
|
170
|
+
return class extends MultiSwitchTriple {
|
|
171
|
+
constructor(platform, accessory) {
|
|
172
|
+
super(platform, accessory, config)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export default make({ label: 'Switch', subtype: 'switch', other: 'Outlet', showAs: 'switch' })
|
|
178
|
+
|
|
179
|
+
export const asOutlet = make({ label: 'Outlet', subtype: 'outlet', other: 'Switch', showAs: 'outlet' })
|
package/lib/device/template.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { base64ToHex, getTwoItemPosition, hexToTwoItems } from '../utils/functions.js'
|
|
2
2
|
import platformLang from '../utils/lang-en.js'
|
|
3
|
+
import { logUnknownData } from '../utils/report-unknown.js'
|
|
3
4
|
|
|
4
5
|
export default class {
|
|
5
6
|
constructor(platform, accessory) {
|
|
@@ -19,7 +20,14 @@ export default class {
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
externalUpdate(params) {
|
|
22
|
-
|
|
23
|
+
// These are the models actively being worked out, so every payload is worth
|
|
24
|
+
// reporting in the full form rather than as a bare dump - it is the whole
|
|
25
|
+
// reason the accessory exists at this stage
|
|
26
|
+
logUnknownData(this.accessory, {
|
|
27
|
+
kind: 'payload',
|
|
28
|
+
source: params.source,
|
|
29
|
+
raw: params,
|
|
30
|
+
})
|
|
23
31
|
|
|
24
32
|
// Check for some other scene/mode change
|
|
25
33
|
;(params.commands || []).forEach((command) => {
|
|
@@ -35,7 +43,12 @@ export default class {
|
|
|
35
43
|
|
|
36
44
|
switch (deviceFunction) {
|
|
37
45
|
default:
|
|
38
|
-
this.accessory
|
|
46
|
+
logUnknownData(this.accessory, {
|
|
47
|
+
kind: 'scene',
|
|
48
|
+
source: params.source,
|
|
49
|
+
raw: command,
|
|
50
|
+
hex: hexString,
|
|
51
|
+
})
|
|
39
52
|
break
|
|
40
53
|
}
|
|
41
54
|
})
|