2 Script
1 General Script Demo
1.1 Address Operation
Write/Read data from address A to B. For example:transfer D2 to D0
Depend on diffferent format of data.V-Box use different script functions.
for example. addr_setshort(addr,num) Function: Write 16-bit signed decimal address
addr_getshort(addr) Function:Read 16-bit signed decimal address
addr_getword(string addr)Function: Read 16-bit unsigned decimal address
More script function are in the second section of “V-BOX Script Interface Manual”
1.2 Arithmetic
1.3 Set 100 to D0--D19
1.4 Short message
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.
When the alarm condition is released,then send an "alarm release" sms. Script is as below:
------send condition------
local temp1 = addr_getword("@Temperature1")
local temp2 = addr_getword("@Temperature2")
local temp3 = addr_getword("@Temperature3")
local timer = addr_getword("@Timer")
local tag = addr_getbit("@Tag")
------lasting time------
if temp1 > 5 and temp2 > 10 and temp3 < 20 then
timer = timer + 1
addr_setword("@Timer",timer)
else
timer = 0
addr_setword("@Timer",timer)
end
------send sms & output Y0------
if timer > 5 then
if tag == 0 then
send_sms_ira("19859254700","alarm trigger")
addr_setbit("@Tag",1)
end
elseif tag == 1 then
send_sms_ira("19859254700","alarm release")
addr_setbit("@Tag",0)
end
end
1.5 Telegram notification
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.
As for How to get the botToken and chatID, please check the following videos:
https://www.youtube.com/watch?v=zh6yYlnjX7k
https://www.youtube.com/watch?v=Pj8mwuMZZvg
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.
After deleting Webhook, you can change to "getUpdates" and continue to follow the second video.
1.Permissions
Bots added to Groups or Channels need to be provided with administrator rights. For example "joe" is bot I created.
2.URL check
You can use the URL to test the status of a group or channel.
url = "https://api.telegram.org/bot"..telegramBotToken.."/sendMessage?text="..message.."&chat_id="..telegramChatID
3.Script
local tempWord = 0
local botToken = "5504549693:AAEy6a5G-sOF3CINONxMNABeYnoS4ABVlfg"
local chatID = "-641959124"--The chat id from Channel or Group
local https = require("https")
local json = require("json")
-- Send http.get request and return response result
function getHttpsUrl(url)
local body = {}
local bodyJson = json.encode(body)
local header = {}
header["content-type"] = "application/json"
local result_table, code, headers, status = https.request(url, bodyJson)
print("code:"..code)
if code~= 200 then
return
else
return body
end
end
function sendAlarm(telegramBotToken, message, telegramChatID)
local url = "https://api.telegram.org/bot"..telegramBotToken.."/sendMessage?text="..message.."&chat_id="..telegramChatID
--local url = 'http://v-box.net'
--local url = 'https://www.google.com/'
print("Get the link:"..url)
getHttpsUrl(url)
end
function AlarmNotificate.main()
local bitValue = addr_getbit("@HDX");
local message = ''
print("b=="..bitValue)
if bitValue == 1 and bitValue ~= tempBit then
message = 'Alarm triggered, the monitoring point test value is '.. bitValue
sendAlarm(botToken, message, chatID)
print("Notification pushed of triggering alarm,"..bitValue)
elseif bitValue == 0 and bitValue ~= tempBit then
message = 'Alarm dismissed, the monitoring point test value is '.. bitValue
sendAlarm(botToken, message, chatID)
print("Notification pushed of dismissing alarm,"..bitValue)
end
tempBit = bitValue----Prevent monitoring values from continuous being sent to the platform
local wordValue = addr_getword("@HDW10")
print("w=="..wordValue)
--dosomething
if wordValue >= 100 and wordValue ~= tempWord and tempWord <= 100 then
message = 'Word alarm triggered, the word value is '.. wordValue
sendAlarm(botToken, message, chatID)
print("Notification pushed of triggering alarm,"..wordValue)
elseif wordValue < 100 and wordValue ~= tempWord and tempWord >= 100 then
message = 'Word alarm dismissed, the word value is '.. wordValue
sendAlarm(botToken, message, chatID)
print("Notification pushed of dismissing alarm,"..wordValue)
end
tempWord = wordValue----Prevent monitoring values from continuous being sent to the platform
end
1.6 LINE Notify
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.
local tempWord = 0
local LineToken = "08XCpubkOdwGdGgRTXF0x8umiyrALtoM0v6lBFUV6PC"
local https = require("https")
local json = require("json")
local ltn12 = require("ltn12")
-- Send http.get request and return response result
function getHttpsUrl(url,header,reqbody)
local body = {}
local bodyJson = json.encode(body)
local result_table, code, headers, status = https.request{
method = "POST",
url = url,
source = ltn12.source.string(reqbody),
headers = header,
sink = ltn12.sink.table(body)
}
print("code:"..code)
if code~= 200 then
return
else
return body
end
end
function getMessageUrl(lineMessage)
local url = "https://notify-api.line.me/api/notify"
local reqMess = "message="..lineMessage
local headers =
{
["Authorization"] = "Bearer "..LineToken,
["Content-Type"] = "application/x-www-form-urlencoded",
["Content-Length"] = #reqMess
}
print("Get the link:"..url)
getHttpsUrl(url, headers, reqMess)
end
function linenotify.main()
local bitValue = addr_getbit("@test");
local message = ''
print("b=="..bitValue)
if bitValue == 1 and bitValue ~= tempBit then
message = 'Alarm V-Box triggered, the output is '.. bitValue
getMessageUrl(message)
print("Notification pushed of triggering alarm,"..bitValue)
elseif bitValue == 0 and bitValue ~= tempBit then
message = 'Alarm V-Box dismissed, the output is '.. bitValue
getMessageUrl(message)
print("Notification pushed of dismissing alarm,"..bitValue)
end
tempBit = bitValue----Prevent monitoring values from continuous being sent to the platform
local wordValue = addr_getword("@t2")
print("w=="..wordValue)
--dosomething
if wordValue >= 100 and wordValue ~= tempWord and tempWord <= 100 then
message = 'Alarm V-Box triggered, the temperature is '.. wordValue
getMessageUrl(message)
print("Notification pushed of triggering alarm,"..wordValue)
elseif wordValue < 100 and wordValue ~= tempWord and tempWord >= 100 then
message = 'Alarm V-Box dismissed, the temperature is '.. wordValue
getMessageUrl(message)
print("Notification pushed of dismissing alarm,"..wordValue)
end
tempWord = wordValue----Prevent monitoring values from continuous being sent to the platform
end
1.7 Twilio WhatsApp Messaging
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.
About how to register the Twilio API, please check the following video:
https://www.youtube.com/watch?v=Id4lKichauU
local tempWord = 0
local https = require("https")
local json = require("json")
local ltn12 = require("ltn12")
local SID = 'AC1703bd710ffa98006d2bcc0b********'
local Token = 'd3c11897623c39e538b20263ec19****'
local twilioPhoneNumber = '+14155238886'
local receiverPhoneNumber = '+8615880018277'
local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
function encodingBase64(data)
return ((data:gsub('.', function(x)
local r,b='',x:byte()
for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
return r;
end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
if (#x < 6) then return '' end
local c=0
for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
return b:sub(c+1,c+1)
end)..({ '', '==', '=' })[#data%3+1])
end
function encodeUrl(str)
str = string.gsub(str, "([^%w%.%- ])", function(c)
return string.format("%%%02X", string.byte(c)) end)
return string.gsub(str, " ", "+")
end
function requestBodySplice(message, sender, receiver)
local reqBody = ''
local encodeMess = encodeUrl(message)
local encodeSend = encodeUrl(sender)
local encodeRece = encodeUrl(receiver)
--reqBody = "Body=Hello%20Wecon2&From=whatsapp%3A%2B14155238886&To=whatsapp%3A%2B8615880018277"
reqBody = string.format("Body=%s&From=whatsapp:%s&To=whatsapp:%s", encodeMess, encodeSend, encodeRece)
print(reqBody)
return reqBody
end
-- Send http.get request and return response result
function getHttpsUrl(url,header,reqbody)
local body = {}
local bodyJson = json.encode(body)
local result_table, code, headers, status = https.request{
method = "POST",
url = url,
source = ltn12.source.string(reqbody),
headers = header,
sink = ltn12.sink.table(body)
}
print("code:"..code)
if code~= 200 then
return
else
return body
end
end
function getMessageUrl(whatsAppMessage)
local auth = SID..':'..Token
local url = "https://api.twilio.com/2010-04-01/Accounts/"..SID.."/Messages"
--local reqMess = "message="..twilioMessage
local reqMess = requestBodySplice(whatsAppMessage, twilioPhoneNumber, receiverPhoneNumber)
local headers =
{
["Authorization"] = "Basic "..encodingBase64(auth),
["Content-Type"] = "application/x-www-form-urlencoded",
["Content-Length"] = #reqMess
}
print("Get the link:"..url)
getHttpsUrl(url, headers, reqMess)
end
function Twilio.main()
--dosomething
--local auth = SID..':'..Token
--print(requestBodySplice("HelloWorld", twilioPhoneNumber, receiverPhoneNumber))
--print(encodingBase64(auth))
local bitValue = addr_getbit("@testBit");
local message = ''
print("b=="..bitValue)
if bitValue == 1 and bitValue ~= tempBit then
message = 'Alarm V-Box triggered, the output is '.. bitValue
getMessageUrl(message)
print("Notification pushed of triggering alarm,"..bitValue)
elseif bitValue == 0 and bitValue ~= tempBit then
message = 'Alarm V-Box dismissed, the output is '.. bitValue
getMessageUrl(message)
print("Notification pushed of dismissing alarm,"..bitValue)
end
tempBit = bitValue----Prevent monitoring values from continuous being sent to the platform
local wordValue = addr_getword("@testWord")
print("w=="..wordValue)
--dosomething
if wordValue >= 100 and wordValue ~= tempWord and tempWord <= 100 then
message = 'Alarm V-Box triggered, the temperature is '.. wordValue
getMessageUrl(message)
print("Notification pushed of triggering alarm,"..wordValue)
elseif wordValue < 100 and wordValue ~= tempWord and tempWord >= 100 then
message = 'Alarm V-Box dismissed, the temperature is '.. wordValue
getMessageUrl(message)
print("Notification pushed of dismissing alarm,"..wordValue)
end
tempWord = wordValue----Prevent monitoring values from continuous being sent to the platform
end
1.8 HTTP response body
This example use 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":
Then the response body would be like as following:
"location": {
"name": "Madrid",
"region": "Madrid",
"country": "Spain",
"lat": 40.4,
"lon": -3.68,
"tz_id": "Europe/Madrid",
"localtime_epoch": 1669022636,
"localtime": "2022-11-21 10:23"
},
"current": {
"last_updated_epoch": 1669022100,
"last_updated": "2022-11-21 10:15",
"temp_c": 13.0,
"temp_f": 55.4,
"is_day": 1,
"condition": {
"text": "Partly cloudy",
"icon": "//cdn.weatherapi.com/weather/64x64/day/116.png",
"code": 1003
},
"wind_mph": 11.9,
"wind_kph": 19.1,
"wind_degree": 210,
"wind_dir": "SSW",
"pressure_mb": 1015.0,
"pressure_in": 29.97,
"precip_mm": 0.0,
"precip_in": 0.0,
"humidity": 88,
"cloud": 75,
"feelslike_c": 10.8,
"feelslike_f": 51.4,
"vis_km": 10.0,
"vis_miles": 6.0,
"uv": 3.0,
"gust_mph": 22.1,
"gust_kph": 35.6
}
}
So we decode json into lua object to assign the value into addresses HDW6060(temperature), HDW7070(humidity), the code example like follows:
local http = require("socket.http")
local json = require("json")
-- Send http.get request and return response result
function getHttpsUrl(url)
local result_table, code, headers, status = http.request(url)
print("code:"..code)
if code~= 200 then
return
else
return result_table
end
end
function sendAPI(key, city)
local url = "http://api.weatherapi.com/v1/current.json?key="..key.."&q="..city.."&aqi=no"
--local url = 'http://v-box.net'
--local url = 'https://www.google.com/'
--http://api.weatherapi.com/v1/current.json?key=70faaecf926b4341b1974006221711&q=Barcelona&aqi=no
print("Get the link:"..url)
local body = getHttpsUrl(url)
--print(body)
local jsonBody = json.decode(body)
--print(jsonBody["current"]["temp_c"])
--print(type(jsonBody["current"]["temp_c"]))
--print(type(jsonBody["current"]["humidity"]))
addr_setfloat("@HDW6060", jsonBody["current"]["temp_c"])
addr_setword("@HDW7070", jsonBody["current"]["humidity"])
end
function Weather.main()
local cityName = addr_getstring("@HDW5050",6)
print("cityName: "..cityName)
sendAPI(APIkey, cityName)
end
1.9 High-Low Byte Switch
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.
addr_setfloat("@W_0#HDW23036",floatNumber,0,2)
local newFloat = addr_getfloat("@W_0#HDW23036")
local formattedFloat = string.format("%.2f",newFloat)
print("The formatted float value is the : "..formattedFloat)
return formattedFloat
end
1.10 Read 64bits Unsigned Value
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.
local highAddress = addr_newnoaddr(address,2)
local low32 = addr_getdword(address)
local high32 = addr_getdword(highAddress)
--print("the low number is "..low32)
--print("the high number is "..high32)
local formatVal = string.format("%64.0f",2^32*high32+low32)
print("the format value is ".. formatVal)
return formatVal
end
2 Third part server
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.
1.Europe server:eu.v-box.net
2.Asean server:asean.v-box.net
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
OpenCloud platform is used in configuring the script.Then V-Box can connect with third part server.
Both mode can support script to connect with third part server.the difference:
1.If you want to store in WECON server ,please use V-NET.
2.If your server requires SSL certificate to log in,please use OpenCloud.Because only OpenCloud platform can support to upload certificate
Tool link: MQTT.fx
2.1 Test server(General Example)
The following example is trying to publish to the topic "testtopic/test/no1/7890", and subscribe the topic "testtopic/test/no1/123456".
And the JSON message is like follows:
"timestamp": 1631152760,
"messageId": 1,
"event": "test_data",
"mfrs": "HMI/box",
"data":
{
"id" : 1436217747670454274,
"waterlevel" : 48,
"temperture" : 23
}
}
local MQTT_CFG={}
--if there is no need the username and password, please put them as ""
MQTT_CFG.username = "weconsupport"
MQTT_CFG.password = "123456"
MQTT_CFG.netway = 0
MQTT_CFG.keepalive = 60
MQTT_CFG.cleansession = 1
--TCP URL
MQTT_URL = "tcp://mq.tongxinmao.com:1883"
--Client ID
MQTT_CLIENT_ID = "V-BOXH-AG"
--Generate UUID
function uuid()
local seed = {'e','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}
local tb = {}
for i=1, 32 do
table.insert(tb, seed[math.random(1,16)])
end
local sid=table.concat(tb)
return string.format('%s',
string.sub(sid,1,32)
)
end
--Topic name to subscribed
local SUBSCRIBE_TOPIC = 'testtopic/test/no1/123456'
--Topic name to be published
local PUBLISH_TOPIC = 'testtopic/test/no1/7890'
--real time
local LAST_TIME = 0
--initialize mqtt
function mqtt_init()
print(string.format("mqtt init mqtt_url:%s mqtt_clientid:%s", MQTT_URL, MQTT_CLIENT_ID))
if g_mq then
mqtt.close(g_mq) --Close mqtt object
end
g_mq, err = mqtt.create(MQTT_URL, MQTT_CLIENT_ID) -- create mqtt object,and declare it as a global variable
if g_mq then
g_mq:on("message", mqtt_msg_callback) -- Register a callback for receiving messages
g_mq:on("offline", mqtt_msg_offline) -- Register a callback for offline
print("mqtt init success")
else
print("mqtt init failed:", err)
end
end
-- connect to mqtt
function mqtt_connect()
print("mqtt connecting...")
local stat, err = g_mq:connect(MQTT_CFG)
if stat == nil then
print("mqtt connect failed:", err)
return
else
print("mqtt connected")
end
g_mq:subscribe(SUBSCRIBE_TOPIC, 0)
end
--Offline callback function
function mqtt_msg_offline(cause)
print("mqtt offline, cause:", cause)
end
-- Received message callback function
function mqtt_msg_callback(topic, msg)
print("topic:", topic)
print("msg:", msg)
local objMsg = json.decode(msg)
local water = objMsg.data.waterlevel
local temp = objMsg.data.temperature
addr_setword("@HDW20",water)
addr_setword("@HDW10",temp)
end
--Send data (data upload to platform and encapsulate it with custom functions)
function send_data()
local pub_data = {
timestamp = os.time(),
messageId = 1,
event = 'test_data',
mfrs = 'V-Box',
data = {
id = uuid(),
waterlevel = addr_getword("@HDW10"),
temperature = addr_getword("@HDW20")
}
}
return g_mq:publish(PUBLISH_TOPIC, json.encode(pub_data), 0, 0)
end
--main function fixed timed execution
function MQTT.main()
--dosomething
print(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " main start")
--determine the mqtt object whether exist
if g_mq then
--determine the mqtt object whether has been connected or not
if g_mq:isconnected() then
send_data()
else
--if exceed 5 sec not connect, reconnect once
if os.time() - LAST_TIME > 5 then
LAST_TIME = os.time()
--reinitial the mqtt object
mqtt_init()
--connect to mqtt or reconnect
mqtt_connect()
end
end
else
--mqtt object does not exist so create new one
mqtt_init()
end
print(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " main end")
end
2.2 Customer server:grouprobotinfo.com
This demo does not use SSL certification. Script is as below
Demo1:
--main
function mq.main()
if not mq.m then
local err = ""
mq.m, err = mqtt.create("tcp://grouprobotinfo.com:1883", "ClienID") -- create connection
if mq.m then
mq.config = {
username = "",-- ID
password = "",-- password
netway = 1, -- Ethernet connection, WIFI=1
-- keepalive = 100, -- Optional, set the connection heartbeat interval for 100 seconds.
-- cleansession = 0, -- Optional, keep session
}
mq.m:on("message", function(topic, msg) -- Register for receiving message callbacks
local str = string.format("%s:%s", topic, msg)
-- print("mqtt msg:", str) -- Print out the received topics and content
end)
mq.m:on("offline", function (cause) -- Register for lost connection callbacks
-- addr_setstring("@xxx", "cause"..(cause or " got nil"))
end)
mq.m:on("arrived", function() -- Registration for sending messages to callbacks
print("msg arrived")
end)
else
print("mqtt create failed:", err) -- Create object failed
end
else
if mq.m:isconnected() then -- If online, post a message
local phaseStatus ="unknow"
if addr_getbit("@Standby")== 1 then
phaseStatus = "Standby"
elseif addr_getbit("@Pre-Freeze")==1 then
phaseStatus= "Pre-Freeze"
elseif addr_getbit("@Prepare")==1 then
phaseStatus ="Prepare"
elseif addr_getbit("@Primary Dry")==1 then
phaseStatus = "Primary dry"
elseif addr_getbit("@Secondary Dry")==1 then
phaseStatus = "Secondary Dry"
end
--print(addr_getbit("@Primary Dry"))
-------------------------------------------------------------------------------------------------------------------------
local activating ="unknow"
if addr_getbit("@Compressor")==1 then
activating = ",".."Compressor"
end
if addr_getbit("@Silicone Pump")==1 then
activating = activating..",".."Silicone Pump"
end
if addr_getbit("@Vacuum Pump")==1 then
activating = activating..",".."Vacuum Pump"
end
if addr_getbit("@Root Pump")==1 then
activating = activating..",".."Root Pump"
end
if addr_getbit("@Heater")==1 then
activating = activating..",".."Heater"
end
if addr_getbit("@Valve Silicone")==1 then
activating = activating..",".."Valve Silicone"
end
if addr_getbit("@Valve Ice Condenser")==1 then
activating = activating..",".."Valve Ice Condenser"
end
if addr_getbit("@Valve Vacuum Pump")==1 then
activating = activating..",".."Valve Vacuum Pump"
end
local pr_activating =string.sub(activating,2)
-- print(pr_activating)
local status_text ="unknow"
if addr_getbit("@Status Run")==1 then
status_text = "RUNNING"
else
status_text = "STOP"
end
-------------------------------------------------------------------------------------------------------------------------
local js = {type="status",
mc_name ="FD300",
status=status_text,
elapsed_time={
hour=addr_getword("@Elapsed Time (Hour)"),
min=addr_getword("@Elapsed Time (Minute)"),
sec=addr_getword("@Elapsed Time (Second)")
},
phase = phaseStatus,
step = addr_getword("@Step"),
activating_output = pr_activating,
sv=addr_getshort("@SV Silicone")/10,
pv=addr_getshort("@PV Silicone")/10,
product1=addr_getshort("@Product 1")/10,
product2=addr_getshort("@Product 2")/10,
product3=addr_getshort("@Product 3")/10,
product4=addr_getshort("@Product 4")/10,
ice1=addr_getshort("@Ice condenser 1")/10,
ice2=addr_getshort("@Ice condenser 2")/10,
vacuum=addr_getfloat("@Vacuum")
}
local jsAlarm = { HPC = addr_getbit("@B_25395#W0.00"),
ODPC = addr_getbit("@B_25395#W0.01"),
MTPC=addr_getbit("@B_25395#W0.02"),
HTT = addr_getbit("@B_25395#W1.03"),
CPC = addr_getbit("@B_25395#W0.08"),
CPSP =addr_getbit("@B_25395#W1.00"),
CPVP =addr_getbit("@B_25395#W0.10"),
CPRP =addr_getbit("@B_25395#W0.11"),
HP =addr_getbit("@B_25395#W1.01"),
PP= addr_getbit("@B_25395#W1.02"),
PO=addr_getbit("@B_25395#W0.07"),
FSE=addr_getbit("@B_25395#W2.04"),
AVVSVV=addr_getbit("@B_25395#W1.12"),
ICHT=addr_getbit("@B_25395#W3.06")
}
-- ("@B_25395#CIO1.02")
mq.m:publish("mqtt-v-box-epsilon-fd300", json.encode(js) , 0, 0)
mq.m:publish("mqtt-v-box-epsilon-alarm-fd300", json.encode(jsAlarm) , 0, 0)
else
local stat, err = mq.m:connect(mq.config) -- connection
if stat == nil then --Determine whether to connect
print("mqtt connect failed:", err)
return -- Connection failed, return directly
end
mq.m:subscribe("mqtt-v-box-epsilon", 0)-- Subscribe to topics
end
-- mq.m:unsubscribe("stc/test")
-- mq.m:disconnect() -- close matt
-- mq.m:close() -- close clase
end
end
2.3 Azure platform
In this demo,V-Box connects with Azure by SSL certification.
Video link: https://youtu.be/cdI6rIQcpMY?list=PL_Bpnb2RgaksCic9HCcVAZhU9sYwCRKzW
Tool Download link: https://wecon-disk.oss-ap-southeast-1.aliyuncs.com/Download/WIKI/V-BOX/Demo/Azure/Azure%20tool.zip
Script is as below
sprint = print
--Get custom configuration parameters (vbox custom information)
--local CUSTOM = bns_get_config("bind")
--local DS_ID = CUSTOM.DSID or "60a71ccbbbe12002c08f3a1a_WECON"
--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)
local MQTT_URL, MQTT_CLIENTID, MQTT_CFG, MQTT_LWT, MQTT_CART = mqtt.setup_cfg()
--MQTT_CFG.username = '60a71ccbbbe12002c08f3a1a_WECON'
--MQTT_CFG.password='wecon123'
--MQTT_CLIENTID = '60a71ccbbbe12002c08f3a1a_WECON_0_0_2021052110usernxame:60a71ccbbbe12002c08f3a1a_WECONpassword:a0a951581855aa8e0262129da6cf1b43f2c0ecfac4fa56117fc5a20c90be169a'
--publish to topics
local pub_RE_TOPIC = string.format('devices/wecon_02/messages/events/')
--Subscribe topics
local Subscribe_RE_TOPIC1 = string.format('devices/wecon_02/messages/devicebound/#')
--variable
local last_time = 0
--Timing main function
function Azure.main()
sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " Azureiot.main start")
if g_mq then
if g_mq:isconnected() then
send_Data()
else
if os.time() - last_time > 20 then
last_time = os.time()
mymqtt_connect()
end
end
else
mymqtt_init()
end
sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " Azureiot.main end")
end
-- Initialize MQTT
function mymqtt_init()
sprint(string.format("mqtt init mqtt_url:%s mqtt_clientid:%s", MQTT_URL, MQTT_CLIENTID))
g_mq, err = mqtt.create(MQTT_URL, MQTT_CLIENTID) -- Create the object and declare it as a global variable
if g_mq then
g_mq:on("message", mymqtt_msg_callback) -- Register to receive message callbacks
sprint("mqtt init success")
else
sprint("mqtt init failed:", err)
end
end
-- Connect to MQTT server
function mymqtt_connect()
sprint("mqtt connecting...")
local stat, err = g_mq:connect(MQTT_CFG,MQTT_LWT, MQTT_CART)
if stat == nil then
sprint("mqtt connect failed:", err)
return
else
sprint("mqtt connected")
end
g_mq:subscribe(Subscribe_RE_TOPIC1, 0)
end
-- Receive MQTT message callback function
function mymqtt_msg_callback(topic, msg)
print("topic:",topic)
print("revdata:",msg)
-- local revData = json.decode(msg)
-- if topic == Subscribe_RE_TOPIC1 then --Process topic information subscribed from the cloud
-- if string.match(topic,Subscribe_RE_TOPIC1) then
-- print("topi11:",topic)
setValue(revData)
-- end
end
--Process the received data
--function setValue(revData)
-- if revData ~=nil then
-- for i,v in pairs(revData) do
-- print("Data received:",i,v)
-- end
-- end
--end
--Get real-time data
function getData()
local jdata = {}
local addr = bns_get_alldata()
print(json.encode(addr))
for i,v in pairs(addr) do
if v[2] == 1 then
jdata[v[3]] = v[4]
end
end
return jdata
end
--send data
function send_Data()
local pub_data = {100
-- services={{
--serviceId ='Temperature',
-- properties={
-- value = 55
-- },
-- }}
}
sprint(json.encode(pub_data))
print("..........",pub_RE_TOPIC)
return g_mq:publish(pub_RE_TOPIC, json.encode(pub_data), 0, 0)
end
2.4 Huawei platform
1.Register a account: https://www.huaweicloud.com/intl/en-us/s/JUlPVERNJQ
2.log in the Huawei IOTDA
https://console.huaweicloud.com/iotdm/?region=cn-north-4&locale=en-us#/dm-portal/home
3.Create product
4.Product name,manufacturer,device type and industry,set according to your own needs.
Protocol: MQTT
Data Type: JSON
After finishing configuration,please click "OK"
5.Device
After product register,continue to configure "individual register".Click "Device"-->"individual register"
Notes for registering device:
Product: Previous product registration.
Node ID, Device Name: set according to your own needs.
Secret: need to be configured, will be used when connecting later
After configuration, click OK to generate a device ID and password, which will be used for device access later.
6. Connection authentication (use MQTT.fx tool to access the IoT platform)
(1)Open mqttClientIdGenerator tool Java(TM) Platform SE binary
(2)Fill in the device ID and secret (deviceid and secret generated when registering the device) to generate connection message
Client ID, user name, password
(3) Download certificate file"North-Beijing4"
https://support.huaweicloud.com/en-us/devg-iothub/iot_02_1004.html
7.Run MQTTfx tool to connect with Huawei
Download link: http://mqttfx.jensd.de/index.php/download
(1)Click on the setting ICON
(2)Fill in IIOT MQTT device access address, and configure authentication parameters.
First: It is the server and port connected to Huawei IOT, which can be viewed through the overview of the interface.
Domain name:iot-mqtts.cn-north-4.myhuaweicloud.com
Port: 8883
Client ID: check step 6
(3)Upload SSL certificate file,check step 6
Select folder java-->DigiCertGlobalRootCA.crt.pem and click OK or apply button
(4)Connect and test publish and subscribe
Huawei publish topic format: $oc/devices/{device_id}/sys/properties/report
Huawei subscribe topic format: $oc/devices/{device_id}/sys/commands/#
(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:
①Select the corresponding product from Huawei products to view
②Custom model: used to display the service ID name of the configuration report.
③Add property, ID of monitoring point, and data format:
④After the configuration is complete, check the received data on the device
Huawei by SSL certification.
1.Create a project access for Huawei IOT
2.configure MQTT configuration
3.Create a script with the demo as below.
Script is as below
4.Download project access into V-Box to test in debug page
2.6 AWS platform
Log in AWS
Login aws account and click“Connect an IoT device”
Create policy
Click “Secure”--->“Policies”--->“Create policy”--->Click “Create”
Name the policy--->Click “JSON”--->Copy the following content--->Click “Create”
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:Connect",
"iot:Publish",
"iot:Subscribe",
"iot:Receive",
"greengrass:Discover"
],
"Resource": "*"
}
]
}
Create things
Click “Manage”--->“Things”--->“Create things”--->“Create single thing”
Name the thing--->Click “Next”
Select the way to create certificate
Select policy
MQTT.fx tool
Click “View Setting” to get the “Broker Adress”
Create one connection in MQTT.fx tool, set broker port as 8883.
Upload the CA File, Client Certificate File, Client Key File
Publish message to topic “TEST”
Click”Test”--->”MQTT test client”--->”Subscrible to a topic”, to get message publish from MQTT.fx tool.
And we can also send message form AWS platform to MQTT.fx tool.
CloudTool
Copy the same setting in MQTT.fx to MQTT configuration
Add a lua script and copy the lua demo into it.
--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)
local MQTT_URL, MQTT_CLIENTID, MQTT_CFG, MQTT_LWT, MQTT_CART = mqtt.setup_cfg()
--publish to topics
local pub_RE_TOPIC = string.format('TEST')
--Subscribe topics
local Subscribe_RE_TOPIC1 = string.format('TEST')
--variable
local last_time = 0
--Timing main function
function aws.main()
sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " aws.main start")
if g_mq then
if g_mq:isconnected() then
send_Data()
else
if os.time() - last_time > 5 then
last_time = os.time()
mymqtt_connect()
end
end
else
mymqtt_init()
end
sprint(os.date("%Y-%m-%d %H:%M %S", os.time()) .. " aws.main end")
end
-- Initialize MQTT
function mymqtt_init()
sprint(string.format("mqtt init mqtt_url:%s mqtt_clientid:%s", MQTT_URL, MQTT_CLIENTID))
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
if g_mq then
g_mq:on("message", mymqtt_msg_callback) -- Register to receive message callbacks
sprint("mqtt init success")
else
sprint("mqtt init failed:", err)
end
end
-- Connect to MQTT server
function mymqtt_connect()
sprint("mqtt connecting...")
local stat, err = g_mq:connect(MQTT_CFG,MQTT_LWT, MQTT_CART)
if stat == nil then
sprint("mqtt connect failed:", err)
return
else
sprint("mqtt connected")
end
g_mq:subscribe(Subscribe_RE_TOPIC1, 0)
end
-- Receive MQTT message callback function
function mymqtt_msg_callback(topic, msg)
print("topic:",topic)
print("revdata:",msg)
local revData = json.decode(msg)
print (revData)
if topic == Subscribe_RE_TOPIC1 then --Process topic information subscribed from the cloud
if string.match(topic,Subscribe_RE_TOPIC1) then
--if revData ~= nil then
for k,v in pairs (revData) do
print("printing revdata after kv here")
print (k,v)
end
print ("current state is",fanstate)
--end
end
end
end
--Get real-time data
function getData()
local jdata = {}
local addr = bns_get_alldata()
print(json.encode(addr))
for i,v in pairs(addr) do
if v[2] == 1 then
jdata[v[3]] = v[4]
end
end
return jdata
end
--send data
function send_Data()
local pub_data =
{
123
}
sprint(json.encode(pub_data))
print("..........",pub_RE_TOPIC)
return g_mq:publish(pub_RE_TOPIC, json.encode(pub_data), 0, 0)
end
Get message in AWS
2.7 Mysql
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.
1.Install Mysql
version
version
Connecting to Mysql with navicat.
3.Create database
Character set should be choose utf8mb3/utf8mb4 and Collation choose utf8mb3_danish_ci/utf8mb4_danish_ci.
4.Create data table
Create a table, enter the fields you need.
Save, enter table name.
5.Input Table Data
6.Script
luaMySql.init(string sourcename, string username, string password, string host, number port, string character)
Function: Configure database connection parameters
Parameter:
sourcename: the name of database
username: the username of the connection
password: the password of the connection
host: the host name of the connection
port: the host port of the connection
character: the character set of the connection
Return:
Succeed: string
Failed: multi
luaMySql.exec(string statement)
Function: Execute the given SQL statement without returning the result set (add, delete, change)
Parameter:
statement: the given SQL statement
Return:
Succeed: status: returns the number of rows affected by SQL statement execution.
Failed: nil, errorString
luaMySql.execWithResult(string statement)
Function: Execute the given SQL statement returning the result set (check)
Parameter:
statement: the given SQL statement
Return:
Succeed: table: returns the result set
Failed: nil, errorString
For example:
mysql = require("mysqlclient")
function DataInitRight()
local dbName = "excel"
local user = "root"
local pwd = "XXXXX"
local host = "192.168.39.146"
local port = 3306
local character = "utf8mb3"
mysql.init(dbName, user, pwd, host, port, character)
end
function ExecFunc()
status, errorString = mysql.exec("delete from student where Name = 'XXX';") --Delete statement, column name = table element
if nil == status then
print("ExecFunc() error:", errorString)
return -1
else
print("the number of rows affected by the command:", status)
end
return 0
end
function ExecWithResultFunc()
status, errorString = mysql.execWithResult("select * from student;")
if nil == status then
print("ExecWithResultFunc() error:", errorString)
return -1
else
print("ExecWithResultFunc() success : status type = ", type(status))
print("ExecWithResultFunc() success : status len = ", #status)
local num = #status
local i = 1
if num > 0 then
for i = 1, num, 1 do
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
print(var)
end
end
print("---------------")
end
return 0
end
function MySQL.main()
print("script running ...")
DataInitRight()
-- use exec demo
if ExecFunc() < 0 then
return
end
-- use execWithResult demo
if ExecWithResultFunc() < 0 then
return
end
print("script running success")
end
7.Debug
8.Problem
During our debugging process it may there are some problems about Mysql, such as
- MySQL: Host 192.168.XXX.XXX is not allowed to connect.
- MySQL: Host 192.168.XXX.XXX is blocked because of many connection errors.
- MySQL: SSL connection error: unknown error number.
1449-The user specified as a definer(‘mysql.infoschema‘@localhost‘) does not exist.
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.