From b6280a6663a075773e146bd765e9f03082d0e41b Mon Sep 17 00:00:00 2001 From: HSZ_HeSongZhen <210202959@qq.com> Date: Wed, 14 May 2025 16:09:17 +0800 Subject: [PATCH] =?UTF-8?q?add:=20=E5=A2=9E=E5=8A=A0=E7=9F=B3=E5=A2=A8?= =?UTF-8?q?=E6=B6=88=E8=A7=A3=E4=BB=AA=E6=89=80=E6=9C=89=E7=9A=84=E5=AD=90?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E7=9A=84=E8=B0=83=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 19 +- .../app/hardware/channel/A8kCanBusConnection.java | 2 +- .../iflytop/app/hardware/channel/keyChannel.java | 127 +++++++++ .../channel/modbus/JSerialCommWrapper.java | 85 +++++++ .../channel/modbus/ModbusMasterFactory.java | 13 + .../channel/modbus/ModbusMasterService.java | 283 +++++++++++++++++++++ .../app/hardware/driver/FillLightDriver.java | 25 ++ .../app/hardware/driver/HeaterRodDriver.java | 125 +++++++++ .../app/hardware/driver/InputDetectDriver.java | 37 +++ .../app/hardware/driver/TricolorLightDriver.java | 30 +++ .../java/iflytop/app/hardware/type/CmdDevice.java | 44 ++++ src/main/java/iflytop/app/hardware/type/CmdId.java | 14 +- .../app/hardware/type/HeaterRodSlavedId.java | 51 ++++ .../java/iflytop/app/hardware/type/InputIOMId.java | 39 +++ .../iflytop/app/menu/ExtApiPageGroupCfgMgr.java | 5 +- src/main/java/iflytop/app/page/DeviceInitPage.java | 22 +- src/main/java/iflytop/app/page/HeaterRodPage.java | 91 +++++++ .../java/iflytop/app/page/IOBoardCtrlPage.java | 61 +++++ .../iflytop/app/page/InputIOStateScannerPage.java | 96 +++++++ .../java/iflytop/app/page/OutputIOCtrlPage.java | 5 + .../appsetup/A8kSubModuleRegInitService.java | 22 +- src/main/resources/application.yml | 12 +- 22 files changed, 1189 insertions(+), 19 deletions(-) create mode 100644 src/main/java/iflytop/app/hardware/channel/keyChannel.java create mode 100644 src/main/java/iflytop/app/hardware/channel/modbus/JSerialCommWrapper.java create mode 100644 src/main/java/iflytop/app/hardware/channel/modbus/ModbusMasterFactory.java create mode 100644 src/main/java/iflytop/app/hardware/channel/modbus/ModbusMasterService.java create mode 100644 src/main/java/iflytop/app/hardware/driver/FillLightDriver.java create mode 100644 src/main/java/iflytop/app/hardware/driver/HeaterRodDriver.java create mode 100644 src/main/java/iflytop/app/hardware/driver/InputDetectDriver.java create mode 100644 src/main/java/iflytop/app/hardware/driver/TricolorLightDriver.java create mode 100644 src/main/java/iflytop/app/hardware/type/CmdDevice.java create mode 100644 src/main/java/iflytop/app/hardware/type/HeaterRodSlavedId.java create mode 100644 src/main/java/iflytop/app/hardware/type/InputIOMId.java create mode 100644 src/main/java/iflytop/app/page/HeaterRodPage.java create mode 100644 src/main/java/iflytop/app/page/IOBoardCtrlPage.java create mode 100644 src/main/java/iflytop/app/page/InputIOStateScannerPage.java diff --git a/pom.xml b/pom.xml index 7f56509..82fe1fe 100644 --- a/pom.xml +++ b/pom.xml @@ -75,11 +75,20 @@ - - - - - + + com.fazecast + jSerialComm + 2.11.0 + + + + + com.github.infiniteautomation + modbus4j + 3.1.0 + system + ${project.basedir}/lib/modbus4j-3.1.0.jar + diff --git a/src/main/java/iflytop/app/hardware/channel/A8kCanBusConnection.java b/src/main/java/iflytop/app/hardware/channel/A8kCanBusConnection.java index 220f6fc..5e0bc82 100644 --- a/src/main/java/iflytop/app/hardware/channel/A8kCanBusConnection.java +++ b/src/main/java/iflytop/app/hardware/channel/A8kCanBusConnection.java @@ -139,7 +139,7 @@ public class A8kCanBusConnection extends WebSocketClient { synchronized public A8kPacket callcmd(MId moduleId, CmdId cmdId, Integer... param) throws HardwareException { - var packet = packParamsToPacket(moduleId.toInt(), cmdId.toInt(), ZList.of(param)); + var packet = packParamsToPacket(moduleId.toInt(), cmdId.toInt(), ZList.of(param)); return autoReSend(packet, A8kPacket.CMD_OVERTIME); } diff --git a/src/main/java/iflytop/app/hardware/channel/keyChannel.java b/src/main/java/iflytop/app/hardware/channel/keyChannel.java new file mode 100644 index 0000000..6b476cc --- /dev/null +++ b/src/main/java/iflytop/app/hardware/channel/keyChannel.java @@ -0,0 +1,127 @@ +package iflytop.app.hardware.channel; + +import iflytop.app.config.IflytophaldConnectionConfig; +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.enums.ReadyState; +import org.java_websocket.handshake.ServerHandshake; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.util.LinkedList; +import java.util.Queue; + +@Slf4j +@Component +@RequiredArgsConstructor +public class keyChannel { + WebSocketClient conn; + + private final IflytophaldConnectionConfig config; + private Queue sendQueue = new LinkedList<>(); + + private Boolean logEnable = false; + + @PostConstruct + void init() { + String url = config.getDatachUrl("key"); + log.info("Key Channel url: {}", url); + conn = new WebSocketClient(URI.create(url)) { + @Override + public void onOpen(ServerHandshake serverHandshake) { + keyChannel.this.onOpen(serverHandshake); + } + + @Override + public void onMessage(String s) { + keyChannel.this.onMessage(s); + } + + @Override + public void onClose(int i, String s, boolean b) { + keyChannel.this.onClose(i, s, b); + } + + @Override + public void onError(Exception e) { + keyChannel.this.onError(e); + } + }; + conn.connect(); + } + + public void setLogEnable(Boolean logEnable) { + this.logEnable = logEnable; + } + + + private void onOpen(ServerHandshake serverHandshake) { + log.info("gd key connect sucess"); + } + + private void onMessage(String s) { + if(logEnable) + { + log.info("gd key message: {}", s); + } + + } + + private void onClose(int i, String s, boolean b) { + log.warn("gd key lost connection..."); + } + + private void onError(Exception e) { + log.info("gd key-websocket-channel on error"); + } + + + synchronized private void pushToSend(byte[] toSend) { + sendQueue.add(toSend); + } + + synchronized private byte[] popToSend() { + if (!sendQueue.isEmpty()) { + return sendQueue.poll(); + } + return null; + } + + @Scheduled(fixedRate = 400) + private void autoSend() { + while (true) { + var tosend = popToSend(); + if (tosend != null) { + if (conn.isOpen()) { + conn.send(tosend); + } + if (tosend.length > 2) { + break; + } + } else { + break; + } + + } + + } + + + @Scheduled(fixedRate = 10000) + private void autoConnect() { + if (!conn.isOpen()) { + if (conn.getReadyState().equals(ReadyState.NOT_YET_CONNECTED)) { + try { + conn.connect(); + } catch (IllegalStateException ignored) { + } + } else if (conn.getReadyState().equals(ReadyState.CLOSED)) { + conn.reconnect(); + } + } + } +} diff --git a/src/main/java/iflytop/app/hardware/channel/modbus/JSerialCommWrapper.java b/src/main/java/iflytop/app/hardware/channel/modbus/JSerialCommWrapper.java new file mode 100644 index 0000000..3e7e4f1 --- /dev/null +++ b/src/main/java/iflytop/app/hardware/channel/modbus/JSerialCommWrapper.java @@ -0,0 +1,85 @@ +package iflytop.app.hardware.channel.modbus; + +import com.fazecast.jSerialComm.SerialPort; +import com.serotonin.modbus4j.serial.SerialPortWrapper; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +@Slf4j +public class JSerialCommWrapper implements SerialPortWrapper { + private final int baudRate; + private final int dataBits; + private final int stopBits; + private final int parity; + + private final SerialPort serialPort; + + public JSerialCommWrapper(String portName, int baudRate, int dataBits, int stopBits, int parity) { + this.baudRate = baudRate; + this.dataBits = dataBits; + this.stopBits = stopBits; + this.parity = parity; + + serialPort = SerialPort.getCommPort(portName); + serialPort.setBaudRate(this.baudRate); + serialPort.setNumDataBits(this.dataBits); + serialPort.setNumStopBits(this.stopBits); + serialPort.setParity(this.parity); + } + + @Override + public void open() throws Exception { + if (!serialPort.openPort()) { + log.error("Could not open serial port {}", serialPort.getSystemPortName()); + throw new IOException("Failed to open serial port: " + serialPort.getSystemPortName()); + } + else{ + log.info("Opened serial port: " + serialPort.getSystemPortName()); + } + } + + @Override + public void close() throws Exception { + if (serialPort != null) { + serialPort.closePort(); + log.info("Closed serial port: {}", serialPort.getSystemPortName()); + } + else + { + log.warn("Could not close serial port: {} null", serialPort.getSystemPortName()); + } + } + + @Override + public InputStream getInputStream() { + return serialPort.getInputStream(); + } + + @Override + public OutputStream getOutputStream() { + return serialPort.getOutputStream(); + } + + @Override + public int getBaudRate() { + return this.baudRate; + } + + @Override + public int getStopBits() { + return this.stopBits; + } + + @Override + public int getParity() { + return this.parity; + } + + @Override + public int getDataBits() { + return this.dataBits; + } +} diff --git a/src/main/java/iflytop/app/hardware/channel/modbus/ModbusMasterFactory.java b/src/main/java/iflytop/app/hardware/channel/modbus/ModbusMasterFactory.java new file mode 100644 index 0000000..99112bf --- /dev/null +++ b/src/main/java/iflytop/app/hardware/channel/modbus/ModbusMasterFactory.java @@ -0,0 +1,13 @@ +package iflytop.app.hardware.channel.modbus; + +import com.serotonin.modbus4j.ModbusFactory; +import com.serotonin.modbus4j.ModbusMaster; + +public class ModbusMasterFactory { + static final ModbusFactory factory = new ModbusFactory(); + + public static ModbusMaster createModbusRtuMaster(String portName, int baudRate) { + JSerialCommWrapper wrapper = new JSerialCommWrapper(portName, baudRate, 8, 1, 0); + return factory.createRtuMaster(wrapper); + } +} diff --git a/src/main/java/iflytop/app/hardware/channel/modbus/ModbusMasterService.java b/src/main/java/iflytop/app/hardware/channel/modbus/ModbusMasterService.java new file mode 100644 index 0000000..4f1b1eb --- /dev/null +++ b/src/main/java/iflytop/app/hardware/channel/modbus/ModbusMasterService.java @@ -0,0 +1,283 @@ +package iflytop.app.hardware.channel.modbus; + +import com.serotonin.modbus4j.ModbusMaster; +import com.serotonin.modbus4j.msg.*; +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.util.concurrent.locks.ReentrantLock; + +@Slf4j +@Component +@RequiredArgsConstructor +public class ModbusMasterService { + private ModbusMaster modbusMaster_; + private final ReentrantLock lock = new ReentrantLock(); + + @Value("${modbus.port}") + private String port; + + @Value("${modbus.baudrate}") + private int baudrate; + + @PostConstruct + public void init() { + modbusMaster_ = ModbusMasterFactory.createModbusRtuMaster(port, baudrate); + log.info("============== ============== ============== ============== =============="); + log.info("============== ============== ============== ============== =============="); + try { + this.connect(); + log.info("Modbus master 端口: {} 波特率:{} initialized successfully.", port, baudrate); + } catch (Exception e) { + modbusMaster_.setConnected(false); + log.error("Failed to initialize Modbus master: {} 端口: {} 波特率: {}", + e.getMessage(), port, baudrate); + } + log.info("============== ============== ============== ============== =============="); + log.info("============== ============== ============== ============== =============="); + } + + /** + * 检查连接状态 + */ + private boolean isConnectionInvalid() { + if (modbusMaster_ == null) { + log.error("Modbus master is not initialized."); + return true; + } +// if (!modbusMaster_.isConnected()) { +// log.error("Modbus master is not connected."); +// return true; +// } + return false; + } + + // ==== ==== ==== ==== ==== ==== Modbus 功能封装 ==== ==== ==== ==== ==== ==== + + /** + * 读取线圈状态 (功能码: 1, READ_COILS) + */ + public boolean[] readCoils(int slaveId, int startAddress, int length) { + lock.lock(); + try { + if (isConnectionInvalid()) return null; + ReadCoilsRequest request = new ReadCoilsRequest(slaveId, startAddress, length); + ReadCoilsResponse response = (ReadCoilsResponse) modbusMaster_.send(request); + if (response.isException()) { + modbusMaster_.setConnected(false); + log.error("Error reading coils: {}", response.getExceptionMessage()); + return null; + } + return response.getBooleanData(); + } catch (Exception e) { + modbusMaster_.setConnected(false); + log.error("Failed to read coils: {}", e.getMessage()); + return null; + } finally { + lock.unlock(); + } + } + + /** + * 读取离散输入 (功能码: 2, READ_DISCRETE_INPUTS) + */ + public boolean[] readDiscreteInputs(int slaveId, int startAddress, int length) { + lock.lock(); + try { + if (isConnectionInvalid()) return null; + ReadDiscreteInputsRequest request = new ReadDiscreteInputsRequest(slaveId, startAddress, length); + ReadDiscreteInputsResponse response = (ReadDiscreteInputsResponse) modbusMaster_.send(request); + if (response.isException()) { + modbusMaster_.setConnected(false); + log.error("Error reading discrete inputs: {}", response.getExceptionMessage()); + return null; + } + return response.getBooleanData(); + } catch (Exception e) { + modbusMaster_.setConnected(false); + log.error("Failed to read discrete inputs: {}", e.getMessage()); + return null; + } finally { + lock.unlock(); + } + } + + /** + * 读取保持寄存器 (功能码: 3, READ_HOLDING_REGISTERS) + */ + public short[] readHoldingRegisters(int slaveId, int startAddress, int length) { + lock.lock(); + try { + if (isConnectionInvalid()) return null; + ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, startAddress, length); + ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) modbusMaster_.send(request); + if (response.isException()) { + modbusMaster_.setConnected(false); + log.error("Error reading holding registers: {}", response.getExceptionMessage()); + return null; + } + return response.getShortData(); + } catch (Exception e) { + modbusMaster_.setConnected(false); + log.error("Failed to read holding registers: {}", e.getMessage()); + return null; + } finally { + lock.unlock(); + } + } + + /** + * 读取输入寄存器 (功能码: 4, READ_INPUT_REGISTERS) + */ + public short[] readInputRegisters(int slaveId, int startAddress, int length) { + lock.lock(); + try { + if (isConnectionInvalid()) return null; + ReadInputRegistersRequest request = new ReadInputRegistersRequest(slaveId, startAddress, length); + ReadInputRegistersResponse response = (ReadInputRegistersResponse) modbusMaster_.send(request); + if (response.isException()) { + modbusMaster_.setConnected(false); + log.error("Error reading input registers: {}", response.getExceptionMessage()); + return null; + } + return response.getShortData(); + } catch (Exception e) { + modbusMaster_.setConnected(false); + log.error("Failed to read input registers: {}", e.getMessage()); + return null; + } finally { + lock.unlock(); + } + } + + /** + * 写单个线圈 (功能码: 5, WRITE_COIL) + */ + public boolean writeCoil(int slaveId, int address, boolean value) { + lock.lock(); + try { + if (isConnectionInvalid()) return false; + WriteCoilRequest request = new WriteCoilRequest(slaveId, address, value); + WriteCoilResponse response = (WriteCoilResponse) modbusMaster_.send(request); + if (response.isException()) { + modbusMaster_.setConnected(false); + log.error("Error writing coil: {}", response.getExceptionMessage()); + return false; + } + return true; + } catch (Exception e) { + modbusMaster_.setConnected(false); + log.error("Failed to write coil: {}", e.getMessage()); + return false; + } finally { + lock.unlock(); + } + } + + /** + * 写单个寄存器 (功能码: 6, WRITE_REGISTER) + */ + public boolean writeRegister(int slaveId, int address, int value) { + lock.lock(); + try { + if (isConnectionInvalid()) return false; + WriteRegisterRequest request = new WriteRegisterRequest(slaveId, address, value); + WriteRegisterResponse response = (WriteRegisterResponse) modbusMaster_.send(request); + if (response.isException()) { + modbusMaster_.setConnected(false); + log.error("Error writing register: {}", response.getExceptionMessage()); + return false; + } + return true; + } catch (Exception e) { + modbusMaster_.setConnected(false); + log.error("Failed to write register: {}", e.getMessage()); + return false; + } finally { + lock.unlock(); + } + } + + /** + * 写多个线圈 (功能码: 15, WRITE_COILS) + */ + public boolean writeCoils(int slaveId, int startAddress, boolean[] values) { + lock.lock(); + try { + if (isConnectionInvalid()) return false; + WriteCoilsRequest request = new WriteCoilsRequest(slaveId, startAddress, values); + WriteCoilsResponse response = (WriteCoilsResponse) modbusMaster_.send(request); + if (response.isException()) { + modbusMaster_.setConnected(false); + log.error("Error writing coils: {}", response.getExceptionMessage()); + return false; + } + return true; + } catch (Exception e) { + modbusMaster_.setConnected(false); + log.error("Failed to write coils: {}", e.getMessage()); + return false; + } finally { + lock.unlock(); + } + } + + /** + * 写多个寄存器 (功能码: 16, WRITE_REGISTERS) + */ + public boolean writeRegisters(int slaveId, int startAddress, short[] values) { + lock.lock(); + try { + if (isConnectionInvalid()) return false; + WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startAddress, values); + WriteRegistersResponse response = (WriteRegistersResponse) modbusMaster_.send(request); + if (response.isException()) { + modbusMaster_.setConnected(false); + log.error("Error writing registers: {}", response.getExceptionMessage()); + return false; + } + return true; + } catch (Exception e) { + modbusMaster_.setConnected(false); + log.error("Failed to write registers: {}", e.getMessage()); + return false; + } finally { + lock.unlock(); + } + } + + // ==== ==== ==== ==== ==== ==== 自动重连 ==== ==== ==== ==== ==== ==== + void connect() throws Exception + { + modbusMaster_.init(); + modbusMaster_.setRetries(3); +// modbusMaster_.setIoLog(new BasicLogger()); + modbusMaster_.setTimeout(2000); + modbusMaster_.setConnected(true); + } + + /** + * 自动重连 + */ + @Scheduled(fixedRate = 1000) + public void autoReconnect() { + lock.lock(); + try { + if(modbusMaster_ ==null || !modbusMaster_.isInitialized() || modbusMaster_.isConnected()) + return; + + this.connect(); + + log.info("Modbus master 重连成功 端口: {} 波特率:{}.", port, baudrate); + } catch (Exception e) { + log.error("Modbus master : {}", e.getMessage()); + log.info("Modbus master 重连失败 端口: {} 波特率:{}. {}", port, baudrate, e.getMessage()); + } finally { + lock.unlock(); + } + } +} diff --git a/src/main/java/iflytop/app/hardware/driver/FillLightDriver.java b/src/main/java/iflytop/app/hardware/driver/FillLightDriver.java new file mode 100644 index 0000000..c3c7a80 --- /dev/null +++ b/src/main/java/iflytop/app/hardware/driver/FillLightDriver.java @@ -0,0 +1,25 @@ +package iflytop.app.hardware.driver; + +import iflytop.app.hardware.channel.A8kCanBusService; +import iflytop.app.hardware.type.CmdId; +import iflytop.app.hardware.type.MId; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import static iflytop.app.hardware.type.MId.PWMLight; + +@Slf4j +@Component +@RequiredArgsConstructor +public class FillLightDriver { + private final A8kCanBusService canBus; + + public void open(Integer brightness) throws Exception { + // 模拟打开 + canBus.callcmd(PWMLight, CmdId.pwm_light_on, brightness); + } + public void close() throws Exception { + canBus.callcmd(PWMLight, CmdId.pwm_light_off); + } +} diff --git a/src/main/java/iflytop/app/hardware/driver/HeaterRodDriver.java b/src/main/java/iflytop/app/hardware/driver/HeaterRodDriver.java new file mode 100644 index 0000000..519536a --- /dev/null +++ b/src/main/java/iflytop/app/hardware/driver/HeaterRodDriver.java @@ -0,0 +1,125 @@ +package iflytop.app.hardware.driver; + +import cn.hutool.core.util.StrUtil; +import iflytop.app.hardware.channel.A8kCanBusService; +import iflytop.app.hardware.channel.modbus.ModbusMasterService; +import iflytop.app.hardware.type.A8kPacket; +import iflytop.app.hardware.type.CmdId; +import iflytop.app.hardware.type.HeaterRodSlavedId; +import iflytop.app.type.exception.HardwareException; +import io.swagger.v3.oas.models.security.SecurityScheme; +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 ModbusMasterService modbusMaster; + private final A8kCanBusService canBus; + + 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); + } + + public 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); + } +} diff --git a/src/main/java/iflytop/app/hardware/driver/InputDetectDriver.java b/src/main/java/iflytop/app/hardware/driver/InputDetectDriver.java new file mode 100644 index 0000000..da60983 --- /dev/null +++ b/src/main/java/iflytop/app/hardware/driver/InputDetectDriver.java @@ -0,0 +1,37 @@ +package iflytop.app.hardware.driver; + +import iflytop.app.hardware.channel.A8kCanBusService; +import iflytop.app.hardware.type.CmdId; +import iflytop.app.hardware.type.InputIOMId; +import iflytop.app.type.exception.HardwareException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@RequiredArgsConstructor +public class InputDetectDriver { + + private final A8kCanBusService canBus; + + public Boolean getIOState(InputIOMId ioid) throws HardwareException { + while (true) { + Boolean firstReadIO = priGetIOState(ioid); + Boolean secondReadIO = priGetIOState(ioid); + if (firstReadIO == secondReadIO) { + if (ioid.mirror) { + return !firstReadIO; + } + return firstReadIO; + } else { + log.warn("getIOState {} not match, retry", ioid); + } + } + } + + + private Boolean priGetIOState(InputIOMId ioid) throws HardwareException { + return canBus.callcmd(ioid.mid, CmdId.read_in_io, ioid.ioIndex).getContentI32(0) != 0; + } +} diff --git a/src/main/java/iflytop/app/hardware/driver/TricolorLightDriver.java b/src/main/java/iflytop/app/hardware/driver/TricolorLightDriver.java new file mode 100644 index 0000000..92643b9 --- /dev/null +++ b/src/main/java/iflytop/app/hardware/driver/TricolorLightDriver.java @@ -0,0 +1,30 @@ +package iflytop.app.hardware.driver; + + +import iflytop.app.hardware.channel.A8kCanBusService; +import iflytop.app.hardware.type.CmdId; +import iflytop.app.hardware.type.MId; +import iflytop.app.type.exception.HardwareException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@RequiredArgsConstructor +public class TricolorLightDriver { + private final A8kCanBusService canBus; + public enum Color { + RED, GREEN, BLUE + } + + public void open(MId mid, Color color) throws HardwareException { + log.info("Open TricolorLight driver Color {}", color); + canBus.callcmd(mid, CmdId.tricolor_light_on, color.ordinal()); + } + + public void close(MId mid) throws HardwareException{ + log.info("Close TricolorLight driver Color"); + canBus.callcmd(mid, CmdId.tricolor_light_off); + } +} diff --git a/src/main/java/iflytop/app/hardware/type/CmdDevice.java b/src/main/java/iflytop/app/hardware/type/CmdDevice.java new file mode 100644 index 0000000..805e4c2 --- /dev/null +++ b/src/main/java/iflytop/app/hardware/type/CmdDevice.java @@ -0,0 +1,44 @@ +package iflytop.app.hardware.type; + +public enum CmdDevice { + door_motor, + shake_motor, + tray_motor, + dual_robot, + gantry_x, + gantry_y, + gantry_z, + heater_motor_1, + heater_motor_2, + heater_motor_3, + heater_motor_4, + heater_motor_5, + heater_motor_6, + acid_pump_1, + acid_pump_2, + acid_pump_3, + acid_pump_4, + acid_pump_5, + acid_pump_6, + acid_pump_7, + acid_pump_8, + claw, + fan_1, + fan_2, + fan_3, + fan_4, + fan_5, + fan_6, + water_pump_power, + ventilator_power, + heat_rod_1, + heat_rod_2, + heat_rod_3, + heat_rod_4, + heat_rod_5, + heat_rod_6, + tricolor_light, + fill_light, + cold_trap, + photo +} diff --git a/src/main/java/iflytop/app/hardware/type/CmdId.java b/src/main/java/iflytop/app/hardware/type/CmdId.java index f291d67..a696580 100644 --- a/src/main/java/iflytop/app/hardware/type/CmdId.java +++ b/src/main/java/iflytop/app/hardware/type/CmdId.java @@ -86,15 +86,15 @@ public enum CmdId { read_out_io_index_in_stm32(0x4005, "READ_OUT_IO_INDEX_IN_STM32"), read_out_io(0x4006, "READ_OUT_IO"), - tricolor_light_on(0x110001, "TRICOLOR_LIGHT_ON"), - tricolor_light_off(0x110002, "TRICOLOR_LIGHT_OFF"), + tricolor_light_on(0x5101, "TRICOLOR_LIGHT_ON"), + tricolor_light_off(0x5102, "TRICOLOR_LIGHT_OFF"), - pwm_light_on(0x012001, "PWM_LIGHT_ON"), - pwm_light_off(0x120002, "PWM_LIGHT_OFF"), + pwm_light_on(0x5201, "PWM_LIGHT_ON"), + pwm_light_off(0x5202, "PWM_LIGHT_OFF"), - adc_enable_log(0x130001, "ADC_ENABLE_LOG"), - adc_read_adc(0x130002, "ADC_READ_ADC"), - adc_read_multi_adc(0x130003, "ADC_READ_MULTI_ADC"), + adc_enable_log(0x05301, "ADC_ENABLE_LOG"), + adc_read_adc(0x05302, "ADC_READ_ADC"), + adc_read_multi_adc(0x05303, "ADC_READ_MULTI_ADC"), ; public final static int ATTACH_IS_BYTES = 1; diff --git a/src/main/java/iflytop/app/hardware/type/HeaterRodSlavedId.java b/src/main/java/iflytop/app/hardware/type/HeaterRodSlavedId.java new file mode 100644 index 0000000..0c6aea0 --- /dev/null +++ b/src/main/java/iflytop/app/hardware/type/HeaterRodSlavedId.java @@ -0,0 +1,51 @@ +package iflytop.app.hardware.type; + + +public enum HeaterRodSlavedId { + HEATER_ROD1_ID(CmdDevice.heat_rod_1, 1, MId.IO1_ADC,0), + HEATER_ROD2_ID(CmdDevice.heat_rod_2, 2, MId.IO1_ADC,1), + HEATER_ROD3_ID(CmdDevice.heat_rod_3, 3, MId.IO1_ADC,2), + HEATER_ROD4_ID(CmdDevice.heat_rod_4, 4, MId.IO1_ADC,3), + HEATER_ROD5_ID(CmdDevice.heat_rod_5, 5, MId.IO1_ADC,4), + HEATER_ROD6_ID(CmdDevice.heat_rod_6, 6, MId.IO1_ADC,5), + ; + + private final CmdDevice cmdDevice; + private final Integer slaveId; + private final MId mid; + private final Integer adcCurrentIndex; // ADC电流索引 + + HeaterRodSlavedId(CmdDevice cmdDevice, Integer slaveId, MId mid, Integer adcCurrentIndex) { + this.cmdDevice = cmdDevice; + this.slaveId = slaveId; + this.mid = mid; + this.adcCurrentIndex = adcCurrentIndex; + } + + public CmdDevice getCmdDevice() { + return cmdDevice; + } + + public Integer getSlaveId() { + return slaveId; + } + + public MId getMid() + { + return mid; + } + + public Integer getAdcCurrentIndex() + { + return adcCurrentIndex; + } + + static public HeaterRodSlavedId getByCmdDevice(CmdDevice cmdDevice) { + for (HeaterRodSlavedId value : HeaterRodSlavedId.values()) { + if (value.cmdDevice == cmdDevice) { + return value; + } + } + return null; + } +} diff --git a/src/main/java/iflytop/app/hardware/type/InputIOMId.java b/src/main/java/iflytop/app/hardware/type/InputIOMId.java new file mode 100644 index 0000000..a29bace --- /dev/null +++ b/src/main/java/iflytop/app/hardware/type/InputIOMId.java @@ -0,0 +1,39 @@ +package iflytop.app.hardware.type; + + + +public enum InputIOMId { + Heater_CAP1_EXSIT("Heater_CAP1_EXSIT [ 加热模块拍子1到位 ]", MId.IO1_IO, 0,false), + Heater_CAP2_EXSIT("Heater_CAP2_EXSIT [ 加热模块拍子2到位 ]", MId.IO1_IO, 1,false), + Heater_CAP3_EXSIT("Heater_CAP3_EXSIT [ 加热模块拍子3到位 ]", MId.IO1_IO, 2,false), + Heater_CAP4_EXSIT("Heater_CAP4_EXSIT [ 加热模块拍子4到位 ]", MId.IO1_IO, 3,false), + Heater_CAP5_EXSIT("Heater_CAP5_EXSIT [ 加热模块拍子5到位 ]", MId.IO1_IO, 4,false), + Heater_CAP6_EXSIT("Heater_CAP6_EXSIT [ 加热模块拍子6到位 ]", MId.IO1_IO, 5,false), + Heater_TUBE1_EXSIT("Heater_TUBE1_EXSIT [ 加热模块托盘1到位 ]", MId.IO1_IO, 6,false), + Heater_TUBE2_EXSIT("Heater_TUBE2_EXSIT [ 加热模块托盘2到位 ]", MId.IO1_IO, 7,false), + Heater_TUBE3_EXSIT("Heater_TUBE3_EXSIT [ 加热模块托盘3到位 ]", MId.IO1_IO, 8,false), + Heater_TUBE4_EXSIT("Heater_TUBE4_EXSIT [ 加热模块托盘4到位 ]", MId.IO1_IO, 9,false), + Heater_TUBE5_EXSIT("Heater_TUBE5_EXSIT [ 加热模块托盘5到位 ]", MId.IO1_IO, 10,false), + Heater_TUBE6_EXSIT("Heater_TUBE6_EXSIT [ 加热模块托盘6到位 ]", MId.IO1_IO, 11,false), + TRAY_CAP1_EXSIT("TRAY_CAP1_EXSIT [ 拍子存放位拍子1到位 ]", MId.IO1_IO, 12,false), + TRAY_CAP2_EXSIT("TRAY_CAP2_EXSIT [ 拍子存放位拍子2到位 ]", MId.IO1_IO, 13,false), + TRAY_CAP3_EXSIT("TRAY_CAP3_EXSIT [ 拍子存放位拍子3到位 ]", MId.IO1_IO, 14,false), + TRAY_CAP4_EXSIT("TRAY_CAP4_EXSIT [ 拍子存放位拍子4到位 ]", MId.IO1_IO, 15,false), + TRAY_CAP5_EXSIT("TRAY_CAP5_EXSIT [ 拍子存放位拍子5到位 ]", MId.IO1_IO, 16,false), + TRAY_CAP6_EXSIT("TRAY_CAP6_EXSIT [ 拍子存放位拍子6到位 ]", MId.IO1_IO, 17,false), + E_STOP("E_STOP [ 急停 ]", MId.IO1_IO, 18,false), + ; + + final public String description; + final public MId mid; + final public int ioIndex; + final public boolean mirror; + + InputIOMId(String description, MId mid, int ioIndex, boolean mirror) { + this.description = description; + this.mid = mid; + this.ioIndex = ioIndex; + this.mirror = mirror; + + } +} diff --git a/src/main/java/iflytop/app/menu/ExtApiPageGroupCfgMgr.java b/src/main/java/iflytop/app/menu/ExtApiPageGroupCfgMgr.java index 11b4a30..ab106ea 100644 --- a/src/main/java/iflytop/app/menu/ExtApiPageGroupCfgMgr.java +++ b/src/main/java/iflytop/app/menu/ExtApiPageGroupCfgMgr.java @@ -71,7 +71,10 @@ public class ExtApiPageGroupCfgMgr { new Menu(LiquidArmPage.class, "加液臂驱动"), new Menu(LeisaiServoPage.class, "雷赛伺服电机驱动"), new Menu(OutputIOCtrlPage.class, "输出IO控制"), - new Menu(MotorParameterQuickConfigPage.class, "电机参数快速配置") + new Menu(MotorParameterQuickConfigPage.class, "电机参数快速配置"), + new Menu(HeaterRodPage.class, "加热棒控制"), + new Menu(IOBoardCtrlPage.class, "IO 板控制"), + new Menu(InputIOStateScannerPage.class, "IO 扫描板") ))); diff --git a/src/main/java/iflytop/app/page/DeviceInitPage.java b/src/main/java/iflytop/app/page/DeviceInitPage.java index be43ca8..79b274b 100644 --- a/src/main/java/iflytop/app/page/DeviceInitPage.java +++ b/src/main/java/iflytop/app/page/DeviceInitPage.java @@ -1,5 +1,6 @@ package iflytop.app.page; +import iflytop.app.hardware.channel.keyChannel; import iflytop.app.hardware.driver.ModuleEnableCtrlDriver; import iflytop.app.service.appsetup.A8kSubModuleRegInitService; import iflytop.app.type.exception.HardwareException; @@ -13,7 +14,8 @@ import org.springframework.stereotype.Component; @Component @RequiredArgsConstructor public class DeviceInitPage { - + @Resource + keyChannel keyChannel; private final ModuleEnableCtrlDriver moduleEnableCtrlDriver; private final A8kSubModuleRegInitService a8kSubModuleRegInitService; @@ -23,6 +25,10 @@ public class DeviceInitPage { return a8kSubModuleRegInitService.getIsInited(); } + public void deviceInit() throws HardwareException { + a8kSubModuleRegInitService.initDevice(); + } + public String moveAllStepMotorToZero() throws HardwareException { return "TODO::Complete"; } @@ -37,6 +43,13 @@ public class DeviceInitPage { return "已使能所有电机"; } + public void enableKeyLog(Boolean enable) + { + keyChannel.setLogEnable(enable); + } + + + @Resource ExtApiPageMgr extApiPageMgr; @@ -45,11 +58,18 @@ public class DeviceInitPage { public void init() { var page = extApiPageMgr.newPage(this); + page.newGroup("设备初始化"); + page.addFunction("设备初始化", this::deviceInit); + + page.newGroup("模块批量控制"); page.addFunction("电机归零", this::moveAllStepMotorToZero); page.addFunction("使能所有", this::enableAll); page.addFunction("失能所有", this::disableAll); + page.newGroup("日志"); + page.addFunction("急停日志", this::enableKeyLog); + extApiPageMgr.addPage(page); } } diff --git a/src/main/java/iflytop/app/page/HeaterRodPage.java b/src/main/java/iflytop/app/page/HeaterRodPage.java new file mode 100644 index 0000000..47fe76a --- /dev/null +++ b/src/main/java/iflytop/app/page/HeaterRodPage.java @@ -0,0 +1,91 @@ +package iflytop.app.page; + +import iflytop.app.hardware.driver.HeaterRodDriver; +import iflytop.app.hardware.type.HeaterRodSlavedId; +import iflytop.app.type.exception.HardwareException; +import iflytop.extui.mgr.ExtApiPageMgr; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +@RequiredArgsConstructor +public class HeaterRodPage { + @Resource + ExtApiPageMgr extApiPageMgr; + + @Resource + HeaterRodDriver heaterRodDriver; + + HeaterRodSlavedId id = HeaterRodSlavedId.HEATER_ROD1_ID; + + public void setHeaterRodId(HeaterRodSlavedId id) { + this.id = id; + } + + public Integer getDecimalPoint() throws Exception + { + return heaterRodDriver.getDecimalPoint(id.getSlaveId()); + } + + public void openPower() throws Exception + { + heaterRodDriver.openPower(id); + } + + public void closePower() throws Exception + { + heaterRodDriver.closePower(id); + } + + public void setTemperature(Double temperature) throws Exception + { + heaterRodDriver.setTemperature(id, temperature); + } + + public double getTemperature() throws Exception + { + return heaterRodDriver.getTemperature(id); + } + + public Integer getCurrent() throws HardwareException + { + return heaterRodDriver.getCurrent(id); + } + + public void open(double temperature) throws Exception { + heaterRodDriver.open(id, temperature); + } + + public void close() throws Exception { + heaterRodDriver.close(id); + } + + @PostConstruct + void init() { + var page = extApiPageMgr.newPage(this); + page.newGroup("加热棒上下文"); + page.addFunction("设置加热棒ID", this::setHeaterRodId); + + page.newGroup("加热棒独立指令"); + page.addFunction("读取加热棒温度", this::getTemperature); + page.addFunction("读取加热棒电流", this::getCurrent); + page.addFunction("获取小数点", this::getDecimalPoint); + page.addFunction("设置加热棒温度", this::setTemperature). + setParamVal("temperature", () -> 20.0); // 默认值20.0 + + + page.newGroup("加热棒复合指令"); + page.addFunction("打开加热棒", this::openPower); + page.addFunction("关闭加热棒", this::closePower); + + extApiPageMgr.addPage(page); + + + } + + +} diff --git a/src/main/java/iflytop/app/page/IOBoardCtrlPage.java b/src/main/java/iflytop/app/page/IOBoardCtrlPage.java new file mode 100644 index 0000000..4d54e57 --- /dev/null +++ b/src/main/java/iflytop/app/page/IOBoardCtrlPage.java @@ -0,0 +1,61 @@ +package iflytop.app.page; + +import iflytop.app.hardware.driver.FillLightDriver; +import iflytop.app.hardware.driver.HeaterRodDriver; +import iflytop.app.hardware.driver.TricolorLightDriver; +import iflytop.app.hardware.type.MId; +import iflytop.extui.mgr.ExtApiPageMgr; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import static iflytop.app.hardware.driver.TricolorLightDriver.Color.GREEN; + +@Component +@Slf4j +@RequiredArgsConstructor +public class IOBoardCtrlPage { + @Resource + ExtApiPageMgr extApiPageMgr; + + @Resource + FillLightDriver fillLightDriver; + + @Resource + TricolorLightDriver tricolorLightDriver; + + + public void openFillLight(Integer brightness) throws Exception { + fillLightDriver.open(brightness); + } + + public void closeFillLight() throws Exception { + fillLightDriver.close(); + } + + public void openTricolorLight(TricolorLightDriver.Color color) throws Exception { + tricolorLightDriver.open(MId.TriColorLight, color); + } + + public void closeTricolorLight() throws Exception { + tricolorLightDriver.close(MId.TriColorLight); + } + + @PostConstruct + void init() { + var page = extApiPageMgr.newPage(this); + page.newGroup("补光灯"); + page.addFunction("打开补光灯", this::openFillLight).setParamVal("brightness", () -> 50); + page.addFunction("关闭补光灯", this::closeFillLight); + + page.newGroup("三色灯"); + page.addFunction("打开三色灯", this::openTricolorLight).setParamVal("color", () -> GREEN); + page.addFunction("关闭三色灯", this::closeTricolorLight); + + extApiPageMgr.addPage(page); + + + } +} diff --git a/src/main/java/iflytop/app/page/InputIOStateScannerPage.java b/src/main/java/iflytop/app/page/InputIOStateScannerPage.java new file mode 100644 index 0000000..214149c --- /dev/null +++ b/src/main/java/iflytop/app/page/InputIOStateScannerPage.java @@ -0,0 +1,96 @@ +package iflytop.app.page; + +import iflytop.app.hardware.driver.InputDetectDriver; +import iflytop.app.hardware.type.InputIOMId; +import iflytop.app.type.exception.HardwareException; +import iflytop.extui.mgr.ExtApiPageMgr; +import iflytop.extui.type.ExtApiStatu; +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class InputIOStateScannerPage { + + + final private ExtApiPageMgr extApiPageMgr; + final private InputDetectDriver inputDetectDriver; + + @ExtApiStatu(name = "加热模块拍子1到位", order = 0) + public Boolean getTubeHeightPPS() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.Heater_CAP1_EXSIT);} + + @ExtApiStatu(name = "加热模块拍子2到位", order = 1) + public Boolean getTubeHeightPPS2() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.Heater_CAP2_EXSIT);} + + @ExtApiStatu(name = "加热模块拍子3到位", order = 2) + public Boolean getTubeHeightPPS3() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.Heater_CAP3_EXSIT);} + + @ExtApiStatu(name = "加热模块拍子4到位", order = 3) + public Boolean getTubeHeightPPS4() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.Heater_CAP4_EXSIT);} + + @ExtApiStatu(name = "加热模块拍子5到位", order = 4) + public Boolean getTubeHeightPPS5() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.Heater_CAP5_EXSIT);} + + @ExtApiStatu(name = "加热模块拍子6到位", order = 5) + public Boolean getTubeHeightPPS6() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.Heater_CAP6_EXSIT);} + + @ExtApiStatu(name = "加热模块托盘1到位", order = 6) + public Boolean getTubeHeightPPS7() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.Heater_TUBE1_EXSIT);} + + @ExtApiStatu(name = "加热模块托盘2到位", order = 7) + public Boolean getTubeHeightPPS8() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.Heater_TUBE2_EXSIT);} + + @ExtApiStatu(name = "加热模块托盘3到位", order = 8) + public Boolean getTubeHeightPPS9() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.Heater_TUBE3_EXSIT);} + + @ExtApiStatu(name = "加热模块托盘4到位", order = 9) + public Boolean getTubeHeightPPS10() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.Heater_TUBE4_EXSIT);} + + @ExtApiStatu(name = "加热模块托盘5到位", order = 10) + public Boolean getTubeHeightPPS11() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.Heater_TUBE5_EXSIT);} + + @ExtApiStatu(name = "加热模块托盘6到位", order = 11) + public Boolean getTubeHeightPPS12() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.Heater_TUBE6_EXSIT);} + + @ExtApiStatu(name = "拍子存放位拍子1到位", order = 12) + public Boolean getTubeHeightPPS13() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.TRAY_CAP1_EXSIT);} + + @ExtApiStatu(name = "拍子存放位拍子2到位", order = 13) + public Boolean getTubeHeightPPS14() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.TRAY_CAP2_EXSIT);} + + @ExtApiStatu(name = "拍子存放位拍子3到位", order = 14) + public Boolean getTubeHeightPPS15() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.TRAY_CAP3_EXSIT);} + + @ExtApiStatu(name = "拍子存放位拍子4到位", order = 15) + public Boolean getTubeHeightPPS16() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.TRAY_CAP4_EXSIT);} + + @ExtApiStatu(name = "拍子存放位拍子5到位", order = 16) + public Boolean getTubeHeightPPS17() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.TRAY_CAP5_EXSIT);} + + @ExtApiStatu(name = "拍子存放位拍子6到位", order = 17) + public Boolean getTubeHeightPPS18() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.TRAY_CAP6_EXSIT);} + + @ExtApiStatu(name = "急停", order = 18) + public Boolean getTubeHeightPPS19() throws HardwareException {return inputDetectDriver.getIOState(InputIOMId.E_STOP);} + + + public Boolean getIOState(InputIOMId iomId) throws HardwareException { + return inputDetectDriver.getIOState(iomId); + } + + + @PostConstruct + void init() { + var page = extApiPageMgr.newPage(this); + page.newGroup("IO 输入"); + page.addFunction("获取IO 状态", this::getIOState); + page.addFunction("获取IO 状态", this::getIOState); + page.addFunction("获取IO 状态", this::getIOState); + page.addFunction("获取IO 状态", this::getIOState); + page.addFunction("获取IO 状态", this::getIOState); + page.addFunction("获取IO 状态", this::getIOState); + + extApiPageMgr.addPage(page); + } +} diff --git a/src/main/java/iflytop/app/page/OutputIOCtrlPage.java b/src/main/java/iflytop/app/page/OutputIOCtrlPage.java index 8b31972..b55cc8f 100644 --- a/src/main/java/iflytop/app/page/OutputIOCtrlPage.java +++ b/src/main/java/iflytop/app/page/OutputIOCtrlPage.java @@ -30,6 +30,11 @@ public class OutputIOCtrlPage { void init() { var page = extApiPageMgr.newPage(this); page.addFunction("设置IO状态", this::setIOState); + page.addFunction("设置IO状态", this::setIOState); + page.addFunction("设置IO状态", this::setIOState); + page.addFunction("设置IO状态", this::setIOState); + page.addFunction("设置IO状态", this::setIOState); + page.addFunction("设置IO状态", this::setIOState); extApiPageMgr.addPage(page); diff --git a/src/main/java/iflytop/app/service/appsetup/A8kSubModuleRegInitService.java b/src/main/java/iflytop/app/service/appsetup/A8kSubModuleRegInitService.java index 49a8637..5fe6351 100644 --- a/src/main/java/iflytop/app/service/appsetup/A8kSubModuleRegInitService.java +++ b/src/main/java/iflytop/app/service/appsetup/A8kSubModuleRegInitService.java @@ -5,6 +5,7 @@ import iflytop.app.config.A8kSubModuleInitRegConfig; import iflytop.app.dao.type.db.SubModuleRegInitialValue; import iflytop.app.hardware.channel.A8kCanBusService; import iflytop.app.hardware.driver.ModuleEnableCtrlDriver; +import iflytop.app.hardware.type.A8kEcode; import iflytop.app.hardware.type.MId; import iflytop.app.hardware.type.ModuleType; import iflytop.app.hardware.type.RegIndex; @@ -36,6 +37,7 @@ public class A8kSubModuleRegInitService { private final A8kSubModuleInitRegConfig a8kSubModuleInitRegConfig; private final SubModuleRegInitialValueMgrService subModuleRegInitialValueMgrService; private Boolean isInited = false; + private Boolean isCanConnected = false; @PostConstruct void init() { @@ -49,10 +51,24 @@ public class A8kSubModuleRegInitService { private void onAppEvent(AppEvent event) { if (event instanceof A8kCanBusOnConnectEvent) { - var initThread = new Thread(this::initModuleRegVal); - initThread.setName("initModuleRegVal"); - initThread.start(); + +// var initThread = new Thread(this::initModuleRegVal); +// initThread.setName("initModuleRegVal"); +// initThread.start(); + isCanConnected = true; + } + } + + public void initDevice() throws HardwareException + { + if(!isCanConnected) + { + log.error("can bus not connected, please check"); + throw HardwareException.of(A8kEcode.WEBSOCKET_CONNECT_ERROR); } + var initThread = new Thread(this::initModuleRegVal); + initThread.setName("initModuleRegVal"); + initThread.start(); } private void initModuleRegVal() { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 700e558..2cf6ea2 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,7 +4,7 @@ server: device.enableCanBus: true iflytophald: - ip: 192.168.8.168 + ip: 192.168.8.188 cmdch.port: 19004 datach.port: 19005 @@ -36,3 +36,13 @@ springdoc: path: /doc/apitest.html # 自定义路径,默认为"/swagger-ui/index.html operationsSorter: method # 接口按照方法排序 +#window config +#modbus: +# port: COM18 +# baudrate: 9600 + +#工控机 config +modbus: + port: ttyS1 + baudrate: 9600 +