iobroker.lorawan 1.20.8 → 1.20.10
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 +28 -28
- package/lib/modules/deviceManager.js +20 -17
- package/main.js +35 -23
- 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.10 (2026-01-26)
|
|
27
|
+
* (BenAhrdt) return to root getCnageInfo
|
|
28
|
+
|
|
29
|
+
### 1.20.9 (2026-01-26)
|
|
30
|
+
* (BenAhrdt) experimental for form
|
|
31
|
+
|
|
26
32
|
### 1.20.8 (2026-01-26)
|
|
27
33
|
* (BenAhrdt) changes in objectStore
|
|
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.10",
|
|
5
5
|
"news": {
|
|
6
|
+
"1.20.10": {
|
|
7
|
+
"en": "return to root getCnageInfo",
|
|
8
|
+
"de": "zurück zu root getCnageInfo",
|
|
9
|
+
"ru": "вернуться в root getCnageInfo",
|
|
10
|
+
"pt": "voltar ao root getCnageInfo",
|
|
11
|
+
"nl": "terug naar root getCnageInfo",
|
|
12
|
+
"fr": "retour à la racine getCnageInfo",
|
|
13
|
+
"it": "ritorno a root getCnageInfo",
|
|
14
|
+
"es": "volver a root getCnageInfo",
|
|
15
|
+
"pl": "powrót do root getCnageInfo",
|
|
16
|
+
"uk": "повернення в корінь GetCnageInfo",
|
|
17
|
+
"zh-cn": "返回到 root 获取CnageInfo"
|
|
18
|
+
},
|
|
19
|
+
"1.20.9": {
|
|
20
|
+
"en": "experimental for form",
|
|
21
|
+
"de": "experiment für form",
|
|
22
|
+
"ru": "экспериментальная форма",
|
|
23
|
+
"pt": "experimental para forma",
|
|
24
|
+
"nl": "experimenteel voor vorm",
|
|
25
|
+
"fr": "expérimental pour la forme",
|
|
26
|
+
"it": "sperimentale per forma",
|
|
27
|
+
"es": "experimental para forma",
|
|
28
|
+
"pl": "eksperymentalne dla formy",
|
|
29
|
+
"uk": "експериментальна форма",
|
|
30
|
+
"zh-cn": "实验形式"
|
|
31
|
+
},
|
|
6
32
|
"1.20.8": {
|
|
7
33
|
"en": "changes in objectStore",
|
|
8
34
|
"de": "änderungen des Objekts Store",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "eksperymentalne debugowanie w systemie live",
|
|
68
94
|
"uk": "експериментальна дебюга в живій системі",
|
|
69
95
|
"zh-cn": "正在运行系统中调试的实验"
|
|
70
|
-
},
|
|
71
|
-
"1.20.3": {
|
|
72
|
-
"en": "bugfix device Manager",
|
|
73
|
-
"de": "bugfix Gerät Manager",
|
|
74
|
-
"ru": "bugfix устройство диспетчер",
|
|
75
|
-
"pt": "gerenciador de dispositivos de correção de erros",
|
|
76
|
-
"nl": "bugfix apparaatbeheer",
|
|
77
|
-
"fr": "gestionnaire de périphériques bugfix",
|
|
78
|
-
"it": "bugfix dispositivo Manager",
|
|
79
|
-
"es": "bugfix device Manager",
|
|
80
|
-
"pl": "menedżer urządzeń bugfix",
|
|
81
|
-
"uk": "диспетчер пристроїв",
|
|
82
|
-
"zh-cn": "错误修正设备管理器"
|
|
83
|
-
},
|
|
84
|
-
"1.20.2": {
|
|
85
|
-
"en": "bugfix device Manager and objectStore device checks",
|
|
86
|
-
"de": "bugfix device Manager und Objekt Geräteüberprüfungen",
|
|
87
|
-
"ru": "bugfix диспетчер устройств и объект Проверка устройств магазина",
|
|
88
|
-
"pt": "gestor e objecto do dispositivo de correção de erros Verificação do dispositivo de armazenamento",
|
|
89
|
-
"nl": "bugfix apparaatbeheer en object Controles van het opslagapparaat",
|
|
90
|
-
"fr": "bugfix device Manager et objet Contrôles des dispositifs de stockage",
|
|
91
|
-
"it": "bugfix device Manager e oggetto Controllo dispositivi di memorizzazione",
|
|
92
|
-
"es": "bugfix device Manager y objeto Controles de dispositivo de la tienda",
|
|
93
|
-
"pl": "menedżer i obiekt urządzenia bugfix Kontrole urządzeń do przechowywania",
|
|
94
|
-
"uk": "диспетчер пристроїв та об'єкт Перевірка пристрою магазину",
|
|
95
|
-
"zh-cn": "错误修正设备管理器和对象 存储设备检查"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
|
@@ -589,7 +589,7 @@
|
|
|
589
589
|
"name": "internal logging types",
|
|
590
590
|
"read": true,
|
|
591
591
|
"write": true,
|
|
592
|
-
"def": "{\"discovery\":false, \"assign\": false, \"messageTo\": false, \"listDevices\": false, \"getStatus\": false, \"deviceinformation\": false, \"downlinkconfig\": false,}"
|
|
592
|
+
"def": "{\"discovery\":false, \"assign\": false, \"messageTo\": false, \"listDevices\": false, \"getStatus\": false, \"deviceinformation\": false, \"downlinkconfig\": false, \"getChangeInfo\": false,}"
|
|
593
593
|
},
|
|
594
594
|
"native": {}
|
|
595
595
|
},
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
const { DeviceManagement } = require('@iobroker/dm-utils');
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* DeviceManager Class
|
|
7
7
|
*/
|
|
8
8
|
class LoRaWANDeviceManagement extends DeviceManagement {
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Initialize Class with Adapter
|
|
11
11
|
*
|
|
12
12
|
* @param adapter Adapter Reference
|
|
13
13
|
*/
|
|
@@ -15,6 +15,7 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
15
15
|
super(adapter);
|
|
16
16
|
this.adapter = adapter;
|
|
17
17
|
}
|
|
18
|
+
|
|
18
19
|
/**
|
|
19
20
|
* List all LoRaWAN devices
|
|
20
21
|
*/
|
|
@@ -26,9 +27,9 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
26
27
|
// Check for logging
|
|
27
28
|
this.adapter.log[this.adapter.logtypes.listDevices]?.(`List device started for device: ${key}`);
|
|
28
29
|
const res = {
|
|
29
|
-
id:
|
|
30
|
+
id: value.object._id,
|
|
30
31
|
name: value.object.common.name,
|
|
31
|
-
icon: await this.getIcon(value),
|
|
32
|
+
icon: 'cistern', //await this.getIcon(value),
|
|
32
33
|
manufacturer: value.informations
|
|
33
34
|
? value.informations.lastUplink
|
|
34
35
|
? new Date(value.informations.lastUplink.state.ts).toLocaleString('de-DE', {
|
|
@@ -48,9 +49,9 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
48
49
|
actions: [
|
|
49
50
|
{
|
|
50
51
|
id: 'rename',
|
|
51
|
-
icon: '
|
|
52
|
+
icon: 'edit',
|
|
52
53
|
description: this.adapter.i18nTranslation['Rename this device'],
|
|
53
|
-
handler:
|
|
54
|
+
handler: async (_id, context) => await this.handleRenameDevice(_id, context),
|
|
54
55
|
},
|
|
55
56
|
],
|
|
56
57
|
};
|
|
@@ -59,13 +60,13 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
59
60
|
id: 'config',
|
|
60
61
|
icon: 'settings',
|
|
61
62
|
description: this.adapter.i18nTranslation['Config this device'],
|
|
62
|
-
handler:
|
|
63
|
+
handler: async (_id, context) => await this.handleRenameDevice(_id, context),
|
|
63
64
|
});
|
|
64
65
|
res.actions.push({
|
|
65
66
|
id: 'Info',
|
|
66
67
|
icon: 'lines',
|
|
67
68
|
description: this.adapter.i18nTranslation['Info of this device'],
|
|
68
|
-
handler:
|
|
69
|
+
handler: async (_id, context) => await this.handleRenameDevice(_id, context),
|
|
69
70
|
});
|
|
70
71
|
}
|
|
71
72
|
arrDevices.push(res);
|
|
@@ -75,23 +76,23 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
75
76
|
|
|
76
77
|
/**
|
|
77
78
|
*
|
|
78
|
-
* @param
|
|
79
|
+
* @param deviceValue values of device
|
|
79
80
|
*/
|
|
80
|
-
async getStatus(
|
|
81
|
+
async getStatus(deviceValue) {
|
|
81
82
|
// Check for logging
|
|
82
83
|
this.adapter.log[this.adapter.logtypes.getStatus]?.(
|
|
83
|
-
`get Status started with value: ${JSON.stringify(
|
|
84
|
+
`get Status started with value: ${JSON.stringify(deviceValue)}`,
|
|
84
85
|
);
|
|
85
86
|
const status = {};
|
|
86
|
-
if (
|
|
87
|
+
if (deviceValue.object.common.icon.includes('offline')) {
|
|
87
88
|
status.connection = 'disconnected';
|
|
88
89
|
} else {
|
|
89
90
|
status.connection = 'connected';
|
|
90
|
-
if (
|
|
91
|
-
status.rssi =
|
|
91
|
+
if (deviceValue.informations.rssi) {
|
|
92
|
+
status.rssi = deviceValue.informations.rssi.state.val;
|
|
92
93
|
}
|
|
93
|
-
if (
|
|
94
|
-
status.battery =
|
|
94
|
+
if (deviceValue.informations.batteryPercent) {
|
|
95
|
+
status.battery = deviceValue.informations.batteryPercent.state.val ?? undefined;
|
|
95
96
|
}
|
|
96
97
|
}
|
|
97
98
|
return status;
|
|
@@ -158,13 +159,15 @@ class LoRaWANDeviceManagement extends DeviceManagement {
|
|
|
158
159
|
name: result.newName,
|
|
159
160
|
},
|
|
160
161
|
};
|
|
161
|
-
const res = await this.adapter.
|
|
162
|
+
const res = await this.adapter.extendForeignObjectAsync(id, obj);
|
|
162
163
|
if (res === null) {
|
|
163
164
|
this.adapter.log.warn(`Can not rename device ${id}: ${JSON.stringify(res)}`);
|
|
164
165
|
return { refresh: false };
|
|
165
166
|
}
|
|
166
167
|
return { refresh: true };
|
|
167
168
|
}
|
|
169
|
+
|
|
170
|
+
// Possible strings for icons
|
|
168
171
|
}
|
|
169
172
|
|
|
170
173
|
module.exports = LoRaWANDeviceManagement;
|
package/main.js
CHANGED
|
@@ -36,7 +36,6 @@ class Lorawan extends utils.Adapter {
|
|
|
36
36
|
ttn: 'ttn',
|
|
37
37
|
chirpstack: 'chirpstack',
|
|
38
38
|
};
|
|
39
|
-
|
|
40
39
|
this.NextSendLocks = new Map(); // key -> Promise-chain
|
|
41
40
|
|
|
42
41
|
// Simulation variables
|
|
@@ -122,7 +121,6 @@ class Lorawan extends utils.Adapter {
|
|
|
122
121
|
}
|
|
123
122
|
|
|
124
123
|
this.deviceManagement = new LoRaWANDeviceManagement(this);
|
|
125
|
-
|
|
126
124
|
//Subscribe all configuration and control states
|
|
127
125
|
await this.subscribeStatesAsync('*');
|
|
128
126
|
await this.subscribeObjectsAsync('*');
|
|
@@ -146,6 +144,16 @@ class Lorawan extends utils.Adapter {
|
|
|
146
144
|
const message = {devEui:"f1c0ae0e-b4a2-4547-b360-7cfa15e85734",confirmed:false,fPort:1,data:"AAA"};
|
|
147
145
|
await this.mqttClient?.publish(topic,JSON.stringify(message));
|
|
148
146
|
}, 5000);*/
|
|
147
|
+
// Test of getChangeInfo with and without object Store
|
|
148
|
+
/*
|
|
149
|
+
const ts = Date.now();
|
|
150
|
+
this.log.error(`start mit objectStore`);
|
|
151
|
+
for (let i = 1; i <= 1000; i++) {
|
|
152
|
+
let a = await this.getChangeInfo(
|
|
153
|
+
'lorawan.0.bbea74d6-1fc5-4238-af20-d2aecdbb4f8e.devices.70b3d52dd301b3cc.configuration.devicetype',
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
this.log.error(`Dauer: ${Date.now() - ts}`);*/
|
|
149
157
|
} catch (error) {
|
|
150
158
|
this.log.error(`error at ${activeFunction}: ${error}`);
|
|
151
159
|
}
|
|
@@ -554,16 +562,22 @@ class Lorawan extends utils.Adapter {
|
|
|
554
562
|
const activeFunction = 'onStateChange';
|
|
555
563
|
try {
|
|
556
564
|
if (state) {
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
)
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
565
|
+
this.log.silly(
|
|
566
|
+
`the state ${id} has changed to ${state.val !== '' ? state.val : '""'} with ack = ${state.ack}.`,
|
|
567
|
+
);
|
|
568
|
+
// Update State in objectStore
|
|
569
|
+
if (id.startsWith(this.namespace)) {
|
|
570
|
+
if (!id.startsWith(`${this.namespace}.info`) && !id.startsWith(`${this.namespace}.bridge`)) {
|
|
571
|
+
// Configuration and Downlink is updated with ack = false / true
|
|
572
|
+
// Other folders only in case of true
|
|
573
|
+
if (
|
|
574
|
+
id.includes(this.messagehandler?.directoryhandler.reachableSubfolders.configuration) ||
|
|
575
|
+
id.includes(this.messagehandler?.directoryhandler.reachableSubfolders.downlinkControl) ||
|
|
576
|
+
state.ack
|
|
577
|
+
) {
|
|
578
|
+
await this.objectStore?.generateObjectStructureFromId(id, { payload: { state: state } });
|
|
579
|
+
}
|
|
580
|
+
}
|
|
567
581
|
}
|
|
568
582
|
if (!state.ack) {
|
|
569
583
|
if (id.startsWith(this.namespace)) {
|
|
@@ -953,11 +967,6 @@ class Lorawan extends utils.Adapter {
|
|
|
953
967
|
// Query for Namespace => Just publish foreign States with ack = true
|
|
954
968
|
if (!id.startsWith(this.namespace)) {
|
|
955
969
|
await this.bridge?.publishId(id, state.val, {});
|
|
956
|
-
} else {
|
|
957
|
-
// Update State in objectStore
|
|
958
|
-
if (!id.startsWith(`${this.namespace}.info`) && !id.startsWith(`${this.namespace}.bridge`)) {
|
|
959
|
-
await this.objectStore?.generateObjectStructureFromId(id, { payload: { state: state } });
|
|
960
|
-
}
|
|
961
970
|
}
|
|
962
971
|
}
|
|
963
972
|
} else {
|
|
@@ -1132,14 +1141,16 @@ class Lorawan extends utils.Adapter {
|
|
|
1132
1141
|
async getChangeInfo(id, options) {
|
|
1133
1142
|
const activeFunction = 'getChangeInfo';
|
|
1134
1143
|
try {
|
|
1135
|
-
|
|
1144
|
+
// Check for logging
|
|
1145
|
+
this.log[this.logtypes.getChangeInfo]?.(`changeinfo of id ${id}, will be generated.`);
|
|
1136
1146
|
const changeInfo = this.getBaseDeviceInfo(id);
|
|
1137
|
-
const myId = `${changeInfo?.objectStartDirectory}.${this.messagehandler?.directoryhandler.reachableSubfolders.configuration}.devicetype`;
|
|
1147
|
+
const myId = `${changeInfo?.objectStartDirectory}.${this.messagehandler?.directoryhandler.reachableSubfolders.configuration}.devicetype`; // commented out on: 26.01.2026 => Use objectStore
|
|
1138
1148
|
// Check for changeInfo
|
|
1139
1149
|
if (changeInfo) {
|
|
1140
|
-
//
|
|
1141
|
-
const
|
|
1142
|
-
const
|
|
1150
|
+
const applicationDirectoryObject = await this.getObjectAsync(changeInfo.applicationId); // commented out on: 26.01.2026 => Use objectStore
|
|
1151
|
+
const startDirectoryObject = await this.getObjectAsync(changeInfo.objectStartDirectory); // commented out on: 26.01.2026 => Use objectStore
|
|
1152
|
+
//const applicationDirectoryObject = this.objectStore?.applications[changeInfo.applicationId].object;
|
|
1153
|
+
//const startDirectoryObject = this.objectStore?.devices[changeInfo.deviceEUI].object;
|
|
1143
1154
|
if (applicationDirectoryObject && startDirectoryObject) {
|
|
1144
1155
|
changeInfo.applicationName = applicationDirectoryObject.native.applicationName;
|
|
1145
1156
|
changeInfo.usedApplicationName = applicationDirectoryObject.common.name;
|
|
@@ -1147,7 +1158,8 @@ class Lorawan extends utils.Adapter {
|
|
|
1147
1158
|
changeInfo.usedDeviceId = startDirectoryObject.common.name;
|
|
1148
1159
|
}
|
|
1149
1160
|
// Get deviceType
|
|
1150
|
-
const deviceTypeIdState = await this.getStateAsync(myId);
|
|
1161
|
+
const deviceTypeIdState = await this.getStateAsync(myId); // commented out on: 26.01.2026 => Use objectStore
|
|
1162
|
+
//const deviceTypeIdState = this.objectStore?.devices[changeInfo.deviceEUI].informations.devicetype.state;
|
|
1151
1163
|
if (deviceTypeIdState) {
|
|
1152
1164
|
changeInfo.deviceType = deviceTypeIdState.val;
|
|
1153
1165
|
if (options && options.withBestMatch) {
|