Wiki source code of 2 Script

Version 6.1 by Devin Chen on 2025/09/09 15:10

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