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.
- package/BTSensor.js +4 -1
- package/README.md +15 -8
- package/bt-sensors-plugin-sk copy.json +170 -0
- package/diff.txt +2860 -0
- package/index.js +31 -15
- package/package.json +1 -1
- package/public/847.js +1 -1
- package/sensor_classes/MopekaTankSensor.js +5 -5
- package/sensor_classes/RuuviTag.js +5 -5
- package/sensor_classes/Victron/VictronSensor.js +29 -8
- package/src/components/PluginConfigurationPanel.js +86 -155
package/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const packageInfo = require("./package.json")
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
const {createBluetooth} = require('node-ble')
|
|
4
5
|
const {Variant} = require('dbus-next')
|
|
5
6
|
const {bluetooth, destroy} = createBluetooth()
|
|
@@ -138,10 +139,27 @@ module.exports = function (app) {
|
|
|
138
139
|
var adapterID=options.adapter
|
|
139
140
|
var foundConfiguredDevices=0
|
|
140
141
|
|
|
142
|
+
if (Object.keys(options).length==0){ //empty config means initial startup. save defaults and enabled=true.
|
|
143
|
+
let json = {configuration:{adapter:"hci0", transport:"le", discoveryTimeout:30, discoveryInterval:10}, enabled:true, enableDebug:false}
|
|
144
|
+
let appDataDirPath = app.getDataDirPath()
|
|
145
|
+
let jsonFile = appDataDirPath+'.json'
|
|
146
|
+
const fs = require("node:fs")
|
|
147
|
+
try {
|
|
148
|
+
fs.writeFileSync(jsonFile, JSON.stringify(json, null,2))
|
|
149
|
+
options=json
|
|
150
|
+
} catch(err){
|
|
151
|
+
console.log(`Error writing initial config: ${err.message} `)
|
|
152
|
+
console.log(err)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
}
|
|
156
|
+
|
|
141
157
|
plugin.registerWithRouter = function(router) {
|
|
142
158
|
|
|
143
159
|
router.post('/updateSensorData', async (req, res) => {
|
|
144
160
|
app.debug(req.body)
|
|
161
|
+
const sensor = sensorMap.get(req.body.mac_address)
|
|
162
|
+
sensor.prepareConfig(req.body)
|
|
145
163
|
const i = deviceConfigs.findIndex((p)=>p.mac_address==req.body.mac_address)
|
|
146
164
|
if (i<0){
|
|
147
165
|
if (!options.peripherals){
|
|
@@ -154,18 +172,17 @@ module.exports = function (app) {
|
|
|
154
172
|
} else {
|
|
155
173
|
options.peripherals[i] = req.body
|
|
156
174
|
}
|
|
175
|
+
deviceConfigs=options.peripherals
|
|
157
176
|
app.savePluginOptions(
|
|
158
177
|
options, async () => {
|
|
159
178
|
app.debug('Plugin options saved')
|
|
160
179
|
res.status(200).json({message: "Sensor updated"})
|
|
161
|
-
const sensor = sensorMap.get(req.body.mac_address)
|
|
162
180
|
if (sensor) {
|
|
163
181
|
removeSensorFromList(sensor)
|
|
164
182
|
if (sensor.isActive())
|
|
165
183
|
await sensor.stopListening()
|
|
166
|
-
initConfiguredDevice(req.body)
|
|
167
184
|
}
|
|
168
|
-
|
|
185
|
+
initConfiguredDevice(req.body)
|
|
169
186
|
}
|
|
170
187
|
)
|
|
171
188
|
|
|
@@ -210,12 +227,6 @@ module.exports = function (app) {
|
|
|
210
227
|
}
|
|
211
228
|
)
|
|
212
229
|
});
|
|
213
|
-
router.get('/getDomains', (req, res) => {
|
|
214
|
-
|
|
215
|
-
res.status(200).json(
|
|
216
|
-
BTSensor.SensorDomains
|
|
217
|
-
);
|
|
218
|
-
})
|
|
219
230
|
|
|
220
231
|
router.get('/getBaseData', (req, res) => {
|
|
221
232
|
|
|
@@ -240,9 +251,10 @@ module.exports = function (app) {
|
|
|
240
251
|
|
|
241
252
|
router.get('/getProgress', (req, res) => {
|
|
242
253
|
app.debug("Sending progress")
|
|
243
|
-
|
|
254
|
+
let deviceCount = deviceConfigs.filter((dc)=>dc.active).length
|
|
255
|
+
const json = {"progress":foundConfiguredDevices/deviceCount, "maxTimeout": 1,
|
|
244
256
|
"deviceCount":foundConfiguredDevices,
|
|
245
|
-
"totalDevices":
|
|
257
|
+
"totalDevices": deviceCount}
|
|
246
258
|
res.status(200).json(json)
|
|
247
259
|
|
|
248
260
|
});
|
|
@@ -287,10 +299,12 @@ module.exports = function (app) {
|
|
|
287
299
|
const config = getDeviceConfig(sensor.getMacAddress())
|
|
288
300
|
const schema = sensor.getJSONSchema()
|
|
289
301
|
schema.htmlDescription = sensor.getDescription()
|
|
302
|
+
|
|
290
303
|
return {
|
|
291
304
|
info: getSensorInfo(sensor),
|
|
292
305
|
schema: schema,
|
|
293
|
-
config: config?config:{}
|
|
306
|
+
config: config?config:{},
|
|
307
|
+
configCopy: JSON.parse(JSON.stringify(config?config:{}))
|
|
294
308
|
}
|
|
295
309
|
}
|
|
296
310
|
|
|
@@ -576,11 +590,13 @@ module.exports = function (app) {
|
|
|
576
590
|
}
|
|
577
591
|
if (!(deviceConfigs===undefined)){
|
|
578
592
|
const maxTimeout=Math.max(...deviceConfigs.map((dc)=>dc?.discoveryTimeout??options.discoveryTimeout))
|
|
593
|
+
const totalDevices = deviceConfigs.filter((dc)=>dc.active).length
|
|
594
|
+
|
|
579
595
|
var progress = 0
|
|
580
596
|
if (progressID==null)
|
|
581
597
|
progressID = setInterval(()=>{
|
|
582
|
-
channel.broadcast({"progress":++progress, "maxTimeout": maxTimeout, "deviceCount":foundConfiguredDevices, "totalDevices":
|
|
583
|
-
if ( foundConfiguredDevices==
|
|
598
|
+
channel.broadcast({"progress":++progress, "maxTimeout": maxTimeout, "deviceCount":foundConfiguredDevices, "totalDevices": totalDevices},"progress")
|
|
599
|
+
if ( foundConfiguredDevices==totalDevices){
|
|
584
600
|
progressID,progressTimeoutID = null
|
|
585
601
|
clearTimeout(progressTimeoutID)
|
|
586
602
|
clearInterval(progressID)
|
|
@@ -593,7 +609,7 @@ module.exports = function (app) {
|
|
|
593
609
|
|
|
594
610
|
clearInterval(progressID);
|
|
595
611
|
progressID=null
|
|
596
|
-
channel.broadcast({"progress":maxTimeout, "maxTimeout": maxTimeout, "deviceCount":foundConfiguredDevices, "totalDevices":
|
|
612
|
+
channel.broadcast({"progress":maxTimeout, "maxTimeout": maxTimeout, "deviceCount":foundConfiguredDevices, "totalDevices": totalDevices},"progress")
|
|
597
613
|
}
|
|
598
614
|
}, (maxTimeout+1)*1000);
|
|
599
615
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bt-sensors-plugin-sk",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.5-1",
|
|
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": {
|
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,{default:()=>k});var a=n(73490),
|
|
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:()=>A,default:()=>k});var a=n(73490),s=n(74810),r=n(40334),o=n(86528),c=n.n(o),i=n(86452),l=n(27606),u=n(82096),m=n(3768),d=n(71431),g=n(39676),f=n(47041),p=n(86038),h=n(95027),E=n(43540),w=n(38250),y=n(31008),v=n(20455),S=n(23399);const b=e=>console.log.bind(console,e);function A(e){const t=(0,u.A)((e=>({root:{"& > *":{margin:e.spacing(1)}}}))),[n,A]=(0,o.useState)({}),[k,D]=(0,o.useState)({}),[C,x]=(0,o.useState)({}),[$,_]=(0,o.useState)({"ui:options":{label:!1},title:{"ui:widget":"hidden"}}),[T,N]=(0,o.useState)(),[O,j]=(0,o.useState)(new Map),[M,J]=(0,o.useState)({progress:0,maxTimeout:100,deviceCount:0,totalDevices:0}),[L,U]=(0,o.useState)("unknown"),[I,B]=(0,o.useState)(),P=t();function R(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 G(e){var t;try{t=fetch(`/plugins/bt-sensors-plugin-sk/${e}`,{credentials:"include"})}catch(e){t={status:500,statusText:e.toString()}}return t}function H(e){return Object.keys(e.configCopy).length>0}function K(e){const t=H(e);return c().createElement(v.A,{action:!0,onClick:()=>{e.config.mac_address=e.info.mac,x(e.schema),N(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 "},function(e){return null==e.info.lastContactDelta||e.info.lastContactDelta>e.config.discoveryTimeout?c().createElement(m.A,null):e.info.signalStrength>80?c().createElement(d.A,null):e.info.signalStrength>60?c().createElement(g.A,null):e.info.signalStrength>40?c().createElement(f.A,null):e.info.signalStrength>20?c().createElement(p.A,null):c().createElement(h.A,null)}(e))));var n}function F(e){window.open(e,"_blank","noreferrer")}return(0,o.useEffect)((()=>{let e=null;return G("getPluginState").then((async t=>{if(404==t.status)throw U("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}`),j((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);j((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);J(t)})),e.addEventListener("pluginstate",(e=>{const t=JSON.parse(e.data);U(t.state)})),U(n.state),(async()=>{const e=await async function(){const e=await G("getSensors");if(200!=e.status)throw new Error(`Unable get sensor data: ${e.statusText} (${e.status}) `);return await e.json()}();j(new Map(e.map((e=>[e.info.mac,e]))))})()})).catch((e=>{B(e)})),()=>{console.log("Closing connection to SSE"),e.close()}}),[]),(0,o.useEffect)((()=>{"started"==L?(async function(){const e=await G("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=>{A(e.schema),D(e.data)})).catch((e=>{B(e)})),async function(){const e=await G("getProgress");if(200!=e.status)throw new Error(`Unable to get progress: ${e.statusText} (${e.status}) `);return await e.json()}().then((e=>{J(e)})).catch((e=>{B(e)}))):(A({}),D({}))}),[L]),"stopped"==L||"unknown"==L?c().createElement("h3",null,"Enable plugin to see configuration"):c().createElement("div",null,c().createElement("div",{className:P.root},c().createElement(i.A,{variant:"contained",onClick:()=>{F("https://github.com/naugehyde/bt-sensors-plugin-sk/tree/1.2.0-beta#configuration")}},"Documentation"),c().createElement(i.A,{variant:"contained",onClick:()=>{F("https://github.com/naugehyde/bt-sensors-plugin-sk/issues/new/choose")}},"Report Issue"),c().createElement(i.A,{variant:"contained",onClick:()=>{F("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}}),I?c().createElement("h2",{style:"color: red;"},I):"",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,j(new Map),R("updateBaseData",n).then((e=>{200!=e.status&&B(new Error(`Unable to update base data: ${e.statusText} (${e.status})`))})),x({})},onError:b("errors"),formData:k}),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),M.deviceCount<M.totalDevices?c().createElement(S.A,{max:M.maxTimeout,now:M.progress}):"",c().createElement("p",null),c().createElement(w.A,{defaultActiveKey:"_configured",id:"domain-tabs",className:"mb-3"},function(){const e=[...new Set(O.entries().map((e=>e[1].info.domain)))].sort(),t=Array.from(O.entries()).filter((e=>H(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=>K(O.get(e[0])))),e.forEach((e=>{var t;n[e]=(t=e,Array.from(O.entries()).filter((e=>e[1].info.domain===t))).map((e=>K(O.get(e[0]))))})),Object.keys(n).map((e=>function(e,t){let n=e.slice("_"===e.charAt(0)?1:0);return c().createElement(y.A,{eventKey:e,title:`${n.charAt(0).toUpperCase()}${n.slice(1)}${"string"==typeof t?"":" ("+t.length+")"}`},c().createElement(E.A,{style:{maxHeight:"300px",overflowY:"auto"}},t))}(e,n[e])))}()),c().createElement("div",{style:{paddingLeft:10,paddingTop:10,display:0==Object.keys(C).length?"none":""}},c().createElement(l.A,{container:!0,direction:"column",style:{spacing:5}},c().createElement(l.A,{item:!0},c().createElement("h2",null,C?.title),c().createElement("p",null)),c().createElement(l.A,{item:!0},(0,r.Ay)(C?.htmlDescription))),c().createElement(a.Ay,{schema:C,validator:s.Ay,uiSchema:$,onChange:e=>{const t=O.get(e.formData.mac_address);t&&(t._changesMade=!0,t.config=e.formData,N(e.formData))},onSubmit:({formData:e},t)=>{var n;R("updateSensorData",n=e).then((e=>{if(200!=e.status)throw new Error(e.statusText);j((e=>(e.delete(n.mac_address),new Map(e)))),x({})})),alert("Changes saved")},onError:b("errors"),formData:T},c().createElement("div",{className:P.root},c().createElement(i.A,{type:"submit",color:"primary",variant:"contained"},"Save"),c().createElement(i.A,{variant:"contained",onClick:()=>{var e;e=T.mac_address,O.get(e)._changesMade=!1,O.get(e).config=JSON.parse(JSON.stringify(O.get(e).configCopy)),N(O.get(e).config)}},"Undo"),c().createElement(i.A,{variant:"contained",color:"secondary",onClick:e=>function(e){const t=O.get(e);(!H(t)||window.confirm(`Delete configuration for ${t.info.name}?`))&&function(e){try{R("removeSensorData",{mac_address:e}).then((e=>{if(200!=e.status)throw new Error(e.statusText)})),j((t=>(t.delete(e),new Map(t)))),x({})}catch{}}(e)}(T.mac_address)},"Delete")))))}const k=A}}]);
|
|
@@ -259,8 +259,8 @@ class MopekaTankSensor extends BTSensor{
|
|
|
259
259
|
|
|
260
260
|
async init(){
|
|
261
261
|
await super.init()
|
|
262
|
-
const md = this.
|
|
263
|
-
this.modelID = md[0]
|
|
262
|
+
const md = this.getManufacturerData(this.constructor.manufacturerID)
|
|
263
|
+
this.modelID = md?md[0]:0
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
getMedium(){
|
|
@@ -287,7 +287,7 @@ class MopekaTankSensor extends BTSensor{
|
|
|
287
287
|
this.addParameter("tankHeight",
|
|
288
288
|
{
|
|
289
289
|
title:"height of tank (in mm)",
|
|
290
|
-
type:"
|
|
290
|
+
type:"integer",
|
|
291
291
|
unit:"mm",
|
|
292
292
|
isRequired: true
|
|
293
293
|
}
|
|
@@ -323,12 +323,12 @@ class MopekaTankSensor extends BTSensor{
|
|
|
323
323
|
this.addMetadatum("accX","Mg","acceleration on X-axis",
|
|
324
324
|
(buffer)=>{ return buffer.readUInt8(8)}
|
|
325
325
|
)
|
|
326
|
-
.
|
|
326
|
+
.examples=["sensors.{macAndName}.accelerationXAxis"]
|
|
327
327
|
|
|
328
328
|
this.addMetadatum("accY","Mg","acceleration on Y-axis",
|
|
329
329
|
(buffer)=>{ return buffer.readUInt8(9)}
|
|
330
330
|
)
|
|
331
|
-
.
|
|
331
|
+
.examples=["sensors.{macAndName}.accelerationYAxis"]
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
propertiesChanged(props){
|
|
@@ -50,15 +50,15 @@ class RuuviTag extends BTSensor{
|
|
|
50
50
|
|
|
51
51
|
this.addMetadatum("accX","Mg","acceleration on X-axis",
|
|
52
52
|
(buffer)=>{ return buffer.readInt16BE(7)}
|
|
53
|
-
).
|
|
53
|
+
).examples=["sensors.{macAndName}.accX"]
|
|
54
54
|
|
|
55
55
|
this.addMetadatum("accY","Mg","acceleration on Y-axis",
|
|
56
56
|
(buffer)=>{ return buffer.readInt16BE(9)}
|
|
57
|
-
) .
|
|
57
|
+
) .examples=["sensors.{macAndName}.accY"]
|
|
58
58
|
|
|
59
59
|
this.addMetadatum("accZ","Mg","acceleration on Z-axis",
|
|
60
60
|
(buffer)=>{ return buffer.readInt16BE(11)}
|
|
61
|
-
) .
|
|
61
|
+
) .examples=["sensors.{macAndName}.accZ"]
|
|
62
62
|
|
|
63
63
|
this.addDefaultPath("battV","sensors.batteryVoltage")
|
|
64
64
|
.read=(buffer)=>{ return parseFloat((1.6+(buffer.readUInt16BE(13)>>5)/1000).toFixed(2))}
|
|
@@ -66,12 +66,12 @@ class RuuviTag extends BTSensor{
|
|
|
66
66
|
this.addMetadatum("mc","","movement counter",
|
|
67
67
|
(buffer)=>{ return buffer.readUInt16BE(13) && 0x1F}
|
|
68
68
|
)
|
|
69
|
-
.
|
|
69
|
+
.examples=["sensors.{macAndName}.movementCounter"]
|
|
70
70
|
|
|
71
71
|
this.addMetadatum("msc","","measurement sequence counter",
|
|
72
72
|
(buffer)=>{ return buffer.readUInt16BE(15)}
|
|
73
73
|
)
|
|
74
|
-
.
|
|
74
|
+
.examples=["sensors.{macAndName}.measurementSequenceCounter"]
|
|
75
75
|
|
|
76
76
|
}
|
|
77
77
|
|
|
@@ -15,9 +15,15 @@ function sleep(x) {
|
|
|
15
15
|
|
|
16
16
|
constructor(device,config,gattConfig){
|
|
17
17
|
super(device,config,gattConfig)
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
if(device.modelID)
|
|
20
|
+
this.modelID=device.modelID
|
|
21
|
+
|
|
19
22
|
}
|
|
20
23
|
|
|
24
|
+
static getModelID(md) {
|
|
25
|
+
return md[0x2e1]?.value.readUInt16LE(2)??-1
|
|
26
|
+
}
|
|
21
27
|
static async identifyMode(device, mode){
|
|
22
28
|
|
|
23
29
|
var md = await this.getDeviceProp(device,'ManufacturerData')
|
|
@@ -26,8 +32,10 @@ function sleep(x) {
|
|
|
26
32
|
else {
|
|
27
33
|
|
|
28
34
|
if (md[0x2e1].value[0]==0x10) {
|
|
29
|
-
if (md[0x2e1].value[4]==mode)
|
|
35
|
+
if (md[0x2e1].value[4]==mode) {
|
|
36
|
+
device.modelID=this.getModelID(md)
|
|
30
37
|
return this
|
|
38
|
+
}
|
|
31
39
|
else
|
|
32
40
|
return null
|
|
33
41
|
}
|
|
@@ -45,8 +53,10 @@ function sleep(x) {
|
|
|
45
53
|
await sleep(500)
|
|
46
54
|
}
|
|
47
55
|
device.helper.removeListeners()
|
|
48
|
-
if (md[0x2e1].value[4]==mode)
|
|
56
|
+
if (md[0x2e1].value[4]==mode) {
|
|
57
|
+
device.modelID=this.getModelID(md)
|
|
49
58
|
return this
|
|
59
|
+
}
|
|
50
60
|
else
|
|
51
61
|
return null
|
|
52
62
|
}
|
|
@@ -60,14 +70,13 @@ function sleep(x) {
|
|
|
60
70
|
title:"Encryption Key"
|
|
61
71
|
}
|
|
62
72
|
)
|
|
63
|
-
this.model_id=this.getManufacturerData(0x2e1)?.readUInt16LE(2)??"Unknown"
|
|
64
|
-
this._schema.title = this.getName()
|
|
65
73
|
}
|
|
66
74
|
alarmReason(alarmValue){
|
|
67
75
|
return this.constructor.AlarmReason[alarmValue]
|
|
68
76
|
}
|
|
69
77
|
getModelName(){
|
|
70
|
-
const
|
|
78
|
+
const mID = this.getModelID()
|
|
79
|
+
const m = VC.MODEL_ID_MAP[mID]
|
|
71
80
|
if(m) {
|
|
72
81
|
if(typeof m == 'string' || m instanceof String ) {
|
|
73
82
|
return m
|
|
@@ -75,7 +84,7 @@ function sleep(x) {
|
|
|
75
84
|
return m.name
|
|
76
85
|
}
|
|
77
86
|
}
|
|
78
|
-
return this.constructor.name
|
|
87
|
+
return this.constructor.name+` (Model ID: ${mID==-1?"Unknown":mID})`
|
|
79
88
|
}
|
|
80
89
|
|
|
81
90
|
decrypt(data){
|
|
@@ -98,6 +107,13 @@ function sleep(x) {
|
|
|
98
107
|
return Buffer.from(decData)
|
|
99
108
|
|
|
100
109
|
}
|
|
110
|
+
getModelID(){
|
|
111
|
+
if (!this.modelID ||this.modelID==-1)
|
|
112
|
+
this.modelID=this.getManufacturerData(0x2e1)?.readUInt16LE(2)??-1
|
|
113
|
+
|
|
114
|
+
return this.modelID
|
|
115
|
+
}
|
|
116
|
+
|
|
101
117
|
getName(){
|
|
102
118
|
return `Victron ${this.getModelName()}`
|
|
103
119
|
}
|
|
@@ -122,7 +138,7 @@ function sleep(x) {
|
|
|
122
138
|
}
|
|
123
139
|
|
|
124
140
|
getImage(){
|
|
125
|
-
const m = VC.MODEL_ID_MAP[this.
|
|
141
|
+
const m = VC.MODEL_ID_MAP[this.getModelID()]
|
|
126
142
|
if (m && m.image)
|
|
127
143
|
return m.image
|
|
128
144
|
else
|
|
@@ -138,5 +154,10 @@ function sleep(x) {
|
|
|
138
154
|
To get the encryption key for your device, follow the instructions <a href=https://communityarchive.victronenergy.com/questions/187303/victron-bluetooth-advertising-protocol.html target="_victron_encrypt">here</a>`
|
|
139
155
|
}
|
|
140
156
|
|
|
157
|
+
prepareConfig(config){
|
|
158
|
+
super.prepareConfig(config)
|
|
159
|
+
config.params.modelID=this.getModelID()
|
|
160
|
+
}
|
|
161
|
+
|
|
141
162
|
}
|
|
142
163
|
module.exports=VictronSensor
|