13693261870
2025-07-02 6708810c4de34dfb9513061432d656f91d56ee3a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
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;
    }
}