Wiki source code of 2 Script

Last modified by Devin Chen on 2025/12/10 10:32

Show last authors
1 = **1 General Script Demo** =
2
3 == **1.1 Address Operation** ==
4
5 (((
6 Write/Read data from address A to B**. **For example:transfer D2 to D0
7 )))
8
9 (% style="text-align:center" %)
10 [[image:1624245865976-320.png||height="182" width="1000" class="img-thumbnail"]]
11
12 Depend on diffferent format of data.V-Box use different script functions.
13 for example. addr_setshort(addr,num) Function: Write 16-bit signed decimal address
14 addr_getshort(addr) Function:Read 16-bit signed decimal address
15 addr_getword(string addr)Function: Read 16-bit unsigned decimal address
16 More script function are in the second section of [[“V-BOX Script Interface Manual”>>doc:V-BOX.V-Net.Manual.04 Lua Script.01 Lua Functions.WebHome]]
17
18 == **1.2 Arithmetic** ==
19
20 (% style="text-align:center" %)
21 [[image:1624249623612-177.png||height="337" width="400" class="img-thumbnail"]]
22
23 == **1.3 Set 100 to D0~-~-D19** ==
24
25 (% style="text-align:center" %)
26 [[image:1624249693457-742.png||height="135" width="400" class="img-thumbnail"]]
27
28 == **1.4 Short message** ==
29
30 The following demo shows that when the alarm condition is reached: temp1 > 50 (lasts more than 5 seconds) , then send an "alarm trigger" sms.
31
32 When the alarm condition is released,then send an  "alarm release" sms.
33
34 Real-time tags setting
35 [[image:1757401730077-284.png]]
36
37 Script is as below:
38
39 {{code language="lua"}}
40 function sms.main()
41 ------send condition------
42 local temp1 = addr_getword("@Temperature1")
43 local timer = addr_getword("@Timer")
44 local tag = addr_getbit("@Tag")
45 local tag2 = addr_getbit("@Y0")
46 local sms_timer = addr_getword("@SMSTimer")
47 local sms_id = addr_getword("@id") -- SMS ID
48
49 ------lasting time------
50 if temp1 > 50 then
51 timer = timer + 1
52 addr_setword("@Timer", timer)
53 else
54 timer = 0
55 addr_setword("@Timer", timer)
56 end
57
58 ------send sms & output Y0------
59 if timer > 5 then
60 if tag == 0 then
61 --send SMS to 2 number
62 local id = send_sms_ira("198****4800", "alarm trigger")
63 local id = send_sms_ira("187****3130", "alarm trigger")
64 addr_setword("@id", id) -- Store SMS ID to dedicated variable
65 addr_setbit("@Tag", 1)
66 addr_setword("@SMSTimer", 0) -- Reset SMS status check timer
67 else
68 -- If SMS already sent, increment timer
69 sms_timer = sms_timer + 1
70 addr_setword("@SMSTimer", sms_timer)
71
72 -- Check SMS status after 20 seconds
73 if sms_timer >= 20 then
74 local state = sms_get_state(sms_id)
75 addr_setword("@state", state)
76 addr_setword("@SMSTimer", 0) -- Reset timer
77 end
78 end
79 elseif tag == 1 then
80 -- Send alarm release SMS
81 send_sms_ira("198****4800","alarm release")
82 send_sms_ira("187****3130", "alarm release")
83 addr_setbit("@Tag", 0)
84 addr_setword("@SMSTimer", 0) -- Reset timer
85 end
86 end
87 {{/code}}
88
89 == **1.5 Telegram notification** ==
90
91 This example shows how to use the Bot API to send message into Telegram group or channel. When monitoring bit "@HDX" changes, it will trigger and send the message. Please replace with your own Token and chat id.
92
93 As for How to get the botToken and chatID, please check the following videos:
94
95 [[https:~~/~~/www.youtube.com/watch?v=zh6yYlnjX7k>>https://www.youtube.com/watch?v=zh6yYlnjX7k]]
96
97 [[https:~~/~~/www.youtube.com/watch?v=Pj8mwuMZZvg>>https://www.youtube.com/watch?v=Pj8mwuMZZvg]]
98
99
100 If when you follow the second video to get chatID and there is a display like the following, you can change "getUpdates" to "deleteWebhook" to solve in website.
101
102
103 (% style="text-align:center" %)
104 [[image:6Z7mdnm13p.png]]
105
106
107 (% style="text-align:center" %)
108 [[image:WjE1P2yxIA.png]]
109
110 After deleting Webhook, you can change to "getUpdates" and continue to follow the second video. 
111
112
113 (% style="text-align:center" %)
114 [[image:zl6CJlwhER.png]]
115
116 (% class="box infomessage" %)
117 (((
118 Note: Bots added to Groups or Channels need to be provided with administrator rights.
119 )))
120
121 === 1.Permissions ===
122
123 Bots added to Groups or Channels need to be provided with administrator rights. For example "joe" is bot I created.
124
125
126 (% style="text-align:center" %)
127 [[image:3GS3dP01Wx.png]]
128
129 (% style="text-align:center" %)
130 [[image:eEyv361VZs.png]]
131
132
133 === 2.URL check ===
134
135 You can use the URL to test the status of a group or channel.
136
137 url = "https:~/~/api.telegram.org/bot"..telegramBotToken.."/sendMessage?text="..message.."&chat_id="..telegramChatID
138
139 (% style="text-align:center" %)
140 [[image:telegram URL.png]]
141
142 === 3.Script ===
143
144 {{code language="Lua"}}
145 local tempBit = 0
146 local tempWord = 0
147
148 local botToken = "5504549693:AAEy6a5G-sOF3CINONxMNABeYnoS4ABVlfg"
149 local chatID = "-641959124"--The chat id from Channel or Group
150
151 local https = require("https")
152 local json = require("json")
153
154 -- Send http.get request and return response result
155 function getHttpsUrl(url)
156 local body = {}
157 local bodyJson = json.encode(body)
158 local header = {}
159 header["content-type"] = "application/json"
160 local result_table, code, headers, status = https.request(url, bodyJson)
161 print("code:"..code)
162 if code~= 200 then
163 return
164 else
165 return body
166 end
167 end
168
169 function sendAlarm(telegramBotToken, message, telegramChatID)
170 local url = "https://api.telegram.org/bot"..telegramBotToken.."/sendMessage?text="..message.."&chat_id="..telegramChatID
171 --local url = 'http://v-box.net'
172 --local url = 'https://www.google.com/'
173 print("Get the link:"..url)
174 getHttpsUrl(url)
175 end
176
177
178 function AlarmNotificate.main()
179 local bitValue = addr_getbit("@HDX");
180 local message = ''
181 print("b=="..bitValue)
182 if bitValue == 1 and bitValue ~= tempBit then
183 message = 'Alarm triggered, the monitoring point test value is '.. bitValue
184 sendAlarm(botToken, message, chatID)
185 print("Notification pushed of triggering alarm,"..bitValue)
186 elseif bitValue == 0 and bitValue ~= tempBit then
187 message = 'Alarm dismissed, the monitoring point test value is '.. bitValue
188 sendAlarm(botToken, message, chatID)
189 print("Notification pushed of dismissing alarm,"..bitValue)
190 end
191 tempBit = bitValue----Prevent monitoring values from continuous being sent to the platform
192
193 local wordValue = addr_getword("@HDW10")
194 print("w=="..wordValue)
195 --dosomething
196 if wordValue >= 100 and wordValue ~= tempWord and tempWord <= 100 then
197 message = 'Word alarm triggered, the word value is '.. wordValue
198 sendAlarm(botToken, message, chatID)
199 print("Notification pushed of triggering alarm,"..wordValue)
200 elseif wordValue < 100 and wordValue ~= tempWord and tempWord >= 100 then
201 message = 'Word alarm dismissed, the word value is '.. wordValue
202 sendAlarm(botToken, message, chatID)
203 print("Notification pushed of dismissing alarm,"..wordValue)
204 end
205 tempWord = wordValue----Prevent monitoring values from continuous being sent to the platform
206 end
207 {{/code}}
208
209 [[image:1715678008611-743.png]]
210
211 (% class="box infomessage" %)
212 (((
213 Note: The name of script must be the same as the main function.
214 )))
215
216 == **1.6 LINE Notify(Not available)** ==
217
218 {{info}}
219 The following scripts are no longer available because the related API service has been discontinued.
220 {{/info}}
221
222 This example shows how to use the LINE Notify to send message into LINE group. When monitoring bit "@test" changes, it will trigger and send the message. Please replace with your own Token.
223
224 {{code language="lua"}}
225 local tempBit = 0
226 local tempWord = 0
227
228 local LineToken = "08XCpubkOdwGdGgRTXF0x8umiyrALtoM0v6lBFUV6PC"
229
230 local https = require("https")
231 local json = require("json")
232 local ltn12 = require("ltn12")
233
234 -- Send http.get request and return response result
235 function getHttpsUrl(url,header,reqbody)
236 local body = {}
237 local bodyJson = json.encode(body)
238 local result_table, code, headers, status = https.request{
239 method = "POST",
240 url = url,
241 source = ltn12.source.string(reqbody),
242 headers = header,
243 sink = ltn12.sink.table(body)
244 }
245 print("code:"..code)
246 if code~= 200 then
247 return
248 else
249 return body
250 end
251 end
252
253 function getMessageUrl(lineMessage)
254 local url = "https://notify-api.line.me/api/notify"
255 local reqMess = "message="..lineMessage
256 local headers =
257 {
258 ["Authorization"] = "Bearer "..LineToken,
259 ["Content-Type"] = "application/x-www-form-urlencoded",
260 ["Content-Length"] = #reqMess
261 }
262
263 print("Get the link:"..url)
264 getHttpsUrl(url, headers, reqMess)
265 end
266
267
268 function linenotify.main()
269 local bitValue = addr_getbit("@test");
270 local message = ''
271 print("b=="..bitValue)
272 if bitValue == 1 and bitValue ~= tempBit then
273 message = 'Alarm V-Box triggered, the output is '.. bitValue
274 getMessageUrl(message)
275 print("Notification pushed of triggering alarm,"..bitValue)
276 elseif bitValue == 0 and bitValue ~= tempBit then
277 message = 'Alarm V-Box dismissed, the output is '.. bitValue
278 getMessageUrl(message)
279 print("Notification pushed of dismissing alarm,"..bitValue)
280 end
281 tempBit = bitValue----Prevent monitoring values from continuous being sent to the platform
282
283 local wordValue = addr_getword("@t2")
284 print("w=="..wordValue)
285 --dosomething
286 if wordValue >= 100 and wordValue ~= tempWord and tempWord <= 100 then
287 message = 'Alarm V-Box triggered, the temperature is '.. wordValue
288 getMessageUrl(message)
289 print("Notification pushed of triggering alarm,"..wordValue)
290 elseif wordValue < 100 and wordValue ~= tempWord and tempWord >= 100 then
291 message = 'Alarm V-Box dismissed, the temperature is '.. wordValue
292 getMessageUrl(message)
293 print("Notification pushed of dismissing alarm,"..wordValue)
294 end
295 tempWord = wordValue----Prevent monitoring values from continuous being sent to the platform
296 end
297 {{/code}}
298
299 == **1.7 Twilio WhatsApp Messaging** ==
300
301 This example shows how to use the Twilio API to send WhatsApp message to private number. When monitoring bit "@testBit" changes, it will trigger and send the message. Please replace with your own SID, Token, twilioPhoneNumber and receiverPhoneNumber.
302
303 About how to register the Twilio API, please check the following video:
304
305 [[https:~~/~~/www.youtube.com/watch?v=Id4lKichauU>>https://www.youtube.com/watch?v=Id4lKichauU]]
306
307 {{code language="Lua"}}
308 local tempBit = 0
309 local tempWord = 0
310
311 local https = require("https")
312 local json = require("json")
313 local ltn12 = require("ltn12")
314
315 local SID = 'AC1703bd710ffa98006d2bcc0b********'
316 local Token = 'd3c11897623c39e538b20263ec19****'
317
318 local twilioPhoneNumber = '+14155238886'
319 local receiverPhoneNumber = '+8615880018277'
320
321 local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
322 function encodingBase64(data)
323 return ((data:gsub('.', function(x)
324 local r,b='',x:byte()
325 for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
326 return r;
327 end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
328 if (#x < 6) then return '' end
329 local c=0
330 for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
331 return b:sub(c+1,c+1)
332 end)..({ '', '==', '=' })[#data%3+1])
333 end
334
335 function encodeUrl(str)
336 str = string.gsub(str, "([^%w%.%- ])", function(c)
337 return string.format("%%%02X", string.byte(c)) end)
338 return string.gsub(str, " ", "+")
339 end
340
341
342
343
344 function requestBodySplice(message, sender, receiver)
345 local reqBody = ''
346 local encodeMess = encodeUrl(message)
347 local encodeSend = encodeUrl(sender)
348 local encodeRece = encodeUrl(receiver)
349 --reqBody = "Body=Hello%20Wecon2&From=whatsapp%3A%2B14155238886&To=whatsapp%3A%2B8615880018277"
350 reqBody = string.format("Body=%s&From=whatsapp:%s&To=whatsapp:%s", encodeMess, encodeSend, encodeRece)
351 print(reqBody)
352 return reqBody
353 end
354
355
356 -- Send http.get request and return response result
357 function getHttpsUrl(url,header,reqbody)
358 local body = {}
359 local bodyJson = json.encode(body)
360 local result_table, code, headers, status = https.request{
361 method = "POST",
362 url = url,
363 source = ltn12.source.string(reqbody),
364 headers = header,
365 sink = ltn12.sink.table(body)
366 }
367 print("code:"..code)
368 if code~= 200 then
369 return
370 else
371 return body
372 end
373 end
374
375 function getMessageUrl(whatsAppMessage)
376 local auth = SID..':'..Token
377 local url = "https://api.twilio.com/2010-04-01/Accounts/"..SID.."/Messages"
378 --local reqMess = "message="..twilioMessage
379 local reqMess = requestBodySplice(whatsAppMessage, twilioPhoneNumber, receiverPhoneNumber)
380 local headers =
381 {
382 ["Authorization"] = "Basic "..encodingBase64(auth),
383 ["Content-Type"] = "application/x-www-form-urlencoded",
384 ["Content-Length"] = #reqMess
385 }
386
387 print("Get the link:"..url)
388 getHttpsUrl(url, headers, reqMess)
389 end
390
391
392
393 function Twilio.main()
394 --dosomething
395 --local auth = SID..':'..Token
396 --print(requestBodySplice("HelloWorld", twilioPhoneNumber, receiverPhoneNumber))
397 --print(encodingBase64(auth))
398 local bitValue = addr_getbit("@testBit");
399 local message = ''
400 print("b=="..bitValue)
401 if bitValue == 1 and bitValue ~= tempBit then
402 message = 'Alarm V-Box triggered, the output is '.. bitValue
403 getMessageUrl(message)
404 print("Notification pushed of triggering alarm,"..bitValue)
405 elseif bitValue == 0 and bitValue ~= tempBit then
406 message = 'Alarm V-Box dismissed, the output is '.. bitValue
407 getMessageUrl(message)
408 print("Notification pushed of dismissing alarm,"..bitValue)
409 end
410 tempBit = bitValue----Prevent monitoring values from continuous being sent to the platform
411
412 local wordValue = addr_getword("@testWord")
413 print("w=="..wordValue)
414 --dosomething
415 if wordValue >= 100 and wordValue ~= tempWord and tempWord <= 100 then
416 message = 'Alarm V-Box triggered, the temperature is '.. wordValue
417 getMessageUrl(message)
418 print("Notification pushed of triggering alarm,"..wordValue)
419 elseif wordValue < 100 and wordValue ~= tempWord and tempWord >= 100 then
420 message = 'Alarm V-Box dismissed, the temperature is '.. wordValue
421 getMessageUrl(message)
422 print("Notification pushed of dismissing alarm,"..wordValue)
423 end
424 tempWord = wordValue----Prevent monitoring values from continuous being sent to the platform
425 end
426 {{/code}}
427
428 == **1.8 HTTP response body** ==
429
430 This example use [[https:~~/~~/www.weatherapi.com/>>https://www.weatherapi.com/]] as example, to show how to parse value from HTTP response body. When we input the city name into address "@HDW5050":
431
432 (% style="text-align:center" %)
433 [[image:InputHTTPparameter.png]]
434
435 Then the response body would be like as following:
436
437 {{code language="json"}}
438 {
439 "location": {
440 "name": "Madrid",
441 "region": "Madrid",
442 "country": "Spain",
443 "lat": 40.4,
444 "lon": -3.68,
445 "tz_id": "Europe/Madrid",
446 "localtime_epoch": 1669022636,
447 "localtime": "2022-11-21 10:23"
448 },
449 "current": {
450 "last_updated_epoch": 1669022100,
451 "last_updated": "2022-11-21 10:15",
452 "temp_c": 13.0,
453 "temp_f": 55.4,
454 "is_day": 1,
455 "condition": {
456 "text": "Partly cloudy",
457 "icon": "//cdn.weatherapi.com/weather/64x64/day/116.png",
458 "code": 1003
459 },
460 "wind_mph": 11.9,
461 "wind_kph": 19.1,
462 "wind_degree": 210,
463 "wind_dir": "SSW",
464 "pressure_mb": 1015.0,
465 "pressure_in": 29.97,
466 "precip_mm": 0.0,
467 "precip_in": 0.0,
468 "humidity": 88,
469 "cloud": 75,
470 "feelslike_c": 10.8,
471 "feelslike_f": 51.4,
472 "vis_km": 10.0,
473 "vis_miles": 6.0,
474 "uv": 3.0,
475 "gust_mph": 22.1,
476 "gust_kph": 35.6
477 }
478 }
479 {{/code}}
480
481 (% class="wikigeneratedid" %)
482 So we decode json into lua object to assign the value into addresses HDW6060(temperature), HDW7070(humidity), the code example like follows:
483
484 {{code language="lua"}}
485 local APIkey = '70faaecf926b4341b1974006221711'
486
487
488 local http = require("socket.http")
489 local json = require("json")
490
491 -- Send http.get request and return response result
492 function getHttpsUrl(url)
493 local result_table, code, headers, status = http.request(url)
494 print("code:"..code)
495 if code~= 200 then
496 return
497 else
498 return result_table
499 end
500 end
501
502 function sendAPI(key, city)
503 local url = "http://api.weatherapi.com/v1/current.json?key="..key.."&q="..city.."&aqi=no"
504 --local url = 'http://v-box.net'
505 --local url = 'https://www.google.com/'
506 --http://api.weatherapi.com/v1/current.json?key=70faaecf926b4341b1974006221711&q=Barcelona&aqi=no
507 print("Get the link:"..url)
508 local body = getHttpsUrl(url)
509 --print(body)
510 local jsonBody = json.decode(body)
511 --print(jsonBody["current"]["temp_c"])
512 --print(type(jsonBody["current"]["temp_c"]))
513 --print(type(jsonBody["current"]["humidity"]))
514 addr_setfloat("@HDW6060", jsonBody["current"]["temp_c"])
515 addr_setword("@HDW7070", jsonBody["current"]["humidity"])
516 end
517
518
519 function Weather.main()
520 local cityName = addr_getstring("@HDW5050",6)
521 print("cityName: "..cityName)
522 sendAPI(APIkey, cityName)
523 end
524 {{/code}}
525
526 == **1.9 High-Low Byte Switch** ==
527
528 The following example is converting the floating number from order 1234 to order 3412, and formating output the number with 2 decimal point. About which high-low word order corresponding to which value, please refer to the [[Address Operation Table>>doc:V-BOX.V-Net.Manual.04 Lua Script.01 Lua Functions.WebHome||anchor="H2Addressoperation"]].
529
530 {{code language="lua"}}
531 function highLowByteSwitch(floatNumber)
532 addr_setfloat("@W_0#HDW23036",floatNumber,0,2)
533 local newFloat = addr_getfloat("@W_0#HDW23036")
534 local formattedFloat = string.format("%.2f",newFloat)
535 print("The formatted float value is the : "..formattedFloat)
536 return formattedFloat
537 end
538 {{/code}}
539
540 == **1.10 Read 64bits Unsigned Value** ==
541
542 In our built-in function library doesn't have the function for reading 64-bit unsigned format value, so the following function is for solve this. But if the number is greater 2^53, the precision will be lost. So the final result will be a little bit different from the original value
543
544 {{code language="lua"}}
545 function addr_getquatra(address)
546 local highAddress = addr_newnoaddr(address,2)
547 local low32 = addr_getdword(address)
548 local high32 = addr_getdword(highAddress)
549 --print("the low number is "..low32)
550 --print("the high number is "..high32)
551 local formatVal = string.format("%64.0f",2^32*high32+low32)
552 print("the format value is ".. formatVal)
553 return formatVal
554 end
555 {{/code}}
556
557 == **1.11 Bit-Activated Timer with Reset and Data Output** ==
558
559 This script implements a timer that increments while enabled (by a control bit) until reaching a threshold (5s), then resets the timer, disables itself, and sets an output data value.
560
561 (% style="text-align:center" %)
562 [[image:1749188641322-409.png]]
563
564 (% style="text-align:center" %)
565 [[image:1749189179543-849.png||height="300" width="571"]]
566
567 {{code language="lua"}}
568 function timer.main()
569 -- Read current state of control bit and timer value
570 local a = addr_getbit("@Bit") -- Get status of control bit (0 or 1)
571 local b = addr_getword("@Timer") -- Get current timer value (word/integer)
572
573 -- Increment phase: When activated and timer < threshold
574 if a == 1 and b < 5 then
575 b = b + 1 -- Increment timer value
576 addr_setword("@Timer", b) -- Update timer memory
577 print(b) -- Output current timer value (debug)
578 end
579
580 -- Reset phase: When timer reaches threshold
581 if b >= 5 then
582 addr_setword("@Timer", 0) -- Reset timer to 0
583 addr_setbit("@Bit", 0) -- Deactivate control bit
584 addr_setword("@Data", 10) -- Set output data to fixed value (10)
585 end
586 end
587 {{/code}}
588
589 == **1.12 Get UTC timestamp and local timezone timestamp** ==
590
591 This demo shows how to obtain UTC standard time from the V-Box and get the local time based on the device's time zone.
592
593 **Real-time tags configuration**
594
595 [[image:1757043722849-910.png]]
596
597 **Script configuration**
598
599 (% style="text-align:center" %)
600 [[image:1757043900216-610.png||height="412" width="439"]]
601
602 **Script**
603
604 {{code language="lua"}}
605 function time.main()
606
607 --Get Coordinated Universal Time
608 local timestamp = os.time()
609 local utcTimeTable = os.date("!*t", timestamp)
610 local utcTimestamp = os.time(utcTimeTable)
611 local formattedTime = os.date("%Y-%m-%d %H:%M:%S", utcTimestamp)
612
613 print("UTC: " ..formattedTime)
614
615 --Calculate the local time at the device's location
616 local utc_7Timestamp = os.time(utcTimeTable) + 25200 -- Enter the corresponding number of seconds based on the time difference,used UTC+7 as an example..
617 local formattedTime1 = os.date("%Y-%m-%d %H:%M:%S", utc_7Timestamp)
618 print("UTC+7: " .. formattedTime1)
619
620
621 --Assign the decomposed timestamp to the specified register
622 addr_setword("@UTC+7_Second",os.date("%S", utc_7Timestamp))
623 addr_setword("@UTC+7_Minute",os.date("%M", utc_7Timestamp))
624 addr_setword("@UTC+7_Hour",os.date("%H", utc_7Timestamp))
625 addr_setword("@UTC+7_Day",os.date("%d", utc_7Timestamp))
626 addr_setword("@UTC+7_Month",os.date("%m", utc_7Timestamp))
627 addr_setword("@UTC+7_Year",os.date("%Y", utc_7Timestamp))
628 print("--------------------------------------")
629
630 end
631 {{/code}}
632
633 **Result**
634
635 (% style="text-align:center" %)
636 [[image:1757044137457-543.png||height="468" width="708"]]
637
638 == **1.13 JSON encoding and decoding** ==
639
640 This demo shows how to encode tag values into JSON format and decode the JSON to assign data to new tags.
641
642 **Real-time tags configuration**
643
644 (% style="text-align:center" %)
645 [[image:PixPin_2025-11-05_09-21-33.png]]
646
647 (% class="wikigeneratedid" %)
648 **Script configuration**
649
650 (% style="text-align:center" %)
651 [[image:PixPin_2025-11-05_09-23-03.png||height="376" width="400"]]
652
653 (% class="wikigeneratedid" %)
654 **Script**
655
656 {{code language="lua"}}
657 function json_test.main()
658
659 -- Load JSON module for encoding and decoding JSON data
660 local json = require("json")
661
662 -- Read values from different types of address tags
663 local a = addr_getbit("@bit") -- Read a bit (boolean) value
664 local b = addr_getword("@word") -- Read a word (integer) value
665 local c = addr_getfloat("@floating number") -- Read a floating point value
666 local d = addr_getstring("@string",10) -- Read a string value with max length 10
667 local e = json.null -- JSON null value constant
668
669 -- Encode the data into JSON format
670 local jsondata = json.encode({
671 bit = a or 0, -- Bit value with default 0
672 word = b or 0, -- Word value with default 0
673 float = c or 0, -- Float value with default 0
674 str = d or 0, -- String value with default 0
675 {none= e} -- Nested table with null value
676 })
677 print("json encode:", jsondata) -- Print the encoded JSON data
678 print(".......................")
679
680 -- Decode the JSON string back to Lua table
681 local data = json.decode(jsondata)
682
683 -- Check if decoding was successful and print the results
684 if type(data) == 'table' then
685 print("json decode:")
686 -- Iterate through all key-value pairs in the decoded table
687 for k, v in pairs(data) do
688 print(k, v)
689 end
690 end
691 -- Write the decoded values back to corresponding address tags
692 addr_setbit("@bit_copy", data["bit"] or 0) -- Write bit value
693 addr_setword("@word_copy", data["word"] or 0) -- Write word value
694 addr_setfloat("@floating number_copy", data["float"] or 0) -- Write float value
695 addr_setstring("@string_copy", data["str"], 10) -- Write string value
696
697 print("-----------------------")
698
699 end
700 {{/code}}
701
702 (% class="wikigeneratedid" %)
703 **Result**
704
705 (% style="text-align:center" %)
706 [[image:1762306008662-362.png||height="485" width="1228"]]
707
708
709 = **2 Third part server** =
710
711 V-Box have two mode.One is for V-Net,User need to use WECON server to store data.We call this V-NET platform.
712
713 (% class="mark" %)1.Europe server:eu.v-box.net
714
715 (% class="mark" %)2.Asean server:asean.v-box.net
716
717 Second is for OpenCloud mode.It means V-Box data will transfer to third part server and do not want to store data to WECON server.We call OpenCloud paltform
718
719 OpenCloud platform is used in configuring the script.Then V-Box can connect with third part server.
720
721 Both mode can support script  to connect with third part server.the difference:
722
723 (% class="mark" %)1.If you want to store in WECON server ,please use V-NET.
724
725 (% class="mark" %)2.If your server requires SSL certificate to log in,please use OpenCloud.Because only OpenCloud platform can support to upload certificate
726
727 {{info}}
728 **✎Note: **Before program the script of MQTT, please make sure the server(MQTT broker) can be connected through MQTT Client tool.
729 {{/info}}
730
731 (% class="wikigeneratedid" %)
732 Tool link: **[[MQTT.fx>>http://mqttfx.jensd.de/index.php/download]]**
733
734 == **2.1 Test server(General Example)** ==
735
736 The following example is trying to publish to the topic "testtopic/test/no1/7890", and subscribe the topic "testtopic/test/no1/123456".
737
738 And the JSON message is like follows:
739
740 {{code language="JSON"}}
741 {
742 "timestamp": 1631152760,
743 "messageId": 1,
744 "event": "test_data",
745 "mfrs": "HMI/box",
746 "data":
747 {
748 "id" : 1436217747670454274,
749 "waterlevel" : 48,
750 "temperture" : 23
751 }
752 }
753 {{/code}}
754
755 {{code language="lua"}}
756 --MQTT configuration table
757 local MQTT_CFG={}
758 --if there is no need the username and password, please put them as ""
759 MQTT_CFG.username = "weconsupport"
760 MQTT_CFG.password = "123456"
761 MQTT_CFG.netway = 0
762 MQTT_CFG.keepalive = 60
763 MQTT_CFG.cleansession = 1
764 --TCP URL
765 MQTT_URL = "tcp://mq.tongxinmao.com:1883"
766 --Client ID
767 MQTT_CLIENT_ID = "V-BOXH-AG"
768
769 --Generate UUID
770 function uuid()
771 local seed = {'e','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}
772 local tb = {}
773 for i=1, 32 do
774 table.insert(tb, seed[math.random(1,16)])
775 end
776 local sid=table.concat(tb)
777 return string.format('%s',
778 string.sub(sid,1,32)
779 )
780 end
781
782
783 --Topic name to subscribed
784 local SUBSCRIBE_TOPIC = 'testtopic/test/no1/123456'
785
786 --Topic name to be published
787 local PUBLISH_TOPIC = 'testtopic/test/no1/7890'
788
789
790 --real time
791 local LAST_TIME = 0
792
793
794 --initialize mqtt
795 function mqtt_init()
796 print(string.format("mqtt init mqtt_url:%s mqtt_clientid:%s", MQTT_URL, MQTT_CLIENT_ID))
797 if g_mq then
798 mqtt.close(g_mq) --Close mqtt object
799 end
800 g_mq, err = mqtt.create(MQTT_URL, MQTT_CLIENT_ID) -- create mqtt object,and declare it as a global variable
801 if g_mq then
802 g_mq:on("message", mqtt_msg_callback) -- Register a callback for receiving messages
803 g_mq:on("offline", mqtt_msg_offline) -- Register a callback for offline
804 print("mqtt init success")
805 else
806 print("mqtt init failed:", err)
807 end
808 end
809
810 -- connect to mqtt
811 function mqtt_connect()
812 print("mqtt connecting...")
813 local stat, err = g_mq:connect(MQTT_CFG)
814 if stat == nil then
815 print("mqtt connect failed:", err)
816 return
817 else
818 print("mqtt connected")
819 end
820 g_mq:subscribe(SUBSCRIBE_TOPIC, 0)
821 end
822
823 --Offline callback function
824 function mqtt_msg_offline(cause)
825 print("mqtt offline, cause:", cause)
826 end
827
828 -- Received message callback function
829 function mqtt_msg_callback(topic, msg)
830 print("topic:", topic)
831 print("msg:", msg)
832 local objMsg = json.decode(msg)
833 local water = objMsg.data.waterlevel
834 local temp = objMsg.data.temperature
835 addr_setword("@HDW20",water)
836 addr_setword("@HDW10",temp)
837 end
838
839 --Send data (data upload to platform and encapsulate it with custom functions)
840 function send_data()
841 local pub_data = {
842 timestamp = os.time(),
843 messageId = 1,
844 event = 'test_data',
845 mfrs = 'V-Box',
846 data = {
847 id = uuid(),
848 waterlevel = addr_getword("@HDW10"),
849 temperature = addr_getword("@HDW20")
850 }
851 }
852 return g_mq:publish(PUBLISH_TOPIC, json.encode(pub_data), 0, 0)
853 end
854
855
856 --main function fixed timed execution
857 function MQTT.main()
858 --dosomething
859 print(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " main start")
860 --determine the mqtt object whether exist
861 if g_mq then
862 --determine the mqtt object whether has been connected or not
863 if g_mq:isconnected() then
864 send_data()
865 else
866 --if exceed 5 sec not connect, reconnect once
867 if os.time() - LAST_TIME > 5 then
868 LAST_TIME = os.time()
869 --reinitial the mqtt object
870 mqtt_init()
871 --connect to mqtt or reconnect
872 mqtt_connect()
873 end
874 end
875 else
876 --mqtt object does not exist so create new one
877 mqtt_init()
878 end
879 print(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " main end")
880 end
881 {{/code}}
882
883 == **2.2 Customer server:grouprobotinfo.com** ==
884
885 This demo does not use SSL certification. Script is as below
886
887 Demo1:
888
889 {{code language="lua"}}
890 -- Meta class
891 --main
892 function mq.main()
893 if not mq.m then
894 local err = ""
895
896 mq.m, err = mqtt.create("tcp://grouprobotinfo.com:1883", "ClienID") -- create connection
897 if mq.m then
898 mq.config = {
899 username = "",-- ID
900 password = "",-- password
901 netway = 1, -- Ethernet connection, WIFI=1
902 -- keepalive = 100, -- Optional, set the connection heartbeat interval for 100 seconds.
903 -- cleansession = 0, -- Optional, keep session
904 }
905 mq.m:on("message", function(topic, msg) -- Register for receiving message callbacks
906 local str = string.format("%s:%s", topic, msg)
907 -- print("mqtt msg:", str) -- Print out the received topics and content
908 end)
909 mq.m:on("offline", function (cause) -- Register for lost connection callbacks
910 -- addr_setstring("@xxx", "cause"..(cause or " got nil"))
911 end)
912 mq.m:on("arrived", function() -- Registration for sending messages to callbacks
913 print("msg arrived")
914 end)
915 else
916 print("mqtt create failed:", err) -- Create object failed
917 end
918 else
919 if mq.m:isconnected() then -- If online, post a message
920 local phaseStatus ="unknow"
921 if addr_getbit("@Standby")== 1 then
922 phaseStatus = "Standby"
923 elseif addr_getbit("@Pre-Freeze")==1 then
924 phaseStatus= "Pre-Freeze"
925 elseif addr_getbit("@Prepare")==1 then
926 phaseStatus ="Prepare"
927 elseif addr_getbit("@Primary Dry")==1 then
928 phaseStatus = "Primary dry"
929 elseif addr_getbit("@Secondary Dry")==1 then
930 phaseStatus = "Secondary Dry"
931 end
932 --print(addr_getbit("@Primary Dry"))
933 -------------------------------------------------------------------------------------------------------------------------
934 local activating ="unknow"
935 if addr_getbit("@Compressor")==1 then
936 activating = ",".."Compressor"
937 end
938 if addr_getbit("@Silicone Pump")==1 then
939 activating = activating..",".."Silicone Pump"
940 end
941 if addr_getbit("@Vacuum Pump")==1 then
942 activating = activating..",".."Vacuum Pump"
943 end
944 if addr_getbit("@Root Pump")==1 then
945 activating = activating..",".."Root Pump"
946 end
947 if addr_getbit("@Heater")==1 then
948 activating = activating..",".."Heater"
949 end
950 if addr_getbit("@Valve Silicone")==1 then
951 activating = activating..",".."Valve Silicone"
952 end
953 if addr_getbit("@Valve Ice Condenser")==1 then
954 activating = activating..",".."Valve Ice Condenser"
955 end
956 if addr_getbit("@Valve Vacuum Pump")==1 then
957 activating = activating..",".."Valve Vacuum Pump"
958 end
959 local pr_activating =string.sub(activating,2)
960 -- print(pr_activating)
961 local status_text ="unknow"
962 if addr_getbit("@Status Run")==1 then
963 status_text = "RUNNING"
964 else
965 status_text = "STOP"
966 end
967 -------------------------------------------------------------------------------------------------------------------------
968 local js = {type="status",
969 mc_name ="FD300",
970 status=status_text,
971 elapsed_time={
972 hour=addr_getword("@Elapsed Time (Hour)"),
973 min=addr_getword("@Elapsed Time (Minute)"),
974 sec=addr_getword("@Elapsed Time (Second)")
975 },
976 phase = phaseStatus,
977 step = addr_getword("@Step"),
978 activating_output = pr_activating,
979 sv=addr_getshort("@SV Silicone")/10,
980 pv=addr_getshort("@PV Silicone")/10,
981 product1=addr_getshort("@Product 1")/10,
982
983 product2=addr_getshort("@Product 2")/10,
984 product3=addr_getshort("@Product 3")/10,
985 product4=addr_getshort("@Product 4")/10,
986 ice1=addr_getshort("@Ice condenser 1")/10,
987 ice2=addr_getshort("@Ice condenser 2")/10,
988 vacuum=addr_getfloat("@Vacuum")
989 }
990 local jsAlarm = { HPC = addr_getbit("@B_25395#W0.00"),
991 ODPC = addr_getbit("@B_25395#W0.01"),
992 MTPC=addr_getbit("@B_25395#W0.02"),
993 HTT = addr_getbit("@B_25395#W1.03"),
994 CPC = addr_getbit("@B_25395#W0.08"),
995 CPSP =addr_getbit("@B_25395#W1.00"),
996 CPVP =addr_getbit("@B_25395#W0.10"),
997 CPRP =addr_getbit("@B_25395#W0.11"),
998 HP =addr_getbit("@B_25395#W1.01"),
999 PP= addr_getbit("@B_25395#W1.02"),
1000 PO=addr_getbit("@B_25395#W0.07"),
1001 FSE=addr_getbit("@B_25395#W2.04"),
1002 AVVSVV=addr_getbit("@B_25395#W1.12"),
1003 ICHT=addr_getbit("@B_25395#W3.06")
1004 }
1005 -- ("@B_25395#CIO1.02")
1006 mq.m:publish("mqtt-v-box-epsilon-fd300", json.encode(js) , 0, 0)
1007 mq.m:publish("mqtt-v-box-epsilon-alarm-fd300", json.encode(jsAlarm) , 0, 0)
1008 else
1009 local stat, err = mq.m:connect(mq.config) -- connection
1010 if stat == nil then --Determine whether to connect
1011 print("mqtt connect failed:", err)
1012 return -- Connection failed, return directly
1013 end
1014 mq.m:subscribe("mqtt-v-box-epsilon", 0)-- Subscribe to topics
1015
1016 end
1017 -- mq.m:unsubscribe("stc/test")
1018 -- mq.m:disconnect() -- close matt
1019 -- mq.m:close() -- close clase
1020 end
1021 end
1022 {{/code}}
1023
1024 == **2.3 Azure platform** ==
1025
1026 In this demo,V-Box connects with Azure by SSL certification.
1027
1028 Video link: [[https:~~/~~/youtu.be/cdI6rIQcpMY?list=PL_Bpnb2RgaksCic9HCcVAZhU9sYwCRKzW>>https://youtu.be/cdI6rIQcpMY?list=PL_Bpnb2RgaksCic9HCcVAZhU9sYwCRKzW]]
1029
1030 Tool Download link: [[https:~~/~~/wecon-disk.oss-ap-southeast-1.aliyuncs.com/Download/WIKI/V-BOX/Demo/Azure/Azure%20tool.zip>>https://wecon-disk.oss-ap-southeast-1.aliyuncs.com/Download/WIKI/V-BOX/Demo/Azure/Azure%20tool.zip]]
1031
1032 Script is as below
1033
1034 {{code language="lua"}}
1035 --https://support.huaweicloud.com/qs-IoT/iot_05_0005.html  mqtt.fx monitor to connect azure iot
1036 sprint = print
1037
1038 --Get custom configuration parameters (vbox custom information)
1039 --local CUSTOM = bns_get_config("bind")
1040 --local DS_ID = CUSTOM.DSID or "60a71ccbbbe12002c08f3a1a_WECON"
1041
1042
1043
1044 --Cloud mode interface to obtain the MQTT information configured by the cloud platform: (5 returns, namely the server address, client ID, connection table, last word table, certificate table)
1045 local MQTT_URL, MQTT_CLIENTID, MQTT_CFG, MQTT_LWT, MQTT_CART = mqtt.setup_cfg()
1046
1047 --MQTT_CFG.username = '60a71ccbbbe12002c08f3a1a_WECON'
1048 --MQTT_CFG.password='wecon123'
1049 --MQTT_CLIENTID = '60a71ccbbbe12002c08f3a1a_WECON_0_0_2021052110usernxame:60a71ccbbbe12002c08f3a1a_WECONpassword:a0a951581855aa8e0262129da6cf1b43f2c0ecfac4fa56117fc5a20c90be169a'
1050
1051 --publish to topics
1052 local pub_RE_TOPIC = string.format('devices/wecon_02/messages/events/')
1053 --Subscribe topics
1054 local Subscribe_RE_TOPIC1 = string.format('devices/wecon_02/messages/devicebound/#')
1055
1056 --variable
1057 local last_time = 0
1058
1059
1060
1061 --Timing main function
1062 function Azure.main()
1063
1064    sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " Azureiot.main start")
1065    if g_mq then
1066         if g_mq:isconnected() then
1067             send_Data()
1068         else
1069             if os.time() - last_time > 20 then
1070                 last_time = os.time()
1071                 mymqtt_connect()
1072             end
1073         end
1074     else
1075         mymqtt_init()
1076     end
1077     sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " Azureiot.main end")
1078 end
1079
1080 -- Initialize MQTT
1081 function mymqtt_init()
1082     sprint(string.format("mqtt init mqtt_url:%s mqtt_clientid:%s", MQTT_URL, MQTT_CLIENTID))
1083     g_mq, err = mqtt.create(MQTT_URL, MQTT_CLIENTID) -- Create the object and declare it as a global variable
1084     if g_mq then
1085         g_mq:on("message", mymqtt_msg_callback) -- Register to receive message callbacks
1086         sprint("mqtt init success")
1087     else
1088         sprint("mqtt init failed:", err)
1089     end
1090 end
1091
1092 -- Connect to MQTT server
1093 function mymqtt_connect()
1094     sprint("mqtt connecting...")
1095     local stat, err = g_mq:connect(MQTT_CFG,MQTT_LWT, MQTT_CART)
1096     if stat == nil then
1097         sprint("mqtt connect failed:", err)
1098         return
1099     else
1100         sprint("mqtt connected")
1101     end
1102     g_mq:subscribe(Subscribe_RE_TOPIC1, 0) 
1103 end
1104
1105 -- Receive MQTT message callback function
1106 function mymqtt_msg_callback(topic, msg)
1107     print("topic:",topic)
1108     print("revdata:",msg)
1109    -- local revData = json.decode(msg)
1110  --  if topic == Subscribe_RE_TOPIC1 then --Process topic information subscribed from the cloud
1111 -- if string.match(topic,Subscribe_RE_TOPIC1) then
1112      --   print("topi11:",topic)
1113        setValue(revData)
1114    -- end
1115 end
1116
1117 --Process the received data
1118 --function setValue(revData)
1119    -- if revData ~=nil then 
1120  --       for i,v in pairs(revData) do
1121   --          print("Data received:",i,v)
1122   --      end
1123    -- end
1124 --end
1125
1126 --Get real-time data
1127 function getData()
1128     local jdata = {}
1129     local addr = bns_get_alldata()
1130     print(json.encode(addr))
1131     for i,v in pairs(addr) do
1132         if v[2] == 1 then
1133            jdata[v[3]] = v[4]
1134         end
1135     end
1136     return jdata
1137 end 
1138
1139
1140
1141 --send data
1142 function send_Data()
1143     local pub_data = {100
1144      --   services={{
1145
1146             --serviceId ='Temperature',
1147            -- properties={
1148                -- value = 55
1149            -- },
1150        -- }}
1151 }
1152 sprint(json.encode(pub_data))
1153 print("..........",pub_RE_TOPIC)
1154     return g_mq:publish(pub_RE_TOPIC, json.encode(pub_data), 0, 0)
1155 end
1156 {{/code}}
1157
1158 == **2.4 Huawei platform** ==
1159
1160 {{info}}
1161 **✎Note**:**Huawei IOT DA function is only in China area.If you want this function,you need to use chinese mobile to register**
1162 {{/info}}
1163
1164 1.Register a account: [[https:~~/~~/www.huaweicloud.com/intl/en-us/s/JUlPVERNJQ>>https://www.huaweicloud.com/intl/en-us/s/JUlPVERNJQ]]
1165
1166 2.log in the Huawei IOTDA
1167
1168 [[https:~~/~~/console.huaweicloud.com/iotdm/?region=cn-north-4&locale=en-us#/dm-portal/home>>https://console.huaweicloud.com/iotdm/?region=cn-north-4&locale=en-us#/dm-portal/home]]
1169
1170 3.Create product
1171
1172 (% style="text-align:center" %)
1173 [[image:1624433478954-859.png||height="497" width="1100" class="img-thumbnail"]]
1174
1175 4.Product name,manufacturer,device type and industry,set according to your own needs.
1176
1177 Protocol: MQTT
1178
1179 Data Type: JSON
1180
1181 After finishing configuration,please click "OK"
1182
1183 (% style="text-align:center" %)
1184 [[image:1624433531968-337.png||height="568" width="700" class="img-thumbnail"]]
1185
1186 5.Device
1187
1188 After product register,continue to configure "individual register".Click "Device"~-~->"individual register"
1189
1190 (% style="text-align:center" %)
1191 [[image:1624434757597-117.png||class="img-thumbnail"]]
1192
1193 **Notes for registering device:**
1194
1195 Product: Previous product registration.
1196
1197 Node ID, Device Name: set according to your own needs.
1198
1199 Secret: need to be configured, will be used when connecting later
1200
1201 After configuration, click OK to generate a device ID and password, which will be used for device access later.
1202
1203 (% style="text-align:center" %)
1204 [[image:1624436421499-613.png||height="499" width="700" class="img-thumbnail"]]
1205
1206 (% style="text-align:center" %)
1207 [[image:1624437798012-126.png||height="366" width="500" class="img-thumbnail"]]
1208
1209 6. Connection authentication (use MQTT.fx tool to access the IoT platform)
1210
1211 (1)Open mqttClientIdGenerator tool Java(TM) Platform SE binary
1212
1213 **[[Download>>https://wecon-disk.oss-ap-southeast-1.aliyuncs.com/Download/WIKI/V-BOX/Demo/Huawei/mqttClientIdGenerator-19.2.0.zip]]**
1214
1215 (% style="text-align:center" %)
1216 [[image:1624437573798-815.png||height="351" width="700" class="img-thumbnail"]]
1217
1218 (2)Fill in the device ID and secret (deviceid and secret generated when registering the device) to generate connection message
1219
1220 Client ID, user name, password
1221
1222 (% style="text-align:center" %)
1223 [[image:1624437756866-251.png||height="405" width="700" class="img-thumbnail"]]
1224
1225 (3) Download certificate file"North-Beijing4"
1226
1227 [[https:~~/~~/support.huaweicloud.com/en-us/devg-iothub/iot_02_1004.html>>https://support.huaweicloud.com/en-us/devg-iothub/iot_02_1004.html]]
1228
1229 (% style="text-align:center" %)
1230 [[image:1624438225398-363.png||height="403" width="800" class="img-thumbnail"]]
1231
1232 (% style="text-align:center" %)
1233 [[image:1624438260025-610.png||height="408" width="700" class="img-thumbnail"]]
1234
1235 7.Run MQTTfx tool to connect with Huawei
1236
1237 Download link: [[http:~~/~~/mqttfx.jensd.de/index.php/download>>url:http://mqttfx.jensd.de/index.php/download]]
1238
1239 (1)Click on the setting ICON
1240
1241 (% style="text-align:center" %)
1242 [[image:1624438821280-974.png||height="198" width="500" class="img-thumbnail"]]
1243
1244 (2)Fill in IIOT MQTT device access address, and configure authentication parameters.
1245 First: It is the server and port connected to Huawei IOT, which can be viewed through the overview of the interface.
1246
1247 (% style="text-align:center" %)
1248 [[image:1624439086268-985.png||class="img-thumbnail"]]
1249
1250 Domain name:iot-mqtts.cn-north-4.myhuaweicloud.com
1251
1252 Port: 8883
1253
1254 Client ID: check step 6
1255
1256 (% style="text-align:center" %)
1257 [[image:1624439672168-492.png||height="458" width="600" class="img-thumbnail"]]
1258
1259 (3)Upload SSL certificate file,check step 6
1260
1261 Select folder java~-~->DigiCertGlobalRootCA.crt.pem and click OK or apply button
1262
1263 (% style="text-align:center" %)
1264 [[image:1624439912938-659.png||height="458" width="600" class="img-thumbnail"]]
1265
1266 (4)Connect and test publish and subscribe
1267
1268 (% style="text-align:center" %)
1269 [[image:1624440014872-688.png||height="232" width="700" class="img-thumbnail"]]
1270
1271 (% style="text-align:center" %)
1272 [[image:1624440026937-386.png||height="215" width="700" class="img-thumbnail"]]
1273
1274 Huawei publish topic format: $oc/devices/{device_id}/sys/properties/report
1275
1276 (% style="text-align:center" %)
1277 [[image:1624440404119-815.png||class="img-thumbnail"]]
1278
1279 Huawei subscribe topic format: **$oc/devices/{device_id}/sys/commands/#**
1280
1281 (% style="text-align:center" %)
1282 [[image:1624447157493-672.png||class="img-thumbnail"]]
1283
1284 (% style="text-align:center" %)
1285 [[image:1624447209982-715.png||class="img-thumbnail"]]
1286
1287 (5).How to configure to view the received data format intuitively, multiple products (Huawei) are required to configure the model. The specific steps are as follows:
1288 ①Select the corresponding product from Huawei products to view
1289
1290 (% style="text-align:center" %)
1291 [[image:1624440647663-632.png||class="img-thumbnail"]]
1292
1293 ②Custom model: used to display the service ID name of the configuration report.
1294
1295 (% style="text-align:center" %)
1296 [[image:1624440793982-974.png||height="410" width="700" class="img-thumbnail"]]
1297
1298 (% style="text-align:center" %)
1299 [[image:1624440883015-105.png||height="370" width="600" class="img-thumbnail"]]
1300
1301 ③Add property, ID of monitoring point, and data format:
1302
1303 (% style="text-align:center" %)
1304 [[image:1624441052296-108.png||height="477" width="600" class="img-thumbnail"]]
1305
1306 ④After the configuration is complete, check the received data on the device
1307
1308 (% style="text-align:center" %)
1309 [[image:1624441186851-536.png||height="434" width="700" class="img-thumbnail"]]
1310
1311 === Huawei by SSL certification. ===
1312
1313 1.Create a project access for Huawei IOT
1314
1315 2.configure MQTT configuration
1316
1317 (% style="text-align:center" %)
1318 [[image:1624506363847-661.png||height="507" width="1000" class="img-thumbnail"]]
1319
1320 3.Create a script with the demo as below.
1321
1322 Script is as below
1323
1324 (% class="box infomessage" %)
1325 (((
1326 (% class="box infomessage" %)
1327 (((
1328 ~-~- mqtt.fx simulated access to Huawei Cloud IoT platform refer to 2.4
1329 sprint = print
1330
1331 ~-~-Get custom configuration parameters (gateway customization information)
1332 local CUSTOM = bns_get_config("bind")
1333 local DS_ID = CUSTOM.DSID or "5dfa0700df1ae506179afb9c_wecon"
1334
1335
1336 ~-~-OpenCloud mode interface, obtain MQTT information configured on cloud platform: (5 returned, respectively server address, client ID, connection table, last word table, certificate table)
1337 local MQTT_URL, MQTT_CLIENTID, MQTT_CFG, MQTT_LWT, MQTT_CART = mqtt.setup_cfg()
1338
1339 MQTT_CFG.username =DS_ID
1340 MQTT_CFG.password='d030d92338fcc18cd10fabb3003a4a0f6620fa6822cd3c23b1d9bc790200c6e7'
1341 MQTT_CLIENTID = '5dfa0700df1ae506179afb9c_wecon_0_0_2019121819'
1342
1343 ~-~-publish topic format:$oc/devices/{device id}/sys/properties/report
1344
1345 local pub_RE_TOPIC = string.format('$oc/devices/60a71ccbbbe12002c08f3a1a_WECON/sys/properties/report')
1346
1347 ~-~-variate
1348 local last_time = 0
1349
1350
1351 ~-~-Timing principal function
1352 function hwyiot.main()
1353
1354 sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " hwyiot.main start")
1355 if g_mq then
1356 if g_mq:isconnected() then
1357 send_Data()
1358 else
1359 if os.time() - last_time > 20 then
1360 last_time = os.time()
1361 mymqtt_connect()
1362 end
1363 end
1364 else
1365 mymqtt_init()
1366 end
1367 sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " hwyiot.main end")
1368 end
1369
1370 ~-~- initializationMQTT
1371 function mymqtt_init()
1372 sprint(string.format("mqtt init mqtt_url:%s mqtt_clientid:%s", MQTT_URL, MQTT_CLIENTID))
1373 g_mq, err = mqtt.create(MQTT_URL, MQTT_CLIENTID) ~-~- Create the object and declare it as a global variable
1374 if g_mq then
1375 g_mq:on("message", mymqtt_msg_callback) ~-~- Register to receive message callbacks
1376 sprint("mqtt init success")
1377 else
1378 sprint("mqtt init failed:", err)
1379 end
1380 end
1381
1382 ~-~- Connect to the MQTT server
1383 function mymqtt_connect()
1384 sprint("mqtt connecting...")
1385 local stat, err = g_mq:connect(MQTT_CFG,MQTT_LWT, MQTT_CART)
1386 if stat == nil then
1387 sprint("mqtt connect failed:", err)
1388 return
1389 else
1390 sprint("mqtt connected")
1391 end
1392
1393 ~-~-subscribe topic format:$oc/devices/{device_id}/sys/commands/#
1394
1395 g_mq:subscribe('$oc/devices/60a71ccbbbe12002c08f3a1a_WECON/sys/commands/#', 0) 
1396 end
1397
1398 ~-~- Receive the message callback function
1399 function mymqtt_msg_callback(topic, msg)
1400 sprint("recv data!")
1401 sprint("topic:msg", topic,msg)
1402 print(msg)
1403 local revData = json.decode(msg)
1404 \\end
1405
1406 ~-~-Send data
1407 function send_Data()
1408 local pub_data = {
1409 msgType = 'deviceReq',
1410 data = ~{~{
1411 serviceId ='Battery',
1412 serviceData={
1413 batteryLevel = 55
1414 }
1415 }}
1416 }
1417 return g_mq:publish(pub_RE_TOPIC, json.encode(pub_data), 0, 0)
1418 end
1419 )))
1420 )))
1421
1422 4.Download project access into V-Box to test in debug page
1423
1424 (% style="text-align:center" %)
1425 [[image:1624506710354-406.png||height="658" width="1000" class="img-thumbnail"]]
1426
1427 (% style="text-align:center" %)
1428 [[image:1624506666650-161.png||height="547" width="1000" class="img-thumbnail"]]
1429
1430 == **2.6 AWS platform** ==
1431
1432 === **Log in AWS** ===
1433
1434 Login aws account and click“Connect an IoT device”
1435
1436 [[image:image-20220709165402-1.png]]
1437
1438 [[image:image-20220709165402-2.png]]
1439
1440
1441 === **Create policy** ===
1442
1443 Click “Secure”~-~-->“Policies”~-~-->“Create policy”~-~-->Click “Create”
1444
1445 [[image:image-20220709165402-3.png]]
1446
1447 Name the policy~-~-->Click “JSON”~-~-->Copy the following content~-~-->Click “Create”
1448
1449 [[image:image-20220709165402-5.png]]
1450
1451 [[image:image-20220709165402-4.png]]
1452
1453 {{code language="java"}}
1454 {
1455   "Version": "2012-10-17",
1456   "Statement": [
1457     {
1458       "Effect": "Allow",
1459       "Action": [
1460         "iot:Connect",
1461         "iot:Publish",
1462         "iot:Subscribe",
1463         "iot:Receive",
1464         "greengrass:Discover"
1465       ],
1466       "Resource": "*"
1467     }
1468   ]
1469 }
1470 {{/code}}
1471
1472 === **Create things** ===
1473
1474 Click “Manage”~-~-->“Things”~-~-->“Create things”~-~-->“Create single thing”
1475
1476 [[image:image-20220709165402-6.png]]
1477
1478 [[image:image-20220709165402-7.png]]
1479
1480 Name the thing~-~-->Click “Next”
1481
1482 [[image:image-20220709165402-8.png]]
1483
1484 Select the way to create certificate
1485
1486 [[image:image-20220709165402-9.png]]
1487
1488 Select policy
1489
1490 [[image:image-20220709165402-10.png]]
1491
1492 [[image:image-20220709165402-11.png]]
1493
1494
1495 === **MQTT.fx tool** ===
1496
1497 Click “View Setting” to get the “Broker Adress”
1498
1499 [[image:image-20220709165402-13.png]]
1500
1501 [[image:image-20220709165402-12.png]]
1502
1503 Create one connection in MQTT.fx tool, set broker port as 8883.
1504
1505 [[image:image-20220709165402-14.png]]
1506
1507 Upload the CA File, Client Certificate File, Client Key File
1508
1509 [[image:image-20220709165402-15.png]]
1510
1511 Publish message to topic “TEST”
1512
1513 [[image:image-20220709165402-17.png]]
1514
1515 Click”Test”~-~-->”MQTT test client”~-~-->”Subscrible to a topic”, to get message publish from MQTT.fx tool.
1516
1517 [[image:image-20220709173500-1.png]]
1518
1519 And we can also send message form AWS platform to MQTT.fx tool.
1520
1521 [[image:image-20220709165402-18.png]]
1522
1523 === **CloudTool** ===
1524
1525 Copy the same setting in MQTT.fx to MQTT configuration
1526
1527 [[image:image-20220709165402-19.png]]
1528
1529 Add a lua script and copy the lua demo into it.
1530
1531 [[image:image-20220709165402-20.png]]
1532
1533 {{info}}
1534 **✎Note:** Before using the following demo script, please make sure the V-Box firmware is newer than 22110701
1535 {{/info}}
1536
1537 {{code language="lua"}}
1538 sprint = print
1539
1540 --Cloud mode interface to obtain the MQTT information configured by the cloud platform: (5 returns, namely the server address, client ID, connection table, last word table, certificate table)
1541
1542 local MQTT_URL, MQTT_CLIENTID, MQTT_CFG, MQTT_LWT, MQTT_CART = mqtt.setup_cfg()
1543
1544 --publish to topics
1545
1546 local pub_RE_TOPIC = string.format('TEST')
1547
1548 --Subscribe topics
1549
1550 local Subscribe_RE_TOPIC1 = string.format('TEST')
1551
1552 --variable
1553
1554 local last_time = 0
1555
1556 --Timing main function
1557
1558 function aws.main()
1559
1560 sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " aws.main start")
1561
1562 if g_mq then
1563
1564 if g_mq:isconnected() then
1565
1566 send_Data()
1567
1568 else
1569
1570 if os.time() - last_time > 5 then
1571
1572 last_time = os.time()
1573
1574 mymqtt_connect()
1575
1576 end
1577
1578 end
1579
1580 else
1581
1582 mymqtt_init()
1583
1584 end
1585
1586 sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " aws.main end")
1587
1588 end
1589
1590
1591
1592 -- Initialize MQTT
1593
1594 function mymqtt_init()
1595
1596 sprint(string.format("mqtt init mqtt_url:%s mqtt_clientid:%s", MQTT_URL, MQTT_CLIENTID))
1597
1598 g_mq, err = mqtt.create(MQTT_URL, MQTT_CLIENTID, 1) -- Create the object and declare it as a global variable, 1 means using the domain to connect
1599
1600 if g_mq then
1601
1602 g_mq:on("message", mymqtt_msg_callback) -- Register to receive message callbacks
1603
1604 sprint("mqtt init success")
1605
1606 else
1607
1608 sprint("mqtt init failed:", err)
1609
1610 end
1611
1612 end
1613
1614 -- Connect to MQTT server
1615
1616 function mymqtt_connect()
1617
1618 sprint("mqtt connecting...")
1619
1620 local stat, err = g_mq:connect(MQTT_CFG,MQTT_LWT, MQTT_CART)
1621
1622 if stat == nil then
1623
1624 sprint("mqtt connect failed:", err)
1625
1626 return
1627
1628 else
1629
1630 sprint("mqtt connected")
1631
1632 end
1633
1634 g_mq:subscribe(Subscribe_RE_TOPIC1, 0)
1635
1636 end
1637
1638 -- Receive MQTT message callback function
1639
1640 function mymqtt_msg_callback(topic, msg)
1641
1642 print("topic:",topic)
1643
1644 print("revdata:",msg)
1645
1646 local revData = json.decode(msg)
1647
1648 print (revData)
1649
1650 if topic == Subscribe_RE_TOPIC1 then --Process topic information subscribed from the cloud
1651
1652 if string.match(topic,Subscribe_RE_TOPIC1) then
1653
1654 --if revData ~= nil then
1655
1656 for k,v in pairs (revData) do
1657
1658 print("printing revdata after kv here")
1659
1660 print (k,v)
1661
1662 end
1663
1664 print ("current state is",fanstate)
1665
1666 --end
1667
1668 end
1669
1670 end
1671
1672 end
1673
1674
1675
1676 --Get real-time data
1677
1678 function getData()
1679
1680 local jdata = {}
1681
1682 local addr = bns_get_alldata()
1683
1684 print(json.encode(addr))
1685
1686 for i,v in pairs(addr) do
1687
1688 if v[2] == 1 then
1689
1690 jdata[v[3]] = v[4]
1691
1692 end
1693
1694 end
1695
1696 return jdata
1697
1698 end
1699
1700 --send data
1701
1702 function send_Data()
1703
1704 local pub_data =
1705 {
1706 123
1707 }
1708
1709 sprint(json.encode(pub_data))
1710
1711 print("..........",pub_RE_TOPIC)
1712
1713 return g_mq:publish(pub_RE_TOPIC, json.encode(pub_data), 0, 0)
1714
1715 end
1716 {{/code}}
1717
1718 Get message in AWS
1719
1720 [[image:image-20220709165402-21.png]]
1721
1722 == **2.7 Mysql** ==
1723
1724 In this demo you can use Mysql import the data to the terminal device through the V-box or save the data to the any Mysql database by the V-box.
1725
1726 (% class="wikigeneratedid" id="H1.InstallMysql" %)
1727 **1.Install Mysql**
1728
1729 version
1730
1731 (% style="text-align:center" %)
1732 [[image:Mysql的软件版本.png]]
1733
1734 (% class="wikigeneratedid" id="H2.InstallNavicat" %)
1735 **2.Install Navicat**
1736
1737 (% class="wikigeneratedid" %)
1738 version
1739
1740 (% style="text-align:center" %)
1741 [[image:navicat 版本.png]]
1742
1743
1744 Connecting to Mysql with navicat.
1745
1746 (% style="text-align:center" %)
1747 [[image:连接到mysql.png]]
1748
1749 (% class="wikigeneratedid" id="H3.Createdatabase" %)
1750 **3.Create database**
1751
1752 Character set should be choose utf8mb3/utf8mb4 and Collation choose utf8mb3_danish_ci/utf8mb4_danish_ci.
1753
1754 (% style="text-align:center" %)
1755 [[image:创建数据库.png]]
1756
1757 (% class="wikigeneratedid" id="H4.Createdatatable" %)
1758 **4.Create data table**
1759
1760 Create a table, enter the fields you need.
1761
1762 (% style="text-align:center" %)
1763 [[image:创建表1.png]]
1764
1765
1766 Save, enter table name.
1767
1768 (% style="text-align:center" %)
1769 [[image:创建表2.png]]
1770
1771 (% class="wikigeneratedid" id="H5.InputTableData" %)
1772 **5.Input Table Data**
1773
1774 (% style="text-align:center" %)
1775 [[image:输入或者导入数据.png]]
1776
1777 (% class="wikigeneratedid" id="H6.Script" %)
1778 **6.Script**
1779
1780 **luaMySql.init(string sourcename, string username, string password, string host, number port, string character)**
1781
1782 **Function:** Configure database connection parameters
1783
1784 **Parameter:**
1785
1786 sourcename: the name of database
1787
1788 username: the username of the connection
1789
1790 password: the password of the connection
1791
1792 host: the host name of the connection
1793
1794 port: the host port of the connection
1795
1796 character: the character set of the connection
1797
1798 **Return:**
1799
1800 Succeed: string
1801
1802 Failed: multi
1803
1804 **luaMySql.exec(string statement)**
1805
1806 **Function:** Execute the given SQL statement without returning the result set (add, delete, change)
1807
1808 **Parameter:**
1809
1810 statement: the given SQL statement
1811
1812 **Return:**
1813
1814 Succeed: status: returns the number of rows affected by SQL statement execution.
1815
1816 Failed: nil, errorString
1817
1818 **luaMySql.execWithResult(string statement)**
1819
1820 **Function:** Execute the given SQL statement returning the result set (check)
1821
1822 **Parameter:**
1823
1824 statement: the given SQL statement
1825
1826 **Return:**
1827
1828 Succeed: table: returns the result set
1829
1830 Failed: nil, errorString
1831
1832 **For example:**
1833
1834
1835 {{code language="LUA"}}
1836 -- Assuming the "mysqlclient" library is properly installed and available
1837 mysql = require("mysqlclient")
1838
1839 function DataInitRight()
1840 local dbName = "excel"
1841 local user = "root"
1842 local pwd = "XXXXX"
1843 local host = "192.168.39.146"
1844 local port = 3306
1845 local character = "utf8mb3"
1846
1847 mysql.init(dbName, user, pwd, host, port, character)
1848 end
1849
1850 function ExecFunc()
1851 status, errorString = mysql.exec("delete from student where Name = 'XXX';") --Delete statement, column name = table element
1852 if nil == status then
1853 print("ExecFunc() error:", errorString)
1854 return -1
1855 else
1856 print("the number of rows affected by the command:", status)
1857 end
1858 return 0
1859 end
1860
1861
1862 function ExecWithResultFunc()
1863 status, errorString = mysql.execWithResult("select * from student;")
1864 if nil == status then
1865 print("ExecWithResultFunc() error:", errorString)
1866 return -1
1867 else
1868 print("ExecWithResultFunc() success : status type = ", type(status))
1869 print("ExecWithResultFunc() success : status len = ", #status)
1870 local num = #status
1871 local i = 1
1872 if num > 0 then
1873 for i = 1, num, 1 do
1874 local var = string.format("select result[%d] :Num = %d,Name = %s,Age = %d", i, status[i].Num, status[i].Name,status[i].Age) --Iterate through the data in the table, noting whether the elements are strings or numbers
1875 print(var)
1876 end
1877 end
1878 print("---------------")
1879 end
1880 return 0
1881 end
1882
1883 function MySQL.main()
1884 print("script running ...")
1885 DataInitRight()
1886
1887 -- use exec demo
1888 if ExecFunc() < 0 then
1889 return
1890 end
1891
1892 -- use execWithResult demo
1893 if ExecWithResultFunc() < 0 then
1894 return
1895 end
1896
1897 print("script running success")
1898 end
1899 {{/code}}
1900
1901 (% class="wikigeneratedid" id="H7.Debug" %)
1902 **7.Debug**
1903
1904 (% style="text-align:center" %)
1905 [[image:调试结果.png]]
1906
1907 (% class="wikigeneratedid" id="H8.Problem" %)
1908 8.Problem
1909
1910 During our debugging process it may there are some problems about Mysql, such as
1911
1912 * MySQL: Host  192.168.XXX.XXX  is not allowed to connect.
1913 * MySQL: Host  192.168.XXX.XXX  is blocked because of many connection errors.
1914 * MySQL: SSL connection error: unknown error number.
1915 * (((
1916 1449-The user specified as a definer(‘mysql.infoschema‘@localhost‘) does not exist.
1917 )))
1918
1919 This type of problem has nothing to do with scripts or devices, it is a Mysql configuration issue. If you have any of these problems, please look for a solution online.
1920
1921 {{info}}
1922 ✎Note: If you want to use CMD to access Mysql, you need to add the bin file to the environment variable, please check online for details of the operation.
1923 {{/info}}