Wiki source code of 2 Script

Version 2.1 by Devin Chen on 2025/09/05 11:50

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