package chushihua;
|
|
import chuankou.Sendmsg;
|
import home.MachineConfig;
|
import publicway.QueryData;
|
|
/**
|
* 轮询查询类
|
* 用于定时向所有卡槽发送查询指令
|
* 支持暂停和恢复功能,检查串口连接状态
|
*/
|
public class lunxun {
|
private static volatile boolean isRunning = false;
|
private static volatile boolean isPaused = false;
|
private static Thread pollingThread;
|
private static int pollingInterval = 100; // 默认轮询间隔
|
|
// 卡槽相关常量
|
private static final int MIN_SLOT = 1;
|
private static final int MAX_SLOT = 60;
|
|
// 串口连接检查相关
|
private static final int SERIAL_CHECK_INTERVAL = 5000; // 5秒检查一次串口连接
|
private static long lastSerialCheckTime = 0;
|
private static boolean serialConnected = false;
|
|
/**
|
* 检查串口连接状态
|
* @return true-串口已连接, false-串口未连接
|
*/
|
public static boolean checkSerialConnection() {
|
// 避免频繁检查,每5秒检查一次
|
long currentTime = System.currentTimeMillis();
|
if (currentTime - lastSerialCheckTime < SERIAL_CHECK_INTERVAL) {
|
return serialConnected;
|
}
|
|
lastSerialCheckTime = currentTime;
|
|
try {
|
// 简化检查:直接检查Sendmsg的串口状态,而不是发送测试指令
|
boolean result = Sendmsg.isPortOpen();
|
|
if (result) {
|
System.out.println("串口连接正常");
|
serialConnected = true;
|
} else {
|
System.err.println("串口连接失败 - 串口未打开");
|
serialConnected = false;
|
}
|
} catch (Exception e) {
|
System.err.println("串口连接检查异常: " + e.getMessage());
|
serialConnected = false;
|
}
|
|
return serialConnected;
|
}
|
|
/**
|
* 启动轮询查询
|
* @return true-启动成功, false-启动失败
|
*/
|
public static boolean startPolling() {
|
if (isRunning) {
|
System.out.println("轮询查询已经在运行中");
|
return true;
|
}
|
|
// 启动前严格检查串口连接
|
if (!checkSerialConnection()) {
|
System.err.println("串口未连接,无法启动轮询查询");
|
return false;
|
}
|
|
// 从配置中获取轮询间隔
|
loadPollingIntervalFromConfig();
|
|
isRunning = true;
|
isPaused = false;
|
|
try {
|
pollingThread = new Thread(new PollingTask(), "CardSlot-Polling-Thread");
|
pollingThread.setDaemon(true);
|
pollingThread.start();
|
|
System.out.println("轮询查询已启动,间隔: " + pollingInterval + "ms");
|
return true;
|
} catch (Exception e) {
|
System.err.println("启动轮询查询线程时发生异常: " + e.getMessage());
|
isRunning = false;
|
return false;
|
}
|
}
|
|
/**
|
* 停止轮询查询
|
* @return true-停止成功, false-停止失败
|
*/
|
public static boolean stopPolling() {
|
if (!isRunning) {
|
System.out.println("轮询查询未在运行");
|
return false;
|
}
|
|
isRunning = false;
|
isPaused = false;
|
if (pollingThread != null) {
|
pollingThread.interrupt();
|
try {
|
pollingThread.join(1000); // 等待线程结束,最多1秒
|
} catch (InterruptedException e) {
|
System.err.println("停止轮询查询时被中断: " + e.getMessage());
|
Thread.currentThread().interrupt();
|
}
|
pollingThread = null;
|
}
|
|
System.out.println("轮询查询已停止");
|
return true;
|
}
|
|
/**
|
* 暂停轮询查询
|
* @return true-暂停成功, false-暂停失败
|
*/
|
public static boolean pausePolling() {
|
if (!isRunning) {
|
System.out.println("轮询查询未在运行,无法暂停");
|
return false;
|
}
|
|
if (isPaused) {
|
System.out.println("轮询查询已经处于暂停状态");
|
return false;
|
}
|
|
isPaused = true;
|
System.out.println("轮询查询已暂停");
|
return true;
|
}
|
|
/**
|
* 恢复轮询查询
|
* @return true-恢复成功, false-恢复失败
|
*/
|
public static boolean resumePolling() {
|
if (!isRunning) {
|
System.out.println("轮询查询未在运行,无法恢复");
|
return false;
|
}
|
|
if (!isPaused) {
|
System.out.println("轮询查询未处于暂停状态");
|
return false;
|
}
|
|
// 恢复前检查串口连接
|
if (!checkSerialConnection()) {
|
System.err.println("串口未连接,无法恢复轮询查询");
|
return false;
|
}
|
|
isPaused = false;
|
synchronized (lunxun.class) {
|
lunxun.class.notifyAll(); // 唤醒等待的线程
|
}
|
System.out.println("轮询查询已恢复");
|
return true;
|
}
|
|
/**
|
* 检查轮询状态
|
* @return true-正在运行, false-已停止
|
*/
|
public static boolean isPolling() {
|
return isRunning;
|
}
|
|
/**
|
* 检查是否暂停
|
* @return true-已暂停, false-未暂停
|
*/
|
public static boolean isPaused() {
|
return isPaused;
|
}
|
|
/**
|
* 检查串口连接状态
|
* @return true-串口已连接, false-串口未连接
|
*/
|
public static boolean isSerialConnected() {
|
return serialConnected;
|
}
|
|
/**
|
* 设置轮询间隔
|
* @param interval 轮询间隔(毫秒)
|
*/
|
public static void setPollingInterval(int interval) {
|
if (interval < 10) {
|
System.err.println("轮询间隔不能小于10ms");
|
return;
|
}
|
|
pollingInterval = interval;
|
System.out.println("轮询间隔已设置为: " + interval + "ms");
|
|
// 如果正在运行,重新启动以应用新的间隔
|
if (isRunning) {
|
restartPolling();
|
}
|
}
|
|
/**
|
* 获取当前轮询间隔
|
* @return 轮询间隔(毫秒)
|
*/
|
public static int getPollingInterval() {
|
return pollingInterval;
|
}
|
|
/**
|
* 重新启动轮询查询
|
* @return true-重启成功, false-重启失败
|
*/
|
public static boolean restartPolling() {
|
stopPolling();
|
|
// 等待一小段时间确保线程完全停止
|
try {
|
Thread.sleep(100);
|
} catch (InterruptedException e) {
|
Thread.currentThread().interrupt();
|
}
|
|
return startPolling();
|
}
|
|
/**
|
* 从配置中加载轮询间隔
|
*/
|
private static void loadPollingIntervalFromConfig() {
|
try {
|
Chushihua configSystem = Chushihua.getInstance();
|
if (configSystem.isInitialized()) {
|
MachineConfig machineConfig = configSystem.getMachineConfig();
|
pollingInterval = machineConfig.getPollingInterval();
|
System.out.println("从配置加载轮询间隔: " + pollingInterval + "ms");
|
} else {
|
System.out.println("配置系统未初始化,使用默认轮询间隔: " + pollingInterval + "ms");
|
}
|
} catch (Exception e) {
|
System.err.println("加载轮询间隔配置失败: " + e.getMessage());
|
System.out.println("使用默认轮询间隔: " + pollingInterval + "ms");
|
}
|
}
|
|
/**
|
* 轮询任务内部类
|
* 优化内存使用:避免在循环中创建新对象
|
*/
|
private static class PollingTask implements Runnable {
|
private int currentSlot = MIN_SLOT;
|
|
@Override
|
public void run() {
|
System.out.println("轮询查询线程开始运行");
|
|
while (isRunning && !Thread.currentThread().isInterrupted()) {
|
try {
|
// 检查是否暂停
|
if (isPaused) {
|
synchronized (lunxun.class) {
|
while (isPaused && isRunning) {
|
lunxun.class.wait(1000); // 等待1秒或直到被唤醒
|
}
|
}
|
continue;
|
}
|
|
// 定期检查串口连接状态(每10次循环检查一次)
|
if (currentSlot % 10 == 0 && !checkSerialConnection()) {
|
System.err.println("串口连接断开,暂停轮询");
|
pausePolling();
|
continue;
|
}
|
|
// 发送当前卡槽的查询指令
|
sendQueryToSlot(currentSlot);
|
|
// 移动到下一个卡槽
|
currentSlot++;
|
if (currentSlot > MAX_SLOT) {
|
currentSlot = MIN_SLOT; // 循环回到第一个卡槽
|
|
// 在循环回到第一个卡槽后,等待间隔时间
|
// 避免连续发送两个相邻周期的第一个卡槽
|
Thread.sleep(pollingInterval);
|
continue; // 跳过本次循环的后续等待
|
}
|
|
// 等待指定的间隔时间
|
Thread.sleep(pollingInterval);
|
|
} catch (InterruptedException e) {
|
System.out.println("轮询查询线程被中断");
|
Thread.currentThread().interrupt();
|
break;
|
} catch (Exception e) {
|
System.err.println("轮询查询过程中发生异常: " + e.getMessage());
|
|
// 发生异常时等待一段时间再继续
|
try {
|
Thread.sleep(1000);
|
} catch (InterruptedException ie) {
|
Thread.currentThread().interrupt();
|
break;
|
}
|
}
|
}
|
|
System.out.println("轮询查询线程结束运行");
|
}
|
|
/**
|
* 向指定卡槽发送查询指令
|
* 优化:避免重复创建对象,使用局部变量
|
*/
|
private void sendQueryToSlot(int slotNumber) {
|
try {
|
// 生成查询指令
|
String queryCommand = QueryData.queryData(slotNumber);
|
|
if (queryCommand != null && !queryCommand.trim().isEmpty()) {
|
// 发送到串口
|
boolean sendResult = Sendmsg.sendMessage(queryCommand);
|
|
if (sendResult) {
|
// 只在调试时输出,避免频繁打印
|
if (slotNumber == 1 || slotNumber % 20 == 0) {
|
System.out.println("发送查询指令到卡槽 " + slotNumber);
|
}
|
} else {
|
System.err.println("发送查询指令到卡槽 " + slotNumber + " 失败");
|
// 发送失败可能是串口断开,更新连接状态
|
serialConnected = false;
|
}
|
} else {
|
System.err.println("生成的查询指令为空,卡槽: " + slotNumber);
|
}
|
|
} catch (Exception e) {
|
System.err.println("发送查询指令到卡槽 " + slotNumber + " 时发生异常: " + e.getMessage());
|
// 发生异常时更新串口连接状态
|
serialConnected = false;
|
}
|
}
|
}
|
|
/**
|
* 立即向指定卡槽发送查询指令(不等待轮询)
|
* @param slotNumber 卡槽编号 (1-60)
|
* @return true-发送成功, false-发送失败
|
*/
|
public static boolean sendImmediateQuery(int slotNumber) {
|
if (slotNumber < MIN_SLOT || slotNumber > MAX_SLOT) {
|
System.err.println("卡槽编号必须在" + MIN_SLOT + "-" + MAX_SLOT + "之间");
|
return false;
|
}
|
|
// 检查串口连接
|
if (!checkSerialConnection()) {
|
System.err.println("串口未连接,无法发送查询指令");
|
return false;
|
}
|
|
try {
|
// 生成查询指令
|
String queryCommand = QueryData.queryData(slotNumber);
|
|
if (queryCommand != null && !queryCommand.trim().isEmpty()) {
|
// 发送到串口
|
boolean sendResult = Sendmsg.sendMessage(queryCommand);
|
|
if (sendResult) {
|
System.out.println("立即查询成功 - 卡槽 " + slotNumber);
|
return true;
|
} else {
|
System.err.println("立即查询失败 - 发送指令到卡槽 " + slotNumber + " 失败");
|
return false;
|
}
|
} else {
|
System.err.println("立即查询失败 - 生成的查询指令为空,卡槽: " + slotNumber);
|
return false;
|
}
|
|
} catch (Exception e) {
|
System.err.println("立即查询卡槽 " + slotNumber + " 时发生异常: " + e.getMessage());
|
return false;
|
}
|
}
|
|
/**
|
* 立即向所有卡槽发送查询指令(批量)
|
* @return 成功发送的指令数量
|
*/
|
public static int sendImmediateQueryToAll() {
|
// 检查串口连接
|
if (!checkSerialConnection()) {
|
System.err.println("串口未连接,无法发送批量查询指令");
|
return 0;
|
}
|
|
int successCount = 0;
|
|
System.out.println("开始批量查询所有卡槽...");
|
|
for (int slot = MIN_SLOT; slot <= MAX_SLOT; slot++) {
|
if (sendImmediateQuery(slot)) {
|
successCount++;
|
}
|
|
// 小间隔避免串口拥堵
|
try {
|
Thread.sleep(10);
|
} catch (InterruptedException e) {
|
Thread.currentThread().interrupt();
|
break;
|
}
|
}
|
|
System.out.println("批量查询完成,成功发送: " + successCount + "/" + MAX_SLOT);
|
return successCount;
|
}
|
|
/**
|
* 手动设置串口连接状态(用于外部检测到串口状态变化时调用)
|
* @param connected 串口连接状态
|
*/
|
public static void setSerialConnected(boolean connected) {
|
serialConnected = connected;
|
lastSerialCheckTime = System.currentTimeMillis();
|
|
if (connected) {
|
System.out.println("串口连接状态已设置为: 已连接");
|
} else {
|
System.err.println("串口连接状态已设置为: 未连接");
|
// 如果串口断开且轮询正在运行,自动暂停轮询
|
if (isRunning && !isPaused) {
|
pausePolling();
|
}
|
}
|
}
|
|
/**
|
* 获取轮询状态信息
|
* @return 状态信息字符串
|
*/
|
public static String getPollingStatus() {
|
String status;
|
if (!isRunning) {
|
status = "已停止";
|
} else if (isPaused) {
|
status = "已暂停";
|
} else {
|
status = "运行中";
|
}
|
|
String serialStatus = serialConnected ? "已连接" : "未连接";
|
|
return String.format("轮询状态: %s, 串口: %s, 间隔: %dms, 卡槽范围: %d-%d",
|
status, serialStatus, pollingInterval, MIN_SLOT, MAX_SLOT);
|
}
|
|
/**
|
* 直接设置轮询暂停状态(供其他类调用)
|
* @param paused true-暂停轮询, false-恢复轮询
|
* @return true-设置成功, false-设置失败(如轮询未运行)
|
*/
|
public static boolean setPollingPaused(boolean paused) {
|
if (!isRunning) {
|
System.out.println("轮询查询未在运行,无法设置暂停状态");
|
return false;
|
}
|
|
if (paused) {
|
// 请求暂停
|
if (!isPaused) {
|
isPaused = true;
|
System.out.println("轮询查询已通过外部调用暂停");
|
return true;
|
} else {
|
System.out.println("轮询查询已经处于暂停状态");
|
return false;
|
}
|
} else {
|
// 请求恢复
|
if (isPaused) {
|
// 恢复前检查串口连接
|
if (!checkSerialConnection()) {
|
System.err.println("串口未连接,无法恢复轮询查询");
|
return false;
|
}
|
|
isPaused = false;
|
synchronized (lunxun.class) {
|
lunxun.class.notifyAll(); // 唤醒等待的线程
|
}
|
System.out.println("轮询查询已通过外部调用恢复");
|
return true;
|
} else {
|
System.out.println("轮询查询未处于暂停状态");
|
return false;
|
}
|
}
|
}
|
}
|