KTK_DeviceBase.cs 13.2 KB
using log4net;
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
 

namespace OnlineStore.DeviceLibrary
{
    public abstract class KTK_DeviceBase
    {
        /// <summary>
        /// 料仓单个调试状态(默认不是调试状态)
        /// </summary>
        public bool IsDebug = false;
        public Dictionary<string, ConfigIO> DIList { get; set; }
        public Dictionary<string, ConfigIO> DOList { get; set; }
        /// <summary>
        ///1=设备联机(正常就绪)(入库后,BOX恢复原始状态)(出库后,移载装置恢复原始状态),
        ///2=急停,3=故障,4=警告,5=调试
        ///  6=入库执行中,7=入仓完成,8=入仓失败
        /// 9=出库执行,10=出仓完成,11=出库失败
        /// </summary>
        public StoreStatus storeStatus = StoreStatus.StoreOnline;
        /// <summary>
        /// 提示消息,一般发给服务器后清空(LineBean表示报警提示消息,BoxBean表示出入库失败的原因记录)
        /// </summary>
        public string WarnMsg = "";
        /// <summary>
        /// 日志颜色
        /// </summary>
        protected static Color storeMoveColor = Color.Blue;
        protected static readonly ILog LOGGER = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public string StoreName { get; set; }
        public int StoreID { get; set; }
        /// <summary>
        /// 料仓状态
        /// </summary>
        private StoreRunStatus storerunstatus = StoreRunStatus.Wait;
        /// <summary>
        /// 定时器
        /// </summary>
        protected System.Timers.Timer timersTimer;

        private bool isInit = false;
        /// <summary>
        /// 初始化
        /// </summary>
        protected virtual void Init()
        {
            if (!isInit)
            {
                StoreMove = new StoreMoveInfo(StoreID);

                timersTimer = new System.Timers.Timer();
                timersTimer.Enabled = false;
                timersTimer.Interval = 300;
                timersTimer.Elapsed += timersTimer_Elapsed;
                timersTimer.AutoReset = true;
                isInit = true;
            }
        }
        public StoreRunStatus storeRunStatus
        {
            get
            {
                return storerunstatus;
            }
            set
            {
                StoreRunStatus oldStatus = storerunstatus;
                storerunstatus = value;
            }
        }

        /// <summary>
        /// 移动信息
        /// </summary>
        public StoreMoveInfo StoreMove = null;
        ///// <summary>
        ///// 回原点,所有装置回到原点位置
        ///// </summary>
        //public abstract void Home();
        /// <summary>
        /// 定时处理,监听信号,监听IO
        /// </summary> 
        protected abstract void timersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e);
        #region 出库
        /// <summary>
        /// 开始出库运动
        /// </summary> 
        public abstract void StartOutStoreMove(InOutStoreParam param);
        protected abstract void OutStoreProcess();
        #endregion

        #region 入库
        /// <summary>
        /// 开始入库移动移动
        /// </summary> 
        public abstract void StartInStoreMove(InOutStoreParam param);
        protected abstract void InStoreProcess();
        #endregion

     
        /// <summary>
        /// 判断急停是否开着,开着表示可以运行
        /// </summary>
        /// <returns></returns>
        public Boolean ShutdownIsOpen()
        {
            if (DeviceControl.isNoDeviceDebug)
            {
                return true;
            }
            //急停按钮和气压检测需要一起判断
            IO_VALUE suddenBtn = GetDeviceIO(Store_IO_Type.SuddenStop_BTN);
            IO_VALUE airCheck = GetDeviceIO(Store_IO_Type.Airpressure_Check);
            if (suddenBtn == IO_VALUE.HIGH && airCheck == IO_VALUE.HIGH)
            {
                return true;
            }
            return false;
        }
        public string GetRunStr()
        {
            string sta = "运行中";
            string aa = "";
            switch (storeRunStatus)
            {
                case StoreRunStatus.Busy:
                    sta = "忙碌";
                    break;
                case StoreRunStatus.HomeMoving:
                    sta = "原点返回";
                    break;
                case StoreRunStatus.Reset:
                    sta = "重置";
                    break;
                case StoreRunStatus.Runing:
                    sta = "运行中";
                    break;
                case StoreRunStatus.Wait:
                    sta = "等待启动";
                    break;
            }
            if (storeRunStatus > StoreRunStatus.Wait)
            {
                //"0":"急停中",   "1":"设备联机",   "2":"故障中", "3":"入库执行中",  "4":"出库执行中",   5":"料盘入仓位完成",   "6":"料盘出仓位完成",  7":"设备调试中",
                switch (storeStatus)
                {
                    case StoreStatus.Debugging:
                        aa = "设备调试中";
                        break;
                    case StoreStatus.InStoreEnd:
                        aa = "料盘入仓位完成";
                        break;
                    case StoreStatus.InStoreExecute:
                        aa = "入库执行中";
                        break;
                    case StoreStatus.InTrouble:
                        aa = "故障中";
                        break;
                    case StoreStatus.OutStoreBoxEnd:
                        aa = "料盘出仓位完成";
                        break;
                    case StoreStatus.OutStoreExecute:
                        aa = "出库执行中";
                        break;
                    case StoreStatus.StoreOnline:
                        aa = "设备联机";
                        break;
                    case StoreStatus.SuddenStop:
                        aa = "急停中";
                        break;
                    case StoreStatus.OutMoveExecute:
                        aa = "出库完成";
                        break;
                    case StoreStatus.InStoreFaild:
                        aa = "入库失败(" + WarnMsg + ")";
                        break;
                    case StoreStatus.OutStoreFaild:
                        aa = "出库失败(" + WarnMsg + ")";
                        break;
                }
                if (!aa.Equals(""))
                {
                    return sta + "_" + aa;
                }
                else
                {
                    return sta;
                }
            }
            else
            {
                return sta;
            }
        }


        #region IO运动和等待
        /// <summary>
        /// 气缸移动方法,将IoLowType的DO写为0,IoHighType的DO写为1
        /// 此方法不加入等待条件
        /// </summary> 
        public void CylinderMove(string IoLowType, string IoHighType)
        {
            DeviceIOMove(IoLowType, IO_VALUE.LOW);
            DeviceIOMove(IoHighType, IO_VALUE.HIGH); 
        }
        /// <summary>
        ///气缸移动方法,将IoLowType的DO写为0,IoHighType的DO写为1
        ///此方法会自动加入等待条件
        /// </summary> 
        public void CylinderMove(StoreMoveInfo moveInfo, string IoLowType, string IoHighType)
        {
            DeviceIOMove(IoLowType, IO_VALUE.LOW);
            DeviceIOMove(IoHighType, IO_VALUE.HIGH);

            moveInfo.WaitList.Add(WaitResultInfo.WaitIO(IoLowType, IO_VALUE.LOW));
            moveInfo.WaitList.Add(WaitResultInfo.WaitIO(IoHighType, IO_VALUE.HIGH));
        }
        //记录上次 写入的DO的值,下次不要重复写
        protected Dictionary<string , IO_VALUE> DOValueMap = new Dictionary<string , IO_VALUE>();
        protected object doMapLock = "";
        protected void  UpdateDoValue(string  ioType,IO_VALUE doValue){
            lock (doMapLock)
            {
                if (DOValueMap.ContainsKey(ioType))
                {
                    DOValueMap[ioType]=doValue;
                }else{
                    DOValueMap.Add(ioType, doValue);
                } 
            }
        }
        /// <summary>
        /// 判断Do是否是传入的值
        /// </summary>
        protected bool IsDoValue(string ioType, IO_VALUE doValue)
        {
            lock (doMapLock)
            {
                if (DOValueMap.ContainsKey(ioType))
                {
                    if (doValue.Equals(DOValueMap[ioType]))
                    {
                        return true;
                    }
                }
            } return false;
        }
        public void DeviceIOMove(string ioType, IO_VALUE ioValue)
        {
            if (DOList.ContainsKey(ioType))
            {
                DeviceControl.WriteSingleIO(DOList[ioType], ioValue);
                UpdateDoValue(ioType, ioValue);
            }
            else
            {
                LogUtil.error(LOGGER, StoreName + "没有DO=" + ioType);
            }
        }

        public IO_VALUE GetDeviceIO(string ioType)
        {
            if (DIList.ContainsKey(ioType))
            {
                return DeviceControl.GetSingleIO(DIList[ioType]);
            }
            else
            {
                //这些IO只有DO没有DI,根据DO的值来判断
                if (
                    //自动料仓的DO
                    ioType.Equals(Store_IO_Type.Run_Sign)
                    || ioType.Equals(Store_IO_Type.Axis_Brake)
                    || ioType.Equals(Store_IO_Type.StartOrStopBlow)
                    || ioType.Equals(Store_IO_Type.StopCylinder_1)
                    || ioType.Equals(Store_IO_Type.StopCylinder_2)
                    //流水线的DO
                    || ioType.Equals(Store_IO_Type.AutoRun_HddLed)
                    || ioType.Equals(Store_IO_Type.RunSign_HddLed)
                    || ioType.Equals(Store_IO_Type.Alarm_HddLed)
                    || ioType.Equals(Store_IO_Type.DriveMotor1_Forward)
                    || ioType.Equals(Store_IO_Type.DriveMotor1_Back)
                    || ioType.Equals(Store_IO_Type.DriveMotor2_Forward)
                    || ioType.Equals(Store_IO_Type.DriveMotor2_Back)
                    )
                {
                    return DeviceControl.GetSingleIO(DOList[ioType]);
                }
                else
                {
                    LogUtil.error(LOGGER, StoreName + "没有DI=" + ioType);
                }
                return IO_VALUE.LOW;
            }
        }
    
       
        ///// <summary>
        ///// IO运动,将指定的IO类型写为指定的置,并等待检测结果成功,方法执行完毕
        ///// </summary>
        ///// <param name="ioMap">key=Store_IO_Type,value=需要写入和等待的值</param>
        //protected void DeviceIOMoveAndWait(string ioType, IO_VALUE ioValue)
        //{
        //    DeviceIOMove(ioType, ioValue);
        //    WaitIO(ioType, ioValue);
        //}
        ///// <summary>
        ///// IO运动,将指定的IO类型写为指定的置,并等待检测结果成功,方法执行完毕
        ///// </summary>
        ///// <param name="ioMap">key=Store_IO_Type,value=需要写入和等待的值</param>
        //protected void DeviceIOMove(Dictionary<string, IO_VALUE> ioMap)
        //{
        //    foreach (string ioType in ioMap.Keys)
        //    {
        //        IO_VALUE value = ioMap[ioType];
        //        DeviceIOMove(ioType, value);
        //    }
             
        //}
        /// <summary>
        /// 验证指定的IO是否达到对应值
        /// </summary>
        /// <param name="ioMap">key=Store_IO_Type,value=需要到达的值</param>
        protected bool CheckIO(Dictionary<string, IO_VALUE> ioMap)
        { 
            bool isAllOk = true;
            foreach (string ioType in ioMap.Keys)
            {
                IO_VALUE value = ioMap[ioType];
                if (GetDeviceIO(ioType).Equals(value) ||
                    (ioType.Equals(Store_IO_Type.Fixture_Check_1) && NoFixture_Check)
                    || DeviceControl.isNoDeviceDebug)
                {
                }
                else
                {
                    isAllOk = false;
                }
            }
            return isAllOk; 
        }

        /// <summary>
        /// 验证指定的IO达到对应的值后返回
        /// </summary>
        /// <param name="ioMap">key=Store_IO_Type,value=需要验证的值</param>
        protected bool CheckIO(string ioType, IO_VALUE ioValue)
        {
            if (GetDeviceIO(ioType).Equals(ioValue)
                || (ioType.Equals(Store_IO_Type.Fixture_Check_1) && NoFixture_Check)
                || DeviceControl.isNoDeviceDebug)
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// TODO:暂时没有夹具检测,调试时暂时=true,后面有信号需要删掉
        /// </summary>
        private bool NoFixture_Check = false;
        #endregion

    }
}