using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Threading;
using Microsoft.VisualBasic;
using DBFactory;
using ICommLayer;

namespace SocketsTCPIP
{
    /// <summary>
    /// 使用SocketsTCPIP的客户端进行通讯
    /// 发送设备命令类
    /// 创建者:Richard.Liu
    /// 20110104升级与AGV控制台通讯协议
    /// </summary>
    public class CSendDeviceOrder: ISendDeviceOrder
    {
        string _commLayerError;
        StringBuilder sql = new StringBuilder();
        Model.MDevice devinfo;
        public string CommLayerError
        {
            get { return _commLayerError; }
            set { _commLayerError = value; }
        }
        
        DBOperator dbo = CClientTCPIP.dbo;
        string AGVAllowSingleFork = CommonClassLib.AppSettings.GetValue("AGVAllowSingleFork");
        public CSendDeviceOrder()
        {
            dbo.Open();
        }



        /// <summary>
        ///序号                  通讯种类	                                           方向	                                                   通讯格式                                                                                 格式说明
        ///1                        监控调度通讯连接建立                    监控调度->AGV控制台                      10001
        ///2                        监控调度通讯连接断开                    监控调度->AGV控制台                      10002
        ///3                       下达任务                                            控调度->AGV控制台                          10003[T1][T2][T][R][P][K][A][F][C][N1][N2]……[CK]
        ///T1为任务号(取值范围1000-65534)
        ///T2为任务步号(取值范围0-99)
        ///T为任务类型(TS编号); 0不指定类型,11演示流程
        ///R为产品类型; 0不指定类型
        ///P为优先级(取值范围1-8,越大优先级越高);2
        ///K为车辆类型; 0不指定类型(14001---〉1;15001---〉2)
        ///A为车辆编号; 0不指定编号
        ///F为后续任务标识(1-有后续任务,0-无后续任务);
        ///C为参数数量;
        ///N1、N2为具体参数;
        ///CK校验码(以上所有字段逐字节累加)
        ///4                        下达任务确认                                   AGV控制台->监控调度                       10003[T1][T2][CK]                                                                ///T1为任务号,T2为任务步号;
        ///5                        AGV任务开始                                  AGV控制台->监控调度                        10004[T1][T2][A][CK]                                                           ///A为车辆编号;
        ///6                        任务开始确认                                   监控调度->AGV控制台                        10004[T1][T2][CK]                                                                
        ///7                        AGV任务完成                                  AGV控制台->监控调度                        10005[T1][T2][A][CK]                                                           
        ///8                        任务完成确认                                   监控调度->AGV控制台                        10005[T1][T2][CK]
        ///9                        监控申请删除任务                           监控调度->AGV控制台                         10006[T1][T2][CK]
        ///10                      监控申请删除任务回复                   AGV控制台->监控调度                         10006[T1][T2][A][CK]                                                           ///A为允许状态(0-不允许,1-允许)
        ///11                      控制台申请删除任务                       AGV控制台->监控调度                         10007[T1][T2][CK]                                                              
        ///12                      控制台申请删除任务确认                监控调度->AGV控制台                         10007[T1][T2][CK]           
        ///13                      监控查询AGV状态                           监控调度->AGV控制台                         10008[A][CK]                                                                        ///A为车辆编号;(0-查询所有车辆)
        ///14                      查询AGV状态确认                           AGV控制台->监控调度                         10008[A][C][CK]                                                                  ///A为车辆编号;C为车辆数目;
        ///15                      控制台上报AGV状态                       AGV控制台->监控调度                         10009[A][T1][S][E][W][C][B][N][O][CK]                           
        ///A为车辆编号;
        ///T1为任务号;
        ///S为当前路段起点;
        ///E为当前路段终点;
        ///W为工作状态;(0空闲,1运行,2暂停,3动态操作,4静态操作,5等待,6休眠,7逻辑离线,8物理离线)
        ///C为故障代码;
        ///B为电池状态;(0电量满,1电量正常2电量低)
        ///N为目标节点;
        ///O为操作码;
        ///16                       确认AGV状态                                  监控调度->AGV控制台                         10009[A][CK]                                                                      ///A为车辆编号;
        ///17                       监控发送信息                                   监控调度->AGV控制台                         10010[R][C][I1][I2]…[CK]
        ///R为是否需要控制台回复确认
        ///(0-不需确认,1-需确认)
        ///C 为信息个数
        ///[I1]…为具体信息
        ///18                       控制台回复信息确认                       AGV控制台->监控调度                         10010[R][C] [I1][I2]…[CK]
        ///19                       控制台发送信息                               AGV控制台->监控调度                         10011[R][C][I1][I2]…[CK]
        ///R为是否需要控制台回复确认
        ///(0-不需确认,1-需确认)
        ///C 为信息个数
        ///[I1]…为具体信息
        ///20                       上位机回复信息确认                       监控调度->AGV控制台                          10011[R][C][I1][I2]…[CK]

        /// </summary>
        /// <param name="MessageIndex">消息编号</param>
        /// <param name="TaskIndex">任务编号</param>
        /// <param name="Order">AGV命令字</param>
        /// <param name="DeviceIndex">设备编号</param>
        /// <param name="StartX">[N1]:取货点</param>
        /// <param name="StartY"></param>
        /// <param name="StartZ"></param>
        /// <param name="EndX">[N2]:放货点</param>
        /// <param name="EndY"></param>
        /// <param name="EndZ"></param>
        /// <returns>发送AGV命令是否成功</returns>
        public bool SendDeviceOrder(int MessageIndex, int TaskIndex, int Order, int DeviceIndex, int StartX, int StartY, int StartZ, int EndX, int EndY, int EndZ)
        {

            devinfo = Model.CGetInfo.GetDeviceInfo(DeviceIndex);
            if (devinfo == null)
            {
                return false;
            }
            else
            {
                if (CClientTCPIP.IfInit[devinfo.RemoteIP] == false)
                {

                    return false;

                }
            }
            //StartX取设备索引 EndX送设备索引
            //20100413根据StartX(取设备索引)获得前(距离车尾远)叉、后(距离车尾近)叉
            //站在车尾沿着行进方向的左、右方向;
            //判断关联双叉是否同步运行
            char useAwayFork = '0';
            char channelLeft = '0';
            int AGVAddress = 0;
            int dorder = 0;
            int _device =  GetAGVNoFromMonitor(TaskIndex);
            int Fid = Model.CGeneralFunction.GetManageTaskIndexfromMonitor(TaskIndex);
            //byte goodsID = GetGoodsIDfromManage(Fid);   // 从管理任务得到产品类型
            byte goodsID = 255;   // 从管理任务得到产品类型
            byte[] _Sdata;
            int NextOrder = 0; // 下一个动作编码,运动时候给AGV发送;  0没有下一个动作;2取货,送货;
            int HaveNextTask = IfHaveNextTask(TaskIndex,DeviceIndex,ref NextOrder );
            int forkNo = 0; int ck = 0;
            bool retvalue = false;
            if (MessageIndex != 1)
            {
                return false;

            }
            try
            {


                switch (Order)
                {
                    case 1://运动命令 StartX取设备索引
                        #region 运动命令

                        GetDeviceInfoFromAGVGate(StartX, ref channelLeft, ref useAwayFork, ref AGVAddress);// 运动命令按照起点设备查找AGV地标点

                        //_Sdata = new byte[52];
                        //_Sdata[0] = Convert.ToByte(10003 & 255); //帧头
                        //_Sdata[1] = Convert.ToByte((10003 >> 8) & 255);
                        //_Sdata[2] = Convert.ToByte((10003 >> 16) & 255);
                        //_Sdata[3] = Convert.ToByte((10003 >> 24) & 255);
                        //_Sdata[4] = Convert.ToByte(Fid & 255);//管理任务号
                        //_Sdata[5] = Convert.ToByte((Fid >> 8) & 255);
                        //_Sdata[6] = Convert.ToByte((Fid >> 16) & 255);
                        //_Sdata[7] = Convert.ToByte((Fid >> 24) & 255);
                        //_Sdata[8] = Convert.ToByte(TaskIndex & 255);//监控任务号
                        //_Sdata[9] = Convert.ToByte((TaskIndex >> 8) & 255);
                        //_Sdata[10] = Convert.ToByte((TaskIndex >> 16) & 255);
                        //_Sdata[11] = Convert.ToByte((TaskIndex >> 24) & 255);
                        //_Sdata[12] = Convert.ToByte(65535 & 255);//任务类型
                        //_Sdata[13] = Convert.ToByte((65535 >> 8) & 255);
                        //_Sdata[14] = Convert.ToByte((65535 >> 16) & 255);
                        //_Sdata[15] = Convert.ToByte((65535 >> 24) & 255);
                        //// 产品类型65535 AGV新加字段 20150115
                        //_Sdata[16] = Convert.ToByte(65535 & 255);
                        //_Sdata[17] = Convert.ToByte((65535 >> 8) & 255);
                        //_Sdata[18] = Convert.ToByte((65535 >> 16) & 255);
                        //_Sdata[19] = Convert.ToByte((65535 >> 24) & 255);
                        //// 产品类型
                        //_Sdata[20] = 2;//优先级
                        //_Sdata[21] = 0;
                        //_Sdata[22] = 0;
                        //_Sdata[23] = 0;
                        //_Sdata[24] = Convert.ToByte(65535 & 255);//车辆类型
                        //_Sdata[25] = Convert.ToByte((65535 >> 8) & 255);
                        //_Sdata[26] = Convert.ToByte((65535 >> 16) & 255);
                        //_Sdata[27] = Convert.ToByte((65535 >> 24) & 255);
                        //_Sdata[28] = Convert.ToByte(65535 & 255);//车辆编号
                        //_Sdata[29] = Convert.ToByte((65535 >> 8) & 255);
                        //_Sdata[30] = Convert.ToByte((65535 >> 16) & 255);
                        //_Sdata[31] = Convert.ToByte((65535 >> 24) & 255);
                        //_Sdata[32] = Convert.ToByte(HaveNextTask & 255);//后续任务标识
                        //_Sdata[33] = Convert.ToByte((HaveNextTask >> 8) & 255);
                        //_Sdata[34] = Convert.ToByte((HaveNextTask >> 16) & 255);
                        //_Sdata[35] = Convert.ToByte((HaveNextTask >> 24) & 255);
                        //_Sdata[36] = 1;//节点数量
                        //_Sdata[37] = 0;
                        //_Sdata[38] = 0;
                        //_Sdata[39] = 0;
                        //_Sdata[40] = Convert.ToByte(AGVAddress & 255);//节点号
                        //_Sdata[41] = Convert.ToByte((AGVAddress >> 8) & 255);
                        //_Sdata[42] = Convert.ToByte((AGVAddress >> 16) & 255);
                        //_Sdata[43] = Convert.ToByte((AGVAddress >> 24) & 255);
                        //_Sdata[44] = Convert.ToByte(Order & 255);//动作设备编号
                        //_Sdata[45] = Convert.ToByte((Order >> 8) & 255);
                        //_Sdata[46] = Convert.ToByte((Order >> 16) & 255);
                        //_Sdata[47] = Convert.ToByte((Order >> 24) & 255);
                        //ck = Convert.ToInt16(60003 + Fid + TaskIndex + 65535 + 65535 + 2 + 65535 + 65535 + HaveNextTask + 1 + AGVAddress + Order);
                        //_Sdata[48] = Convert.ToByte(ck & 255);//校验码(以上所有任务码按无符号作加法)
                        //_Sdata[49] = Convert.ToByte((ck >> 8) & 255);
                        //_Sdata[50] = Convert.ToByte((ck >> 16) & 255);
                        //_Sdata[51] = Convert.ToByte((ck >> 24) & 255);


                         _Sdata = new byte[28];
                            
                        _Sdata[0] = Convert.ToByte(10003 & 255); //帧头
                        _Sdata[1] = Convert.ToByte((10003 >> 8) & 255);

                        _Sdata[2] = Convert.ToByte(Fid & 255);//管理任务号
                        _Sdata[3] = Convert.ToByte((Fid >> 8) & 255);
                        _Sdata[4] = Convert.ToByte((Fid >> 16) & 255);
                        _Sdata[5] = Convert.ToByte((Fid >> 24) & 255);

                        _Sdata[6] = Convert.ToByte(TaskIndex & 255);//调度任务号
                        _Sdata[7] = Convert.ToByte((TaskIndex >> 8) & 255);

                        _Sdata[8] = Convert.ToByte(65535 & 255);//任务类型
                        _Sdata[9] = Convert.ToByte((65535 >> 8) & 255);

                        if (StartX < 19000)//输送机编号小于19000
                        {
                            _Sdata[10] = 1;//产品类型,输送机1,地面2
                            _Sdata[11] = 0;
                        }
                        else
                        {

                            _Sdata[10] = 2;//产品类型,输送机1,地面2
                            _Sdata[11] = 0;
                        }
                       

                        _Sdata[12] = 2;//优先级
                        _Sdata[13] = 0;

                        _Sdata[14] = goodsID;//车辆类型   -- 传入货物类型bba 13\14时空托盘
                        _Sdata[15] = 0;

                        _Sdata[16] =  0;//车辆编号
                        _Sdata[17] =  0;

                        _Sdata[18] =Convert.ToByte(HaveNextTask & 255);//后续任务标识
                        _Sdata[19] =Convert.ToByte((HaveNextTask >> 8) & 255);

                        _Sdata[20] = 2;//参数数量
                        _Sdata[21] = 0;

                        _Sdata[22] = Convert.ToByte(AGVAddress & 255);//取货节点号
                        _Sdata[23] = Convert.ToByte((AGVAddress >> 8) & 255);

                        dorder = 65535;
                        _Sdata[24] = Convert.ToByte(dorder & 255);//Convert.ToByte(Order & 255);//设备动作编号,无动作65535 --Convert.ToByte(NextOrder);
                        _Sdata[25] = Convert.ToByte((dorder >> 8) & 255); // 高位FF03


                        for (int i = 0; i <= 25; i++)
                        {
                            ck += Convert.ToInt32(_Sdata[i]);
                        }
                        _Sdata[26] = Convert.ToByte(ck & 255);//校验码(以上所有任务码按无符号作加法)
                        _Sdata[27] = Convert.ToByte((ck >> 8) & 255);
                        
                        retvalue= SendData(DeviceIndex, _Sdata);
                        
                        #endregion
                        break;
                    case 2://取货命令
                        #region 取货命令

                        GetDeviceInfoFromAGVGate(StartX, ref channelLeft, ref useAwayFork, ref AGVAddress);
                        dorder = 2;//取货命令
                        if ((Model.CGeneralFunction.MutiForkIfSync(TaskIndex, DeviceIndex, 6) == null) && (AGVAllowSingleFork == "1"))//20100710
                        {//不能同步

                            if (useAwayFork == '1')//前叉
                            {

                                forkNo = 1;
                            }
                            else//后叉
                            {
                                forkNo = 2;
                            }

                        }
                        else
                        {//同步
                            forkNo = 3;

                        }
                        //_Sdata = new byte[52];
                        //_Sdata[0] = Convert.ToByte(10003 & 255); //帧头
                        //_Sdata[1] = Convert.ToByte((10003 >> 8) & 255);
                        //_Sdata[2] = Convert.ToByte((10003 >> 16) & 255);
                        //_Sdata[3] = Convert.ToByte((10003 >> 24) & 255);
                        //_Sdata[4] = Convert.ToByte(Fid & 255);//管理任务号
                        //_Sdata[5] = Convert.ToByte((Fid >> 8) & 255);
                        //_Sdata[6] = Convert.ToByte((Fid >> 16) & 255);
                        //_Sdata[7] = Convert.ToByte((Fid >> 24) & 255);
                        //_Sdata[8] = Convert.ToByte(TaskIndex & 255);//监控任务号
                        //_Sdata[9] = Convert.ToByte((TaskIndex >> 8) & 255);
                        //_Sdata[10] = Convert.ToByte((TaskIndex >> 16) & 255);
                        //_Sdata[11] = Convert.ToByte((TaskIndex >> 24) & 255);
                        //_Sdata[12] = Convert.ToByte(65535 & 255);//任务类型
                        //_Sdata[13] = Convert.ToByte((65535 >> 8) & 255);
                        //_Sdata[14] = Convert.ToByte((65535 >> 16) & 255);
                        //_Sdata[15] = Convert.ToByte((65535 >> 24) & 255);
                        //// 产品类型65535 AGV新加字段 20150115
                        //_Sdata[16] = Convert.ToByte(65535 & 255);
                        //_Sdata[17] = Convert.ToByte((65535 >> 8) & 255);
                        //_Sdata[18] = Convert.ToByte((65535 >> 16) & 255);
                        //_Sdata[19] = Convert.ToByte((65535 >> 24) & 255);
                        //// 产品类型
                        //_Sdata[20] = 2;//优先级
                        //_Sdata[21] = 0;
                        //_Sdata[22] = 0;
                        //_Sdata[23] = 0;
                        //_Sdata[24] = Convert.ToByte(65535 & 255);//车辆类型
                        //_Sdata[25] = Convert.ToByte((65535 >> 8) & 255);
                        //_Sdata[26] = Convert.ToByte((65535 >> 16) & 255);
                        //_Sdata[27] = Convert.ToByte((65535 >> 24) & 255);
                        //_Sdata[28] = Convert.ToByte(65535 & 255);//车辆编号
                        //_Sdata[29] = Convert.ToByte((65535 >> 8) & 255);
                        //_Sdata[30] = Convert.ToByte((65535 >> 16) & 255);
                        //_Sdata[31] = Convert.ToByte((65535 >> 24) & 255);
                        //_Sdata[32] = Convert.ToByte(HaveNextTask & 255);//后续任务标识
                        //_Sdata[33] = Convert.ToByte((HaveNextTask >> 8) & 255);
                        //_Sdata[34] = Convert.ToByte((HaveNextTask >> 16) & 255);
                        //_Sdata[35] = Convert.ToByte((HaveNextTask >> 24) & 255);
                        //_Sdata[36] = 1;//节点数量
                        //_Sdata[37] = 0;
                        //_Sdata[38] = 0;
                        //_Sdata[39] = 0;
                        //_Sdata[40] = Convert.ToByte(AGVAddress & 255);//节点号
                        //_Sdata[41] = Convert.ToByte((AGVAddress >> 8) & 255);
                        //_Sdata[42] = Convert.ToByte((AGVAddress >> 16) & 255);
                        //_Sdata[43] = Convert.ToByte((AGVAddress >> 24) & 255);
                        //_Sdata[44] = Convert.ToByte(Order & 255);//动作设备编号
                        //_Sdata[45] = Convert.ToByte((Order >> 8) & 255);
                        //_Sdata[46] = Convert.ToByte((Order >> 16) & 255);
                        //_Sdata[47] = Convert.ToByte((Order >> 24) & 255);
                        //ck = Convert.ToInt32(10003 + Fid + TaskIndex + 65535 + 65535 + 2 + 65535 + 65535 + HaveNextTask + 1 + AGVAddress + Order);
                        //_Sdata[48] = Convert.ToByte(ck & 255);//校验码(以上所有任务码按无符号作加法)
                        //_Sdata[49] = Convert.ToByte((ck >> 8) & 255);
                        //_Sdata[50] = Convert.ToByte((ck >> 16) & 255);
                        //_Sdata[51] = Convert.ToByte((ck >> 24) & 255);
                        //writeDark(Fid, TaskIndex, DeviceIndex, dorder, AGVAddress);



                        _Sdata = new byte[28];
                            
                        _Sdata[0] = Convert.ToByte(10003 & 255); //帧头
                        _Sdata[1] = Convert.ToByte((10003 >> 8) & 255);

                        _Sdata[2] = Convert.ToByte(Fid & 255);//管理任务号
                        _Sdata[3] = Convert.ToByte((Fid >> 8) & 255);
                        _Sdata[4] = Convert.ToByte((Fid >> 16) & 255);
                        _Sdata[5] = Convert.ToByte((Fid >> 24) & 255);

                        _Sdata[6] = Convert.ToByte(TaskIndex & 255);//调度任务号
                        _Sdata[7] = Convert.ToByte((TaskIndex >> 8) & 255);

                        _Sdata[8] = Convert.ToByte(65535 & 255);//任务类型
                        _Sdata[9] = Convert.ToByte((65535 >> 8) & 255);

                        if (StartX < 19000)//输送机编号小于19000
                        {
                            _Sdata[10] = 1;//产品类型,输送机1,地面2
                            _Sdata[11] = 0;
                        }
                        else
                        {

                            _Sdata[10] = 2;//产品类型,输送机1,地面2
                            _Sdata[11] = 0;
                        }
                       

                        _Sdata[12] = 2;//优先级
                        _Sdata[13] = 0;

                        _Sdata[14] = goodsID;//车辆类型   -- 传入货物类型bba 13\14时空托盘
                        _Sdata[15] = 0;

                        _Sdata[16] =  0;//车辆编号
                        _Sdata[17] =  0;

                        _Sdata[18] =Convert.ToByte(HaveNextTask & 255);//后续任务标识
                        _Sdata[19] =Convert.ToByte((HaveNextTask >> 8) & 255);

                        _Sdata[20] = 2;//参数数量
                        _Sdata[21] = 0;

                        _Sdata[22] = Convert.ToByte(AGVAddress & 255);//取货节点号
                        _Sdata[23] = Convert.ToByte((AGVAddress >> 8) & 255);

                        dorder = 28901;
                        _Sdata[24] = Convert.ToByte(dorder & 255);//Convert.ToByte(Order & 255);//设备动作编号,无动作65535 --Convert.ToByte(NextOrder);
                        _Sdata[25] = Convert.ToByte((dorder >> 8) & 255); // 高位FF03



                        for (int i = 0; i <= 25; i++)
                        {
                            ck += Convert.ToInt32(_Sdata[i]);
                        }
                        _Sdata[26] = Convert.ToByte(ck & 255);//校验码(以上所有任务码按无符号作加法)
                        _Sdata[27] = Convert.ToByte((ck >> 8) & 255);
                        
                        retvalue= SendData(DeviceIndex, _Sdata);
  
                        
                        #endregion
                        break;
                    case 3://送货
                        #region 送货

                        GetDeviceInfoFromAGVGate(EndX, ref channelLeft, ref useAwayFork, ref AGVAddress);
                        dorder = 3;//送货
                        //if (channelLeft == '1')
                        //{
                        //    dorder = 2;//左送
                        //}
                        //else
                        //{
                        //    dorder = 4;//右送
                        //}
                        if ((Model.CGeneralFunction.MutiForkIfSync(TaskIndex, DeviceIndex, 6) == null) && (AGVAllowSingleFork == "1"))//20100710
                        {//不能同步

                            if (useAwayFork == '1')//前叉
                            {

                                forkNo = 1;
                            }
                            else//后叉
                            {
                                forkNo = 2;
                            }

                        }
                        else
                        {//同步
                            forkNo = 3;

                        }
                        //_Sdata = new byte[52];
                        //_Sdata[0] = Convert.ToByte(10003 & 255); //帧头
                        //_Sdata[1] = Convert.ToByte((10003 >> 8) & 255);
                        //_Sdata[2] = Convert.ToByte((10003 >> 16) & 255);
                        //_Sdata[3] = Convert.ToByte((10003 >> 24) & 255);
                        //_Sdata[4] = Convert.ToByte(Fid & 255);//管理任务号
                        //_Sdata[5] = Convert.ToByte((Fid >> 8) & 255);
                        //_Sdata[6] = Convert.ToByte((Fid >> 16) & 255);
                        //_Sdata[7] = Convert.ToByte((Fid >> 24) & 255);
                        //_Sdata[8] = Convert.ToByte(TaskIndex & 255);//监控任务号
                        //_Sdata[9] = Convert.ToByte((TaskIndex >> 8) & 255);
                        //_Sdata[10] = Convert.ToByte((TaskIndex >> 16) & 255);
                        //_Sdata[11] = Convert.ToByte((TaskIndex >> 24) & 255);
                        //_Sdata[12] = Convert.ToByte(65535 & 255);//任务类型
                        //_Sdata[13] = Convert.ToByte((65535 >> 8) & 255);
                        //_Sdata[14] = Convert.ToByte((65535 >> 16) & 255);
                        //_Sdata[15] = Convert.ToByte((65535 >> 24) & 255);
                        //// 产品类型65535 AGV新加字段 20150115
                        //_Sdata[16] = Convert.ToByte(65535 & 255);
                        //_Sdata[17] = Convert.ToByte((65535 >> 8) & 255);
                        //_Sdata[18] = Convert.ToByte((65535 >> 16) & 255);
                        //_Sdata[19] = Convert.ToByte((65535 >> 24) & 255);
                        //// 产品类型
                        //_Sdata[20] = 2;//优先级
                        //_Sdata[21] = 0;
                        //_Sdata[22] = 0;
                        //_Sdata[23] = 0;
                        //_Sdata[24] = Convert.ToByte(65535 & 255);//车辆类型
                        //_Sdata[25] = Convert.ToByte((65535 >> 8) & 255);
                        //_Sdata[26] = Convert.ToByte((65535 >> 16) & 255);
                        //_Sdata[27] = Convert.ToByte((65535 >> 24) & 255);
                        //_Sdata[28] = Convert.ToByte(65535 & 255);//车辆编号
                        //_Sdata[29] = Convert.ToByte((65535 >> 8) & 255);
                        //_Sdata[30] = Convert.ToByte((65535 >> 16) & 255);
                        //_Sdata[31] = Convert.ToByte((65535 >> 24) & 255);
                        //_Sdata[32] = Convert.ToByte(HaveNextTask & 255);//后续任务标识
                        //_Sdata[33] = Convert.ToByte((HaveNextTask >> 8) & 255);
                        //_Sdata[34] = Convert.ToByte((HaveNextTask >> 16) & 255);
                        //_Sdata[35] = Convert.ToByte((HaveNextTask >> 24) & 255);
                        //_Sdata[36] = 1;//节点数量
                        //_Sdata[37] = 0;
                        //_Sdata[38] = 0;
                        //_Sdata[39] = 0;
                        //_Sdata[40] = Convert.ToByte(AGVAddress & 255);//节点号
                        //_Sdata[41] = Convert.ToByte((AGVAddress >> 8) & 255);
                        //_Sdata[42] = Convert.ToByte((AGVAddress >> 16) & 255);
                        //_Sdata[43] = Convert.ToByte((AGVAddress >> 24) & 255);
                        //_Sdata[44] = Convert.ToByte(Order & 255);//动作设备编号
                        //_Sdata[45] = Convert.ToByte((Order >> 8) & 255);
                        //_Sdata[46] = Convert.ToByte((Order >> 16) & 255);
                        //_Sdata[47] = Convert.ToByte((Order >> 24) & 255);
                        //ck = Convert.ToInt32(10003 + Fid + TaskIndex + 65535 + 65535 + 2 + 65535 + 65535 + HaveNextTask + 1 + AGVAddress + Order);
                        //_Sdata[48] = Convert.ToByte(ck & 255);//校验码(以上所有任务码按无符号作加法)
                        //_Sdata[49] = Convert.ToByte((ck >> 8) & 255);
                        //_Sdata[50] = Convert.ToByte((ck >> 16) & 255);
                        //_Sdata[51] = Convert.ToByte((ck >> 24) & 255);
                        //writeDark(Fid, TaskIndex, DeviceIndex, dorder, AGVAddress);




                        _Sdata = new byte[28];
                            
                        _Sdata[0] = Convert.ToByte(10003 & 255); //帧头
                        _Sdata[1] = Convert.ToByte((10003 >> 8) & 255);

                        _Sdata[2] = Convert.ToByte(Fid & 255);//管理任务号
                        _Sdata[3] = Convert.ToByte((Fid >> 8) & 255);
                        _Sdata[4] = Convert.ToByte((Fid >> 16) & 255);
                        _Sdata[5] = Convert.ToByte((Fid >> 24) & 255);

                        _Sdata[6] = Convert.ToByte(TaskIndex & 255);//调度任务号
                        _Sdata[7] = Convert.ToByte((TaskIndex >> 8) & 255);

                        _Sdata[8] = Convert.ToByte(65535 & 255);//任务类型
                        _Sdata[9] = Convert.ToByte((65535 >> 8) & 255);

                        if (StartX < 19000)//输送机编号小于19000
                        {
                            _Sdata[10] = 1;//产品类型,输送机1,地面2
                            _Sdata[11] = 0;
                        }
                        else
                        {

                            _Sdata[10] = 2;//产品类型,输送机1,地面2
                            _Sdata[11] = 0;
                        }
                       

                        _Sdata[12] = 2;//优先级
                        _Sdata[13] = 0;

                        _Sdata[14] = goodsID;//车辆类型   -- 传入货物类型bba 13\14时空托盘
                        _Sdata[15] = 0;

                        _Sdata[16] =  0;//车辆编号
                        _Sdata[17] =  0;

                        _Sdata[18] =Convert.ToByte(HaveNextTask & 255);//后续任务标识
                        _Sdata[19] =Convert.ToByte((HaveNextTask >> 8) & 255);

                        _Sdata[20] = 2;//参数数量
                        _Sdata[21] = 0;

                        _Sdata[22] = Convert.ToByte(AGVAddress & 255);//取货节点号
                        _Sdata[23] = Convert.ToByte((AGVAddress >> 8) & 255);

                        dorder = 28902;
                        _Sdata[24] = Convert.ToByte(dorder & 255);//Convert.ToByte(Order & 255);//设备动作编号,无动作65535 --Convert.ToByte(NextOrder);
                        _Sdata[25] = Convert.ToByte((dorder >> 8) & 255); // 高位FF03



                        for (int i = 0; i <= 25; i++)
                        {
                            ck += Convert.ToInt32(_Sdata[i]);
                        }
                        _Sdata[26] = Convert.ToByte(ck & 255);//校验码(以上所有任务码按无符号作加法)
                        _Sdata[27] = Convert.ToByte((ck >> 8) & 255);
                        
                        retvalue= SendData(DeviceIndex, _Sdata);
                        
                        #endregion
                        break;
                    case 4://取送货
                        #region 取送货
                        //取货
                        GetDeviceInfoFromAGVGate(StartX, ref channelLeft, ref useAwayFork, ref AGVAddress);

                        dorder = 4;
                       
                        if ((Model.CGeneralFunction.MutiForkIfSync(TaskIndex, DeviceIndex, 6) == null) && (AGVAllowSingleFork == "1"))//20100710
                        {//不能同步

                            if (useAwayFork == '1')//前叉
                            {

                                forkNo = 1;
                            }
                            else//后叉
                            {
                                forkNo = 2;
                            }

                        }
                        else
                        {//同步
                            forkNo = 3;

                        }
                        _Sdata = new byte[32];
                            
                        _Sdata[0] = Convert.ToByte(10003 & 255); //帧头
                        _Sdata[1] = Convert.ToByte((10003 >> 8) & 255);

                        _Sdata[2] = Convert.ToByte(Fid & 255);//管理任务号
                        _Sdata[3] = Convert.ToByte((Fid >> 8) & 255);
                        _Sdata[4] = Convert.ToByte((Fid >> 16) & 255);
                        _Sdata[5] = Convert.ToByte((Fid >> 24) & 255);

                        _Sdata[6] = Convert.ToByte(TaskIndex & 255);//调度任务号
                        _Sdata[7] = Convert.ToByte((TaskIndex >> 8) & 255);

                        _Sdata[8] = Convert.ToByte(65535 & 255);//任务类型
                        _Sdata[9] = Convert.ToByte((65535 >> 8) & 255);

                        if (StartX < 19000)//输送机编号小于19000
                        {
                            _Sdata[10] = 1;//产品类型,输送机1,地面2
                            _Sdata[11] = 0;
                        }
                        else
                        {

                            _Sdata[10] = 2;//产品类型,输送机1,地面2
                            _Sdata[11] = 0;
                        }
                       

                        _Sdata[12] = 2;//优先级
                        _Sdata[13] = 0;

                        _Sdata[14] = goodsID;//车辆类型   -- 传入货物类型bba 13\14时空托盘
                        _Sdata[15] = 0;

                        _Sdata[16] =  0;//车辆编号
                        _Sdata[17] =  0;

                        _Sdata[18] =Convert.ToByte(HaveNextTask & 255);//后续任务标识
                        _Sdata[19] =Convert.ToByte((HaveNextTask >> 8) & 255);

                        _Sdata[20] = 4;//参数数量
                        _Sdata[21] = 0;

                        _Sdata[22] = Convert.ToByte(AGVAddress & 255);//取货节点号
                        _Sdata[23] = Convert.ToByte((AGVAddress >> 8) & 255);

                        dorder = 2;
                        _Sdata[24] = Convert.ToByte(dorder & 255);//Convert.ToByte(Order & 255);//设备动作编号,无动作65535 --Convert.ToByte(NextOrder);
                        _Sdata[25] = Convert.ToByte((dorder >> 8) & 255); // 高位FF03

                        GetDeviceInfoFromAGVGate(EndX, ref channelLeft, ref useAwayFork, ref AGVAddress);

                        _Sdata[26] = Convert.ToByte(AGVAddress & 255);//送货节点号
                        _Sdata[27] = Convert.ToByte((AGVAddress >> 8) & 255);

                        dorder = 3;
                        _Sdata[28] = Convert.ToByte(dorder & 255);//Convert.ToByte(Order & 255);//设备动作编号,无动作65535 --Convert.ToByte(NextOrder);
                        _Sdata[29] = Convert.ToByte((dorder >> 8) & 255); // 

                        for (int i = 0; i <= 29; i++)
                        {
                            ck += Convert.ToInt32(_Sdata[i]);
                        }
                        _Sdata[30] = Convert.ToByte(ck & 255);//校验码(以上所有任务码按无符号作加法)
                        _Sdata[31] = Convert.ToByte((ck >> 8) & 255);
                        
                        retvalue= SendData(DeviceIndex, _Sdata);

                        #endregion
                        break;
                    //case 5://允许AGV移载,使用起始坐标作为允许AGV移载的坐标设备
                    //    #region 允许AGV移载

                    //    GetDeviceInfoFromAGVGate(StartX, ref channelLeft, ref useAwayFork, ref AGVAddress);
                    //    //获得实际取货或者送货任务号F_AGVNextTask
                    //    object ob = dbo.GetSingle("select F_AGVNextTask from T_Monitor_Task where F_MonitorIndex=" + TaskIndex);
                    //    if (ob != null)
                    //    {
                    //        TaskIndex = Convert.ToInt32(ob);
                    //    }
                    //    _Sdata = new byte[12];
                    //    _Sdata[0] = Convert.ToByte(60005 & 255); //帧头
                    //    _Sdata[1] = Convert.ToByte(60005 >> 8);
                    //    _Sdata[2] = Convert.ToByte(Fid & 255);//管理任务号
                    //    _Sdata[3] = Convert.ToByte(Fid >> 8);
                    //    _Sdata[4] = Convert.ToByte(TaskIndex & 255);//监控任务号
                    //    _Sdata[5] = Convert.ToByte(TaskIndex >> 8);
                    //    _Sdata[6] = Convert.ToByte(AGVAddress & 255);//节点
                    //    _Sdata[7] = Convert.ToByte(AGVAddress >> 8);
                    //    _Sdata[8] = Convert.ToByte(forkNo & 255);//动作设备编号
                    //    _Sdata[9] = Convert.ToByte(forkNo >> 8);
                    //    _Sdata[10] =Convert.ToByte(dorder & 255);//动作类型
                    //    _Sdata[11] =Convert.ToByte(dorder >> 8);

                    //    return SendData(DeviceIndex, _Sdata);

                    //    #endregion
                    default:
                        break;
                }


                return retvalue;
            }
            catch (Exception ex)
            {
                _commLayerError = this.ToString() + ":SendDeviceOrder---" + ex.Message;
                return false;
            }
            finally
            {
                if (retvalue == true)
                {
                    writeDark(Fid, TaskIndex, DeviceIndex, dorder, AGVAddress);
                }
            }

        }

        // 从管理任务号得到物料类型,发送给AGV;物料类型管理下达任务时候在'GOODS_TEMPLATE_ID'字段,调度保存在 FREMARK 字段
        public byte GetGoodsIDfromManage(int fid)
        {
            DataView dv;
            try
            {                                                               
                sql.Remove(0, sql.Length);
                sql.Append("SELECT GOODS_TEMPLATE_ID FROM T_MANAGE_TASK WHERE FID = ").Append(fid);
                dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView;
                if (dv.Count > 0)
                {
                    if (dv[0][0] == DBNull.Value)
                    {
                        return 0;
                    }
                    else
                    {
                         return Convert.ToByte(dv[0][0]);
                    }
                }
                else
                {
                    return 0;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                dv = null;
            }
        }
        public void writeDark(int Fid, int TaskIndex, int DeviceIndex, int dorder, int AGVAddress)
        {
            
                string barcode = string.Empty;
                StringBuilder sss = new StringBuilder("");
                sss.Remove(0, sss.Length);
                sss.Append("SELECT  F_TxtParam FROM T_Monitor_Task WHERE (F_MonitorIndex = ").Append(TaskIndex).Append(")");
                DataView dvb = dbo.ExceSQL(sss.ToString()).Tables[0].DefaultView;
                if (dvb.Count > 0)
                {
                    barcode = dvb[0]["F_TxtParam"].ToString();
                }
                else
                {
                    barcode = "-";
                }
                sss.Remove(0, sss.Length);
                sss.Append("条码:").Append(barcode).Append("**写标志10003").Append("**管理任务:" + Fid.ToString()).Append("**设备指令索引:" + TaskIndex.ToString())
                                    .Append("**命令字" + dorder.ToString()).Append("**位置" + AGVAddress.ToString());

                CommonClassLib.CCarryConvert.WriteDarkCasket(this.ToString(), "发送AGV指令", DeviceIndex.ToString(), sss.ToString());
           
        }
        /// <summary>
        /// 发送AGV命令
        /// </summary>
        /// <param name="MessageIndex">消息编号</param>
        /// <param name="TaskIndex">任务编号</param>
        /// <param name="Order">AGV命令字 61:MAN通知LC通讯连接建立;62MAN通知LC通讯连接断开</param>
        /// <param name="DeviceIndex">设备编号</param>
        /// <returns>发送AGV设备命令是否成功</returns>
        public bool SendDeviceOrder(int MessageIndex, int TaskIndex, int Order, int DeviceIndex, int ArrowDeviceIndex)
        {
            Model.MDevice devinfo = Model.CGetInfo.GetDeviceInfo(DeviceIndex);
            try
            {
                byte[] _Sdata = new byte[2];
                _Sdata[0] = Convert.ToByte(Order);
                _Sdata[1] = 0;
                _Sdata[2] = Convert.ToByte(TaskIndex & 255);//低八位
                _Sdata[3] = Convert.ToByte(TaskIndex >> 8);//高八位

                //根据DeviceIndex,得到Sockets通讯的初始设置



                if (devinfo == null)
                {
                    return false;
                }
                else
                {

                    CClientTCPIP.Send(devinfo.RemoteIP, devinfo.RemotePort, _Sdata);
                    return true;

                }

            }
            catch (Exception ex)
            {
                _commLayerError = this.ToString() + ":SendDeviceOrder---" + ex.Message;
                return false;
            }
            finally
            {
                devinfo = null;
            }

        }
        /// <summary>
        /// 上位机给下位机发送烟箱按品牌码分道信息共15字节,有数据时写入实际数据,否则全部写零
        /// </summary>
        /// <param name="DeviceIndex">码垛位设备号索引</param>
        /// <param name="TobaccoCode">第1--13字节,烟箱码</param>
        /// <param name="HaveFirstProjectCode">第14字节,1-有一号工程码,0-无一号工程码</param>
        /// <param name="IfSmallTobacco">第15字节,1-小烟箱,0-正常烟箱</param>
        /// <returns></returns>
        public bool SendDeviceOrder(int DeviceIndex, string TobaccoCode, bool HaveFirstProjectCode, bool IfSmallTobacco,int Count)
        {
            return true;
        }
        bool SendData(int devID, byte[] _Sdata)
        {
            //根据DeviceIndex,得到Sockets通讯的初始设置
            Model.MDevice devinfo = Model.CGetInfo.GetDeviceInfo(devID);
            try
            {
                if (devinfo == null)
                {
                    return false;
                }
                else
                {

                    if (CClientTCPIP.Send(devinfo.RemoteIP, devinfo.RemotePort, _Sdata) == false)
                    {
                        if (CClientTCPIP.TcpError != null) _commLayerError = CClientTCPIP.TcpError;
                        return false;
                    }
                    return true;

                }
            }
            finally
            {
                devinfo = null;
            }
        }
        /// <summary>
        /// 向PLC的DB区写入数据
        /// </summary>
        /// <param name="ItemNames">标签变量名称数组</param>
        /// <param name="ItemValues">标签值数组</param>
        /// <returns></returns>
        public bool WriteDBData(StringBuilder[] ItemNames, StringBuilder[] ItemValues)
        {
            return true;
        }
        public bool WriteDBData(StringBuilder[] ItemNames, StringBuilder[] ItemValues, string PLCconnectionID)
        {
            return true;
        }
        void GetDeviceInfoFromAGVGate(int agvGateDevice,ref char channelLeft,ref char useAwayFork,ref int AGVAddress)
        {
            DataView dv;
            try
            {
                sql.Remove(0, sql.Length);
                sql.Append("SELECT  F_Address,F_IfChannelLeft,F_UseAwayFork FROM T_Base_AGV_Gate WHERE (F_AGVGateDeviceIndex = " ).Append( agvGateDevice ).Append( ")");
                dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView;
                if (dv.Count > 0)
                {
                    channelLeft = Convert.ToChar(dv[0]["F_IfChannelLeft"]);
                    useAwayFork = Convert.ToChar(dv[0]["F_UseAwayFork"]);
                   // AGVAddress = Convert.ToChar(dv[0]["F_Address"]);
                    AGVAddress = Convert.ToInt32(dv[0]["F_Address"]);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                dv = null;
            }
        }
        int GetAGVNoFromMonitor(int taskIndex)
        {

            DataView dv;
            try
            {
                sql.Remove(0, sql.Length);
                sql.Append("SELECT F_AgvNo FROM T_Monitor_Task WHERE (F_MonitorIndex = " ).Append( taskIndex ).Append( ") and (F_AgvNo is not null)");
                dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView;
                if (dv.Count > 0)
                {
                    return Convert.ToInt32(dv[0][0]);
                }
                else
                {
                    return 65535;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                dv = null;
            }
        }
        int GetAGVTaskFromMonitor(int taskIndex)
        {

            DataView dv;
            try
            {
                sql.Remove(0, sql.Length);
                sql.Append("SELECT F_AgvTask FROM T_Monitor_Task WHERE (F_MonitorIndex = " ).Append( taskIndex ).Append( ") and (F_AgvTask is not null)");
                dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView;
                if (dv.Count > 0)
                {
                    return Convert.ToInt32(dv[0][0]);
                }
                else
                {
                    return 65535;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                dv = null;
            }
        }
        /// <summary>
        /// 是否有后续任务:1,有;0,无
        /// <summary>
        /// <param name="taskindex"></param>
        /// <returns></returns>
        int IfHaveNextTask(int taskindex,int deviceindex,ref int NextOrder)
        {
            int mankind = Model.CGeneralFunction.GetManageTaskKindIndexFromMonitor(taskindex);
            int fid = Model.CGeneralFunction.GetManageTaskIndexfromMonitor(taskindex);
            sql.Remove(0, sql.Length);
            sql.Append("SELECT F_MonitorIndex, F_DEVICECOMMANDINDEX FROM T_Monitor_Task WHERE (F_DeviceCommandIndex <> 5) AND (F_DeviceIndex = ").Append(deviceindex).Append(") AND (F_MonitorIndex <> ").Append(taskindex).Append(") AND F_ManageTaskIndex=").Append(fid).Append(" AND F_ManageTASKKINDINDEX=").Append(mankind).Append(" ORDER BY F_MonitorIndex asc");
            DataView dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView ;
            if (dv.Count > 0)
            {
                NextOrder = Convert.ToInt32(dv[0]["F_DEVICECOMMANDINDEX"]);
                dv = null;
                return 1;
            }
            else
            {
                dv = null;
                return 0;
            }

        }
        /// <summary>
        /// 根据fid、设备id 和 AGV命令 返回对应的任务号
        /// <summary> 
        int GetTaskFromDeviceOrder(int fid, int deviceIndx, int Order) 
        {
            DataView dv;
            try
            {
                sql.Remove(0, sql.Length);
                sql.Append(string.Format("select F_MonitorIndex from t_monitor_task where F_ManageTaskindex = {0} and F_DeviceIndex = {1} and F_DeviceCommandIndex = {2} order by F_MonitorIndex", fid, deviceIndx, Order));
                dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView;
                if (dv.Count > 0)
                {
                    return Convert.ToInt32(dv[0][0]);
                }
                else
                {
                    return 0;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                dv = null;
            }
        }

        public bool SendDeviceOrder(int MessageIndex, int TaskIndex, int Order, int DeviceIndex, int ArrowDeviceIndex, int boxnum)
        {
            return true;
        }
    }
}