bt-sensors-plugin-sk 1.3.6-3 → 1.3.6-beta5
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 +22 -16
- package/README.md +7 -0
- package/package.json +1 -1
- package/plugin_defaults.json +1 -2
- package/public/124.js +1 -0
- package/public/159.js +1 -1
- package/public/540.js +1 -1
- package/public/598.js +8 -0
- package/public/{834.js.LICENSE.txt → 598.js.LICENSE.txt} +2 -0
- package/public/images/bm6.webp +0 -0
- package/public/main.js +1 -1
- package/public/remoteEntry.js +1 -1
- package/sensor_classes/BMBatteryMonitor.js +221 -0
- package/sensor_classes/Beacon/AbstractBeaconMixin.js +27 -9
- package/sensor_classes/FeasyComBeacon.js +1 -1
- package/sensor_classes/GobiusCTankMeter.js +15 -0
- package/sensor_classes/JBDBMS.js +357 -220
- package/sensor_classes/TestData/Jikong.json +36 -0
- package/sensor_classes/Victron/VictronSensor.js +7 -1
- package/sensor_classes/testxiaomi.js +45 -0
- package/src/components/BeaconRenderer.js +261 -0
- package/temp.html +0 -0
- package/testxiaomi.js +27 -0
- package/.vscode/settings.json +0 -2
- package/Screenshot 2025-06-12 at 9.33.57/342/200/257AM.png +0 -0
- package/bt-sensors-plugin-sk copy.json +0 -170
- package/bt-sensors-plugin-sk.json.bak +0 -121
- package/development/TestData/Jikong.json +0 -14
- package/diff.txt +0 -2860
- package/public/143.js +0 -1
- package/public/834.js +0 -14
- package/test.txt +0 -805
- package/testGATT.js +0 -24
- package/vsl_patch_17_06_25.patch +0 -13
|
@@ -19,6 +19,8 @@ object-assign
|
|
|
19
19
|
|
|
20
20
|
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
|
21
21
|
|
|
22
|
+
/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
|
23
|
+
|
|
22
24
|
/**
|
|
23
25
|
* @license React
|
|
24
26
|
* react-is.production.min.js
|
|
Binary file
|
package/public/main.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var e,r,t={49445:()=>{}},n={};function o(e){var r=n[e];if(void 0!==r)return r.exports;var a=n[e]={exports:{}};return t[e](a,a.exports,o),a.exports}o.m=t,o.c=n,o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce((
|
|
1
|
+
(()=>{var e,r,t={49445:()=>{}},n={};function o(e){var r=n[e];if(void 0!==r)return r.exports;var a=n[e]={exports:{}};return t[e](a,a.exports,o),a.exports}o.m=t,o.c=n,o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce((r,t)=>(o.f[t](e,r),r),[])),o.u=e=>e+".js",o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),e={},r="bt-sensors-plugin-sk:",o.l=(t,n,a,i)=>{if(e[t])e[t].push(n);else{var s,l;if(void 0!==a)for(var u=document.getElementsByTagName("script"),c=0;c<u.length;c++){var p=u[c];if(p.getAttribute("src")==t||p.getAttribute("data-webpack")==r+a){s=p;break}}s||(l=!0,(s=document.createElement("script")).charset="utf-8",s.timeout=120,o.nc&&s.setAttribute("nonce",o.nc),s.setAttribute("data-webpack",r+a),s.src=t),e[t]=[n];var d=(r,n)=>{s.onerror=s.onload=null,clearTimeout(f);var o=e[t];if(delete e[t],s.parentNode&&s.parentNode.removeChild(s),o&&o.forEach(e=>e(n)),r)return r(n)},f=setTimeout(d.bind(null,void 0,{type:"timeout",target:s}),12e4);s.onerror=d.bind(null,s.onerror),s.onload=d.bind(null,s.onload),l&&document.head.appendChild(s)}},(()=>{o.S={};var e={},r={};o.I=(t,n)=>{n||(n=[]);var a=r[t];if(a||(a=r[t]={}),!(n.indexOf(a)>=0)){if(n.push(a),e[t])return e[t];o.o(o.S,t)||(o.S[t]={});var i=o.S[t],s="bt-sensors-plugin-sk",l=[];return"default"===t&&((e,r,t,n)=>{var a=i[e]=i[e]||{},l=a[r];(!l||!l.loaded&&(1!=!l.eager?n:s>l.from))&&(a[r]={get:()=>o.e(159).then(()=>()=>o(96540)),from:s,eager:!1})})("react","16.14.0"),e[t]=l.length?Promise.all(l).then(()=>e[t]=1):1}}})(),(()=>{var e;o.g.importScripts&&(e=o.g.location+"");var r=o.g.document;if(!e&&r&&(r.currentScript&&"SCRIPT"===r.currentScript.tagName.toUpperCase()&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var n=t.length-1;n>-1&&(!e||!/^http(s?):/.test(e));)e=t[n--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),o.p=e})(),(()=>{var e={792:0};o.f.j=(r,t)=>{var n=o.o(e,r)?e[r]:void 0;if(0!==n)if(n)t.push(n[2]);else{var a=new Promise((t,o)=>n=e[r]=[t,o]);t.push(n[2]=a);var i=o.p+o.u(r),s=new Error;o.l(i,t=>{if(o.o(e,r)&&(0!==(n=e[r])&&(e[r]=void 0),n)){var a=t&&("load"===t.type?"missing":t.type),i=t&&t.target&&t.target.src;s.message="Loading chunk "+r+" failed.\n("+a+": "+i+")",s.name="ChunkLoadError",s.type=a,s.request=i,n[1](s)}},"chunk-"+r,r)}};var r=(r,t)=>{var n,a,[i,s,l]=t,u=0;if(i.some(r=>0!==e[r])){for(n in s)o.o(s,n)&&(o.m[n]=s[n]);l&&l(o)}for(r&&r(t);u<i.length;u++)a=i[u],o.o(e,a)&&e[a]&&e[a][0](),e[a]=0},t=self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),o(49445)})();
|
package/public/remoteEntry.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var bt_sensors_plugin_sk;(()=>{"use strict";var e,r,t,n,a,o,i,u,s,l,f,d,c,p,h,v,g,b,m,y,w,k={43237:(e,r,t)=>{var n={"./PluginConfigurationPanel":()=>Promise.all([t.e(
|
|
1
|
+
var bt_sensors_plugin_sk;(()=>{"use strict";var e,r,t,n,a,o,i,u,s,l,f,d,c,p,h,v,g,b,m,y,w,k={43237:(e,r,t)=>{var n={"./PluginConfigurationPanel":()=>Promise.all([t.e(598),t.e(124)]).then(()=>()=>t(62995))},a=(e,r)=>(t.R=r,r=t.o(n,e)?n[e]():Promise.resolve().then(()=>{throw new Error('Module "'+e+'" does not exist in container.')}),t.R=void 0,r),o=(e,r)=>{if(t.S){var n="default",a=t.S[n];if(a&&a!==e)throw new Error("Container initialization failed as it has already been initialized with a different share scope");return t.S[n]=e,t.I(n,r)}};t.d(r,{get:()=>a,init:()=>o})}},S={};function _(e){var r=S[e];if(void 0!==r)return r.exports;var t=S[e]={id:e,loaded:!1,exports:{}};return k[e].call(t.exports,t,t.exports,_),t.loaded=!0,t.exports}_.m=k,_.c=S,_.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return _.d(r,{a:r}),r},_.d=(e,r)=>{for(var t in r)_.o(r,t)&&!_.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},_.f={},_.e=e=>Promise.all(Object.keys(_.f).reduce((r,t)=>(_.f[t](e,r),r),[])),_.u=e=>e+".js",_.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),_.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),e={},r="bt-sensors-plugin-sk:",_.l=(t,n,a,o)=>{if(e[t])e[t].push(n);else{var i,u;if(void 0!==a)for(var s=document.getElementsByTagName("script"),l=0;l<s.length;l++){var f=s[l];if(f.getAttribute("src")==t||f.getAttribute("data-webpack")==r+a){i=f;break}}i||(u=!0,(i=document.createElement("script")).charset="utf-8",i.timeout=120,_.nc&&i.setAttribute("nonce",_.nc),i.setAttribute("data-webpack",r+a),i.src=t),e[t]=[n];var d=(r,n)=>{i.onerror=i.onload=null,clearTimeout(c);var a=e[t];if(delete e[t],i.parentNode&&i.parentNode.removeChild(i),a&&a.forEach(e=>e(n)),r)return r(n)},c=setTimeout(d.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=d.bind(null,i.onerror),i.onload=d.bind(null,i.onload),u&&document.head.appendChild(i)}},_.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},_.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{_.S={};var e={},r={};_.I=(t,n)=>{n||(n=[]);var a=r[t];if(a||(a=r[t]={}),!(n.indexOf(a)>=0)){if(n.push(a),e[t])return e[t];_.o(_.S,t)||(_.S[t]={});var o=_.S[t],i="bt-sensors-plugin-sk",u=[];return"default"===t&&((e,r,t,n)=>{var a=o[e]=o[e]||{},u=a[r];(!u||!u.loaded&&(1!=!u.eager?n:i>u.from))&&(a[r]={get:()=>_.e(159).then(()=>()=>_(96540)),from:i,eager:!1})})("react","16.14.0"),e[t]=u.length?Promise.all(u).then(()=>e[t]=1):1}}})(),(()=>{var e;_.g.importScripts&&(e=_.g.location+"");var r=_.g.document;if(!e&&r&&(r.currentScript&&"SCRIPT"===r.currentScript.tagName.toUpperCase()&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var n=t.length-1;n>-1&&(!e||!/^http(s?):/.test(e));)e=t[n--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),_.p=e})(),t=e=>{var r=e=>e.split(".").map(e=>+e==e?+e:e),t=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(e),n=t[1]?r(t[1]):[];return t[2]&&(n.length++,n.push.apply(n,r(t[2]))),t[3]&&(n.push([]),n.push.apply(n,r(t[3]))),n},n=(e,r)=>{e=t(e),r=t(r);for(var n=0;;){if(n>=e.length)return n<r.length&&"u"!=(typeof r[n])[0];var a=e[n],o=(typeof a)[0];if(n>=r.length)return"u"==o;var i=r[n],u=(typeof i)[0];if(o!=u)return"o"==o&&"n"==u||"s"==u||"u"==o;if("o"!=o&&"u"!=o&&a!=i)return a<i;n++}},a=e=>{var r=e[0],t="";if(1===e.length)return"*";if(r+.5){t+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var n=1,o=1;o<e.length;o++)n--,t+="u"==(typeof(u=e[o]))[0]?"-":(n>0?".":"")+(n=2,u);return t}var i=[];for(o=1;o<e.length;o++){var u=e[o];i.push(0===u?"not("+s()+")":1===u?"("+s()+" || "+s()+")":2===u?i.pop()+" "+i.pop():a(u))}return s();function s(){return i.pop().replace(/^\((.+)\)$/,"$1")}},o=(e,r)=>{if(0 in e){r=t(r);var n=e[0],a=n<0;a&&(n=-n-1);for(var i=0,u=1,s=!0;;u++,i++){var l,f,d=u<e.length?(typeof e[u])[0]:"";if(i>=r.length||"o"==(f=(typeof(l=r[i]))[0]))return!s||("u"==d?u>n&&!a:""==d!=a);if("u"==f){if(!s||"u"!=d)return!1}else if(s)if(d==f)if(u<=n){if(l!=e[u])return!1}else{if(a?l>e[u]:l<e[u])return!1;l!=e[u]&&(s=!1)}else if("s"!=d&&"n"!=d){if(a||u<=n)return!1;s=!1,u--}else{if(u<=n||f<d!=a)return!1;s=!1}else"s"!=d&&"n"!=d&&(s=!1,u--)}}var c=[],p=c.pop.bind(c);for(i=1;i<e.length;i++){var h=e[i];c.push(1==h?p()|p():2==h?p()&p():h?o(h,r):!p())}return!!p()},i=(e,r)=>e&&_.o(e,r),u=e=>(e.loaded=1,e.get()),s=e=>Object.keys(e).reduce((r,t)=>(e[t].eager&&(r[t]=e[t]),r),{}),l=(e,r,t)=>{var a=t?s(e[r]):e[r];return(r=Object.keys(a).reduce((e,r)=>!e||n(e,r)?r:e,0))&&a[r]},f=(e,r,t,a)=>{var i=a?s(e[r]):e[r];return(r=Object.keys(i).reduce((e,r)=>!o(t,r)||e&&!n(e,r)?e:r,0))&&i[r]},d=(e,r,t,n,o)=>{var i=e[t];return"No satisfying version ("+a(n)+")"+(o?" for eager consumption":"")+" of shared module "+t+" found in shared scope "+r+".\nAvailable versions: "+Object.keys(i).map(e=>e+" from "+i[e].from).join(", ")},c=e=>{throw new Error(e)},h=(e,r,t)=>t?t():((e,r)=>c("Shared module "+r+" doesn't exist in shared scope "+e))(e,r),v=(p=e=>function(r,t,n,a,o){var i=_.I(r);return i&&i.then&&!n?i.then(e.bind(e,r,_.S[r],t,!1,a,o)):e(r,_.S[r],t,n,a,o)})((e,r,t,n,a)=>i(r,t)?u(l(r,t,n)):h(e,t,a)),g=p((e,r,t,n,a,o)=>{if(!i(r,t))return h(e,t,o);var s=f(r,t,a,n);return s?u(s):o?o():void c(d(r,e,t,a,n))}),b={},m={11097:()=>g("default","react",!1,[0,16],()=>_.e(540).then(()=>()=>_(96540))),21490:()=>g("default","react",!1,[,[1,17,0,0],[1,16,8,0],1],()=>_.e(540).then(()=>()=>_(96540))),42417:()=>g("default","react",!1,[0,16,8,0],()=>_.e(540).then(()=>()=>_(96540))),44167:()=>v("default","react",!1,()=>_.e(540).then(()=>()=>_(96540))),57920:()=>g("default","react",!1,[,[0,17],[1,16,14,0],1],()=>_.e(540).then(()=>()=>_(96540))),61104:()=>g("default","react",!1,[,[1,16,0,0,,0],[1,15,0,0],[2,0,14,0],1,1],()=>_.e(540).then(()=>()=>_(96540))),62085:()=>g("default","react",!1,[1,16,14,0],()=>_.e(540).then(()=>()=>_(96540))),64147:()=>g("default","react",!1,[1,16,13,1],()=>_.e(540).then(()=>()=>_(96540))),87227:()=>g("default","react",!1,[0,16,6,0],()=>_.e(540).then(()=>()=>_(96540))),96932:()=>g("default","react",!1,[0,15,0,0],()=>_.e(540).then(()=>()=>_(96540))),98271:()=>g("default","react",!1,[0,0,14,0],()=>_.e(540).then(()=>()=>_(96540)))},y={124:[11097,21490,42417,44167,57920,61104,62085,64147,87227,96932,98271]},w={},_.f.consumes=(e,r)=>{_.o(y,e)&&y[e].forEach(e=>{if(_.o(b,e))return r.push(b[e]);if(!w[e]){var t=r=>{b[e]=0,_.m[e]=t=>{delete _.c[e],t.exports=r()}};w[e]=!0;var n=r=>{delete b[e],_.m[e]=t=>{throw delete _.c[e],r}};try{var a=m[e]();a.then?r.push(b[e]=a.then(t).catch(n)):t(a)}catch(e){n(e)}}})},(()=>{var e={592:0};_.f.j=(r,t)=>{var n=_.o(e,r)?e[r]:void 0;if(0!==n)if(n)t.push(n[2]);else{var a=new Promise((t,a)=>n=e[r]=[t,a]);t.push(n[2]=a);var o=_.p+_.u(r),i=new Error;_.l(o,t=>{if(_.o(e,r)&&(0!==(n=e[r])&&(e[r]=void 0),n)){var a=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src;i.message="Loading chunk "+r+" failed.\n("+a+": "+o+")",i.name="ChunkLoadError",i.type=a,i.request=o,n[1](i)}},"chunk-"+r,r)}};var r=(r,t)=>{var n,a,[o,i,u]=t,s=0;if(o.some(r=>0!==e[r])){for(n in i)_.o(i,n)&&(_.m[n]=i[n]);u&&u(_)}for(r&&r(t);s<o.length;s++)a=o[s],_.o(e,a)&&e[a]&&e[a][0](),e[a]=0},t=self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})();var j=_(43237);bt_sensors_plugin_sk=j})();
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
const { buffer } = require("stream/consumers");
|
|
2
|
+
const BTSensor = require("../BTSensor");
|
|
3
|
+
const crypto = require("crypto");
|
|
4
|
+
|
|
5
|
+
//69 7e a0 b5 d5 4c f0 24 e7 94 77 23 55 55 41 14
|
|
6
|
+
|
|
7
|
+
class BMBatteryMonitor extends BTSensor {
|
|
8
|
+
static Domain = BTSensor.SensorDomains.electrical;
|
|
9
|
+
static GATT_SERVICE_UUID = "0000fff0-0000-1000-8000-00805f9b34fb";
|
|
10
|
+
static GATT_READ_UUID = "0000fff4-0000-1000-8000-00805f9b34fb";
|
|
11
|
+
static GATT_WRITE_UUID = "0000fff3-0000-1000-8000-00805f9b34fb";
|
|
12
|
+
static cryptKeys = {
|
|
13
|
+
2: Buffer.from([
|
|
14
|
+
0x6c,
|
|
15
|
+
0x65,
|
|
16
|
+
0x61,
|
|
17
|
+
0x67,
|
|
18
|
+
0x65,
|
|
19
|
+
0x6e,
|
|
20
|
+
0x64,
|
|
21
|
+
0xff,
|
|
22
|
+
0xfe,
|
|
23
|
+
0x31,
|
|
24
|
+
0x38,
|
|
25
|
+
0x38,
|
|
26
|
+
0x32,
|
|
27
|
+
0x34,
|
|
28
|
+
0x36,
|
|
29
|
+
0x36,
|
|
30
|
+
]),
|
|
31
|
+
6: Buffer.from([
|
|
32
|
+
0x6c,
|
|
33
|
+
0x65,
|
|
34
|
+
0x61,
|
|
35
|
+
0x67,
|
|
36
|
+
0x65,
|
|
37
|
+
0x6e,
|
|
38
|
+
0x64,
|
|
39
|
+
0xff,
|
|
40
|
+
0xfe,
|
|
41
|
+
0x30,
|
|
42
|
+
0x31,
|
|
43
|
+
0x30,
|
|
44
|
+
0x30,
|
|
45
|
+
0x30,
|
|
46
|
+
0x30,
|
|
47
|
+
0x39,
|
|
48
|
+
]),
|
|
49
|
+
7: Buffer.from([
|
|
50
|
+
0x6c,
|
|
51
|
+
0x65,
|
|
52
|
+
0x61,
|
|
53
|
+
0x67,
|
|
54
|
+
0x65,
|
|
55
|
+
0x6e,
|
|
56
|
+
0x64,
|
|
57
|
+
0xff,
|
|
58
|
+
0xfe,
|
|
59
|
+
0x30,
|
|
60
|
+
0x31,
|
|
61
|
+
0x30,
|
|
62
|
+
0x30,
|
|
63
|
+
0x30,
|
|
64
|
+
0x30,
|
|
65
|
+
0x40,
|
|
66
|
+
]),
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
static BatteryState = {
|
|
70
|
+
0: "Normal",
|
|
71
|
+
1: "Low voltage",
|
|
72
|
+
2: "Charging",
|
|
73
|
+
};
|
|
74
|
+
static COMMAND_HEX = "d1550700000000000000000000000000";
|
|
75
|
+
|
|
76
|
+
static async identify(device) {
|
|
77
|
+
const name = await this.getDeviceProp(device, "Name");
|
|
78
|
+
|
|
79
|
+
if (name && /BM[2|6|7]$/.test(name)) return this;
|
|
80
|
+
else return null;
|
|
81
|
+
}
|
|
82
|
+
static ImageFile = "bm6.webp";
|
|
83
|
+
|
|
84
|
+
createCipher(encrypt = true) {
|
|
85
|
+
const iv = Buffer.alloc(16, 0);
|
|
86
|
+
const cipher = encrypt
|
|
87
|
+
? crypto.createCipheriv("aes-128-cbc", this._getCryptKey(), iv)
|
|
88
|
+
: crypto.createDecipheriv("aes-128-cbc", this._getCryptKey(), iv);
|
|
89
|
+
cipher.setAutoPadding(false);
|
|
90
|
+
return cipher;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
encryptCommand() {
|
|
94
|
+
const cipher = this.createCipher();
|
|
95
|
+
const plaintext = Buffer.from(this.constructor.COMMAND_HEX, "hex");
|
|
96
|
+
return Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
decryptPayload(payload) {
|
|
100
|
+
const cipher = this.createCipher(false);
|
|
101
|
+
const decrypted = Buffer.concat([cipher.update(payload), cipher.final()]);
|
|
102
|
+
return decrypted;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
hasGATT() {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
usingGATT() {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async emitGATT() {
|
|
113
|
+
return new Promise(async (resolve, reject) => {
|
|
114
|
+
await this.read.startNotifications();
|
|
115
|
+
await this.write.writeValueWithResponse(
|
|
116
|
+
this.encryptCommand(this._getCryptKey())
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
const timer = setTimeout(() => {
|
|
120
|
+
this.read.removeAllListeners();
|
|
121
|
+
clearTimeout(timer);
|
|
122
|
+
reject(
|
|
123
|
+
new Error(
|
|
124
|
+
`Response timed out (+30s) getting results for command ${command} from BM device ${this.getName()}.`
|
|
125
|
+
)
|
|
126
|
+
);
|
|
127
|
+
}, 30000);
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
this.read.once("valuechanged", (buffer) => {
|
|
131
|
+
this.read.stopNotifications();
|
|
132
|
+
clearTimeout(timer);
|
|
133
|
+
this.emitValuesFrom(buffer);
|
|
134
|
+
resolve(this);
|
|
135
|
+
});
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
_getCryptKey() {
|
|
139
|
+
return this.constructor.cryptKeys[this.monitorVersion];
|
|
140
|
+
}
|
|
141
|
+
initSchema() {
|
|
142
|
+
super.initSchema();
|
|
143
|
+
this.getGATTParams()["useGATT"].default = true;
|
|
144
|
+
this.addParameter("monitorVersion", {
|
|
145
|
+
title: "monitor version", //unclear if version 2 has same GATT characteristics and data format
|
|
146
|
+
enum: [2, 6, 7],
|
|
147
|
+
isRequired: true,
|
|
148
|
+
type: "number",
|
|
149
|
+
default: 6,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
this.addDefaultParam("batteryID");
|
|
153
|
+
|
|
154
|
+
this.addDefaultPath("voltage", "electrical.batteries.voltage").read = (
|
|
155
|
+
buffer
|
|
156
|
+
) => {
|
|
157
|
+
return buffer.readUInt16BE(7) / 100;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
this.addDefaultPath(
|
|
161
|
+
"soc",
|
|
162
|
+
"electrical.batteries.capacity.stateOfCharge"
|
|
163
|
+
).read = (buffer) => {
|
|
164
|
+
return buffer.readUInt8(6) / 100;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
this.addMetadatum("batteryState", "", "battery state", (buff) => {
|
|
168
|
+
return this.constructor.BatteryState[buff.readUInt8(5)];
|
|
169
|
+
}).default = "electrical.batteries.{batteryID}.state";
|
|
170
|
+
|
|
171
|
+
this.addDefaultPath(
|
|
172
|
+
"temperature",
|
|
173
|
+
"electrical.batteries.temperature"
|
|
174
|
+
).read = (buffer) => {
|
|
175
|
+
return (buffer.readUInt8(3) ? -1 : 1) * buffer.readUInt8(4) + 273.15;
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async initGATTConnection(isReconnecting) {
|
|
180
|
+
await super.initGATTConnection(isReconnecting);
|
|
181
|
+
const gattServer = await this.getGATTServer();
|
|
182
|
+
const service = await gattServer.getPrimaryService(
|
|
183
|
+
this.constructor.GATT_SERVICE_UUID
|
|
184
|
+
);
|
|
185
|
+
this.write = await service.getCharacteristic(
|
|
186
|
+
this.constructor.GATT_WRITE_UUID
|
|
187
|
+
);
|
|
188
|
+
this.read = await service.getCharacteristic(
|
|
189
|
+
this.constructor.GATT_READ_UUID
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
emitValuesFrom(buffer) {
|
|
194
|
+
if (buffer.length < 16) {
|
|
195
|
+
this.debug(`Received invalid buffer ${JSON.stringify(buffer)}`);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const b = this.decryptPayload(buffer);
|
|
199
|
+
if (Buffer.compare(b.subarray(0, 3), Buffer.from([0xd1, 0x55, 0x07])) == 0)
|
|
200
|
+
super.emitValuesFrom(b);
|
|
201
|
+
else
|
|
202
|
+
this.debug(`Received invalid decrypted buffer ${JSON.stringify(b)}`);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
async initGATTNotifications() {
|
|
206
|
+
await this.read.startNotifications();
|
|
207
|
+
await this.write.writeValueWithResponse(
|
|
208
|
+
this.encryptCommand(this._getCryptKey())
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
this.read.on("valuechanged", (buffer) => {
|
|
212
|
+
this.emitValuesFrom(buffer);
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
async deactivateGATT() {
|
|
217
|
+
await this.stopGATTNotifications(this.read);
|
|
218
|
+
await super.deactivateGATT();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
module.exports = BMBatteryMonitor;
|
|
@@ -5,7 +5,7 @@ function getDistances(distanceManager, mac, txPower, rssi ){
|
|
|
5
5
|
const accuracy = (Math.min(1,+(txPower/rssi).toFixed(3)))
|
|
6
6
|
return {
|
|
7
7
|
avgDistance: +distanceManager.getDistance(mac, txPower, DistanceManager.METHOD_AVG, true).toFixed(2),
|
|
8
|
-
|
|
8
|
+
weightedAvgDistance: +distanceManager.getDistance(mac, txPower, DistanceManager.METHOD_WEIGHTED_AVG, true).toFixed(2),
|
|
9
9
|
sampledDistance: +distanceManager.getDistance(mac, txPower, DistanceManager.METHOD_LAST_FEW_SAMPLES, true).toFixed(2),
|
|
10
10
|
accuracy: accuracy
|
|
11
11
|
}
|
|
@@ -20,7 +20,7 @@ class AbstractBeaconMixin {
|
|
|
20
20
|
this.propertiesChanged=this.propertiesChanged.bind(obj)
|
|
21
21
|
this.activate=this.activate.bind(obj)
|
|
22
22
|
this.stopListening=this.stopListening.bind(obj)
|
|
23
|
-
obj.GPSLog=[]
|
|
23
|
+
obj.GPSLog={log:[],beam:0,loa:0}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
initListen() {
|
|
@@ -86,16 +86,17 @@ class AbstractBeaconMixin {
|
|
|
86
86
|
this.emit("approxDistance", distances)
|
|
87
87
|
this.emit("onBoard", distances.avgDistance<this?.presenceThreshold??20)
|
|
88
88
|
}
|
|
89
|
-
if (
|
|
90
|
-
this.GPSLog.unshift(
|
|
89
|
+
if (his.GPSLog.currentPosition){
|
|
90
|
+
this.GPSLog.log.unshift(
|
|
91
91
|
{
|
|
92
92
|
timestamp: new Date().toISOString(),
|
|
93
|
-
|
|
94
|
-
longitude: this._position.longitude,
|
|
93
|
+
heading: this.GPSLog.heading,
|
|
95
94
|
distances: distances
|
|
96
95
|
})
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
Object.assign(this.GPSLog.log[0], this.GPSLog.currentPosition)
|
|
97
|
+
|
|
98
|
+
if (this.GPSLog.log.length>AbstractBeaconMixin.logSize){
|
|
99
|
+
this.GPSLog.log = this.GPSLog.log.slice(0,AbstractBeaconMixin.logSize)
|
|
99
100
|
}
|
|
100
101
|
this.emit("GPSLog", this.GPSLog)
|
|
101
102
|
}
|
|
@@ -104,13 +105,26 @@ class AbstractBeaconMixin {
|
|
|
104
105
|
|
|
105
106
|
async activate(config,paths){
|
|
106
107
|
|
|
108
|
+
this.GPSLog.beam=this._app.getSelfPath('design.beam')
|
|
109
|
+
this.GPSLog.loa=this._app.getSelfPath('design.length.overall')
|
|
110
|
+
|
|
107
111
|
this._positionSub = this._app.streambundle.getSelfStream('navigation.position')
|
|
108
112
|
.onValue(
|
|
109
113
|
(pos) => {
|
|
110
|
-
this.
|
|
114
|
+
this.GPSLog.currentPosition=pos
|
|
115
|
+
|
|
116
|
+
this.emit("GPSLog",this.GPSLog)
|
|
111
117
|
}
|
|
112
118
|
);
|
|
113
119
|
|
|
120
|
+
this._headingSub = this._app.streambundle.getSelfStream('navigation.headingTrue')
|
|
121
|
+
.onValue(
|
|
122
|
+
(pos) => {
|
|
123
|
+
this.GPSLog.heading=heading
|
|
124
|
+
|
|
125
|
+
this.emit("GPSLog",this.GPSLog)
|
|
126
|
+
}
|
|
127
|
+
);
|
|
114
128
|
}
|
|
115
129
|
|
|
116
130
|
async stopListening(){
|
|
@@ -118,6 +132,10 @@ class AbstractBeaconMixin {
|
|
|
118
132
|
this._positionSub()
|
|
119
133
|
this._positionSub = null
|
|
120
134
|
}
|
|
135
|
+
if (this._headingSub){
|
|
136
|
+
this._headingSub()
|
|
137
|
+
this._headingSub = null
|
|
138
|
+
}
|
|
121
139
|
}
|
|
122
140
|
|
|
123
141
|
}
|
|
@@ -301,6 +301,16 @@ class GobiusCTankMeter extends BTSensor{
|
|
|
301
301
|
this.addDefaultParam("id")
|
|
302
302
|
.default="1"
|
|
303
303
|
|
|
304
|
+
this.addParameter("capacity",
|
|
305
|
+
{
|
|
306
|
+
title:"capacity of tank in m3 (liters/1000)",
|
|
307
|
+
type:"number",
|
|
308
|
+
unit:"m3",
|
|
309
|
+
isRequired: true,
|
|
310
|
+
default:10000
|
|
311
|
+
}
|
|
312
|
+
)
|
|
313
|
+
|
|
304
314
|
this.addMetadatum("mst","","Device state",
|
|
305
315
|
(buffer)=>{return GobiusState.get(buffer.readInt8(0))}
|
|
306
316
|
)
|
|
@@ -322,6 +332,11 @@ class GobiusCTankMeter extends BTSensor{
|
|
|
322
332
|
)
|
|
323
333
|
.default='tanks.{type}.{id}.currentLevel'
|
|
324
334
|
|
|
335
|
+
this.addMetadatum("mfr","m3","Remaining volume",
|
|
336
|
+
(buffer)=>{return this.capacity*(buffer.readInt16BE(3)/1000)}
|
|
337
|
+
)
|
|
338
|
+
.default='tanks.{type}.{id}.remaining'
|
|
339
|
+
|
|
325
340
|
this.addMetadatum("minc","rad","Sensor inclination",
|
|
326
341
|
(buffer)=>{return buffer.readInt8(5) * Math.PI/180}
|
|
327
342
|
)
|