bt-sensors-plugin-sk 1.2.6-beta-5 → 1.2.6-beta-6a
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 +120 -85
- package/README.md +4 -0
- package/index.js +34 -19
- package/package.json +2 -2
- package/public/847.js +1 -1
- package/sensor_classes/BankManager.js +23 -35
- package/sensor_classes/Beacon/Eddystone.js +1 -1
- package/sensor_classes/Beacon/iBeacon.js +1 -1
- package/sensor_classes/EcoWorthyBW02.js +13 -20
- package/sensor_classes/EctiveBMS.js +8 -11
- package/sensor_classes/GobiusCTankMeter.js +13 -26
- package/sensor_classes/JBDBMS.js +7 -10
- package/sensor_classes/JikongBMS.js +37 -42
- package/sensor_classes/Junctek.js +13 -24
- package/sensor_classes/KilovaultHLXPlus.js +16 -25
- package/sensor_classes/MercurySmartcraft.js +26 -36
- package/sensor_classes/MopekaTankSensor.js +1 -1
- package/sensor_classes/RemoranWave3.js +23 -31
- package/sensor_classes/Renogy/RenogySensor.js +6 -13
- package/sensor_classes/ShenzhenLiOnBMS.js +11 -23
- package/sensor_classes/UltrasonicWindMeter.js +26 -43
- package/sensor_classes/XiaomiMiBeacon.js +10 -27
- package/src/components/PluginConfigurationPanel.js +1 -2
package/BTSensor.js
CHANGED
|
@@ -102,7 +102,7 @@ class BTSensor extends EventEmitter {
|
|
|
102
102
|
Object.assign(this,config)
|
|
103
103
|
Object.assign(this,gattConfig)
|
|
104
104
|
|
|
105
|
-
this._state =
|
|
105
|
+
this._state = "UNKNOWN"
|
|
106
106
|
}
|
|
107
107
|
/**
|
|
108
108
|
* @function _test Test sensor parsing
|
|
@@ -257,6 +257,9 @@ class BTSensor extends EventEmitter {
|
|
|
257
257
|
|
|
258
258
|
_debugLog=[]
|
|
259
259
|
_errorLog=[]
|
|
260
|
+
_error = false
|
|
261
|
+
|
|
262
|
+
|
|
260
263
|
|
|
261
264
|
getErrorLog(){
|
|
262
265
|
return this._errorLog
|
|
@@ -267,22 +270,23 @@ class BTSensor extends EventEmitter {
|
|
|
267
270
|
|
|
268
271
|
debug(message){
|
|
269
272
|
if (this._app)
|
|
270
|
-
this._app.debug(
|
|
273
|
+
this._app.debug(`(${this.getName()} ${this.getMacAddress()}) ${message}`)
|
|
271
274
|
else
|
|
272
|
-
console.log(
|
|
275
|
+
console.log(`(${this.getName()} ${this.getMacAddress()})) ${message}`)
|
|
273
276
|
this._debugLog.push({timestamp:Date.now(), message:message})
|
|
274
277
|
}
|
|
275
278
|
|
|
276
279
|
setError(message){
|
|
277
280
|
if (this._app){
|
|
278
|
-
this._app.debug(
|
|
279
|
-
this._app.setPluginError(
|
|
281
|
+
this._app.debug(`(${this.getName()} ${this.getMacAddress()}) ${message}`)
|
|
282
|
+
this._app.setPluginError(`(${this.getName()} ${this.getMacAddress()}) ${message}`)
|
|
280
283
|
}
|
|
281
284
|
else
|
|
282
|
-
console.log(message)
|
|
285
|
+
console.log(`(${this.getName()} ${this.getMacAddress()}) ${message}`)
|
|
283
286
|
|
|
284
287
|
this._errorLog.push({timestamp:Date.now(), message:message})
|
|
285
|
-
this.
|
|
288
|
+
this._error=true
|
|
289
|
+
this.emit("error", true)
|
|
286
290
|
}
|
|
287
291
|
|
|
288
292
|
//Instance Initialization functions
|
|
@@ -327,7 +331,7 @@ class BTSensor extends EventEmitter {
|
|
|
327
331
|
description: this.getGATTDescription(),
|
|
328
332
|
type:"object",
|
|
329
333
|
properties:{
|
|
330
|
-
useGATT: {title: "Use GATT connection", type: "boolean", default:
|
|
334
|
+
useGATT: {title: "Use GATT connection", type: "boolean", default: true },
|
|
331
335
|
pollFreq: { type: "number", title: "Polling frequency in seconds"}
|
|
332
336
|
}
|
|
333
337
|
}
|
|
@@ -349,16 +353,21 @@ class BTSensor extends EventEmitter {
|
|
|
349
353
|
|
|
350
354
|
}
|
|
351
355
|
async init(){
|
|
356
|
+
this.setState("INITIALIZING")
|
|
357
|
+
|
|
352
358
|
this.currentProperties = await this.constructor.getDeviceProps(this.device)
|
|
353
359
|
await this.initSchema()
|
|
354
360
|
|
|
355
361
|
this.initListen()
|
|
362
|
+
this.setState("DORMANT")
|
|
363
|
+
|
|
356
364
|
}
|
|
357
365
|
|
|
358
366
|
initListen(){
|
|
359
367
|
this.listen()
|
|
360
368
|
}
|
|
361
|
-
activate(config, plugin){
|
|
369
|
+
async activate(config, plugin){
|
|
370
|
+
this.setState("ACTIVATING")
|
|
362
371
|
if (config.paths){
|
|
363
372
|
this.createPaths(config,plugin.id)
|
|
364
373
|
this.initPaths(config,plugin.id)
|
|
@@ -366,13 +375,16 @@ class BTSensor extends EventEmitter {
|
|
|
366
375
|
}
|
|
367
376
|
if (this.usingGATT()){
|
|
368
377
|
try {
|
|
369
|
-
this.activateGATT()
|
|
378
|
+
await this.activateGATT()
|
|
370
379
|
} catch (e) {
|
|
371
|
-
this.setError(`GATT services unavailable
|
|
372
|
-
|
|
380
|
+
this.setError(`GATT services unavailable.`)
|
|
381
|
+
throw new Error(`GATT services unavailable for ${this.getName()}. Reason: ${e}`)
|
|
373
382
|
}
|
|
383
|
+
} else {
|
|
384
|
+
this.setState("ACTIVE")
|
|
374
385
|
}
|
|
375
|
-
this.
|
|
386
|
+
this._active = true
|
|
387
|
+
|
|
376
388
|
this._propertiesChanged(this.currentProperties)
|
|
377
389
|
|
|
378
390
|
}
|
|
@@ -383,23 +395,17 @@ class BTSensor extends EventEmitter {
|
|
|
383
395
|
return this._gattServer
|
|
384
396
|
}
|
|
385
397
|
async activateGATT(isReconnecting=false){
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
}
|
|
394
|
-
catch(e) {
|
|
395
|
-
this.debug(`Unable to activate GATT connection for ${this.getName()} (${this.getMacAddress()}): ${e}`)
|
|
396
|
-
}
|
|
398
|
+
this.setState("ACTIVATING GATT")
|
|
399
|
+
await this.initGATTConnection(isReconnecting)
|
|
400
|
+
if (this.pollFreq)
|
|
401
|
+
await this.initGATTInterval()
|
|
402
|
+
else
|
|
403
|
+
await this.initGATTNotifications()
|
|
404
|
+
|
|
397
405
|
}
|
|
398
406
|
|
|
399
|
-
async
|
|
400
|
-
if (this.
|
|
401
|
-
this.debug(`(${this.getName()}) disconnecting from GATT server`)
|
|
402
|
-
if (this._gattServer) { //getGATTServer() was called which calls node-ble's Device::gatt() which needs cleaning up after
|
|
407
|
+
async stopAllGATTNotifications(){
|
|
408
|
+
if (this._gattServer) { //getGATTServer() was called which calls node-ble's Device::gatt() which needs cleaning up after
|
|
403
409
|
(await this._gattServer.services()).forEach(async (uuid) => {
|
|
404
410
|
await this._gattServer.getPrimaryService(uuid).then(async (service) => {
|
|
405
411
|
(await service.characteristics()).forEach(async (uuid) => {
|
|
@@ -409,8 +415,12 @@ class BTSensor extends EventEmitter {
|
|
|
409
415
|
});
|
|
410
416
|
this._gattServer.helper.removeListeners();
|
|
411
417
|
});
|
|
412
|
-
|
|
413
|
-
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
async deactivateGATT(){
|
|
421
|
+
if (this.device) {
|
|
422
|
+
this.debug(`Disconnecting from GATT server...`)
|
|
423
|
+
await this.deviceDisconnect()
|
|
414
424
|
}
|
|
415
425
|
}
|
|
416
426
|
|
|
@@ -528,7 +538,7 @@ class BTSensor extends EventEmitter {
|
|
|
528
538
|
for (let attempts = 0; attempts<retries; attempts++) {
|
|
529
539
|
try
|
|
530
540
|
{
|
|
531
|
-
this.debug( `
|
|
541
|
+
this.debug( `Trying to connect (attempt # ${attempts +1}) to Bluetooth device.` );
|
|
532
542
|
await this.deviceConnect(isReconnecting);
|
|
533
543
|
return this.device
|
|
534
544
|
}
|
|
@@ -536,43 +546,56 @@ class BTSensor extends EventEmitter {
|
|
|
536
546
|
catch (e){
|
|
537
547
|
if (attempts==retries)
|
|
538
548
|
throw new Error (`(${this.getName}) Unable to connect to Bluetooth device after ${attempts} attempts`)
|
|
539
|
-
this.debug(`
|
|
549
|
+
this.debug(`Error connecting to device. Retrying... `);
|
|
540
550
|
await new Promise((r) => setTimeout(r, retryInterval*1000));
|
|
541
551
|
|
|
542
552
|
}
|
|
543
553
|
}
|
|
544
554
|
}
|
|
545
555
|
setConnected(state){
|
|
546
|
-
this.
|
|
547
|
-
this.emit("connected", this._connected)
|
|
556
|
+
this.setState(state?"CONNECTED":"DISCONNECTED")
|
|
548
557
|
}
|
|
549
|
-
deviceConnect(isReconnecting=false, autoReconnect=false) {
|
|
550
558
|
|
|
559
|
+
isError(){
|
|
560
|
+
return this._error
|
|
561
|
+
}
|
|
562
|
+
deviceConnect(isReconnecting=false, autoReconnect=false) {
|
|
551
563
|
|
|
552
564
|
return connectQueue.enqueue( async ()=>{
|
|
553
565
|
this.debug(`Connecting... ${this.getName()}`)
|
|
566
|
+
this.setState("CONNECTING")
|
|
567
|
+
if (!isReconnecting){
|
|
568
|
+
this.device.on("disconnect", () => {
|
|
569
|
+
this.debug("Device disconnected.")
|
|
570
|
+
this.setConnected(false)
|
|
571
|
+
})
|
|
572
|
+
this.device.on("connect", () => {
|
|
573
|
+
this.debug("Device connected.")
|
|
574
|
+
this.setConnected(true)
|
|
575
|
+
})
|
|
576
|
+
}
|
|
554
577
|
await this.device.helper.callMethod('Connect')
|
|
578
|
+
this.setConnected(true)
|
|
555
579
|
|
|
556
580
|
this.debug(`Connected to ${this.getName()}`)
|
|
557
581
|
if (!isReconnecting) {
|
|
558
582
|
this.device.helper.on(
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
583
|
+
"PropertiesChanged",
|
|
584
|
+
(propertiesChanged) => {
|
|
585
|
+
if ("Connected" in propertiesChanged) {
|
|
586
|
+
const { value } = propertiesChanged.Connected;
|
|
587
|
+
if (value) {
|
|
588
|
+
this.device.emit("connect", { connected: true });
|
|
589
|
+
} else {
|
|
590
|
+
this.device.emit("disconnect", { connected: false });
|
|
591
|
+
}
|
|
592
|
+
}
|
|
569
593
|
}
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
this._connected = false;
|
|
594
|
+
);
|
|
595
|
+
|
|
596
|
+
if (autoReconnect){
|
|
597
|
+
this.device.on("disconnect", async () => {
|
|
598
|
+
|
|
576
599
|
if (this.isActive()) {
|
|
577
600
|
this.debug(
|
|
578
601
|
`Device disconnected. Attempting to reconnect to ${this.getName()}`
|
|
@@ -583,16 +606,16 @@ class BTSensor extends EventEmitter {
|
|
|
583
606
|
this.debug(`(${this.getName()}) Device reconnected.`);
|
|
584
607
|
} catch (e) {
|
|
585
608
|
this.setError(
|
|
586
|
-
`Error while reconnecting
|
|
609
|
+
`Error while reconnecting: ${
|
|
587
610
|
e.message
|
|
588
611
|
}`
|
|
589
612
|
);
|
|
590
613
|
this.debug(
|
|
591
|
-
`Error while reconnecting
|
|
614
|
+
`Error while reconnecting: ${
|
|
592
615
|
e.message
|
|
593
616
|
}`
|
|
594
617
|
);
|
|
595
|
-
this.debug(e);
|
|
618
|
+
this._app.debug(e);
|
|
596
619
|
}
|
|
597
620
|
}
|
|
598
621
|
});
|
|
@@ -628,36 +651,51 @@ class BTSensor extends EventEmitter {
|
|
|
628
651
|
|
|
629
652
|
})
|
|
630
653
|
|
|
631
|
-
}
|
|
654
|
+
}
|
|
655
|
+
async deviceDisconnect(){
|
|
656
|
+
await this.stopAllGATTNotifications()
|
|
657
|
+
await this.device.disconnect()
|
|
658
|
+
this.setConnected(false)
|
|
659
|
+
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
async stopGATTNotifications(gattCharacteristic) {
|
|
663
|
+
if (gattCharacteristic){
|
|
664
|
+
gattCharacteristic.removeAllListeners()
|
|
632
665
|
|
|
666
|
+
try{
|
|
667
|
+
if (await gattCharacteristic.isNotifying())
|
|
668
|
+
await gattCharacteristic.stopNotifications();
|
|
669
|
+
} catch (e){
|
|
670
|
+
this.debug(`Error stopping notifications: ${e.message}`)
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
633
674
|
/**
|
|
634
|
-
*
|
|
635
|
-
*
|
|
636
|
-
* This function is only called when the property pollFreq is set to > 0
|
|
637
|
-
* The function calls #emitGATT() at the specified interval then disconnects
|
|
638
|
-
* from the device.
|
|
675
|
+
* The function calls #emitGATT() at the specified interval then calls deactivateGATT()
|
|
676
|
+
* which disconnects from the device.
|
|
639
677
|
*/
|
|
640
678
|
|
|
641
|
-
initGATTInterval(){
|
|
642
|
-
this.
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
catch(error) {
|
|
649
|
-
this.debug(error)
|
|
650
|
-
throw new Error(`unable to emit values for device ${this.getName()}:${error}`)
|
|
651
|
-
}
|
|
652
|
-
finally{
|
|
653
|
-
this.deactivateGATT().catch(
|
|
654
|
-
(e)=>{
|
|
655
|
-
this.debug(`(${this.getName()}) Error deactivating GATT Connection: ${e.message}`)
|
|
656
|
-
})
|
|
657
|
-
}
|
|
679
|
+
async initGATTInterval(){
|
|
680
|
+
await this.deviceDisconnect()
|
|
681
|
+
|
|
682
|
+
this.intervalID = setInterval( async () => {
|
|
683
|
+
try {
|
|
684
|
+
await this.initGATTConnection(true)
|
|
685
|
+
await this.emitGATT()
|
|
658
686
|
}
|
|
659
|
-
|
|
660
|
-
|
|
687
|
+
catch(error) {
|
|
688
|
+
this.debug(error)
|
|
689
|
+
this.setError(`Unable to emit values for device: ${error.message}`)
|
|
690
|
+
}
|
|
691
|
+
finally{
|
|
692
|
+
await this.deactivateGATT().catch( (e)=>{
|
|
693
|
+
this.debug(`Error deactivating GATT Connection: ${e.message}`)
|
|
694
|
+
})
|
|
695
|
+
this.setState("WAITING")
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
, this.pollFreq*1000)
|
|
661
699
|
}
|
|
662
700
|
|
|
663
701
|
/**
|
|
@@ -828,7 +866,7 @@ class BTSensor extends EventEmitter {
|
|
|
828
866
|
}
|
|
829
867
|
|
|
830
868
|
isActive(){
|
|
831
|
-
return this
|
|
869
|
+
return this?._active??false
|
|
832
870
|
}
|
|
833
871
|
getBars(){
|
|
834
872
|
const ss = this.getSignalStrength()
|
|
@@ -903,9 +941,7 @@ class BTSensor extends EventEmitter {
|
|
|
903
941
|
emitData(tag, buffer, ...args){
|
|
904
942
|
const md = this.getPath(tag)
|
|
905
943
|
if (md && md.read)
|
|
906
|
-
this.emit(tag, md.read(buffer, ...args))
|
|
907
|
-
|
|
908
|
-
|
|
944
|
+
this.emit(tag, md.read(buffer, ...args))
|
|
909
945
|
}
|
|
910
946
|
|
|
911
947
|
emitValuesFrom(buffer){
|
|
@@ -963,12 +999,11 @@ class BTSensor extends EventEmitter {
|
|
|
963
999
|
this.device.helper.removeListeners()
|
|
964
1000
|
|
|
965
1001
|
if (this.intervalID){
|
|
966
|
-
this.debug(`${this.getName()}::stopListening called clearInterval()`)
|
|
967
1002
|
clearInterval(this.intervalID)
|
|
968
1003
|
}
|
|
969
1004
|
if( this.usingGATT() )
|
|
970
1005
|
await this.deactivateGATT()
|
|
971
|
-
this.setState("
|
|
1006
|
+
this.setState("DORMANT")
|
|
972
1007
|
}
|
|
973
1008
|
//END Sensor listen-to-changes functions
|
|
974
1009
|
|
package/README.md
CHANGED
package/index.js
CHANGED
|
@@ -256,9 +256,9 @@ module.exports = function (app) {
|
|
|
256
256
|
options, async () => {
|
|
257
257
|
res.status(200).json({message: "Sensor updated"})
|
|
258
258
|
if (sensor) {
|
|
259
|
-
removeSensorFromList(sensor)
|
|
260
259
|
if (sensor.isActive())
|
|
261
260
|
await sensor.stopListening()
|
|
261
|
+
removeSensorFromList(sensor)
|
|
262
262
|
}
|
|
263
263
|
initConfiguredDevice(req.body)
|
|
264
264
|
}
|
|
@@ -364,6 +364,7 @@ module.exports = function (app) {
|
|
|
364
364
|
class: sensor.constructor.name,
|
|
365
365
|
domain: sensor.getDomain().name,
|
|
366
366
|
state: sensor.getState(),
|
|
367
|
+
error: sensor.isError(),
|
|
367
368
|
errorLog: sensor.getErrorLog(),
|
|
368
369
|
debugLog: sensor.getDebugLog(),
|
|
369
370
|
RSSI: sensor.getRSSI(),
|
|
@@ -415,12 +416,29 @@ module.exports = function (app) {
|
|
|
415
416
|
}
|
|
416
417
|
|
|
417
418
|
function removeSensorFromList(sensor){
|
|
419
|
+
sensor.removeAllListeners("state")
|
|
420
|
+
sensor.removeAllListeners("connected")
|
|
421
|
+
sensor.removeAllListeners("error")
|
|
422
|
+
sensor.removeAllListeners("debug")
|
|
423
|
+
|
|
418
424
|
sensorMap.delete(sensor.getMacAddress())
|
|
419
425
|
channel.broadcast({mac:sensor.getMacAddress()},"removesensor")
|
|
420
426
|
}
|
|
421
427
|
|
|
422
428
|
function addSensorToList(sensor){
|
|
423
429
|
sensorMap.set(sensor.getMacAddress(),sensor)
|
|
430
|
+
sensor.on("state", (state)=>{
|
|
431
|
+
updateSensor(sensor)
|
|
432
|
+
})
|
|
433
|
+
sensor.on("connected", (state)=>{
|
|
434
|
+
updateSensor(sensor)
|
|
435
|
+
})
|
|
436
|
+
sensor.on("error",(error)=>{
|
|
437
|
+
updateSensor(sensor)
|
|
438
|
+
})
|
|
439
|
+
sensor.on("debug", ()=>{
|
|
440
|
+
updateSensor(sensor)
|
|
441
|
+
})
|
|
424
442
|
channel.broadcast(sensorToJSON(sensor),"newsensor");
|
|
425
443
|
}
|
|
426
444
|
function deviceNameAndAddress(config){
|
|
@@ -469,19 +487,10 @@ module.exports = function (app) {
|
|
|
469
487
|
device.once("deviceFound",async (device)=>{
|
|
470
488
|
s.device=device
|
|
471
489
|
s.listen()
|
|
472
|
-
s.activate(config, plugin)
|
|
490
|
+
await s.activate(config, plugin)
|
|
473
491
|
removeSensorFromList(s)
|
|
474
492
|
addSensorToList(s)
|
|
475
493
|
})
|
|
476
|
-
s.on("state", (state)=>{
|
|
477
|
-
channel.broadcast(getSensorInfo(s), "sensorchanged")
|
|
478
|
-
})
|
|
479
|
-
s.on("error",(error)=>{
|
|
480
|
-
channel.broadcast(getSensorInfo(s), "sensorchanged")
|
|
481
|
-
})
|
|
482
|
-
s.on("debug", ()=>{
|
|
483
|
-
channel.broadcast(getSensorInfo(s), "sensorchanged")
|
|
484
|
-
})
|
|
485
494
|
addSensorToList(s)
|
|
486
495
|
resolve(s)
|
|
487
496
|
}
|
|
@@ -537,11 +546,13 @@ module.exports = function (app) {
|
|
|
537
546
|
return sensor
|
|
538
547
|
}
|
|
539
548
|
catch(error){
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
549
|
+
if (!config.unconfigured) {
|
|
550
|
+
const msg = `Unable to instantiate ${await BTSensor.getDeviceProp(device,"Address")}: ${error.message} `
|
|
551
|
+
plugin.debug(msg)
|
|
552
|
+
plugin.debug(error)
|
|
553
|
+
if (config.active)
|
|
554
|
+
plugin.setError(msg)
|
|
555
|
+
}
|
|
545
556
|
return null
|
|
546
557
|
}
|
|
547
558
|
|
|
@@ -552,19 +563,23 @@ module.exports = function (app) {
|
|
|
552
563
|
plugin.setStatusText(`Initializing ${deviceNameAndAddress(deviceConfig)}`);
|
|
553
564
|
if (!deviceConfig.discoveryTimeout)
|
|
554
565
|
deviceConfig.discoveryTimeout = options.discoveryTimeout
|
|
555
|
-
createSensor(adapter, deviceConfig).then((sensor)=>{
|
|
566
|
+
createSensor(adapter, deviceConfig).then(async (sensor)=>{
|
|
556
567
|
if (startNumber != starts ) {
|
|
557
568
|
return
|
|
558
569
|
}
|
|
559
570
|
if (deviceConfig.active && !(sensor.device instanceof OutOfRangeDevice) ) {
|
|
560
571
|
plugin.setStatusText(`Listening to ${++foundConfiguredDevices} sensors.`);
|
|
561
|
-
|
|
572
|
+
try {
|
|
573
|
+
await sensor.activate(deviceConfig, plugin)
|
|
574
|
+
} catch (e){
|
|
575
|
+
sensor.setError(`Unable to activate sensor. Reason: ${e.message}`)
|
|
576
|
+
}
|
|
562
577
|
}
|
|
563
578
|
|
|
564
579
|
})
|
|
565
580
|
.catch((error)=>
|
|
566
581
|
{
|
|
567
|
-
if (deviceConfig
|
|
582
|
+
if (deviceConfig?.unconfigured??false) return
|
|
568
583
|
if (startNumber != starts ) {
|
|
569
584
|
return
|
|
570
585
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bt-sensors-plugin-sk",
|
|
3
|
-
"version": "1.2.6-beta-
|
|
3
|
+
"version": "1.2.6-beta-6a",
|
|
4
4
|
"description": "Bluetooth Sensors for Signalk - see https://www.npmjs.com/package/bt-sensors-plugin-sk#supported-sensors for a list of supported sensors",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"dependencies": {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"@rjsf/validator-ajv8": "^5.24.11",
|
|
11
11
|
"better-sse": "^0.14.1",
|
|
12
12
|
"buffer": "^6.0.3",
|
|
13
|
-
"dbus-next": "^0.10.
|
|
13
|
+
"@jellybrick/dbus-next": "^0.10.3",
|
|
14
14
|
"int24": "^0.0.1",
|
|
15
15
|
"kaitai-struct": "^0.10.0",
|
|
16
16
|
"node-ble": "^1.13.0",
|
package/public/847.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[]).push([[847],{9337:()=>{},62995:(e,t,n)=>{"use strict";n.r(t),n.d(t,{BTConfig:()=>k,default:()=>C});var a=n(73490),s=n(74810),r=n(40334),o=n(86528),c=n.n(o),i=n(11363),l=n(97493),u=n(27606),m=n(82096),d=n(3768),g=n(71431),f=n(39676),h=n(47041),p=n(86038),E=n(95027),w=n(43540),y=n(38250),S=n(31008),b=n(20455),v=n(23399);const A=e=>console.log.bind(console,e);function k(e){const t=(0,m.A)((e=>({root:{"& > *":{margin:e.spacing(1)}}}))),[n,k]=(0,o.useState)({}),[C,D]=(0,o.useState)({}),[_
|
|
1
|
+
(self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[]).push([[847],{9337:()=>{},62995:(e,t,n)=>{"use strict";n.r(t),n.d(t,{BTConfig:()=>k,default:()=>C});var a=n(73490),s=n(74810),r=n(40334),o=n(86528),c=n.n(o),i=n(11363),l=n(97493),u=n(27606),m=n(82096),d=n(3768),g=n(71431),f=n(39676),h=n(47041),p=n(86038),E=n(95027),w=n(43540),y=n(38250),S=n(31008),b=n(20455),v=n(23399);const A=e=>console.log.bind(console,e);function k(e){const t=(0,m.A)((e=>({root:{"& > *":{margin:e.spacing(1)}}}))),[n,k]=(0,o.useState)({}),[C,D]=(0,o.useState)({}),[$,_]=(0,o.useState)({}),[x,N]=(0,o.useState)({"ui:options":{label:!1},paths:{enableMarkdownInDescription:!0},title:{"ui:widget":"hidden"}}),[O,T]=(0,o.useState)(),[j,M]=(0,o.useState)(!1),[U,J]=(0,o.useState)(!0),[L,R]=(0,o.useState)(new Map),[I,P]=(0,o.useState)({progress:0,maxTimeout:100,deviceCount:0,totalDevices:0}),[K,B]=(0,o.useState)("unknown"),[G,W]=(0,o.useState)(),[F,H]=(0,o.useState)(!1),[z,Y]=(0,o.useState)(""),q=t();function Q(e,t){const n=new Headers;return n.append("Content-Type","application/json"),fetch(`/plugins/bt-sensors-plugin-sk/${e}`,{credentials:"include",method:"POST",body:JSON.stringify(t),headers:n})}async function V(e,t={}){let n;try{const a=Object.keys(t).length?"?"+new URLSearchParams(t).toString():"";n=await fetch(`/plugins/bt-sensors-plugin-sk/${e}${a}`,{credentials:"include",method:"GET"})}catch(e){n={status:500,statusText:e.toString()}}return n}function X(e){return Object.keys(e.configCopy).length>0}function Z(e){const t=X(e);return c().createElement(b.A,{action:!0,onClick:()=>{e.config.mac_address=e.info.mac,_(e.schema),T(e.config)}},c().createElement("div",{class:"d-flex justify-content-between align-items-center",style:t?{fontWeight:"normal"}:{fontStyle:"italic"}},`${e._changesMade?"*":""}${e.info.name} MAC: ${e.info.mac} RSSI: ${n=e.info.RSSI,null==n?NaN:n}`,c().createElement("div",{class:"d-flex justify-content-between "},`${e.info.state} ${e.info.error?" (ERROR)":""}`,c().createElement("div",{class:"d-flex justify-content-between "},function(e){return null==e.info.lastContactDelta||e.info.lastContactDelta>e.config.discoveryTimeout?c().createElement(d.A,null):e.info.signalStrength>80?c().createElement(g.A,null):e.info.signalStrength>60?c().createElement(f.A,null):e.info.signalStrength>40?c().createElement(h.A,null):e.info.signalStrength>20?c().createElement(p.A,null):c().createElement(E.A,null)}(e)))));var n}function ee(e){window.open(e,"_blank","noreferrer")}return(0,o.useEffect)((()=>{let e=null;return V("getPluginState").then((async t=>{if(404==t.status)throw B("unknown"),new Error("unable to get plugin state");const n=await t.json();e=new EventSource("/plugins/bt-sensors-plugin-sk/sse",{withCredentials:!0}),e.addEventListener("newsensor",(e=>{!function(e){let t=JSON.parse(e.data);console.log(`New sensor: ${t.info.mac}`),R((e=>(e.set(t.info.mac,t),new Map(e))))}(e)})),e.addEventListener("sensorchanged",(e=>{!function(e){console.log("sensorchanged");const t=JSON.parse(e.data);console.log(t),R((e=>{const n=e.get(t.mac);return n&&Object.assign(n.info,t),new Map(e)}))}(e)})),e.addEventListener("progress",(e=>{const t=JSON.parse(e.data);P(t)})),e.addEventListener("pluginstate",(e=>{const t=JSON.parse(e.data);B(t.state)})),B(n.state),(async()=>{const e=await async function(){const e=await V("getSensors");if(200!=e.status)throw new Error(`Unable get sensor data: ${e.statusText} (${e.status}) `);return await e.json()}();R(new Map(e.map((e=>[e.info.mac,e]))))})()})).catch((e=>{W(e.message)})),()=>{console.log("Closing connection to SSE"),e.close()}}),[]),(0,o.useEffect)((()=>{if(!j)return;if(!O||!L)return;const e=L.get(O.mac_address);e&&$&&O&&Object.hasOwn(O,"params")&&"UNKNOWN"==e.info.class&&O.params.sensorClass&&"UNKNOWN"!=O.params.sensorClass&&(J(!1),Y(`Please wait. Fetching schema for ${O.params.sensorClass}...`),async function(e,t){const n=await V("getSensorInfo",{mac_address:e,class:t});if(200!=n.status)throw new Error(`Unable get sensor info: ${n.statusText} (${n.status}) `);return await n.json()}(O.mac_address,O.params.sensorClass).then((e=>{_(e.schema)})).catch((e=>{alert(e.message)})).finally((()=>{Y(""),J(!0),M(!1)})))}),[j]),(0,o.useEffect)((()=>{H(""!=z)}),[z]),(0,o.useEffect)((()=>{"started"==K?(async function(){const e=await V("getBaseData");if(200!=e.status)throw new Error(`Unable to get base data: ${e.statusText} (${e.status}) `);const t=await e.json();return t.schema.htmlDescription=c().createElement("div",null,(0,r.Ay)(t.schema.htmlDescription),c().createElement("p",null)),t}().then((e=>{k(e.schema),D(e.data)})).catch((e=>{W(e.message)})),async function(){const e=await V("getProgress");if(200!=e.status)throw new Error(`Unable to get progress: ${e.statusText} (${e.status}) `);return await e.json()}().then((e=>{P(e)})).catch((e=>{W(e.message)}))):(k({}),D({}))}),[K]),"stopped"==K||"unknown"==K?c().createElement("h3",null,"Enable plugin to see configuration"):c().createElement("div",null,c().createElement(i.A,{anchorOrigin:{horizontal:"center",vertical:"bottom"},onClose:()=>H(!1),open:F,message:z,key:"snackbar"}),c().createElement("div",{className:q.root},c().createElement(l.A,{variant:"contained",onClick:()=>{ee("https://github.com/naugehyde/bt-sensors-plugin-sk/tree/1.2.0-beta#configuration")}},"Documentation"),c().createElement(l.A,{variant:"contained",onClick:()=>{ee("https://github.com/naugehyde/bt-sensors-plugin-sk/issues/new/choose")}},"Report Issue"),c().createElement(l.A,{variant:"contained",onClick:()=>{ee("https://discord.com/channels/1170433917761892493/1295425963466952725")}},"Discord Thread"),c().createElement("p",null),c().createElement("p",null)),c().createElement("hr",{style:{width:"100%",height:"1px",color:"gray","background-color":"gray","text-align":"left","margin-left":0}}),G?c().createElement("h2",{style:{color:"red"}},G):"",c().createElement(a.Ay,{schema:n,validator:s.Ay,uiSchema:{"ui:field":"LayoutGridField","ui:layoutGrid":{"ui:row":[{"ui:row":{className:"row",children:[{"ui:columns":{className:"col-xs-4",children:["adapter","transport","duplicateData","discoveryTimeout","discoveryInterval"]}}]}}]}},onChange:e=>D(e.formData),onSubmit:({formData:e},t)=>{var n;n=e,R(new Map),Q("updateBaseData",n).then((e=>{200!=e.status&&W(`Unable to update base data: ${e.statusText} (${e.status})`)})),_({})},onError:A("errors"),formData:C}),c().createElement("hr",{style:{width:"100%",height:"1px",color:"gray","background-color":"gray","text-align":"left","margin-left":0}}),c().createElement("p",null),c().createElement("p",null),I.deviceCount<I.totalDevices?c().createElement(v.A,{max:I.maxTimeout,now:I.progress}):"",c().createElement("p",null),c().createElement(y.A,{defaultActiveKey:"_configured",id:"domain-tabs",className:"mb-3"},function(){const e=[...new Set(L.entries().map((e=>e[1].info.domain)))].sort(),t=Array.from(L.entries()).filter((e=>X(e[1])));let n={};return n._configured=0==t.length?"Select a device from its domain tab (Electrical etc.) and configure it.":t.map((e=>Z(L.get(e[0])))),e.forEach((e=>{var t;n[e]=(t=e,Array.from(L.entries()).filter((e=>e[1].info.domain===t))).map((e=>Z(L.get(e[0]))))})),Object.keys(n).map((e=>function(e,t){let n=e.slice("_"===e.charAt(0)?1:0);return c().createElement(S.A,{eventKey:e,title:`${n.charAt(0).toUpperCase()}${n.slice(1)}${"string"==typeof t?"":" ("+t.length+")"}`},c().createElement(w.A,{style:{maxHeight:"300px",overflowY:"auto"}},t))}(e,n[e])))}()),c().createElement("div",{style:{paddingLeft:10,paddingTop:10,display:0==Object.keys($).length?"none":""}},c().createElement(u.A,{container:!0,direction:"column",style:{spacing:5}},c().createElement(u.A,{item:!0},c().createElement("h2",null,$?.title),c().createElement("p",null)),c().createElement(u.A,{item:!0},(0,r.Ay)($?.htmlDescription))),c().createElement("fieldset",{disabled:!U},c().createElement(a.Ay,{schema:$,validator:s.Ay,uiSchema:x,onChange:(e,t)=>{const n=L.get(e.formData.mac_address);n&&(n._changesMade=!0,n.config=e.formData,T(e.formData)),"root_params_sensorClass"==t&&M(!0)},onSubmit:({formData:e},t)=>{var n;Q("updateSensorData",n=e).then((e=>{if(200!=e.status)throw new Error(e.statusText);R((e=>(e.delete(n.mac_address),new Map(e)))),_({})})),alert("Changes saved")},onError:A("errors"),formData:O},c().createElement("div",{className:q.root},c().createElement(l.A,{type:"submit",color:"primary",variant:"contained"},"Save"),c().createElement(l.A,{variant:"contained",onClick:()=>{var e;e=O.mac_address,L.get(e)._changesMade=!1,L.get(e).config=JSON.parse(JSON.stringify(L.get(e).configCopy)),T(L.get(e).config)}},"Undo"),c().createElement(l.A,{variant:"contained",color:"secondary",onClick:e=>function(e){const t=L.get(e);(!X(t)||window.confirm(`Delete configuration for ${t.info.name}?`))&&function(e){try{Q("removeSensorData",{mac_address:e}).then((e=>{if(200!=e.status)throw new Error(e.statusText)})),R((t=>(t.delete(e),new Map(t)))),_({})}catch{}}(e)}(O.mac_address)},"Delete"))))))}const C=k}}]);
|
|
@@ -36,9 +36,7 @@ class BankManager extends BTSensor{
|
|
|
36
36
|
getManufacturer(){
|
|
37
37
|
return "Bank Manager"
|
|
38
38
|
}
|
|
39
|
-
|
|
40
|
-
return false
|
|
41
|
-
}
|
|
39
|
+
|
|
42
40
|
usingGATT(){
|
|
43
41
|
return true
|
|
44
42
|
}
|
|
@@ -49,48 +47,38 @@ class BankManager extends BTSensor{
|
|
|
49
47
|
this.emit("current", parseFloat(data[3]))
|
|
50
48
|
this.emit("soc", parseFloat(data[4])/100)
|
|
51
49
|
this.emit("connectionStatus", parseInt(data[5]))
|
|
52
|
-
|
|
53
50
|
}
|
|
51
|
+
|
|
54
52
|
emitGATT(){
|
|
55
53
|
|
|
56
54
|
}
|
|
57
55
|
ImageFile = "BankManager.webp"
|
|
58
56
|
|
|
59
|
-
initGATTConnection(){
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
this.characteristic = await this.service.getCharacteristic("0000ffe1-0000-1000-8000-00805f9b34fb")
|
|
65
|
-
}
|
|
66
|
-
resolve(this)
|
|
67
|
-
}) .catch((e)=>{ reject(e.message) }) })
|
|
57
|
+
async initGATTConnection(isReconnecting){
|
|
58
|
+
await super.initGATTConnection(isReconnecting)
|
|
59
|
+
const gattServer= await this.getGATTServer()
|
|
60
|
+
const service = await gattServer.getPrimaryService("0000ffe0-0000-1000-8000-00805f9b34fb")
|
|
61
|
+
this.characteristic = await service.getCharacteristic("0000ffe1-0000-1000-8000-00805f9b34fb")
|
|
68
62
|
}
|
|
69
63
|
|
|
70
|
-
initGATTNotifications() {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}))
|
|
83
|
-
|
|
64
|
+
async initGATTNotifications() {
|
|
65
|
+
await this.characteristic.startNotifications()
|
|
66
|
+
let data = null
|
|
67
|
+
this.characteristic.on('valuechanged', buffer => {
|
|
68
|
+
if (buffer.length>0 && buffer[0]==0x23) {
|
|
69
|
+
data = Buffer.from(buffer)
|
|
70
|
+
} else if (data && buffer.indexOf(0x0d0a)!==-1) {
|
|
71
|
+
data=Buffer.concat([data,buffer.subarray(0,buffer.indexOf(0x0d0a)-1)], data.length+buffer.indexOf(0x0d0a)-1)
|
|
72
|
+
this.emitDataFrom(data)
|
|
73
|
+
data=null
|
|
74
|
+
}
|
|
75
|
+
})
|
|
84
76
|
}
|
|
85
77
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
if (await this.device.isConnected()){
|
|
92
|
-
await this.device.disconnect()
|
|
93
|
-
}
|
|
78
|
+
|
|
79
|
+
async deactivateGATT(){
|
|
80
|
+
await this.stopGATTNotifications(this.characteristic)
|
|
81
|
+
await this.deactivateGATT()
|
|
94
82
|
}
|
|
95
83
|
}
|
|
96
84
|
module.exports=BankManager
|