package com.mes.controller; import com.alibaba.fastjson2.JSON; import com.mes.device.LaserDevice; import com.mes.ui.MesClient; import com.mes.util.DateLocalUtils; import com.mes.util.JdbcUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; /** * 激光切割设备控制器 * 参考OP60焊接PlcUtil的模式 */ public class LaserController { private static final Logger log = LoggerFactory.getLogger(LaserController.class); private LaserDevice device; // 状态机 0=未开始 1=已扫码等待启动 2=设备运行中 3=设备运行结束 public static Integer tjFlag = 0; // 当前工件号 public static String curSn = ""; // 参数采集缓存(60条批量存储) public static List hjparams = new ArrayList<>(); // 上传失败标志 public static Integer tjStatus = 0; // 1=提交失败 // 开始时间 private long startTime = 0; // 宏变量地址配置 private static final int MACRO_MES_ENABLE = 3100; // MES允许启动 private static final int MACRO_SPEED = 33563; // 进给速度 private static final int MACRO_TIME = 33868; // 加工时间 private static final int MACRO_COUNT = 33870; // 零件计数 // PLC变量地址配置 private static final String PLC_RUNNING = "42.0"; // 运行中 MO42.0 private static final String PLC_STOPPED = "42.2"; // 停止 MO42.2 private static final String PLC_READY = "42.3"; // 就绪 MO42.3 private static final int PLC_TYPE_MO = 1; // MO类型 public LaserController(LaserDevice device) { this.device = device; } /** * 扫码处理(参考OP60) */ public boolean onScanCode(String sn, String user) { try { // 检查状态 if(tjFlag != 0) { log.warn("上一个工件未完成,不能扫码"); MesClient.showError("上一个工件未完成"); return false; } // 检查设备连接 if(!device.isConnected()) { log.error("设备未连接"); MesClient.showError("设备未连接"); return false; } log.info("扫码: {}", sn); // 1. MES质检(这里需要调用MES接口) // TODO: 调用checkQuality接口 // 2. 开始加工(通知MES) // TODO: 调用startWork接口 // 3. 写MES允许启动信号 boolean writeResult = device.writeMacro(MACRO_MES_ENABLE, 1.0); if(!writeResult) { log.error("写入MES允许信号失败"); MesClient.showError("写入MES允许信号失败"); return false; } // 4. 切换状态 tjFlag = 1; curSn = sn; startTime = System.currentTimeMillis(); log.info("扫码成功,等待操作员启动设备"); return true; } catch (Exception e) { log.error("扫码处理异常", e); return false; } } /** * 状态检测(1秒调用1次,参考OP60的getPlcParam) */ public void checkStatus() { try { if(!device.isConnected()) { return; } // 根据状态执行不同逻辑 if(tjFlag == 1) { checkStart(); // 检测启动 } else if(tjFlag == 2) { checkFinish(); // 检测完成 } } catch (Exception e) { log.error("状态检测异常", e); } } /** * 检测设备是否启动(参考OP60的getStatusA) */ private void checkStart() { try { // 读取运行状态 MO42.0 long running = device.readPlc(PLC_RUNNING, PLC_TYPE_MO); if(running == 1) { // 检测到设备启动 tjFlag = 2; log.info("检测到设备启动,开始采集参数"); MesClient.updateStatus("设备运行中"); // 记录实际开始时间 startTime = System.currentTimeMillis(); } } catch (Exception e) { log.error("检测启动异常", e); } } /** * 检测设备是否完成(参考OP60的getStatusA) */ private void checkFinish() { try { // 读取停止和就绪状态 long stopped = device.readPlc(PLC_STOPPED, PLC_TYPE_MO); long ready = device.readPlc(PLC_READY, PLC_TYPE_MO); if(stopped == 1 && ready == 1) { // 设备完成 tjFlag = 3; log.info("检测到设备完成"); MesClient.updateStatus("设备运行结束,提交结果中"); // 保存剩余参数 if(hjparams.size() > 0) { saveParams(); } // 上传结果到MES boolean sendret = sendQuality(curSn, "OK"); if(!sendret) { // 上传失败 tjStatus = 1; log.error("结果上传MES失败"); MesClient.updateStatus("结果上传MES失败"); } else { // 上传成功,复位 log.info("结果上传成功,复位状态"); resetStatus(); MesClient.updateStatus("提交成功"); } } } catch (Exception e) { log.error("检测完成异常", e); } } /** * 参数采集(1秒调用1次,参考OP60的getPlcParams) */ public void collectParams() { try { if(!device.isConnected()) { return; } // 只有运行中才采集 if(tjFlag != 2) { return; } // 读取系统宏变量 double speed = device.readMacro(MACRO_SPEED); // 进给速度 double time = device.readMacro(MACRO_TIME); // 加工时间 double count = device.readMacro(MACRO_COUNT); // 零件计数 // 拼接参数字符串(参考OP60的格式) String timestamp = DateLocalUtils.getCurrentTime(); String record = speed + "|" + time + "|" + count + "|" + timestamp; hjparams.add(record); log.debug("采集参数: {}", record); // 满60条存储(参考OP60) if(hjparams.size() == 60) { saveParams(); } } catch (Exception e) { log.error("参数采集异常", e); } } /** * 保存参数到SQLite(参考OP60) */ private void saveParams() { try { if(hjparams.size() == 0) { return; } // 检查工件码是否为空 if(curSn == null || curSn.trim().isEmpty()) { log.warn("工件码为空,跳过保存数据"); hjparams.clear(); return; } String oprno = MesClient.mes_gw; String lineSn = MesClient.mes_line_sn; String paramsJson = JSON.toJSONString(hjparams); JdbcUtils.insertLaserData(oprno, lineSn, curSn, paramsJson); log.info("保存参数: sn={}, count={}", curSn, hjparams.size()); hjparams.clear(); } catch (Exception e) { log.error("保存参数异常", e); } } /** * 上传结果到MES(参考OP60的sendQuality) */ private boolean sendQuality(String sn, String result) { try { // TODO: 调用MES接口上传结果 // 参考OP60: DataUtil.sendQuality(nettyClient, sn, result, user, oprno); // 实际项目中需要实现这个接口 log.info("上传结果: sn={}, result={}", sn, result); // 暂时返回true,等待实际MES接口对接 return true; } catch (Exception e) { log.error("上传结果异常", e); return false; } } /** * 更新UI状态(静态方法,供MesClient调用) */ public static void updateStatusLabel(String text) { try { if(MesClient.fxlabel != null) { MesClient.fxlabel.setText(text); } } catch (Exception e) { log.error("更新状态标签异常", e); } } /** * 复位状态(完成后调用) */ private void resetStatus() { try { // 1. 复位MES允许信号(激光切割需要,OP60不需要) device.writeMacro(MACRO_MES_ENABLE, 0.0); // 2. 清空状态 tjFlag = 0; curSn = ""; hjparams.clear(); tjStatus = 0; startTime = 0; log.info("状态已复位"); } catch (Exception e) { log.error("复位状态异常", e); } } /** * 手动复位(上传失败时使用) */ public void manualReset() { log.warn("手动复位状态"); resetStatus(); } /** * 获取当前状态 */ public int getStatus() { return tjFlag; } /** * 获取当前工件号 */ public String getCurrentSn() { return curSn; } /** * 获取运行时长(秒) */ public long getRunningTime() { if(startTime == 0) { return 0; } return (System.currentTimeMillis() - startTime) / 1000; } }