bt-sensors-plugin-sk 1.2.0-beta.0.1.1 → 1.2.0-beta.0.1.2
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 +21 -14
- package/README.md +4 -0
- package/index.js +14 -9
- package/package.json +1 -1
- package/public/159.js +1 -1
- package/public/239.js +5 -11
- package/public/540.js +1 -1
- package/public/778.js +1 -1
- package/public/main.js +1 -1
- package/public/remoteEntry.js +1 -1
- package/sensor_classes/ATC.js +6 -3
- package/src/components/PluginConfigurationPanel.js +13 -7
- package/testqueue.js +64 -0
- package/bt-sensors-plugin-sk.json.bak +0 -121
package/BTSensor.js
CHANGED
|
@@ -465,23 +465,24 @@ class BTSensor extends EventEmitter {
|
|
|
465
465
|
|
|
466
466
|
deviceConnect() {
|
|
467
467
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
Bluez for some cockamamie reason (It's 2025 for chrissake.
|
|
471
|
-
BLUETOOTH ISN'T JUST FOR DESKTOPS ANYMORE, BLUEZ DEVS!)
|
|
472
|
-
SUSPENDS scanning while connected to a device.
|
|
473
|
-
|
|
474
|
-
The next line of code gives the scanner a kick in the arse,
|
|
475
|
-
starting it up again so, I dunno, another device might be able
|
|
476
|
-
to connect and sensor classes could maybe get beacon updates.
|
|
477
|
-
|
|
478
|
-
You know, the little things.
|
|
479
|
-
*/
|
|
468
|
+
|
|
480
469
|
return connectQueue.enqueue( async ()=>{
|
|
481
470
|
this.debug(`Connecting to ${this.getName()}`)
|
|
482
471
|
await this.device.connect()
|
|
483
472
|
try {
|
|
484
473
|
|
|
474
|
+
/* CAUTION: HACK AHEAD
|
|
475
|
+
|
|
476
|
+
Bluez for some cockamamie reason (It's 2025 for chrissake.
|
|
477
|
+
BLUETOOTH ISN'T JUST FOR DESKTOPS ANYMORE, BLUEZ DEVS!)
|
|
478
|
+
SUSPENDS scanning while connected to a device.
|
|
479
|
+
|
|
480
|
+
The next line of code gives the scanner a kick in the arse,
|
|
481
|
+
starting it up again so, I dunno, another device might be able
|
|
482
|
+
to connect and sensor classes could maybe get beacon updates.
|
|
483
|
+
|
|
484
|
+
You know, the little things.
|
|
485
|
+
*/
|
|
485
486
|
await this._adapter.helper.callMethod('StopDiscovery')
|
|
486
487
|
await this._adapter.helper.callMethod('SetDiscoveryFilter', {
|
|
487
488
|
Transport: new Variant('s', this._adapter?._transport??"le")
|
|
@@ -492,9 +493,13 @@ class BTSensor extends EventEmitter {
|
|
|
492
493
|
//probably ignorable error. probably.
|
|
493
494
|
console.log(e)
|
|
494
495
|
}
|
|
496
|
+
/* END HACK*/
|
|
497
|
+
this.device.on("disconnect", ()=>{
|
|
498
|
+
this.debug(`${this.macAndName()} disconnected`)
|
|
499
|
+
})
|
|
495
500
|
})
|
|
496
|
-
|
|
497
|
-
|
|
501
|
+
|
|
502
|
+
}
|
|
498
503
|
|
|
499
504
|
/**
|
|
500
505
|
*
|
|
@@ -771,7 +776,9 @@ class BTSensor extends EventEmitter {
|
|
|
771
776
|
|
|
772
777
|
async stopListening(){
|
|
773
778
|
this.removeAllListeners()
|
|
779
|
+
this.device.removeAllListeners()
|
|
774
780
|
this.device.helper.removeListeners()
|
|
781
|
+
|
|
775
782
|
if (this.intervalID){
|
|
776
783
|
clearInterval(this.intervalID)
|
|
777
784
|
}
|
package/README.md
CHANGED
package/index.js
CHANGED
|
@@ -125,6 +125,7 @@ module.exports = function (app) {
|
|
|
125
125
|
var discoveryIntervalID, progressID, progressTimeoutID, deviceHealthID
|
|
126
126
|
var adapter
|
|
127
127
|
const channel = createChannel()
|
|
128
|
+
|
|
128
129
|
const classMap = loadClassMap(app)
|
|
129
130
|
const sensorMap=new Map()
|
|
130
131
|
|
|
@@ -248,17 +249,20 @@ module.exports = function (app) {
|
|
|
248
249
|
});
|
|
249
250
|
|
|
250
251
|
router.get('/getPluginState', async (req, res) => {
|
|
251
|
-
|
|
252
252
|
res.status(200).json({
|
|
253
|
+
"connectionId": Date.now(),
|
|
253
254
|
"state":(plugin.started?"started":"stopped")
|
|
254
255
|
})
|
|
255
256
|
});
|
|
256
257
|
router.get("/sse", async (req, res) => {
|
|
257
|
-
const session = await createSession(req,
|
|
258
|
+
const session = await createSession(req,res)
|
|
258
259
|
channel.register(session)
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
260
|
+
req.on("close", ()=>{
|
|
261
|
+
app.debug("deregistering session")
|
|
262
|
+
channel.deregister(session)
|
|
263
|
+
})
|
|
264
|
+
});
|
|
265
|
+
|
|
262
266
|
};
|
|
263
267
|
|
|
264
268
|
function sensorsToJSON(){
|
|
@@ -350,12 +354,12 @@ module.exports = function (app) {
|
|
|
350
354
|
addSensorToList(s)
|
|
351
355
|
s._lastRSSI=-1*Infinity
|
|
352
356
|
s.on("RSSI",(()=>{
|
|
353
|
-
if (Date.now()-s._lastRSSI >
|
|
354
|
-
//app.debug(
|
|
357
|
+
if (Date.now()-s._lastRSSI > 30000) { //only update RSSI on client every 30 seconds
|
|
358
|
+
//app.debug(`Updating ${s.getMacAddress()} RSSI after ${Date.now()-s._lastRSSI} ms`)
|
|
359
|
+
|
|
355
360
|
s._lastRSSI=Date.now()
|
|
356
361
|
|
|
357
362
|
updateSensor(s)
|
|
358
|
-
//app.debug(`Updated Sensor ${config.mac_address}`)
|
|
359
363
|
}
|
|
360
364
|
|
|
361
365
|
}))
|
|
@@ -528,8 +532,9 @@ module.exports = function (app) {
|
|
|
528
532
|
}
|
|
529
533
|
|
|
530
534
|
sensorMap.clear()
|
|
531
|
-
if (channel)
|
|
535
|
+
if (channel){
|
|
532
536
|
channel.broadcast({state:"started"},"pluginstate")
|
|
537
|
+
}
|
|
533
538
|
deviceConfigs=options?.peripherals??[]
|
|
534
539
|
|
|
535
540
|
if (plugin.stopped) {
|
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.
|
|
3
|
+
"version": "1.2.0-beta.0.1.2",
|
|
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/public/159.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";(self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[]).push([[159],{
|
|
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,C]=(0,o.useState)({"ui:submitButtonOptions":{props:{disabled:!1,className:"btn btn-info"},norender:!0,submitText:"Submit"}}),[x,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([])");let e=null;return H("getPluginState").then((async t=>{if(404==t.status)throw L("unknown"),new Error("unable to get plugin state");const n=await t.json();console.log("Setting up eventsource"),e=new EventSource("/plugins/bt-sensors-plugin-sk/sse",{withCredentials:!0}),L(n.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}(),e.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))))})),e.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))}})),e.addEventListener("progress",(e=>{console.log("progress");const t=JSON.parse(e.data);U(t),console.log(t)})),e.addEventListener("pluginstate",(e=>{console.log("pluginstate");const t=JSON.parse(e.data);L(t.state)}))})).catch((e=>{K(e)})),()=>{console.log("Closing connection to SSE"),e.close()}}),[]),(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}))))}}}]);
|