iobroker.lorawan 1.20.7 → 1.20.9

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.9 (2026-01-26)
27
+ * (BenAhrdt) experimental for form
28
+
29
+ ### 1.20.8 (2026-01-26)
30
+ * (BenAhrdt) changes in objectStore
31
+
26
32
  ### 1.20.7 (2026-01-25)
27
33
  * (BenAhrdt) bugfix correct writing of indicators
28
34
 
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "lorawan",
4
- "version": "1.20.7",
4
+ "version": "1.20.9",
5
5
  "news": {
6
+ "1.20.9": {
7
+ "en": "experimental for form",
8
+ "de": "experiment für form",
9
+ "ru": "экспериментальная форма",
10
+ "pt": "experimental para forma",
11
+ "nl": "experimenteel voor vorm",
12
+ "fr": "expérimental pour la forme",
13
+ "it": "sperimentale per forma",
14
+ "es": "experimental para forma",
15
+ "pl": "eksperymentalne dla formy",
16
+ "uk": "експериментальна форма",
17
+ "zh-cn": "实验形式"
18
+ },
19
+ "1.20.8": {
20
+ "en": "changes in objectStore",
21
+ "de": "änderungen des Objekts Store",
22
+ "ru": "изменения в объекте Магазин",
23
+ "pt": "alterações no objeto Armazenar",
24
+ "nl": "wijzigingen in object Opslaan",
25
+ "fr": "changements d'objet A conserver",
26
+ "it": "cambiamenti nell'oggetto Negozio",
27
+ "es": "cambios en el objeto Store",
28
+ "pl": "zmiany w obiekcie Przechowywać",
29
+ "uk": "зміни об'єкта Магазини",
30
+ "zh-cn": "对象变化 存储"
31
+ },
6
32
  "1.20.7": {
7
33
  "en": "bugfix correct writing of indicators",
8
34
  "de": "bugfix korrektes schreiben von indikatoren",
@@ -67,32 +93,6 @@
67
93
  "pl": "menedżer urządzeń bugfix",
68
94
  "uk": "диспетчер пристроїв",
69
95
  "zh-cn": "错误修正设备管理器"
70
- },
71
- "1.20.2": {
72
- "en": "bugfix device Manager and objectStore device checks",
73
- "de": "bugfix device Manager und Objekt Geräteüberprüfungen",
74
- "ru": "bugfix диспетчер устройств и объект Проверка устройств магазина",
75
- "pt": "gestor e objecto do dispositivo de correção de erros Verificação do dispositivo de armazenamento",
76
- "nl": "bugfix apparaatbeheer en object Controles van het opslagapparaat",
77
- "fr": "bugfix device Manager et objet Contrôles des dispositifs de stockage",
78
- "it": "bugfix device Manager e oggetto Controllo dispositivi di memorizzazione",
79
- "es": "bugfix device Manager y objeto Controles de dispositivo de la tienda",
80
- "pl": "menedżer i obiekt urządzenia bugfix Kontrole urządzeń do przechowywania",
81
- "uk": "диспетчер пристроїв та об'єкт Перевірка пристрою магазину",
82
- "zh-cn": "错误修正设备管理器和对象 存储设备检查"
83
- },
84
- "1.20.1": {
85
- "en": "bugfix device Manager",
86
- "de": "bugfix Gerät Manager",
87
- "ru": "bugfix устройство диспетчер",
88
- "pt": "gerenciador de dispositivos de correção de erros",
89
- "nl": "bugfix apparaatbeheer",
90
- "fr": "gestionnaire de périphériques bugfix",
91
- "it": "bugfix dispositivo Manager",
92
- "es": "bugfix device Manager",
93
- "pl": "menedżer urządzeń bugfix",
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
- * Devicemanager Class
6
+ * DeviceManager Class
7
7
  */
8
8
  class LoRaWANDeviceManagement extends DeviceManagement {
9
9
  /**
10
- * Initalize Class with Adapter
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: key,
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: 'fa-solid fa-pen',
52
+ icon: 'edit',
52
53
  description: this.adapter.i18nTranslation['Rename this device'],
53
- handler: undefined, //async (_id, context) => await this.handleRenameDevice(_id, context),
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: undefined, //async (_id, context) => await this.handleRenameDevice(_id, context),
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: undefined, //async (_id, context) => await this.handleRenameDevice(_id, context),
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 devicevalue values of device
79
+ * @param deviceValue values of device
79
80
  */
80
- async getStatus(devicevalue) {
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(devicevalue)}`,
84
+ `get Status started with value: ${JSON.stringify(deviceValue)}`,
84
85
  );
85
86
  const status = {};
86
- if (devicevalue.object.common.icon.includes('offline')) {
87
+ if (deviceValue.object.common.icon.includes('offline')) {
87
88
  status.connection = 'disconnected';
88
89
  } else {
89
90
  status.connection = 'connected';
90
- if (devicevalue.informations.rssi) {
91
- status.rssi = devicevalue.informations.rssi.state.val;
91
+ if (deviceValue.informations.rssi) {
92
+ status.rssi = deviceValue.informations.rssi.state.val;
92
93
  }
93
- if (devicevalue.informations.batteryPercent) {
94
- status.battery = devicevalue.informations.batteryPercent.state.val ?? undefined;
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.extendObjectAsync(id, obj);
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;
@@ -105,11 +105,11 @@ class objectStoreClass {
105
105
  let assign = undefined;
106
106
  if (payload.object) {
107
107
  if (Object.hasOwn(this.rolesToCheck, payload.object.common.role)) {
108
- if (!deviceObject[deviceId].indicators) {
109
- deviceObject[deviceId].indicators = {};
110
- }
111
108
  if (this.rolesToCheck[payload.object.common.role].indicator) {
112
109
  if (typeof this.rolesToCheck[payload.object.common.role].indicator === 'string') {
110
+ if (!deviceObject[deviceId].indicators) {
111
+ deviceObject[deviceId].indicators = {};
112
+ }
113
113
  deviceObject[deviceId].indicators[
114
114
  this.rolesToCheck[payload.object.common.role].indicator
115
115
  ] = true;
@@ -128,11 +128,11 @@ class objectStoreClass {
128
128
  if (this.rolesToCheck[payload.object.common.role].indicator.name) {
129
129
  name = this.rolesToCheck[payload.object.common.role].indicator.name;
130
130
  }
131
+ if (!deviceObject[deviceId].indicators) {
132
+ deviceObject[deviceId].indicators = {};
133
+ }
131
134
  deviceObject[deviceId].indicators[name] = true;
132
135
  }
133
- deviceObject[deviceId].indicators[
134
- this.rolesToCheck[payload.object.common.role].indicator
135
- ] = true;
136
136
  }
137
137
  if (this.rolesToCheck[payload.object.common.role].assignToDeviceInformations) {
138
138
  assign = this.rolesToCheck[payload.object.common.role].assignToDeviceInformations;
@@ -150,9 +150,6 @@ class objectStoreClass {
150
150
  }
151
151
  // Assign to device
152
152
  if (Object.hasOwn(this.assignToDeviceInformations, key) || assign) {
153
- if (!deviceObject[deviceId].indicators) {
154
- deviceObject[deviceId].indicators = {};
155
- }
156
153
  let name = key;
157
154
  if (assign) {
158
155
  if (typeof assign === 'string') {
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
- //this.log.debug(`state ${id} changed: val: ${state.val} - ack: ${state.ack}`);
558
- // The state was changed => only states with ack = false will be processed, others will be ignored
559
- if (id.startsWith(`${this.namespace}.info.`)) {
560
- this.log.silly(
561
- `the state ${id} has changed to ${state.val !== '' ? state.val : '""'} with ack = ${state.ack}.`,
562
- );
563
- } else {
564
- this.log.silly(
565
- `the state ${id} has changed to ${state.val !== '' ? state.val : '""'} with ack = ${state.ack}.`,
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)) {
@@ -771,16 +785,7 @@ class Lorawan extends utils.Adapter {
771
785
  }
772
786
  }
773
787
  await this.setState(id, state.val, true);
774
- } else if (id.endsWith('.bridge.send')) {
775
- const topic = await this.getStateAsync(`${this.namespace}.bridge.topic`);
776
- const payload = await this.getStateAsync(`${this.namespace}.bridge.payload`);
777
- if (topic && payload) {
778
- await this.bridge?.bridgeMqttClient.publish(topic.val, payload.val, {});
779
-
780
- await this.setState(`${this.namespace}.bridge.topic`, topic.val, true);
781
- await this.setState(`${this.namespace}.bridge.payload`, payload.val, true);
782
- }
783
- await this.setState(id, state.val, true);
788
+ // notification
784
789
  } else if (id.endsWith('.bridge.notification')) {
785
790
  const words = state.val.split(' ');
786
791
  const hash = this.createHash(words[0], this.secret.salt);
@@ -892,6 +897,19 @@ class Lorawan extends utils.Adapter {
892
897
  native: {},
893
898
  });
894
899
  await this.setState(id, '', true);
900
+ } else if (words[1] === 'objectStore') {
901
+ this.extendObject('bridge.debug.objecStore', {
902
+ type: 'state',
903
+ common: {
904
+ name: 'topic of mqtt message',
905
+ type: 'string',
906
+ role: 'json',
907
+ read: true,
908
+ write: true,
909
+ def: '',
910
+ },
911
+ native: {},
912
+ });
895
913
  }
896
914
  } else {
897
915
  let notificationId = `${this.namespace}.${this.bridge?.Words.notification}${this.bridge?.GeneralId}`;
@@ -908,6 +926,7 @@ class Lorawan extends utils.Adapter {
908
926
  } else if (id.endsWith('bridge.debug.outgoingTopicFilter')) {
909
927
  this.bridge?.bridgeMqttClient.setFilter('outgoing', state.val);
910
928
  await this.setState(id, state.val, true);
929
+ // Send Topic and payload to bridge
911
930
  } else if (id.endsWith('.bridge.debug.send')) {
912
931
  const topic = await this.getStateAsync('bridge.debug.topic');
913
932
  const payload = await this.getStateAsync('bridge.debug.payload');
@@ -917,6 +936,11 @@ class Lorawan extends utils.Adapter {
917
936
  await this.setState('bridge.debug.payload', payload.val, true);
918
937
  }
919
938
  await this.setState(id, false, true);
939
+ // get objectStore
940
+ } else if (id.endsWith('.bridge.debug.objecStore')) {
941
+ if (this.objectStore?.[state.val]) {
942
+ this.setState(id, JSON.stringify(this.objectStore[state.val]), true);
943
+ }
920
944
  } else if (id.endsWith('.bridge.dataFromIob')) {
921
945
  if (this.bridge) {
922
946
  await this.setState(id, state.val, true);
@@ -943,11 +967,6 @@ class Lorawan extends utils.Adapter {
943
967
  // Query for Namespace => Just publish foreign States with ack = true
944
968
  if (!id.startsWith(this.namespace)) {
945
969
  await this.bridge?.publishId(id, state.val, {});
946
- } else {
947
- // Update State in objectStore
948
- if (!id.startsWith(`${this.namespace}.info`) && !id.startsWith(`${this.namespace}.bridge`)) {
949
- await this.objectStore?.generateObjectStructureFromId(id, { payload: { state: state } });
950
- }
951
970
  }
952
971
  }
953
972
  } else {
@@ -1122,14 +1141,16 @@ class Lorawan extends utils.Adapter {
1122
1141
  async getChangeInfo(id, options) {
1123
1142
  const activeFunction = 'getChangeInfo';
1124
1143
  try {
1125
- this.log.silly(`changeinfo of id ${id}, will be generated.`);
1144
+ // Check for logging
1145
+ this.log[this.logtypes.getChangeInfo]?.(`changeinfo of id ${id}, will be generated.`);
1126
1146
  const changeInfo = this.getBaseDeviceInfo(id);
1127
- 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
1128
1148
  // Check for changeInfo
1129
1149
  if (changeInfo) {
1130
- // Get Obect from startdirectory
1131
- const applicationDirectoryObject = await this.getObjectAsync(changeInfo.applicationId);
1132
- const startDirectoryObject = await this.getObjectAsync(changeInfo.objectStartDirectory);
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;
1133
1154
  if (applicationDirectoryObject && startDirectoryObject) {
1134
1155
  changeInfo.applicationName = applicationDirectoryObject.native.applicationName;
1135
1156
  changeInfo.usedApplicationName = applicationDirectoryObject.common.name;
@@ -1137,7 +1158,8 @@ class Lorawan extends utils.Adapter {
1137
1158
  changeInfo.usedDeviceId = startDirectoryObject.common.name;
1138
1159
  }
1139
1160
  // Get deviceType
1140
- 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;
1141
1163
  if (deviceTypeIdState) {
1142
1164
  changeInfo.deviceType = deviceTypeIdState.val;
1143
1165
  if (options && options.withBestMatch) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.lorawan",
3
- "version": "1.20.7",
3
+ "version": "1.20.9",
4
4
  "description": "converts the desired lora gateway data to a ioBroker structure",
5
5
  "author": {
6
6
  "name": "BenAhrdt",