新聞中心
PRESS CENTER本章節(jié)主要實(shí)現(xiàn)一個(gè)流程:EG8200采集西門(mén)子S7-200 Smart的數(shù)據(jù),并組裝成JSON格式,通過(guò)MQTT上報(bào)應(yīng)用平臺(tái);同時(shí)能夠接收應(yīng)用平臺(tái)下發(fā)的控制命令,實(shí)現(xiàn)遠(yuǎn)程開(kāi)關(guān)。要實(shí)現(xiàn)此流程,需要提前準(zhǔn)備好以下材料:
要采集的PLC的IP端口以及點(diǎn)位表,例如:
PLC | S7-200 Smart | ||
IP | 192.168.0.24/102 | ||
點(diǎn)表(DB1) | |||
地址 | 數(shù)據(jù)類(lèi)型 | 屬性 | 名稱(chēng) |
V0.0 | Boolean | 只讀 | 1號(hào)電機(jī)啟停狀態(tài) |
V0.1 | Boolean | 只讀 | 2號(hào)電機(jī)啟停狀態(tài) |
V0.2 | Boolean | 只讀 | 3號(hào)電機(jī)啟停狀態(tài) |
V0.3 | Boolean | 只讀 | 4號(hào)電機(jī)啟停狀態(tài) |
V0.4 | Boolean | 讀寫(xiě) | 1號(hào)電機(jī)啟??刂?/span> |
V0.5 | Boolean | 讀寫(xiě) | 2號(hào)電機(jī)啟停控制 |
V0.6 | Boolean | 讀寫(xiě) | 3號(hào)電機(jī)啟??刂?/span> |
V0.7 | Boolean | 讀寫(xiě) | 4號(hào)電機(jī)啟??刂?/span> |
VD100 | Unsigned16 | 只讀 | 電壓(V) |
VD200 | Unsigned16 | 只讀 | 電流(A) |
MQTT通信相關(guān)參數(shù)及JSON數(shù)據(jù)格式要求,例如:
url:1883.dtuip.com:1883 clientID:820000003058164F username:19381903226 password:ZHZK19381903226 訂閱:820000003058164F/+ 發(fā)布:820000003058164F JSON格式: { "sensorDatas": [ { "flag":"em1Status", "switcher":1 }, { "flag":"em2Status", "switcher":1 }, { "flag":"em3Status", "switcher":1 }, { "flag":"em4Status", "switcher":1 }, { "flag":"em1Control", "switcher":0 }, { "flag":"em2Control", "switcher":0 }, { "flag":"em3Control", "switcher":0 }, { "flag":"em4Control", "switcher":0 }, { "flag":"voltage", "value":220.0 }, { "flag":"current", "value":10.2 } ] }
在制作流程時(shí),基礎(chǔ)的邏輯是根據(jù)數(shù)據(jù)走向來(lái)制作流程。該需求經(jīng)過(guò)分析可以得出,主要分為數(shù)據(jù)上行和數(shù)據(jù)下行兩個(gè)部分。其中,數(shù)據(jù)上行主要工作有:
通過(guò)S7協(xié)議讀取PLC的數(shù)據(jù),得到的數(shù)據(jù)存儲(chǔ)在內(nèi)存中(S7節(jié)點(diǎn)
)
將數(shù)據(jù)按照J(rèn)SON格式進(jìn)行格式化(函數(shù)節(jié)點(diǎn)
)
建立MQTT連接,發(fā)布到指定主題(MQTT發(fā)布節(jié)點(diǎn)
)
數(shù)據(jù)下行主要工作有:
訂閱MQTT主題,接收平臺(tái)下發(fā)數(shù)據(jù)(MQTT訂閱節(jié)點(diǎn)
)
將收到的JSON數(shù)據(jù)解析后存儲(chǔ)在內(nèi)存中(函數(shù)節(jié)點(diǎn)
)
按照S7要求的格式寫(xiě)入PLC中(S7節(jié)點(diǎn)
)
從節(jié)點(diǎn)庫(kù)拖入一個(gè)S7讀數(shù)據(jù)節(jié)點(diǎn)
,以及一個(gè)調(diào)試節(jié)點(diǎn)
,調(diào)試節(jié)點(diǎn)
用于查看讀取到的PLC的數(shù)據(jù),方便定位問(wèn)題
雙擊S7讀數(shù)據(jù)節(jié)點(diǎn)
,根據(jù)需求概述的內(nèi)容填寫(xiě)對(duì)應(yīng)的設(shè)置參數(shù),如下圖所示:
IP:PLC的IP 端口:102(S7協(xié)議通信默認(rèn)端口102) 模式:TASP(S7-200 Smart選擇TASP,其余型號(hào)選擇Rack/Slot) 本地TSAP:1002(固定值) 遠(yuǎn)端TSAP:0301(固定值) 采集周期:1000ms(默認(rèn)1000ms,可自定義) 超時(shí)周期:2000ms(默認(rèn)2000ms,可自定義) 數(shù)據(jù)點(diǎn)配置(根據(jù)幫助文檔可以找到對(duì)應(yīng)關(guān)系) V0.0-->DB1,X0.0 V0.1-->DB1,X0.1 V0.2-->DB1,X0.2 V0.3-->DB1,X0.3 V0.4-->DB1,X0.4 V0.5-->DB1,X0.5 V0.6-->DB1,X0.6 V0.7-->DB1,X0.7 VD100 -->DB1,W100 VD200 -->DB1,W200 輸出模式可以根據(jù)需求選擇,這里選擇所有變量輸出一條
如果設(shè)置正確,調(diào)試窗口會(huì)有日志打印,顯示的是讀取到的數(shù)據(jù)內(nèi)容
有的時(shí)候PLC數(shù)據(jù)點(diǎn)比較多,手動(dòng)依次錄入比較繁瑣。節(jié)點(diǎn)支持?jǐn)?shù)據(jù)點(diǎn)的導(dǎo)入導(dǎo)出:
根據(jù)步驟2的引導(dǎo),在調(diào)試窗口可以看到讀到的PLC數(shù)據(jù)如下:
因?yàn)閼?yīng)用平臺(tái)已經(jīng)規(guī)定了數(shù)據(jù)必須按照J(rèn)SON格式上報(bào)。接下來(lái)使用函數(shù)節(jié)點(diǎn)
Javascrip代碼將數(shù)據(jù)進(jìn)行格式化,代碼如下:
let jsonArray = [] jsonArray.push({ "flag": "em1Status", "switcher": msg.payload.em1Status == true ? 1 : 0 }) jsonArray.push({ "flag": "em2Status", "switcher": msg.payload.em2Status == true ? 1 : 0 }) jsonArray.push({ "flag": "em3Status", "switcher": msg.payload.em3Status == true ? 1 : 0 }) jsonArray.push({ "flag": "em4Status", "switcher": msg.payload.em4Status == true ? 1 : 0 }) jsonArray.push({ "flag": "em1Control", "switcher": msg.payload.em1Control == true ? 1 : 0 }) jsonArray.push({ "flag": "em2Control", "switcher": msg.payload.em2Control == true ? 1 : 0 }) jsonArray.push({ "flag": "em3Control", "switcher": msg.payload.em3Control == true ? 1 : 0 }) jsonArray.push({ "flag": "em4Control", "switcher": msg.payload.em4Control == true ? 1 : 0 }) jsonArray.push({ "flag": "voltage", "value": msg.payload.voltage / 100 })/*兩位小數(shù)*/ jsonArray.push({ "flag": "current", "value": msg.payload.current / 100 })/*兩位小數(shù)*/ let data = {} data.sensorDatas = jsonArray msg.payload = JSON.stringify(data) return msg
復(fù)制以上代碼,粘貼到函數(shù)節(jié)點(diǎn)內(nèi),部署后即可看到效果:
可以看到,已經(jīng)將讀到的PLC數(shù)據(jù),按照需求要求轉(zhuǎn)換成了最終的JSON格式,且對(duì)數(shù)據(jù)進(jìn)行了一定程度的計(jì)算(兩位小數(shù))。此處只是函數(shù)節(jié)點(diǎn)的冰山一角,因?yàn)橹С諮avascrip語(yǔ)言編程,幾乎你能想到的任何功能都可以在這里實(shí)現(xiàn)
拖入一個(gè)MQTT發(fā)布節(jié)點(diǎn)
,根據(jù)提示進(jìn)行配置,填入MQTT連接相關(guān)信息及MQTT發(fā)布主題后(詳情見(jiàn)需求概述),即可實(shí)現(xiàn)數(shù)據(jù)上報(bào)??梢钥吹?,數(shù)據(jù)上報(bào)成功后,應(yīng)用平臺(tái)顯示綠色表明設(shè)備上線且數(shù)據(jù)正常:
至此,數(shù)據(jù)上報(bào)已經(jīng)完成,很簡(jiǎn)單幾步即可實(shí)現(xiàn):采集PLC數(shù)據(jù)并按照自定義JSON格式上報(bào)。
拖入一個(gè)MQTT訂閱節(jié)點(diǎn)
,注意:MQTT發(fā)布節(jié)點(diǎn)
和MQTT訂閱節(jié)點(diǎn)
可以共用一個(gè)MQTT連接,如果使用的是同一個(gè)連接,只是不同的Topic,拖入節(jié)點(diǎn)后選擇已經(jīng)配置好的連接即可。如果選擇添加新的mqtt-broker節(jié)點(diǎn),則代表的是新建一個(gè)MQTT連接
選擇一個(gè)調(diào)試節(jié)點(diǎn),在平臺(tái)點(diǎn)擊控制按鈕后,調(diào)試窗口可以看到下發(fā)的指令:
根據(jù)S7寫(xiě)數(shù)據(jù)
節(jié)點(diǎn)的幫助文檔,可以知道,要想實(shí)現(xiàn)向PLC寫(xiě)入數(shù)據(jù),需要傳遞的數(shù)據(jù)攜帶兩個(gè)參數(shù),如下:
因此,數(shù)據(jù)解析時(shí),需要將應(yīng)用平臺(tái)下發(fā)的數(shù)據(jù)轉(zhuǎn)換為攜帶payload
和variable
兩個(gè)變量的消息,傳遞給S7寫(xiě)數(shù)據(jù)節(jié)點(diǎn)
,函數(shù)節(jié)點(diǎn)的代碼如下:
let cmdDate = msg.payload msg.variable = cmdDate.sensorDatas[0].flag msg.payload = cmdDate.sensorDatas[0].switcher == 1 ? true : false return msg
復(fù)制以上代碼,粘貼到函數(shù)節(jié)點(diǎn)內(nèi),將調(diào)試節(jié)點(diǎn)設(shè)置為輸出原始消息,可以看到打印內(nèi)容如下:
可以看到數(shù)據(jù)已經(jīng)轉(zhuǎn)換為S7寫(xiě)數(shù)據(jù)節(jié)點(diǎn)要求的格式
拖入一個(gè)S7寫(xiě)數(shù)據(jù)
節(jié)點(diǎn),連接函數(shù)計(jì)算
節(jié)點(diǎn),在應(yīng)用平臺(tái)操作開(kāi)關(guān),看演示效果:
本章節(jié)介紹了一個(gè)相對(duì)復(fù)雜的流程,旨在表述網(wǎng)關(guān)所具備的能力,因此并未對(duì)程序的安全性、穩(wěn)定性、靈活性等方面做優(yōu)化。通過(guò)理解本流程,相信你已經(jīng)對(duì)網(wǎng)關(guān)的可視化編程有了一定的熟悉。接下來(lái),深入學(xué)習(xí)每個(gè)節(jié)點(diǎn)的功能用法吧,掌握它們將會(huì)為你制作更復(fù)雜的流程提供更多的選擇和可能!
所有的流程支持以json格式導(dǎo)入導(dǎo)出,方便與其他人分享做好的流程。本章節(jié)的流程json文件如下,復(fù)制后在菜單欄右上角選擇導(dǎo)入粘貼即可,導(dǎo)出同理
[{"id":"c8d138cd30e452fc","type":"s7 in","z":"2ff624305b8cb30b","endpoint":"374f5d9e3d2741c0","mode":"all","variable":"","diff":false,"name":"讀PLC數(shù)據(jù)","x":180,"y":180,"wires":[["03f0b9014af25c1d"]]},{"id":"4abb25e7e75b3447","type":"mqtt out","z":"2ff624305b8cb30b","name":"發(fā)布數(shù)據(jù)","topic":"820000003058164F","qos":"0","retain":"false","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"8d85be060cbc6545","x":520,"y":180,"wires":[]},{"id":"63f2816a781192d5","type":"mqtt in","z":"2ff624305b8cb30b","name":"訂閱數(shù)據(jù)","topic":"820000003058164F/+","qos":"0","datatype":"auto-detect","broker":"8d85be060cbc6545","nl":false,"rap":true,"rh":0,"inputs":0,"x":180,"y":260,"wires":[["1b6776e208355720"]]},{"id":"03f0b9014af25c1d","type":"function","z":"2ff624305b8cb30b","name":"數(shù)據(jù)格式化","func":"let jsonArray = []\n\njsonArray.push({ \"flag\": \"em1Status\", \"switcher\": msg.payload.em1Status == true ? 1 : 0 })\njsonArray.push({ \"flag\": \"em2Status\", \"switcher\": msg.payload.em2Status == true ? 1 : 0 })\njsonArray.push({ \"flag\": \"em3Status\", \"switcher\": msg.payload.em3Status == true ? 1 : 0 })\njsonArray.push({ \"flag\": \"em4Status\", \"switcher\": msg.payload.em4Status == true ? 1 : 0 })\njsonArray.push({ \"flag\": \"em1Control\", \"switcher\": msg.payload.em1Control == true ? 1 : 0 })\njsonArray.push({ \"flag\": \"em2Control\", \"switcher\": msg.payload.em2Control == true ? 1 : 0 })\njsonArray.push({ \"flag\": \"em3Control\", \"switcher\": msg.payload.em3Control == true ? 1 : 0 })\njsonArray.push({ \"flag\": \"em4Control\", \"switcher\": msg.payload.em4Control == true ? 1 : 0 })\njsonArray.push({ \"flag\": \"voltage\", \"value\": msg.payload.voltage / 100 })/*兩位小數(shù)*/\njsonArray.push({ \"flag\": \"current\", \"value\": msg.payload.current / 100 })/*兩位小數(shù)*/\n\nlet data = {}\ndata.sensorDatas = jsonArray\n\nmsg.payload = JSON.stringify(data)\n\nreturn msg\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":180,"wires":[["4abb25e7e75b3447"]]},{"id":"1b6776e208355720","type":"function","z":"2ff624305b8cb30b","name":"函數(shù)計(jì)算 1","func":"let cmdDate = msg.payload\n\nmsg.variable = cmdDate.sensorDatas[0].flag\nmsg.payload = cmdDate.sensorDatas[0].switcher == 1 ? true : false\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":260,"wires":[["140b525dd4d0608b"]]},{"id":"140b525dd4d0608b","type":"s7 out","z":"2ff624305b8cb30b","endpoint":"374f5d9e3d2741c0","variable":"","name":"","x":510,"y":260,"wires":[]},{"id":"374f5d9e3d2741c0","type":"s7 endpoint","transport":"iso-on-tcp","address":"192.168.0.24","port":"102","rack":"0","slot":"2","localtsaphi":"10","localtsaplo":"02","remotetsaphi":"03","remotetsaplo":"01","connmode":"tsap","adapter":"","busaddr":"2","cycletime":"2000","timeout":"2000","name":"PLC","vartable":[{"addr":"DB1,X0.0","name":"em1Status"},{"addr":"DB1,X0.1","name":"em2Status"},{"addr":"DB1,X0.2","name":"em3Status"},{"addr":"DB1,X0.3","name":"em4Status"},{"addr":"DB1,X0.4","name":"em1Control"},{"addr":"DB1,X0.5","name":"em2Control"},{"addr":"DB1,X0.6","name":"em3Control"},{"addr":"DB1,X0.7","name":"em4Control"},{"addr":"DB1,W100","name":"voltage"},{"addr":"DB1,DW200","name":"current"}]},{"id":"8d85be060cbc6545","type":"mqtt-broker","name":"","broker":"1883.dtuip.com:1883","port":"1883","clientid":"820000003058164F","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""}]
MQTT配置節(jié)點(diǎn)導(dǎo)出時(shí),不會(huì)攜帶用戶名和密碼。因此導(dǎo)入時(shí)需要重新錄入用戶名和密碼