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.
@@ -1,255 +1,392 @@
1
1
  const BTSensor = require("../BTSensor");
2
+
2
3
  function sumByteArray(byteArray) {
3
- let sum = 0;
4
- for (let i = 0; i < byteArray.length; i++) {
5
- sum += byteArray[i];
6
- }
7
- return sum;
8
- }
9
-
10
- function checkSum(buffer){
11
- if (buffer.length<5) {
12
- console.log (`Can't checksum ${buffer}. Invalid buffer. Buffer must be at least 5 bytes long.`)
13
- return false
14
- }
15
- const checksum = buffer.readUInt16BE(buffer.length-3)
16
- let sum = sumByteArray(Uint8Array.prototype.slice.call(buffer, 2, buffer.length-3))
17
- if ((0xffff-sum)+1 == checksum) return true
18
- sum = sumByteArray(Uint8Array.prototype.slice.call(buffer, 2, buffer.length-2))
19
- return (0xffff-sum)+1 == checksum
4
+ let sum = 0;
5
+ for (let i = 0; i < byteArray.length; i++) {
6
+ sum += byteArray[i];
7
+ }
8
+ return sum;
9
+ }
10
+
11
+ function checkSum(buffer) {
12
+ if (buffer.length < 5) {
13
+ console.log(
14
+ `Can't checksum ${buffer}. Invalid buffer. Buffer must be at least 5 bytes long.`
15
+ );
16
+ return false;
17
+ }
18
+ const checksum = buffer.readUInt16BE(buffer.length - 3);
19
+ let sum = sumByteArray(
20
+ Uint8Array.prototype.slice.call(buffer, 2, buffer.length - 3)
21
+ );
22
+ if (0xffff - sum + 1 == checksum) return true;
23
+ sum = sumByteArray(
24
+ Uint8Array.prototype.slice.call(buffer, 2, buffer.length - 2)
25
+ );
26
+ return 0xffff - sum + 1 == checksum;
20
27
  }
21
28
 
22
29
  class JBDBMS extends BTSensor {
23
- static Domain = BTSensor.SensorDomains.electrical
30
+ static Domain = BTSensor.SensorDomains.electrical;
24
31
 
25
- static TX_RX_SERVICE = "0000ff00-0000-1000-8000-00805f9b34fb"
26
- static NOTIFY_CHAR_UUID = "0000ff01-0000-1000-8000-00805f9b34fb"
27
- static WRITE_CHAR_UUID = "0000ff02-0000-1000-8000-00805f9b34fb"
28
-
29
- static identify(device){
30
- return null
32
+ static TX_RX_SERVICE = "0000ff00-0000-1000-8000-00805f9b34fb";
33
+ static NOTIFY_CHAR_UUID = "0000ff01-0000-1000-8000-00805f9b34fb";
34
+ static WRITE_CHAR_UUID = "0000ff02-0000-1000-8000-00805f9b34fb";
35
+
36
+ static identify(device) {
37
+ return null;
31
38
  }
32
- static ImageFile = "JBDBMS.webp"
39
+ static ImageFile = "JBDBMS.webp";
33
40
 
34
41
  jbdCommand(command) {
35
- return [0xDD, 0xA5, command, 0x00, 0xFF, 0xFF - (command - 1), 0x77]
36
- }
37
-
38
- async sendReadFunctionRequest( command ){
39
- this.debug( `sending ${command}`)
40
- return await this.txChar.writeValueWithoutResponse(Buffer.from(this.jbdCommand(command)))
41
- }
42
-
43
- async initSchema(){
44
- super.initSchema()
45
- this.addDefaultParam("batteryID")
46
-
47
- this.addDefaultPath('voltage','electrical.batteries.voltage')
48
- .read=
49
- (buffer)=>{return buffer.readUInt16BE(4) / 100}
50
-
51
- this.addDefaultPath('current','electrical.batteries.current')
52
- .read=
53
- (buffer)=>{return buffer.readInt16BE(6) / 100}
54
-
55
- this.addDefaultPath('remainingCapacity','electrical.batteries.capacity.remaining')
56
- .read=(buffer)=>{return (buffer.readUInt16BE(8) / 100)*3600}
57
-
58
- this.addDefaultPath('capacity','electrical.batteries.capacity.actual')
59
- .read=(buffer)=>{return (buffer.readUInt16BE(10) / 100)*3600}
60
-
61
- this.addDefaultPath('cycles','electrical.batteries.cycles' )
62
- .read=(buffer)=>{return buffer.readUInt16BE(12)}
63
-
64
- this.addMetadatum('protectionStatus', '', 'Protection Status',
65
- (buffer)=>{
66
- const bits = buffer.readUInt16BE(20).toString(2)
67
- return {
68
- singleCellOvervolt: bits[0]=='1',
69
- singleCellUndervolt: bits[1]=='1',
70
- packOvervolt: (bits[2]=='1'),
71
- packUndervolt: bits[3]=='1',
72
- chargeOvertemp:bits[4]=='1',
73
- chargeUndertemp:bits[5]=='1',
74
- dischargeOvertemp:bits[6]=='1',
75
- dischargeUndertemp:bits[7]=='1',
76
- chargeOvercurrent:bits[8]=='1',
77
- dischargeOvercurrent:bits[9]=='1',
78
- shortCircut:bits[10]=='1',
79
- frontEndDetectionICError:bits[11]=='1',
80
- softwareLockMOS:bits[12]=='1',
81
- }
82
- })
83
- .default="electrical.batteries.{batteryID}.protectionStatus"
84
-
85
- this.addDefaultPath('SOC','electrical.batteries.capacity.stateOfCharge')
86
- .read=(buffer)=>{return buffer.readUInt8(23)/100}
87
-
88
-
89
- this.addMetadatum('FET', '', 'FET On/Off Status',
90
- (buffer)=>{return buffer.readUInt8(24) !=0 } )
91
- .default="electrical.batteries.{batteryID}.FETStatus"
92
-
93
- this.addMetadatum('FETCharging', '', 'FET Status Charging',
94
- (buffer)=>{return (buffer.readUInt8(24) & 0x1) !=0 })
95
- .default="electrical.batteries.{batteryID}.FETStatus.charging"
96
-
97
- this.addMetadatum('FETDischarging', '', 'FET Status Discharging',
98
- (buffer)=>{return (buffer.readUInt8(24) & 0x2) !=0 })
99
- .default="electrical.batteries.{batteryID}.FETStatus.discharging"
100
-
101
- await this.deviceConnect()
102
- const gattServer = await this.device.gatt()
103
- const txRxService= await gattServer.getPrimaryService(this.constructor.TX_RX_SERVICE)
104
- this.rxChar = await txRxService.getCharacteristic(this.constructor.NOTIFY_CHAR_UUID)
105
- this.txChar = await txRxService.getCharacteristic(this.constructor.WRITE_CHAR_UUID)
106
- await this.rxChar.startNotifications()
107
-
108
- const cellsAndTemps = await this.getNumberOfCellsAndTemps()
109
- this.numberOfCells=cellsAndTemps.cells
110
- this.numberOfTemps=cellsAndTemps.temps
111
-
112
- for (let i=0; i<this.numberOfTemps; i++){
113
- this.addMetadatum(`temp${i}`, 'K', `Temperature${i+1} reading`,
114
- (buffer)=>{
115
- return buffer.readUInt16BE(27+(i*2))/10
116
- })
117
- .default=`electrical.batteries.{batteryID}.Temperature${i+1}`
42
+ return [0xdd, 0xa5, command, 0x00, 0xff, 0xff - (command - 1), 0x77];
43
+ }
44
+
45
+ async sendReadFunctionRequest(command) {
46
+ this.debug(`${this.getName()}::sendReadFunctionRequest sending ${command}`);
47
+ return await this.txChar.writeValueWithoutResponse(
48
+ Buffer.from(this.jbdCommand(command))
49
+ );
50
+ }
51
+
52
+ async initSchema() {
53
+ this.debug(`${this.getName()}::initSchema`);
54
+
55
+ super.initSchema();
56
+ this.addDefaultParam("batteryID");
57
+
58
+ this.addDefaultPath("voltage", "electrical.batteries.voltage").read = (
59
+ buffer
60
+ ) => {
61
+ return buffer.readUInt16BE(4) / 100;
62
+ };
63
+
64
+ this.addDefaultPath("current", "electrical.batteries.current").read = (
65
+ buffer
66
+ ) => {
67
+ return buffer.readInt16BE(6) / 100;
68
+ };
69
+
70
+ this.addDefaultPath(
71
+ "remainingCapacity",
72
+ "electrical.batteries.capacity.remaining"
73
+ ).read = (buffer) => {
74
+ return (buffer.readUInt16BE(8) / 100) * 3600;
75
+ };
76
+
77
+ this.addDefaultPath(
78
+ "capacity",
79
+ "electrical.batteries.capacity.actual"
80
+ ).read = (buffer) => {
81
+ return (buffer.readUInt16BE(10) / 100) * 3600;
82
+ };
83
+
84
+ this.addDefaultPath("cycles", "electrical.batteries.cycles").read = (
85
+ buffer
86
+ ) => {
87
+ return buffer.readUInt16BE(12);
88
+ };
89
+
90
+ this.addMetadatum("protectionStatus", "", "Protection Status", (buffer) => {
91
+ const bits = buffer.readUInt16BE(20).toString(2);
92
+ return {
93
+ singleCellOvervolt: bits[0] == "1",
94
+ singleCellUndervolt: bits[1] == "1",
95
+ packOvervolt: bits[2] == "1",
96
+ packUndervolt: bits[3] == "1",
97
+ chargeOvertemp: bits[4] == "1",
98
+ chargeUndertemp: bits[5] == "1",
99
+ dischargeOvertemp: bits[6] == "1",
100
+ dischargeUndertemp: bits[7] == "1",
101
+ chargeOvercurrent: bits[8] == "1",
102
+ dischargeOvercurrent: bits[9] == "1",
103
+ shortCircut: bits[10] == "1",
104
+ frontEndDetectionICError: bits[11] == "1",
105
+ softwareLockMOS: bits[12] == "1",
106
+ };
107
+ }).default = "electrical.batteries.{batteryID}.protectionStatus";
108
+
109
+ this.addDefaultPath(
110
+ "SOC",
111
+ "electrical.batteries.capacity.stateOfCharge"
112
+ ).read = (buffer) => {
113
+ return buffer.readUInt8(23) / 100;
114
+ };
115
+
116
+ this.addMetadatum("FET", "", "FET On/Off Status", (buffer) => {
117
+ return buffer.readUInt8(24) != 0;
118
+ }).default = "electrical.batteries.{batteryID}.FETStatus";
119
+
120
+ this.addMetadatum("FETCharging", "", "FET Status Charging", (buffer) => {
121
+ return (buffer.readUInt8(24) & 0x1) != 0;
122
+ }).default = "electrical.batteries.{batteryID}.FETStatus.charging";
123
+
124
+ this.addMetadatum(
125
+ "FETDischarging",
126
+ "",
127
+ "FET Status Discharging",
128
+ (buffer) => {
129
+ return (buffer.readUInt8(24) & 0x2) != 0;
118
130
  }
119
-
120
- for (let i=0; i<this.numberOfCells; i++){
121
- this.addMetadatum(`cell${i}Voltage`, 'V', `Cell ${i+1} voltage`,
122
- (buffer)=>{return buffer.readUInt16BE((4+(i*2)))/1000} )
123
- .default=`electrical.batteries.{batteryID}.cell${i}.voltage`
124
- this.addMetadatum(`cell${i}Balance`, '', `Cell ${i+1} balance` )
125
- .default=`electrical.batteries.{batteryID}.cell${i}.balance`
126
-
131
+ ).default = "electrical.batteries.{batteryID}.FETStatus.discharging";
132
+
133
+ if (this.numberOfCells == undefined || this.numberOfTemps == undefined) {
134
+ try {
135
+ this.debug(
136
+ `${this.getName()}::initSchema Getting number of cells and temps...`
137
+ );
138
+ // NOTE gatt conn initiated here, in init
139
+ await this.initGATTConnection();
140
+ const cellsAndTemps = await this.getNumberOfCellsAndTemps();
141
+ this.numberOfCells = cellsAndTemps.cells;
142
+ this.numberOfTemps = cellsAndTemps.temps;
143
+ } catch (e) {
144
+ console.error(e);
145
+ this.numberOfCells = 4;
146
+ this.numberOfTemps = 2;
127
147
  }
148
+ }
149
+
150
+ for (let i = 0; i < this.numberOfTemps; i++) {
151
+ this.addMetadatum(
152
+ `temp${i}`,
153
+ "K",
154
+ `Temperature${i + 1} reading`,
155
+ (buffer) => {
156
+ return buffer.readUInt16BE(27 + i * 2) / 10;
157
+ }
158
+ ).default = `electrical.batteries.{batteryID}.Temperature${i + 1}`;
159
+ }
160
+
161
+ for (let i = 0; i < this.numberOfCells; i++) {
162
+ this.addMetadatum(
163
+ `cell${i}Voltage`,
164
+ "V",
165
+ `Cell ${i + 1} voltage`,
166
+ (buffer) => {
167
+ return buffer.readUInt16BE(4 + i * 2) / 1000;
168
+ }
169
+ ).default = `electrical.batteries.{batteryID}.cell${i}.voltage`;
170
+ this.addMetadatum(
171
+ `cell${i}Balance`,
172
+ "",
173
+ `Cell ${i + 1} balance`
174
+ ).default = `electrical.batteries.{batteryID}.cell${i}.balance`;
175
+ }
128
176
  }
129
177
 
130
- hasGATT(){
131
- return true
178
+ hasGATT() {
179
+ this.debug(`${this.getName()}::hasGATT`);
180
+ return true;
132
181
  }
133
- usingGATT(){
134
- return true
182
+
183
+ usingGATT() {
184
+ this.debug(`${this.getName()}::usingGATT`);
185
+ return true;
135
186
  }
136
- async initGATTNotifications(){
137
- this.intervalID = setInterval( async ()=>{
138
- await this.emitGATT()
139
- }, 1000*(this?.pollFreq??60) )
187
+ // FIXME not really needed:
188
+ async initGATTNotifications() {
189
+ this.debug(`${this.getName()}::initGATTNotifications`);
140
190
  }
141
191
 
142
- async emitGATT(){
192
+ async emitGATT() {
193
+ this.debug(`${this.getName()}::emitGATT`);
143
194
  try {
144
- await this.getAndEmitBatteryInfo()
195
+ this.debug(`${this.getName()}::emitGATT calling getAndEmitBatteryInfo`);
196
+ await this.getAndEmitBatteryInfo();
197
+ this.debug(
198
+ `${this.getName()}::emitGATT returned from getAndEmitBatteryInfo`
199
+ );
200
+ } catch (e) {
201
+ console.error(e);
202
+ this.debug(
203
+ `${this.getName()}::emitGATT Failed to emit battery info for ${this.getName()}: ${e}`
204
+ );
145
205
  }
146
- catch (e) {
147
- this.debug(`Failed to emit battery info for ${this.getName()}: ${e}`)
206
+ // setTimeout(async () => {
207
+ try {
208
+ this.debug(`${this.getName()}::emitGATT calling getAndEmitCellVoltages`);
209
+ await this.getAndEmitCellVoltages();
210
+ this.debug(
211
+ `${this.getName()}::emitGATT returned from getAndEmitCellVoltages`
212
+ );
213
+ } catch (e) {
214
+ console.error(e);
215
+ this.debug(
216
+ `${this.getName()}::emitGATT Failed to emit Cell Voltages for ${this.getName()}: ${e}`
217
+ );
148
218
  }
149
- setTimeout(async ()=>{
150
- try {await this.getAndEmitCellVoltages()}
151
- catch (e) {
152
- this.debug(`Failed to emit Cell Voltages for ${this.getName()}: ${e}`)
153
- }
154
- }, 10000)
155
- }
219
+ // }, 10000);
220
+ }
156
221
 
157
- async getNumberOfCellsAndTemps(){
158
- const b = await this.getBuffer(0x3)
159
- return {cells:b[25], temps:b[26]}
160
- }
161
-
162
-
163
- getBuffer (command){
164
-
165
- return new Promise( async ( resolve, reject )=>{
166
- const r = await this.sendReadFunctionRequest(command)
167
- let result = Buffer.alloc(256)
168
- let offset = 0
169
- let datasize = -1
170
- const timer = setTimeout(() => {
171
- clearTimeout(timer)
172
- reject(new Error(`Response timed out (+30s) from JBDBMS device ${this.getName()}. `));
173
- }, 30000);
174
-
175
- const valChanged = async (buffer) => {
176
- if (offset==0){ //first packet
177
- if (buffer[0]!==0xDD || buffer.length < 5 || buffer[1] !== command)
178
- reject(`Invalid buffer from ${this.getName()}, not processing.`)
179
- else
180
- datasize=buffer[3]
181
- }
182
- buffer.copy(result,offset)
183
- if (buffer[buffer.length-1]==0x77 && offset+buffer.length-7==datasize){
184
-
185
- result = Uint8Array.prototype.slice.call(result, 0, offset+buffer.length)
186
- this.rxChar.removeAllListeners()
187
- clearTimeout(timer)
188
- if (!checkSum(result))
189
- reject(`Invalid checksum from ${this.getName()}, not processing.`)
190
-
191
- resolve(result)
192
- }
193
- offset+=buffer.length
222
+ async getNumberOfCellsAndTemps() {
223
+ this.debug(`${this.getName()}::getNumberOfCellsAndTemps`);
224
+ const b = await this.getBuffer(0x3);
225
+ return { cells: b[25], temps: b[26] };
226
+ }
227
+
228
+ getBuffer(command) {
229
+ return new Promise(async (resolve, reject) => {
230
+ const r = await this.sendReadFunctionRequest(command);
231
+ let result = Buffer.alloc(256);
232
+ let offset = 0;
233
+ let datasize = -1;
234
+ const timer = setTimeout(() => {
235
+ clearTimeout(timer);
236
+ reject(
237
+ new Error(
238
+ `Response timed out (+30s) from JBDBMS device ${this.getName()}. `
239
+ )
240
+ );
241
+ }, 30000);
242
+
243
+ const valChanged = async (buffer) => {
244
+ if (offset == 0) {
245
+ //first packet
246
+ if (buffer[0] !== 0xdd || buffer.length < 5 || buffer[1] !== command)
247
+ reject(`Invalid buffer from ${this.getName()}, not processing.`);
248
+ else datasize = buffer[3];
194
249
  }
195
- this.rxChar.on('valuechanged', valChanged )
196
- })
197
- }
250
+ buffer.copy(result, offset);
251
+ if (
252
+ buffer[buffer.length - 1] == 0x77 &&
253
+ offset + buffer.length - 7 == datasize
254
+ ) {
255
+ result = Uint8Array.prototype.slice.call(
256
+ result,
257
+ 0,
258
+ offset + buffer.length
259
+ );
260
+ this.rxChar.removeAllListeners();
261
+ clearTimeout(timer);
262
+ if (!checkSum(result))
263
+ reject(`Invalid checksum from ${this.getName()}, not processing.`);
198
264
 
199
- async initGATTConnection() {
200
- this.setConnected(await this.device.isConnected())
201
- return this
202
- }
265
+ resolve(result);
266
+ }
267
+ offset += buffer.length;
268
+ };
269
+ this.rxChar.on("valuechanged", valChanged);
270
+ });
271
+ }
203
272
 
204
- async getAndEmitBatteryInfo(){
205
- return this.getBuffer(0x03).then((buffer)=>{
206
- (["current", "voltage", "remainingCapacity", "capacity","cycles", "protectionStatus", "SOC","FET",]).forEach((tag) =>
207
- this.emitData( tag, buffer )
208
- )
209
- for (let i = 0; i<this.numberOfTemps; i++){
210
- this.emitData(`temp${i}`,buffer)
211
- }
212
- const balances = buffer.readUInt32BE(16)
273
+ async initGATTConnection(isReconnecting = false) {
274
+ this.debug(`${this.getName()}::initGATTConnection`);
213
275
 
214
- for (let i = 0; i<this.numberOfCells; i++){
215
- this.emit(`cell${i}Balance`,(1<<i & balances)?1:0)
216
- }
276
+ if (this.rxChar)
277
+ try {
278
+ this.rxChar.removeAllListeners();
279
+ await this.rxChar.stopNotifications();
280
+ } catch (e) {
281
+ console.error(e);
282
+ this.debug(`error while stopping notifications`);
283
+ this.debug(e);
284
+ }
217
285
 
218
- // cells 0-15 - read bits right to left
219
- let balanceCells0to15 = buffer.readUInt16BE(16);
220
- for (let i = 0; i < Math.min(16, this.numberOfCells); i++) {
221
- const bit = (balanceCells0to15 >> i) & 1; // right-to-left
222
- this.emit(`cell${i}Balance`,bit);
286
+ try {
287
+ await super.initGATTConnection(isReconnecting);
288
+ const gattServer = await this.getGATTServer();
289
+
290
+ this.txRxService = await gattServer.getPrimaryService(
291
+ this.constructor.TX_RX_SERVICE
292
+ );
293
+ this.rxChar = await this.txRxService.getCharacteristic(
294
+ this.constructor.NOTIFY_CHAR_UUID
295
+ );
296
+ this.txChar = await this.txRxService.getCharacteristic(
297
+ this.constructor.WRITE_CHAR_UUID
298
+ );
299
+ await this.rxChar.startNotifications();
300
+ } catch (e) {
301
+ console.error(e);
302
+ this.setError(e.message);
223
303
  }
224
304
 
225
- // cells 16-31 - read bits right to left
226
- let balanceCells16to31 = buffer.readUInt16BE(18);
227
- for (let i = 0; i < Math.min(16, this.numberOfCells - 16); i++) {
228
- const bit = (balanceCells16to31 >> i) & 1; // right-to-left
229
- this.emit(`cell${16 + i}Balance`,bit);
305
+ try {
306
+ // FIXME not really needed?
307
+ this.debug(`${this.getName()}::initGATTConnection sending a test poll`);
308
+ await this.getBuffer(0x03);
309
+ } catch (e) {
310
+ console.error(e);
311
+ this.debug(`Error encountered calling getBuffer(0x03)`);
230
312
  }
231
- })
232
- }
313
+ //this.debug(`(${this.getName()}) Connections: ${this.connections++}`)
314
+ }
233
315
 
234
- async getAndEmitCellVoltages(){
235
- return this.getBuffer(0x4).then((buffer)=>{
316
+ async getAndEmitBatteryInfo() {
317
+ return this.getBuffer(0x03).then((buffer) => {
318
+ [
319
+ "current",
320
+ "voltage",
321
+ "remainingCapacity",
322
+ "capacity",
323
+ "cycles",
324
+ "protectionStatus",
325
+ "SOC",
326
+ "FET",
327
+ ].forEach((tag) => this.emitData(tag, buffer));
328
+ for (let i = 0; i < this.numberOfTemps; i++) {
329
+ this.emitData(`temp${i}`, buffer);
330
+ }
236
331
 
237
- for (let i=0; i<this.numberOfCells; i++){
238
- this.emitData(`cell${i}Voltage`,buffer)
239
- }})
240
- }
332
+ // cells 0-15 - read bits right to left
333
+ let balanceCells0to15 = buffer.readUInt16BE(16);
334
+ for (let i = 0; i < Math.min(16, this.numberOfCells); i++) {
335
+ const bit = (balanceCells0to15 >> i) & 1; // right-to-left
336
+ this.emit(`cell${i}Balance`, bit);
337
+ }
241
338
 
242
- async initGATTInterval(){
243
-
244
- await this.emitGATT()
245
- await this.initGATTNotifications()
246
- }
339
+ // cells 16-31 - read bits right to left
340
+ let balanceCells16to31 = buffer.readUInt16BE(18);
341
+ for (let i = 0; i < Math.min(16, this.numberOfCells - 16); i++) {
342
+ const bit = (balanceCells16to31 >> i) & 1; // right-to-left
343
+ this.emit(`cell${16 + i}Balance`, bit);
344
+ }
345
+ });
346
+ }
247
347
 
248
- async deactivateGATT(){
249
- await this.stopGATTNotifications(this.rxChar)
250
- await super.deactivateGATT()
251
- }
252
-
348
+ async getAndEmitCellVoltages() {
349
+ return this.getBuffer(0x4).then((buffer) => {
350
+ for (let i = 0; i < this.numberOfCells; i++) {
351
+ this.emitData(`cell${i}Voltage`, buffer);
352
+ }
353
+ });
354
+ }
355
+
356
+ async initGATTInterval() {
357
+ this.debug(
358
+ `${this.getName()}::initGATTInterval pollFreq=${this?.pollFreq}`
359
+ );
360
+ this.intervalID = setInterval(
361
+ async () => {
362
+ this._error = false;
363
+ if (!(await this.device.isConnected())) {
364
+ await this.initGATTConnection(true);
365
+ }
366
+ await this.emitGATT();
367
+ },
368
+ (this?.pollFreq ?? 40) * 1000
369
+ );
370
+
371
+ try {
372
+ await this.emitGATT();
373
+ } catch (e) {
374
+ console.error(e);
375
+ this.setError(e.message);
376
+ }
377
+ }
378
+
379
+ async deactivateGATT() {
380
+ this.debug(`${this.getName()}::deactivateGATT`);
381
+
382
+ // FIXME added this. needed any more?
383
+ if (this.intervalID) {
384
+ clearInterval(this.intervalID);
385
+ }
386
+
387
+ await this.stopGATTNotifications(this.rxChar);
388
+ await super.deactivateGATT();
389
+ }
253
390
  }
254
391
 
255
- module.exports = JBDBMS;
392
+ module.exports = JBDBMS;
@@ -0,0 +1,36 @@
1
+ {
2
+ "delay":100,
3
+ "data":
4
+ {
5
+ "0x96": [
6
+ "55 aa eb 90 01 de 58 02 00 00 f0 0a 00 00 54 0b 00 00 10 0e 00 00 de 0d 00 00 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f6 09 00 00 f0 49 02 00 1e 00 00 00 3c 00 00 00 40 0d 03 00 1e 00 00 00 3c 00 00 00 3c 00 00 00 d0 07 00 00 f4 01 00 00 c2 01 00 00 f4 01 00 00 c2 01 00 00 00 00 00 00 1e 00 00 00 84 03 00 00 20 03 00 00 04 00 00 00 01 00 00 00 01 00 00 00 01 00",
7
+ "00 00 e0 93 04 00 dc 05 00 00 48 0d 00 00 00 00 00 00 00 00 00 00",
8
+ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00",
9
+ "b0 71 0b 00 08 00 00 00 00 7c f8 ff ff 1f 0d 00 00 00 00 00 00 2a",
10
+ "55 aa eb 90 02 de 02 0d 02 0d 02 0d 02 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0f 00 00 00 02 0d 00 00 00 00 2e 00 31 00 34 00 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
11
+ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 cb 00 00 00 00 00",
12
+ "06 34 00 00 e9 1d 00 00 c1 fd ff ff ac 00 ac 00 00 00 00 00 00 00 00 2a 5b f4 01 00 e0 93 04 00 40 00 00 00 bd 30 29 01 64 00 00 00 19 95 c1 03 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 00 01 00 00 00 bf 03 01 00 03 00 12 5b 3f 40 00 00 00 00 33 05 39 1b 00 01 00 01 00 05 00 00 c0 2c df 00 00 00 00 00 cb 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
13
+ "00 00 00 00 00 00 00 00 00 fe ff 7f dc 0f 01 00 00 00 00 00 00 f1",
14
+ "55 aa eb 90 02 de 02 0d 02 0d 02 0d 02 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0f 00 00 00 02 0d 00 00 00 00 2e 00 31 00 34 00 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
15
+ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 cb 00 00 00 00 00",
16
+ "06 34 00 00 e9 1d 00 00 c1 fd ff ff ac 00 ac 00 00 00 00 00 00 00 00 2a 5b f4 01 00 e0 93 04 00 40 00 00 00 bd 30 29 01 64 00 00 00 19 95 c1 03 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 00 01 00 00 00 bf 03 01 00 03 00 12 5b 3f 40 00 00 00 00 33 05 39 1b 00 01 00 01 00 05 00 00 c0 2c df 00 00 00 00 00 cb 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
17
+ "00 00 00 00 00 00 00 00 00 fe ff 7f dc 0f 01 00 00 00 00 00 00 f1",
18
+ "55 aa eb 90 01 de 58 02 00 00 f0 0a 00 00 54 0b 00 00 10 0e 00 00 de 0d 00 00 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f6 09 00 00 f0 49 02 00 1e 00 00 00 3c 00 00 00 40 0d 03 00 1e 00 00 00 3c 00 00 00 3c 00 00 00 d0 07 00 00 f4 01 00 00 c2 01 00 00 f4 01 00 00 c2 01 00 00 00 00 00 00 1e 00 00 00 84 03 00 00 20 03 00 00 04 00 00 00 01 00 00 00 01 00 00 00 01 00",
19
+ "00 00 e0 93 04 00 dc 05 00 00 48 0d 00 00 00 00 00 00 00 00 00 00",
20
+ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00",
21
+ "b0 71 0b 00 08 00 00 00 00 7c f8 ff ff 1f 0d 00 00 00 00 00 00 2a",
22
+ "aa bb cc dd ee ff",
23
+ "aa bb cc",
24
+ "55 aa eb 90 02 de 02 0d 02 0d 02 0d 02 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0f 00 00 00 02 0d 00 00 00 00 2e 00 31 00 34 00 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
25
+ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 cb 00 00 00 00 00",
26
+ "06 34 00 00 e9 1d 00 00 c1 fd ff ff ac 00 ac 00 00 00 00 00 00 00 00 2a 5b f4 01 00 e0 93 04 00 40 00 00 00 bd 30 29 01 64 00 00 00 19 95 c1 03 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 00 01 00 00 00 bf 03 01 00 03 00 12 5b 3f 40 00 00 00 00 33 05 39 1b 00 01 00 01 00 05 00 00 c0 2c df 00 00 00 00 00 cb 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
27
+ "00 00 00 00 00 00 00 00 00 fe ff 7f dc 0f 01 00 00 00 00 00 00 f1"
28
+ ],
29
+ "0x97":[
30
+ "55 aa eb 90 03 c4 4a 4b 5f 42 32 41 38 53 32 30 50 00 00 00 00 00 31 31 2e 58 57 00 00 00 31 31 2e 32 36 31 00 00 68 96 c1 03 18 00 00 00 48 42 31 5f 42 34 00 00 00 00 00 00 00 00 00 00 31 32 33 34 00 00 00 00 00 00 00 00 00 00 00 00 32 33 30 38 31 34 00 00 33 30 32 32 38 34 34 32 36 37 00 30 30 30 30 00 49 6e 70 75 74 20 55 73 65 72 64 61 74 61 00 00 31 32 33 33 32 31 00 00 00 00",
31
+ "00 00 00 00 00 00 49 6e 70 75 74 20 55 73 65 72 64 61 74 61 00 00",
32
+ "7c f8 ff ff 1f 0d 00 00 00 00 00 00 90 0f 00 00 00 00 c0 d8 03 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
33
+ "00 00 00 00 00 00 00 00 00 fe 2f 00 00 00 00 00 00 00 00 00 00 bf"
34
+ ]
35
+ }
36
+ }