iobroker.lorawan 1.20.22 → 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 +3 -0
- package/admin/icons/PowerOn.png +0 -0
- package/admin/icons/sensor.contact.png +0 -0
- package/io-package.json +14 -14
- package/lib/modules/deviceManager.js +33 -136
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,6 +23,9 @@ 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
|
+
|
|
26
29
|
### 1.20.22 (2026-01-27)
|
|
27
30
|
* (BenAhrdt) change preasure quere to pressure
|
|
28
31
|
|
|
Binary file
|
|
Binary file
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "lorawan",
|
|
4
|
-
"version": "1.20.
|
|
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
|
+
},
|
|
6
19
|
"1.20.22": {
|
|
7
20
|
"en": "change preasure quere to pressure",
|
|
8
21
|
"de": "voreinstellungsanfrage zum druck ändern",
|
|
@@ -80,19 +93,6 @@
|
|
|
80
93
|
"pl": "wdrożenie Szczegóły dotyczące urządzenia",
|
|
81
94
|
"uk": "реалізація Деталі пристрою",
|
|
82
95
|
"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": {
|
|
@@ -149,6 +149,8 @@ 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
155
|
if (deviceValue.detectedRoles['value.pressure']) {
|
|
154
156
|
return possibleIcons.weatherCurrent;
|
|
@@ -159,7 +161,7 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
159
161
|
return possibleIcons.temperature;
|
|
160
162
|
}
|
|
161
163
|
}
|
|
162
|
-
return
|
|
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] =
|
|
319
|
+
subfolders[subfolder][key] = value[subfolder];
|
|
316
320
|
}
|
|
317
321
|
}
|
|
318
|
-
subfolders =
|
|
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
|
-
|
|
328
|
-
|
|
329
|
-
.
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
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
|
-
*
|
|
373
|
-
* @
|
|
370
|
+
*
|
|
371
|
+
* @param object Object to sort
|
|
374
372
|
*/
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
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
|
-
|
|
418
|
-
|
|
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
|
-
.
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
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
|
-
|
|
470
|
-
|
|
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
|
|