Wiki source code of 2 Script

Version 8.2 by Devin Chen on 2025/11/05 09:27

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