Wiki source code of 2 Script

Version 4.1 by Devin Chen on 2025/09/09 11:11

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