| | |
| | | private static volatile SerialPortService serialService = null; |
| | | private static volatile boolean isPortOpen = false; |
| | | |
| | | // 调试模式开关 |
| | | private static final boolean DEBUG_MODE = false; |
| | | // 改为非final,支持动态控制 |
| | | private static boolean DEBUG_MODE = false; |
| | | |
| | | // 日期格式化 |
| | | private static final SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss.SSS"); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 发送消息到串口 |
| | | * @param message 要发送的HEX格式消息 |
| | | * @return 发送成功返回true,失败返回false |
| | | * 发送消息到串口(带重试机制) |
| | | */ |
| | | public static boolean sendMessage(String message) { |
| | | if (!isPortOpen || serialService == null) { |
| | | if (DEBUG_MODE) { |
| | | System.err.println("[" + getCurrentTime() + "] 串口未打开,无法发送数据"); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | if (message == null || message.trim().isEmpty()) { |
| | | if (DEBUG_MODE) { |
| | | System.err.println("[" + getCurrentTime() + "] 发送数据为空"); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | String text = message.trim(); |
| | | int retryCount = 0; |
| | | final int MAX_RETRY = 2; |
| | | |
| | | while (retryCount <= MAX_RETRY) { |
| | | try { |
| | | // HEX格式发送 |
| | | byte[] data = hexStringToByteArray(text); |
| | | if (data != null && serialService.send(data)) { |
| | | // 高频调用时避免频繁的日志输出,只在调试时记录 |
| | | if (data == null) { |
| | | System.err.println("[" + getCurrentTime() + "] HEX转换失败,数据: " + text); |
| | | return false; |
| | | } |
| | | |
| | | boolean sendResult = serialService.send(data); |
| | | |
| | | if (sendResult) { |
| | | if (DEBUG_MODE) { |
| | | System.out.println("[" + getCurrentTime() + "] 发送: " + text.toUpperCase()); |
| | | System.out.println("[" + getCurrentTime() + "] 发送成功: " + text.toUpperCase()); |
| | | } |
| | | return true; |
| | | } else { |
| | | if (DEBUG_MODE) { |
| | | System.err.println("[" + getCurrentTime() + "] 数据发送失败"); |
| | | retryCount++; |
| | | if (retryCount <= MAX_RETRY) { |
| | | System.err.println("[" + getCurrentTime() + "] 发送失败,正在重试 (" + retryCount + "/" + MAX_RETRY + ")"); |
| | | try { |
| | | Thread.sleep(50); // 重试前等待 |
| | | } catch (InterruptedException e) { |
| | | Thread.currentThread().interrupt(); |
| | | break; |
| | | } |
| | | } else { |
| | | System.err.println("[" + getCurrentTime() + "] 串口发送失败,指令: " + text.toUpperCase()); |
| | | System.err.println("[" + getCurrentTime() + "] 串口状态 - 打开: " + isPortOpen + ", 服务: " + (serialService != null)); |
| | | if (serialService != null) { |
| | | System.err.println("[" + getCurrentTime() + "] 串口服务状态 - 是否打开: " + serialService.isOpen()); |
| | | } |
| | | return false; |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | if (DEBUG_MODE) { |
| | | System.err.println("[" + getCurrentTime() + "] 数据格式错误: " + e.getMessage()); |
| | | } |
| | | System.err.println("[" + getCurrentTime() + "] 发送异常,指令: " + text.toUpperCase()); |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | |
| | | * @return 串口打开状态 |
| | | */ |
| | | public static boolean isPortOpen() { |
| | | return isPortOpen && serialService != null; |
| | | boolean open = isPortOpen && serialService != null; |
| | | if (!open && DEBUG_MODE) { |
| | | System.err.println("[" + getCurrentTime() + "] 串口状态检查: 未打开"); |
| | | } |
| | | return open; |
| | | } |
| | | |
| | | /** |
| | |
| | | s = s.replaceAll("\\s+", ""); // 移除空格 |
| | | int len = s.length(); |
| | | if (len % 2 != 0) { |
| | | throw new IllegalArgumentException("HEX字符串长度必须为偶数"); |
| | | throw new IllegalArgumentException("HEX字符串长度必须为偶数,当前长度: " + len + ", 数据: " + s); |
| | | } |
| | | |
| | | byte[] data = new byte[len / 2]; |
| | |
| | | int low = Character.digit(s.charAt(i + 1), 16); |
| | | |
| | | if (high == -1 || low == -1) { |
| | | throw new IllegalArgumentException("无效的HEX字符: " + s.charAt(i) + s.charAt(i + 1)); |
| | | throw new IllegalArgumentException("无效的HEX字符: '" + s.charAt(i) + s.charAt(i + 1) + "' 在位置 " + i + "-" + (i+1) + ", 完整数据: " + s); |
| | | } |
| | | |
| | | data[i / 2] = (byte) ((high << 4) + low); |
| | |
| | | |
| | | /** |
| | | * 启用调试模式 |
| | | * 注意:这会修改静态final变量,实际项目中不建议这样做 |
| | | * 这里只是演示,实际应该通过配置文件控制 |
| | | */ |
| | | public static void enableDebugMode() { |
| | | // 在实际项目中,应该使用可配置的方式而不是修改final变量 |
| | | // 这里只是示意,实际使用时需要重新设计 |
| | | System.out.println("调试模式已启用"); |
| | | DEBUG_MODE = true; |
| | | System.out.println("[" + getCurrentTime() + "] Sendmsg调试模式已启用"); |
| | | } |
| | | |
| | | /** |
| | | * 禁用调试模式 |
| | | */ |
| | | public static void disableDebugMode() { |
| | | DEBUG_MODE = false; |
| | | System.out.println("[" + getCurrentTime() + "] Sendmsg调试模式已禁用"); |
| | | } |
| | | |
| | | /** |
| | | * 设置调试模式 |
| | | */ |
| | | public static void setDebugMode(boolean debug) { |
| | | DEBUG_MODE = debug; |
| | | System.out.println("[" + getCurrentTime() + "] Sendmsg调试模式: " + (debug ? "启用" : "禁用")); |
| | | } |
| | | } |