Wiki source code of 2 Script

Last modified by Devin Chen on 2025/06/06 14:03

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