iobroker.lorawan 1.20.16 → 1.20.17
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/i18n/de/translations.json +1 -0
- package/admin/i18n/en/translations.json +2 -1
- package/admin/i18n/es/translations.json +1 -0
- package/admin/i18n/fr/translations.json +1 -0
- package/admin/i18n/it/translations.json +1 -0
- package/admin/i18n/nl/translations.json +1 -0
- package/admin/i18n/pl/translations.json +1 -0
- package/admin/i18n/pt/translations.json +1 -0
- package/admin/i18n/ru/translations.json +1 -0
- package/admin/i18n/uk/translations.json +1 -0
- package/admin/i18n/zh-cn/translations.json +1 -0
- package/io-package.json +15 -2
- package/lib/modules/bridge.js +4 -4
- package/lib/modules/bridgeMqttclient.js +7 -3
- package/lib/modules/deviceManager.js +31 -29
- package/lib/modules/directorieshandler.js +6 -4
- package/lib/modules/mqttclient.js +3 -2
- 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.17 (2026-01-27)
|
|
27
|
+
* (BenAhrdt) implement Device details
|
|
28
|
+
|
|
26
29
|
### 1.20.16 (2026-01-27)
|
|
27
30
|
* (BenAhrdt) add informations to device Manager
|
|
28
31
|
|
|
@@ -219,6 +219,7 @@
|
|
|
219
219
|
"ipUrlTooltip": "Geben Sie die IP-Adresse oder die URL ein, zu der Sie eine Verbindung herstellen möchten",
|
|
220
220
|
"keepalive": "keepalive",
|
|
221
221
|
"keepaliveTooltip": "Geben Sie die Zeit in Sekunden für die Keepalive-Funktion ein",
|
|
222
|
+
"lastJoined": "Letzter Join:",
|
|
222
223
|
"lengthInByte": "Statelänge (Byte)",
|
|
223
224
|
"lengthInByteTooltip": "Geben Sie die Länge des States in Bytes an",
|
|
224
225
|
"limitMax": "Maximum begrenzen",
|
|
@@ -219,6 +219,7 @@
|
|
|
219
219
|
"ipUrlTooltip": "ingrese la dirección IP o la URL a la que desea conectarse",
|
|
220
220
|
"keepalive": "mantener vivo",
|
|
221
221
|
"keepaliveTooltip": "ingrese el tiempo en segundos para la función keepalive",
|
|
222
|
+
"lastJoined": "último unido",
|
|
222
223
|
"lengthInByte": "longitud del estado (byte)",
|
|
223
224
|
"lengthInByteTooltip": "insertar la longitud del estado en bytes",
|
|
224
225
|
"limitMax": "límite máx.",
|
|
@@ -219,6 +219,7 @@
|
|
|
219
219
|
"ipUrlTooltip": "saisissez l'adresse IP ou l'URL à laquelle vous souhaitez vous connecter",
|
|
220
220
|
"keepalive": "rester en vie",
|
|
221
221
|
"keepaliveTooltip": "entrez le temps en secondes pour la fonction keepalive",
|
|
222
|
+
"lastJoined": "dernier rejoint",
|
|
222
223
|
"lengthInByte": "longueur de l'état (octet)",
|
|
223
224
|
"lengthInByteTooltip": "insérer la longueur de l'état en octets",
|
|
224
225
|
"limitMax": "limite max.",
|
|
@@ -219,6 +219,7 @@
|
|
|
219
219
|
"ipUrlTooltip": "inserisci l'indirizzo IP o l'URL a cui desideri connetterti",
|
|
220
220
|
"keepalive": "keepalive",
|
|
221
221
|
"keepaliveTooltip": "inserire il tempo in secondi per la funzione keepalive",
|
|
222
|
+
"lastJoined": "ultimo unito",
|
|
222
223
|
"lengthInByte": "lunghezza dello stato (byte)",
|
|
223
224
|
"lengthInByteTooltip": "inserire la lunghezza dello stato in byte",
|
|
224
225
|
"limitMax": "limite massimo",
|
|
@@ -219,6 +219,7 @@
|
|
|
219
219
|
"ipUrlTooltip": "voer het ip-adres in, of de url waarmee u verbinding wilt maken",
|
|
220
220
|
"keepalive": "in leven houden",
|
|
221
221
|
"keepaliveTooltip": "voer de tijd in seconden in voor de keepalive-functie",
|
|
222
|
+
"lastJoined": "laatst lid geworden",
|
|
222
223
|
"lengthInByte": "lengte van staat (byte)",
|
|
223
224
|
"lengthInByteTooltip": "voer de lengte van de status in bytes in",
|
|
224
225
|
"limitMax": "limiet max.",
|
|
@@ -219,6 +219,7 @@
|
|
|
219
219
|
"ipUrlTooltip": "wprowadź adres IP lub adres URL, z którym chcesz się połączyć",
|
|
220
220
|
"keepalive": "podtrzymać",
|
|
221
221
|
"keepaliveTooltip": "wprowadź czas w sekundach dla funkcji utrzymywania aktywności",
|
|
222
|
+
"lastJoined": "dołączył jako ostatni",
|
|
222
223
|
"lengthInByte": "długość stanu (bajt)",
|
|
223
224
|
"lengthInByteTooltip": "wstaw długość stanu w bajtach",
|
|
224
225
|
"limitMax": "ograniczenie maks.",
|
|
@@ -219,6 +219,7 @@
|
|
|
219
219
|
"ipUrlTooltip": "insira o endereço IP ou o URL ao qual deseja se conectar",
|
|
220
220
|
"keepalive": "manutenção de atividade",
|
|
221
221
|
"keepaliveTooltip": "insira o tempo em segundos para a função keepalive",
|
|
222
|
+
"lastJoined": "última adesão",
|
|
222
223
|
"lengthInByte": "comprimento do estado (byte)",
|
|
223
224
|
"lengthInByteTooltip": "insira o comprimento do estado em bytes",
|
|
224
225
|
"limitMax": "limite máx.",
|
|
@@ -219,6 +219,7 @@
|
|
|
219
219
|
"ipUrlTooltip": "введите IP-адрес или URL-адрес, к которому вы хотите подключиться",
|
|
220
220
|
"keepalive": "поддерживать активность",
|
|
221
221
|
"keepaliveTooltip": "введите время в секундах для функции поддержки активности",
|
|
222
|
+
"lastJoined": "последний раз присоединился",
|
|
222
223
|
"lengthInByte": "длина состояния (байт)",
|
|
223
224
|
"lengthInByteTooltip": "вставьте длину состояния в байтах",
|
|
224
225
|
"limitMax": "предел макс.",
|
|
@@ -219,6 +219,7 @@
|
|
|
219
219
|
"ipUrlTooltip": "введіть ip-адресу або URL-адресу, до якої ви хочете підключитися",
|
|
220
220
|
"keepalive": "keepalive",
|
|
221
221
|
"keepaliveTooltip": "введіть час у секундах для функції підтримки активності",
|
|
222
|
+
"lastJoined": "останній приєднався",
|
|
222
223
|
"lengthInByte": "довжина стану (байт)",
|
|
223
224
|
"lengthInByteTooltip": "вставити довжину стану в байтах",
|
|
224
225
|
"limitMax": "обмеження макс.",
|
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.17",
|
|
5
5
|
"news": {
|
|
6
|
+
"1.20.17": {
|
|
7
|
+
"en": "implement Device details",
|
|
8
|
+
"de": "durchführung Gerätedetails",
|
|
9
|
+
"ru": "осуществлять Детали устройства",
|
|
10
|
+
"pt": "implementar Detalhes do dispositivo",
|
|
11
|
+
"nl": "implementeren Apparaatdetails",
|
|
12
|
+
"fr": "mise en œuvre Détails du périphérique",
|
|
13
|
+
"it": "attuazione Dettagli del dispositivo",
|
|
14
|
+
"es": "aplicación Detalles del dispositivo",
|
|
15
|
+
"pl": "wdrożenie Szczegóły dotyczące urządzenia",
|
|
16
|
+
"uk": "реалізація Деталі пристрою",
|
|
17
|
+
"zh-cn": "执行 设备细节"
|
|
18
|
+
},
|
|
6
19
|
"1.20.16": {
|
|
7
20
|
"en": "add informations to device Manager",
|
|
8
21
|
"de": "informationen zum Gerätemanager hinzufügen",
|
|
@@ -576,7 +589,7 @@
|
|
|
576
589
|
"name": "internal logging types",
|
|
577
590
|
"read": true,
|
|
578
591
|
"write": true,
|
|
579
|
-
"def": "{\"discovery\":false, \"assign\": false, \"messageTo\": false, \"listDevices\": false, \"getStatus\": false, \"deviceinformation\": false, \"downlinkconfig\": false, \"getChangeInfo\": false}"
|
|
592
|
+
"def": "{\"discovery\":false, \"assign\": false, \"messageTo\": false, \"listDevices\": false, \"getStatus\": false, \"deviceinformation\": false, \"downlinkconfig\": false, \"getChangeInfo\": false, \"assign\": false, \"assignHandler\": false, \"bridgeMqtt\": false, \"mqtt\": false}"
|
|
580
593
|
},
|
|
581
594
|
"native": {}
|
|
582
595
|
},
|
package/lib/modules/bridge.js
CHANGED
|
@@ -282,7 +282,7 @@ class bridgeClass {
|
|
|
282
282
|
message = this.SubscribedTopics[topic].messageAssign[message];
|
|
283
283
|
} else {
|
|
284
284
|
this.adapter.log.warn(
|
|
285
|
-
`
|
|
285
|
+
`Incoming Message: ${message} at topic: ${topic} can not be found in possible values.`,
|
|
286
286
|
);
|
|
287
287
|
return;
|
|
288
288
|
}
|
|
@@ -296,7 +296,7 @@ class bridgeClass {
|
|
|
296
296
|
message = this.SubscribedTopics[topic].messageAssign[message];
|
|
297
297
|
} else {
|
|
298
298
|
this.adapter.log.warn(
|
|
299
|
-
`
|
|
299
|
+
`Incoming Message: ${message} at topic: ${topic} can not be found in possible values.`,
|
|
300
300
|
);
|
|
301
301
|
return;
|
|
302
302
|
}
|
|
@@ -3119,7 +3119,7 @@ class bridgeClass {
|
|
|
3119
3119
|
}
|
|
3120
3120
|
|
|
3121
3121
|
// Assign Subscribed Topics
|
|
3122
|
-
//
|
|
3122
|
+
// Incoming set
|
|
3123
3123
|
this.assignTopicStructure(
|
|
3124
3124
|
this.SubscribedTopics,
|
|
3125
3125
|
`${coverTopic}${this.EndingSet}`,
|
|
@@ -3545,7 +3545,7 @@ class bridgeClass {
|
|
|
3545
3545
|
}
|
|
3546
3546
|
|
|
3547
3547
|
// Assign Subscribed Topics
|
|
3548
|
-
//
|
|
3548
|
+
// Incoming set
|
|
3549
3549
|
this.assignTopicStructure(
|
|
3550
3550
|
this.SubscribedTopics,
|
|
3551
3551
|
`${lockTopic}${this.EndingSet}`,
|
|
@@ -105,8 +105,9 @@ class bridgeMqttClientClass {
|
|
|
105
105
|
});
|
|
106
106
|
|
|
107
107
|
this.client.on('message', async (topic, message) => {
|
|
108
|
-
|
|
109
|
-
this.adapter.log.
|
|
108
|
+
// Check for logging
|
|
109
|
+
this.adapter.log[this.adapter.logtypes.bridgeMqtt]?.(`incoming bridge topic: ${topic}`);
|
|
110
|
+
this.adapter.log[this.adapter.logtypes.bridgeMqtt]?.(`incoming bridge message: ${message}`);
|
|
110
111
|
|
|
111
112
|
// String zuweisen, wenn JSON.parse ein Fehler auswirft.
|
|
112
113
|
let payload = message.toString('utf8');
|
|
@@ -136,7 +137,10 @@ class bridgeMqttClientClass {
|
|
|
136
137
|
* @param opt optional data
|
|
137
138
|
*/
|
|
138
139
|
async publish(topic, message, opt) {
|
|
139
|
-
|
|
140
|
+
// Check for logging
|
|
141
|
+
this.adapter.log[this.adapter.logtypes.bridgeMqtt]?.(
|
|
142
|
+
`Publishing bridge topic: ${topic} with message: ${message}.`,
|
|
143
|
+
);
|
|
140
144
|
|
|
141
145
|
// Write into debug
|
|
142
146
|
if (await this.adapter.objectExists('bridge.debug.outgoingTopic')) {
|
|
@@ -30,7 +30,7 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
30
30
|
id: key,
|
|
31
31
|
name: value.object.common.name,
|
|
32
32
|
icon: await this.getIcon(value),
|
|
33
|
-
manufacturer:
|
|
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
36
|
hasDetails: value.detectedRoles ? true : false,
|
|
@@ -276,10 +276,10 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
276
276
|
*/
|
|
277
277
|
async getDeviceDetails(id) {
|
|
278
278
|
const generalItems = {};
|
|
279
|
-
const
|
|
279
|
+
const lastUplinkTs = new Date(
|
|
280
280
|
this.adapter.objectStore.devices[id].informations.lastUplink.state.ts,
|
|
281
281
|
).toLocaleString('de-DE', {
|
|
282
|
-
weekday: '
|
|
282
|
+
weekday: 'long', // Mo
|
|
283
283
|
year: 'numeric', // 2026
|
|
284
284
|
month: '2-digit', // 01
|
|
285
285
|
day: '2-digit', // 24
|
|
@@ -287,23 +287,34 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
287
287
|
minute: '2-digit', // 32
|
|
288
288
|
second: '2-digit', // 10
|
|
289
289
|
});
|
|
290
|
-
generalItems['Timestamp_text'] = {
|
|
291
|
-
newLine: true,
|
|
292
|
-
type: 'header',
|
|
293
|
-
text: 'LastUplink',
|
|
294
|
-
size: 3,
|
|
295
|
-
xs: 12,
|
|
296
|
-
sm: 12,
|
|
297
|
-
md: 12,
|
|
298
|
-
lg: 12,
|
|
299
|
-
xl: 12,
|
|
300
|
-
};
|
|
301
290
|
generalItems['Timestamp_value'] = {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
291
|
+
type: 'staticInfo',
|
|
292
|
+
label: 'LastUplink',
|
|
293
|
+
size: 16,
|
|
294
|
+
data: lastUplinkTs,
|
|
306
295
|
};
|
|
296
|
+
if (this.adapter.objectStore.devices[id].join?.raw?.json?.state?.lc) {
|
|
297
|
+
const lastJoinedLc = new Date(this.adapter.objectStore.devices[id].join.raw.json.state.lc).toLocaleString(
|
|
298
|
+
'de-DE',
|
|
299
|
+
{
|
|
300
|
+
weekday: 'long', // Mo
|
|
301
|
+
year: 'numeric', // 2026
|
|
302
|
+
month: '2-digit', // 01
|
|
303
|
+
day: '2-digit', // 24
|
|
304
|
+
hour: '2-digit', // 14
|
|
305
|
+
minute: '2-digit', // 32
|
|
306
|
+
second: '2-digit', // 10
|
|
307
|
+
},
|
|
308
|
+
);
|
|
309
|
+
generalItems['Join_value'] = {
|
|
310
|
+
type: 'staticInfo',
|
|
311
|
+
label: 'lastJoined',
|
|
312
|
+
size: 16,
|
|
313
|
+
data: lastJoinedLc,
|
|
314
|
+
};
|
|
315
|
+
} else {
|
|
316
|
+
this.adapter.log.warn(JSON.stringify(this.adapter.objectStore.devices[id].join));
|
|
317
|
+
}
|
|
307
318
|
|
|
308
319
|
let subfolders = {};
|
|
309
320
|
for (const [key, value] of Object.entries(this.adapter.objectStore.devices[id].detectedRoles)) {
|
|
@@ -334,12 +345,13 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
334
345
|
let detectedRoles = ' ';
|
|
335
346
|
detectedRoles += Object.keys(subfolders[subfolder])
|
|
336
347
|
.sort((a, b) => a.localeCompare(b))
|
|
337
|
-
.join('
|
|
348
|
+
.join(' -- ');
|
|
338
349
|
|
|
339
350
|
roleItems[`${subfolder}_Roles`] = {
|
|
340
351
|
newLine: true,
|
|
341
352
|
type: 'staticText',
|
|
342
353
|
text: detectedRoles,
|
|
354
|
+
size: 10,
|
|
343
355
|
};
|
|
344
356
|
}
|
|
345
357
|
return {
|
|
@@ -353,11 +365,6 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
353
365
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
354
366
|
// @ts-expect-error
|
|
355
367
|
items: generalItems,
|
|
356
|
-
xs: 12,
|
|
357
|
-
sm: 12,
|
|
358
|
-
md: 12,
|
|
359
|
-
lg: 12,
|
|
360
|
-
xl: 12,
|
|
361
368
|
},
|
|
362
369
|
roleTab: {
|
|
363
370
|
type: 'panel',
|
|
@@ -365,11 +372,6 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
365
372
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
366
373
|
// @ts-expect-error
|
|
367
374
|
items: roleItems,
|
|
368
|
-
xs: 12,
|
|
369
|
-
sm: 12,
|
|
370
|
-
md: 12,
|
|
371
|
-
lg: 12,
|
|
372
|
-
xl: 12,
|
|
373
375
|
},
|
|
374
376
|
},
|
|
375
377
|
},
|
|
@@ -456,16 +456,18 @@ class directorieshandlerClass {
|
|
|
456
456
|
}
|
|
457
457
|
// Check for an assign definition (calculation and / or role assignment)
|
|
458
458
|
if (this.assigns[elementName] && !options?.dontAssign) {
|
|
459
|
-
|
|
460
|
-
|
|
459
|
+
// Check for logging
|
|
460
|
+
this.adapter.log[this.adapter.logtypes.assign]?.(
|
|
461
|
+
`the state with the id ${objectId} will be assigned by internal assign function`,
|
|
461
462
|
);
|
|
462
463
|
stateVal = this.assigns[elementName](stateVal, common);
|
|
463
464
|
}
|
|
464
465
|
|
|
465
466
|
// Check for assign (new implemented function)
|
|
466
467
|
if (this.assignhandler.assign[elementName] && !options?.dontAssign) {
|
|
467
|
-
|
|
468
|
-
|
|
468
|
+
// Check for logging
|
|
469
|
+
this.adapter.log[this.adapter.logtypes.assignHandler]?.(
|
|
470
|
+
`the state with the id ${objectId} will be assigned by internal assign function assignHandler`,
|
|
469
471
|
);
|
|
470
472
|
stateVal = this.assignhandler.executeAssign(
|
|
471
473
|
objectId,
|
|
@@ -77,8 +77,9 @@ class mqttClientClass {
|
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
this.client.on('message', async (topic, message) => {
|
|
80
|
-
|
|
81
|
-
this.adapter.log.
|
|
80
|
+
// Check for logging
|
|
81
|
+
this.adapter.log[this.adapter.logtypes.mqtt]?.(`incoming topic: ${topic}`);
|
|
82
|
+
this.adapter.log[this.adapter.logtypes.mqtt]?.(`incoming message: ${message}`);
|
|
82
83
|
// @ts-expect-error assignmessage in JSON.parse
|
|
83
84
|
message = JSON.parse(message);
|
|
84
85
|
|