iobroker.lorawan 0.3.6 → 0.3.7

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
@@ -22,6 +22,9 @@ For now there is documentation in English here: http://www.hafenmeister.com/Lora
22
22
  Placeholder for the next version (at the beginning of the line):
23
23
  ### **WORK IN PROGRESS**
24
24
  -->
25
+ ### 0.3.7 (2024-02-22)
26
+ * (BenAhrdt) improove forbidden chars and implements join raw
27
+
25
28
  ### 0.3.6 (2024-02-21)
26
29
  * (BenAhrdt) set attributs if undefined
27
30
 
@@ -180,7 +180,8 @@
180
180
  "label": "name",
181
181
  "tooltip": "nameTooltip",
182
182
  "default": "",
183
- "validator": "if(data.name === '' || data.name === null){return false;}else{return true;}",
183
+ "validator": "if(data.name === '' || data.name === null){return false;}else{const myRegEx = /^([0-9a-z])*$/i; return myRegEx.test(data.name);}",
184
+ "validatorNoSaveOnError": true,
184
185
  "sm":2
185
186
  },
186
187
  {
@@ -246,6 +247,7 @@
246
247
  "tooltip": "frontTooltip",
247
248
  "default": "03",
248
249
  "validator": "if(data.type !== 'string'){const myRegEx = /^([0-9a-f]{2})*$/i; return myRegEx.test(data.front)}else{return true}",
250
+ "validatorNoSaveOnError": true,
249
251
  "hidden": "data.type === 'boolean' || data.type === 'button'",
250
252
  "sm":2
251
253
  },
@@ -256,6 +258,7 @@
256
258
  "tooltip": "endTooltip",
257
259
  "default": "11",
258
260
  "validator": "if(data.type !== 'string'){const myRegEx = /^([0-9a-f]{2})*$/i; return myRegEx.test(data.front)}else{return true}",
261
+ "validatorNoSaveOnError": true,
259
262
  "hidden": "data.type === 'boolean' || data.type === 'button'",
260
263
  "sm":2
261
264
  },
@@ -278,6 +281,7 @@
278
281
  "tooltip": "onTooltip",
279
282
  "default": "01",
280
283
  "validator": "const myRegEx = /^([0-9a-f]{2})*$/i; return myRegEx.test(data.on);",
284
+ "validatorNoSaveOnError": true,
281
285
  "hidden": "data.type !== 'boolean'",
282
286
  "sm":2
283
287
  },
@@ -288,6 +292,7 @@
288
292
  "tooltip": "offTooltip",
289
293
  "default": "11",
290
294
  "validator": "const myRegEx = /^([0-9a-f]{2})*$/i; return myRegEx.test(data.off);",
295
+ "validatorNoSaveOnError": true,
291
296
  "hidden": "data.type !== 'boolean'",
292
297
  "sm":2
293
298
  },
@@ -299,6 +304,7 @@
299
304
  "tooltip": "onClickTooltip",
300
305
  "default": "030111",
301
306
  "validator": "const myRegEx = /^([0-9a-f]{2})*$/i; return myRegEx.test(data.onClick);",
307
+ "validatorNoSaveOnError": true,
302
308
  "hidden": "data.type !== 'button'",
303
309
  "sm":2
304
310
  },
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "lorawan",
4
- "version": "0.3.6",
4
+ "version": "0.3.7",
5
5
  "news": {
6
+ "0.3.7": {
7
+ "en": "improove forbidden chars and implements join raw",
8
+ "de": "unproove verbotene wagen und geräte roh beitreten",
9
+ "ru": "импровизировать запрещенные шары и реализаций присоединяются к сырому",
10
+ "pt": "improove proibido chars e implementos se juntar cru",
11
+ "nl": "improove verboden tekens en werktuigen samen rauw",
12
+ "fr": "improove prohibed chars and implements joignent brut",
13
+ "it": "improove vietati carboni e strumenti si uniscono crudo",
14
+ "es": "improove chars prohibidos e implementos se unen a crudo",
15
+ "pl": "improove zakazane znaki i narzędzia dołączyć surowe",
16
+ "uk": "неприпустимий заборонений діаграма і реалізує приєднатися до сировини",
17
+ "zh-cn": "将禁用字符和工具合并为原始字符"
18
+ },
6
19
  "0.3.6": {
7
20
  "en": "set attributs if undefined",
8
21
  "de": "wenn nicht definiert",
@@ -80,19 +93,6 @@
80
93
  "pl": "odbudowa dzięki lepszemu rozwiązywaniu problemów",
81
94
  "uk": "перебудувати краще повідомлення",
82
95
  "zh-cn": "以更好的信息重建"
83
- },
84
- "0.3.0": {
85
- "en": "define user friendly Blockly Blocks with result",
86
- "de": "benutzerfreundlich definieren Blockly Blocks mit Ergebnis",
87
- "ru": "определение пользователя Блоки с результатом",
88
- "pt": "definir amigável Blocos com resultado",
89
- "nl": "gebruikersvriendelijk definiëren Blokkeren met resultaat",
90
- "fr": "définir une utilisation conviviale Blocs avec résultat",
91
- "it": "definire l'utente amichevole Blocchi Blockly con risultato",
92
- "es": "definir fácil de usar Bloqueo bloques con resultado",
93
- "pl": "zdefiniować przyjazny dla użytkownika Blokady z wynikiem",
94
- "uk": "визначення дружності користувача Блокнотні блоки з результатом",
95
- "zh-cn": "定义用户友好 块状块及结果"
96
96
  }
97
97
  },
98
98
  "title": "LoRaWAN",
@@ -24,7 +24,9 @@ class directorieshandlerClass {
24
24
  downlinkControl: "downlink.control",
25
25
  downlinkRemaining: "downlink.remaining",
26
26
  downlinkNextSend: "downlink.nextSend",
27
- downlinkLastSend: "downlink.lastSend"
27
+ downlinkLastSend: "downlink.lastSend",
28
+ join: "join",
29
+ joinRaw: "join.raw"
28
30
  };
29
31
 
30
32
  //define path for uplink roles
@@ -96,6 +98,10 @@ class directorieshandlerClass {
96
98
  remaining:{
97
99
  }
98
100
  },
101
+ join:{
102
+ raw:{
103
+ }
104
+ }
99
105
  }
100
106
  }
101
107
  }
@@ -44,17 +44,17 @@ class downlinkConfighandlerClass {
44
44
  const activeFunction = "addAndMergeDownlinkConfigs";
45
45
  this.adapter.log.silly(`the standard and configed downlinks will be merged`);
46
46
  try{
47
- // Add standard downlink config
47
+ // Add user downlink config first
48
+ for(const downlinkConfig of Object.values(this.adapter.config.downlinkConfig)){
49
+ this.addDownlinkConfigByType(downlinkConfig,this.activeDownlinkConfigs);
50
+ }
51
+ // Add standard downlink config if devices not present
48
52
  const internalDownlinks = this.getJsonArrayFromDirectoryfiles(`${this.adapter.adapterDir}${this.deviceProfilesPath}`);
49
53
  if(Array.isArray(internalDownlinks)){
50
54
  for(const downlinkConfig of Object.values(internalDownlinks)){
51
55
  this.addDownlinkConfigByType(downlinkConfig,this.activeDownlinkConfigs);
52
56
  }
53
57
  }
54
- // Add user downlink config
55
- for(const downlinkConfig of Object.values(this.adapter.config.downlinkConfig)){
56
- this.addDownlinkConfigByType(downlinkConfig,this.activeDownlinkConfigs);
57
- }
58
58
  // Check active userconfig
59
59
  const adapterId = `system.adapter.${this.adapter.namespace}`;
60
60
  const obj = await this.adapter.getForeignObjectAsync(adapterId);
@@ -89,22 +89,25 @@ class downlinkConfighandlerClass {
89
89
  addDownlinkConfigByType(downlinkConfig,config){
90
90
  const activeFunction = "addDownlinkConfigByType";
91
91
  try{
92
- // override standard with userconfig
93
- config[downlinkConfig.deviceType] = structuredClone(downlinkConfig);
94
- config[downlinkConfig.deviceType].downlinkState = {};
95
- // generate downlinkstates for internal use
96
- for(const downlinkParameter of Object.values(config[downlinkConfig.deviceType].downlinkParameter)){
97
- // check name for forbidden chars
98
- downlinkParameter.name = downlinkParameter.name.replace(this.adapter.FORBIDDEN_CHARS,"_");
99
- // check the downlinkparameters for all needed attributes and generate them if undefined
100
- for(const attribute in this.downlinkParameterAttributs){
101
- if(downlinkConfig.deviceType !== this.internalDevices.baseDevice && downlinkParameter[attribute] === undefined){
102
- this.adapter.log.debug(`attribute ${attribute} in parameter ${downlinkParameter.name} at devicetype ${downlinkConfig.deviceType} generated`);
103
- downlinkParameter[attribute] = this.downlinkParameterAttributs[attribute];
92
+ // Check for device not present
93
+ if(!config[downlinkConfig.deviceType]){
94
+ // override standard with userconfig
95
+ config[downlinkConfig.deviceType] = structuredClone(downlinkConfig);
96
+ config[downlinkConfig.deviceType].downlinkState = {};
97
+ // generate downlinkstates for internal use
98
+ for(const downlinkParameter of Object.values(config[downlinkConfig.deviceType].downlinkParameter)){
99
+ // check name for forbidden chars
100
+ downlinkParameter.name = downlinkParameter.name.replace(this.adapter.FORBIDDEN_CHARS,"_");
101
+ // check the downlinkparameters for all needed attributes and generate them if undefined
102
+ for(const attribute in this.downlinkParameterAttributs){
103
+ if(downlinkConfig.deviceType !== this.internalDevices.baseDevice && downlinkParameter[attribute] === undefined){
104
+ this.adapter.log.debug(`attribute ${attribute} in parameter ${downlinkParameter.name} at devicetype ${downlinkConfig.deviceType} generated`);
105
+ downlinkParameter[attribute] = this.downlinkParameterAttributs[attribute];
106
+ }
104
107
  }
108
+ // assign downlinkparamter to internal structure
109
+ config[downlinkConfig.deviceType].downlinkState[downlinkParameter.name] = downlinkParameter;
105
110
  }
106
- // assign downlinkparamter to internal structure
107
- config[downlinkConfig.deviceType].downlinkState[downlinkParameter.name] = downlinkParameter;
108
111
  }
109
112
  }
110
113
  catch(error){
@@ -185,7 +185,7 @@ class messagehandlerClass {
185
185
  * ****************** Check device startdirectory ********************
186
186
  * ******************************************************************/
187
187
 
188
- if(messageType !== "up" && !await this.adapter.objectExists(`${deviceStartdirectory}`)){
188
+ if(messageType !== "up" && messageType !== "join" && !await this.adapter.objectExists(`${deviceStartdirectory}`)){
189
189
  this.adapter.log.debug(`There was a message with the topic ${topic}, but the object ${deviceStartdirectory} does not exists yet.`);
190
190
  return;
191
191
  }
@@ -199,7 +199,7 @@ class messagehandlerClass {
199
199
  * ******************************************************************/
200
200
 
201
201
  // check for uplink message
202
- if(messageType === "up"){//if(message.uplink_message){
202
+ if(messageType === "up"){
203
203
  /*********************************************************************
204
204
  * ************************ Main directories *************************
205
205
  * ******************************************************************/
@@ -211,9 +211,9 @@ class messagehandlerClass {
211
211
  * ******************************************************************/
212
212
 
213
213
  this.adapter.log.silly(`write rawdata`);
214
- let startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRaw}`;
214
+ let startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRaw}`;
215
215
  // write json
216
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.json`,{
216
+ await this.adapter.setObjectNotExistsAsync(`${startId}.json`,{
217
217
  type: "state",
218
218
  common: {
219
219
  name: "last recieved message",
@@ -224,7 +224,7 @@ class messagehandlerClass {
224
224
  },
225
225
  native: {},
226
226
  });
227
- await this.adapter.setStateAsync(`${startDirectory}.json`,JSON.stringify(message),true);
227
+ await this.adapter.setStateAsync(`${startId}.json`,JSON.stringify(message),true);
228
228
 
229
229
  /*********************************************************************
230
230
  * ********************** Rawdata (Base64) ***************************
@@ -233,7 +233,7 @@ class messagehandlerClass {
233
233
  if(message.uplink_message.frm_payload){
234
234
  // wite base64 data
235
235
  this.adapter.log.silly(`write base64`);
236
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.base64`,{
236
+ await this.adapter.setObjectNotExistsAsync(`${startId}.base64`,{
237
237
  type: "state",
238
238
  common: {
239
239
  name: "last recieved data as base64",
@@ -245,11 +245,11 @@ class messagehandlerClass {
245
245
  native: {},
246
246
  });
247
247
  const writedata = message.uplink_message.frm_payload;
248
- await this.adapter.setStateAsync(`${startDirectory}.base64`,writedata,true);
248
+ await this.adapter.setStateAsync(`${startId}.base64`,writedata,true);
249
249
 
250
250
  // write base64 data in hex data
251
251
  this.adapter.log.silly(`write hex`);
252
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.hex`,{
252
+ await this.adapter.setObjectNotExistsAsync(`${startId}.hex`,{
253
253
  type: "state",
254
254
  common: {
255
255
  name: "last recieved data as hex",
@@ -261,11 +261,11 @@ class messagehandlerClass {
261
261
  native: {},
262
262
  });
263
263
  const hexdata = Buffer.from(message.uplink_message.frm_payload, "base64").toString("hex").toUpperCase();
264
- await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
264
+ await this.adapter.setStateAsync(`${startId}.hex`,hexdata,true);
265
265
 
266
266
  // write base64 data in string data
267
267
  this.adapter.log.silly(`write string`);
268
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
268
+ await this.adapter.setObjectNotExistsAsync(`${startId}.string`,{
269
269
  type: "state",
270
270
  common: {
271
271
  name: "last recieved data as string",
@@ -277,25 +277,25 @@ class messagehandlerClass {
277
277
  native: {},
278
278
  });
279
279
  const stringdata = Buffer.from(message.uplink_message.frm_payload, "base64").toString();
280
- await this.adapter.setStateAsync(`${startDirectory}.string`,stringdata,true);
280
+ await this.adapter.setStateAsync(`${startId}.string`,stringdata,true);
281
281
  }
282
282
 
283
283
  /*********************************************************************
284
284
  * ********************** decoded payload ****************************
285
285
  * ******************************************************************/
286
286
 
287
- startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkDecoded}`;
287
+ startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkDecoded}`;
288
288
  this.adapter.log.silly(`write decoded payload`);
289
- await this.directoryhandler.generateRekursivObjects(message.uplink_message.decoded_payload,startDirectory,topic,message);
289
+ await this.directoryhandler.generateRekursivObjects(message.uplink_message.decoded_payload,startId,topic,message);
290
290
 
291
291
  /*********************************************************************
292
292
  * ************************* remaining *******************************
293
293
  * ******************************************************************/
294
294
 
295
- startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRemaining}`;
295
+ startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRemaining}`;
296
296
  this.adapter.log.silly(`write remaining uplink data`);
297
297
 
298
- await this.directoryhandler.generateRekursivObjects(message.uplink_message,startDirectory,topic,message,{ignoredElementNames:{decoded_payload:{},frm_payload:{}}});
298
+ await this.directoryhandler.generateRekursivObjects(message.uplink_message,startId,topic,message,{ignoredElementNames:{decoded_payload:{},frm_payload:{}}});
299
299
 
300
300
  /*********************************************************************
301
301
  * ******************* Check downlink at uplink **********************
@@ -309,17 +309,17 @@ class messagehandlerClass {
309
309
  * ******************************************************************/
310
310
 
311
311
  // check for uplink message
312
- else if(messageType === "queued" || messageType === "sent"){ //if(message.downlink_queued || message.downlink_sent)//if(message.downlink_queued || message.downlink_sent){
312
+ else if(messageType === "queued" || messageType === "sent"){
313
313
  // Check wich downlink was recieved
314
314
  const downlinkType = `downlink_${messageType}`;
315
315
  /*********************************************************************
316
316
  * ************************ Rawdata json *****************************
317
317
  * ******************************************************************/
318
318
 
319
- let startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.downlinkRaw}`;
319
+ let startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.downlinkRaw}`;
320
320
  // write json
321
321
  this.adapter.log.silly(`write rawdata`);
322
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.json`,{
322
+ await this.adapter.setObjectNotExistsAsync(`${startId}.json`,{
323
323
  type: "state",
324
324
  common: {
325
325
  name: "last recieved message",
@@ -330,7 +330,7 @@ class messagehandlerClass {
330
330
  },
331
331
  native: {},
332
332
  });
333
- await this.adapter.setStateAsync(`${startDirectory}.json`,JSON.stringify(message),true);
333
+ await this.adapter.setStateAsync(`${startId}.json`,JSON.stringify(message),true);
334
334
 
335
335
  /*********************************************************************
336
336
  * ********************** Rawdata (Base64) ***************************
@@ -340,7 +340,7 @@ class messagehandlerClass {
340
340
  this.adapter.log.silly(`write base64`);
341
341
  if(message[downlinkType].frm_payload){
342
342
  // wite base64 data
343
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.base64`,{
343
+ await this.adapter.setObjectNotExistsAsync(`${startId}.base64`,{
344
344
  type: "state",
345
345
  common: {
346
346
  name: "last recieved data as base64",
@@ -352,11 +352,11 @@ class messagehandlerClass {
352
352
  native: {},
353
353
  });
354
354
  const writedata = message[downlinkType].frm_payload;
355
- await this.adapter.setStateAsync(`${startDirectory}.base64`,writedata,true);
355
+ await this.adapter.setStateAsync(`${startId}.base64`,writedata,true);
356
356
 
357
357
  // write base64 data in hex data
358
358
  this.adapter.log.silly(`write hex`);
359
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.hex`,{
359
+ await this.adapter.setObjectNotExistsAsync(`${startId}.hex`,{
360
360
  type: "state",
361
361
  common: {
362
362
  name: "last recieved data as hex",
@@ -368,11 +368,11 @@ class messagehandlerClass {
368
368
  native: {},
369
369
  });
370
370
  const hexdata = Buffer.from(message[downlinkType].frm_payload,"base64").toString("hex").toUpperCase();
371
- await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
371
+ await this.adapter.setStateAsync(`${startId}.hex`,hexdata,true);
372
372
 
373
373
  // write base64 data in string data
374
374
  this.adapter.log.silly(`write string`);
375
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
375
+ await this.adapter.setObjectNotExistsAsync(`${startId}.string`,{
376
376
  type: "state",
377
377
  common: {
378
378
  name: "last recieved data as string",
@@ -384,16 +384,52 @@ class messagehandlerClass {
384
384
  native: {},
385
385
  });
386
386
  const stringdata = Buffer.from(message[downlinkType].frm_payload,"base64").toString();
387
- await this.adapter.setStateAsync(`${startDirectory}.string`,stringdata,true);
387
+ await this.adapter.setStateAsync(`${startId}.string`,stringdata,true);
388
388
  }
389
389
 
390
390
  /*********************************************************************
391
391
  * ************************* remaining *******************************
392
392
  * ******************************************************************/
393
393
 
394
- startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.downlinkRemaining}`;
394
+ startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.downlinkRemaining}`;
395
395
  this.adapter.log.silly(`write remaining downlink data`);
396
- await this.directoryhandler.generateRekursivObjects(message[downlinkType],startDirectory,topic,message,{ignoredElementNames:{frm_payload:{}}});
396
+ await this.directoryhandler.generateRekursivObjects(message[downlinkType],startId,topic,message,{ignoredElementNames:{frm_payload:{}}});
397
+ }
398
+
399
+ // check for join message
400
+ else if(messageType === "join"){
401
+
402
+ /*********************************************************************
403
+ * ************************ Main directories *************************
404
+ * ******************************************************************/
405
+
406
+ await this.directoryhandler.generateRekursivObjects(this.directoryhandler.directories,"",topic,message);
407
+
408
+ /*********************************************************************
409
+ * ************************ Rawdata json *****************************
410
+ * ******************************************************************/
411
+
412
+ this.adapter.log.silly(`write rawdata`);
413
+ const startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.joinRaw}`;
414
+ // write json
415
+ await this.adapter.setObjectNotExistsAsync(`${startId}.json`,{
416
+ type: "state",
417
+ common: {
418
+ name: "last recieved message",
419
+ type: "json",
420
+ role: "value",
421
+ read: true,
422
+ write: false
423
+ },
424
+ native: {},
425
+ });
426
+ await this.adapter.setStateAsync(`${startId}.json`,JSON.stringify(message),true);
427
+ const changeInfo = await this.adapter.getChangeInfo(startId);
428
+ this.adapter.log.info(`the device ${changeInfo.deviceEUI} joined network`);
429
+ }
430
+ // Other messagetypes
431
+ else{
432
+ this.adapter.log.debug(`the messagetype: ${messageType}, is not implemented yet`);
397
433
  }
398
434
 
399
435
  /*********************************************************************
@@ -434,7 +470,7 @@ class messagehandlerClass {
434
470
  * ****************** Check device startdirectory ********************
435
471
  * ******************************************************************/
436
472
 
437
- if(messageType !== "up" && !await this.adapter.objectExists(`${deviceStartdirectory}`)){
473
+ if(messageType !== "up" && messageType !== "join" && !await this.adapter.objectExists(`${deviceStartdirectory}`)){
438
474
  this.adapter.log.debug(`There was a message with the topic ${topic}, but the object ${deviceStartdirectory} does not exists yet.`);
439
475
  return;
440
476
  }
@@ -448,7 +484,7 @@ class messagehandlerClass {
448
484
  * ******************************************************************/
449
485
 
450
486
  // check for uplink message
451
- if(messageType === "up"){//if(message.uplink_message){
487
+ if(messageType === "up"){
452
488
 
453
489
  /*********************************************************************
454
490
  * ************************ Main directories *************************
@@ -460,10 +496,10 @@ class messagehandlerClass {
460
496
  * ************************ Rawdata json *****************************
461
497
  * ******************************************************************/
462
498
 
463
- let startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRaw}`;
499
+ let startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRaw}`;
464
500
  // write json
465
501
  this.adapter.log.silly(`write rawdata`);
466
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.json`,{
502
+ await this.adapter.setObjectNotExistsAsync(`${startId}.json`,{
467
503
  type: "state",
468
504
  common: {
469
505
  name: "last recieved message",
@@ -474,7 +510,7 @@ class messagehandlerClass {
474
510
  },
475
511
  native: {},
476
512
  });
477
- await this.adapter.setStateAsync(`${startDirectory}.json`,JSON.stringify(message),true);
513
+ await this.adapter.setStateAsync(`${startId}.json`,JSON.stringify(message),true);
478
514
 
479
515
  /*********************************************************************
480
516
  * ********************** Rawdata (Base64) ***************************
@@ -483,7 +519,7 @@ class messagehandlerClass {
483
519
  if(message.data){
484
520
  // wite base64 data
485
521
  this.adapter.log.silly(`write base64`);
486
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.base64`,{
522
+ await this.adapter.setObjectNotExistsAsync(`${startId}.base64`,{
487
523
  type: "state",
488
524
  common: {
489
525
  name: "last recieved data as base64",
@@ -495,11 +531,11 @@ class messagehandlerClass {
495
531
  native: {},
496
532
  });
497
533
  const writedata = message.data;
498
- await this.adapter.setStateAsync(`${startDirectory}.base64`,writedata,true);
534
+ await this.adapter.setStateAsync(`${startId}.base64`,writedata,true);
499
535
 
500
536
  // write base64 data in hex data
501
537
  this.adapter.log.silly(`write hex`);
502
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.hex`,{
538
+ await this.adapter.setObjectNotExistsAsync(`${startId}.hex`,{
503
539
  type: "state",
504
540
  common: {
505
541
  name: "last recieved data as hex",
@@ -511,11 +547,11 @@ class messagehandlerClass {
511
547
  native: {},
512
548
  });
513
549
  const hexdata = Buffer.from(message.data, "base64").toString("hex").toUpperCase();
514
- await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
550
+ await this.adapter.setStateAsync(`${startId}.hex`,hexdata,true);
515
551
 
516
552
  // write base64 data in string data
517
553
  this.adapter.log.silly(`write string`);
518
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
554
+ await this.adapter.setObjectNotExistsAsync(`${startId}.string`,{
519
555
  type: "state",
520
556
  common: {
521
557
  name: "last recieved data as string",
@@ -527,23 +563,23 @@ class messagehandlerClass {
527
563
  native: {},
528
564
  });
529
565
  const stringdata = Buffer.from(message.data, "base64").toString();
530
- await this.adapter.setStateAsync(`${startDirectory}.string`,stringdata,true);
566
+ await this.adapter.setStateAsync(`${startId}.string`,stringdata,true);
531
567
  }
532
568
 
533
569
  /*********************************************************************
534
570
  * ****************** decoded payload (Object) ***********************
535
571
  * ******************************************************************/
536
- startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkDecoded}`;
572
+ startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkDecoded}`;
537
573
  this.adapter.log.silly(`write decoded payload (Object)`);
538
- await this.directoryhandler.generateRekursivObjects(message.object,startDirectory,topic,message);
574
+ await this.directoryhandler.generateRekursivObjects(message.object,startId,topic,message);
539
575
 
540
576
  /*********************************************************************
541
577
  * ************************* remaining *******************************
542
578
  * ******************************************************************/
543
579
 
544
- startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRemaining}`;
580
+ startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRemaining}`;
545
581
  this.adapter.log.silly(`write remaining uplink data`);
546
- await this.directoryhandler.generateRekursivObjects(message,startDirectory,topic,message,{ignoredElementNames:{deduplicationId:{},deviceInfo:{},data:{},object:{}}});
582
+ await this.directoryhandler.generateRekursivObjects(message,startId,topic,message,{ignoredElementNames:{deduplicationId:{},deviceInfo:{},data:{},object:{}}});
547
583
 
548
584
  /*********************************************************************
549
585
  * ******************* Check downlink at uplink **********************
@@ -557,16 +593,16 @@ class messagehandlerClass {
557
593
  * ******************************************************************/
558
594
 
559
595
  // check for uplink message
560
- else if(messageType === "down"){ //if(message.downlink_queued || message.downlink_sent)//if(message.downlink_queued || message.downlink_sent){
596
+ else if(messageType === "down"){
561
597
 
562
598
  /*********************************************************************
563
599
  * ************************ Rawdata json *****************************
564
600
  * ******************************************************************/
565
601
 
566
- const startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.downlinkRaw}`;
602
+ const startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.downlinkRaw}`;
567
603
  // write json
568
604
  this.adapter.log.silly(`write rawdata`);
569
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.json`,{
605
+ await this.adapter.setObjectNotExistsAsync(`${startId}.json`,{
570
606
  type: "state",
571
607
  common: {
572
608
  name: "last recieved message",
@@ -577,7 +613,7 @@ class messagehandlerClass {
577
613
  },
578
614
  native: {},
579
615
  });
580
- await this.adapter.setStateAsync(`${startDirectory}.json`,JSON.stringify(message),true);
616
+ await this.adapter.setStateAsync(`${startId}.json`,JSON.stringify(message),true);
581
617
 
582
618
  /*********************************************************************
583
619
  * ********************** Rawdata (Base64) ***************************
@@ -587,7 +623,7 @@ class messagehandlerClass {
587
623
  if(message.data){
588
624
  // wite base64 data
589
625
  this.adapter.log.silly(`write base64`);
590
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.base64`,{
626
+ await this.adapter.setObjectNotExistsAsync(`${startId}.base64`,{
591
627
  type: "state",
592
628
  common: {
593
629
  name: "last recieved data as base64",
@@ -599,11 +635,11 @@ class messagehandlerClass {
599
635
  native: {},
600
636
  });
601
637
  const writedata = message.data;
602
- await this.adapter.setStateAsync(`${startDirectory}.base64`,writedata,true);
638
+ await this.adapter.setStateAsync(`${startId}.base64`,writedata,true);
603
639
 
604
640
  // write base64 data in hex data
605
641
  this.adapter.log.silly(`write hex`);
606
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.hex`,{
642
+ await this.adapter.setObjectNotExistsAsync(`${startId}.hex`,{
607
643
  type: "state",
608
644
  common: {
609
645
  name: "last recieved data as hex",
@@ -615,11 +651,11 @@ class messagehandlerClass {
615
651
  native: {},
616
652
  });
617
653
  const hexdata = Buffer.from(message.data,"base64").toString("hex").toUpperCase();
618
- await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
654
+ await this.adapter.setStateAsync(`${startId}.hex`,hexdata,true);
619
655
 
620
656
  // write base64 data in string data
621
657
  this.adapter.log.silly(`write string`);
622
- await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
658
+ await this.adapter.setObjectNotExistsAsync(`${startId}.string`,{
623
659
  type: "state",
624
660
  common: {
625
661
  name: "last recieved data as string",
@@ -631,7 +667,7 @@ class messagehandlerClass {
631
667
  native: {},
632
668
  });
633
669
  const stringdata = Buffer.from(message.data,"base64").toString();
634
- await this.adapter.setStateAsync(`${startDirectory}.string`,stringdata,true);
670
+ await this.adapter.setStateAsync(`${startId}.string`,stringdata,true);
635
671
  }
636
672
 
637
673
  /*********************************************************************
@@ -639,6 +675,42 @@ class messagehandlerClass {
639
675
  * ******************************************************************/
640
676
 
641
677
  }
678
+
679
+ // check for uplink message
680
+ else if(messageType === "join"){
681
+ /*********************************************************************
682
+ * ************************ Main directories *************************
683
+ * ******************************************************************/
684
+
685
+ await this.directoryhandler.generateRekursivObjects(this.directoryhandler.directories,"",topic,message);
686
+
687
+ /*********************************************************************
688
+ * ************************ Rawdata json *****************************
689
+ * ******************************************************************/
690
+
691
+ const startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.joinRaw}`;
692
+ // write json
693
+ this.adapter.log.silly(`write rawdata`);
694
+ await this.adapter.setObjectNotExistsAsync(`${startId}.json`,{
695
+ type: "state",
696
+ common: {
697
+ name: "last recieved message",
698
+ type: "json",
699
+ role: "value",
700
+ read: true,
701
+ write: false
702
+ },
703
+ native: {},
704
+ });
705
+ await this.adapter.setStateAsync(`${startId}.json`,JSON.stringify(message),true);
706
+ const changeInfo = await this.adapter.getChangeInfo(startId);
707
+ this.adapter.log.info(`the device ${changeInfo.deviceEUI} joined network`);
708
+ }
709
+ // Other messagetypes
710
+ else{
711
+ this.adapter.log.debug(`the messagetype: ${messageType}, is not implemented yet`);
712
+ }
713
+
642
714
  /*********************************************************************
643
715
  * ********************** downlinkConfigs ****************************
644
716
  * ******************************************************************/
@@ -54,9 +54,9 @@ class mqttClientClass {
54
54
  getSubscribtionArray(){
55
55
  switch(this.adapter.config.origin){
56
56
  case this.adapter.origin.ttn:
57
- return ["v3/+/devices/+/up","v3/+/devices/+/down/#"];
57
+ return ["v3/+/devices/+/+","v3/+/devices/+/down/+"];
58
58
  case this.adapter.origin.chirpstack:
59
- return ["application/+/device/+/event/up","application/+/device/+/command/down"];
59
+ return ["application/+/device/+/event/+","application/+/device/+/command/down"];
60
60
  }
61
61
  }
62
62
  }
package/main.js CHANGED
@@ -82,8 +82,8 @@ class Lorawan extends utils.Adapter {
82
82
  //const message = {"end_device_ids":{"device_id":"eui-lobaro-modbus","application_ids":{"application_id":"hafi-ttn-lorawan"},"dev_eui":"70B3D5E050013950","join_eui":"D55B58C0DDC074DE","dev_addr":"260B5972"},"correlation_ids":["gs:uplink:01HMQZVSCX4D7JRDNFA7GJ9D4W"],"received_at":"2024-01-22T07:06:25.260676101Z","uplink_message":{"session_key_id":"AY0v/ZirzRkpNW0Cgjdhig==","f_port":20,"f_cnt":2,"frm_payload":"AA5BAf0AxwIAAQ==","decoded_payload":{"airhumidity":50.9,"airtemperature":19.9,"port":20,"relais1":0,"relais2":1,"relais3":null,"relais5":null,"volt":3.649,"zisternenpegel":2},"rx_metadata":[{"gateway_ids":{"gateway_id":"hafenmeister-port2ttn-ng","eui":"50313953530A4750"},"time":"2024-01-22T07:06:25.013878Z","timestamp":995696116,"rssi":-37,"channel_rssi":-37,"snr":8.5,"location":{"latitude":53.5548443059465,"longitude":9.92155426743724,"altitude":10,"source":"SOURCE_REGISTRY"},"uplink_token":"CiYKJAoYaGFmZW5tZWlzdGVyLXBvcnQydHRuLW5nEghQMTlTUwpHUBD0u+TaAxoLCPGnuK0GEM3uvhkgoIL0oP24Sg==","channel_index":5,"received_at":"2024-01-22T07:06:25.032492359Z"}],"settings":{"data_rate":{"lora":{"bandwidth":125000,"spreading_factor":9,"coding_rate":"4/5"}},"frequency":"867500000","timestamp":995696116,"time":"2024-01-22T07:06:25.013878Z"},"received_at":"2024-01-22T07:06:25.054442349Z","consumed_airtime":"0.205824s","network_ids":{"net_id":"000013","ns_id":"EC656E0000000181","tenant_id":"ttn","cluster_id":"eu1","cluster_address":"eu1.cloud.thethings.network"}}};
83
83
 
84
84
  // ACK
85
- const topic = "v3/hafi-ttn-lorawan@ttn/devices/eui-a84041162183f8fb/down/ack";
86
- const message = {"end_device_ids":{"device_id":"eui-a84041162183f8fb","application_ids":{"application_id":"hafi-ttn-lorawan"},"dev_eui":"A84041162183F8FB","join_eui":"A840410000000101","dev_addr":"260B141A"},"correlation_ids":["as:downlink:01HP6D18MQXJN90J5B07DC11HY","gs:uplink:01HP6D1A9X4WAA3SFMXH4ESSMV"],"received_at":"2024-02-09T07:41:41.776887672Z","downlink_ack":{"session_key_id":"AY2MUrmnuovS8DCZAfYmsA==","f_port":1,"f_cnt":21,"frm_payload":"AQAAeA==","confirmed":true,"priority":"NORMAL","correlation_ids":["as:downlink:01HP6D18MQXJN90J5B07DC11HY"],"confirmed_retry":{"attempt":1}}};
85
+ //const topic = "v3/hafi-ttn-lorawan@ttn/devices/eui-a84041162183f8fb/down/ack";
86
+ //const message = {"end_device_ids":{"device_id":"eui-a84041162183f8fb","application_ids":{"application_id":"hafi-ttn-lorawan"},"dev_eui":"A84041162183F8FB","join_eui":"A840410000000101","dev_addr":"260B141A"},"correlation_ids":["as:downlink:01HP6D18MQXJN90J5B07DC11HY","gs:uplink:01HP6D1A9X4WAA3SFMXH4ESSMV"],"received_at":"2024-02-09T07:41:41.776887672Z","downlink_ack":{"session_key_id":"AY2MUrmnuovS8DCZAfYmsA==","f_port":1,"f_cnt":21,"frm_payload":"AQAAeA==","confirmed":true,"priority":"NORMAL","correlation_ids":["as:downlink:01HP6D18MQXJN90J5B07DC11HY"],"confirmed_retry":{"attempt":1}}};
87
87
 
88
88
  // Chipstack
89
89
  //const topic = "application/d63c10b6-9263-4ab3-9299-4308fa19a2ad/device/a84041f621857cd2/event/up";
@@ -118,8 +118,8 @@ class Lorawan extends utils.Adapter {
118
118
  //const message = {"time":"2024-01-27T10:29:58.221817559+00:00","deviceInfo":{"tenantId":"52f14cd4-c6f1-4fbd-8f87-4025e1d49242","tenantName":"ChirpStack","applicationId":"59bcc5a7-59e2-4481-9615-fc4e58791915","applicationName":"Mclimate_Vicki","deviceProfileId":"3a9bc28f-3664-4bdf-b3be-a20d1eb32dc8","deviceProfileName":"Mclimate_Vicki","deviceName":"MClimate_Vicki_Heizkoerperventil_001","devEui":"70b3d52dd300ed31","deviceClassEnabled":"CLASS_A","tags":{}},"level":"ERROR","code":"UPLINK_CODEC","description":"Exception generated by quickjs","context":{"deduplication_id":"c44e7e25-09ce-4c95-b96f-5a298c5c6440"}};
119
119
 
120
120
  // JOIN
121
- //const topic = "application/59bcc5a7-59e2-4481-9615-fc4e58791915/device/70b3d52dd300ed31/event/join";
122
- //const message = {"deduplicationId":"44cef56d-1b8d-45fc-a762-03b98b620db2","time":"2023-12-12T03:13:21.551178+00:00","deviceInfo":{"tenantId":"52f14cd4-c6f1-4fbd-8f87-4025e1d49242","tenantName":"ChirpStack","applicationId":"59bcc5a7-59e2-4481-9615-fc4e58791915","applicationName":"Mclimate_Vicki","deviceProfileId":"3a9bc28f-3664-4bdf-b3be-a20d1eb32dc8","deviceProfileName":"Mclimate_Vicki","deviceName":"MClimate_Vicki_Heizkoerperventil_001","devEui":"70b3d52dd300ed31","deviceClassEnabled":"CLASS_A","tags":{}},"devAddr":"01009400"};
121
+ const topic = "application/59bcc5a7-59e2-4481-9615-fc4e58791915/device/70b3d52dd300ed31/event/join";
122
+ const message = {"deduplicationId":"44cef56d-1b8d-45fc-a762-03b98b620db2","time":"2023-12-12T03:13:21.551178+00:00","deviceInfo":{"tenantId":"52f14cd4-c6f1-4fbd-8f87-4025e1d49242","tenantName":"ChirpStack","applicationId":"59bcc5a7-59e2-4481-9615-fc4e58791915","applicationName":"Mclimate_Vicki","deviceProfileId":"3a9bc28f-3664-4bdf-b3be-a20d1eb32dc8","deviceProfileName":"Mclimate_Vicki","deviceName":"MClimate_Vicki_Heizkoerperventil_001","devEui":"70b3d52dd300ed31","deviceClassEnabled":"CLASS_A","tags":{}},"devAddr":"01009400"};
123
123
 
124
124
  // DOWN
125
125
  //const topic = "application/59bcc5a7-59e2-4481-9615-fc4e58791915/device/70b3d52dd300ed31/command/down";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.lorawan",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "description": "converts the desired lora gateway data to a ioBroker structure",
5
5
  "author": {
6
6
  "name": "BenAhrdt",