| | |
| | | package com.zy.acs.charge.impl; |
| | | |
| | | 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.model.ChargerStatus; |
| | | import com.zy.acs.charge.protocol.ModbusAdapter; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.annotation.Primary; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | |
| | | @Service |
| | | @Primary |
| | | @Slf4j |
| | | public class AiPowerChargeServiceImpl implements ChargeCoreService { |
| | | public class AiPowerChargeServiceImpl implements ChargeCoreService { |
| | | |
| | | @Autowired |
| | | private ModbusAdapter modbusAdapter; |
| | | |
| | | /** |
| | | * 开始充电 |
| | | * |
| | | * @param client |
| | | * @return |
| | | */ |
| | | @Override |
| | | public boolean connect() throws Exception { |
| | | modbusAdapter.connect(); |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public void disconnect() { |
| | | modbusAdapter.disconnect(); |
| | | } |
| | | |
| | | @Override |
| | | public boolean isConnected() { |
| | | // 可以通过尝试读取一个寄存器来判断,但为了简单,这里直接返回连接状态(需改造 ModbusAdapter 暴露状态) |
| | | // 可在 ModbusAdapter 中添加 isConnected() 方法 |
| | | return false; // 待实现 |
| | | } |
| | | |
| | | @Override |
| | | public boolean startCharging() throws Exception { |
| | | public boolean startCharging(ModbusTCPMaster client) { |
| | | // AGV车报告到位 -> true |
| | | modbusAdapter.writeCoil(AiPowerChargerCoilEnum.AGV_REPORTED_IN_POSITION.getAddr(), true); |
| | | return true; |
| | | try { |
| | | if (!client.isConnected()) { |
| | | client.connect(); |
| | | } |
| | | return client.writeCoil(AiPowerChargerCoilEnum.AGV_REPORTED_IN_POSITION.getAddr(), true); |
| | | } catch (Exception e) { |
| | | log.info("写入开始充电指令报错:{} ", e.getMessage()); |
| | | }finally { |
| | | //client.disconnect(); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 停止充电 |
| | | * |
| | | * @param client |
| | | * @return |
| | | */ |
| | | @Override |
| | | public boolean stopCharging() throws Exception { |
| | | modbusAdapter.writeCoil(AiPowerChargerCoilEnum.AGV_REPORTED_IN_POSITION.getAddr(), false); |
| | | return true; |
| | | public boolean stopCharging(ModbusTCPMaster client) { |
| | | try { |
| | | if (!client.isConnected()) { |
| | | client.connect(); |
| | | } |
| | | return client.writeCoil(AiPowerChargerCoilEnum.AGV_REPORTED_IN_POSITION.getAddr(), false); |
| | | } catch (Exception e) { |
| | | log.info("写入停止充电指令报错:{} ", e.getMessage()); |
| | | }finally { |
| | | //client.disconnect(); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 在线正继电器状态(前进到位) |
| | | * |
| | | * @param client |
| | | * @return |
| | | */ |
| | | @Override |
| | | public ChargerStatus getStatus() throws Exception { |
| | | public boolean checkForwardRelayOnline(ModbusTCPMaster client) { |
| | | try { |
| | | if (!client.isConnected()) { |
| | | client.connect(); |
| | | } |
| | | return client.readCoils(AiPowerChargerCoilEnum.FORWARD_RELAY_ONLINE.getAddr(), 1).getBit(0); |
| | | } catch (Exception e) { |
| | | log.info("读取在线正继电器状态报错:{} ", e.getMessage()); |
| | | }finally { |
| | | //client.disconnect(); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 离线正继电器状态(后退到位) |
| | | * |
| | | * @param client |
| | | * @return |
| | | */ |
| | | @Override |
| | | public boolean checkBackwardRelayOffline(ModbusTCPMaster client) { |
| | | try { |
| | | if (!client.isConnected()) { |
| | | client.connect(); |
| | | } |
| | | return client.readCoils(AiPowerChargerCoilEnum.BACKWARD_RELAY_OFFLINE.getAddr(), 1).getBit(0); |
| | | } catch (Exception e) { |
| | | log.info("读取离线正继电器状态报错:{} ", e.getMessage()); |
| | | }finally { |
| | | //client.disconnect(); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 获取充电机充电电压 |
| | | * |
| | | * @param client |
| | | * @return |
| | | */ |
| | | @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 (Exception e) { |
| | | log.info("读取充电电压报错:{} ", e.getMessage()); |
| | | }finally { |
| | | //client.disconnect(); |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * 获取充电机充电电流 |
| | | * |
| | | * @param client |
| | | * @return |
| | | */ |
| | | @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 (Exception e) { |
| | | log.info("读取充电电流报错:{} ", e.getMessage()); |
| | | }finally { |
| | | //client.disconnect(); |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * 获取充电机充电模式 |
| | | * |
| | | * @param client |
| | | * @return |
| | | */ |
| | | @Override |
| | | public int getChargeMode(ModbusTCPMaster client) { |
| | | try { |
| | | if (!client.isConnected()) { |
| | | client.connect(); |
| | | } |
| | | return client.readMultipleRegisters(AiPowerChargerRegisterEnum.CHARGE_MODE.getAddr(), 1)[0].getValue(); |
| | | } 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; |
| | | } |
| | | |
| | | /** |
| | | * 获取充电机状态 |
| | | * |
| | | * @param client |
| | | * @return |
| | | */ |
| | | @Override |
| | | public ChargerStatus getStatus(ModbusTCPMaster client) { |
| | | |
| | | ChargerStatus status = new ChargerStatus(); |
| | | |
| | | // ---------- 批量读取线圈(地址100~115共16个) ---------- |
| | | boolean[] coils = modbusAdapter.readCoils(100, 16); |
| | | status.setWorking(coils[0]); // 地址100 |
| | | status.setOverheat(coils[1]); // 101 |
| | | status.setFault(coils[2]); // 102 |
| | | status.setCvMode(coils[3]); // 103 |
| | | status.setBatteryConnected(coils[4]); // 104 |
| | | status.setFanAbnormal(coils[5]); // 105 |
| | | status.setPlateOverheat(coils[6]); // 106 |
| | | status.setBrushPressed(coils[7]); // 107 |
| | | status.setAgvReportedInPosition(coils[8]); // 108 |
| | | status.setChargerConfirmedAgvReady(coils[9]); // 109 |
| | | status.setForwardRelayOnline(coils[10]); // 110 |
| | | status.setBackwardRelayOffline(coils[11]); // 111 |
| | | status.setBmsChargeEnable(coils[12]); // 112 |
| | | status.setCommRs485Success(!coils[13]); // 113(注意:0=成功,1=超时) |
| | | status.setCommCanSuccess(!coils[14]); // 114 |
| | | status.setCommBmsSuccess(!coils[15]); // 115 |
| | | 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) { |
| | | case 0: |
| | | status.setWorking(coils.getBit(i)); |
| | | break; |
| | | case 1: |
| | | status.setOverheat(coils.getBit(i)); |
| | | break; |
| | | case 2: |
| | | status.setFault(coils.getBit(i)); |
| | | break; |
| | | case 3: |
| | | status.setCvMode(coils.getBit(i)); |
| | | break; |
| | | case 4: |
| | | status.setBatteryConnected(coils.getBit(i)); |
| | | break; |
| | | case 5: |
| | | status.setFanAbnormal(coils.getBit(i)); |
| | | break; |
| | | case 6: |
| | | status.setPlateOverheat(coils.getBit(i)); |
| | | break; |
| | | case 7: |
| | | status.setBrushPressed(coils.getBit(i)); |
| | | break; |
| | | case 8: |
| | | status.setAgvReportedInPosition(coils.getBit(i)); |
| | | break; |
| | | case 9: |
| | | status.setChargerConfirmedAgvReady(coils.getBit(i)); |
| | | break; |
| | | case 10: |
| | | status.setForwardRelayOnline(coils.getBit(i)); |
| | | break; |
| | | case 11: |
| | | status.setBackwardRelayOffline(coils.getBit(i)); |
| | | break; |
| | | case 12: |
| | | status.setBmsChargeEnable(coils.getBit(i)); |
| | | break; |
| | | case 13: |
| | | status.setCommRs485Success(!coils.getBit(i)); |
| | | break; |
| | | case 14: |
| | | status.setCommCanSuccess(!coils.getBit(i)); |
| | | break; |
| | | case 15: |
| | | status.setCommBmsSuccess(!coils.getBit(i)); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |
| | | // ---------- 批量读取保持寄存器(地址100~116共17个) ---------- |
| | | int[] regs = modbusAdapter.readHoldingRegisters(100, 17); |
| | | status.setVoltage(regs[0] * AiPowerChargerRegisterEnum.CHARGE_VOLTAGE.getRaw()); |
| | | status.setCurrent(regs[1] * AiPowerChargerRegisterEnum.CHARGE_CURRENT.getRaw()); |
| | | status.setChargingTime(regs[2]); |
| | | status.setCapacity(regs[3] * AiPowerChargerRegisterEnum.CHARGE_CAPACITY.getRaw()); |
| | | status.setEnergy(regs[4] * AiPowerChargerRegisterEnum.CHARGE_ENERGY.getRaw()); |
| | | status.setCellMaxVoltage(regs[5]); |
| | | status.setCellMinVoltage(regs[6]); |
| | | status.setPackVoltage(regs[7] * AiPowerChargerRegisterEnum.BMS_PACK_VOLTAGE.getRaw()); |
| | | status.setVoltageDemand(regs[8] * AiPowerChargerRegisterEnum.BMS_VOLTAGE_DEMAND.getRaw()); |
| | | status.setCurrentDemand(regs[9] * AiPowerChargerRegisterEnum.BMS_CURRENT_DEMAND.getRaw()); |
| | | status.setTemperature(regs[10]); |
| | | status.setSoc(regs[11] * AiPowerChargerRegisterEnum.BMS_SOC.getRaw()); |
| | | status.setEndFlag(regs[12]); |
| | | status.setChargerId(regs[13]); |
| | | status.setFaultCode(regs[14]); |
| | | status.setChargeMode(regs[15]); |
| | | status.setScheduleFlag(regs[16]); |
| | | // ---------- 批量读取保持寄存器(地址100~116共17个) ---------- |
| | | |
| | | Register[] registers = client.readMultipleRegisters(AiPowerChargerRegisterEnum.CHARGE_VOLTAGE.getAddr(), AiPowerChargerRegisterEnum.values().length); |
| | | for (int i = 0; i < registers.length; i++) { |
| | | switch (i) { |
| | | case 0: |
| | | status.setVoltage(registers[i].getValue() * AiPowerChargerRegisterEnum.CHARGE_VOLTAGE.getRaw()); |
| | | break; |
| | | case 1: |
| | | status.setCurrent(registers[i].getValue() * AiPowerChargerRegisterEnum.CHARGE_CURRENT.getRaw()); |
| | | break; |
| | | case 2: |
| | | status.setChargingTime(registers[i].getValue()); |
| | | break; |
| | | case 3: |
| | | status.setCapacity(registers[i].getValue() * AiPowerChargerRegisterEnum.CHARGE_CAPACITY.getRaw()); |
| | | break; |
| | | case 4: |
| | | status.setEnergy(registers[i].getValue() * AiPowerChargerRegisterEnum.CHARGE_ENERGY.getRaw()); |
| | | break; |
| | | case 5: |
| | | status.setCellMaxVoltage(registers[i].getValue()); |
| | | break; |
| | | case 6: |
| | | status.setCellMinVoltage(registers[i].getValue()); |
| | | break; |
| | | case 7: |
| | | status.setPackVoltage(registers[i].getValue() * AiPowerChargerRegisterEnum.BMS_PACK_VOLTAGE.getRaw()); |
| | | break; |
| | | case 8: |
| | | status.setVoltageDemand(registers[i].getValue() * AiPowerChargerRegisterEnum.BMS_VOLTAGE_DEMAND.getRaw()); |
| | | break; |
| | | case 9: |
| | | status.setCurrentDemand(registers[i].getValue() * AiPowerChargerRegisterEnum.BMS_CURRENT_DEMAND.getRaw()); |
| | | break; |
| | | case 10: |
| | | status.setTemperature(registers[i].getValue()); |
| | | break; |
| | | case 11: |
| | | status.setSoc(registers[i].getValue() * AiPowerChargerRegisterEnum.BMS_SOC.getRaw()); |
| | | break; |
| | | case 12: |
| | | status.setEndFlag(registers[i].getValue()); |
| | | break; |
| | | case 13: |
| | | status.setChargerId(registers[i].getValue()); |
| | | break; |
| | | case 14: |
| | | status.setFaultCode(registers[i].getValue()); |
| | | break; |
| | | case 15: |
| | | status.setChargeMode(registers[i].getValue()); |
| | | break; |
| | | case 16: |
| | | status.setScheduleFlag(registers[i].getValue()); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | log.info("批量读取线圈报错:{} ", e.getMessage()); |
| | | log.info("批量读取保持寄存器报错:{} ", e.getMessage()); |
| | | }finally { |
| | | //client.disconnect(); |
| | | } |
| | | |
| | | return status; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 清除故障 |
| | | * |
| | | * @param client |
| | | * @return |
| | | */ |
| | | @Override |
| | | public boolean setVoltage(int voltageDecivolts) throws Exception { |
| | | // BMS无时才允许写入,这里假设允许 |
| | | modbusAdapter.writeHoldingRegister(AiPowerChargerRegisterEnum.CHARGE_VOLTAGE.getAddr(), voltageDecivolts); |
| | | public boolean clearFault(ModbusTCPMaster client) { |
| | | try { |
| | | client.writeSingleRegister(AiPowerChargerRegisterEnum.SCHEDULE_FLAG.getAddr(), new SimpleRegister(1)); |
| | | } catch (ModbusException e) { |
| | | log.error("充电器清除故障失败......"); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 完成退回 |
| | | * |
| | | * @param client |
| | | * @return |
| | | */ |
| | | @Override |
| | | public boolean setCurrent(int currentDecamperes) throws Exception { |
| | | modbusAdapter.writeHoldingRegister(AiPowerChargerRegisterEnum.CHARGE_CURRENT.getAddr(), currentDecamperes); |
| | | public boolean finishRetract(ModbusTCPMaster client) { |
| | | try { |
| | | client.writeSingleRegister(AiPowerChargerRegisterEnum.SCHEDULE_FLAG.getAddr(), new SimpleRegister(2)); |
| | | } catch (ModbusException e) { |
| | | log.error("充电器完成退回失败......"); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 恢复待机 |
| | | * |
| | | * @param client |
| | | * @return |
| | | */ |
| | | @Override |
| | | public boolean clearFault() throws Exception { |
| | | // 写入调度标识地址为1:清除故障 |
| | | modbusAdapter.writeHoldingRegister(AiPowerChargerRegisterEnum.SCHEDULE_FLAG.getAddr(), 1); |
| | | public boolean restoreStandby(ModbusTCPMaster client) { |
| | | try { |
| | | client.writeSingleRegister(AiPowerChargerRegisterEnum.SCHEDULE_FLAG.getAddr(), new SimpleRegister(3)); |
| | | } catch (ModbusException e) { |
| | | log.error("充电器恢复待机失败......"); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | |
| | | } |
| | | |