Wiki source code of 2 Script

Version 84.1 by Devin Chen on 2025/06/06 13:55

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 = =
532
533 == **1.11 Bit-Activated Timer with Reset and Data Output** ==
534
535 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.
536
537 (% style="text-align:center" %)
538 [[image:1749188641322-409.png]]
539
540 (% style="text-align:center" %)
541 [[image:1749189179543-849.png||height="300" width="571"]]
542
543 = =
544
545 {{code language="lua"}}
546 function timer.main()
547 -- Read current state of control bit and timer value
548 local a = addr_getbit("@Bit") -- Get status of control bit (0 or 1)
549 local b = addr_getword("@Timer") -- Get current timer value (word/integer)
550
551 -- Increment phase: When activated and timer < threshold
552 if a == 1 and b < 5 then
553 b = b + 1 -- Increment timer value
554 addr_setword("@Timer", b) -- Update timer memory
555 print(b) -- Output current timer value (debug)
556 end
557
558 -- Reset phase: When timer reaches threshold
559 if b >= 5 then
560 addr_setword("@Timer", 0) -- Reset timer to 0
561 addr_setbit("@Bit", 0) -- Deactivate control bit
562 addr_setword("@Data", 10) -- Set output data to fixed value (10)
563 end
564 end
565 {{/code}}
566
567 = **2 Third part server** =
568
569 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.
570
571 (% class="mark" %)1.Europe server:eu.v-box.net
572
573 (% class="mark" %)2.Asean server:asean.v-box.net
574
575 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
576
577 OpenCloud platform is used in configuring the script.Then V-Box can connect with third part server.
578
579 Both mode can support script  to connect with third part server.the difference:
580
581 (% class="mark" %)1.If you want to store in WECON server ,please use V-NET.
582
583 (% class="mark" %)2.If your server requires SSL certificate to log in,please use OpenCloud.Because only OpenCloud platform can support to upload certificate
584
585 {{info}}
586 **✎Note: **Before program the script of MQTT, please make sure the server(MQTT broker) can be connected through MQTT Client tool.
587 {{/info}}
588
589 (% class="wikigeneratedid" %)
590 Tool link: **[[MQTT.fx>>http://mqttfx.jensd.de/index.php/download]]**
591
592 == **2.1 Test server(General Example)** ==
593
594 The following example is trying to publish to the topic "testtopic/test/no1/7890", and subscribe the topic "testtopic/test/no1/123456".
595
596 And the JSON message is like follows:
597
598 {{code language="JSON"}}
599 {
600 "timestamp": 1631152760,
601 "messageId": 1,
602 "event": "test_data",
603 "mfrs": "HMI/box",
604 "data":
605 {
606 "id" : 1436217747670454274,
607 "waterlevel" : 48,
608 "temperture" : 23
609 }
610 }
611 {{/code}}
612
613 {{code language="lua"}}
614 --MQTT configuration table
615 local MQTT_CFG={}
616 --if there is no need the username and password, please put them as ""
617 MQTT_CFG.username = "weconsupport"
618 MQTT_CFG.password = "123456"
619 MQTT_CFG.netway = 0
620 MQTT_CFG.keepalive = 60
621 MQTT_CFG.cleansession = 1
622 --TCP URL
623 MQTT_URL = "tcp://mq.tongxinmao.com:1883"
624 --Client ID
625 MQTT_CLIENT_ID = "V-BOXH-AG"
626
627 --Generate UUID
628 function uuid()
629 local seed = {'e','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}
630 local tb = {}
631 for i=1, 32 do
632 table.insert(tb, seed[math.random(1,16)])
633 end
634 local sid=table.concat(tb)
635 return string.format('%s',
636 string.sub(sid,1,32)
637 )
638 end
639
640
641 --Topic name to subscribed
642 local SUBSCRIBE_TOPIC = 'testtopic/test/no1/123456'
643
644 --Topic name to be published
645 local PUBLISH_TOPIC = 'testtopic/test/no1/7890'
646
647
648 --real time
649 local LAST_TIME = 0
650
651
652 --initialize mqtt
653 function mqtt_init()
654 print(string.format("mqtt init mqtt_url:%s mqtt_clientid:%s", MQTT_URL, MQTT_CLIENT_ID))
655 if g_mq then
656 mqtt.close(g_mq) --Close mqtt object
657 end
658 g_mq, err = mqtt.create(MQTT_URL, MQTT_CLIENT_ID) -- create mqtt object,and declare it as a global variable
659 if g_mq then
660 g_mq:on("message", mqtt_msg_callback) -- Register a callback for receiving messages
661 g_mq:on("offline", mqtt_msg_offline) -- Register a callback for offline
662 print("mqtt init success")
663 else
664 print("mqtt init failed:", err)
665 end
666 end
667
668 -- connect to mqtt
669 function mqtt_connect()
670 print("mqtt connecting...")
671 local stat, err = g_mq:connect(MQTT_CFG)
672 if stat == nil then
673 print("mqtt connect failed:", err)
674 return
675 else
676 print("mqtt connected")
677 end
678 g_mq:subscribe(SUBSCRIBE_TOPIC, 0)
679 end
680
681 --Offline callback function
682 function mqtt_msg_offline(cause)
683 print("mqtt offline, cause:", cause)
684 end
685
686 -- Received message callback function
687 function mqtt_msg_callback(topic, msg)
688 print("topic:", topic)
689 print("msg:", msg)
690 local objMsg = json.decode(msg)
691 local water = objMsg.data.waterlevel
692 local temp = objMsg.data.temperature
693 addr_setword("@HDW20",water)
694 addr_setword("@HDW10",temp)
695 end
696
697 --Send data (data upload to platform and encapsulate it with custom functions)
698 function send_data()
699 local pub_data = {
700 timestamp = os.time(),
701 messageId = 1,
702 event = 'test_data',
703 mfrs = 'V-Box',
704 data = {
705 id = uuid(),
706 waterlevel = addr_getword("@HDW10"),
707 temperature = addr_getword("@HDW20")
708 }
709 }
710 return g_mq:publish(PUBLISH_TOPIC, json.encode(pub_data), 0, 0)
711 end
712
713
714 --main function fixed timed execution
715 function MQTT.main()
716 --dosomething
717 print(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " main start")
718 --determine the mqtt object whether exist
719 if g_mq then
720 --determine the mqtt object whether has been connected or not
721 if g_mq:isconnected() then
722 send_data()
723 else
724 --if exceed 5 sec not connect, reconnect once
725 if os.time() - LAST_TIME > 5 then
726 LAST_TIME = os.time()
727 --reinitial the mqtt object
728 mqtt_init()
729 --connect to mqtt or reconnect
730 mqtt_connect()
731 end
732 end
733 else
734 --mqtt object does not exist so create new one
735 mqtt_init()
736 end
737 print(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " main end")
738 end
739 {{/code}}
740
741 == **2.2 Customer server:grouprobotinfo.com** ==
742
743 This demo does not use SSL certification. Script is as below
744
745 Demo1:
746
747 {{code language="lua"}}
748 -- Meta class
749 --main
750 function mq.main()
751 if not mq.m then
752 local err = ""
753
754 mq.m, err = mqtt.create("tcp://grouprobotinfo.com:1883", "ClienID") -- create connection
755 if mq.m then
756 mq.config = {
757 username = "",-- ID
758 password = "",-- password
759 netway = 1, -- Ethernet connection, WIFI=1
760 -- keepalive = 100, -- Optional, set the connection heartbeat interval for 100 seconds.
761 -- cleansession = 0, -- Optional, keep session
762 }
763 mq.m:on("message", function(topic, msg) -- Register for receiving message callbacks
764 local str = string.format("%s:%s", topic, msg)
765 -- print("mqtt msg:", str) -- Print out the received topics and content
766 end)
767 mq.m:on("offline", function (cause) -- Register for lost connection callbacks
768 -- addr_setstring("@xxx", "cause"..(cause or " got nil"))
769 end)
770 mq.m:on("arrived", function() -- Registration for sending messages to callbacks
771 print("msg arrived")
772 end)
773 else
774 print("mqtt create failed:", err) -- Create object failed
775 end
776 else
777 if mq.m:isconnected() then -- If online, post a message
778 local phaseStatus ="unknow"
779 if addr_getbit("@Standby")== 1 then
780 phaseStatus = "Standby"
781 elseif addr_getbit("@Pre-Freeze")==1 then
782 phaseStatus= "Pre-Freeze"
783 elseif addr_getbit("@Prepare")==1 then
784 phaseStatus ="Prepare"
785 elseif addr_getbit("@Primary Dry")==1 then
786 phaseStatus = "Primary dry"
787 elseif addr_getbit("@Secondary Dry")==1 then
788 phaseStatus = "Secondary Dry"
789 end
790 --print(addr_getbit("@Primary Dry"))
791 -------------------------------------------------------------------------------------------------------------------------
792 local activating ="unknow"
793 if addr_getbit("@Compressor")==1 then
794 activating = ",".."Compressor"
795 end
796 if addr_getbit("@Silicone Pump")==1 then
797 activating = activating..",".."Silicone Pump"
798 end
799 if addr_getbit("@Vacuum Pump")==1 then
800 activating = activating..",".."Vacuum Pump"
801 end
802 if addr_getbit("@Root Pump")==1 then
803 activating = activating..",".."Root Pump"
804 end
805 if addr_getbit("@Heater")==1 then
806 activating = activating..",".."Heater"
807 end
808 if addr_getbit("@Valve Silicone")==1 then
809 activating = activating..",".."Valve Silicone"
810 end
811 if addr_getbit("@Valve Ice Condenser")==1 then
812 activating = activating..",".."Valve Ice Condenser"
813 end
814 if addr_getbit("@Valve Vacuum Pump")==1 then
815 activating = activating..",".."Valve Vacuum Pump"
816 end
817 local pr_activating =string.sub(activating,2)
818 -- print(pr_activating)
819 local status_text ="unknow"
820 if addr_getbit("@Status Run")==1 then
821 status_text = "RUNNING"
822 else
823 status_text = "STOP"
824 end
825 -------------------------------------------------------------------------------------------------------------------------
826 local js = {type="status",
827 mc_name ="FD300",
828 status=status_text,
829 elapsed_time={
830 hour=addr_getword("@Elapsed Time (Hour)"),
831 min=addr_getword("@Elapsed Time (Minute)"),
832 sec=addr_getword("@Elapsed Time (Second)")
833 },
834 phase = phaseStatus,
835 step = addr_getword("@Step"),
836 activating_output = pr_activating,
837 sv=addr_getshort("@SV Silicone")/10,
838 pv=addr_getshort("@PV Silicone")/10,
839 product1=addr_getshort("@Product 1")/10,
840
841 product2=addr_getshort("@Product 2")/10,
842 product3=addr_getshort("@Product 3")/10,
843 product4=addr_getshort("@Product 4")/10,
844 ice1=addr_getshort("@Ice condenser 1")/10,
845 ice2=addr_getshort("@Ice condenser 2")/10,
846 vacuum=addr_getfloat("@Vacuum")
847 }
848 local jsAlarm = { HPC = addr_getbit("@B_25395#W0.00"),
849 ODPC = addr_getbit("@B_25395#W0.01"),
850 MTPC=addr_getbit("@B_25395#W0.02"),
851 HTT = addr_getbit("@B_25395#W1.03"),
852 CPC = addr_getbit("@B_25395#W0.08"),
853 CPSP =addr_getbit("@B_25395#W1.00"),
854 CPVP =addr_getbit("@B_25395#W0.10"),
855 CPRP =addr_getbit("@B_25395#W0.11"),
856 HP =addr_getbit("@B_25395#W1.01"),
857 PP= addr_getbit("@B_25395#W1.02"),
858 PO=addr_getbit("@B_25395#W0.07"),
859 FSE=addr_getbit("@B_25395#W2.04"),
860 AVVSVV=addr_getbit("@B_25395#W1.12"),
861 ICHT=addr_getbit("@B_25395#W3.06")
862 }
863 -- ("@B_25395#CIO1.02")
864 mq.m:publish("mqtt-v-box-epsilon-fd300", json.encode(js) , 0, 0)
865 mq.m:publish("mqtt-v-box-epsilon-alarm-fd300", json.encode(jsAlarm) , 0, 0)
866 else
867 local stat, err = mq.m:connect(mq.config) -- connection
868 if stat == nil then --Determine whether to connect
869 print("mqtt connect failed:", err)
870 return -- Connection failed, return directly
871 end
872 mq.m:subscribe("mqtt-v-box-epsilon", 0)-- Subscribe to topics
873
874 end
875 -- mq.m:unsubscribe("stc/test")
876 -- mq.m:disconnect() -- close matt
877 -- mq.m:close() -- close clase
878 end
879 end
880 {{/code}}
881
882 == **2.3 Azure platform** ==
883
884 In this demo,V-Box connects with Azure by SSL certification.
885
886 Video link: [[https:~~/~~/youtu.be/cdI6rIQcpMY?list=PL_Bpnb2RgaksCic9HCcVAZhU9sYwCRKzW>>https://youtu.be/cdI6rIQcpMY?list=PL_Bpnb2RgaksCic9HCcVAZhU9sYwCRKzW]]
887
888 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]]
889
890 Script is as below
891
892 {{code language="lua"}}
893 --https://support.huaweicloud.com/qs-IoT/iot_05_0005.html  mqtt.fx monitor to connect azure iot
894 sprint = print
895
896 --Get custom configuration parameters (vbox custom information)
897 --local CUSTOM = bns_get_config("bind")
898 --local DS_ID = CUSTOM.DSID or "60a71ccbbbe12002c08f3a1a_WECON"
899
900
901
902 --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)
903 local MQTT_URL, MQTT_CLIENTID, MQTT_CFG, MQTT_LWT, MQTT_CART = mqtt.setup_cfg()
904
905 --MQTT_CFG.username = '60a71ccbbbe12002c08f3a1a_WECON'
906 --MQTT_CFG.password='wecon123'
907 --MQTT_CLIENTID = '60a71ccbbbe12002c08f3a1a_WECON_0_0_2021052110usernxame:60a71ccbbbe12002c08f3a1a_WECONpassword:a0a951581855aa8e0262129da6cf1b43f2c0ecfac4fa56117fc5a20c90be169a'
908
909 --publish to topics
910 local pub_RE_TOPIC = string.format('devices/wecon_02/messages/events/')
911 --Subscribe topics
912 local Subscribe_RE_TOPIC1 = string.format('devices/wecon_02/messages/devicebound/#')
913
914 --variable
915 local last_time = 0
916
917
918
919 --Timing main function
920 function Azure.main()
921
922    sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " Azureiot.main start")
923    if g_mq then
924         if g_mq:isconnected() then
925             send_Data()
926         else
927             if os.time() - last_time > 20 then
928                 last_time = os.time()
929                 mymqtt_connect()
930             end
931         end
932     else
933         mymqtt_init()
934     end
935     sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " Azureiot.main end")
936 end
937
938 -- Initialize MQTT
939 function mymqtt_init()
940     sprint(string.format("mqtt init mqtt_url:%s mqtt_clientid:%s", MQTT_URL, MQTT_CLIENTID))
941     g_mq, err = mqtt.create(MQTT_URL, MQTT_CLIENTID) -- Create the object and declare it as a global variable
942     if g_mq then
943         g_mq:on("message", mymqtt_msg_callback) -- Register to receive message callbacks
944         sprint("mqtt init success")
945     else
946         sprint("mqtt init failed:", err)
947     end
948 end
949
950 -- Connect to MQTT server
951 function mymqtt_connect()
952     sprint("mqtt connecting...")
953     local stat, err = g_mq:connect(MQTT_CFG,MQTT_LWT, MQTT_CART)
954     if stat == nil then
955         sprint("mqtt connect failed:", err)
956         return
957     else
958         sprint("mqtt connected")
959     end
960     g_mq:subscribe(Subscribe_RE_TOPIC1, 0) 
961 end
962
963 -- Receive MQTT message callback function
964 function mymqtt_msg_callback(topic, msg)
965     print("topic:",topic)
966     print("revdata:",msg)
967    -- local revData = json.decode(msg)
968  --  if topic == Subscribe_RE_TOPIC1 then --Process topic information subscribed from the cloud
969 -- if string.match(topic,Subscribe_RE_TOPIC1) then
970      --   print("topi11:",topic)
971        setValue(revData)
972    -- end
973 end
974
975 --Process the received data
976 --function setValue(revData)
977    -- if revData ~=nil then 
978  --       for i,v in pairs(revData) do
979   --          print("Data received:",i,v)
980   --      end
981    -- end
982 --end
983
984 --Get real-time data
985 function getData()
986     local jdata = {}
987     local addr = bns_get_alldata()
988     print(json.encode(addr))
989     for i,v in pairs(addr) do
990         if v[2] == 1 then
991            jdata[v[3]] = v[4]
992         end
993     end
994     return jdata
995 end 
996
997
998
999 --send data
1000 function send_Data()
1001     local pub_data = {100
1002      --   services={{
1003
1004             --serviceId ='Temperature',
1005            -- properties={
1006                -- value = 55
1007            -- },
1008        -- }}
1009 }
1010 sprint(json.encode(pub_data))
1011 print("..........",pub_RE_TOPIC)
1012     return g_mq:publish(pub_RE_TOPIC, json.encode(pub_data), 0, 0)
1013 end
1014 {{/code}}
1015
1016 == **2.4 Huawei platform** ==
1017
1018 {{info}}
1019 **✎Note**:**Huawei IOT DA function is only in China area.If you want this function,you need to use chinese mobile to register**
1020 {{/info}}
1021
1022 1.Register a account: [[https:~~/~~/www.huaweicloud.com/intl/en-us/s/JUlPVERNJQ>>https://www.huaweicloud.com/intl/en-us/s/JUlPVERNJQ]]
1023
1024 2.log in the Huawei IOTDA
1025
1026 [[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]]
1027
1028 3.Create product
1029
1030 (% style="text-align:center" %)
1031 [[image:1624433478954-859.png||height="497" width="1100" class="img-thumbnail"]]
1032
1033 4.Product name,manufacturer,device type and industry,set according to your own needs.
1034
1035 Protocol: MQTT
1036
1037 Data Type: JSON
1038
1039 After finishing configuration,please click "OK"
1040
1041 (% style="text-align:center" %)
1042 [[image:1624433531968-337.png||height="568" width="700" class="img-thumbnail"]]
1043
1044 5.Device
1045
1046 After product register,continue to configure "individual register".Click "Device"~-~->"individual register"
1047
1048 (% style="text-align:center" %)
1049 [[image:1624434757597-117.png||class="img-thumbnail"]]
1050
1051 **Notes for registering device:**
1052
1053 Product: Previous product registration.
1054
1055 Node ID, Device Name: set according to your own needs.
1056
1057 Secret: need to be configured, will be used when connecting later
1058
1059 After configuration, click OK to generate a device ID and password, which will be used for device access later.
1060
1061 (% style="text-align:center" %)
1062 [[image:1624436421499-613.png||height="499" width="700" class="img-thumbnail"]]
1063
1064 (% style="text-align:center" %)
1065 [[image:1624437798012-126.png||height="366" width="500" class="img-thumbnail"]]
1066
1067 6. Connection authentication (use MQTT.fx tool to access the IoT platform)
1068
1069 (1)Open mqttClientIdGenerator tool Java(TM) Platform SE binary
1070
1071 **[[Download>>https://wecon-disk.oss-ap-southeast-1.aliyuncs.com/Download/WIKI/V-BOX/Demo/Huawei/mqttClientIdGenerator-19.2.0.zip]]**
1072
1073 (% style="text-align:center" %)
1074 [[image:1624437573798-815.png||height="351" width="700" class="img-thumbnail"]]
1075
1076 (2)Fill in the device ID and secret (deviceid and secret generated when registering the device) to generate connection message
1077
1078 Client ID, user name, password
1079
1080 (% style="text-align:center" %)
1081 [[image:1624437756866-251.png||height="405" width="700" class="img-thumbnail"]]
1082
1083 (3) Download certificate file"North-Beijing4"
1084
1085 [[https:~~/~~/support.huaweicloud.com/en-us/devg-iothub/iot_02_1004.html>>https://support.huaweicloud.com/en-us/devg-iothub/iot_02_1004.html]]
1086
1087 (% style="text-align:center" %)
1088 [[image:1624438225398-363.png||height="403" width="800" class="img-thumbnail"]]
1089
1090 (% style="text-align:center" %)
1091 [[image:1624438260025-610.png||height="408" width="700" class="img-thumbnail"]]
1092
1093 7.Run MQTTfx tool to connect with Huawei
1094
1095 Download link: [[http:~~/~~/mqttfx.jensd.de/index.php/download>>url:http://mqttfx.jensd.de/index.php/download]]
1096
1097 (1)Click on the setting ICON
1098
1099 (% style="text-align:center" %)
1100 [[image:1624438821280-974.png||height="198" width="500" class="img-thumbnail"]]
1101
1102 (2)Fill in IIOT MQTT device access address, and configure authentication parameters.
1103 First: It is the server and port connected to Huawei IOT, which can be viewed through the overview of the interface.
1104
1105 (% style="text-align:center" %)
1106 [[image:1624439086268-985.png||class="img-thumbnail"]]
1107
1108 Domain name:iot-mqtts.cn-north-4.myhuaweicloud.com
1109
1110 Port: 8883
1111
1112 Client ID: check step 6
1113
1114 (% style="text-align:center" %)
1115 [[image:1624439672168-492.png||height="458" width="600" class="img-thumbnail"]]
1116
1117 (3)Upload SSL certificate file,check step 6
1118
1119 Select folder java~-~->DigiCertGlobalRootCA.crt.pem and click OK or apply button
1120
1121 (% style="text-align:center" %)
1122 [[image:1624439912938-659.png||height="458" width="600" class="img-thumbnail"]]
1123
1124 (4)Connect and test publish and subscribe
1125
1126 (% style="text-align:center" %)
1127 [[image:1624440014872-688.png||height="232" width="700" class="img-thumbnail"]]
1128
1129 (% style="text-align:center" %)
1130 [[image:1624440026937-386.png||height="215" width="700" class="img-thumbnail"]]
1131
1132 Huawei publish topic format: $oc/devices/{device_id}/sys/properties/report
1133
1134 (% style="text-align:center" %)
1135 [[image:1624440404119-815.png||class="img-thumbnail"]]
1136
1137 Huawei subscribe topic format: **$oc/devices/{device_id}/sys/commands/#**
1138
1139 (% style="text-align:center" %)
1140 [[image:1624447157493-672.png||class="img-thumbnail"]]
1141
1142 (% style="text-align:center" %)
1143 [[image:1624447209982-715.png||class="img-thumbnail"]]
1144
1145 (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:
1146 ①Select the corresponding product from Huawei products to view
1147
1148 (% style="text-align:center" %)
1149 [[image:1624440647663-632.png||class="img-thumbnail"]]
1150
1151 ②Custom model: used to display the service ID name of the configuration report.
1152
1153 (% style="text-align:center" %)
1154 [[image:1624440793982-974.png||height="410" width="700" class="img-thumbnail"]]
1155
1156 (% style="text-align:center" %)
1157 [[image:1624440883015-105.png||height="370" width="600" class="img-thumbnail"]]
1158
1159 ③Add property, ID of monitoring point, and data format:
1160
1161 (% style="text-align:center" %)
1162 [[image:1624441052296-108.png||height="477" width="600" class="img-thumbnail"]]
1163
1164 ④After the configuration is complete, check the received data on the device
1165
1166 (% style="text-align:center" %)
1167 [[image:1624441186851-536.png||height="434" width="700" class="img-thumbnail"]]
1168
1169 === Huawei by SSL certification. ===
1170
1171 1.Create a project access for Huawei IOT
1172
1173 2.configure MQTT configuration
1174
1175 (% style="text-align:center" %)
1176 [[image:1624506363847-661.png||height="507" width="1000" class="img-thumbnail"]]
1177
1178 3.Create a script with the demo as below.
1179
1180 Script is as below
1181
1182 (% class="box infomessage" %)
1183 (((
1184 (% class="box infomessage" %)
1185 (((
1186 ~-~- mqtt.fx simulated access to Huawei Cloud IoT platform refer to 2.4
1187 sprint = print
1188
1189 ~-~-Get custom configuration parameters (gateway customization information)
1190 local CUSTOM = bns_get_config("bind")
1191 local DS_ID = CUSTOM.DSID or "5dfa0700df1ae506179afb9c_wecon"
1192
1193
1194 ~-~-OpenCloud mode interface, obtain MQTT information configured on cloud platform: (5 returned, respectively server address, client ID, connection table, last word table, certificate table)
1195 local MQTT_URL, MQTT_CLIENTID, MQTT_CFG, MQTT_LWT, MQTT_CART = mqtt.setup_cfg()
1196
1197 MQTT_CFG.username =DS_ID
1198 MQTT_CFG.password='d030d92338fcc18cd10fabb3003a4a0f6620fa6822cd3c23b1d9bc790200c6e7'
1199 MQTT_CLIENTID = '5dfa0700df1ae506179afb9c_wecon_0_0_2019121819'
1200
1201 ~-~-publish topic format:$oc/devices/{device id}/sys/properties/report
1202
1203 local pub_RE_TOPIC = string.format('$oc/devices/60a71ccbbbe12002c08f3a1a_WECON/sys/properties/report')
1204
1205 ~-~-variate
1206 local last_time = 0
1207
1208
1209 ~-~-Timing principal function
1210 function hwyiot.main()
1211
1212 sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " hwyiot.main start")
1213 if g_mq then
1214 if g_mq:isconnected() then
1215 send_Data()
1216 else
1217 if os.time() - last_time > 20 then
1218 last_time = os.time()
1219 mymqtt_connect()
1220 end
1221 end
1222 else
1223 mymqtt_init()
1224 end
1225 sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " hwyiot.main end")
1226 end
1227
1228 ~-~- initializationMQTT
1229 function mymqtt_init()
1230 sprint(string.format("mqtt init mqtt_url:%s mqtt_clientid:%s", MQTT_URL, MQTT_CLIENTID))
1231 g_mq, err = mqtt.create(MQTT_URL, MQTT_CLIENTID) ~-~- Create the object and declare it as a global variable
1232 if g_mq then
1233 g_mq:on("message", mymqtt_msg_callback) ~-~- Register to receive message callbacks
1234 sprint("mqtt init success")
1235 else
1236 sprint("mqtt init failed:", err)
1237 end
1238 end
1239
1240 ~-~- Connect to the MQTT server
1241 function mymqtt_connect()
1242 sprint("mqtt connecting...")
1243 local stat, err = g_mq:connect(MQTT_CFG,MQTT_LWT, MQTT_CART)
1244 if stat == nil then
1245 sprint("mqtt connect failed:", err)
1246 return
1247 else
1248 sprint("mqtt connected")
1249 end
1250
1251 ~-~-subscribe topic format:$oc/devices/{device_id}/sys/commands/#
1252
1253 g_mq:subscribe('$oc/devices/60a71ccbbbe12002c08f3a1a_WECON/sys/commands/#', 0) 
1254 end
1255
1256 ~-~- Receive the message callback function
1257 function mymqtt_msg_callback(topic, msg)
1258 sprint("recv data!")
1259 sprint("topic:msg", topic,msg)
1260 print(msg)
1261 local revData = json.decode(msg)
1262 \\end
1263
1264 ~-~-Send data
1265 function send_Data()
1266 local pub_data = {
1267 msgType = 'deviceReq',
1268 data = ~{~{
1269 serviceId ='Battery',
1270 serviceData={
1271 batteryLevel = 55
1272 }
1273 }}
1274 }
1275 return g_mq:publish(pub_RE_TOPIC, json.encode(pub_data), 0, 0)
1276 end
1277 )))
1278 )))
1279
1280 4.Download project access into V-Box to test in debug page
1281
1282 (% style="text-align:center" %)
1283 [[image:1624506710354-406.png||height="658" width="1000" class="img-thumbnail"]]
1284
1285 (% style="text-align:center" %)
1286 [[image:1624506666650-161.png||height="547" width="1000" class="img-thumbnail"]]
1287
1288 == **2.6 AWS platform** ==
1289
1290 === **Log in AWS** ===
1291
1292 Login aws account and click“Connect an IoT device”
1293
1294 [[image:image-20220709165402-1.png]]
1295
1296 [[image:image-20220709165402-2.png]]
1297
1298
1299 === **Create policy** ===
1300
1301 Click “Secure”~-~-->“Policies”~-~-->“Create policy”~-~-->Click “Create”
1302
1303 [[image:image-20220709165402-3.png]]
1304
1305 Name the policy~-~-->Click “JSON”~-~-->Copy the following content~-~-->Click “Create”
1306
1307 [[image:image-20220709165402-5.png]]
1308
1309 [[image:image-20220709165402-4.png]]
1310
1311 {{code language="java"}}
1312 {
1313   "Version": "2012-10-17",
1314   "Statement": [
1315     {
1316       "Effect": "Allow",
1317       "Action": [
1318         "iot:Connect",
1319         "iot:Publish",
1320         "iot:Subscribe",
1321         "iot:Receive",
1322         "greengrass:Discover"
1323       ],
1324       "Resource": "*"
1325     }
1326   ]
1327 }
1328 {{/code}}
1329
1330 === **Create things** ===
1331
1332 Click “Manage”~-~-->“Things”~-~-->“Create things”~-~-->“Create single thing”
1333
1334 [[image:image-20220709165402-6.png]]
1335
1336 [[image:image-20220709165402-7.png]]
1337
1338 Name the thing~-~-->Click “Next”
1339
1340 [[image:image-20220709165402-8.png]]
1341
1342 Select the way to create certificate
1343
1344 [[image:image-20220709165402-9.png]]
1345
1346 Select policy
1347
1348 [[image:image-20220709165402-10.png]]
1349
1350 [[image:image-20220709165402-11.png]]
1351
1352
1353 === **MQTT.fx tool** ===
1354
1355 Click “View Setting” to get the “Broker Adress”
1356
1357 [[image:image-20220709165402-13.png]]
1358
1359 [[image:image-20220709165402-12.png]]
1360
1361 Create one connection in MQTT.fx tool, set broker port as 8883.
1362
1363 [[image:image-20220709165402-14.png]]
1364
1365 Upload the CA File, Client Certificate File, Client Key File
1366
1367 [[image:image-20220709165402-15.png]]
1368
1369 Publish message to topic “TEST”
1370
1371 [[image:image-20220709165402-17.png]]
1372
1373 Click”Test”~-~-->”MQTT test client”~-~-->”Subscrible to a topic”, to get message publish from MQTT.fx tool.
1374
1375 [[image:image-20220709173500-1.png]]
1376
1377 And we can also send message form AWS platform to MQTT.fx tool.
1378
1379 [[image:image-20220709165402-18.png]]
1380
1381 === **CloudTool** ===
1382
1383 Copy the same setting in MQTT.fx to MQTT configuration
1384
1385 [[image:image-20220709165402-19.png]]
1386
1387 Add a lua script and copy the lua demo into it.
1388
1389 [[image:image-20220709165402-20.png]]
1390
1391 {{info}}
1392 **✎Note:** Before using the following demo script, please make sure the V-Box firmware is newer than 22110701
1393 {{/info}}
1394
1395 {{code language="lua"}}
1396 sprint = print
1397
1398 --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)
1399
1400 local MQTT_URL, MQTT_CLIENTID, MQTT_CFG, MQTT_LWT, MQTT_CART = mqtt.setup_cfg()
1401
1402 --publish to topics
1403
1404 local pub_RE_TOPIC = string.format('TEST')
1405
1406 --Subscribe topics
1407
1408 local Subscribe_RE_TOPIC1 = string.format('TEST')
1409
1410 --variable
1411
1412 local last_time = 0
1413
1414 --Timing main function
1415
1416 function aws.main()
1417
1418 sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " aws.main start")
1419
1420 if g_mq then
1421
1422 if g_mq:isconnected() then
1423
1424 send_Data()
1425
1426 else
1427
1428 if os.time() - last_time > 5 then
1429
1430 last_time = os.time()
1431
1432 mymqtt_connect()
1433
1434 end
1435
1436 end
1437
1438 else
1439
1440 mymqtt_init()
1441
1442 end
1443
1444 sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " aws.main end")
1445
1446 end
1447
1448
1449
1450 -- Initialize MQTT
1451
1452 function mymqtt_init()
1453
1454 sprint(string.format("mqtt init mqtt_url:%s mqtt_clientid:%s", MQTT_URL, MQTT_CLIENTID))
1455
1456 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
1457
1458 if g_mq then
1459
1460 g_mq:on("message", mymqtt_msg_callback) -- Register to receive message callbacks
1461
1462 sprint("mqtt init success")
1463
1464 else
1465
1466 sprint("mqtt init failed:", err)
1467
1468 end
1469
1470 end
1471
1472 -- Connect to MQTT server
1473
1474 function mymqtt_connect()
1475
1476 sprint("mqtt connecting...")
1477
1478 local stat, err = g_mq:connect(MQTT_CFG,MQTT_LWT, MQTT_CART)
1479
1480 if stat == nil then
1481
1482 sprint("mqtt connect failed:", err)
1483
1484 return
1485
1486 else
1487
1488 sprint("mqtt connected")
1489
1490 end
1491
1492 g_mq:subscribe(Subscribe_RE_TOPIC1, 0)
1493
1494 end
1495
1496 -- Receive MQTT message callback function
1497
1498 function mymqtt_msg_callback(topic, msg)
1499
1500 print("topic:",topic)
1501
1502 print("revdata:",msg)
1503
1504 local revData = json.decode(msg)
1505
1506 print (revData)
1507
1508 if topic == Subscribe_RE_TOPIC1 then --Process topic information subscribed from the cloud
1509
1510 if string.match(topic,Subscribe_RE_TOPIC1) then
1511
1512 --if revData ~= nil then
1513
1514 for k,v in pairs (revData) do
1515
1516 print("printing revdata after kv here")
1517
1518 print (k,v)
1519
1520 end
1521
1522 print ("current state is",fanstate)
1523
1524 --end
1525
1526 end
1527
1528 end
1529
1530 end
1531
1532
1533
1534 --Get real-time data
1535
1536 function getData()
1537
1538 local jdata = {}
1539
1540 local addr = bns_get_alldata()
1541
1542 print(json.encode(addr))
1543
1544 for i,v in pairs(addr) do
1545
1546 if v[2] == 1 then
1547
1548 jdata[v[3]] = v[4]
1549
1550 end
1551
1552 end
1553
1554 return jdata
1555
1556 end
1557
1558 --send data
1559
1560 function send_Data()
1561
1562 local pub_data =
1563 {
1564 123
1565 }
1566
1567 sprint(json.encode(pub_data))
1568
1569 print("..........",pub_RE_TOPIC)
1570
1571 return g_mq:publish(pub_RE_TOPIC, json.encode(pub_data), 0, 0)
1572
1573 end
1574 {{/code}}
1575
1576 Get message in AWS
1577
1578 [[image:image-20220709165402-21.png]]
1579
1580 == **2.7 Mysql** ==
1581
1582 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.
1583
1584 (% class="wikigeneratedid" id="H1.InstallMysql" %)
1585 **1.Install Mysql**
1586
1587 version
1588
1589 (% style="text-align:center" %)
1590 [[image:Mysql的软件版本.png]]
1591
1592 (% class="wikigeneratedid" id="H2.InstallNavicat" %)
1593 **2.Install Navicat**
1594
1595 (% class="wikigeneratedid" %)
1596 version
1597
1598 (% style="text-align:center" %)
1599 [[image:navicat 版本.png]]
1600
1601
1602 Connecting to Mysql with navicat.
1603
1604 (% style="text-align:center" %)
1605 [[image:连接到mysql.png]]
1606
1607 (% class="wikigeneratedid" id="H3.Createdatabase" %)
1608 **3.Create database**
1609
1610 Character set should be choose utf8mb3/utf8mb4 and Collation choose utf8mb3_danish_ci/utf8mb4_danish_ci.
1611
1612 (% style="text-align:center" %)
1613 [[image:创建数据库.png]]
1614
1615 (% class="wikigeneratedid" id="H4.Createdatatable" %)
1616 **4.Create data table**
1617
1618 Create a table, enter the fields you need.
1619
1620 (% style="text-align:center" %)
1621 [[image:创建表1.png]]
1622
1623
1624 Save, enter table name.
1625
1626 (% style="text-align:center" %)
1627 [[image:创建表2.png]]
1628
1629 (% class="wikigeneratedid" id="H5.InputTableData" %)
1630 **5.Input Table Data**
1631
1632 (% style="text-align:center" %)
1633 [[image:输入或者导入数据.png]]
1634
1635 (% class="wikigeneratedid" id="H6.Script" %)
1636 **6.Script**
1637
1638 **luaMySql.init(string sourcename, string username, string password, string host, number port, string character)**
1639
1640 **Function:** Configure database connection parameters
1641
1642 **Parameter:**
1643
1644 sourcename: the name of database
1645
1646 username: the username of the connection
1647
1648 password: the password of the connection
1649
1650 host: the host name of the connection
1651
1652 port: the host port of the connection
1653
1654 character: the character set of the connection
1655
1656 **Return:**
1657
1658 Succeed: string
1659
1660 Failed: multi
1661
1662 **luaMySql.exec(string statement)**
1663
1664 **Function:** Execute the given SQL statement without returning the result set (add, delete, change)
1665
1666 **Parameter:**
1667
1668 statement: the given SQL statement
1669
1670 **Return:**
1671
1672 Succeed: status: returns the number of rows affected by SQL statement execution.
1673
1674 Failed: nil, errorString
1675
1676 **luaMySql.execWithResult(string statement)**
1677
1678 **Function:** Execute the given SQL statement returning the result set (check)
1679
1680 **Parameter:**
1681
1682 statement: the given SQL statement
1683
1684 **Return:**
1685
1686 Succeed: table: returns the result set
1687
1688 Failed: nil, errorString
1689
1690 **For example:**
1691
1692
1693 {{code language="LUA"}}
1694 -- Assuming the "mysqlclient" library is properly installed and available
1695 mysql = require("mysqlclient")
1696
1697 function DataInitRight()
1698 local dbName = "excel"
1699 local user = "root"
1700 local pwd = "XXXXX"
1701 local host = "192.168.39.146"
1702 local port = 3306
1703 local character = "utf8mb3"
1704
1705 mysql.init(dbName, user, pwd, host, port, character)
1706 end
1707
1708 function ExecFunc()
1709 status, errorString = mysql.exec("delete from student where Name = 'XXX';") --Delete statement, column name = table element
1710 if nil == status then
1711 print("ExecFunc() error:", errorString)
1712 return -1
1713 else
1714 print("the number of rows affected by the command:", status)
1715 end
1716 return 0
1717 end
1718
1719
1720 function ExecWithResultFunc()
1721 status, errorString = mysql.execWithResult("select * from student;")
1722 if nil == status then
1723 print("ExecWithResultFunc() error:", errorString)
1724 return -1
1725 else
1726 print("ExecWithResultFunc() success : status type = ", type(status))
1727 print("ExecWithResultFunc() success : status len = ", #status)
1728 local num = #status
1729 local i = 1
1730 if num > 0 then
1731 for i = 1, num, 1 do
1732 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
1733 print(var)
1734 end
1735 end
1736 print("---------------")
1737 end
1738 return 0
1739 end
1740
1741 function MySQL.main()
1742 print("script running ...")
1743 DataInitRight()
1744
1745 -- use exec demo
1746 if ExecFunc() < 0 then
1747 return
1748 end
1749
1750 -- use execWithResult demo
1751 if ExecWithResultFunc() < 0 then
1752 return
1753 end
1754
1755 print("script running success")
1756 end
1757 {{/code}}
1758
1759 (% class="wikigeneratedid" id="H7.Debug" %)
1760 **7.Debug**
1761
1762 (% style="text-align:center" %)
1763 [[image:调试结果.png]]
1764
1765 (% class="wikigeneratedid" id="H8.Problem" %)
1766 8.Problem
1767
1768 During our debugging process it may there are some problems about Mysql, such as
1769
1770 * MySQL: Host  192.168.XXX.XXX  is not allowed to connect.
1771 * MySQL: Host  192.168.XXX.XXX  is blocked because of many connection errors.
1772 * MySQL: SSL connection error: unknown error number.
1773 * (((
1774 1449-The user specified as a definer(‘mysql.infoschema‘@localhost‘) does not exist.
1775 )))
1776
1777 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.
1778
1779 {{info}}
1780 ✎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.
1781 {{/info}}