iobroker.lorawan 0.0.9 → 0.0.11

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
@@ -19,6 +19,12 @@ Adapter was created in collaboration with Joerg Froehner LoraWan@hafenmeister.co
19
19
  Placeholder for the next version (at the beginning of the line):
20
20
  ### **WORK IN PROGRESS**
21
21
  -->
22
+ ### 0.0.11 (2024-01-20)
23
+ * (BenAhrdt) toSend und lastSend added to folders
24
+
25
+ ### 0.0.10 (2024-01-19)
26
+ * (BenAhrdt) changes in length calculation
27
+
22
28
  ### 0.0.9 (2024-01-19)
23
29
  * (BenAhrdt) first version for beta
24
30
 
@@ -167,18 +167,14 @@
167
167
  "sm":2
168
168
  },
169
169
  {
170
- "type": "select",
170
+ "type": "number",
171
171
  "attr": "length",
172
172
  "label": "length",
173
173
  "tooltip": "lengthTooltip",
174
- "options": [
175
- {"label":"2","value":2},
176
- {"label":"4","value":4},
177
- {"label":"6","value":6},
178
- {"label":"8","value":8}
179
- ],
180
174
  "default": 8,
181
- "hidden": "data.type === 'boolean' || data.type === 'button'",
175
+ "min":2,
176
+ "max": 20,
177
+ "hidden": "data.type === 'boolean' || data.type === 'button' || data.type === 'string'",
182
178
  "sm":2
183
179
  },
184
180
  {
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "lorawan",
4
- "version": "0.0.9",
4
+ "version": "0.0.11",
5
5
  "news": {
6
+ "0.0.11": {
7
+ "en": "toSend und lastSend added to folders",
8
+ "de": "toSend und lastSend in Ordnern hinzugefügt",
9
+ "ru": "toSend und lastSend добавлен в папки",
10
+ "pt": "toSend und lastSend adicionado a pastas",
11
+ "nl": "toSend und lastSend toegevoegd aan mappen",
12
+ "fr": "toSend und lastSend ajouté aux dossiers",
13
+ "it": "toSend und lastSend aggiunto alle cartelle",
14
+ "es": "toSend und lastSend añadido a carpetas",
15
+ "pl": "toSend und lastSend dodany do folderów",
16
+ "uk": "toSend und lastSend додано до папок",
17
+ "zh-cn": "到文件夹中发送最后的发送"
18
+ },
19
+ "0.0.10": {
20
+ "en": "changes in length calculation",
21
+ "de": "änderungen der längenberechnung",
22
+ "ru": "изменения в расчете длины",
23
+ "pt": "alterações no cálculo de comprimento",
24
+ "nl": "wijzigingen in de lengteberekening",
25
+ "fr": "changements dans le calcul de la longueur",
26
+ "it": "variazioni del calcolo della lunghezza",
27
+ "es": "cambios en el cálculo de longitud",
28
+ "pl": "zmiany w obliczeniach długości",
29
+ "uk": "зміни розрахунку довжини",
30
+ "zh-cn": "长度计算的变化"
31
+ },
6
32
  "0.0.9": {
7
33
  "en": "first version for beta",
8
34
  "de": "erste version für beta",
@@ -67,32 +93,6 @@
67
93
  "pl": "usuń nieskonfigurowane stany przy starcie",
68
94
  "uk": "видалити не налаштовані стани при запуску",
69
95
  "zh-cn": "删除启动时未配置状态"
70
- },
71
- "0.0.4": {
72
- "en": "implements buttons and standard downlink control ind json (push / replace)",
73
- "de": "implementiert tasten und standard-downlink-steuerung ind json (push / ersetzen)",
74
- "ru": "реализует кнопки и стандартный нисходящий контрольный джсон (push / заменить)",
75
- "pt": "implementa botões e padrão downlink control ind json (push / substituir)",
76
- "nl": "implementeert knoppen en standaard downlink control ind json (push / replace)",
77
- "fr": "implémente boutons et standard de contrôle de liaison descendante json (pousser / remplacer)",
78
- "it": "implementa pulsanti e controllo standard downlink ind json (push / sostituire)",
79
- "es": "implementa botones y control de enlace estándar json (push / reemplazar)",
80
- "pl": "implementuje przyciski i standardową kontrolę łącza w dół ind json (push / replacement)",
81
- "uk": "реалізує кнопки та стандартний контроль за допомогою перемикача json (push / заміна)",
82
- "zh-cn": "执行按钮和标准下行链路控制 ind json(推/替换)"
83
- },
84
- "0.0.3": {
85
- "en": "first config for downlinks inputed",
86
- "de": "erste config für downlinks eingegeben",
87
- "ru": "первая настройка для входных ссылок",
88
- "pt": "primeiro config para downlinks inseridos",
89
- "nl": "eerste configuratie voor downlinks ingevoerd",
90
- "fr": "première configuration pour les liaisons descendantes entrée",
91
- "it": "prima configurazione per downlink in ingresso",
92
- "es": "primer config para downlinks",
93
- "pl": "pierwszy config dla downlinks nieznany",
94
- "uk": "перший конфігурація для вхідних посилань",
95
- "zh-cn": "输入下行链路的第一个配置"
96
96
  }
97
97
  },
98
98
  "title": "LoRaWAN",
@@ -1,6 +1,6 @@
1
1
  const uplinkClass = require("./uplinks/uplinks");
2
2
 
3
- class messagehandlerClass {
3
+ class directorieshandlerClass {
4
4
  constructor(adapter) {
5
5
  this.adapter = adapter;
6
6
 
@@ -19,9 +19,16 @@ class messagehandlerClass {
19
19
  downlinkRaw: "downlinkRaw",
20
20
  downlinkConfiguration: "downlinkConfiguration",
21
21
  downlinkControl: "downlinkControl",
22
+ downlinkToSend: "downlinkToSend",
23
+ downlinkLastSend: "downlinkLastSend",
22
24
  downlinkRemaining: "downlinkRemaining"
23
25
  };
24
26
 
27
+ this.directoryStructur = {
28
+ downlinkToSend: "downlink.toSend",
29
+ downlinkLastSend: "downlink.lastSend"
30
+ };
31
+
25
32
  this.reachableDirectories = {};
26
33
 
27
34
  this.uplinks = new uplinkClass();
@@ -50,7 +57,7 @@ class messagehandlerClass {
50
57
  devicetype:{
51
58
  isState: true,
52
59
  stateCommonType: "string",
53
- stateCommonWrite: true,
60
+ stateCommonWrite: true
54
61
  }
55
62
  },
56
63
  uplink:{
@@ -74,6 +81,16 @@ class messagehandlerClass {
74
81
  configuration:{
75
82
  safeDirectory: this.safeableDirectories.downlinkConfiguration,
76
83
  },
84
+ toSend:{
85
+ safeDirectory: this.safeableDirectories.downlinkToSend,
86
+ hex:{
87
+ isState: true,
88
+ stateCommonType: "string"
89
+ }
90
+ },
91
+ lastSend:{
92
+ safeDirectory: this.safeableDirectories.downlinkLastSend,
93
+ },
77
94
  remaining:{
78
95
  safeDirectory: this.safeableDirectories.downlinkRemaining
79
96
  }
@@ -224,7 +241,7 @@ class messagehandlerClass {
224
241
  * *********************** Topic resolved ****************************
225
242
  * ******************************************************************/
226
243
  getTopicResoled(topic){
227
- this.adapter.log.debug(`topic ${topic} is requested for resolveing`);
244
+ this.adapter.log.silly(`topic ${topic} is requested for resolveing`);
228
245
  const topicElements = topic.split("/");
229
246
  const topicResolved = {
230
247
  applicationId: topicElements[1],
@@ -248,7 +265,7 @@ class messagehandlerClass {
248
265
  * ******************************************************************/
249
266
 
250
267
  getTtnAttributValue(topic,message,resolvetype){
251
- this.adapter.log.debug(`attribute ${resolvetype} is requested for ttn`);
268
+ this.adapter.log.silly(`attribute ${resolvetype} is requested for ttn`);
252
269
  const topicResolved = this.getTopicResoled(topic);
253
270
  switch(resolvetype){
254
271
  case this.searchableAttributeNames.apllicationId:
@@ -271,7 +288,7 @@ class messagehandlerClass {
271
288
  * ******************************************************************/
272
289
 
273
290
  getTtnObjectDirectory(topic,message,resolvetype){
274
- this.adapter.log.debug(`directory ${resolvetype} is requested for ttn`);
291
+ this.adapter.log.silly(`directory ${resolvetype} is requested for ttn`);
275
292
  const topicResolved = this.getTopicResoled(topic);
276
293
  if(typeof message !== "string"){
277
294
  switch(resolvetype){
@@ -302,7 +319,7 @@ class messagehandlerClass {
302
319
 
303
320
 
304
321
  getChirpstackAttributValue(topic,message,resolvetype){
305
- this.adapter.log.debug(`attribute ${resolvetype} is requested for chirpstack`);
322
+ this.adapter.log.silly(`attribute ${resolvetype} is requested for chirpstack`);
306
323
  const topicResolved = this.getTopicResoled(topic);
307
324
  let devUid = undefined;
308
325
  switch(resolvetype){
@@ -333,7 +350,7 @@ class messagehandlerClass {
333
350
  * ******************************************************************/
334
351
 
335
352
  getChirpstackObjectDirectory(topic,message,resolvetype){
336
- this.adapter.log.debug(`directory ${resolvetype} is requested for chirpstack`);
353
+ this.adapter.log.silly(`directory ${resolvetype} is requested for chirpstack`);
337
354
  const topicResolved = this.getTopicResoled(topic);
338
355
  let devUid = undefined;
339
356
  if(topicResolved.messageType === "up"){
@@ -364,4 +381,4 @@ class messagehandlerClass {
364
381
  }
365
382
  }
366
383
 
367
- module.exports = messagehandlerClass;
384
+ module.exports = directorieshandlerClass;
@@ -3,7 +3,6 @@ const downlinkClass = require("./downlinks/downlinks");
3
3
  class downlinkConfighandlerClass {
4
4
  constructor(adapter) {
5
5
  this.adapter = adapter;
6
- //this.presentConfigs = {};
7
6
 
8
7
  this.downlinks = new downlinkClass(adapter);
9
8
  this.activeDownlinkConfigs = {};
@@ -15,7 +14,7 @@ class downlinkConfighandlerClass {
15
14
  * ******************************************************************/
16
15
 
17
16
  addAndMergeDownlinkConfigs(){
18
- this.adapter.log.debug(`the standard and configed downlinks will be merged`);
17
+ this.adapter.log.silly(`the standard and configed downlinks will be merged`);
19
18
  // @ts-ignore
20
19
  for(const downlinkConfig of Object.values(this.downlinks.internalDownlinks)){
21
20
  this.addDownlinkConfigByType(downlinkConfig);
@@ -36,7 +35,7 @@ class downlinkConfighandlerClass {
36
35
 
37
36
  getDownlinkConfig(changeInfo,options){
38
37
  const activeFunction = "getDownlinkConfig";
39
- this.adapter.log.debug(`the downlinkconfig is requested for the following changeinfo: ${JSON.stringify(changeInfo)}`);
38
+ this.adapter.log.silly(`the downlinkconfig is requested for the following changeinfo: ${JSON.stringify(changeInfo)}`);
40
39
  try{
41
40
  let downlinkConfig = undefined;
42
41
  for(const deviceType in this.activeDownlinkConfigs){
@@ -70,14 +69,14 @@ class downlinkConfighandlerClass {
70
69
  }
71
70
  }
72
71
 
73
- getDownlink(downlinkConfig,state,changeInfo){
72
+ async getDownlink(downlinkConfig,state,changeInfo){
74
73
  // Select downlink in case of origin
75
- this.adapter.log.debug(`the downlink for the changeinfo ${JSON.stringify(changeInfo)} is requested`);
74
+ this.adapter.log.silly(`the downlink for the changeinfo ${JSON.stringify(changeInfo)} is requested`);
76
75
  switch(this.adapter.config.origin){
77
76
  case "ttn":
78
- return this.getTtnDownlink(downlinkConfig,state);
77
+ return await this.getTtnDownlink(downlinkConfig,state,changeInfo);
79
78
  case "chirpstack":
80
- return this.getChirpstackDownlink(downlinkConfig,state,changeInfo);
79
+ return await this.getChirpstackDownlink(downlinkConfig,state,changeInfo);
81
80
  }
82
81
  }
83
82
 
@@ -85,9 +84,9 @@ class downlinkConfighandlerClass {
85
84
  * ******************* Calculation of payload ************************
86
85
  * ******************************************************************/
87
86
 
88
- calculatePayload(downlinkConfig,state){
87
+ async calculatePayload(downlinkConfig,state,changeInfo){
89
88
  // declare pyaload variable
90
- this.adapter.log.debug(`the payload will be calculated`);
89
+ this.adapter.log.silly(`the payload will be calculated`);
91
90
  let payloadInHex = "";
92
91
  let multipliedVal = 0;
93
92
  //Check type
@@ -103,6 +102,8 @@ class downlinkConfighandlerClass {
103
102
  }
104
103
  }
105
104
  else{
105
+ let numberOfDiggits = 0;
106
+ let zeroDiggits = "";
106
107
  switch(downlinkConfig.type){
107
108
  case "number":
108
109
  multipliedVal = state.val * downlinkConfig.multiplyfaktor;
@@ -110,23 +111,28 @@ class downlinkConfighandlerClass {
110
111
  break;
111
112
 
112
113
  case "ascii":
113
- case "string":
114
- payloadInHex = Buffer.from(state.val).toString("hex");
114
+ payloadInHex = Buffer.from(state.val).toString("hex").toUpperCase();
115
+ numberOfDiggits = downlinkConfig.length - downlinkConfig.front.length - downlinkConfig.end.length;
116
+ for(let index = 1; index <= numberOfDiggits; index++){
117
+ zeroDiggits += "0";
118
+ }
119
+ payloadInHex = (zeroDiggits + payloadInHex).slice(-numberOfDiggits);
120
+ payloadInHex = downlinkConfig.front + payloadInHex + downlinkConfig.end;
115
121
  break;
116
- }
117
- const numberOfDiggits = downlinkConfig.length - downlinkConfig.front.length + downlinkConfig.end.length;
118
- let zeroDiggits = "";
119
122
 
120
- for(let index = 1; index <= numberOfDiggits; index++){
121
- zeroDiggits += "0";
123
+ case "string":
124
+ payloadInHex = downlinkConfig.front + state.val + downlinkConfig.end;
125
+ payloadInHex = Buffer.from(payloadInHex).toString("hex").toUpperCase();
126
+ break;
122
127
  }
123
- payloadInHex = (zeroDiggits + payloadInHex).slice(-numberOfDiggits);
124
- payloadInHex = downlinkConfig.front + payloadInHex + downlinkConfig.end;
125
128
  }
126
129
 
130
+ //write hex into toSend state
131
+ const idFolder = `${changeInfo.obectStartDirectory}.${this.adapter.messagehandler.directoryhandler.directoryStructur.downlinkToSend}`;
132
+ await this.adapter.setStateAsync(`${idFolder}.hex`,payloadInHex,true);
133
+
127
134
  //convert hex in base64
128
135
  return Buffer.from(payloadInHex, "hex").toString("base64");
129
-
130
136
  }
131
137
 
132
138
  /*********************************************************************
@@ -152,7 +158,7 @@ class downlinkConfighandlerClass {
152
158
  * ******************************************************************/
153
159
 
154
160
  getTtnDownlinkTopicFromDirektory(changeInfo,suffix){
155
- this.adapter.log.debug(`the downlinktopic for ttn is requested`);
161
+ this.adapter.log.silly(`the downlinktopic for ttn is requested`);
156
162
  const topicElements = {
157
163
  Version : "v3",
158
164
  applicationId : `/${changeInfo.applicationId}`,
@@ -172,9 +178,9 @@ class downlinkConfighandlerClass {
172
178
  * ************************** Downlink ******************************
173
179
  * ******************************************************************/
174
180
 
175
- getTtnDownlink(downlinkConfig,state){
176
- this.adapter.log.debug(`the downlink for ttn is requested`);
177
- const payloadInBase64 = this.calculatePayload(downlinkConfig,state);
181
+ async getTtnDownlink(downlinkConfig,state,changeInfo){
182
+ this.adapter.log.silly(`the downlink for ttn is requested`);
183
+ const payloadInBase64 = await this.calculatePayload(downlinkConfig,state,changeInfo);
178
184
  // retun the whole downlink
179
185
  return {downlinks:[{f_port:downlinkConfig.port,frm_payload:payloadInBase64,priority:downlinkConfig.priority,confirmed:downlinkConfig.confirmed}]};
180
186
  }
@@ -191,7 +197,7 @@ class downlinkConfighandlerClass {
191
197
  * ******************************************************************/
192
198
 
193
199
  getChirpstackDownlinkTopicFromDirektory(changeInfo,suffix){
194
- this.adapter.log.debug(`the downlinktopic for chirpstack is requested`);
200
+ this.adapter.log.silly(`the downlinktopic for chirpstack is requested`);
195
201
  const topicElements = {
196
202
  Version : "application",
197
203
  applicationId : `/${changeInfo.applicationId}`,
@@ -211,9 +217,9 @@ class downlinkConfighandlerClass {
211
217
  * ************************** Downlink ******************************
212
218
  * ******************************************************************/
213
219
 
214
- getChirpstackDownlink(downlinkConfig,state,changeInfo){
215
- this.adapter.log.debug(`the downlink for chirpstack is requested`);
216
- const payloadInBase64 = this.calculatePayload(downlinkConfig,state);
220
+ async getChirpstackDownlink(downlinkConfig,state,changeInfo){
221
+ this.adapter.log.silly(`the downlink for chirpstack is requested`);
222
+ const payloadInBase64 = await this.calculatePayload(downlinkConfig,state,changeInfo);
217
223
  // retun the whole downlink
218
224
  return {devEui:changeInfo.dev_uid,confirmed:downlinkConfig.confirmed,fPort:downlinkConfig.port,data:payloadInBase64};
219
225
  }
@@ -29,6 +29,8 @@ class messagehandlerClass {
29
29
  if(adapterObject.type === "channel" && adapterObject.common.name !== "Information"){
30
30
  const stateId = this.adapter.removeNamespace(adapterObject._id);
31
31
  await this.fillWithDownlinkConfig(stateId);
32
+ await this.addDirectoriesToPresentDirectory(`${stateId}.${this.directoryhandler.directoryStructur.downlinkToSend}`);
33
+ await this.addDirectoriesToPresentDirectory(`${stateId}.${this.directoryhandler.directoryStructur.downlinkLastSend}`);
32
34
  }
33
35
  }
34
36
 
@@ -44,10 +46,14 @@ class messagehandlerClass {
44
46
  }
45
47
  }
46
48
 
49
+ async addDirectoriesToPresentDirectory(startDirectory){
50
+ this.directoryhandler.generateRekursivObjects(this.directoryhandler.directories.application.devices.deviceUid.deviceId.downlink.toSend,startDirectory,"","");
51
+ }
52
+
47
53
  async fillWithDownlinkConfig(deviceStartdirectory){
48
54
  for(const downlinkDevices of Object.values(this.adapter.downlinkConfighandler.activeDownlinkConfigs)){
49
55
  for(const downlinkConfig of Object.values(downlinkDevices)){
50
- this.adapter.log.debug(`the downlinkconfig ${JSON.stringify(downlinkConfig)}, will checked.`);
56
+ this.adapter.log.silly(`the downlinkconfig ${JSON.stringify(downlinkConfig)}, will checked.`);
51
57
  let startDirectory = "";
52
58
  if(!downlinkConfig.isConfiguration){
53
59
  startDirectory = `${deviceStartdirectory}.downlink.control`;
@@ -102,15 +108,17 @@ class messagehandlerClass {
102
108
 
103
109
  try{
104
110
  const messageType = topic.substring(topic.lastIndexOf("/") + 1 ,topic.length);
105
- this.adapter.log.debug(`the messagetype ${messageType} was determined`);
111
+ this.adapter.log.silly(`the messagetype ${messageType} was determined`);
106
112
  // generate startdirectory of device
107
113
  const deviceStartdirectory = this.directoryhandler.getObjectDirectory(topic,message,this.directoryhandler.searchableAttributeNames.deviceId);
108
- this.adapter.log.debug(`the startdirectory ${deviceStartdirectory} was determined`);
114
+ this.adapter.log.silly(`the startdirectory ${deviceStartdirectory} was determined`);
109
115
 
110
116
  /*********************************************************************
111
117
  * ************************ Main directories *************************
112
118
  * ******************************************************************/
113
119
 
120
+ await this.directoryhandler.generateRekursivObjects(this.directoryhandler.directories,"",topic,message);
121
+
114
122
  /*********************************************************************
115
123
  * ************************* Infodata ********************************
116
124
  * ******************************************************************/
@@ -122,16 +130,12 @@ class messagehandlerClass {
122
130
  // check for uplink message
123
131
  if(messageType === "up"){//if(message.uplink_message){
124
132
 
125
- // Generate new directories only with uplink
126
-
127
- await this.directoryhandler.generateRekursivObjects(this.directoryhandler.directories,"",topic,message);
128
-
129
133
  /*********************************************************************
130
134
  * ************************ Rawdata json *****************************
131
135
  * ******************************************************************/
132
136
 
133
137
  if(this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.uplinkRaw]){
134
- this.adapter.log.debug(`write rawdata`);
138
+ this.adapter.log.silly(`write rawdata`);
135
139
  const startDirectory = this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.uplinkRaw];
136
140
  // write json
137
141
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.json`,{
@@ -154,7 +158,7 @@ class messagehandlerClass {
154
158
  // check for frm payload
155
159
  if(message.uplink_message.frm_payload){
156
160
  // wite base64 data
157
- this.adapter.log.debug(`write base64`);
161
+ this.adapter.log.silly(`write base64`);
158
162
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.base64`,{
159
163
  type: "state",
160
164
  common: {
@@ -170,7 +174,7 @@ class messagehandlerClass {
170
174
  await this.adapter.setStateAsync(`${startDirectory}.base64`,writedata,true);
171
175
 
172
176
  // write base64 data in hex data
173
- this.adapter.log.debug(`write hex`);
177
+ this.adapter.log.silly(`write hex`);
174
178
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.hex`,{
175
179
  type: "state",
176
180
  common: {
@@ -186,7 +190,7 @@ class messagehandlerClass {
186
190
  await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
187
191
 
188
192
  // write base64 data in string data
189
- this.adapter.log.debug(`write string`);
193
+ this.adapter.log.silly(`write string`);
190
194
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
191
195
  type: "state",
192
196
  common: {
@@ -209,7 +213,7 @@ class messagehandlerClass {
209
213
 
210
214
  if(this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.uplinkDecoded]){
211
215
  const startDirectory = this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.uplinkDecoded];
212
- this.adapter.log.debug(`write decoded payload`);
216
+ this.adapter.log.silly(`write decoded payload`);
213
217
  await this.directoryhandler.generateRekursivObjects(message.uplink_message.decoded_payload,startDirectory,topic,message);
214
218
  }
215
219
 
@@ -219,7 +223,7 @@ class messagehandlerClass {
219
223
 
220
224
  if(this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.uplinkRemaining]){
221
225
  const startDirectory = this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.uplinkRemaining];
222
- this.adapter.log.debug(`write remaining uplink data`);
226
+ this.adapter.log.silly(`write remaining uplink data`);
223
227
  // @ts-ignore
224
228
  await this.directoryhandler.generateRekursivObjects(message.uplink_message,startDirectory,topic,message,{ignoredElementNames:{decoded_payload:{},frm_payload:{}}});
225
229
  }
@@ -240,7 +244,7 @@ class messagehandlerClass {
240
244
  if(this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.downlinkRaw]){
241
245
  const startDirectory = this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.downlinkRaw];
242
246
  // write json
243
- this.adapter.log.debug(`write rawdata`);
247
+ this.adapter.log.silly(`write rawdata`);
244
248
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.json`,{
245
249
  type: "state",
246
250
  common: {
@@ -259,7 +263,7 @@ class messagehandlerClass {
259
263
  * ******************************************************************/
260
264
 
261
265
  // check for frm payload
262
- this.adapter.log.debug(`write base64`);
266
+ this.adapter.log.silly(`write base64`);
263
267
  if(message[downlinkType].frm_payload){
264
268
  // wite base64 data
265
269
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.base64`,{
@@ -277,7 +281,7 @@ class messagehandlerClass {
277
281
  await this.adapter.setStateAsync(`${startDirectory}.base64`,writedata,true);
278
282
 
279
283
  // write base64 data in hex data
280
- this.adapter.log.debug(`write hex`);
284
+ this.adapter.log.silly(`write hex`);
281
285
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.hex`,{
282
286
  type: "state",
283
287
  common: {
@@ -293,7 +297,7 @@ class messagehandlerClass {
293
297
  await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
294
298
 
295
299
  // write base64 data in string data
296
- this.adapter.log.debug(`write string`);
300
+ this.adapter.log.silly(`write string`);
297
301
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
298
302
  type: "state",
299
303
  common: {
@@ -316,7 +320,7 @@ class messagehandlerClass {
316
320
 
317
321
  if(this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.downlinkRemaining]){
318
322
  const startDirectory = this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.downlinkRemaining];
319
- this.adapter.log.debug(`write remaining downlink data`);
323
+ this.adapter.log.silly(`write remaining downlink data`);
320
324
  // @ts-ignore
321
325
  await this.directoryhandler.generateRekursivObjects(message[downlinkType],startDirectory,topic,message,{ignoredElementNames:{frm_payload:{}}});
322
326
  }
@@ -325,7 +329,7 @@ class messagehandlerClass {
325
329
  /*********************************************************************
326
330
  * ********************** downlinkConfigs ****************************
327
331
  * ******************************************************************/
328
- this.adapter.log.debug(`check configed downlinks`);
332
+ this.adapter.log.silly(`check configed downlinks`);
329
333
  await this.fillWithDownlinkConfig(deviceStartdirectory);
330
334
  }
331
335
  catch(error){
@@ -352,15 +356,17 @@ class messagehandlerClass {
352
356
 
353
357
  try{
354
358
  const messageType = topic.substring(topic.lastIndexOf("/") + 1 ,topic.length);
355
- this.adapter.log.debug(`the messagetype ${messageType} was determined`);
359
+ this.adapter.log.silly(`the messagetype ${messageType} was determined`);
356
360
  // generate startdirectory of device
357
361
  const deviceStartdirectory = this.directoryhandler.getObjectDirectory(topic,message,this.directoryhandler.searchableAttributeNames.deviceId);
358
- this.adapter.log.debug(`the startdirectory ${deviceStartdirectory} was determined`);
362
+ this.adapter.log.silly(`the startdirectory ${deviceStartdirectory} was determined`);
359
363
 
360
364
  /*********************************************************************
361
365
  * ************************ Main directories *************************
362
366
  * ******************************************************************/
363
367
 
368
+ await this.directoryhandler.generateRekursivObjects(this.directoryhandler.directories,"",topic,message);
369
+
364
370
  /*********************************************************************
365
371
  * ************************* Infodata ********************************
366
372
  * ******************************************************************/
@@ -372,9 +378,6 @@ class messagehandlerClass {
372
378
  // check for uplink message
373
379
  if(messageType === "up"){//if(message.uplink_message){
374
380
 
375
- // generate new directories only with uplink
376
- await this.directoryhandler.generateRekursivObjects(this.directoryhandler.directories,"",topic,message);
377
-
378
381
  /*********************************************************************
379
382
  * ************************ Rawdata json *****************************
380
383
  * ******************************************************************/
@@ -382,7 +385,7 @@ class messagehandlerClass {
382
385
  if(this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.uplinkRaw]){
383
386
  const startDirectory = this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.uplinkRaw];
384
387
  // write json
385
- this.adapter.log.debug(`write rawdata`);
388
+ this.adapter.log.silly(`write rawdata`);
386
389
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.json`,{
387
390
  type: "state",
388
391
  common: {
@@ -403,7 +406,7 @@ class messagehandlerClass {
403
406
  // check for data
404
407
  if(message.data){
405
408
  // wite base64 data
406
- this.adapter.log.debug(`write base64`);
409
+ this.adapter.log.silly(`write base64`);
407
410
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.base64`,{
408
411
  type: "state",
409
412
  common: {
@@ -419,7 +422,7 @@ class messagehandlerClass {
419
422
  await this.adapter.setStateAsync(`${startDirectory}.base64`,writedata,true);
420
423
 
421
424
  // write base64 data in hex data
422
- this.adapter.log.debug(`write hex`);
425
+ this.adapter.log.silly(`write hex`);
423
426
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.hex`,{
424
427
  type: "state",
425
428
  common: {
@@ -435,7 +438,7 @@ class messagehandlerClass {
435
438
  await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
436
439
 
437
440
  // write base64 data in string data
438
- this.adapter.log.debug(`write string`);
441
+ this.adapter.log.silly(`write string`);
439
442
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
440
443
  type: "state",
441
444
  common: {
@@ -458,7 +461,7 @@ class messagehandlerClass {
458
461
 
459
462
  if(this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.uplinkDecoded]){
460
463
  const startDirectory = this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.uplinkDecoded];
461
- this.adapter.log.debug(`write decoded payload (Object)`);
464
+ this.adapter.log.silly(`write decoded payload (Object)`);
462
465
  await this.directoryhandler.generateRekursivObjects(message.object,startDirectory,topic,message);
463
466
  }
464
467
 
@@ -468,7 +471,7 @@ class messagehandlerClass {
468
471
 
469
472
  if(this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.uplinkRemaining]){
470
473
  const startDirectory = this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.uplinkRemaining];
471
- this.adapter.log.debug(`write remaining uplink data`);
474
+ this.adapter.log.silly(`write remaining uplink data`);
472
475
  // @ts-ignore
473
476
  await this.directoryhandler.generateRekursivObjects(message,startDirectory,topic,message,{ignoredElementNames:{deduplicationId:{},deviceInfo:{},data:{},object:{}}});
474
477
  }
@@ -488,7 +491,7 @@ class messagehandlerClass {
488
491
  if(this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.downlinkRaw]){
489
492
  const startDirectory = this.directoryhandler.reachableDirectories[deviceStartdirectory][this.directoryhandler.safeableDirectories.downlinkRaw];
490
493
  // write json
491
- this.adapter.log.debug(`write rawdata`);
494
+ this.adapter.log.silly(`write rawdata`);
492
495
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.json`,{
493
496
  type: "state",
494
497
  common: {
@@ -509,7 +512,7 @@ class messagehandlerClass {
509
512
  // check for data
510
513
  if(message.data){
511
514
  // wite base64 data
512
- this.adapter.log.debug(`write base64`);
515
+ this.adapter.log.silly(`write base64`);
513
516
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.base64`,{
514
517
  type: "state",
515
518
  common: {
@@ -525,7 +528,7 @@ class messagehandlerClass {
525
528
  await this.adapter.setStateAsync(`${startDirectory}.base64`,writedata,true);
526
529
 
527
530
  // write base64 data in hex data
528
- this.adapter.log.debug(`write hex`);
531
+ this.adapter.log.silly(`write hex`);
529
532
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.hex`,{
530
533
  type: "state",
531
534
  common: {
@@ -541,7 +544,7 @@ class messagehandlerClass {
541
544
  await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
542
545
 
543
546
  // write base64 data in string data
544
- this.adapter.log.debug(`write string`);
547
+ this.adapter.log.silly(`write string`);
545
548
  await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
546
549
  type: "state",
547
550
  common: {
@@ -567,7 +570,7 @@ class messagehandlerClass {
567
570
  /*********************************************************************
568
571
  * ********************** downlinkConfigs ****************************
569
572
  * ******************************************************************/
570
- this.adapter.log.debug(`check configed downlinks`);
573
+ this.adapter.log.silly(`check configed downlinks`);
571
574
  await this.fillWithDownlinkConfig(deviceStartdirectory);
572
575
  }
573
576
  catch(error){
package/main.js CHANGED
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+
2
3
  /*
3
4
  * Created with @iobroker/create-adapter v2.6.0
4
5
  */
@@ -54,7 +55,7 @@ class Lorawan extends utils.Adapter {
54
55
  this.log.debug(`the adapter start with the config: ${JSON.stringify(this.config)}.`);
55
56
  }
56
57
  catch(error){
57
- this.log.error(`error at ${activeFunction}: ` + error.stack);
58
+ this.log.error(`error at ${activeFunction}: ` + error);
58
59
  }
59
60
  }
60
61
 
@@ -97,34 +98,34 @@ class Lorawan extends utils.Adapter {
97
98
  const activeFunction = "onStateChange";
98
99
  try{
99
100
  if (state) {
100
- //this.log.debug(`state ${id} changed: val: ${state.val} - ack: ${state.ack}`);
101
+ //this.log.silly(`state ${id} changed: val: ${state.val} - ack: ${state.ack}`);
101
102
  // The state was changed => only states with ack = false will be processed, others will be ignored
102
103
  if(!state.ack){
103
104
  // Check for downlink in id
104
105
  if(id.indexOf("downlink") !== -1){
105
- this.log.debug(`the state ${id} has changed to ${state.val}.`);
106
+ this.log.silly(`the state ${id} has changed to ${state.val}.`);
106
107
  // get information of the changing state
107
108
  const changeInfo = await this.getChangeInfo(id);
108
109
  if(this.config.origin === "ttn"){
109
110
  let appending = "push";
110
111
  if(changeInfo?.changedState === "push"){
111
- const downlinkTopic = this.downlinkConfighandler?.getDownlinkTopic(changeInfo,`/down/${appending}`);
112
- this.sendDownlink(downlinkTopic,state.val);
112
+ const downlinkTopic = await this.downlinkConfighandler?.getDownlinkTopic(changeInfo,`/down/${appending}`);
113
+ await this.sendDownlink(downlinkTopic,state.val);
113
114
  this.setStateAsync(id,state.val,true);
114
115
  }
115
116
  else if(changeInfo?.changedState === "replace"){
116
117
  appending = "replace";
117
- const downlinkTopic = this.downlinkConfighandler?.getDownlinkTopic(changeInfo,`/down/${appending}`);
118
- this.sendDownlink(downlinkTopic,state.val);
118
+ const downlinkTopic = await this.downlinkConfighandler?.getDownlinkTopic(changeInfo,`/down/${appending}`);
119
+ await this.sendDownlink(downlinkTopic,state.val,changeInfo);
119
120
  this.setStateAsync(id,state.val,true);
120
121
  }
121
122
  else{
122
- const downlinkTopic = this.downlinkConfighandler?.getDownlinkTopic(changeInfo,`/down/${appending}`);
123
+ const downlinkTopic = await this.downlinkConfighandler?.getDownlinkTopic(changeInfo,`/down/${appending}`);
123
124
  const downlinkConfig = this.downlinkConfighandler?.getDownlinkConfig(changeInfo);
124
125
  if(downlinkConfig !== undefined){
125
- const downlink = this.downlinkConfighandler?.getDownlink(downlinkConfig,state,changeInfo);
126
+ const downlink = await this.downlinkConfighandler?.getDownlink(downlinkConfig,state,changeInfo);
126
127
  if(downlink !== undefined){
127
- this.sendDownlink(downlinkTopic,JSON.stringify(downlink));
128
+ await this.sendDownlink(downlinkTopic,JSON.stringify(downlink),changeInfo);
128
129
  }
129
130
  this.setStateAsync(id,state.val,true);
130
131
  }
@@ -132,17 +133,17 @@ class Lorawan extends utils.Adapter {
132
133
  }
133
134
  else if(this.config.origin === "chirpstack"){
134
135
  if(changeInfo?.changedState === "push"){
135
- const downlinkTopic = this.downlinkConfighandler?.getDownlinkTopic(changeInfo,`/down`);
136
- this.sendDownlink(downlinkTopic,state.val);
136
+ const downlinkTopic = await this.downlinkConfighandler?.getDownlinkTopic(changeInfo,`/down`);
137
+ await this.sendDownlink(downlinkTopic,state.val,changeInfo);
137
138
  this.setStateAsync(id,state.val,true);
138
139
  }
139
140
  else{
140
- const downlinkTopic = this.downlinkConfighandler?.getDownlinkTopic(changeInfo,`/down`);
141
- const downlinkConfig = this.downlinkConfighandler?.getDownlinkConfig(changeInfo);
141
+ const downlinkTopic = await this.downlinkConfighandler?.getDownlinkTopic(changeInfo,`/down`);
142
+ const downlinkConfig = await this.downlinkConfighandler?.getDownlinkConfig(changeInfo);
142
143
  if(downlinkConfig !== undefined){
143
- const downlink = this.downlinkConfighandler?.getDownlink(downlinkConfig,state,changeInfo);
144
+ const downlink = await this.downlinkConfighandler?.getDownlink(downlinkConfig,state,changeInfo);
144
145
  if(downlink !== undefined){
145
- this.sendDownlink(downlinkTopic,JSON.stringify(downlink));
146
+ await this.sendDownlink(downlinkTopic,JSON.stringify(downlink),changeInfo);
146
147
  }
147
148
  this.setStateAsync(id,state.val,true);
148
149
  }
@@ -164,22 +165,53 @@ class Lorawan extends utils.Adapter {
164
165
  }
165
166
  }
166
167
 
167
- sendDownlink(topic,message){
168
+ async sendDownlink(topic,message,changeInfo){
168
169
  this.mqttClient?.publish(topic,message);
170
+ const idFolderToSend = `${changeInfo.obectStartDirectory}.${this.messagehandler?.directoryhandler.directoryStructur.downlinkToSend}`;
171
+ const idFolderLastSend = `${changeInfo.obectStartDirectory}.${this.messagehandler?.directoryhandler.directoryStructur.downlinkLastSend}`;
172
+ const toSend = await this.getStateAsync(`${idFolderToSend}.hex`);
173
+ const lastSend = this.getHexpayloadFromDownlink(message);
174
+ await this.setStateAsync(`${idFolderLastSend}.hex`,lastSend,true);
175
+ if(toSend && lastSend === toSend?.val){
176
+ await this.setStateAsync(`${idFolderToSend}.hex`,0,true);
177
+ }
178
+ }
179
+
180
+ getHexpayloadFromDownlink(downlinkmessage){
181
+ let downlink = downlinkmessage;
182
+ if(typeof downlink === "string"){
183
+ downlink = JSON.parse(downlinkmessage);
184
+ }
185
+ else if(typeof downlink !== "object"){
186
+ return 0;
187
+ }
188
+ let payload = "";
189
+ switch(this.config.origin){
190
+ case "ttn":
191
+ payload = downlink.downlinks[0].frm_payload;
192
+ break;
193
+
194
+ case "chirpstack":
195
+ payload = downlink.data;
196
+ break;
197
+ }
198
+ return Buffer.from(payload, "base64").toString("hex").toUpperCase();
169
199
  }
170
200
 
171
201
  async getChangeInfo(id){
172
202
  const activeFunction = "getChangeInfo";
173
203
  try{
174
- this.log.debug(`changeinfo of id ${id}, will be generated.`);
204
+ this.log.silly(`changeinfo of id ${id}, will be generated.`);
175
205
  id = this.removeNamespace(id);
176
206
  const idElements = id.split(".");
177
207
  const changeInfo = {
208
+ id: id,
178
209
  applicationId : idElements[0],
179
210
  dev_uid : idElements[2],
180
211
  device_id : idElements[3],
181
212
  changedState : idElements[idElements.length - 1],
182
213
  deviceType : "",
214
+ obectStartDirectory : `${idElements[0]}.devices.${idElements[2]}.${idElements[3]}`,
183
215
  allElements : idElements
184
216
  };
185
217
  const myId = `${changeInfo.applicationId}.devices.${changeInfo.dev_uid}.${changeInfo.device_id}.configuration.devicetype`;
@@ -188,7 +220,7 @@ class Lorawan extends utils.Adapter {
188
220
  // @ts-ignore
189
221
  changeInfo.deviceType = deviceTypeIdState.val;
190
222
  }
191
- this.log.debug(`changeinfo is ${JSON.stringify(changeInfo)}.`);
223
+ this.log.silly(`changeinfo is ${JSON.stringify(changeInfo)}.`);
192
224
  return changeInfo;
193
225
  }
194
226
  catch(error){
@@ -198,7 +230,7 @@ class Lorawan extends utils.Adapter {
198
230
 
199
231
  removeNamespace(id){
200
232
  if(id.indexOf(this.namespace) !== -1){
201
- this.log.debug(`namespace will be removed from id ${id}.`);
233
+ this.log.silly(`namespace will be removed from id ${id}.`);
202
234
  id = id.substring(this.namespace.length + 1,id.length);
203
235
  }
204
236
  return id;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.lorawan",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "description": "converts the desired lora gateway data to a ioBroker structure",
5
5
  "author": {
6
6
  "name": "BenAhrdt",