iobroker.lorawan 1.0.2 → 1.0.3

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,10 @@ 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.0.3 (2024-05-10)
27
+ * (BenAhrdt) notifications for connection and disconnection LNS added
28
+ * (BenAhrdt) notifiction for device offline added
29
+
26
30
  ### 1.0.2 (2024-03-27)
27
31
  * (BenAhrdt) change some comments and logging
28
32
 
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "lorawan",
4
- "version": "1.0.2",
4
+ "version": "1.0.3",
5
5
  "news": {
6
+ "1.0.3": {
7
+ "en": "notifications for connection and disconnection LNS added\nnotifiction for device offline added",
8
+ "de": "benachrichtigungen für Anschluss und Abschaltung LNS hinzugefügt\nnotification für gerät offline hinzugefügt",
9
+ "ru": "уведомления для подключения и отключения\nnotification for device offline added",
10
+ "pt": "notificações para conexão e desconexão LNS adicionado\nnotificação para dispositivo offline adicionado",
11
+ "nl": "meldingen voor verbinding en loskoppeling LNS toegevoegd\nnotatie voor apparaat offline toegevoegd",
12
+ "fr": "notifications pour connexion et déconnexion LNS ajoutées\nnotifition pour périphérique hors ligne ajouté",
13
+ "it": "notifiche per connessione e disconnessione LNS aggiunto\nnotifica per dispositivo offline aggiunto",
14
+ "es": "notificaciones para conexión y desconexión LNS añadido\nnotifiction para dispositivo offline añadido",
15
+ "pl": "powiadomienia o dodanych LNS podłączenia i odłączenia\nname",
16
+ "uk": "повідомлення про підключення та відключення LNS додано\nдодано невідповідність пристрою",
17
+ "zh-cn": "添加连接和断开LNS的通知\n设备下线通知已添加"
18
+ },
6
19
  "1.0.2": {
7
20
  "en": "change some comments and logging",
8
21
  "de": "einige kommentare und protokollierung ändern",
@@ -80,19 +93,6 @@
80
93
  "pl": "Zmień pisanie informacji na temat treści w Ttn",
81
94
  "uk": "Зміна письмової інформації про пристрій",
82
95
  "zh-cn": "在 Ttn 更改设备信息的写入"
83
- },
84
- "0.6.3": {
85
- "en": "def of deviceinformations changed",
86
- "de": "def von geräteinformationen geändert",
87
- "ru": "изменена дефабрикация устройств",
88
- "pt": "def das informações do dispositivo alteradas",
89
- "nl": "de def van apparaatinformatie gewijzigd",
90
- "fr": "def des informations de l'appareil changé",
91
- "it": "def delle informazioni sui dispositivi modificate",
92
- "es": "def de las desinformaciones de dispositivo cambiadas",
93
- "pl": "def deviceinformations changed",
94
- "uk": "змінено деф приладів",
95
- "zh-cn": "设备信息已更改"
96
96
  }
97
97
  },
98
98
  "titleLang": {
@@ -157,6 +157,135 @@
157
157
  }
158
158
  ]
159
159
  },
160
+ "notifications": [
161
+ {
162
+ "scope": "lorawan",
163
+ "name": {
164
+ "en": "LoRaWAN",
165
+ "de": "LoRaWAN",
166
+ "ru": "LoRaWAN",
167
+ "pt": "LoRaWAN",
168
+ "nl": "LoRaWAN",
169
+ "fr": "LORAWAN",
170
+ "it": "LoRaWAN",
171
+ "es": "LoRaWAN",
172
+ "pl": "LoRaWAN",
173
+ "uk": "Лоравіан",
174
+ "zh-cn": "洛拉万语"
175
+ },
176
+ "description": {
177
+ "en": "These notifications represent news of devices, gateways or LoraWAN Network Services",
178
+ "de": "Diese Benachrichtigungen stellen Nachrichten von Geräten, Gateways oder LoraWAN Network Services dar",
179
+ "ru": "Эти уведомления представляют новости об устройствах, шлюзах или LoraWAN Network Services",
180
+ "pt": "Estas notificações representam notícias de dispositivos, gateways ou serviços de rede LoraWAN",
181
+ "nl": "Deze meldingen vertegenwoordigen nieuws van apparaten, gateways of LoraWAN Network Services",
182
+ "fr": "Ces notifications représentent des nouvelles d'appareils, passerelles ou services réseau LoraWAN",
183
+ "it": "Queste notifiche rappresentano notizie di dispositivi, gateway o LoraWAN Network Services",
184
+ "es": "Estas notificaciones representan noticias de dispositivos, portales o LoraWAN Network Services",
185
+ "pl": "Powiadomienia te stanowią wiadomości o urządzeniach, bramach lub usługach sieciowych LoraWAN",
186
+ "uk": "Ці повідомлення представляють новини пристроїв, шлюзу або LoraWAN",
187
+ "zh-cn": "这些通知代表设备、网关或LoraWAN网络服务的新闻"
188
+ },
189
+ "categories": [
190
+ {
191
+ "category": "LoRaWAN Network Service connected",
192
+ "name": {
193
+ "en": "The desired LoRaWAN Network service was connected",
194
+ "de": "Der gewünschte LoRaWAN Network Service wurde verbunden",
195
+ "ru": "Желаемый сервис LoRaWAN Network был подключен",
196
+ "pt": "O serviço de rede LoRaWAN desejado foi conectado",
197
+ "nl": "De gewenste LoRaWAN Network service was aangesloten",
198
+ "fr": "Le service de réseau LoRaWAN souhaité était connecté",
199
+ "it": "Il servizio LoRaWAN Network desiderato è stato collegato",
200
+ "es": "El servicio LoRaWAN Network deseado estaba conectado",
201
+ "pl": "Połączono żądaną usługę sieci LoRaWAN",
202
+ "uk": "З'єднано бажаний сервіс LoRaWAN",
203
+ "zh-cn": "所期望的LORAWAN网络服务已连接"
204
+ },
205
+ "severity": "info",
206
+ "description": {
207
+ "en": "The connection to the LoRaWAN Network service changed from disconnected to connected",
208
+ "de": "Die Verbindung zum LoRaWAN Network-Service hat sich von getrennt zu verbunden geändert",
209
+ "ru": "Соединение с сервисом LoRaWAN Network изменилось от отключенного к подключенному",
210
+ "pt": "A conexão com o serviço de rede LoRaWAN mudou de desconectado para conectado",
211
+ "nl": "De verbinding met de LoRaWAN Network service veranderde van losgekoppeld naar verbonden",
212
+ "fr": "La connexion au service réseau LoRaWAN est passée de déconnectée à connectée",
213
+ "it": "Il collegamento al servizio di rete LoRaWAN è cambiato da disconnesso a collegato",
214
+ "es": "La conexión con el servicio LoRaWAN Network cambió de desconectado a conectado",
215
+ "pl": "Połączenie z siecią LoRaWAN zmieniło się z odłączonego na podłączony",
216
+ "uk": "З'єднання до мережі LoRaWAN змінено з відключення",
217
+ "zh-cn": "连接 LoRAWAN 网络服务从断开到连接"
218
+ },
219
+ "regex": [],
220
+ "limit": 1
221
+ },
222
+ {
223
+ "category": "LoRaWAN Network Service disconnected",
224
+ "name": {
225
+ "en": "The desired LoRaWAN Network service was disconnected",
226
+ "de": "Der gewünschte LoRaWAN Network Service ist nicht mehr erreichbar",
227
+ "ru": "Желаемый сервис LoRaWAN Network был отключен",
228
+ "pt": "O serviço de rede LoRaWAN desejado foi desligado",
229
+ "nl": "De gewenste LoRaWAN Network service werd afgesloten",
230
+ "fr": "Le service de réseau LoRaWAN souhaité a été déconnecté",
231
+ "it": "Il servizio LoRaWAN Network desiderato è stato disconnesso",
232
+ "es": "El servicio LoRaWAN Network deseado fue desconectado",
233
+ "pl": "Wybrana usługa LoRaWAN Network została odłączona",
234
+ "uk": "Відключено бажаний сервіс мережі LoRaWAN",
235
+ "zh-cn": "想要的LORAWAN网络服务已断开"
236
+ },
237
+ "severity": "alert",
238
+ "description": {
239
+ "en": "The connection to the LoRaWAN Network service changed from connected to disconnected",
240
+ "de": "Die Verbindung zum LoRaWAN-Netzwerk-Service hat sich von verbunden zu getrennt geändert",
241
+ "ru": "Соединение с сервисом LoRaWAN Network изменилось от подключения к отключенному",
242
+ "pt": "A conexão com o serviço de rede LoRaWAN mudou de conectado para desconectado",
243
+ "nl": "De verbinding met de LoRaWAN Network service veranderde van verbonden naar losgekoppeld",
244
+ "fr": "La connexion au service réseau LoRaWAN a changé de connecté à déconnecté",
245
+ "it": "La connessione al servizio di rete LoRaWAN è cambiata da collegato a disconnesso",
246
+ "es": "La conexión con el servicio LoRaWAN Network cambió de conexión a desconexión",
247
+ "pl": "Połączenie z siecią LoRaWAN zmieniło się z podłączonego na odłączony",
248
+ "uk": "З'єднання до мережі LoRaWAN змінено з підключеного до відключення",
249
+ "zh-cn": "连接到 LoRAWAN 网络服务从连接到断开"
250
+ },
251
+ "regex": [],
252
+ "limit": 1
253
+ },
254
+ {
255
+ "category": "LoRaWAN device offline",
256
+ "name": {
257
+ "en": "A LoRaWAN device is offline",
258
+ "de": "Ein LoRaWAN Gerät ist offline",
259
+ "ru": "Устройство LoRaWAN отключено",
260
+ "pt": "Um dispositivo LoRaWAN está offline",
261
+ "nl": "Een LoRaWAN apparaat is offline",
262
+ "fr": "Un périphérique LoRaWAN est hors ligne",
263
+ "it": "Un dispositivo LoRaWAN è offline",
264
+ "es": "Un dispositivo LoRaWAN está fuera de línea",
265
+ "pl": "Urządzenie LoRaWAN jest wyłączone",
266
+ "uk": "Пристрій LoRaWAN автономний",
267
+ "zh-cn": "LORAWAN 设备已下线"
268
+ },
269
+ "severity": "notify",
270
+ "description": {
271
+ "en": "A LoraWAN device has not sended a message for a long time",
272
+ "de": "Ein LoraWAN-Gerät hat lange keine Nachricht gesendet",
273
+ "ru": "Устройство LoraWAN не посылало сообщения в течение длительного времени",
274
+ "pt": "Um dispositivo LoraWAN não enviou uma mensagem por muito tempo",
275
+ "nl": "Een LoraWAN-apparaat heeft al lange tijd geen bericht meer verstuurd",
276
+ "fr": "Un périphérique LoraWAN n'a pas envoyé de message depuis longtemps",
277
+ "it": "Un dispositivo LoraWAN non ha inviato un messaggio per molto tempo",
278
+ "es": "Un dispositivo LoraWAN no ha enviado un mensaje durante mucho tiempo",
279
+ "pl": "Urządzenie LoraWAN nie wysłało wiadomości przez długi czas",
280
+ "uk": "Пристрій LoraWAN не відправляє повідомлення тривалий час",
281
+ "zh-cn": "LoraWAN 设备已经很久没有固定消息了"
282
+ },
283
+ "regex": [],
284
+ "limit": 10
285
+ }
286
+ ]
287
+ }
288
+ ],
160
289
  "encryptedNative": [
161
290
  "password"
162
291
  ],
@@ -331,7 +331,7 @@ class directorieshandlerClass {
331
331
  }
332
332
  // Check for an assign definition (calculation and / or role assignment)
333
333
  if(this.assigns[elementName] && !options?.dontAssign){
334
- this.adapter.log.debug(`the state with th id ${objectId} will be assigned by internal function`);
334
+ this.adapter.log.debug(`the state with the id ${objectId} will be assigned by internal function`);
335
335
  stateVal = this.assigns[elementName](stateVal,common);
336
336
  }
337
337
  common.read = common.role !== "button";
@@ -105,7 +105,7 @@ class messagehandlerClass {
105
105
  case this.adapter.origin.ttn:
106
106
  if(message.uplink_message && message.uplink_message){
107
107
  this.deviceinformations[changeInfo.deviceEUI].uplink.decoded = message.uplink_message.decoded_payload;
108
- this.deviceinformations[changeInfo.deviceEUI].uplink.time = message.uplink_message.rx_metadata.time;
108
+ this.deviceinformations[changeInfo.deviceEUI].uplink.time = message.uplink_message.rx_metadata[0].time;
109
109
  }
110
110
  break;
111
111
  case this.adapter.origin.chirpstack:
@@ -10,9 +10,20 @@ class mqttClientClass {
10
10
  password: settings.password,
11
11
  clientId: `iobroker_${this.adapter.namespace}`
12
12
  });
13
+
14
+ // Variables for correct connection (disconnection) notification / logging
15
+ this.interanConnectionstate = false;
16
+ this.errorCountdown = 0;
17
+ this.numberOfErrorsToLog = 10;
18
+
13
19
  this.client.on("connect", () => {
14
- this.adapter.log.info(`Connection is active.`);
20
+ if(!this.interanConnectionstate){
21
+ this.adapter.log.info(`Connection is active.`);
22
+ this.adapter.registerNotification("lorawan", "LoRaWAN Network Service connected", `The LoRaWAN Network Service ${settings.ipUrl} was connected`);
23
+ }
15
24
  this.adapter.setState("info.connection", true, true);
25
+ this.interanConnectionstate = true;
26
+ this.errorCountdown = this.numberOfErrorsToLog;
16
27
  // @ts-ignore
17
28
  this.client.subscribe(this.getSubscribtionArray(), (err) => {
18
29
  if (err) {
@@ -21,16 +32,29 @@ class mqttClientClass {
21
32
  });
22
33
  });
23
34
  this.client.on("disconnect", () => {
24
- this.adapter.setState("info.connection", false, true);
25
- this.adapter.log.info(`disconnected`);
35
+ if(this.interanConnectionstate){
36
+ this.adapter.setState("info.connection", false, true);
37
+ this.interanConnectionstate = false;
38
+ this.adapter.log.info(`disconnected`);
39
+ }
26
40
  });
27
41
  this.client.on("error", (err) => {
28
- this.adapter.log.error(`${err}`);
42
+ if(this.errorCountdown === 0){
43
+ this.adapter.log.error(`${err}`);
44
+ this.errorCountdown = this.numberOfErrorsToLog;
45
+ }
46
+ else{
47
+ this.errorCountdown--;
48
+ }
29
49
  });
30
50
 
31
51
  this.client.on("close", () => {
52
+ if(this.interanConnectionstate){
53
+ this.adapter.log.info(`Connection is closed.`);
54
+ this.adapter.registerNotification("lorawan", "LoRaWAN Network Service disconnected", `The LoRaWAN Network Service ${settings.ipUrl} was disconnected`);
55
+ }
32
56
  this.adapter.setState("info.connection", false, true);
33
- this.adapter.log.info(`Connection is closed.`);
57
+ this.interanConnectionstate = false;
34
58
  });
35
59
 
36
60
  this.client.on("message", async (topic, message) => {
package/main.js CHANGED
@@ -7,6 +7,7 @@
7
7
  // The adapter-core module gives you access to the core ioBroker functions
8
8
  // you need to create an adapter
9
9
  const utils = require("@iobroker/adapter-core");
10
+ const schedule = require("node-schedule");
10
11
  const mqttClientClass = require("./lib/modules/mqttclient");
11
12
  const messagehandlerClass = require("./lib/modules/messagehandler");
12
13
  const downlinkConfighandlerClass = require("./lib/modules/downlinkConfighandler");
@@ -32,6 +33,14 @@ class Lorawan extends utils.Adapter {
32
33
  chirpstack: "chirpstack"
33
34
  };
34
35
 
36
+ this.cronJobs = {};
37
+ this.cronJobIds = {
38
+ checkTimestamp: "checkTimestamp"
39
+ };
40
+ this.cronJosValues = {
41
+ checkTimestamp: "* * * * *"//"0 * * * *"
42
+ };
43
+
35
44
  // Simulation variables
36
45
  this.simulation = {};
37
46
  }
@@ -66,6 +75,9 @@ class Lorawan extends utils.Adapter {
66
75
  this.log.silly(`the adapter starts with downlinkconfigs: ${JSON.stringify(this.config.downlinkConfig)}.`);
67
76
  this.log.silly(`the active downlinkconfigs are: ${JSON.stringify(this.downlinkConfighandler.activeDownlinkConfigs)}`);
68
77
 
78
+ // Create cronjob to check timestamps (for device offline notification)
79
+ this.cronJobs[this.cronJobIds.checkTimestamp] = schedule.scheduleJob(this.cronJosValues.checkTimestamp,this.checkTimestamps.bind(this));
80
+
69
81
  /*setTimeout(async () => {
70
82
  await this.startSimulation();
71
83
  }, 5000);*/
@@ -81,6 +93,36 @@ class Lorawan extends utils.Adapter {
81
93
  }
82
94
  }
83
95
 
96
+ async checkTimestamps(){
97
+ const activeFunction = "checkTimestamps";
98
+ try{
99
+ const adapterObjects = await this.getAdapterObjectsAsync();
100
+ // Generate Infos of all defices and decoded folders
101
+ for(const adapterObject of Object.values(adapterObjects)){
102
+ if(adapterObject._id.endsWith(`${this.messagehandler?.directoryhandler.reachableSubfolders.uplinkRaw}.json`)){
103
+ const uplinkState = await this.getStateAsync(adapterObject._id);
104
+ if(uplinkState){
105
+ const msInOneHour = 1000 * 60 * 60;
106
+ const maxDifferenceMin = 25 * msInOneHour;
107
+ const maxDifferenceMax = 26 * msInOneHour;
108
+ const timestampNow = Date.now();
109
+ const timestampData = uplinkState.ts;
110
+ const difference = timestampNow - timestampData;
111
+ if(difference >= maxDifferenceMin && difference <= maxDifferenceMax){
112
+ const changeInfo = await this.getChangeInfo(adapterObject._id);
113
+ if(changeInfo){
114
+ this.registerNotification("lorawan", "LoRaWAN device offline", `The LoRaWAN device ${changeInfo.usedDeviceId} in the application ${changeInfo.usedApplicationName} is offline`);
115
+ }
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+ catch(error){
122
+ this.log.error(`error at ${activeFunction}: ` + error);
123
+ }
124
+ }
125
+
84
126
  async startSimulation(){
85
127
 
86
128
  // TTN
@@ -510,6 +552,15 @@ class Lorawan extends utils.Adapter {
510
552
  this.log.error(`error at ${activeFunction}: ` + error);
511
553
  }
512
554
  }
555
+
556
+ // Clear all schedules, if there are some
557
+ clearAllSchedules(){
558
+ for(const cronJob in this.cronJobs)
559
+ {
560
+ schedule.cancelJob(this.cronJobs[cronJob]);
561
+ delete this.cronJobs[cronJob];
562
+ }
563
+ }
513
564
  }
514
565
 
515
566
  if (require.main !== module) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.lorawan",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "converts the desired lora gateway data to a ioBroker structure",
5
5
  "author": {
6
6
  "name": "BenAhrdt",
@@ -24,9 +24,10 @@
24
24
  "node": ">= 18"
25
25
  },
26
26
  "dependencies": {
27
- "@iobroker/adapter-core": "^3.0.4",
27
+ "@iobroker/adapter-core": "^3.1.4",
28
28
  "easy-crc": "^1.1.0",
29
- "mqtt": "^5.3.6"
29
+ "mqtt": "^5.5.5",
30
+ "node-schedule": "^2.1.1"
30
31
  },
31
32
  "devDependencies": {
32
33
  "@alcalzone/release-script": "^3.7.0",
@@ -34,23 +35,23 @@
34
35
  "@alcalzone/release-script-plugin-license": "^3.7.0",
35
36
  "@alcalzone/release-script-plugin-manual-review": "^3.7.0",
36
37
  "@iobroker/adapter-dev": "^1.3.0",
37
- "@iobroker/testing": "^4.1.0",
38
+ "@iobroker/testing": "^4.1.3",
38
39
  "@tsconfig/node18": "^18.2.2",
39
40
  "@types/chai": "^4.3.11",
40
41
  "@types/chai-as-promised": "^7.1.8",
41
42
  "@types/mocha": "^10.0.6",
42
- "@types/node": "^20.11.24",
43
+ "@types/node": "^20.12.2",
43
44
  "@types/proxyquire": "^1.3.31",
44
45
  "@types/sinon": "^17.0.3",
45
46
  "@types/sinon-chai": "^3.2.12",
46
47
  "chai": "^4.4.1",
47
48
  "chai-as-promised": "^7.1.1",
48
49
  "eslint": "^8.57.0",
49
- "mocha": "^10.3.0",
50
+ "mocha": "^10.4.0",
50
51
  "proxyquire": "^2.1.3",
51
52
  "sinon": "^17.0.1",
52
53
  "sinon-chai": "^3.7.0",
53
- "typescript": "~5.3.3"
54
+ "typescript": "~5.4.5"
54
55
  },
55
56
  "main": "main.js",
56
57
  "files": [