iobroker.lorawan 1.20.19 → 1.20.21
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 +6 -0
- package/io-package.json +27 -27
- package/lib/modules/deviceManager.js +140 -28
- package/main.js +1 -0
- package/package.json +1 -1
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.21 (2026-01-27)
|
|
27
|
+
* (BenAhrdt) set Details to informations and add icons for weateher station / humidity
|
|
28
|
+
|
|
29
|
+
### 1.20.20 (2026-01-27)
|
|
30
|
+
* (BenAhrdt) icon assign changed
|
|
31
|
+
|
|
26
32
|
### 1.20.19 (2026-01-27)
|
|
27
33
|
* (BenAhrdt) bugfix incon set
|
|
28
34
|
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "lorawan",
|
|
4
|
-
"version": "1.20.
|
|
4
|
+
"version": "1.20.21",
|
|
5
5
|
"news": {
|
|
6
|
+
"1.20.21": {
|
|
7
|
+
"en": "set Details to informations and add icons for weateher station / humidity",
|
|
8
|
+
"de": "set Details zu Informationen und Icons für Weateher Station / Feuchtigkeit hinzufügen",
|
|
9
|
+
"ru": "установить детали для информации и добавить значки для Weateher станции / влажности",
|
|
10
|
+
"pt": "definir detalhes para informações e adicionar ícones para estação / umidade",
|
|
11
|
+
"nl": "set Details aan informatie en voeg pictogrammen voor weateher station / vochtigheid",
|
|
12
|
+
"fr": "définir les détails aux informations et ajouter des icônes pour la station de soudeuse / humidité",
|
|
13
|
+
"it": "impostare Dettagli alle informazioni e aggiungere icone per la stazione di bagnatura / umidità",
|
|
14
|
+
"es": "set Detalles a información y añadir iconos para estación de weateher / humedad",
|
|
15
|
+
"pl": "ustaw szczegóły informacji i dodaj ikony dla stacji / wilgotności",
|
|
16
|
+
"uk": "встановити деталі до інформації та додати іконки для станції плетіння / вологості",
|
|
17
|
+
"zh-cn": "设置信息的细节并添加编织站/湿度的图标"
|
|
18
|
+
},
|
|
19
|
+
"1.20.20": {
|
|
20
|
+
"en": "icon assign changed",
|
|
21
|
+
"de": "symbol assign geändert",
|
|
22
|
+
"ru": "изменить иконку",
|
|
23
|
+
"pt": "atribuição do ícone alterada",
|
|
24
|
+
"nl": "pictogram toegewezen",
|
|
25
|
+
"fr": "icon assigner changé",
|
|
26
|
+
"it": "icona assegna cambiato",
|
|
27
|
+
"es": "icono asignado cambiado",
|
|
28
|
+
"pl": "ikona przypisz zmieniony",
|
|
29
|
+
"uk": "ікона призначає зміни",
|
|
30
|
+
"zh-cn": "图标已更改"
|
|
31
|
+
},
|
|
6
32
|
"1.20.19": {
|
|
7
33
|
"en": "bugfix incon set",
|
|
8
34
|
"de": "bugfix incon set",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "sortowanie wyników dla informacji",
|
|
68
94
|
"uk": "сортування інформації",
|
|
69
95
|
"zh-cn": "信息排序输出"
|
|
70
|
-
},
|
|
71
|
-
"1.20.13": {
|
|
72
|
-
"en": "remove nod from crypto",
|
|
73
|
-
"de": "nod from crypto entfernen",
|
|
74
|
-
"ru": "удалить nod из crypto",
|
|
75
|
-
"pt": "remover aceno do cripto",
|
|
76
|
-
"nl": "verwijderen knik uit crypto",
|
|
77
|
-
"fr": "enlever le noeud de crypto",
|
|
78
|
-
"it": "rimuovere il nodo da crypto",
|
|
79
|
-
"es": "quitar el fideo de cripto",
|
|
80
|
-
"pl": "usunąć skinienie z krypto",
|
|
81
|
-
"uk": "видалити nod з крипто",
|
|
82
|
-
"zh-cn": "从加密中删除点头"
|
|
83
|
-
},
|
|
84
|
-
"1.20.11": {
|
|
85
|
-
"en": "improve device Manager icons and Buttons",
|
|
86
|
-
"de": "verbesserung der Vorrichtung Icons und Buttons verwalten",
|
|
87
|
-
"ru": "улучшить устройство Иконки менеджера и кнопки",
|
|
88
|
-
"pt": "melhorar o dispositivo Gerir ícones e botões",
|
|
89
|
-
"nl": "apparaat verbeteren Pictogrammen en knoppen voor de manager",
|
|
90
|
-
"fr": "améliorer l'appareil Icônes de gestionnaire et boutons",
|
|
91
|
-
"it": "migliorare il dispositivo Icone Manager e pulsanti",
|
|
92
|
-
"es": "mejorar el dispositivo Gestor de iconos y botones",
|
|
93
|
-
"pl": "ulepszenie urządzenia Ikony menedżera i przyciski",
|
|
94
|
-
"uk": "поліпшення пристрою Ім'я користувача",
|
|
95
|
-
"zh-cn": "改进设备 管理器图标和按钮"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
|
@@ -33,7 +33,7 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
33
33
|
manufacturer: 'LoRaWAN',
|
|
34
34
|
model: value.informations ? value.informations.devicetype.state.val : undefined, // - ${value.uplink.remaining.rxInfo[0].rssi.ts}`,
|
|
35
35
|
status: await this.getStatus(value),
|
|
36
|
-
hasDetails:
|
|
36
|
+
hasDetails: false,
|
|
37
37
|
actions: [
|
|
38
38
|
{
|
|
39
39
|
id: 'rename',
|
|
@@ -146,9 +146,17 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
146
146
|
if (deviceValue.detectedRoles['level.temperature']) {
|
|
147
147
|
return possibleIcons.thermostat;
|
|
148
148
|
} else if (deviceValue.detectedRoles['sensor.door']) {
|
|
149
|
-
return possibleIcons.
|
|
149
|
+
return possibleIcons.door;
|
|
150
150
|
} else if (deviceValue.detectedRoles['sensor.window']) {
|
|
151
|
-
return possibleIcons.
|
|
151
|
+
return possibleIcons.window;
|
|
152
|
+
} else if (deviceValue.detectedRoles['value.temperature']) {
|
|
153
|
+
if (deviceValue.detectedRoles['value.preasure']) {
|
|
154
|
+
return possibleIcons.weatherCurrent;
|
|
155
|
+
}
|
|
156
|
+
if (deviceValue.detectedRoles['value.humidity']) {
|
|
157
|
+
return possibleIcons.humidity;
|
|
158
|
+
}
|
|
159
|
+
return possibleIcons.temperature;
|
|
152
160
|
}
|
|
153
161
|
}
|
|
154
162
|
return 'node'; //`/adapter/${this.adapter.name}/icons/Node.png`; //${value.object.common.icon}`,
|
|
@@ -240,33 +248,123 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
240
248
|
* @param context context sendet from Backend
|
|
241
249
|
*/
|
|
242
250
|
async handleInfo(id, context) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
251
|
+
const generalItems = {};
|
|
252
|
+
const lastUplinkTs = new Date(
|
|
253
|
+
this.adapter.objectStore.devices[id].informations.lastUplink.state.ts,
|
|
254
|
+
).toLocaleString('de-DE', {
|
|
255
|
+
weekday: 'long', // Mo
|
|
256
|
+
year: 'numeric', // 2026
|
|
257
|
+
month: '2-digit', // 01
|
|
258
|
+
day: '2-digit', // 24
|
|
259
|
+
hour: '2-digit', // 14
|
|
260
|
+
minute: '2-digit', // 32
|
|
261
|
+
second: '2-digit', // 10
|
|
262
|
+
});
|
|
263
|
+
generalItems['Timestamp_value'] = {
|
|
264
|
+
type: 'staticInfo',
|
|
265
|
+
label: 'LastUplink',
|
|
266
|
+
size: 16,
|
|
267
|
+
data: lastUplinkTs,
|
|
268
|
+
};
|
|
269
|
+
if (this.adapter.objectStore.devices[id].join?.raw?.json?.state?.lc) {
|
|
270
|
+
const lastJoinedLc = new Date(this.adapter.objectStore.devices[id].join.raw.json.state.lc).toLocaleString(
|
|
271
|
+
'de-DE',
|
|
272
|
+
{
|
|
273
|
+
weekday: 'long', // Mo
|
|
274
|
+
year: 'numeric', // 2026
|
|
275
|
+
month: '2-digit', // 01
|
|
276
|
+
day: '2-digit', // 24
|
|
277
|
+
hour: '2-digit', // 14
|
|
278
|
+
minute: '2-digit', // 32
|
|
279
|
+
second: '2-digit', // 10
|
|
257
280
|
},
|
|
258
|
-
|
|
259
|
-
{
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
281
|
+
);
|
|
282
|
+
generalItems['Join_value'] = {
|
|
283
|
+
type: 'staticInfo',
|
|
284
|
+
label: 'lastJoined',
|
|
285
|
+
size: 16,
|
|
286
|
+
data: lastJoinedLc,
|
|
287
|
+
};
|
|
288
|
+
} else {
|
|
289
|
+
this.adapter.log.warn(JSON.stringify(this.adapter.objectStore.devices[id].join));
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
generalItems['uplinkDecodedHeader'] = {
|
|
293
|
+
newLine: true,
|
|
294
|
+
type: 'header',
|
|
295
|
+
text: 'Uplink Decoded',
|
|
296
|
+
size: 3,
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
generalItems['uplinkDecoded'] = {
|
|
300
|
+
type: 'text',
|
|
301
|
+
readOnly: true,
|
|
302
|
+
minRows: 10,
|
|
303
|
+
maxRows: 40,
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
let subfolders = {};
|
|
307
|
+
for (const [key, value] of Object.entries(this.adapter.objectStore.devices[id].detectedRoles)) {
|
|
308
|
+
if (key === 'state') {
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
for (const subfolder in value) {
|
|
312
|
+
if (!subfolders[subfolder]) {
|
|
313
|
+
subfolders[subfolder] = {};
|
|
314
|
+
}
|
|
315
|
+
subfolders[subfolder][key] = true;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
subfolders = Object.fromEntries(Object.entries(subfolders).sort(([a], [b]) => a.localeCompare(b)));
|
|
319
|
+
const roleItems = {};
|
|
320
|
+
for (const subfolder in subfolders) {
|
|
321
|
+
roleItems[subfolder] = {
|
|
322
|
+
newLine: true,
|
|
323
|
+
type: 'header',
|
|
324
|
+
text: subfolder,
|
|
325
|
+
size: 3,
|
|
326
|
+
};
|
|
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,
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
const schema = {
|
|
340
|
+
type: 'tabs',
|
|
341
|
+
items: {
|
|
342
|
+
generalTab: {
|
|
343
|
+
type: 'panel',
|
|
344
|
+
label: 'generalInformations',
|
|
345
|
+
items: generalItems,
|
|
346
|
+
},
|
|
347
|
+
roleTab: {
|
|
348
|
+
type: 'panel',
|
|
349
|
+
label: 'detectedRoles',
|
|
350
|
+
items: roleItems,
|
|
266
351
|
},
|
|
267
|
-
title: this.adapter.i18nTranslation['Info of this device'],
|
|
268
352
|
},
|
|
269
|
-
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
let deviceInfo = await this.adapter.getStateAsync('info.deviceinformations');
|
|
356
|
+
deviceInfo = JSON.parse(deviceInfo.val);
|
|
357
|
+
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
|
+
},
|
|
365
|
+
title: this.adapter.i18nTranslation['Info of this device'],
|
|
366
|
+
};
|
|
367
|
+
await context.showForm(schema, options);
|
|
270
368
|
return { refresh: true };
|
|
271
369
|
}
|
|
272
370
|
|
|
@@ -316,6 +414,20 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
316
414
|
this.adapter.log.warn(JSON.stringify(this.adapter.objectStore.devices[id].join));
|
|
317
415
|
}
|
|
318
416
|
|
|
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
|
+
|
|
319
431
|
let subfolders = {};
|
|
320
432
|
for (const [key, value] of Object.entries(this.adapter.objectStore.devices[id].detectedRoles)) {
|
|
321
433
|
if (key === 'state') {
|
|
@@ -342,7 +454,7 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
342
454
|
lg: 12,
|
|
343
455
|
xl: 12,
|
|
344
456
|
};
|
|
345
|
-
let detectedRoles = '
|
|
457
|
+
let detectedRoles = '';
|
|
346
458
|
detectedRoles += Object.keys(subfolders[subfolder])
|
|
347
459
|
.sort((a, b) => a.localeCompare(b))
|
|
348
460
|
.join(' -- ');
|
package/main.js
CHANGED
|
@@ -1224,6 +1224,7 @@ class Lorawan extends utils.Adapter {
|
|
|
1224
1224
|
// Handled by Device Manager class itself, so ignored here
|
|
1225
1225
|
return;
|
|
1226
1226
|
}
|
|
1227
|
+
this.log.warn(JSON.stringify(obj));
|
|
1227
1228
|
const activeFunction = 'onMessage';
|
|
1228
1229
|
this.log.silly(`message received: command = ${obj.command} - message = ${JSON.stringify(obj.message)}`);
|
|
1229
1230
|
try {
|