using RGD.Common;
using RGD.DataService;
using RGD.DBUtility;
using RGD.Model;
using RGD.OPCClient;
using RGD.ZhiQianAPI;
using RGD.ZhiQianAPI.ZhiQianModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;

namespace RGD.WCS
{
    /// <summary>
    /// Creator:RGD
    /// 监控调度类
    /// </summary>
    public class CControl
    {
        private Object thisLock = new Object();
        private Model.MError errs;
        private Model.MDevice devinfo;
        private ISendDeviceOrder sdo;
        private StringBuilder AheadDetectUnallow = new StringBuilder();
        private CCommonFunction ccf = new CCommonFunction();
        private int _DeviceIdx = 0;//设备索引
        private int _routeID = 0;//路径唯一索引
        private int _serialNumber = 0;//路径上的设备方向性链表的序号
        private int _ManageTaskIdx = 0;//调度任务索引
        private int _ManageKindIdx = 0;//调度任务类型
        private int _DeviceOrder = 0;//设备命令
        private int _LockedState = 0;
        private int _Associate = 0;
        private int _ManTaskReserve = 0;
        private string _AheadDetect = "";
        private int _NumParam1 = 0;
        private int _NumParam2 = 0;
        private int _NumParam3 = 0;
        private int _NumParam4 = 0;
        private int _NumParam5 = 0;
        private int _NumParam6 = 0;
        private string _TxtParam = "-";
        private int _DeviceKind = 0;
        private int _OutsideAltDevice = 0;
        private int _InsideAltDevice = 0;
        private int _StartDevice = 0;
        private int _EndDevice = 0;
        private int _RouteKind = 0;
        private int _CorrelDoubleFork = -1;
        private int _AgvNo = 65535;
        private string _CControlError = "";//监控调度类错误说明
        private string _PickUpLocation = "0";

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

        public CControl()
        {
        }
        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里的所有对应设备索引加锁，但是关联设备不加锁           
            DataView taskDetail = DbHelperSQL.Query("select * from t_warehouse").Tables[0].DefaultView;
            string task_type = taskDetail[0]["F_TASK_TYPE"].ToString();
            string taskkind = " (F_ManageTaskKindIndex = 1 or F_ManageTaskKindIndex = 2 or F_ManageTaskKindIndex = 4) "; //调度任务与调度生成的自动任务
            //获得管理单据
            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 dvM = new DataView();
            string strM = "";
            if (task_type != "Inventory")
            {
                try
                {
                    char[] sep = new char[1] { '-' };
                    string taskType = string.Empty;
                    string aa = DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();
                    
                    
                    //在设备指令依次执行前,将拆分完成的所有出库任务的取货任务全部发送至AGV,且出库任务不需要追加任务,直接形成完整的任务组
                    //DataView allouttask = DbHelperSQL.Query("select * from T_Monitor_Task,T_Manage_Task where T_Monitor_Task.F_DeviceCommandIndex='4'and f_status='0' and T_Monitor_Task.F_ManageTaskIndex=T_Manage_Task.fid and T_Manage_Task.FCONTROLTASKTYPE='2'").Tables[0].DefaultView;
                    DataView outTaskCount = DbHelperSQL.Query("select * from t_manage_task where FCONTROLTASKTYPE=2 and FIntoStepOK='1' and fstatus=0").Tables[0].DefaultView;
                    if (outTaskCount.Count != 0)
                    {
                        for (int a = 0; a < outTaskCount.Count; a++)
                        {
                            List<BoxList> boxLists = new List<BoxList>();
                            if (a % 5 == 0 || a == 0)
                            {
                                CreateOrder createOrder = new CreateOrder();
                                createOrder.zoneid = 0;
                                createOrder.poolid = 1;
                                createOrder.orderno = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                                if ( a==outTaskCount.Count-1)
                                {
                                    createOrder.appendflag = false;
                                }
                                else
                                {
                                    createOrder.appendflag = true;
                                }

                                BoxList boxList = new BoxList();
                                boxList.src = outTaskCount[a]["FSTARTCELL"].ToString();
                                boxList.dst = "12004";
                                boxList.box = outTaskCount[a]["FPALLETBARCODE"].ToString();
                                boxList.rgsTaskId = int.Parse(outTaskCount[a]["FID"].ToString());
                                boxLists.Add(boxList);
                                createOrder.boxlist = boxLists;
                                if (boxLists.Count != 0)
                                {
                                    CreateOrderResponse createOrderResponse = SendDataToAgv.SendOutOrInvTasksToAgv(createOrder);

                                    if (createOrderResponse.code == "0")
                                    {
                                        //发送成功后,首先将该条任务置为执行中
                                        DbHelperSQL.ExecuteSql("update t_manage_task set FStatus = '1'  where fid="+ outTaskCount[a]["FID"]);
                                        DbHelperSQL.ExecuteSql("update t_monitor_task set F_Status = '2'  where f_status=0 and F_DeviceCommandIndex='4' and F_ManageTaskIndex="+ outTaskCount[a]["FID"]);
                                        FrmMain.taskId = createOrderResponse.result.taskid;
                                        //FrmMain.taskId = 1560;
                                    }
                                }

                            }
                            else
                            {
                                AppendOrder appendOrder = new AppendOrder();
                                appendOrder.taskid = FrmMain.taskId;
                                List<BoxList> list = new List<BoxList>();
                                BoxList boxList = new BoxList();
                                boxList.src = outTaskCount[a]["FSTARTCELL"].ToString();
                                boxList.dst = "12004";
                                boxList.box = outTaskCount[a]["FPALLETBARCODE"].ToString();
                                boxList.rgsTaskId = int.Parse(outTaskCount[a]["FID"].ToString());
                                list.Add(boxList);
                                appendOrder.boxlist = list;
                                AppendCompleteCancelResponse appendResponse = SendDataToAgv.SendSuperaddTaskToAgv(appendOrder);
                                //将取货任务置为正在执行
                                DbHelperSQL.ExecuteSql("update t_manage_task set FStatus = '2'  where fid=" + outTaskCount[a]["FID"]);
                                DbHelperSQL.ExecuteSql("update t_monitor_task set F_Status=2 where F_DeviceCommandIndex=4 and F_ManageTaskIndex=" + Convert.ToInt32(outTaskCount[0]["FID"]));
                                if(a== outTaskCount.Count-1 ||a%5==0)
                                {
                                    CompleteOrder completeOrder = new CompleteOrder();
                                    completeOrder.taskid = FrmMain.taskId;
                                    AppendCompleteCancelResponse completeResponse = SendDataToAgv.SendStopAppendTaskToAgv(completeOrder);
                                }
                            }
                            

                        }
                        
                    }
                    DataView dv = DbHelperSQL.Query(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 = DbHelperSQL.Query(strM).Tables[0].DefaultView;
                                //获取出入库任务类型
                                if (dvM.Count > 0 && dvM[0]["minMidx"] != DBNull.Value)
                                {
                                    //判断是入库还是出库任务
                                    DataView InOut = DbHelperSQL.Query("select * from t_manage_task where fid='" + dv[i]["MIndex"] + "'").Tables[0].DefaultView;
                                    //判断任务是否涉及AGV,若涉及,只发送取货任务,放货任务搁置,待AGV上报接口后再依次完成
                                    DataView isAgv = DbHelperSQL.Query("select * from t_monitor_task,t_manage_task where t_manage_task.fid=t_monitor_task.F_ManageTaskIndex and t_monitor_task.f_monitorindex='" + dvM[0]["minMidx"] + "' and F_Status = '0' and F_DeviceCommandIndex='4'").Tables[0].DefaultView;
                                    if (isAgv.Count != 0)
                                    {
                                        //入库任务
                                        if (InOut[0]["FCONTROLTASKTYPE"].ToString() == "1")
                                        {
                                            //入库任务首先判断是否是待执行的第一条任务,如果是第一条则使用下发运单接口,若不是使用追加接口
                                            //若agv正在入库,那么后续需要入库的第一个箱子也应该用下发而不是追加,所以需要判断此时设备指令是否还存在agv取货命令
                                            //其次判断是否是尾箱,需要根据调度任务的***字段来判断,***字段来源是射频返回的接口结果,将该结果放至生成的调度任务中
                                            //DataView isFirstManageTask = DbHelperSQL.Query("select * from t_manage_task where FCONTROLTASKTYPE=1 and FIntoStepOK='1'").Tables[0].DefaultView;
                                            DataView haveSendTask = DbHelperSQL.Query("select * from t_monitor_task where F_DeviceCommandIndex=5 and F_Status=0").Tables[0].DefaultView;
                                            DataView haveTakeTask = DbHelperSQL.Query("select * from t_monitor_task where F_DeviceCommandIndex=4 and F_Status=0").Tables[0].DefaultView;
                                            DataView monitorTask = DbHelperSQL.Query("select * from t_monitor_task").Tables[0].DefaultView;
                                            
                                            //需要添加叠盘机逻辑
                                            if (FrmMain.taskCount %5==0|| haveTakeTask.Count==0)//①没有正在执行的任务②有正在执行的任务但都在送货途中,只存在当前任务的取货任务
                                            {
                                                CreateOrder createFirstOrder = new CreateOrder();
                                                createFirstOrder.zoneid = 0;
                                                createFirstOrder.poolid = 1;
                                                createFirstOrder.orderno = DateTime.Now.ToString("yyyyMMddHHmmssfff");

                                                //createFirstOrder.appendflag = false;//货位测试用false
                                                createFirstOrder.appendflag = true;
                                                DataView RFIDCount = DbHelperSQL.Query("select * from T_InTask_QTY").Tables[0].DefaultView;
                                                if (RFIDCount.Count > 0)
                                                {
                                                    int number = int.Parse(RFIDCount[0]["count"].ToString());
                                                    if (number == 0)
                                                    {createFirstOrder.appendflag = false;
                                                    }
                                                }
                                                List<BoxList> list = new List<BoxList>();
                                                BoxList boxList = new BoxList();
                                                boxList.src = "12004";
                                                boxList.dst = InOut[0]["FENDCELL"].ToString();
                                                boxList.box = InOut[0]["FPALLETBARCODE"].ToString();
                                                boxList.rgsTaskId = int.Parse(InOut[0]["FID"].ToString());
                                                list.Add(boxList);
                                                createFirstOrder.boxlist = list;
                                                CreateOrderResponse createResponse = SendDataToAgv.SendFirstInTaskToAgv(createFirstOrder);
                                                FrmMain.taskId = createResponse.result.taskid;

                                                //将取货任务置为正在执行
                                                DbHelperSQL.ExecuteSql("update t_monitor_task set F_Status=2 where F_DeviceCommandIndex=4 and F_ManageTaskIndex=" + Convert.ToInt32(InOut[0]["FID"]));     
                                                
                                            }
                                            else//并非第一个任务,使用追加接口
                                            {
                                                AppendOrder appendOrder = new AppendOrder();
                                                appendOrder.taskid = FrmMain.taskId ;
                                                List<BoxList> list = new List<BoxList>();
                                                BoxList boxList = new BoxList();
                                                boxList.src = "12004";
                                                boxList.dst = InOut[0]["FENDCELL"].ToString();
                                                boxList.box = InOut[0]["FPALLETBARCODE"].ToString();
                                                boxList.rgsTaskId = int.Parse(InOut[0]["FID"].ToString());
                                                list.Add(boxList);
                                                appendOrder.boxlist = list;
                                                AppendCompleteCancelResponse appendResponse = SendDataToAgv.SendSuperaddTaskToAgv(appendOrder);
                                                //将取货任务置为正在执行
                                                DbHelperSQL.ExecuteSql("update t_monitor_task set F_Status=2 where F_DeviceCommandIndex=4 and F_ManageTaskIndex=" + Convert.ToInt32(InOut[0]["FID"]));
                                                //追加任务后需要判断是否是尾箱,若是尾箱,调用结束追加接口
                                                DataView RFIDCount = DbHelperSQL.Query("select * from T_InTask_QTY").Tables[0].DefaultView;
                                                if (RFIDCount.Count > 0)
                                                {
                                                    int number = int.Parse(RFIDCount[0]["count"].ToString());
                                                    if (number==0)
                                                    {
                                                        CompleteOrder completeOrder = new CompleteOrder();
                                                        completeOrder.taskid = FrmMain.taskId;
                                                        AppendCompleteCancelResponse completeResponse = SendDataToAgv.SendStopAppendTaskToAgv(completeOrder);
                                                    }
                                                }else if (InOut[0]["LAST_BOX_REMARK"].ToString() == "1")
                                                {

                                                    CompleteOrder completeOrder = new CompleteOrder();
                                                    completeOrder.taskid = FrmMain.taskId;
                                                    AppendCompleteCancelResponse completeResponse = SendDataToAgv.SendStopAppendTaskToAgv(completeOrder);
                                                }
                                            }
                                            FrmMain.taskCount += 1;
                                            if (FrmMain.taskCount % 5 == 0)
                                            {
                                                CompleteOrder completeOrder = new CompleteOrder();
                                                completeOrder.taskid = FrmMain.taskId;
                                                AppendCompleteCancelResponse completeResponse = SendDataToAgv.SendStopAppendTaskToAgv(completeOrder);
                                            }
                                        }

                                    }

                                    if (dvM[0]["F_Status"].ToString() == "0")
                                    {
                                        SendMonitorTask(Convert.ToInt32(dvM[0]["minMidx"]));
                                    }
                                    else
                                    {
                                        continue;
                                    }
                                }
                                else
                                {
                                    continue;
                                }
                            }
                            catch (Exception ex)
                            {
                                _CControlError = "发送命令时：" + ex.Message;
                            }
                        }//for语句结束
                        dv = null;
                        dvM = null;
                        return;
                    }
                    else
                    {
                        dv = null;
                        dvM = null;
                        //_CControlError = "没有命令可以执行！";
                        if (FrmControlMonitor.FormInstance.GetObjectText("tsStatus").IndexOf(_CControlError) < 0)
                        {
                            FrmControlMonitor.FormInstance.FlashPanit("tsStatus", _CControlError, true);
                        }
                        if (string.IsNullOrEmpty(task_type))
                        {
                            FrmMain.taskCount = 0;
                        }
                        return;
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            else
            {
                //1.一组盘库运单是由出入库任务交替组成的
                //2.入库任务只有在射频完成时才会拆分,所以盘库运单应根据调度任务生成
                //3.盘库运单每次应获取2*agv层数的调度任务
                //4.每个盘库任务组只需发送一次,因为不会有新的任务生成
                //5.每次取前八条 储存FID判断如果当前八条执行完了，再去下发下一次任务

                DataView invGroupTask = DbHelperSQL.Query("select top 10 * from t_manage_task where FMANAGEID="+ taskDetail[0]["F_TASK_NO"].ToString()).Tables[0].DefaultView;

                bool IsinvGroupTask = true;
                foreach (DataRowView row in invGroupTask)
                {
                    // 判断该 FID 是否在 lastBatchFids 中出现过
                    if (CControl_Model.lastBatchFids.Contains(row["FID"].ToString()))
                    {
                        IsinvGroupTask = false;
                        break;
                    }
                }
                if (IsinvGroupTask && invGroupTask.Count>0)
                {
                    CControl_Model.lastBatchFids.Clear();
                    CreateOrder invCreateOrder = new CreateOrder();
                    List<BoxList> invBoxLists = new List<BoxList>();
                    invCreateOrder.zoneid = 0;//必须采用盘库模式,否则执行顺序会乱
                    invCreateOrder.poolid = 1;
                    invCreateOrder.orderno = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                    invCreateOrder.appendflag = false;//完整任务组不需追加
                    for (int i = 0; i < invGroupTask.Count; i++)
                    {
                        CControl_Model.lastBatchFids.Add(invGroupTask[i]["FID"].ToString());
                        BoxList invBoxList = new BoxList();
                        //取货位和放货位取决于调度任务类型
                        if (invGroupTask[i]["FCONTROLTASKTYPE"].ToString() == "1")
                        {
                            //入库任务
                            invBoxList.src = "12004";
                            invBoxList.dst = invGroupTask[i]["FENDCELL"].ToString();
                        }
                        else
                        {
                            //出库任务
                            invBoxList.src = invGroupTask[i]["FSTARTCELL"].ToString();
                            invBoxList.dst = "12004";
                        }
                        invBoxList.box = invGroupTask[i]["FPALLETBARCODE"].ToString();
                        invBoxList.rgsTaskId = Convert.ToInt32(invGroupTask[i]["FID"].ToString());
                        invBoxLists.Add(invBoxList);
                    }
                    invCreateOrder.boxlist = invBoxLists;
                    CreateOrderResponse invCreateOrderResponse = SendDataToAgv.SendOutOrInvTasksToAgv(invCreateOrder);
                }

                DataView dv = DbHelperSQL.Query(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 = DbHelperSQL.Query(strM).Tables[0].DefaultView;
                            //获取出入库任务类型
                            if (dvM.Count > 0 && dvM[0]["minMidx"] != DBNull.Value)
                            {
                                ////盘库时agv任务直接忽略,只判断输送线逻辑
                                //if (dvM[0]["F_DeviceIndex"].ToString() == "11001")
                                //{
                                //    continue;
                                //}
                                if (dvM[0]["F_Status"].ToString() == "0")
                                {
                                    SendMonitorTask(Convert.ToInt32(dvM[0]["minMidx"]));
                                }
                                else
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                continue;
                            }
                        }
                        catch (Exception ex)
                        {
                            _CControlError = "发送命令时：" + ex.Message;
                        }
                    }//for语句结束
                }
                else
                {
                    //_CControlError = "没有命令可以执行！";
                    if (FrmControlMonitor.FormInstance.GetObjectText("tsStatus").IndexOf(_CControlError) < 0)
                    {
                        FrmControlMonitor.FormInstance.FlashPanit("tsStatus", _CControlError, true);
                    }
                }
            }
            strM = null;
            dvM = null;
            if (string.IsNullOrEmpty(task_type))
            {
                FrmMain.taskCount = 0;
            }
            return;
        }

        /// <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;//关联设备的设备指令索引
            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;

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

                if (((_LockedState == 0) && (checkLockedstate == true)) || (checkLockedstate == false))
                {
                    #region 是否被调度任务预约F_ManTaskReserve，且类型、INDEX不同

                    if (_ManTaskReserve > 0 && (_ManTaskReserve.ToString() != _ManageKindIdx.ToString() + _ManageTaskIdx.ToString()))
                    {
                        return true;
                    }

                    #endregion 是否被调度任务预约F_ManTaskReserve，且类型、INDEX不同

                    //3：F_AheadDetect检测(检测开关编号组“;”)
                    if (AheadDetectOK(minMidx, _AheadDetect) == true)//提前检测通过
                    {
                        //检查同步运行的关联设备F_AssociateDeviceIndex
                        //4：是否有关联设备命令？
                        //AssociateDevice = ccf.GetAssociateDevice(minMidx);

                        #region 检查_Associate

                        if (_Associate != 0)
                        {
                            //5：如果有，找到可以运行的关联设备的设备指令,能否运行？
                            //重复递归到2
                            //split = AssociateDevice.Split(sep);
                            adidx = _Associate;
                            if (adidx != 0)
                            {
                                if (new MonitorTaskService().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
                                    {
                                        sendok = sdo.SendDeviceOrder(msgIdx, adidx, _DeviceOrder, _DeviceIdx, gc[5]);
                                    }
                                    if (sendok == false)
                                    {
                                        return true;
                                    }
                                    else
                                    {
                                        //8：更改作业记录的状态F_Status为1,更改设备为占用状态（T_Base_device的F_LockedState=设备指令单）
                                        DbHelperSQL.ExecuteSql("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;
                            }
                        }

                        #endregion 检查_Associate
                        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
            {
            }
        }

        /// <summary>
        /// 检测指定设备命令的执行先决条件是否成立
        /// </summary>
        /// <param name="minMidx">监控唯一索引</param>
        /// <returns>是否检测通过，true表示设备执行命令的先决条件成立</returns>
        public bool AheadDetectOK(int minMidx, string _AheadDetect)
        {
            //检测(检测开关编号组“;”)
            DataView dvdv;
            DataTable dt;
            try
            {
                AheadDetectUnallow.Remove(0, AheadDetectUnallow.Length);//dzf
                int[] States;

                int DeviceIdx = _DeviceIdx;
                int TaskIdx = minMidx;
                int fid = ccf.GetManageTaskIndexfromMonitor(TaskIdx);
                int mti = ccf.GetManageTaskKindIndexFromMonitor(TaskIdx);
                int DeviceKind = BaseDeviceService.GetDeviceKindIdx(DeviceIdx);//20100617
                //20100706
                devinfo = BaseDeviceService.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 = BaseDeviceService.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 = DbHelperSQL.Query(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;
                            }
                            //记录发生故障的设备正在执行的任务号
                            DbHelperSQL.ExecuteSql("update T_Base_Device set F_ErrorTaskNo= " + TaskIdx + "  where F_DeviceIndex= " + DeviceIdx);

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

                            errs = BaseDeviceService.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)
                            {
                                string sResult = string.Empty;
                                //RGDWCSServices.WMS.uploadWhExceptionInfo ss = new RGDWCSServices.WMS.uploadWhExceptionInfo();
                                //ss.Notify(devinfo.DeviceIndex.ToString(), devinfo.DeviceName, "准备执行管理任务时：" + devinfo.DeviceName + "," + DeviceIdx + errs.ErrorName, DateTime.Now.ToString(), out sResult);
                            }
                            DbHelperSQL.ExecuteSql("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 OPC通讯设备检测设备是否故障
                }
                //#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")//检测逻辑有探物
                        {
                            //本地设备表读取
                            dvdv = DbHelperSQL.Query("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)
                            {
                                if (Convert.ToInt32(dvdv[0]["F_HaveGoods"]) != 1)//dzf
                                {
                                    AheadDetectUnallow.Append(AheadDetect[i].Trim().Substring(1) + "设备逻辑无物！");
                                }
                                fs = fs & Convert.ToInt32(dvdv[0]["F_HaveGoods"]);
                            }

                            continue;
                        }
                        if (AheadDetect[i].Trim().Substring(0, 1).ToUpper() == "N")//检测逻辑无探物
                        {
                            //本地设备表读取
                            dvdv = DbHelperSQL.Query("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)
                            {
                                if (Convert.ToInt32(dvdv[0]["F_HaveGoods"]) != 0)//dzf
                                {
                                    AheadDetectUnallow.Append(AheadDetect[i].Trim().Substring(1) + "设备逻辑有物！");
                                }
                                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)
                            {
                                if (States[1] != 0)//dzf
                                {
                                    AheadDetectUnallow.Append(AheadDetect[i].Trim().Substring(1) + "设备不空闲！");
                                }
                                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 (fsn != 1)//dzf
                                {
                                    StringBuilder kg = new StringBuilder();
                                    switch (devbit)
                                    {
                                        case 0:
                                            kg.Append("有物");
                                            break;

                                        case 1:
                                            kg.Append("高位");
                                            break;

                                        default:
                                            break;
                                    }
                                    AheadDetectUnallow.Append(Convert.ToInt32((-devicebyte)).ToString() + kg.ToString() + "光电开关不遮挡！");
                                }
                                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 (sssn != 0)//dzf
                                {
                                    StringBuilder kg = new StringBuilder();
                                    switch (devbit)
                                    {
                                        case 0:
                                            kg.Append("有物");
                                            break;

                                        case 1:
                                            kg.Append("高位");
                                            break;

                                        case 2:
                                            kg.Append("低位");
                                            break;

                                        default:
                                            break;
                                    }
                                    AheadDetectUnallow.Append(devicebyte.ToString() + kg.ToString() + "光电开关遮挡！");
                                }
                                if (sssn == -1)//20101220
                                {
                                    return false;
                                }
                                s = s + sssn;
                            }
                        }

                        #endregion 20101118检测设备光电信号

                        if ((s != 0) || (fs != 1))//dzf
                        {
                            UpdateAheadDetectUnallow(AheadDetectUnallow, minMidx);
                            return false;
                        }
                    }
                }

                #endregion 提前检测信息处理

                return true;//20101011
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                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,F_PickUpLocation " +
                    " FROM  V_Monitor_Route_Device where F_MonitorIndex=" + minMidx;
                dvD = DbHelperSQL.Query(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;
                    }
                    if (dvD[0]["F_PickUpLocation"] != DBNull.Value)
                    {
                        _PickUpLocation = dvD[0]["F_PickUpLocation"].ToString();
                    }
                    else
                    {
                        _PickUpLocation = "0";
                    }

                    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();
                //获得要发送的信息
                if (GetSendInfo(MonitorIndex) == false) { return false; }
                devinfo = BaseDeviceService.GetDeviceInfo(_DeviceIdx);//dzf
                if ((_DeviceKind == 1) && (devinfo.XCoor == 0))//dzf
                {//堆垛机
                    AheadDetectUnallow.Clear();
                    AheadDetectUnallow.Append(_DeviceIdx.ToString() + "的光通讯被遮挡，或者没上电！");
                    UpdateAheadDetectUnallow(AheadDetectUnallow, MonitorIndex);
                    return false;
                }

                #region 手工任务

                if (ccf.GetManageTaskKindIndexFromMonitor(MonitorIndex) == 4)
                {
                    CStaticClass.MessageIndex = 1;
                    msgIdx = (CStaticClass.MessageIndex);
                    sdo = CommModeCreate.CreateSendDeviceOrder(_DeviceIdx);
                    int[] gc = new int[6] { _NumParam2, _NumParam3, _NumParam1, _NumParam5, _NumParam6, _NumParam4 };
                    if (_DeviceKind == 1)//垛机
                    {
                        sendok = sdo.SendDeviceOrder(msgIdx, MonitorIndex, _DeviceOrder, _DeviceIdx, gc[0], gc[1], gc[2], gc[3], gc[4], gc[5]);
                    }
                    else if (_DeviceKind == 32 || _DeviceKind == 33)//拣选-贴标
                    {
                        sendok = sdo.SendDeviceOrder(msgIdx, MonitorIndex, _DeviceOrder, _DeviceIdx, _PickUpLocation);
                    }
                    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 = BaseDeviceService.GetDeviceInfo(_DeviceIdx);
                        if (devinfo.IfCorrelDoubleFork == "1")
                        {
                            //20220303 双叉已注释
                            //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：提取每个管理单据的第一个设备状态
                //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)
                    {
                        //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 == 32)
                    {
                        sendok = sdo.SendDeviceOrder(msgIdx, MonitorIndex, _DeviceOrder, _DeviceIdx, _PickUpLocation);
                    }
                    else if (_DeviceKind == 33)
                    {
                        sendok = sdo.SendDeviceOrder(msgIdx, MonitorIndex, _DeviceOrder, _DeviceIdx, _PickUpLocation);
                    }
                    else
                    {
                        
                        sendok = sdo.SendDeviceOrder(msgIdx, MonitorIndex, _DeviceOrder, _DeviceIdx, gc[5]); // 输送机的发生指令  _NumParam4参数表示目标位置
                    }
                    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//发送命令成功
                    {
                        //////////////////////////
                        DbHelperSQL.ExecuteSql("update T_Monitor_Task set F_SendFlag='1' where F_MonitorIndex=" + MonitorIndex);//20100905只重发主任务
                        ccf.SendOrderSuccess(_ManageKindIdx, _ManageTaskIdx, MonitorIndex, _DeviceIdx, _routeID);

                        #region 双叉关联任务，能同步的同时报告发送命令成功

                        //20100323
                        devinfo = BaseDeviceService.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 自动命令(taskkind == 1，2)
            }
        }

        private int GetDeviceFromMonitor(int monitorIndex)
        {
            DataView dv = DbHelperSQL.Query("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>
        /// 该方法 全部删除  原关于双叉的处理，目前没有双叉现场 20220303
        /// </summary>
        /// <param name="taskno"></param>
        /// <returns></returns>
        private int GetDoubleForkMinRouteTask(int taskno)
        {
            return taskno;
        }

        private 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 = DbHelperSQL.Query("SELECT F_MoveCellCode FROM T_Base_LaneInfo WHERE (F_MoveCellCode = '" + zxystr + "')").Tables[0].DefaultView;
            if (dv.Count > 0)//倒库货位的任务后执行
            {
                return false;
            }
            return true;
        }

        private void UpdateAheadDetectUnallow(StringBuilder aheadUnallow, int taskindex)//dzf
        {
            #region

            int rec = 0;
            if (aheadUnallow.Length > 0)
            {
                rec = DbHelperSQL.ExecuteSql(string.Format("UPDATE T_Monitor_Task SET  F_ErrorCode ='{0}' WHERE F_MonitorIndex ={1} ", aheadUnallow.ToString(), taskindex));//and F_ErrorCode <>'{0}'
            }
            else
            {
                rec = DbHelperSQL.ExecuteSql(string.Format("UPDATE T_Monitor_Task SET  F_ErrorCode ='' WHERE F_MonitorIndex ={1} and F_ErrorCode <>''", aheadUnallow.ToString(), taskindex));
            }

            #endregion
        }

        //public string sendAGVTask(string F_MonitorIndex,string cell,string barcode)
        //{
        //    string url = "POST  /adapter/task/create";
        //    TaskApply taskapply = new TaskApply();
        //    task ts = new task();
        //    taskDescribe des = new taskDescribe();
        //    ts.TaskCode = F_MonitorIndex;
        //    des.ContainerCode = barcode;
        //    des.ContainerType = "物料型号";
        //    des.FromLocationCode = "12005";
        //    des.LocationCode = cell;
        //    ts.TaskDescribe.Add(des);
        //    taskapply.Tasks.Add(ts);
        //    taskapply.TaskType = "tote_inbound";
        //    string json = JsonConvert.SerializeObject(taskapply);
        //    string getJson = GetJson.Post(url, json);
        //    ApplyResult result = JsonConvert.DeserializeObject<ApplyResult>(getJson);
        //    if (result.CODE == "0")
        //    {
        //        return "success";
        //    }
        //    else
        //    {
        //        return "发送AGV命令失败,为原因" + result.MSG;
        //    }

        //}
    }
}