using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.EnterpriseServices;
using System.Text;
using System.Data;
using System;
using CommLayerFactory;
using ICommLayer;
using DBFactory;

namespace ControlSystem
{
    
    /// <summary>
    /// Creator:Richard.liu
    /// 监控调度类
    /// </summary>
   
    public class CControl
    {
        private Object thisLock = new Object();
        DBOperator dbo =CStaticClass.dbo;
        DBOperator dboM = CStaticClass.dboM;
        Model.MError errs;
        Model.MDevice devinfo;
        ISendDeviceOrder sdo;
        CCommonFunction ccf = new CCommonFunction();
       // CGetState cgs = new CGetState();
        //CGetState gs = new CGetState();
        int _DeviceIdx = 0;//设备索引
        int _routeID = 0;//路径唯一索引
        int _serialNumber = 0;//路径上的设备方向性链表的序号
        int _ManageTaskIdx = 0;//调度任务索引
        int _ManageKindIdx = 0;//调度任务类型
        int _DeviceOrder = 0;//设备命令
        int _LockedState = 0;
        int _Associate = 0;
        int _ManTaskReserve = 0;
        string _AheadDetect = "";
        int _NumParam1=0;
        int _NumParam2 = 0;
        int _NumParam3 = 0;
        int _NumParam4 = 0;
        int _NumParam5 = 0;
        int _NumParam6 = 0;
        string _TxtParam = "-";
        int _DeviceKind = 0;
        int _OutsideAltDevice = 0;
        int _InsideAltDevice = 0;
        int _StartDevice = 0;
        int _EndDevice = 0;
        int _RouteKind = 0;
        int _CorrelDoubleFork = -1;
        //int _UseAwayFork = 1;
        int _AgvNo = 65535;
        string _CControlError = "";//监控调度类错误说明
        //20110329
        int LastMachine = 0;//上一次叠盘输送机
        int RightUseTimes = 0;//12049
        int LeftUseTimes = 0;//12054

        public string CControlError
        {
            get { return _CControlError; }
            set { _CControlError = value; }
        }

        public CControl()
        {
            //dbo.Open();
        }
        //~CControl()
        //{
        //    dbo.Close();
        //}
        public void StartOrder()
        {
           
            //首先检测第一个调度任务单的“第一个”（所有剩下中的第一个）设备是否被占用，被占用则执行下一个调度任务单；
            //然后检测第一个设备的F_AheadDetect都是否满足条件，不满足，则执行下一个调度任务单；
            //最后开始执行时检查同步运行的关联设备F_AssociateDeviceIndex,准备给该设备发指令；
            //更改作业记录的状态F_Status为1,更改设备为占用状态（T_Base_device的F_LockedState=设备指令单）
            //给调度任务表回写调度任务IO_Control的正在执行状态FSTATUS=1;T_Manage_Task的正在执行状态FSTATUS=1
            //路径明细表F_LockedDeviceIndex里的所有对应设备索引加锁，但是关联设备不加锁
            string  taskkind =string.Empty ;
            
            try
            {
                
                if (CStaticClass.AutoOrder == true)
                {
                    taskkind = " (F_ManageTaskKindIndex = 1 or F_ManageTaskKindIndex = 2 or F_ManageTaskKindIndex = 4) "; //调度任务与调度生成的自动任务
                    
                }
                else
                {
                    if (FrmControlMonitor.FormInstance.GetObjectText("tsStatus").IndexOf(_CControlError) < 0)
                    {
                        
                        FrmControlMonitor.FormInstance.FlashPanit("tsStatus", _CControlError, true);
                    }
                    return;
                }

                DataView dvM = new DataView();
                string strM = "";
                char[] sep = new char[1] { '-' };
                string aa = DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();
                //获得管理单据
                string strsql = "SELECT DISTINCT F_ManageTaskIndex AS MIndex,F_MonitorTaskLevel,F_ManageTaskKindIndex FROM T_Monitor_Task where " +
                    taskkind + " order by F_ManageTaskKindIndex desc, F_MonitorTaskLevel desc, F_ManageTaskIndex asc";
                
                DataView dv =  dbo.ExceSQL(strsql).Tables[0].DefaultView;
                if (dv.Count > 0)
                {
                    for (int i = 0; i < dv.Count; i++)
                    {
                        try
                        {
                            //1：提取每个管理单据的第一个设备指令 
                            strM = "select top 1  min(F_MonitorIndex) as minMidx,f_status from T_Monitor_Task where " + taskkind + " and F_ManageTaskIndex = " + dv[i]["MIndex"] + " GROUP BY F_MonitorIndex, F_Status";
                            dvM = dbo.ExceSQL(strM).Tables[0].DefaultView;
                            if (dvM.Count > 0 && dvM[0]["minMidx"] != DBNull.Value)
                            {

                                if (dvM[0]["F_Status"].ToString() == "0")
                                {
                                    SendMonitorTask(Convert.ToInt32(dvM[0]["minMidx"]));
                                }
                                else
                                {
                                    continue;
                                }
                                
                            }
                            else
                            {
                                continue;
                            }
                        }
                        catch(Exception ex)
                        {
                            _CControlError = "发送命令时："+ex.Message ;
                        }
                        
                    }//for语句结束
                    //20091107
                    
                    dv = null;
                    
                    dvM = null;
                    
                    return  ;
                }
                else
                {
                    //20091107
                    
                    dv = null;
                    
                    dvM = null;
                    //_CControlError = "没有命令可以执行！";
                    if (FrmControlMonitor.FormInstance.GetObjectText("tsStatus").IndexOf(_CControlError) < 0)
                    {
                        FrmControlMonitor.FormInstance.FlashPanit("tsStatus",_CControlError,true );
                    }
                    return;
                }
                
                
            }
            catch (Exception ex)
            {
                
                throw ex;
            }
        }
        /// <summary>
        /// 提取每个管理单据的第一个设备是否被锁定,true表示被锁定；false表示空闲
        /// </summary>
        /// <param name="minMidx">调度任务号</param>
        /// <returns>true表示被锁定；false表示空闲</returns>
        public bool GetFirstDeviceIFLocked(int minMidx, bool checkLockedstate)
        {
            char[] sep = new char[1] { '-' };
            int msgIdx = 0;//消息编号
            int adidx = 0;//关联设备的设备指令索引
            DataView dv;
            try
            {

                //获得要发送的信息
                if (GetSendInfo(minMidx) == false) { return true; }

                int DeviceIdx = _DeviceIdx;//设备索引
                int routeID = _routeID;//路径唯一索引
                int serialNumber = _serialNumber;//路径上的设备方向性链表的序号
                int ManageTaskIdx = _ManageTaskIdx;//调度任务索引
                int ManageKindIdx = _ManageKindIdx;//调度任务类型
                int DeviceOrder = _DeviceOrder;//设备命令
                int LockedState = _LockedState;
                int Associate = _Associate;
                int ManTaskReserve = _ManTaskReserve;
                string AheadDetect = _AheadDetect;
                int NumParam1 = _NumParam1;
                int NumParam2 = _NumParam2;
                int NumParam3 = _NumParam3;
                int NumParam4 = _NumParam4;
                int NumParam5 = _NumParam5;
                int NumParam6 = _NumParam6;
                string TxtParam = _TxtParam;
                int DeviceKind = _DeviceKind;
                int OutsideAltDevice = _OutsideAltDevice;
                int InsideAltDevice = _InsideAltDevice;
                int StartDevice = _StartDevice;
                int EndDevice = _EndDevice;
                int RouteKind = _RouteKind;
                int AgvNo = _AgvNo;


                #region 设备故障时是否自动改道
                
                if (CStaticClass.DeviceErrorAutoModifyRoutePath == "1")
                {//20100108
                    #region 只针对与RGV有关的五个动作判断改路径
                    //20100108 输送机的接货对接指令不参与改道
                    if ((_DeviceKind == 4) || ((_DeviceKind == 2) && ((_DeviceOrder == 3))) && (RouteKind != 3))
                    {
                        bool IfModify = false, IfUseNegativeDevice = false;//20100610
                        //20091102 RGV的第一个被提前触发的运动指令不需要更改路径
                        if ((_DeviceKind == 4) && (_DeviceOrder == 7) &&
                            (ccf.GetSerialNumberFromRouteDevice(_routeID, _DeviceIdx) >
                            ccf.GetSerialNumberFromRouteDevice(_routeID, _NumParam1)))
                        {
                            dv = dbo.ExceSQL("SELECT MIN(F_MonitorIndex) AS mmi FROM dbo.T_Monitor_Task WHERE (F_ManageTaskIndex = " + ManageTaskIdx + ") AND (F_ManageTASKKINDINDEX = 1)").Tables[0].DefaultView;
                            if (dv.Count > 0)
                            {
                                //20091218

                                if ((dv[0]["mmi"] != DBNull.Value) && (dv[0]["mmi"].ToString() == minMidx.ToString()))
                                {
                                    IfModify = true;
                                    IfUseNegativeDevice = true;//20100610
                                }
                            }
                            
                        }
                        else if ((_DeviceKind == 4) && ((_DeviceOrder == 3) || (_DeviceOrder == 5)))
                        {//20100108对穿梭车送货对接应该加于限制，载货，空闲
                            devinfo = Model.CGetInfo.DeviceInfo[DeviceIdx];
                            if ((devinfo.RunState == 0) && (devinfo.HaveGoods == true))
                            {
                                IfModify = true;
                                IfUseNegativeDevice = false;//20100610
                            }
                            devinfo = null;
                        }
                        else
                        {
                            IfModify = true;
                            IfUseNegativeDevice = true;//20100610

                        }



                        if (IfModify == true)
                        {
                            int altsn = ccf.GetSerialNumberFromRouteDevice(_routeID, _OutsideAltDevice);
                            string sql = "SELECT F_SerialNumber FROM T_Base_Device,T_Base_Route_Device,T_Base_Device_State where " +
                            " T_Base_Device.F_DeviceIndex = T_Base_Route_Device.F_DeviceIndex and F_ErrorCode =F_DeviceErrorIndex and " +
                            " T_Base_Device_State.F_DeviceKindIndex = T_Base_Device.F_DeviceKindIndex AND T_Base_Device.F_ErrorCode > 0 AND " +
                            " T_Base_Route_Device.F_SerialNumber > " + _serialNumber + " AND T_Base_Route_Device.F_SerialNumber > " +
                            altsn + " AND T_Base_Route_Device.F_RouteIDSub = " + _routeID + " and F_ErrorLevel=2 ";
                            dv= dbo.ExceSQL(sql).Tables[0].DefaultView;
                            if (dv.Count > 0)
                            {
                                //判断能否改道;向管理申请改道;把ManageTaskIdx，ManageKindIdx 的调度任务全部申请改道
                                if (GetUsableDestination(_ManageTaskIdx, _ManageKindIdx) == true)
                                {
                                    
                                    return true;
                                }
                            }
                            #region RGV目标位置被占用需要申请改道
                            //20100610
                            devinfo = null;
                            if (_DeviceKind == 4)
                            {//RGV
                                devinfo = Model.CGetInfo.GetDeviceInfo(CDisassembleTask.GetNextDevice(_routeID, _serialNumber)[0]);
                            }
                            else
                            {//输送机送货
                                devinfo = Model.CGetInfo.GetDeviceInfo(CDisassembleTask.GetNextDevice(_routeID, _serialNumber)[0]);//RGV
                                int sn = 0;
                                if (devinfo != null)
                                {
                                    sn = ccf.GetSerialNumberFromRouteDevice(_routeID, devinfo.DeviceIndex);
                                }
                                devinfo  = Model.CGetInfo.GetDeviceInfo(CDisassembleTask.GetNextDevice(_routeID, sn)[0]);//接货输送机
                                
                            }
                            if (devinfo != null)
                            {
                                if (devinfo.HaveGoods == true)
                                {//目标位置被占用，申请改道
                                    if (GetRGVIdleDestination(_ManageTaskIdx, _ManageKindIdx, devinfo.DeviceIndex, IfUseNegativeDevice) == true)
                                    {
                                        return true;
                                    }
                                }
                            }
                            #endregion
                        }
                        
                    }
                    #endregion

                }

                #endregion


                //判断F_PriorMonitor的值是否存在，存在就不允许执行。
                //sql = "SELECT T_Monitor_Task.F_MonitorIndex FROM T_Monitor_Task,T_Monitor_Task T_Monitor_Task_1 WHERE "+
                //    " T_Monitor_Task.F_PriorMonitor = T_Monitor_Task_1.F_MonitorIndex AND (T_Monitor_Task.F_PriorMonitor IS NOT NULL)";
                //dv = dbo.ExceSQL(sql).Tables[0].DefaultView;
                //if (dv.Count > 0)
                //{
                //    return true;
                //}

                
                if (_DeviceIdx == 1001)
                {//20100512 AGV
                    if (AgvNo != 65535)//如果是已经分配车号的AGV命令，检查这个车号对应的设备索引是否被锁定
                    {
                        LockedState = Convert.ToInt32(dbo.GetSingle("SELECT F_LockedState FROM T_Base_Device where F_DeviceIndex="+(1001+AgvNo)+""));
                        if(LockedState>0)return true;
                    }
                    if (AheadDetectOK(minMidx, _AheadDetect) == true)//提前检测通过
                    {
                        #region 双叉AGV检测，能同步的关联任务是否AheadDetectOK
                        //20100323
                        devinfo = Model.CGetInfo.GetDeviceInfo(_DeviceIdx);
                        if (devinfo.IfCorrelDoubleFork == "1")
                        {
                            if (Model.CGeneralFunction.DoubleForkIfSync(minMidx, _DeviceIdx, _DeviceKind) == true)
                            {
                                string[] df = Model.CGeneralFunction.GetDoubleForkMonitorInfo(minMidx, _DeviceIdx);
                                if (df != null)
                                {
                                    if (AheadDetectOK(Convert.ToInt32(df[0]), df[1]) == false)//双叉关联提前检测失败
                                    {
                                        return true;
                                    }
                                    #region 关联指令不是第一个指令不能发送
                                    int rmankind = Model.CGeneralFunction.GetManageTaskKindIndexFromMonitor(Convert.ToInt32(df[0]));
                                    int rman = Model.CGeneralFunction.GetManageTaskIndexfromMonitor(Convert.ToInt32(df[0]));
                                    dv = dbo.ExceSQL("SELECT MIN(F_MonitorIndex) AS mmi FROM dbo.T_Monitor_Task WHERE (F_ManageTaskIndex = " + rman + ") AND (F_ManageTASKKINDINDEX = " + rmankind + ")").Tables[0].DefaultView;
                                    if (dv.Count > 0)
                                    {
                                        if ((dv[0]["mmi"] != DBNull.Value) && (dv[0]["mmi"].ToString() != df[0]))
                                        {
                                            return true;
                                        }
                                    }
                                    #endregion
                                }

                            }
                            
                        }
                        #endregion

                        return false;
                    }
                    else
                    {
                        return true;
                    }
                }
                else
                {
                    //第一个设备是否被占用，RGV和堆垛机要考虑分步控制时，没执行完连续动作时不接受新的调度任务

                    if (((_LockedState == 0) && (checkLockedstate == true)) || (checkLockedstate == false))
                    {

                        #region 检查RGV、堆垛机等是否被调度任务预约F_ManTaskReserve

                        if (_ManTaskReserve > 0)
                        {
                            devinfo = Model.CGetInfo.GetDeviceInfo(_DeviceIdx);
                            if (devinfo.IfCorrelDoubleFork == "1")
                            {
                                string[] df = Model.CGeneralFunction.GetDoubleForkMonitorInfo(minMidx, _DeviceIdx);
                                if (df != null)
                                {
                                    int rman = Model.CGeneralFunction.GetManageTaskIndexfromMonitor(Convert.ToInt32(df[0]));
                                    int rmankind = Model.CGeneralFunction.GetManageTaskKindIndexFromMonitor(Convert.ToInt32(df[0]));
                                    if ((_ManTaskReserve.ToString() != _ManageKindIdx.ToString() + _ManageTaskIdx.ToString()) && (_ManTaskReserve.ToString() != rmankind.ToString() + rman.ToString()))
                                    {
                                        return true;
                                    }
                                }
                                else//20100702修正关联任务被删除时的预约锁
                                {
                                    object rob = dbo.GetSingle("SELECT F_RELATIVECONTORLID FROM T_Manage_Task WHERE (F_ManageTaskKindIndex = "+_ManageKindIdx+") AND (FID = "+_ManageTaskIdx+") AND (F_RELATIVECONTORLID <> - 1)");
                                    string rlres = string.Empty ;
                                    if (rob != null)
                                    {
                                        rlres = _ManageKindIdx.ToString() + rob.ToString();
                                    }
                                    else
                                    {
                                        rob = dbo.GetSingle("SELECT FID FROM T_Manage_Task WHERE (F_ManageTaskKindIndex = " + _ManageKindIdx + ") AND (F_RELATIVECONTORLID = " + _ManageTaskIdx + ") ");
                                        if (rob != null)
                                        {
                                            rlres = _ManageKindIdx.ToString() + rob.ToString();
                                        }
                                    }
                                    if ((_ManTaskReserve.ToString() != _ManageKindIdx.ToString() + _ManageTaskIdx.ToString())&&(_ManTaskReserve.ToString() !=rlres))
                                    {
                                        return true;
                                    }
                                }
                                
                            }
                            else
                            {
                                if (_ManTaskReserve.ToString() != _ManageKindIdx.ToString() + _ManageTaskIdx.ToString())
                                {
                                    return true;
                                }
                            }
                            
                        }


                        #endregion

                        #region 判断穿梭车的运动到3215的指令是否触发3215-3213
                        //if ((_DeviceIdx == 3301) && (_DeviceOrder == 7) && ((_NumParam1 != 3215) && (_NumParam1 != 3233)))
                        //{
                        //    DataView dvma = dbo.ExceSQL("select FID, F_ManageTaskKindIndex,FENDDEVICE from T_Manage_Task where F_ManageTaskKindIndex=" +
                        //        ccf.GetManageTaskKindIndexFromMonitor(minMidx) + " and fid=" + ccf.GetManageTaskIndexfromMonitor(minMidx)
                        //        + " and FENDDEVICE=3215").Tables[0].DefaultView;
                        //    if (dvma.Count > 0)
                        //    {
                        //        int startdev = 3215;
                        //        int dcode = 3213;
                        //        if (CStaticClass.GetDevicePhotoelectric(32151) == 1)
                        //        {
                        //            DataView dv11 = dbo.ExceSQL("select FSTARTDEVICE,FENDDEVICE from T_Manage_Task where FSTARTDEVICE=" + startdev + " and FENDDEVICE=" + dcode + "").Tables[0].DefaultView;
                        //            if (dv11.Count <= 0)
                        //            {
                        //                int fid = ccf.GetTempManageIdx();
                        //                //ccf.RecordMaxTempManageTaskFID(fid);
                        //                string warehouse = "13";
                        //                DataView dvw = dbo.ExceSQL("SELECT F_WarehouseIndex  FROM T_Warehouse").Tables[0].DefaultView;
                        //                if (dvw.Count > 0)
                        //                {
                        //                    warehouse = dvw[0]["F_WarehouseIndex"].ToString();
                        //                }

                        //                string sql = "INSERT INTO T_Manage_Task" +
                        //              "(FID, F_ManageTaskKindIndex,FPALLETBARCODE,FMANAGETASKTYPE,FCONTROLTASKTYPE, FTASKLEVEL, FISRETURN," +
                        //              "FWAREHOUSE, FSTARTCELL, FSTARTDEVICE, FENDDEVICE, FENDCELL, " +
                        //              "FSTATUS, FBEGTIME, FENDTIME,FIntoStepOK,FREMARK,FLANEWAY,FSTACK)" +
                        //              "VALUES (" + fid + ",2,'-','0','3','1','1','" + warehouse + "','-','"
                        //              + startdev + "','" + dcode + "','-',"
                        //              + "'0','-','-','0','',0,0)";

                        //                dbo.ExceSQL(sql);
                        //            }
                        //        }
                        //    }
                        //}
                        #endregion

                        #region 检查是否有阻挡设备和命令

                        ////3.5检查是否有阻挡设备和命令
                        //BlockDevice = ccf.GetBlockDevice(_DetailIndex);
                        //if ((BlockDevice != null) && (BlockDevice!= ""))
                        //{
                        //    split = BlockDevice.Split(sep);
                        //    adidx = GetMonitorTaskIndex(Convert.ToInt32(split[0]), Convert.ToInt32(split[1]));

                        //    //6：发送阻挡设备和命令
                        //    //CStaticClass.MessageIndex++;
                        //    CStaticClass.MessageIndex = 1;
                        //    msgIdx = (CStaticClass.MessageIndex);
                        //    sdo = CommModeCreate.CreateSendDeviceOrder(Convert.ToInt32(split[1]));
                        //    //判断是否为堆垛机设备
                        //    bool sendok;
                        //    if ((ccf.GetDeviceKindIdx(Convert.ToInt32(split[0])) == 1) || (ccf.GetDeviceKindIdx(Convert.ToInt32(split[0])) == 4) || (ccf.GetDeviceKindIdx(Convert.ToInt32(split[0])) == 6))
                        //    {
                        //        int[] gc = ccf.GetCoordinatesFromMonitorTask(adidx);//获得坐标
                        //        if (gc != null)
                        //        {
                        //            //1：堆垛机；4：RGV；6：AGV如果需要优化调度（设备表的F_NeedOptimize='1'）
                        //            //直接写入表：T_Monitor_Task_Child，不发送命令
                        //            if (ccf.NeedOptimize(_DeviceIdx) == true)
                        //            {
                        //                ccf.InsertMonitorOptimizeChildTask(adidx);
                        //                sendok = true;
                        //            }
                        //            else
                        //            {
                        //                sendok = sdo.SendDeviceOrder(msgIdx, adidx, Convert.ToInt32(split[1]),
                        //                    Convert.ToInt32(split[0]), gc[0], gc[1], gc[2], gc[3], gc[4], gc[5]);
                        //            }

                        //        }
                        //        else
                        //            return true;

                        //    }
                        //    else
                        //    {
                        //        sendok = sdo.SendDeviceOrder(msgIdx, adidx, Convert.ToInt32(split[1]), Convert.ToInt32(split[0]));
                        //    }
                        //    if (sendok == false)
                        //    {
                        //        return true;
                        //    }
                        //}

                        #endregion
                        #region 指定一层叠盘机
                        if (18007 == NumParam4)
                        {
                            #region 优先选择有一垛的叠盘机
                            

                        //    if (LastMachine == 0)//第一次叠盘选择右侧叠盘机
                        //    {
                        //        LastMachine = 12049;
                        //        RightUseTimes=1;

                        //    }
                        //    else
                        //    {
                        //        if (RightUseTimes == 1)//优先
                        //        {
                        //            LastMachine = 12049;
                        //            RightUseTimes = 0;
                        //        }
                        //        else                                                                      
                        //            if (LeftUseTimes == 1)
                        //            {
                        //                LastMachine = 12054;
                        //                LeftUseTimes = 0;
                        //            } 
                        //            else
                        //            if (LeftUseTimes == 0)
                        //            {
                        //                if (LastMachine == 12049)
                        //                {
                        //                    LastMachine = 12054;
                        //                    LeftUseTimes = 1;
                        //                }
                        //                else
                        //                {
                        //                    LastMachine = 12049;
                        //                    RightUseTimes = 1;
                        //                }
                        //            }

                        //            else
                        //                if (RightUseTimes == 0)
                        //                {
                        //                    if (LastMachine == 12054)
                        //                    {
                        //                        LastMachine = 12049;
                        //                        RightUseTimes = 1;
                        //                    }
                        //                    else
                        //                    {
                        //                        LastMachine = 12054;
                        //                        LeftUseTimes = 1;
                        //                    }

                        //                }

                        //}
                            #endregion
                            #region 优先选择空闲的叠盘机

                        if (LastMachine == 0)//第一次叠盘选择右侧叠盘机
                        {
                            LastMachine = 12049;
                            RightUseTimes = 1;

                        }
                        else
                        {
                            if (LastMachine == 12049)
                            {
                                LastMachine = 12054;
                                LeftUseTimes = 1;
                            }
                            else
                            {
                                LastMachine = 12049;
                                RightUseTimes = 1;
                            }


                        }
                        #endregion
                            dbo.ExceSQL("update T_Monitor_Task set F_NumParam4= " + LastMachine + " where F_MonitorIndex= " + minMidx);
                            dbo.ExceSQL("UPDATE T_Manage_Task SET FENDDEVICE=" + LastMachine + " where FID=" + ManageTaskIdx + " and F_ManageTaskKindIndex=" + ManageKindIdx+ "");

                            return true;
                        }


                        #endregion
                        //3：F_AheadDetect检测(检测开关编号组“;”)
                        if (AheadDetectOK(minMidx, _AheadDetect) == true)//提前检测通过
                        {
                            #region 双叉堆垛机检测，能同步的F_CorrelDoubleFork是否AheadDetectOK
                            //20100323
                            devinfo = Model.CGetInfo.GetDeviceInfo(_DeviceIdx);
                            if (devinfo.IfCorrelDoubleFork == "1")
                            {
                                if (Model.CGeneralFunction.DoubleForkIfSync(minMidx, _DeviceIdx, _DeviceKind) == true)
                                {
                                    string[] df = Model.CGeneralFunction.GetDoubleForkMonitorInfo(minMidx, _DeviceIdx);
                                    if (df != null)
                                    {
                                        if (AheadDetectOK(Convert.ToInt32(df[0]), df[1]) == false)//双叉关联提前检测失败
                                        {
                                            return true;
                                        }
                                        #region 关联指令不是第一个指令不能发送
                                        int rmankind = Model.CGeneralFunction.GetManageTaskKindIndexFromMonitor(Convert.ToInt32(df[0]));
                                        int rman = Model.CGeneralFunction.GetManageTaskIndexfromMonitor(Convert.ToInt32(df[0]));
                                        dv = dbo.ExceSQL("SELECT MIN(F_MonitorIndex) AS mmi FROM dbo.T_Monitor_Task WHERE (F_ManageTaskIndex = " + rman + ") AND (F_ManageTASKKINDINDEX = "+rmankind+")").Tables[0].DefaultView;
                                        if (dv.Count > 0)
                                        {
                                            if ((dv[0]["mmi"] != DBNull.Value) && (dv[0]["mmi"].ToString() != df[0]))
                                            {
                                                return true;
                                            }
                                        }
                                        #endregion
                                    }
                                    
                                }
                                else
                                {//20100406堆垛机取送货时，检测隔壁输送机是否有阻碍堆垛机取送货的探物信息

                                }
                            }
                            #endregion

                            //检查同步运行的关联设备F_AssociateDeviceIndex
                            //4：是否有关联设备命令？
                            //AssociateDevice = ccf.GetAssociateDevice(minMidx);
                            if (_Associate != 0)
                            {
                                //5：如果有，找到可以运行的关联设备的设备指令,能否运行？
                                //重复递归到2
                                //split = AssociateDevice.Split(sep);
                                adidx = _Associate;
                                if (adidx != 0)
                                {
                                    if (ccf.GetAssociateMonitor(minMidx) == 0)
                                    {
                                        if (FrmControlMonitor.FormInstance.GetObjectText("tsStatus").IndexOf("设备指令：" + minMidx.ToString() + "无法获得关联任务" + adidx.ToString() + "，不能发送此类命令！") < 0)
                                        {

                                            FrmControlMonitor.FormInstance.FlashPanit("tsStatus", "设备指令：" + minMidx.ToString() + "无法获得关联任务" + adidx.ToString() + "，不能发送此类命令！", true);
                                        }
                                        return true;
                                    }
                                    if (GetFirstDeviceIFLocked(adidx, false) == false)
                                    {
                                        //6：发送关联设备命令
                                        //CStaticClass.MessageIndex++;
                                        CStaticClass.MessageIndex = 1;
                                        msgIdx = (CStaticClass.MessageIndex);
                                        sdo = CommModeCreate.CreateSendDeviceOrder(_DeviceIdx);
                                        //判断是否为堆垛机设备
                                        bool sendok;
                                        int[] gc = new int[6] { _NumParam2, _NumParam3, _NumParam1, _NumParam5, _NumParam6, _NumParam4 }; //ccf.GetCoordinatesFromMonitorTask(adidx);//获得坐标

                                        if ((_DeviceKind == 1) || (_DeviceKind == 6))
                                        {

                                            //1：堆垛机；4：RGV；6：AGV如果需要优化调度（设备表的F_NeedOptimize='1'）
                                            //直接写入表：T_Monitor_Task_Child，不发送命令
                                            if (ccf.NeedOptimize(_DeviceIdx) == true)
                                            {
                                                ccf.InsertMonitorOptimizeChildTask(adidx);
                                                sendok = true;
                                            }
                                            else
                                            {
                                                sendok = sdo.SendDeviceOrder(msgIdx, adidx, _DeviceOrder,
                                                    _DeviceIdx, gc[0], gc[1], gc[2], gc[3], gc[4], gc[5]);
                                            }

                                        }
                                        else if (_DeviceKind == 4)
                                        {
                                            if (ccf.NeedOptimize(_DeviceIdx) == true)
                                            {
                                                ccf.InsertMonitorOptimizeChildTask(adidx);
                                                sendok = true;
                                            }
                                            else
                                            {
                                                sendok = sdo.SendDeviceOrder(msgIdx, adidx, _DeviceOrder, _DeviceIdx, gc[2]);
                                            }

                                        }
                                        else
                                        {
                                            sendok = sdo.SendDeviceOrder(msgIdx, adidx, _DeviceOrder, _DeviceIdx, gc[5]);
                                        }
                                        if (sendok == false)
                                        {
                                            return true;
                                        }
                                        else
                                        {
                                            //8：更改作业记录的状态F_Status为1,更改设备为占用状态（T_Base_device的F_LockedState=设备指令单）
                                            dbo.ExceSQL("update T_Monitor_Task set F_StartTime='" + DateTime.Now.ToString("u") + "',F_Status='1' where F_MonitorIndex=" + adidx);
                                            //dbo.ExceSQL("update T_Base_device set F_LockedState=" + adidx + " where F_DeviceIndex=" + _DeviceIdx);


                                            //返回到原来设备值
                                            _DeviceIdx = DeviceIdx;//设备索引
                                            _routeID = routeID;//路径唯一索引
                                            _serialNumber = serialNumber;//路径上的设备方向性链表的序号
                                            _ManageTaskIdx = ManageTaskIdx;//调度任务索引
                                            _ManageKindIdx = ManageKindIdx;//调度任务类型
                                            _DeviceOrder = DeviceOrder;//设备命令
                                            _LockedState = LockedState;
                                            _Associate = Associate;
                                            _ManTaskReserve = ManTaskReserve;
                                            _AheadDetect = AheadDetect;
                                            _NumParam1 = NumParam1;
                                            _NumParam2 = NumParam2;
                                            _NumParam3 = NumParam3;
                                            _NumParam4 = NumParam4;
                                            _NumParam5 = NumParam5;
                                            _NumParam6 = NumParam6;
                                            _TxtParam = TxtParam;
                                            _DeviceKind = DeviceKind;
                                            _OutsideAltDevice = OutsideAltDevice;
                                            _InsideAltDevice = InsideAltDevice;
                                            _StartDevice = StartDevice;
                                            _EndDevice = EndDevice;
                                            _RouteKind = RouteKind;
                                            _AgvNo = AgvNo;
                                            return false;
                                        }
                                    }
                                    else
                                    {
                                        return true;
                                    }
                                }
                                else//
                                {
                                    //返回到原来设备值
                                    _DeviceIdx = DeviceIdx;//设备索引
                                    _routeID = routeID;//路径唯一索引
                                    _serialNumber = serialNumber;//路径上的设备方向性链表的序号
                                    _ManageTaskIdx = ManageTaskIdx;//调度任务索引
                                    _ManageKindIdx = ManageKindIdx;//调度任务类型
                                    _DeviceOrder = DeviceOrder;//设备命令
                                    _LockedState = LockedState;
                                    _Associate = Associate;
                                    _ManTaskReserve = ManTaskReserve;
                                    _AheadDetect = AheadDetect;
                                    _NumParam1 = NumParam1;
                                    _NumParam2 = NumParam2;
                                    _NumParam3 = NumParam3;
                                    _NumParam4 = NumParam4;
                                    _NumParam5 = NumParam5;
                                    _NumParam6 = NumParam6;
                                    _TxtParam = TxtParam;
                                    _DeviceKind = DeviceKind;
                                    _OutsideAltDevice = OutsideAltDevice;
                                    _InsideAltDevice = InsideAltDevice;
                                    _StartDevice = StartDevice;
                                    _EndDevice = EndDevice;
                                    _RouteKind = RouteKind;
                                    _CControlError = "拆分调度任务得到的设备指令与详细路径的检索到的关联设备指令不匹配，系统作为没有关联设备指令处理！";
                                    return false;
                                }

                            }
                            else
                            {
                                //返回到原来设备值
                                _DeviceIdx = DeviceIdx;//设备索引
                                _routeID = routeID;//路径唯一索引
                                _serialNumber = serialNumber;//路径上的设备方向性链表的序号
                                _ManageTaskIdx = ManageTaskIdx;//调度任务索引
                                _ManageKindIdx = ManageKindIdx;//调度任务类型
                                _DeviceOrder = DeviceOrder;//设备命令
                                _LockedState = LockedState;
                                _Associate = Associate;
                                _ManTaskReserve = ManTaskReserve;
                                _AheadDetect = AheadDetect;
                                _NumParam1 = NumParam1;
                                _NumParam2 = NumParam2;
                                _NumParam3 = NumParam3;
                                _NumParam4 = NumParam4;
                                _NumParam5 = NumParam5;
                                _NumParam6 = NumParam6;
                                _TxtParam = TxtParam;
                                _DeviceKind = DeviceKind;
                                _OutsideAltDevice = OutsideAltDevice;
                                _InsideAltDevice = InsideAltDevice;
                                _StartDevice = StartDevice;
                                _EndDevice = EndDevice;
                                _RouteKind = RouteKind;

                                return false;
                            }
                        }
                        else
                        {
                            return true;
                        }

                    }
                    else
                    {

                        return true;

                    }
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                dv = null;
            }
        }
        /// <summary>
        /// 检测指定设备命令的执行先决条件是否成立
        /// </summary>
        /// <param name="minMidx">监控唯一索引</param>
        /// <returns>是否检测通过，true表示设备执行命令的先决条件成立</returns>
        public bool AheadDetectOK(int minMidx, string _AheadDetect)
        {
            //检测(检测开关编号组“;”)
            DataView dv;//20100319
            DataView dvdv;
            DataTable dt;
            try
            {

                int[] States;

                int DeviceIdx = _DeviceIdx;
                int TaskIdx = minMidx;
                int fid = ccf.GetManageTaskIndexfromMonitor(TaskIdx);
                int mti = ccf.GetManageTaskKindIndexFromMonitor(TaskIdx);
                int DeviceKind = ccf.GetDeviceKindIdx(DeviceIdx);//20100617
                //20100706
                devinfo = Model.CGetInfo.GetDeviceInfo(DeviceIdx);
                if (devinfo.CommType == "OPCClient")//20100706 只有OPCClient通讯类型的检查设备状态
                {
                     #region OPC通讯设备检测设备是否故障
                        
                        
                        //gds = CommModeCreate.CreateGetDeviceState(DeviceIdx);
                        try
                        {
                            //States = gds.GetDeviceState(DeviceIdx, TaskIdx);//1完成,2任务号,5设备号
                            States = CStaticClass.GetDeviceState(DeviceIdx);

                        }
                        catch (Exception ex)
                        {
                            if (FrmControlMonitor.FormInstance.GetObjectText("tsStatus").IndexOf("获取状态时：" + ex.Message) < 0)
                            {

                                FrmControlMonitor.FormInstance.FlashPanit("tsStatus", "获取状态时：" + ex.Message, true);
                            }
                            return false;
                        }
                        if (States == null)//没接收到任何返回值
                        {
                            if (FrmControlMonitor.FormInstance.GetObjectText("tsStatus").IndexOf("发送命令时，提前检测没收到PLC数据！") < 0)
                            {

                                FrmControlMonitor.FormInstance.FlashPanit("tsStatus", "发送命令时，提前检测没收到PLC数据！", true);
                            }
                            return false;
                        }
                        if ((States[1] == 1) || (States[1] >= 30))//运行或者故障
                        {
                            if (States[1] >= 30)
                            {
                                devinfo = Model.CGetInfo.GetDeviceInfo(DeviceIdx);
                                int ErrId = States[1];
                                //20090910
                                //有过记录的故障设备的任务号，不再重复处理
                                string devstr = "SELECT F_DeviceIndex FROM T_Base_Device where F_DeviceIndex=" + DeviceIdx + " and F_ErrorTaskNo=" + TaskIdx + "";
                                dt = dbo.ExceSQL(devstr).Tables[0];
                                if (dt.Rows.Count >= 1)
                                {
                                    //dbo.ExceSQL("update T_Monitor_Task set F_Status= " + ErrId + "  where (F_MonitorIndex= " + TaskIdx + ") and ((F_Status<> " + ErrId + ") and (F_Status<> 3))");
                                    return false;
                                }
                                //记录发生故障的设备正在执行的任务号
                                dbo.ExceSQL("update T_Base_Device set F_ErrorTaskNo= " + TaskIdx + "  where F_DeviceIndex= " + DeviceIdx);

                                if (CStaticClass.IsEquals(devinfo.ReturnMessage, States, 2) == true) return false;

                                //if ((_DeviceKind == 2) || (_DeviceKind == 4))
                                //{//输送机故障清零
                                //    sdo = CommModeCreate.CreateSendDeviceOrder(DeviceIdx);
                                //    sdo.SendDeviceOrder(2, 0, 0, DeviceIdx, 0);
                                //}
                                //if (_DeviceKind == 1) //堆垛机、RGV
                                //{

                                //    sdo = CommModeCreate.CreateSendDeviceOrder(DeviceIdx);
                                //    sdo.SendDeviceOrder(2, 0, 0, DeviceIdx, 0, 0, 0, 0, 0, 0);
                                //}
                                errs = Model.CGetInfo.GetErrorInfo(Convert.ToInt32(_DeviceKind.ToString() + States[1].ToString()));
                                if (FrmControlMonitor.FormInstance.GetObjectText("tsStatus").IndexOf("设备索引" + DeviceIdx + "有故障：" + errs.ErrorName) < 0)
                                {

                                    FrmControlMonitor.FormInstance.FlashPanit("tsStatus", "设备索引" + DeviceIdx + "有故障：" + errs.ErrorName, true);
                                }
                                FrmMain.FormInstance.notifyIcon1.BalloonTipText = "警告:" + devinfo.DeviceName + "," + DeviceIdx + "发生故障：" + errs.ErrorName;
                                FrmMain.FormInstance.notifyIcon1.ShowBalloonTip(10000, "警告", devinfo.DeviceName + "," + DeviceIdx + "发生故障：" + errs.ErrorName, System.Windows.Forms.ToolTipIcon.Warning);
                                if (mti == 1)
                                {
                                    dboM.ExceSQL("update IO_Control set ERROR_TEXT='" + "准备执行管理任务时：" + devinfo.DeviceName + "," + DeviceIdx + errs.ErrorName + "' where Control_ID=" + fid);
                                }
                                dbo.ExceSQL("update T_Manage_Task set FERRORCODE='" + "准备执行管理任务时：" + devinfo.DeviceName + "," + DeviceIdx + errs.ErrorName + "' where F_ManageTaskKindIndex=" + mti + " and FID=" + fid);
                            }
                            return false;
                        }
                        //20110724 
                        if (devinfo.DeviceKind == 1 && States[3]== 0)//堆垛机坐标为0时不发送命令
                        {
                            return false;
                        }
                        #endregion
                   
                }
                else
                {
                    //延吉：20100319 AGV的指令67：允许AGV放残托时，如果有1219的送出指令、1220的指令正在执行或者已发送，提前检测失败，需要等待

                    //if (ccf.GetDeviceOrderFromMonitor(minMidx) == 67)
                    //{
                    //    dv = dbo.ExceSQL("SELECT F_MonitorIndex FROM T_Monitor_Task WHERE (F_DeviceIndex = 1219) AND (F_DeviceCommandIndex = 6) AND (F_Status > 0)").Tables[0].DefaultView;
                    //    if (dv.Count > 0)
                    //    {
                    //        return false;
                    //    }
                    //    dv = dbo.ExceSQL("SELECT F_MonitorIndex FROM T_Monitor_Task WHERE (F_DeviceIndex = 1220) AND (F_Status > 0)").Tables[0].DefaultView;
                    //    if (dv.Count > 0)
                    //    {
                    //        return false;
                    //    }
                    //}
                }




                 #region 顶升机构入库任务单独处理//20101011
                int CONTROLTASKTYPE = ccf.GetFCONTROLTASKTYPEFromManageTask(mti, fid);
                if (ccf.GetCorrel_DeviceIndex(devinfo.DeviceIndex,true) == 0)//顶升设备自关联
                {
                    string[] CorrelInfo = ccf.GetCorrel_DeviceInfo(devinfo.DeviceIndex,true);
                    if (CorrelInfo==null) return false;
                    //20100406入库顶升时必要检测：1102内探物“-11021”；1121低到位“-11212”；有关联任务时，1102外探物“-11022”；

                    if(CONTROLTASKTYPE == 1)//入库任务
                    {
                        if ((CStaticClass.GetDevicePhotoelectric(CorrelInfo[5]) == 1) )//&& (CStaticClass.GetDevicePhotoelectric(CorrelInfo[2]) == 1))//近巷道2列有物，顶升低位(顶升开关要在中位)
                        {
                            #region 等待关联任务配对
                            //在CStaticClass.DoubleForkWaitTime规定时间内等待；1102（11027）转动等待
                            dv = dbo.ExceSQL("SELECT F_TaskIndex,F_DeviceIndex,F_Remark FROM T_Base_PLC_Ask WHERE (F_TaskIndex =" + TaskIdx + ") AND (F_Remark <> '') AND (F_DeviceIndex=" + devinfo.DeviceIndex + ")").Tables[0].DefaultView;
                            if (dv.Count > 0)
                            {   
                               if((Convert.ToDateTime(dv[0]["F_Remark"]).AddSeconds(Convert.ToInt32(CStaticClass.DoubleForkWaitTime)) > DateTime.Now) ||
                           //   (GetIOControlStatus(minMidx) != Model.CGeneralFunction.TASKSINGLEFORKRUN) ||
                                    ((CStaticClass.GetDevicePhotoelectric(CorrelInfo[6]) == 1) && (CStaticClass.GetDeviceRunState(int.Parse(CorrelInfo[4])) == 0)))//20110106
                                {
                                    if ((CStaticClass.GetDevicePhotoelectric(CorrelInfo[6]) == 1)
                                        && (CStaticClass.GetDeviceRunState(int.Parse(CorrelInfo[4])) == 0)
                                        && (CStaticClass.GetDevicePhotoelectric(CorrelInfo[1]) == 1))//1列探物，不运行,在高位//20110106
                                    {
                                        //查找本地管理任务做双叉关联配对，关联任务分配近叉
                                        int mfid = GetEnableDoubleForkManageTask(1, devinfo.DeviceIndex, fid);
                                        if (mfid > 0)
                                        {
                                            dbo.ExecuteSql("update T_Manage_Task set F_RELATIVECONTORLID=" + mfid + " where F_ManageTaskKindIndex=" + mti + " and FID=" + fid);
                                            dbo.ExecuteSql("update T_Manage_Task set FUseAwayFork='0',F_RELATIVECONTORLID=" + fid + " where F_ManageTaskKindIndex=" + mti + " and FID=" + mfid);
                                            dbo.ExecuteSql("update T_Monitor_Task set F_UseAwayFork='0' where F_ManageTASKKINDINDEX=" + mti + " and F_ManageTaskIndex=" + mfid + "");
                                            //由于已经分配路径不一定符合远近货叉的分配原则，需要改道
                                            AlterRoutePath(mti, mfid, CONTROLTASKTYPE, '0', devinfo.DeviceIndex);
                                            return true;
                                        }
                                        return false;
                           
                                    }
                                    else
                                    {
                                        return false;
                                    }
                                }
                                else
                                {//超过等待时间或者管理强制执行单叉任务
                                    if (CStaticClass.GetDeviceRunState(int.Parse(CorrelInfo[4])) == 1)//20110106
                                    {
                                        string dtime = DateTime.Now.ToString("u");
                                        dtime = dtime.Substring(0, dtime.Length - 1);
                                        dbo.ExecuteSql("update T_Base_PLC_Ask set F_Remark='" + dtime + "' where (F_DeviceIndex=" + devinfo.DeviceIndex + ")");
                                        //20110108
                                        dbo.ExecuteSql("update T_Monitor_Task set F_UseAwayFork='1' where F_ManageTASKKINDINDEX=" + mti + " and F_ManageTaskIndex=" + fid + "");
                                        dbo.ExecuteSql("update T_Manage_Task set FUseAwayFork='1' where F_ManageTASKKINDINDEX=" + mti + " and FID=" + fid + "");
                  
                                        return false;
                                    }
                                   //如果等待超时
                                    dbo.ExecuteSql("update T_Base_PLC_Ask set F_TaskIndex=0,F_Remark='' where (F_DeviceIndex=" + devinfo.DeviceIndex + ")");
                                   //20110108
                                    dbo.ExecuteSql("update T_Monitor_Task set F_UseAwayFork='1' where F_ManageTASKKINDINDEX=" + mti + " and F_ManageTaskIndex=" + fid + "");
                                    dbo.ExecuteSql("update T_Manage_Task set FUseAwayFork='1' where F_ManageTASKKINDINDEX=" + mti + " and FID=" + fid + "");
                                    dboM.ExceSQL("update IO_Control set CONTROL_STATUS=" + Model.CGeneralFunction.TASKSINGLEFORKRUN + " where CONTROL_ID=" + fid);

                                    return true;

                                }
                            }
                            else//20101220开始记录2列表箱开始等待的时间
                            {
                                dv = dbo.ExceSQL("SELECT F_TaskIndex,F_DeviceIndex,F_Remark FROM T_Base_PLC_Ask WHERE (F_TaskIndex =0) AND (F_Remark = '') AND (F_DeviceIndex=" + devinfo.DeviceIndex + ")").Tables[0].DefaultView;
                                if (dv.Count > 0)
                                {
                                    string dtime = DateTime.Now.ToString("u");
                                    dtime = dtime.Substring(0, dtime.Length - 1);
                                    dbo.ExecuteSql("update T_Base_PLC_Ask set F_TaskIndex=" + TaskIdx + ",F_Remark='" + dtime + "' where (F_DeviceIndex=" + devinfo.DeviceIndex + ")");
                                    dbo.ExecuteSql("update T_Monitor_Task set F_UseAwayFork='1' where F_ManageTASKKINDINDEX=" + mti + " and F_ManageTaskIndex=" + fid + "");
                                    dbo.ExecuteSql("update T_Manage_Task set FUseAwayFork='1' where F_ManageTASKKINDINDEX=" + mti + " and FID=" + fid + "");
                                    //由于已经分配路径不一定符合远近货叉的分配原则，需要改道
                                    AlterRoutePath(mti, fid, CONTROLTASKTYPE, '1', devinfo.DeviceIndex);
                                    return false;
                                }
                                else//20110401
                                {
                                    dv = dbo.ExceSQL("SELECT FID,F_RELATIVECONTORLID FROM T_Manage_Task where F_RELATIVECONTORLID=-1 and F_ManageTaskKindIndex=" + mti + " and FID=" + fid+"").Tables[0].DefaultView;
                                if(dv.Count>0)
                                {
                                    if (CStaticClass.GetDevicePhotoelectric(CorrelInfo[6]) == 1)//1列有货不执行单盘上升
                                    {
                                      return false;
                                    }
                                }
                                }
                            }

                            #endregion
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else
                    if (CONTROLTASKTYPE == 2)//出库任务，在下达升降站台送出指令时判断1列或是2列位置有货状态
                    {
                        if ((CStaticClass.GetDevicePhotoelectric(CorrelInfo[5]) == 0) && (CStaticClass.GetDevicePhotoelectric(CorrelInfo[6]) == 0))
                        {
                            return false ;
                        }
                    }

                }

                #endregion
                #region 提前检测信息处理
                if ((_AheadDetect != "") && (_AheadDetect != null))
                {


                    char[] cc = new char[1];
                    cc[0] = ';';
                    string[] AheadDetect = _AheadDetect.Split(cc);
                    char[] dd = new char[1] { '.' };//20101118
                    string[] DS;

                    //通过抽象类工厂获得IGetDeviceState的派生类
                    //IGetDeviceState GDS;
                    int s = 0;
                    //int[] sss;
                    int fs = 1;
                    //int[] fsss;
                    //提取光电开关索引值
                    for (int i = AheadDetect.GetLowerBound(0); i <= AheadDetect.GetUpperBound(0); i++)
                    {
                        if (AheadDetect[i].Trim().Length <= 0) continue;
                        if (AheadDetect[i].Trim().Substring(0, 1).ToUpper() == "H")//检测逻辑有探物
                        {
                            DeviceKind = ccf.GetDeviceKindIdx(Convert.ToInt32(AheadDetect[i].Trim().Substring(1)));
                            if (DeviceKind == 9)
                            {//机台需要从管理设备表读取
                                if (dboM.ExceSQL("SELECT FID FROM T_ITEMDEVICESTATION WHERE (FCODE = '" + AheadDetect[i].Trim().Substring(1) + "') AND (FSTATUS = '1002')").Tables[0].DefaultView.Count > 0)
                                {
                                    fs = fs & 1;
                                }
                                else
                                {
                                    fs = fs & 0;
                                }
                            }
                            else
                            {
                                //本地设备表读取
                                dvdv = dbo.ExceSQL("SELECT F_DeviceIndex, F_HaveGoods FROM T_Base_Device where F_DeviceIndex=" +
                                    Convert.ToInt32(AheadDetect[i].Trim().Substring(1)) + "").Tables[0].DefaultView;
                                if (dvdv.Count > 0)
                                {
                                    fs = fs & Convert.ToInt32(dvdv[0]["F_HaveGoods"]);
                                }
                            }
                            continue;
                        }
                        if (AheadDetect[i].Trim().Substring(0, 1).ToUpper() == "N")//检测逻辑无探物
                        {
                            DeviceKind = ccf.GetDeviceKindIdx(Convert.ToInt32(AheadDetect[i].Trim().Substring(1)));
                            if (DeviceKind == 9)
                            {//机台需要从管理设备表读取;20101028管理依赖任务控制机台的站台是否有物
                                //if (dboM.ExceSQL("SELECT FID FROM T_ITEMDEVICESTATION WHERE (FCODE = '" + AheadDetect[i].Trim().Substring(1) + "') AND (FSTATUS = '1002')").Tables[0].DefaultView.Count > 0)
                                //{
                                //    fs = fs & 1;
                                //}
                                //else
                                //{
                                //    fs = fs & 0;
                                //}
                            }
                            else
                            {
                                //本地设备表读取
                                dvdv = dbo.ExceSQL("SELECT F_DeviceIndex, F_HaveGoods FROM T_Base_Device where  F_DeviceIndex=" +
                                    Convert.ToInt32(AheadDetect[i].Trim().Substring(1)) + "").Tables[0].DefaultView;
                                if (dvdv.Count > 0)
                                {
                                    s = s + Convert.ToInt32(dvdv[0]["F_HaveGoods"]);
                                }
                            }
                            continue;
                        }
                        //20090803检测设备是否空闲idle
                        if (AheadDetect[i].Trim().Substring(0, 1).ToUpper() == "I")//检测设备是否空闲idle
                        {
                            States = CStaticClass.GetDeviceState(Convert.ToInt32(AheadDetect[i].Trim().Substring(1)));

                            if (States != null)
                            {
                                s = s + States[1];
                            }
                            continue;
                        }

                        #region 20101118检测设备光电信号

                        //检测设备的光电信号：D-12001.0表示输送机12001的入口开关有物；D12001.1表示输送机12001的入口开关无物
                        //D-12001.2表示输送机12001的顶升高位（高到位）；D12001.3表示输送机12001的顶升不在低位（不是低到位）
                        if (AheadDetect[i].Trim().Substring(0, 1).ToUpper() == "D")
                        {
                            DS = AheadDetect[i].Trim().Substring(1).Split(dd);
                            int devicebyte = 0; int devbit = 0;
                            int.TryParse(DS[0], out devicebyte);
                            int.TryParse(DS[1], out devbit);
                            //判断是否检测负数索引值（负数代表是否满足开关量＝１的执行前提）
                            if (devicebyte < 0)
                            {
                                //调用通讯接口获得光电的开关量０，１
                                //GDS = CommModeCreate.CreateGetDeviceState(-Convert.ToInt32(AheadDetect[i]));+

                                //fsss = GDS.GetDeviceState(-Convert.ToInt32(AheadDetect[i]), Convert.ToInt32(dvD[0]["F_MonitorIndex"]));
                                int fsn = CStaticClass.GetDevicePhotoelectric(-devicebyte, devbit);
                                //if (fsss == null)
                                //{
                                //    this._CControlError = GDS.CommLayerError;
                                //    return false;
                                //}
                                if (fsn == -1)//20101220
                                {
                                    return false;
                                }
                                fs = fs & fsn;
                            }
                            else
                            {//不能为１的开关量检测
                                //调用通讯接口获得光电的开关量０，１
                                //GDS = CommModeCreate.CreateGetDeviceState(Convert.ToInt32(AheadDetect[i]));
                                //sss = GDS.GetDeviceState(Convert.ToInt32(AheadDetect[i]), Convert.ToInt32(dvD[0]["F_MonitorIndex"]));
                                int sssn = CStaticClass.GetDevicePhotoelectric(devicebyte, devbit);
                                //if (sss == null)
                                //{
                                //    this._CControlError = GDS.CommLayerError;
                                //    return false;
                                //}
                                if (sssn == -1)//20101220
                                {
                                    return false;
                                }
                                s = s + sssn;
                            }
                        }

                        #endregion

                    }
                    if ((s == 0) && (fs == 1))
                    {
                        //if (CStaticClass.AGVAllowSingleFork == "0")//20100710
                        //{
                        //    #region 和AGV取货交互的输送机的单一出库任务，检查隔壁输送机是否有任务在执行
                        //    //奇数加一；偶数减一
                        //    string[] outstation = new string[4] { "2241", "2242", "3241", "3242" };
                        //    if ((Array.IndexOf(outstation, DeviceIdx.ToString()) >= 0) && (Model.CGeneralFunction.GetDoubleForkMonitorInfo(TaskIdx, DeviceIdx) == null))
                        //    {
                        //        if ((DeviceIdx % 2) == 0)
                        //        {
                        //            dvdv = dbo.ExceSQL("SELECT F_MonitorIndex FROM T_Monitor_Task WHERE F_DeviceIndex = " + (DeviceIdx - 1) + " AND F_Status > 0").Tables[0].DefaultView;
                        //            if (dvdv.Count > 0)
                        //            {
                        //                return false;
                        //            }
                        //            if (CStaticClass.GetDevicePhotoelectric(ccf.GetBindingDeviceIndexOut(DeviceIdx - 1)) == 1)
                        //            {
                        //                return false;
                        //            }
                        //        }
                        //        else
                        //        {
                        //            dvdv = dbo.ExceSQL("SELECT F_MonitorIndex FROM T_Monitor_Task WHERE F_DeviceIndex = " + (DeviceIdx + 1) + " AND F_Status > 0").Tables[0].DefaultView;
                        //            if (dvdv.Count > 0)
                        //            {
                        //                return false;
                        //            }
                        //            if (CStaticClass.GetDevicePhotoelectric(ccf.GetBindingDeviceIndexOut(DeviceIdx + 1)) == 1)
                        //            {
                        //                return false;
                        //            }
                        //        }
                        //    }
                        //    #endregion
                        //}
                        //return true;//20101011
                    }
                    else
                    {
                        return false;
                    }

                }
                else
                {
                    //此设备没有设置提前检测开关索引
                    //return true;//20101011

                }
                                #endregion
                //20101011
                #region 双叉堆垛机的取货任务在此判断是否关联双叉、验证双叉任务是否为双叉极限货位
                if ((devinfo.DeviceKind == 1) && (devinfo.IfCorrelDoubleFork == "1") && (ccf.GetDeviceOrderFromMonitor(minMidx) == 4) && (CONTROLTASKTYPE == 1))
                {
                    string[] CorrelInfo = ccf.GetCorrel_DeviceInfo(minMidx);
                    if (CorrelInfo == null) return false;

                    string[] corrinfo=Model.CGeneralFunction.GetDoubleForkMonitorInfo(minMidx, devinfo.DeviceIndex);
                    
                    if (corrinfo == null)
                    {
                      int IfCorrel = ccf.GetCorrel_DeviceIndex(minMidx);
                      if (IfCorrel == 0)//堆垛机执行单叉任务时，要判断1列无货20110108
                      {

                          if (CStaticClass.GetDevicePhotoelectric(CorrelInfo[6]) != 0)
                          {

                              return false;
                          }
                          //20110108
                          dbo.ExecuteSql("update T_Monitor_Task set F_UseAwayFork='1' where F_ManageTASKKINDINDEX=" + mti + " and F_ManageTaskIndex=" + fid + "");
                          dbo.ExecuteSql("update T_Manage_Task set FUseAwayFork='1' where F_ManageTASKKINDINDEX=" + mti + " and FID=" + fid + "");
         
                          //单叉极限货位判断
                          string ChangeForkCell = IfLimitCellChangeFork(minMidx);
                          if (ChangeForkCell != "-")//主任务需要倒换货叉
                          {
                              ChangeEndCellCode(minMidx, ChangeForkCell, devinfo.DeviceIndex);
                          }

                      }
                       
                        #region 双叉对等站台的单任务在此等待关联，双叉极限货位不关联
                        else if (IfCorrel> 0)
                        {
                            //string[] CorrelInfo = ccf.GetCorrel_DeviceInfo(minMidx);
                            //if (CorrelInfo == null) return false;
                           
                            if(CStaticClass.GetDevicePhotoelectric(int.Parse(CorrelInfo[5])) == 1)
                            {
                                dv = dbo.ExceSQL("SELECT F_TaskIndex,F_DeviceIndex,F_Remark FROM T_Base_PLC_Ask WHERE (F_TaskIndex =" + TaskIdx + ") AND (F_Remark <> '') AND (F_DeviceIndex=" + CorrelInfo[0] + ")").Tables[0].DefaultView;
                                if (dv.Count > 0)
                                {
                                    CorrelInfo = ccf.GetCorrelOther_DeviceInfo(Convert.ToInt32(CorrelInfo[8]));//关联站台的信息
                                    //(Convert.ToDateTime(dv[0]["F_Remark"]).AddSeconds(Convert.ToInt32(CStaticClass.DoubleForkWaitTime)) > DateTime.Now)
                                    if ((GetIOControlStatus(TaskIdx) != Model.CGeneralFunction.TASKSINGLEFORKRUN)
                                       || ((CStaticClass.GetDevicePhotoelectric(int.Parse(CorrelInfo[5])) == 1)) && (CStaticClass.GetDeviceRunState(int.Parse(CorrelInfo[4])) == 0))//20110106
                                    {//没超时或者近巷道有物，不运行
                                        if ((CStaticClass.GetDevicePhotoelectric(int.Parse(CorrelInfo[5])) == 1)//近巷道有物
                                            && (CStaticClass.GetDeviceRunState(int.Parse(CorrelInfo[4])) == 0))//不运行//20110106
                                        {
                                            //查找本地管理任务做双叉关联配对，关联任务分配货叉
                                            int mfid = GetEnableDoubleForkManageTask(1,devinfo.DeviceIndex, int.Parse(CorrelInfo[0]), fid);
                                            if (mfid > 0)
                                            {
                                                #region 双叉同为前极限后者后极限不关联，单独执行
                                                if ((IfInSameLimitX(fid, mfid,mti) == true) && (mti == 1))
                                                {
                                                    dboM.ExecuteSql(" update IO_CONTROL set CONTROL_STATUS=" + Model.CGeneralFunction.TASKSINGLEFORKRUN + " WHERE (CONTROL_ID = " + fid + ")");
                                                    dboM.ExecuteSql(" update IO_CONTROL set CONTROL_STATUS=" + Model.CGeneralFunction.TASKSINGLEFORKRUN + " WHERE (CONTROL_ID = " + mfid + ")");
                                                    return true;
                                                }
                                                #endregion
                                                dbo.ExecuteSql("update T_Manage_Task set F_RELATIVECONTORLID=" + mfid + " where F_ManageTaskKindIndex=" + mti + " and FID=" + fid);
                                                dbo.ExecuteSql("update T_Manage_Task set F_RELATIVECONTORLID=" + fid + " where F_ManageTaskKindIndex=" + mti + " and FID=" + mfid);
                                                return false;
                                            }
                                            else
                                            {
                                                return false;
                                            }
                                            
                                        }
                                        else
                                        {
                                            return false;
                                        }
                                    }
                                    else
                                    {//超过等待时间或者管理强制执行单叉任务
                                        if (CStaticClass.GetDeviceRunState(int.Parse(CorrelInfo[4])) == 1)//20110106
                                        {//隔壁对等输送机在运行，重新计时
                                            string dtime = DateTime.Now.ToString("u");
                                            dtime = dtime.Substring(0, dtime.Length - 1);
                                            dbo.ExecuteSql("update T_Base_PLC_Ask set F_Remark='" + dtime + "' where (F_DeviceIndex=" + int.Parse(CorrelInfo[0]) + ")");
                                            return false;
                                        }
                                        else
                                        {//超时或者管理强制执行单叉任务
                                            dbo.ExecuteSql("update T_Base_PLC_Ask set F_TaskIndex=0,F_Remark='' where (F_DeviceIndex=" + int.Parse(CorrelInfo[0]) + ")");
                                            return true;
                                        }

                                    }
                                }
                                else
                                {
                                    dv = dbo.ExceSQL("SELECT F_TaskIndex,F_DeviceIndex,F_Remark FROM T_Base_PLC_Ask WHERE (F_TaskIndex =0) AND (F_Remark = '') AND (F_DeviceIndex=" + int.Parse(CorrelInfo[0]) + ")").Tables[0].DefaultView;
                                    if (dv.Count > 0)
                                    {
                                        string dtime = DateTime.Now.ToString("u");
                                        dtime = dtime.Substring(0, dtime.Length - 1);
                                        dbo.ExecuteSql("update T_Base_PLC_Ask set F_TaskIndex=" + TaskIdx + ",F_Remark='" + dtime + "' where (F_DeviceIndex=" + int.Parse(CorrelInfo[0]) + ")");
                                        
                                        return false;
                                    }
                                
                                }
                           
                            }
                        }

                        #endregion
                    }
                    else
                    {
                        #region 双叉任务在此验证，是否为双叉极限货位，双极限货位使用双叉倒库货位修改任务
                        //把倒库货位作为取货和送货动作的目标货位，增加取货和送货动作对于倒库货位的逻辑有物的提前检测
                        //报告倒库货位完成时，追加倒库货位---》需要换叉的极限货位的取货和送货任务
                        if (CStaticClass.GetDevicePhotoelectric(CorrelInfo[6]) == 0)//双叉任务要判断1列有货20110108
                        {

                            return false;
                        }

                        #region 检查自己任务
                        string ChangeForkCell = IfLimitCellChangeFork(minMidx);
                        
                        #endregion
                        #region 检查关联任务
                        string ChangeForkCell1 = IfLimitCellChangeFork(int.Parse(corrinfo[0]));
                        
                        #endregion
                        if ((ChangeForkCell != "-") && (ChangeForkCell1 != "-"))
                        {//主任务和关联任务都需要倒换货叉，向管理申请修改货位

                        }
                        else if ((ChangeForkCell != "-")&& (ChangeForkCell1 == "-"))//主任务需要倒换货叉
                        {
                            ChangeEndCellCode(minMidx, ChangeForkCell, devinfo.DeviceIndex);
                        }
                        else if ((ChangeForkCell1 != "-") && (ChangeForkCell == "-"))//关联任务需要倒换货叉
                        {
                            ChangeEndCellCode(int.Parse(corrinfo[0]), ChangeForkCell1, devinfo.DeviceIndex);
                        }
                        #endregion
                    }

                    

                    
                }
                #endregion

                #region 双叉AGV的取货任务在此判断是否关联双叉、验证双叉任务是否为双叉极限货位

                //if ((devinfo.DeviceKind == 6) && (devinfo.IfCorrelDoubleFork == "1") && (ccf.GetDeviceOrderFromMonitor(minMidx) == 1) && (CONTROLTASKTYPE == 1))
                //{

                //    string[] corrinfo = Model.CGeneralFunction.GetDoubleForkMonitorInfo(minMidx, devinfo.DeviceIndex);

                //    if (corrinfo == null)
                //    {
                //        #region 双叉对等站台的单任务在此等待关联，双叉极限货位不关联
                //        if (GetIOControlStatus(TaskIdx) != Model.CGeneralFunction.TASKSINGLEFORKRUN)
                //        {//没强制单叉执行
                            
                //            //查找关联站台
                //            int agvCorrel = GetAGVCorrelIndex(TaskIdx);
                //            if (agvCorrel != -1)
                //            {
                //                //查找本地管理任务做双叉关联配对，关联任务分配货叉
                //                int mfid = GetAGVEnableDoubleForkManageTask(1,agvCorrel);
                //                if (mfid > 0)
                //                {
                //                    #region 双叉同为前极限后者后极限不关联，单独执行
                //                    if ((IfInSameLimitX(fid, mfid,mti) == true) && (mti==1))
                //                    {
                //                        dboM.ExecuteSql(" update IO_CONTROL set CONTROL_STATUS="+Model.CGeneralFunction.TASKSINGLEFORKRUN+" WHERE (CONTROL_ID = "+fid+")");
                //                        dboM.ExecuteSql(" update IO_CONTROL set CONTROL_STATUS=" + Model.CGeneralFunction.TASKSINGLEFORKRUN + " WHERE (CONTROL_ID = " + mfid + ")");
                //                        return true;
                //                    }
                //                    #endregion
                //                    dbo.ExecuteSql("update T_Manage_Task set F_RELATIVECONTORLID=" + mfid + " where F_ManageTaskKindIndex=" + mti + " and FID=" + fid);
                //                    dbo.ExecuteSql("update T_Manage_Task set F_RELATIVECONTORLID=" + fid + " where F_ManageTaskKindIndex=" + mti + " and FID=" + mfid);
                //                    return true;
                //                }

                //                else
                //                    return false;
                //            }
                //            else
                //                return true ;
                //        }
                //        else
                //        {//管理强制执行单叉任务
                //            return true;

                //        }
                        

                //        #endregion
                //    }

                //}
                #endregion




                #region 双向任务判读 
                int StartDevice = _StartDevice;//当前调度任务起点
                int EndDevice = _EndDevice;//当前调度任务终点
                int DeviceOrder = _DeviceOrder;//设备命令

                int END = 12604;
                string sqlstr = string.Empty;

                #region 堆垛机执行出库任务时，判断堆垛机执行出库取货指令时，判断是否有入库任务，输送机是否空闲无货
                if (DeviceIdx == 11005 && DeviceOrder == 4 && CONTROLTASKTYPE == 2 && EndDevice == END)//
                { //不能有入库任务，
                    string checkdevice = "12603;12604";
                    int freecount = ccf.GetTransDeviceGoodsCounts(checkdevice);
                    if (freecount > 0)
                    {
                        return false;
                    }

                    sqlstr = string.Format("SELECT FID  FROM T_Manage_Task WHERE  FCONTROLTASKTYPE=1  and  FSTARTDEVICE ={0}", END);
                    dv = dbo.ExceSQL(sqlstr).Tables[0].DefaultView;
                    if (dv.Count > 0)
                    {
                        return false;
                    }



                } 
                #endregion
                #region 输送机执行入库任务时判断
                if (DeviceIdx == END && DeviceOrder == 6 && CONTROLTASKTYPE == 1)//
                { 
                    //不能有出库任务在执行
                    sqlstr = string.Format("SELECT FID  FROM T_Manage_Task WHERE  FCONTROLTASKTYPE=2  and FSTATUS > 0  and  FENDDEVICE ={0}", END);
                    dv = dbo.ExceSQL(sqlstr).Tables[0].DefaultView;
                    if (dv.Count > 0)
                    {
                        return false;
                    }



                }
                #endregion
                #endregion

                return true;//20101011


            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                dv = null;
                dt = null;
                dvdv = null;
            }
        }

        /// <summary>
        /// 获得发送信息
        /// </summary>
        /// <param name="minMidx">设备指令索引</param>
        public bool  GetSendInfo(int minMidx)
        {
            DataView dvD ;
            try
            {
                
                string strD = "";
                strD = "SELECT F_DeviceKindIndex,F_NumParam1,F_NumParam2,F_NumParam3,F_NumParam4," +
                    "F_NumParam5,F_NumParam6,F_TxtParam,F_AheadDetect,F_ManTaskReserve,F_LockedState," +
                    "F_Associate,F_SerialNumber,F_RouteID,F_DeviceIndex,F_DeviceCommandIndex," +
                    "F_MonitorIndex,F_ManageTaskIndex,F_ManageTaskKindIndex,F_OutsideAltDevice," +
                    "F_InsideAltDevice,F_StartDevice,F_EndDevice,F_RouteKind,F_CorrelDoubleFork,F_UseAwayFork,F_AgvNo " +
                    " FROM  V_Monitor_Route_Device where F_MonitorIndex=" + minMidx;
                dvD = dbo.ExceSQL(strD).Tables[0].DefaultView;

                if (dvD.Count > 0)
                {
                    if (dvD[0]["F_AheadDetect"] != DBNull.Value)
                    {
                        _AheadDetect = dvD[0]["F_AheadDetect"].ToString();
                    }
                    else
                    {
                        _AheadDetect = "";
                    }
                    if (dvD[0]["F_ManTaskReserve"] != DBNull.Value)
                    {
                        _ManTaskReserve = Convert.ToInt32(dvD[0]["F_ManTaskReserve"]);
                    }
                    else
                    {
                        _ManTaskReserve = 0;
                    }
                    if (dvD[0]["F_Associate"] != DBNull.Value)
                    {
                        _Associate = Convert.ToInt32(dvD[0]["F_Associate"]);
                    }
                    else
                    {
                        _Associate = 0;
                    }
                    if (dvD[0]["F_LockedState"] != DBNull.Value)
                    {
                        _LockedState = Convert.ToInt32(dvD[0]["F_LockedState"]);
                    }
                    else
                    {
                        _LockedState = 0;
                    }
                    if (dvD[0]["F_NumParam1"] != DBNull.Value)
                    {
                        _NumParam1 = Convert.ToInt32(dvD[0]["F_NumParam1"]);
                    }
                    else
                    {
                        _NumParam1 = 0;
                    }
                    if (dvD[0]["F_NumParam2"] != DBNull.Value)
                    {
                        _NumParam2 = Convert.ToInt32(dvD[0]["F_NumParam2"]);
                    }
                    else
                    {
                        _NumParam2 = 0;
                    }
                    if (dvD[0]["F_NumParam3"] != DBNull.Value)
                    {
                        _NumParam3 = Convert.ToInt32(dvD[0]["F_NumParam3"]);
                    }
                    else
                    {
                        _NumParam3 = 0;
                    }
                    if (dvD[0]["F_NumParam4"] != DBNull.Value)
                    {
                        _NumParam4 = Convert.ToInt32(dvD[0]["F_NumParam4"]);
                    }
                    else
                    {
                        _NumParam4 = 0;
                    }
                    if (dvD[0]["F_NumParam5"] != DBNull.Value)
                    {
                        _NumParam5 = Convert.ToInt32(dvD[0]["F_NumParam5"]);
                    }
                    else
                    {
                        _NumParam5 = 0;
                    }
                    if (dvD[0]["F_NumParam6"] != DBNull.Value)
                    {
                        _NumParam6 = Convert.ToInt32(dvD[0]["F_NumParam6"]);
                    }
                    else
                    {
                        _NumParam6 = 0;
                    }
                    if (dvD[0]["F_TxtParam"] != DBNull.Value)
                    {
                        _TxtParam = dvD[0]["F_TxtParam"].ToString();
                    }
                    else
                    {
                        _TxtParam = "-";
                    }
                    _serialNumber = Convert.ToInt32(dvD[0]["F_SerialNumber"]);
                    _routeID = Convert.ToInt32(dvD[0]["F_RouteID"]);
                    _DeviceIdx = Convert.ToInt32(dvD[0]["F_DeviceIndex"]);
                    _DeviceOrder = Convert.ToInt32(dvD[0]["F_DeviceCommandIndex"]);
                    _ManageKindIdx = Convert.ToInt32(dvD[0]["F_ManageTaskKindIndex"]);
                    _ManageTaskIdx = Convert.ToInt32(dvD[0]["F_ManageTaskIndex"]);
                    _DeviceKind = Convert.ToInt32(dvD[0]["F_DeviceKindIndex"]);
                    if (dvD[0]["F_OutsideAltDevice"] != DBNull.Value)
                    {
                        _OutsideAltDevice = Convert.ToInt32(dvD[0]["F_OutsideAltDevice"]);
                    }
                    else 
                    {
                        _OutsideAltDevice = 0;
                    }
                    if (dvD[0]["F_InsideAltDevice"] != DBNull.Value)
                    {
                        _InsideAltDevice = Convert.ToInt32(dvD[0]["F_InsideAltDevice"]);
                    }
                    else
                    {
                        _InsideAltDevice = 0;
                    }
                    _StartDevice = Convert.ToInt32(dvD[0]["F_StartDevice"]);
                    _EndDevice = Convert.ToInt32(dvD[0]["F_EndDevice"]);
                    _RouteKind = Convert.ToInt32(dvD[0]["F_RouteKind"]);
                    if (dvD[0]["F_CorrelDoubleFork"] != DBNull.Value)
                    {
                        _CorrelDoubleFork = Convert.ToInt32(dvD[0]["F_CorrelDoubleFork"]);
                    }
                    else
                    {
                        _CorrelDoubleFork = -1;
                    }
                    if (dvD[0]["F_AgvNo"] != DBNull.Value)
                    {
                        _AgvNo = Convert.ToInt32(dvD[0]["F_AgvNo"]);
                    }
                    else
                    {
                        _AgvNo = 65535;
                    }
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                dvD = null;
            }
        }
        /// <summary>
        /// 发送指定调度任务号的命令
        /// </summary>
        /// <param name="MonitorIndex"></param>
        /// <returns></returns>
        public bool SendMonitorTask(int MonitorIndex)
        {
            
            lock (thisLock)
            {
                char[] sep = new char[1] { '-' };
                int msgIdx = 0;//消息编号
                bool sendok;
                //string aa222 = DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();
                #region 双叉关联设备指令，如果不能同步执行，发送距离堆垛机当前位置近的设备指令
                MonitorIndex = GetDoubleForkMinRouteTask(MonitorIndex);
                #endregion
                //string aa22 = DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();
                //获得要发送的信息
               // 20121014
                if (GetSendInfo(MonitorIndex) == false) { return false; }

                #region 手工任务

                if (ccf.GetManageTaskKindIndexFromMonitor(MonitorIndex) == 4)
                {
                    //20120915
                   // if (AheadDetectOK(MonitorIndex, ccf.GetBeDetectedDevices(_DeviceIdx)) == false) 
                    if (AheadDetectOK(MonitorIndex, ccf.GetBeDetectedDevices(_DeviceIdx)) == false) //不符合运行条件
                    {
                        return false;
                    }

                    //CStaticClass.MessageIndex++;
                    CStaticClass.MessageIndex = 1;
                    msgIdx = (CStaticClass.MessageIndex);

                    sdo = CommModeCreate.CreateSendDeviceOrder(_DeviceIdx);

                    int[] gc = new int[6] {_NumParam2, _NumParam3, _NumParam1, _NumParam5, _NumParam6, _NumParam4 };

                    if ((_DeviceKind == 1) || (_DeviceKind == 6))
                    {

                        sendok = sdo.SendDeviceOrder(msgIdx, MonitorIndex, _DeviceOrder,
                            _DeviceIdx, gc[0], gc[1], gc[2], gc[3], gc[4], gc[5]);
                       // CommonClassLib.CCarryConvert.WriteDarkCasket("send", "1111", _DeviceIdx.ToString(), "------");

                    }
                    else if (_DeviceKind == 4)
                    {
                        if (ccf.NeedOptimize(_DeviceIdx) == true)
                        {
                            ccf.InsertMonitorOptimizeChildTask(MonitorIndex);
                            sendok = true;
                        }
                        else
                        {

                            sendok = sdo.SendDeviceOrder(msgIdx, MonitorIndex, _DeviceOrder, _DeviceIdx, gc[2]);
                        }

                    }
                    else
                    {


                        sendok = sdo.SendDeviceOrder(msgIdx, MonitorIndex, _DeviceOrder, _DeviceIdx, gc[5]);
                    }
                    if (sendok == false)
                    {
                        if (sdo.CommLayerError != null)
                        {
                            if (FrmControlMonitor.FormInstance.GetObjectText("tsStatus").IndexOf(sdo.CommLayerError) < 0)
                            {
                                FrmControlMonitor.FormInstance.FlashPanit("tsStatus", sdo.CommLayerError, true);

                            }
                        }
                        return false;
                    }
                    else
                    {
                        //////////////////////////
                        ccf.SendOrderSuccess(_ManageKindIdx, _ManageTaskIdx, MonitorIndex, _DeviceIdx, _routeID);
                        #region 双叉关联任务，能同步的同时报告发送命令成功
                        //20100323
                        devinfo = Model.CGetInfo.GetDeviceInfo(_DeviceIdx);
                        if (devinfo.IfCorrelDoubleFork == "1")
                        {
                            if (Model.CGeneralFunction.DoubleForkIfSync(MonitorIndex, _DeviceIdx, _DeviceKind) == true)
                            {
                                string[] df = Model.CGeneralFunction.GetDoubleForkMonitorInfo(MonitorIndex, _DeviceIdx);
                                if (df != null)
                                {
                                    ccf.SendOrderSuccess(ccf.GetManageTaskKindIndexFromMonitor(Convert.ToInt32(df[0])), ccf.GetManageTaskIndexfromMonitor(Convert.ToInt32(df[0])), Convert.ToInt32(df[0]), Convert.ToInt32(df[2]), Convert.ToInt32(df[3]));
                                    //dbo.ExceSQL("update T_Monitor_Task set F_CorrelDoubleFork=" + df[0] + " where F_MonitorIndex=" + MonitorIndex + "");
                                    //dbo.ExceSQL("update T_Monitor_Task set F_CorrelDoubleFork=" + MonitorIndex + " where F_MonitorIndex=" + df[0] + "");
                                }
                            }
                        }
                        #endregion
                        return true;
                    }

                }

                #endregion

                #region 自动命令(taskkind == 1，2)
                //(taskkind == 1，2)自动命令和临时管理管理命令
                ///////////////////////////////////////
                //2--6应该做递归调用函数
                ///////////////////////////////////////
                /////////////////////
                //20100208
                #region 环形穿梭车RGV分配车号修改提前检测

                #endregion
                ////////////////////


                //2：提取每个管理单据的第一个设备状态
                //string aa221 = DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();

                if (GetFirstDeviceIFLocked(MonitorIndex, true) == false)//没有被锁定，空闲
                {
                  
                    
                    //7：发送此设备命令
                    //CStaticClass.MessageIndex++;
                    CStaticClass.MessageIndex = 1;
                    msgIdx = (CStaticClass.MessageIndex);
                    sdo = CommModeCreate.CreateSendDeviceOrder(_DeviceIdx);
                    //判断设备是否为堆垛机RGV和ＡＧＶ
                    int[] gc = new int[6] { _NumParam2, _NumParam3, _NumParam1, _NumParam5, _NumParam6, _NumParam4 };//获得坐标
                    if (gc == null)
                    {
                        this._CControlError += "发送命令时不能取得设备坐标！";
                        return false;
                    }
                    if ((_DeviceKind == 1) || (_DeviceKind == 6))
                    {

                        //1：堆垛机；4：RGV；6：AGV如果需要优化调度（设备表的F_NeedOptimize='1'）
                        //直接写入表：T_Monitor_Task_Child，不发送命令
                        if (ccf.NeedOptimize(_DeviceIdx) == true)
                        {
                            ccf.InsertMonitorOptimizeChildTask(MonitorIndex);
                            sendok = true;
                        }
                        else
                        {
                            sendok = sdo.SendDeviceOrder(msgIdx, MonitorIndex, _DeviceOrder,
                                _DeviceIdx, gc[0], gc[1], gc[2], gc[3], gc[4], gc[5]);
                        }


                    }
                    else if (_DeviceKind == 4) // RGV穿梭车
                    {
                        if (ccf.NeedOptimize(_DeviceIdx) == true)
                        {
                            ccf.InsertMonitorOptimizeChildTask(MonitorIndex);
                            sendok = true;
                        }
                        else
                        {
                            sendok = sdo.SendDeviceOrder(msgIdx, MonitorIndex, _DeviceOrder, _DeviceIdx, gc[2]);
                        }

                    }
                    else
                    {
                        sendok = sdo.SendDeviceOrder(msgIdx, MonitorIndex, _DeviceOrder, _DeviceIdx, gc[5]); // 输送机的发生指令  _NumParam4参数表示目标位置
                        if (_DeviceOrder == 7 || _DeviceOrder == 8)
                        {
                           // cgs.ActionComplete(_DeviceIdx, MonitorIndex, 1);
                        }
                       
                    }


                    if (sendok == false)
                    {
                        if (sdo.CommLayerError != null)
                        {
                            if (FrmControlMonitor.FormInstance.GetObjectText("tsStatus").IndexOf(sdo.CommLayerError) < 0)
                            {

                                FrmControlMonitor.FormInstance.FlashPanit("tsStatus", sdo.CommLayerError, true);
                            }
                        }
                        return false;
                    }
                    else//发送命令成功
                    {
                        //////////////////////////
                        dbo.ExecuteSql("update T_Monitor_Task set F_SendFlag='1' where F_MonitorIndex=" + MonitorIndex);//20100905只重发主任务
                        ccf.SendOrderSuccess(_ManageKindIdx, _ManageTaskIdx, MonitorIndex, _DeviceIdx, _routeID);
                        #region 双叉关联任务，能同步的同时报告发送命令成功
                        //20100323
                        devinfo = Model.CGetInfo.GetDeviceInfo(_DeviceIdx);
                        if (devinfo.IfCorrelDoubleFork == "1")
                        {
                            if (Model.CGeneralFunction.DoubleForkIfSync(MonitorIndex, _DeviceIdx, _DeviceKind) == true)
                            {
                                string[] df = Model.CGeneralFunction.GetDoubleForkMonitorInfo(MonitorIndex, _DeviceIdx);
                                if (df != null)
                                {
                                    ccf.SendOrderSuccess(ccf.GetManageTaskKindIndexFromMonitor(Convert.ToInt32(df[0])), ccf.GetManageTaskIndexfromMonitor(Convert.ToInt32(df[0])), Convert.ToInt32(df[0]), Convert.ToInt32(df[2]), Convert.ToInt32(df[3]));
                                    //dbo.ExceSQL("update T_Monitor_Task set F_CorrelDoubleFork=" + df[0] + " where F_MonitorIndex=" + MonitorIndex + "");
                                    //dbo.ExceSQL("update T_Monitor_Task set F_CorrelDoubleFork=" + MonitorIndex + " where F_MonitorIndex=" + df[0] + "");
                                }
                            }
                        }
                        #endregion
                        return true;
                    }
                }
                else
                {
                    return false;
                }

                #endregion
            }
        }

        int GetDeviceFromMonitor(int monitorIndex)
        {
            DataView dv = dbo.ExceSQL("SELECT F_MonitorIndex, F_DeviceIndex FROM T_Monitor_Task WHERE (F_MonitorIndex = " + monitorIndex + ")").Tables[0].DefaultView;
            if (dv.Count > 0)
            {
                return Convert.ToInt32(dv[0]["F_DeviceIndex"]);
            }
            else
            {
                return -1;
            }
        }

        /// <summary>
        /// 获取可用的目标位置：入库的巷道或者出库站台
        /// </summary>
        /// <param name="manageTaskIdx">调度任务索引</param>
        /// <param name="manageKindIdx">调度任务类别</param>
        /// <returns></returns>
        bool  GetUsableDestination(int manageTaskIdx,int manageKindIdx )
        {
            //20100610查找一个路径可用，任务数最少的终点设备
            Dictionary<int, int> advDev=new Dictionary<int,int>();
            object ob;


            DataView dv = dbo.ExceSQL("SELECT * FROM T_Manage_Task WHERE (FID = " + manageTaskIdx + ") AND (F_ManageTaskKindIndex = " + manageKindIdx + ")").Tables[0].DefaultView;
            if (dv.Count <= 0)
            {
                return false ;
            }
            DataRowView dr = dv[0];

            //20091107
            DataView dvIO = dboM.ExceSQL("select CONTROL_ID, CONTROL_STATUS from IO_Control where (CONTROL_ID = " + Convert.ToInt32(dr["FID"]) + ") AND ((CONTROL_STATUS=" + Model.CGeneralFunction.TASKALTERROUTEAPPLY + ") or (CONTROL_STATUS=" + Model.CGeneralFunction.TASKALTERROUTEREPLY + "))").Tables[0].DefaultView;
            if (dvIO.Count <= 0)
            {
                //只修申请改调度任务的路径，不修改调度自动任务路径
                if (dr["F_ManageTaskKindIndex"].ToString() != "1") return false;
                string sql = "";
                string adviceDev = "";
                DataTable dtd = dbo.ExceSQL("SELECT F_TASKKIND, F_DESTINATION FROM T_Base_Destination WHERE (F_TASKKIND = " + dr["FCONTROLTASKTYPE"] + ") and (F_AbendStation=1) and (F_DESTINATION=" + dr["FENDDEVICE"] + ")").Tables[0];
                if (dtd.Rows.Count > 0)//原来终点是应急站台那么还分配这个站台，不需要改变
                {
                    adviceDev = dtd.Rows[0]["F_DESTINATION"].ToString();
                    return false;
                }
                else
                {
                    //查找可用目标位置
                    DataTable dt = dbo.ExceSQL("SELECT F_TASKKIND, F_DESTINATION FROM T_Base_Destination WHERE (F_TASKKIND = " + dr["FCONTROLTASKTYPE"] + ") and (F_DESTINATION <>" + dr["FENDDEVICE"] + ") and (F_AbendStation=0)").Tables[0];
                    if (dt.Rows.Count > 0)
                    {
                        for (int i = 0; i < dt.Rows.Count; i++)
                        {
                            if (CDisassembleTask.MinRouteID(Convert.ToInt32(dr["FSTARTDEVICE"]), Convert.ToInt32(dt.Rows[i]["F_DESTINATION"]), dr["FUseAwayFork"]) != -1)
                            {

                                //20100610统计到终点设备正在执行的任务数
                                ob = dbo.GetSingle("SELECT count(FENDDEVICE) as counts FROM T_Manage_Task where FENDDEVICE='" + dt.Rows[i]["F_DESTINATION"] + "' and fstatus>0");
                                advDev.Add(Convert.ToInt32(dt.Rows[i]["F_DESTINATION"]),Convert.ToInt32(ob));

                                //20100610 break;
                            }
                        }
                        if (advDev.Count == 0)//20100610
                        {

                            return false;


                        }
                        else
                        {//20100610
                            int mincount=9999;
                            foreach (int aaa in advDev.Keys)
                            {
                                if (advDev[aaa] < mincount)
                                {
                                    mincount = advDev[aaa];
                                    adviceDev = aaa.ToString();
                                }
                            }
                            if (adviceDev == "")
                            {

                                return false;

                            }
                        }
                    }
                    else
                    {//20100610
                        return false;
                    }
                }

                //DataView DV = dboM.ExceSQL("select IO_CONTROL_APPLY_SEQ.NEXTVAL FROM DUAL").Tables[0].DefaultView;
                //20101108int fid = dboM.GetManageTableIndex("IO_CONTROL_APPLY");
                string dtime = DateTime.Now.ToString("u");
                dtime = dtime.Substring(0, dtime.Length - 1);
                //20091128
                dboM.TransBegin();
                try
                {
                    dboM.ExceSQL(" update IO_CONTROL set CONTROL_STATUS="+Model.CGeneralFunction.TASKALTERROUTEAPPLY+" where CONTROL_ID=" + dr["FID"] + "");
                    //向管理申请修改任务//20101108CONTROL_APPLY_ID, " + fid + ",
                    sql = "INSERT INTO IO_CONTROL_APPLY ( CONTROL_ID,CONTROL_APPLY_TYPE,WAREHOUSE_CODE, STOCK_BARCODE, DEVICE_CODE, APPLY_TASK_STATUS, CREATE_TIME, " +
                            " CONTROL_APPLY_REMARK)" +
                    "VALUES (" + dr["FID"] + ",2,'" + dr["FSTARTWAREHOUSE"] + "','" + dr["FPALLETBARCODE"] + "','" + adviceDev + "',0,'" + dtime + "',null)";
                    
                    dboM.ExceSQL(sql);
                    dboM.TransCommit();
                    //把ManageTaskIdx，ManageKindIdx 的调度任务全部申请改道
                    dbo.ExceSQL("UPDATE T_Monitor_Task SET  F_Status = 3 WHERE (F_ManageTaskIndex = " + manageTaskIdx + ") AND (F_ManageTASKKINDINDEX =" + manageKindIdx + ")");
                    return true;
                }
                catch (Exception ex)
                {
                    _CControlError = "发送指令，申请改道时：" + ex.Message;
                    dboM.TransRollback();
                    return false;
                }
                                    
                    
            }
            else
            {
                return false;

            }
        }
        /// <summary>
        /// 获取RGV空闲无物可用的目标位置：入库的巷道或者出库站台
        /// </summary>
        /// <param name="manageTaskIdx">调度任务索引</param>
        /// <param name="manageKindIdx">调度任务类别</param>
        /// <param name="IfUseNegativeDevice">是否可以选择负数设备索引。负数代表当前设备前面的设备（环形RGV行走方向的反方向）</param>
        /// <returns></returns>
        bool GetRGVIdleDestination(int manageTaskIdx, int manageKindIdx,int RGVGateDevice, bool IfUseNegativeDevice)
        {

            //20100610 t_Base_device 表F_UsableEndDevice字段存放入库或者出库对等的设备索引组（以分号隔开）：
            //负数代表位于当前设备前面（环形RGV行走方向的反方向），只允许在发送RGV取货和第一、二个运动时使用；
            //正数代表当前设备后面的设备，可以在发送送货和之前的所有命令使用.直道RGV都是正数。
            //T_Base_RGV_Gate新增字段“F_EndDevice”用于记载入库时靠近巷道一侧的RGV出入口输送机的对应的巷道设备索引
            //或者出库时靠近出库站台一侧的输送机对应的出库站台索引

            //可变更目标位置的选择原则：RGV目标位置空闲、无物；目标位置参与的正在执行的调度任务数最少

            DataView dv;
            DataRowView dr;
            string sql = "";
            string adviceDev = "";
            char[] cc = new char[1] { ';' };
            string[] sp;
            DataView dvIO;
            Dictionary<int, int> advDev=new Dictionary<int,int>();
            object ob;

            try
            {
                dv = dbo.ExceSQL("SELECT * FROM T_Manage_Task WHERE (FID = " + manageTaskIdx + ") AND (F_ManageTaskKindIndex = " + manageKindIdx + ")").Tables[0].DefaultView;
                if (dv.Count <= 0)
                {
                    return false;
                }
                dr = dv[0];
                //只修申请改调度任务的路径，不修改调度自动任务路径
                if (dr["F_ManageTaskKindIndex"].ToString() != "1") return false;
                dvIO = dboM.ExceSQL("select CONTROL_ID, CONTROL_STATUS from IO_Control where (CONTROL_ID = " + Convert.ToInt32(dr["FID"]) + ") AND ((CONTROL_STATUS=" + Model.CGeneralFunction.TASKALTERROUTEAPPLY + ") or (CONTROL_STATUS=" + Model.CGeneralFunction.TASKCANCEL + ") or(CONTROL_STATUS=" + Model.CGeneralFunction.TASKALTERROUTEREPLY + "))").Tables[0].DefaultView;
                if (dvIO.Count <= 0)
                {

                    #region 根据T_Base_Device表的F_UsableEndDevice查找可用终点设备
                    DataView dvu = dbo.ExceSQL("select F_UsableEndDevice from T_Base_Device where F_UsableEndDevice is not null and F_DeviceIndex=" + RGVGateDevice + "").Tables[0].DefaultView;
                    if (dvu.Count > 0)
                    {
                        int enddv = 0, DESTINATION = 0;
                        sp = dvu[0]["F_UsableEndDevice"].ToString().Split(cc);

                        for (int i = sp.GetLowerBound(0); i <= sp.GetUpperBound(0); i++)
                        {
                            if (Microsoft.VisualBasic.Information.IsNumeric(sp[i]) == false) continue;
                            enddv = Convert.ToInt32(sp[i]);
                            if (enddv < 0)
                            {
                                //负数代表当前设备前面的设备（环形RGV行走方向的反方向）
                                if (IfUseNegativeDevice == true)
                                {
                                    enddv = -(enddv);
                                }
                                else
                                {
                                    continue;
                                }
                            }
                            devinfo = Model.CGetInfo.GetDeviceInfo(enddv);
                            if ((devinfo.HaveGoods == true)||(devinfo.RunState==2))
                            {//目标位置被占用或者故障
                                continue;
                            }
                            ob = dbo.GetSingle("SELECT F_EndDevice FROM T_Base_RGV_Gate WHERE (F_RGVGateDeviceIndex = " + enddv + ") AND (F_EndDevice IS NOT NULL)");
                            if (ob == null) continue;
                            DESTINATION = Convert.ToInt32(ob);
                            if (CDisassembleTask.MinRouteID(Convert.ToInt32(dr["FSTARTDEVICE"]), DESTINATION) != -1)
                            {
                                //20100609统计到终点设备正在执行的任务数
                                ob = dbo.GetSingle("SELECT count(FENDDEVICE) as counts FROM T_Manage_Task where FENDDEVICE='" + DESTINATION + "' and fstatus>0");
                                advDev.Add(DESTINATION, Convert.ToInt32(ob));

                            }

                        }
                    }
                    else
                    {
                        return false;
                    }
                    dvu = null;
                    if (advDev.Count<=0)
                    {
                        return false;
                    }
                    else
                    {
                        int mincount = 9999;
                        foreach (int aaa in advDev.Keys)
                        {
                            if (advDev[aaa] < mincount)
                            {
                                mincount = advDev[aaa];
                                adviceDev = aaa.ToString();
                            }
                        }
                        if (adviceDev == "")
                        {

                            return false;

                        }
                    }
                    #endregion

                    //20101108int fid = dboM.GetManageTableIndex("IO_CONTROL_APPLY");
                    string dtime = DateTime.Now.ToString("u");
                    dtime = dtime.Substring(0, dtime.Length - 1);

                    dboM.TransBegin();
                    try
                    {
                       
                        dboM.ExceSQL(" update IO_CONTROL set CONTROL_STATUS=" + Model.CGeneralFunction.TASKALTERROUTEAPPLY + " where CONTROL_ID=" + dr["FID"] + " and CONTROL_STATUS<>" + Model.CGeneralFunction.TASKCANCEL + "");
                        //向管理申请修改任务//20101108CONTROL_APPLY_ID," + fid + ",
                        sql = "INSERT INTO IO_CONTROL_APPLY ( CONTROL_ID, WAREHOUSE_CODE, STOCK_BARCODE, DEVICE_CODE, APPLY_TASK_STATUS, CREATE_TIME,CONTROL_APPLY_REMARK)" +
                        "VALUES (" + dr["FID"] + ",'" + dr["FENDWAREHOUSE"] + "','" + dr["FPALLETBARCODE"] + "','" + adviceDev + "',0,'" + dtime + "',null)";
                        dboM.ExceSQL(sql);
                        dboM.TransCommit();
                        //把ManageTaskIdx，ManageKindIdx 的调度任务全部申请改道
                        dbo.ExceSQL("UPDATE T_Monitor_Task SET  F_Status = 3 WHERE (F_ManageTaskIndex = " + manageTaskIdx + ") AND (F_ManageTASKKINDINDEX =" + manageKindIdx + ")");

                        return true;
                    }
                    catch (Exception ex)
                    {
                        dboM.TransRollback();
                        _CControlError = "发送指令，申请改道时：" + ex.Message;
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                _CControlError = "发送指令，申请改道时：" + ex.Message;
                return false;
            }
            finally
            {
                dv = null;
                dr = null;
                cc = null;
                sp = null;
                dvIO = null;
            }
        }
        /// <summary>
        /// 返回在顶升处入库任务可以双叉关联的调度任务索引
        /// </summary>
        /// <param name="controlTaskType">控制任务类型</param>
        /// <param name="devindex">设备索引</param>
        /// <returns></returns>
        int GetEnableDoubleForkManageTask(int controlTaskType, int devindex,int FID)
        {
            DataView dv0;
            string sql = "SELECT F_MonitorIndex,T_Monitor_Task.F_ManageTaskIndex,T_Monitor_Task.F_ManageTASKKINDINDEX FROM T_Monitor_Task ,T_Manage_Task where T_Monitor_Task.F_ManageTaskIndex = T_Manage_Task.FID AND T_Monitor_Task.F_ManageTASKKINDINDEX = T_Manage_Task.F_ManageTaskKindIndex AND F_DeviceIndex=" + devindex + " and FCONTROLTASKTYPE=" + controlTaskType;
            DataView dv = dbo.ExceSQL(sql).Tables[0].DefaultView;
            if (dv.Count > 0)
            {
                for (int i = 0; i < dv.Count; i++)
                {
                    dv0 = dbo.ExceSQL("select min(F_MonitorIndex) as mm from T_Monitor_Task where F_ManageTaskIndex=" + dv[i]["F_ManageTaskIndex"] + " and F_ManageTASKKINDINDEX=" + dv[i]["F_ManageTASKKINDINDEX"] + " ").Tables[0].DefaultView;
                    if (dv0.Count > 0)
                    {
                        if (dv0[0]["mm"].ToString() == dv[i]["F_MonitorIndex"].ToString())
                        {
                            if (FID != Convert.ToInt32(dv[i]["F_ManageTaskIndex"]))
                            {
                                return Convert.ToInt32( dv[i]["F_ManageTaskIndex"]);
                            }
                        }
                    }
                }
                return -1;
            }
            else
            {
                return -1;
            }
        }
        /// <summary>
        /// 获得堆垛机在对等站台取货的双叉关联任务
        /// </summary>
        /// <param name="controlTaskType">控制任务类型</param>
        /// <param name="Stackdevindex">堆垛机设备索引</param>
        /// <param name="StationDevice">站台设备索引</param>
        /// <param name="FID">调度任务索引</param>
        /// <returns></returns>
        int GetEnableDoubleForkManageTask(int controlTaskType, int Stackdevindex,int StationDevice, int FID)
        {
            DataView dv1 = dbo.ExceSQL("SELECT F_ZXY FROM T_Base_Lane_Gate,T_Base_LaneInfo WHERE "+
                "(T_Base_Lane_Gate.F_LaneIndex = T_Base_LaneInfo.F_LaneDeviceIndex) and (T_Base_LaneInfo.F_StackIndex = " +
                Stackdevindex + ") and (F_LaneGateDeviceIndex=" + StationDevice + ")").Tables[0].DefaultView;
            if (dv1.Count <= 0) return -1;
            char[] cc = new char[1] {'-' };
            string[] zxy = dv1[0]["F_ZXY"].ToString().Split(cc);
            DataView dv0;
            string sql = "SELECT F_MonitorIndex,T_Monitor_Task.F_ManageTaskIndex,T_Monitor_Task.F_ManageTASKKINDINDEX "+
                " FROM T_Monitor_Task ,T_Manage_Task where T_Monitor_Task.F_ManageTaskIndex = T_Manage_Task.FID AND "+
                "T_Monitor_Task.F_ManageTASKKINDINDEX = T_Manage_Task.F_ManageTaskKindIndex AND F_DeviceIndex=" +
                Stackdevindex + " and FCONTROLTASKTYPE=" + controlTaskType + " and F_NumParam1=" + zxy[0] + 
                " and F_NumParam2=" + zxy[1] + " and F_NumParam3=" + zxy[2] + "";
            DataView dv = dbo.ExceSQL(sql).Tables[0].DefaultView;
            if (dv.Count > 0)
            {
                for (int i = 0; i < dv.Count; i++)
                {
                    dv0 = dbo.ExceSQL("select min(F_MonitorIndex) as mm from T_Monitor_Task where F_ManageTaskIndex=" + dv[i]["F_ManageTaskIndex"] + " and F_ManageTASKKINDINDEX=" + dv[i]["F_ManageTASKKINDINDEX"] + " ").Tables[0].DefaultView;
                    if (dv0.Count > 0)
                    {
                        if (dv0[0]["mm"].ToString() == dv[i]["F_MonitorIndex"].ToString())
                        {
                            if (FID != Convert.ToInt32(dv[i]["F_ManageTaskIndex"]))
                            {
                                return Convert.ToInt32(dv[i]["F_ManageTaskIndex"]);
                            }
                        }
                    }
                }
                return -1;
            }
            else
            {
                return -1;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="Mankind">调度任务类型索引</param>
        /// <param name="FID">调度任务索引</param>
        /// <param name="ControlTaskType">调度任务类型</param>
        /// <param name="UseAwayFork">最后分配的远、近货叉</param>
        void AlterRoutePath(int Mankind,int FID,int ControlTaskType,char UseAwayFork,int NowDevice)
        {
            DataView dv; DataView dv1; DataView dvnew;
            
            //先找到以前的路径是否与最后分配的货叉匹配，不匹配的改道
            try
            {
                dv = dbo.ExceSQL("SELECT  T_Monitor_Task.F_MonitorIndex,T_Monitor_Task.F_DeviceIndex FROM T_Monitor_Task,T_Base_Route_Device where "+
                    " T_Monitor_Task.F_RouteID = T_Base_Route_Device.F_RouteIDSub AND T_Monitor_Task.F_DeviceIndex = T_Base_Route_Device.F_DeviceIndex and T_Monitor_Task.F_ManageTaskIndex="+
                    FID+" and T_Monitor_Task.F_ManageTASKKINDINDEX="+Mankind+" and T_Base_Route_Device.F_UseAwayFork<>'"+UseAwayFork+"'").Tables[0].DefaultView;
                if (dv.Count > 0)
                {
                    dv = dbo.ExceSQL("select * from T_Manage_Task where F_ManageTaskKindIndex=" + Mankind + " and FID=" + FID).Tables[0].DefaultView;
                    if (dv.Count > 0)
                    {
                        //20100702
                        string sql = "SELECT T_Base_Route_Device.F_RouteIDSub FROM T_Base_Route,T_Base_Route_Device where T_Base_Route.F_RouteID = T_Base_Route_Device.F_RouteID " +
                            " and (T_Base_Route_Device.F_UseAwayFork = '" + UseAwayFork + "') AND (T_Base_Route_Device.F_DeviceIndex = " + NowDevice + ") AND (T_Base_Route.F_StartDevice = " +
                            dv[0]["FSTARTDEVICE"] + ") AND (T_Base_Route.F_EndDevice = " + dv[0]["FENDDEVICE"] + " and F_RouteKind="+ControlTaskType+")";
                        dv1 = dbo.ExceSQL(sql).Tables[0].DefaultView;
                        if (dv1.Count > 0)
                        {
                            int routeidNew=Convert.ToInt32( dv1[0][0]);
                            //删除原来的申请修改路径任务，拆分新的任务并且只保留现有设备开始的任务
                            dbo.ExceSQL("DELETE FROM T_Monitor_Task WHERE (F_ManageTaskIndex = " + FID + ") AND (F_ManageTASKKINDINDEX ="+Mankind+")");
                            if (CDisassembleTask.CreateMonitor(Mankind, FID, routeidNew, dv[0], 3) > 0)
                            {
                                dvnew = dbo.ExceSQL("SELECT F_MonitorIndex FROM T_Monitor_Task WHERE (F_ManageTaskIndex = " +
                                                FID + ") AND (F_ManageTASKKINDINDEX = "+Mankind+") AND (F_DeviceIndex = " +
                                                NowDevice + ") AND (F_RouteID = " + routeidNew +
                                                ") AND (F_Status = 3) ").Tables[0].DefaultView;
                                if (dvnew.Count > 0)
                                {
                                    dbo.ExceSQL("delete from T_Monitor_Task where F_MonitorIndex<" + dvnew[0]["F_MonitorIndex"] + " and (F_ManageTaskIndex = " +
                                    FID + ") AND (F_ManageTASKKINDINDEX = "+Mankind+") AND (F_Status = 3)");
                                    
                                    dbo.ExceSQL("update  T_Monitor_Task set F_Status =0 where  (F_ManageTaskIndex = " +
                                    FID + ") AND (F_ManageTASKKINDINDEX = "+Mankind+") AND (F_Status = 3)");


                                }
                            }
                        }
                        
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                dv = null;
                dv1 = null;
                dvnew = null;
            }
        }
        int GetDoubleForkMinRouteTask(int taskno)
        {
            DataView dv;
            //不是双叉的直接返回taskno；是双叉但是可以同步的直接返回taskno
            //双叉不能同步的反馈距离当前堆垛机位置最短的taskno
            
            int manKind=Model.CGeneralFunction.GetManageTaskKindIndexFromMonitor(taskno);
            int manFid=Model.CGeneralFunction.GetManageTaskIndexfromMonitor(taskno);
            int deviceindex = Model.CGeneralFunction.GetDeviceIndexFromMonitor(taskno);
            int devKind=Model.CGeneralFunction.GetDeviceKindIdx(deviceindex);
            int devOrder = Model.CGeneralFunction.GetDeviceOrderFromMonitor(taskno);
            
            devinfo = Model.CGetInfo.GetDeviceInfo(deviceindex);
           // string aa1212q = DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();
            int nX=Model.CGeneralFunction.GetXCoorFromMonitor(taskno,deviceindex,devOrder);
            int nY=Model.CGeneralFunction.GetYCoorFromMonitor(taskno,deviceindex,devOrder);
           // string aa212q = DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();
            double  nXY = 0, doubleXY = 0;
            int doubleX=Model.CGeneralFunction.GetDoubleForkX(manKind,manFid,deviceindex,devOrder);
            //string aa212 = DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();
            int doubleY=Model.CGeneralFunction.GetDoubleForkY(manKind,manFid,deviceindex,devOrder);
           // string aa122 = DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();
            if (devinfo.IfCorrelDoubleFork == "1")
            {
                string[] df = Model.CGeneralFunction.GetDoubleForkMonitorInfo(taskno, deviceindex);
                if(df==null)return taskno;
                if (Model.CGeneralFunction.DoubleForkIfSync(taskno, deviceindex, devKind) == false)
                {
                    #region 关联指令不是第一个指令不能发送
                    int rmankind = Model.CGeneralFunction.GetManageTaskKindIndexFromMonitor(Convert.ToInt32(df[0]));
                    int rman = Model.CGeneralFunction.GetManageTaskIndexfromMonitor(Convert.ToInt32(df[0]));
                    dv = dbo.ExceSQL("SELECT MIN(F_MonitorIndex) AS mmi FROM dbo.T_Monitor_Task WHERE (F_ManageTaskIndex = " + rman + ") AND (F_ManageTASKKINDINDEX = " + rmankind + ")").Tables[0].DefaultView;
                    if (dv.Count > 0)
                    {
                        if ((dv[0]["mmi"] != DBNull.Value) && (dv[0]["mmi"].ToString() != df[0]))
                        {
                            return taskno;
                        }
                    }
                    #endregion
                    if (devKind == 1)//堆垛机
                    {//如果存在倒库货位，则后执行该任务
                        if(devOrder==5)//送货指令时判断20110425
                        {
                            if (false == IfExcuteFirst(taskno))
                            {
                                return Convert.ToInt32(df[0]);
                            }
                            if (false == IfExcuteFirst(Convert.ToInt32(df[0])))
                            {
                                return taskno;
                            }

                        }
                        nXY = Math.Pow((double)(nX - devinfo.XCoor), 2) + (Math.Pow((double)(nY - devinfo.YCoor), 2));
                        doubleXY = Math.Pow((double)(doubleX - devinfo.XCoor), 2) + (Math.Pow((double)(doubleY - devinfo.YCoor), 2));
                        if (nXY < doubleXY)
                        {
                            return taskno;
                        }
                        else
                        {
                            return Convert.ToInt32(df[0]);
                        }
                    }
                    else if (devKind == 6)//AGV
                    {
                        nXY =Convert.ToInt32(dbo.GetSingle("SELECT F_Sequence FROM T_Base_AGV_Gate WHERE (F_AGVGateDeviceIndex = "+nX+")"));
                        doubleXY = Convert.ToInt32(dbo.GetSingle("SELECT F_Sequence FROM T_Base_AGV_Gate WHERE (F_AGVGateDeviceIndex = " + doubleX + ")"));
                        if (nXY < doubleXY)
                        {
                            return taskno;
                        }
                        else
                        {
                            return Convert.ToInt32(df[0]);
                        }
                    }
                    else
                    {
                        return taskno;
                    }
                }
                else
                {
                    return taskno;
                }

            }
            else
            {
                return taskno;
            }
        }

        int CountAGVTask(int taskno)
        {//大于2代表不能继续发送任务

            //每个AGV通道只允许有两组AGV任务（两个单一任务；两组双叉关联任务；一组双叉关联任务，一个单一任务）
            //F_status>0的任务数量小于2时，判断F_status>0的任务是否与taskno双叉关联，有关联则返回3，否则返回实际的任务个数；
            //F_status>0的任务数量大于或等于2时，返回3
            int devindex = GetDeviceFromMonitor(taskno);
            int devorder = ccf.GetDeviceOrderFromMonitor(taskno);
            int devStation=Model.CGeneralFunction.GetXCoorFromMonitor(taskno, devindex, devorder);
            string  bt = " < 3000 ";
            if (devStation < 3000)
            {//二楼
                bt = " < 3000 ";
            }
            else
            {//三楼
                bt = " > 3000 ";
            }
            int agvc = dbo.ExceSQL("SELECT F_MonitorIndex FROM T_Monitor_Task WHERE (F_Status > 0) AND (F_NumParam1 "+bt+") AND (F_DeviceIndex = 1001)").Tables[0].DefaultView.Count;
            if (agvc == 1)
            {
                if (Model.CGeneralFunction.GetDoubleForkMonitorInfo(taskno, devindex,0) ==true)
                {
                    return 3;
                }
                else
                {
                    return 0;
                }
            }
            else if (agvc == 0)
            {
                return 0;
            }
            else
            {
                return 3;
            }
        }

        bool IFAGVGate(int devIndex)
        {
            if (dbo.ExceSQL("SELECT F_AGVGateDeviceIndex FROM T_Base_AGV_Gate WHERE (F_AGVGateDeviceIndex = "+devIndex +")").Tables[0].DefaultView.Count > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 返回需要倒库更换货叉的倒库货位，“-”代表不需要更换货叉 20121030
        /// </summary>
        /// <param name="TaskIndex"></param>
        /// <returns></returns>
        string IfLimitCellChangeFork(int TaskIndex)
        {
        //    int[] zxy = ccf.GetCoordinatesFromMonitorTask(TaskIndex);
        //    int xCoor = zxy[4];
        //    string zxystr = (zxy[0].ToString().Length == 1 ? "0" + zxy[0].ToString() : zxy[0].ToString()) + "-" +
        //            ((zxy[1].ToString().Length == 1) ? ("0" + zxy[1].ToString()) : (zxy[1].ToString())) + "-" +
        //            ((zxy[2].ToString().Length == 1) ? ("0" + zxy[2].ToString()) : (zxy[2].ToString()));
        // //   string zxystr = (zxy[3].ToString().Length == 1 ? "0" + zxy[3].ToString() : zxy[3].ToString()) + "-" +
        // //((zxy[4].ToString().Length == 1) ? ("0" + zxy[4].ToString()) : (zxy[4].ToString())) + "-" +
        // //((zxy[5].ToString().Length == 1) ? ("0" + zxy[5].ToString()) : (zxy[5].ToString()));

        //    string UseAwayFork=Model.CGeneralFunction.GetUseAwayFork(TaskIndex);//1,远货叉；0，近货叉；'-'，没分配货叉
        //    //判断前极限货位，应该近货叉
        //    DataView dv = dbo.ExceSQL("SELECT F_MoveCellCode FROM T_Base_Lane_Gate,T_Base_LaneInfo where T_Base_Lane_Gate.F_LaneIndex = T_Base_LaneInfo.F_LaneDeviceIndex and (T_Base_LaneInfo.F_ForwardLimitX = " + xCoor + ") and F_ZXY='" + zxystr + "'").Tables[0].DefaultView;
        //  // DataView dv = dbo.ExceSQL("SELECT F_MoveCellCode FROM T_Base_LaneInfo where F_ForwardLimitX = " + xCoor + "").Tables[0].DefaultView;

        //    if (dv.Count > 0)
        //    {
        //        if (UseAwayFork == "1")
        //        {
        //            return dv[0]["F_MoveCellCode"].ToString();
        //        }
        //    }
        //    //判断后极限货位，应该远货叉
        //    dv = dbo.ExceSQL("SELECT F_MoveCellCode FROM T_Base_Lane_Gate,T_Base_LaneInfo where T_Base_Lane_Gate.F_LaneIndex = T_Base_LaneInfo.F_LaneDeviceIndex and (T_Base_LaneInfo.F_BackLimitX = " + xCoor + ") and F_ZXY='" + zxystr + "'").Tables[0].DefaultView;
        //    //dv = dbo.ExceSQL("SELECT F_MoveCellCode FROM T_Base_LaneInfo where F_BackLimitX = " + xCoor + "").Tables[0].DefaultView;

        //    if (dv.Count > 0)
        //    {
        //        if (UseAwayFork == "0")
        //        {
        //            return dv[0]["F_MoveCellCode"].ToString();
        //        }
        //    }

            return "-";
        }

        bool IfExcuteFirst(int TaskIndex)
        {
            int[] zxy = ccf.GetCoordinatesFromMonitorTask(TaskIndex);
            string zxystr = (zxy[3].ToString().Length == 1 ? "0" + zxy[0].ToString() : zxy[3].ToString()) + "-" +
                    ((zxy[4].ToString().Length == 1) ? ("0" + zxy[4].ToString()) : (zxy[4].ToString())) + "-" +
                    ((zxy[5].ToString().Length == 1) ? ("0" + zxy[5].ToString()) : (zxy[5].ToString()));

            DataView dv = dbo.ExceSQL("SELECT F_MoveCellCode FROM T_Base_LaneInfo WHERE (F_MoveCellCode = '" + zxystr + "')").Tables[0].DefaultView;
            if (dv.Count > 0)//倒库货位的任务后执行
            {
                return false;
            }
            return true;

        }
        /// <summary>
        /// 需要换叉的极限货位，把终点坐标改为倒库货位坐标
        /// </summary>
        /// <param name="taskindex">设备任务索引</param>
        /// <param name="ChangeForkCell">可更改货叉的倒库货位编码</param>
        void ChangeEndCellCode(int taskindex, string ChangeForkCell,int StackIndex)
        {
            char[] cc=new char[1]{'-'};
            string[] endCell = ChangeForkCell.Split(cc);
            int fid = ccf.GetManageTaskIndexfromMonitor(taskindex);
            int Mankind = ccf.GetManageTaskKindIndexFromMonitor(taskindex);
            //dbo.TransBegin();
            try
            {
                DataView dv = dbo.ExceSQL("SELECT F_LaneGateDeviceIndex FROM T_Base_Lane_Gate,T_Base_Device WHERE (T_Base_Lane_Gate.F_LaneGateDeviceIndex = T_Base_Device.F_DeviceIndex) and (F_ZXY = '" + ChangeForkCell + "')").Tables[0].DefaultView;
                if (dv.Count > 0)
                {

                    dbo.ExecuteSql("update T_Monitor_Task set F_AheadDetect=F_AheadDetect+'" + ";N" + dv[0]["F_LaneGateDeviceIndex"].ToString() + "', F_NumParam4=" + endCell[0] + ",F_NumParam5=" + endCell[1]
                        + ",F_NumParam6=" + endCell[2] + " where F_ManageTaskIndex=" + fid + " and F_ManageTASKKINDINDEX=" + Mankind + " and F_DeviceIndex=" + StackIndex);
                    dbo.ExecuteSql("update T_Manage_Task set FExceptionNO=" + Model.CGeneralFunction.TASKCHANGEFORK + " where FID=" + fid + " and F_ManageTaskKindIndex=" + Mankind);
                }
                    //dbo.TransCommit();
            }
            catch(Exception ex)
            {
                throw ex;
                //dbo.TransRollback();
            }
        }

        int GetIOControlStatus(int TaskIndex)
        {
            int mankind = ccf.GetManageTaskKindIndexFromMonitor(TaskIndex);
            int Fid = ccf.GetManageTaskIndexfromMonitor(TaskIndex);
            if (mankind == 1)
            {
                object ob=dboM.GetSingle("SELECT CONTROL_STATUS FROM IO_CONTROL WHERE (CONTROL_ID = "+Fid+")");
                if (ob != null)
                {
                    return Convert.ToInt32(ob);
                }
                else
                {
                    return Model.CGeneralFunction.TASKSINGLEFORKRUN;
                }
            }
            else
            {
                return Model.CGeneralFunction.TASKSINGLEFORKRUN;
            }
        }
        /// <summary>
        /// 返回AGV双叉的关联站台,“-1”代表没有关联
        /// </summary>
        /// <param name="taskindex">设备指令索引</param>
        /// <returns></returns>
        int GetAGVCorrelIndex(int taskindex)
        {
            object ob = dbo.GetSingle("SELECT F_NumParam2 FROM T_Monitor_Task WHERE (F_MonitorIndex = "+taskindex+")");
            if (ob != null)
            {
                int cs = Convert.ToInt32(ob);
                if (cs % 2 == 0)
                {
                    return (cs-1);
                }
                else
                {
                    return (cs + 1);
                }
            }
            else
            {
                return -1;
            }
        }
        /// <summary>
        /// 返回AGV在此站台取货的调度任务索引
        /// </summary>
        /// <param name="controltype">控制任务类型</param>
        /// <param name="stationIndex">AGV站台索引</param>
        /// <returns></returns>
        int GetAGVEnableDoubleForkManageTask(int controltype, int stationIndex)
        {
            string sql = "SELECT T_Monitor_Task.F_ManageTaskIndex  "+
                " FROM T_Monitor_Task ,T_Manage_Task where T_Monitor_Task.F_ManageTaskIndex = T_Manage_Task.FID AND "+
                "T_Monitor_Task.F_ManageTASKKINDINDEX = T_Manage_Task.F_ManageTaskKindIndex and FCONTROLTASKTYPE=" + 
                controltype + " and F_NumParam2=" + stationIndex + " and F_DeviceIndex=1001 and F_DeviceCommandIndex=1";
            DataView dv = dbo.ExceSQL(sql).Tables[0].DefaultView;
            if (dv.Count > 0)
            {
                return Convert.ToInt32(dv[0]["F_ManageTaskIndex"]);
            }
            else
                return -1;
        }
        bool IfInSameLimitX(int fid, int mfid,int manKind)
        {
            //DataView dv = dbo.ExceSQL("SELECT F_ForwardLimitX,F_BackLimitX,FEndCol FROM T_Manage_Task,T_Base_LaneInfo WHERE T_Manage_Task.FLANEWAY = T_Base_LaneInfo.F_LaneDeviceIndex and (F_ManageTaskKindIndex = " + manKind + ") AND (FID = " + fid + ")").Tables[0].DefaultView;
            //if (dv.Count == 0)
            //{
            //    return false;
            //}
            //DataView dv1 = dbo.ExceSQL("SELECT F_ForwardLimitX,F_BackLimitX,FEndCol FROM T_Manage_Task,T_Base_LaneInfo WHERE T_Manage_Task.FLANEWAY = T_Base_LaneInfo.F_LaneDeviceIndex and (F_ManageTaskKindIndex = " + manKind + ") AND (FID = " + mfid + ")").Tables[0].DefaultView;
            //if (dv1.Count == 0)
            //{
            //    return false;
            //}
            //if ((dv[0]["FEndCol"].ToString() == dv[0]["F_ForwardLimitX"].ToString()) && (dv1[0]["F_ForwardLimitX"].ToString() == dv1[0]["FEndCol"].ToString()))
            //{
            //    return true;
            //}
            //if ((dv[0]["FEndCol"].ToString() == dv[0]["F_BackLimitX"].ToString()) && (dv1[0]["F_BackLimitX"].ToString() == dv1[0]["FEndCol"].ToString()))
            //{
            //    return true;
            //}
            return false;
        }
    }
}
