@mschaeffler/node-red-bthome 1.1.0 → 1.2.0

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.
Files changed (3) hide show
  1. package/btevent.js +31 -30
  2. package/bthome.js +48 -16
  3. package/package.json +1 -1
package/btevent.js CHANGED
@@ -1,52 +1,49 @@
1
1
  class BtEvent {
2
- constructor(prefix)
2
+ static eventLut = {
3
+ 9: {
4
+ button: ["left","right"]
5
+ }
6
+ };
7
+ constructor(prefix,item)
3
8
  {
4
9
  this._events = {};
5
10
  this._prefix = prefix;
11
+ this._item = item;
6
12
  }
7
13
  pushEvent(type,event,data=null)
8
14
  {
9
- if( event && data !== null )
10
- {
11
- event = `${event}|${data}`;
12
- }
13
- switch( typeof this._events[type] )
15
+ if( this._events[type] === undefined )
14
16
  {
15
- case "undefined":
16
- this._events[type] = event;
17
- break;
18
- case "string":
19
- this._events[type] = [ this._events[type] ];
20
- // fall through
21
- case "object":
22
- this._events[type].push( event );
23
- break;
17
+ this._events[type] = [];
24
18
  }
19
+ this._events[type].push( { event:event, data:data } );
25
20
  }
26
- eventMessages(name)
21
+ eventMessages(name,channel)
27
22
  {
28
23
  function pushResult(type,event,index=null)
29
24
  {
30
- if( event )
25
+ if( event.event && event.data !== 0 )
31
26
  {
32
- const help = event.split( '|' );
33
- let payload = { type: type, event: help[0] };
34
- let topic;
35
- if( index === null )
27
+ let payload = { type: type, event: event.event };
28
+ let indexStr = "";;
29
+ if( channel !== null )
36
30
  {
37
- topic = `${prefix}${name}/${help[0]}`;
31
+ indexStr += "/"
32
+ indexStr += channel;
33
+ payload.channel = channel;
38
34
  }
39
- else
35
+ if( index !== null )
40
36
  {
41
- topic = `${prefix}${name}/${index}/${help[0]}`;
37
+ indexStr += "/";
38
+ indexStr += index;
42
39
  payload.id = index;
43
40
  }
44
- if( help[1] !== undefined )
41
+ if( event.data !== null )
45
42
  {
46
- payload.data = help[1];
43
+ payload.data = event.data;
47
44
  }
48
45
  result.push( {
49
- topic: topic,
46
+ topic: `${prefix}${name}${indexStr}/${event.event}`,
50
47
  payload: payload
51
48
  } );
52
49
  }
@@ -57,15 +54,19 @@ class BtEvent {
57
54
  for( const t in this._events )
58
55
  {
59
56
  const event = this._events[t];
60
- if( typeof event == "string" )
57
+ if( event.length == 1 )
61
58
  {
62
- pushResult( t, event );
59
+ pushResult( t, event[0] );
63
60
  }
64
61
  else
65
62
  {
66
63
  for( const i in event )
67
64
  {
68
- pushResult( t, event[i], Number( i ) + 1 );
65
+ pushResult(
66
+ t,
67
+ event[i],
68
+ BtEvent.eventLut[this._item.typeId]?.[t]?.[i] ?? Number( i ) + 1
69
+ );
69
70
  }
70
71
  }
71
72
  }
package/bthome.js CHANGED
@@ -3,6 +3,12 @@ const Tools = require( './tools.js' );
3
3
  const Rawdata = require( "./rawdata.js" );
4
4
  const BtEvent = require( "./btevent.js" );
5
5
 
6
+ class TypeIds {
7
+ static bluDW = 0x0202;
8
+ static bluRemote = 9;
9
+ }
10
+ Object.freeze( TypeIds );
11
+
6
12
  module.exports = function(RED) {
7
13
 
8
14
  function BtHomeNode(config) {
@@ -10,7 +16,7 @@ module.exports = function(RED) {
10
16
  var node = this;
11
17
  this.flowcontext = this.context().flow;
12
18
  this.devices = JSON.parse( config.devices ?? "{}" );
13
- this.counterMode = config.counterMode ?? "none";
19
+ this.counterMode = config.counterMode ?? "none";
14
20
  this.statusPrefix = config.statusPrefix ? config.statusPrefix+'/' : "";
15
21
  this.eventPrefix = config.eventPrefix ? config.eventPrefix +'/' : "";
16
22
  this.contextVar = config.contextVar ?? "bthome";
@@ -124,18 +130,18 @@ module.exports = function(RED) {
124
130
  {
125
131
  item.data = {};
126
132
  }
127
- switch( typeof counter[name] )
133
+ switch( counter[name] )
128
134
  {
129
- case "undefined":
135
+ case undefined:
130
136
  counter[name] = 1;
131
137
  item.data[name] = value;
132
138
  break;
133
- case "boolean":
134
- case "number":
135
- case "string":
139
+ case 1:
136
140
  item.data[name] = [ item.data[name] ];
137
141
  // fall through
138
- case "object":
142
+ case 2:
143
+ case 3:
144
+ case 4:
139
145
  counter[name]++;
140
146
  item.data[name].push( value );
141
147
  break;
@@ -173,10 +179,19 @@ module.exports = function(RED) {
173
179
  setData( "dewpoint", rawdata.getInt16() * 0.01 );
174
180
  break;
175
181
  case 0x0C:
176
- setData( "voltage", rawdata.getUInt16() * 0.001 );
182
+ if( node.batteryState )
183
+ {
184
+ setData( "voltage", rawdata.getUInt16() * 0.001 );
185
+ delete item.voltage;
186
+ }
187
+ else
188
+ {
189
+ item.voltage = rawdata.getUInt16() * 0.001;
190
+ delete item.data?.voltage;
191
+ }
177
192
  break;
178
193
  case 0x20:
179
- setData( "rain", Boolean( rawdata.getUInt8() ) );
194
+ setData( "moisture", Boolean( rawdata.getUInt8() ) );
180
195
  break;
181
196
  case 0x21:
182
197
  events.pushEvent( "motion", rawdata.getEnum( ["","motion"] ) );
@@ -185,13 +200,15 @@ module.exports = function(RED) {
185
200
  setData( "vibration", Boolean( rawdata.getUInt8() ) );
186
201
  break;
187
202
  case 0x2D:
203
+ {
188
204
  let state = rawdata.getUInt8();
189
- if( item.typeId === 0x0202 )
205
+ if( item.typeId === TypeIds.bluDW )
190
206
  {
191
207
  state = Boolean( state );
192
208
  }
193
209
  setData( "state", state );
194
210
  break;
211
+ }
195
212
  case 0x2E:
196
213
  setData( "humidity", rawdata.getUInt8() );
197
214
  break;
@@ -199,14 +216,21 @@ module.exports = function(RED) {
199
216
  events.pushEvent( "button", rawdata.getEnum( ["","S","SS","SSS","L"] ) );
200
217
  break;
201
218
  case 0x3C:
202
- events.pushEvent( "dimmer", rawdata.getEnum( ["","Left","Right"] ), rawdata.getUInt8() );
219
+ {
220
+ const dimmer = rawdata.getUInt8();
221
+ const data = rawdata.getUInt8();
222
+ events.pushEvent( "dimmer", "dimmer", dimmer==1 ? data : -data );
203
223
  break;
224
+ }
204
225
  case 0x3F:
205
226
  setData( "tilt", rawdata.getInt16() * 0.1 );
206
227
  break;
207
228
  case 0x40:
208
- setData( "distance", rawdata.getUInt16() );
229
+ {
230
+ const distance = rawdata.getUInt16();
231
+ setData( "distance", distance != 0 ? distance : null );
209
232
  break;
233
+ }
210
234
  case 0x44:
211
235
  setData( "wind", rawdata.getUInt16() * 0.01 );
212
236
  break;
@@ -216,6 +240,9 @@ module.exports = function(RED) {
216
240
  case 0x46:
217
241
  setData( "uv", rawdata.getUInt8() * 0.1 );
218
242
  break;
243
+ case 0x59:
244
+ setData( "count", rawdata.getInt8() );
245
+ break;
219
246
  case 0x5E:
220
247
  setData( "direction", rawdata.getUInt16() * 0.01 );
221
248
  break;
@@ -223,7 +250,7 @@ module.exports = function(RED) {
223
250
  setData( "precipitation", rawdata.getUInt16() * 0.1 );
224
251
  break;
225
252
  case 0x60:
226
- setData( "channel", rawdata.getUInt8() );
253
+ setData( "channel", rawdata.getUInt8() + 1 );
227
254
  break;
228
255
  case 0xF0:
229
256
  item.typeId = rawdata.getUInt16();
@@ -248,7 +275,11 @@ module.exports = function(RED) {
248
275
  rawdata.reset();
249
276
  }
250
277
  }
251
- //console.log(counter)
278
+ if( item.typeId === TypeIds.bluRemote && item.data?.tilt )
279
+ {
280
+ events.pushEvent( "rotation", "rotation", item.data.tilt );
281
+ delete item.data.tilt;
282
+ }
252
283
  }
253
284
 
254
285
  function checkPid()
@@ -291,7 +322,7 @@ module.exports = function(RED) {
291
322
  node.status( name );
292
323
  send( [
293
324
  item.data ? { topic:node.statusPrefix+name, payload:item.data } : null,
294
- events.eventMessages( name )
325
+ events.eventMessages( name, item.data?.channel ?? null )
295
326
  ] );
296
327
  }
297
328
 
@@ -302,8 +333,8 @@ module.exports = function(RED) {
302
333
  const encrypted = Boolean( dib & 0x1 );
303
334
  const version = dib >> 5;
304
335
  let pid = null;
305
- const events = new BtEvent( node.eventPrefix );
306
336
  let item = node.data[name];
337
+ let events;
307
338
 
308
339
  try
309
340
  {
@@ -317,6 +348,7 @@ module.exports = function(RED) {
317
348
  {
318
349
  decryptMsg();
319
350
  }
351
+ events = new BtEvent( node.eventPrefix, item );
320
352
  decodeMsg();
321
353
  if( checkPid() )
322
354
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mschaeffler/node-red-bthome",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "A Node Red node to decrypt and decode BT-Home frames",
5
5
  "author": {
6
6
  "name": "Mathias Schäffler",