bt-sensors-plugin-sk 1.1.0-beta.2.2.0 → 1.1.0-beta.2.2.1.0
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/BTSensor.js +16 -7
- package/README.md +10 -1
- package/index.js +31 -4
- package/package.json +2 -2
- package/sensor_classes/BlackListedDevice.js +8 -5
- package/sensor_classes/GoveeH50xx.js +47 -0
- package/sensor_classes/{GoveeTH.js → GoveeH510x.js} +3 -3
- package/sensor_classes/Victron/VictronSensor.js +1 -1
- package/sensor_classes/XiaomiMiBeacon.js +3 -0
package/BTSensor.js
CHANGED
|
@@ -227,7 +227,7 @@ class BTSensor extends EventEmitter {
|
|
|
227
227
|
const _propsProxy = await this._getPropsProxy(device)
|
|
228
228
|
try{
|
|
229
229
|
const rawProps = await _propsProxy.Get(device.helper.iface,prop)
|
|
230
|
-
return rawProps?.value
|
|
230
|
+
return rawProps?.value
|
|
231
231
|
}
|
|
232
232
|
catch(e){
|
|
233
233
|
return null //Property $prop (probably) doesn't exist in $device
|
|
@@ -258,7 +258,7 @@ class BTSensor extends EventEmitter {
|
|
|
258
258
|
if (!md) return null
|
|
259
259
|
const keys = Object.keys(md)
|
|
260
260
|
if (keys && keys.length>0){
|
|
261
|
-
return parseInt(keys[
|
|
261
|
+
return parseInt(keys[keys.length-1])
|
|
262
262
|
}
|
|
263
263
|
return null
|
|
264
264
|
}
|
|
@@ -374,16 +374,21 @@ class BTSensor extends EventEmitter {
|
|
|
374
374
|
* NOTE: The function mucks about with node-ble internal functions to help make sure the
|
|
375
375
|
* DBUS connection stays alive, doesn't tax resources and doesn't spit out spurious errors.
|
|
376
376
|
*/
|
|
377
|
-
|
|
377
|
+
initPropertiesChanged(){
|
|
378
378
|
|
|
379
379
|
this.propertiesChanged.bind(this)
|
|
380
380
|
this.device.helper._prepare()
|
|
381
381
|
this.device.helper.on("PropertiesChanged",
|
|
382
382
|
((props)=> {
|
|
383
|
-
|
|
383
|
+
try{
|
|
384
|
+
this.propertiesChanged(props)
|
|
385
|
+
}
|
|
386
|
+
catch(error){
|
|
387
|
+
this.debug(`Error occured on ${this.getNameAndAddress()}: ${error?.message??error}`)
|
|
388
|
+
this.debug(error)
|
|
389
|
+
}
|
|
384
390
|
}))
|
|
385
391
|
}
|
|
386
|
-
|
|
387
392
|
//END instance initialization functions
|
|
388
393
|
|
|
389
394
|
//Metadata functions
|
|
@@ -569,8 +574,12 @@ class BTSensor extends EventEmitter {
|
|
|
569
574
|
|
|
570
575
|
|
|
571
576
|
listen(){
|
|
572
|
-
|
|
573
|
-
|
|
577
|
+
try{
|
|
578
|
+
this.initPropertiesChanged()
|
|
579
|
+
this.propertiesChanged(this.currentProperties)
|
|
580
|
+
} catch(e){
|
|
581
|
+
this.debug(e)
|
|
582
|
+
}
|
|
574
583
|
if (this.usingGATT()){
|
|
575
584
|
this.initGATTConnection().then(async ()=>{
|
|
576
585
|
this.emitGATT()
|
package/README.md
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
# Bluetooth Sensors for [Signal K](http://www.signalk.org)
|
|
2
2
|
|
|
3
|
+
## BETA 2.2.1
|
|
4
|
+
|
|
5
|
+
### What's New
|
|
6
|
+
|
|
7
|
+
GoveeH50xx sensor support. Selectable bluetooth adapter on config screen (in case you have more than bluetooth adapter on your server).
|
|
8
|
+
|
|
9
|
+
|
|
3
10
|
## BETA 2.2.0
|
|
4
11
|
|
|
5
12
|
### What's New
|
|
13
|
+
|
|
6
14
|
Support for Aranet4 environment sensor and Renogy Rover/Wanderer Controllers. Untested support for Renogy Battery and Inverter clients. If you have a Renogy Battery or Inverter with bluetooth support, please give it a try and let me know how it goes.
|
|
7
15
|
|
|
8
16
|
### RENOGY NOTES
|
|
@@ -30,7 +38,7 @@ Signalk users with a Linux boat-puter (Windows and MacOS are NOT currently suppo
|
|
|
30
38
|
|
|
31
39
|
## REQUIREMENTS
|
|
32
40
|
|
|
33
|
-
* A Linux Signalk boat-puter with
|
|
41
|
+
* A Linux Signalk boat-puter with bluetooth-DBUS support
|
|
34
42
|
* A Bluetooth adapter
|
|
35
43
|
* [Bluez](https://www.bluez.org) installed
|
|
36
44
|
(Go here for [Snap installation instructions](https://snapcraft.io/bluez))
|
|
@@ -57,6 +65,7 @@ If you want to install directly from source (this is mostly of interest to custo
|
|
|
57
65
|
git clone https://github.com/naugehyde/bt-sensors-plugin-sk
|
|
58
66
|
cd bt-sensors-plugin-sk
|
|
59
67
|
git switch '1.1.0'
|
|
68
|
+
git pull
|
|
60
69
|
npm i
|
|
61
70
|
[sudo] npm link
|
|
62
71
|
cd [signalk_home]
|
package/index.js
CHANGED
|
@@ -102,6 +102,8 @@ module.exports = function (app) {
|
|
|
102
102
|
const sensor = new c(device,config?.params, config?.gattParams)
|
|
103
103
|
sensor.debug=app.debug
|
|
104
104
|
await sensor.init()
|
|
105
|
+
app.debug(`instantiated ${await BTSensor.getDeviceProp(device,"Address")}`)
|
|
106
|
+
|
|
105
107
|
return sensor
|
|
106
108
|
}
|
|
107
109
|
}} catch(error){
|
|
@@ -174,8 +176,11 @@ module.exports = function (app) {
|
|
|
174
176
|
"2) You will have to wait until the scanner has found your device before seeing your device's config fields and saving the configuration. \n"+
|
|
175
177
|
"3) To refresh the list of available devices and their configurations, just open and close the config screen by clicking on the arrow symbol in the config's top bar. \n"+
|
|
176
178
|
"4) If you submit and get errors it may be because the configured devices have not yet all been discovered.",
|
|
177
|
-
required:["discoveryTimeout", "discoveryInterval"],
|
|
179
|
+
required:["adapter","discoveryTimeout", "discoveryInterval"],
|
|
178
180
|
properties: {
|
|
181
|
+
adapter: {title: "Bluetooth adapter",
|
|
182
|
+
type: "string", default: "hci0"},
|
|
183
|
+
|
|
179
184
|
discoveryTimeout: {title: "Default device discovery timeout (in seconds)",
|
|
180
185
|
type: "integer", default: 30,
|
|
181
186
|
minimum: 10,
|
|
@@ -358,13 +363,16 @@ module.exports = function (app) {
|
|
|
358
363
|
createSensor(adapter, deviceConfig).then((sensor)=>{
|
|
359
364
|
deviceConfig.sensor=sensor
|
|
360
365
|
if (deviceConfig.active) {
|
|
361
|
-
|
|
362
|
-
|
|
366
|
+
if (deviceConfig.paths){
|
|
367
|
+
createPaths(deviceConfig)
|
|
368
|
+
initPaths(deviceConfig)
|
|
369
|
+
}
|
|
363
370
|
const result = Promise.resolve(deviceConfig.sensor.listen())
|
|
364
371
|
result.then(() => {
|
|
365
372
|
app.debug(`Listening for changes from ${deviceConfig.sensor.getDisplayName()}`);
|
|
366
373
|
app.setPluginStatus(`Initial scan complete. Listening to ${++found} sensors.`);
|
|
367
374
|
})
|
|
375
|
+
|
|
368
376
|
}
|
|
369
377
|
|
|
370
378
|
})
|
|
@@ -417,13 +425,32 @@ module.exports = function (app) {
|
|
|
417
425
|
sensorMap.clear()
|
|
418
426
|
deviceConfigs=options?.peripherals??[]
|
|
419
427
|
|
|
428
|
+
|
|
429
|
+
|
|
420
430
|
if (plugin.stopped) {
|
|
421
431
|
await sleep(5000) //Make sure plugin.stop() completes first
|
|
422
432
|
//plugin.start is called asynchronously for some reason
|
|
423
433
|
//and does not wait for plugin.stop to complete
|
|
424
434
|
plugin.stopped=false
|
|
425
435
|
}
|
|
426
|
-
|
|
436
|
+
var adapterID=options.adapter
|
|
437
|
+
|
|
438
|
+
if (!adapterID || adapterID==="")
|
|
439
|
+
adapterID = "hci0"
|
|
440
|
+
|
|
441
|
+
app.debug(`Connecting to bluetooth adapter ${adapterID}`);
|
|
442
|
+
|
|
443
|
+
const activeAdapters = await bluetooth.activeAdapters()
|
|
444
|
+
plugin.schema.properties.adapter.enum=[]
|
|
445
|
+
plugin.schema.properties.adapter.enumNames=[]
|
|
446
|
+
for (a of activeAdapters){
|
|
447
|
+
plugin.schema.properties.adapter.enum.push(a.adapter)
|
|
448
|
+
plugin.schema.properties.adapter.enumNames.push(`${a.adapter} @ ${ await a.getAddress()} (${await a.getName()})`)
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
plugin.uiSchema.adapter={'ui:disabled': (activeAdapters.length==1)}
|
|
452
|
+
|
|
453
|
+
adapter = await bluetooth.getAdapter(adapterID)
|
|
427
454
|
await startScanner()
|
|
428
455
|
if (starts>0){
|
|
429
456
|
app.debug(`Plugin ${packageInfo.version} restarting...`);
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bt-sensors-plugin-sk",
|
|
3
|
-
"version": "1.1.0-beta.2.2.0",
|
|
3
|
+
"version": "1.1.0-beta.2.2.1.0",
|
|
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": {
|
|
7
7
|
"dbus-next": "^0.10.2",
|
|
8
|
-
"node-ble": "^1.
|
|
8
|
+
"node-ble": "^1.12.0",
|
|
9
9
|
"int24":"^0.0.1"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
@@ -2,10 +2,13 @@ const BTSensor = require("../BTSensor");
|
|
|
2
2
|
class BLACKLISTED extends BTSensor{
|
|
3
3
|
static isSystem = true
|
|
4
4
|
static async identify(device){
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
const md = await this.getDeviceProp(device,'ManufacturerData')
|
|
6
|
+
if (md){
|
|
7
|
+
const keys = Object.keys(md)
|
|
8
|
+
if (keys.length==1 && keys[0]==0x004C)
|
|
9
|
+
return this
|
|
10
|
+
}
|
|
11
|
+
return null
|
|
9
12
|
}
|
|
10
13
|
async init(){
|
|
11
14
|
await super.init()
|
|
@@ -13,7 +16,7 @@ class BLACKLISTED extends BTSensor{
|
|
|
13
16
|
}
|
|
14
17
|
reasonForBlacklisting() {
|
|
15
18
|
switch ( this.getManufacturerID()){
|
|
16
|
-
case (0x004C): return "Randomized MAC address"
|
|
19
|
+
case (0x004C): return "Randomized MAC address (Apple)"
|
|
17
20
|
case (0x02e1): return "Device is using VE.Smart" //NOTE: Victron/VictronSensor class
|
|
18
21
|
//determines if a device is using VE.Smart
|
|
19
22
|
//in identify(). If so, identify() returns
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const BTSensor = require("../BTSensor");
|
|
2
|
+
|
|
3
|
+
class GoveeH50xx extends BTSensor {
|
|
4
|
+
|
|
5
|
+
static async identify(device){
|
|
6
|
+
const regex = /^Govee_H50[0-9]{2}_[a-f,A-F,0-9]{4}$/
|
|
7
|
+
//this.getManufacturer()
|
|
8
|
+
const name = await this.getDeviceProp(device,"Name")
|
|
9
|
+
const uuids = await this.getDeviceProp(device,'UUIDs')
|
|
10
|
+
|
|
11
|
+
if (name && name.match(regex) &&
|
|
12
|
+
uuids && uuids.length > 0 &&
|
|
13
|
+
uuids[0] == '0000ec88-0000-1000-8000-00805f9b34fb')
|
|
14
|
+
return this
|
|
15
|
+
else
|
|
16
|
+
return null
|
|
17
|
+
t
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async init(){
|
|
21
|
+
await super.init()
|
|
22
|
+
this.initMetadata()
|
|
23
|
+
}
|
|
24
|
+
initMetadata(){
|
|
25
|
+
this.addMetadatum('temp','K', 'temperature',
|
|
26
|
+
(buffer)=>{return 273.15+(buffer.readUInt16LE(1)/100)
|
|
27
|
+
})
|
|
28
|
+
this.addMetadatum('humidity','ratio', 'humidity',
|
|
29
|
+
(buffer)=>{return buffer.readUInt16LE(3)/10000
|
|
30
|
+
})
|
|
31
|
+
this.addMetadatum('battery','ratio', 'battery strength', (buffer)=>{return buffer.readUInt8(5)/100})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
getManufacturer(){
|
|
35
|
+
return "Govee"
|
|
36
|
+
}
|
|
37
|
+
async propertiesChanged(props){
|
|
38
|
+
super.propertiesChanged(props)
|
|
39
|
+
if (props.ManufacturerData) {
|
|
40
|
+
const buffer = this.getManufacturerData(0xec88)
|
|
41
|
+
if (buffer) {
|
|
42
|
+
this.emitValuesFrom(buffer)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
module.exports=GoveeH50xx
|
|
@@ -18,10 +18,10 @@ function decodeTempHumid(tempHumidBytes) {
|
|
|
18
18
|
return {t: tempAsFloat, h: humid};
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
class
|
|
21
|
+
class GoveeH510x extends BTSensor{
|
|
22
22
|
|
|
23
23
|
static async identify(device){
|
|
24
|
-
const regex = /^
|
|
24
|
+
const regex = /^GVH510[0-9]_[a-f,A-F,0-9]{4}$/
|
|
25
25
|
const name = await this.getDeviceProp(device,"Name")
|
|
26
26
|
const uuids = await this.getDeviceProp(device,'UUIDs')
|
|
27
27
|
|
|
@@ -64,4 +64,4 @@ class GoveeTH extends BTSensor{
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
module.exports=
|
|
67
|
+
module.exports=GoveeH510x
|
|
@@ -64,7 +64,7 @@ function sleep(x) {
|
|
|
64
64
|
|
|
65
65
|
decrypt(data){
|
|
66
66
|
if (!this.encryptionKey)
|
|
67
|
-
throw Error("Unable to decrypt: no encryption key set")
|
|
67
|
+
throw new Error("Unable to decrypt: no encryption key set")
|
|
68
68
|
|
|
69
69
|
const encMethod = 'aes-128-ctr';
|
|
70
70
|
const iv = data.readUInt16LE(5);
|
|
@@ -166,6 +166,9 @@ class XiaomiMiBeacon extends BTSensor{
|
|
|
166
166
|
if (this.usingGATT()) return
|
|
167
167
|
const data = this.getServiceData(this.constructor.SERVICE_MIBEACON)
|
|
168
168
|
var dec
|
|
169
|
+
if (!this.encryptionKey){
|
|
170
|
+
throw new Error(`${this.getNameAndAddress()} requires an encryption key.`)
|
|
171
|
+
}
|
|
169
172
|
if (this.encryptionVersion >= 4) {
|
|
170
173
|
dec = this.decryptV4and5(data)
|
|
171
174
|
} else {
|