diff --git a/src/pom.xml b/src/pom.xml
index 5bdcb6a..a7335ef 100644
--- a/src/pom.xml
+++ b/src/pom.xml
@@ -33,6 +33,11 @@
jSerialComm
2.6.2
+
+ org.yaml
+ snakeyaml
+ 1.33
+
diff --git a/src/src/main/java/com/my/graphiteDigesterBg/MyApplicationRunner.java b/src/src/main/java/com/my/graphiteDigesterBg/MyApplicationRunner.java
index 3757f3f..c59fb13 100644
--- a/src/src/main/java/com/my/graphiteDigesterBg/MyApplicationRunner.java
+++ b/src/src/main/java/com/my/graphiteDigesterBg/MyApplicationRunner.java
@@ -5,7 +5,9 @@ import com.my.graphiteDigesterBg.diframe.DiDeviceIO;
import com.my.graphiteDigesterBg.diframe.DiDeviceIOManager;
import com.my.graphiteDigesterBg.diframe.actuator.DiActMotor;
import com.my.graphiteDigesterBg.diframe.actuator.DiActPeristalticPump;
+import com.my.graphiteDigesterBg.diframe.actuator.DiActServo;
import jakarta.annotation.Resource;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
@@ -18,6 +20,8 @@ public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
+ this.device.getRegisters().setup();
+
this.setupIO();
this.setupActuators();
}
@@ -53,7 +57,7 @@ public class MyApplicationRunner implements ApplicationRunner {
actuators.register(MyDevice.ACT_HEAT_PLATE_MOTOR, new DiActMotor(){{
mid = 11;
}});
- actuators.register(MyDevice.ACT_HEAT_SLOT_01_COVER_SERVO, new DiActMotor(){{
+ actuators.register(MyDevice.ACT_HEAT_SLOT_01_COVER_SERVO, new DiActServo(){{
mid = 12;
}});
actuators.register(MyDevice.ACT_TRANSFER_UD_MOTOR, new DiActMotor(){{
diff --git a/src/src/main/java/com/my/graphiteDigesterBg/MyDevice.java b/src/src/main/java/com/my/graphiteDigesterBg/MyDevice.java
index 8fb147c..3606055 100644
--- a/src/src/main/java/com/my/graphiteDigesterBg/MyDevice.java
+++ b/src/src/main/java/com/my/graphiteDigesterBg/MyDevice.java
@@ -15,4 +15,6 @@ public class MyDevice extends DiDevice {
public static String IO_HEAT_SLOT_01_HEATER_03 = "heatSlot01Heater03";
public static String IO_HEAT_SLOT_01_HEATER_04 = "heatSlot01Heater04";
public static String IO_AIR_COMPRESSOR = "airCompressor";
+
+ public static String RES_HEATING_TUBE_RACK_SLOT = "HeatingTubeRackSlot";
}
diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiActuator.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiActuator.java
index 1a1e421..23ae857 100644
--- a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiActuator.java
+++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiActuator.java
@@ -1,5 +1,12 @@
package com.my.graphiteDigesterBg.diframe;
public interface DiActuator {
+ static Integer MODULE_STATUS_IDLE = 0;
+ static Integer MODULE_STATUS_BUSY = 1;
+ static Integer MODULE_STATUS_ERROR = 2;
+
// set device
void setDevice( DiDevice device );
+
+ // get mid
+ Integer getMid();
}
diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiActuatorBase.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiActuatorBase.java
index 29c6e20..b85acc0 100644
--- a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiActuatorBase.java
+++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiActuatorBase.java
@@ -1,8 +1,5 @@
package com.my.graphiteDigesterBg.diframe;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Objects;
abstract public class DiActuatorBase implements DiActuator {
// message index
private static short messageIndex = 0;
@@ -21,71 +18,36 @@ abstract public class DiActuatorBase implements DiActuator {
this.call(DiCommand.MODULE_ENABLE, enable ? 1 : 0);
}
- // execute device command
- protected DiCommandResponse call( DiCommand cmd, Object... args ) {
- DiCommandRequest request = null;
- String cmdMode = this.device.getEnv().getProperty("device.connection.mode");
- if ("text".equals(cmdMode)) {
- request = this.buildCommandRequestForTextMode(cmd, args);
- } else if ("binary".equals(cmdMode) ) {
- request = this.buildCommandRequestForBinaryMode(cmd, args);
- } else {
- throw new RuntimeException("Unknown command mode: " + cmdMode);
- }
- this.device.getConnection().call(request);
- return new DiCommandResponse(request.response);
+ // active config
+ public void activeConfig() {
+ this.call(DiCommand.MODULE_ACTIVE_CFG);
}
- // build command buffer for text mode
- private DiCommandRequest buildCommandRequestForTextMode(DiCommand cmd, Object... args) {
- List parts = new ArrayList<>();
- parts.add(cmd.getName());
- parts.add(this.mid.toString());
- for ( Object arg : args ) {
- parts.add(arg.toString());
- }
- String command = String.join(" ", parts);
-
- DiCommandRequest request = new DiCommandRequest();
- request.parameter = ByteBuffer.wrap(command.getBytes());
- return request;
+ // get mid
+ public Integer getMid() {
+ return this.mid;
}
- // build command buffer for binary mode
- private DiCommandRequest buildCommandRequestForBinaryMode(DiCommand cmd, Object... args) {
- int length = 2/*PacketIndex*/ + 2/*MainCmdId*/ + 1/*SubCmdId*/ + 1/*CmdType*/ + 2/*ModuleId*/;
- for ( Object param : args ) {
- if ( param instanceof Integer ) {
- length += 4;
- } else {
- throw new RuntimeException("param type error");
+ // wait for finish
+ protected void waitForFinish() {
+ Integer status = DiActuator.MODULE_STATUS_BUSY;
+ do {
+ try {
+ DiCommandResponse response = this.call(DiCommand.MODULE_GET_STATUS);
+ status = response.readInteger(0);
+ } catch ( RuntimeException e ) {
+ continue;
}
- }
- int cmdId = cmd.getCmdId();
- int subCmdId = cmdId & 0xFF;
- int mainCmdId = (cmdId >> 8) & 0xFFFF;
- int moduleId = this.mid;
-
- DiCommandRequest request = new DiCommandRequest();
- request.id = DiActuatorBase.messageIndex;
- request.parameter = ByteBuffer.allocate(length);
- request.parameter.order(ByteOrder.LITTLE_ENDIAN);
- request.parameter.putShort(DiActuatorBase.messageIndex);
- request.parameter.putShort((short)mainCmdId); // main cmd id
- request.parameter.put((byte)subCmdId); // sub cmd id
- request.parameter.put((byte)0); // directive type
- request.parameter.putShort((short)moduleId); // mid
- for ( Object param : args ) {
- if ( param instanceof Integer ) {
- request.parameter.putInt((Integer)param);
+ try {
+ Thread.sleep(100);
+ } catch ( InterruptedException e ) {
+ continue ;
}
- }
-
- DiActuatorBase.messageIndex ++;
- if ( DiActuatorBase.messageIndex > 30000 ) {
- DiActuatorBase.messageIndex = 0;
- }
+ } while (!Objects.equals(status, DiActuator.MODULE_STATUS_IDLE));
+ }
- return request;
+ // execute device command
+ protected DiCommandResponse call( DiCommand cmd, Object... args ) {
+ return this.device.call(cmd, this.mid, args);
}
}
diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiApplicationRunner.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiApplicationRunner.java
index 5665522..7fee866 100644
--- a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiApplicationRunner.java
+++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiApplicationRunner.java
@@ -13,5 +13,6 @@ public class DiApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
this.device.getTaskManager().scanTaskClasses("com.my.graphiteDigesterBg.task");
+ this.device.getResource().scanResourceManagerClasses("com.my.graphiteDigesterBg.resource");
}
}
diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommand.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommand.java
index c70e9ce..5956030 100644
--- a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommand.java
+++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommand.java
@@ -1,7 +1,12 @@
package com.my.graphiteDigesterBg.diframe;
public enum DiCommand {
+ MODULE_ACTIVE_CFG("module_active_cfg", 0x0110),
+ MODULE_GET_STATUS("module_get_status", 0x0104),
+ MODULE_SET_REG("module_set_reg", 0x0105),
+ MODULE_GET_REG("module_get_reg", 0x0106),
MODULE_ENABLE("module_enable", 0x0114),
- MOTOR_EASY_MOVE_BY("motor_easy_move_by", 0x0212);
+ MOTOR_EASY_MOVE_BY("motor_easy_move_by", 0x0212),
+ MOTOR_EASY_MOVE_TO_ZERO("motor_easy_move_to_zero", 0x0214);
// command name
private final String name;
diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommandRequest.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommandRequest.java
index 90e3123..465ef7c 100644
--- a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommandRequest.java
+++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommandRequest.java
@@ -5,6 +5,8 @@ public class DiCommandRequest {
public short id;
// parameter
public ByteBuffer parameter;
+ // parameter text
+ public String parameterText;
// response
public ByteBuffer response;
// error code
diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommandResponse.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommandResponse.java
index fc238fb..847584c 100644
--- a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommandResponse.java
+++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommandResponse.java
@@ -1,5 +1,6 @@
package com.my.graphiteDigesterBg.diframe;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
public class DiCommandResponse {
// response
private final ByteBuffer response;
@@ -11,6 +12,7 @@ public class DiCommandResponse {
// read integer
public Integer readInteger( Integer index ) {
- return this.response.getInt(index);
+ this.response.order(ByteOrder.LITTLE_ENDIAN);
+ return this.response.getInt(8 + index);
}
}
diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDevice.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDevice.java
index c32eba4..578d4d2 100644
--- a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDevice.java
+++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDevice.java
@@ -1,34 +1,76 @@
package com.my.graphiteDigesterBg.diframe;
-import com.my.graphiteDigesterBg.diframe.connection.DiConSerialPort;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.springframework.core.env.Environment;
+import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
+import org.yaml.snakeyaml.Yaml;
+import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
@Component
public class DiDevice {
@Resource
private Environment env;
+ // config
+ private Map config;
// connection
private DiDeviceConnection connection;
// io manager
private DiDeviceIOManager io;
+ // register manager
+ private DiDeviceRegisterManager registers;
// actuator manager
private DiDeviceActuatorManager actuators;
+ // resource manager
+ private DiDeviceResourceManager resource;
// task manager
private DiTaskManager taskManager;
+ // message index
+ private short messageIndex = 0;
@PostConstruct
public void init() {
+ this.messageIndex = 0;
+
+ this.loadDeviceYml();
this.setupConnection();
this.io = new DiDeviceIOManager(this);
+ this.registers = new DiDeviceRegisterManager(this);
this.actuators = new DiDeviceActuatorManager(this);
+ this.resource = new DiDeviceResourceManager(this);
this.taskManager = new DiTaskManager(this);
}
+ // load device.yml
+ private void loadDeviceYml() {
+ InputStream input = null;
+ try {
+ ClassPathResource resource = new ClassPathResource("device.yml");
+ input = resource.getInputStream();
+ Yaml yaml = new Yaml();
+ this.config = yaml.loadAs(input, Map.class);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (input != null) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+
// setup connection
private void setupConnection() {
String connectionClassName = this.env.getProperty("device.connection.class");
@@ -79,4 +121,103 @@ public class DiDevice {
public Environment getEnv() {
return this.env;
}
+
+ // get resource manager
+ public DiDeviceResourceManager getResource() {
+ return this.resource;
+ }
+
+ // get register manager
+ public DiDeviceRegisterManager getRegisters() {
+ return this.registers;
+ }
+
+ // get config
+ public Map getConfig() {
+ return this.config;
+ }
+
+ // get config
+ public String getConfig( String path ) {
+ String[] parts = path.split("\\.");
+ Object config = this.config;
+ for ( int i=0; i)config).get(parts[i]);
+ }
+ String lastKey = parts[parts.length-1];
+ return (String)((Map)config).get(lastKey);
+ }
+
+ // execute device command
+ protected DiCommandResponse call( DiCommand cmd, Integer mid, Object... args ) {
+ DiCommandRequest request = null;
+ String cmdMode = this.getConfig("connection.mode");
+ if ("text".equals(cmdMode)) {
+ request = this.buildCommandRequestForTextMode(cmd, mid, args);
+ } else if ("binary".equals(cmdMode) ) {
+ request = this.buildCommandRequestForBinaryMode(cmd, mid, args);
+ } else {
+ throw new RuntimeException("Unknown command mode: " + cmdMode);
+ }
+ request.parameterText = this.buildCommandRequestParameterText(cmd, mid, args);
+ this.getConnection().call(request);
+ return new DiCommandResponse(request.response);
+ }
+
+ // build command request parameter text
+ private String buildCommandRequestParameterText(DiCommand cmd, Integer mid, Object... args) {
+ List parts = new ArrayList<>();
+ parts.add(cmd.getName());
+ parts.add(mid.toString());
+ for ( Object arg : args ) {
+ parts.add(arg.toString());
+ }
+ return String.join(" ", parts);
+ }
+
+ // build command buffer for text mode
+ private DiCommandRequest buildCommandRequestForTextMode(DiCommand cmd, Integer mid, Object... args) {
+ String command = this.buildCommandRequestParameterText(cmd, mid, args);
+ DiCommandRequest request = new DiCommandRequest();
+ request.parameter = ByteBuffer.wrap(command.getBytes());
+ return request;
+ }
+
+ // build command buffer for binary mode
+ private DiCommandRequest buildCommandRequestForBinaryMode(DiCommand cmd, Integer mid, Object... args) {
+ int length = 2/*PacketIndex*/ + 2/*MainCmdId*/ + 1/*SubCmdId*/ + 1/*CmdType*/ + 2/*ModuleId*/;
+ for ( Object param : args ) {
+ if ( param instanceof Integer ) {
+ length += 4;
+ } else {
+ throw new RuntimeException("param type error");
+ }
+ }
+ int cmdId = cmd.getCmdId();
+ int subCmdId = cmdId & 0xFF;
+ int mainCmdId = (cmdId >> 8) & 0xFFFF;
+ int moduleId = mid;
+
+ DiCommandRequest request = new DiCommandRequest();
+ request.id = this.messageIndex;
+ request.parameter = ByteBuffer.allocate(length);
+ request.parameter.order(ByteOrder.LITTLE_ENDIAN);
+ request.parameter.putShort(this.messageIndex);
+ request.parameter.putShort((short)mainCmdId); // main cmd id
+ request.parameter.put((byte)subCmdId); // sub cmd id
+ request.parameter.put((byte)0); // directive type
+ request.parameter.putShort((short)moduleId); // mid
+ for ( Object param : args ) {
+ if ( param instanceof Integer ) {
+ request.parameter.putInt((Integer)param);
+ }
+ }
+
+ this.messageIndex ++;
+ if ( this.messageIndex > 30000 ) {
+ this.messageIndex = 0;
+ }
+
+ return request;
+ }
}
\ No newline at end of file
diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDeviceRegister.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDeviceRegister.java
index 2c24d93..2a3f3de 100644
--- a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDeviceRegister.java
+++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDeviceRegister.java
@@ -1,2 +1,11 @@
-package com.my.graphiteDigesterBg.diframe;public class DiDeviceRegister {
+package com.my.graphiteDigesterBg.diframe;
+public class DiDeviceRegister {
+ // key
+ public String key;
+ // module id
+ public Integer mid;
+ // index
+ public Integer index;
+ // default value
+ public Integer defaultValue;
}
diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDeviceRegisterManager.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDeviceRegisterManager.java
index 9ce1b19..6d51b83 100644
--- a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDeviceRegisterManager.java
+++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDeviceRegisterManager.java
@@ -1,2 +1,52 @@
-package com.my.graphiteDigesterBg.diframe;public class DiDeviceRegisterManager {
+package com.my.graphiteDigesterBg.diframe;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+public class DiDeviceRegisterManager {
+ // device instance
+ private final DiDevice device;
+ // id => actuator
+ private final Map registers;
+
+ // constructor
+ public DiDeviceRegisterManager(DiDevice device ) {
+ this.device = device;
+ this.registers = new HashMap();
+ }
+
+ // setup
+ public void setup() {
+ Object config = this.device.getConfig().get("registers");
+ if ( config == null ) {
+ return;
+ }
+
+ if ( !(config instanceof List) ) {
+ throw new RuntimeException("Invalid registers config");
+ }
+
+ List