iobroker.lorawan 0.3.6 → 0.3.8
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/admin/jsonConfig.json +7 -1
- package/io-package.json +27 -27
- package/lib/modules/directorieshandler.js +7 -1
- package/lib/modules/downlinkConfighandler.js +22 -19
- package/lib/modules/messagehandler.js +150 -67
- package/lib/modules/mqttclient.js +2 -2
- package/main.js +4 -4
- 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.8 (2024-02-23)
|
|
26
|
+
* (BenAhrdt) write def into state in case of type changes
|
|
27
|
+
|
|
28
|
+
### 0.3.7 (2024-02-22)
|
|
29
|
+
* (BenAhrdt) improove forbidden chars and implements join raw
|
|
30
|
+
|
|
25
31
|
### 0.3.6 (2024-02-21)
|
|
26
32
|
* (BenAhrdt) set attributs if undefined
|
|
27
33
|
|
package/admin/jsonConfig.json
CHANGED
|
@@ -180,7 +180,8 @@
|
|
|
180
180
|
"label": "name",
|
|
181
181
|
"tooltip": "nameTooltip",
|
|
182
182
|
"default": "",
|
|
183
|
-
"validator": "if(data.name === '' || data.name === null){return false;}else{return
|
|
183
|
+
"validator": "if(data.name === '' || data.name === null){return false;}else{const myRegEx = /^([0-9a-z_ ])*$/i; return myRegEx.test(data.name);}",
|
|
184
|
+
"validatorNoSaveOnError": true,
|
|
184
185
|
"sm":2
|
|
185
186
|
},
|
|
186
187
|
{
|
|
@@ -246,6 +247,7 @@
|
|
|
246
247
|
"tooltip": "frontTooltip",
|
|
247
248
|
"default": "03",
|
|
248
249
|
"validator": "if(data.type !== 'string'){const myRegEx = /^([0-9a-f]{2})*$/i; return myRegEx.test(data.front)}else{return true}",
|
|
250
|
+
"validatorNoSaveOnError": true,
|
|
249
251
|
"hidden": "data.type === 'boolean' || data.type === 'button'",
|
|
250
252
|
"sm":2
|
|
251
253
|
},
|
|
@@ -256,6 +258,7 @@
|
|
|
256
258
|
"tooltip": "endTooltip",
|
|
257
259
|
"default": "11",
|
|
258
260
|
"validator": "if(data.type !== 'string'){const myRegEx = /^([0-9a-f]{2})*$/i; return myRegEx.test(data.front)}else{return true}",
|
|
261
|
+
"validatorNoSaveOnError": true,
|
|
259
262
|
"hidden": "data.type === 'boolean' || data.type === 'button'",
|
|
260
263
|
"sm":2
|
|
261
264
|
},
|
|
@@ -278,6 +281,7 @@
|
|
|
278
281
|
"tooltip": "onTooltip",
|
|
279
282
|
"default": "01",
|
|
280
283
|
"validator": "const myRegEx = /^([0-9a-f]{2})*$/i; return myRegEx.test(data.on);",
|
|
284
|
+
"validatorNoSaveOnError": true,
|
|
281
285
|
"hidden": "data.type !== 'boolean'",
|
|
282
286
|
"sm":2
|
|
283
287
|
},
|
|
@@ -288,6 +292,7 @@
|
|
|
288
292
|
"tooltip": "offTooltip",
|
|
289
293
|
"default": "11",
|
|
290
294
|
"validator": "const myRegEx = /^([0-9a-f]{2})*$/i; return myRegEx.test(data.off);",
|
|
295
|
+
"validatorNoSaveOnError": true,
|
|
291
296
|
"hidden": "data.type !== 'boolean'",
|
|
292
297
|
"sm":2
|
|
293
298
|
},
|
|
@@ -299,6 +304,7 @@
|
|
|
299
304
|
"tooltip": "onClickTooltip",
|
|
300
305
|
"default": "030111",
|
|
301
306
|
"validator": "const myRegEx = /^([0-9a-f]{2})*$/i; return myRegEx.test(data.onClick);",
|
|
307
|
+
"validatorNoSaveOnError": true,
|
|
302
308
|
"hidden": "data.type !== 'button'",
|
|
303
309
|
"sm":2
|
|
304
310
|
},
|
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.8",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.3.8": {
|
|
7
|
+
"en": "write def into state in case of type changes",
|
|
8
|
+
"de": "schreiben def in zustand bei typänderungen",
|
|
9
|
+
"ru": "написать деф в состояние в случае изменения типа",
|
|
10
|
+
"pt": "escrever def em estado em caso de alterações de tipo",
|
|
11
|
+
"nl": "def in status schrijven in geval van typewijzigingen",
|
|
12
|
+
"fr": "écrire def dans l'état en cas de changement de type",
|
|
13
|
+
"it": "scrivere def in stato in caso di variazioni di tipo",
|
|
14
|
+
"es": "escribir def en estado en caso de cambios de tipo",
|
|
15
|
+
"pl": "zapis def do stanu w przypadku zmian typu",
|
|
16
|
+
"uk": "писати деф в стан у разі зміни типу",
|
|
17
|
+
"zh-cn": "在类型变化时将 def 写入状态"
|
|
18
|
+
},
|
|
19
|
+
"0.3.7": {
|
|
20
|
+
"en": "improove forbidden chars and implements join raw",
|
|
21
|
+
"de": "unproove verbotene wagen und geräte roh beitreten",
|
|
22
|
+
"ru": "импровизировать запрещенные шары и реализаций присоединяются к сырому",
|
|
23
|
+
"pt": "improove proibido chars e implementos se juntar cru",
|
|
24
|
+
"nl": "improove verboden tekens en werktuigen samen rauw",
|
|
25
|
+
"fr": "improove prohibed chars and implements joignent brut",
|
|
26
|
+
"it": "improove vietati carboni e strumenti si uniscono crudo",
|
|
27
|
+
"es": "improove chars prohibidos e implementos se unen a crudo",
|
|
28
|
+
"pl": "improove zakazane znaki i narzędzia dołączyć surowe",
|
|
29
|
+
"uk": "неприпустимий заборонений діаграма і реалізує приєднатися до сировини",
|
|
30
|
+
"zh-cn": "将禁用字符和工具合并为原始字符"
|
|
31
|
+
},
|
|
6
32
|
"0.3.6": {
|
|
7
33
|
"en": "set attributs if undefined",
|
|
8
34
|
"de": "wenn nicht definiert",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "sformułowanie otrzymane = > otrzymywane w procesie messaging",
|
|
68
94
|
"uk": "javascript licenses api веб-сайт go1.13.8 отримувати повідомлення",
|
|
69
95
|
"zh-cn": "重述的语句 发送信件时收到"
|
|
70
|
-
},
|
|
71
|
-
"0.3.1": {
|
|
72
|
-
"en": "rebuild with better messageing",
|
|
73
|
-
"de": "neuaufbau mit besserer botschaft",
|
|
74
|
-
"ru": "перестроить с лучшим сообщением",
|
|
75
|
-
"pt": "reconstruir com melhor mensagem",
|
|
76
|
-
"nl": "herbouwen met betere berichtgeving",
|
|
77
|
-
"fr": "reconstruire avec un meilleur message",
|
|
78
|
-
"it": "ricostruire con messaggi migliori",
|
|
79
|
-
"es": "reconstruir con mejor mensaje",
|
|
80
|
-
"pl": "odbudowa dzięki lepszemu rozwiązywaniu problemów",
|
|
81
|
-
"uk": "перебудувати краще повідомлення",
|
|
82
|
-
"zh-cn": "以更好的信息重建"
|
|
83
|
-
},
|
|
84
|
-
"0.3.0": {
|
|
85
|
-
"en": "define user friendly Blockly Blocks with result",
|
|
86
|
-
"de": "benutzerfreundlich definieren Blockly Blocks mit Ergebnis",
|
|
87
|
-
"ru": "определение пользователя Блоки с результатом",
|
|
88
|
-
"pt": "definir amigável Blocos com resultado",
|
|
89
|
-
"nl": "gebruikersvriendelijk definiëren Blokkeren met resultaat",
|
|
90
|
-
"fr": "définir une utilisation conviviale Blocs avec résultat",
|
|
91
|
-
"it": "definire l'utente amichevole Blocchi Blockly con risultato",
|
|
92
|
-
"es": "definir fácil de usar Bloqueo bloques con resultado",
|
|
93
|
-
"pl": "zdefiniować przyjazny dla użytkownika Blokady z wynikiem",
|
|
94
|
-
"uk": "визначення дружності користувача Блокнотні блоки з результатом",
|
|
95
|
-
"zh-cn": "定义用户友好 块状块及结果"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"title": "LoRaWAN",
|
|
@@ -24,7 +24,9 @@ class directorieshandlerClass {
|
|
|
24
24
|
downlinkControl: "downlink.control",
|
|
25
25
|
downlinkRemaining: "downlink.remaining",
|
|
26
26
|
downlinkNextSend: "downlink.nextSend",
|
|
27
|
-
downlinkLastSend: "downlink.lastSend"
|
|
27
|
+
downlinkLastSend: "downlink.lastSend",
|
|
28
|
+
join: "join",
|
|
29
|
+
joinRaw: "join.raw"
|
|
28
30
|
};
|
|
29
31
|
|
|
30
32
|
//define path for uplink roles
|
|
@@ -96,6 +98,10 @@ class directorieshandlerClass {
|
|
|
96
98
|
remaining:{
|
|
97
99
|
}
|
|
98
100
|
},
|
|
101
|
+
join:{
|
|
102
|
+
raw:{
|
|
103
|
+
}
|
|
104
|
+
}
|
|
99
105
|
}
|
|
100
106
|
}
|
|
101
107
|
}
|
|
@@ -44,17 +44,17 @@ class downlinkConfighandlerClass {
|
|
|
44
44
|
const activeFunction = "addAndMergeDownlinkConfigs";
|
|
45
45
|
this.adapter.log.silly(`the standard and configed downlinks will be merged`);
|
|
46
46
|
try{
|
|
47
|
-
// Add
|
|
47
|
+
// Add user downlink config first
|
|
48
|
+
for(const downlinkConfig of Object.values(this.adapter.config.downlinkConfig)){
|
|
49
|
+
this.addDownlinkConfigByType(downlinkConfig,this.activeDownlinkConfigs);
|
|
50
|
+
}
|
|
51
|
+
// Add standard downlink config if devices not present
|
|
48
52
|
const internalDownlinks = this.getJsonArrayFromDirectoryfiles(`${this.adapter.adapterDir}${this.deviceProfilesPath}`);
|
|
49
53
|
if(Array.isArray(internalDownlinks)){
|
|
50
54
|
for(const downlinkConfig of Object.values(internalDownlinks)){
|
|
51
55
|
this.addDownlinkConfigByType(downlinkConfig,this.activeDownlinkConfigs);
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
|
-
// Add user downlink config
|
|
55
|
-
for(const downlinkConfig of Object.values(this.adapter.config.downlinkConfig)){
|
|
56
|
-
this.addDownlinkConfigByType(downlinkConfig,this.activeDownlinkConfigs);
|
|
57
|
-
}
|
|
58
58
|
// Check active userconfig
|
|
59
59
|
const adapterId = `system.adapter.${this.adapter.namespace}`;
|
|
60
60
|
const obj = await this.adapter.getForeignObjectAsync(adapterId);
|
|
@@ -89,22 +89,25 @@ class downlinkConfighandlerClass {
|
|
|
89
89
|
addDownlinkConfigByType(downlinkConfig,config){
|
|
90
90
|
const activeFunction = "addDownlinkConfigByType";
|
|
91
91
|
try{
|
|
92
|
-
//
|
|
93
|
-
config[downlinkConfig.deviceType]
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
//
|
|
98
|
-
downlinkParameter
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
92
|
+
// Check for device not present
|
|
93
|
+
if(!config[downlinkConfig.deviceType]){
|
|
94
|
+
// override standard with userconfig
|
|
95
|
+
config[downlinkConfig.deviceType] = structuredClone(downlinkConfig);
|
|
96
|
+
config[downlinkConfig.deviceType].downlinkState = {};
|
|
97
|
+
// generate downlinkstates for internal use
|
|
98
|
+
for(const downlinkParameter of Object.values(config[downlinkConfig.deviceType].downlinkParameter)){
|
|
99
|
+
// check name for forbidden chars
|
|
100
|
+
downlinkParameter.name = downlinkParameter.name.replace(this.adapter.FORBIDDEN_CHARS,"_");
|
|
101
|
+
// check the downlinkparameters for all needed attributes and generate them if undefined
|
|
102
|
+
for(const attribute in this.downlinkParameterAttributs){
|
|
103
|
+
if(downlinkConfig.deviceType !== this.internalDevices.baseDevice && downlinkParameter[attribute] === undefined){
|
|
104
|
+
this.adapter.log.debug(`attribute ${attribute} in parameter ${downlinkParameter.name} at devicetype ${downlinkConfig.deviceType} generated`);
|
|
105
|
+
downlinkParameter[attribute] = this.downlinkParameterAttributs[attribute];
|
|
106
|
+
}
|
|
104
107
|
}
|
|
108
|
+
// assign downlinkparamter to internal structure
|
|
109
|
+
config[downlinkConfig.deviceType].downlinkState[downlinkParameter.name] = downlinkParameter;
|
|
105
110
|
}
|
|
106
|
-
// assign downlinkparamter to internal structure
|
|
107
|
-
config[downlinkConfig.deviceType].downlinkState[downlinkParameter.name] = downlinkParameter;
|
|
108
111
|
}
|
|
109
112
|
}
|
|
110
113
|
catch(error){
|
|
@@ -63,7 +63,7 @@ class messagehandlerClass {
|
|
|
63
63
|
await this.directoryhandler.generateRekursivObjects(this.directoryhandler.directories.application.devices.deviceEUI.deviceId.downlink.lastSend,`${startDirectory}.${this.directoryhandler.reachableSubfolders.downlinkLastSend}`,"","");
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
async fillWithDownlinkConfig(deviceStartdirectory){
|
|
66
|
+
async fillWithDownlinkConfig(deviceStartdirectory,options){
|
|
67
67
|
const activeFunction = "fillWithDownlinkConfig";
|
|
68
68
|
try{
|
|
69
69
|
const changeInfo = await this.adapter.getChangeInfo(`${deviceStartdirectory}.fillDownlinkFolder`);
|
|
@@ -122,24 +122,35 @@ class messagehandlerClass {
|
|
|
122
122
|
stateCommonMax = 1000000;
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
|
-
|
|
125
|
+
// common set into variable to read later (for options)
|
|
126
|
+
const common = {
|
|
127
|
+
name: "",
|
|
128
|
+
type: stateCommonType,
|
|
129
|
+
role: stateCommonRole,
|
|
130
|
+
read: stateCommonRole !== "button",
|
|
131
|
+
write: true,
|
|
132
|
+
unit: downlinkParameter.unit? downlinkParameter.unit:"",
|
|
133
|
+
min: stateCommonMin,
|
|
134
|
+
max: stateCommonMax,
|
|
135
|
+
def: stateCommonType === "boolean"? false : stateCommonType === "number"? stateCommonDef: "",
|
|
136
|
+
};
|
|
137
|
+
const stateId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.downlinkControl}.${downlinkParameter.name}`;
|
|
138
|
+
await this.adapter.extendObjectAsync(stateId,{
|
|
126
139
|
type: "state",
|
|
127
|
-
common:
|
|
128
|
-
name: "",
|
|
129
|
-
type: stateCommonType,
|
|
130
|
-
role: stateCommonRole,
|
|
131
|
-
read: stateCommonRole !== "button",
|
|
132
|
-
write: true,
|
|
133
|
-
unit: downlinkParameter.unit? downlinkParameter.unit:"",
|
|
134
|
-
min: stateCommonMin,
|
|
135
|
-
max: stateCommonMax,
|
|
136
|
-
def: stateCommonType === "boolean"? false : stateCommonType === "number"? stateCommonDef: "",
|
|
137
|
-
},
|
|
140
|
+
common: common,
|
|
138
141
|
native: {},
|
|
139
142
|
});
|
|
140
143
|
if(downlinkDevice !=="all" && downlinkDevice !== this.adapter.downlinkConfighandler.internalDevices.baseDevice){
|
|
141
144
|
foundLength[downlinkParameter.name] = downlinkDevice.length;
|
|
142
145
|
}
|
|
146
|
+
//check for right type of data (after a possible change)
|
|
147
|
+
if(!options || !options.inMessage){
|
|
148
|
+
const state = await this.adapter.getStateAsync(stateId);
|
|
149
|
+
if(typeof state.val !== typeof common.def){
|
|
150
|
+
this.adapter.log.silly(`the defaultvale for state ${stateId} will set to ${common.def}`);
|
|
151
|
+
await this.adapter.setStateAsync(stateId,common.def,true);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
143
154
|
}
|
|
144
155
|
}
|
|
145
156
|
}
|
|
@@ -185,7 +196,7 @@ class messagehandlerClass {
|
|
|
185
196
|
* ****************** Check device startdirectory ********************
|
|
186
197
|
* ******************************************************************/
|
|
187
198
|
|
|
188
|
-
if(messageType !== "up" && !await this.adapter.objectExists(`${deviceStartdirectory}`)){
|
|
199
|
+
if(messageType !== "up" && messageType !== "join" && !await this.adapter.objectExists(`${deviceStartdirectory}`)){
|
|
189
200
|
this.adapter.log.debug(`There was a message with the topic ${topic}, but the object ${deviceStartdirectory} does not exists yet.`);
|
|
190
201
|
return;
|
|
191
202
|
}
|
|
@@ -199,7 +210,7 @@ class messagehandlerClass {
|
|
|
199
210
|
* ******************************************************************/
|
|
200
211
|
|
|
201
212
|
// check for uplink message
|
|
202
|
-
if(messageType === "up"){
|
|
213
|
+
if(messageType === "up"){
|
|
203
214
|
/*********************************************************************
|
|
204
215
|
* ************************ Main directories *************************
|
|
205
216
|
* ******************************************************************/
|
|
@@ -211,9 +222,9 @@ class messagehandlerClass {
|
|
|
211
222
|
* ******************************************************************/
|
|
212
223
|
|
|
213
224
|
this.adapter.log.silly(`write rawdata`);
|
|
214
|
-
let
|
|
225
|
+
let startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRaw}`;
|
|
215
226
|
// write json
|
|
216
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
227
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.json`,{
|
|
217
228
|
type: "state",
|
|
218
229
|
common: {
|
|
219
230
|
name: "last recieved message",
|
|
@@ -224,7 +235,7 @@ class messagehandlerClass {
|
|
|
224
235
|
},
|
|
225
236
|
native: {},
|
|
226
237
|
});
|
|
227
|
-
await this.adapter.setStateAsync(`${
|
|
238
|
+
await this.adapter.setStateAsync(`${startId}.json`,JSON.stringify(message),true);
|
|
228
239
|
|
|
229
240
|
/*********************************************************************
|
|
230
241
|
* ********************** Rawdata (Base64) ***************************
|
|
@@ -233,7 +244,7 @@ class messagehandlerClass {
|
|
|
233
244
|
if(message.uplink_message.frm_payload){
|
|
234
245
|
// wite base64 data
|
|
235
246
|
this.adapter.log.silly(`write base64`);
|
|
236
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
247
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.base64`,{
|
|
237
248
|
type: "state",
|
|
238
249
|
common: {
|
|
239
250
|
name: "last recieved data as base64",
|
|
@@ -245,11 +256,11 @@ class messagehandlerClass {
|
|
|
245
256
|
native: {},
|
|
246
257
|
});
|
|
247
258
|
const writedata = message.uplink_message.frm_payload;
|
|
248
|
-
await this.adapter.setStateAsync(`${
|
|
259
|
+
await this.adapter.setStateAsync(`${startId}.base64`,writedata,true);
|
|
249
260
|
|
|
250
261
|
// write base64 data in hex data
|
|
251
262
|
this.adapter.log.silly(`write hex`);
|
|
252
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
263
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.hex`,{
|
|
253
264
|
type: "state",
|
|
254
265
|
common: {
|
|
255
266
|
name: "last recieved data as hex",
|
|
@@ -261,11 +272,11 @@ class messagehandlerClass {
|
|
|
261
272
|
native: {},
|
|
262
273
|
});
|
|
263
274
|
const hexdata = Buffer.from(message.uplink_message.frm_payload, "base64").toString("hex").toUpperCase();
|
|
264
|
-
await this.adapter.setStateAsync(`${
|
|
275
|
+
await this.adapter.setStateAsync(`${startId}.hex`,hexdata,true);
|
|
265
276
|
|
|
266
277
|
// write base64 data in string data
|
|
267
278
|
this.adapter.log.silly(`write string`);
|
|
268
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
279
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.string`,{
|
|
269
280
|
type: "state",
|
|
270
281
|
common: {
|
|
271
282
|
name: "last recieved data as string",
|
|
@@ -277,25 +288,25 @@ class messagehandlerClass {
|
|
|
277
288
|
native: {},
|
|
278
289
|
});
|
|
279
290
|
const stringdata = Buffer.from(message.uplink_message.frm_payload, "base64").toString();
|
|
280
|
-
await this.adapter.setStateAsync(`${
|
|
291
|
+
await this.adapter.setStateAsync(`${startId}.string`,stringdata,true);
|
|
281
292
|
}
|
|
282
293
|
|
|
283
294
|
/*********************************************************************
|
|
284
295
|
* ********************** decoded payload ****************************
|
|
285
296
|
* ******************************************************************/
|
|
286
297
|
|
|
287
|
-
|
|
298
|
+
startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkDecoded}`;
|
|
288
299
|
this.adapter.log.silly(`write decoded payload`);
|
|
289
|
-
await this.directoryhandler.generateRekursivObjects(message.uplink_message.decoded_payload,
|
|
300
|
+
await this.directoryhandler.generateRekursivObjects(message.uplink_message.decoded_payload,startId,topic,message);
|
|
290
301
|
|
|
291
302
|
/*********************************************************************
|
|
292
303
|
* ************************* remaining *******************************
|
|
293
304
|
* ******************************************************************/
|
|
294
305
|
|
|
295
|
-
|
|
306
|
+
startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRemaining}`;
|
|
296
307
|
this.adapter.log.silly(`write remaining uplink data`);
|
|
297
308
|
|
|
298
|
-
await this.directoryhandler.generateRekursivObjects(message.uplink_message,
|
|
309
|
+
await this.directoryhandler.generateRekursivObjects(message.uplink_message,startId,topic,message,{ignoredElementNames:{decoded_payload:{},frm_payload:{}}});
|
|
299
310
|
|
|
300
311
|
/*********************************************************************
|
|
301
312
|
* ******************* Check downlink at uplink **********************
|
|
@@ -309,17 +320,17 @@ class messagehandlerClass {
|
|
|
309
320
|
* ******************************************************************/
|
|
310
321
|
|
|
311
322
|
// check for uplink message
|
|
312
|
-
else if(messageType === "queued" || messageType === "sent"){
|
|
323
|
+
else if(messageType === "queued" || messageType === "sent"){
|
|
313
324
|
// Check wich downlink was recieved
|
|
314
325
|
const downlinkType = `downlink_${messageType}`;
|
|
315
326
|
/*********************************************************************
|
|
316
327
|
* ************************ Rawdata json *****************************
|
|
317
328
|
* ******************************************************************/
|
|
318
329
|
|
|
319
|
-
let
|
|
330
|
+
let startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.downlinkRaw}`;
|
|
320
331
|
// write json
|
|
321
332
|
this.adapter.log.silly(`write rawdata`);
|
|
322
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
333
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.json`,{
|
|
323
334
|
type: "state",
|
|
324
335
|
common: {
|
|
325
336
|
name: "last recieved message",
|
|
@@ -330,7 +341,7 @@ class messagehandlerClass {
|
|
|
330
341
|
},
|
|
331
342
|
native: {},
|
|
332
343
|
});
|
|
333
|
-
await this.adapter.setStateAsync(`${
|
|
344
|
+
await this.adapter.setStateAsync(`${startId}.json`,JSON.stringify(message),true);
|
|
334
345
|
|
|
335
346
|
/*********************************************************************
|
|
336
347
|
* ********************** Rawdata (Base64) ***************************
|
|
@@ -340,7 +351,7 @@ class messagehandlerClass {
|
|
|
340
351
|
this.adapter.log.silly(`write base64`);
|
|
341
352
|
if(message[downlinkType].frm_payload){
|
|
342
353
|
// wite base64 data
|
|
343
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
354
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.base64`,{
|
|
344
355
|
type: "state",
|
|
345
356
|
common: {
|
|
346
357
|
name: "last recieved data as base64",
|
|
@@ -352,11 +363,11 @@ class messagehandlerClass {
|
|
|
352
363
|
native: {},
|
|
353
364
|
});
|
|
354
365
|
const writedata = message[downlinkType].frm_payload;
|
|
355
|
-
await this.adapter.setStateAsync(`${
|
|
366
|
+
await this.adapter.setStateAsync(`${startId}.base64`,writedata,true);
|
|
356
367
|
|
|
357
368
|
// write base64 data in hex data
|
|
358
369
|
this.adapter.log.silly(`write hex`);
|
|
359
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
370
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.hex`,{
|
|
360
371
|
type: "state",
|
|
361
372
|
common: {
|
|
362
373
|
name: "last recieved data as hex",
|
|
@@ -368,11 +379,11 @@ class messagehandlerClass {
|
|
|
368
379
|
native: {},
|
|
369
380
|
});
|
|
370
381
|
const hexdata = Buffer.from(message[downlinkType].frm_payload,"base64").toString("hex").toUpperCase();
|
|
371
|
-
await this.adapter.setStateAsync(`${
|
|
382
|
+
await this.adapter.setStateAsync(`${startId}.hex`,hexdata,true);
|
|
372
383
|
|
|
373
384
|
// write base64 data in string data
|
|
374
385
|
this.adapter.log.silly(`write string`);
|
|
375
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
386
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.string`,{
|
|
376
387
|
type: "state",
|
|
377
388
|
common: {
|
|
378
389
|
name: "last recieved data as string",
|
|
@@ -384,23 +395,59 @@ class messagehandlerClass {
|
|
|
384
395
|
native: {},
|
|
385
396
|
});
|
|
386
397
|
const stringdata = Buffer.from(message[downlinkType].frm_payload,"base64").toString();
|
|
387
|
-
await this.adapter.setStateAsync(`${
|
|
398
|
+
await this.adapter.setStateAsync(`${startId}.string`,stringdata,true);
|
|
388
399
|
}
|
|
389
400
|
|
|
390
401
|
/*********************************************************************
|
|
391
402
|
* ************************* remaining *******************************
|
|
392
403
|
* ******************************************************************/
|
|
393
404
|
|
|
394
|
-
|
|
405
|
+
startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.downlinkRemaining}`;
|
|
395
406
|
this.adapter.log.silly(`write remaining downlink data`);
|
|
396
|
-
await this.directoryhandler.generateRekursivObjects(message[downlinkType],
|
|
407
|
+
await this.directoryhandler.generateRekursivObjects(message[downlinkType],startId,topic,message,{ignoredElementNames:{frm_payload:{}}});
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// check for join message
|
|
411
|
+
else if(messageType === "join"){
|
|
412
|
+
|
|
413
|
+
/*********************************************************************
|
|
414
|
+
* ************************ Main directories *************************
|
|
415
|
+
* ******************************************************************/
|
|
416
|
+
|
|
417
|
+
await this.directoryhandler.generateRekursivObjects(this.directoryhandler.directories,"",topic,message);
|
|
418
|
+
|
|
419
|
+
/*********************************************************************
|
|
420
|
+
* ************************ Rawdata json *****************************
|
|
421
|
+
* ******************************************************************/
|
|
422
|
+
|
|
423
|
+
this.adapter.log.silly(`write rawdata`);
|
|
424
|
+
const startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.joinRaw}`;
|
|
425
|
+
// write json
|
|
426
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.json`,{
|
|
427
|
+
type: "state",
|
|
428
|
+
common: {
|
|
429
|
+
name: "last recieved message",
|
|
430
|
+
type: "json",
|
|
431
|
+
role: "value",
|
|
432
|
+
read: true,
|
|
433
|
+
write: false
|
|
434
|
+
},
|
|
435
|
+
native: {},
|
|
436
|
+
});
|
|
437
|
+
await this.adapter.setStateAsync(`${startId}.json`,JSON.stringify(message),true);
|
|
438
|
+
const changeInfo = await this.adapter.getChangeInfo(startId);
|
|
439
|
+
this.adapter.log.info(`the device ${changeInfo.deviceEUI} joined network`);
|
|
440
|
+
}
|
|
441
|
+
// Other messagetypes
|
|
442
|
+
else{
|
|
443
|
+
this.adapter.log.debug(`the messagetype: ${messageType}, is not implemented yet`);
|
|
397
444
|
}
|
|
398
445
|
|
|
399
446
|
/*********************************************************************
|
|
400
447
|
* ********************** downlinkConfigs ****************************
|
|
401
448
|
* ******************************************************************/
|
|
402
449
|
this.adapter.log.silly(`check configed downlinks`);
|
|
403
|
-
await this.fillWithDownlinkConfig(deviceStartdirectory);
|
|
450
|
+
await this.fillWithDownlinkConfig(deviceStartdirectory,{inMessage: true});
|
|
404
451
|
}
|
|
405
452
|
catch(error){
|
|
406
453
|
this.adapter.log.error(`error at ${activeFunction}: ${error} - - - Message: ${JSON.stringify(message)}`);
|
|
@@ -434,7 +481,7 @@ class messagehandlerClass {
|
|
|
434
481
|
* ****************** Check device startdirectory ********************
|
|
435
482
|
* ******************************************************************/
|
|
436
483
|
|
|
437
|
-
if(messageType !== "up" && !await this.adapter.objectExists(`${deviceStartdirectory}`)){
|
|
484
|
+
if(messageType !== "up" && messageType !== "join" && !await this.adapter.objectExists(`${deviceStartdirectory}`)){
|
|
438
485
|
this.adapter.log.debug(`There was a message with the topic ${topic}, but the object ${deviceStartdirectory} does not exists yet.`);
|
|
439
486
|
return;
|
|
440
487
|
}
|
|
@@ -448,7 +495,7 @@ class messagehandlerClass {
|
|
|
448
495
|
* ******************************************************************/
|
|
449
496
|
|
|
450
497
|
// check for uplink message
|
|
451
|
-
if(messageType === "up"){
|
|
498
|
+
if(messageType === "up"){
|
|
452
499
|
|
|
453
500
|
/*********************************************************************
|
|
454
501
|
* ************************ Main directories *************************
|
|
@@ -460,10 +507,10 @@ class messagehandlerClass {
|
|
|
460
507
|
* ************************ Rawdata json *****************************
|
|
461
508
|
* ******************************************************************/
|
|
462
509
|
|
|
463
|
-
let
|
|
510
|
+
let startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRaw}`;
|
|
464
511
|
// write json
|
|
465
512
|
this.adapter.log.silly(`write rawdata`);
|
|
466
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
513
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.json`,{
|
|
467
514
|
type: "state",
|
|
468
515
|
common: {
|
|
469
516
|
name: "last recieved message",
|
|
@@ -474,7 +521,7 @@ class messagehandlerClass {
|
|
|
474
521
|
},
|
|
475
522
|
native: {},
|
|
476
523
|
});
|
|
477
|
-
await this.adapter.setStateAsync(`${
|
|
524
|
+
await this.adapter.setStateAsync(`${startId}.json`,JSON.stringify(message),true);
|
|
478
525
|
|
|
479
526
|
/*********************************************************************
|
|
480
527
|
* ********************** Rawdata (Base64) ***************************
|
|
@@ -483,7 +530,7 @@ class messagehandlerClass {
|
|
|
483
530
|
if(message.data){
|
|
484
531
|
// wite base64 data
|
|
485
532
|
this.adapter.log.silly(`write base64`);
|
|
486
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
533
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.base64`,{
|
|
487
534
|
type: "state",
|
|
488
535
|
common: {
|
|
489
536
|
name: "last recieved data as base64",
|
|
@@ -495,11 +542,11 @@ class messagehandlerClass {
|
|
|
495
542
|
native: {},
|
|
496
543
|
});
|
|
497
544
|
const writedata = message.data;
|
|
498
|
-
await this.adapter.setStateAsync(`${
|
|
545
|
+
await this.adapter.setStateAsync(`${startId}.base64`,writedata,true);
|
|
499
546
|
|
|
500
547
|
// write base64 data in hex data
|
|
501
548
|
this.adapter.log.silly(`write hex`);
|
|
502
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
549
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.hex`,{
|
|
503
550
|
type: "state",
|
|
504
551
|
common: {
|
|
505
552
|
name: "last recieved data as hex",
|
|
@@ -511,11 +558,11 @@ class messagehandlerClass {
|
|
|
511
558
|
native: {},
|
|
512
559
|
});
|
|
513
560
|
const hexdata = Buffer.from(message.data, "base64").toString("hex").toUpperCase();
|
|
514
|
-
await this.adapter.setStateAsync(`${
|
|
561
|
+
await this.adapter.setStateAsync(`${startId}.hex`,hexdata,true);
|
|
515
562
|
|
|
516
563
|
// write base64 data in string data
|
|
517
564
|
this.adapter.log.silly(`write string`);
|
|
518
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
565
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.string`,{
|
|
519
566
|
type: "state",
|
|
520
567
|
common: {
|
|
521
568
|
name: "last recieved data as string",
|
|
@@ -527,23 +574,23 @@ class messagehandlerClass {
|
|
|
527
574
|
native: {},
|
|
528
575
|
});
|
|
529
576
|
const stringdata = Buffer.from(message.data, "base64").toString();
|
|
530
|
-
await this.adapter.setStateAsync(`${
|
|
577
|
+
await this.adapter.setStateAsync(`${startId}.string`,stringdata,true);
|
|
531
578
|
}
|
|
532
579
|
|
|
533
580
|
/*********************************************************************
|
|
534
581
|
* ****************** decoded payload (Object) ***********************
|
|
535
582
|
* ******************************************************************/
|
|
536
|
-
|
|
583
|
+
startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkDecoded}`;
|
|
537
584
|
this.adapter.log.silly(`write decoded payload (Object)`);
|
|
538
|
-
await this.directoryhandler.generateRekursivObjects(message.object,
|
|
585
|
+
await this.directoryhandler.generateRekursivObjects(message.object,startId,topic,message);
|
|
539
586
|
|
|
540
587
|
/*********************************************************************
|
|
541
588
|
* ************************* remaining *******************************
|
|
542
589
|
* ******************************************************************/
|
|
543
590
|
|
|
544
|
-
|
|
591
|
+
startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.uplinkRemaining}`;
|
|
545
592
|
this.adapter.log.silly(`write remaining uplink data`);
|
|
546
|
-
await this.directoryhandler.generateRekursivObjects(message,
|
|
593
|
+
await this.directoryhandler.generateRekursivObjects(message,startId,topic,message,{ignoredElementNames:{deduplicationId:{},deviceInfo:{},data:{},object:{}}});
|
|
547
594
|
|
|
548
595
|
/*********************************************************************
|
|
549
596
|
* ******************* Check downlink at uplink **********************
|
|
@@ -557,16 +604,16 @@ class messagehandlerClass {
|
|
|
557
604
|
* ******************************************************************/
|
|
558
605
|
|
|
559
606
|
// check for uplink message
|
|
560
|
-
else if(messageType === "down"){
|
|
607
|
+
else if(messageType === "down"){
|
|
561
608
|
|
|
562
609
|
/*********************************************************************
|
|
563
610
|
* ************************ Rawdata json *****************************
|
|
564
611
|
* ******************************************************************/
|
|
565
612
|
|
|
566
|
-
const
|
|
613
|
+
const startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.downlinkRaw}`;
|
|
567
614
|
// write json
|
|
568
615
|
this.adapter.log.silly(`write rawdata`);
|
|
569
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
616
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.json`,{
|
|
570
617
|
type: "state",
|
|
571
618
|
common: {
|
|
572
619
|
name: "last recieved message",
|
|
@@ -577,7 +624,7 @@ class messagehandlerClass {
|
|
|
577
624
|
},
|
|
578
625
|
native: {},
|
|
579
626
|
});
|
|
580
|
-
await this.adapter.setStateAsync(`${
|
|
627
|
+
await this.adapter.setStateAsync(`${startId}.json`,JSON.stringify(message),true);
|
|
581
628
|
|
|
582
629
|
/*********************************************************************
|
|
583
630
|
* ********************** Rawdata (Base64) ***************************
|
|
@@ -587,7 +634,7 @@ class messagehandlerClass {
|
|
|
587
634
|
if(message.data){
|
|
588
635
|
// wite base64 data
|
|
589
636
|
this.adapter.log.silly(`write base64`);
|
|
590
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
637
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.base64`,{
|
|
591
638
|
type: "state",
|
|
592
639
|
common: {
|
|
593
640
|
name: "last recieved data as base64",
|
|
@@ -599,11 +646,11 @@ class messagehandlerClass {
|
|
|
599
646
|
native: {},
|
|
600
647
|
});
|
|
601
648
|
const writedata = message.data;
|
|
602
|
-
await this.adapter.setStateAsync(`${
|
|
649
|
+
await this.adapter.setStateAsync(`${startId}.base64`,writedata,true);
|
|
603
650
|
|
|
604
651
|
// write base64 data in hex data
|
|
605
652
|
this.adapter.log.silly(`write hex`);
|
|
606
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
653
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.hex`,{
|
|
607
654
|
type: "state",
|
|
608
655
|
common: {
|
|
609
656
|
name: "last recieved data as hex",
|
|
@@ -615,11 +662,11 @@ class messagehandlerClass {
|
|
|
615
662
|
native: {},
|
|
616
663
|
});
|
|
617
664
|
const hexdata = Buffer.from(message.data,"base64").toString("hex").toUpperCase();
|
|
618
|
-
await this.adapter.setStateAsync(`${
|
|
665
|
+
await this.adapter.setStateAsync(`${startId}.hex`,hexdata,true);
|
|
619
666
|
|
|
620
667
|
// write base64 data in string data
|
|
621
668
|
this.adapter.log.silly(`write string`);
|
|
622
|
-
await this.adapter.setObjectNotExistsAsync(`${
|
|
669
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.string`,{
|
|
623
670
|
type: "state",
|
|
624
671
|
common: {
|
|
625
672
|
name: "last recieved data as string",
|
|
@@ -631,7 +678,7 @@ class messagehandlerClass {
|
|
|
631
678
|
native: {},
|
|
632
679
|
});
|
|
633
680
|
const stringdata = Buffer.from(message.data,"base64").toString();
|
|
634
|
-
await this.adapter.setStateAsync(`${
|
|
681
|
+
await this.adapter.setStateAsync(`${startId}.string`,stringdata,true);
|
|
635
682
|
}
|
|
636
683
|
|
|
637
684
|
/*********************************************************************
|
|
@@ -639,11 +686,47 @@ class messagehandlerClass {
|
|
|
639
686
|
* ******************************************************************/
|
|
640
687
|
|
|
641
688
|
}
|
|
689
|
+
|
|
690
|
+
// check for uplink message
|
|
691
|
+
else if(messageType === "join"){
|
|
692
|
+
/*********************************************************************
|
|
693
|
+
* ************************ Main directories *************************
|
|
694
|
+
* ******************************************************************/
|
|
695
|
+
|
|
696
|
+
await this.directoryhandler.generateRekursivObjects(this.directoryhandler.directories,"",topic,message);
|
|
697
|
+
|
|
698
|
+
/*********************************************************************
|
|
699
|
+
* ************************ Rawdata json *****************************
|
|
700
|
+
* ******************************************************************/
|
|
701
|
+
|
|
702
|
+
const startId = `${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.joinRaw}`;
|
|
703
|
+
// write json
|
|
704
|
+
this.adapter.log.silly(`write rawdata`);
|
|
705
|
+
await this.adapter.setObjectNotExistsAsync(`${startId}.json`,{
|
|
706
|
+
type: "state",
|
|
707
|
+
common: {
|
|
708
|
+
name: "last recieved message",
|
|
709
|
+
type: "json",
|
|
710
|
+
role: "value",
|
|
711
|
+
read: true,
|
|
712
|
+
write: false
|
|
713
|
+
},
|
|
714
|
+
native: {},
|
|
715
|
+
});
|
|
716
|
+
await this.adapter.setStateAsync(`${startId}.json`,JSON.stringify(message),true);
|
|
717
|
+
const changeInfo = await this.adapter.getChangeInfo(startId);
|
|
718
|
+
this.adapter.log.info(`the device ${changeInfo.deviceEUI} joined network`);
|
|
719
|
+
}
|
|
720
|
+
// Other messagetypes
|
|
721
|
+
else{
|
|
722
|
+
this.adapter.log.debug(`the messagetype: ${messageType}, is not implemented yet`);
|
|
723
|
+
}
|
|
724
|
+
|
|
642
725
|
/*********************************************************************
|
|
643
726
|
* ********************** downlinkConfigs ****************************
|
|
644
727
|
* ******************************************************************/
|
|
645
728
|
this.adapter.log.silly(`check configed downlinks`);
|
|
646
|
-
await this.fillWithDownlinkConfig(deviceStartdirectory);
|
|
729
|
+
await this.fillWithDownlinkConfig(deviceStartdirectory,{inMessage: true});
|
|
647
730
|
|
|
648
731
|
}
|
|
649
732
|
catch(error){
|
|
@@ -54,9 +54,9 @@ class mqttClientClass {
|
|
|
54
54
|
getSubscribtionArray(){
|
|
55
55
|
switch(this.adapter.config.origin){
|
|
56
56
|
case this.adapter.origin.ttn:
|
|
57
|
-
return ["v3/+/devices
|
|
57
|
+
return ["v3/+/devices/+/+","v3/+/devices/+/down/+"];
|
|
58
58
|
case this.adapter.origin.chirpstack:
|
|
59
|
-
return ["application/+/device/+/event
|
|
59
|
+
return ["application/+/device/+/event/+","application/+/device/+/command/down"];
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
}
|
package/main.js
CHANGED
|
@@ -82,8 +82,8 @@ class Lorawan extends utils.Adapter {
|
|
|
82
82
|
//const message = {"end_device_ids":{"device_id":"eui-lobaro-modbus","application_ids":{"application_id":"hafi-ttn-lorawan"},"dev_eui":"70B3D5E050013950","join_eui":"D55B58C0DDC074DE","dev_addr":"260B5972"},"correlation_ids":["gs:uplink:01HMQZVSCX4D7JRDNFA7GJ9D4W"],"received_at":"2024-01-22T07:06:25.260676101Z","uplink_message":{"session_key_id":"AY0v/ZirzRkpNW0Cgjdhig==","f_port":20,"f_cnt":2,"frm_payload":"AA5BAf0AxwIAAQ==","decoded_payload":{"airhumidity":50.9,"airtemperature":19.9,"port":20,"relais1":0,"relais2":1,"relais3":null,"relais5":null,"volt":3.649,"zisternenpegel":2},"rx_metadata":[{"gateway_ids":{"gateway_id":"hafenmeister-port2ttn-ng","eui":"50313953530A4750"},"time":"2024-01-22T07:06:25.013878Z","timestamp":995696116,"rssi":-37,"channel_rssi":-37,"snr":8.5,"location":{"latitude":53.5548443059465,"longitude":9.92155426743724,"altitude":10,"source":"SOURCE_REGISTRY"},"uplink_token":"CiYKJAoYaGFmZW5tZWlzdGVyLXBvcnQydHRuLW5nEghQMTlTUwpHUBD0u+TaAxoLCPGnuK0GEM3uvhkgoIL0oP24Sg==","channel_index":5,"received_at":"2024-01-22T07:06:25.032492359Z"}],"settings":{"data_rate":{"lora":{"bandwidth":125000,"spreading_factor":9,"coding_rate":"4/5"}},"frequency":"867500000","timestamp":995696116,"time":"2024-01-22T07:06:25.013878Z"},"received_at":"2024-01-22T07:06:25.054442349Z","consumed_airtime":"0.205824s","network_ids":{"net_id":"000013","ns_id":"EC656E0000000181","tenant_id":"ttn","cluster_id":"eu1","cluster_address":"eu1.cloud.thethings.network"}}};
|
|
83
83
|
|
|
84
84
|
// ACK
|
|
85
|
-
const topic = "v3/hafi-ttn-lorawan@ttn/devices/eui-a84041162183f8fb/down/ack";
|
|
86
|
-
const message = {"end_device_ids":{"device_id":"eui-a84041162183f8fb","application_ids":{"application_id":"hafi-ttn-lorawan"},"dev_eui":"A84041162183F8FB","join_eui":"A840410000000101","dev_addr":"260B141A"},"correlation_ids":["as:downlink:01HP6D18MQXJN90J5B07DC11HY","gs:uplink:01HP6D1A9X4WAA3SFMXH4ESSMV"],"received_at":"2024-02-09T07:41:41.776887672Z","downlink_ack":{"session_key_id":"AY2MUrmnuovS8DCZAfYmsA==","f_port":1,"f_cnt":21,"frm_payload":"AQAAeA==","confirmed":true,"priority":"NORMAL","correlation_ids":["as:downlink:01HP6D18MQXJN90J5B07DC11HY"],"confirmed_retry":{"attempt":1}}};
|
|
85
|
+
//const topic = "v3/hafi-ttn-lorawan@ttn/devices/eui-a84041162183f8fb/down/ack";
|
|
86
|
+
//const message = {"end_device_ids":{"device_id":"eui-a84041162183f8fb","application_ids":{"application_id":"hafi-ttn-lorawan"},"dev_eui":"A84041162183F8FB","join_eui":"A840410000000101","dev_addr":"260B141A"},"correlation_ids":["as:downlink:01HP6D18MQXJN90J5B07DC11HY","gs:uplink:01HP6D1A9X4WAA3SFMXH4ESSMV"],"received_at":"2024-02-09T07:41:41.776887672Z","downlink_ack":{"session_key_id":"AY2MUrmnuovS8DCZAfYmsA==","f_port":1,"f_cnt":21,"frm_payload":"AQAAeA==","confirmed":true,"priority":"NORMAL","correlation_ids":["as:downlink:01HP6D18MQXJN90J5B07DC11HY"],"confirmed_retry":{"attempt":1}}};
|
|
87
87
|
|
|
88
88
|
// Chipstack
|
|
89
89
|
//const topic = "application/d63c10b6-9263-4ab3-9299-4308fa19a2ad/device/a84041f621857cd2/event/up";
|
|
@@ -118,8 +118,8 @@ class Lorawan extends utils.Adapter {
|
|
|
118
118
|
//const message = {"time":"2024-01-27T10:29:58.221817559+00:00","deviceInfo":{"tenantId":"52f14cd4-c6f1-4fbd-8f87-4025e1d49242","tenantName":"ChirpStack","applicationId":"59bcc5a7-59e2-4481-9615-fc4e58791915","applicationName":"Mclimate_Vicki","deviceProfileId":"3a9bc28f-3664-4bdf-b3be-a20d1eb32dc8","deviceProfileName":"Mclimate_Vicki","deviceName":"MClimate_Vicki_Heizkoerperventil_001","devEui":"70b3d52dd300ed31","deviceClassEnabled":"CLASS_A","tags":{}},"level":"ERROR","code":"UPLINK_CODEC","description":"Exception generated by quickjs","context":{"deduplication_id":"c44e7e25-09ce-4c95-b96f-5a298c5c6440"}};
|
|
119
119
|
|
|
120
120
|
// JOIN
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
const topic = "application/59bcc5a7-59e2-4481-9615-fc4e58791915/device/70b3d52dd300ed31/event/join";
|
|
122
|
+
const message = {"deduplicationId":"44cef56d-1b8d-45fc-a762-03b98b620db2","time":"2023-12-12T03:13:21.551178+00:00","deviceInfo":{"tenantId":"52f14cd4-c6f1-4fbd-8f87-4025e1d49242","tenantName":"ChirpStack","applicationId":"59bcc5a7-59e2-4481-9615-fc4e58791915","applicationName":"Mclimate_Vicki","deviceProfileId":"3a9bc28f-3664-4bdf-b3be-a20d1eb32dc8","deviceProfileName":"Mclimate_Vicki","deviceName":"MClimate_Vicki_Heizkoerperventil_001","devEui":"70b3d52dd300ed31","deviceClassEnabled":"CLASS_A","tags":{}},"devAddr":"01009400"};
|
|
123
123
|
|
|
124
124
|
// DOWN
|
|
125
125
|
//const topic = "application/59bcc5a7-59e2-4481-9615-fc4e58791915/device/70b3d52dd300ed31/command/down";
|