Wiki source code of 2 Script

Version 81.4 by Joe on 2024/05/21 11:24

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