bt-sensors-plugin-sk 1.2.0-beta.0.0.7 → 1.2.0-beta.0.0.9
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/.vscode/launch.json +7 -0
- package/BTSensor.js +7 -2
- package/README.md +10 -0
- package/index.js +18 -12
- package/package.json +1 -1
- package/plugin_defaults.json +5 -4
- package/public/893.js +1 -1
- package/sensor_classes/Aranet4.js +1 -1
- package/sensor_classes/GoveeH50xx.js +2 -0
- package/sensor_classes/MopekaTankSensor.js +2 -2
- package/sensor_classes/UltrasonicWindMeter.js +4 -0
- package/sensor_classes/VictronSmartBatteryProtect.js +1 -0
- package/src/components/PluginConfigurationPanel.js +35 -12
package/BTSensor.js
CHANGED
|
@@ -100,7 +100,6 @@ function preparePath(obj, str) {
|
|
|
100
100
|
*/
|
|
101
101
|
|
|
102
102
|
class BTSensor extends EventEmitter {
|
|
103
|
-
//static metadata=new Map()
|
|
104
103
|
|
|
105
104
|
static DEFAULTS = require('./plugin_defaults.json');
|
|
106
105
|
|
|
@@ -318,6 +317,7 @@ class BTSensor extends EventEmitter {
|
|
|
318
317
|
|
|
319
318
|
//create the 'name' parameter
|
|
320
319
|
this.addDefaultParam("name")
|
|
320
|
+
.default=this?.currentProperties?.Name
|
|
321
321
|
|
|
322
322
|
//create the 'location' parameter
|
|
323
323
|
|
|
@@ -365,13 +365,15 @@ class BTSensor extends EventEmitter {
|
|
|
365
365
|
}
|
|
366
366
|
else
|
|
367
367
|
await this.initGATTNotifications()
|
|
368
|
+
}).catch((e)=>{
|
|
369
|
+
this.app.debug(`Unable to activate GATT connection for ${this.getName()} (${this.getMacAddress()}): ${e}`)
|
|
368
370
|
})
|
|
369
371
|
}
|
|
370
372
|
|
|
371
373
|
/**
|
|
372
374
|
* Add a metadatum instance to the sensor instance
|
|
373
375
|
*
|
|
374
|
-
* @param {String} tag
|
|
376
|
+
* @param {String} tag
|
|
375
377
|
* @param {...any} args
|
|
376
378
|
* @returns {this.Metadatum} the new metadatum instance
|
|
377
379
|
*/
|
|
@@ -552,6 +554,9 @@ class BTSensor extends EventEmitter {
|
|
|
552
554
|
getParams(){
|
|
553
555
|
return this._schema.properties.params.properties
|
|
554
556
|
}
|
|
557
|
+
getParameter(param){
|
|
558
|
+
return this.getParams()[param]
|
|
559
|
+
}
|
|
555
560
|
getGATTParams(){
|
|
556
561
|
return this._schema.properties.gattParams.properties
|
|
557
562
|
|
package/README.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## What's New
|
|
4
4
|
|
|
5
|
+
## 1.2.0-beta-0.0.9
|
|
6
|
+
|
|
7
|
+
Fixes to config page RSSI update.
|
|
8
|
+
|
|
9
|
+
## 1.2.0-beta-0.0.8
|
|
10
|
+
|
|
11
|
+
Improved handling of changed state on config page.
|
|
12
|
+
|
|
13
|
+
Several small fixes to various sensor classes.
|
|
14
|
+
|
|
5
15
|
## 1.2.0-beta-0.0.7
|
|
6
16
|
|
|
7
17
|
Added zone config param for environmental sensors. Removed location parameter.
|
package/index.js
CHANGED
|
@@ -21,15 +21,13 @@ class MissingSensor {
|
|
|
21
21
|
this.addPath=BTSensor.prototype.addPath.bind(this)
|
|
22
22
|
this.addParameter=BTSensor.prototype.addParameter.bind(this)
|
|
23
23
|
this.addDefaultPath=BTSensor.prototype.addDefaultPath.bind(this)
|
|
24
|
-
this.addDefaultParam=BTSensor.prototype.
|
|
25
|
-
this.addDefaultParam=BTSensor.prototype.addDefaultPath.bind(this)
|
|
24
|
+
this.addDefaultParam=BTSensor.prototype.addDefaultParam.bind(this)
|
|
26
25
|
this.getPath=BTSensor.prototype.getPath.bind(this)
|
|
27
26
|
|
|
28
27
|
this.getJSONSchema = BTSensor.prototype.getJSONSchema.bind(this)
|
|
29
28
|
this.initSchema = BTSensor.prototype.initSchema.bind(this)
|
|
30
29
|
|
|
31
30
|
this.initSchema()
|
|
32
|
-
|
|
33
31
|
var keys = Object.keys(config?.paths??{})
|
|
34
32
|
|
|
35
33
|
keys.forEach((key)=>{
|
|
@@ -321,13 +319,13 @@ module.exports = function (app) {
|
|
|
321
319
|
}
|
|
322
320
|
|
|
323
321
|
function getSensorInfo(sensor){
|
|
324
|
-
|
|
325
|
-
|
|
322
|
+
|
|
323
|
+
const etslc = sensor.elapsedTimeSinceLastContact()
|
|
326
324
|
return { mac: sensor.getMacAddress(),
|
|
327
325
|
name: sensor.getName(),
|
|
328
326
|
RSSI: sensor.getRSSI(),
|
|
329
327
|
signalStrength: sensor.getSignalStrength(),
|
|
330
|
-
lastContactDelta:
|
|
328
|
+
lastContactDelta: etslc
|
|
331
329
|
}
|
|
332
330
|
}
|
|
333
331
|
|
|
@@ -390,7 +388,6 @@ module.exports = function (app) {
|
|
|
390
388
|
adapter.waitDevice(config.mac_address,(config?.discoveryTimeout??30)*1000)
|
|
391
389
|
.then(async (device)=> {
|
|
392
390
|
if (startNumber != starts ) {
|
|
393
|
-
debugger
|
|
394
391
|
return
|
|
395
392
|
}
|
|
396
393
|
//app.debug(`Found ${config.mac_address}`)
|
|
@@ -400,8 +397,14 @@ module.exports = function (app) {
|
|
|
400
397
|
reject ( `Device is blacklisted (${s.reasonForBlacklisting()}).`)
|
|
401
398
|
else{
|
|
402
399
|
addSensorToList(s)
|
|
400
|
+
s._lastRSSI=-1*Infinity
|
|
403
401
|
s.on("RSSI",(()=>{
|
|
404
|
-
|
|
402
|
+
if (Date.now()-s._lastRSSI > 20000) { //only update RSSI on client every five seconds
|
|
403
|
+
//app.debug(`${s.getMacAddress()} ${Date.now()-s._lastRSSI}`)
|
|
404
|
+
s._lastRSSI=Date.now()
|
|
405
|
+
updateSensor(s)
|
|
406
|
+
}
|
|
407
|
+
|
|
405
408
|
}))
|
|
406
409
|
resolve(s)
|
|
407
410
|
}
|
|
@@ -443,7 +446,7 @@ module.exports = function (app) {
|
|
|
443
446
|
app.setPluginError(msg)
|
|
444
447
|
}
|
|
445
448
|
//if we're here ain't got no class for the device
|
|
446
|
-
var sensor
|
|
449
|
+
var sensor
|
|
447
450
|
if (config.params?.sensorClass){
|
|
448
451
|
var c = classMap.get(config.params.sensorClass)
|
|
449
452
|
} else{
|
|
@@ -636,15 +639,18 @@ module.exports = function (app) {
|
|
|
636
639
|
}
|
|
637
640
|
}
|
|
638
641
|
const minTimeout=Math.min(...deviceConfigs.map((dc)=>dc?.discoveryTimeout??options.discoveryTimeout))
|
|
639
|
-
|
|
642
|
+
const intervalTimeout = ((minTimeout==Infinity)?(options?.discoveryTimeout??plugin.schema.properties.discoveryTimeout.default):minTimeout)*1000
|
|
640
643
|
deviceHealthID = setInterval( ()=> {
|
|
641
644
|
sensorMap.forEach((sensor)=>{
|
|
642
645
|
const config = getDeviceConfig(sensor.getMacAddress())
|
|
643
646
|
const dt = config?.discoveryTimeout??options.discoveryTimeout
|
|
644
|
-
|
|
647
|
+
const lc=sensor.elapsedTimeSinceLastContact()
|
|
648
|
+
if (lc > dt) {
|
|
649
|
+
app.debug(`${sensor.getMacAddress()} not heard from in ${lc} seconds`)
|
|
645
650
|
channel.broadcast(getSensorInfo(sensor), "sensorchanged")
|
|
651
|
+
}
|
|
646
652
|
})
|
|
647
|
-
},
|
|
653
|
+
}, intervalTimeout)
|
|
648
654
|
|
|
649
655
|
if (!options.hasOwnProperty("discoveryInterval" )) //no config -- first run
|
|
650
656
|
options.discoveryInterval = plugin.schema.properties.discoveryInterval.default
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bt-sensors-plugin-sk",
|
|
3
|
-
"version": "1.2.0-beta.0.0.
|
|
3
|
+
"version": "1.2.0-beta.0.0.9",
|
|
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, Aranet4 environment sensors, SwitchBot temp and humidity sensors, KilovaultHLXPlus smart batteries, and Govee GVH51xx temp sensors",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"dependencies": {
|
package/plugin_defaults.json
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"environment":{
|
|
23
23
|
"temperature":
|
|
24
24
|
{
|
|
25
|
+
"title":"Current zone's temperature",
|
|
25
26
|
"unit":"K",
|
|
26
27
|
"default": "environment.{zone}.temperature"
|
|
27
28
|
},
|
|
@@ -32,15 +33,15 @@
|
|
|
32
33
|
},
|
|
33
34
|
"relativeHumidity":
|
|
34
35
|
{
|
|
35
|
-
"title":"Current relative humidity",
|
|
36
|
+
"title":"Current zone's relative humidity",
|
|
36
37
|
"unit":"ratio",
|
|
37
|
-
"default":"environment.{zone}.
|
|
38
|
+
"default":"environment.{zone}.relativeHumidity"
|
|
38
39
|
},
|
|
39
40
|
"pressure":
|
|
40
41
|
{
|
|
41
|
-
"title": "Current
|
|
42
|
+
"title": "Current zone's ambient air pressure",
|
|
42
43
|
"unit":"Pa",
|
|
43
|
-
"default":"environment.{zone}.
|
|
44
|
+
"default":"environment.{zone}.pressure"
|
|
44
45
|
}
|
|
45
46
|
},
|
|
46
47
|
"electrical":{
|
package/public/893.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";(self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[]).push([[893],{2995:(e,t,n)=>{n.r(t),n.d(t,{default:()=>v});var
|
|
1
|
+
"use strict";(self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[]).push([[893],{2995:(e,t,n)=>{n.r(t),n.d(t,{default:()=>v});var s=n(3490),a=n(4810),o=n(4147),r=n.n(o),l=n(7606),c=n(4952),i=n(3768),u=n(1431),g=n(9676),d=n(7041),m=n(3657),f=n(5027),p=n(7265),h=n(6890),E=n(8207);const w=e=>console.log.bind(console,e);var S;const v=e=>{const[t,n]=(0,o.useState)({}),[v,b]=(0,o.useState)({}),[y,D]=(0,o.useState)({}),[A,$]=(0,o.useState)({"ui:submitButtonOptions":{props:{disabled:!1,className:"btn btn-info"},norender:!0,submitText:"Submit"}}),[_,k]=(0,o.useState)([]),[x,C]=(0,o.useState)(),[T,M]=(0,o.useState)(new Map),[j,O]=(0,o.useState)({progress:0,maxTimeout:100,deviceCount:0,totalDevices:0}),[N,B]=(0,o.useState)("unknown"),[J,L]=(0,o.useState)();function U(e,t){console.log(`sending ${e}`),console.log(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 P(e){return console.log(`fetching ${e}`),fetch(`/plugins/bt-sensors-plugin-sk/${e}`,{credentials:"include"})}async function z(){console.log("getProgress");const e=await P("progress");if(200!=e.status)throw new Error(`Unable get progres: ${e.statusText} (${e.status}) `);const t=await e.json();return console.log(t),t}function H(){console.log("refreshing sensor map"),async function(){console.log("getSensorData");const e=await P("sensors");if(200!=e.status)throw new Error(`Unable get sensor data: ${e.statusText} (${e.status}) `);const t=await e.json();return console.log(t),t}().then((e=>{M(new Map(e.map((e=>[e.info.mac,e]))))})).catch((e=>{L(e)}))}return(0,o.useEffect)((()=>{console.log("useEffect([])"),P("sendPluginState").then((async e=>{const t=await e.json();B(t.state),console.log("Setting up eventsource");const n=new EventSource("/plugins/bt-sensors-plugin-sk/sse");return n.addEventListener("newsensor",(e=>{console.log("newsensor");let t=JSON.parse(e.data);S.has(t.info.mac)||(console.log(`New sensor: ${t.info.mac}`),M(new Map(S.set(t.info.mac,t))))})),n.addEventListener("sensorchanged",(e=>{let t=JSON.parse(e.data);if(console.log("sensorchanged"),console.log(t),S.has(t.mac)){let e=S.get(t.mac);Object.assign(e.info,t),M(new Map(S))}})),n.addEventListener("progress",(e=>{console.log("progress");const t=JSON.parse(e.data);O(t),console.log(t)})),n.addEventListener("pluginstate",(e=>{console.log("pluginstate");const t=JSON.parse(e.data);B(t.state)})),()=>n.close()})).catch((e=>{L(e)}))}),[]),(0,o.useEffect)((()=>{console.log("useEffect([pluginState])"),"started"==N?(H(),async function(){console.log("getBaseData");const e=await P("base");if(200!=e.status)throw new Error(`Unable get base data: ${e.statusText} (${e.status}) `);const t=await e.json();return console.log(t),t}().then((e=>{n(e.schema),b(e.data)})).catch((e=>{L(e)})),z().then((e=>{O(e)})).catch((e=>{L(e)}))):(M(new Map),n({}),b({}))}),[N]),(0,o.useEffect)((()=>{console.log("useEffect([error])"),console.log(J)}),[J]),(0,o.useEffect)((()=>{console.log("useEffect([sensorMap])"),S=T,k(Array.from(T.entries()).map((e=>{const t=T.get(e[0]),n=t.config,s=Object.keys(n).length>0;return r().createElement(h.A,{action:!0,onClick:()=>{t&&(n.mac_address=e[0],D(t.schema),C(n))}},r().createElement("div",{class:"d-flex justify-content-between align-items-center",style:s?{fontWeight:"normal"}:{fontStyle:"italic"}},`${t._changesMade?"*":""}${t.info.name} MAC: ${t.info.mac} RSSI: ${a=t.info.RSSI,null==a?NaN:a}`,r().createElement("div",{class:"d-flex justify-content-between "},function(e){return null==e.info.lastContactDelta||e.info.lastContactDelta>e.config.discoveryTimeout?r().createElement(i.A,null):e.info.signalStrength>80?r().createElement(u.A,null):e.info.signalStrength>60?r().createElement(g.A,null):e.info.signalStrength>40?r().createElement(d.A,null):e.info.signalStrength>20?r().createElement(m.A,null):r().createElement(f.A,null)}(t))));var a})))}),[T]),"stopped"==N?r().createElement("h1",null,"Enable plugin to see configuration"):r().createElement("div",null,J?r().createElement("h2",{style:"color: red;"},J.message):"",r().createElement(s.Ay,{schema:t,validator:a.Ay,onChange:e=>b(e.formData),onSubmit:({formData:e},t)=>{var n;C(null),n=e,console.log("updateBaseData"),U("sendBaseData",n).then((e=>{200!=e.status?L(new Error(`Unable to update base data: ${e.statusText} (${e.status})`)):(z().then((e=>{O(e)})).catch((e=>{L(e)})),H())}))},onError:w("errors"),formData:v}),r().createElement("p",null),r().createElement("p",null),j.deviceCount<j.totalDevices?r().createElement(E.A,{max:j.maxTimeout,now:j.progress}):"",r().createElement("h2",null,T.size>0?"Bluetooth Devices click to configure":""),r().createElement("h2",null,T.size>0?"(* means sensor has unsaved changes)":""),r().createElement("p",null),r().createElement("div",{style:{paddingBottom:20},class:"d-flex flex-wrap justify-content-start align-items-start"},r().createElement(p.A,{style:{maxHeight:"300px",overflowY:"auto"}},_),r().createElement("div",{style:{paddingLeft:10,paddingTop:10,display:0==Object.keys(y).length?"none":""}},r().createElement(s.Ay,{schema:y,validator:a.Ay,uiSchema:A,onChange:e=>{T.get(e.formData.mac_address)._changesMade=!0,C(e.formData)},onSubmit:({formData:e},t)=>{var n;console.log(e),n=e,console.log("updateSensorData"),U("sendSensorData",n).then((e=>{if(200!=e.status)throw new Error(e.statusText);T.get(n.mac_address)._changesMade=!1,T.get(n.mac_address).config=n})),D({}),alert("Changes saved")},onError:w("errors"),formData:x},r().createElement("div",null,r().createElement(l.A,{direction:"row",style:{spacing:5}},r().createElement(c.A,{type:"submit",color:"primary",variant:"contained"},"Save"),r().createElement(c.A,{variant:"contained",onClick:()=>{var e;e=x.mac_address,console.log("undoChanges"),T.get(e)._changesMade=!1,C(T.get(e).config)}},"Undo"),r().createElement(c.A,{variant:"contained",color:"secondary",onClick:e=>{return t=x.mac_address,void(window.confirm(`Delete configuration for ${t}?`)&&function(e){console.log("removeSensorData");try{U("removeSensorData",{mac_address:e}).then((e=>{if(200!=e.status)throw new Error(e.statusText)})),S.delete(e),M(new Map(S)),D({})}catch{}}(t));var t}},"Delete")))))))}}}]);
|
|
@@ -31,7 +31,7 @@ class Aranet4 extends AranetSensor{
|
|
|
31
31
|
this.addDefaultPath("pressure","environment.pressure")
|
|
32
32
|
.read=(buff)=>{return ((buff.readUInt16LE(12)))/10}
|
|
33
33
|
|
|
34
|
-
this.addDefaultPath('relativeHumidity','environment.
|
|
34
|
+
this.addDefaultPath('relativeHumidity','environment.relativeHumidity')
|
|
35
35
|
.read=(buff)=>{return ((buff.readUInt8(14))/100)}
|
|
36
36
|
|
|
37
37
|
this.addMetadatum('color', '', 'Warning color (G Y R)',
|
|
@@ -335,8 +335,8 @@ class MopekaTankSensor extends BTSensor{
|
|
|
335
335
|
if (this.name)
|
|
336
336
|
return this.name
|
|
337
337
|
|
|
338
|
-
const _name =
|
|
339
|
-
return _name?_name:
|
|
338
|
+
const _name = MopekaDevices.get(this?.modelID??0x0).name
|
|
339
|
+
return _name?_name:MopekaDevices.get(0x0).name
|
|
340
340
|
|
|
341
341
|
}
|
|
342
342
|
}
|
|
@@ -12,6 +12,9 @@ class UltrasonicWindMeter extends BTSensor{
|
|
|
12
12
|
hasGATT(){
|
|
13
13
|
return true
|
|
14
14
|
}
|
|
15
|
+
usingGATT(){
|
|
16
|
+
return true
|
|
17
|
+
}
|
|
15
18
|
emitGATT(){
|
|
16
19
|
this.battCharacteristic.readValue()
|
|
17
20
|
.then((buffer)=>
|
|
@@ -29,6 +32,7 @@ class UltrasonicWindMeter extends BTSensor{
|
|
|
29
32
|
}
|
|
30
33
|
initSchema(){
|
|
31
34
|
super.initSchema()
|
|
35
|
+
this.getGATTParams()["useGATT"].default=true
|
|
32
36
|
this.addDefaultPath("batt",'sensors.batteryStrength')
|
|
33
37
|
.read=(buffer)=>{return (buffer.readUInt8())/100}
|
|
34
38
|
|
|
@@ -26,6 +26,7 @@ class VictronSmartBatteryProtect extends VictronSensor{
|
|
|
26
26
|
|
|
27
27
|
initSchema(){
|
|
28
28
|
super.initSchema()
|
|
29
|
+
this.addDefaultParam("id")
|
|
29
30
|
this.addMetadatum('deviceState','', 'device state',
|
|
30
31
|
(buff)=>{return VC.OperationMode.get(buff.readUInt8(1))})
|
|
31
32
|
this.addMetadatum('outputStatus','', 'output status', //TODO
|
|
@@ -5,8 +5,7 @@ import {useEffect, useState} from 'react'
|
|
|
5
5
|
|
|
6
6
|
import {Button, Grid} from '@material-ui/core';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
import { SignalCellular0Bar, SignalCellular1Bar, SignalCellular2Bar, SignalCellular3Bar, SignalCellular4Bar, SignalCellularConnectedNoInternet0Bar } from '@material-ui/icons';
|
|
8
|
+
import { SignalCellular0Bar, SignalCellular1Bar, SignalCellular2Bar, SignalCellular3Bar, SignalCellular4Bar, SignalCellularConnectedNoInternet0Bar } from '@material-ui/icons';
|
|
10
9
|
|
|
11
10
|
const log = (type) => console.log.bind(console, type);
|
|
12
11
|
|
|
@@ -74,7 +73,7 @@ export default (props) => {
|
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
async function getSensorData(){
|
|
77
|
-
|
|
76
|
+
console.log("getSensorData")
|
|
78
77
|
const response = await fetchJSONData("sensors")
|
|
79
78
|
if (response.status!=200){
|
|
80
79
|
throw new Error(`Unable get sensor data: ${response.statusText} (${response.status}) `)
|
|
@@ -86,7 +85,7 @@ export default (props) => {
|
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
async function getBaseData(){
|
|
89
|
-
|
|
88
|
+
console.log("getBaseData")
|
|
90
89
|
const response = await fetchJSONData("base")
|
|
91
90
|
if (response.status!=200){
|
|
92
91
|
throw new Error(`Unable get base data: ${response.statusText} (${response.status}) `)
|
|
@@ -96,7 +95,7 @@ export default (props) => {
|
|
|
96
95
|
return json
|
|
97
96
|
}
|
|
98
97
|
async function getProgress(){
|
|
99
|
-
|
|
98
|
+
console.log("getProgress")
|
|
100
99
|
const response = await fetchJSONData("progress")
|
|
101
100
|
if (response.status!=200){
|
|
102
101
|
throw new Error(`Unable get progres: ${response.statusText} (${response.status}) `)
|
|
@@ -107,21 +106,26 @@ export default (props) => {
|
|
|
107
106
|
}
|
|
108
107
|
|
|
109
108
|
function updateSensorData(data){
|
|
109
|
+
console.log("updateSensorData")
|
|
110
110
|
sendJSONData("sendSensorData", data).then((response)=>{
|
|
111
111
|
if (response.status != 200) {
|
|
112
112
|
throw new Error(response.statusText)
|
|
113
113
|
}
|
|
114
|
-
|
|
114
|
+
sensorMap.get(data.mac_address)._changesMade=false
|
|
115
115
|
sensorMap.get(data.mac_address).config = data
|
|
116
116
|
|
|
117
117
|
})
|
|
118
|
-
}
|
|
118
|
+
}
|
|
119
119
|
|
|
120
120
|
function undoChanges(mac) {
|
|
121
|
+
console.log("undoChanges")
|
|
122
|
+
sensorMap.get(mac)._changesMade = false
|
|
121
123
|
setSensorData( sensorMap.get(mac).config )
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
function removeSensorData(mac){
|
|
127
|
+
console.log("removeSensorData")
|
|
128
|
+
|
|
125
129
|
try{
|
|
126
130
|
|
|
127
131
|
sendJSONData("removeSensorData", {mac_address:mac} ).then((response)=>{
|
|
@@ -142,6 +146,8 @@ export default (props) => {
|
|
|
142
146
|
|
|
143
147
|
|
|
144
148
|
function updateBaseData(data){
|
|
149
|
+
console.log("updateBaseData")
|
|
150
|
+
|
|
145
151
|
sendJSONData("sendBaseData", data).then( (response )=>{
|
|
146
152
|
if (response.status != 200) {
|
|
147
153
|
setError(new Error(`Unable to update base data: ${response.statusText} (${response.status})`))
|
|
@@ -170,7 +176,7 @@ export default (props) => {
|
|
|
170
176
|
|
|
171
177
|
|
|
172
178
|
useEffect(()=>{
|
|
173
|
-
|
|
179
|
+
console.log("useEffect([])")
|
|
174
180
|
fetchJSONData("sendPluginState").then( async (response)=> {
|
|
175
181
|
const json = await response.json()
|
|
176
182
|
setPluginState(json.state)
|
|
@@ -178,6 +184,7 @@ export default (props) => {
|
|
|
178
184
|
const eventSource = new EventSource("/plugins/bt-sensors-plugin-sk/sse")
|
|
179
185
|
|
|
180
186
|
eventSource.addEventListener("newsensor", (event) => {
|
|
187
|
+
console.log("newsensor")
|
|
181
188
|
let json = JSON.parse(event.data)
|
|
182
189
|
|
|
183
190
|
if (!_sensorMap.has(json.info.mac)) {
|
|
@@ -187,7 +194,9 @@ export default (props) => {
|
|
|
187
194
|
});
|
|
188
195
|
|
|
189
196
|
eventSource.addEventListener("sensorchanged", (event) => {
|
|
190
|
-
let json = JSON.parse(event.data)
|
|
197
|
+
let json = JSON.parse(event.data)
|
|
198
|
+
console.log("sensorchanged")
|
|
199
|
+
console.log(json)
|
|
191
200
|
|
|
192
201
|
if (_sensorMap.has(json.mac)) {
|
|
193
202
|
let sensor = _sensorMap.get(json.mac)
|
|
@@ -196,12 +205,14 @@ export default (props) => {
|
|
|
196
205
|
}
|
|
197
206
|
});
|
|
198
207
|
eventSource.addEventListener("progress", (event) => {
|
|
208
|
+
console.log("progress")
|
|
199
209
|
const json = JSON.parse(event.data)
|
|
200
210
|
setProgress(json)
|
|
201
211
|
console.log(json)
|
|
202
212
|
});
|
|
203
213
|
|
|
204
214
|
eventSource.addEventListener("pluginstate", (event) => {
|
|
215
|
+
console.log("pluginstate")
|
|
205
216
|
const json = JSON.parse(event.data)
|
|
206
217
|
setPluginState(json.state)
|
|
207
218
|
});
|
|
@@ -215,6 +226,7 @@ export default (props) => {
|
|
|
215
226
|
},[])
|
|
216
227
|
|
|
217
228
|
useEffect(()=>{
|
|
229
|
+
console.log("useEffect([pluginState])")
|
|
218
230
|
if (pluginState=="started"){
|
|
219
231
|
refreshSensors()
|
|
220
232
|
|
|
@@ -240,6 +252,7 @@ useEffect(()=>{
|
|
|
240
252
|
},[pluginState])
|
|
241
253
|
|
|
242
254
|
useEffect(()=>{
|
|
255
|
+
console.log("useEffect([error])")
|
|
243
256
|
console.log(error)
|
|
244
257
|
},[error])
|
|
245
258
|
|
|
@@ -269,6 +282,8 @@ function signalStrengthIcon(sensor){
|
|
|
269
282
|
|
|
270
283
|
}
|
|
271
284
|
useEffect(()=>{
|
|
285
|
+
console.log("useEffect([sensorMap])")
|
|
286
|
+
|
|
272
287
|
_sensorMap = sensorMap
|
|
273
288
|
|
|
274
289
|
setSensorList(
|
|
@@ -289,7 +304,7 @@ useEffect(()=>{
|
|
|
289
304
|
}
|
|
290
305
|
}>
|
|
291
306
|
<div class="d-flex justify-content-between align-items-center" style={hasConfig?{fontWeight:"normal"}:{fontStyle:"italic"}}>
|
|
292
|
-
{`${sensor.info.name} MAC: ${sensor.info.mac} RSSI: ${ifNullNaN(sensor.info.RSSI)}` }
|
|
307
|
+
{`${sensor._changesMade?"*":""}${sensor.info.name} MAC: ${sensor.info.mac} RSSI: ${ifNullNaN(sensor.info.RSSI)}` }
|
|
293
308
|
<div class="d-flex justify-content-between ">
|
|
294
309
|
{
|
|
295
310
|
signalStrengthIcon(sensor)
|
|
@@ -329,7 +344,8 @@ useEffect(()=>{
|
|
|
329
344
|
now={progress.progress}
|
|
330
345
|
/>:""
|
|
331
346
|
}
|
|
332
|
-
<h2>{`${sensorMap.size>0?"
|
|
347
|
+
<h2>{`${sensorMap.size>0?"Bluetooth Devices click to configure" :""}`}</h2>
|
|
348
|
+
<h2>{`${sensorMap.size>0?"(* means sensor has unsaved changes)" :""}`}</h2>
|
|
333
349
|
<p></p>
|
|
334
350
|
<div style={{paddingBottom: 20}} class="d-flex flex-wrap justify-content-start align-items-start">
|
|
335
351
|
<ListGroup style={{ maxHeight: '300px', overflowY: 'auto' }}>
|
|
@@ -340,7 +356,14 @@ useEffect(()=>{
|
|
|
340
356
|
schema={schema}
|
|
341
357
|
validator={validator}
|
|
342
358
|
uiSchema={uiSchema}
|
|
343
|
-
onChange={(e) =>
|
|
359
|
+
onChange={(e) => {
|
|
360
|
+
const s = sensorMap.get(e.formData.mac_address)
|
|
361
|
+
s._changesMade=true
|
|
362
|
+
//s.config = e.formData;
|
|
363
|
+
|
|
364
|
+
setSensorData(e.formData)
|
|
365
|
+
}
|
|
366
|
+
}
|
|
344
367
|
onSubmit={({ formData }, e) => {
|
|
345
368
|
console.log(formData)
|
|
346
369
|
updateSensorData(formData)
|