zy-acs-charge/src/main/java/com/zy/acs/charge/ChargeCoreService.java
@@ -63,7 +63,13 @@ * @return */ int getChargeMode(ModbusTCPMaster client); /** * 获取充电机id * * @param client * @return */ int getChargeId(ModbusTCPMaster client); /** * 获取充电机状态 * @param client zy-acs-charge/src/main/java/com/zy/acs/charge/impl/AiPowerChargeServiceImpl.java
@@ -2,6 +2,7 @@ import com.ghgande.j2mod.modbus.ModbusException; import com.ghgande.j2mod.modbus.facade.ModbusTCPMaster; import com.ghgande.j2mod.modbus.io.AbstractModbusTransport; import com.ghgande.j2mod.modbus.procimg.Register; import com.ghgande.j2mod.modbus.procimg.SimpleRegister; import com.ghgande.j2mod.modbus.util.BitVector; @@ -19,7 +20,7 @@ @Service @Primary @Slf4j public class AiPowerChargeServiceImpl implements ChargeCoreService { public class AiPowerChargeServiceImpl implements ChargeCoreService { /** * 开始充电 @@ -28,12 +29,17 @@ * @return */ @Override public boolean startCharging(ModbusTCPMaster client) { public boolean startCharging(ModbusTCPMaster client) { // AGV车报告到位 -> true try { if (!client.isConnected()) { client.connect(); } return client.writeCoil(AiPowerChargerCoilEnum.AGV_REPORTED_IN_POSITION.getAddr(), true); } catch (ModbusException e) { } catch (Exception e) { log.info("写入开始充电指令报错:{} ", e.getMessage()); }finally { //client.disconnect(); } return false; } @@ -47,9 +53,14 @@ @Override public boolean stopCharging(ModbusTCPMaster client) { try { if (!client.isConnected()) { client.connect(); } return client.writeCoil(AiPowerChargerCoilEnum.AGV_REPORTED_IN_POSITION.getAddr(), false); } catch (ModbusException e) { } catch (Exception e) { log.info("写入停止充电指令报错:{} ", e.getMessage()); }finally { //client.disconnect(); } return false; } @@ -63,9 +74,14 @@ @Override public boolean checkForwardRelayOnline(ModbusTCPMaster client) { try { if (!client.isConnected()) { client.connect(); } return client.readCoils(AiPowerChargerCoilEnum.FORWARD_RELAY_ONLINE.getAddr(), 1).getBit(0); } catch (ModbusException e) { } catch (Exception e) { log.info("读取在线正继电器状态报错:{} ", e.getMessage()); }finally { //client.disconnect(); } return false; } @@ -79,9 +95,14 @@ @Override public boolean checkBackwardRelayOffline(ModbusTCPMaster client) { try { if (!client.isConnected()) { client.connect(); } return client.readCoils(AiPowerChargerCoilEnum.BACKWARD_RELAY_OFFLINE.getAddr(), 1).getBit(0); } catch (ModbusException e) { } catch (Exception e) { log.info("读取离线正继电器状态报错:{} ", e.getMessage()); }finally { //client.disconnect(); } return false; } @@ -95,9 +116,14 @@ @Override public double getVoltage(ModbusTCPMaster client) { try { if (!client.isConnected()) { client.connect(); } return client.readMultipleRegisters(AiPowerChargerRegisterEnum.CHARGE_VOLTAGE.getAddr(), 1)[0].getValue() * AiPowerChargerRegisterEnum.CHARGE_CURRENT.getRaw(); } catch (ModbusException e) { } catch (Exception e) { log.info("读取充电电压报错:{} ", e.getMessage()); }finally { //client.disconnect(); } return 0; } @@ -111,9 +137,14 @@ @Override public double getCurrent(ModbusTCPMaster client) { try { if (!client.isConnected()) { client.connect(); } return client.readMultipleRegisters(AiPowerChargerRegisterEnum.CHARGE_CURRENT.getAddr(), 1)[0].getValue() * AiPowerChargerRegisterEnum.CHARGE_CURRENT.getRaw(); } catch (ModbusException e) { } catch (Exception e) { log.info("读取充电电流报错:{} ", e.getMessage()); }finally { //client.disconnect(); } return 0; } @@ -127,9 +158,37 @@ @Override public int getChargeMode(ModbusTCPMaster client) { try { if (!client.isConnected()) { client.connect(); } return client.readMultipleRegisters(AiPowerChargerRegisterEnum.CHARGE_MODE.getAddr(), 1)[0].getValue(); } catch (ModbusException e) { } catch (Exception e) { e.printStackTrace(); log.info("读取充电模式报错:{} ", e.getMessage()); }finally { //client.disconnect(); } return -1; } /** * 获取充电机编号 * * @param client * @return */ @Override public int getChargeId(ModbusTCPMaster client) { try { if (!client.isConnected()) { client.connect(); } return client.readMultipleRegisters(AiPowerChargerRegisterEnum.CHARGER_ID.getAddr(), 1)[0].getValue(); } catch (Exception e) { e.printStackTrace(); log.info("读取充电机编号报错:{} ", e.getMessage()); }finally { //client.disconnect(); } return -1; } @@ -142,11 +201,15 @@ */ @Override public ChargerStatus getStatus(ModbusTCPMaster client) { ChargerStatus status = new ChargerStatus(); // ---------- 批量读取线圈(地址100~115共16个) ---------- BitVector coils = null; try { if (!client.isConnected()) { client.connect(); } coils = client.readCoils(AiPowerChargerCoilEnum.WORK_STATUS.getAddr(), AiPowerChargerCoilEnum.values().length); for (int i = 0; i < coils.size(); i++) { switch (i) { @@ -202,12 +265,9 @@ break; } } } catch (ModbusException e) { log.info("批量读取线圈报错:{} ", e.getMessage()); } // ---------- 批量读取保持寄存器(地址100~116共17个) ---------- try { // ---------- 批量读取保持寄存器(地址100~116共17个) ---------- Register[] registers = client.readMultipleRegisters(AiPowerChargerRegisterEnum.CHARGE_VOLTAGE.getAddr(), AiPowerChargerRegisterEnum.values().length); for (int i = 0; i < registers.length; i++) { switch (i) { @@ -266,8 +326,11 @@ break; } } } catch (ModbusException e) { log.info("批量读取保持寄存器报错:{} ", e.getMessage()); } catch (Exception e) { log.info("批量读取线圈报错:{} ", e.getMessage()); log.info("批量读取保持寄存器报错:{} ", e.getMessage()); }finally { //client.disconnect(); } return status; @@ -321,5 +384,7 @@ } return true; } } zy-acs-manager/src/main/java/com/zy/acs/manager/core/integrate/charge/ChargeTestController.java
@@ -30,8 +30,8 @@ @IntegrationAuth(name = NamespaceType.RCS_STA_QUERY) @GetMapping("/charge/{type}") public R test(@PathVariable("type") Integer type){ ModbusTCPMaster modbusTCPMaster = chargeService.get("10"); public R test(@PathVariable("type") String type){ ModbusTCPMaster modbusTCPMaster = chargeService.get(type); ChargerStatus status = chargeCoreService.getStatus(modbusTCPMaster); return R.ok(status); } zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/MaintainScheduler.java
@@ -133,7 +133,7 @@ // continue; // } // 判读是否可以自动断开充电(即充电过程中不能接受任务),跳过 if (!agvService.judgeAutoStopCharge(agvModel,agvDetail, agv)) { if (!agvService.judgeAutoStopCharge(agvModel, agvDetail, agv)) { continue; } // is charging ? @@ -252,6 +252,7 @@ * 调度对接充电桩 * 状态1:开始充电 * 状态2:充电中 * 状态3:人为操作下发断开充电操作 */ @Scheduled(cron = "0/5 * * * * ? ") private synchronized void startCharge() { @@ -262,7 +263,7 @@ continue; } AgvDetail agvDetail = agvDetailService.selectByAgvNo(key); if (agvDetail == null){ if (agvDetail == null) { log.error("{} 号待充电小车不存在", key); continue; } @@ -275,39 +276,71 @@ if (null == agvDetail || null == agvDetail.getSoc() || null == agvDetail.getAgvStatus() || funcSta == null || null == modbusTCPMaster) { continue; } if (chargeCoreService.getChargeMode(modbusTCPMaster) != 0) { log.info("{} 该充电机不是自动充电模式", funcSta.getName()); continue; int chargeMode = chargeCoreService.getChargeMode(modbusTCPMaster); if (chargeMode != 0) { log.info("{} 该充电机不是自动充电模式", chargeMode); continue; } switch (status) { case 1: // 后退信号消失,说明马达正在前进 if (chargeCoreService.checkBackwardRelayOffline(modbusTCPMaster)) { log.info("发送充电机充电指令:车号:{}", agvDetail.getAgvId$()); chargeCoreService.startCharging(modbusTCPMaster); continue; } if (chargeCoreService.checkForwardRelayOnline(modbusTCPMaster)) { double current = chargeCoreService.getCurrent(modbusTCPMaster); double voltage = chargeCoreService.getVoltage(modbusTCPMaster); if (current > 0 && voltage > 0) { redis.setMap(RedisConstant.AGV_CHARGE_FLAG, key, 2); log.info("charge complete"); log.info("charge start:{}", agvDetail.getAgvId$()); } else { log.info("read charge current and voltage: {},{}", current, voltage); } } else { log.info("前进到位信号失败:车号:{}", agvDetail.getAgvId$()); } break; case 2: AgvModel agvModel = agvModelService.getByAgvId(agvDetail.getAgvId()); if (agvDetail.getSoc() >= agvModel.getQuaBattery()) { // 前进信号存在,说明机械臂未伸回 if (chargeCoreService.checkForwardRelayOnline(modbusTCPMaster)) { chargeCoreService.stopCharging(modbusTCPMaster); // 如果充电机完成充电会自动断开 // 但充电标识哈在缓存中,那么需要清除缓存标记 // 获取充电机编号且后退到位信号存在,那么说明机械臂已经伸回,那么就需要清除缓存 if (chargeCoreService.getChargeId(modbusTCPMaster) > 0 && chargeCoreService.checkBackwardRelayOffline(modbusTCPMaster)) { redis.deleteMap(RedisConstant.AGV_CHARGE_FLAG, key); log.info("charge over By Auto:{}", agvDetail.getAgvId$()); }else { AgvModel agvModel = agvModelService.getByAgvId(agvDetail.getAgvId()); if (agvDetail.getSoc() >= agvModel.getQuaBattery()) { // 前进信号存在,说明机械臂未伸回 if (chargeCoreService.checkForwardRelayOnline(modbusTCPMaster)) { log.info("发送充电机断充指令:车号:{}", agvDetail.getAgvId$()); chargeCoreService.stopCharging(modbusTCPMaster); continue; } if (chargeCoreService.checkBackwardRelayOffline(modbusTCPMaster)) { redis.deleteMap(RedisConstant.AGV_CHARGE_FLAG, key); log.info("charge over:{}", agvDetail.getAgvId$()); } else { log.info("后退到位信号失败:车号:{}", agvDetail.getAgvId$()); } } if (chargeCoreService.checkBackwardRelayOffline(modbusTCPMaster)) { redis.deleteMap(RedisConstant.AGV_CHARGE_FLAG, key); log.info("charge over"); } } break; case 3: // 手动断开充电 // 前进信号存在,说明机械臂未伸回 if (chargeCoreService.checkForwardRelayOnline(modbusTCPMaster)) { log.info("发送充电机手动断充指令:车号:{}", agvDetail.getAgvId$()); chargeCoreService.stopCharging(modbusTCPMaster); continue; } if (chargeCoreService.checkBackwardRelayOffline(modbusTCPMaster)) { redis.deleteMap(RedisConstant.AGV_CHARGE_FLAG, key); log.info("charge over by handle:{}", agvDetail.getAgvId$()); } else { log.info("手动后退到位信号失败:车号:{}", agvDetail.getAgvId$()); } break; default: zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/ChargeService.java
@@ -26,6 +26,7 @@ private final Map<String, ModbusTCPMaster> CHARGE_CACHE = new ConcurrentHashMap<>(); private final Map<String, Object> deviceLocks = new ConcurrentHashMap<>(); @PostConstruct public void init() { @@ -42,22 +43,41 @@ public void add(FuncSta funcSta) { ModbusTCPMaster modbusTcp = new ModbusTCPMaster(funcSta.getIp(), funcSta.getPort(), true); try { modbusTcp.connect(); } catch (Exception e) { log.info("连接失败"); } CHARGE_CACHE.put(funcSta.getUuid(), modbusTcp); } public void remove(String chargePointId) { CHARGE_CACHE.remove(chargePointId); ModbusTCPMaster master = CHARGE_CACHE.remove(chargePointId); if (master != null && master.isConnected()) { master.disconnect(); } } public ModbusTCPMaster get(String chargePointId) { ModbusTCPMaster modbusTcp = CHARGE_CACHE.get(chargePointId); if (modbusTcp != null) { // 获取或创建设备锁 Object lock = deviceLocks.computeIfAbsent(chargePointId, k -> new Object()); synchronized (lock) { ModbusTCPMaster modbusTcp = CHARGE_CACHE.get(chargePointId); if (modbusTcp != null) { return modbusTcp; } FuncSta funcSta = funcStaService.getOne(new LambdaQueryWrapper<FuncSta>().eq(FuncSta::getUuid, chargePointId)); modbusTcp = new ModbusTCPMaster(funcSta.getIp(), funcSta.getPort(),true); try { modbusTcp.connect(); } catch (Exception e) { log.info("连接失败"); return null; } CHARGE_CACHE.put(chargePointId, modbusTcp); return modbusTcp; } FuncSta funcSta = funcStaService.getOne(new LambdaQueryWrapper<FuncSta>().eq(FuncSta::getUuid, chargePointId)); modbusTcp = new ModbusTCPMaster(funcSta.getIp(), funcSta.getPort(),true); CHARGE_CACHE.put(chargePointId, modbusTcp); return modbusTcp; } zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/AgvServiceImpl.java
@@ -343,18 +343,18 @@ @Override public Boolean judgeAutoStopCharge(AgvModel agvModel, AgvDetail agvDetail, Agv agv ) { if (redis.getMap(RedisConstant.AGV_CHARGE_FLAG, agv.getUuid()) != null){ return false; return true; } // 手动充电模式,跳过 if (agvModel.getNeedUndocking() != null && agvModel.getNeedUndockingBool()) { FuncSta funcSta = funcStaService.getByCodeAndType(agvDetail.getCode(), FuncStaType.CHARGE.toString()); ModbusTCPMaster modbusTCPMaster = chargeService.get(funcSta.getUuid()); // 手动充电模式,跳过 if (chargeCoreService.getChargeMode(modbusTCPMaster) != 1) { return false; if (chargeCoreService.getChargeMode(modbusTCPMaster) == 1) { return true; } } return true; return false; } }