Wiki source code of 2 Script

Version 3.1 by Devin Chen on 2025/09/05 11:51

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