using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Text; using HslCommunication.Core; using HslCommunication.Core.IMessage; using HslCommunication.Core.Net; namespace HslCommunication.Robot.YASKAWA { /// /// 安川机器人的Ethernet 服务器功能的通讯类 /// public class YRC1000TcpNet : NetworkDoubleBase, IRobotNet { #region Constructor /// /// 实例化一个默认的对象 /// /// Ip地址 /// 端口号 public YRC1000TcpNet( string ipAddress, int port ) { } #endregion #region IRobot Interface /// /// 根据地址读取机器人的原始的字节数据信息 /// /// 指定的地址信息,对于某些机器人无效 /// 带有成功标识的byte[]数组 public OperateResult Read( string address ) { OperateResult read = ReadString( address ); if (!read.IsSuccess) return OperateResult.CreateFailedResult( read ); return OperateResult.CreateSuccessResult( Encoding.ASCII.GetBytes( read.Content ) ); } /// /// 根据地址读取机器人的字符串的数据信息 /// /// 地址信息 /// 带有成功标识的字符串数据 public OperateResult ReadString( string address ) { if (address.IndexOf( '.' ) >= 0 || address.IndexOf( ':' ) >= 0 || address.IndexOf( ';' ) >= 0) { string[] commands = address.Split( new char[] { '.', ':', ';' } ); return ReadByCommand( commands[0], commands[1] ); } else { return ReadByCommand( address, null ); } } /// /// 根据地址,来写入设备的相关的数据 /// /// 指定的地址信息,有些机器人可能不支持 /// 原始的字节数据信息 /// 是否成功的写入 public OperateResult Write( string address, byte[] value ) { return Write( address, Encoding.ASCII.GetString( value ) ); } /// /// 根据地址,来写入设备相关的数据 /// /// 指定的地址信息,有些机器人可能不支持 /// 字符串的数据信息 /// 是否成功的写入 public OperateResult Write( string address, string value ) { return ReadByCommand( address, value ); } #endregion #region Initialization Override /// /// before read data , the connection should be Initialized /// /// connected socket /// whether is the Initialization is success. protected override OperateResult InitializationOnConnect( Socket socket ) { var read = ReadFromCoreServer( socket, "CONNECT Robot_access KeepAlive:-1\r\n" ); if (!read.IsSuccess) return read; if (read.Content != "OK:YR Information Server(Ver) Keep-Alive:-1.\r\n") return new OperateResult( read.Content ); return OperateResult.CreateSuccessResult( ); } #endregion #region Override Read /// /// 重写父类的数据交互方法,接收的时候采用标识符来接收 /// /// 套接字 /// 发送的数据 /// 发送结果对象 public override OperateResult ReadFromCoreServer( Socket socket, byte[] send ) { LogNet?.WriteDebug( ToString( ), StringResources.Language.Send + " : " + BasicFramework.SoftBasic.ByteToHexString( send, ' ' ) ); // send OperateResult sendResult = Send( socket, send ); if (!sendResult.IsSuccess) { socket?.Close( ); return OperateResult.CreateFailedResult( sendResult ); } if (ReceiveTimeOut < 0) return OperateResult.CreateSuccessResult( new byte[0] ); // receive msg OperateResult resultReceive = NetSupport.ReceiveCommandLineFromSocket( socket, (byte)'\r', (byte)'\n' ); if (!resultReceive.IsSuccess) return new OperateResult( StringResources.Language.ReceiveDataTimeout + ReceiveTimeOut ); LogNet?.WriteDebug( ToString( ), StringResources.Language.Receive + " : " + BasicFramework.SoftBasic.ByteToHexString( resultReceive.Content, ' ' ) ); // Success return OperateResult.CreateSuccessResult( resultReceive.Content ); } /// /// Read string value from socket /// /// connected socket /// string value /// received string value with is successfully protected OperateResult ReadFromCoreServer( Socket socket, string send ) { var read = ReadFromCoreServer( socket, Encoding.Default.GetBytes( send ) ); if (!read.IsSuccess) return OperateResult.CreateFailedResult( read ); return OperateResult.CreateSuccessResult( Encoding.Default.GetString( read.Content ) ); } /// /// 根据指令来读取设备的信息,如果命令数据为空,则传入null即可,注意,所有的命令不带换行符 /// /// 命令的内容 /// 命令数据内容 /// 最终的结果内容,需要对IsSuccess进行验证 public OperateResult ReadByCommand( string command, string commandData ) { InteractiveLock.Enter( ); // 获取有用的网络通道,如果没有,就建立新的连接 OperateResult resultSocket = GetAvailableSocket( ); if (!resultSocket.IsSuccess) { IsSocketError = true; if (AlienSession != null) AlienSession.IsStatusOk = false; InteractiveLock.Leave( ); return OperateResult.CreateFailedResult( resultSocket ); } // 先发送命令 string sendCommand = string.IsNullOrEmpty( commandData ) ? $"HOSTCTRL_REQUEST {command} 0\r\n" : $"HOSTCTRL_REQUEST {command} {commandData.Length}\r\n"; OperateResult readCommand = ReadFromCoreServer( resultSocket.Content, sendCommand ); if (!readCommand.IsSuccess) { IsSocketError = true; if (AlienSession != null) AlienSession.IsStatusOk = false; InteractiveLock.Leave( ); return OperateResult.CreateFailedResult( readCommand ); } // 检查命令是否返回成功的状态 if (!readCommand.Content.StartsWith( "OK:" )) { if (!isPersistentConn) resultSocket.Content?.Close( ); InteractiveLock.Leave( ); return new OperateResult( readCommand.Content.Remove( readCommand.Content.Length - 2 ) ); } // 在必要的情况下发送命令数据 if(!string.IsNullOrEmpty( commandData )) { byte[] send2 = Encoding.ASCII.GetBytes( $"{commandData}\r" ); LogNet?.WriteDebug( ToString( ), StringResources.Language.Send + " : " + BasicFramework.SoftBasic.ByteToHexString( send2, ' ' ) ); OperateResult sendResult2 = Send( resultSocket.Content, send2 ); if (!sendResult2.IsSuccess) { resultSocket.Content?.Close( ); IsSocketError = true; if (AlienSession != null) AlienSession.IsStatusOk = false; InteractiveLock.Leave( ); return OperateResult.CreateFailedResult( sendResult2 ); } } // 接收数据信息,先接收到\r为止,再根据实际情况决定是否接收\r OperateResult resultReceive2 = NetSupport.ReceiveCommandLineFromSocket( resultSocket.Content, (byte)'\r' ); if (!resultReceive2.IsSuccess) { IsSocketError = true; if (AlienSession != null) AlienSession.IsStatusOk = false; InteractiveLock.Leave( ); return OperateResult.CreateFailedResult( resultReceive2 ); } string commandDataReturn = Encoding.ASCII.GetString( resultReceive2.Content ); if (commandDataReturn.StartsWith( "ERROR:" )) { if (!isPersistentConn) resultSocket.Content?.Close( ); InteractiveLock.Leave( ); NetSupport.ReadBytesFromSocket( resultSocket.Content, 1 ); return new OperateResult( commandDataReturn ); } else if (commandDataReturn.StartsWith( "0000\r" )) { if (!isPersistentConn) resultSocket.Content?.Close( ); NetSupport.ReadBytesFromSocket( resultSocket.Content, 1 ); InteractiveLock.Leave( ); return OperateResult.CreateSuccessResult( "0000" ); } else { if (!isPersistentConn) resultSocket.Content?.Close( ); InteractiveLock.Leave( ); return OperateResult.CreateSuccessResult( commandDataReturn.Remove( commandDataReturn.Length - 1 ) ); } } #endregion #region Public Method /// /// 读取机器人的报警信息 /// /// 原始的报警信息 public OperateResult ReadRALARM( ) { return ReadByCommand( "RALARM", null ); } /// /// 读取机器人的坐标数据信息 /// /// 原始的报警信息 public OperateResult ReadRPOSJ( ) { return ReadByCommand( "RPOSJ", null ); } #endregion #region Object Override /// /// 返回表示当前对象的字符串 /// /// 字符串信息 public override string ToString( ) { return $"YRC1000TcpNet Robot[{IpAddress}:{Port}]"; } #endregion #region Static Member #endregion } }