bt-sensors-plugin-sk 1.2.0-beta.0.1.0 → 1.2.0-beta.0.1.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/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # Bluetooth Sensors for [Signal K](http://www.signalk.org)
2
2
 
3
3
  ## What's New
4
+ ## 1.2.0-beta-0.1.1
5
+
6
+ Gobius fix for inclination path, id parameter.
4
7
 
5
8
  ## 1.2.0-beta-0.1.0
6
9
 
@@ -0,0 +1,121 @@
1
+ {
2
+ "configuration": {
3
+ "discoveryTimeout": 30,
4
+ "discoveryInterval": 0,
5
+ "peripherals": [
6
+ {
7
+ "active": true,
8
+ "mac_address": "D4:50:46:39:38:C5",
9
+ "discoveryTimeout": 30,
10
+ "params": {
11
+ "name": "Victron Smart Shunt",
12
+ "encryptionKey": "8cce8529307cf9dd0c85611c4fef42d9"
13
+ },
14
+ "paths": {
15
+ "RSSI": "sensors.smartshunt.rssi",
16
+ "current": "electrical.battery.house.current",
17
+ "power": "electrical.battery.house.power",
18
+ "voltage": "electrical.battery.house.voltage",
19
+ "alarm": "electrical.battery.house.alarm",
20
+ "consumed": "electrical.battery.house.consumedAh",
21
+ "soc": "electrical.battery.house.soc",
22
+ "ttg": "electrical.battery.house.ttg",
23
+ "starterVoltage": "electrical.battery.starter.voltage",
24
+ "__state__": "sensors.smartshunt.state"
25
+ },
26
+ "gattParams": {
27
+ "useGATT": false
28
+ }
29
+ },
30
+ {
31
+ "active": true,
32
+ "mac_address": "F9:B0:6E:63:BC:7E",
33
+ "discoveryTimeout": 30,
34
+ "params": {
35
+ "name": "Ruuvi sensor for cabin"
36
+ },
37
+ "paths": {
38
+ "RSSI": "sensors.ruuviBC7E.rssi",
39
+ "temp": "environment.cabin.temperature",
40
+ "humidity": "environment.cabin.humidity",
41
+ "pressure": "environment.cabin.pressure",
42
+ "battV": "sensors.ruuviBC7E.voltage",
43
+ "mc": "sensors.ruuviBC7E.movementCounter",
44
+ "battery": "sensors.temperature.reefer.batterystrength",
45
+ "__state__": "sensors.ruuviBC7E.state"
46
+ }
47
+ },
48
+ {
49
+ "active": true,
50
+ "mac_address": "49:22:05:17:2B:AE",
51
+ "discoveryTimeout": 120,
52
+ "params": {
53
+ "name": "Inkbird temperature sensor"
54
+ },
55
+ "paths": {
56
+ "RSSI": "sensors.inkbird-th2.rssi",
57
+ "temp": "environment.refrigerator.temperature",
58
+ "battery": "sensors.inkbird-th2.battery",
59
+ "__state__": "sensors.inkbird-th2.state"
60
+ }
61
+ },
62
+ {
63
+ "active": true,
64
+ "mac_address": "A4:C1:38:9F:F7:7E",
65
+ "discoveryTimeout": 300,
66
+ "params": {
67
+ "name": "ATC Temp/Humidity sensor for Deck",
68
+ "parser": "ATC-LE"
69
+ },
70
+ "paths": {
71
+ "RSSI": "sensors.ATC_9FF77E.rssi",
72
+ "temp": "environment.deck.temperature",
73
+ "humidity": "environment.deck.humidity",
74
+ "voltage": "sensors.ATC_9FF77E.voltage",
75
+ "batteryStrength": "sensors.ATC_9FF77E.batteryStrength",
76
+ "__state__": "sensors.ATC_9FF77E.state"
77
+ }
78
+ },
79
+ {
80
+ "active": true,
81
+ "mac_address": "D4:40:59:BE:2A:8C",
82
+ "discoveryTimeout": 30,
83
+ "params": {
84
+ "medium": "PROPANE",
85
+ "tankHeight": "304.8",
86
+ "name": "Galley propane level"
87
+ },
88
+ "paths": {
89
+ "RSSI": "sensors.mopeka-59be8c.rssi",
90
+ "battVolt": "sensors.mopeka-59be8c.battery.voltage",
91
+ "battStrength": "sensors.mopeka-59be8c.battery.strength",
92
+ "temp": "sensors.mopeka-59be8c.temperature",
93
+ "tankLevel": "sensors.mopeka-59be8c.tankLevel",
94
+ "readingQuality": "sensors.mopeka-59be8c.quality",
95
+ "__state__": "sensors.mopeka-59be8c.state"
96
+ }
97
+ },
98
+ {
99
+ "active": true,
100
+ "mac_address": "A4:C1:38:3E:7E:94",
101
+ "discoveryTimeout": 30,
102
+ "params": {
103
+ "encryptionKey": "3985f4ebc032f276cc316f1f6ecea085",
104
+ "__state__": "sensors.xiaomi.state"
105
+ },
106
+ "paths": {
107
+ "RSSI": "sensors.xiaomi.rssi",
108
+ "temp": "sensors.xiaomi.temp",
109
+ "humidity": "sensors.xiaomi.humidity",
110
+ "voltage": "sensors.xiaomi.voltage",
111
+ "__state__": "sensors.xiaomi.state"
112
+ },
113
+ "gattParams": {
114
+ "useGATT": false
115
+ }
116
+ }
117
+ ]
118
+ },
119
+ "enabled": true,
120
+ "enableDebug": true
121
+ }
package/index.js CHANGED
@@ -339,19 +339,23 @@ module.exports = function (app) {
339
339
  if (startNumber != starts ) {
340
340
  return
341
341
  }
342
- //app.debug(`Found ${config.mac_address}`)
343
342
  s = await instantiateSensor(device,config)
344
-
343
+ //app.debug(`Instantiated ${config.mac_address}`)
344
+
345
345
  if (s instanceof BLACKLISTED)
346
346
  reject ( `Device is blacklisted (${s.reasonForBlacklisting()}).`)
347
347
  else{
348
+ //app.debug(`Adding sensor to list ${config.mac_address}`)
349
+
348
350
  addSensorToList(s)
349
351
  s._lastRSSI=-1*Infinity
350
352
  s.on("RSSI",(()=>{
351
- if (Date.now()-s._lastRSSI > 20000) { //only update RSSI on client every five seconds
353
+ if (Date.now()-s._lastRSSI > 20000) { //only update RSSI on client every 20 seconds
352
354
  //app.debug(`${s.getMacAddress()} ${Date.now()-s._lastRSSI}`)
353
355
  s._lastRSSI=Date.now()
356
+
354
357
  updateSensor(s)
358
+ //app.debug(`Updated Sensor ${config.mac_address}`)
355
359
  }
356
360
 
357
361
  }))
@@ -591,7 +595,7 @@ module.exports = function (app) {
591
595
  const dt = config?.discoveryTimeout??options.discoveryTimeout
592
596
  const lc=sensor.elapsedTimeSinceLastContact()
593
597
  if (lc > dt) {
594
- app.debug(`${sensor.getMacAddress()} not heard from in ${lc} seconds`)
598
+ //app.debug(`${sensor.getMacAddress()} not heard from in ${lc} seconds`)
595
599
  channel.broadcast(getSensorInfo(sensor), "sensorchanged")
596
600
  }
597
601
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bt-sensors-plugin-sk",
3
- "version": "1.2.0-beta.0.1.0",
3
+ "version": "1.2.0-beta.0.1.1",
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": {
@@ -10,9 +10,8 @@
10
10
  "better-sse": "^0.14.1",
11
11
  "dbus-next": "^0.10.2",
12
12
  "int24": "^0.0.1",
13
- "kaitai-struct": "^0.10.0",
13
+ "kaitai-struct": "^0.10.0",
14
14
  "node-ble": "^1.13.0",
15
- "rimraf": "^6.0.1",
16
15
  "semver": "^7.7.1"
17
16
  },
18
17
  "devDependencies": {
package/public/159.js CHANGED
@@ -1 +1 @@
1
- "use strict";(self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[]).push([[159],{2995:(e,t,n)=>{n.r(t),n.d(t,{default:()=>A});var a=n(3490),s=n(4810),o=n(4147),r=n.n(o),l=n(7606),c=n(6452),i=n(3768),u=n(1431),g=n(9676),d=n(7041),m=n(3657),f=n(5027),p=n(3540),h=n(4712),E=n(5056),w=n(6890),S=n(3399);const v=e=>console.log.bind(console,e);var y,b={};const A=e=>{const[t,n]=(0,o.useState)({}),[A,D]=(0,o.useState)({}),[$,_]=(0,o.useState)({}),[k,x]=(0,o.useState)({"ui:submitButtonOptions":{props:{disabled:!1,className:"btn btn-info"},norender:!0,submitText:"Submit"}}),[C,T]=(0,o.useState)([]),[j,M]=(0,o.useState)(),[O,N]=(0,o.useState)(new Map),[B,U]=(0,o.useState)({progress:0,maxTimeout:100,deviceCount:0,totalDevices:0}),[J,L]=(0,o.useState)("unknown"),[P,K]=(0,o.useState)();function z(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 H(e){return console.log(`fetching ${e}`),fetch(`/plugins/bt-sensors-plugin-sk/${e}`,{credentials:"include"})}async function I(){console.log("getProgress");const e=await H("getProgress");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 R(){console.log("refreshing sensor map"),async function(){console.log("getSensors");const e=await H("getSensors");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=>{N(new Map(e.map((e=>[e.info.mac,e]))))})).catch((e=>{K(e)}))}function W(e){return Object.keys(e.config).length>0}function Y(e){const t=W(e);return r().createElement(w.A,{action:!0,onClick:()=>{e.config.mac_address=e.info.mac,_(e.schema),M(e.config)}},r().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}`,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)}(e))));var n}return(0,o.useEffect)((()=>{console.log("useEffect([])"),H("getPluginState").then((async e=>{if(404==e.status)throw L("unknown"),new Error("unable to get plugin state");const t=await e.json();L(t.state),await async function(){console.log("getDomains");const e=await H("getDomains");if(200!=e.status)throw new Error(`Unable get domain data: ${e.statusText} (${e.status}) `);const t=await e.json();return console.log(t),t}(),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);y.has(t.info.mac)||(console.log(`New sensor: ${t.info.mac}`),N(new Map(y.set(t.info.mac,t))))})),n.addEventListener("sensorchanged",(e=>{let t=JSON.parse(e.data);if(console.log("sensorchanged"),console.log(t),y.has(t.mac)){let e=y.get(t.mac);Object.assign(e.info,t),N(new Map(y))}})),n.addEventListener("progress",(e=>{console.log("progress");const t=JSON.parse(e.data);U(t),console.log(t)})),n.addEventListener("pluginstate",(e=>{console.log("pluginstate");const t=JSON.parse(e.data);L(t.state)})),()=>n.close()})).catch((e=>{K(e)}))}),[]),(0,o.useEffect)((()=>{console.log("useEffect([pluginState])"),"started"==J?(R(),async function(){console.log("getBaseData");const e=await H("getBaseData");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),D(e.data)})).catch((e=>{K(e)})),I().then((e=>{U(e)})).catch((e=>{K(e)}))):(N(new Map),n({}),D({}))}),[J]),(0,o.useEffect)((()=>{console.log("useEffect([sensorMap])"),y=O;const e=new Set(O.entries().map((e=>e[1].info.domain))),t={_configured:Array.from(O.entries()).filter((e=>W(e[1]))).map((e=>Y(O.get(e[0]))))};e.forEach((e=>{var n;t[e]=(n=e,Array.from(O.entries()).filter((e=>e[1].info.domain===n))).map((e=>Y(O.get(e[0]))))})),b=t}),[O]),"stopped"==J||"unknown"==J?r().createElement("h1",null,"Enable plugin to see configuration (if plugin is Enabled and you're seeing this message, restart SignalK)"):r().createElement("div",null,P?r().createElement("h2",{style:"color: red;"},P):"",r().createElement(a.Ay,{schema:t,validator:s.Ay,onChange:e=>D(e.formData),onSubmit:({formData:e},t)=>{var n;n=e,console.log("updateBaseData"),z("updateBaseData",n).then((e=>{200!=e.status?K(new Error(`Unable to update base data: ${e.statusText} (${e.status})`)):(I().then((e=>{U(e)})).catch((e=>{K(e)})),R())})),_({})},onError:v("errors"),formData:A}),r().createElement("p",null),r().createElement("p",null),B.deviceCount<B.totalDevices?r().createElement(S.A,{max:B.maxTimeout,now:B.progress}):"",r().createElement("h2",null,O.size>0?"Bluetooth Devices - Select to configure":""),r().createElement("h2",null,O.size>0?"(* = sensor has unsaved changes)":""),r().createElement("p",null),r().createElement(h.A,{defaultActiveKey:"_configured",id:"domain-tabs",className:"mb-3"},Object.keys(b).map((e=>{return n=(t=e).slice("_"===t.charAt(0)?1:0),r().createElement(E.A,{eventKey:t,title:n.charAt(0).toUpperCase()+n.slice(1)},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"}},function(e){return b[e]}(t)),r().createElement("div",{style:{paddingLeft:10,paddingTop:10,display:0==Object.keys($).length?"none":""}},r().createElement(a.Ay,{schema:$,validator:s.Ay,uiSchema:k,onChange:e=>{O.get(e.formData.mac_address)._changesMade=!0,M(e.formData)},onSubmit:({formData:e},t)=>{var n;console.log(e),n=e,console.log("updateSensorData"),z("updateSensorData",n).then((e=>{if(200!=e.status)throw new Error(e.statusText);O.get(n.mac_address)._changesMade=!1,O.get(n.mac_address).config=n})),_({}),alert("Changes saved")},onError:v("errors"),formData:j},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=j.mac_address,console.log("undoChanges"),O.get(e)._changesMade=!1,M(O.get(e).config)}},"Undo"),r().createElement(c.A,{variant:"contained",color:"secondary",onClick:e=>{return t=j.mac_address,void(window.confirm(`Delete configuration for ${t}?`)&&function(e){console.log("removeSensorData");try{z("removeSensorData",{mac_address:e}).then((e=>{if(200!=e.status)throw new Error(e.statusText)})),y.delete(e),N(new Map(y)),_({})}catch{}}(t));var t}},"Delete")))))));var t,n}))))}}}]);
1
+ "use strict";(self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[]).push([[159],{62995:(e,t,n)=>{n.r(t),n.d(t,{default:()=>A});var a=n(73490),s=n(74810),o=n(86528),r=n.n(o),l=n(27606),c=n(86452),i=n(3768),u=n(71431),g=n(39676),d=n(47041),m=n(86038),f=n(95027),p=n(43540),h=n(24712),E=n(75056),w=n(96890),S=n(23399);const v=e=>console.log.bind(console,e);var y,b={};const A=e=>{const[t,n]=(0,o.useState)({}),[A,D]=(0,o.useState)({}),[$,_]=(0,o.useState)({}),[k,x]=(0,o.useState)({"ui:submitButtonOptions":{props:{disabled:!1,className:"btn btn-info"},norender:!0,submitText:"Submit"}}),[C,T]=(0,o.useState)([]),[j,M]=(0,o.useState)(),[O,N]=(0,o.useState)(new Map),[B,U]=(0,o.useState)({progress:0,maxTimeout:100,deviceCount:0,totalDevices:0}),[J,L]=(0,o.useState)("unknown"),[P,K]=(0,o.useState)();function z(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 H(e){return console.log(`fetching ${e}`),fetch(`/plugins/bt-sensors-plugin-sk/${e}`,{credentials:"include"})}async function I(){console.log("getProgress");const e=await H("getProgress");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 R(){console.log("refreshing sensor map"),async function(){console.log("getSensors");const e=await H("getSensors");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=>{N(new Map(e.map((e=>[e.info.mac,e]))))})).catch((e=>{K(e)}))}function W(e){return Object.keys(e.config).length>0}function Y(e){const t=W(e);return r().createElement(w.A,{action:!0,onClick:()=>{e.config.mac_address=e.info.mac,_(e.schema),M(e.config)}},r().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}`,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)}(e))));var n}return(0,o.useEffect)((()=>{console.log("useEffect([])"),H("getPluginState").then((async e=>{if(404==e.status)throw L("unknown"),new Error("unable to get plugin state");const t=await e.json();L(t.state),await async function(){console.log("getDomains");const e=await H("getDomains");if(200!=e.status)throw new Error(`Unable get domain data: ${e.statusText} (${e.status}) `);const t=await e.json();return console.log(t),t}(),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);y.has(t.info.mac)||(console.log(`New sensor: ${t.info.mac}`),N(new Map(y.set(t.info.mac,t))))})),n.addEventListener("sensorchanged",(e=>{let t=JSON.parse(e.data);if(console.log("sensorchanged"),console.log(t),y.has(t.mac)){let e=y.get(t.mac);Object.assign(e.info,t),N(new Map(y))}})),n.addEventListener("progress",(e=>{console.log("progress");const t=JSON.parse(e.data);U(t),console.log(t)})),n.addEventListener("pluginstate",(e=>{console.log("pluginstate");const t=JSON.parse(e.data);L(t.state)})),()=>n.close()})).catch((e=>{K(e)}))}),[]),(0,o.useEffect)((()=>{console.log("useEffect([pluginState])"),"started"==J?(R(),async function(){console.log("getBaseData");const e=await H("getBaseData");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),D(e.data)})).catch((e=>{K(e)})),I().then((e=>{U(e)})).catch((e=>{K(e)}))):(N(new Map),n({}),D({}))}),[J]),(0,o.useEffect)((()=>{console.log("useEffect([sensorMap])"),y=O;const e=new Set(O.entries().map((e=>e[1].info.domain))),t={_configured:Array.from(O.entries()).filter((e=>W(e[1]))).map((e=>Y(O.get(e[0]))))};e.forEach((e=>{var n;t[e]=(n=e,Array.from(O.entries()).filter((e=>e[1].info.domain===n))).map((e=>Y(O.get(e[0]))))})),b=t}),[O]),"stopped"==J||"unknown"==J?r().createElement("h1",null,"Enable plugin to see configuration (if plugin is Enabled and you're seeing this message, restart SignalK)"):r().createElement("div",null,P?r().createElement("h2",{style:"color: red;"},P):"",r().createElement(a.Ay,{schema:t,validator:s.Ay,onChange:e=>D(e.formData),onSubmit:({formData:e},t)=>{var n;n=e,console.log("updateBaseData"),z("updateBaseData",n).then((e=>{200!=e.status?K(new Error(`Unable to update base data: ${e.statusText} (${e.status})`)):(I().then((e=>{U(e)})).catch((e=>{K(e)})),R())})),_({})},onError:v("errors"),formData:A}),r().createElement("p",null),r().createElement("p",null),B.deviceCount<B.totalDevices?r().createElement(S.A,{max:B.maxTimeout,now:B.progress}):"",r().createElement("h2",null,O.size>0?"Bluetooth Devices - Select to configure":""),r().createElement("h2",null,O.size>0?"(* = sensor has unsaved changes)":""),r().createElement("p",null),r().createElement(h.A,{defaultActiveKey:"_configured",id:"domain-tabs",className:"mb-3"},Object.keys(b).map((e=>{return n=(t=e).slice("_"===t.charAt(0)?1:0),r().createElement(E.A,{eventKey:t,title:n.charAt(0).toUpperCase()+n.slice(1)},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"}},function(e){return b[e]}(t)),r().createElement("div",{style:{paddingLeft:10,paddingTop:10,display:0==Object.keys($).length?"none":""}},r().createElement(a.Ay,{schema:$,validator:s.Ay,uiSchema:k,onChange:e=>{O.get(e.formData.mac_address)._changesMade=!0,M(e.formData)},onSubmit:({formData:e},t)=>{var n;console.log(e),n=e,console.log("updateSensorData"),z("updateSensorData",n).then((e=>{if(200!=e.status)throw new Error(e.statusText);O.get(n.mac_address)._changesMade=!1,O.get(n.mac_address).config=n})),_({}),alert("Changes saved")},onError:v("errors"),formData:j},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=j.mac_address,console.log("undoChanges"),O.get(e)._changesMade=!1,M(O.get(e).config)}},"Undo"),r().createElement(c.A,{variant:"contained",color:"secondary",onClick:e=>{return t=j.mac_address,void(window.confirm(`Delete configuration for ${t}?`)&&function(e){console.log("removeSensorData");try{z("removeSensorData",{mac_address:e}).then((e=>{if(200!=e.status)throw new Error(e.statusText)})),y.delete(e),N(new Map(y)),_({})}catch{}}(t));var t}},"Delete")))))));var t,n}))))}}}]);