Browse Source

feat:定义指令生成器

tags/freeze
白凤吉 3 months ago
parent
commit
2f7c2c4ff8
  1. 10
      src/main/java/com/iflytop/gd/app/core/BaseCommandHandler.java
  2. 11
      src/main/java/com/iflytop/gd/app/service/cmd/DemoCommand.java
  3. 55
      src/main/java/com/iflytop/gd/common/device/CommandFuture.java
  4. 39
      src/main/java/com/iflytop/gd/common/device/CyclicNumberGenerator.java
  5. 38
      src/main/java/com/iflytop/gd/common/device/DeviceCommand.java
  6. 501
      src/main/java/com/iflytop/gd/common/device/DeviceCommandGenerator.java
  7. 1
      src/main/java/com/iflytop/gd/infrastructure/modules/area/LiquidArea.java
  8. 1
      src/main/java/com/iflytop/gd/infrastructure/modules/area/RailArmArea.java
  9. 27
      src/main/java/com/iflytop/gd/infrastructure/repository/DeviceFactory.java
  10. 28
      src/main/java/com/iflytop/gd/infrastructure/repository/DeviceStrategyFactory.java

10
src/main/java/com/iflytop/gd/app/core/BaseCommandHandler.java

@ -4,9 +4,12 @@ package com.iflytop.gd.app.core;
import com.iflytop.gd.common.annotation.CheckedRunnable;
import com.iflytop.gd.common.cmd.CommandHandler;
import com.iflytop.gd.common.device.CommandFuture;
import com.iflytop.gd.common.utils.LambdaUtil;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public abstract class BaseCommandHandler implements CommandHandler {
@ -14,4 +17,11 @@ public abstract class BaseCommandHandler implements CommandHandler {
return CompletableFuture.runAsync(LambdaUtil.unchecked(task));
}
protected void commandWait(CommandFuture... futures) throws Exception {
CompletableFuture<?>[] responseFutures = Arrays.stream(futures)
.map(CommandFuture::getResponseFuture)
.toArray(CompletableFuture[]::new);
CompletableFuture.allOf(responseFutures)
.get(120, TimeUnit.SECONDS);
}
}

11
src/main/java/com/iflytop/gd/app/service/cmd/DemoCommand.java

@ -1,8 +1,12 @@
package com.iflytop.gd.app.service.cmd;
import com.iflytop.gd.app.core.BaseCommandHandler;
import com.iflytop.gd.app.model.dto.CmdDTO;
import com.iflytop.gd.common.annotation.CommandMapping;
import com.iflytop.gd.common.cmd.CommandHandler;
import com.iflytop.gd.common.device.CommandFuture;
import com.iflytop.gd.common.device.DeviceCommand;
import com.iflytop.gd.common.device.DeviceCommandGenerator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@ -12,10 +16,15 @@ import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
@CommandMapping("demo_command")//业务指令注解
public class DemoCommand implements CommandHandler {
public class DemoCommand extends BaseCommandHandler {
@Override
public void handle(CmdDTO cmdDTO) {
log.info("cmdDTO:{}", cmdDTO);
//XYZ回原点
DeviceCommand motorXOriginCommand = DeviceCommandGenerator.motorXOrigin();
DeviceCommand motorYOriginCommand = DeviceCommandGenerator.motorYOrigin();
DeviceCommand motorZOriginCommand = DeviceCommandGenerator.motorZOrigin();
}
}

55
src/main/java/com/iflytop/gd/common/device/CommandFuture.java

@ -0,0 +1,55 @@
package com.iflytop.gd.common.device;
import cn.hutool.json.JSONObject;
import lombok.Getter;
import lombok.Setter;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@Setter
@Getter
public class CommandFuture {
/**
* 用于保存response反馈
*/
private CompletableFuture<JSONObject> responseFuture = new CompletableFuture<>();
private long startSendTime;
private long endSendTime;
/**
* 业务指令id
*/
private String cmdId;
/**
* 业务指令code
*/
private String cmdCode;
/**
* 设备指令
*/
private DeviceCommand deviceCommand;
/**
* 完成response
*/
public void completeResponse(JSONObject result) {
responseFuture.complete(result);
}
/**
* 异常完成response
*/
public void completeResponseExceptionally(Throwable ex) {
responseFuture.completeExceptionally(ex);
}
/**
* 获取response的json
*/
public JSONObject getResponseResult() throws ExecutionException, InterruptedException {
return responseFuture.get();
}
}

39
src/main/java/com/iflytop/gd/common/device/CyclicNumberGenerator.java

@ -0,0 +1,39 @@
package com.iflytop.gd.common.device;
public class CyclicNumberGenerator {
// 饿汉式单例在类加载时就创建实例
private static final CyclicNumberGenerator INSTANCE = new CyclicNumberGenerator();
// 当前生成的数字初始值为 1
private int currentNumber = 1;
// 私有构造函数防止外部实例化
private CyclicNumberGenerator() {
}
// 提供全局访问点获取单例实例
public static CyclicNumberGenerator getInstance() {
return INSTANCE;
}
public static void main(String[] args) {
CyclicNumberGenerator generator = CyclicNumberGenerator.getInstance();
for (int i = 0; i < 4096; i++) {
System.out.println(generator.generateNumber());
}
}
/**
* 生成 1 255 之间的循环整数
*
* @return 生成的整数
*/
public synchronized int generateNumber() {
int result = currentNumber;
// 每次生成后将当前数字加 1
currentNumber++;
if (currentNumber > 4096) {
currentNumber = 1;
}
return result;
}
}

38
src/main/java/com/iflytop/gd/common/device/DeviceCommand.java

@ -0,0 +1,38 @@
package com.iflytop.gd.common.device;
import lombok.Data;
import java.util.Map;
@Data
public class DeviceCommand {
/**
* 指令ID
*/
private Integer cmdId;
/**
* 指令名称
*/
private String cmdName;
/**
* 指令代码 例如 "device_status_get"
*/
private String cmdCode;
/**
* 目标设备
*/
private String device;
/**
* 执行动作
*/
private String action;
/**
* 指令参数
*/
private Map<String, Object> param;
}

501
src/main/java/com/iflytop/gd/common/device/DeviceCommandGenerator.java

@ -0,0 +1,501 @@
package com.iflytop.gd.common.device;
import java.util.HashMap;
import java.util.Map;
/**
* 生成给设备发送的指令
*/
public class DeviceCommandGenerator {
/**
* 全部关闭三通阀
*/
public static DeviceCommand threeWayValveCloseAll() {
// 上层方法直接取方法注释全部关闭三通阀
return threeWayValveControl("close_all", "全部关闭三通阀");
}
/**
* 打开三通阀喷嘴管路
*/
public static DeviceCommand threeWayValveOpenSyringePipeline() {
return threeWayValveControl("open_syringe", "打开三通阀喷嘴管路");
}
/**
* 打开三通阀注射器管路
*/
public static DeviceCommand threeWayValveOpenNozzlePipeline() {
return threeWayValveControl("open_nozzle", "打开三通阀注射器管路");
}
/**
* 控制三通阀
*/
public static DeviceCommand threeWayValveControl(String action, String commandName) {
// 调用中层 controlCmd 直接用方法注释固定描述"控制三通阀"
return controlCmd("three_way_valve", action, null, commandName != null ? commandName : "控制三通阀");
}
/**
* 关闭清洗阀
*/
public static DeviceCommand washValveClose() {
return washValveControl("close", "关闭清洗阀");
}
/**
* 开启清洗阀
*/
public static DeviceCommand washValveOpen() {
return washValveControl("open", "开启清洗阀");
}
/**
* 控制清洗阀
*/
public static DeviceCommand washValveControl(String action, String commandName) {
return controlCmd("wash_valve", action, null, commandName != null ? commandName : "控制清洗阀");
}
/**
* 关闭喷嘴阀
*/
public static DeviceCommand nozzleValveClose() {
return nozzleValveControl("close", "关闭喷嘴阀");
}
/**
* 开启喷嘴阀
*/
public static DeviceCommand nozzleValveOpen() {
return nozzleValveControl("open", "开启喷嘴阀");
}
/**
* 控制喷嘴阀
*/
public static DeviceCommand nozzleValveControl(String action, String commandName) {
return controlCmd("nozzle_valve", action, null, commandName != null ? commandName : "控制喷嘴阀");
}
/**
* 关闭除湿阀
*/
public static DeviceCommand dehumidifierValveClose() {
return dehumidifierValveControl("close", "关闭除湿阀");
}
/**
* 开启除湿阀
*/
public static DeviceCommand dehumidifierValveOpen() {
return dehumidifierValveControl("open", "开启除湿阀");
}
/**
* 控制除湿阀
*/
public static DeviceCommand dehumidifierValveControl(String action, String commandName) {
return controlCmd("dehumidifier_valve", action, null, commandName != null ? commandName : "控制除湿阀");
}
/**
* 关闭照明灯板
*/
public static DeviceCommand lightingPanelClose() {
return controlCmd("lighting_panel", "close", null, "关闭照明灯板");
}
/**
* 打开照明灯板
*/
public static DeviceCommand lightingPanelOpen() {
return controlCmd("lighting_panel", "open", null, "打开照明灯板");
}
/**
* 控制照明灯板
*/
public static DeviceCommand lightingPanelControl(String action, String commandName) {
return controlCmd("lighting_panel", action, null, commandName != null ? commandName : "控制照明灯板");
}
/**
* 关闭激光
*/
public static DeviceCommand laserControlClose() {
return laserControl("close", null);
}
/**
* 打开激光
*
* @param power 功率[0-100]
*/
public static DeviceCommand laserControlOpen(Double power) {
return laserControl("open", power);
}
/**
* 控制激光
*
* @param power 功率[0-100]
*/
public static DeviceCommand laserControl(String action, Double power) {
Map<String, Object> params = new HashMap<>();
params.put("power", power);
return controlCmd("laser", action, params, "控制激光");
}
/**
* 关闭高压
*/
public static DeviceCommand highVoltageClose() {
return highVoltageControl("close", null);
}
/**
* 开启高压
*/
public static DeviceCommand highVoltageOpen(Double voltage) {
return highVoltageControl("open", voltage);
}
/**
* 控制高压
*/
public static DeviceCommand highVoltageControl(String action, Double voltage) {
Map<String, Object> params = new HashMap<>();
params.put("voltage", voltage);
return controlCmd("high_voltage", action, params, "控制高压");
}
/**
* 停止推动注射泵
*/
public static DeviceCommand syringePumpStop() {
return controlCmd("syringe_pump", "stop", null, "停止推动注射泵");
}
/**
* 推动移动注射泵
*
* @param speed 是指注射泵每分钟注射多少微升(volume 最低0.1)
*/
public static DeviceCommand syringePumpStart(String direction, Double speed) {
Map<String, Object> params = new HashMap<>();
params.put("direction", direction);
params.put("speed", speed);
return controlCmd("syringe_pump", "move", params, "推动移动注射泵");
}
/**
* 推动移动注射泵
*
* @param speed 是指注射泵每分钟注射多少微升(volume 最低0.1)
*/
public static DeviceCommand syringePumpForward(Double speed) {
Map<String, Object> params = new HashMap<>();
params.put("direction", "forward");
params.put("speed", speed);
return controlCmd("syringe_pump", "move", params, "推动移动注射泵");
}
/**
* 注射泵流速设置
*/
public static DeviceCommand syringePumpVolumeSet(Double speed) {
Map<String, Object> params = new HashMap<>();
params.put("speed", speed);
return controlCmd("syringe_pump", "set", params, "注射泵流速设置");
}
/**
* 控制注射泵
*/
public static DeviceCommand syringePumpControl(String action, String forward, Double volume) {
Map<String, Object> params = new HashMap<>();
params.put("current", forward);
params.put("volume", volume);
return controlCmd("syringe_pump", action, params, "控制注射泵");
}
/**
* 获取设备当前湿度
*/
public static DeviceCommand humidityGet() {
return getInfoCmd("humidity", "获取设备当前湿度");
}
/**
* 获取设备当前温度
*/
public static DeviceCommand temperatureGet() {
return getInfoCmd("temperature", "获取设备当前温度");
}
/**
* 推入玻片托盘
*/
public static DeviceCommand slideTrayIn(Double position, Double speed) {
return motorYPositionSet(position, speed, "推入玻片托盘");
}
/**
* 推出玻片托盘
*/
public static DeviceCommand slideTrayOut(Double position, Double speed) {
return motorYPositionSet(position, speed, "推出玻片托盘");
}
/**
* 获得电机XYZ相对原点坐标
*/
public static DeviceCommand motorXyzPositionGet() {
return getInfoCmd("xyz", "获得电机XYZ相对原点坐标");
}
/**
* x轴停止移动
*/
public static DeviceCommand motorXStop() {
return controlMotorCmd("x", "stop", null, null, null, null, "x轴停止移动");
}
/**
* y轴停止移动
*/
public static DeviceCommand motorYStop() {
return controlMotorCmd("y", "stop", null, null, null, null, "y轴停止移动");
}
/**
* z轴停止移动
*/
public static DeviceCommand motorZStop() {
return controlMotorCmd("z", "stop", null, null, null, null, "z轴停止移动");
}
/**
* x轴回原点
*/
public static DeviceCommand motorXOrigin() {
return controlMotorCmd("x", "origin", null, null, null, null, "x轴回原点");
}
/**
* y轴回原点
*/
public static DeviceCommand motorYOrigin() {
return controlMotorCmd("y", "origin", null, null, null, null, "y轴回原点");
}
/**
* z轴回原点
*/
public static DeviceCommand motorZOrigin() {
return controlMotorCmd("z", "origin", null, null, null, null, "z轴回原点");
}
/**
* 移动x轴到指定位置
*/
public static DeviceCommand motorXPositionSet(Double position) {
return motorXPositionSet(position, null, "移动x轴到指定位置");
}
/**
* 移动y轴到指定位置
*/
public static DeviceCommand motorYPositionSet(Double position) {
return motorYPositionSet(position, null, "移动y轴到指定位置");
}
/**
* 移动z轴到指定位置
*/
public static DeviceCommand motorZPositionSet(Double position) {
return motorZPositionSet(position, null, "移动z轴到指定位置");
}
/**
* 移动x轴到指定位置
*/
public static DeviceCommand motorXPositionSet(Double position, Double speed) {
return motorXPositionSet(position, speed, "移动x轴到指定位置");
}
/**
* 移动y轴到指定位置
*/
public static DeviceCommand motorYPositionSet(Double position, Double speed) {
return motorYPositionSet(position, speed, "移动y轴到指定位置");
}
/**
* 移动z轴到指定位置
*/
public static DeviceCommand motorZPositionSet(Double position, Double speed) {
return motorZPositionSet(position, speed, "移动z轴到指定位置");
}
/**
* 移动x轴到指定位置
*/
private static DeviceCommand motorXPositionSet(Double position, Double speed, String commandName) {
return controlMotorCmd("x", "move", null, "forward", position, speed, commandName);
}
/**
* 移动y轴到指定位置
*/
private static DeviceCommand motorYPositionSet(Double position, Double speed, String commandName) {
return controlMotorCmd("y", "move", null, "forward", position, speed, commandName);
}
/**
* 移动z轴到指定位置
*/
private static DeviceCommand motorZPositionSet(Double position, Double speed, String commandName) {
return controlMotorCmd("z", "move", null, "forward", position, speed, commandName);
}
/**
* x电机方向设置
*/
public static DeviceCommand motorXDirectionSet(String direction) {
return controlMotorCmd("x", "set", null, direction, null, null, "x电机方向设置");
}
/**
* y电机方向设置
*/
public static DeviceCommand motorYDirectionSet(String direction) {
return controlMotorCmd("y", "set", null, direction, null, null, "y电机方向设置");
}
/**
* z电机方向设置
*/
public static DeviceCommand motorZDirectionSet(String direction) {
return controlMotorCmd("z", "set", null, direction, null, null, "z电机方向设置");
}
/**
* x轴电机电流设置
*/
public static DeviceCommand motorXCurrentSet(Double current) {
return controlMotorCmd("x", "set", current, null, null, null, "x轴电机电流设置");
}
/**
* y轴电机电流设置
*/
public static DeviceCommand motorYCurrentSet(Double current) {
return controlMotorCmd("y", "set", current, null, null, null, "y轴电机电流设置");
}
/**
* z轴电机电流设置
*/
public static DeviceCommand motorZCurrentSet(Double current) {
return controlMotorCmd("z", "set", current, null, null, null, "z轴电机电流设置");
}
/**
* x轴电机速度设置
*/
public static DeviceCommand motorXSpeedSet(Double speed) {
return controlMotorCmd("x", "set", null, null, null, speed, "x轴电机速度设置");
}
/**
* y轴电机速度设置
*/
public static DeviceCommand motorYSpeedSet(Double speed) {
return controlMotorCmd("y", "set", null, null, null, speed, "y轴电机速度设置");
}
/**
* z轴电机速度设置
*/
public static DeviceCommand motorZSpeedSet(Double speed) {
return controlMotorCmd("z", "set", null, null, null, speed, "z轴电机速度设置");
}
/**
* x轴电机控制
*/
public static DeviceCommand motorX(String action, Double current, String direction, Double position, Double speed) {
return controlMotorCmd("x", action, current, direction, position, speed, "x轴电机控制");
}
/**
* y轴电机控制
*/
public static DeviceCommand motorY(String action, Double current, String direction, Double position, Double speed) {
return controlMotorCmd("y", action, current, direction, position, speed, "y轴电机控制");
}
/**
* z轴电机控制
*/
public static DeviceCommand motorZ(String action, Double current, String direction, Double position, Double speed) {
return controlMotorCmd("z", action, current, direction, position, speed, "z轴电机控制");
}
/**
* 控制设备电机
*/
public static DeviceCommand controlMotorCmd(String device, String action, Double current, String direction, Double position, Double speed, String commandName) {
if (commandName == null) {
commandName = "控制设备电机";
}
Map<String, Object> params = new HashMap<>();
params.put("current", current);
params.put("direction", direction);
params.put("position", position);
params.put("speed", speed);
return deviceCmd("controlMotorCmd", device, action, params, commandName);
}
/**
* 获取设备整体状态
*/
public static DeviceCommand overallDeviceStatusGet() {
return getInfoCmd("device", "获取设备整体状态");
}
/**
* 设备控制指令包装
*/
private static DeviceCommand controlCmd(String device, String action, Map<String, Object> params, String commandName) {
return deviceCmd("controlCmd", device, action, params, commandName);
}
/**
* 获取设备信息指令包装
*/
private static DeviceCommand getInfoCmd(String device, String commandName) {
return deviceCmd("getInfoCmd", device, "get", null, commandName);
}
/**
* 设备指令包装
*/
private static DeviceCommand deviceCmd(String code, String device, String action, Map<String, Object> params, String commandName) {
// int cmdId = CyclicNumberGenerator.getInstance().generateNumber();
DeviceCommand cmdToDevice = new DeviceCommand();
// cmdToDevice.setCmdId(cmdId);
cmdToDevice.setCmdCode(code);
cmdToDevice.setDevice(device);
cmdToDevice.setAction(action);
cmdToDevice.setParam(params);
cmdToDevice.setCmdName(commandName);
return cmdToDevice;
}
}

1
src/main/java/com/iflytop/gd/infrastructure/modules/area/LiquidArea.java

@ -7,4 +7,5 @@ import org.springframework.stereotype.Component;
*/
@Component
public class LiquidArea {
}

1
src/main/java/com/iflytop/gd/infrastructure/modules/area/RailArmArea.java

@ -7,4 +7,5 @@ import org.springframework.stereotype.Component;
*/
@Component
public class RailArmArea {
}

27
src/main/java/com/iflytop/gd/infrastructure/repository/DeviceFactory.java

@ -1,27 +0,0 @@
package com.iflytop.gd.infrastructure.repository;
import com.iflytop.gd.infrastructure.devices.physical.PhysicalStepMotor;
import com.iflytop.gd.infrastructure.devices.virtual.VirtualStepMotor;
import com.iflytop.gd.infrastructure.drivers.ModuleId;
import com.iflytop.gd.system.devices.StepMotor;
import com.iflytop.gd.system.drivers.CommandBus;
import com.iflytop.gd.system.constants.SystemMode;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
@RequiredArgsConstructor
@Component
public class DeviceFactory {
private final CommandBus commandBus;
public StepMotor createStepMotor(SystemMode systemMode, ModuleId moduleId) {
if (SystemMode.VIRTUAL.equals(systemMode)) {
return new VirtualStepMotor(moduleId);
}
if (SystemMode.PHYSICAL.equals(systemMode)) {
return new PhysicalStepMotor(moduleId, commandBus);
}
throw new IllegalArgumentException("Unsupported system mode: " + systemMode);
}
}

28
src/main/java/com/iflytop/gd/infrastructure/repository/DeviceStrategyFactory.java

@ -0,0 +1,28 @@
package com.iflytop.gd.infrastructure.repository;
import com.iflytop.gd.system.drivers.CommandBus;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@RequiredArgsConstructor
public class DeviceStrategyFactory {
private final ApplicationContext ctx;
private final CommandBus commandBus;
/**
* @param type 接口 Class 对象 ColdTray.class
* @param beanName @Component 中定义的名称 "coldTrayA"
*/
public <T> T getStrategy(Class<T> type, String beanName) {
Map<String, T> beans = ctx.getBeansOfType(type);
T strategy = beans.get(beanName);
if (strategy == null) {
throw new IllegalArgumentException("No bean named '" + beanName + "' for type " + type.getSimpleName());
}
return strategy;
}
}
Loading…
Cancel
Save