iobroker.lorawan 0.0.12 → 0.0.13
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 +3 -0
- package/io-package.json +14 -14
- package/lib/modules/directorieshandler.js +180 -120
- package/lib/modules/downlinkConfighandler.js +6 -0
- package/lib/modules/messagehandler.js +260 -278
- package/main.js +19 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,6 +19,9 @@ 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.13 (2024-01-21)
|
|
23
|
+
* (BenAhrdt) change device id selecting in chirpstack out of directory (for downlink queued)
|
|
24
|
+
|
|
22
25
|
### 0.0.12 (2024-01-21)
|
|
23
26
|
* (BenAhrdt) change flow of downlink
|
|
24
27
|
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "lorawan",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.13",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.0.13": {
|
|
7
|
+
"en": "change device id selecting in chirpstack out of directory (for downlink queued)",
|
|
8
|
+
"de": "id auswahl in chirpstack aus verzeichnis (für downlink queued)",
|
|
9
|
+
"ru": "переменное устройство id выбора в кирпштак из каталога (для очерченной очертания обратной ссылки)",
|
|
10
|
+
"pt": "mudar o dispositivo id selecionando no chirpstack fora do diretório (para downlink queued)",
|
|
11
|
+
"nl": "apparaat-id wijzigen in chirpstack uit de map (voor downlink wachtrij)",
|
|
12
|
+
"fr": "modifier l'id de l'appareil en sélectionnant dans chirpstack hors du répertoire (pour la file d'attente en bas)",
|
|
13
|
+
"it": "cambiamento dispositivo id selezionando in chirpstack fuori directory (per downlink coda)",
|
|
14
|
+
"es": "cambiar dispositivo id seleccionando en chirpstack fuera del directorio (para downlink queued)",
|
|
15
|
+
"pl": "zmienić id urządzenia wybierając w chirpstock z katalogu (dla downlink kolejka)",
|
|
16
|
+
"uk": "змінити пристрій id виберіть в chirpstack з каталогу (для кривих посилань)",
|
|
17
|
+
"zh-cn": "更改设备 id 从目录中选择 chirpstack (用于下链条队列)"
|
|
18
|
+
},
|
|
6
19
|
"0.0.12": {
|
|
7
20
|
"en": "change flow of downlink",
|
|
8
21
|
"de": "wechselstrom von downlink",
|
|
@@ -80,19 +93,6 @@
|
|
|
80
93
|
"pl": "hex do górnej skrzyni, więcej jednostek dla dekodowanych wartości ładunku",
|
|
81
94
|
"uk": "hex до верхнього корпусу, більше одиниць для декодованих значень навантаження",
|
|
82
95
|
"zh-cn": "十六进制到大写, 更多解码有效载荷值的单位"
|
|
83
|
-
},
|
|
84
|
-
"0.0.6": {
|
|
85
|
-
"en": "insert whole translation for config and move some functions",
|
|
86
|
-
"de": "vollständige übersetzung einfügen und einige funktionen verschieben",
|
|
87
|
-
"ru": "включить полный перевод для настройки и переместить некоторые функции",
|
|
88
|
-
"pt": "inserir tradução inteira para config e mover algumas funções",
|
|
89
|
-
"nl": "gehele vertaling invoegen voor config en sommige functies verplaatsen",
|
|
90
|
-
"fr": "insérer la traduction complète pour la configuration et déplacer certaines fonctions",
|
|
91
|
-
"it": "inserire l'intera traduzione per configurare e spostare alcune funzioni",
|
|
92
|
-
"es": "insertar traducción completa para configuración y mover algunas funciones",
|
|
93
|
-
"pl": "wstaw całe tłumaczenie dla config i przesuń niektóre funkcje",
|
|
94
|
-
"uk": "вставити весь переклад для налаштування та переміщення деяких функцій",
|
|
95
|
-
"zh-cn": "插入配置的全部翻译并移动一些函数"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"title": "LoRaWAN",
|
|
@@ -11,6 +11,17 @@ class directorieshandlerClass {
|
|
|
11
11
|
deviceId: "deviceId"
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
+
this.reachableSubfolders = {
|
|
15
|
+
configuration: "configuration",
|
|
16
|
+
uplinkDecoded: "uplink.decoded",
|
|
17
|
+
uplinkRaw: "uplink.raw",
|
|
18
|
+
uplinkRemaining: "uplink.remaining",
|
|
19
|
+
downlinkRaw: "downlink.raw",
|
|
20
|
+
downlinkConfiguration: "downlink.configuration",
|
|
21
|
+
downlinkControl: "downlink.control",
|
|
22
|
+
downlinkRemaining: "downlink.remaining"
|
|
23
|
+
};
|
|
24
|
+
|
|
14
25
|
this.safeableDirectories = {
|
|
15
26
|
configuration: "configuration",
|
|
16
27
|
uplinkDecoded: "uplinkDecoded",
|
|
@@ -34,19 +45,19 @@ class directorieshandlerClass {
|
|
|
34
45
|
// declare the directory structre
|
|
35
46
|
this.directories = {
|
|
36
47
|
application:{
|
|
37
|
-
objectStateName : (topic,message) =>{
|
|
38
|
-
return this.getAttributValue(topic,message,this.searchableAttributeNames.apllicationId);
|
|
48
|
+
objectStateName : async (topic,message) =>{
|
|
49
|
+
return await this.getAttributValue(topic,message,this.searchableAttributeNames.apllicationId);
|
|
39
50
|
},
|
|
40
51
|
objectCommonName: "application",
|
|
41
52
|
devices:{
|
|
42
53
|
deviceUid:{
|
|
43
|
-
objectStateName : (topic,message) =>{
|
|
44
|
-
return this.getAttributValue(topic,message,this.searchableAttributeNames.deviceUid);
|
|
54
|
+
objectStateName : async (topic,message) =>{
|
|
55
|
+
return await this.getAttributValue(topic,message,this.searchableAttributeNames.deviceUid);
|
|
45
56
|
},
|
|
46
57
|
objectCommonName: "device UID",
|
|
47
58
|
deviceId:{
|
|
48
|
-
objectStateName : (topic,message) =>{
|
|
49
|
-
return this.getAttributValue(topic,message,this.searchableAttributeNames.deviceId);
|
|
59
|
+
objectStateName : async (topic,message) =>{
|
|
60
|
+
return await this.getAttributValue(topic,message,this.searchableAttributeNames.deviceId);
|
|
50
61
|
},
|
|
51
62
|
objectCommonName: "device ID",
|
|
52
63
|
objectType:"channel",
|
|
@@ -123,103 +134,113 @@ class directorieshandlerClass {
|
|
|
123
134
|
* ******************************************************************/
|
|
124
135
|
|
|
125
136
|
async generateRekursivObjects(obj,startDirectory,topic,message,options = undefined){
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
//
|
|
132
|
-
|
|
133
|
-
// Check
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
if(obj[elementName].safeDirectory){
|
|
146
|
-
if(!this.reachableDirectories){
|
|
147
|
-
this.reachableDirectories = {};
|
|
137
|
+
const activeFunction = "handleTtnMessage";
|
|
138
|
+
|
|
139
|
+
try{
|
|
140
|
+
// just proceed with ojects
|
|
141
|
+
if(typeof obj === "object"){
|
|
142
|
+
// go to every element in the object
|
|
143
|
+
for(const elementName in obj){
|
|
144
|
+
// Check the the elementname is not in ignored object
|
|
145
|
+
// @ts-ignore
|
|
146
|
+
if(!this.ignoredElementNames[elementName] && !options?.ignoredElementNames[elementName]){
|
|
147
|
+
// Check if the element is an object
|
|
148
|
+
if(typeof obj[elementName] === "object" && !(obj[elementName] && obj[elementName].isState)){
|
|
149
|
+
// if there is an declared ObjectStateName (must be a function)=> take it
|
|
150
|
+
let objectId = `${startDirectory}.${elementName}`;
|
|
151
|
+
let internalObjectId = elementName;
|
|
152
|
+
if(obj[elementName].objectStateName){
|
|
153
|
+
internalObjectId = `${await obj[elementName].objectStateName(topic,message)}`;
|
|
154
|
+
objectId = `${startDirectory}.${internalObjectId}`;
|
|
148
155
|
}
|
|
149
|
-
if(
|
|
150
|
-
|
|
156
|
+
if(objectId.indexOf(".") === 0){
|
|
157
|
+
objectId = objectId.substring(1,objectId.length);
|
|
151
158
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
stateVal = obj[elementName].stateVal !== undefined? obj[elementName].stateVal: undefined;
|
|
171
|
-
stateCommonType = obj[elementName].stateCommonType? obj[elementName].stateCommonType : typeof stateVal;
|
|
172
|
-
stateCommonName = obj[elementName].stateCommonName ? obj[elementName].stateCommonName : stateCommonName;
|
|
173
|
-
stateCommonWrite = obj[elementName].stateCommonWrite ? obj[elementName].stateCommonWrite : stateCommonWrite;
|
|
174
|
-
}
|
|
175
|
-
let objectId = `${startDirectory}.${elementName}`;
|
|
176
|
-
let internalObjectId = elementName;
|
|
177
|
-
if(obj[elementName].objectStateName){
|
|
178
|
-
internalObjectId = `${obj[elementName].objectStateName(topic,message)}`;
|
|
179
|
-
objectId = `${startDirectory}.${internalObjectId}`;
|
|
180
|
-
}
|
|
181
|
-
if(objectId.indexOf(".") === 0){
|
|
182
|
-
objectId.substring(1,objectId.length);
|
|
183
|
-
}
|
|
184
|
-
await this.adapter.setObjectNotExistsAsync(objectId,{
|
|
185
|
-
type: "state",
|
|
186
|
-
common: {
|
|
187
|
-
type: stateCommonType,
|
|
188
|
-
name: stateCommonName,
|
|
189
|
-
role: "value",
|
|
190
|
-
read: true,
|
|
191
|
-
unit: obj[elementName].CommonStateUnit? obj[elementName].CommonStateUnit : this.uplinks.units[internalObjectId]? this.uplinks.units[internalObjectId] : "",
|
|
192
|
-
def: stateCommonType === "boolean"? false : stateCommonType === "number"? 0: "",
|
|
193
|
-
write: stateCommonWrite
|
|
194
|
-
},
|
|
195
|
-
native: {},
|
|
196
|
-
});
|
|
197
|
-
if(typeof stateVal === "object"){
|
|
198
|
-
stateVal = JSON.stringify(stateVal);
|
|
199
|
-
}
|
|
200
|
-
if(stateVal !== undefined){
|
|
201
|
-
await this.adapter.setStateAsync(`${objectId}`,stateVal,true);
|
|
159
|
+
if(obj[elementName].safeDirectory){
|
|
160
|
+
if(!this.reachableDirectories){
|
|
161
|
+
this.reachableDirectories = {};
|
|
162
|
+
}
|
|
163
|
+
if(!this.reachableDirectories[this.getObjectDirectory(topic,message,this.searchableAttributeNames.deviceId)]){
|
|
164
|
+
this.reachableDirectories[this.getObjectDirectory(topic,message,this.searchableAttributeNames.deviceId)] = {};
|
|
165
|
+
}
|
|
166
|
+
this.reachableDirectories[this.getObjectDirectory(topic,message,this.searchableAttributeNames.deviceId)][obj[elementName].safeDirectory] = objectId;
|
|
167
|
+
}
|
|
168
|
+
await this.adapter.setObjectNotExistsAsync(objectId,{
|
|
169
|
+
// @ts-ignore
|
|
170
|
+
type: obj[elementName].objectType? obj[elementName].objectType : "folder",
|
|
171
|
+
common: {
|
|
172
|
+
name: obj[elementName].objectCommonName? obj[elementName].objectCommonName : ""
|
|
173
|
+
},
|
|
174
|
+
native : {},
|
|
175
|
+
});
|
|
176
|
+
await this.generateRekursivObjects(obj[elementName],objectId,topic,message);
|
|
202
177
|
}
|
|
203
|
-
|
|
204
|
-
|
|
178
|
+
else{
|
|
179
|
+
let stateCommonType = typeof obj[elementName];
|
|
180
|
+
let stateCommonName = "";
|
|
181
|
+
let stateCommonWrite = false;
|
|
182
|
+
let stateVal = obj[elementName];
|
|
183
|
+
let objectId = `${startDirectory}.${elementName}`;
|
|
184
|
+
let internalObjectId = elementName;
|
|
185
|
+
if(obj[elementName]){
|
|
186
|
+
if(obj[elementName].isState){
|
|
187
|
+
stateVal = obj[elementName].stateVal !== undefined? obj[elementName].stateVal: undefined;
|
|
188
|
+
stateCommonType = obj[elementName].stateCommonType? obj[elementName].stateCommonType : typeof stateVal;
|
|
189
|
+
stateCommonName = obj[elementName].stateCommonName ? obj[elementName].stateCommonName : stateCommonName;
|
|
190
|
+
stateCommonWrite = obj[elementName].stateCommonWrite ? obj[elementName].stateCommonWrite : stateCommonWrite;
|
|
191
|
+
}
|
|
192
|
+
if(obj[elementName].objectStateName){
|
|
193
|
+
internalObjectId = `${await obj[elementName].objectStateName(topic,message)}`;
|
|
194
|
+
objectId = `${startDirectory}.${internalObjectId}`;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if(objectId.indexOf(".") === 0){
|
|
198
|
+
objectId.substring(1,objectId.length);
|
|
199
|
+
}
|
|
200
|
+
await this.adapter.setObjectNotExistsAsync(objectId,{
|
|
201
|
+
type: "state",
|
|
202
|
+
common: {
|
|
203
|
+
type: stateCommonType!== "object"? stateCommonType: "mixed",
|
|
204
|
+
name: stateCommonName,
|
|
205
|
+
role: "value",
|
|
206
|
+
read: true,
|
|
207
|
+
unit: obj[elementName].CommonStateUnit? obj[elementName].CommonStateUnit : this.uplinks.units[internalObjectId]? this.uplinks.units[internalObjectId] : "",
|
|
208
|
+
def: stateCommonType === "boolean"? false : stateCommonType === "number"? 0: "",
|
|
209
|
+
write: stateCommonWrite
|
|
210
|
+
},
|
|
211
|
+
native: {},
|
|
212
|
+
});
|
|
213
|
+
if(typeof stateVal === "object"){
|
|
214
|
+
stateVal = JSON.stringify(stateVal);
|
|
215
|
+
}
|
|
216
|
+
if(stateVal !== undefined){
|
|
217
|
+
await this.adapter.setStateAsync(`${objectId}`,stateVal,true);
|
|
218
|
+
}
|
|
219
|
+
if(obj[elementName].subscribe){
|
|
220
|
+
this.adapter.subscribeStatesAsync(objectId);
|
|
221
|
+
}
|
|
205
222
|
}
|
|
206
223
|
}
|
|
207
224
|
}
|
|
208
225
|
}
|
|
209
226
|
}
|
|
227
|
+
catch(error){
|
|
228
|
+
this.adapter.log.error(`error at ${activeFunction}: ` + error);
|
|
229
|
+
this.adapter.log.warn("Message: " + JSON.stringify(message));
|
|
230
|
+
}
|
|
210
231
|
}
|
|
211
232
|
|
|
212
233
|
/*********************************************************************
|
|
213
234
|
* ************************** Attribute ******************************
|
|
214
235
|
* ******************************************************************/
|
|
215
236
|
|
|
216
|
-
getAttributValue(topic,message,resolvetype){
|
|
237
|
+
async getAttributValue(topic,message,resolvetype){
|
|
217
238
|
// Select search in case of origin
|
|
218
239
|
switch(this.adapter.config.origin){
|
|
219
240
|
case "ttn":
|
|
220
|
-
return this.getTtnAttributValue(topic,message,resolvetype);
|
|
241
|
+
return await this.getTtnAttributValue(topic,message,resolvetype);
|
|
221
242
|
case "chirpstack":
|
|
222
|
-
return this.getChirpstackAttributValue(topic,message,resolvetype);
|
|
243
|
+
return await this.getChirpstackAttributValue(topic,message,resolvetype);
|
|
223
244
|
}
|
|
224
245
|
}
|
|
225
246
|
|
|
@@ -240,20 +261,15 @@ class directorieshandlerClass {
|
|
|
240
261
|
/*********************************************************************
|
|
241
262
|
* *********************** Topic resolved ****************************
|
|
242
263
|
* ******************************************************************/
|
|
243
|
-
|
|
264
|
+
getTopicResolved(topic){
|
|
244
265
|
this.adapter.log.silly(`topic ${topic} is requested for resolveing`);
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
// clean up application id
|
|
252
|
-
const indexOfOrigin = topicResolved.applicationId.indexOf("@");
|
|
253
|
-
if(indexOfOrigin !== -1){
|
|
254
|
-
topicResolved.applicationId = topicResolved.applicationId.substring(0,indexOfOrigin);
|
|
266
|
+
// Select in case of origin
|
|
267
|
+
switch(this.adapter.config.origin){
|
|
268
|
+
case "ttn":
|
|
269
|
+
return this.getTtnTopicResolved(topic);
|
|
270
|
+
case "chirpstack":
|
|
271
|
+
return this.getChirpstackTopicResolved(topic);
|
|
255
272
|
}
|
|
256
|
-
return topicResolved;
|
|
257
273
|
}
|
|
258
274
|
|
|
259
275
|
/*********************************************************************
|
|
@@ -264,18 +280,18 @@ class directorieshandlerClass {
|
|
|
264
280
|
* ************************** Attribute ******************************
|
|
265
281
|
* ******************************************************************/
|
|
266
282
|
|
|
267
|
-
getTtnAttributValue(topic,message,resolvetype){
|
|
283
|
+
async getTtnAttributValue(topic,message,resolvetype){
|
|
268
284
|
this.adapter.log.silly(`attribute ${resolvetype} is requested for ttn`);
|
|
269
|
-
const topicResolved = this.
|
|
285
|
+
const topicResolved = this.getTopicResolved(topic);
|
|
270
286
|
switch(resolvetype){
|
|
271
287
|
case this.searchableAttributeNames.apllicationId:
|
|
272
|
-
return topicResolved
|
|
288
|
+
return topicResolved?.applicationId;
|
|
273
289
|
|
|
274
290
|
case this.searchableAttributeNames.deviceUid:
|
|
275
291
|
return message.end_device_ids.dev_eui;
|
|
276
292
|
|
|
277
293
|
case this.searchableAttributeNames.deviceId:
|
|
278
|
-
return topicResolved
|
|
294
|
+
return topicResolved?.deviceId;
|
|
279
295
|
|
|
280
296
|
default:
|
|
281
297
|
this.adapter.log.warn(`No attribute with the name ${resolvetype} found.`);
|
|
@@ -289,11 +305,11 @@ class directorieshandlerClass {
|
|
|
289
305
|
|
|
290
306
|
getTtnObjectDirectory(topic,message,resolvetype){
|
|
291
307
|
this.adapter.log.silly(`directory ${resolvetype} is requested for ttn`);
|
|
292
|
-
const topicResolved = this.
|
|
308
|
+
const topicResolved = this.getTopicResolved(topic);
|
|
293
309
|
if(typeof message !== "string"){
|
|
294
310
|
switch(resolvetype){
|
|
295
311
|
case this.searchableAttributeNames.deviceId:
|
|
296
|
-
return `${topicResolved
|
|
312
|
+
return `${topicResolved?.applicationId}.devices.${message.end_device_ids.dev_eui}.${topicResolved?.deviceId}`;
|
|
297
313
|
|
|
298
314
|
default:
|
|
299
315
|
return message;
|
|
@@ -304,8 +320,24 @@ class directorieshandlerClass {
|
|
|
304
320
|
}
|
|
305
321
|
}
|
|
306
322
|
|
|
323
|
+
/*********************************************************************
|
|
324
|
+
* ************************ Object Directory *************************
|
|
325
|
+
* ******************************************************************/
|
|
307
326
|
|
|
308
|
-
|
|
327
|
+
getTtnTopicResolved(topic){
|
|
328
|
+
const topicElements = topic.split("/");
|
|
329
|
+
const topicResolved = {
|
|
330
|
+
applicationId: topicElements[1],
|
|
331
|
+
deviceId: topicElements[3],
|
|
332
|
+
messageType: topicElements[topicElements.length - 1]
|
|
333
|
+
};
|
|
334
|
+
// clean up application id
|
|
335
|
+
const indexOfOrigin = topicResolved.applicationId.indexOf("@");
|
|
336
|
+
if(indexOfOrigin !== -1){
|
|
337
|
+
topicResolved.applicationId = topicResolved.applicationId.substring(0,indexOfOrigin);
|
|
338
|
+
}
|
|
339
|
+
return topicResolved;
|
|
340
|
+
}
|
|
309
341
|
|
|
310
342
|
|
|
311
343
|
|
|
@@ -318,26 +350,35 @@ class directorieshandlerClass {
|
|
|
318
350
|
* ******************************************************************/
|
|
319
351
|
|
|
320
352
|
|
|
321
|
-
getChirpstackAttributValue(topic,message,resolvetype){
|
|
353
|
+
async getChirpstackAttributValue(topic,message,resolvetype){
|
|
322
354
|
this.adapter.log.silly(`attribute ${resolvetype} is requested for chirpstack`);
|
|
323
|
-
const topicResolved = this.
|
|
324
|
-
let
|
|
355
|
+
const topicResolved = this.getTopicResolved(topic);
|
|
356
|
+
let devId = undefined;
|
|
325
357
|
switch(resolvetype){
|
|
326
358
|
case this.searchableAttributeNames.apllicationId:
|
|
327
|
-
return topicResolved
|
|
359
|
+
return topicResolved?.applicationId;
|
|
328
360
|
|
|
329
361
|
case this.searchableAttributeNames.deviceUid:
|
|
330
|
-
|
|
331
|
-
|
|
362
|
+
return topicResolved?.devUid;
|
|
363
|
+
|
|
364
|
+
case this.searchableAttributeNames.deviceId:
|
|
365
|
+
if(topicResolved?.messageType === "up"){
|
|
366
|
+
devId = message.deviceInfo.deviceName;
|
|
332
367
|
}
|
|
333
|
-
else if(topicResolved
|
|
368
|
+
else if(topicResolved?.messageType === "down")
|
|
334
369
|
{
|
|
335
|
-
|
|
370
|
+
const adapterObjectsAtStart = await this.adapter.getAdapterObjectsAsync();
|
|
371
|
+
for(const adapterObject of Object.values(adapterObjectsAtStart)){
|
|
372
|
+
if(adapterObject.type === "channel" && adapterObject.common.name !== "Information"){
|
|
373
|
+
const baseDeviceInfo = this.adapter.getBaseDeviceInfo(`${adapterObject._id}.deviceInfo`);
|
|
374
|
+
if(baseDeviceInfo.obectStartDirectory === adapterObject._id){
|
|
375
|
+
devId = baseDeviceInfo.obectStartDirectory;
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
336
380
|
}
|
|
337
|
-
return
|
|
338
|
-
|
|
339
|
-
case this.searchableAttributeNames.deviceId:
|
|
340
|
-
return topicResolved.deviceId;
|
|
381
|
+
return devId;
|
|
341
382
|
|
|
342
383
|
default:
|
|
343
384
|
this.adapter.log.warn(`No attribute with the name ${resolvetype} found.`);
|
|
@@ -351,12 +392,12 @@ class directorieshandlerClass {
|
|
|
351
392
|
|
|
352
393
|
getChirpstackObjectDirectory(topic,message,resolvetype){
|
|
353
394
|
this.adapter.log.silly(`directory ${resolvetype} is requested for chirpstack`);
|
|
354
|
-
const topicResolved = this.
|
|
395
|
+
const topicResolved = this.getTopicResolved(topic);
|
|
355
396
|
let devUid = undefined;
|
|
356
|
-
if(topicResolved
|
|
397
|
+
if(topicResolved?.messageType === "up"){
|
|
357
398
|
devUid = message.deviceInfo.devEui;
|
|
358
399
|
}
|
|
359
|
-
else if(topicResolved
|
|
400
|
+
else if(topicResolved?.messageType === "down")
|
|
360
401
|
{
|
|
361
402
|
devUid = message.devEui;
|
|
362
403
|
}
|
|
@@ -364,7 +405,7 @@ class directorieshandlerClass {
|
|
|
364
405
|
if(typeof message !== "string"){
|
|
365
406
|
switch(resolvetype){
|
|
366
407
|
case this.searchableAttributeNames.deviceId:
|
|
367
|
-
return `${topicResolved
|
|
408
|
+
return `${topicResolved?.applicationId}.devices.${devUid}.${topicResolved?.deviceId}`;
|
|
368
409
|
|
|
369
410
|
default:
|
|
370
411
|
return message;
|
|
@@ -379,6 +420,25 @@ class directorieshandlerClass {
|
|
|
379
420
|
this.adapter.log.warn(`message: ${message}`);
|
|
380
421
|
}
|
|
381
422
|
}
|
|
423
|
+
|
|
424
|
+
/*********************************************************************
|
|
425
|
+
* ************************ Object Directory *************************
|
|
426
|
+
* ******************************************************************/
|
|
427
|
+
|
|
428
|
+
getChirpstackTopicResolved(topic){
|
|
429
|
+
const topicElements = topic.split("/");
|
|
430
|
+
const topicResolved = {
|
|
431
|
+
applicationId: topicElements[1],
|
|
432
|
+
deviceUid: topicElements[3],
|
|
433
|
+
messageType: topicElements[topicElements.length - 1]
|
|
434
|
+
};
|
|
435
|
+
// clean up application id
|
|
436
|
+
const indexOfOrigin = topicResolved.applicationId.indexOf("@");
|
|
437
|
+
if(indexOfOrigin !== -1){
|
|
438
|
+
topicResolved.applicationId = topicResolved.applicationId.substring(0,indexOfOrigin);
|
|
439
|
+
}
|
|
440
|
+
return topicResolved;
|
|
441
|
+
}
|
|
382
442
|
}
|
|
383
443
|
|
|
384
444
|
module.exports = directorieshandlerClass;
|
|
@@ -126,6 +126,12 @@ class downlinkConfighandlerClass {
|
|
|
126
126
|
case "number":
|
|
127
127
|
multipliedVal = state.val * downlinkConfig.multiplyfaktor;
|
|
128
128
|
payloadInHex = multipliedVal.toString(16).toUpperCase();
|
|
129
|
+
numberOfDiggits = downlinkConfig.length - downlinkConfig.front.length - downlinkConfig.end.length;
|
|
130
|
+
for(let index = 1; index <= numberOfDiggits; index++){
|
|
131
|
+
zeroDiggits += "0";
|
|
132
|
+
}
|
|
133
|
+
payloadInHex = (zeroDiggits + payloadInHex).slice(-numberOfDiggits);
|
|
134
|
+
payloadInHex = downlinkConfig.front + payloadInHex + downlinkConfig.end;
|
|
129
135
|
break;
|
|
130
136
|
|
|
131
137
|
case "ascii":
|
|
@@ -140,99 +140,93 @@ class messagehandlerClass {
|
|
|
140
140
|
* ************************ Rawdata json *****************************
|
|
141
141
|
* ******************************************************************/
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
143
|
+
this.adapter.log.silly(`write rawdata`);
|
|
144
|
+
let startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRaw}`;
|
|
145
|
+
// write json
|
|
146
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.json`,{
|
|
147
|
+
type: "state",
|
|
148
|
+
common: {
|
|
149
|
+
name: "last recieved message",
|
|
150
|
+
type: "json",
|
|
151
|
+
role: "value",
|
|
152
|
+
read: true,
|
|
153
|
+
write: false
|
|
154
|
+
},
|
|
155
|
+
native: {},
|
|
156
|
+
});
|
|
157
|
+
await this.adapter.setStateAsync(`${startDirectory}.json`,JSON.stringify(message),true);
|
|
158
|
+
|
|
159
|
+
/*********************************************************************
|
|
160
|
+
* ********************** Rawdata (Base64) ***************************
|
|
161
|
+
* ******************************************************************/
|
|
162
|
+
|
|
163
|
+
// check for frm payload
|
|
164
|
+
if(message.uplink_message.frm_payload){
|
|
165
|
+
// wite base64 data
|
|
166
|
+
this.adapter.log.silly(`write base64`);
|
|
167
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.base64`,{
|
|
148
168
|
type: "state",
|
|
149
169
|
common: {
|
|
150
|
-
name: "last recieved
|
|
151
|
-
type: "
|
|
170
|
+
name: "last recieved data as base64",
|
|
171
|
+
type: "string",
|
|
152
172
|
role: "value",
|
|
153
173
|
read: true,
|
|
154
174
|
write: false
|
|
155
175
|
},
|
|
156
176
|
native: {},
|
|
157
177
|
});
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
},
|
|
193
|
-
native: {},
|
|
194
|
-
});
|
|
195
|
-
const hexdata = Buffer.from(message.uplink_message.frm_payload, "base64").toString("hex").toUpperCase();
|
|
196
|
-
await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
|
|
197
|
-
|
|
198
|
-
// write base64 data in string data
|
|
199
|
-
this.adapter.log.silly(`write string`);
|
|
200
|
-
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
|
|
201
|
-
type: "state",
|
|
202
|
-
common: {
|
|
203
|
-
name: "last recieved data as string",
|
|
204
|
-
type: "string",
|
|
205
|
-
role: "value",
|
|
206
|
-
read: true,
|
|
207
|
-
write: false
|
|
208
|
-
},
|
|
209
|
-
native: {},
|
|
210
|
-
});
|
|
211
|
-
const stringdata = Buffer.from(message.uplink_message.frm_payload, "base64").toString();
|
|
212
|
-
await this.adapter.setStateAsync(`${startDirectory}.string`,stringdata,true);
|
|
213
|
-
}
|
|
178
|
+
const writedata = message.uplink_message.frm_payload;
|
|
179
|
+
await this.adapter.setStateAsync(`${startDirectory}.base64`,writedata,true);
|
|
180
|
+
|
|
181
|
+
// write base64 data in hex data
|
|
182
|
+
this.adapter.log.silly(`write hex`);
|
|
183
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.hex`,{
|
|
184
|
+
type: "state",
|
|
185
|
+
common: {
|
|
186
|
+
name: "last recieved data as hex",
|
|
187
|
+
type: "string",
|
|
188
|
+
role: "value",
|
|
189
|
+
read: true,
|
|
190
|
+
write: false
|
|
191
|
+
},
|
|
192
|
+
native: {},
|
|
193
|
+
});
|
|
194
|
+
const hexdata = Buffer.from(message.uplink_message.frm_payload, "base64").toString("hex").toUpperCase();
|
|
195
|
+
await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
|
|
196
|
+
|
|
197
|
+
// write base64 data in string data
|
|
198
|
+
this.adapter.log.silly(`write string`);
|
|
199
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
|
|
200
|
+
type: "state",
|
|
201
|
+
common: {
|
|
202
|
+
name: "last recieved data as string",
|
|
203
|
+
type: "string",
|
|
204
|
+
role: "value",
|
|
205
|
+
read: true,
|
|
206
|
+
write: false
|
|
207
|
+
},
|
|
208
|
+
native: {},
|
|
209
|
+
});
|
|
210
|
+
const stringdata = Buffer.from(message.uplink_message.frm_payload, "base64").toString();
|
|
211
|
+
await this.adapter.setStateAsync(`${startDirectory}.string`,stringdata,true);
|
|
214
212
|
}
|
|
215
213
|
|
|
216
214
|
/*********************************************************************
|
|
217
215
|
* ********************** decoded payload ****************************
|
|
218
216
|
* ******************************************************************/
|
|
219
217
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
await this.directoryhandler.generateRekursivObjects(message.uplink_message.decoded_payload,startDirectory,topic,message);
|
|
224
|
-
}
|
|
218
|
+
startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkDecoded}`;
|
|
219
|
+
this.adapter.log.silly(`write decoded payload`);
|
|
220
|
+
await this.directoryhandler.generateRekursivObjects(message.uplink_message.decoded_payload,startDirectory,topic,message);
|
|
225
221
|
|
|
226
222
|
/*********************************************************************
|
|
227
223
|
* ************************* remaining *******************************
|
|
228
224
|
* ******************************************************************/
|
|
229
225
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
await this.directoryhandler.generateRekursivObjects(message.uplink_message,startDirectory,topic,message,{ignoredElementNames:{decoded_payload:{},frm_payload:{}}});
|
|
235
|
-
}
|
|
226
|
+
startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRemaining}`;
|
|
227
|
+
this.adapter.log.silly(`write remaining uplink data`);
|
|
228
|
+
// @ts-ignore
|
|
229
|
+
await this.directoryhandler.generateRekursivObjects(message.uplink_message,startDirectory,topic,message,{ignoredElementNames:{decoded_payload:{},frm_payload:{}}});
|
|
236
230
|
}
|
|
237
231
|
|
|
238
232
|
/*********************************************************************
|
|
@@ -247,89 +241,85 @@ class messagehandlerClass {
|
|
|
247
241
|
* ************************ Rawdata json *****************************
|
|
248
242
|
* ******************************************************************/
|
|
249
243
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
244
|
+
let startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.downlinkRaw}`;
|
|
245
|
+
// write json
|
|
246
|
+
this.adapter.log.silly(`write rawdata`);
|
|
247
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.json`,{
|
|
248
|
+
type: "state",
|
|
249
|
+
common: {
|
|
250
|
+
name: "last recieved message",
|
|
251
|
+
type: "json",
|
|
252
|
+
role: "value",
|
|
253
|
+
read: true,
|
|
254
|
+
write: false
|
|
255
|
+
},
|
|
256
|
+
native: {},
|
|
257
|
+
});
|
|
258
|
+
await this.adapter.setStateAsync(`${startDirectory}.json`,JSON.stringify(message),true);
|
|
259
|
+
|
|
260
|
+
/*********************************************************************
|
|
261
|
+
* ********************** Rawdata (Base64) ***************************
|
|
262
|
+
* ******************************************************************/
|
|
263
|
+
|
|
264
|
+
// check for frm payload
|
|
265
|
+
this.adapter.log.silly(`write base64`);
|
|
266
|
+
if(message[downlinkType].frm_payload){
|
|
267
|
+
// wite base64 data
|
|
268
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.base64`,{
|
|
255
269
|
type: "state",
|
|
256
270
|
common: {
|
|
257
|
-
name: "last recieved
|
|
258
|
-
type: "
|
|
271
|
+
name: "last recieved data as base64",
|
|
272
|
+
type: "string",
|
|
259
273
|
role: "value",
|
|
260
274
|
read: true,
|
|
261
275
|
write: false
|
|
262
276
|
},
|
|
263
277
|
native: {},
|
|
264
278
|
});
|
|
265
|
-
|
|
279
|
+
const writedata = message[downlinkType].frm_payload;
|
|
280
|
+
await this.adapter.setStateAsync(`${startDirectory}.base64`,writedata,true);
|
|
266
281
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
282
|
+
// write base64 data in hex data
|
|
283
|
+
this.adapter.log.silly(`write hex`);
|
|
284
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.hex`,{
|
|
285
|
+
type: "state",
|
|
286
|
+
common: {
|
|
287
|
+
name: "last recieved data as hex",
|
|
288
|
+
type: "string",
|
|
289
|
+
role: "value",
|
|
290
|
+
read: true,
|
|
291
|
+
write: false
|
|
292
|
+
},
|
|
293
|
+
native: {},
|
|
294
|
+
});
|
|
295
|
+
const hexdata = Buffer.from(message[downlinkType].frm_payload,"base64").toString("hex").toUpperCase();
|
|
296
|
+
await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
|
|
270
297
|
|
|
271
|
-
//
|
|
272
|
-
this.adapter.log.silly(`write
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
const writedata = message[downlinkType].frm_payload;
|
|
287
|
-
await this.adapter.setStateAsync(`${startDirectory}.base64`,writedata,true);
|
|
288
|
-
|
|
289
|
-
// write base64 data in hex data
|
|
290
|
-
this.adapter.log.silly(`write hex`);
|
|
291
|
-
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.hex`,{
|
|
292
|
-
type: "state",
|
|
293
|
-
common: {
|
|
294
|
-
name: "last recieved data as hex",
|
|
295
|
-
type: "string",
|
|
296
|
-
role: "value",
|
|
297
|
-
read: true,
|
|
298
|
-
write: false
|
|
299
|
-
},
|
|
300
|
-
native: {},
|
|
301
|
-
});
|
|
302
|
-
const hexdata = Buffer.from(message[downlinkType].frm_payload,"base64").toString("hex").toUpperCase();
|
|
303
|
-
await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
|
|
304
|
-
|
|
305
|
-
// write base64 data in string data
|
|
306
|
-
this.adapter.log.silly(`write string`);
|
|
307
|
-
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
|
|
308
|
-
type: "state",
|
|
309
|
-
common: {
|
|
310
|
-
name: "last recieved data as string",
|
|
311
|
-
type: "string",
|
|
312
|
-
role: "value",
|
|
313
|
-
read: true,
|
|
314
|
-
write: false
|
|
315
|
-
},
|
|
316
|
-
native: {},
|
|
317
|
-
});
|
|
318
|
-
const stringdata = Buffer.from(message[downlinkType].frm_payload,"base64").toString();
|
|
319
|
-
await this.adapter.setStateAsync(`${startDirectory}.string`,stringdata,true);
|
|
320
|
-
}
|
|
298
|
+
// write base64 data in string data
|
|
299
|
+
this.adapter.log.silly(`write string`);
|
|
300
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
|
|
301
|
+
type: "state",
|
|
302
|
+
common: {
|
|
303
|
+
name: "last recieved data as string",
|
|
304
|
+
type: "string",
|
|
305
|
+
role: "value",
|
|
306
|
+
read: true,
|
|
307
|
+
write: false
|
|
308
|
+
},
|
|
309
|
+
native: {},
|
|
310
|
+
});
|
|
311
|
+
const stringdata = Buffer.from(message[downlinkType].frm_payload,"base64").toString();
|
|
312
|
+
await this.adapter.setStateAsync(`${startDirectory}.string`,stringdata,true);
|
|
321
313
|
}
|
|
322
314
|
|
|
323
315
|
/*********************************************************************
|
|
324
316
|
* ************************* remaining *******************************
|
|
325
317
|
* ******************************************************************/
|
|
326
318
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
await this.directoryhandler.generateRekursivObjects(message[downlinkType],startDirectory,topic,message,{ignoredElementNames:{frm_payload:{}}});
|
|
332
|
-
}
|
|
319
|
+
startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.downlinkRemaining}`;
|
|
320
|
+
this.adapter.log.silly(`write remaining downlink data`);
|
|
321
|
+
// @ts-ignore
|
|
322
|
+
await this.directoryhandler.generateRekursivObjects(message[downlinkType],startDirectory,topic,message,{ignoredElementNames:{frm_payload:{}}});
|
|
333
323
|
}
|
|
334
324
|
|
|
335
325
|
/*********************************************************************
|
|
@@ -388,99 +378,93 @@ class messagehandlerClass {
|
|
|
388
378
|
* ************************ Rawdata json *****************************
|
|
389
379
|
* ******************************************************************/
|
|
390
380
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
381
|
+
let startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRaw}`;
|
|
382
|
+
// write json
|
|
383
|
+
this.adapter.log.silly(`write rawdata`);
|
|
384
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.json`,{
|
|
385
|
+
type: "state",
|
|
386
|
+
common: {
|
|
387
|
+
name: "last recieved message",
|
|
388
|
+
type: "json",
|
|
389
|
+
role: "value",
|
|
390
|
+
read: true,
|
|
391
|
+
write: false
|
|
392
|
+
},
|
|
393
|
+
native: {},
|
|
394
|
+
});
|
|
395
|
+
await this.adapter.setStateAsync(`${startDirectory}.json`,JSON.stringify(message),true);
|
|
396
|
+
|
|
397
|
+
/*********************************************************************
|
|
398
|
+
* ********************** Rawdata (Base64) ***************************
|
|
399
|
+
* ******************************************************************/
|
|
400
|
+
|
|
401
|
+
// check for data
|
|
402
|
+
if(message.data){
|
|
403
|
+
// wite base64 data
|
|
404
|
+
this.adapter.log.silly(`write base64`);
|
|
405
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.base64`,{
|
|
396
406
|
type: "state",
|
|
397
407
|
common: {
|
|
398
|
-
name: "last recieved
|
|
399
|
-
type: "
|
|
408
|
+
name: "last recieved data as base64",
|
|
409
|
+
type: "string",
|
|
400
410
|
role: "value",
|
|
401
411
|
read: true,
|
|
402
412
|
write: false
|
|
403
413
|
},
|
|
404
414
|
native: {},
|
|
405
415
|
});
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
},
|
|
441
|
-
native: {},
|
|
442
|
-
});
|
|
443
|
-
const hexdata = Buffer.from(message.data, "base64").toString("hex").toUpperCase();
|
|
444
|
-
await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
|
|
445
|
-
|
|
446
|
-
// write base64 data in string data
|
|
447
|
-
this.adapter.log.silly(`write string`);
|
|
448
|
-
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
|
|
449
|
-
type: "state",
|
|
450
|
-
common: {
|
|
451
|
-
name: "last recieved data as string",
|
|
452
|
-
type: "string",
|
|
453
|
-
role: "value",
|
|
454
|
-
read: true,
|
|
455
|
-
write: false
|
|
456
|
-
},
|
|
457
|
-
native: {},
|
|
458
|
-
});
|
|
459
|
-
const stringdata = Buffer.from(message.data, "base64").toString();
|
|
460
|
-
await this.adapter.setStateAsync(`${startDirectory}.string`,stringdata,true);
|
|
461
|
-
}
|
|
416
|
+
const writedata = message.data;
|
|
417
|
+
await this.adapter.setStateAsync(`${startDirectory}.base64`,writedata,true);
|
|
418
|
+
|
|
419
|
+
// write base64 data in hex data
|
|
420
|
+
this.adapter.log.silly(`write hex`);
|
|
421
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.hex`,{
|
|
422
|
+
type: "state",
|
|
423
|
+
common: {
|
|
424
|
+
name: "last recieved data as hex",
|
|
425
|
+
type: "string",
|
|
426
|
+
role: "value",
|
|
427
|
+
read: true,
|
|
428
|
+
write: false
|
|
429
|
+
},
|
|
430
|
+
native: {},
|
|
431
|
+
});
|
|
432
|
+
const hexdata = Buffer.from(message.data, "base64").toString("hex").toUpperCase();
|
|
433
|
+
await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
|
|
434
|
+
|
|
435
|
+
// write base64 data in string data
|
|
436
|
+
this.adapter.log.silly(`write string`);
|
|
437
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
|
|
438
|
+
type: "state",
|
|
439
|
+
common: {
|
|
440
|
+
name: "last recieved data as string",
|
|
441
|
+
type: "string",
|
|
442
|
+
role: "value",
|
|
443
|
+
read: true,
|
|
444
|
+
write: false
|
|
445
|
+
},
|
|
446
|
+
native: {},
|
|
447
|
+
});
|
|
448
|
+
const stringdata = Buffer.from(message.data, "base64").toString();
|
|
449
|
+
await this.adapter.setStateAsync(`${startDirectory}.string`,stringdata,true);
|
|
462
450
|
}
|
|
463
451
|
|
|
464
452
|
/*********************************************************************
|
|
465
453
|
* ****************** decoded payload (Object) ***********************
|
|
466
454
|
* ******************************************************************/
|
|
467
455
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
await this.directoryhandler.generateRekursivObjects(message.object,startDirectory,topic,message);
|
|
472
|
-
}
|
|
456
|
+
startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkDecoded}`;
|
|
457
|
+
this.adapter.log.silly(`write decoded payload (Object)`);
|
|
458
|
+
await this.directoryhandler.generateRekursivObjects(message.object,startDirectory,topic,message);
|
|
473
459
|
|
|
474
460
|
/*********************************************************************
|
|
475
461
|
* ************************* remaining *******************************
|
|
476
462
|
* ******************************************************************/
|
|
477
463
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
await this.directoryhandler.generateRekursivObjects(message,startDirectory,topic,message,{ignoredElementNames:{deduplicationId:{},deviceInfo:{},data:{},object:{}}});
|
|
483
|
-
}
|
|
464
|
+
startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRemaining}`;
|
|
465
|
+
this.adapter.log.silly(`write remaining uplink data`);
|
|
466
|
+
// @ts-ignore
|
|
467
|
+
await this.directoryhandler.generateRekursivObjects(message,startDirectory,topic,message,{ignoredElementNames:{deduplicationId:{},deviceInfo:{},data:{},object:{}}});
|
|
484
468
|
}
|
|
485
469
|
|
|
486
470
|
/*********************************************************************
|
|
@@ -494,77 +478,75 @@ class messagehandlerClass {
|
|
|
494
478
|
* ************************ Rawdata json *****************************
|
|
495
479
|
* ******************************************************************/
|
|
496
480
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
481
|
+
const startDirectory = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.downlinkRaw}`;
|
|
482
|
+
// write json
|
|
483
|
+
this.adapter.log.silly(`write rawdata`);
|
|
484
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.json`,{
|
|
485
|
+
type: "state",
|
|
486
|
+
common: {
|
|
487
|
+
name: "last recieved message",
|
|
488
|
+
type: "json",
|
|
489
|
+
role: "value",
|
|
490
|
+
read: true,
|
|
491
|
+
write: false
|
|
492
|
+
},
|
|
493
|
+
native: {},
|
|
494
|
+
});
|
|
495
|
+
await this.adapter.setStateAsync(`${startDirectory}.json`,JSON.stringify(message),true);
|
|
496
|
+
|
|
497
|
+
/*********************************************************************
|
|
498
|
+
* ********************** Rawdata (Base64) ***************************
|
|
499
|
+
* ******************************************************************/
|
|
500
|
+
|
|
501
|
+
// check for data
|
|
502
|
+
if(message.data){
|
|
503
|
+
// wite base64 data
|
|
504
|
+
this.adapter.log.silly(`write base64`);
|
|
505
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.base64`,{
|
|
502
506
|
type: "state",
|
|
503
507
|
common: {
|
|
504
|
-
name: "last recieved
|
|
505
|
-
type: "
|
|
508
|
+
name: "last recieved data as base64",
|
|
509
|
+
type: "string",
|
|
506
510
|
role: "value",
|
|
507
511
|
read: true,
|
|
508
512
|
write: false
|
|
509
513
|
},
|
|
510
514
|
native: {},
|
|
511
515
|
});
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
},
|
|
547
|
-
native: {},
|
|
548
|
-
});
|
|
549
|
-
const hexdata = Buffer.from(message.data,"base64").toString("hex").toUpperCase();
|
|
550
|
-
await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
|
|
551
|
-
|
|
552
|
-
// write base64 data in string data
|
|
553
|
-
this.adapter.log.silly(`write string`);
|
|
554
|
-
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
|
|
555
|
-
type: "state",
|
|
556
|
-
common: {
|
|
557
|
-
name: "last recieved data as string",
|
|
558
|
-
type: "string",
|
|
559
|
-
role: "value",
|
|
560
|
-
read: true,
|
|
561
|
-
write: false
|
|
562
|
-
},
|
|
563
|
-
native: {},
|
|
564
|
-
});
|
|
565
|
-
const stringdata = Buffer.from(message.data,"base64").toString();
|
|
566
|
-
await this.adapter.setStateAsync(`${startDirectory}.string`,stringdata,true);
|
|
567
|
-
}
|
|
516
|
+
const writedata = message.data;
|
|
517
|
+
await this.adapter.setStateAsync(`${startDirectory}.base64`,writedata,true);
|
|
518
|
+
|
|
519
|
+
// write base64 data in hex data
|
|
520
|
+
this.adapter.log.silly(`write hex`);
|
|
521
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.hex`,{
|
|
522
|
+
type: "state",
|
|
523
|
+
common: {
|
|
524
|
+
name: "last recieved data as hex",
|
|
525
|
+
type: "string",
|
|
526
|
+
role: "value",
|
|
527
|
+
read: true,
|
|
528
|
+
write: false
|
|
529
|
+
},
|
|
530
|
+
native: {},
|
|
531
|
+
});
|
|
532
|
+
const hexdata = Buffer.from(message.data,"base64").toString("hex").toUpperCase();
|
|
533
|
+
await this.adapter.setStateAsync(`${startDirectory}.hex`,hexdata,true);
|
|
534
|
+
|
|
535
|
+
// write base64 data in string data
|
|
536
|
+
this.adapter.log.silly(`write string`);
|
|
537
|
+
await this.adapter.setObjectNotExistsAsync(`${startDirectory}.string`,{
|
|
538
|
+
type: "state",
|
|
539
|
+
common: {
|
|
540
|
+
name: "last recieved data as string",
|
|
541
|
+
type: "string",
|
|
542
|
+
role: "value",
|
|
543
|
+
read: true,
|
|
544
|
+
write: false
|
|
545
|
+
},
|
|
546
|
+
native: {},
|
|
547
|
+
});
|
|
548
|
+
const stringdata = Buffer.from(message.data,"base64").toString();
|
|
549
|
+
await this.adapter.setStateAsync(`${startDirectory}.string`,stringdata,true);
|
|
568
550
|
}
|
|
569
551
|
|
|
570
552
|
/*********************************************************************
|
package/main.js
CHANGED
|
@@ -169,13 +169,14 @@ class Lorawan extends utils.Adapter {
|
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
async
|
|
172
|
+
async checkSendDownlinkWithUplink(id){
|
|
173
173
|
const changeInfo = await this.getChangeInfo(id);
|
|
174
|
-
this.log.
|
|
174
|
+
this.log.silly(JSON.stringify(changeInfo));
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
async writeNextSend(startDirectory,payloadInHex){
|
|
178
178
|
const idFolder = `${startDirectory}.${this.messagehandler?.directoryhandler.directoryStructur.downlinkNextSend}`;
|
|
179
|
+
this.log.warn(payloadInHex);
|
|
179
180
|
await this.setStateAsync(`${idFolder}.hex`,payloadInHex,true);
|
|
180
181
|
}
|
|
181
182
|
|
|
@@ -212,23 +213,33 @@ class Lorawan extends utils.Adapter {
|
|
|
212
213
|
return Buffer.from(payload, "base64").toString("hex").toUpperCase();
|
|
213
214
|
}
|
|
214
215
|
|
|
215
|
-
|
|
216
|
-
const activeFunction = "
|
|
216
|
+
getBaseDeviceInfo(id){
|
|
217
|
+
const activeFunction = "getBaseDeviceInfo";
|
|
217
218
|
try{
|
|
218
|
-
this.log.silly(`changeinfo of id ${id}, will be generated.`);
|
|
219
219
|
id = this.removeNamespace(id);
|
|
220
220
|
const idElements = id.split(".");
|
|
221
|
-
const
|
|
221
|
+
const deviceInfo = {
|
|
222
222
|
id: id,
|
|
223
223
|
applicationId : idElements[0],
|
|
224
224
|
dev_uid : idElements[2],
|
|
225
225
|
device_id : idElements[3],
|
|
226
226
|
changedState : idElements[idElements.length - 1],
|
|
227
|
-
deviceType : "",
|
|
228
227
|
obectStartDirectory : `${idElements[0]}.devices.${idElements[2]}.${idElements[3]}`,
|
|
229
228
|
allElements : idElements
|
|
230
229
|
};
|
|
231
|
-
|
|
230
|
+
return deviceInfo;
|
|
231
|
+
}
|
|
232
|
+
catch(error){
|
|
233
|
+
this.log.error(`error at ${activeFunction}: ` + error);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async getChangeInfo(id){
|
|
238
|
+
const activeFunction = "getChangeInfo";
|
|
239
|
+
try{
|
|
240
|
+
this.log.silly(`changeinfo of id ${id}, will be generated.`);
|
|
241
|
+
const changeInfo = this.getBaseDeviceInfo(id);
|
|
242
|
+
const myId = `${changeInfo?.applicationId}.devices.${changeInfo?.dev_uid}.${changeInfo?.device_id}.configuration.devicetype`;
|
|
232
243
|
const deviceTypeIdState = await this.getStateAsync(myId);
|
|
233
244
|
if(deviceTypeIdState){
|
|
234
245
|
// @ts-ignore
|