package com.ruoyi.fuzhou.utils; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.fuzhou.domain.ReceiveModuleInfo; import com.ruoyi.fuzhou.utils.electricitymodbus.HexStringToInt; import com.ruoyi.fuzhou.utils.oilmodbus.Crc16Utils; import com.ruoyi.fuzhou.utils.watermodbus.FloatInverseWaterParser; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.ByteOrder; public class ModbusYdkfmjUtils { public static JSONObject getValue(ReceiveModuleInfo rmi) throws Exception { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(rmi.getPort()); System.out.println("🛡️ 服务端已启动,正在监听 " + rmi.getIp() + ":" + rmi.getPort() + "..."); serverSocket.setSoTimeout(1500); Socket clientSocket = serverSocket.accept(); System.out.println("🔌 客户端已连接: " + clientSocket.getInetAddress().getHostAddress() + ":" + clientSocket.getPort()); try (clientSocket; InputStream inputStream = clientSocket.getInputStream(); OutputStream outputStream = clientSocket.getOutputStream()) { ByteBuffer buffer = getRequestBuffer(rmi); outputStream.write(buffer.array()); // 发送请求帧 System.out.println("📤 已发送 MODBUS 请求: " + Crc16Utils.bytesToHex(buffer.array())); byte[] response = new byte[1024]; int bytesRead = inputStream.read(response); // 接收设备响应 if (bytesRead == -1) { System.out.println("❌ 未收到设备响应"); throw new Exception("未收到设备响应"); } byte[] data = new byte[bytesRead]; System.arraycopy(response, 0, data, 0, bytesRead); return getValue(data, rmi); } catch (Exception ex) { System.out.println("⚠️ 客户端异常断开: " + ex.getMessage()); throw ex; } } catch (Exception e) { System.out.println("❌ 服务端启动失败: " + e.getMessage()); throw e; } finally { if (serverSocket != null) { try { System.out.println("设备不在线"); serverSocket.close(); } catch (Exception ex) { System.out.println("❌ 服务端关闭失败: " + ex.getMessage()); } } } } private static ByteBuffer getRequestBuffer(ReceiveModuleInfo rmi) { ByteBuffer buffer = ByteBuffer.allocate(8); // 构造请求帧 if (rmi.getDeviceAddress() != 0) buffer.put(rmi.getDeviceAddress()); // 设备地址 if (rmi.getFunctionCode() != 0) buffer.put(rmi.getFunctionCode()); // 功能码 if (rmi.getRegisterAdress() != 0) buffer.putShort((short) rmi.getRegisterAdress().intValue()); // 寄存器地址 if (rmi.getRegisterCount() != 0) buffer.putShort((short) rmi.getRegisterCount().intValue()); // 寄存器数量 byte[] bytes = buffer.array(); // 计算CRC校验码 String hex = Crc16Utils.makeCRC(Crc16Utils.bytesToHex(bytes).substring(0, Crc16Utils.bytesToHex(bytes).length() - 4), true); int decimal = Integer.parseInt(hex, 16); buffer.putShort((short) decimal); // CRC校验码 return buffer; } private static JSONObject getValue(byte[] data, ReceiveModuleInfo rmi) throws Exception { String result = Crc16Utils.bytesToHex(data); System.out.println("📥 收到设备响应: " + result); // 打印响应数据 if (data.length < 6) { System.out.println("❌ 无效的响应长度: " + data.length + " 字节"); throw new Exception("无效的响应长度: " + data.length + " 字节"); } byte byteCount = data[2]; // 数据字节数 byte[] bytes = new byte[byteCount]; System.arraycopy(data, 3, bytes, 0, byteCount); byte[] crcReceived = new byte[2]; System.arraycopy(data, data.length - 2, crcReceived, 0, 2); byte functionCode = data[1]; // 功能码 if ((functionCode & 0x80) != 0) { // 检查是否为错误响应(功能码 + 0x80) byte errorCode = data[2]; // 错误码 System.out.println("❌ 设备返回错误响应,错误码: " + errorCode); throw new Exception("设备返回错误响应,错误码: " + errorCode); } JSONObject jsonObject = new JSONObject(); String src = result.substring(6, 6 + byteCount * 2); if (src.length() == 8) { byte[] arr = FloatInverseWaterParser.hexStringToByteArray(src); byte[] reversedBytes = FloatInverseWaterParser.reverseByteArray(arr); // 解析为浮点数(大端字节顺序) float floatValue = FloatInverseWaterParser.parseAsFloat(reversedBytes, ByteOrder.LITTLE_ENDIAN); jsonObject.put(rmi.getParamCode(), floatValue); System.out.println(rmi.getParam() + "的值为" + floatValue + rmi.getUnit()); } else { long value = HexStringToInt.hexStringToInt(src); jsonObject.put(rmi.getParamCode(), value); System.out.println(rmi.getParam() + "的值为" + value + rmi.getUnit()); } return jsonObject; } public static void main(String[] args) throws Exception { // 模拟发送数据 ReceiveModuleInfo rmi = new ReceiveModuleInfo(); rmi.setIp("0.0.0.0"); rmi.setPort(8379); rmi.setParam("获取开关状态"); rmi.setParamCode("getStatus"); rmi.setUnit(""); rmi.setDeviceAddress((byte) (1 & 0XFF)); rmi.setFunctionCode((byte) (3 & 0XFF)); rmi.setRegisterAdress(50); rmi.setRegisterCount(1); ByteBuffer requestBuffer = getRequestBuffer(rmi); System.out.println("requestBuffer = " + Crc16Utils.bytesToHex(requestBuffer.array())); // 模拟接收数据 ByteBuffer responseBuffer = ByteBuffer.allocate(7); responseBuffer.put((byte) (0x1)); responseBuffer.put((byte) (0x3)); responseBuffer.put((byte) (0x2)); responseBuffer.put((byte) (0x0)); responseBuffer.put((byte) (0x1)); responseBuffer.put((byte) (0x79)); responseBuffer.put((byte) (0x84)); String resp = Crc16Utils.bytesToHex(responseBuffer.array()); System.out.println("responseBuffer = " + resp); JSONObject jsonObject = getValue(responseBuffer.array(), rmi); System.out.println("json = " + jsonObject.toJSONString()); } public static boolean getYdkfmStatus(ReceiveModuleInfo rmi) throws Exception { return true; } public static boolean ctrlYdkfm(ReceiveModuleInfo rmi, Boolean flag) throws Exception { return true; } }