bt-sensors-plugin-sk 1.1.0-beta.2.2.1.0 → 1.1.0-beta.2.2.1.1
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/package.json +1 -1
- package/sensor_classes/ATC.js +2 -0
- package/sensor_classes/Aranet2.js +3 -1
- package/sensor_classes/Aranet4.js +2 -0
- package/sensor_classes/GoveeH50xx.js +6 -6
- package/sensor_classes/GoveeH510x.js +6 -6
- package/sensor_classes/Inkbird.js +1 -0
- package/sensor_classes/SwitchBotTH.js +81 -0
- package/sensor_classes/UltrasonicWindMeter.js +2 -2
- package/sensor_classes/Victron/VictronSensor.js +1 -1
- package/sensor_classes/XiaomiMiBeacon.js +19 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bt-sensors-plugin-sk",
|
|
3
|
-
"version": "1.1.0-beta.2.2.1.
|
|
3
|
+
"version": "1.1.0-beta.2.2.1.1",
|
|
4
4
|
"description": "Bluetooth Sensors for Signalk -- support for Victron devices, RuuviTag, Xiaomi, ATC and Inkbird, Ultrasonic wind meters, Mopeka tank readers, Renogy Battery and Solar Controllers (new), Aranet4 environment sensors, and Govee GVH51xx temp sensors",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"dependencies": {
|
package/sensor_classes/ATC.js
CHANGED
|
@@ -51,6 +51,8 @@ class ATC extends BTSensor{
|
|
|
51
51
|
}
|
|
52
52
|
propertiesChanged(props){
|
|
53
53
|
super.propertiesChanged(props)
|
|
54
|
+
if (!props.hasOwnProperty("ServiceData")) return
|
|
55
|
+
|
|
54
56
|
const buff = this.getServiceData("0000181a-0000-1000-8000-00805f9b34fb")
|
|
55
57
|
if (!buff)
|
|
56
58
|
throw new Error("Unable to get service data for "+this.getDisplayName())
|
|
@@ -34,7 +34,9 @@ class Aranet2 extends AranetSensor{
|
|
|
34
34
|
|
|
35
35
|
}
|
|
36
36
|
propertiesChanged(props){
|
|
37
|
-
super.propertiesChanged(props)
|
|
37
|
+
super.propertiesChanged(props)
|
|
38
|
+
if (!props.hasOwnProperty("ManufacturerData")) return
|
|
39
|
+
|
|
38
40
|
const buff = this.getManufacturerData(0x0702)
|
|
39
41
|
this.emitData("temp", buff)
|
|
40
42
|
this.emitData("humidity", buff)
|
|
@@ -39,6 +39,8 @@ class Aranet4 extends AranetSensor{
|
|
|
39
39
|
}
|
|
40
40
|
propertiesChanged(props){
|
|
41
41
|
super.propertiesChanged(props)
|
|
42
|
+
if (!props.hasOwnProperty("ManufacturerData")) return
|
|
43
|
+
|
|
42
44
|
const buff = this.getManufacturerData(0x0702)
|
|
43
45
|
this.emitData("co2", buff)
|
|
44
46
|
this.emitData("temp", buff)
|
|
@@ -36,12 +36,12 @@ class GoveeH50xx extends BTSensor {
|
|
|
36
36
|
}
|
|
37
37
|
async propertiesChanged(props){
|
|
38
38
|
super.propertiesChanged(props)
|
|
39
|
-
if (props.ManufacturerData)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
39
|
+
if (!props.hasOwnProperty("ManufacturerData")) return
|
|
40
|
+
|
|
41
|
+
const buffer = this.getManufacturerData(0xec88)
|
|
42
|
+
if (buffer) {
|
|
43
|
+
this.emitValuesFrom(buffer)
|
|
44
|
+
}
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
module.exports=GoveeH50xx
|
|
@@ -56,12 +56,12 @@ class GoveeH510x extends BTSensor{
|
|
|
56
56
|
}
|
|
57
57
|
async propertiesChanged(props){
|
|
58
58
|
super.propertiesChanged(props)
|
|
59
|
-
if (props.ManufacturerData)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
59
|
+
if (!props.hasOwnProperty("ManufacturerData")) return
|
|
60
|
+
|
|
61
|
+
const buffer = this.getManufacturerData(0x0001)
|
|
62
|
+
if (buffer) {
|
|
63
|
+
this.emitValuesFrom(buffer)
|
|
64
|
+
}
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
module.exports=GoveeH510x
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
const BTSensor = require("../BTSensor");
|
|
2
|
+
|
|
3
|
+
class SwitchBotTH extends BTSensor {
|
|
4
|
+
static async test(){
|
|
5
|
+
|
|
6
|
+
const p = {[this.ID.toString()]: [0xd8, 0x35, 0x34, 0x38, 0x4f, 0x70, 0x07, 0x02, 0x04, 0x96, 0x2c, 0x00]}
|
|
7
|
+
this.getDeviceProp=async ()=>{
|
|
8
|
+
return p
|
|
9
|
+
}
|
|
10
|
+
const c = await this.identify()
|
|
11
|
+
const sb = new c()
|
|
12
|
+
sb.initMetadata()
|
|
13
|
+
sb.currentProperties={}
|
|
14
|
+
sb.on("temp", (t)=>console.log(t))
|
|
15
|
+
sb.on("humidity", (h)=>console.log(h))
|
|
16
|
+
sb.on("battery", (b)=>console.log(b))
|
|
17
|
+
|
|
18
|
+
sb.propertiesChanged( {ManufacturerData: p})
|
|
19
|
+
|
|
20
|
+
sb.propertiesChanged( {ServiceData: {[this.batteryService]:[0x77,0x00,0x64]}})
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
}
|
|
24
|
+
static ID = 0x0969
|
|
25
|
+
static batteryService = "0000fd3d-0000-1000-8000-00805f9b34fb"
|
|
26
|
+
static async identify(device){
|
|
27
|
+
const md = await this.getDeviceProp(device,'ManufacturerData')
|
|
28
|
+
if (!md) return null
|
|
29
|
+
const keys = Object.keys(md)
|
|
30
|
+
if (keys && keys.length>0){
|
|
31
|
+
const id = keys[keys.length-1]
|
|
32
|
+
if (parseInt(id)==this.ID && md[id].length==12)
|
|
33
|
+
return this
|
|
34
|
+
}
|
|
35
|
+
return null
|
|
36
|
+
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async init(){
|
|
40
|
+
await super.init()
|
|
41
|
+
this.initMetadata()
|
|
42
|
+
}
|
|
43
|
+
initMetadata(){
|
|
44
|
+
this.addMetadatum('temp','K', 'temperature',
|
|
45
|
+
(buffer)=>{
|
|
46
|
+
return (27315+(((buffer[8] & 0x0F)/10 + (buffer[9] & 0x7F)) * (((buffer[9] & 0x80)>0)?100:-100)))/100
|
|
47
|
+
})
|
|
48
|
+
this.addMetadatum('humidity','ratio', 'humidity',
|
|
49
|
+
|
|
50
|
+
(buffer)=>{return (buffer[10] & 0x7F)/100
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
this.addMetadatum("battery", "ratio", "battery strength",
|
|
54
|
+
(buffer)=>{return buffer[2]/100}
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
getManufacturer(){
|
|
59
|
+
return "Wonder Labs"
|
|
60
|
+
}
|
|
61
|
+
getName() {
|
|
62
|
+
"SwitchBotTH"
|
|
63
|
+
}
|
|
64
|
+
async propertiesChanged(props){
|
|
65
|
+
super.propertiesChanged(props)
|
|
66
|
+
if (props.ManufacturerData) {
|
|
67
|
+
const buffer = this.getManufacturerData(this.constructor.ID)
|
|
68
|
+
if (buffer) {
|
|
69
|
+
this.emitData("temp", buffer)
|
|
70
|
+
this.emitData("humidity", buffer)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (props.ServiceData) {
|
|
74
|
+
const buffer = this.getServiceData(this.constructor.batteryService)
|
|
75
|
+
if (buffer){
|
|
76
|
+
this.emitData("battery", buffer)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
module.exports=SwitchBotTH
|
|
@@ -19,12 +19,12 @@ class UltrasonicWindMeter extends BTSensor{
|
|
|
19
19
|
)
|
|
20
20
|
this.awsCharacteristic.readValue()
|
|
21
21
|
.then((buffer)=>
|
|
22
|
-
this.
|
|
22
|
+
this.emitData("aws", buffer)
|
|
23
23
|
|
|
24
24
|
)
|
|
25
25
|
this.awaCharacteristic.readValue()
|
|
26
26
|
.then((buffer)=>
|
|
27
|
-
this.
|
|
27
|
+
this.emitData("awa", buffer)
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
}
|
|
@@ -88,7 +88,7 @@ function sleep(x) {
|
|
|
88
88
|
propertiesChanged(props){
|
|
89
89
|
super.propertiesChanged(props)
|
|
90
90
|
if (this.usingGATT()) return
|
|
91
|
-
|
|
91
|
+
if (!props.hasOwnProperty("ManufacturerData")) return
|
|
92
92
|
try{
|
|
93
93
|
const md = this.getManufacturerData(0x2e1)
|
|
94
94
|
if (md && md.length && md[0]==0x10){
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const { throws } = require("assert");
|
|
2
1
|
const BTSensor = require("../BTSensor");
|
|
3
2
|
|
|
4
3
|
const crypto = require('crypto');
|
|
4
|
+
const util = require('util');
|
|
5
5
|
const { isGeneratorFunction } = require("util/types");
|
|
6
6
|
|
|
7
7
|
const DEVICE_TYPES = new Map([
|
|
@@ -96,7 +96,7 @@ class XiaomiMiBeacon extends BTSensor{
|
|
|
96
96
|
|
|
97
97
|
emitValues(buffer){
|
|
98
98
|
this.emitData("temp", buffer, 0)
|
|
99
|
-
this.
|
|
99
|
+
this.emit("humidity", buffer.readUInt8(2)/100)
|
|
100
100
|
this.emitData("voltage",buffer,3);
|
|
101
101
|
}
|
|
102
102
|
getManufacturer(){
|
|
@@ -164,6 +164,8 @@ class XiaomiMiBeacon extends BTSensor{
|
|
|
164
164
|
propertiesChanged(props){
|
|
165
165
|
super.propertiesChanged(props)
|
|
166
166
|
if (this.usingGATT()) return
|
|
167
|
+
if (!props.hasOwnProperty("ServiceData")) return
|
|
168
|
+
|
|
167
169
|
const data = this.getServiceData(this.constructor.SERVICE_MIBEACON)
|
|
168
170
|
var dec
|
|
169
171
|
if (!this.encryptionKey){
|
|
@@ -180,14 +182,22 @@ class XiaomiMiBeacon extends BTSensor{
|
|
|
180
182
|
throw new Error(`${this.getNameAndAddress()} received empty decrypted packet. Check that the bind/encryption key in config is correct.`)
|
|
181
183
|
|
|
182
184
|
switch(dec[0]){
|
|
185
|
+
case 0x0D:
|
|
186
|
+
this.emitData("temp",dec,3)
|
|
187
|
+
this.emitData("humidity",dec,5)
|
|
188
|
+
break
|
|
189
|
+
|
|
190
|
+
case 0x0A:
|
|
191
|
+
this.emitData("batteryStrength",dec,3)
|
|
192
|
+
break
|
|
183
193
|
case 0x04:
|
|
184
|
-
this.
|
|
194
|
+
this.emitData("temp",dec,3)
|
|
185
195
|
break
|
|
186
196
|
case 0x06:
|
|
187
|
-
this.
|
|
197
|
+
this.emitData("humidity",dec,3)
|
|
188
198
|
break
|
|
189
199
|
default:
|
|
190
|
-
throw new Error(`${this.getNameAndAddress()} unable to parse decrypted service data (${dec})`)
|
|
200
|
+
throw new Error(`${this.getNameAndAddress()} unable to parse decrypted service data (${util.inspect(dec)})`)
|
|
191
201
|
|
|
192
202
|
}
|
|
193
203
|
}
|
|
@@ -197,8 +207,11 @@ class XiaomiMiBeacon extends BTSensor{
|
|
|
197
207
|
const md = this.addMetadatum("encryptionKey", "", "encryptionKey (AKA bindKey) for decryption")
|
|
198
208
|
md.isParam=true
|
|
199
209
|
this.addMetadatum('temp','K', 'temperature',
|
|
200
|
-
(buff,offset)=>{return ((buff.readInt16LE(offset))/
|
|
210
|
+
(buff,offset)=>{return ((buff.readInt16LE(offset))/10) + 273.15})
|
|
201
211
|
this.addMetadatum('humidity','ratio', 'humidity',
|
|
212
|
+
(buff,offset)=>{return buff.readInt16LE(offset)/1000})
|
|
213
|
+
|
|
214
|
+
this.addMetadatum('batteryStrength', 'ratio', 'sensor battery strength',
|
|
202
215
|
(buff,offset)=>{return ((buff.readUInt8(offset))/100)})
|
|
203
216
|
this.addMetadatum('voltage', 'V', 'sensor battery voltage',
|
|
204
217
|
(buff,offset)=>{return ((buff.readUInt16LE(offset))/1000)})
|