bt-sensors-plugin-sk 1.1.0-beta.2.2.1.0 → 1.1.0-beta.2.2.1.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.
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.0",
3
+ "version": "1.1.0-beta.2.2.1.2",
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": {
@@ -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
- const buffer = this.getManufacturerData(0xec88)
41
- if (buffer) {
42
- this.emitValuesFrom(buffer)
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
- const buffer = this.getManufacturerData(0x0001)
61
- if (buffer) {
62
- this.emitValuesFrom(buffer)
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
@@ -27,6 +27,7 @@ class Inkbird extends BTSensor{
27
27
  }
28
28
  async propertiesChanged(props){
29
29
  super.propertiesChanged(props)
30
+
30
31
  if (props.ManufacturerData) {
31
32
  const keys = Object.keys(this.currentProperties.ManufacturerData)
32
33
  const key = keys[keys.length-1]
@@ -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,24 +19,23 @@ class UltrasonicWindMeter extends BTSensor{
19
19
  )
20
20
  this.awsCharacteristic.readValue()
21
21
  .then((buffer)=>
22
- this.emit("aws", buffer)
23
-
22
+ this.emitData("aws", buffer)
24
23
  )
25
24
  this.awaCharacteristic.readValue()
26
25
  .then((buffer)=>
27
- this.emit("awa", buffer)
26
+ this.emitData("awa", buffer)
28
27
  )
29
28
 
30
29
  }
31
30
  async init(){
32
31
  await super.init()
33
- this.addMetadatum("batt","","Battery strength",
34
- (buffer)=>{return buffer.readUInt8()})
35
- this.addMetadatum("awa","","Apparent Wind Angle",
36
- (buffer)=>{return buffer.readInt16LE()}
32
+ this.addMetadatum("batt","ratio","Battery strength",
33
+ (buffer)=>{return (buffer.readUInt8())/100})
34
+ this.addMetadatum("awa","rad","Apparent Wind Angle",
35
+ (buffer)=>{return (buffer.readInt16LE())/10000}
37
36
  )
38
- this.addMetadatum("aws","","Apparent Wind Speed",
39
- (buffer)=>{return buffer.readInt16LE()}
37
+ this.addMetadatum("aws","m/s","Apparent Wind Speed",
38
+ (buffer)=>{return (buffer.readInt16LE()/100)*.514444} //convert knots to m/s
40
39
  )
41
40
  }
42
41
 
@@ -85,7 +84,7 @@ class UltrasonicWindMeter extends BTSensor{
85
84
  this.awsCharacteristic=null
86
85
  }
87
86
  if (await this.device.isConnected()){
88
- await this.device.disconnect()
87
+ await this.device.disconnect()
89
88
  }
90
89
  }
91
90
  }
@@ -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.emitData("humidity", buffer,2)
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.emit("temp",(dec.readInt16LE(3)/10)+273.15)
194
+ this.emitData("temp",dec,3)
185
195
  break
186
196
  case 0x06:
187
- this.emit("humidity",(dec.readInt16LE(3)/1000))
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))/100) + 273.1})
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)})