1、 工控网关是什么git
网关是物联网和工控系统的核心组件。网关起的是承上启下的做用。上即上位机,电脑/触屏监控系统、MES这些;下即下位机,包括PLC、传感器、嵌入式芯片等。github
不一样厂家的下位机,每每讲的是不一样的语言,西门子的语言叫ProfiBus,施耐德的语言叫Modbus,AB的语言叫Ethernet IP。在楼宇自控领域,又有BACnet 。。数据库
网关要担当沟通上、下位机的重任,它的基本功能就是翻译,即协议转换。管你说哪一种方言,最后转给上位机的都是普通话。数组
2、 如何实现软网关:启下架构
程序就是对客观事物的抽象。网关若是要完整无误的转述各类下位机的“方言”,那必定是它可以提取出下位机的共性。编码
共性的部分,抽象成接口。特性的部分,在各自的类里实现。spa
分析以后,我认为下位机最重要的两个共性是:可读写性。可链接性。插件
这样就有了两个基本接口(在Dataservice项目中):IReaderWriter,描述读写性。IDriver,描述链接性。翻译
IReaderWriter接口的方法,都是和读写有关的:读入/写入一个位,读入/写入一字节、一个整数、一个浮点数、一个字符串。设计
这些方法都有一个共同的参数,DeviceAddress。表明一个下位机地址。
DeviceAddresss 是一个结构体。包含区域号Area,区块号DBNumber,起始位置Start,位号Bit。
区域包含区块,区块有起始地址,逻辑变量有位号。加上VarType描述数据类型(布尔型、整型、浮点型、字符型等等),DataSize描述数据长度。
这样的四级地址加上数据描述,足够映射到任何一个下位机变量地址了。
IDriver 接口的方法,都是和链接有关的。Connect方法负责链接、IsClosed判断链接是否断开、TimeOut设置超时、OnClose事件在链接断开时触发。
ServerName属性表示下位机的IP或者主机名。由这样一些属性、方法,就能够定义一个下位机的链接了。
也许你们会问,为何不把两个接口合并为一个?
由于必定有某种只具有链接性,不具有可读写性,或者只有可读写性,并无可链接性的对象存在。
好比内存数据库对象。由于全部下位机的地址,都是各有各的表述方式,我在A小区X栋X号,我在B小区住独栋。
下位机的地址小区不一样,门牌号不一样,并且极可能是不连续的,散乱的。
要对这些乱七八糟的地址进行统一管理,就像这些来自五湖四海的客人,住到同一家大酒店。每一个人今后只有一个标准化的地址:房号。
内存数据库ICache就是对下位机地址变量的映射。映射到一个连续的内存地址空间,便于统一编号,统一管理。
对内存数据库而言,它具备可读写性,但不须要可链接性。也就是只要继承IReaderWriter。
在这个继承图里,有一个抽象类专门描述PLC类型下位机的,就是IPLCDriver。
首先全部的PLC都具备可链接性,可读写性。所以两个接口都继承。
同时,PLC的地址每每表示为格式化的字符串。好比西门子地址可写为DB3,D122.1,Modubs为30001.1。
GetDeviceAddress\GetAddress两个方法就是对DeviceAddress 与字符串之间编码、解码。
PDU 是PLC的一个特殊属性。也就是报文的数据单元。
全部的PLC如西门子、三菱、AB、Modbus都继承于IPLCDriver 。
IFileDriver表明另外一类下位机,好比来自数据库、文件流等。它们的共性是具备文件名FileName。
在类图里看到一个孤零零的IMultiReadWrite ,它是作什么的?
由于部分下位机支持批量读写,尤为在注重效率的场合,批量读写十分重要。一次读入几百个变量,和几百次读入单个变量,效率天壤之别。
所以IMultiReadWrite 要实现两个方法,ReadMultiple(批量读),WriteMultiple(批量写),参数都是一个DeviceAddress 数组。
若是你的下位机支持批量读写,直接继承这个接口并实现就能够了。若是读写时发现继承了这个接口,系统就会自动调用更高效的方式。
3、 如何实现软网关:承上
一个能链接、能读写的下位机若是实现了,要想在界面显示,必须作一件事,
就是让下位机数据的变化,反映为上位机图形的变化。
好比这幅界面里的电机,启动后变绿;电流温度数据会显示并刷新。
要作到这一点,就必须有一个上下位机的中介:Tag。
Tag 这个对象,必须有一个上位机设计者理解的名字,好比1号马达运行信号,就叫作Motor1_Running。
这个名字,在下位机是不存在的。下位机只有呆板的地址,好比DB3,D122.1。
这些上位机设计者不必知道。但他们必定知道这是一个布尔量,名字叫Motor1_Running。
所以网关还有一个必要的功能,下位机数据变化了,Tag值会相应变化,反过来也同样。
由于上位机设计员只知道Tag的数据类型是整型、仍是浮点数、仍是布尔量,所以Tag也分IntTag、FloatTag、BoolTag等类型。
无论哪一种类型的Tag,必定继承ITag抽象类。 ITag有Address属性,就是映射到DeviceAddress 。同时还有TimeStamp(时间戳),Value(值),Quailty(数据质量)。
一样的,Tag自己也具备读写功能(Read,Write方法),也就是上位机对Tag的读写,最终反映为下位机对地址的读写。
而不一样类型的Tag,天然就对应到上面所提到的IReaderWriter 接口,正好有匹配的读/写布尔量,读/写整型,读/写浮点型等等的方法。
这样,就把下位机设备和Tag变量的读写对应起来 了。
4、 下面的计划
请继续关注个人帖子,并提出宝贵意见和建议。
提纲和目录也拟好了。大体以下: