package com.iflytop.gd.hardware.drivers; import cn.hutool.core.util.StrUtil; import com.iflytop.gd.hardware.comm.can.A8kCanBusService; import com.iflytop.gd.hardware.comm.modbus.ModbusMasterService; import com.iflytop.gd.hardware.exception.HardwareException; import com.iflytop.gd.hardware.type.A8kPacket; import com.iflytop.gd.hardware.type.CmdId; import com.iflytop.gd.hardware.type.driver.HeaterRodSlavedId; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Slf4j @Component @RequiredArgsConstructor public class HeaterRodDriver { private final A8kCanBusService canBus; private final ModbusMasterService modbusMaster; private static final int SV_ADDRESS = 0x2000; private static final int PV_ADDRESS = 0x2010; private static final int CONTROL_REGISTER = 0x2106; private static final int DP_ADDRESS = 0x2107; private static final int DEVICE_ADDRESS_REGISTER = 0x2112; private final Map dpCache = new ConcurrentHashMap<>(); private static final int DEFAULT_DP = 1; public void setDeviceAddress(HeaterRodSlavedId heaterRodId, int newAddress) throws Exception { int slaveId = heaterRodId.getSlaveId(); if (!modbusMaster.writeRegister(slaveId, DEVICE_ADDRESS_REGISTER, newAddress)) { throw new Exception("Failed to set device address for heater rod with ID: " + heaterRodId.name()); } log.info("Device address for heater rod with ID: {} set to: {}", heaterRodId.name(), newAddress); } private int getDecimalPoint(int slaveId) throws Exception { return dpCache.computeIfAbsent(slaveId, id -> { try { short[] response = modbusMaster.readHoldingRegisters(id, DP_ADDRESS, 1); if (response != null && response.length > 0) { return (int) response[0]; } } catch (Exception e) { log.warn("Failed to read DP for slave ID: {}, using default DP: {}", id, DEFAULT_DP); } return DEFAULT_DP; }); } public void openPower(HeaterRodSlavedId heaterRodId) throws Exception { int slaveId = heaterRodId.getSlaveId(); if (!modbusMaster.writeRegister(slaveId, CONTROL_REGISTER, 1)) { // 1 = Start throw new Exception("Failed to start heater rod with ID: " + heaterRodId.name()); } } public void closePower(HeaterRodSlavedId heaterRodId) throws Exception { int slaveId = heaterRodId.getSlaveId(); if (!modbusMaster.writeRegister(slaveId, CONTROL_REGISTER, 2)) { // 2 = Stop throw new Exception("Failed to stop heater rod with ID: " + heaterRodId.name()); } log.info("{} stopped.", heaterRodId.name()); } public void setTemperature(HeaterRodSlavedId heaterRodId, double temperature) throws Exception { int slaveId = heaterRodId.getSlaveId(); int decimalPoint = getDecimalPoint(slaveId); int scaledTemperature = (int) (temperature * Math.pow(10, decimalPoint)); if (!modbusMaster.writeRegister(slaveId, SV_ADDRESS, scaledTemperature)) { throw new Exception("Failed to set temperature for heater rod with ID: " + heaterRodId.name()); } log.info("{} started with temperature: {}", heaterRodId.name(), temperature); } public double getTemperature(HeaterRodSlavedId heaterRodId) throws Exception { int slaveId = heaterRodId.getSlaveId(); int decimalPoint = getDecimalPoint(slaveId); short[] response = modbusMaster.readHoldingRegisters(slaveId, PV_ADDRESS, 1); if (response == null || response.length == 0) { throw new Exception(StrUtil.format("Failed to read temperature {}", heaterRodId.name())); } double temperature = response[0] / Math.pow(10, decimalPoint); log.info("{} GET temperature {}", heaterRodId.name(), temperature); return temperature; } /** * 获取电流 * @return */ public Integer getCurrent(HeaterRodSlavedId heaterRodId) throws HardwareException { A8kPacket packet = canBus.callcmd(heaterRodId.getMid(), CmdId.adc_read_adc, heaterRodId.getAdcCurrentIndex()); Integer current = packet.getContentI32(0); return current; } // ==== ==== ==== ==== ==== ==== application ==== ==== ==== ==== ==== ==== public void open(HeaterRodSlavedId heaterRodId, double temperature) throws Exception { this.openPower(heaterRodId); this.setTemperature(heaterRodId, temperature); } public void close(HeaterRodSlavedId heaterRodId) throws Exception { this.closePower(heaterRodId); } }