iobroker.lorawan 0.6.6 → 1.0.1

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
@@ -22,6 +22,12 @@ For now there is documentation in English here: https://wiki.hafenmeister.de
22
22
  Placeholder for the next version (at the beginning of the line):
23
23
  ### **WORK IN PROGRESS**
24
24
  -->
25
+ ### 1.0.1 (2024-03-25)
26
+ * (BenAhrdt) support 2's complement
27
+
28
+ ### 1.0.0 (2024-03-21)
29
+ * (BenAhrdt) implement wifi icons
30
+
25
31
  ### 0.6.6 (2024-03-11)
26
32
  * (BenAhrdt) update Vicki device-config
27
33
 
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "lorawan",
4
- "version": "0.6.6",
4
+ "version": "1.0.1",
5
5
  "news": {
6
+ "1.0.1": {
7
+ "en": "support 2's complement",
8
+ "de": "support 2's ergänzung",
9
+ "ru": "поддержка 2",
10
+ "pt": "complemento do suporte 2",
11
+ "nl": "ondersteuning 2's complement",
12
+ "fr": "soutenir le complément 2",
13
+ "it": "supporto 2's complemento",
14
+ "es": "complemento de soporte 2",
15
+ "pl": "wsparcie dopełnienia 2",
16
+ "uk": "підтримка 2 доповнення",
17
+ "zh-cn": "支助2的补充"
18
+ },
19
+ "1.0.0": {
20
+ "en": "implement wifi icons",
21
+ "de": "wifi-symbole implementieren",
22
+ "ru": "реализовать wifi иконки",
23
+ "pt": "implementar ícones de wifi",
24
+ "nl": "wifi-pictogrammen implementeren",
25
+ "fr": "implémenter des icônes wifi",
26
+ "it": "implementare le icone wifi",
27
+ "es": "implementar iconos wifi",
28
+ "pl": "implementuj ikony wifi",
29
+ "uk": "впроваджувати іконки wifi",
30
+ "zh-cn": "执行wifi图标"
31
+ },
6
32
  "0.6.6": {
7
33
  "en": "update Vicki device-config",
8
34
  "de": "vicki Gerät-config aktualisieren",
@@ -67,35 +93,8 @@
67
93
  "pl": "seperate dp for deviceinformations",
68
94
  "uk": "seperate dp для пристроюінформаційних систем",
69
95
  "zh-cn": "设备信息的 seperate dp"
70
- },
71
- "0.6.1": {
72
- "en": "better concept to write values and change setObjectNotExists to extendObject",
73
- "de": "besseres Konzept zum Schreiben von Werten und Änderungsset ObjectNotExists to erweitern Gegenstand",
74
- "ru": "лучшее понятие для написания ценностей и изменения набора ObjectNotExists Объект",
75
- "pt": "melhor conceito para escrever valores e alterar o conjunto ObjectNotExists para estender Objeto",
76
- "nl": "beter concept om waarden en verandering set te schrijven ObjectNotBestaat om uit te breiden Doel",
77
- "fr": "meilleur concept pour écrire des valeurs et changer ensemble ObjectNotExiste à étendre Objet",
78
- "it": "migliore concetto per scrivere valori e cambiare set ObjectNotEsiste per estendere Oggetto",
79
- "es": "mejor concepto para escribir valores y cambiar conjunto ObjectNotExists to extend Objeto",
80
- "pl": "lepsza koncepcja zapisu wartości i zestaw zmian ObjectNotExists rozszerzyć Obiekt",
81
- "uk": "краща концепція для написання значень та змін Об'єктNotExists для розширення Об'єкт",
82
- "zh-cn": "更好的写值和更改集的概念 要扩展的对象不包含 对象"
83
- },
84
- "0.6.0": {
85
- "en": "change concept of assigning roles, values and writecommands",
86
- "de": "änderungskonzept der zuordnung von rollen, werten und schreibbefehlen",
87
- "ru": "изменение концепции присвоения ролей, ценностей и комманд",
88
- "pt": "mudar o conceito de atribuir papéis, valores e redigircomando",
89
- "nl": "verandering concept van het toewijzen van rollen, waarden en schrijfcommando's",
90
- "fr": "changer le concept d'attribution des rôles, des valeurs et des commandes écrites",
91
- "it": "cambiare il concetto di assegnare ruoli, valori e comandi di scrittura",
92
- "es": "cambio de concepto de asignación de roles, valores y",
93
- "pl": "zmiana koncepcji przypisywania ról, wartości i pisarek",
94
- "uk": "зміни концепції присвоєння ролей, значень та написаннякоманд",
95
- "zh-cn": "更改指定角色、值和写入命令的概念"
96
96
  }
97
97
  },
98
- "title": "LoRaWAN",
99
98
  "titleLang": {
100
99
  "en": "LoRaWAN",
101
100
  "de": "LoRaWAN",
@@ -28,6 +28,10 @@ class directorieshandlerClass {
28
28
  joinRaw: "join.raw"
29
29
  };
30
30
 
31
+ this.icons = {
32
+ wifi: "wifi"
33
+ };
34
+
31
35
  /*********************************************************************
32
36
  * ********************* Definition of Assigns **********************
33
37
  * ******************************************************************/
@@ -113,6 +117,9 @@ class directorieshandlerClass {
113
117
  deviceId : this.getAttributValue(topic,message,this.searchableAttributeNames.deviceId)
114
118
  };
115
119
  },
120
+ objectIconPath: (topic,message)=>{
121
+ return this.getIconPath(topic,message,this.icons.wifi);
122
+ },
116
123
  objectType: "device",
117
124
  configuration:{
118
125
  devicetype:{
@@ -165,7 +172,8 @@ class directorieshandlerClass {
165
172
  objectCommonName: "objectCommonName",
166
173
  objectCommonFromNative: "objectCommonFromNative",
167
174
  objectType: "objectType",
168
- objectNative : "objectNative"
175
+ objectNative: "objectNative",
176
+ objectIconPath: "objectIconPath"
169
177
  };
170
178
  }
171
179
 
@@ -215,6 +223,14 @@ class directorieshandlerClass {
215
223
  myObject.common = {};
216
224
  }
217
225
 
226
+ // Check for icon assignment
227
+ if(obj[elementName].objectIconPath){
228
+ const iconPath = obj[elementName].objectIconPath(topic,message);
229
+ if(iconPath !== ""){
230
+ myObject.common.icon = iconPath;
231
+ }
232
+ }
233
+
218
234
  // check whether a common name was specified
219
235
  if(obj[elementName].objectCommonName){
220
236
  if(typeof obj[elementName].objectCommonName === "function"){
@@ -351,6 +367,63 @@ class directorieshandlerClass {
351
367
  }
352
368
  }
353
369
 
370
+ /*********************************************************************
371
+ * *************************** iconPath ******************************
372
+ * ******************************************************************/
373
+
374
+ getIconPath(topic,message,icontype){
375
+ const activeFunction = "getIconPath";
376
+ try{
377
+ // Select search in case of origin
378
+ switch(this.adapter.config.origin){
379
+ case this.adapter.origin.ttn:
380
+ return this.getTtnIconPath(topic,message,icontype);
381
+ case this.adapter.origin.chirpstack:
382
+ return this.getChirpstackIconPath(topic,message,icontype);
383
+ }
384
+ }
385
+ catch(error){
386
+ this.adapter.log.error(`error at ${activeFunction}: ${error} - - - Message: ${JSON.stringify(message)}`);
387
+ }
388
+ }
389
+
390
+ analyseConnection(sf,rssi){
391
+ const activeFunction = "getIcon";
392
+ try{
393
+ this.adapter.log.silly(`icon for device with sf: ${sf} and rssi: ${rssi} requested`);
394
+ let iconPath = `icons/wifiSf`;
395
+ if(sf === 7 || sf === 9 || sf === 12){
396
+ iconPath += `${sf}`;
397
+ }
398
+ else{
399
+ iconPath += `X`;
400
+ }
401
+ if(rssi >= -70){
402
+ rssi = 5;
403
+ }
404
+ else if(rssi >= -80){
405
+ rssi = 4;
406
+ }
407
+ else if(rssi >= -90){
408
+ rssi = 3;
409
+ }
410
+ else if(rssi >= -100){
411
+ rssi = 2;
412
+ }
413
+ else if(rssi >= -110){
414
+ rssi = 1;
415
+ }
416
+ else{
417
+ rssi = 0;
418
+ }
419
+ iconPath += `_${rssi}.png`;
420
+
421
+ return iconPath;
422
+ }
423
+ catch(error){
424
+ this.adapter.log.error(`error at ${activeFunction}: ${error}`);
425
+ }
426
+ }
354
427
  /*********************************************************************
355
428
  * ******************** Object Start Directory ***********************
356
429
  * ******************************************************************/
@@ -423,6 +496,32 @@ class directorieshandlerClass {
423
496
  }
424
497
  }
425
498
 
499
+ /*********************************************************************
500
+ * *************************** iconPath ******************************
501
+ * ******************************************************************/
502
+
503
+ getTtnIconPath(topic,message,icontype){
504
+ const activeFunction = "getTtnIconPath";
505
+ try{
506
+ this.adapter.log.silly(`icontype ${icontype} is requested for ttn`);
507
+ switch(icontype){
508
+ case this.icons.wifi:
509
+ if(message.uplink_message?.settings.data_rate.lora.spreading_factor &&
510
+ message.uplink_message?.rx_metadata[0].rssi){
511
+ return this.analyseConnection(message.uplink_message.settings.data_rate.lora.spreading_factor,message.uplink_message.rx_metadata[0].rssi);
512
+ }
513
+ return "";
514
+
515
+ default:
516
+ this.adapter.log.warn(`No icontype with the name ${icontype} found.`);
517
+ return "";
518
+ }
519
+ }
520
+ catch(error){
521
+ this.adapter.log.error(`error at ${activeFunction}: ${error} - - - Topic: ${JSON.stringify(topic)}`);
522
+ }
523
+ }
524
+
426
525
  /*********************************************************************
427
526
  * ************************ Object Directory *************************
428
527
  * ******************************************************************/
@@ -490,6 +589,34 @@ class directorieshandlerClass {
490
589
  }
491
590
  }
492
591
 
592
+ /*********************************************************************
593
+ * *************************** iconPath ******************************
594
+ * ******************************************************************/
595
+
596
+ getChirpstackIconPath(topic,message,icontype){
597
+ const activeFunction = "getChirpstackIconPath";
598
+ try{
599
+ this.adapter.log.silly(`icontype ${icontype} is requested for ttn`);
600
+ switch(icontype){
601
+ case this.icons.wifi:
602
+ if(message.txInfo?.modulation.lora.spreadingFactor &&
603
+ message.rxInfo[0]?.rssi){
604
+ return this.analyseConnection(message.txInfo.modulation.lora.spreadingFactor,message.rxInfo[0].rssi);
605
+ }
606
+ else{
607
+ return "";
608
+ }
609
+
610
+ default:
611
+ this.adapter.log.warn(`No icontype with the name ${icontype} found.`);
612
+ return "";
613
+ }
614
+ }
615
+ catch(error){
616
+ this.adapter.log.error(`error at ${activeFunction}: ${error} - - - Topic: ${JSON.stringify(topic)}`);
617
+ }
618
+ }
619
+
493
620
  /*********************************************************************
494
621
  * ************************ Resolved Topic ***************************
495
622
  * ******************************************************************/
@@ -293,14 +293,17 @@ class downlinkConfighandlerClass {
293
293
  case "number":
294
294
  if(downlinkParameter.decimalPlaces){
295
295
  const expotentialFactor = Math.pow(10,downlinkParameter.decimalPlaces);
296
- const StateWithExotetialFactor = Math.trunc(state.val * expotentialFactor);
296
+ const StateWithExotetialFactor = Math.round(state.val * expotentialFactor);
297
+ this.adapter.log.warn(StateWithExotetialFactor);
297
298
  resultAfterdecimalPlaces = StateWithExotetialFactor / expotentialFactor;
298
299
  }
299
300
  else{
300
301
  resultAfterdecimalPlaces = Math.trunc(state.val);
301
302
  }
302
303
  multipliedVal = resultAfterdecimalPlaces * downlinkParameter.multiplyfaktor;
303
- payloadInHex = multipliedVal.toString(16);
304
+ // Assign absolute value
305
+ payloadInHex = Math.abs(multipliedVal).toString(16);
306
+ // create the zero diggits
304
307
  numberOfDiggits = downlinkParameter.lengthInByte * 2;
305
308
  for(let index = 1; index <= numberOfDiggits; index++){
306
309
  zeroDiggits += "0";
@@ -309,6 +312,14 @@ class downlinkConfighandlerClass {
309
312
  if(downlinkParameter.swap){
310
313
  payloadInHex = Buffer.from(payloadInHex,"hex").reverse().toString("hex");
311
314
  }
315
+
316
+ // Create negative 2´s complement
317
+ if(multipliedVal < 0){
318
+ const compareFactor = Math.pow(2,(downlinkParameter.lengthInByte * 8))-1;
319
+ payloadInHex = (~parseInt(payloadInHex,16)+1 & compareFactor).toString(16);
320
+ }
321
+
322
+ // Assign the front and end
312
323
  payloadInHex = downlinkParameter.front + payloadInHex + downlinkParameter.end;
313
324
  break;
314
325
 
package/main.js CHANGED
@@ -31,6 +31,9 @@ class Lorawan extends utils.Adapter {
31
31
  ttn: "ttn",
32
32
  chirpstack: "chirpstack"
33
33
  };
34
+
35
+ // Simulation variables
36
+ this.simulation = {};
34
37
  }
35
38
 
36
39
  /**
@@ -66,7 +69,7 @@ class Lorawan extends utils.Adapter {
66
69
  /*setTimeout(async () => {
67
70
  await this.startSimulation();
68
71
  }, 5000);*/
69
- /*setTimeout(async () => {
72
+ /*this.simulation.timeout = setTimeout(async () => {
70
73
  const topic = "application/d63c10b6-9263-4ab3-9299-4308fa19a2ad/device/f1c0ae0e-b4a2-4547-b360-7cfa15e85734/command/down";
71
74
  const message = {devEui:"f1c0ae0e-b4a2-4547-b360-7cfa15e85734",confirmed:false,fPort:1,data:"AAA"};
72
75
  await this.mqttClient?.publish(topic,JSON.stringify(message));
@@ -136,6 +139,11 @@ class Lorawan extends utils.Adapter {
136
139
  */
137
140
  onUnload(callback) {
138
141
  try {
142
+ // clear timeout (for simulation)
143
+ if(this.simulation.timeout){
144
+ this.clearTimeout(this.simulation.timeout);
145
+ delete this.simulation.timeout;
146
+ }
139
147
  this.mqttClient?.destroy();
140
148
  callback();
141
149
  } catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.lorawan",
3
- "version": "0.6.6",
3
+ "version": "1.0.1",
4
4
  "description": "converts the desired lora gateway data to a ioBroker structure",
5
5
  "author": {
6
6
  "name": "BenAhrdt",