using RGD.Common;
using RGD.DataService;
using RGD.DBUtility;
using System;
using System.Data;
using System.Threading;

namespace RGD.WCS
{
    /// <summary>
    /// Creator:RGD
    /// 解析PLC返回的数据
    /// </summary>
    public static class CParsePLCData
    {
        private static string _CParsePLCError = "";//监控调度类错误说明

        public static string CParsePLCError
        {
            get { return _CParsePLCError; }
            set { _CParsePLCError = value; }
        }

        private static Model.MDevice devinfo28 = BaseDeviceService.GetDeviceInfo(65534);
        private static Thread mythread;
        private static bool exitThread = false;

        #region 监听 子线程 300ms

        public static void StartListen()
        {
            exitThread = false;
            mythread = new Thread(new ThreadStart(BeginListen));
            mythread.IsBackground = true;
            mythread.Start();
        }

        private static void BeginListen()
        {
            while (!exitThread)
            {
                try
                {
                    SetDeviceState();
                }
                catch (Exception ex)
                {
                    _CParsePLCError = ex.Message;
                }
                //Thread.Sleep(300);
            }
        }

        public static void EndListen()
        {//20091107
            exitThread = true;

            if (mythread != null)
            {
                mythread.Abort();
                mythread = null;
            }
        }

        #endregion 监听 子线程 300ms

        /// <summary>
        /// 解析PLC主方法 设置所有设备的当前动态属性 依赖于 CStaticClass.AllReturns
        /// </summary>
        public static void SetDeviceState()
        {
            try
            {
                #region 更新路径，每30s 回报状态，每3s
                bool updateroute = false;//更新路径，每30s
                bool reportstatus = false;//回报状态，每3s
                if (CStaticClass.routetime.AddSeconds(30) <= DateTime.Now)
                {
                    updateroute = true;
                    CStaticClass.routetime = DateTime.Now;
                }
                if (CStaticClass.reporttime.AddSeconds(3) <= DateTime.Now)
                {
                    reportstatus = true;
                    CStaticClass.reporttime = DateTime.Now;
                }
                else
                {
                    reportstatus = false;
                }
                #endregion 更新路径，每30s 回报状态，每3s

                //当CStaticClass.AllReturns位Null时 此循环无意义 优化重点
                int[] States;
                //LogUtil.WriteLog("", "解析PLC主方法 设置所有设备的当前动态属性 依赖于 CStaticClass.AllReturns");
                //DateTime dt1 = DateTime.Now;
                DataTable dvvDeviceState = DbHelperSQL.Query("SELECT F_DeviceIndex,F_LockedState FROM T_Base_Device").Tables[0];
                //LogUtil.WriteLog("", "解析PLC设备状态,运行时间:" + (DateTime.Now - dt1).TotalMilliseconds + ";");  //经测试 超过2秒
                foreach (Model.MDevice devinfo1 in BaseDeviceService.DeviceInfo.Values)
                {
                    //循环中增加了查询数据库频率 检测射频是否停用 考虑去掉
                    #region 循环所有设备 0表示空闲；-1表示停用
                    DataRow[] rows = dvvDeviceState.Select("F_LockedState=-1 and F_DeviceIndex=" + devinfo1.DeviceIndex);
                    if (rows.Length > 0)
                    {
                        #region 停用 超时更新路径 此处未用20210915
                        if (updateroute == true)
                        {//20100131
                            UpdateErrorCode(devinfo1.DeviceIndex, 98);
                            AlterRoute(devinfo1.DeviceIndex, 98);
                        }
                        //20090926
                        if (devinfo1.ErrorCode != 98)
                        {
                            UpdateErrorCode(devinfo1.DeviceIndex, 98);
                            AlterRoute(devinfo1.DeviceIndex, 98);
                            devinfo1.RunState = 4;
                        }
                        devinfo1.ErrorCode = 98;
                        #endregion 停用 超时更新路径 此处未用20210915
                    }
                    else
                    {
                        #region 根据设备类型 更新设备实时信息 更新错误状态与路径信息
                        if ((devinfo1.DeviceKind == 14) || (devinfo1.DeviceKind == 18))//暂无 位置设备类型
                        {
                            devinfo1.DeviceVisual = GetDevicePhotoelectric(devinfo1.DeviceIndex);
                            continue;
                        }
                        if (devinfo1.DeviceKind == 2 || devinfo1.DeviceKind == 3 || devinfo1.DeviceKind == 5 || devinfo1.DeviceKind == 7 || devinfo1.DeviceKind == 32 || devinfo1.DeviceKind == 34)
                        {
                            #region 输送线|升降机|折叠盘机条码滑台模组AGV等 SQL是否有物更新
                            //有些输送机、提升机在调度路径中存在，但是不需要调度来下指令，电器自己控制，只考察是否运行和故障位就可以了
                            if (devinfo1.OnlyDetectIO == "1")//只检测IO信号
                            {
                                #region 运行位（设备索引+7）
                                devinfo1.RunState = GetDevicePhotoelectric(Convert.ToInt32(devinfo1.DeviceIndex.ToString() + "7"));
                                if (updateroute == true)
                                {//20100131
                                    UpdateErrorCode(devinfo1.DeviceIndex, 0);
                                    AlterRoute(devinfo1.DeviceIndex, 0);
                                }
                                if (devinfo1.ErrorCode != 0)
                                {
                                    AlterRoute(devinfo1.DeviceIndex, 0);
                                }
                                //20090926
                                int err = 0;
                                //devinfo1.ErrorCode = 0;
                                #endregion 运行位（设备索引+7）

                                #region 故障位（设备索引+6）
                                if (GetDevicePhotoelectric(Convert.ToInt32(devinfo1.DeviceIndex.ToString() + "6")) == 1)
                                {
                                    if (updateroute == true)
                                    {//20100131
                                        UpdateErrorCode(devinfo1.DeviceIndex, 97);
                                        AlterRoute(devinfo1.DeviceIndex, 97);
                                    }
                                    devinfo1.RunState = 2;
                                    if (devinfo1.ErrorCode != 97)
                                    {
                                        UpdateErrorCode(devinfo1.DeviceIndex, 97);
                                        AlterRoute(devinfo1.DeviceIndex, 97);
                                    }
                                    err = 97;
                                }
                                if (updateroute == true)
                                {
                                    UpdateErrorCode(devinfo1.DeviceIndex, err);
                                    AlterRoute(devinfo1.DeviceIndex, err);
                                }
                                if (devinfo1.ErrorCode != err)
                                {
                                    UpdateErrorCode(devinfo1.DeviceIndex, err);
                                    AlterRoute(devinfo1.DeviceIndex, err);
                                }
                                devinfo1.ErrorCode = err;
                                #endregion 故障位（设备索引+6）
                            }
                            else
                            {
                                States = GetDeviceState(devinfo1.DeviceIndex);
                                if (States == null) continue;
                                if (States[1] >= 30)
                                {
                                    if (updateroute == true)
                                    {
                                        UpdateErrorCode(devinfo1.DeviceIndex, States[1]);
                                        AlterRoute(devinfo1.DeviceIndex, States[1]);
                                    }
                                    //修改路径表
                                    if (States[1] != devinfo1.ErrorCode)
                                    {
                                        UpdateErrorCode(devinfo1.DeviceIndex, States[1]);
                                        AlterRoute(devinfo1.DeviceIndex, States[1]);
                                    }
                                    devinfo1.ErrorCode = States[1];
                                    devinfo1.RunState = 2;
                                }
                                else if ((States[1] == 0) || (States[1] == 1) || (States[1] == 2))
                                {
                                    if (updateroute == true)
                                    {
                                        UpdateErrorCode(devinfo1.DeviceIndex, 0);
                                        AlterRoute(devinfo1.DeviceIndex, States[1]);
                                    }
                                    //修改路径表
                                    if (States[1] != devinfo1.ErrorCode)
                                    {
                                        UpdateErrorCode(devinfo1.DeviceIndex, 0);
                                        AlterRoute(devinfo1.DeviceIndex, States[1]);
                                    }
                                    if (States[1] == 2)
                                    {
                                        //20090920
                                        devinfo1.RunState = 5;
                                    }
                                    else
                                    {
                                        devinfo1.RunState = States[1];
                                    }
                                    devinfo1.ErrorCode = States[1];
                                }
                                devinfo1.TaskNo = States[2];
                                if (devinfo1.SplitByte != -1)
                                {
                                    devinfo1.SplitByte_0 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 0);
                                    devinfo1.SplitByte_1 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 1);
                                    devinfo1.SplitByte_2 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 2);
                                    devinfo1.SplitByte_3 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 3);
                                    devinfo1.SplitByte_4 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 4);
                                    devinfo1.SplitByte_5 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 5);
                                    devinfo1.SplitByte_6 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 6);
                                    devinfo1.SplitByte_7 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 7);
                                }
                                DbHelperSQL.ExecuteSql("UPDATE T_Base_Device SET F_HaveGoodsDetect = " + devinfo1.SplitByte_0 + " WHERE F_DeviceIndex = " + devinfo1.DeviceIndex);
                            }
                            #endregion 输送线|升降机|折叠盘机条码滑台模组AGV等 SQL是否有物更新
                        }
                        if (devinfo1.DeviceKind == 33)
                        {
                            #region 贴标机
                            States = GetDeviceState(devinfo1.DeviceIndex);
                            if (States == null) continue;

                            if (States[1] >= 30)
                            {
                                if (updateroute == true)
                                {//20100131
                                    UpdateErrorCode(devinfo1.DeviceIndex, States[1]);
                                    AlterRoute(devinfo1.DeviceIndex, States[1]);
                                }
                                //修改路径表
                                if (States[1] != devinfo1.ErrorCode)
                                {
                                    UpdateErrorCode(devinfo1.DeviceIndex, States[1]);
                                    AlterRoute(devinfo1.DeviceIndex, States[1]);
                                }
                                devinfo1.ErrorCode = States[1];
                                devinfo1.RunState = 2;
                            }
                            else if ((States[1] == 0) || (States[1] == 1) || (States[1] == 2))
                            {
                                if (updateroute == true)
                                {//20100131
                                    UpdateErrorCode(devinfo1.DeviceIndex, 0);
                                    AlterRoute(devinfo1.DeviceIndex, States[1]);
                                }
                                //修改路径表
                                if (States[1] != devinfo1.ErrorCode)
                                {
                                    UpdateErrorCode(devinfo1.DeviceIndex, 0);
                                    AlterRoute(devinfo1.DeviceIndex, States[1]);
                                }
                                if (States[1] == 2)
                                {
                                    devinfo1.RunState = 5;
                                }
                                else
                                {
                                    devinfo1.RunState = States[1];
                                }
                                devinfo1.ErrorCode = States[1];
                            }
                            devinfo1.TaskNo = States[2];
                            devinfo1.CurrentLocation = States[3];
                            devinfo1.PLCAskNo = States[4];
                            if (devinfo1.SplitByte != -1)
                            {
                                devinfo1.SplitByte_0 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 0);
                                devinfo1.SplitByte_1 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 1);
                                devinfo1.SplitByte_2 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 2);
                                devinfo1.SplitByte_3 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 3);
                                devinfo1.SplitByte_4 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 4);
                                devinfo1.SplitByte_5 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 5);
                                devinfo1.SplitByte_6 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 6);
                                devinfo1.SplitByte_7 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 7);
                            }
                            #endregion 贴标机
                        }
                        if (devinfo1.DeviceKind == 5)
                        {
                            #region 拆盘叠盘
                            States = GetDeviceState(devinfo1.DeviceIndex);
                            if (States == null) continue;

                            if (States[1] >= 30)
                            {
                                if (updateroute == true)
                                {//20100131
                                    UpdateErrorCode(devinfo1.DeviceIndex, States[1]);
                                    AlterRoute(devinfo1.DeviceIndex, States[1]);
                                }
                                //修改路径表
                                if (States[1] != devinfo1.ErrorCode)
                                {
                                    UpdateErrorCode(devinfo1.DeviceIndex, States[1]);
                                    AlterRoute(devinfo1.DeviceIndex, States[1]);
                                }
                                devinfo1.ErrorCode = States[1];
                                devinfo1.RunState = 2;
                            }
                            else if ((States[1] == 0) || (States[1] == 1) || (States[1] == 2))
                            {
                                if (updateroute == true)
                                {
                                    UpdateErrorCode(devinfo1.DeviceIndex, 0);
                                    AlterRoute(devinfo1.DeviceIndex, States[1]);
                                }
                                //修改路径表
                                if (States[1] != devinfo1.ErrorCode)
                                {
                                    UpdateErrorCode(devinfo1.DeviceIndex, 0);
                                    AlterRoute(devinfo1.DeviceIndex, States[1]);
                                }
                                if (States[1] == 2)
                                {
                                    devinfo1.RunState = 5;
                                }
                                else
                                {
                                    devinfo1.RunState = States[1];
                                }
                                devinfo1.ErrorCode = States[1];
                            }
                            devinfo1.TaskNo = States[2];

                            if (devinfo1.SplitByte != -1)
                            {
                                devinfo1.SplitByte_0 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 0);
                                devinfo1.SplitByte_1 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 1);
                                devinfo1.SplitByte_2 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 2);
                                devinfo1.SplitByte_3 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 3);
                                devinfo1.SplitByte_4 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 4);
                                devinfo1.SplitByte_5 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 5);
                                devinfo1.SplitByte_6 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 6);
                                devinfo1.SplitByte_7 = GetDevicePhotoelectric(devinfo1.DeviceIndex, 7);
                            }
                            #endregion 拆盘叠盘
                        }
                        if (devinfo1.DeviceKind == 1)
                        {
                            #region 堆垛机
                            States = GetDeviceState(devinfo1.DeviceIndex);
                            if (States == null) continue;
                            //堆垛机报异常
                            if (States[1] >= 30)
                            {
                                #region
                                if (updateroute == true)
                                {
                                    UpdateErrorCode(devinfo1.DeviceIndex, States[1]);
                                    AlterRoute(devinfo1.DeviceIndex, States[1]);
                                }
                                //修改路径表
                                if (States[1] != devinfo1.ErrorCode)
                                {
                                    //20100131
                                    UpdateErrorCode(devinfo1.DeviceIndex, States[1]);
                                    AlterRoute(devinfo1.DeviceIndex, States[1]);
                                }
                                devinfo1.ErrorCode = States[1];
                                devinfo1.RunState = 2;
                                #endregion 堆垛机
                            }
                            else if ((States[1] == 0) || (States[1] == 1) || (States[1] == 2))
                            {
                                if (updateroute == true)
                                {//20100131
                                    UpdateErrorCode(devinfo1.DeviceIndex, 0);
                                    AlterRoute(devinfo1.DeviceIndex, States[1]);
                                }
                                //修改路径表
                                if (States[1] != devinfo1.ErrorCode)
                                {
                                    //20100131
                                    UpdateErrorCode(devinfo1.DeviceIndex, 0);
                                    AlterRoute(devinfo1.DeviceIndex, States[1]);
                                }
                                if (States[1] == 2)
                                {
                                    devinfo1.RunState = 5;//动作完成
                                }
                                else
                                {
                                    devinfo1.RunState = States[1];
                                }
                                devinfo1.ErrorCode = States[1];
                            }
                            devinfo1.TaskNo = States[2];
                            devinfo1.XCoor = States[3];
                            devinfo1.YCoor = States[4];
                            #endregion 根据设备类型 更新设备实时信息 更新错误状态与路径信息
                        }
                        #endregion 循环所有设备 0表示空闲；-1表示停用

                        #region 设备是否逻辑有物 当前位置
                        int bdv = 0, bdov = 0;
                        string[] DS; char[] dd = new char[1] { '.' };
                        int devicebyte = 0; int devbit = 0;

                        if (devinfo1.BindingDevice != null)
                        {
                            DS = devinfo1.BindingDevice.Split(dd);
                            int.TryParse(DS[0], out devicebyte);
                            int.TryParse(DS[1], out devbit);
                            bdv = GetDevicePhotoelectric(devicebyte, devbit);
                        }
                        if (devinfo1.BindingDeviceOut != null)
                        {
                            DS = devinfo1.BindingDeviceOut.Split(dd);
                            int.TryParse(DS[0], out devicebyte);
                            int.TryParse(DS[1], out devbit);
                            bdov = GetDevicePhotoelectric(devicebyte, devbit);
                        }
                        if ((bdv + bdov) >= 1)
                        {
                            devinfo1.HaveGoods = true;//dzf 运行时鼠标点控件的出现的属性 有物 条码 等在这赋值
                        }
                        else
                        {
                            devinfo1.HaveGoods = false;
                        }

                        DataView dvb = DbHelperSQL.Query("SELECT F_MonitorIndex,F_NumParam1,F_NumParam2,F_NumParam3,F_NumParam4,F_NumParam5,F_NumParam6, F_TxtParam FROM T_Monitor_Task WHERE (F_MonitorIndex = " + devinfo1.TaskNo + ")").Tables[0].DefaultView;
                        if (dvb.Count > 0)
                        {
                            if (devinfo1.DeviceKind == 1)
                            {
                                devinfo1.ArrowLocation = dvb[0]["F_NumParam4"].ToString() + "排" + dvb[0]["F_NumParam5"].ToString() + "列" + dvb[0]["F_NumParam6"].ToString() + "层";
                            }
                            if (devinfo1.DeviceKind == 2)
                            {
                                devinfo1.ArrowLocation = dvb[0]["F_NumParam4"].ToString();
                            }
                            devinfo1.Barcode = dvb[0]["F_TxtParam"].ToString();
                        }
                        else
                        {
                            devinfo1.Barcode = "";
                            devinfo1.ArrowLocation = "";
                        }
                        dvb = null;
                        #endregion 设备是否逻辑有物 当前位置
                    }
                    //更新内存中的设备信息
                    BaseDeviceService.SetDeviceInfo(devinfo1);
                    //LogUtil.WriteLog("", "解析PLC主方法CParsePLCData:" + devinfo1.DeviceIndex);
                    //距离上次循环超过3秒 更新设备运行状态
                    if (reportstatus == true)
                    {
                        #region 1堆垛机2输送线3滑块模组5叠拆盘机
                        if (devinfo1.DeviceKind == 1 || devinfo1.DeviceKind == 2 || devinfo1.DeviceKind == 3 || devinfo1.DeviceKind == 5)
                        {
                            int CurRunState = 0;
                            if (devinfo1.RunState == 0 || devinfo1.RunState == 5)
                            {
                                CurRunState = 0;
                            }
                            else if (devinfo1.RunState == 4)
                            {
                                CurRunState = 3;
                            }
                            else
                            {
                                CurRunState = devinfo1.RunState;
                            }
                            try
                            {
                                #region 上报设备状态和当前时间 逻辑有物
                                string dtime = DateTime.Now.ToString("u");
                                dtime = dtime.Substring(0, dtime.Length - 1);
                                dtime = dtime.Substring(0, dtime.Length - 1);
                                string sql = "";
                                if (DbHelperSQL.Exists(string.Format("select DEVICE_CODE from DEVICE_MONITOR where DEVICE_CODE ={0} ", devinfo1.DeviceIndex)))
                                {
                                    sql = string.Format("Update DEVICE_MONITOR set DEVICE_CUR_STATUS={0},UPDATE_TIME='{1}',HAVE_GOODS={3} where DEVICE_CODE ={2}", CurRunState, dtime, devinfo1.DeviceIndex, devinfo1.HaveGoods ? 1 : 0);
                                }
                                else
                                {
                                    sql = string.Format("insert into DEVICE_MONITOR  (DEVICE_CUR_STATUS,UPDATE_TIME,HAVE_GOODS,DEVICE_CODE) values({0},'{1}',{3},{2})", CurRunState, dtime, devinfo1.DeviceIndex, devinfo1.HaveGoods ? 1 : 0);
                                }
                                DbHelperSQL.ExecuteSql(sql);
                                devinfo1.LastRunState = CurRunState;
                                BaseDeviceService.SetDeviceLastRunState(devinfo1);
                                #endregion 上报设备状态和当前时间 逻辑有物
                            }
                            catch (Exception ex)
                            {
                                _CParsePLCError = string.Format("上报设备{0}的设备状态时发生错误:{1}", devinfo1.DeviceIndex, ex.Message);
                            }
                        }
                        #endregion 1堆垛机2输送线3滑块模组5叠拆盘机
                    }
                    #endregion
                }
            }
            catch (Exception exa)
            {
                _CParsePLCError = "解析PLC反馈数据的记录设备状态时发生错误：" + exa.Message;
            }
        }

        /// <summary>
        /// 取得指定光电开关（确认按钮）设备索引的信号（0，1）
        /// </summary>
        /// <param name="deviceIdx">设备索引</param>
        /// <returns>0，1</returns>
        public static int GetDevicePhotoelectric(int deviceIdx)
        {
            try
            {
                if (devinfo28.DeviceKind == 28)
                {
                    if (CStaticClass.AllReturns != null)
                    {
                        #region 获取开关量的值

                        DataView dvle = DbHelperSQL.Query("SELECT F_DeviceIndex, F_DeviceKindIndex,F_DBWGetLength," +
                            " F_DBW2Address FROM T_Base_Device WHERE ((F_DeviceKindIndex = 14)" +
                            " OR (F_DeviceKindIndex = 18)) and (F_DBW2Address is not NULL) and F_DeviceIndex=" + deviceIdx + "").Tables[0].DefaultView;

                        int glen = 0;
                        int IfVis = 0;
                        if (dvle.Count > 0)
                        {
                            int temp = Convert.ToInt32(dvle[0]["F_DBW2Address"]) - devinfo28.Dbw2Address;
                            if (Convert.ToInt32((Convert.ToDecimal(dvle[0]["F_DBWGetLength"]) * 8 - 1)) > 7)//devinfo.Dbw2Getlength
                            {
                                glen = Convert.ToInt32((Convert.ToDecimal(dvle[0]["F_DBWGetLength"]) * 8 - 1)) - 8;
                                temp = temp + 1;
                            }
                            else
                            {
                                glen = Convert.ToInt32((Convert.ToDecimal(dvle[0]["F_DBWGetLength"]) * 8 - 1));
                            }
                            if (temp >= 0)
                            {
                                IfVis = CCarryConvert.GetBitFromInteger(CStaticClass.AllReturns[temp], glen);
                                return IfVis;
                            }
                            else
                            {
                                return -1;
                            }
                        }
                        else
                        {
                            return -1;
                        }
                        #endregion
                    }
                    else
                    {
                        return -1;
                    }
                }
                else
                {
                    return -1;
                }
            }
            catch
            {
                return -1;
            }
        }

        /// <summary>
        /// 20101118根据设备号和bit位，取得F_SplitByte里的光电bit值：0,1
        /// </summary>
        /// <param name="deviceIdx"></param>
        /// <param name="bit"></param>
        /// <returns></returns>
        public static int GetDevicePhotoelectric(int deviceIdx, int abit)
        {
            try
            {
                if (devinfo28.DeviceKind == 28)
                {
                    if (CStaticClass.AllReturns != null)
                    {
                        #region 获取开关量的值

                        DataView dvle = new DataView();
                        try
                        {
                            dvle = DbHelperSQL.Query("SELECT F_SplitByte  FROM T_Base_Device WHERE  F_DeviceIndex=" + deviceIdx + " and F_SplitByte>=0").Tables[0].DefaultView;
                        }
                        catch (Exception e)
                        {
                            FrmControlMonitor.FormInstance.FlashPanit("tsStatus", e.Message + "\r\n", true);
                        }
                        int glen = 0;
                        int IfVis = 0;
                        if (dvle.Count > 0)
                        {
                            int temp = Convert.ToInt32(dvle[0]["F_SplitByte"]) - devinfo28.Dbw2Address;
                            if (abit > 7)
                            {
                                glen = abit - 8;
                                temp = temp + 1;
                            }
                            else
                            {
                                glen = abit;
                            }
                            if (temp >= 0)
                            {
                                if (temp!=305)
                                {
                                    IfVis = CCarryConvert.GetBitFromInteger(CStaticClass.AllReturns[temp], glen);
                                }
                                return IfVis;
                            }
                            else
                            {
                                return -1;
                            }
                        }
                        else
                        {
                            return -1;
                        }
                        #endregion
                    }
                    else
                    {
                        return -1;
                    }
                }
                else
                {
                    return -1;
                }
            }
            catch
            {
                return -1;
            }
        }

        /// <summary>
        /// 20101118根据设备号和bit位，取得F_SplitByte里的光电bit值：0,1
        /// </summary>
        /// <param name="deviceIdx"></param>
        /// <param name="bit"></param>
        /// <returns></returns>
        public static int GetDevicePhotoelectric(Model.MDevice deviceinfo, int abit)
        {
            try
            {
                if (devinfo28.DeviceKind == 28)
                {
                    if (CStaticClass.AllReturns != null)
                    {
                        #region 获取开关量的值
                        int glen = 0;
                        int IfVis = 0;
                        if (deviceinfo.SplitByte > 0)
                        {
                            int temp = Convert.ToInt32(deviceinfo.SplitByte) - devinfo28.Dbw2Address;
                            if (abit > 7)
                            {
                                glen = abit - 8;
                                temp = temp + 1;
                            }
                            else
                            {
                                glen = abit;
                            }
                            if (temp >= 0)
                            {
                                IfVis = CCarryConvert.GetBitFromInteger(CStaticClass.AllReturns[temp], glen);
                                return IfVis;
                            }
                            else
                            {
                                return -1;
                            }
                        }
                        else
                        {
                            return -1;
                        }
                        #endregion
                    }
                    else
                    {
                        return -1;
                    }
                }
                else
                {
                    return -1;
                }
            }
            catch
            {
                return -1;
            }
        }

        /// <summary>
        /// 取得指定设备索引的设备状态:[0]读写标志;[1]状态;[2]任务号；[3]X坐标;[4]Y坐标;[5]设备索引
        /// </summary>
        /// <param name="deviceIdx">设备索引</param>
        /// <returns></returns>
        public static int[] GetDeviceState(int deviceIdx)
        {
            try
            {
                if (devinfo28.DeviceKind == 28)
                {
                    if (CStaticClass.AllReturns != null)
                    {
                        #region 获取设备状态
                        DataView dvle = DbHelperSQL.Query("SELECT F_DeviceIndex, F_DeviceKindIndex,F_DBWGetLength," +
                            " F_DBW2Address FROM T_Base_Device WHERE (F_DBW2Address is not NULL) and F_DeviceIndex=" + deviceIdx + "").Tables[0].DefaultView;
                        if (dvle.Count > 0)
                        {
                            int temp = Convert.ToInt32(dvle[0]["F_DBW2Address"]) - devinfo28.Dbw2Address;//devinfo.Dbw2Address
                            decimal glen = Convert.ToDecimal(dvle[0]["F_DBWGetLength"]);//devinfo.Dbw2Getlength
                            int[] states = new int[6];
                            switch (dvle[0]["F_DeviceKindIndex"].ToString())//devinfo.DeviceKind.ToString()
                            {
                                #region 设备类型 获取设备信息
                                case "1"://堆垛机
                                    states[0] = CStaticClass.AllReturns[temp];//读写标志
                                    states[1] = CStaticClass.AllReturns[temp + 1];//状态
                                    states[2] = (CStaticClass.AllReturns[temp + 2] << 8) + CStaticClass.AllReturns[temp + 3];//任务号
                                    states[3] = CStaticClass.AllReturns[temp + 7] + (CStaticClass.AllReturns[temp + 6] << 8) + (CStaticClass.AllReturns[temp + 5] << 16) + (CStaticClass.AllReturns[temp + 4] << 32);//X坐标
                                    states[4] = CStaticClass.AllReturns[temp + 11] + (CStaticClass.AllReturns[temp + 10] << 8) + (CStaticClass.AllReturns[temp + 9] << 16) + (CStaticClass.AllReturns[temp + 8] << 32);//Y坐标
                                    states[5] = deviceIdx;//设备号索引
                                    break;

                                case "2"://输送机
                                    states[0] = CStaticClass.AllReturns[temp];//读写标志
                                    states[1] = CStaticClass.AllReturns[temp + 1];//状态
                                    states[2] = (CStaticClass.AllReturns[temp + 2] << 8) + CStaticClass.AllReturns[temp + 3];//任务号
                                    states[3] = 0;
                                    states[4] = 0;
                                    states[5] = deviceIdx;//设备号索引
                                    break;

                                case "5"://拆盘机和叠盘机
                                    states[0] = CStaticClass.AllReturns[temp];//读写标志
                                    states[1] = CStaticClass.AllReturns[temp + 1];//状态
                                    states[2] = (CStaticClass.AllReturns[temp + 2] << 8) + CStaticClass.AllReturns[temp + 3];
                                    states[3] = (CStaticClass.AllReturns[temp + 4] << 8) + CStaticClass.AllReturns[temp + 5];
                                    states[4] = 0;
                                    states[5] = deviceIdx;//设备号索引
                                    break;

                                case "32"://拣选模组
                                    states[0] = CStaticClass.AllReturns[temp];//读写标志
                                    states[1] = CStaticClass.AllReturns[temp + 1];//状态
                                    states[2] = (CStaticClass.AllReturns[temp + 2] << 8) + CStaticClass.AllReturns[temp + 3];//任务号
                                    states[3] = 0;
                                    states[4] = 0;
                                    states[5] = deviceIdx;//设备号索引
                                    break;

                                case "33"://贴标机
                                    states[0] = CStaticClass.AllReturns[temp];//读写标志
                                    states[1] = CStaticClass.AllReturns[temp + 1];//状态
                                    states[2] = (CStaticClass.AllReturns[temp + 2] << 8) + CStaticClass.AllReturns[temp + 3];//任务号
                                    states[3] = CStaticClass.AllReturns[temp + 5];//贴标位置
                                    states[4] = (CStaticClass.AllReturns[temp + 6] << 8) + CStaticClass.AllReturns[temp + 7];
                                    states[5] = deviceIdx;//设备号索引
                                    break;

                                case "34"://AGV
                                    states[0] = CStaticClass.AllReturns[temp];//读写标志
                                    states[1] = CStaticClass.AllReturns[temp + 1];//状态
                                    states[2] = (CStaticClass.AllReturns[temp + 2] << 8) + CStaticClass.AllReturns[temp + 3];//任务号
                                    states[3] = 0;
                                    states[4] = 0;
                                    states[5] = deviceIdx;//设备号索引
                                    break;
                                    #endregion
                            }
                            return states;
                        }
                        else
                        {
                            return null;
                        }
                        #endregion
                    }
                    else
                    {
                        return null;
                    }
                }
                else
                {
                    return null;
                }
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 修改本地路径表、反馈给管理的路径表以及提出修改申请
        /// </summary>
        /// <param name="devInx">发生故障的设备索引</param>
        /// <returns></returns>
        public static bool AlterRoute(int devInx, int state)
        {
            //string ss1 = DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();
            try
            {
                DataView dv = DbHelperSQL.Query("select distinct F_RouteID from T_Base_Route_Device where F_DeviceIndex=" + devInx).Tables[0].DefaultView;
                for (int i = 0; i < dv.Count; i++)
                {
                    if (state >= 30)
                    {
                        #region
                        //所有子路径都不可用时，方才设定此路径真的不可用
                        string sql = " SELECT T_Base_Route_Device.F_RouteIDSub, SUM(T_Base_Device.F_ErrorCode) AS ErrorCodes " +
                                    " FROM T_Base_Route_Device,T_Base_Device where T_Base_Route_Device.F_DeviceIndex = T_Base_Device.F_DeviceIndex" +
                                    " and T_Base_Route_Device.F_RouteID=" + dv[i]["F_RouteID"] + " GROUP BY T_Base_Route_Device.F_RouteIDSub ";
                        DataView dvr = DbHelperSQL.Query(sql).Tables[0].DefaultView;
                        bool ifUsable = false;
                        for (int kk = 0; kk < dvr.Count; kk++)
                        {
                            if (Convert.ToInt32(dvr[kk]["ErrorCodes"]) <= 0)
                            {
                                ifUsable = true;
                                break;
                            }
                        }
                        if (ifUsable == false)
                        {
                            int ups = DbHelperSQL.ExecuteSql("update t_base_route set F_Status=0 where f_routeid=" + dv[i]["F_RouteID"] + " and F_Status=1 and F_AutoUpdate=1 ");
                        }
                        #endregion
                    }
                    else
                    {
                        #region 设备无错误 更新路径路径 状态：1可用；0有设备发生故障禁止使用
                        DataView dv1 = DbHelperSQL.Query("SELECT SUM(T_Base_Device.F_ErrorCode) as errcode FROM T_Base_Device ,T_Base_Route_Device" +
                            " where T_Base_Device.F_DeviceIndex = T_Base_Route_Device.F_DeviceIndex and T_Base_Route_Device.F_RouteID=" + dv[i]["F_RouteID"]).Tables[0].DefaultView;
                        if (dv1.Count > 0)
                        {
                            int errcode = 0;
                            if (Microsoft.VisualBasic.Information.IsNumeric(dv1[0]["errcode"]) == true)
                            {
                                errcode = Convert.ToInt32(dv1[0]["errcode"]);
                            }
                            if (errcode <= 0)
                            {
                                //20101011
                                int ups = DbHelperSQL.ExecuteSql("update t_base_route set F_Status=1 where f_routeid=" + dv[i]["F_RouteID"] + " and F_Status=0 and F_AutoUpdate=1 ");
                            }
                        }
                        #endregion
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                _CParsePLCError = "解析PLC反馈数据的修改路径时发生错误：" + ex.Message;
                return false;
            }
        }

        private static void UpdateErrorCode(int devInx, int errorCode)
        {
            DbHelperSQL.ExecuteSql("UPDATE T_Base_Device SET F_ErrorCode = " + errorCode + " WHERE (F_DeviceIndex = " + devInx + ")and (F_ErrorCode <> " + errorCode + ")");
        }
    }
}