zy-acs-charge/src/main/java/com/zy/acs/charge/ChargeCoreService.java
@@ -1,6 +1,7 @@ package com.zy.acs.charge; import com.ghgande.j2mod.modbus.facade.ModbusTCPMaster; import com.zy.acs.charge.constant.ChargerType; import com.zy.acs.charge.model.ChargerStatus; /** @@ -8,6 +9,8 @@ */ public interface ChargeCoreService { ChargerType supportedType(); /** * 调度开启充电 * zy-acs-charge/src/main/java/com/zy/acs/charge/ChargeStrategyFactory.java
New file @@ -0,0 +1,32 @@ package com.zy.acs.charge; import com.zy.acs.charge.constant.ChargerType; import org.springframework.stereotype.Component; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; @Component public class ChargeStrategyFactory { private final Map<ChargerType, ChargeCoreService> serviceMap; // 构造函数注入 List<PaymentService>,Spring 会自动收集所有实现类 public ChargeStrategyFactory(List<ChargeCoreService> services) { serviceMap = services.stream() .collect(Collectors.toMap( ChargeCoreService::supportedType, Function.identity() )); } public ChargeCoreService getService(ChargerType type) { ChargeCoreService service = serviceMap.get(type); if (service == null) { throw new IllegalArgumentException("不支持的支付类型: " + type); } return service; } } zy-acs-charge/src/main/java/com/zy/acs/charge/constant/AiPowerChargeCoilEnum.java
File was renamed from zy-acs-charge/src/main/java/com/zy/acs/charge/constant/AiPowerChargerCoilEnum.java @@ -3,7 +3,7 @@ /** * */ public enum AiPowerChargerCoilEnum { public enum AiPowerChargeCoilEnum { WORK_STATUS(100, 1, "工作状态"), @@ -34,7 +34,7 @@ private String des; AiPowerChargerCoilEnum(int addr, int type, String des) { AiPowerChargeCoilEnum(int addr, int type, String des) { this.addr = addr; this.type = type; this.des = des; zy-acs-charge/src/main/java/com/zy/acs/charge/constant/AiPowerChargeRegisterEnum.java
File was renamed from zy-acs-charge/src/main/java/com/zy/acs/charge/constant/AiPowerChargerRegisterEnum.java @@ -1,6 +1,6 @@ package com.zy.acs.charge.constant; public enum AiPowerChargerRegisterEnum { public enum AiPowerChargeRegisterEnum { // 寄存器地址 100~116 CHARGE_VOLTAGE(100, 3, "充电机充电电压", 0.1), // 单位0.1V CHARGE_CURRENT(101, 3, "充电机充电电流", 0.1), // 单位0.1A @@ -37,7 +37,7 @@ private final String des; private final Double raw; // 单位转换因子(原始值 × raw = 实际物理量) AiPowerChargerRegisterEnum(Integer addr, Integer type, String des, Double raw) { AiPowerChargeRegisterEnum(Integer addr, Integer type, String des, Double raw) { this.addr = addr; this.type = type; this.des = des; zy-acs-charge/src/main/java/com/zy/acs/charge/constant/ChargerType.java
New file @@ -0,0 +1,16 @@ package com.zy.acs.charge.constant; public enum ChargerType { Modbus,Default; public static ChargerType getByCode(String code) { for (ChargerType value : values()) { if (value.name().equalsIgnoreCase(code)) { return value; } } return null; } } zy-acs-charge/src/main/java/com/zy/acs/charge/impl/AiPowerChargeServiceImpl.java
@@ -2,25 +2,28 @@ 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; import com.zy.acs.charge.ChargeCoreService; import com.zy.acs.charge.constant.AiPowerChargerCoilEnum; import com.zy.acs.charge.constant.AiPowerChargerRegisterEnum; import com.zy.acs.charge.constant.AiPowerChargeCoilEnum; import com.zy.acs.charge.constant.AiPowerChargeRegisterEnum; import com.zy.acs.charge.constant.ChargerType; import com.zy.acs.charge.model.ChargerStatus; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; /** * 爱普拉AGV锂电智能充电机调度 */ @Service @Primary @Service("aiPowerChargeService") @Slf4j public class AiPowerChargeServiceImpl implements ChargeCoreService { @Override public ChargerType supportedType() { return ChargerType.Modbus; } /** * 开始充电 @@ -35,7 +38,7 @@ if (!client.isConnected()) { client.connect(); } return client.writeCoil(AiPowerChargerCoilEnum.AGV_REPORTED_IN_POSITION.getAddr(), true); return client.writeCoil(AiPowerChargeCoilEnum.AGV_REPORTED_IN_POSITION.getAddr(), true); } catch (Exception e) { log.info("写入开始充电指令报错:{} ", e.getMessage()); }finally { @@ -56,7 +59,7 @@ if (!client.isConnected()) { client.connect(); } return client.writeCoil(AiPowerChargerCoilEnum.AGV_REPORTED_IN_POSITION.getAddr(), false); return client.writeCoil(AiPowerChargeCoilEnum.AGV_REPORTED_IN_POSITION.getAddr(), false); } catch (Exception e) { log.info("写入停止充电指令报错:{} ", e.getMessage()); }finally { @@ -77,7 +80,7 @@ if (!client.isConnected()) { client.connect(); } return client.readCoils(AiPowerChargerCoilEnum.FORWARD_RELAY_ONLINE.getAddr(), 1).getBit(0); return client.readCoils(AiPowerChargeCoilEnum.FORWARD_RELAY_ONLINE.getAddr(), 1).getBit(0); } catch (Exception e) { log.info("读取在线正继电器状态报错:{} ", e.getMessage()); }finally { @@ -98,7 +101,7 @@ if (!client.isConnected()) { client.connect(); } return client.readCoils(AiPowerChargerCoilEnum.BACKWARD_RELAY_OFFLINE.getAddr(), 1).getBit(0); return client.readCoils(AiPowerChargeCoilEnum.BACKWARD_RELAY_OFFLINE.getAddr(), 1).getBit(0); } catch (Exception e) { log.info("读取离线正继电器状态报错:{} ", e.getMessage()); }finally { @@ -119,7 +122,7 @@ if (!client.isConnected()) { client.connect(); } return client.readMultipleRegisters(AiPowerChargerRegisterEnum.CHARGE_VOLTAGE.getAddr(), 1)[0].getValue() * AiPowerChargerRegisterEnum.CHARGE_CURRENT.getRaw(); return client.readMultipleRegisters(AiPowerChargeRegisterEnum.CHARGE_VOLTAGE.getAddr(), 1)[0].getValue() * AiPowerChargeRegisterEnum.CHARGE_CURRENT.getRaw(); } catch (Exception e) { log.info("读取充电电压报错:{} ", e.getMessage()); }finally { @@ -140,7 +143,7 @@ if (!client.isConnected()) { client.connect(); } return client.readMultipleRegisters(AiPowerChargerRegisterEnum.CHARGE_CURRENT.getAddr(), 1)[0].getValue() * AiPowerChargerRegisterEnum.CHARGE_CURRENT.getRaw(); return client.readMultipleRegisters(AiPowerChargeRegisterEnum.CHARGE_CURRENT.getAddr(), 1)[0].getValue() * AiPowerChargeRegisterEnum.CHARGE_CURRENT.getRaw(); } catch (Exception e) { log.info("读取充电电流报错:{} ", e.getMessage()); }finally { @@ -161,7 +164,7 @@ if (!client.isConnected()) { client.connect(); } return client.readMultipleRegisters(AiPowerChargerRegisterEnum.CHARGE_MODE.getAddr(), 1)[0].getValue(); return client.readMultipleRegisters(AiPowerChargeRegisterEnum.CHARGE_MODE.getAddr(), 1)[0].getValue(); } catch (Exception e) { e.printStackTrace(); log.info("读取充电模式报错:{} ", e.getMessage()); @@ -183,7 +186,7 @@ if (!client.isConnected()) { client.connect(); } return client.readMultipleRegisters(AiPowerChargerRegisterEnum.CHARGER_ID.getAddr(), 1)[0].getValue(); return client.readMultipleRegisters(AiPowerChargeRegisterEnum.CHARGER_ID.getAddr(), 1)[0].getValue(); } catch (Exception e) { e.printStackTrace(); log.info("读取充电机编号报错:{} ", e.getMessage()); @@ -210,7 +213,7 @@ if (!client.isConnected()) { client.connect(); } coils = client.readCoils(AiPowerChargerCoilEnum.WORK_STATUS.getAddr(), AiPowerChargerCoilEnum.values().length); coils = client.readCoils(AiPowerChargeCoilEnum.WORK_STATUS.getAddr(), AiPowerChargeCoilEnum.values().length); for (int i = 0; i < coils.size(); i++) { switch (i) { case 0: @@ -268,23 +271,23 @@ // ---------- 批量读取保持寄存器(地址100~116共17个) ---------- Register[] registers = client.readMultipleRegisters(AiPowerChargerRegisterEnum.CHARGE_VOLTAGE.getAddr(), AiPowerChargerRegisterEnum.values().length); Register[] registers = client.readMultipleRegisters(AiPowerChargeRegisterEnum.CHARGE_VOLTAGE.getAddr(), AiPowerChargeRegisterEnum.values().length); for (int i = 0; i < registers.length; i++) { switch (i) { case 0: status.setVoltage(registers[i].getValue() * AiPowerChargerRegisterEnum.CHARGE_VOLTAGE.getRaw()); status.setVoltage(registers[i].getValue() * AiPowerChargeRegisterEnum.CHARGE_VOLTAGE.getRaw()); break; case 1: status.setCurrent(registers[i].getValue() * AiPowerChargerRegisterEnum.CHARGE_CURRENT.getRaw()); status.setCurrent(registers[i].getValue() * AiPowerChargeRegisterEnum.CHARGE_CURRENT.getRaw()); break; case 2: status.setChargingTime(registers[i].getValue()); break; case 3: status.setCapacity(registers[i].getValue() * AiPowerChargerRegisterEnum.CHARGE_CAPACITY.getRaw()); status.setCapacity(registers[i].getValue() * AiPowerChargeRegisterEnum.CHARGE_CAPACITY.getRaw()); break; case 4: status.setEnergy(registers[i].getValue() * AiPowerChargerRegisterEnum.CHARGE_ENERGY.getRaw()); status.setEnergy(registers[i].getValue() * AiPowerChargeRegisterEnum.CHARGE_ENERGY.getRaw()); break; case 5: status.setCellMaxVoltage(registers[i].getValue()); @@ -293,19 +296,19 @@ status.setCellMinVoltage(registers[i].getValue()); break; case 7: status.setPackVoltage(registers[i].getValue() * AiPowerChargerRegisterEnum.BMS_PACK_VOLTAGE.getRaw()); status.setPackVoltage(registers[i].getValue() * AiPowerChargeRegisterEnum.BMS_PACK_VOLTAGE.getRaw()); break; case 8: status.setVoltageDemand(registers[i].getValue() * AiPowerChargerRegisterEnum.BMS_VOLTAGE_DEMAND.getRaw()); status.setVoltageDemand(registers[i].getValue() * AiPowerChargeRegisterEnum.BMS_VOLTAGE_DEMAND.getRaw()); break; case 9: status.setCurrentDemand(registers[i].getValue() * AiPowerChargerRegisterEnum.BMS_CURRENT_DEMAND.getRaw()); status.setCurrentDemand(registers[i].getValue() * AiPowerChargeRegisterEnum.BMS_CURRENT_DEMAND.getRaw()); break; case 10: status.setTemperature(registers[i].getValue()); break; case 11: status.setSoc(registers[i].getValue() * AiPowerChargerRegisterEnum.BMS_SOC.getRaw()); status.setSoc(registers[i].getValue() * AiPowerChargeRegisterEnum.BMS_SOC.getRaw()); break; case 12: status.setEndFlag(registers[i].getValue()); @@ -346,7 +349,7 @@ @Override public boolean clearFault(ModbusTCPMaster client) { try { client.writeSingleRegister(AiPowerChargerRegisterEnum.SCHEDULE_FLAG.getAddr(), new SimpleRegister(1)); client.writeSingleRegister(AiPowerChargeRegisterEnum.SCHEDULE_FLAG.getAddr(), new SimpleRegister(1)); } catch (ModbusException e) { log.error("充电器清除故障失败......"); } @@ -362,7 +365,7 @@ @Override public boolean finishRetract(ModbusTCPMaster client) { try { client.writeSingleRegister(AiPowerChargerRegisterEnum.SCHEDULE_FLAG.getAddr(), new SimpleRegister(2)); client.writeSingleRegister(AiPowerChargeRegisterEnum.SCHEDULE_FLAG.getAddr(), new SimpleRegister(2)); } catch (ModbusException e) { log.error("充电器完成退回失败......"); } @@ -378,7 +381,7 @@ @Override public boolean restoreStandby(ModbusTCPMaster client) { try { client.writeSingleRegister(AiPowerChargerRegisterEnum.SCHEDULE_FLAG.getAddr(), new SimpleRegister(3)); client.writeSingleRegister(AiPowerChargeRegisterEnum.SCHEDULE_FLAG.getAddr(), new SimpleRegister(3)); } catch (ModbusException e) { log.error("充电器恢复待机失败......"); } zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/ChargeScheduler.java
New file @@ -0,0 +1,147 @@ package com.zy.acs.manager.core.scheduler; import com.ghgande.j2mod.modbus.facade.ModbusTCPMaster; import com.zy.acs.charge.ChargeCoreService; import com.zy.acs.charge.ChargeStrategyFactory; import com.zy.acs.charge.constant.ChargerType; import com.zy.acs.common.constant.RedisConstant; import com.zy.acs.common.utils.RedisSupport; import com.zy.acs.manager.common.config.UplinkProperties; import com.zy.acs.manager.core.integrate.wms.FaultReportService; import com.zy.acs.manager.core.integrate.wms.TaskReportService; import com.zy.acs.manager.core.service.ChargeService; import com.zy.acs.manager.core.service.MainLockWrapService; import com.zy.acs.manager.manager.entity.AgvDetail; import com.zy.acs.manager.manager.entity.AgvModel; import com.zy.acs.manager.manager.entity.FuncSta; import com.zy.acs.manager.manager.enums.FuncStaType; import com.zy.acs.manager.manager.service.*; import com.zy.acs.manager.system.service.ConfigService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.Set; @Slf4j @Component public class ChargeScheduler { private final RedisSupport redis = RedisSupport.defaultRedisSupport; @Autowired private AgvDetailService agvDetailService; @Autowired private FuncStaService funcStaService; @Autowired private AgvModelService agvModelService; @Autowired private ChargeService chargeService; @Autowired private ChargeStrategyFactory chargeStrategyFactory; /** * 调度对接充电桩 * 状态1:开始充电 * 状态2:充电中 * 状态3:人为操作下发断开充电操作 */ @Scheduled(cron = "0/5 * * * * ? ") private synchronized void startCharge() { Set<String> mapKeys = redis.getMapKeys(RedisConstant.AGV_CHARGE_FLAG); for (String key : mapKeys) { Integer status = redis.getMap(RedisConstant.AGV_CHARGE_FLAG, key); if (null == status) { continue; } AgvDetail agvDetail = agvDetailService.selectByAgvNo(key); if (agvDetail == null) { log.error("{} 号待充电小车不存在", key); continue; } if (agvDetail.getCode() == null) { log.error("{} 号待充电小车无地址码", key); continue; } FuncSta funcSta = funcStaService.getByCodeAndType(agvDetail.getCode(), FuncStaType.CHARGE.toString()); ModbusTCPMaster modbusTCPMaster = chargeService.get(funcSta.getUuid()); if (null == agvDetail || null == agvDetail.getSoc() || null == agvDetail.getAgvStatus() || funcSta == null || null == modbusTCPMaster) { continue; } ChargeCoreService chargeCoreService = chargeStrategyFactory.getService(ChargerType.getByCode(funcSta.getProtocol())); 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 start:{}", agvDetail.getAgvId$()); } else { log.info("read charge current and voltage: {},{}", current, voltage); } } else { log.info("前进到位信号失败:车号:{}", agvDetail.getAgvId$()); } break; case 2: // 如果充电机完成充电会自动断开 // 但充电标识哈在缓存中,那么需要清除缓存标记 // 获取充电机编号且后退到位信号存在,那么说明机械臂已经伸回,那么就需要清除缓存 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$()); } } } 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: log.error("charge status error: {}", status); break; } } } } zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/MaintainScheduler.java
@@ -1,17 +1,12 @@ package com.zy.acs.manager.core.scheduler; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ghgande.j2mod.modbus.facade.ModbusTCPMaster; import com.zy.acs.charge.ChargeCoreService; import com.zy.acs.common.constant.RedisConstant; import com.zy.acs.common.enums.AgvStatusType; import com.zy.acs.common.utils.RedisSupport; import com.zy.acs.framework.common.Cools; import com.zy.acs.framework.common.DateUtils; import com.zy.acs.manager.common.config.UplinkProperties; import com.zy.acs.manager.core.integrate.wms.FaultReportService; import com.zy.acs.manager.core.integrate.wms.TaskReportService; import com.zy.acs.manager.core.service.ChargeService; import com.zy.acs.manager.core.service.MainLockWrapService; import com.zy.acs.manager.manager.entity.*; import com.zy.acs.manager.manager.enums.*; @@ -22,12 +17,9 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.time.Instant; import java.time.ZoneId; import java.util.Date; import java.util.List; import java.util.Optional; import java.util.Set; /** * judge whether agv go to funcSta which be charging or standby @@ -59,21 +51,10 @@ private SegmentService segmentService; @Autowired private TaskReportService taskReportService; @Autowired private VehFaultRecService vehFaultRecService; @Autowired private FaultReportService faultReportService; @Autowired private ChargeService chargeService; @Autowired private ChargeCoreService chargeCoreService; @Scheduled(cron = "0/5 * * * * ? ") private synchronized void autoCharge() { if (!configService.getVal("TaskAssignMode", Boolean.class)) { return; } private synchronized void autoCharge(){ if (!configService.getVal("TaskAssignMode", Boolean.class)) { return; } List<Agv> agvList = agvService.list(new LambdaQueryWrapper<Agv>().eq(Agv::getStatus, StatusType.ENABLE.val)); for (Agv agv : agvList) { AgvDetail agvDetail = agvDetailService.selectByAgvId(agv.getId()); @@ -97,7 +78,7 @@ } if (0 < segmentService.count(new LambdaQueryWrapper<Segment>() .eq(Segment::getAgvId, agv.getId()) .and(i -> { .and( i -> { // i.eq(Segment::getState, SegmentStateType.WAITING.toString()).or() i.eq(Segment::getState, SegmentStateType.RUNNING.toString()); }) @@ -113,13 +94,9 @@ @Scheduled(cron = "0/1 * * * * ? ") // @Scheduled(cron = "0 */2 * * * ? ") private synchronized void autoStandby() { if (!configService.getVal("TaskAssignMode", Boolean.class)) { return; } if (!configService.getVal("automaticStandbyPosition", Boolean.class)) { return; } private synchronized void autoStandby(){ if (!configService.getVal("TaskAssignMode", Boolean.class)) { return; } if (!configService.getVal("automaticStandbyPosition", Boolean.class)) { return; } List<Agv> agvList = agvService.list(new LambdaQueryWrapper<Agv>().eq(Agv::getStatus, StatusType.ENABLE.val)); for (Agv agv : agvList) { @@ -132,10 +109,6 @@ // if (agvDetailService.isPowerLoss(agv, agvDetail, agvModel)) { // continue; // } // 判读是否可以自动断开充电(即充电过程中不能接受任务),跳过 if (!agvService.judgeAutoStopCharge(agvModel, agvDetail, agv)) { continue; } // is charging ? if (agvDetail.getAgvStatus().equals(AgvStatusType.CHARGE)) { if (agvDetail.getSoc() < agvModel.getQuaBattery()) { @@ -170,9 +143,7 @@ Optional.ofNullable(latestTask.getEndTime()).orElse(latestTask.getUpdateTime()) , new Date() ); if (seconds < intervalOfAutoStandby) { continue; } if (seconds < intervalOfAutoStandby) { continue; } } } else { continue; @@ -184,18 +155,14 @@ } @Scheduled(cron = "0/3 * * * * ? ") private synchronized void reportTaskToUplink() { if (!uplinkProperties.getEnabled()) { return; } private void reportTaskToUplink() { if (!uplinkProperties.getEnabled()) { return; } List<Task> taskList = taskService.list(new LambdaQueryWrapper<Task>() .in(Task::getUplinkSts, TaskUplinkStateType.PENDING.toString(), TaskUplinkStateType.FAILED.toString()) .eq(Task::getTaskSts, TaskStsType.COMPLETE.val()) .isNotNull(Task::getBusId) ); if (Cools.isEmpty(taskList)) { return; } if (Cools.isEmpty(taskList)) { return; } for (Task task : taskList) { boolean finished = taskReportService.reportFinished(task); if (finished) { @@ -223,132 +190,5 @@ } } } @Scheduled(cron = "0/3 * * * * ? ") private synchronized void reportFault() { String reportFaultUrl = configService.getVal("reportFaultUrl", String.class); if (Cools.isEmpty(reportFaultUrl)) { return; } List<VehFaultRec> vehFaultRecList = vehFaultRecService.list((new LambdaQueryWrapper<VehFaultRec>().eq(VehFaultRec::getState, VehFaultRecStateType.PENDING).ge(VehFaultRec::getHappenTime, Instant.now().minusSeconds(180).atZone(ZoneId.systemDefault()).toLocalDateTime()))); if (Cools.isEmpty(vehFaultRecList)) { return; } for (VehFaultRec vehFaultRec : vehFaultRecList) { boolean finished = faultReportService.reportFinished(vehFaultRec, reportFaultUrl); if (finished) { vehFaultRec.setState(VehFaultRecStateType.REPORT_SUCCESS.name()); } else { log.error("failed to report vehFaultRec to uplink"); vehFaultRec.setState(VehFaultRecStateType.REPORT_FAILED.name()); } vehFaultRecService.updateById(vehFaultRec); } } /** * 调度对接充电桩 * 状态1:开始充电 * 状态2:充电中 * 状态3:人为操作下发断开充电操作 */ @Scheduled(cron = "0/5 * * * * ? ") private synchronized void startCharge() { Set<String> mapKeys = redis.getMapKeys(RedisConstant.AGV_CHARGE_FLAG); for (String key : mapKeys) { Integer status = redis.getMap(RedisConstant.AGV_CHARGE_FLAG, key); if (null == status) { continue; } AgvDetail agvDetail = agvDetailService.selectByAgvNo(key); if (agvDetail == null) { log.error("{} 号待充电小车不存在", key); continue; } if (agvDetail.getCode() == null) { log.error("{} 号待充电小车无地址码", key); continue; } FuncSta funcSta = funcStaService.getByCodeAndType(agvDetail.getCode(), FuncStaType.CHARGE.toString()); ModbusTCPMaster modbusTCPMaster = chargeService.get(funcSta.getUuid()); if (null == agvDetail || null == agvDetail.getSoc() || null == agvDetail.getAgvStatus() || funcSta == null || null == modbusTCPMaster) { 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 start:{}", agvDetail.getAgvId$()); } else { log.info("read charge current and voltage: {},{}", current, voltage); } } else { log.info("前进到位信号失败:车号:{}", agvDetail.getAgvId$()); } break; case 2: // 如果充电机完成充电会自动断开 // 但充电标识哈在缓存中,那么需要清除缓存标记 // 获取充电机编号且后退到位信号存在,那么说明机械臂已经伸回,那么就需要清除缓存 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$()); } } } 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: log.error("charge status error: {}", status); break; } } } } zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/ReportUpScheduler.java
New file @@ -0,0 +1,65 @@ package com.zy.acs.manager.core.scheduler; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.acs.charge.ChargeCoreService; import com.zy.acs.common.utils.RedisSupport; import com.zy.acs.framework.common.Cools; import com.zy.acs.manager.common.config.UplinkProperties; import com.zy.acs.manager.core.integrate.wms.FaultReportService; import com.zy.acs.manager.core.integrate.wms.TaskReportService; import com.zy.acs.manager.core.service.ChargeService; import com.zy.acs.manager.core.service.MainLockWrapService; import com.zy.acs.manager.manager.entity.VehFaultRec; import com.zy.acs.manager.manager.enums.VehFaultRecStateType; import com.zy.acs.manager.manager.service.*; import com.zy.acs.manager.system.service.ConfigService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.time.Instant; import java.time.ZoneId; import java.util.List; @Slf4j @Component public class ReportUpScheduler { private final RedisSupport redis = RedisSupport.defaultRedisSupport; @Autowired private ConfigService configService; @Autowired private VehFaultRecService vehFaultRecService; @Autowired private FaultReportService faultReportService; @Scheduled(cron = "0/3 * * * * ? ") private synchronized void reportFault() { String reportFaultUrl = configService.getVal("reportFaultUrl", String.class); if (Cools.isEmpty(reportFaultUrl)) { return; } List<VehFaultRec> vehFaultRecList = vehFaultRecService.list((new LambdaQueryWrapper<VehFaultRec>().eq(VehFaultRec::getState, VehFaultRecStateType.PENDING).ge(VehFaultRec::getHappenTime, Instant.now().minusSeconds(180).atZone(ZoneId.systemDefault()).toLocalDateTime()))); if (Cools.isEmpty(vehFaultRecList)) { return; } for (VehFaultRec vehFaultRec : vehFaultRecList) { boolean finished = faultReportService.reportFinished(vehFaultRec, reportFaultUrl); if (finished) { vehFaultRec.setState(VehFaultRecStateType.REPORT_SUCCESS.name()); } else { log.error("failed to report vehFaultRec to uplink"); vehFaultRec.setState(VehFaultRecStateType.REPORT_FAILED.name()); } vehFaultRecService.updateById(vehFaultRec); } } } zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/AgvService.java
@@ -7,8 +7,6 @@ import com.zy.acs.manager.core.domain.VehicleDto; import com.zy.acs.manager.manager.controller.result.AgvResult; import com.zy.acs.manager.manager.entity.Agv; import com.zy.acs.manager.manager.entity.AgvDetail; import com.zy.acs.manager.manager.entity.AgvModel; import java.util.List; @@ -45,7 +43,5 @@ Agv findByPosition(Long codeId); int getBackpackRemainingCapacity(Long agvId); Boolean judgeAutoStopCharge(AgvModel agvModel, AgvDetail agvDetail, Agv agv); } zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/AgvServiceImpl.java
@@ -2,8 +2,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ghgande.j2mod.modbus.facade.ModbusTCPMaster; import com.zy.acs.charge.ChargeCoreService; import com.zy.acs.common.constant.RedisConstant; import com.zy.acs.common.enums.AgvStatusType; import com.zy.acs.common.utils.RedisSupport; @@ -14,11 +12,12 @@ import com.zy.acs.manager.common.domain.PageResult; import com.zy.acs.manager.core.cache.CoreCache; import com.zy.acs.manager.core.domain.VehicleDto; import com.zy.acs.manager.core.service.ChargeService; import com.zy.acs.manager.core.service.astart.MapDataDispatcher; import com.zy.acs.manager.manager.controller.result.AgvResult; import com.zy.acs.manager.manager.entity.*; import com.zy.acs.manager.manager.enums.FuncStaType; import com.zy.acs.manager.manager.entity.Agv; import com.zy.acs.manager.manager.entity.AgvDetail; import com.zy.acs.manager.manager.entity.AgvModel; import com.zy.acs.manager.manager.entity.Segment; import com.zy.acs.manager.manager.enums.SegmentStateType; import com.zy.acs.manager.manager.mapper.AgvMapper; import com.zy.acs.manager.manager.service.*; @@ -67,15 +66,6 @@ private AreaAgvService areaAgvService; @Autowired private MapDataDispatcher mapDataDispatcher; @Autowired private FuncStaService funcStaService; @Autowired private ChargeService chargeService; @Autowired private ChargeCoreService chargeCoreService; @Autowired private AgvService agvService; @PostConstruct public void init() { @@ -234,10 +224,6 @@ return false; } } if (judgeAutoStopCharge(agvModel, agvDetail,agvService.getById(agvId))) { log.warn("[{}]号Agv需要断充操作,无法执行任务......", agvNo); return false; } if (agvDetail.getAgvStatus().equals(AgvStatusType.CHARGE)) { if (agvDetail.getSoc() < agvModel.getQuaBattery()) { return false; @@ -332,29 +318,6 @@ AgvModel agvModel = agvModelService.getByAgvId(agvId); return Math.max(agvModel.getBackpack() - usedSlots, 0); // if less than zero, then return zero } /** * 判断充电过程,自动断开 * @param agvModel * @param agvDetail * @return */ @Override public Boolean judgeAutoStopCharge(AgvModel agvModel, AgvDetail agvDetail, Agv agv ) { if (redis.getMap(RedisConstant.AGV_CHARGE_FLAG, agv.getUuid()) != null){ return true; } // 手动充电模式,跳过 // if (agvModel.getNeedUndocking() != null && agvModel.getNeedUndockingBool()) { // FuncSta funcSta = funcStaService.getByCodeAndType(agvDetail.getCode(), FuncStaType.CHARGE.toString()); // ModbusTCPMaster modbusTCPMaster = chargeService.get(funcSta.getUuid()); // // 手动充电模式,跳过 // if (modbusTCPMaster != null && chargeCoreService.getChargeMode(modbusTCPMaster) == 1) { // return true; // } // } return false; } }