using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using System.Text.RegularExpressions; using System.Collections.ObjectModel; using FLY.ModbusModule; using FObjBase; namespace FLY.FeedbackRenZiJia.Server { public class HMI : IPLCLink { FLY.ModbusModule.ServerTCP modbusserver; PLCRegister mPLCRegs; #region 地址 const int ADDR_M_HasElectricCurrent = 0;//bit 三相电 电流 const int ADDR_M_HasFan = 1;//bit 风机启动 const int ADDR_D_ChannelCnt = 0;//加热通道数 const int ADDR_D_HeatUpdate = 1;//加热更新 const int ADDR_D_CurrUpdate = 2;//当前值更新 const int ADDR_D_Heats = 100;//加热量 const int ADDR_D_Currs = 300;//当前值 #endregion public HMI() { mPLCRegs = new PLCRegister(3, 600); mPLCRegs.RegChanged += new PLCRegister.RegChangedEventHandler(mPLCRegs_RegChanged); RegToPropertyNameInit(); modbusserver = new ServerTCP(mPLCRegs); PollModule.Current.Poll_Config(PollModule.POLL_CONFIG.ADD, new PollModule.PollHandler(OnPoll)); } void mPLCRegs_RegChanged(object sender, PLCRegister.RegChangedEventArgs e) { var propertyNames = from _r in rpn where _r.type == e.RegType && e.IsCover(_r.addr,_r.len) select _r.propertyName; if (propertyNames.Count() > 0) { foreach (var n in propertyNames) NotifyPropertyChanged(n); } } class RegToPropertyName { public PLCRegister.RegChangedEventArgs.REG_TYPE type; public int addr; public int len; public string propertyName; public RegToPropertyName(PLCRegister.RegChangedEventArgs.REG_TYPE type, int addr, int len, string propertyName) { this.type = type; this.addr = addr; this.len = len; this.propertyName = propertyName; } } List<RegToPropertyName> rpn = new List<RegToPropertyName>(); /// <summary> /// 用于 外部写入后,地址转为PropertyName 触发 PropertyChanged /// </summary> void RegToPropertyNameInit() { rpn.Add(new RegToPropertyName(PLCRegister.RegChangedEventArgs.REG_TYPE.COIL, ADDR_M_HasElectricCurrent, 1, "HasElectricity")); rpn.Add(new RegToPropertyName(PLCRegister.RegChangedEventArgs.REG_TYPE.COIL, ADDR_M_HasFan, 1, "HasFan")); rpn.Add(new RegToPropertyName(PLCRegister.RegChangedEventArgs.REG_TYPE.REG, ADDR_D_ChannelCnt, 1, "ChannelCnt")); rpn.Add(new RegToPropertyName(PLCRegister.RegChangedEventArgs.REG_TYPE.REG, ADDR_D_HeatUpdate, 1, "HeatUpdate_R")); rpn.Add(new RegToPropertyName(PLCRegister.RegChangedEventArgs.REG_TYPE.REG, ADDR_D_CurrUpdate, 1, "CurrUpdate")); } public void OnPoll() { //需要访问modbusserver 判断最近有没通讯 if (DateTime.Now.Subtract(modbusserver.LastCommDT).TotalSeconds > 3) { //有3秒没通讯 Errno = -1; } else { Errno = 0; } } #region PLCLink 成员 #region 状态 /// <summary> /// -1 HMI 没有连接到 本服务器; -2 串口打开异常 /// </summary> public int Errno { get; set; } = -1; public int RetCode { get; set; } #endregion /// <summary> /// 当前电流 有没? /// </summary> public bool HasElectricity { get { return mPLCRegs.GetBool(ADDR_M_HasElectricCurrent); } } /// <summary> /// 风机是否启动? /// </summary> public bool HasFan { get { return mPLCRegs.GetBool(ADDR_M_HasFan); } } public ushort ChannelCnt { get { return mPLCRegs.GetUInt16(ADDR_D_ChannelCnt); } set { mPLCRegs.SetUInt16(ADDR_D_ChannelCnt, value); } } public ushort HeatUpdate { get { return mPLCRegs.GetUInt16(ADDR_D_HeatUpdate); } set { mPLCRegs.SetUInt16(ADDR_D_HeatUpdate, value); } } public ushort HeatUpdate_R { get { return mPLCRegs.GetUInt16(ADDR_D_HeatUpdate); } } public ushort CurrUpdate { get { return mPLCRegs.GetUInt16(ADDR_D_CurrUpdate); } set { mPLCRegs.SetUInt16(ADDR_D_CurrUpdate, value); } } public void SetHeat(IEnumerable<UInt16> value) { for (int i = 0; i < value.Count(); i++) { mPLCRegs.SetUInt16(ADDR_D_Heats + i, value.ElementAt(i)); } } public IEnumerable<UInt16> GetCurr() { List<UInt16> list = new List<UInt16>(); for (int i = 0; i < ChannelCnt; i++) { list.Add(mPLCRegs.GetUInt16(ADDR_D_Currs + i)); } return list; } #endregion #region INotifyPropertyChanged 成员 public event PropertyChangedEventHandler PropertyChanged; protected void NotifyPropertyChanged(string propertyname) { if (PropertyChanged != null) { PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyname)); } } #endregion } }