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
+