bt-sensors-plugin-sk 1.2.6-beta-6a → 1.2.6-beta-6e

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 CHANGED
@@ -1,4 +1,4 @@
1
- const { Variant } = require('dbus-next');
1
+ const { Variant } = require('@jellybrick/dbus-next');
2
2
  const { log } = require('node:console');
3
3
  const EventEmitter = require('node:events');
4
4
  const AutoQueue = require("./Queue.js")
@@ -67,8 +67,8 @@ function signalQualityPercentQuad(rssi, perfect_rssi=-20, worst_rssi=-85) {
67
67
  * @abstract
68
68
  * @extends EventEmitter
69
69
  *
70
- * @requires module:node-ble/Device
71
- * @requires module:node-ble/BusHelper
70
+ * @requires module:@naugehyde/node-ble/Device
71
+ * @requires module:@naugehyde/node-ble/BusHelper
72
72
  *
73
73
  */
74
74
 
@@ -276,7 +276,13 @@ class BTSensor extends EventEmitter {
276
276
  this._debugLog.push({timestamp:Date.now(), message:message})
277
277
  }
278
278
 
279
+ unsetError(){
280
+ this._error=false
281
+ this.emit("error", false)
282
+ }
283
+
279
284
  setError(message){
285
+
280
286
  if (this._app){
281
287
  this._app.debug(`(${this.getName()} ${this.getMacAddress()}) ${message}`)
282
288
  this._app.setPluginError(`(${this.getName()} ${this.getMacAddress()}) ${message}`)
@@ -368,6 +374,8 @@ class BTSensor extends EventEmitter {
368
374
  }
369
375
  async activate(config, plugin){
370
376
  this.setState("ACTIVATING")
377
+ this.unsetError()
378
+
371
379
  if (config.paths){
372
380
  this.createPaths(config,plugin.id)
373
381
  this.initPaths(config,plugin.id)
@@ -384,6 +392,7 @@ class BTSensor extends EventEmitter {
384
392
  this.setState("ACTIVE")
385
393
  }
386
394
  this._active = true
395
+ this._error = false
387
396
 
388
397
  this._propertiesChanged(this.currentProperties)
389
398
 
@@ -553,6 +562,7 @@ class BTSensor extends EventEmitter {
553
562
  }
554
563
  }
555
564
  setConnected(state){
565
+ this._connected=state
556
566
  this.setState(state?"CONNECTED":"DISCONNECTED")
557
567
  }
558
568
 
package/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  const packageInfo = require("./package.json")
2
2
 
3
3
 
4
- const {createBluetooth} = require('node-ble')
5
- const {Variant} = require('dbus-next')
4
+ const {createBluetooth} = require('@naugehyde/node-ble')
5
+ const {Variant} = require('@jellybrick/dbus-next')
6
6
  const {bluetooth, destroy} = createBluetooth()
7
7
 
8
8
  const BTSensor = require('./BTSensor.js')
@@ -78,7 +78,7 @@ class MissingSensor {
78
78
  return NaN
79
79
  }
80
80
  getState(){
81
- return "ERROR"
81
+ return "OUT_OF_RANGE"
82
82
  }
83
83
  stopListening(){}
84
84
  listen(){}
@@ -104,6 +104,17 @@ class MissingSensor {
104
104
  return []
105
105
  }
106
106
 
107
+ removeAllListeners(){
108
+
109
+ }
110
+ on(){
111
+
112
+ }
113
+
114
+ isError(){
115
+ return true
116
+ }
117
+
107
118
  }
108
119
  module.exports = function (app) {
109
120
  var deviceConfigs=[]
@@ -420,6 +431,7 @@ module.exports = function (app) {
420
431
  sensor.removeAllListeners("connected")
421
432
  sensor.removeAllListeners("error")
422
433
  sensor.removeAllListeners("debug")
434
+ sensor.removeAllListeners("RSSI")
423
435
 
424
436
  sensorMap.delete(sensor.getMacAddress())
425
437
  channel.broadcast({mac:sensor.getMacAddress()},"removesensor")
@@ -439,6 +451,16 @@ module.exports = function (app) {
439
451
  sensor.on("debug", ()=>{
440
452
  updateSensor(sensor)
441
453
  })
454
+ sensor._lastRSSI=-1*Infinity
455
+ sensor.on("RSSI",(()=>{
456
+ if (Date.now()-sensor._lastRSSI > 30000) { //only update RSSI on client every 30 seconds
457
+
458
+ sensor._lastRSSI=Date.now()
459
+
460
+ updateSensor(sensor)
461
+ }
462
+
463
+ }))
442
464
  channel.broadcast(sensorToJSON(sensor),"newsensor");
443
465
  }
444
466
  function deviceNameAndAddress(config){
@@ -461,18 +483,7 @@ module.exports = function (app) {
461
483
  if (s instanceof BLACKLISTED)
462
484
  reject ( `Device is blacklisted (${s.reasonForBlacklisting()}).`)
463
485
  else{
464
-
465
486
  addSensorToList(s)
466
- s._lastRSSI=-1*Infinity
467
- s.on("RSSI",(()=>{
468
- if (Date.now()-s._lastRSSI > 30000) { //only update RSSI on client every 30 seconds
469
-
470
- s._lastRSSI=Date.now()
471
-
472
- updateSensor(s)
473
- }
474
-
475
- }))
476
487
  resolve(s)
477
488
  }
478
489
  })
@@ -750,7 +761,7 @@ module.exports = function (app) {
750
761
  const dt = config?.discoveryTimeout??options.discoveryTimeout
751
762
  const lc=sensor.elapsedTimeSinceLastContact()
752
763
  if (lc > dt) {
753
- channel.broadcast(getSensorInfo(sensor), "sensorchanged")
764
+ updateSensor(sensor)
754
765
  }
755
766
  })
756
767
  }, intervalTimeout)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bt-sensors-plugin-sk",
3
- "version": "1.2.6-beta-6a",
3
+ "version": "1.2.6-beta-6e",
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": {
@@ -13,7 +13,7 @@
13
13
  "@jellybrick/dbus-next": "^0.10.3",
14
14
  "int24": "^0.0.1",
15
15
  "kaitai-struct": "^0.10.0",
16
- "node-ble": "^1.13.0",
16
+ "@naugehyde/node-ble":"^1.13.4",
17
17
  "semver": "^7.7.1",
18
18
  "lru-cache": "^11.1.0"
19
19
  },
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)({}),[$,_]=(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}}]);
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:()=>C,default:()=>D});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(55877),g=n(3768),f=n(71431),h=n(39676),p=n(47041),E=n(86038),w=n(95027),y=n(43540),S=n(38250),b=n(31008),v=n(20455),A=n(23399);const k=e=>console.log.bind(console,e);function C(e){const t=(0,m.A)((e=>({root:{"& > *":{margin:e.spacing(1)}}}))),[n,C]=(0,o.useState)({}),[D,$]=(0,o.useState)({}),[_,x]=(0,o.useState)({}),[N,O]=(0,o.useState)({"ui:options":{label:!1},paths:{enableMarkdownInDescription:!0},title:{"ui:widget":"hidden"}}),[T,j]=(0,o.useState)(),[M,U]=(0,o.useState)(!1),[J,L]=(0,o.useState)(!0),[R,I]=(0,o.useState)(new Map),[P,K]=(0,o.useState)({progress:0,maxTimeout:100,deviceCount:0,totalDevices:0}),[B,G]=(0,o.useState)("unknown"),[W,F]=(0,o.useState)(),[H,z]=(0,o.useState)(!1),[Y,q]=(0,o.useState)(""),Q=t();function V(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 X(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 Z(e){return Object.keys(e.configCopy).length>0}function ee(e){const t=Z(e);return c().createElement(v.A,{action:!0,onClick:()=>{e.config.mac_address=e.info.mac,x(e.schema),j(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 e.info.connected?c().createElement(d.A,null):null==e.info.lastContactDelta||e.info.lastContactDelta>e.config.discoveryTimeout?c().createElement(g.A,null):e.info.signalStrength>80?c().createElement(f.A,null):e.info.signalStrength>60?c().createElement(h.A,null):e.info.signalStrength>40?c().createElement(p.A,null):e.info.signalStrength>20?c().createElement(E.A,null):c().createElement(w.A,null)}(e)))));var n}function te(e){window.open(e,"_blank","noreferrer")}return(0,o.useEffect)((()=>{let e=null;return X("getPluginState").then((async t=>{if(404==t.status)throw G("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}`),I((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),I((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);K(t)})),e.addEventListener("pluginstate",(e=>{const t=JSON.parse(e.data);G(t.state)})),G(n.state),(async()=>{const e=await async function(){const e=await X("getSensors");if(200!=e.status)throw new Error(`Unable get sensor data: ${e.statusText} (${e.status}) `);return await e.json()}();I(new Map(e.map((e=>[e.info.mac,e]))))})()})).catch((e=>{F(e.message)})),()=>{console.log("Closing connection to SSE"),e.close()}}),[]),(0,o.useEffect)((()=>{if(!M)return;if(!T||!R)return;const e=R.get(T.mac_address);e&&_&&T&&Object.hasOwn(T,"params")&&"UNKNOWN"==e.info.class&&T.params.sensorClass&&"UNKNOWN"!=T.params.sensorClass&&(L(!1),q(`Please wait. Fetching schema for ${T.params.sensorClass}...`),async function(e,t){const n=await X("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()}(T.mac_address,T.params.sensorClass).then((e=>{x(e.schema)})).catch((e=>{alert(e.message)})).finally((()=>{q(""),L(!0),U(!1)})))}),[M]),(0,o.useEffect)((()=>{z(""!=Y)}),[Y]),(0,o.useEffect)((()=>{"started"==B?(async function(){const e=await X("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=>{C(e.schema),$(e.data)})).catch((e=>{F(e.message)})),async function(){const e=await X("getProgress");if(200!=e.status)throw new Error(`Unable to get progress: ${e.statusText} (${e.status}) `);return await e.json()}().then((e=>{K(e)})).catch((e=>{F(e.message)}))):(C({}),$({}))}),[B]),"stopped"==B||"unknown"==B?c().createElement("h3",null,"Enable plugin to see configuration"):c().createElement("div",null,c().createElement(i.A,{anchorOrigin:{horizontal:"center",vertical:"bottom"},onClose:()=>z(!1),open:H,message:Y,key:"snackbar"}),c().createElement("div",{className:Q.root},c().createElement(l.A,{variant:"contained",onClick:()=>{te("https://github.com/naugehyde/bt-sensors-plugin-sk/tree/1.2.0-beta#configuration")}},"Documentation"),c().createElement(l.A,{variant:"contained",onClick:()=>{te("https://github.com/naugehyde/bt-sensors-plugin-sk/issues/new/choose")}},"Report Issue"),c().createElement(l.A,{variant:"contained",onClick:()=>{te("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}}),W?c().createElement("h2",{style:{color:"red"}},W):"",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=>$(e.formData),onSubmit:({formData:e},t)=>{var n;n=e,I(new Map),V("updateBaseData",n).then((e=>{200!=e.status&&F(`Unable to update base data: ${e.statusText} (${e.status})`)})),x({})},onError:k("errors"),formData:D}),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),P.deviceCount<P.totalDevices?c().createElement(A.A,{max:P.maxTimeout,now:P.progress}):"",c().createElement("p",null),c().createElement(S.A,{defaultActiveKey:"_configured",id:"domain-tabs",className:"mb-3"},function(){const e=[...new Set(R.entries().map((e=>e[1].info.domain)))].sort(),t=Array.from(R.entries()).filter((e=>Z(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=>ee(R.get(e[0])))),e.forEach((e=>{var t;n[e]=(t=e,Array.from(R.entries()).filter((e=>e[1].info.domain===t))).map((e=>ee(R.get(e[0]))))})),Object.keys(n).map((e=>function(e,t){let n=e.slice("_"===e.charAt(0)?1:0);return c().createElement(b.A,{eventKey:e,title:`${n.charAt(0).toUpperCase()}${n.slice(1)}${"string"==typeof t?"":" ("+t.length+")"}`},c().createElement(y.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:!J},c().createElement(a.Ay,{schema:_,validator:s.Ay,uiSchema:N,onChange:(e,t)=>{const n=R.get(e.formData.mac_address);n&&(n._changesMade=!0,n.config=e.formData,j(e.formData)),"root_params_sensorClass"==t&&U(!0)},onSubmit:({formData:e},t)=>{var n;V("updateSensorData",n=e).then((e=>{if(200!=e.status)throw new Error(e.statusText);I((e=>(e.delete(n.mac_address),new Map(e)))),x({})})),alert("Changes saved")},onError:k("errors"),formData:T},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=T.mac_address,R.get(e)._changesMade=!1,R.get(e).config=JSON.parse(JSON.stringify(R.get(e).configCopy)),j(R.get(e).config)}},"Undo"),c().createElement(l.A,{variant:"contained",color:"secondary",onClick:e=>function(e){const t=R.get(e);(!Z(t)||window.confirm(`Delete configuration for ${t.info.name}?`))&&function(e){try{V("removeSensorData",{mac_address:e}).then((e=>{if(200!=e.status)throw new Error(e.statusText)})),I((t=>(t.delete(e),new Map(t)))),x({})}catch{}}(e)}(T.mac_address)},"Delete"))))))}const D=C}}]);