bt-sensors-plugin-sk 1.2.4-4 → 1.2.5-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.
@@ -1,8 +1,7 @@
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
7
  import {Button, Grid } from '@material-ui/core';
@@ -20,9 +19,7 @@ import { ListGroupItem } from 'react-bootstrap';
20
19
 
21
20
  import ProgressBar from 'react-bootstrap/ProgressBar';
22
21
 
23
- var _sensorMap, _sensorDomains={}, _sensorList={}
24
-
25
- export default function BTConfig (props) {
22
+ export function BTConfig (props) {
26
23
 
27
24
  const _uiSchema= {
28
25
  "ui:options": {label: false},
@@ -71,10 +68,9 @@ const useStyles = makeStyles((theme) => ({
71
68
 
72
69
  const [schema, setSchema] = useState({})
73
70
  const [ uiSchema, setUISchema] = useState(_uiSchema )
74
- const [sensorList, setSensorList] = useState([])
75
71
 
76
72
  const [sensorData, setSensorData] = useState()
77
- const [sensorMap, setSensorMap ] = useState(new Map() )
73
+ const [sensorMap, setSensorMap ] = useState(new Map())
78
74
 
79
75
  const [progress, setProgress ] = useState({
80
76
  "progress":0, "maxTimeout": 100,
@@ -89,8 +85,6 @@ const useStyles = makeStyles((theme) => ({
89
85
 
90
86
  function sendJSONData(cmd, data){
91
87
 
92
- console.log(`sending ${cmd}`)
93
- console.log(data)
94
88
  const headers = new Headers();
95
89
  headers.append("Content-Type", "application/json");
96
90
  return fetch(`/plugins/bt-sensors-plugin-sk/${cmd}`, {
@@ -102,7 +96,6 @@ const useStyles = makeStyles((theme) => ({
102
96
  }
103
97
 
104
98
  async function fetchJSONData(path){
105
- console.log(`fetching ${path}`)
106
99
  var result
107
100
  try {
108
101
  result = fetch(`/plugins/bt-sensors-plugin-sk/${path}`, {
@@ -119,72 +112,53 @@ const useStyles = makeStyles((theme) => ({
119
112
  }
120
113
 
121
114
  async function getSensors(){
122
- console.log("getSensors")
123
115
  const response = await fetchJSONData("getSensors")
124
116
  if (response.status!=200){
125
117
  throw new Error(`Unable get sensor data: ${response.statusText} (${response.status}) `)
126
118
  }
127
119
  const json = await response.json()
128
- console.log(json)
129
- //for (let i=0;i<json.length;i++){
130
- // json[i].schema.htmlDescription=<div>{ReactHtmlParser(json[i].schema.htmlDescription)}<p></p></div>
131
- //}
132
- return json
133
120
 
134
- }
135
- async function getDomains(){
136
- console.log("getDomains")
137
- const response = await fetchJSONData("getDomains")
138
- if (response.status!=200){
139
- throw new Error(`Unable get domain data: ${response.statusText} (${response.status}) `)
140
- }
141
- const json = await response.json()
142
- console.log(json)
143
121
  return json
144
122
 
145
123
  }
124
+
146
125
  async function getBaseData(){
147
- console.log("getBaseData")
148
126
  const response = await fetchJSONData("getBaseData")
149
127
  if (response.status!=200){
150
128
  throw new Error(`Unable to get base data: ${response.statusText} (${response.status}) `)
151
129
  }
152
130
  const json = await response.json()
153
- console.log(json)
154
131
  json.schema.htmlDescription=<div>{ReactHtmlParser(json.schema.htmlDescription)}<p></p></div>
155
132
  return json
156
133
  }
134
+
157
135
  async function getProgress(){
158
- console.log("getProgress")
159
136
  const response = await fetchJSONData("getProgress")
160
137
  if (response.status!=200){
161
138
  throw new Error(`Unable to get progress: ${response.statusText} (${response.status}) `)
162
139
  }
163
140
  const json = await response.json()
164
- console.log(json)
165
141
  return json
166
142
  }
167
143
 
168
144
  function updateSensorData(data){
169
- console.log("updateSensorData")
170
145
  sendJSONData("updateSensorData", data).then((response)=>{
171
146
  if (response.status != 200) {
172
147
  throw new Error(response.statusText)
173
148
  }
174
- sensorMap.get(data.mac_address)._changesMade=false
175
- sensorMap.get(data.mac_address).config = data
176
-
149
+ setSensorMap((sm)=>{sm.delete(data.mac_address); return new Map(sm) })
150
+ setSchema( {} )
151
+
177
152
  })
178
153
  }
179
154
 
180
155
  function undoChanges(mac) {
181
- console.log("undoChanges")
182
156
  sensorMap.get(mac)._changesMade = false
157
+ sensorMap.get(mac).config = JSON.parse(JSON.stringify(sensorMap.get(mac).configCopy))
183
158
  setSensorData( sensorMap.get(mac).config )
184
159
  }
185
160
 
186
161
  function removeSensorData(mac){
187
- console.log("removeSensorData")
188
162
 
189
163
  try{
190
164
 
@@ -193,10 +167,7 @@ const useStyles = makeStyles((theme) => ({
193
167
  throw new Error(response.statusText)
194
168
  }
195
169
  })
196
-
197
- _sensorMap.delete(mac)
198
-
199
- setSensorMap(new Map(_sensorMap))
170
+ setSensorMap((sm)=>{sm.delete(mac); return new Map(sm) })
200
171
  setSchema( {} )
201
172
  } catch {(e)=>
202
173
  setError( new Error(`Couldn't remove ${mac}: ${e}`))
@@ -206,88 +177,80 @@ const useStyles = makeStyles((theme) => ({
206
177
 
207
178
 
208
179
  function updateBaseData(data){
209
- console.log("updateBaseData")
210
-
180
+ setSensorMap(new Map())
181
+ //setSensorList({})
211
182
  sendJSONData("updateBaseData", data).then( (response )=>{
212
183
  if (response.status != 200) {
213
184
  setError(new Error(`Unable to update base data: ${response.statusText} (${response.status})`))
214
- } /*else {
215
- getProgress().then((json)=>{
216
- setProgress(json)
217
- }).catch((e)=>{
218
- setError(e)
219
- })
220
- }*/
185
+ }
221
186
  })
222
- }
223
-
224
-
225
- function refreshSensors(){
226
- console.log('refreshing sensor map')
227
187
 
228
- getSensors().then((sensors)=>{
229
- setSensorMap (new Map(sensors.map((sensor)=>[sensor.info.mac,sensor])));
230
- })
231
- .catch((e)=>{
232
- setError(e)
233
- })
234
188
  }
189
+
190
+
235
191
 
236
192
 
237
193
  useEffect(()=>{
238
- console.log("useEffect([])")
239
194
  let eventSource=null
240
-
241
195
  fetchJSONData("getPluginState").then( async (response)=> {
196
+
197
+ function newSensorEvent(event){
198
+ let json = JSON.parse(event.data)
199
+ console.log(`New sensor: ${json.info.mac}`)
200
+ setSensorMap( (_sm)=> {
201
+ //if (!_sm.has(json.info.mac))
202
+ _sm.set(json.info.mac, json)
203
+
204
+ return new Map(_sm)
205
+ }
206
+ )
207
+ }
208
+ function sensorChangedEvent(event){
209
+ console.log("sensorchanged")
210
+ const json = JSON.parse(event.data)
211
+
212
+ setSensorMap( (_sm) => {
213
+ const sensor = _sm.get(json.mac)
214
+ if (sensor)
215
+ Object.assign(sensor.info, json )
216
+ return new Map(_sm)
217
+ })
218
+ }
219
+
220
+
242
221
  if (response.status==404) {
243
222
  setPluginState("unknown")
244
223
  throw new Error("unable to get plugin state")
245
224
  }
246
225
  const json = await response.json()
247
- console.log("Setting up eventsource")
248
226
  eventSource = new EventSource("/plugins/bt-sensors-plugin-sk/sse", { withCredentials: true })
249
227
 
250
- setPluginState(json.state)
251
-
252
- _sensorDomains = await getDomains()
253
-
254
228
  eventSource.addEventListener("newsensor", (event) => {
255
- console.log("newsensor")
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
- }
229
+ newSensorEvent(event)
262
230
  });
263
231
 
264
232
  eventSource.addEventListener("sensorchanged", (event) => {
265
- let json = JSON.parse(event.data)
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
- }
233
+ sensorChangedEvent(event)
275
234
  });
235
+
276
236
  eventSource.addEventListener("progress", (event) => {
277
- console.log("progress")
278
237
  const json = JSON.parse(event.data)
279
238
  setProgress(json)
280
- console.log(json)
281
239
  });
282
240
 
283
241
  eventSource.addEventListener("pluginstate", (event) => {
284
- console.log("pluginstate")
285
242
  const json = JSON.parse(event.data)
286
243
  setPluginState(json.state)
287
244
  });
288
-
289
- })
245
+
246
+ setPluginState(json.state);
290
247
 
248
+ (async ()=>{
249
+ const sensors = await getSensors()
250
+ setSensorMap ( new Map(sensors.map((sensor)=>[sensor.info.mac,sensor])) )
251
+ })()
252
+
253
+ })
291
254
  .catch( (e) => {
292
255
  setError(e)
293
256
  }
@@ -296,13 +259,11 @@ const useStyles = makeStyles((theme) => ({
296
259
  console.log("Closing connection to SSE")
297
260
  eventSource.close()
298
261
  };
262
+
299
263
  },[])
300
264
 
301
265
  useEffect(()=>{
302
- console.log("useEffect([pluginState])")
303
- if (pluginState=="started"){
304
- refreshSensors()
305
-
266
+ if (pluginState=="started") {
306
267
  getBaseData().then((json) => {
307
268
  setBaseSchema(json.schema);
308
269
  setBaseData(json.data);
@@ -317,7 +278,6 @@ useEffect(()=>{
317
278
  })
318
279
 
319
280
  } else{
320
- setSensorMap(new Map())
321
281
  setBaseSchema({})
322
282
  setBaseData({})
323
283
  }
@@ -325,9 +285,10 @@ useEffect(()=>{
325
285
  },[pluginState])
326
286
 
327
287
 
328
-
329
288
  function confirmDelete(mac){
330
- const result = window.confirm(`Delete configuration for ${mac}?`)
289
+
290
+ const sensor = sensorMap.get(mac)
291
+ const result = !hasConfig(sensor) || window.confirm(`Delete configuration for ${sensor.info.name}?`)
331
292
  if (result)
332
293
  removeSensorData(mac)
333
294
  }
@@ -352,7 +313,7 @@ function signalStrengthIcon(sensor){
352
313
 
353
314
  }
354
315
  function hasConfig(sensor){
355
- return Object.keys(sensor.config).length>0;
316
+ return Object.keys(sensor.configCopy).length>0;
356
317
  }
357
318
 
358
319
  function createListGroupItem(sensor){
@@ -376,60 +337,43 @@ function createListGroupItem(sensor){
376
337
  </ListGroupItem>
377
338
  }
378
339
 
379
- function configuredDevices(){
380
- return Array.from(sensorMap.entries()).filter((entry)=>hasConfig(entry[1]))
381
- }
382
340
 
383
341
  function devicesInDomain(domain){
342
+
384
343
  return Array.from(sensorMap.entries()).filter((entry)=>entry[1].info.domain===domain)
385
344
  }
386
345
 
387
-
388
- useEffect(()=>{
389
- console.log("useEffect([sensorMap])")
390
-
391
- _sensorMap = sensorMap
392
-
393
- const _sensorDomains = new Set(sensorMap.entries().map((entry)=>{ return entry[1].info.domain}))
394
- const sl = {
395
- _configured: configuredDevices().map((entry) => {
396
- return createListGroupItem(sensorMap.get(entry[0]))
397
- })
398
- }
399
-
400
- _sensorDomains.forEach((d)=>{
401
- sl[d]=devicesInDomain(d).map((entry) => {
402
- return createListGroupItem(sensorMap.get(entry[0]))
403
- })
404
- })
405
- _sensorList=sl
406
-
407
-
408
- },[sensorMap]
409
- )
410
-
411
346
  function ifNullNaN(value){
412
347
  return value==null? NaN : value
413
348
  }
414
349
 
415
- function getSensorList(domain){
416
- return _sensorList[domain]
417
- }
418
-
419
350
  function getTabs(){
351
+ const sensorDomains = [... (new Set(sensorMap.entries().map((entry)=>{ return entry[1].info.domain})))].sort()
352
+ const cd = Array.from(sensorMap.entries()).filter((entry)=>hasConfig(entry[1]))
353
+ let sensorList={}
354
+ sensorList["_configured"]=
355
+ cd.length==0?
356
+ "Select a device from its domain tab (Electrical etc.) and configure it.":
357
+ cd.map((entry) => {
358
+ return createListGroupItem(sensorMap.get(entry[0]))
359
+ })
360
+
361
+ sensorDomains.forEach((d)=>{
362
+ sensorList[d]=devicesInDomain(d).map((entry) => {
363
+ return createListGroupItem(sensorMap.get(entry[0]))
364
+ })
365
+ })
420
366
 
421
- return Object.keys(_sensorList).map((domain)=> {return getTab(domain)})
367
+ return Object.keys(sensorList).map((domain)=> {return getTab(domain, sensorList[domain])})
422
368
  }
423
- // <div style={{paddingBottom: 20}} class="d-flex flex-wrap justify-content-start align-items-start">
424
- // <div class="d-flex flex-column" >
425
369
 
426
- function getTab(key){
427
- var title = key.slice(key.charAt(0)==="_"?1:0)
370
+ function getTab(key, sensorList){
371
+ let title = key.slice(key.charAt(0)==="_"?1:0)
428
372
 
429
- return <Tab eventKey={key} title={title.charAt(0).toUpperCase()+title.slice(1) }>
373
+ return <Tab eventKey={key} title={`${title.charAt(0).toUpperCase()}${title.slice(1)}${typeof sensorList=='string'?'':' ('+sensorList.length+')'}` } >
430
374
 
431
375
  <ListGroup style={{ maxHeight: '300px', overflowY: 'auto' }}>
432
- {getSensorList(key)}
376
+ {sensorList}
433
377
  </ListGroup>
434
378
 
435
379
 
@@ -441,22 +385,6 @@ useEffect(()=>{
441
385
  window.open(url, "_blank", "noreferrer");
442
386
  }
443
387
 
444
- function CustomFieldTemplate(props) {
445
- const { id, classNames, style, label, help, required, description, errors, children } = props;
446
- return (
447
- <div className={classNames} style={style}>
448
- <Grid container xs={12} direction="row" spacing="1">
449
- <Grid item xs={1} sm container direction="column">
450
- <Grid item ><label htmlFor={id}>{label}{required ? '*' : null}</label></Grid>
451
- <Grid item> {description}</Grid>
452
- </Grid>
453
- <Grid item>{children}</Grid>
454
- </Grid>
455
- {errors}
456
- {help}
457
- </div>
458
- );
459
- }
460
388
 
461
389
  if (pluginState=="stopped" || pluginState=="unknown")
462
390
  return (<h3>Enable plugin to see configuration</h3>)
@@ -498,7 +426,7 @@ useEffect(()=>{
498
426
  defaultActiveKey="_configured"
499
427
  id="domain-tabs"
500
428
  className="mb-3"
501
- onClick={()=>{setSchema({})}}
429
+
502
430
  >
503
431
  {getTabs()}
504
432
  </Tabs>
@@ -514,13 +442,15 @@ useEffect(()=>{
514
442
  uiSchema={uiSchema}
515
443
  onChange={(e) => {
516
444
  const s = sensorMap.get(e.formData.mac_address)
517
- s._changesMade=true
518
- setSensorData(e.formData)
445
+ if(s) {
446
+ s._changesMade=true
447
+ s.config = e.formData
448
+ setSensorData(e.formData)
449
+ }
519
450
  }
520
451
  }
521
452
  onSubmit={({ formData }, e) => {
522
453
  updateSensorData(formData)
523
- setSchema({})
524
454
  alert("Changes saved")
525
455
  }}
526
456
  onError={log('errors')}
@@ -538,4 +468,5 @@ useEffect(()=>{
538
468
  )
539
469
 
540
470
 
541
- }
471
+ }
472
+ export default BTConfig