iobroker.lorawan 1.20.22 → 1.20.24

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.24 (2026-01-28)
27
+ * (BenAhrdt) change info Form to Detail button
28
+
29
+ ### 1.20.23 (2026-01-28)
30
+ * (BenAhrdt) change role display and icons
31
+
26
32
  ### 1.20.22 (2026-01-27)
27
33
  * (BenAhrdt) change preasure quere to pressure
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.22",
4
+ "version": "1.20.24",
5
5
  "news": {
6
+ "1.20.24": {
7
+ "en": "change info Form to Detail button",
8
+ "de": "änderungen Formular zum Detail Knopf",
9
+ "ru": "изменить информацию Форма для детализации кнопки",
10
+ "pt": "alterar informações Botão de Formulário para Detalhe",
11
+ "nl": "info wijzigen Vorm naar detailknop",
12
+ "fr": "modifier les informations Formulaire au bouton Détail",
13
+ "it": "cambiare le informazioni Modulo per Dettaglio pulsante",
14
+ "es": "cambio de información Forma al botón Detalle",
15
+ "pl": "zmiana informacji Format do przycisku Szczegóły",
16
+ "uk": "зміна інформації Форма для докладної кнопки",
17
+ "zh-cn": "更改信息 详细按钮的窗体"
18
+ },
19
+ "1.20.23": {
20
+ "en": "change role display and icons",
21
+ "de": "rollenanzeige und icons ändern",
22
+ "ru": "изменить отображение ролей и иконки",
23
+ "pt": "alterar a exibição de funções e ícones",
24
+ "nl": "rolweergave en pictogrammen wijzigen",
25
+ "fr": "modifier l'affichage des rôles et les icônes",
26
+ "it": "modifica visualizzazione del ruolo e icone",
27
+ "es": "función de cambio de visualización e iconos",
28
+ "pl": "zmienić wyświetlacz ról i ikony",
29
+ "uk": "змінити відображення ролі та іконки",
30
+ "zh-cn": "更改角色显示和图标"
31
+ },
6
32
  "1.20.22": {
7
33
  "en": "change preasure quere to pressure",
8
34
  "de": "voreinstellungsanfrage zum druck ändern",
@@ -67,32 +93,6 @@
67
93
  "pl": "nadchodzące nazewnictwo bugfix Temat",
68
94
  "uk": "виправлення ім'я користувача Головна",
69
95
  "zh-cn": "正在接收错误修正名称 专题"
70
- },
71
- "1.20.17": {
72
- "en": "implement Device details",
73
- "de": "durchführung Gerätedetails",
74
- "ru": "осуществлять Детали устройства",
75
- "pt": "implementar Detalhes do dispositivo",
76
- "nl": "implementeren Apparaatdetails",
77
- "fr": "mise en œuvre Détails du périphérique",
78
- "it": "attuazione Dettagli del dispositivo",
79
- "es": "aplicación Detalles del dispositivo",
80
- "pl": "wdrożenie Szczegóły dotyczące urządzenia",
81
- "uk": "реалізація Деталі пристрою",
82
- "zh-cn": "执行 设备细节"
83
- },
84
- "1.20.16": {
85
- "en": "add informations to device Manager",
86
- "de": "informationen zum Gerätemanager hinzufügen",
87
- "ru": "добавление информации в диспетчер устройств",
88
- "pt": "adicionar informações ao gerenciador de dispositivos",
89
- "nl": "informatie toevoegen aan apparaatbeheer",
90
- "fr": "ajouter des informations au gestionnaire de périphériques",
91
- "it": "aggiungere informazioni al gestore del dispositivo",
92
- "es": "añadir información al administrador del dispositivo",
93
- "pl": "dodać informacje do urządzenia Manager",
94
- "uk": "додати інформацію в диспетчер пристроїв",
95
- "zh-cn": "向设备管理器添加信息"
96
96
  }
97
97
  },
98
98
  "titleLang": {
@@ -16,6 +16,7 @@ class LoRaWANDeviceManagement extends DeviceManagement {
16
16
  this.adapter = adapter;
17
17
  this.x = adapter;
18
18
  }
19
+
19
20
  /**
20
21
  * List all LoRaWAN devices
21
22
  */
@@ -23,36 +24,36 @@ class LoRaWANDeviceManagement extends DeviceManagement {
23
24
  // @ts-expect-error
24
25
  async listDevices() {
25
26
  const arrDevices = [];
26
- for (const [key, value] of Object.entries(this.adapter.objectStore.devices)) {
27
+ for (const [devEUI, deviceValue] of Object.entries(this.adapter.objectStore.devices)) {
27
28
  // Check for logging
28
- this.adapter.log[this.adapter.logtypes.listDevices]?.(`List device started for device: ${key}`);
29
+ this.adapter.log[this.adapter.logtypes.listDevices]?.(`List device started for device: ${devEUI}`);
29
30
  const res = {
30
- id: key,
31
- name: value.object.common.name,
32
- icon: await this.getIcon(value),
31
+ id: devEUI,
32
+ name: deviceValue.object.common.name,
33
+ icon: await this.getIcon(deviceValue),
33
34
  manufacturer: 'LoRaWAN',
34
- model: value.informations ? value.informations.devicetype.state.val : undefined, // - ${value.uplink.remaining.rxInfo[0].rssi.ts}`,
35
- status: await this.getStatus(value),
36
- hasDetails: false,
35
+ model: deviceValue.informations ? deviceValue.informations.devicetype.state.val : undefined, // - ${value.uplink.remaining.rxInfo[0].rssi.ts}`,
36
+ status: await this.getStatus(deviceValue),
37
+ hasDetails: true,
37
38
  actions: [
38
39
  {
39
40
  id: 'rename',
40
41
  icon: 'edit',
41
42
  description: this.adapter.i18nTranslation['Rename this device'],
42
- handler: async (_id, context) => await this.handleRenameDevice(_id, context, value),
43
+ handler: async (_id, context) => await this.handleRenameDevice(_id, context, deviceValue),
43
44
  },
44
45
  {
45
46
  id: 'config',
46
47
  icon: 'settings',
47
48
  description: this.adapter.i18nTranslation['Config this device'],
48
- handler: async (_id, context) => await this.handleConfigDevice(_id, context, value),
49
+ handler: async (_id, context) => await this.handleConfigDevice(_id, context, deviceValue),
49
50
  },
50
- {
51
+ /* {
51
52
  id: 'Info',
52
53
  icon: 'lines',
53
54
  description: this.adapter.i18nTranslation['Info of this device'],
54
55
  handler: async (_id, context) => await this.handleInfo(_id, context),
55
- },
56
+ }, Outcommented at 28.01.2026 (use Details)*/
56
57
  ],
57
58
  };
58
59
  arrDevices.push(res);
@@ -149,6 +150,8 @@ class LoRaWANDeviceManagement extends DeviceManagement {
149
150
  return possibleIcons.door;
150
151
  } else if (deviceValue.detectedRoles['sensor.window']) {
151
152
  return possibleIcons.window;
153
+ } else if (deviceValue.detectedRoles['sensor.contact']) {
154
+ return `/adapter/${this.adapter.name}/icons/sensor.contact.png`;
152
155
  } else if (deviceValue.detectedRoles['value.temperature']) {
153
156
  if (deviceValue.detectedRoles['value.pressure']) {
154
157
  return possibleIcons.weatherCurrent;
@@ -159,7 +162,7 @@ class LoRaWANDeviceManagement extends DeviceManagement {
159
162
  return possibleIcons.temperature;
160
163
  }
161
164
  }
162
- return 'node'; //`/adapter/${this.adapter.name}/icons/Node.png`; //${value.object.common.icon}`,
165
+ return possibleIcons.hub5; //`/adapter/${this.adapter.name}/icons/Node.png`; //${value.object.common.icon}`,
163
166
  }
164
167
 
165
168
  /**
@@ -247,8 +250,9 @@ class LoRaWANDeviceManagement extends DeviceManagement {
247
250
  * @param id ID to rename
248
251
  * @param context context sendet from Backend
249
252
  */
250
- async handleInfo(id, context) {
253
+ /*async handleInfo(id, context) {
251
254
  const generalItems = {};
255
+ const data = {};
252
256
  const lastUplinkTs = new Date(
253
257
  this.adapter.objectStore.devices[id].informations.lastUplink.state.ts,
254
258
  ).toLocaleString('de-DE', {
@@ -285,8 +289,6 @@ class LoRaWANDeviceManagement extends DeviceManagement {
285
289
  size: 16,
286
290
  data: lastJoinedLc,
287
291
  };
288
- } else {
289
- this.adapter.log.warn(JSON.stringify(this.adapter.objectStore.devices[id].join));
290
292
  }
291
293
 
292
294
  generalItems['uplinkDecodedHeader'] = {
@@ -309,13 +311,16 @@ class LoRaWANDeviceManagement extends DeviceManagement {
309
311
  continue;
310
312
  }
311
313
  for (const subfolder in value) {
314
+ if (!subfolder.startsWith('uplink') && subfolder !== 'downlink.control') {
315
+ continue;
316
+ }
312
317
  if (!subfolders[subfolder]) {
313
318
  subfolders[subfolder] = {};
314
319
  }
315
- subfolders[subfolder][key] = true;
320
+ subfolders[subfolder][key] = value[subfolder];
316
321
  }
317
322
  }
318
- subfolders = Object.fromEntries(Object.entries(subfolders).sort(([a], [b]) => a.localeCompare(b)));
323
+ subfolders = this.sortObjectDeep(subfolders);
319
324
  const roleItems = {};
320
325
  for (const subfolder in subfolders) {
321
326
  roleItems[subfolder] = {
@@ -324,17 +329,15 @@ class LoRaWANDeviceManagement extends DeviceManagement {
324
329
  text: subfolder,
325
330
  size: 3,
326
331
  };
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,
332
+ const detectedRoles = Object.entries(subfolders[subfolder])
333
+ .map(([key, value]) => `${key}(${value})`)
334
+ .join(' ');
335
+ roleItems[`${subfolder.replace(/\./g, '_')}Roles`] = {
336
+ type: 'text',
337
+ minRows: 2,
338
+ readOnly: true,
337
339
  };
340
+ data[`${subfolder.replace(/\./g, '_')}Roles`] = detectedRoles;
338
341
  }
339
342
  const schema = {
340
343
  type: 'tabs',
@@ -354,18 +357,35 @@ class LoRaWANDeviceManagement extends DeviceManagement {
354
357
 
355
358
  let deviceInfo = await this.adapter.getStateAsync('info.deviceinformations');
356
359
  deviceInfo = JSON.parse(deviceInfo.val);
360
+ const sortedUplinkDecoded = this.sortObjectDeep(deviceInfo[id].uplink.decoded);
361
+ data.uplinkDecoded = JSON.stringify(sortedUplinkDecoded, null, 2);
357
362
  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
- },
363
+ data,
365
364
  title: this.adapter.i18nTranslation['Info of this device'],
366
365
  };
367
366
  await context.showForm(schema, options);
368
367
  return { refresh: true };
368
+ } Outcommented at 28.01.2026 (use Details)*/
369
+
370
+ /**
371
+ *
372
+ * @param object Object to sort
373
+ */
374
+ sortObjectDeep(object) {
375
+ if (Array.isArray(object)) {
376
+ return object.map(this.sortObjectDeep);
377
+ }
378
+
379
+ if (object !== null && typeof object === 'object') {
380
+ return Object.keys(object)
381
+ .sort((a, b) => a.localeCompare(b))
382
+ .reduce((acc, key) => {
383
+ acc[key] = this.sortObjectDeep(object[key]);
384
+ return acc;
385
+ }, {});
386
+ }
387
+
388
+ return object;
369
389
  }
370
390
 
371
391
  /**
@@ -373,7 +393,10 @@ class LoRaWANDeviceManagement extends DeviceManagement {
373
393
  * @returns {Promise<import('@iobroker/dm-utils').DeviceDetails>} return the right value
374
394
  */
375
395
  async getDeviceDetails(id) {
396
+ // eslint-disable-next-line jsdoc/check-tag-names
397
+ /** @type {Record<string, import('@iobroker/dm-utils').ConfigItemAny>} */
376
398
  const generalItems = {};
399
+ const data = {};
377
400
  const lastUplinkTs = new Date(
378
401
  this.adapter.objectStore.devices[id].informations.lastUplink.state.ts,
379
402
  ).toLocaleString('de-DE', {
@@ -410,22 +433,20 @@ class LoRaWANDeviceManagement extends DeviceManagement {
410
433
  size: 16,
411
434
  data: lastJoinedLc,
412
435
  };
413
- } else {
414
- this.adapter.log.warn(JSON.stringify(this.adapter.objectStore.devices[id].join));
415
436
  }
416
437
 
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'] = {
438
+ generalItems['uplinkDecodedHeader'] = {
439
+ newLine: true,
440
+ type: 'header',
441
+ text: 'Uplink Decoded',
442
+ size: 3,
443
+ };
444
+
445
+ generalItems['uplinkDecoded'] = {
425
446
  type: 'text',
426
- defaultSendTo: `BS:sendBack:${data}`,
427
447
  readOnly: true,
428
448
  minRows: 10,
449
+ maxRows: 40,
429
450
  };
430
451
 
431
452
  let subfolders = {};
@@ -434,13 +455,18 @@ class LoRaWANDeviceManagement extends DeviceManagement {
434
455
  continue;
435
456
  }
436
457
  for (const subfolder in value) {
458
+ if (!subfolder.startsWith('uplink') && subfolder !== 'downlink.control') {
459
+ continue;
460
+ }
437
461
  if (!subfolders[subfolder]) {
438
462
  subfolders[subfolder] = {};
439
463
  }
440
- subfolders[subfolder][key] = true;
464
+ subfolders[subfolder][key] = value[subfolder];
441
465
  }
442
466
  }
443
- subfolders = Object.fromEntries(Object.entries(subfolders).sort(([a], [b]) => a.localeCompare(b)));
467
+ subfolders = this.sortObjectDeep(subfolders);
468
+ // eslint-disable-next-line jsdoc/check-tag-names
469
+ /** @type {Record<string, import('@iobroker/dm-utils').ConfigItemAny>} */
444
470
  const roleItems = {};
445
471
  for (const subfolder in subfolders) {
446
472
  roleItems[subfolder] = {
@@ -448,46 +474,40 @@ class LoRaWANDeviceManagement extends DeviceManagement {
448
474
  type: 'header',
449
475
  text: subfolder,
450
476
  size: 3,
451
- xs: 12,
452
- sm: 12,
453
- md: 12,
454
- lg: 12,
455
- xl: 12,
456
477
  };
457
- let detectedRoles = '';
458
- detectedRoles += Object.keys(subfolders[subfolder])
459
- .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,
478
+ const detectedRoles = Object.entries(subfolders[subfolder])
479
+ .map(([key, value]) => `${key}(${value})`)
480
+ .join(' ');
481
+ roleItems[`${subfolder.replace(/\./g, '_')}Roles`] = {
482
+ type: 'text',
483
+ minRows: 2,
484
+ readOnly: true,
467
485
  };
486
+ data[`${subfolder.replace(/\./g, '_')}Roles`] = detectedRoles;
468
487
  }
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
+ // eslint-disable-next-line jsdoc/check-tag-names
489
+ /** @type {import('@iobroker/dm-utils').JsonFormSchema} */
490
+ const schema = {
491
+ type: 'tabs',
492
+ items: {
493
+ generalTab: {
494
+ type: 'panel',
495
+ label: 'generalInformations',
496
+ items: generalItems,
497
+ },
498
+ roleTab: {
499
+ type: 'panel',
500
+ label: 'detectedRoles',
501
+ items: roleItems,
488
502
  },
489
503
  },
490
504
  };
505
+
506
+ let deviceInfo = await this.adapter.getStateAsync('info.deviceinformations');
507
+ deviceInfo = JSON.parse(deviceInfo.val);
508
+ const sortedUplinkDecoded = this.sortObjectDeep(deviceInfo[id].uplink.decoded);
509
+ data.uplinkDecoded = JSON.stringify(sortedUplinkDecoded, null, 2);
510
+ return { id, schema, data };
491
511
  }
492
512
  }
493
513
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.lorawan",
3
- "version": "1.20.22",
3
+ "version": "1.20.24",
4
4
  "description": "converts the desired lora gateway data to a ioBroker structure",
5
5
  "author": {
6
6
  "name": "BenAhrdt",