package com.zy.common.HslCommunication.Profinet.Melsec; import com.zy.common.HslCommunication.Core.Types.OperateResultExTwo; import com.zy.common.HslCommunication.Utilities; /** * 所有三菱通讯类的通用辅助工具类,包含了一些通用的静态方法,可以使用本类来获取一些原始的报文信息。详细的操作参见例子 */ public class MelsecHelper { /** * 解析A1E协议数据地址 * @param address 数据地址 * @return 解析值 */ public static OperateResultExTwo McA1EAnalysisAddress( String address ) { OperateResultExTwo result = new OperateResultExTwo(); try { switch (address.charAt(0)) { case 'X': case 'x': { result.Content1 = MelsecA1EDataType.X; result.Content2 = Short.parseShort(address.substring(1), MelsecA1EDataType.X.getFromBase()); break; } case 'Y': case 'y': { result.Content1 = MelsecA1EDataType.Y; result.Content2 = Short.parseShort(address.substring(1), MelsecA1EDataType.Y.getFromBase()); break; } case 'M': case 'm': { result.Content1 = MelsecA1EDataType.M; result.Content2 = Short.parseShort(address.substring(1), MelsecA1EDataType.M.getFromBase()); break; } case 'S': case 's': { result.Content1 = MelsecA1EDataType.S; result.Content2 = Short.parseShort(address.substring(1), MelsecA1EDataType.S.getFromBase()); break; } case 'D': case 'd': { result.Content1 = MelsecA1EDataType.D; result.Content2 = Short.parseShort(address.substring(1), MelsecA1EDataType.D.getFromBase()); break; } case 'R': case 'r': { result.Content1 = MelsecA1EDataType.R; result.Content2 = Short.parseShort(address.substring(1), MelsecA1EDataType.R.getFromBase()); break; } default: throw new Exception("输入的类型不支持,请重新输入"); } } catch (Exception ex) { result.Message = "地址格式填写错误:" + ex.getMessage(); return result; } result.IsSuccess = true; return result; } /** * 解析数据地址 * @param address 数据地址 * @return 解析值 */ public static OperateResultExTwo McAnalysisAddress( String address ) { OperateResultExTwo result = new OperateResultExTwo(); try { switch (address.charAt(0)) { case 'M': case 'm': { result.Content1 = MelsecMcDataType.M; result.Content2 = Short.parseShort(address.substring(1), MelsecMcDataType.M.getFromBase()); break; } case 'X': case 'x': { result.Content1 = MelsecMcDataType.X; result.Content2 = Short.parseShort(address.substring(1), MelsecMcDataType.X.getFromBase()); break; } case 'Y': case 'y': { result.Content1 = MelsecMcDataType.Y; result.Content2 = Short.parseShort(address.substring(1), MelsecMcDataType.Y.getFromBase()); break; } case 'D': case 'd': { result.Content1 = MelsecMcDataType.D; result.Content2 = Short.parseShort(address.substring(1), MelsecMcDataType.D.getFromBase()); break; } case 'W': case 'w': { result.Content1 = MelsecMcDataType.W; result.Content2 = Short.parseShort(address.substring(1), MelsecMcDataType.W.getFromBase()); break; } case 'L': case 'l': { result.Content1 = MelsecMcDataType.L; result.Content2 = Short.parseShort(address.substring(1), MelsecMcDataType.L.getFromBase()); break; } case 'F': case 'f': { result.Content1 = MelsecMcDataType.F; result.Content2 = Short.parseShort(address.substring(1), MelsecMcDataType.F.getFromBase()); break; } case 'V': case 'v': { result.Content1 = MelsecMcDataType.V; result.Content2 = Short.parseShort(address.substring(1), MelsecMcDataType.V.getFromBase()); break; } case 'B': case 'b': { result.Content1 = MelsecMcDataType.B; result.Content2 = Short.parseShort(address.substring(1), MelsecMcDataType.B.getFromBase()); break; } case 'R': case 'r': { result.Content1 = MelsecMcDataType.R; result.Content2 = Short.parseShort(address.substring(1), MelsecMcDataType.R.getFromBase()); break; } case 'S': case 's': { result.Content1 = MelsecMcDataType.S; result.Content2 = Short.parseShort(address.substring(1), MelsecMcDataType.S.getFromBase()); break; } case 'Z': case 'z': { result.Content1 = MelsecMcDataType.Z; result.Content2 = Short.parseShort(address.substring(1), MelsecMcDataType.Z.getFromBase()); break; } case 'T': case 't': { result.Content1 = MelsecMcDataType.T; result.Content2 = Short.parseShort(address.substring(1), MelsecMcDataType.T.getFromBase()); break; } case 'C': case 'c': { result.Content1 = MelsecMcDataType.C; result.Content2 = Short.parseShort(address.substring(1), MelsecMcDataType.C.getFromBase()); break; } default: throw new Exception("输入的类型不支持,请重新输入"); } } catch (Exception ex) { result.Message = "地址格式填写错误:" + ex.getMessage(); return result; } result.IsSuccess = true; return result; } /** * 从字节构建一个ASCII格式的地址字节 * @param value 字节信息 * @return ASCII格式的地址 */ public static byte[] BuildBytesFromData(byte value ) { return Utilities.getBytes(String.format("%02x",value),"ASCII"); } /** * 从short数据构建一个ASCII格式地址字节 * @param value short值 * @return ASCII格式的地址 */ public static byte[] BuildBytesFromData( short value ) { return Utilities.getBytes(String.format("%04x",value),"ASCII"); } /** * 从int数据构建一个ASCII格式地址字节 * @param value int值 * @return ASCII格式的地址 */ public static byte[] BuildBytesFromData( int value ) { return Utilities.getBytes(String.format("%04x",value),"ASCII"); } /** * 从三菱的地址中构建MC协议的6字节的ASCII格式的地址 * @param address 三菱地址 * @param type 三菱的数据类型 * @return 6字节的ASCII格式的地址 */ public static byte[] BuildBytesFromAddress( int address, MelsecMcDataType type ) { return Utilities.getBytes(String.format(type.getFromBase() == 10 ? "%06d" : "%06x",address),"ASCII"); } /** * 从字节数组构建一个ASCII格式的地址字节 * @param value 字节信息 * @return ASCII格式的地址 */ public static byte[] BuildBytesFromData( byte[] value ) { byte[] buffer = new byte[value.length * 2]; for (int i = 0; i < value.length; i++) { byte[] data = BuildBytesFromData( value[i] ); buffer[2*i+0] = data[0]; buffer[2*i+1] = data[1]; } return buffer; } /** * 将0,1,0,1的字节数组压缩成三菱格式的字节数组来表示开关量的 * @param value 原始的数据字节 * @return 压缩过后的数据字节 */ public static byte[] TransBoolArrayToByteData( byte[] value ) { int length = value.length % 2 == 0 ? value.length / 2 : (value.length / 2) + 1; byte[] buffer = new byte[length]; for (int i = 0; i < length; i++) { if (value[i * 2 + 0] != 0x00) buffer[i] += 0x10; if ((i * 2 + 1) < value.length) { if (value[i * 2 + 1] != 0x00) buffer[i] += 0x01; } } return buffer; } /** * 计算Fx协议指令的和校验信息 * @param data 字节数据 * @return 校验之后的数据 */ public static byte[] FxCalculateCRC( byte[] data ) { int sum = 0; for (int i = 1; i < data.length - 2; i++) { sum += data[i]; } return BuildBytesFromData( (byte)sum ); } /** * 检查指定的和校验是否是正确的 * @param data 字节数据 * @return 是否成功 */ public static boolean CheckCRC( byte[] data ) { byte[] crc = FxCalculateCRC( data ); if (crc[0] != data[data.length - 2]) return false; if (crc[1] != data[data.length - 1]) return false; return true; } }