dede如何生成网站源码,怎么提高网站转化率,网站建设应注意哪些问题,免费 开源 企业网站一、 引子 之前都在讲网关#xff0c;不少网友关注如何实现界面。想了解下位机变量变化#xff0c;是怎样一步步触发人机界面动画的。 这个步步触发#xff0c;实质上是变量组#xff08;Group#xff09;的批量数据变化#xff08;DataChange#xff09;事件#xf… 一、 引子 之前都在讲网关不少网友关注如何实现界面。想了解下位机变量变化是怎样一步步触发人机界面动画的。 这个步步触发实质上是变量组Group的批量数据变化DataChange事件引发了变量Tag的值更新ValueChange事件最终触发了图元的动画脚本Action。这是一个连锁反应。 简言之界面是一批叫Tag乘客从网关坐TLV协议的列车到了上位机车站下车在ClientService这个舞台上用各自的乐器ITagReader演奏了一出交响乐。 二、 承上启下的核心对象Tag Tag标签或者叫变量是整个项目的核心对象。所谓核心对象就是它无所不在是动态的流动的就像血液融汇贯通。 实质上Tag对下位机就是一个个传感器的数据、一个个开关信号对上位机就是一个个按钮、仪表盘、电机。 Tag在变量管理器TagConfig产生在系统初始化时分配存在于人机界面程序和网关服务的各个角落它们的值和时间戳在不断的变化。 对上位机设计者用到的是Tag的名字、Tag的数据类型对下位机设计者看到的是Tag的地址、Tag的长度。对变量报警和数据归档需要知道Tag的时间戳。 所有的Tag继承于ITag接口。Tag的类型就是数据的类型有FloatTag浮点型、BoolTag逻辑型、还有整型、字符型。不同类型Tag的读写对应IReaderWriter接口的ReadXXX/WriteXXX方法。 Tag可以主动去读Read写Write)也可以被动的刷新Update强制刷新Refresh。 Tag的Read方法是调用所属Group、最终是调用所属IDriver的ReadXXX方法从下位机读入数据。但Tag的主要应用场景是被动刷新触发ValueChanged事件以驱动人机界面。 三、 上下位机连接的纽带TLV协议 前文已经阐述了网关如何通过轮询下位机、推送批量数据给上位机。上位机需要将推送来的数据流解析为一堆变化的Tag以驱动整个人机界面和控制逻辑。 网关和上位机之间通讯我这里使用了一个自定义的简单的TLV协议Tag-Length-Value承载于Socket。 这个协议包括两部分 数据推送将网关一端变化的Tag打包封装传输给客户端客户端拆包还原为一堆Tag。具体流程为 网关的DataChange事件调用SendData方法将变化的Tag打包为HistoryData数组包含变量ID、值、时间戳 Socket将HistoryData数组转换为字节流推送给客户端 客户端的ClientDriver 包含ReciveData方法将字节流还原为HistoryData数组并触发客户端DataChange事件 客户端的DataChange事件将HistoryData数组转换为Tag数组并调用Tag的Update,触发ValueChanging和ValueChanged事件。 指令客户端主动向网关发送指令一般用来读、写特定变量或一批变量还可以查询历史归档、查询报警等。指令格式如下 指令码FCTCOMMAND包含各种命令 参数如读入时间段内所有归档数据则需要起始时间、结束时间读入变量则需要变量ID。 返回值网关接收指令并返回数据也是字节流。 public class FCTCOMMAND{ public const byte fctHead 0xAB;//报头可加密如报头不符则不进行任何操作客户端Socket发送报警请求封装于Serverpublic const byte fctHdaIdRequest 30;//按变量ID读入历史数据public const byte fctHdaRequest 31;//读时间段内所有历史数据public const byte fctAlarmRequest 32;//读报警数据public const byte fctOrderChange 33;//读订单public const byte fctReset 34;//重置指令一般用来释放网关套接字public const byte fctXMLHead 0xEE;//xml协议public const byte fctReadSingle 1;//读单一变量public const byte fctReadMultiple 2;//读多个变量public const byte fctWriteSingle 5;//写单一变量public const byte fctWriteMultiple 15;//写多个变量} 四、 人机界面的驱动引擎ClientService 人机界面客户端的 ClientService与网关的DAService如出一辙都具有相类似的结构继承了IDataServer, IAlarmServer都从同一个数据库加载驱动、组、变量、报警 客户端的 public sealed class DAServer : IDataServer, IAlarmServer, IHDAServer 网关的 public class DAService : IDataExchangeService, IDataServer, IAlarmServer 只是多了一个IHDAServer具有查询历史数据的功能而历史数据归档是网关的功能。 因此ClientService也带有自己的驱动ClientDriverClientDriver也带有自己的组ClientGroup。 注意的是ClientDriver是上位机唯一的DriverClientGroup也是ClientDriver唯一的Group。这是因为上位机无需和各类型下位机打交道与它打交道的唯一对象就是网关本身。 因此人机界面的各类操作指令如按按钮、读归档数据、查询报警等最终都反映成TLV协议指令发送给网关并得到反馈。 而人机界面图元的动画都是来自网关推送的Tag触发ValueChanged事件事件的订阅者就是图元对应的ITagReader图元动画的幕后指挥。 五、 图元动画的幕后指挥ITagReader ITagReader接口为所有图元组件继承它的功能就是将Tag与动画绑定。先看下结构 public interface ITagReader : ITagLink{ string TagReadText { get; set; } string[] GetActions();Action SetTagReader(string key, Delegate tagChanged);IListITagLink Children { get; }} TagReadText属性就是与图元动画关联的变量表达式形如Tag1*2Tag2*510。我实现了一个自定义表达式编译器Eval,可以解析表达式语法分离出Tag1和Tag2。这段代码在Example-WindowHelper-BindingControl。 接着图元组件订阅Tag1和Tag2的ValueChanged事件。 如果值发生变化这个事件内部会执行SetTagReader计算表达式的结果如满足条件将向界面发送指令。 例如变量表达式为Tag1*2Tag2*510此时若Tag11,Tag22满足条件最终会触发一个动画脚本Action。这个Action可以是让电机报警颜色变为闪烁的红色也可以是点亮一盏灯或打开一座阀门。下文会详细阐述。 从网关到人机界面流程 六、 下面的计划 写一系列帖子把架构、原理讲清楚。大致如下 网关层接口概述 上下位机通讯原理 如何实现一个设备驱动 从网关到人机界面 如何设计图元 VS插件模块及原理 归档模块及文件格式 如何进行功能扩展 组态变量表达式实现 github地址https://github.com/GavinYellow/SharpSCADA。QQ群102486275 相关文章 .NET十年回顾 开源纯C#工控网关组态软件 开源纯C#工控网关组态软件(三)加入一个新驱动西门子S7 开源纯C#工控网关组态软件(四)上下位机通讯原理 原文地址http://www.cnblogs.com/evilcat/p/7782265.html.NET社区新闻深度好文微信中搜索dotNET跨平台或扫描二维码关注