package chuankou;
|
import java.text.SimpleDateFormat;
|
import java.util.Date;
|
|
import javax.swing.SwingWorker;
|
|
import chushihua.lunxun;
|
import dialog.Charulog;
|
import dialog.Dingshidialog;
|
import dialog.Errlog;
|
import publicway.OpenDoor;
|
import xitongshezhi.SystemDebugDialog;
|
|
/**
|
* 串口消息发送工具类
|
* 提供高性能的串口消息发送功能,适合高频调用
|
*/
|
public class Sendmsg {
|
// 静态串口服务实例
|
private static volatile SerialPortService serialService = null;
|
private static volatile boolean isPortOpen = false;
|
|
// 改为非final,支持动态控制
|
private static boolean DEBUG_MODE = false;
|
|
// 日期格式化
|
private static final SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss.SSS");
|
|
|
/**发卡服务器控制打开某个柜门调用指令
|
* @param int slotId柜门编号1-60
|
* @param int type 1是服务器发卡,2是管理员发卡*/
|
public static boolean opendoorzhiling(int slotId,int type) {
|
lunxun.setSendChaxunzhiling(false);//暂停查询指令
|
// 调用OpenDoor生成开门指令
|
String command = OpenDoor.openOneDoor(slotId, type);
|
boolean sendResult = Sendmsg.sendMessage(command);
|
String mes=command+";type"+type+"控制打开"+slotId+"柜门";
|
Charulog.logOperation(mes);
|
if (lunxun.DEBUG_ENABLED) {
|
SystemDebugDialog.appendAsciiData(mes);
|
}
|
|
lunxun.setSendChaxunzhiling(true);//开始查询指令
|
return sendResult;
|
}
|
|
/**
|
* 打开全部卡槽的公用静态方法
|
* @param type 操作类型:1-服务器发卡,2-管理员发卡
|
*/
|
public static void openAllSlots(int type) {
|
lunxun.setSendChaxunzhiling(false);//暂停查询指令
|
// 使用SwingWorker在后台执行,避免阻塞UI
|
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
|
@Override
|
protected Void doInBackground() throws Exception {
|
// 遍历所有卡槽(1-60)
|
for (int slotId = 1; slotId <= 60; slotId++) {
|
try {
|
// 生成开门指令
|
String command = OpenDoor.openOneDoor(slotId, type);
|
|
// 发送串口指令
|
boolean sent = Sendmsg.sendMessage(command);
|
|
if (!sent) {
|
Errlog.logOperation("发送指令到卡槽 " + slotId + " 失败");
|
}
|
|
// 间隔100ms
|
Thread.sleep(100);
|
|
} catch (Exception e) {
|
Errlog.logOperation("处理卡槽 " + slotId + " 时发生错误: " + e.getMessage());
|
e.printStackTrace();
|
}
|
}
|
return null;
|
}
|
|
@Override
|
protected void done() {
|
// 可选:完成后可以添加回调处理
|
System.out.println("全部卡槽开门指令发送完成");
|
String types="管理员";
|
if(type==1) {
|
types="服务器指令";
|
}
|
String message=types+"已将全部卡槽已经打开请取卡";
|
Dingshidialog.showTimedDialog(null,5,message);
|
Charulog.logOperation(message);
|
}
|
};
|
|
worker.execute();
|
lunxun.setSendChaxunzhiling(true);//开始查询指令
|
}
|
|
|
/**
|
* 设置串口服务实例
|
* @param service 串口服务实例
|
* @param open 串口是否打开
|
*/
|
public static void setSerialService(SerialPortService service, boolean open) {
|
serialService = service;
|
isPortOpen = open;
|
}
|
|
/**
|
* 获取串口服务实例
|
*/
|
public static SerialPortService getSerialService() {
|
return serialService;
|
}
|
|
/**
|
* 发送消息到串口(带重试机制)
|
*/
|
public static boolean sendMessage(String message) {
|
if (!isPortOpen || serialService == null) {
|
Errlog.logOperation("[" + getCurrentTime() + "] 串口未打开,无法发送数据");
|
return false;
|
}
|
|
if (message == null || message.trim().isEmpty()) {
|
Errlog.logOperation("[" + getCurrentTime() + "] 发送数据为空");
|
return false;
|
}
|
|
String text = message.trim();
|
int retryCount = 0;
|
final int MAX_RETRY = 2;
|
|
while (retryCount <= MAX_RETRY) {
|
try {
|
byte[] data = hexStringToByteArray(text);
|
if (data == null) {
|
Errlog.logOperation("[" + getCurrentTime() + "] HEX转换失败,数据: " + text);
|
return false;
|
}
|
|
boolean sendResult = serialService.send(data);
|
|
if (sendResult) {
|
if (DEBUG_MODE) {
|
System.out.println("[" + getCurrentTime() + "] 发送成功: " + text.toUpperCase());
|
}
|
return true;
|
} else {
|
retryCount++;
|
if (retryCount <= MAX_RETRY) {
|
Errlog.logOperation("[" + getCurrentTime() + "] 发送失败,正在重试 (" + retryCount + "/" + MAX_RETRY + ")");
|
try {
|
Thread.sleep(50); // 重试前等待
|
} catch (InterruptedException e) {
|
Thread.currentThread().interrupt();
|
break;
|
}
|
} else {
|
Errlog.logOperation("[" + getCurrentTime() + "] 串口发送失败,指令: " + text.toUpperCase());
|
Errlog.logOperation("[" + getCurrentTime() + "] 串口状态 - 打开: " + isPortOpen + ", 服务: " + (serialService != null));
|
if (serialService != null) {
|
Errlog.logOperation("[" + getCurrentTime() + "] 串口服务状态 - 是否打开: " + serialService.isOpen());
|
}
|
return false;
|
}
|
}
|
} catch (Exception e) {
|
Errlog.logOperation("[" + getCurrentTime() + "] 发送异常,指令: " + text.toUpperCase());
|
e.printStackTrace();
|
return false;
|
}
|
}
|
|
return false;
|
}
|
|
/**
|
* 检查串口是否已打开
|
* @return 串口打开状态
|
*/
|
public static boolean isPortOpen() {
|
boolean open = isPortOpen && serialService != null;
|
if (!open && DEBUG_MODE) {
|
Errlog.logOperation("[" + getCurrentTime() + "] 串口状态检查: 未打开");
|
}
|
return open;
|
}
|
|
/**
|
* HEX字符串转字节数组
|
* @param s HEX字符串
|
* @return 字节数组
|
*/
|
private static byte[] hexStringToByteArray(String s) {
|
if (s == null || s.isEmpty()) {
|
return new byte[0];
|
}
|
|
s = s.replaceAll("\\s+", ""); // 移除空格
|
int len = s.length();
|
if (len % 2 != 0) {
|
throw new IllegalArgumentException("HEX字符串长度必须为偶数,当前长度: " + len + ", 数据: " + s);
|
}
|
|
byte[] data = new byte[len / 2];
|
for (int i = 0; i < len; i += 2) {
|
int high = Character.digit(s.charAt(i), 16);
|
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) + "' 在位置 " + i + "-" + (i+1) + ", 完整数据: " + s);
|
}
|
|
data[i / 2] = (byte) ((high << 4) + low);
|
}
|
return data;
|
}
|
|
/**
|
* 字节数组转HEX字符串
|
* @param bytes 字节数组
|
* @return HEX字符串
|
*/
|
public static String bytesToHex(byte[] bytes) {
|
if (bytes == null || bytes.length == 0) {
|
return "";
|
}
|
|
StringBuilder sb = new StringBuilder();
|
for (byte b : bytes) {
|
sb.append(String.format("%02x", b));
|
}
|
return sb.toString();
|
}
|
|
/**
|
* 获取当前时间字符串
|
* @return 时间字符串
|
*/
|
private static String getCurrentTime() {
|
return timeFormat.format(new Date());
|
}
|
|
/**
|
* 启用调试模式
|
*/
|
public static void enableDebugMode() {
|
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 ? "启用" : "禁用"));
|
}
|
}
|