| | |
| | | package jiekou; |
| | | import chushihua.SlotManager; |
| | | import xitongshezhi.Fkj; |
| | | import home.Fkj; |
| | | |
| | | /** |
| | | * 轮询卡槽状态类 |
| | | * 用于定期轮询并输出所有卡槽的状态信息 |
| | | */ |
| | | public class lunxunkazhuangtai { |
| | | private static Thread pollThread; |
| | | private static volatile boolean isRunning = false; |
| | | private static final int POLL_INTERVAL = 30000; // 30秒间隔 |
| | | private static Thread pollThread; |
| | | private static volatile boolean isRunning = false; |
| | | private static volatile int pollInterval = 30000; // 30秒间隔,改为可变的 |
| | | |
| | | // 常量定义,避免重复创建字符串 |
| | | private static final String THREAD_NAME = "SlotStatusPollingThread"; |
| | | private static final String UNKNOWN = "未知"; |
| | | private static final String NORMAL = "正常"; |
| | | private static final String NULL_VALUE = "null"; |
| | | |
| | | // 状态常量 |
| | | private static final String STATUS_INVALID = "0"; |
| | | private static final String STATUS_STANDBY = "1"; |
| | | private static final String STATUS_CHARGING = "2"; |
| | | private static final String STATUS_FULL = "3"; |
| | | private static final String STATUS_FAULT = "4"; |
| | | private static final String STATUS_AUTH_EXPIRED = "5"; |
| | | private static final String STATUS_TIMEOUT = "6"; |
| | | private static final String STATUS_UNKNOWN = "-1"; |
| | | |
| | | // 故障常量 |
| | | private static final String FAULT_NORMAL = "0"; |
| | | private static final String FAULT_CARD_ERROR = "1"; |
| | | private static final String FAULT_OVER_CURRENT = "2"; |
| | | private static final String FAULT_DOOR_FAULT = "3"; |
| | | private static final String FAULT_OVER_VOLTAGE = "4"; |
| | | private static final String FAULT_UNDER_VOLTAGE = "5"; |
| | | private static final String FAULT_UNKNOWN = "-1"; |
| | | |
| | | /** |
| | | * 启动轮询线程 |
| | | */ |
| | | public static void startPolling() { |
| | | if (isRunning) {; |
| | | return; |
| | | } |
| | | /** |
| | | * 启动轮询线程 |
| | | */ |
| | | public static void startPolling() { |
| | | if (isRunning) { |
| | | System.out.println("轮询线程已在运行中"); |
| | | return; |
| | | } |
| | | |
| | | isRunning = true; |
| | | pollThread = new Thread(new PollingTask(), "SlotStatusPollingThread"); |
| | | pollThread.setDaemon(true); // 设置为守护线程,当主线程结束时自动结束 |
| | | pollThread.start(); |
| | | } |
| | | isRunning = true; |
| | | pollThread = new Thread(new PollingTask(), THREAD_NAME); |
| | | pollThread.setDaemon(true); |
| | | pollThread.start(); |
| | | System.out.println("卡槽状态轮询线程已启动,间隔: " + pollInterval + "ms"); |
| | | } |
| | | |
| | | /** |
| | | * 停止轮询线程 |
| | | */ |
| | | public static void stopPolling() { |
| | | isRunning = false; |
| | | if (pollThread != null) { |
| | | pollThread.interrupt(); |
| | | pollThread = null; |
| | | } |
| | | System.out.println("卡槽状态轮询线程已停止"); |
| | | } |
| | | /** |
| | | * 停止轮询线程 |
| | | */ |
| | | public static void stopPolling() { |
| | | if (!isRunning) { |
| | | return; |
| | | } |
| | | |
| | | isRunning = false; |
| | | if (pollThread != null) { |
| | | pollThread.interrupt(); |
| | | try { |
| | | // 等待线程安全结束,最多等待2秒 |
| | | pollThread.join(2000); |
| | | } catch (InterruptedException e) { |
| | | Thread.currentThread().interrupt(); |
| | | System.out.println("等待轮询线程停止时被中断"); |
| | | } |
| | | pollThread = null; |
| | | } |
| | | System.out.println("卡槽状态轮询线程已停止"); |
| | | } |
| | | |
| | | /** |
| | | * 检查轮询线程是否在运行 |
| | | * @return 运行状态 |
| | | */ |
| | | public static boolean isPolling() { |
| | | return isRunning; |
| | | } |
| | | /** |
| | | * 检查轮询线程是否在运行 |
| | | * @return 运行状态 |
| | | */ |
| | | public static boolean isPolling() { |
| | | return isRunning; |
| | | } |
| | | |
| | | /** |
| | | * 轮询任务实现 |
| | | */ |
| | | private static class PollingTask implements Runnable { |
| | | @Override |
| | | public void run() { |
| | | while (isRunning && !Thread.currentThread().isInterrupted()) { |
| | | try { |
| | | // 输出所有卡槽状态 |
| | | printAllSlotsStatus(); |
| | | /** |
| | | * 轮询任务实现 |
| | | */ |
| | | private static class PollingTask implements Runnable { |
| | | @Override |
| | | public void run() { |
| | | System.out.println("轮询任务开始执行"); |
| | | |
| | | while (isRunning && !Thread.currentThread().isInterrupted()) { |
| | | try { |
| | | // 输出所有卡槽状态 |
| | | printAllSlotsStatus(); |
| | | |
| | | // 等待指定间隔 |
| | | Thread.sleep(POLL_INTERVAL); |
| | | } catch (InterruptedException e) { |
| | | System.out.println("轮询线程被中断"); |
| | | Thread.currentThread().interrupt(); |
| | | break; |
| | | } catch (Exception e) { |
| | | System.err.println("轮询过程中发生错误: " + e.getMessage()); |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | isRunning = false; |
| | | } |
| | | // 使用动态间隔,支持运行时调整 |
| | | Thread.sleep(pollInterval); |
| | | |
| | | } catch (InterruptedException e) { |
| | | System.out.println("轮询线程被中断,正在退出..."); |
| | | Thread.currentThread().interrupt(); |
| | | break; |
| | | } catch (Exception e) { |
| | | System.err.println("轮询过程中发生错误: " + e.getMessage()); |
| | | // 记录异常但继续运行,避免因单次异常导致整个监控停止 |
| | | e.printStackTrace(); |
| | | |
| | | // 发生异常时短暂等待后再继续,避免频繁错误循环 |
| | | try { |
| | | Thread.sleep(5000); |
| | | } catch (InterruptedException ie) { |
| | | Thread.currentThread().interrupt(); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | isRunning = false; |
| | | // System.out.println("轮询任务执行结束"); |
| | | } |
| | | |
| | | /** |
| | | * 输出所有卡槽状态信息 |
| | | */ |
| | | private void printAllSlotsStatus() { |
| | | Fkj[] slots = SlotManager.getSlotArray(); |
| | | if (slots == null || slots.length == 0) { |
| | | return; |
| | | } |
| | | for (Fkj slot : slots) { |
| | | if (slot != null) { |
| | | //使用下面的推给服务器卡的状态 |
| | | String kacaobianhao=safeGetValue(slot.getSlotNumber()); |
| | | String kahao=safeGetValue(slot.getCardNumber()); |
| | | String shifouyouka=formatHasCard(safeGetValue(slot.getHasCard())); |
| | | String kazhuangtai=formatWorkStatus(safeGetValue(slot.getWorkStatus())); |
| | | String kacaodianya=safeGetValue(slot.getVoltage()); |
| | | String kacaodianliu=safeGetValue(slot.getCurrent()); |
| | | String guzhangyuanyin=formatFault(safeGetValue(slot.getFault())); |
| | | } |
| | | } |
| | | /** |
| | | * 输出所有卡槽状态信息 |
| | | */ |
| | | private void printAllSlotsStatus() { |
| | | Fkj[] slots = SlotManager.getSlotArray(); |
| | | if (slots == null || slots.length == 0) { |
| | | // System.out.println("无卡槽数据"); |
| | | return; |
| | | } |
| | | |
| | | // 使用StringBuilder减少字符串拼接开销 |
| | | StringBuilder statusBuilder = new StringBuilder(); |
| | | |
| | | |
| | | int validSlotCount = 0; |
| | | for (Fkj slot : slots) { |
| | | if (slot != null) { |
| | | validSlotCount++; |
| | | // 使用下面的推给服务器卡的状态 |
| | | String kacaobianhao = safeGetValue(slot.getSlotNumber()); |
| | | String kahao = safeGetValue(slot.getCardNumber()); |
| | | String shifouyouka = formatHasCard(safeGetValue(slot.getHasCard())); |
| | | String kazhuangtai = formatWorkStatus(safeGetValue(slot.getWorkStatus())); |
| | | String kacaodianya = safeGetValue(slot.getVoltage()); |
| | | String kacaodianliu = safeGetValue(slot.getCurrent()); |
| | | String guzhangyuanyin = formatFault(safeGetValue(slot.getFault())); |
| | | |
| | | |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 安全获取值,避免空指针 |
| | | */ |
| | | private String safeGetValue(String value) { |
| | | return value != null ? value : "null"; |
| | | } |
| | | /** |
| | | * 安全获取值,避免空指针 |
| | | */ |
| | | private String safeGetValue(String value) { |
| | | return value != null ? value : NULL_VALUE; |
| | | } |
| | | |
| | | /** |
| | | * 格式化有卡状态 |
| | | */ |
| | | private String formatHasCard(String hasCard) { |
| | | if ("1".equals(hasCard)) return "有卡"; |
| | | if ("0".equals(hasCard)) return "无卡"; |
| | | if ("-1".equals(hasCard)) return "未知"; |
| | | return hasCard; |
| | | } |
| | | /** |
| | | * 格式化有卡状态 |
| | | */ |
| | | private String formatHasCard(String hasCard) { |
| | | if ("1".equals(hasCard)) return "有卡"; |
| | | if ("0".equals(hasCard)) return "无卡"; |
| | | if ("-1".equals(hasCard)) return UNKNOWN; |
| | | return hasCard; |
| | | } |
| | | |
| | | /** |
| | | * 格式化工作状态 |
| | | */ |
| | | private String formatWorkStatus(String status) { |
| | | switch (status) { |
| | | case "0": return "无效"; |
| | | case "1": return "待机"; |
| | | case "2": return "充电中"; |
| | | case "3": return "已充满"; |
| | | case "4": return "故障"; |
| | | case "5": return "授权到期"; |
| | | case "6": return "通信超时"; |
| | | case "-1": return "未知"; |
| | | default: return status; |
| | | } |
| | | } |
| | | /** |
| | | * 格式化工作状态 |
| | | */ |
| | | private String formatWorkStatus(String status) { |
| | | switch (status) { |
| | | case STATUS_INVALID: return "无效"; |
| | | case STATUS_STANDBY: return "待机"; |
| | | case STATUS_CHARGING: return "充电中"; |
| | | case STATUS_FULL: return "已充满"; |
| | | case STATUS_FAULT: return "故障"; |
| | | case STATUS_AUTH_EXPIRED: return "授权到期"; |
| | | case STATUS_TIMEOUT: return "通信超时"; |
| | | case STATUS_UNKNOWN: return UNKNOWN; |
| | | default: return status; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 格式化故障状态 |
| | | */ |
| | | private String formatFault(String fault) { |
| | | switch (fault) { |
| | | case "0": return "正常"; |
| | | case "1": return "插卡错误"; |
| | | case "2": return "过流"; |
| | | case "3": return "门控故障"; |
| | | case "4": return "过压"; |
| | | case "5": return "欠压"; |
| | | case "-1": return "未知"; |
| | | default: return fault; |
| | | } |
| | | } |
| | | } |
| | | /** |
| | | * 格式化故障状态 |
| | | */ |
| | | private String formatFault(String fault) { |
| | | switch (fault) { |
| | | case FAULT_NORMAL: return NORMAL; |
| | | case FAULT_CARD_ERROR: return "插卡错误"; |
| | | case FAULT_OVER_CURRENT: return "过流"; |
| | | case FAULT_DOOR_FAULT: return "门控故障"; |
| | | case FAULT_OVER_VOLTAGE: return "过压"; |
| | | case FAULT_UNDER_VOLTAGE: return "欠压"; |
| | | case FAULT_UNKNOWN: return UNKNOWN; |
| | | default: return fault; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 设置轮询间隔(单位:毫秒) |
| | | * @param interval 间隔时间,毫秒 |
| | | */ |
| | | public static void setPollInterval(int interval) { |
| | | // 注意:这个设置不会立即生效,需要重启轮询线程 |
| | | System.out.println("新的轮询间隔将在下次启动时生效: " + interval + "ms"); |
| | | } |
| | | /** |
| | | * 设置轮询间隔(单位:毫秒) |
| | | * @param interval 间隔时间,毫秒 |
| | | */ |
| | | public static void setPollInterval(int interval) { |
| | | if (interval <= 0) { |
| | | throw new IllegalArgumentException("轮询间隔必须大于0"); |
| | | } |
| | | pollInterval = interval; |
| | | System.out.println("轮询间隔已更新: " + interval + "ms"); |
| | | } |
| | | |
| | | /** |
| | | * 获取当前轮询间隔 |
| | | * @return 轮询间隔(毫秒) |
| | | */ |
| | | public static int getPollInterval() { |
| | | return POLL_INTERVAL; |
| | | } |
| | | /** |
| | | * 获取当前轮询间隔 |
| | | * @return 轮询间隔(毫秒) |
| | | */ |
| | | public static int getPollInterval() { |
| | | return pollInterval; |
| | | } |
| | | |
| | | /** |
| | | * 手动触发一次状态输出(不等待间隔) |
| | | */ |
| | | public static void triggerManualOutput() { |
| | | if (isRunning) { |
| | | new PollingTask().printAllSlotsStatus(); |
| | | } else { |
| | | System.out.println("轮询线程未运行,无法手动触发输出"); |
| | | } |
| | | } |
| | | /** |
| | | * 手动触发一次状态输出(不等待间隔) |
| | | */ |
| | | public static void triggerManualOutput() { |
| | | if (isRunning && pollThread != null) { |
| | | new PollingTask().printAllSlotsStatus(); |
| | | } else { |
| | | System.out.println("轮询线程未运行,无法手动触发输出"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 安全关闭所有资源 |
| | | */ |
| | | public static void shutdown() { |
| | | stopPolling(); |
| | | } |
| | | } |