iobroker.lorawan 1.20.21 → 1.20.23

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
@@ -23,6 +23,12 @@ For now there is documentation in English here: https://wiki.hafenmeister.de
23
23
  Placeholder for the next version (at the beginning of the line):
24
24
  ### **WORK IN PROGRESS**
25
25
  -->
26
+ ### 1.20.23 (2026-01-28)
27
+ * (BenAhrdt) change role display and icons
28
+
29
+ ### 1.20.22 (2026-01-27)
30
+ * (BenAhrdt) change preasure quere to pressure
31
+
26
32
  ### 1.20.21 (2026-01-27)
27
33
  * (BenAhrdt) set Details to informations and add icons for weateher station / humidity
28
34
 
Binary file
Binary file
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "lorawan",
4
- "version": "1.20.21",
4
+ "version": "1.20.23",
5
5
  "news": {
6
+ "1.20.23": {
7
+ "en": "change role display and icons",
8
+ "de": "rollenanzeige und icons ändern",
9
+ "ru": "изменить отображение ролей и иконки",
10
+ "pt": "alterar a exibição de funções e ícones",
11
+ "nl": "rolweergave en pictogrammen wijzigen",
12
+ "fr": "modifier l'affichage des rôles et les icônes",
13
+ "it": "modifica visualizzazione del ruolo e icone",
14
+ "es": "función de cambio de visualización e iconos",
15
+ "pl": "zmienić wyświetlacz ról i ikony",
16
+ "uk": "змінити відображення ролі та іконки",
17
+ "zh-cn": "更改角色显示和图标"
18
+ },
19
+ "1.20.22": {
20
+ "en": "change preasure quere to pressure",
21
+ "de": "voreinstellungsanfrage zum druck ändern",
22
+ "ru": "изменение преасмента к давлению",
23
+ "pt": "mudança preasure quere à pressão",
24
+ "nl": "verandering preasure quere aan druk",
25
+ "fr": "changement de mesure quere à pression",
26
+ "it": "cambiare la quere preasure alla pressione",
27
+ "es": "cambiar preasure quere a presión",
28
+ "pl": "zmiana preasure quere do ciśnienia",
29
+ "uk": "змінити запобіжний привід для тиску",
30
+ "zh-cn": "将预置排程改为压力"
31
+ },
6
32
  "1.20.21": {
7
33
  "en": "set Details to informations and add icons for weateher station / humidity",
8
34
  "de": "set Details zu Informationen und Icons für Weateher Station / Feuchtigkeit hinzufügen",
@@ -67,32 +93,6 @@
67
93
  "pl": "wdrożenie Szczegóły dotyczące urządzenia",
68
94
  "uk": "реалізація Деталі пристрою",
69
95
  "zh-cn": "执行 设备细节"
70
- },
71
- "1.20.16": {
72
- "en": "add informations to device Manager",
73
- "de": "informationen zum Gerätemanager hinzufügen",
74
- "ru": "добавление информации в диспетчер устройств",
75
- "pt": "adicionar informações ao gerenciador de dispositivos",
76
- "nl": "informatie toevoegen aan apparaatbeheer",
77
- "fr": "ajouter des informations au gestionnaire de périphériques",
78
- "it": "aggiungere informazioni al gestore del dispositivo",
79
- "es": "añadir información al administrador del dispositivo",
80
- "pl": "dodać informacje do urządzenia Manager",
81
- "uk": "додати інформацію в диспетчер пристроїв",
82
- "zh-cn": "向设备管理器添加信息"
83
- },
84
- "1.20.15": {
85
- "en": "sort output for informations",
86
- "de": "sortierausgabe für informationen",
87
- "ru": "сортировать выход для информации",
88
- "pt": "sort output para informações",
89
- "nl": "uitvoer voor informatie sorteren",
90
- "fr": "trier la sortie pour les informations",
91
- "it": "sort output per informazioni",
92
- "es": "salida de tipo para información",
93
- "pl": "sortowanie wyników dla informacji",
94
- "uk": "сортування інформації",
95
- "zh-cn": "信息排序输出"
96
96
  }
97
97
  },
98
98
  "titleLang": {
@@ -149,8 +149,10 @@ class LoRaWANDeviceManagement extends DeviceManagement {
149
149
  return possibleIcons.door;
150
150
  } else if (deviceValue.detectedRoles['sensor.window']) {
151
151
  return possibleIcons.window;
152
+ } else if (deviceValue.detectedRoles['sensor.contact']) {
153
+ return `/adapter/${this.adapter.name}/icons/sensor.contact.png`;
152
154
  } else if (deviceValue.detectedRoles['value.temperature']) {
153
- if (deviceValue.detectedRoles['value.preasure']) {
155
+ if (deviceValue.detectedRoles['value.pressure']) {
154
156
  return possibleIcons.weatherCurrent;
155
157
  }
156
158
  if (deviceValue.detectedRoles['value.humidity']) {
@@ -159,7 +161,7 @@ class LoRaWANDeviceManagement extends DeviceManagement {
159
161
  return possibleIcons.temperature;
160
162
  }
161
163
  }
162
- return 'node'; //`/adapter/${this.adapter.name}/icons/Node.png`; //${value.object.common.icon}`,
164
+ return possibleIcons.hub5; //`/adapter/${this.adapter.name}/icons/Node.png`; //${value.object.common.icon}`,
163
165
  }
164
166
 
165
167
  /**
@@ -249,6 +251,7 @@ class LoRaWANDeviceManagement extends DeviceManagement {
249
251
  */
250
252
  async handleInfo(id, context) {
251
253
  const generalItems = {};
254
+ const data = {};
252
255
  const lastUplinkTs = new Date(
253
256
  this.adapter.objectStore.devices[id].informations.lastUplink.state.ts,
254
257
  ).toLocaleString('de-DE', {
@@ -285,8 +288,6 @@ class LoRaWANDeviceManagement extends DeviceManagement {
285
288
  size: 16,
286
289
  data: lastJoinedLc,
287
290
  };
288
- } else {
289
- this.adapter.log.warn(JSON.stringify(this.adapter.objectStore.devices[id].join));
290
291
  }
291
292
 
292
293
  generalItems['uplinkDecodedHeader'] = {
@@ -309,13 +310,16 @@ class LoRaWANDeviceManagement extends DeviceManagement {
309
310
  continue;
310
311
  }
311
312
  for (const subfolder in value) {
313
+ if (!subfolder.startsWith('uplink') && subfolder !== 'downlink.control') {
314
+ continue;
315
+ }
312
316
  if (!subfolders[subfolder]) {
313
317
  subfolders[subfolder] = {};
314
318
  }
315
- subfolders[subfolder][key] = true;
319
+ subfolders[subfolder][key] = value[subfolder];
316
320
  }
317
321
  }
318
- subfolders = Object.fromEntries(Object.entries(subfolders).sort(([a], [b]) => a.localeCompare(b)));
322
+ subfolders = this.sortObjectDeep(subfolders);
319
323
  const roleItems = {};
320
324
  for (const subfolder in subfolders) {
321
325
  roleItems[subfolder] = {
@@ -324,17 +328,15 @@ class LoRaWANDeviceManagement extends DeviceManagement {
324
328
  text: subfolder,
325
329
  size: 3,
326
330
  };
327
- let detectedRoles = '';
328
- detectedRoles += Object.keys(subfolders[subfolder])
329
- .sort((a, b) => a.localeCompare(b))
330
- .join(' -- ');
331
-
332
- roleItems[`${subfolder}_Roles`] = {
333
- newLine: true,
334
- type: 'staticText',
335
- text: detectedRoles,
336
- size: 10,
331
+ const detectedRoles = Object.entries(subfolders[subfolder])
332
+ .map(([key, value]) => `${key}(${value})`)
333
+ .join(' ');
334
+ roleItems[`${subfolder.replace(/\./g, '_')}Roles`] = {
335
+ type: 'text',
336
+ minRows: 2,
337
+ readOnly: true,
337
338
  };
339
+ data[`${subfolder.replace(/\./g, '_')}Roles`] = detectedRoles;
338
340
  }
339
341
  const schema = {
340
342
  type: 'tabs',
@@ -354,14 +356,10 @@ class LoRaWANDeviceManagement extends DeviceManagement {
354
356
 
355
357
  let deviceInfo = await this.adapter.getStateAsync('info.deviceinformations');
356
358
  deviceInfo = JSON.parse(deviceInfo.val);
359
+ const sortedUplinkDecoded = this.sortObjectDeep(deviceInfo[id].uplink.decoded);
360
+ data.uplinkDecoded = JSON.stringify(sortedUplinkDecoded, null, 2);
357
361
  const options = {
358
- data: {
359
- uplinkDecoded: JSON.stringify(
360
- deviceInfo[id].uplink.decoded,
361
- Object.keys(deviceInfo[id].uplink.decoded).sort(),
362
- 2,
363
- ),
364
- },
362
+ data,
365
363
  title: this.adapter.i18nTranslation['Info of this device'],
366
364
  };
367
365
  await context.showForm(schema, options);
@@ -369,125 +367,24 @@ class LoRaWANDeviceManagement extends DeviceManagement {
369
367
  }
370
368
 
371
369
  /**
372
- * @param {string} id ID from device
373
- * @returns {Promise<import('@iobroker/dm-utils').DeviceDetails>} return the right value
370
+ *
371
+ * @param object Object to sort
374
372
  */
375
- async getDeviceDetails(id) {
376
- const generalItems = {};
377
- const lastUplinkTs = new Date(
378
- this.adapter.objectStore.devices[id].informations.lastUplink.state.ts,
379
- ).toLocaleString('de-DE', {
380
- weekday: 'long', // Mo
381
- year: 'numeric', // 2026
382
- month: '2-digit', // 01
383
- day: '2-digit', // 24
384
- hour: '2-digit', // 14
385
- minute: '2-digit', // 32
386
- second: '2-digit', // 10
387
- });
388
- generalItems['Timestamp_value'] = {
389
- type: 'staticInfo',
390
- label: 'LastUplink',
391
- size: 16,
392
- data: lastUplinkTs,
393
- };
394
- if (this.adapter.objectStore.devices[id].join?.raw?.json?.state?.lc) {
395
- const lastJoinedLc = new Date(this.adapter.objectStore.devices[id].join.raw.json.state.lc).toLocaleString(
396
- 'de-DE',
397
- {
398
- weekday: 'long', // Mo
399
- year: 'numeric', // 2026
400
- month: '2-digit', // 01
401
- day: '2-digit', // 24
402
- hour: '2-digit', // 14
403
- minute: '2-digit', // 32
404
- second: '2-digit', // 10
405
- },
406
- );
407
- generalItems['Join_value'] = {
408
- type: 'staticInfo',
409
- label: 'lastJoined',
410
- size: 16,
411
- data: lastJoinedLc,
412
- };
413
- } else {
414
- this.adapter.log.warn(JSON.stringify(this.adapter.objectStore.devices[id].join));
373
+ sortObjectDeep(object) {
374
+ if (Array.isArray(object)) {
375
+ return object.map(this.sortObjectDeep);
415
376
  }
416
377
 
417
- let deviceInfo = await this.adapter.getStateAsync('info.deviceinformations');
418
- deviceInfo = JSON.parse(deviceInfo.val);
419
- const data = JSON.stringify(
420
- deviceInfo[id].uplink.decoded,
421
- Object.keys(deviceInfo[id].uplink.decoded).sort(),
422
- 2,
423
- );
424
- generalItems['Uplink_decoded'] = {
425
- type: 'text',
426
- defaultSendTo: `BS:sendBack:${data}`,
427
- readOnly: true,
428
- minRows: 10,
429
- };
430
-
431
- let subfolders = {};
432
- for (const [key, value] of Object.entries(this.adapter.objectStore.devices[id].detectedRoles)) {
433
- if (key === 'state') {
434
- continue;
435
- }
436
- for (const subfolder in value) {
437
- if (!subfolders[subfolder]) {
438
- subfolders[subfolder] = {};
439
- }
440
- subfolders[subfolder][key] = true;
441
- }
442
- }
443
- subfolders = Object.fromEntries(Object.entries(subfolders).sort(([a], [b]) => a.localeCompare(b)));
444
- const roleItems = {};
445
- for (const subfolder in subfolders) {
446
- roleItems[subfolder] = {
447
- newLine: true,
448
- type: 'header',
449
- text: subfolder,
450
- size: 3,
451
- xs: 12,
452
- sm: 12,
453
- md: 12,
454
- lg: 12,
455
- xl: 12,
456
- };
457
- let detectedRoles = '';
458
- detectedRoles += Object.keys(subfolders[subfolder])
378
+ if (object !== null && typeof object === 'object') {
379
+ return Object.keys(object)
459
380
  .sort((a, b) => a.localeCompare(b))
460
- .join(' -- ');
461
-
462
- roleItems[`${subfolder}_Roles`] = {
463
- newLine: true,
464
- type: 'staticText',
465
- text: detectedRoles,
466
- size: 10,
467
- };
381
+ .reduce((acc, key) => {
382
+ acc[key] = this.sortObjectDeep(object[key]);
383
+ return acc;
384
+ }, {});
468
385
  }
469
- return {
470
- id,
471
- schema: {
472
- type: 'tabs',
473
- items: {
474
- generalTab: {
475
- type: 'panel',
476
- label: 'generalInformations',
477
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
478
- // @ts-expect-error
479
- items: generalItems,
480
- },
481
- roleTab: {
482
- type: 'panel',
483
- label: 'detectedRoles',
484
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
485
- // @ts-expect-error
486
- items: roleItems,
487
- },
488
- },
489
- },
490
- };
386
+
387
+ return object;
491
388
  }
492
389
  }
493
390
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.lorawan",
3
- "version": "1.20.21",
3
+ "version": "1.20.23",
4
4
  "description": "converts the desired lora gateway data to a ioBroker structure",
5
5
  "author": {
6
6
  "name": "BenAhrdt",