HMI.cs 5.97 KB
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

    }
}