iobroker.lorawan 0.2.0 → 0.3.0
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 +12 -1
- package/admin/blockly.js +440 -0
- package/io-package.json +28 -27
- package/lib/modules/deviceProfiles/Dragino LT22222.json +3 -1
- package/lib/modules/deviceProfiles/Dragino.json +3 -1
- package/lib/modules/deviceProfiles/Vicki.json +3 -1
- package/lib/modules/directorieshandler.js +3 -1
- package/lib/modules/messagehandler.js +1 -1
- package/main.js +53 -37
- 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.0 (2024-02-15)
|
|
26
|
+
* (BenAhrdt) define user friendly Blockly Blocks with result
|
|
27
|
+
|
|
28
|
+
### 0.2.1 (2024-02-13)
|
|
29
|
+
* (BenAhrdt) check types of messaging values and implements more blockly blocks
|
|
30
|
+
|
|
25
31
|
### 0.2.0 (2024-02-12)
|
|
26
32
|
* (BenAhrdt) more functionality in messageing
|
|
27
33
|
|
|
@@ -146,4 +152,9 @@ SOFTWARE.
|
|
|
146
152
|
The rights of the trademarks and company names,
|
|
147
153
|
remain with their owners and have no relation to this adapter.
|
|
148
154
|
The fairuse policy must continue to be adhered to by the operator of the adapter.
|
|
149
|
-
If this repository is forked, it must be cited as the source.
|
|
155
|
+
If this repository is forked, it must be cited as the source.
|
|
156
|
+
|
|
157
|
+
LoRa® is a registered trademark or service
|
|
158
|
+
mark of Semtech Corporation or its affilantes.
|
|
159
|
+
|
|
160
|
+
LoRaWAN® is a licensed mark.
|
package/admin/blockly.js
ADDED
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
/* eslint-disable prefer-const */
|
|
2
|
+
/* eslint-disable no-undef */
|
|
3
|
+
// @ts-nocheck
|
|
4
|
+
"use strict";
|
|
5
|
+
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
if (typeof goog !== "undefined") {
|
|
8
|
+
goog.provide("Blockly.JavaScript.Sendto");
|
|
9
|
+
goog.require("Blockly.JavaScript");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
// --- general translations --------------------------------------------------
|
|
14
|
+
Blockly.Words["anyInstance"] = {
|
|
15
|
+
"en": "all instances",
|
|
16
|
+
"pt": "todas as instâncias",
|
|
17
|
+
"pl": "wszystkie przypadki",
|
|
18
|
+
"nl": "alle instanties",
|
|
19
|
+
"it": "tutte le istanze",
|
|
20
|
+
"es": "todas las instancias",
|
|
21
|
+
"fr": "toutes les instances",
|
|
22
|
+
"de": "Alle Instanzen",
|
|
23
|
+
"ru": "На все драйвера"
|
|
24
|
+
};
|
|
25
|
+
Blockly.Words["lorawanDeviceEUI"] = {
|
|
26
|
+
"en": "device EUI",
|
|
27
|
+
"de": "Device EUI",
|
|
28
|
+
"ru": "устройство EUI",
|
|
29
|
+
"pt": "dispositivo EUI",
|
|
30
|
+
"nl": "apparaat EUI",
|
|
31
|
+
"fr": "dispositif IUE",
|
|
32
|
+
"it": "dispositivo EUI",
|
|
33
|
+
"es": "dispositivo EUI",
|
|
34
|
+
"pl": "urządzenie EUI",
|
|
35
|
+
"uk": "пристрій EUI",
|
|
36
|
+
"zh-cn": "设备 EUI"
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**************************************************************************
|
|
40
|
+
******************************Get Device Info******************************
|
|
41
|
+
**************************************************************************/
|
|
42
|
+
|
|
43
|
+
// --- Get DeviceInfo translations --------------------------------------------------
|
|
44
|
+
Blockly.Words["lorawanGetDeviceInfo"] = {
|
|
45
|
+
"en": "lorawan Device Info",
|
|
46
|
+
"de": "lorawan Geräteinfo",
|
|
47
|
+
"ru": "lorawan Device Info",
|
|
48
|
+
"pt": "lorawan Informações do dispositivo",
|
|
49
|
+
"nl": "lorawan Apparaatinformatie",
|
|
50
|
+
"fr": "lorawan Informations sur le périphérique",
|
|
51
|
+
"it": "lorawan Dispositivi Info",
|
|
52
|
+
"es": "lorawan Device Info",
|
|
53
|
+
"pl": "informacje o urządzeniu Lorawan",
|
|
54
|
+
"uk": "інформація про пристрій lorawan",
|
|
55
|
+
"zh-cn": "lorawan 设备信息"
|
|
56
|
+
};
|
|
57
|
+
Blockly.Words["lorawanGetDeviceInfotooltip"] = {
|
|
58
|
+
"en": "get Informations about the device with the given device EUI",
|
|
59
|
+
"de": "Informationen über das Gerät mit der angegebenen Geräte EUI",
|
|
60
|
+
"ru": "получить информацию об устройстве с данным устройством EUI",
|
|
61
|
+
"pt": "obter informações sobre o dispositivo com o dispositivo dado EUI",
|
|
62
|
+
"nl": "informatie over het apparaat met het gegeven apparaat opvragen EUI",
|
|
63
|
+
"fr": "obtenir des informations sur l'appareil avec l'appareil donné IUE",
|
|
64
|
+
"it": "ottenere informazioni sul dispositivo con il dispositivo fornito EUI",
|
|
65
|
+
"es": "obtener Información sobre el dispositivo con el dispositivo dado EUI",
|
|
66
|
+
"pl": "pobierz informacje o urządzeniu z podanym urządzeniem EUI",
|
|
67
|
+
"uk": "отримувати інформацію про пристрій з заданим пристроєм EUI",
|
|
68
|
+
"zh-cn": "用指定的设备获取设备信息 EUI"
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// eslint-disable-next-line no-undef
|
|
72
|
+
Blockly.Sendto.blocks["lorawanGetDeviceInfo"] =
|
|
73
|
+
"<block type='lorawanGetDeviceInfo'>"
|
|
74
|
+
+ " <value name='INSTANCE'>"
|
|
75
|
+
+ " </value>"
|
|
76
|
+
+ " <value name='deviceEUI'>"
|
|
77
|
+
+ " <shadow type='text'>"
|
|
78
|
+
+ " <field name='TEXT'>text</field>"
|
|
79
|
+
+ " </shadow>"
|
|
80
|
+
+ " </value>"
|
|
81
|
+
+ "</block>";
|
|
82
|
+
|
|
83
|
+
// eslint-disable-next-line no-undef
|
|
84
|
+
Blockly.Blocks["lorawanGetDeviceInfo"] = {
|
|
85
|
+
init: function() {
|
|
86
|
+
const options = [[Blockly.Translate("anyInstance"), ""]];
|
|
87
|
+
if (typeof main !== "undefined" && main.instances) {
|
|
88
|
+
for (let i = 0; i < main.instances.length; i++) {
|
|
89
|
+
// eslint-disable-next-line prefer-const
|
|
90
|
+
let m = main.instances[i].match(/^system.adapter.lorawan.(\d+)$/);
|
|
91
|
+
if (m) {
|
|
92
|
+
// eslint-disable-next-line prefer-const
|
|
93
|
+
let k = parseInt(m[1], 10);
|
|
94
|
+
options.push(["lorawan." + k, "." + k]);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (options.length === 0) {
|
|
98
|
+
for (let u = 0; u <= 4; u++) {
|
|
99
|
+
options.push(["lorawan." + u, "." + u]);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
for (let n = 0; n <= 4; n++) {
|
|
104
|
+
options.push(["lorawan." + n, "." + n]);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
this.appendDummyInput("INSTANCE")
|
|
109
|
+
.appendField(Blockly.Translate("lorawanGetDeviceInfo"))
|
|
110
|
+
.appendField(new Blockly.FieldDropdown(options), "INSTANCE");
|
|
111
|
+
|
|
112
|
+
this.appendValueInput("deviceEUI")
|
|
113
|
+
.appendField(Blockly.Translate("lorawanDeviceEUI"));
|
|
114
|
+
|
|
115
|
+
this.appendStatementInput("result");
|
|
116
|
+
|
|
117
|
+
this.setInputsInline(false);
|
|
118
|
+
this.setPreviousStatement(true, null);
|
|
119
|
+
this.setNextStatement(true, null);
|
|
120
|
+
|
|
121
|
+
this.setColour(Blockly.Sendto.HUE);
|
|
122
|
+
this.setTooltip(Blockly.Translate("lorawanGetDeviceInfotooltip"));
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
Blockly.JavaScript["lorawanGetDeviceInfo"] = function(block){
|
|
127
|
+
const value_devEUI = Blockly.JavaScript.valueToCode(block, "deviceEUI", Blockly.JavaScript.ORDER_ATOMIC);
|
|
128
|
+
const code_result = Blockly.JavaScript.statementToCode(block, "result");
|
|
129
|
+
|
|
130
|
+
// build code
|
|
131
|
+
const objParameter = [];
|
|
132
|
+
objParameter.push("deviceEUI:" + value_devEUI);
|
|
133
|
+
const objEnd = [];
|
|
134
|
+
if(code_result){
|
|
135
|
+
objEnd.push(`, async (result) => {${code_result}});`);
|
|
136
|
+
}
|
|
137
|
+
else{
|
|
138
|
+
objEnd.push(`);`);
|
|
139
|
+
}
|
|
140
|
+
return `sendTo("lorawan${block.getFieldValue("INSTANCE")}", "getDeviceInfo", {${objParameter.join(",")}}${objEnd}`;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
/**************************************************************************
|
|
144
|
+
*********************************Get uplink********************************
|
|
145
|
+
**************************************************************************/
|
|
146
|
+
|
|
147
|
+
// --- Get DeviceInfo translations --------------------------------------------------
|
|
148
|
+
Blockly.Words["lorawanGetUplink"] = {
|
|
149
|
+
"en": "lorawan uplinkinfo",
|
|
150
|
+
"de": "lorawan uplinkinfo",
|
|
151
|
+
"ru": "lorawan uplinkinfo",
|
|
152
|
+
"pt": "o que fazer",
|
|
153
|
+
"nl": "lorawan uplinkinfo",
|
|
154
|
+
"fr": "lorawan uplinkinfo",
|
|
155
|
+
"it": "condividi su google",
|
|
156
|
+
"es": "lorawan uplinkinfo",
|
|
157
|
+
"pl": "lorawan uplinkinfo",
|
|
158
|
+
"uk": "український",
|
|
159
|
+
"zh-cn": "lorawan 上行链接信息"
|
|
160
|
+
};
|
|
161
|
+
Blockly.Words["lorawanGetUplinktooltip"] = {
|
|
162
|
+
"en": "get information about the given uplink",
|
|
163
|
+
"de": "Informationen zum angegebenen uplink",
|
|
164
|
+
"ru": "получить информацию об отказе от ссылки",
|
|
165
|
+
"pt": "obter informações sobre o link fornecido",
|
|
166
|
+
"nl": "informatie krijgen over de opgegeven uplink",
|
|
167
|
+
"fr": "obtenir des informations sur le lien ascendant donné",
|
|
168
|
+
"it": "ottenere informazioni su il link up",
|
|
169
|
+
"es": "obtener información sobre el enlace dado",
|
|
170
|
+
"pl": "uzyskać informacje o danym łączniku",
|
|
171
|
+
"uk": "отримувати інформацію про задану посилання",
|
|
172
|
+
"zh-cn": "获取上行链路的信息"
|
|
173
|
+
};
|
|
174
|
+
Blockly.Words["lorawanUplink"] = {
|
|
175
|
+
"en": "uplink",
|
|
176
|
+
"de": "Uplink",
|
|
177
|
+
"ru": "uplink",
|
|
178
|
+
"pt": "o que é",
|
|
179
|
+
"nl": "uplink",
|
|
180
|
+
"fr": "lien ascendant",
|
|
181
|
+
"it": "uplink",
|
|
182
|
+
"es": "subtítulos",
|
|
183
|
+
"pl": "link",
|
|
184
|
+
"uk": "посилання",
|
|
185
|
+
"zh-cn": "上行链接"
|
|
186
|
+
};
|
|
187
|
+
Blockly.Words["lorawanSubfolder"] = {
|
|
188
|
+
"en": "subfolder",
|
|
189
|
+
"de": "Unterordner",
|
|
190
|
+
"ru": "subfolder",
|
|
191
|
+
"pt": "subpastas",
|
|
192
|
+
"nl": "submap",
|
|
193
|
+
"fr": "sous-dossier",
|
|
194
|
+
"it": "sottocartella",
|
|
195
|
+
"es": "subcarpeta",
|
|
196
|
+
"pl": "podfolder",
|
|
197
|
+
"uk": "підпалювач",
|
|
198
|
+
"zh-cn": "子文件夹"
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// eslint-disable-next-line no-undef
|
|
202
|
+
Blockly.Sendto.blocks["lorawanGetUplink"] =
|
|
203
|
+
"<block type='lorawanGetUplink'>"
|
|
204
|
+
+ " <value name='INSTANCE'>"
|
|
205
|
+
+ " </value>"
|
|
206
|
+
+ " <value name='deviceEUI'>"
|
|
207
|
+
+ " <shadow type='text'>"
|
|
208
|
+
+ " <field name='TEXT'>text</field>"
|
|
209
|
+
+ " </shadow>"
|
|
210
|
+
+ " </value>"
|
|
211
|
+
+ " <value name='uplink'>"
|
|
212
|
+
+ " <shadow type='text'>"
|
|
213
|
+
+ " <field name='TEXT'>text</field>"
|
|
214
|
+
+ " </shadow>"
|
|
215
|
+
+ " </value>"
|
|
216
|
+
+ " <value name='subfolder'>"
|
|
217
|
+
+ " <shadow type='text'>"
|
|
218
|
+
+ " <field name='TEXT'>decoded</field>"
|
|
219
|
+
+ " </shadow>"
|
|
220
|
+
+ " </value>"
|
|
221
|
+
+ "</block>";
|
|
222
|
+
|
|
223
|
+
// eslint-disable-next-line no-undef
|
|
224
|
+
Blockly.Blocks["lorawanGetUplink"] = {
|
|
225
|
+
init: function() {
|
|
226
|
+
const options = [[Blockly.Translate("anyInstance"), ""]];
|
|
227
|
+
if (typeof main !== "undefined" && main.instances) {
|
|
228
|
+
for (let i = 0; i < main.instances.length; i++) {
|
|
229
|
+
// eslint-disable-next-line prefer-const
|
|
230
|
+
let m = main.instances[i].match(/^system.adapter.lorawan.(\d+)$/);
|
|
231
|
+
if (m) {
|
|
232
|
+
// eslint-disable-next-line prefer-const
|
|
233
|
+
let k = parseInt(m[1], 10);
|
|
234
|
+
options.push(["lorawan." + k, "." + k]);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
if (options.length === 0) {
|
|
238
|
+
for (let u = 0; u <= 4; u++) {
|
|
239
|
+
options.push(["lorawan." + u, "." + u]);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
} else {
|
|
243
|
+
for (let n = 0; n <= 4; n++) {
|
|
244
|
+
options.push(["lorawan." + n, "." + n]);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
this.appendDummyInput("INSTANCE")
|
|
249
|
+
.appendField(Blockly.Translate("lorawanGetUplink"))
|
|
250
|
+
.appendField(new Blockly.FieldDropdown(options), "INSTANCE");
|
|
251
|
+
|
|
252
|
+
this.appendValueInput("deviceEUI")
|
|
253
|
+
.appendField(Blockly.Translate("lorawanDeviceEUI"));
|
|
254
|
+
|
|
255
|
+
this.appendValueInput("uplink")
|
|
256
|
+
.appendField(Blockly.Translate("lorawanUplink"));
|
|
257
|
+
|
|
258
|
+
this.appendValueInput("subfolder")
|
|
259
|
+
.appendField(Blockly.Translate("lorawanSubfolder"));
|
|
260
|
+
|
|
261
|
+
this.appendStatementInput("result");
|
|
262
|
+
|
|
263
|
+
this.setInputsInline(false);
|
|
264
|
+
this.setPreviousStatement(true, null);
|
|
265
|
+
this.setNextStatement(true, null);
|
|
266
|
+
|
|
267
|
+
this.setColour(Blockly.Sendto.HUE);
|
|
268
|
+
this.setTooltip(Blockly.Translate("lorawanGetUplinktooltip"));
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
Blockly.JavaScript["lorawanGetUplink"] = function(block){
|
|
273
|
+
const value_devEUI = Blockly.JavaScript.valueToCode(block, "deviceEUI", Blockly.JavaScript.ORDER_ATOMIC);
|
|
274
|
+
const value_uplink = Blockly.JavaScript.valueToCode(block, "uplink", Blockly.JavaScript.ORDER_ATOMIC);
|
|
275
|
+
const value_subfolder = Blockly.JavaScript.valueToCode(block, "subfolder", Blockly.JavaScript.ORDER_ATOMIC);
|
|
276
|
+
const code_result = Blockly.JavaScript.statementToCode(block, "result");
|
|
277
|
+
|
|
278
|
+
// build code
|
|
279
|
+
const objParameter = [];
|
|
280
|
+
objParameter.push("deviceEUI:" + value_devEUI);
|
|
281
|
+
objParameter.push("uplink:" + value_uplink);
|
|
282
|
+
objParameter.push("subfolder:" + value_subfolder);
|
|
283
|
+
const objEnd = [];
|
|
284
|
+
if(code_result){
|
|
285
|
+
objEnd.push(`, async (result) => {${code_result}});`);
|
|
286
|
+
}
|
|
287
|
+
else{
|
|
288
|
+
objEnd.push(`);`);
|
|
289
|
+
}
|
|
290
|
+
return `sendTo("lorawan${block.getFieldValue("INSTANCE")}", "getUplink", {${objParameter.join(",")}}${objEnd}`;
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
/**************************************************************************
|
|
294
|
+
*******************************Set downlink********************************
|
|
295
|
+
**************************************************************************/
|
|
296
|
+
|
|
297
|
+
// --- Get DeviceInfo translations --------------------------------------------------
|
|
298
|
+
Blockly.Words["lorawanSetDownlink"] = {
|
|
299
|
+
"en": "lorawan downlink",
|
|
300
|
+
"de": "lorawan downlink",
|
|
301
|
+
"ru": "lorawan downlink",
|
|
302
|
+
"pt": "para baixo",
|
|
303
|
+
"nl": "lorawan downlink",
|
|
304
|
+
"fr": "lorawan lien descendant",
|
|
305
|
+
"it": "lorawan downlink",
|
|
306
|
+
"es": "lorawan downlink",
|
|
307
|
+
"pl": "lorawan downlink",
|
|
308
|
+
"uk": "логін",
|
|
309
|
+
"zh-cn": "龙卷风下行链路"
|
|
310
|
+
};
|
|
311
|
+
Blockly.Words["lorawanSetDownlinktooltip"] = {
|
|
312
|
+
"en": "set downlink",
|
|
313
|
+
"de": "Downlink zur lorawan instanz absetzen",
|
|
314
|
+
"ru": "set downlink",
|
|
315
|
+
"pt": "definir link",
|
|
316
|
+
"nl": "downlink instellen",
|
|
317
|
+
"fr": "définir la liaison descendante",
|
|
318
|
+
"it": "impostare il collegamento",
|
|
319
|
+
"es": "desplazamiento",
|
|
320
|
+
"pl": "set downlink",
|
|
321
|
+
"uk": "увійти",
|
|
322
|
+
"zh-cn": "设置下行链路"
|
|
323
|
+
};
|
|
324
|
+
Blockly.Words["lorawanDownlink"] = {
|
|
325
|
+
"en": "downlink",
|
|
326
|
+
"de": "Downlink",
|
|
327
|
+
"ru": "downlink",
|
|
328
|
+
"pt": "o que é",
|
|
329
|
+
"nl": "downlink",
|
|
330
|
+
"fr": "lien ascendant",
|
|
331
|
+
"it": "downlink",
|
|
332
|
+
"es": "subtítulos",
|
|
333
|
+
"pl": "link",
|
|
334
|
+
"uk": "посилання",
|
|
335
|
+
"zh-cn": "上行链接"
|
|
336
|
+
};
|
|
337
|
+
Blockly.Words["lorawanValue"] = {
|
|
338
|
+
"en": "value",
|
|
339
|
+
"de": "Wert",
|
|
340
|
+
"ru": "стоимость",
|
|
341
|
+
"pt": "valor",
|
|
342
|
+
"nl": "waarde",
|
|
343
|
+
"fr": "valeur",
|
|
344
|
+
"it": "valore",
|
|
345
|
+
"es": "valor",
|
|
346
|
+
"pl": "wartość",
|
|
347
|
+
"uk": "значення",
|
|
348
|
+
"zh-cn": "价值"
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
// eslint-disable-next-line no-undef
|
|
352
|
+
Blockly.Sendto.blocks["lorawanSetDownlink"] =
|
|
353
|
+
"<block type='lorawanSetDownlink'>"
|
|
354
|
+
+ " <value name='INSTANCE'>"
|
|
355
|
+
+ " </value>"
|
|
356
|
+
+ " <value name='deviceEUI'>"
|
|
357
|
+
+ " <shadow type='text'>"
|
|
358
|
+
+ " <field name='TEXT'>text</field>"
|
|
359
|
+
+ " </shadow>"
|
|
360
|
+
+ " </value>"
|
|
361
|
+
+ " <value name='downlink'>"
|
|
362
|
+
+ " <shadow type='text'>"
|
|
363
|
+
+ " <field name='TEXT'>text</field>"
|
|
364
|
+
+ " </shadow>"
|
|
365
|
+
+ " </value>"
|
|
366
|
+
+ " <value name='value'>"
|
|
367
|
+
+ " <shadow type='text'>"
|
|
368
|
+
+ " <field name='text'></field>"
|
|
369
|
+
+ " </shadow>"
|
|
370
|
+
+ " </value>"
|
|
371
|
+
+ "</block>";
|
|
372
|
+
|
|
373
|
+
// eslint-disable-next-line no-undef
|
|
374
|
+
Blockly.Blocks["lorawanSetDownlink"] = {
|
|
375
|
+
init: function() {
|
|
376
|
+
const options = [[Blockly.Translate("anyInstance"), ""]];
|
|
377
|
+
if (typeof main !== "undefined" && main.instances) {
|
|
378
|
+
for (let i = 0; i < main.instances.length; i++) {
|
|
379
|
+
let m = main.instances[i].match(/^system.adapter.lorawan.(\d+)$/);
|
|
380
|
+
if (m) {
|
|
381
|
+
// eslint-disable-next-line prefer-const
|
|
382
|
+
let k = parseInt(m[1], 10);
|
|
383
|
+
options.push(["lorawan." + k, "." + k]);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
if (options.length === 0) {
|
|
387
|
+
for (let u = 0; u <= 4; u++) {
|
|
388
|
+
options.push(["lorawan." + u, "." + u]);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
} else {
|
|
392
|
+
for (let n = 0; n <= 4; n++) {
|
|
393
|
+
options.push(["lorawan." + n, "." + n]);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
this.appendDummyInput("INSTANCE")
|
|
398
|
+
.appendField(Blockly.Translate("lorawanSetDownlink"))
|
|
399
|
+
.appendField(new Blockly.FieldDropdown(options), "INSTANCE");
|
|
400
|
+
|
|
401
|
+
this.appendValueInput("deviceEUI")
|
|
402
|
+
.appendField(Blockly.Translate("lorawanDeviceEUI"));
|
|
403
|
+
|
|
404
|
+
this.appendValueInput("downlink")
|
|
405
|
+
.appendField(Blockly.Translate("lorawanDownlink"));
|
|
406
|
+
|
|
407
|
+
this.appendValueInput("value")
|
|
408
|
+
.appendField(Blockly.Translate("lorawanValue"));
|
|
409
|
+
|
|
410
|
+
this.appendStatementInput("result");
|
|
411
|
+
|
|
412
|
+
this.setInputsInline(false);
|
|
413
|
+
this.setPreviousStatement(true, null);
|
|
414
|
+
this.setNextStatement(true, null);
|
|
415
|
+
|
|
416
|
+
this.setColour(Blockly.Sendto.HUE);
|
|
417
|
+
this.setTooltip(Blockly.Translate("lorawanSetDownlinktooltip"));
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
Blockly.JavaScript["lorawanSetDownlink"] = function(block){
|
|
422
|
+
const value_devEUI = Blockly.JavaScript.valueToCode(block, "deviceEUI", Blockly.JavaScript.ORDER_ATOMIC);
|
|
423
|
+
const value_downlink = Blockly.JavaScript.valueToCode(block, "downlink", Blockly.JavaScript.ORDER_ATOMIC);
|
|
424
|
+
const value_value = Blockly.JavaScript.valueToCode(block, "value", Blockly.JavaScript.ORDER_ATOMIC);
|
|
425
|
+
const code_result = Blockly.JavaScript.statementToCode(block, "result");
|
|
426
|
+
|
|
427
|
+
// build code
|
|
428
|
+
const objParameter = [];
|
|
429
|
+
objParameter.push("deviceEUI:" + value_devEUI);
|
|
430
|
+
objParameter.push("downlink:" + value_downlink);
|
|
431
|
+
objParameter.push("value:" + value_value);
|
|
432
|
+
const objEnd = [];
|
|
433
|
+
if(code_result){
|
|
434
|
+
objEnd.push(`, async (result) => {${code_result}});`);
|
|
435
|
+
}
|
|
436
|
+
else{
|
|
437
|
+
objEnd.push(`);`);
|
|
438
|
+
}
|
|
439
|
+
return `sendTo("lorawan${block.getFieldValue("INSTANCE")}", "setDownlink", {${objParameter.join(",")}}${objEnd}`;
|
|
440
|
+
};
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "lorawan",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.3.0": {
|
|
7
|
+
"en": "define user friendly Blockly Blocks with result",
|
|
8
|
+
"de": "benutzerfreundlich definieren Blockly Blocks mit Ergebnis",
|
|
9
|
+
"ru": "определение пользователя Блоки с результатом",
|
|
10
|
+
"pt": "definir amigável Blocos com resultado",
|
|
11
|
+
"nl": "gebruikersvriendelijk definiëren Blokkeren met resultaat",
|
|
12
|
+
"fr": "définir une utilisation conviviale Blocs avec résultat",
|
|
13
|
+
"it": "definire l'utente amichevole Blocchi Blockly con risultato",
|
|
14
|
+
"es": "definir fácil de usar Bloqueo bloques con resultado",
|
|
15
|
+
"pl": "zdefiniować przyjazny dla użytkownika Blokady z wynikiem",
|
|
16
|
+
"uk": "визначення дружності користувача Блокнотні блоки з результатом",
|
|
17
|
+
"zh-cn": "定义用户友好 块状块及结果"
|
|
18
|
+
},
|
|
19
|
+
"0.2.1": {
|
|
20
|
+
"en": "check types of messaging values and implements more blockly blocks",
|
|
21
|
+
"de": "überprüfen sie die arten der messaging-werte und implementiert mehr blockweise blöcke",
|
|
22
|
+
"ru": "проверить типы значений обмена сообщениями и реализовать более блоков",
|
|
23
|
+
"pt": "verificar os tipos de valores de mensagens e implementa blocos mais bloqueados",
|
|
24
|
+
"nl": "controleer soorten messaging waarden en implementeert meer blokken",
|
|
25
|
+
"fr": "vérifier les types de valeurs de messagerie et implémente des blocs plus bloc",
|
|
26
|
+
"it": "controllare i tipi di valori di messaggistica e implementa più blocchi bloccati",
|
|
27
|
+
"es": "comprobar tipos de valores de mensajería e implementar bloques más bloque",
|
|
28
|
+
"pl": "sprawdzają typy wartości wiadomości i wdrażają blokowane bloki",
|
|
29
|
+
"uk": "перевіряти типи значень обміну повідомленнями та реалізовувати більше блоків",
|
|
30
|
+
"zh-cn": "检查消息值的类型, 执行更多块"
|
|
31
|
+
},
|
|
6
32
|
"0.2.0": {
|
|
7
33
|
"en": "more functionality in messageing",
|
|
8
34
|
"de": "mehr funktionalität in der meldung",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "domyślna zmiana crc",
|
|
68
94
|
"uk": "за замовчуванням змінного струму",
|
|
69
95
|
"zh-cn": "默认 crc 已更改"
|
|
70
|
-
},
|
|
71
|
-
"0.1.9": {
|
|
72
|
-
"en": "crc calculation improoved",
|
|
73
|
-
"de": "cc berechnung improoviert",
|
|
74
|
-
"ru": "crccalc improov",
|
|
75
|
-
"pt": "cálculo de crc improoved",
|
|
76
|
-
"nl": "crc berekening geïmproviseerd",
|
|
77
|
-
"fr": "calcul crc réalisé",
|
|
78
|
-
"it": "crc calcolo improvato",
|
|
79
|
-
"es": "crc cálculo improvido",
|
|
80
|
-
"pl": "crc obliczenia improuved",
|
|
81
|
-
"uk": "розрахунок обертів",
|
|
82
|
-
"zh-cn": "crc 计算未启动"
|
|
83
|
-
},
|
|
84
|
-
"0.1.8": {
|
|
85
|
-
"en": "implement crc calculation",
|
|
86
|
-
"de": "ck-berechnung implementieren",
|
|
87
|
-
"ru": "целевые вычисления",
|
|
88
|
-
"pt": "cálculo de crc de implementação",
|
|
89
|
-
"nl": "crc berekening uitvoeren",
|
|
90
|
-
"fr": "mettre en œuvre le calcul crc",
|
|
91
|
-
"it": "implementare il calcolo crc",
|
|
92
|
-
"es": "cálculo de crc",
|
|
93
|
-
"pl": "implementation crc calculation",
|
|
94
|
-
"uk": "реалізація розрахунку кришки",
|
|
95
|
-
"zh-cn": "执行计算"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"title": "LoRaWAN",
|
|
@@ -143,6 +143,7 @@
|
|
|
143
143
|
"connectionType": "cloud",
|
|
144
144
|
"messagebox": true,
|
|
145
145
|
"dataSource": "push",
|
|
146
|
+
"blockly": true,
|
|
146
147
|
"adminUI": {
|
|
147
148
|
"config": "json"
|
|
148
149
|
},
|
|
@@ -13,9 +13,11 @@ class directorieshandlerClass {
|
|
|
13
13
|
|
|
14
14
|
this.reachableSubfolders = {
|
|
15
15
|
configuration: "configuration",
|
|
16
|
+
uplink: "uplink",
|
|
16
17
|
uplinkDecoded: "uplink.decoded",
|
|
17
18
|
uplinkRaw: "uplink.raw",
|
|
18
19
|
uplinkRemaining: "uplink.remaining",
|
|
20
|
+
downlink: "downlink",
|
|
19
21
|
downlinkRaw: "downlink.raw",
|
|
20
22
|
downlinkControl: "downlink.control",
|
|
21
23
|
downlinkRemaining: "downlink.remaining",
|
|
@@ -200,7 +202,7 @@ class directorieshandlerClass {
|
|
|
200
202
|
role: stateCommonRole,
|
|
201
203
|
read: stateCommonRole !== "button",
|
|
202
204
|
unit: obj[elementName]? obj[elementName].CommonStateUnit? obj[elementName].CommonStateUnit : "" : "",
|
|
203
|
-
def: obj[elementName]? obj[elementName].stateCommonDef? obj[elementName].stateCommonDef: stateCommonType === "boolean"? false : stateCommonType === "number"? 0: "": stateCommonType === "number"? 0: "",
|
|
205
|
+
def: obj[elementName] || typeof obj[elementName] === "boolean" ? obj[elementName].stateCommonDef? obj[elementName].stateCommonDef: stateCommonType === "boolean"? false : stateCommonType === "number"? 0: "": stateCommonType === "number"? 0: "",
|
|
204
206
|
write: stateCommonWrite
|
|
205
207
|
},
|
|
206
208
|
native: {},
|
|
@@ -113,7 +113,7 @@ class messagehandlerClass {
|
|
|
113
113
|
else if(stateCommonType === "number"){
|
|
114
114
|
stateCommonMax = 1000000;
|
|
115
115
|
}
|
|
116
|
-
await this.adapter.extendObjectAsync(`${deviceStartdirectory}.
|
|
116
|
+
await this.adapter.extendObjectAsync(`${deviceStartdirectory}.${this.directoryhandler.reachableSubfolders.downlinkControl}.${downlinkParameter.name}`,{
|
|
117
117
|
type: "state",
|
|
118
118
|
common: {
|
|
119
119
|
name: "",
|
package/main.js
CHANGED
|
@@ -375,7 +375,7 @@ class Lorawan extends utils.Adapter {
|
|
|
375
375
|
return id;
|
|
376
376
|
}
|
|
377
377
|
|
|
378
|
-
// Get
|
|
378
|
+
// Get Changeinfo in case of device EUI (used more times in onMessage)
|
|
379
379
|
async getChangeInfoFromDeviceEUI(deviceUI,subId){
|
|
380
380
|
let changeInfo = undefined;
|
|
381
381
|
const adapterObjects = await this.getAdapterObjectsAsync();
|
|
@@ -396,8 +396,10 @@ class Lorawan extends utils.Adapter {
|
|
|
396
396
|
// * Using this method requires "common.messagebox" property to be set to true in io-package.json
|
|
397
397
|
// * @param {ioBroker.Message} obj
|
|
398
398
|
// */
|
|
399
|
+
|
|
399
400
|
async onMessage(obj){
|
|
400
401
|
const activeFunction = "onMessage";
|
|
402
|
+
this.log.debug(`message recieved: command = ${obj.command} - message = ${JSON.stringify(obj.message)}`);
|
|
401
403
|
try{
|
|
402
404
|
if (typeof obj === "object" && obj.message){
|
|
403
405
|
let result = {};
|
|
@@ -417,72 +419,86 @@ class Lorawan extends utils.Adapter {
|
|
|
417
419
|
// Send response
|
|
418
420
|
if (obj.callback) this.sendTo(obj.from, obj.command, result, obj.callback);
|
|
419
421
|
}
|
|
420
|
-
else if (obj.command === "
|
|
421
|
-
if(obj.message.deviceEUI && obj.message.
|
|
422
|
-
const
|
|
422
|
+
else if (obj.command === "getUplink"){
|
|
423
|
+
if(obj.message.deviceEUI && obj.message.uplink){
|
|
424
|
+
const folderAndUplinkId = obj.message.subfolder? `${this.messagehandler?.directoryhandler.reachableSubfolders.uplink}.${obj.message.subfolder}.${obj.message.uplink}`: obj.message.uplink;
|
|
425
|
+
const changeInfo = await this.getChangeInfoFromDeviceEUI(obj.message.deviceEUI,folderAndUplinkId);
|
|
423
426
|
if(changeInfo){
|
|
424
|
-
const
|
|
425
|
-
if(await this.objectExists(
|
|
426
|
-
const
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
// Check limit
|
|
430
|
-
if((!downlinkParameter.limitMin || obj.message.value >= downlinkParameter.limitMinValue) && (!downlinkParameter.limitMax || obj.message.value <= downlinkParameter.limitMaxValue)){
|
|
431
|
-
await this.setStateAsync(downlinkId,obj.message.value);
|
|
432
|
-
result = {applicationId: changeInfo.applicationId, deviceEUI: changeInfo.deviceEUI, deviceId: changeInfo.deviceId, deviceType: changeInfo.deviceType,downlink: obj.message.downlink, value: obj.message.value};
|
|
433
|
-
}
|
|
434
|
-
else{
|
|
435
|
-
result = {error:true, message:"value is not in valid range"};
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
// downlinkvalue not a number
|
|
439
|
-
else{
|
|
440
|
-
await this.setStateAsync(downlinkId,obj.message.value);
|
|
441
|
-
result = {applicationId: changeInfo.applicationId, deviceEUI: changeInfo.deviceEUI, deviceId: changeInfo.deviceId, deviceType: changeInfo.deviceType, downlink: obj.message.downlink, value: obj.message.value};
|
|
427
|
+
const uplinkId = changeInfo.id;
|
|
428
|
+
if(await this.objectExists(uplinkId)){
|
|
429
|
+
const stateResult = await this.getStateAsync(changeInfo.id);
|
|
430
|
+
if(stateResult){
|
|
431
|
+
result = {applicationId: changeInfo.applicationId, deviceEUI: changeInfo.deviceEUI, deviceId: changeInfo.deviceId, deviceType: changeInfo.deviceType, value: stateResult.val, recieved:obj.message};
|
|
442
432
|
}
|
|
443
433
|
}
|
|
444
434
|
else{
|
|
445
|
-
result = {error:true, message:"No
|
|
435
|
+
result = {error:true, message:"No uplink matches", recieved:obj.message};
|
|
446
436
|
}
|
|
447
437
|
}
|
|
448
438
|
else{
|
|
449
|
-
result = {error:true, message:"No device found"};
|
|
439
|
+
result = {error:true, message:"No device found", recieved:obj.message};
|
|
450
440
|
}
|
|
451
441
|
}
|
|
452
442
|
else{
|
|
453
|
-
result = {error:true, message:"No deviceEUI
|
|
443
|
+
result = {error:true, message:"No deviceEUI & uplink found", recieved:obj.message};
|
|
454
444
|
}
|
|
455
445
|
// Send response
|
|
456
446
|
if (obj.callback) this.sendTo(obj.from, obj.command, result, obj.callback);
|
|
457
447
|
}
|
|
458
|
-
else if (obj.command === "
|
|
459
|
-
if(obj.message.deviceEUI && obj.message.
|
|
460
|
-
const changeInfo = await this.getChangeInfoFromDeviceEUI(obj.message.deviceEUI,`${this.messagehandler?.directoryhandler.reachableSubfolders.
|
|
448
|
+
else if (obj.command === "setDownlink"){
|
|
449
|
+
if(obj.message.deviceEUI && obj.message.downlink && (obj.message.value || obj.message.value === false)){
|
|
450
|
+
const changeInfo = await this.getChangeInfoFromDeviceEUI(obj.message.deviceEUI,`${this.messagehandler?.directoryhandler.reachableSubfolders.downlinkControl}.${obj.message.downlink}`);
|
|
461
451
|
if(changeInfo){
|
|
462
|
-
const
|
|
463
|
-
if(await this.objectExists(
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
452
|
+
const downlinkId = changeInfo.id;
|
|
453
|
+
if(await this.objectExists(downlinkId)){
|
|
454
|
+
// get Object to decide min and max value
|
|
455
|
+
const downlinkObject = await this.getObjectAsync(downlinkId);
|
|
456
|
+
if(downlinkObject){
|
|
457
|
+
// check typ number
|
|
458
|
+
if(downlinkObject.common.type === "number"){
|
|
459
|
+
if(typeof obj.message.value === "number"){
|
|
460
|
+
// Check limit
|
|
461
|
+
if((!downlinkObject.common.min || obj.message.value >= downlinkObject.common.min) && (!downlinkObject.common.max || obj.message.value <= downlinkObject.common.max)){
|
|
462
|
+
await this.setStateAsync(downlinkId,obj.message.value);
|
|
463
|
+
result = {applicationId: changeInfo.applicationId, deviceEUI: changeInfo.deviceEUI, deviceId: changeInfo.deviceId, deviceType: changeInfo.deviceType,downlink: obj.message.downlink, value: obj.message.value, recieved:obj.message};
|
|
464
|
+
}
|
|
465
|
+
else{
|
|
466
|
+
result = {error:true, message:"value is not in valid range", recieved:obj.message};
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
else{
|
|
470
|
+
result = {error:true, message: `downlink is type number, but recieved ${typeof obj.message.value}`, recieved:obj.message};
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
// downlinkobject is not a number
|
|
474
|
+
else{
|
|
475
|
+
if(downlinkObject.common.type !== typeof obj.message.value){
|
|
476
|
+
result = {error:true, message: `downlink is type ${downlinkObject.common.type}, but recieved ${typeof obj.message.value}`, recieved:obj.message};
|
|
477
|
+
}
|
|
478
|
+
else{
|
|
479
|
+
await this.setStateAsync(downlinkId,obj.message.value);
|
|
480
|
+
result = {applicationId: changeInfo.applicationId, deviceEUI: changeInfo.deviceEUI, deviceId: changeInfo.deviceId, deviceType: changeInfo.deviceType, downlink: obj.message.downlink, value: obj.message.value, recieved:obj.message};
|
|
481
|
+
}
|
|
482
|
+
}
|
|
467
483
|
}
|
|
468
484
|
}
|
|
469
485
|
else{
|
|
470
|
-
result = {error:true, message:"No
|
|
486
|
+
result = {error:true, message:"No downlink matches", recieved:obj.message};
|
|
471
487
|
}
|
|
472
488
|
}
|
|
473
489
|
else{
|
|
474
|
-
result = {error:true, message:"No device found"};
|
|
490
|
+
result = {error:true, message:"No device found", recieved:obj.message};
|
|
475
491
|
}
|
|
476
492
|
}
|
|
477
493
|
else{
|
|
478
|
-
result = {error:true, message:"No deviceEUI &
|
|
494
|
+
result = {error:true, message:"No deviceEUI, downlink & value found", recieved:obj.message};
|
|
479
495
|
}
|
|
480
496
|
// Send response
|
|
481
497
|
if (obj.callback) this.sendTo(obj.from, obj.command, result, obj.callback);
|
|
482
498
|
}
|
|
483
499
|
else
|
|
484
500
|
{
|
|
485
|
-
const result = {error:true, message: "No message matched"};
|
|
501
|
+
const result = {error:true, message: "No message matched", recieved:obj.message};
|
|
486
502
|
if (obj.callback) this.sendTo(obj.from, obj.command, result, obj.callback);
|
|
487
503
|
}
|
|
488
504
|
}
|