| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 | using Houdar.PLC.Driver.Simenss;using Houdar.PLC.Driver.Simenss.Protocol.Common;using Houdar.PLC.Driver.Simenss.Protocol.ReadData;using System;using WCS.Data;using WCS.Data.Utils;namespace WCS.PLC{    public class PLC    {        private readonly object olock = new object();        private string _plc_name = string.Empty;        private PlcErrorCount _plcErrorCount = new PlcErrorCount() { ErrorCount = 0, LastTime = DateTime.MinValue };        private Action StopPlcEvent;        internal SimenssPlc _splc = null;        public PLC() { _splc = new SimenssPlc(); }        //slot 插槽,port 端口,rack 道轨        public bool Connect(string ip, int rack, int slot)        {            if (_splc.ConnectTo(ip, rack, slot))                return true;            return false;        }        public bool Connect(string ip, int rack, int slot, string plc_name)        {            if (_splc.ConnectTo(ip, rack, slot))            {                _plc_name = plc_name;                _splc.RegisterMessageEvent(PrintMsg);                return true;            }            return false;        }        #region 读取值;        public object ReadSignal(ushort DBNumber, ushort start, ushort len)        {            object obj = 0;            byte[] msg = new byte[len];            if (Read(DBNumber, start, len, ref msg))            {                if (len == 1)                {                    //obj = BitConverter.ToUInt16(bt,0);                    obj = msg[0];                }                else if (len == 2)                {                    //byte[] temp = new byte[2];                    //temp[0] = bt[1];                    //temp[1] = bt[0];                    //obj = BitConverter.ToInt16(temp, 0);                    obj = Convert.ToUInt16(msg[0] * 256 + msg[1]);                }                else if (len == 4)                {                    //byte[] temp = new byte[4];                    //temp[0] = bt[3];                    //temp[1] = bt[2];                    //temp[2] = bt[1];                    //temp[3] = bt[0];                    //obj = BitConverter.ToInt16(temp, 0);                    obj = Convert.ToUInt32(msg[0] * 256 * 256 * 256 + msg[1] * 256 * 256 + msg[2] * 256 + msg[3]);                }            }            else            {                obj = 0;            }            return obj;        }        public bool ReadBit(ushort DBNumber, ushort start)        {            if (_splc.Connected)            {                DataItem di = _splc.ReadArea(AreaType.DB, DBNumber, start, 1, DataType.Bit);                if (di != null && di.Err == ResultCode.OKFF)                {                    return Convert.ToBoolean(di.Data[0]);                }                else                {                    if (di != null)                        Log4netHelper.Logger_Error.ErrorFormat(di.Err.ToString());                    return false;                }            }            Log4netHelper.Logger_Error.ErrorFormat("PLC未连接。");            return false;        }        public bool ReadBitArea(ushort DBNumber, ushort start, ushort len, ref byte[] msg)        {            if (_splc.Connected)            {                for (int i = 0; i < len; i++)                {                    DataItem di = _splc.ReadArea(AreaType.DB, DBNumber, (ushort)i, 1, DataType.Bit);                    if (di != null && di.Err == ResultCode.OKFF)                    {                        msg[i] = di.Data[0];                        //return true;                    }                    else                    {                        if (di != null)                            Log4netHelper.Logger_Error.ErrorFormat(di.Err.ToString());                        return false;                    }                }                return true;            }            Log4netHelper.Logger_Error.ErrorFormat("PLC未连接。");            return false;        }        public bool Read(ushort DBNumber, ushort start, ushort len, ref byte[] msg)        {            if (_splc.Connected)            {                DataType dt;                if (len == 1) dt = DataType.Byte;                else if (len == 2) dt = DataType.Word;                else if (len == 4) dt = DataType.DWord;                else return false;                DataItem di = _splc.ReadArea(AreaType.DB, DBNumber, start, len, dt);                if (di != null && di.Err == ResultCode.OKFF)                {                    msg = di.Data;                    return true;                }                else                {                    if (di != null)                        Log4netHelper.Logger_Error.ErrorFormat(di.Err.ToString());                    return false;                }            }            Log4netHelper.Logger_Error.ErrorFormat("PLC未连接。");            return false;        }        public bool ReadByteArea(ushort DBNumber, ushort start, ushort len, ref byte[] msg)        {            lock (olock)            {                try                {                    if (_splc.Connected)                    {                        DataItem di = _splc.ReadArea(AreaType.DB, DBNumber, start, len, DataType.Byte);                        if (di != null && di.Err == ResultCode.OKFF)                        {                            msg = di.Data;                            return true;                        }                        else                        {                            if (di == null)                            {                                Log4netHelper.Logger_Error.ErrorFormat(string.Format("DB[{0}]读取失败,未查询到读取失败原因。", DBNumber));                                if (PlcErrorIsFull(DBNumber))                                {                                    StopPlc();                                }                            }                            else                                Log4netHelper.Logger_Error.ErrorFormat(string.Format("DB[{0}]读取失败,原因:[{1}]", DBNumber, di.Err.ToString()));                            return false;                        }                    }                    else                    {                        LogMessageHelper.RecordLogMessage(string.Format("PLC[{0}]DB[{1}]读取失败,Connected为fasle,系统将重新连接plc。", _plc_name, DBNumber));                    }                }                catch (Exception ex)                {                    Log4netHelper.Logger_Error.ErrorFormat(ex.ToString());                }            }            return false;        }        private void PrintMsg(MessageEvent msg)        {            if (msg.Message.Trim() != "OK")            {                Log4netHelper.Logger_Info.Info(string.Format("PLC通信DLL消息:方法:[{0}]消息[{1}]", msg.Method, msg.Message));            }        }        private bool PlcErrorIsFull(ushort dbnumber)        {            bool result = false;            int count = 18;            if (dbnumber == 520 || dbnumber == 521)            {                if (_plcErrorCount.ErrorCount == 0)                {                    Log4netHelper.Logger_Error.ErrorFormat(string.Format("PLC[{0}]第一次报错,次数+1", _plc_name));                    _plcErrorCount.ErrorCount = 1;                    _plcErrorCount.LastTime = DateTime.Now;                }                else if (_plcErrorCount.ErrorCount < count)                {                    if (_plcErrorCount.LastTime.AddSeconds(10) > DateTime.Now)                    {                        _plcErrorCount.ErrorCount += 1;                        _plcErrorCount.LastTime = DateTime.Now;                        Log4netHelper.Logger_Error.ErrorFormat(string.Format("PLC[{0}]次数+1 ,现有次数[{1}]", _plc_name, _plcErrorCount.ErrorCount));                    }                    else                    {                        _plcErrorCount.ErrorCount = 0;                        _plcErrorCount.LastTime = DateTime.Now;                        Log4netHelper.Logger_Error.ErrorFormat(string.Format("PLC[{0}]10秒未报错,次数重置", _plc_name, _plcErrorCount.ErrorCount));                    }                }                else if (_plcErrorCount.ErrorCount >= count)                {                    _plcErrorCount.ErrorCount = 0;                    LogMessageHelper.RecordLogMessage(string.Format("PLC[{0}]读取DB频繁返回Null值达到[{1}]次,将停止PLC连接,次数清零,并重启PLC连接。", _plc_name, count));                    result = true;                }            }            return result;        }        //public bool ReadWordArea(ushort DBNumber, ushort start, ushort len, ref byte[] msg)        //{        //    if (_splc.Connected)        //    {        //        DataItem di = _splc.ReadArea(AreaType.DB, DBNumber, start, len, DataType.Word);        //        if (di != null && di.Err == ResultCode.OKFF)        //        {        //            msg = di.Data;        //            return true;        //        }        //        else        //        {        //            Current.Logger_Error.ErrorFormat(di.Err.ToString());        //            return false;        //        }        //    }        //    Current.Logger_Error.ErrorFormat("PLC未连接。");        //    return false;        //}        #endregion;        #region 写入值        public bool WriteSignal(ushort DBNumber, ushort start, ushort len, object msg)        {            lock (olock)            {                bool result = false;                byte[] bt = new byte[len];                if (len == 1)                {                    bt[0] = Convert.ToByte(msg);                }                else if (len == 2)                {                    byte[] from_wcs = System.BitConverter.GetBytes(Convert.ToUInt16(msg));                    bt[0] = from_wcs[1];//地位值                    bt[1] = from_wcs[0];//高位值                }                else if (len == 4)                {                    byte[] from_wcs = System.BitConverter.GetBytes(Convert.ToUInt32(msg));                    bt[0] = from_wcs[3];                    bt[1] = from_wcs[2];                    bt[2] = from_wcs[1];                    bt[3] = from_wcs[0];                }                result = Write(DBNumber, start, bt);                return result;            }        }        public bool WriteBits(ushort DBNumber, uint start, bool status)        {            lock (olock)            {                bool result = false;                if (_splc.Connected)                {                    byte[] bt = new byte[1];                    bt[0] = Convert.ToByte(status);                    if (_splc.WriteArea(AreaType.DB, DBNumber, start, 1, DataType.Bit, bt))                    {                        result = true;                    }                    else                    {                        Log4netHelper.Logger_Error.ErrorFormat("写入DB信息失败,PLC可能未连接。(WriteBits)");                    }                }                else                {                    Log4netHelper.Logger_Error.ErrorFormat("写入DB信息失败,PLC未连接。(WriteBits)");                }                return result;            }        }        public bool Write(ushort DBNumber, ushort start, byte[] msg)        {            lock (olock)            {                bool result = false;                if (_splc.Connected)                {                    //DataType dt;                    //if (len == 1) dt = DataType.Byte;                    //else if (len == 2) dt = DataType.Word;                    //else if (len == 4) dt = DataType.DWord;                    //else return false;                    if (_splc.WriteArea(AreaType.DB, DBNumber, start, (ushort)msg.Length, DataType.Byte, msg))                    {                        result = true;                    }                    else                    {                        Log4netHelper.Logger_Error.ErrorFormat("写入DB信息失败,PLC可能未连接。(Write)");                    }                }                else                {                    Log4netHelper.Logger_Error.ErrorFormat("写入DB信息失败,PLC未连接。(Write)");                }                return result;            }        }        #endregion;        public void PlcStop()        {            _splc.PlcStop();        }        public void RegisterStopPlcEvent(Action stopPlcAction)        {            if (stopPlcAction == null) throw new ArgumentNullException("stopPlcAction");            StopPlcEvent = stopPlcAction;        }        private void StopPlc()        {            if (StopPlcEvent != null) StopPlcEvent.Invoke();        }    }    public struct PlcErrorCount    {        public int ErrorCount;        public DateTime LastTime;    }}
 |