Wiki source code of 2 Script

Version 5.1 by Devin Chen on 2025/09/09 11:17

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