iobroker.lorawan 0.3.2 → 0.3.4
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 +27 -40
- package/lib/modules/directorieshandler.js +118 -108
- package/lib/modules/downlinkConfighandler.js +5 -5
- package/lib/modules/messagehandler.js +2 -2
- package/main.js +6 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,6 +22,12 @@ For now there is documentation in English here: http://www.hafenmeister.com/Lora
|
|
|
22
22
|
Placeholder for the next version (at the beginning of the line):
|
|
23
23
|
### **WORK IN PROGRESS**
|
|
24
24
|
-->
|
|
25
|
+
### 0.3.4 (2024-02-20)
|
|
26
|
+
* (BenAhrdt) put some debug and silly logging to code
|
|
27
|
+
|
|
28
|
+
### 0.3.3 (2024-02-19)
|
|
29
|
+
* (BenAhrdt) set infos into native
|
|
30
|
+
|
|
25
31
|
### 0.3.2 (2024-02-16)
|
|
26
32
|
* (BenAhrdt) wording recieved => received in messageing
|
|
27
33
|
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "lorawan",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.4",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.3.4": {
|
|
7
|
+
"en": "put some debug and silly logging to code",
|
|
8
|
+
"de": "debug und silly logging auf code setzen",
|
|
9
|
+
"ru": "положить некоторые отладки и глупые журналы для кодирования",
|
|
10
|
+
"pt": "colocar algum debug e log tonto para o código",
|
|
11
|
+
"nl": "zet wat debug en dom loggen op code",
|
|
12
|
+
"fr": "mettre un peu de débogage et stupide log pour coder",
|
|
13
|
+
"it": "mettere alcuni debug e stupido registrazione al codice",
|
|
14
|
+
"es": "poner un poco de depuración y registro tonto para el código",
|
|
15
|
+
"pl": "dodaj debug i głupie logowanie do kodu",
|
|
16
|
+
"uk": "покласти деякі debug і silly журналювання до коду",
|
|
17
|
+
"zh-cn": "把一些调试和愚蠢的日志输入代码"
|
|
18
|
+
},
|
|
19
|
+
"0.3.3": {
|
|
20
|
+
"en": "set infos into native",
|
|
21
|
+
"de": "informationen in die heimat",
|
|
22
|
+
"ru": "установить информацию на родной",
|
|
23
|
+
"pt": "definir informações em nativo",
|
|
24
|
+
"nl": "info's instellen in native",
|
|
25
|
+
"fr": "définir les infos dans native",
|
|
26
|
+
"it": "impostare le informazioni in nativo",
|
|
27
|
+
"es": "set infos into native",
|
|
28
|
+
"pl": "zestaw infos do rodzimej",
|
|
29
|
+
"uk": "встановити інформацію на рідні",
|
|
30
|
+
"zh-cn": "设置为本地信息"
|
|
31
|
+
},
|
|
6
32
|
"0.3.2": {
|
|
7
33
|
"en": "wording recieved => received in messageing",
|
|
8
34
|
"de": "zurückgegeben => in der mitteilung empfangen",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "większa funkcjonalność w zakresie rozwiązywania problemów",
|
|
68
94
|
"uk": "більше функцій в повідомленнях",
|
|
69
95
|
"zh-cn": "信件中更多的功能"
|
|
70
|
-
},
|
|
71
|
-
"0.1.13": {
|
|
72
|
-
"en": "building of directory changed and message implemented",
|
|
73
|
-
"de": "aufbau des geänderten verzeichnisses und der implementierten meldung",
|
|
74
|
-
"ru": "создание измененного каталога и реализовано сообщение",
|
|
75
|
-
"pt": "construção de diretório alterado e mensagem implementada",
|
|
76
|
-
"nl": "opbouw van map gewijzigd en bericht geïmplementeerd",
|
|
77
|
-
"fr": "la construction du répertoire modifié et le message mis en œuvre",
|
|
78
|
-
"it": "costruzione della directory modificata e messa in atto",
|
|
79
|
-
"es": "la construcción del directorio cambiado y el mensaje implementado",
|
|
80
|
-
"pl": "budowa zmienionych katalogów i wdrożona wiadomość",
|
|
81
|
-
"uk": "створення каталогу змінено та повідомлення",
|
|
82
|
-
"zh-cn": "更改目录构建并执行消息"
|
|
83
|
-
},
|
|
84
|
-
"0.1.12": {
|
|
85
|
-
"en": "default value crc config bug fixed",
|
|
86
|
-
"de": "standardwert crc config bug behoben",
|
|
87
|
-
"ru": "по умолчанию",
|
|
88
|
-
"pt": "valor padrão crc config bug corrigido",
|
|
89
|
-
"nl": "standaard waarde crc config bug vast",
|
|
90
|
-
"fr": "valeur par défaut crc config bug corrigé",
|
|
91
|
-
"it": "valore predefinito crc config bug fisso",
|
|
92
|
-
"es": "valor predeterminado crc config error fijo",
|
|
93
|
-
"pl": "wartość domyślna błąd konfiguracyjny crc",
|
|
94
|
-
"uk": "за замовчуванням значення crc config fix",
|
|
95
|
-
"zh-cn": "默认值 crc 配置错误已修正"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"title": "LoRaWAN",
|
|
@@ -195,19 +195,6 @@
|
|
|
195
195
|
"def": false
|
|
196
196
|
},
|
|
197
197
|
"native": {}
|
|
198
|
-
},
|
|
199
|
-
{
|
|
200
|
-
"_id": "info.logAvailableConfignames",
|
|
201
|
-
"type": "state",
|
|
202
|
-
"common": {
|
|
203
|
-
"role": "button",
|
|
204
|
-
"name": "logs the names of available device configurations",
|
|
205
|
-
"type": "boolean",
|
|
206
|
-
"read": true,
|
|
207
|
-
"write": true,
|
|
208
|
-
"def": false
|
|
209
|
-
},
|
|
210
|
-
"native": {}
|
|
211
198
|
}
|
|
212
199
|
]
|
|
213
200
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { isDeepStrictEqual } = require("util");
|
|
1
2
|
const fs = require("fs");
|
|
2
3
|
|
|
3
4
|
class directorieshandlerClass {
|
|
@@ -6,8 +7,9 @@ class directorieshandlerClass {
|
|
|
6
7
|
|
|
7
8
|
// used dataentries in directory structurt
|
|
8
9
|
this.searchableAttributeNames = {
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
applicationId: "applicationId",
|
|
11
|
+
applicationName: "applicationName",
|
|
12
|
+
deviceEUI: "deviceEui",
|
|
11
13
|
deviceId: "deviceId"
|
|
12
14
|
};
|
|
13
15
|
|
|
@@ -34,17 +36,26 @@ class directorieshandlerClass {
|
|
|
34
36
|
// declare the directory structre
|
|
35
37
|
this.directories = {
|
|
36
38
|
application:{
|
|
37
|
-
|
|
38
|
-
return
|
|
39
|
+
objectId : (topic,message) =>{
|
|
40
|
+
return this.getAttributValue(topic,message,this.searchableAttributeNames.applicationId);
|
|
41
|
+
},
|
|
42
|
+
objectCommonFromNative: {name:"applicationName"},
|
|
43
|
+
objectNative : (topic,message) =>{
|
|
44
|
+
return {
|
|
45
|
+
applicationName : this.getAttributValue(topic,message,this.searchableAttributeNames.applicationName)
|
|
46
|
+
};
|
|
39
47
|
},
|
|
40
|
-
objectCommonName: "application",
|
|
41
48
|
devices:{
|
|
42
49
|
deviceEUI:{
|
|
43
|
-
|
|
44
|
-
return
|
|
50
|
+
objectId : (topic,message) =>{
|
|
51
|
+
return this.getAttributValue(topic,message,this.searchableAttributeNames.deviceEUI);
|
|
45
52
|
},
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
objectCommonFromNative: {name:"deviceId"},
|
|
54
|
+
objectNative : (topic,message) =>{
|
|
55
|
+
return {
|
|
56
|
+
applicationName : this.getAttributValue(topic,message,this.searchableAttributeNames.applicationName),
|
|
57
|
+
deviceId : this.getAttributValue(topic,message,this.searchableAttributeNames.deviceId)
|
|
58
|
+
};
|
|
48
59
|
},
|
|
49
60
|
objectType: "device",
|
|
50
61
|
configuration:{
|
|
@@ -90,9 +101,11 @@ class directorieshandlerClass {
|
|
|
90
101
|
}
|
|
91
102
|
};
|
|
92
103
|
this.ignoredElementNames ={
|
|
93
|
-
|
|
104
|
+
objectId: "objectId",
|
|
94
105
|
objectCommonName: "objectCommonName",
|
|
95
|
-
|
|
106
|
+
objectCommonFromNative: "objectCommonFromNative",
|
|
107
|
+
objectType: "objectType",
|
|
108
|
+
objectNative : "objectNative"
|
|
96
109
|
};
|
|
97
110
|
}
|
|
98
111
|
|
|
@@ -131,38 +144,86 @@ class directorieshandlerClass {
|
|
|
131
144
|
if(!this.ignoredElementNames[elementName] && !options?.ignoredElementNames[elementName]){
|
|
132
145
|
// Check if the element is an object
|
|
133
146
|
if(typeof obj[elementName] === "object" && obj[elementName] && !obj[elementName].isState){
|
|
134
|
-
//
|
|
147
|
+
// Generate the desired id
|
|
135
148
|
let objectId = `${startDirectory}.${elementName}`;
|
|
136
149
|
let internalObjectId = elementName;
|
|
137
|
-
if(obj[elementName].
|
|
138
|
-
internalObjectId = `${
|
|
150
|
+
if(obj[elementName].objectId){
|
|
151
|
+
internalObjectId = `${obj[elementName].objectId(topic,message)}`;
|
|
139
152
|
objectId = `${startDirectory}.${internalObjectId}`;
|
|
140
153
|
}
|
|
141
154
|
if(objectId.indexOf(".") === 0){
|
|
142
155
|
objectId = objectId.substring(1,objectId.length);
|
|
143
156
|
}
|
|
144
|
-
let
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
common: {
|
|
150
|
-
name: objectCommonName
|
|
151
|
-
},
|
|
152
|
-
native : {},
|
|
153
|
-
});
|
|
157
|
+
let myObject = {};
|
|
158
|
+
// check object exists
|
|
159
|
+
if(await this.adapter.objectExists(objectId)){
|
|
160
|
+
this.adapter.log.silly(`get object ${objectId}`);
|
|
161
|
+
myObject = await this.adapter.getObjectAsync(objectId);
|
|
154
162
|
}
|
|
155
163
|
else{
|
|
156
|
-
|
|
157
|
-
|
|
164
|
+
this.adapter.log.silly(`object ${objectId} not exists`);
|
|
165
|
+
}
|
|
166
|
+
const myObjectBefore = structuredClone(myObject);
|
|
167
|
+
|
|
168
|
+
//Set type of object
|
|
169
|
+
if(!myObject.type){
|
|
170
|
+
myObject.type = obj[elementName].objectType? obj[elementName].objectType : "folder";
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
//check for common
|
|
174
|
+
if(!myObject.common){
|
|
175
|
+
myObject.common = {};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// check whether a common name was specified
|
|
179
|
+
if(obj[elementName].objectCommonName && typeof obj[elementName].objectCommonName === "function"){
|
|
180
|
+
if(typeof obj[elementName].objectCommonName === "function"){
|
|
181
|
+
myObject.common.name = obj[elementName].objectCommonName(topic,message);
|
|
182
|
+
}
|
|
183
|
+
else{
|
|
184
|
+
myObject.common.name = obj[elementName].objectCommonName;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Check wheter a native content was specified
|
|
189
|
+
if(!myObject.native){
|
|
190
|
+
myObject.native = {};
|
|
191
|
+
}
|
|
192
|
+
if(obj[elementName].objectNative){
|
|
193
|
+
const objectNative = obj[elementName].objectNative(topic,message);
|
|
194
|
+
for(const attribute in objectNative){
|
|
195
|
+
myObject.native[attribute] = objectNative[attribute];
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Assigne to common, if there are values specified
|
|
199
|
+
if(obj[elementName].objectCommonFromNative){
|
|
200
|
+
for(const attribute in obj[elementName].objectCommonFromNative){
|
|
201
|
+
// Check, whether the actual native is present
|
|
202
|
+
if(myObject.native[obj[elementName].objectCommonFromNative[attribute]]){
|
|
203
|
+
// check for old common => existing object
|
|
204
|
+
if(myObjectBefore.common){
|
|
205
|
+
//check for content
|
|
206
|
+
if(myObjectBefore.common[attribute] === myObjectBefore.native[obj[elementName].objectCommonFromNative[attribute]] ||
|
|
207
|
+
myObjectBefore.common[attribute] === ""){
|
|
208
|
+
this.adapter.log.silly(`set common attribut ${attribute} to ${myObject.native[obj[elementName].objectCommonFromNative[attribute]]}`);
|
|
209
|
+
myObject.common[attribute] = myObject.native[obj[elementName].objectCommonFromNative[attribute]];
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
else{
|
|
213
|
+
this.adapter.log.silly(`set common attribut ${attribute} to ${myObject.native[obj[elementName].objectCommonFromNative[attribute]]}`);
|
|
214
|
+
myObject.common[attribute] = myObject.native[obj[elementName].objectCommonFromNative[attribute]];
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
158
218
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
});
|
|
219
|
+
}
|
|
220
|
+
// Check for name
|
|
221
|
+
if(!myObject.common.name){
|
|
222
|
+
myObject.common.name = "";
|
|
223
|
+
}
|
|
224
|
+
if(!isDeepStrictEqual(myObject,myObjectBefore)){
|
|
225
|
+
this.adapter.log.debug(`set object ${objectId}`);
|
|
226
|
+
await this.adapter.setObject(objectId,myObject);
|
|
166
227
|
}
|
|
167
228
|
// Jump into next step (next directory / attribute)
|
|
168
229
|
await this.generateRekursivObjects(obj[elementName],objectId,topic,message);
|
|
@@ -183,8 +244,8 @@ class directorieshandlerClass {
|
|
|
183
244
|
stateCommonWrite = obj[elementName].stateCommonWrite ? obj[elementName].stateCommonWrite : stateCommonWrite;
|
|
184
245
|
stateCommonRole = obj[elementName].stateCommonRole ? obj[elementName].stateCommonRole : stateCommonRole;
|
|
185
246
|
}
|
|
186
|
-
if(obj[elementName].
|
|
187
|
-
internalObjectId = `${
|
|
247
|
+
if(obj[elementName].objectId){
|
|
248
|
+
internalObjectId = `${obj[elementName].objectId(topic,message)}`;
|
|
188
249
|
objectId = `${startDirectory}.${internalObjectId}`;
|
|
189
250
|
}
|
|
190
251
|
}
|
|
@@ -227,15 +288,15 @@ class directorieshandlerClass {
|
|
|
227
288
|
* ************************** Attribute ******************************
|
|
228
289
|
* ******************************************************************/
|
|
229
290
|
|
|
230
|
-
|
|
291
|
+
getAttributValue(topic,message,resolvetype){
|
|
231
292
|
const activeFunction = "getAttributValue";
|
|
232
293
|
try{
|
|
233
294
|
// Select search in case of origin
|
|
234
295
|
switch(this.adapter.config.origin){
|
|
235
296
|
case this.adapter.origin.ttn:
|
|
236
|
-
return
|
|
297
|
+
return this.getTtnAttributValue(topic,message,resolvetype);
|
|
237
298
|
case this.adapter.origin.chirpstack:
|
|
238
|
-
return
|
|
299
|
+
return this.getChirpstackAttributValue(topic,message,resolvetype);
|
|
239
300
|
}
|
|
240
301
|
}
|
|
241
302
|
catch(error){
|
|
@@ -244,19 +305,15 @@ class directorieshandlerClass {
|
|
|
244
305
|
}
|
|
245
306
|
|
|
246
307
|
/*********************************************************************
|
|
247
|
-
*
|
|
308
|
+
* ******************** Object Start Directory ***********************
|
|
248
309
|
* ******************************************************************/
|
|
249
310
|
|
|
250
|
-
|
|
251
|
-
const activeFunction = "
|
|
311
|
+
getDeviceStartDirectory(topic,message){
|
|
312
|
+
const activeFunction = "getDeviceStartDirectory";
|
|
252
313
|
try{
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
return await this.getTtnObjectDirectory(topic,message,resolvetype);
|
|
257
|
-
case this.adapter.origin.chirpstack:
|
|
258
|
-
return await this.getChirpstackObjectDirectory(topic,message,resolvetype);
|
|
259
|
-
}
|
|
314
|
+
const applicationId = `${this.getAttributValue(topic,message,this.searchableAttributeNames.applicationId)}`;
|
|
315
|
+
const deviceEUI = `${this.getAttributValue(topic,message,this.searchableAttributeNames.deviceEUI)}`;
|
|
316
|
+
return `${applicationId}.devices.${deviceEUI}`;
|
|
260
317
|
}
|
|
261
318
|
catch(error){
|
|
262
319
|
this.adapter.log.error(`error at ${activeFunction}: ${error} - - - Message: ${JSON.stringify(message)}`);
|
|
@@ -291,15 +348,18 @@ class directorieshandlerClass {
|
|
|
291
348
|
* ************************** Attribute ******************************
|
|
292
349
|
* ******************************************************************/
|
|
293
350
|
|
|
294
|
-
|
|
351
|
+
getTtnAttributValue(topic,message,resolvetype){
|
|
295
352
|
const activeFunction = "getTtnAttributValue";
|
|
296
353
|
try{
|
|
297
354
|
this.adapter.log.silly(`attribute ${resolvetype} is requested for ttn`);
|
|
298
355
|
const topicResolved = this.getTopicResolved(topic);
|
|
299
356
|
switch(resolvetype){
|
|
300
|
-
case this.searchableAttributeNames.
|
|
357
|
+
case this.searchableAttributeNames.applicationId:
|
|
301
358
|
return topicResolved?.applicationId;
|
|
302
359
|
|
|
360
|
+
case this.searchableAttributeNames.applicationName:
|
|
361
|
+
return topicResolved?.applicationName;
|
|
362
|
+
|
|
303
363
|
case this.searchableAttributeNames.deviceEUI:
|
|
304
364
|
return message.end_device_ids.dev_eui;
|
|
305
365
|
|
|
@@ -316,33 +376,6 @@ class directorieshandlerClass {
|
|
|
316
376
|
}
|
|
317
377
|
}
|
|
318
378
|
|
|
319
|
-
/*********************************************************************
|
|
320
|
-
* ************************ Object Directory *************************
|
|
321
|
-
* ******************************************************************/
|
|
322
|
-
|
|
323
|
-
async getTtnObjectDirectory(topic,message,resolvetype){
|
|
324
|
-
const activeFunction = "getTtnObjectDirectory";
|
|
325
|
-
try{
|
|
326
|
-
this.adapter.log.silly(`directory ${resolvetype} is requested for ttn`);
|
|
327
|
-
const topicResolved = this.getTopicResolved(topic);
|
|
328
|
-
if(typeof message !== "string"){
|
|
329
|
-
switch(resolvetype){
|
|
330
|
-
case this.searchableAttributeNames.deviceEUI:
|
|
331
|
-
return `${topicResolved?.applicationId}.devices.${message.end_device_ids.dev_eui}`;
|
|
332
|
-
|
|
333
|
-
default:
|
|
334
|
-
return message;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
else{
|
|
338
|
-
return message;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
catch(error){
|
|
342
|
-
this.adapter.log.error(`error at ${activeFunction}: ${error} - - - Message: ${JSON.stringify(message)}`);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
379
|
/*********************************************************************
|
|
347
380
|
* ************************ Object Directory *************************
|
|
348
381
|
* ******************************************************************/
|
|
@@ -352,6 +385,7 @@ class directorieshandlerClass {
|
|
|
352
385
|
try{
|
|
353
386
|
const topicElements = topic.split("/");
|
|
354
387
|
const topicResolved = {
|
|
388
|
+
applicationName: "",
|
|
355
389
|
applicationId: topicElements[1],
|
|
356
390
|
deviceId: topicElements[3],
|
|
357
391
|
messageType: topicElements[topicElements.length - 1]
|
|
@@ -359,6 +393,7 @@ class directorieshandlerClass {
|
|
|
359
393
|
// clean up application id
|
|
360
394
|
const indexOfOrigin = topicResolved.applicationId.indexOf("@");
|
|
361
395
|
if(indexOfOrigin !== -1){
|
|
396
|
+
topicResolved.applicationName = topicResolved.applicationId;
|
|
362
397
|
topicResolved.applicationId = topicResolved.applicationId.substring(0,indexOfOrigin);
|
|
363
398
|
}
|
|
364
399
|
return topicResolved;
|
|
@@ -379,15 +414,19 @@ class directorieshandlerClass {
|
|
|
379
414
|
* ******************************************************************/
|
|
380
415
|
|
|
381
416
|
|
|
382
|
-
|
|
417
|
+
// !!! Dont use resoletypes with message.deviceInfo in down => No deviceInfo in down message present
|
|
418
|
+
getChirpstackAttributValue(topic,message,resolvetype){
|
|
383
419
|
const activeFunction = "getChirpstackAttributValue";
|
|
384
420
|
try{
|
|
385
421
|
this.adapter.log.silly(`attribute ${resolvetype} is requested for chirpstack`);
|
|
386
422
|
const topicResolved = this.getTopicResolved(topic);
|
|
387
423
|
switch(resolvetype){
|
|
388
|
-
case this.searchableAttributeNames.
|
|
424
|
+
case this.searchableAttributeNames.applicationId:
|
|
389
425
|
return topicResolved?.applicationId;
|
|
390
426
|
|
|
427
|
+
case this.searchableAttributeNames.applicationName:
|
|
428
|
+
return message.deviceInfo.applicationName;
|
|
429
|
+
|
|
391
430
|
case this.searchableAttributeNames.deviceEUI:
|
|
392
431
|
return topicResolved?.deviceEUI;
|
|
393
432
|
|
|
@@ -404,35 +443,6 @@ class directorieshandlerClass {
|
|
|
404
443
|
}
|
|
405
444
|
}
|
|
406
445
|
|
|
407
|
-
/*********************************************************************
|
|
408
|
-
* ************************ Object Directory *************************
|
|
409
|
-
* ******************************************************************/
|
|
410
|
-
|
|
411
|
-
async getChirpstackObjectDirectory(topic,message,resolvetype){
|
|
412
|
-
const activeFunction = "getChirpstackObjectDirectory";
|
|
413
|
-
try{
|
|
414
|
-
this.adapter.log.silly(`directory ${resolvetype} is requested for chirpstack`);
|
|
415
|
-
const topicResolved = this.getTopicResolved(topic);
|
|
416
|
-
let devUid = undefined;
|
|
417
|
-
if(topicResolved?.messageType !== "down"){
|
|
418
|
-
devUid = message.deviceInfo.devEui;
|
|
419
|
-
}
|
|
420
|
-
else{
|
|
421
|
-
devUid = message.devEui;
|
|
422
|
-
}
|
|
423
|
-
switch(resolvetype){
|
|
424
|
-
case this.searchableAttributeNames.deviceEUI:
|
|
425
|
-
return `${topicResolved?.applicationId}.devices.${devUid}`;
|
|
426
|
-
|
|
427
|
-
default:
|
|
428
|
-
return message;
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
catch(error){
|
|
432
|
-
this.adapter.log.error(`error at ${activeFunction}: ${error} - - - Message: ${JSON.stringify(message)}`);
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
|
|
436
446
|
/*********************************************************************
|
|
437
447
|
* ************************ Resolved Topic ***************************
|
|
438
448
|
* ******************************************************************/
|
|
@@ -38,7 +38,7 @@ class downlinkConfighandlerClass {
|
|
|
38
38
|
// generate the Config without own objects
|
|
39
39
|
const ownConfig = [];
|
|
40
40
|
for(const downlinkConfig of Object.values(this.activeDownlinkConfigs)){
|
|
41
|
-
ownConfig.push(JSON.parse(JSON.stringify(downlinkConfig)));
|
|
41
|
+
ownConfig.push(structuredClone(downlinkConfig));//JSON.parse(JSON.stringify(downlinkConfig)));
|
|
42
42
|
delete ownConfig[ownConfig.length - 1].downlinkState;
|
|
43
43
|
}
|
|
44
44
|
// Add internal base downlinks
|
|
@@ -170,9 +170,9 @@ class downlinkConfighandlerClass {
|
|
|
170
170
|
// Select downlinktopic in case of origin
|
|
171
171
|
switch(this.adapter.config.origin){
|
|
172
172
|
case this.adapter.origin.ttn:
|
|
173
|
-
return this.
|
|
173
|
+
return this.getTtnDownlinkTopic(changeInfo,suffix);
|
|
174
174
|
case this.adapter.origin.chirpstack:
|
|
175
|
-
return this.
|
|
175
|
+
return this.getChirpstackDownlinkTopic(changeInfo,suffix);
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
|
|
@@ -303,7 +303,7 @@ class downlinkConfighandlerClass {
|
|
|
303
303
|
* *********************** Downlinktopic *****************************
|
|
304
304
|
* ******************************************************************/
|
|
305
305
|
|
|
306
|
-
|
|
306
|
+
getTtnDownlinkTopic(changeInfo,suffix){
|
|
307
307
|
this.adapter.log.silly(`the downlinktopic for ttn is requested`);
|
|
308
308
|
const topicElements = {
|
|
309
309
|
Version : "v3",
|
|
@@ -349,7 +349,7 @@ class downlinkConfighandlerClass {
|
|
|
349
349
|
* *********************** Downlinktopic *****************************
|
|
350
350
|
* ******************************************************************/
|
|
351
351
|
|
|
352
|
-
|
|
352
|
+
getChirpstackDownlinkTopic(changeInfo,suffix){
|
|
353
353
|
this.adapter.log.silly(`the downlinktopic for chirpstack is requested`);
|
|
354
354
|
const topicElements = {
|
|
355
355
|
Version : "application",
|
|
@@ -169,7 +169,7 @@ class messagehandlerClass {
|
|
|
169
169
|
const messageType = topic.substring(topic.lastIndexOf("/") + 1 ,topic.length);
|
|
170
170
|
this.adapter.log.silly(`the messagetype ${messageType} was determined`);
|
|
171
171
|
// generate startdirectory of device
|
|
172
|
-
const deviceStartdirectory =
|
|
172
|
+
const deviceStartdirectory = this.directoryhandler.getDeviceStartDirectory(topic,message);
|
|
173
173
|
this.adapter.log.silly(`the startdirectory ${deviceStartdirectory} was determined`);
|
|
174
174
|
|
|
175
175
|
/*********************************************************************
|
|
@@ -418,7 +418,7 @@ class messagehandlerClass {
|
|
|
418
418
|
const messageType = topic.substring(topic.lastIndexOf("/") + 1 ,topic.length);
|
|
419
419
|
this.adapter.log.silly(`the messagetype ${messageType} was determined`);
|
|
420
420
|
// generate startdirectory of device
|
|
421
|
-
const deviceStartdirectory =
|
|
421
|
+
const deviceStartdirectory = this.directoryhandler.getDeviceStartDirectory(topic,message);
|
|
422
422
|
this.adapter.log.silly(`the startdirectory ${deviceStartdirectory} was determined`);
|
|
423
423
|
|
|
424
424
|
/*********************************************************************
|
package/main.js
CHANGED
|
@@ -214,18 +214,6 @@ class Lorawan extends utils.Adapter {
|
|
|
214
214
|
}
|
|
215
215
|
this.setStateAsync(id,state.val,true);
|
|
216
216
|
}
|
|
217
|
-
// logging of the actual available configs
|
|
218
|
-
else if(id.indexOf(".logAvailableConfignames") !== -1){
|
|
219
|
-
this.log.info(`The following devicenames has an existing downlink-config`);
|
|
220
|
-
let index = 0;
|
|
221
|
-
for(const devicename in this.downlinkConfighandler?.activeDownlinkConfigs){
|
|
222
|
-
index++;
|
|
223
|
-
if(devicename !== this.downlinkConfighandler.internalDevices.baseDevice){
|
|
224
|
-
this.log.info(`Device ${index}: ${devicename}`);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
this.setStateAsync(id,state.val,true);
|
|
228
|
-
}
|
|
229
217
|
}
|
|
230
218
|
} else {
|
|
231
219
|
// The state was deleted
|
|
@@ -340,7 +328,8 @@ class Lorawan extends utils.Adapter {
|
|
|
340
328
|
// Get Obect from startdirectory
|
|
341
329
|
const startDirectoryObject = await this.getObjectAsync(changeInfo.objectStartDirectory);
|
|
342
330
|
if(startDirectoryObject){
|
|
343
|
-
changeInfo.
|
|
331
|
+
changeInfo.applicationName = startDirectoryObject.native.applicationName;
|
|
332
|
+
changeInfo.deviceId = startDirectoryObject.native.deviceId;
|
|
344
333
|
}
|
|
345
334
|
// Get deviceType
|
|
346
335
|
const deviceTypeIdState = await this.getStateAsync(myId);
|
|
@@ -407,7 +396,7 @@ class Lorawan extends utils.Adapter {
|
|
|
407
396
|
if(obj.message.deviceEUI){
|
|
408
397
|
const changeInfo = await this.getChangeInfoFromDeviceEUI(obj.message.deviceEUI,`${this.messagehandler?.directoryhandler.reachableSubfolders.configuration}.devicetype`);
|
|
409
398
|
if(changeInfo){
|
|
410
|
-
result = {applicationId: changeInfo.applicationId, deviceEUI: changeInfo.deviceEUI, deviceId: changeInfo.deviceId, deviceType: changeInfo.deviceType, received:obj.message};
|
|
399
|
+
result = {applicationId: changeInfo.applicationId, applicationName: changeInfo.applicationName, deviceEUI: changeInfo.deviceEUI, deviceId: changeInfo.deviceId, deviceType: changeInfo.deviceType, received:obj.message};
|
|
411
400
|
}
|
|
412
401
|
else{
|
|
413
402
|
result = {error:true, message:"No device found", received:obj.message};
|
|
@@ -428,7 +417,7 @@ class Lorawan extends utils.Adapter {
|
|
|
428
417
|
if(await this.objectExists(uplinkId)){
|
|
429
418
|
const stateResult = await this.getStateAsync(changeInfo.id);
|
|
430
419
|
if(stateResult){
|
|
431
|
-
result = {applicationId: changeInfo.applicationId, deviceEUI: changeInfo.deviceEUI, deviceId: changeInfo.deviceId, deviceType: changeInfo.deviceType, value: stateResult.val, received:obj.message};
|
|
420
|
+
result = {applicationId: changeInfo.applicationId, applicationName: changeInfo.applicationName, deviceEUI: changeInfo.deviceEUI, deviceId: changeInfo.deviceId, deviceType: changeInfo.deviceType, value: stateResult.val, received:obj.message};
|
|
432
421
|
}
|
|
433
422
|
}
|
|
434
423
|
else{
|
|
@@ -460,7 +449,7 @@ class Lorawan extends utils.Adapter {
|
|
|
460
449
|
// Check limit
|
|
461
450
|
if((!downlinkObject.common.min || obj.message.value >= downlinkObject.common.min) && (!downlinkObject.common.max || obj.message.value <= downlinkObject.common.max)){
|
|
462
451
|
await this.setStateAsync(downlinkId,obj.message.value);
|
|
463
|
-
result = {applicationId: changeInfo.applicationId, deviceEUI: changeInfo.deviceEUI, deviceId: changeInfo.deviceId, deviceType: changeInfo.deviceType, downlink: obj.message.downlink, value: obj.message.value, received:obj.message};
|
|
452
|
+
result = {applicationId: changeInfo.applicationId, applicationName: changeInfo.applicationName, deviceEUI: changeInfo.deviceEUI, deviceId: changeInfo.deviceId, deviceType: changeInfo.deviceType, downlink: obj.message.downlink, value: obj.message.value, received:obj.message};
|
|
464
453
|
}
|
|
465
454
|
else{
|
|
466
455
|
result = {error:true, message:"value is not in valid range", received:obj.message};
|
|
@@ -477,7 +466,7 @@ class Lorawan extends utils.Adapter {
|
|
|
477
466
|
}
|
|
478
467
|
else{
|
|
479
468
|
await this.setStateAsync(downlinkId,obj.message.value);
|
|
480
|
-
result = {applicationId: changeInfo.applicationId, deviceEUI: changeInfo.deviceEUI, deviceId: changeInfo.deviceId, deviceType: changeInfo.deviceType, downlink: obj.message.downlink, value: obj.message.value, received:obj.message};
|
|
469
|
+
result = {applicationId: changeInfo.applicationId, applicationName: changeInfo.applicationName, deviceEUI: changeInfo.deviceEUI, deviceId: changeInfo.deviceId, deviceType: changeInfo.deviceType, downlink: obj.message.downlink, value: obj.message.value, received:obj.message};
|
|
481
470
|
}
|
|
482
471
|
}
|
|
483
472
|
}
|