bt-sensors-plugin-sk 1.2.5 → 1.2.6-beta-1
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/settings.json +2 -0
- package/BTSensor.js +77 -38
- package/DistanceManager.js +249 -0
- package/Mixin.js +19 -0
- package/OutOfRangeDevice.js +46 -0
- package/README.md +26 -6
- package/classLoader.js +13 -8
- package/connectUUID.exp +26 -0
- package/development/FakeBTDevice.js +57 -0
- package/development/package.json +5 -0
- package/diff.txt +2860 -0
- package/index.js +58 -12
- package/package.json +8 -6
- package/public/698.js +14 -0
- package/public/847.js +1 -1
- package/public/images/ATC.jpeg +0 -0
- package/public/images/Aranet4.webp +0 -0
- package/public/images/BP108B.webp +0 -0
- package/public/images/GoveeH5074.jpg +0 -0
- package/public/images/GoveeH5075.webp +0 -0
- package/public/images/GoveeH510x.jpg +0 -0
- package/public/images/InkbirdTH3.webp +0 -0
- package/public/images/JBDBMS.webp +0 -0
- package/public/images/Junctek.webp +0 -0
- package/public/images/KilovaultHLXPlus.jpg +0 -0
- package/public/images/LancolVoltageMeter.webp +0 -0
- package/public/images/LiTimeLiFePo4Battery.avif +0 -0
- package/public/images/MercurySmartcraft.jpg +0 -0
- package/public/images/MopekaTankSensor.jpg +0 -0
- package/public/images/RemoranWave3.jpeg +0 -0
- package/public/images/RenogyInverter.jpg +0 -0
- package/public/images/RenogyRoverClient.jpg +0 -0
- package/public/images/RenogySmartLiFePo4Battery.webp +0 -0
- package/public/images/RuuviTag.jpg +0 -0
- package/public/images/ShellyBLUHT.webp +0 -0
- package/public/images/ShellyBLUMotion.webp +0 -0
- package/public/images/ShellyBluDoorWindow.webp +0 -0
- package/public/images/Skanbatt.jpg +0 -0
- package/public/images/SmartBatteryProtect.webp +0 -0
- package/public/images/SmartBatterySense.webp +0 -0
- package/public/images/SwitchBotMeterPlus.webp +0 -0
- package/public/images/SwitchBotTH.webp +0 -0
- package/public/images/TopbandBattery.webp +0 -0
- package/public/images/Ultrasonic.jpg +0 -0
- package/public/images/VictronBlueSmartACCharger.jpg +0 -0
- package/public/images/VictronBlueSolarMPPT.jpeg +0 -0
- package/public/images/VictronCerboGX.webp +0 -0
- package/public/images/VictronInverterRS.webp +0 -0
- package/public/images/VictronLynxSmartBMS.webp +0 -0
- package/public/images/VictronMultiPlus-II.webp +0 -0
- package/public/images/VictronOrionTrIsolated.webp +0 -0
- package/public/images/VictronOrionTrNonIsolated.webp +0 -0
- package/public/images/VictronPhoenixInverter.webp +0 -0
- package/public/images/VictronPhoenixSmart1600.webp +0 -0
- package/public/images/VictronSmartBatteryProtect.jpg +0 -0
- package/public/images/VictronSmartIP43.webp +0 -0
- package/public/images/VictronSmartLithiumBattery.jpg +0 -0
- package/public/images/VictronSmartSolarMPPT.webp +0 -0
- package/public/images/VictronVEBus.webp +0 -0
- package/public/images/eco-worthy.webp +0 -0
- package/public/images/iBeacon.jpg +0 -0
- package/public/remoteEntry.js +1 -1
- package/readUUID.exp +23 -0
- package/sensor_classes/ATC.js +3 -2
- package/sensor_classes/Aranet2.js +3 -1
- package/sensor_classes/Aranet4.js +1 -2
- package/sensor_classes/BankManager.js +1 -1
- package/sensor_classes/Beacon/AbstractBeaconMixin.js +85 -0
- package/sensor_classes/Beacon/Eddystone.js +77 -0
- package/sensor_classes/Beacon/iBeacon.js +58 -0
- package/sensor_classes/EcoWorthy.js +160 -0
- package/sensor_classes/EctiveBMS.js +269 -0
- package/sensor_classes/FeasyComBeacon.js +68 -0
- package/sensor_classes/GobiusCTankMeter.js +4 -3
- package/sensor_classes/GoveeH5074.js +2 -0
- package/sensor_classes/GoveeH5075.js +2 -0
- package/sensor_classes/GoveeH510x.js +1 -0
- package/sensor_classes/Inkbird.js +1 -0
- package/sensor_classes/JBDBMS.js +1 -0
- package/sensor_classes/Junctek.js +14 -6
- package/sensor_classes/KilovaultHLXPlus.js +1 -0
- package/sensor_classes/LancolVoltageMeter.js +2 -0
- package/sensor_classes/MercurySmartcraft.js +1 -0
- package/sensor_classes/MopekaTankSensor.js +7 -204
- package/sensor_classes/RemoranWave3.js +2 -0
- package/sensor_classes/Renogy/RenogySensor.js +1 -0
- package/sensor_classes/RenogyBattery.js +3 -4
- package/sensor_classes/RenogyInverter.js +3 -6
- package/sensor_classes/RenogyRoverClient.js +3 -0
- package/sensor_classes/RuuviTag.js +11 -8
- package/sensor_classes/ShellySBDW002C.js +3 -1
- package/sensor_classes/ShellySBHT003C.js +7 -0
- package/sensor_classes/ShellySBMO003Z.js +3 -2
- package/sensor_classes/ShenzhenLiOnBMS.js +4 -0
- package/sensor_classes/SwitchBotMeterPlus.js +1 -1
- package/sensor_classes/SwitchBotTH.js +2 -1
- package/sensor_classes/UNKNOWN.js +2 -1
- package/sensor_classes/UltrasonicWindMeter.js +3 -0
- package/sensor_classes/Victron/VictronConstants.js +2 -0
- package/sensor_classes/Victron/VictronIdentifier.js +24 -0
- package/sensor_classes/Victron/VictronSensor.js +59 -49
- package/sensor_classes/VictronACCharger.js +1 -6
- package/sensor_classes/VictronBatteryMonitor.js +39 -28
- package/sensor_classes/VictronDCDCConverter.js +1 -4
- package/sensor_classes/VictronDCEnergyMeter.js +1 -4
- package/sensor_classes/VictronGXDevice.js +1 -4
- package/sensor_classes/VictronInverter.js +2 -3
- package/sensor_classes/VictronInverterRS.js +2 -4
- package/sensor_classes/VictronLynxSmartBMS.js +1 -4
- package/sensor_classes/VictronOrionXS.js +1 -3
- package/sensor_classes/VictronSmartBatteryProtect.js +1 -4
- package/sensor_classes/VictronSmartLithium.js +1 -4
- package/sensor_classes/VictronSolarCharger.js +1 -3
- package/sensor_classes/VictronVEBus.js +1 -4
- package/sensor_classes/XiaomiMiBeacon.js +5 -2
- package/sensor_classes/iBeaconSensor.js +40 -0
- package/src/components/PluginConfigurationPanel.js +179 -184
- package/test.txt +805 -0
- package/public/681.js +0 -14
- package/sensor_classes/IBeacon.js +0 -45
- /package/public/{681.js.LICENSE.txt → 698.js.LICENSE.txt} +0 -0
- /package/public/images/{Aranet2_HOME_F_900x900_90OVA5J.original.webp → Aranet2.webp} +0 -0
- /package/public/images/{Bank Manager All-in-onewc.webp → BankManager.webp} +0 -0
- /package/public/images/{Gobius_C.png → GobiusCTankMeter.png} +0 -0
- /package/public/images/{Victron-SmartShunt.jpg → VictronSmartShunt.jpg} +0 -0
- /package/public/images/{smartsolarMPPT7515.png → VictronSmartSolarMPPT7515.png} +0 -0
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import Form from '@rjsf/core' ;
|
|
2
2
|
import validator from '@rjsf/validator-ajv8';
|
|
3
|
-
import React from "react";
|
|
4
3
|
import ReactHtmlParser from 'react-html-parser';
|
|
5
|
-
|
|
4
|
+
import React from 'react'
|
|
6
5
|
import {useEffect, useState} from 'react'
|
|
7
6
|
|
|
8
|
-
import {Button, Grid } from '@material-ui/core';
|
|
7
|
+
import {Button, Grid, Snackbar } from '@material-ui/core';
|
|
9
8
|
import { makeStyles } from '@material-ui/core/styles';
|
|
10
9
|
|
|
11
10
|
import { SignalCellular0Bar, SignalCellular1Bar, SignalCellular2Bar, SignalCellular3Bar, SignalCellular4Bar, SignalCellularConnectedNoInternet0Bar } from '@material-ui/icons';
|
|
@@ -20,13 +19,14 @@ import { ListGroupItem } from 'react-bootstrap';
|
|
|
20
19
|
|
|
21
20
|
import ProgressBar from 'react-bootstrap/ProgressBar';
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
export default function BTConfig (props) {
|
|
22
|
+
export function BTConfig (props) {
|
|
26
23
|
|
|
27
24
|
const _uiSchema= {
|
|
28
25
|
"ui:options": {label: false},
|
|
29
|
-
|
|
26
|
+
"paths":{
|
|
27
|
+
enableMarkdownInDescription:true
|
|
28
|
+
},
|
|
29
|
+
'title': { 'ui:widget': 'hidden' },
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
const baseUISchema =
|
|
@@ -71,10 +71,12 @@ const useStyles = makeStyles((theme) => ({
|
|
|
71
71
|
|
|
72
72
|
const [schema, setSchema] = useState({})
|
|
73
73
|
const [ uiSchema, setUISchema] = useState(_uiSchema )
|
|
74
|
-
const [sensorList, setSensorList] = useState([])
|
|
75
74
|
|
|
76
75
|
const [sensorData, setSensorData] = useState()
|
|
77
|
-
const [
|
|
76
|
+
const [sensorClassChanged, setSensorClassChanged] = useState(false)
|
|
77
|
+
|
|
78
|
+
const [enableSchema, setEnableSchema] = useState(true)
|
|
79
|
+
const [sensorMap, setSensorMap ] = useState(new Map())
|
|
78
80
|
|
|
79
81
|
const [progress, setProgress ] = useState({
|
|
80
82
|
"progress":0, "maxTimeout": 100,
|
|
@@ -84,13 +86,14 @@ const useStyles = makeStyles((theme) => ({
|
|
|
84
86
|
|
|
85
87
|
const [pluginState, setPluginState ] = useState("unknown")
|
|
86
88
|
const [error, setError ] = useState()
|
|
89
|
+
const [snackbarOpen, setSnackbarOpen] = useState(false)
|
|
90
|
+
const [snackbarMessage, setSnackbarMessage] = useState("")
|
|
87
91
|
const classes = useStyles();
|
|
88
92
|
|
|
93
|
+
|
|
89
94
|
|
|
90
95
|
function sendJSONData(cmd, data){
|
|
91
96
|
|
|
92
|
-
console.log(`sending ${cmd}`)
|
|
93
|
-
console.log(data)
|
|
94
97
|
const headers = new Headers();
|
|
95
98
|
headers.append("Content-Type", "application/json");
|
|
96
99
|
return fetch(`/plugins/bt-sensors-plugin-sk/${cmd}`, {
|
|
@@ -100,91 +103,85 @@ const useStyles = makeStyles((theme) => ({
|
|
|
100
103
|
headers:headers
|
|
101
104
|
})
|
|
102
105
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
106
|
+
async function fetchJSONData(path, data = {}) {
|
|
107
|
+
let result;
|
|
108
|
+
try {
|
|
109
|
+
// Convert data object to query string
|
|
110
|
+
const query = Object.keys(data).length
|
|
111
|
+
? '?' + new URLSearchParams(data).toString()
|
|
112
|
+
: '';
|
|
113
|
+
result = await fetch(`/plugins/bt-sensors-plugin-sk/${path}${query}`, {
|
|
114
|
+
credentials: 'include',
|
|
115
|
+
method: 'GET'
|
|
116
|
+
});
|
|
117
|
+
} catch (e) {
|
|
118
|
+
result = {
|
|
119
|
+
status: 500,
|
|
120
|
+
statusText: e.toString()
|
|
121
|
+
};
|
|
119
122
|
}
|
|
120
|
-
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
121
125
|
async function getSensors(){
|
|
122
|
-
console.log("getSensors")
|
|
123
126
|
const response = await fetchJSONData("getSensors")
|
|
124
127
|
if (response.status!=200){
|
|
125
128
|
throw new Error(`Unable get sensor data: ${response.statusText} (${response.status}) `)
|
|
126
129
|
}
|
|
127
130
|
const json = await response.json()
|
|
128
|
-
|
|
129
|
-
//for (let i=0;i<json.length;i++){
|
|
130
|
-
// json[i].schema.htmlDescription=<div>{ReactHtmlParser(json[i].schema.htmlDescription)}<p></p></div>
|
|
131
|
-
//}
|
|
131
|
+
|
|
132
132
|
return json
|
|
133
133
|
|
|
134
134
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
async function getSensorInfo(mac, sensorClass){
|
|
138
|
+
|
|
139
|
+
const response = await fetchJSONData("getSensorInfo",{mac_address: mac, class: sensorClass})
|
|
138
140
|
if (response.status!=200){
|
|
139
|
-
|
|
141
|
+
debugger
|
|
142
|
+
throw new Error(`Unable get sensor info: ${response.statusText} (${response.status}) `)
|
|
140
143
|
}
|
|
141
144
|
const json = await response.json()
|
|
142
|
-
console.log(json)
|
|
143
145
|
return json
|
|
144
|
-
|
|
145
146
|
}
|
|
147
|
+
|
|
146
148
|
async function getBaseData(){
|
|
147
|
-
console.log("getBaseData")
|
|
148
149
|
const response = await fetchJSONData("getBaseData")
|
|
149
150
|
if (response.status!=200){
|
|
150
151
|
throw new Error(`Unable to get base data: ${response.statusText} (${response.status}) `)
|
|
151
152
|
}
|
|
152
153
|
const json = await response.json()
|
|
153
|
-
console.log(json)
|
|
154
154
|
json.schema.htmlDescription=<div>{ReactHtmlParser(json.schema.htmlDescription)}<p></p></div>
|
|
155
155
|
return json
|
|
156
156
|
}
|
|
157
|
+
|
|
157
158
|
async function getProgress(){
|
|
158
|
-
console.log("getProgress")
|
|
159
159
|
const response = await fetchJSONData("getProgress")
|
|
160
160
|
if (response.status!=200){
|
|
161
161
|
throw new Error(`Unable to get progress: ${response.statusText} (${response.status}) `)
|
|
162
162
|
}
|
|
163
163
|
const json = await response.json()
|
|
164
|
-
console.log(json)
|
|
165
164
|
return json
|
|
166
165
|
}
|
|
167
166
|
|
|
168
167
|
function updateSensorData(data){
|
|
169
|
-
console.log("updateSensorData")
|
|
170
168
|
sendJSONData("updateSensorData", data).then((response)=>{
|
|
171
169
|
if (response.status != 200) {
|
|
172
170
|
throw new Error(response.statusText)
|
|
173
171
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
172
|
+
setSensorMap((sm)=>{sm.delete(data.mac_address); return new Map(sm) })
|
|
173
|
+
setSchema( {} )
|
|
174
|
+
|
|
177
175
|
})
|
|
178
176
|
}
|
|
179
177
|
|
|
180
178
|
function undoChanges(mac) {
|
|
181
|
-
console.log("undoChanges")
|
|
182
179
|
sensorMap.get(mac)._changesMade = false
|
|
180
|
+
sensorMap.get(mac).config = JSON.parse(JSON.stringify(sensorMap.get(mac).configCopy))
|
|
183
181
|
setSensorData( sensorMap.get(mac).config )
|
|
184
182
|
}
|
|
185
183
|
|
|
186
184
|
function removeSensorData(mac){
|
|
187
|
-
console.log("removeSensorData")
|
|
188
185
|
|
|
189
186
|
try{
|
|
190
187
|
|
|
@@ -193,131 +190,151 @@ const useStyles = makeStyles((theme) => ({
|
|
|
193
190
|
throw new Error(response.statusText)
|
|
194
191
|
}
|
|
195
192
|
})
|
|
196
|
-
|
|
197
|
-
_sensorMap.delete(mac)
|
|
198
|
-
|
|
199
|
-
setSensorMap(new Map(_sensorMap))
|
|
193
|
+
setSensorMap((sm)=>{sm.delete(mac); return new Map(sm) })
|
|
200
194
|
setSchema( {} )
|
|
201
195
|
} catch {(e)=>
|
|
202
|
-
setError(
|
|
196
|
+
setError( `Couldn't remove ${mac}: ${e}`)
|
|
203
197
|
}
|
|
204
198
|
|
|
205
199
|
}
|
|
206
200
|
|
|
207
201
|
|
|
208
202
|
function updateBaseData(data){
|
|
209
|
-
|
|
210
|
-
|
|
203
|
+
setSensorMap(new Map())
|
|
204
|
+
//setSensorList({})
|
|
211
205
|
sendJSONData("updateBaseData", data).then( (response )=>{
|
|
212
206
|
if (response.status != 200) {
|
|
213
|
-
setError(
|
|
214
|
-
}
|
|
215
|
-
getProgress().then((json)=>{
|
|
216
|
-
setProgress(json)
|
|
217
|
-
}).catch((e)=>{
|
|
218
|
-
setError(e)
|
|
219
|
-
})
|
|
220
|
-
}*/
|
|
207
|
+
setError(`Unable to update base data: ${response.statusText} (${response.status})`)
|
|
208
|
+
}
|
|
221
209
|
})
|
|
222
|
-
}
|
|
223
|
-
|
|
224
210
|
|
|
225
|
-
function refreshSensors(){
|
|
226
|
-
console.log('refreshing sensor map')
|
|
227
|
-
|
|
228
|
-
getSensors().then((sensors)=>{
|
|
229
|
-
setSensorMap (new Map(sensors.map((sensor)=>[sensor.info.mac,sensor])));
|
|
230
|
-
})
|
|
231
|
-
.catch((e)=>{
|
|
232
|
-
setError(e)
|
|
233
|
-
})
|
|
234
211
|
}
|
|
235
212
|
|
|
236
|
-
|
|
237
213
|
useEffect(()=>{
|
|
238
|
-
console.log("useEffect([])")
|
|
239
214
|
let eventSource=null
|
|
240
|
-
|
|
241
215
|
fetchJSONData("getPluginState").then( async (response)=> {
|
|
216
|
+
|
|
217
|
+
function newSensorEvent(event){
|
|
218
|
+
let json = JSON.parse(event.data)
|
|
219
|
+
console.log(`New sensor: ${json.info.mac}`)
|
|
220
|
+
setSensorMap( (_sm)=> {
|
|
221
|
+
//if (!_sm.has(json.info.mac))
|
|
222
|
+
_sm.set(json.info.mac, json)
|
|
223
|
+
|
|
224
|
+
return new Map(_sm)
|
|
225
|
+
}
|
|
226
|
+
)
|
|
227
|
+
}
|
|
228
|
+
function sensorChangedEvent(event){
|
|
229
|
+
console.log("sensorchanged")
|
|
230
|
+
const json = JSON.parse(event.data)
|
|
231
|
+
|
|
232
|
+
setSensorMap( (_sm) => {
|
|
233
|
+
const sensor = _sm.get(json.mac)
|
|
234
|
+
if (sensor)
|
|
235
|
+
Object.assign(sensor.info, json )
|
|
236
|
+
return new Map(_sm)
|
|
237
|
+
})
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
|
|
242
241
|
if (response.status==404) {
|
|
243
242
|
setPluginState("unknown")
|
|
244
243
|
throw new Error("unable to get plugin state")
|
|
245
244
|
}
|
|
246
245
|
const json = await response.json()
|
|
247
|
-
console.log("Setting up eventsource")
|
|
248
246
|
eventSource = new EventSource("/plugins/bt-sensors-plugin-sk/sse", { withCredentials: true })
|
|
249
247
|
|
|
250
|
-
setPluginState(json.state)
|
|
251
|
-
|
|
252
|
-
_sensorDomains = await getDomains()
|
|
253
|
-
|
|
254
248
|
eventSource.addEventListener("newsensor", (event) => {
|
|
255
|
-
|
|
256
|
-
let json = JSON.parse(event.data)
|
|
257
|
-
|
|
258
|
-
if (!_sensorMap.has(json.info.mac)) {
|
|
259
|
-
console.log(`New sensor: ${json.info.mac}`)
|
|
260
|
-
setSensorMap(new Map(_sensorMap.set(json.info.mac, json)))
|
|
261
|
-
}
|
|
249
|
+
newSensorEvent(event)
|
|
262
250
|
});
|
|
263
251
|
|
|
264
252
|
eventSource.addEventListener("sensorchanged", (event) => {
|
|
265
|
-
|
|
266
|
-
console.log("sensorchanged")
|
|
267
|
-
console.log(json)
|
|
268
|
-
|
|
269
|
-
if (_sensorMap.has(json.mac)) {
|
|
270
|
-
let sensor = _sensorMap.get(json.mac)
|
|
271
|
-
|
|
272
|
-
Object.assign(sensor.info, json )
|
|
273
|
-
setSensorMap(new Map ( _sensorMap ))
|
|
274
|
-
}
|
|
253
|
+
sensorChangedEvent(event)
|
|
275
254
|
});
|
|
255
|
+
|
|
276
256
|
eventSource.addEventListener("progress", (event) => {
|
|
277
|
-
console.log("progress")
|
|
278
257
|
const json = JSON.parse(event.data)
|
|
279
258
|
setProgress(json)
|
|
280
|
-
console.log(json)
|
|
281
259
|
});
|
|
282
260
|
|
|
283
261
|
eventSource.addEventListener("pluginstate", (event) => {
|
|
284
|
-
console.log("pluginstate")
|
|
285
262
|
const json = JSON.parse(event.data)
|
|
286
263
|
setPluginState(json.state)
|
|
287
264
|
});
|
|
288
|
-
|
|
289
|
-
|
|
265
|
+
|
|
266
|
+
setPluginState(json.state);
|
|
290
267
|
|
|
268
|
+
(async ()=>{
|
|
269
|
+
const sensors = await getSensors()
|
|
270
|
+
setSensorMap ( new Map(sensors.map((sensor)=>[sensor.info.mac,sensor])) )
|
|
271
|
+
})()
|
|
272
|
+
|
|
273
|
+
})
|
|
291
274
|
.catch( (e) => {
|
|
292
|
-
setError(e)
|
|
275
|
+
setError(e.message)
|
|
293
276
|
}
|
|
294
277
|
)
|
|
295
278
|
return () => {
|
|
296
279
|
console.log("Closing connection to SSE")
|
|
297
280
|
eventSource.close()
|
|
298
281
|
};
|
|
282
|
+
|
|
299
283
|
},[])
|
|
300
284
|
|
|
285
|
+
|
|
286
|
+
useEffect(()=>{
|
|
287
|
+
|
|
288
|
+
if (!sensorClassChanged) return
|
|
289
|
+
if (!(sensorData && sensorMap) ) return
|
|
290
|
+
|
|
291
|
+
const _sensor = sensorMap.get(sensorData.mac_address)
|
|
292
|
+
if (_sensor && schema && sensorData &&
|
|
293
|
+
Object.hasOwn(sensorData,"params" )){
|
|
294
|
+
if (_sensor.info.class == "UNKNOWN" && sensorData.params.sensorClass && sensorData.params.sensorClass != "UNKNOWN") {
|
|
295
|
+
setEnableSchema(false)
|
|
296
|
+
setSnackbarMessage(`Please wait. Fetching schema for ${sensorData.params.sensorClass}...`)
|
|
297
|
+
getSensorInfo(sensorData.mac_address, sensorData.params.sensorClass).then((json)=>{
|
|
298
|
+
setSchema(json.schema)
|
|
299
|
+
}).catch((e)=>{
|
|
300
|
+
alert(e.message)
|
|
301
|
+
})
|
|
302
|
+
.finally(()=>{
|
|
303
|
+
setSnackbarMessage("")
|
|
304
|
+
setEnableSchema(true)
|
|
305
|
+
setSensorClassChanged(false)
|
|
306
|
+
})
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
},[sensorClassChanged])
|
|
312
|
+
|
|
301
313
|
useEffect(()=>{
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
314
|
+
if (snackbarMessage=="")
|
|
315
|
+
setSnackbarOpen(false)
|
|
316
|
+
else {
|
|
317
|
+
setSnackbarOpen(true)
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
},[snackbarMessage])
|
|
321
|
+
|
|
322
|
+
useEffect(()=>{
|
|
323
|
+
if (pluginState=="started") {
|
|
306
324
|
getBaseData().then((json) => {
|
|
307
325
|
setBaseSchema(json.schema);
|
|
308
326
|
setBaseData(json.data);
|
|
309
327
|
}).catch((e)=>{
|
|
310
|
-
setError(e)
|
|
328
|
+
setError(e.message)
|
|
311
329
|
})
|
|
312
330
|
|
|
313
331
|
getProgress().then((json)=>{
|
|
314
332
|
setProgress(json)
|
|
315
333
|
}).catch((e)=>{
|
|
316
|
-
setError(e)
|
|
334
|
+
setError(e.message)
|
|
317
335
|
})
|
|
318
336
|
|
|
319
337
|
} else{
|
|
320
|
-
setSensorMap(new Map())
|
|
321
338
|
setBaseSchema({})
|
|
322
339
|
setBaseData({})
|
|
323
340
|
}
|
|
@@ -325,9 +342,10 @@ useEffect(()=>{
|
|
|
325
342
|
},[pluginState])
|
|
326
343
|
|
|
327
344
|
|
|
328
|
-
|
|
329
345
|
function confirmDelete(mac){
|
|
330
|
-
|
|
346
|
+
|
|
347
|
+
const sensor = sensorMap.get(mac)
|
|
348
|
+
const result = !hasConfig(sensor) || window.confirm(`Delete configuration for ${sensor.info.name}?`)
|
|
331
349
|
if (result)
|
|
332
350
|
removeSensorData(mac)
|
|
333
351
|
}
|
|
@@ -352,7 +370,7 @@ function signalStrengthIcon(sensor){
|
|
|
352
370
|
|
|
353
371
|
}
|
|
354
372
|
function hasConfig(sensor){
|
|
355
|
-
return Object.keys(sensor.
|
|
373
|
+
return Object.keys(sensor.configCopy).length>0;
|
|
356
374
|
}
|
|
357
375
|
|
|
358
376
|
function createListGroupItem(sensor){
|
|
@@ -376,66 +394,43 @@ function createListGroupItem(sensor){
|
|
|
376
394
|
</ListGroupItem>
|
|
377
395
|
}
|
|
378
396
|
|
|
379
|
-
function configuredDevices(){
|
|
380
|
-
return Array.from(sensorMap.entries()).filter((entry)=>hasConfig(entry[1]))
|
|
381
|
-
}
|
|
382
397
|
|
|
383
398
|
function devicesInDomain(domain){
|
|
384
|
-
|
|
385
|
-
return configuredDevices()
|
|
386
|
-
else
|
|
399
|
+
|
|
387
400
|
return Array.from(sensorMap.entries()).filter((entry)=>entry[1].info.domain===domain)
|
|
388
401
|
}
|
|
389
402
|
|
|
403
|
+
function ifNullNaN(value){
|
|
404
|
+
return value==null? NaN : value
|
|
405
|
+
}
|
|
390
406
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
const sl = {
|
|
398
|
-
_configured: configuredDevices().length==0?
|
|
407
|
+
function getTabs(){
|
|
408
|
+
const sensorDomains = [... (new Set(sensorMap.entries().map((entry)=>{ return entry[1].info.domain})))].sort()
|
|
409
|
+
const cd = Array.from(sensorMap.entries()).filter((entry)=>hasConfig(entry[1]))
|
|
410
|
+
let sensorList={}
|
|
411
|
+
sensorList["_configured"]=
|
|
412
|
+
cd.length==0?
|
|
399
413
|
"Select a device from its domain tab (Electrical etc.) and configure it.":
|
|
400
|
-
|
|
414
|
+
cd.map((entry) => {
|
|
401
415
|
return createListGroupItem(sensorMap.get(entry[0]))
|
|
402
416
|
})
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
sl[d]=devicesInDomain(d).map((entry) => {
|
|
417
|
+
|
|
418
|
+
sensorDomains.forEach((d)=>{
|
|
419
|
+
sensorList[d]=devicesInDomain(d).map((entry) => {
|
|
407
420
|
return createListGroupItem(sensorMap.get(entry[0]))
|
|
408
421
|
})
|
|
409
|
-
|
|
410
|
-
_sensorList=sl
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
},[sensorMap]
|
|
414
|
-
)
|
|
415
|
-
|
|
416
|
-
function ifNullNaN(value){
|
|
417
|
-
return value==null? NaN : value
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
function getSensorList(domain){
|
|
421
|
-
return _sensorList[domain]
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
function getTabs(){
|
|
422
|
+
})
|
|
425
423
|
|
|
426
|
-
return Object.keys(
|
|
424
|
+
return Object.keys(sensorList).map((domain)=> {return getTab(domain, sensorList[domain])})
|
|
427
425
|
}
|
|
428
|
-
// <div style={{paddingBottom: 20}} class="d-flex flex-wrap justify-content-start align-items-start">
|
|
429
|
-
// <div class="d-flex flex-column" >
|
|
430
426
|
|
|
431
|
-
function getTab(key){
|
|
432
|
-
|
|
433
|
-
let sl = getSensorList(key)
|
|
427
|
+
function getTab(key, sensorList){
|
|
428
|
+
let title = key.slice(key.charAt(0)==="_"?1:0)
|
|
434
429
|
|
|
435
|
-
return <Tab eventKey={key} title={`${title.charAt(0).toUpperCase()}${title.slice(1)}${
|
|
430
|
+
return <Tab eventKey={key} title={`${title.charAt(0).toUpperCase()}${title.slice(1)}${typeof sensorList=='string'?'':' ('+sensorList.length+')'}` } >
|
|
436
431
|
|
|
437
432
|
<ListGroup style={{ maxHeight: '300px', overflowY: 'auto' }}>
|
|
438
|
-
{
|
|
433
|
+
{sensorList}
|
|
439
434
|
</ListGroup>
|
|
440
435
|
|
|
441
436
|
|
|
@@ -447,22 +442,6 @@ useEffect(()=>{
|
|
|
447
442
|
window.open(url, "_blank", "noreferrer");
|
|
448
443
|
}
|
|
449
444
|
|
|
450
|
-
function CustomFieldTemplate(props) {
|
|
451
|
-
const { id, classNames, style, label, help, required, description, errors, children } = props;
|
|
452
|
-
return (
|
|
453
|
-
<div className={classNames} style={style}>
|
|
454
|
-
<Grid container xs={12} direction="row" spacing="1">
|
|
455
|
-
<Grid item xs={1} sm container direction="column">
|
|
456
|
-
<Grid item ><label htmlFor={id}>{label}{required ? '*' : null}</label></Grid>
|
|
457
|
-
<Grid item> {description}</Grid>
|
|
458
|
-
</Grid>
|
|
459
|
-
<Grid item>{children}</Grid>
|
|
460
|
-
</Grid>
|
|
461
|
-
{errors}
|
|
462
|
-
{help}
|
|
463
|
-
</div>
|
|
464
|
-
);
|
|
465
|
-
}
|
|
466
445
|
|
|
467
446
|
if (pluginState=="stopped" || pluginState=="unknown")
|
|
468
447
|
return (<h3>Enable plugin to see configuration</h3>)
|
|
@@ -470,6 +449,14 @@ useEffect(()=>{
|
|
|
470
449
|
return(
|
|
471
450
|
|
|
472
451
|
<div>
|
|
452
|
+
|
|
453
|
+
<Snackbar
|
|
454
|
+
anchorOrigin={{ horizontal: 'center', vertical: 'bottom' }}
|
|
455
|
+
onClose={() => setSnackbarOpen(false)}
|
|
456
|
+
open={snackbarOpen}
|
|
457
|
+
message={snackbarMessage}
|
|
458
|
+
key={"snackbar"}
|
|
459
|
+
/>
|
|
473
460
|
<div className={classes.root}>
|
|
474
461
|
|
|
475
462
|
<Button variant="contained" onClick={()=>{openInNewTab("https://github.com/naugehyde/bt-sensors-plugin-sk/tree/1.2.0-beta#configuration")}}>Documentation</Button>
|
|
@@ -480,7 +467,7 @@ useEffect(()=>{
|
|
|
480
467
|
</div>
|
|
481
468
|
<hr style={{"width":"100%","height":"1px","color":"gray","background-color":"gray","text-align":"left","margin-left":0}}></hr>
|
|
482
469
|
|
|
483
|
-
{error?<h2 style=
|
|
470
|
+
{error?<h2 style={{color: 'red'}}>{error}</h2>:""}
|
|
484
471
|
<Form
|
|
485
472
|
schema={baseSchema}
|
|
486
473
|
validator={validator}
|
|
@@ -504,7 +491,7 @@ useEffect(()=>{
|
|
|
504
491
|
defaultActiveKey="_configured"
|
|
505
492
|
id="domain-tabs"
|
|
506
493
|
className="mb-3"
|
|
507
|
-
|
|
494
|
+
|
|
508
495
|
>
|
|
509
496
|
{getTabs()}
|
|
510
497
|
</Tabs>
|
|
@@ -513,20 +500,27 @@ useEffect(()=>{
|
|
|
513
500
|
<Grid item><h2>{schema?.title}</h2><p></p></Grid>
|
|
514
501
|
<Grid item>{ReactHtmlParser(schema?.htmlDescription)}</Grid>
|
|
515
502
|
</Grid>
|
|
516
|
-
|
|
503
|
+
<fieldset disabled={!enableSchema}>
|
|
517
504
|
<Form
|
|
518
505
|
schema={schema}
|
|
519
506
|
validator={validator}
|
|
520
507
|
uiSchema={uiSchema}
|
|
521
|
-
onChange={(e) => {
|
|
508
|
+
onChange={(e,id) => {
|
|
522
509
|
const s = sensorMap.get(e.formData.mac_address)
|
|
523
|
-
s
|
|
524
|
-
|
|
510
|
+
if(s) {
|
|
511
|
+
s._changesMade=true
|
|
512
|
+
s.config = e.formData
|
|
513
|
+
setSensorData(e.formData)
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
if (id=="root_params_sensorClass") {
|
|
517
|
+
setSensorClassChanged(true)
|
|
518
|
+
}
|
|
519
|
+
|
|
525
520
|
}
|
|
526
521
|
}
|
|
527
522
|
onSubmit={({ formData }, e) => {
|
|
528
523
|
updateSensorData(formData)
|
|
529
|
-
setSchema({})
|
|
530
524
|
alert("Changes saved")
|
|
531
525
|
}}
|
|
532
526
|
onError={log('errors')}
|
|
@@ -537,11 +531,12 @@ useEffect(()=>{
|
|
|
537
531
|
<Button variant="contained" color="secondary" onClick={(e)=>confirmDelete(sensorData.mac_address)}>Delete</Button>
|
|
538
532
|
</div>
|
|
539
533
|
</Form>
|
|
540
|
-
|
|
534
|
+
</fieldset>
|
|
541
535
|
|
|
542
536
|
</div>
|
|
543
537
|
</div>
|
|
544
538
|
)
|
|
545
539
|
|
|
546
540
|
|
|
547
|
-
}
|
|
541
|
+
}
|
|
542
|
+
export default BTConfig
|