using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Threading; using Microsoft.VisualBasic; using DBFactory; using ICommLayer; namespace SocketsTCPIP { /// /// 使用SocketsTCPIP的客户端进行通讯 /// 发送设备命令类 /// 创建者:Richard.Liu /// public class CSendDeviceOrder: ISendDeviceOrder { string _commLayerError; public string CommLayerError { get { return _commLayerError; } set { _commLayerError = value; } } DBOperator dbo = CClientTCPIP.dbo; string AGVAllowSingleFork = CommonClassLib.AppSettings.GetValue("AGVAllowSingleFork"); public CSendDeviceOrder() { dbo.Open(); } public bool SendDeviceOrder(int MessageIndex, int TaskIndex, int Order, int DeviceIndex, int StartX, int StartY, int StartZ, int EndX, int EndY, int EndZ,string DoubleFork) { return true; } /// /// 每两个字节(一个字)代表一个帧内容 /// 1客户端连接命令:标志头61;客户端断开命令:标志头62; /// 2任务开始命令:标志头63+任务优先级(1--8)+取货位编号+操作码+送货位编号+操作码 /// 操作码含义:0—无动作;1—辅料出库;2—空托盘回收;3—残烟、废纸的回收;4—剩余辅料返库;5—辅料出库,同时空托盘回收 /// 3取消任务:标志头65+任务编号(控制台分配的任务编号) /// 4申请辊道停止确认(可以向辅料回库口输送机放货):标志头67 /// 5查询小车状态:标志头69+小车编号 /// /// 消息编号 /// 任务编号 /// AGV命令字 /// 设备编号 /// [N1]:取货点 /// /// /// [N2]:放货点 /// /// /// 发送AGV命令是否成功 public bool SendDeviceOrder(int MessageIndex, int TaskIndex, int Order, int DeviceIndex, int StartX, int StartY, int StartZ, int EndX, int EndY, int EndZ) { //StartX取设备索引 EndX送设备索引 //28901:前叉左取 28902:前叉左送 28903:前叉右取 28904:前叉右送 //28905:后叉左取 28906:后叉左送 28907:后叉右取 28908:后叉右送 //28909:双叉左取 28910:双叉左送 28911:双叉右取 28912:双叉右送 //20100413根据StartX(取设备索引)获得前(距离车尾远)叉、后(距离车尾近)叉 //order==1 根据StartX(取设备索引)得到 取左右;order==2 根据EndX(送设备索引)得到 送左右 //站在车尾沿着行进方向的左、右方向; //判断关联双叉是否同步运行 char useAwayFork = '0'; char channelLeft = '0'; int AGVAddress = 0; int dorder = 0; int _device = GetAGVNoFromMonitor(TaskIndex); byte[] _Sdata; try { switch (Order) { case 1://取货命令 StartX取设备索引 GetDeviceInfoFromAGVGate(StartX, ref channelLeft, ref useAwayFork, ref AGVAddress); if ((Model.CGeneralFunction.DoubleForkIfSync(TaskIndex, DeviceIndex, 6) == false) && (AGVAllowSingleFork=="1"))//20100710 {//不能同步 GetDeviceInfoFromAGVGate(StartX, ref channelLeft, ref useAwayFork, ref AGVAddress); if (useAwayFork == '1')//前叉 { if (channelLeft == '1') { dorder = 28901;//前叉左取 } else { dorder = 28903;//前叉右取 } } else//后叉 { if (channelLeft == '1') { dorder = 28905;//后叉左取 } else { dorder = 28907;//后叉右取 } } } else {//同步 if (channelLeft == '1') { dorder = 28909;//双叉左取 } else { dorder = 28911;//双叉右取 } } _Sdata = new byte[10]; _Sdata[0] = 72; _Sdata[1] = 0; _Sdata[2] = Convert.ToByte(TaskIndex & 255); _Sdata[3] = Convert.ToByte(TaskIndex >> 8); _Sdata[4] = Convert.ToByte(AGVAddress & 255); _Sdata[5] = Convert.ToByte(AGVAddress >> 8); _Sdata[6] = Convert.ToByte(dorder & 255); _Sdata[7] = Convert.ToByte(dorder >> 8); _Sdata[8] = Convert.ToByte(_device & 255); _Sdata[9] = Convert.ToByte(_device >> 8); return SendData(DeviceIndex, _Sdata); case 2://送货命令 GetDeviceInfoFromAGVGate(EndX, ref channelLeft, ref useAwayFork, ref AGVAddress); if ((Model.CGeneralFunction.DoubleForkIfSync(TaskIndex, DeviceIndex, 6) == false) && (AGVAllowSingleFork == "1"))//20100710 {//不能同步 GetDeviceInfoFromAGVGate(EndX, ref channelLeft, ref useAwayFork, ref AGVAddress); if (useAwayFork == '1')//前叉 { if (channelLeft == '1') { dorder = 28902;//前叉左送 } else { dorder = 28904;//前叉右送 } } else//后叉 { if (channelLeft == '1') { dorder = 28906;//后叉左送 } else { dorder = 28908;//后叉右送 } } } else {//同步 if (channelLeft == '1') { dorder = 28910;//双叉左送 } else { dorder = 28912;//双叉右送 } } _Sdata = new byte[10]; _Sdata[0] = 72; _Sdata[1] = 0; _Sdata[2] = Convert.ToByte(TaskIndex & 255); _Sdata[3] = Convert.ToByte(TaskIndex >> 8); _Sdata[4] = Convert.ToByte(AGVAddress & 255); _Sdata[5] = Convert.ToByte(AGVAddress >> 8); _Sdata[6] = Convert.ToByte(dorder & 255); _Sdata[7] = Convert.ToByte(dorder >> 8); _Sdata[8] = Convert.ToByte(_device & 255); _Sdata[9] = Convert.ToByte(_device >> 8); return SendData(DeviceIndex, _Sdata); case 3: //发送完成的应答帧75 _Sdata = new byte[6]; _Sdata[0] = 75; _Sdata[1] = 0; TaskIndex = GetAGVTaskFromMonitor(TaskIndex); _Sdata[2] = Convert.ToByte(TaskIndex & 255); _Sdata[3] = Convert.ToByte(TaskIndex >> 8); _Sdata[4] = Convert.ToByte(65535 & 255); _Sdata[5] = Convert.ToByte(65535 >> 8); return SendData(DeviceIndex, _Sdata); case 4: //发送运行 GetDeviceInfoFromAGVGate(EndX, ref channelLeft, ref useAwayFork, ref AGVAddress); _Sdata = new byte[10]; _Sdata[0] = 72; _Sdata[1] = 0; _Sdata[2] = Convert.ToByte(TaskIndex & 255); _Sdata[3] = Convert.ToByte(TaskIndex >> 8); _Sdata[4] = Convert.ToByte(AGVAddress & 255); _Sdata[5] = Convert.ToByte(AGVAddress >> 8); _Sdata[6] = Convert.ToByte(65535 & 255);//运行 _Sdata[7] = Convert.ToByte(65535 >> 8); _Sdata[8] = Convert.ToByte(_device & 255); _Sdata[9] = Convert.ToByte(_device >> 8); return SendData(DeviceIndex, _Sdata); default: break; } return false; } catch (Exception ex) { _commLayerError = this.ToString() + ":SendDeviceOrder---" +ex.Message ; return false; } } /// /// 发送AGV命令 /// /// 消息编号 /// 任务编号 /// AGV命令字 61:MAN通知LC通讯连接建立;62MAN通知LC通讯连接断开 /// 设备编号 /// 发送AGV设备命令是否成功 public bool SendDeviceOrder(int MessageIndex, int TaskIndex, int Order, int DeviceIndex, int ArrowDeviceIndex) { 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通讯的初始设置 DataSet ds = dbo.ExceSQL("SELECT F_DeviceIndex,F_DeviceKindIndex, F_LocalIP, F_LocalPort, F_RemoteIP, F_RemotePort FROM T_Base_Device where F_DeviceIndex=" + DeviceIndex); DataView dv = ds.Tables[0].DefaultView; if (ds.Tables[0].DefaultView.Count == 0) { return false; } else { CClientTCPIP.Send(dv[0]["F_RemoteIP"].ToString(), (int)dv[0]["F_RemotePort"], _Sdata); return true; } } catch (Exception ex) { _commLayerError = this.ToString() + ":SendDeviceOrder---" + ex.Message; return false; } } /// /// 上位机给下位机发送烟箱按品牌码分道信息共15字节,有数据时写入实际数据,否则全部写零 /// /// 码垛位设备号索引 /// 第1--13字节,烟箱码 /// 第14字节,1-有一号工程码,0-无一号工程码 /// 第15字节,1-小烟箱,0-正常烟箱 /// public bool SendDeviceOrder(int DeviceIndex, string TobaccoCode, bool HaveFirstProjectCode, bool IfSmallTobacco,int Count) { return true; } bool SendData(int devID, byte[] _Sdata) { //根据DeviceIndex,得到Sockets通讯的初始设置 DataSet ds = dbo.ExceSQL("SELECT F_DeviceIndex,F_DeviceKindIndex, F_LocalIP, F_LocalPort, F_RemoteIP, F_RemotePort FROM T_Base_Device where F_DeviceIndex=" + devID); DataView dv = ds.Tables[0].DefaultView; if (dv.Count == 0) { return false; } else { if (CClientTCPIP.Send(dv[0]["F_RemoteIP"].ToString(), Convert.ToInt32(dv[0]["F_RemotePort"]), _Sdata) == false) { if (CClientTCPIP.TcpError != null) _commLayerError = CClientTCPIP.TcpError; return false; } return true; } } /// /// 向PLC的DB区写入数据 /// /// 标签变量名称数组 /// 标签值数组 /// public bool WriteDBData(StringBuilder[] ItemNames, StringBuilder[] ItemValues,int deviceindex) { return true; } void GetDeviceInfoFromAGVGate(int agvGateDevice,ref char channelLeft,ref char useAwayFork,ref int AGVAddress) { DataView dv; try { dv = dbo.ExceSQL("SELECT F_Address,F_IfChannelLeft,F_UseAwayFork FROM T_Base_AGV_Gate WHERE (F_AGVGateDeviceIndex = " + agvGateDevice + ")").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"]); } } catch (Exception ex) { throw ex; } finally { dv = null; } } int GetAGVNoFromMonitor(int taskIndex) { DataView dv; try { dv = dbo.ExceSQL("SELECT F_AgvNo FROM T_Monitor_Task WHERE (F_MonitorIndex = " + taskIndex + ") and (F_AgvNo is not null)").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 { dv = dbo.ExceSQL("SELECT F_AgvTask FROM T_Monitor_Task WHERE (F_MonitorIndex = " + taskIndex + ") and (F_AgvTask is not null)").Tables[0].DefaultView; if (dv.Count > 0) { return Convert.ToInt32(dv[0][0]); } else { return 65535; } } catch (Exception ex) { throw ex; } finally { dv = null; } } } }