bt-sensors-plugin-sk 1.2.0-beta.0.0.8 → 1.2.0-beta.0.0.9
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
|
@@ -365,13 +365,15 @@ class BTSensor extends EventEmitter {
|
|
|
365
365
|
}
|
|
366
366
|
else
|
|
367
367
|
await this.initGATTNotifications()
|
|
368
|
+
}).catch((e)=>{
|
|
369
|
+
this.app.debug(`Unable to activate GATT connection for ${this.getName()} (${this.getMacAddress()}): ${e}`)
|
|
368
370
|
})
|
|
369
371
|
}
|
|
370
372
|
|
|
371
373
|
/**
|
|
372
374
|
* Add a metadatum instance to the sensor instance
|
|
373
375
|
*
|
|
374
|
-
* @param {String} tag
|
|
376
|
+
* @param {String} tag
|
|
375
377
|
* @param {...any} args
|
|
376
378
|
* @returns {this.Metadatum} the new metadatum instance
|
|
377
379
|
*/
|
|
@@ -552,6 +554,9 @@ class BTSensor extends EventEmitter {
|
|
|
552
554
|
getParams(){
|
|
553
555
|
return this._schema.properties.params.properties
|
|
554
556
|
}
|
|
557
|
+
getParameter(param){
|
|
558
|
+
return this.getParams()[param]
|
|
559
|
+
}
|
|
555
560
|
getGATTParams(){
|
|
556
561
|
return this._schema.properties.gattParams.properties
|
|
557
562
|
|
package/README.md
CHANGED
package/index.js
CHANGED
|
@@ -319,13 +319,13 @@ module.exports = function (app) {
|
|
|
319
319
|
}
|
|
320
320
|
|
|
321
321
|
function getSensorInfo(sensor){
|
|
322
|
-
|
|
323
|
-
|
|
322
|
+
|
|
323
|
+
const etslc = sensor.elapsedTimeSinceLastContact()
|
|
324
324
|
return { mac: sensor.getMacAddress(),
|
|
325
325
|
name: sensor.getName(),
|
|
326
326
|
RSSI: sensor.getRSSI(),
|
|
327
327
|
signalStrength: sensor.getSignalStrength(),
|
|
328
|
-
lastContactDelta:
|
|
328
|
+
lastContactDelta: etslc
|
|
329
329
|
}
|
|
330
330
|
}
|
|
331
331
|
|
|
@@ -397,10 +397,11 @@ module.exports = function (app) {
|
|
|
397
397
|
reject ( `Device is blacklisted (${s.reasonForBlacklisting()}).`)
|
|
398
398
|
else{
|
|
399
399
|
addSensorToList(s)
|
|
400
|
-
|
|
400
|
+
s._lastRSSI=-1*Infinity
|
|
401
401
|
s.on("RSSI",(()=>{
|
|
402
|
-
if (Date.now()-_lastRSSI >
|
|
403
|
-
|
|
402
|
+
if (Date.now()-s._lastRSSI > 20000) { //only update RSSI on client every five seconds
|
|
403
|
+
//app.debug(`${s.getMacAddress()} ${Date.now()-s._lastRSSI}`)
|
|
404
|
+
s._lastRSSI=Date.now()
|
|
404
405
|
updateSensor(s)
|
|
405
406
|
}
|
|
406
407
|
|
|
@@ -638,15 +639,18 @@ module.exports = function (app) {
|
|
|
638
639
|
}
|
|
639
640
|
}
|
|
640
641
|
const minTimeout=Math.min(...deviceConfigs.map((dc)=>dc?.discoveryTimeout??options.discoveryTimeout))
|
|
641
|
-
|
|
642
|
+
const intervalTimeout = ((minTimeout==Infinity)?(options?.discoveryTimeout??plugin.schema.properties.discoveryTimeout.default):minTimeout)*1000
|
|
642
643
|
deviceHealthID = setInterval( ()=> {
|
|
643
644
|
sensorMap.forEach((sensor)=>{
|
|
644
645
|
const config = getDeviceConfig(sensor.getMacAddress())
|
|
645
646
|
const dt = config?.discoveryTimeout??options.discoveryTimeout
|
|
646
|
-
|
|
647
|
+
const lc=sensor.elapsedTimeSinceLastContact()
|
|
648
|
+
if (lc > dt) {
|
|
649
|
+
app.debug(`${sensor.getMacAddress()} not heard from in ${lc} seconds`)
|
|
647
650
|
channel.broadcast(getSensorInfo(sensor), "sensorchanged")
|
|
651
|
+
}
|
|
648
652
|
})
|
|
649
|
-
},
|
|
653
|
+
}, intervalTimeout)
|
|
650
654
|
|
|
651
655
|
if (!options.hasOwnProperty("discoveryInterval" )) //no config -- first run
|
|
652
656
|
options.discoveryInterval = plugin.schema.properties.discoveryInterval.default
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bt-sensors-plugin-sk",
|
|
3
|
-
"version": "1.2.0-beta.0.0.
|
|
3
|
+
"version": "1.2.0-beta.0.0.9",
|
|
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/893.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";(self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[]).push([[893],{2995:(e,t,n)=>{n.r(t),n.d(t,{default:()=>
|
|
1
|
+
"use strict";(self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[]).push([[893],{2995:(e,t,n)=>{n.r(t),n.d(t,{default:()=>v});var s=n(3490),a=n(4810),o=n(4147),r=n.n(o),l=n(7606),c=n(4952),i=n(3768),u=n(1431),g=n(9676),d=n(7041),m=n(3657),f=n(5027),p=n(7265),h=n(6890),E=n(8207);const w=e=>console.log.bind(console,e);var S;const v=e=>{const[t,n]=(0,o.useState)({}),[v,b]=(0,o.useState)({}),[y,D]=(0,o.useState)({}),[A,$]=(0,o.useState)({"ui:submitButtonOptions":{props:{disabled:!1,className:"btn btn-info"},norender:!0,submitText:"Submit"}}),[_,k]=(0,o.useState)([]),[x,C]=(0,o.useState)(),[T,M]=(0,o.useState)(new Map),[j,O]=(0,o.useState)({progress:0,maxTimeout:100,deviceCount:0,totalDevices:0}),[N,B]=(0,o.useState)("unknown"),[J,L]=(0,o.useState)();function U(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 P(e){return console.log(`fetching ${e}`),fetch(`/plugins/bt-sensors-plugin-sk/${e}`,{credentials:"include"})}async function z(){console.log("getProgress");const e=await P("progress");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 H(){console.log("refreshing sensor map"),async function(){console.log("getSensorData");const e=await P("sensors");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=>{M(new Map(e.map((e=>[e.info.mac,e]))))})).catch((e=>{L(e)}))}return(0,o.useEffect)((()=>{console.log("useEffect([])"),P("sendPluginState").then((async e=>{const t=await e.json();B(t.state),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);S.has(t.info.mac)||(console.log(`New sensor: ${t.info.mac}`),M(new Map(S.set(t.info.mac,t))))})),n.addEventListener("sensorchanged",(e=>{let t=JSON.parse(e.data);if(console.log("sensorchanged"),console.log(t),S.has(t.mac)){let e=S.get(t.mac);Object.assign(e.info,t),M(new Map(S))}})),n.addEventListener("progress",(e=>{console.log("progress");const t=JSON.parse(e.data);O(t),console.log(t)})),n.addEventListener("pluginstate",(e=>{console.log("pluginstate");const t=JSON.parse(e.data);B(t.state)})),()=>n.close()})).catch((e=>{L(e)}))}),[]),(0,o.useEffect)((()=>{console.log("useEffect([pluginState])"),"started"==N?(H(),async function(){console.log("getBaseData");const e=await P("base");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),b(e.data)})).catch((e=>{L(e)})),z().then((e=>{O(e)})).catch((e=>{L(e)}))):(M(new Map),n({}),b({}))}),[N]),(0,o.useEffect)((()=>{console.log("useEffect([error])"),console.log(J)}),[J]),(0,o.useEffect)((()=>{console.log("useEffect([sensorMap])"),S=T,k(Array.from(T.entries()).map((e=>{const t=T.get(e[0]),n=t.config,s=Object.keys(n).length>0;return r().createElement(h.A,{action:!0,onClick:()=>{t&&(n.mac_address=e[0],D(t.schema),C(n))}},r().createElement("div",{class:"d-flex justify-content-between align-items-center",style:s?{fontWeight:"normal"}:{fontStyle:"italic"}},`${t._changesMade?"*":""}${t.info.name} MAC: ${t.info.mac} RSSI: ${a=t.info.RSSI,null==a?NaN:a}`,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)}(t))));var a})))}),[T]),"stopped"==N?r().createElement("h1",null,"Enable plugin to see configuration"):r().createElement("div",null,J?r().createElement("h2",{style:"color: red;"},J.message):"",r().createElement(s.Ay,{schema:t,validator:a.Ay,onChange:e=>b(e.formData),onSubmit:({formData:e},t)=>{var n;C(null),n=e,console.log("updateBaseData"),U("sendBaseData",n).then((e=>{200!=e.status?L(new Error(`Unable to update base data: ${e.statusText} (${e.status})`)):(z().then((e=>{O(e)})).catch((e=>{L(e)})),H())}))},onError:w("errors"),formData:v}),r().createElement("p",null),r().createElement("p",null),j.deviceCount<j.totalDevices?r().createElement(E.A,{max:j.maxTimeout,now:j.progress}):"",r().createElement("h2",null,T.size>0?"Bluetooth Devices click to configure":""),r().createElement("h2",null,T.size>0?"(* means sensor has unsaved changes)":""),r().createElement("p",null),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"}},_),r().createElement("div",{style:{paddingLeft:10,paddingTop:10,display:0==Object.keys(y).length?"none":""}},r().createElement(s.Ay,{schema:y,validator:a.Ay,uiSchema:A,onChange:e=>{T.get(e.formData.mac_address)._changesMade=!0,C(e.formData)},onSubmit:({formData:e},t)=>{var n;console.log(e),n=e,console.log("updateSensorData"),U("sendSensorData",n).then((e=>{if(200!=e.status)throw new Error(e.statusText);T.get(n.mac_address)._changesMade=!1,T.get(n.mac_address).config=n})),D({}),alert("Changes saved")},onError:w("errors"),formData:x},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=x.mac_address,console.log("undoChanges"),T.get(e)._changesMade=!1,C(T.get(e).config)}},"Undo"),r().createElement(c.A,{variant:"contained",color:"secondary",onClick:e=>{return t=x.mac_address,void(window.confirm(`Delete configuration for ${t}?`)&&function(e){console.log("removeSensorData");try{U("removeSensorData",{mac_address:e}).then((e=>{if(200!=e.status)throw new Error(e.statusText)})),S.delete(e),M(new Map(S)),D({})}catch{}}(t));var t}},"Delete")))))))}}}]);
|
|
@@ -335,8 +335,8 @@ class MopekaTankSensor extends BTSensor{
|
|
|
335
335
|
if (this.name)
|
|
336
336
|
return this.name
|
|
337
337
|
|
|
338
|
-
const _name =
|
|
339
|
-
return _name?_name:
|
|
338
|
+
const _name = MopekaDevices.get(this?.modelID??0x0).name
|
|
339
|
+
return _name?_name:MopekaDevices.get(0x0).name
|
|
340
340
|
|
|
341
341
|
}
|
|
342
342
|
}
|
|
@@ -12,6 +12,9 @@ class UltrasonicWindMeter extends BTSensor{
|
|
|
12
12
|
hasGATT(){
|
|
13
13
|
return true
|
|
14
14
|
}
|
|
15
|
+
usingGATT(){
|
|
16
|
+
return true
|
|
17
|
+
}
|
|
15
18
|
emitGATT(){
|
|
16
19
|
this.battCharacteristic.readValue()
|
|
17
20
|
.then((buffer)=>
|
|
@@ -29,6 +32,7 @@ class UltrasonicWindMeter extends BTSensor{
|
|
|
29
32
|
}
|
|
30
33
|
initSchema(){
|
|
31
34
|
super.initSchema()
|
|
35
|
+
this.getGATTParams()["useGATT"].default=true
|
|
32
36
|
this.addDefaultPath("batt",'sensors.batteryStrength')
|
|
33
37
|
.read=(buffer)=>{return (buffer.readUInt8())/100}
|
|
34
38
|
|
|
@@ -73,7 +73,7 @@ export default (props) => {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
async function getSensorData(){
|
|
76
|
-
|
|
76
|
+
console.log("getSensorData")
|
|
77
77
|
const response = await fetchJSONData("sensors")
|
|
78
78
|
if (response.status!=200){
|
|
79
79
|
throw new Error(`Unable get sensor data: ${response.statusText} (${response.status}) `)
|
|
@@ -85,7 +85,7 @@ export default (props) => {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
async function getBaseData(){
|
|
88
|
-
|
|
88
|
+
console.log("getBaseData")
|
|
89
89
|
const response = await fetchJSONData("base")
|
|
90
90
|
if (response.status!=200){
|
|
91
91
|
throw new Error(`Unable get base data: ${response.statusText} (${response.status}) `)
|
|
@@ -95,7 +95,7 @@ export default (props) => {
|
|
|
95
95
|
return json
|
|
96
96
|
}
|
|
97
97
|
async function getProgress(){
|
|
98
|
-
|
|
98
|
+
console.log("getProgress")
|
|
99
99
|
const response = await fetchJSONData("progress")
|
|
100
100
|
if (response.status!=200){
|
|
101
101
|
throw new Error(`Unable get progres: ${response.statusText} (${response.status}) `)
|
|
@@ -106,6 +106,7 @@ export default (props) => {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
function updateSensorData(data){
|
|
109
|
+
console.log("updateSensorData")
|
|
109
110
|
sendJSONData("sendSensorData", data).then((response)=>{
|
|
110
111
|
if (response.status != 200) {
|
|
111
112
|
throw new Error(response.statusText)
|
|
@@ -114,14 +115,17 @@ export default (props) => {
|
|
|
114
115
|
sensorMap.get(data.mac_address).config = data
|
|
115
116
|
|
|
116
117
|
})
|
|
117
|
-
}
|
|
118
|
+
}
|
|
118
119
|
|
|
119
120
|
function undoChanges(mac) {
|
|
121
|
+
console.log("undoChanges")
|
|
120
122
|
sensorMap.get(mac)._changesMade = false
|
|
121
123
|
setSensorData( sensorMap.get(mac).config )
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
function removeSensorData(mac){
|
|
127
|
+
console.log("removeSensorData")
|
|
128
|
+
|
|
125
129
|
try{
|
|
126
130
|
|
|
127
131
|
sendJSONData("removeSensorData", {mac_address:mac} ).then((response)=>{
|
|
@@ -142,6 +146,8 @@ export default (props) => {
|
|
|
142
146
|
|
|
143
147
|
|
|
144
148
|
function updateBaseData(data){
|
|
149
|
+
console.log("updateBaseData")
|
|
150
|
+
|
|
145
151
|
sendJSONData("sendBaseData", data).then( (response )=>{
|
|
146
152
|
if (response.status != 200) {
|
|
147
153
|
setError(new Error(`Unable to update base data: ${response.statusText} (${response.status})`))
|
|
@@ -170,7 +176,7 @@ export default (props) => {
|
|
|
170
176
|
|
|
171
177
|
|
|
172
178
|
useEffect(()=>{
|
|
173
|
-
|
|
179
|
+
console.log("useEffect([])")
|
|
174
180
|
fetchJSONData("sendPluginState").then( async (response)=> {
|
|
175
181
|
const json = await response.json()
|
|
176
182
|
setPluginState(json.state)
|
|
@@ -178,6 +184,7 @@ export default (props) => {
|
|
|
178
184
|
const eventSource = new EventSource("/plugins/bt-sensors-plugin-sk/sse")
|
|
179
185
|
|
|
180
186
|
eventSource.addEventListener("newsensor", (event) => {
|
|
187
|
+
console.log("newsensor")
|
|
181
188
|
let json = JSON.parse(event.data)
|
|
182
189
|
|
|
183
190
|
if (!_sensorMap.has(json.info.mac)) {
|
|
@@ -187,7 +194,9 @@ export default (props) => {
|
|
|
187
194
|
});
|
|
188
195
|
|
|
189
196
|
eventSource.addEventListener("sensorchanged", (event) => {
|
|
190
|
-
let json = JSON.parse(event.data)
|
|
197
|
+
let json = JSON.parse(event.data)
|
|
198
|
+
console.log("sensorchanged")
|
|
199
|
+
console.log(json)
|
|
191
200
|
|
|
192
201
|
if (_sensorMap.has(json.mac)) {
|
|
193
202
|
let sensor = _sensorMap.get(json.mac)
|
|
@@ -196,12 +205,14 @@ export default (props) => {
|
|
|
196
205
|
}
|
|
197
206
|
});
|
|
198
207
|
eventSource.addEventListener("progress", (event) => {
|
|
208
|
+
console.log("progress")
|
|
199
209
|
const json = JSON.parse(event.data)
|
|
200
210
|
setProgress(json)
|
|
201
211
|
console.log(json)
|
|
202
212
|
});
|
|
203
213
|
|
|
204
214
|
eventSource.addEventListener("pluginstate", (event) => {
|
|
215
|
+
console.log("pluginstate")
|
|
205
216
|
const json = JSON.parse(event.data)
|
|
206
217
|
setPluginState(json.state)
|
|
207
218
|
});
|
|
@@ -215,6 +226,7 @@ export default (props) => {
|
|
|
215
226
|
},[])
|
|
216
227
|
|
|
217
228
|
useEffect(()=>{
|
|
229
|
+
console.log("useEffect([pluginState])")
|
|
218
230
|
if (pluginState=="started"){
|
|
219
231
|
refreshSensors()
|
|
220
232
|
|
|
@@ -240,6 +252,7 @@ useEffect(()=>{
|
|
|
240
252
|
},[pluginState])
|
|
241
253
|
|
|
242
254
|
useEffect(()=>{
|
|
255
|
+
console.log("useEffect([error])")
|
|
243
256
|
console.log(error)
|
|
244
257
|
},[error])
|
|
245
258
|
|
|
@@ -269,6 +282,8 @@ function signalStrengthIcon(sensor){
|
|
|
269
282
|
|
|
270
283
|
}
|
|
271
284
|
useEffect(()=>{
|
|
285
|
+
console.log("useEffect([sensorMap])")
|
|
286
|
+
|
|
272
287
|
_sensorMap = sensorMap
|
|
273
288
|
|
|
274
289
|
setSensorList(
|