@mschaeffler/node-red-bthome 0.1.1 → 0.1.3

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/README.md CHANGED
@@ -8,10 +8,10 @@ At the moment these sensors are implemented and tested:
8
8
  - Shelly BLU Door/Window
9
9
  - Shelly BLU H&T
10
10
  - Shelly BLU Button 1
11
- - Shelly BLU Button Tough 1
11
+ - Shelly BLU Button Tough 1
12
12
  - Shelly BLU RC Button 4
13
13
  - Shelly BLU Wall Switch 4
14
- - Shelly BLU Motion
14
+ - Shelly BLU Motion
15
15
 
16
16
  ## Capture of Raw Frames
17
17
 
@@ -19,6 +19,10 @@ The raw data frames are captured by Shelly devices with Bluetooth (Gen2 up to Ge
19
19
 
20
20
  [This is the script to be used.](https://raw.githubusercontent.com/m-schaeffler/ShellyScripts/refs/heads/main/ShellyBlu.js)
21
21
 
22
+ ## Encryption
23
+
24
+ is at the moment not supported, an update will follow shortly.
25
+
22
26
  ## Install
23
27
 
24
28
  ```
@@ -29,21 +33,101 @@ $ npm install @mschaeffler/node-red-bthome
29
33
 
30
34
  |msg. | type | description |
31
35
  |:-------|:-------|:----------------------------------|
32
- |topic | string | topic for the output message|
33
- |payload | | payload for the output message |
36
+ |payload | object | data from Shelly script|
37
+
38
+ ### msg.payload
39
+
40
+ Only the first two values are needed, the others are optional.
41
+
42
+ |msg.payload| type | description |
43
+ |:----------|:-------|:----------------------------------|
44
+ |addr | string |mac of the BT-Home device (needed) |
45
+ |data | array of bytes|raw BT-Home message (needed) |
46
+ |rssi | number |signal strength |
47
+ |time | number |Javscript timestamp of the reception |
48
+ |gateway | string |name of the geteway |
49
+
50
+ This is an example of such a message payload:
51
+ ```
52
+ {
53
+ "addr": "11:22:33:44:55:66",
54
+ "rssi": -85,
55
+ "time": 1745395033113,
56
+ "gateway": "Shelly Gateway",
57
+ "data": [68,0,164,1,100,46,56,69,43,255]
58
+ }
59
+ ```
60
+
61
+ ## Outputs
62
+
63
+ There are two output ports:
64
+ 1. one for meassurement values (states)
65
+ 2. one for actions done with the devices (events)
66
+
67
+ ### State
68
+
69
+ |msg. | type | description |
70
+ |:-------|:-------|:----------------------------------|
71
+ |topic | string | `State-Prefix` + name of the device|
72
+ |payload | object | decoded state data|
34
73
 
35
- ## Output
74
+ ### Events
36
75
 
37
76
  |msg. | type | description |
38
77
  |:-------|:-------|:----------------------------------|
39
- |topic | string | same is in corresponding input message|
40
- |payload | | same is in corresponding input message|
78
+ |topic | string | `Event-Prefix` + name of the device|
79
+ |payload | object | data of the decoded event|
41
80
 
42
81
  ## Parameters
43
82
 
44
- |config| type | description |
45
- |:-----|:-------|:----------------------------------|
46
- |interval | number | the intervall between two resends |
83
+ |config | type | description |
84
+ |:------------|:-------|:----------------------------------|
85
+ |Devices | JSON | configuration of the BT-Home devices |
86
+ |Status-Prefix| string | prefix for the topic for state output |
87
+ |Event-Prefix | string | prefix for the topic for event output |
88
+ |Context-Variable| string | name of the variable in flow context storage |
89
+ |Contextstore | string | context store to be used |
90
+
91
+ ### Device-Configuration
92
+
93
+ With this JSON string the installed [BT-Home](https://bthome.io) devices are configured:
94
+ ```
95
+ {
96
+ "<mac address of the device>": { "topic": "<name of the device>", "key": "<encryption key, if device is encrypted>" }
97
+ }
98
+ ```
99
+
100
+ An example for such a config from the unit tests:
101
+ ```
102
+ {
103
+ "11:22:33:44:55:66": { "topic": "dev_unencrypted_1" },
104
+ "00:01:02:03:04:05": { "topic": "dev_unencrypted_2" },
105
+ "00:10:20:30:40:50": { "topic": "dev_encrypted_1", "key": "00112233445566778899AABBCCDDEEFF" },
106
+ "00:00:00:00:00:00": { "topic": "dev_encrypted_2", "key": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] }
107
+ }
108
+ ```
109
+
110
+ ### Context storage
111
+
112
+ All recorded data can be stored in a flow context variable for
113
+ - initialisation
114
+ - statistics
115
+ - visualisation
116
+
117
+ Example:
118
+ ```
119
+ {
120
+ "dev_unencrypted_1":
121
+ {
122
+ "pid": 164,
123
+ "time": 1745395033113,
124
+ "encrypted": false,
125
+ "battery": 100,
126
+ "gw": { "Shelly Gateway": { "time": 1745395033113, "rssi":-85 } },
127
+ data": { "humidity":56, "temperature":-21.3 }
128
+ }
129
+ }
130
+ ```
47
131
 
48
132
  ## Example Flow
49
133
 
package/bthome.html CHANGED
@@ -7,20 +7,21 @@
7
7
  devices:{value:"[]",required:true},
8
8
  statusPrefix:{value:""},
9
9
  eventPrefix:{value:""},
10
+ contextVar:{value:"bthome",required:true},
10
11
  contextStore:{value:"",required:true}
11
12
  },
12
13
  inputs:1,
13
- outputs:1,
14
+ outputs:2,
14
15
  icon: "bthome.png",
15
16
  label: function() {
16
- return this.name||"bthome";
17
+ return this.name||"BT-Home";
17
18
  },
18
19
  labelStyle: function() {
19
20
  return this.name?"node_label_italic":"";
20
21
  },
21
22
  paletteLabel: "bthome",
22
- inputLabels: 'bthome frame',
23
- outputLabels: 'decoded frame',
23
+ inputLabels: 'raw bthome frame',
24
+ outputLabels: ['state output','event output'],
24
25
  oneditprepare: function() {
25
26
  const node = this;
26
27
  $("#node-input-devices").typedInput({
@@ -61,6 +62,10 @@
61
62
  <label for="node-input-eventPrefix"><i class="fa fa-star-o"></i> Event-Prefix</label>
62
63
  <input type="text" id="node-input-eventPrefix"></input>
63
64
  </div>
65
+ <div class="form-row">
66
+ <label for="node-input-contextVar"><i class="fa fa-database"></i> Context-Variable</label>
67
+ <input type="text" id="node-input-contextVar"></input>
68
+ </div>
64
69
  <div class="form-row">
65
70
  <label for="node-input-contextStore"><i class="fa fa-database"></i> Contextstore</label>
66
71
  <select type="text" id="node-input-contextStore"></select>
@@ -69,30 +74,126 @@
69
74
 
70
75
  <script type="text/x-red" data-help-name="bthome">
71
76
 
72
- <p>A Node Red node to decrypt and decode bthome frames.</p>
77
+ <p>A Node Red node to decrypt and decode raw data frames from <a href="https://bthome.io">BT-Home</a> sensors.</p>
73
78
 
74
- <p>.</p>
79
+ <p>At the moment these sensors are implemented and tested:</p>
80
+ <ul>
81
+ <li>Shelly BLU Door/Window</li>
82
+ <li>Shelly BLU H&T</li>
83
+ <li>Shelly BLU Button 1</li>
84
+ <li>Shelly BLU Button Tough 1</li>
85
+ <li>Shelly BLU RC Button 4</li>
86
+ <li>Shelly BLU Wall Switch 4</li>
87
+ <li>Shelly BLU Motion</li>
88
+ </ul>
75
89
 
90
+ <h3>Capture of Raw Frames</h3>
91
+ <p>The raw data frames are captured by Shelly devices with Bluetooth (Gen2 up to Gen4) and then sent via MQTT to Node-Red.</p>
92
+ <a href="https://raw.githubusercontent.com/m-schaeffler/ShellyScripts/refs/heads/main/ShellyBlu.js">This is the script to be used.</a>
93
+
94
+ <h3>Encryption</h3>
95
+ <p>is at the moment not supported, an update will follow shortly.</p>
96
+
76
97
  <h3>Input</h3>
98
+ <dl class="message-properties">
99
+ <dt>payload <span class="property-type">object</span></dt>
100
+ <dd> data from Shelly script</dd>
101
+ </dl>
102
+
103
+ <h4>msg.payload</h4>
104
+ <p>Only the first two values are needed, the others are optional.</p>
105
+ <dl class="message-properties">
106
+ <dt>payload.addr <span class="property-type">string</span></dt>
107
+ <dd> mac of the BT-Home device (needed)</dd>
108
+ <dt>payload.data <span class="property-type">array of bytes</span></dt>
109
+ <dd> raw BT-Home message (needed)</dd>
110
+ <dt>payload.rssi <span class="property-type">number</span></dt>
111
+ <dd> signal strength</dd>
112
+ <dt>payload.time <span class="property-type">number</span></dt>
113
+ <dd> Javscript timestamp of the reception</dd>
114
+ <dt>payload.gateway <span class="property-type">string</span></dt>
115
+ <dd> name of the geteway</dd>
116
+ </dl>
117
+
118
+ <p>This is an example of such a message payload:</p>
119
+ <code>{<br>
120
+ "addr": "11:22:33:44:55:66",<br>
121
+ "rssi": -85,<br>
122
+ "time": 1745395033113,<br>
123
+ "gateway": "Shelly Gateway",<br>
124
+ "data": [68,0,164,1,100,46,56,69,43,255]<br>
125
+ }</code>
126
+
127
+ <h3>Outputs</h3>
128
+ <p>There are two output ports:</p>
129
+ <ol>
130
+ <li>one for meassurement values (states)</li>
131
+ <li>one for actions done with the devices (events)</li>
132
+ </ol>
133
+
134
+ <h4>State</h4>
77
135
  <dl class="message-properties">
78
136
  <dt>topic <span class="property-type">string</span></dt>
79
- <dd> topic for the output message</dd>
137
+ <dd> <code>State-Prefix</code> + name of the device</dd>
80
138
  <dt>payload <span class="property-type"></span></dt>
81
- <dd> payload for the output message</dd>
139
+ <dd> decoded state data</dd>
82
140
  </dl>
83
141
 
84
- <h3>Outputs</h3>
142
+ </h4>Events</h4>
85
143
  <dl class="message-properties">
86
144
  <dt>topic <span class="property-type">string</span></dt>
87
- <dd> same is in corresponding input message</dd>
145
+ <dd> <code>Event-Prefix</code> + name of the device</dd>
88
146
  <dt>payload <span class="property-type"></span></dt>
89
- <dd> same is in corresponding input message</dd>
147
+ <dd> data of the decoded event</dd>
90
148
  </dl>
91
149
 
92
150
  <h3>Parameters</h3>
93
151
  <dl class="message-properties">
94
- <dt>devices <span class="property-type">JSON</span></dt>
95
- <dd> data of the connected BT-Home devices.</dd>
152
+ <dt>Devices <span class="property-type">JSON</span></dt>
153
+ <dd> configuration of the BT-Home devices.</dd>
154
+ <dt>Status-Prefix <span class="property-type">string</span></dt>
155
+ <dd> prefix for the topic for state output.</dd>
156
+ <dt>Event-Prefix <span class="property-type">string</span></dt>
157
+ <dd> prefix for the topic for event output.</dd>
158
+ <dt>Context-Variable <span class="property-type">string</span></dt>
159
+ <dd> name of the variable in flow context storage.</dd>
160
+ <dt>Contextstore <span class="property-type">string</span></dt>
161
+ <dd> context store to be used.</dd>
96
162
  </dl>
97
163
 
164
+ <h4>Device-Configuration</h4>
165
+ <p>With this JSON string the installed <a href="https://bthome.io">BT-Home</a> devices are configured:</p>
166
+ <code>{<br>
167
+ "<mac address of the device>": { "topic": "<name of the device>", "key": "<encryption key, if device is encrypted>" }<br>
168
+ }</code>
169
+
170
+ <p>An example for such a config from the unit tests:</p>
171
+ <code>{<br>
172
+ "11:22:33:44:55:66": { "topic": "dev_unencrypted_1" },<br>
173
+ "00:01:02:03:04:05": { "topic": "dev_unencrypted_2" },<br>
174
+ "00:10:20:30:40:50": { "topic": "dev_encrypted_1", "key": "00112233445566778899AABBCCDDEEFF" },<br>
175
+ "00:00:00:00:00:00": { "topic": "dev_encrypted_2", "key": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] }<br>
176
+ }</code>
177
+
178
+ <h4>Context storage</h4>
179
+ <p>All recorded data can be stored in a flow context variable for</p>
180
+ <ul>
181
+ <li>initialisation</li>
182
+ <li>statistics</li>
183
+ <li>visualisation</li>
184
+ </ul>
185
+
186
+ <p>Example:</p>
187
+ <code>{<br>
188
+ "dev_unencrypted_1":<br>
189
+ {<br>
190
+ "pid": 164,<br>
191
+ "time": 1745395033113,<br>
192
+ "encrypted": false,<br>
193
+ "battery": 100,<br>
194
+ "gw": { "Shelly Gateway": { "time": 1745395033113, "rssi":-85 } },<br>
195
+ data": { "humidity":56, "temperature":-21.3 }<br>
196
+ }
197
+ }<code>
198
+
98
199
  </script>
package/bthome.js CHANGED
@@ -216,7 +216,7 @@ module.exports = function(RED) {
216
216
  {
217
217
  if( encrypted )
218
218
  {
219
- decyrptMsg();
219
+ decryptMsg();
220
220
  done();return;
221
221
  }
222
222
  if( item == undefined )
@@ -0,0 +1,137 @@
1
+ [
2
+ {
3
+ "id": "3a9fcdbd98993dbc",
4
+ "type": "mqtt in",
5
+ "z": "8e0e9a167c607864",
6
+ "name": "",
7
+ "topic": "node-red/bleraw",
8
+ "qos": "0",
9
+ "datatype": "json",
10
+ "broker": "66b8b47e.0f87bc",
11
+ "nl": false,
12
+ "rap": true,
13
+ "rh": 0,
14
+ "inputs": 0,
15
+ "x": 140,
16
+ "y": 1460,
17
+ "wires": [
18
+ [
19
+ "c4df490573c18fc4"
20
+ ]
21
+ ]
22
+ },
23
+ {
24
+ "id": "c4df490573c18fc4",
25
+ "type": "bthome",
26
+ "z": "8e0e9a167c607864",
27
+ "name": "",
28
+ "devices": "{\"11:22:33:44:55:66\":{\"topic\":\"dev_unencrypted_1\"},\"00:01:02:03:04:05\":{\"topic\":\"dev_unencrypted_2\"},\"00:10:20:30:40:50\":{\"topic\":\"dev_encrypted_1\",\"key\":\"00112233445566778899AABBCCDDEEFF\"},\"00:00:00:00:00:00\":{\"topic\":\"dev_encrypted_2\",\"key\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}",
29
+ "statusPrefix": "Status",
30
+ "eventPrefix": "Event",
31
+ "contextVar": "bt-home",
32
+ "contextStore": "memoryOnly",
33
+ "x": 340,
34
+ "y": 1440,
35
+ "wires": [
36
+ [
37
+ "3c9fee837ed43fc0"
38
+ ],
39
+ [
40
+ "26ebe1833f97c4d4"
41
+ ]
42
+ ]
43
+ },
44
+ {
45
+ "id": "3c9fee837ed43fc0",
46
+ "type": "debug",
47
+ "z": "8e0e9a167c607864",
48
+ "name": "debug 9",
49
+ "active": true,
50
+ "tosidebar": true,
51
+ "console": false,
52
+ "tostatus": false,
53
+ "complete": "false",
54
+ "statusVal": "",
55
+ "statusType": "auto",
56
+ "x": 520,
57
+ "y": 1420,
58
+ "wires": []
59
+ },
60
+ {
61
+ "id": "26ebe1833f97c4d4",
62
+ "type": "debug",
63
+ "z": "8e0e9a167c607864",
64
+ "name": "debug 10",
65
+ "active": true,
66
+ "tosidebar": true,
67
+ "console": false,
68
+ "tostatus": false,
69
+ "complete": "false",
70
+ "statusVal": "",
71
+ "statusType": "auto",
72
+ "x": 520,
73
+ "y": 1460,
74
+ "wires": []
75
+ },
76
+ {
77
+ "id": "e3ad83be53fa3fe3",
78
+ "type": "inject",
79
+ "z": "8e0e9a167c607864",
80
+ "name": "",
81
+ "props": [
82
+ {
83
+ "p": "payload"
84
+ },
85
+ {
86
+ "p": "topic",
87
+ "vt": "str"
88
+ }
89
+ ],
90
+ "repeat": "",
91
+ "crontab": "",
92
+ "once": false,
93
+ "onceDelay": 0.1,
94
+ "topic": "",
95
+ "payload": "{\"addr\":\"11:22:33:44:55:66\",\"rssi\":-85,\"time\":1745395033113,\"gateway\":\"Shelly Gateway\",\"data\":[68,0,164,1,100,46,56,69,43,255]}",
96
+ "payloadType": "json",
97
+ "x": 170,
98
+ "y": 1420,
99
+ "wires": [
100
+ [
101
+ "c4df490573c18fc4"
102
+ ]
103
+ ]
104
+ },
105
+ {
106
+ "id": "66b8b47e.0f87bc",
107
+ "type": "mqtt-broker",
108
+ "name": "mqtt.lan",
109
+ "broker": "mqtt.lan",
110
+ "port": "1883",
111
+ "clientid": "node-red",
112
+ "autoConnect": false,
113
+ "usetls": false,
114
+ "compatmode": false,
115
+ "protocolVersion": "4",
116
+ "keepalive": "60",
117
+ "cleansession": true,
118
+ "autoUnsubscribe": true,
119
+ "birthTopic": "node-red/online",
120
+ "birthQos": "1",
121
+ "birthRetain": "true",
122
+ "birthPayload": "true",
123
+ "birthMsg": {},
124
+ "closeTopic": "node-red/online",
125
+ "closeQos": "1",
126
+ "closeRetain": "true",
127
+ "closePayload": "false",
128
+ "closeMsg": {},
129
+ "willTopic": "node-red/online",
130
+ "willQos": "1",
131
+ "willRetain": "true",
132
+ "willPayload": "false",
133
+ "willMsg": {},
134
+ "userProps": "",
135
+ "sessionExpiry": ""
136
+ }
137
+ ]
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mschaeffler/node-red-bthome",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "A Node Red node to decrypt and decode BT-Home frames",
5
5
  "author": {
6
6
  "name": "Mathias Schäffler",