bt-sensors-plugin-sk 1.2.0-beta.0.0.6 → 1.2.0-beta.0.0.8
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 +2 -2
- package/README.md +26 -12
- package/index.js +8 -6
- package/package.json +1 -1
- package/plugin_defaults.json +5 -4
- package/public/893.js +1 -1
- package/sensor_classes/ATC.js +2 -0
- package/sensor_classes/Aranet4.js +1 -1
- package/sensor_classes/GoveeH50xx.js +2 -0
- package/sensor_classes/GoveeH510x.js +2 -0
- package/sensor_classes/Inkbird.js +2 -0
- package/sensor_classes/RuuviTag.js +2 -1
- package/sensor_classes/ShellySBHT003C.js +2 -0
- package/sensor_classes/SwitchBotMeterPlus.js +2 -0
- package/sensor_classes/SwitchBotTH.js +2 -0
- package/sensor_classes/VictronSmartBatteryProtect.js +1 -0
- package/sensor_classes/XiaomiMiBeacon.js +2 -0
- package/src/components/PluginConfigurationPanel.js +14 -6
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,10 +317,11 @@ 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
|
|
|
324
|
-
this.addDefaultParam("location")
|
|
324
|
+
//this.addDefaultParam("location")
|
|
325
325
|
|
|
326
326
|
//create the 'RSSI' parameter
|
|
327
327
|
this.addDefaultPath("RSSI","sensors.RSSI")
|
package/README.md
CHANGED
|
@@ -1,8 +1,27 @@
|
|
|
1
1
|
# Bluetooth Sensors for [Signal K](http://www.signalk.org)
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## What's New
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## 1.2.0-beta-0.0.8
|
|
6
|
+
|
|
7
|
+
Improved handling of changed state on config page.
|
|
8
|
+
|
|
9
|
+
Several small fixes to various sensor classes.
|
|
10
|
+
|
|
11
|
+
## 1.2.0-beta-0.0.7
|
|
12
|
+
|
|
13
|
+
Added zone config param for environmental sensors. Removed location parameter.
|
|
14
|
+
|
|
15
|
+
## 1.2.0-beta-0.0.6
|
|
16
|
+
Default values for paths for most sensor classes.
|
|
17
|
+
|
|
18
|
+
## 1.2.0-beta-0.0.5
|
|
19
|
+
|
|
20
|
+
Added workaround to support multiple simultaneous GATT connections. Owing to problematic behavior in Bluez where making a GATT connection halted the scanner which made additional updates and connections impossible, added a scanner restart after making each GATT connection.
|
|
21
|
+
|
|
22
|
+
## 1.2.0-beta-0.0.1
|
|
23
|
+
|
|
24
|
+
Dynamic configuration added. List updates when new devices are found by scanner. (No more screen refreshing necessary).
|
|
6
25
|
|
|
7
26
|
## WHAT IT IS
|
|
8
27
|
|
|
@@ -33,13 +52,13 @@ Signalk users with a Linux boat-puter (Windows and MacOS are NOT currently suppo
|
|
|
33
52
|
NOTE: If you're running the 1.0.3 release, you will have to reconfigure your devices.<br>
|
|
34
53
|
|
|
35
54
|
### Signalk Appstore
|
|
36
|
-
The plugin is currently available in the Signalk Appstore. <br>
|
|
55
|
+
The beta plugin is not currently available in the Signalk Appstore. <br>
|
|
37
56
|
|
|
38
57
|
### NPM
|
|
39
58
|
|
|
40
59
|
Go to you signalk home (usually ~/.signalk) and run:
|
|
41
60
|
|
|
42
|
-
npm i bt-sensors-plugin-sk@1.
|
|
61
|
+
npm i bt-sensors-plugin-sk@1.2.0-beta.0.0.7
|
|
43
62
|
|
|
44
63
|
### Linux
|
|
45
64
|
|
|
@@ -48,7 +67,7 @@ If you want to install directly from source (this is mostly of interest to custo
|
|
|
48
67
|
<pre> cd ~/[some_dir]
|
|
49
68
|
git clone https://github.com/naugehyde/bt-sensors-plugin-sk
|
|
50
69
|
cd bt-sensors-plugin-sk
|
|
51
|
-
git switch '1.
|
|
70
|
+
git switch '1.2.0-beta'
|
|
52
71
|
git pull
|
|
53
72
|
npm i
|
|
54
73
|
[sudo] npm link
|
|
@@ -68,16 +87,11 @@ After installing and restarting Signalk you should see a "BT Sensors Plugin" opt
|
|
|
68
87
|
|
|
69
88
|
On initial configuration, wait for your Bluetooth adapter to scan devices. The plugin will scan for new devices at whatever you set the "scan for new devices interval" value to. <br><br>
|
|
70
89
|
|
|
71
|
-
> TIP: Close and re-open the config screen to refresh the screen. The config screen isn't as <i>reactive</i> as it oughtta be.<br><br>
|
|
72
|
-
|
|
73
|
-
Then press the + button to add a sensor. Your screen should look something like this:<br><br>
|
|
74
|
-
<img width="1122" alt="Screenshot 2024-10-13 at 6 52 52 PM" src="https://github.com/user-attachments/assets/0487b8d0-4bc0-4358-85c6-a507bc3c97d2">
|
|
75
|
-
|
|
76
90
|
<br><br>
|
|
77
91
|
|
|
78
|
-
Select the sensor you want Signalk to listen to from the
|
|
92
|
+
Select the sensor you want Signalk to listen to from the list.<br>
|
|
79
93
|
|
|
80
|
-
If you don't see your device and you know that it's on and nearby to the server, it may not be currently supported. But fear not, you can add custom sensor classes yourself. (Check out [the development section](#development).). <br><br>
|
|
94
|
+
If you don't see your device and you know that it's on and nearby to the server, it may not be currently supported (It could also be out of range.) But fear not, you can add custom sensor classes yourself. (Check out [the development section](#development).). <br><br>
|
|
81
95
|
|
|
82
96
|
Now it's a simple matter of associating the data emitted by the sensor with the Signalk path you want it to update. (Also, you can name your sensor so when it appears in logs its easy to recognize.) <br><br>
|
|
83
97
|
|
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)=>{
|
|
@@ -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,13 @@ module.exports = function (app) {
|
|
|
400
397
|
reject ( `Device is blacklisted (${s.reasonForBlacklisting()}).`)
|
|
401
398
|
else{
|
|
402
399
|
addSensorToList(s)
|
|
400
|
+
let _lastRSSI=-1*Infinity
|
|
403
401
|
s.on("RSSI",(()=>{
|
|
404
|
-
|
|
402
|
+
if (Date.now()-_lastRSSI > 5000) { //only update RSSI on client every five seconds
|
|
403
|
+
_lastRSSI=Date.now()
|
|
404
|
+
updateSensor(s)
|
|
405
|
+
}
|
|
406
|
+
|
|
405
407
|
}))
|
|
406
408
|
resolve(s)
|
|
407
409
|
}
|
|
@@ -443,7 +445,7 @@ module.exports = function (app) {
|
|
|
443
445
|
app.setPluginError(msg)
|
|
444
446
|
}
|
|
445
447
|
//if we're here ain't got no class for the device
|
|
446
|
-
var sensor
|
|
448
|
+
var sensor
|
|
447
449
|
if (config.params?.sensorClass){
|
|
448
450
|
var c = classMap.get(config.params.sensorClass)
|
|
449
451
|
} else{
|
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.8",
|
|
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:()=>
|
|
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:()=>S});var a=n(3490),s=n(4810),o=n(4147),r=n.n(o),c=n(7606),l=n(4952),i=n(3768),u=n(1431),d=n(9676),m=n(7041),g=n(3657),f=n(5027),h=n(7265),p=n(6890),E=n(8207);const w=e=>console.log.bind(console,e);var v;const S=e=>{const[t,n]=(0,o.useState)({}),[S,b]=(0,o.useState)({}),[y,A]=(0,o.useState)({}),[$,D]=(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,j]=(0,o.useState)(new Map),[M,O]=(0,o.useState)({progress:0,maxTimeout:100,deviceCount:0,totalDevices:0}),[N,J]=(0,o.useState)("unknown"),[L,U]=(0,o.useState)();function B(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 z(e){return console.log(`fetching ${e}`),fetch(`/plugins/bt-sensors-plugin-sk/${e}`,{credentials:"include"})}async function H(){const e=await z("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 I(){console.log("refreshing sensor map"),async function(){const e=await z("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=>{j(new Map(e.map((e=>[e.info.mac,e]))))})).catch((e=>{U(e)}))}return(0,o.useEffect)((()=>{z("sendPluginState").then((async e=>{const t=await e.json();J(t.state),console.log("Setting up eventsource");const n=new EventSource("/plugins/bt-sensors-plugin-sk/sse");return n.addEventListener("newsensor",(e=>{let t=JSON.parse(e.data);v.has(t.info.mac)||(console.log(`New sensor: ${t.info.mac}`),j(new Map(v.set(t.info.mac,t))))})),n.addEventListener("sensorchanged",(e=>{let t=JSON.parse(e.data);if(v.has(t.mac)){let e=v.get(t.mac);Object.assign(e.info,t),j(new Map(v))}})),n.addEventListener("progress",(e=>{const t=JSON.parse(e.data);O(t),console.log(t)})),n.addEventListener("pluginstate",(e=>{const t=JSON.parse(e.data);J(t.state)})),()=>n.close()})).catch((e=>{U(e)}))}),[]),(0,o.useEffect)((()=>{"started"==N?(I(),async function(){const e=await z("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=>{U(e)})),H().then((e=>{O(e)})).catch((e=>{U(e)}))):(j(new Map),n({}),b({}))}),[N]),(0,o.useEffect)((()=>{console.log(L)}),[L]),(0,o.useEffect)((()=>{v=T,k(Array.from(T.entries()).map((e=>{const t=T.get(e[0]),n=t.config,a=Object.keys(n).length>0;return r().createElement(p.A,{action:!0,onClick:()=>{t&&(n.mac_address=e[0],A(t.schema),C(n))}},r().createElement("div",{class:"d-flex justify-content-between align-items-center",style:a?{fontWeight:"normal"}:{fontStyle:"italic"}},`${t._changesMade?"*":""}${t.info.name} MAC: ${t.info.mac} RSSI: ${s=t.info.RSSI,null==s?NaN:s}`,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(d.A,null):e.info.signalStrength>40?r().createElement(m.A,null):e.info.signalStrength>20?r().createElement(g.A,null):r().createElement(f.A,null)}(t))));var s})))}),[T]),"stopped"==N?r().createElement("h1",null,"Enable plugin to see configuration"):r().createElement("div",null,L?r().createElement("h2",{style:"color: red;"},L.message):"",r().createElement(a.Ay,{schema:t,validator:s.Ay,onChange:e=>b(e.formData),onSubmit:({formData:e},t)=>{C(null),B("sendBaseData",e).then((e=>{200!=e.status?U(new Error(`Unable to update base data: ${e.statusText} (${e.status})`)):(H().then((e=>{O(e)})).catch((e=>{U(e)})),I())}))},onError:w("errors"),formData:S}),r().createElement("p",null),r().createElement("p",null),M.deviceCount<M.totalDevices?r().createElement(E.A,{max:M.maxTimeout,now:M.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(h.A,{style:{maxHeight:"300px",overflowY:"auto"}},_),r().createElement("div",{style:{paddingLeft:10,paddingTop:10,display:0==Object.keys(y).length?"none":""}},r().createElement(a.Ay,{schema:y,validator:s.Ay,uiSchema:$,onChange:e=>{T.get(e.formData.mac_address)._changesMade=!0,C(e.formData)},onSubmit:({formData:e},t)=>{var n;console.log(e),B("sendSensorData",n=e).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})),A({}),alert("Changes saved")},onError:w("errors"),formData:x},r().createElement("div",null,r().createElement(c.A,{direction:"row",style:{spacing:5}},r().createElement(l.A,{type:"submit",color:"primary",variant:"contained"},"Save"),r().createElement(l.A,{variant:"contained",onClick:()=>{var e;e=x.mac_address,T.get(e)._changesMade=!1,C(T.get(e).config)}},"Undo"),r().createElement(l.A,{variant:"contained",color:"secondary",onClick:e=>{return t=x.mac_address,void(window.confirm(`Delete configuration for ${t}?`)&&function(e){try{B("removeSensorData",{mac_address:e}).then((e=>{if(200!=e.status)throw new Error(e.statusText)})),v.delete(e),j(new Map(v)),A({})}catch{}}(t));var t}},"Delete")))))))}}}]);
|
package/sensor_classes/ATC.js
CHANGED
|
@@ -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)',
|
|
@@ -36,6 +36,8 @@ class GoveeH510x extends BTSensor{
|
|
|
36
36
|
|
|
37
37
|
initSchema(){
|
|
38
38
|
super.initSchema()
|
|
39
|
+
this.addDefaultParam("zone")
|
|
40
|
+
|
|
39
41
|
this.addDefaultPath("temp","environment.temperature")
|
|
40
42
|
this.addDefaultPath("humidity", "environment.humidity")
|
|
41
43
|
this.addDefaultPath("battery","sensors.batteryStrength")
|
|
@@ -15,6 +15,8 @@ class Inkbird extends BTSensor{
|
|
|
15
15
|
|
|
16
16
|
initSchema() {
|
|
17
17
|
super.initSchema()
|
|
18
|
+
this.addDefaultParam("zone")
|
|
19
|
+
|
|
18
20
|
this.addDefaultPath('temp','environment.temperature')
|
|
19
21
|
this.addDefaultPath('battery', 'sensors.batteryStrength')
|
|
20
22
|
if (this.getName() == 'sps'){
|
|
@@ -10,13 +10,14 @@ class RuuviTag extends BTSensor{
|
|
|
10
10
|
|
|
11
11
|
initSchema(){
|
|
12
12
|
super.initSchema()
|
|
13
|
+
this.addDefaultParam("zone")
|
|
14
|
+
|
|
13
15
|
const md = this.valueIfVariant(this.getManufacturerData(this.constructor.manufacturerID))
|
|
14
16
|
this.mode = md[0]
|
|
15
17
|
if (this['_initModeV'+this.mode])
|
|
16
18
|
this['_initModeV'+this.mode]()
|
|
17
19
|
else
|
|
18
20
|
throw new Error("Unrecognized Ruuvitag data mode "+md[0])
|
|
19
|
-
this.addDefaultParam("zone")
|
|
20
21
|
|
|
21
22
|
}
|
|
22
23
|
|
|
@@ -37,6 +37,8 @@ class SwitchBotMeterPlus extends BTSensor{
|
|
|
37
37
|
// Refer https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/meter.md#(new)-broadcast-message
|
|
38
38
|
|
|
39
39
|
super.initSchema()
|
|
40
|
+
this.addDefaultParam("zone")
|
|
41
|
+
|
|
40
42
|
this.addDefaultPath('temp', 'environment.temperature')
|
|
41
43
|
.read= (buffer)=>{return (( ( ( (buffer[4] & 0x7f) + ((buffer[3] & 0x0f)/10) ) * ( (buffer[4] & 0x80)>0 ? 1 : -1 ) ) - ( (buffer[5] & 0x80)>0 ? 32 : 0) ) / ( (buffer[5] & 0x80)>0 ? 1.8 : 1) ) + 273.15 }
|
|
42
44
|
this.addDefaultPath('humidity', 'environment.humidity')
|
|
@@ -39,6 +39,8 @@ class SwitchBotTH extends BTSensor {
|
|
|
39
39
|
|
|
40
40
|
initSchema(){
|
|
41
41
|
super.initSchema()
|
|
42
|
+
this.addDefaultParam("zone")
|
|
43
|
+
|
|
42
44
|
this.addDefaultPath('temp', 'environment.temperature')
|
|
43
45
|
.read=(buffer)=>{
|
|
44
46
|
return (27315+(((buffer[8] & 0x0F)/10 + (buffer[9] & 0x7F)) * (((buffer[9] & 0x80)>0)?100:-100)))/100
|
|
@@ -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
|
|
|
@@ -111,13 +110,14 @@ export default (props) => {
|
|
|
111
110
|
if (response.status != 200) {
|
|
112
111
|
throw new Error(response.statusText)
|
|
113
112
|
}
|
|
114
|
-
|
|
113
|
+
sensorMap.get(data.mac_address)._changesMade=false
|
|
115
114
|
sensorMap.get(data.mac_address).config = data
|
|
116
115
|
|
|
117
116
|
})
|
|
118
117
|
}
|
|
119
118
|
|
|
120
119
|
function undoChanges(mac) {
|
|
120
|
+
sensorMap.get(mac)._changesMade = false
|
|
121
121
|
setSensorData( sensorMap.get(mac).config )
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -289,7 +289,7 @@ useEffect(()=>{
|
|
|
289
289
|
}
|
|
290
290
|
}>
|
|
291
291
|
<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)}` }
|
|
292
|
+
{`${sensor._changesMade?"*":""}${sensor.info.name} MAC: ${sensor.info.mac} RSSI: ${ifNullNaN(sensor.info.RSSI)}` }
|
|
293
293
|
<div class="d-flex justify-content-between ">
|
|
294
294
|
{
|
|
295
295
|
signalStrengthIcon(sensor)
|
|
@@ -329,7 +329,8 @@ useEffect(()=>{
|
|
|
329
329
|
now={progress.progress}
|
|
330
330
|
/>:""
|
|
331
331
|
}
|
|
332
|
-
<h2>{`${sensorMap.size>0?"
|
|
332
|
+
<h2>{`${sensorMap.size>0?"Bluetooth Devices click to configure" :""}`}</h2>
|
|
333
|
+
<h2>{`${sensorMap.size>0?"(* means sensor has unsaved changes)" :""}`}</h2>
|
|
333
334
|
<p></p>
|
|
334
335
|
<div style={{paddingBottom: 20}} class="d-flex flex-wrap justify-content-start align-items-start">
|
|
335
336
|
<ListGroup style={{ maxHeight: '300px', overflowY: 'auto' }}>
|
|
@@ -340,7 +341,14 @@ useEffect(()=>{
|
|
|
340
341
|
schema={schema}
|
|
341
342
|
validator={validator}
|
|
342
343
|
uiSchema={uiSchema}
|
|
343
|
-
onChange={(e) =>
|
|
344
|
+
onChange={(e) => {
|
|
345
|
+
const s = sensorMap.get(e.formData.mac_address)
|
|
346
|
+
s._changesMade=true
|
|
347
|
+
//s.config = e.formData;
|
|
348
|
+
|
|
349
|
+
setSensorData(e.formData)
|
|
350
|
+
}
|
|
351
|
+
}
|
|
344
352
|
onSubmit={({ formData }, e) => {
|
|
345
353
|
console.log(formData)
|
|
346
354
|
updateSensorData(formData)
|