|
一、工控網(wǎng)關(guān)是什么 網(wǎng)關(guān)是物聯(lián)網(wǎng)和工控系統(tǒng)的核心組件。網(wǎng)關(guān)起的是承上啟下的作用。上即上位機(jī),電腦/觸屏監(jiān)控系統(tǒng)、MES這些;下即下位機(jī),包括PLC、傳感器、嵌入式芯片等。 不同廠家的下位機(jī),往往講的是不同的語言,西門子的語言叫ProfiBus,施耐德的語言叫Modbus,AB的語言叫Ethernet IP。在樓宇自控領(lǐng)域,又有BACnet 。 網(wǎng)關(guān)要擔(dān)當(dāng)溝通上、下位機(jī)的重任,它的基本功能就是翻譯,即協(xié)議轉(zhuǎn)換。管你說哪種方言,最后轉(zhuǎn)給上位機(jī)的都是普通話。 二、如何實(shí)現(xiàn)軟網(wǎng)關(guān):啟下 網(wǎng)關(guān)是對(duì)下位機(jī)的抽象 程序就是對(duì)客觀事物的抽象。網(wǎng)關(guān)如果要完整無誤的轉(zhuǎn)述各種下位機(jī)的“方言”,那一定是它能夠提取出下位機(jī)的共性。 共性的部分,抽象成接口。特性的部分,在各自的類里實(shí)現(xiàn)。 分析之后,我認(rèn)為下位機(jī)最重要的兩個(gè)共性是:可讀寫性??蛇B接性。 這樣就有了兩個(gè)基本接口(在Dataservice項(xiàng)目中):IReaderWriter,描述讀寫性。IDriver,描述連接性。 接口類圖及繼承關(guān)系 IReaderWriter接口的方法,都是和讀寫有關(guān)的:讀入/寫入一個(gè)位,讀入/寫入一字節(jié)、一個(gè)整數(shù)、一個(gè)浮點(diǎn)數(shù)、一個(gè)字符串。 這些方法都有一個(gè)共同的參數(shù),DeviceAddress。代表一個(gè)下位機(jī)地址。 DeviceAddresss 是一個(gè)結(jié)構(gòu)體。包含區(qū)域號(hào)Area,區(qū)塊號(hào)DBNumber,起始位置Start,位號(hào)Bit。 區(qū)域包含區(qū)塊,區(qū)塊有起始地址,邏輯變量有位號(hào)。加上VarType描述數(shù)據(jù)類型(布爾型、整型、浮點(diǎn)型、字符型等等),DataSize描述數(shù)據(jù)長度。 這樣的四級(jí)地址加上數(shù)據(jù)描述,足夠映射到任何一個(gè)下位機(jī)變量地址了。 IDriver 接口的方法,都是和連接有關(guān)的。Connect方法負(fù)責(zé)連接、IsClosed判斷連接是否斷開、TimeOut設(shè)置超時(shí)、OnClose事件在連接斷開時(shí)觸發(fā)。 ServerName屬性表示下位機(jī)的IP或者主機(jī)名。由這樣一些屬性、方法,就可以定義一個(gè)下位機(jī)的連接了。 也許大家會(huì)問,為什么不把兩個(gè)接口合并為一個(gè)? 因?yàn)橐欢ㄓ心撤N只具備連接性,不具備可讀寫性,或者只有可讀寫性,并沒有可連接性的對(duì)象存在。 比如內(nèi)存數(shù)據(jù)庫對(duì)象。因?yàn)樗邢挛粰C(jī)的地址,都是各有各的表述方式,我在A小區(qū)X棟X號(hào),我在B小區(qū)住獨(dú)棟。 下位機(jī)的地址小區(qū)不同,門牌號(hào)不同,而且很可能是不連續(xù)的,散亂的。 要對(duì)這些亂七八糟的地址進(jìn)行統(tǒng)一管理,就像這些來自五湖四海的客人,住到同一家大酒店。每個(gè)人從此只有一個(gè)標(biāo)準(zhǔn)化的地址:房號(hào)。 內(nèi)存數(shù)據(jù)庫ICache就是對(duì)下位機(jī)地址變量的映射。映射到一個(gè)連續(xù)的內(nèi)存地址空間,便于統(tǒng)一編號(hào),統(tǒng)一管理。 對(duì)內(nèi)存數(shù)據(jù)庫而言,它具有可讀寫性,但不需要可連接性。也就是只要繼承IReaderWriter。 在這個(gè)繼承圖里,有一個(gè)抽象類專門描述PLC類型下位機(jī)的,就是IPLCDriver。 首先所有的PLC都具有可連接性,可讀寫性。因此兩個(gè)接口都繼承。 同時(shí),PLC的地址往往表示為格式化的字符串。比如西門子地址可寫為DB3,D122.1,Modubs為30001.1。 GetDeviceAddress\GetAddress兩個(gè)方法就是對(duì)DeviceAddress 與字符串之間編碼、解碼。 PDU 是PLC的一個(gè)特殊屬性。也就是報(bào)文的數(shù)據(jù)單元。 所有的PLC如西門子、三菱、AB、Modbus都繼承于IPLCDriver 。 IFileDriver代表另一類下位機(jī),比如來自數(shù)據(jù)庫、文件流等。它們的共性是具有文件名FileName。 在類圖里看到一個(gè)孤零零的IMultiReadWrite ,它是做什么的? 因?yàn)椴糠窒挛粰C(jī)支持批量讀寫,(https://www./ 電工之家)尤其在注重效率的場合,批量讀寫十分重要。一次讀入幾百個(gè)變量,和幾百次讀入單個(gè)變量,效率天壤之別。 因此IMultiReadWrite 要實(shí)現(xiàn)兩個(gè)方法,ReadMultiple(批量讀),WriteMultiple(批量寫),參數(shù)都是一個(gè)DeviceAddress 數(shù)組。 如果你的下位機(jī)支持批量讀寫,直接繼承這個(gè)接口并實(shí)現(xiàn)就可以了。如果讀寫時(shí)發(fā)現(xiàn)繼承了這個(gè)接口,系統(tǒng)就會(huì)自動(dòng)調(diào)用更高效的方式。 三、如何實(shí)現(xiàn)軟網(wǎng)關(guān):承上 網(wǎng)關(guān)是對(duì)上位機(jī)變量的映射 一個(gè)能連接、能讀寫的下位機(jī)如果實(shí)現(xiàn)了,要想在界面顯示,必須做一件事, 就是讓下位機(jī)數(shù)據(jù)的變化,反映為上位機(jī)圖形的變化。 比如這幅界面里的電機(jī),啟動(dòng)后變綠;電流溫度數(shù)據(jù)會(huì)顯示并刷新。 要做到這一點(diǎn),就必須有一個(gè)上下位機(jī)的中介:Tag。 Tag 這個(gè)對(duì)象,必須有一個(gè)上位機(jī)設(shè)計(jì)者理解的名字,比如1號(hào)馬達(dá)運(yùn)行信號(hào),就叫做Motor1_Running。 這個(gè)名字,在下位機(jī)是不存在的。下位機(jī)只有呆板的地址,比如DB3,D122.1。 這些上位機(jī)設(shè)計(jì)者沒必要知道。但他們一定知道這是一個(gè)布爾量,名字叫Motor1_Running。 因此網(wǎng)關(guān)還有一個(gè)必要的功能,下位機(jī)數(shù)據(jù)變化了,Tag值會(huì)相應(yīng)變化,反過來也一樣。 Tag的結(jié)構(gòu) 因?yàn)樯衔粰C(jī)設(shè)計(jì)員只知道Tag的數(shù)據(jù)類型是整型、還是浮點(diǎn)數(shù)、還是布爾量,因此Tag也分IntTag、FloatTag、BoolTag等類型。 不管哪種類型的Tag,一定繼承ITag抽象類。 ITag有Address屬性,就是映射到DeviceAddress 。同時(shí)還有TimeStamp(時(shí)間戳),Value(值),Quailty(數(shù)據(jù)質(zhì)量)。 同樣的,Tag本身也具有讀寫功能(Read,Write方法),也就是上位機(jī)對(duì)Tag的讀寫,最終反映為下位機(jī)對(duì)地址的讀寫。 而不同類型的Tag,自然就對(duì)應(yīng)到上面所提到的IReaderWriter 接口,正好有匹配的讀/寫布爾量,讀/寫整型,讀/寫浮點(diǎn)型等等的方法。 這樣,就把下位機(jī)設(shè)備和Tag變量的讀寫對(duì)應(yīng)起來 了。 |
|
|