14 changed files with 495 additions and 2 deletions
-
BINapp.db
-
248src/main/java/com/iflytop/digester/StartResetTaskThread.java
-
31src/main/java/com/iflytop/digester/controller/DeviceController.java
-
21src/main/java/com/iflytop/digester/controller/HeatSlotController.java
-
21src/main/java/com/iflytop/digester/controller/LiquidController.java
-
19src/main/java/com/iflytop/digester/deviceinstance/Device.java
-
5src/main/java/com/iflytop/digester/deviceinstance/HeatingTurntableInstance.java
-
8src/main/java/com/iflytop/digester/deviceinstance/LiquidAdditionInstance.java
-
17src/main/java/com/iflytop/digester/underframework/controller/UfApiDictionary.java
-
18src/main/java/com/iflytop/digester/underframework/controller/UfApiRuntimeVariable.java
-
33src/main/java/com/iflytop/digester/underframework/dao/model/UfMdbDictItem.java
-
67src/main/java/com/iflytop/digester/underframework/dao/model/UfMdbRuntimeVariable.java
-
7src/main/java/com/iflytop/digester/underframework/dao/record/UfActiveRecord.java
-
2web
@ -0,0 +1,248 @@ |
|||
package com.iflytop.digester; |
|||
import com.iflytop.digester.deviceinstance.Device; |
|||
import com.iflytop.digester.underframework.dao.model.UfMdbRuntimeVariable; |
|||
public class StartResetTaskThread extends Thread { |
|||
// 是否需要放置异常处理试管架 |
|||
private Boolean isErrorTubeRackRequired = true; |
|||
|
|||
@Override |
|||
public void run() { |
|||
var device = Device.getInstance(); |
|||
device.setStatus("preparing"); |
|||
this.setProgressMessage("设备初始化..."); |
|||
|
|||
try { |
|||
Thread.sleep(5000); |
|||
} catch (InterruptedException e) { |
|||
throw new RuntimeException(e); |
|||
} |
|||
|
|||
// this.getDevice().getIO().setValue("LightRed", 1); |
|||
// |
|||
// this.setProgressMessage("设备初始化 : 关闭设备门"); |
|||
// DiActMotor doorMotor = this.getActuator(MyDevice.ACT_DOOR_MOTOR, DiActMotor.class); |
|||
// doorMotor.setEnable(true); |
|||
// MoveDoorClose.execute(this.getDevice()); |
|||
// |
|||
// this.setProgressMessage("设备初始化 : 加液臂复位"); |
|||
// DiActMotor liquidMotor = this.getActuator(MyDevice.ACT_LIQUID_MOTOR, DiActMotor.class); |
|||
// liquidMotor.setEnable(true); |
|||
// liquidMotor.reset(); |
|||
// liquidMotor.moveTo("LiquidArmStandby"); |
|||
// |
|||
// this.setProgressMessage("设备初始化 : 关闭夹爪"); |
|||
// DiActServo transferClipServo = this.getActuator(MyDevice.ACT_TRANSFER_CLIP_SERVO, DiActServo.class); |
|||
// transferClipServo.setEnable(true); |
|||
// transferClipServo.moveTo("TransClipServoClose"); |
|||
// |
|||
// this.setProgressMessage("设备初始化 : 搬运机械臂上下移动复位"); |
|||
// DiActMotor transUdMotor = this.getActuator(MyDevice.ACT_TRANSFER_UD_MOTOR, DiActMotor.class); |
|||
// transUdMotor.setEnable(true); |
|||
// transUdMotor.reset(); |
|||
// transUdMotor.moveTo("TransUdMotorStandby"); |
|||
// |
|||
// this.setProgressMessage("设备初始化 : 搬运机械臂左右移动复位"); |
|||
// DiActMotor transLrMotor = this.getActuator(MyDevice.ACT_TRANSFER_LR_MOTOR, DiActMotor.class); |
|||
// transLrMotor.setEnable(true); |
|||
// transLrMotor.reset(); |
|||
// transLrMotor.setMoveOffset("TransLrMotorGlobalOffset"); |
|||
// transLrMotor.moveTo("TransLrMotorStandby"); |
|||
// |
|||
// // @TODO : http://127.0.0.1:5566/issues/39 |
|||
// this.setProgressMessage("设备初始化 : 加液转盘复位"); |
|||
// DiActMotor liquidPlateMotor = this.getActuator(MyDevice.ACT_LIQUID_PLATE_MOTOR, DiActMotor.class); |
|||
// liquidPlateMotor.setEnable(true); |
|||
// liquidPlateMotor.reset(); |
|||
// |
|||
// // @TODO : http://127.0.0.1:5566/issues/40 |
|||
// this.setProgressMessage("设备初始化 : 加热盘转盘复位"); |
|||
// DiActMotor heatPlateMotor = this.getActuator(MyDevice.ACT_HEAT_PLATE_MOTOR, DiActMotor.class); |
|||
// heatPlateMotor.setEnable(true); |
|||
// heatPlateMotor.reset(); |
|||
// heatPlateMotor.moveTo("HeatPlateStandby"); |
|||
// |
|||
// this.setupHeatingSlotCover(); |
|||
// this.setupPeristalticPump(); |
|||
// |
|||
// this.setProgressMessage("设备初始化 : 相机"); |
|||
// DiActCameraBasler camera = this.getActuator(MyDevice.ACT_CAMERA, DiActCameraBasler.class); |
|||
// camera.setEnable(true); |
|||
// |
|||
// this.setProgressMessage("设备初始化 : 定时刷新加热盘温度"); |
|||
// var slotMan = this.getResourceManager(ResHeatingTubeRackSlotManager.class); |
|||
// slotMan.startTemperatureRefresh(); |
|||
// |
|||
// if ( this.isErrorTubeRackRequired ) { |
|||
// this.setProgressMessage("设备初始化 : 放入异常处理试管架"); |
|||
// doorMotor.reset(); // 打开设备门 |
|||
// DiMdbNotification.taskAction(this, "TaskStartResetErrorTubeRackPutIn"); |
|||
// this.waitAction("TaskStartResetErrorTubeRackPutIn"); |
|||
// } |
|||
// |
|||
// this.getDevice().getIO().setValue("LightRed", 0); |
|||
// this.getDevice().getIO().setValue("LightGreen", 1); |
|||
|
|||
this.setProgressMessage("设备初始化 : 完成"); |
|||
device.setStatus("ready"); |
|||
UfMdbRuntimeVariable.setString("设备已就绪","device.message"); |
|||
} |
|||
// |
|||
// // 设置蠕动泵 |
|||
// private void setupPeristalticPump() { |
|||
// int peristalticPumpCount = 1; |
|||
// var actuators = this.getDevice().getActuators().getAll(); |
|||
// for ( var actuator : actuators ) { |
|||
// if (actuator instanceof DiActPeristalticPump pump) { |
|||
// this.setProgressMessage("设备初始化 : 蠕动泵复位 " + peristalticPumpCount + "/16"); |
|||
// pump.setEnable(true); |
|||
// peristalticPumpCount++; |
|||
// } |
|||
// } |
|||
// |
|||
// Boolean enableSetup = this.getDevice().getEnv().getProperty("app.liquidPeristalticPumpPipeSetupEnable",Boolean.class); |
|||
// assert enableSetup != null; |
|||
// if ( !enableSetup ) { |
|||
// return ; |
|||
// } |
|||
// |
|||
// DiActMotor liquidPlateMotor = this.getActuator(MyDevice.ACT_LIQUID_PLATE_MOTOR, DiActMotor.class); |
|||
// DiActMotor liquidMotor = this.getActuator(MyDevice.ACT_LIQUID_MOTOR, DiActMotor.class); |
|||
// |
|||
// this.setProgressMessage("设备初始化 : 初始化加液管路"); |
|||
// MoveDoorOpen.execute(this.getDevice()); |
|||
// DiMdbNotification.taskAction(this, "TaskStartResetPumpPipeSetupTubeRankPutIn"); |
|||
// this.waitAction("TaskStartResetPumpPipeSetupTubeRankPutIn"); |
|||
// MoveDoorClose.execute(this.getDevice()); |
|||
// |
|||
// // 加液管充满 |
|||
// for ( int i=0; i<8; i++ ) { |
|||
// this.setProgressMessage("设备初始化 : 初始化加液管路 " + (i+1) + "/8"); |
|||
// if ( 0 == i%2 ) { |
|||
// liquidMotor.moveTo("LiquidArmPumpGroupOut"); |
|||
// liquidPlateMotor.moveTo("LiquidPlateSlotPumpOutGroup",i/2); |
|||
// } else { |
|||
// liquidMotor.moveTo("LiquidArmPumpGroupIn"); |
|||
// liquidPlateMotor.moveTo("LiquidPlateSlotPumpInGroup", i/2); |
|||
// } |
|||
// |
|||
// var pump0 = this.getActuator("LiquidPeristalticPump_"+i+"_0", DiActPeristalticPump.class); |
|||
// var pump1 = this.getActuator("LiquidPeristalticPump_"+i+"_1", DiActPeristalticPump.class); |
|||
// var pipeVolumeCircle0 = pump1.getLocationValue("LiquidPeristalticPumpPipeVolumeCircle",i, 0); |
|||
// var pipeVolumeCircle1 = pump1.getLocationValue("LiquidPeristalticPumpPipeVolumeCircle",i, 1); |
|||
// this.batchExecute(List.of( |
|||
// () -> pump0.moveBy(pipeVolumeCircle0), |
|||
// () -> pump1.moveBy(pipeVolumeCircle1) |
|||
// )); |
|||
// pump0.retract(); |
|||
// pump1.retract(); |
|||
// } |
|||
// |
|||
// liquidMotor.moveTo("LiquidArmStandby"); |
|||
// |
|||
// // 加液管充满, 需要取出试管架 |
|||
// MoveDoorOpen.execute(this.getDevice()); |
|||
// DiMdbNotification.taskAction(this, "TaskStartResetPumpPipeSetupTubeRankTakeOut"); |
|||
// this.waitAction("TaskStartResetPumpPipeSetupTubeRankTakeOut"); |
|||
// MoveDoorClose.execute(this.getDevice()); |
|||
// } |
|||
// |
|||
// /** |
|||
// * 清理试管架 |
|||
// * @issue : <a href="http://127.0.0.1:5566/issues/85">无法获取加液位置是否存在试管架</a> |
|||
// */ |
|||
// private void setupHeatingSlotCover() { |
|||
// boolean isDoorOpen = false; |
|||
// Integer errorSlotIndex = this.getDevice().getEnv().getProperty("app.errorSlotIndex",Integer.class); |
|||
// |
|||
// for ( int i=0; i<5; i++ ) { |
|||
// this.setProgressMessage("设备初始化 : 检查试管架 " + (i+1) + "/5"); |
|||
// String key = "HeatingPlateMotorSlotCover_" + i; |
|||
// DiActServo heatSlotCoverServo = this.getActuator(key, DiActServo.class); |
|||
// heatSlotCoverServo.setEnable(true); |
|||
// var currentPos = heatSlotCoverServo.getCurrentPos(); |
|||
// LOG.info("HeatingPlateMotorSlotCover #{} : current pos = {}", i, currentPos); |
|||
// |
|||
// // 如果是空的,则初始化位置后继续下一步 |
|||
// var rackExistsPos = heatSlotCoverServo.getLocationValue("HeatingPlateMotorSlotCoverRackExists"); |
|||
// if ( currentPos > rackExistsPos ) { |
|||
// heatSlotCoverServo.setCurrentPosAsMiddle(); |
|||
// continue; |
|||
// } |
|||
// |
|||
// // 如果是空试管架, 又是异常区域则不处理, 因为异常区域始终要有个试管架 |
|||
// var emptyRackExistsPos = heatSlotCoverServo.getLocationValue("HeatingPlateMotorSlotCoverEmptyRackExists"); |
|||
// if ( currentPos > emptyRackExistsPos && null != errorSlotIndex && errorSlotIndex == i ) { // 异常区域存在空试管架 |
|||
// this.isErrorTubeRackRequired = false; |
|||
// continue; |
|||
// } |
|||
// |
|||
// var moveToLiquidPlate = new MoveMoveTubeRackFromHeatPlateToLiquidPlate(); |
|||
// moveToLiquidPlate.setDevice(this.getDevice()); |
|||
// moveToLiquidPlate.slotIndex = i; |
|||
// moveToLiquidPlate.updateSlotStatus = false; |
|||
// moveToLiquidPlate.run(); |
|||
// |
|||
// if ( !isDoorOpen ) { |
|||
// MoveDoorOpen.execute(this.getDevice()); |
|||
// isDoorOpen = true; |
|||
// } |
|||
// |
|||
// heatSlotCoverServo.moveTo("HeatingPlateMotorSlotCoverEmpty"); |
|||
// heatSlotCoverServo.setEnable(false); |
|||
// |
|||
// // 等待取出试管架 |
|||
// DiMdbNotification.taskAction(this, "TaskStartResetErrorTubeRackTakeOut"); |
|||
// this.waitAction("TaskStartResetErrorTubeRackTakeOut"); |
|||
// LOG.info("HeatingPlateMotorSlotCover #{} : take out", i); |
|||
// |
|||
// heatSlotCoverServo.setEnable(true); |
|||
// heatSlotCoverServo.setCurrentPosAsMiddle(); |
|||
// } |
|||
// |
|||
// if ( isDoorOpen ) { |
|||
// MoveDoorClose.execute(this.getDevice()); |
|||
// } |
|||
// } |
|||
// |
|||
// // 异常处理位试管架取出 |
|||
// public void actionErrorTubeRackTakeOut() { |
|||
// var action = this.getAction("TaskStartResetErrorTubeRackTakeOut"); |
|||
// action.finish(); |
|||
// } |
|||
// |
|||
// // 放入异常处理位试管架 |
|||
// public void actionErrorTubeRackPutIn() { |
|||
// var slotMan = this.getResourceManager(ResHeatingTubeRackSlotManager.class); |
|||
// var slot = slotMan.getErrorSlot(); |
|||
// |
|||
// // 关闭设备门 |
|||
// DiActMotor doorMotor = this.getActuator(MyDevice.ACT_DOOR_MOTOR, DiActMotor.class); |
|||
// doorMotor.moveToIO(1, 1); |
|||
// |
|||
// var move = new MoveMoveTubeRackFromLiquidPlateToHeatPlate(); |
|||
// move.slotIndex = slot.index; |
|||
// move.setDevice(this.getDevice()); |
|||
// move.run(); |
|||
// slot.lock(); |
|||
// |
|||
// var action = this.getAction("TaskStartResetErrorTubeRackPutIn"); |
|||
// action.finish(); |
|||
// } |
|||
// |
|||
// // 蠕动泵管路初始化 |
|||
// public void actionPumpPipeSetupTubeRankPutIn() { |
|||
// var action = this.getAction("TaskStartResetPumpPipeSetupTubeRankPutIn"); |
|||
// action.finish(); |
|||
// } |
|||
// |
|||
// // 蠕动泵管路初始化 |
|||
// public void actionPumpPipeSetupTubeRankTakeOut() { |
|||
// var action = this.getAction("TaskStartResetPumpPipeSetupTubeRankTakeOut"); |
|||
// action.finish(); |
|||
// } |
|||
|
|||
// set progress message |
|||
private void setProgressMessage(String message) { |
|||
UfMdbRuntimeVariable.setString(message, "device.start.message"); |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
package com.iflytop.digester.controller; |
|||
import com.iflytop.digester.StartResetTaskThread; |
|||
import com.iflytop.digester.deviceinstance.Device; |
|||
import com.iflytop.digester.underframework.controller.UfApiControllerBase; |
|||
import com.iflytop.digester.underframework.controller.UfApiResponse; |
|||
import jakarta.annotation.Resource; |
|||
import org.springframework.stereotype.Controller; |
|||
import org.springframework.web.bind.annotation.PostMapping; |
|||
import org.springframework.web.bind.annotation.ResponseBody; |
|||
@Controller |
|||
public class DeviceController extends UfApiControllerBase { |
|||
@Resource |
|||
private Device device; |
|||
|
|||
@ResponseBody |
|||
@PostMapping("/api/device/start") |
|||
public UfApiResponse start() { |
|||
if (!"new".equals(this.device.getStatus())) { |
|||
return this.error("当前设备无法执行启动操作"); |
|||
} |
|||
var startReset = new StartResetTaskThread(); |
|||
startReset.start(); |
|||
return this.success(); |
|||
} |
|||
|
|||
@ResponseBody |
|||
@PostMapping("/api/device/status-get") |
|||
public UfApiResponse statusGet() { |
|||
return this.success(this.device.getStatus()); |
|||
} |
|||
} |
@ -0,0 +1,21 @@ |
|||
package com.iflytop.digester.controller; |
|||
import com.iflytop.digester.deviceinstance.Device; |
|||
import com.iflytop.digester.underframework.controller.UfApiControllerBase; |
|||
import com.iflytop.digester.underframework.controller.UfApiResponse; |
|||
import jakarta.annotation.Resource; |
|||
import org.springframework.stereotype.Controller; |
|||
import org.springframework.web.bind.annotation.PostMapping; |
|||
import org.springframework.web.bind.annotation.ResponseBody; |
|||
import java.util.Map; |
|||
@Controller |
|||
public class HeatSlotController extends UfApiControllerBase { |
|||
@Resource |
|||
private Device device; |
|||
|
|||
@ResponseBody |
|||
@PostMapping("/api/heat-slot/list") |
|||
public UfApiResponse list() { |
|||
var heatSlots = this.device.heatingTurntable.getSlots(); |
|||
return this.success(Map.of("slots", heatSlots)); |
|||
} |
|||
} |
@ -0,0 +1,21 @@ |
|||
package com.iflytop.digester.controller; |
|||
import com.iflytop.digester.deviceinstance.Device; |
|||
import com.iflytop.digester.underframework.controller.UfApiControllerBase; |
|||
import com.iflytop.digester.underframework.controller.UfApiResponse; |
|||
import jakarta.annotation.Resource; |
|||
import org.springframework.stereotype.Controller; |
|||
import org.springframework.web.bind.annotation.PostMapping; |
|||
import org.springframework.web.bind.annotation.ResponseBody; |
|||
import java.util.Map; |
|||
@Controller |
|||
public class LiquidController extends UfApiControllerBase { |
|||
@Resource |
|||
private Device device; |
|||
|
|||
@ResponseBody |
|||
@PostMapping("/api/liquid/list") |
|||
public UfApiResponse list() { |
|||
var liquids = this.device.liquidAddition.getLiquids(); |
|||
return this.success(Map.of("liquids", liquids)); |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
package com.iflytop.digester.underframework.controller; |
|||
import com.iflytop.digester.underframework.dao.model.UfMdbDictItem; |
|||
import org.springframework.stereotype.Controller; |
|||
import org.springframework.web.bind.annotation.PostMapping; |
|||
import org.springframework.web.bind.annotation.RequestBody; |
|||
import org.springframework.web.bind.annotation.ResponseBody; |
|||
import java.util.Map; |
|||
@Controller |
|||
public class UfApiDictionary extends UfApiControllerBase { |
|||
@ResponseBody |
|||
@PostMapping("/api/dictionary/list-by-group") |
|||
public UfApiResponse listByGroup(@RequestBody Map<String, Object> params ) { |
|||
var group = (String)params.get("group"); |
|||
var items = UfMdbDictItem.getItems(group); |
|||
return success(items); |
|||
} |
|||
} |
@ -0,0 +1,18 @@ |
|||
package com.iflytop.digester.underframework.controller; |
|||
import com.iflytop.digester.underframework.dao.model.UfMdbRuntimeVariable; |
|||
import org.springframework.stereotype.Controller; |
|||
import org.springframework.web.bind.annotation.PostMapping; |
|||
import org.springframework.web.bind.annotation.RequestBody; |
|||
import org.springframework.web.bind.annotation.ResponseBody; |
|||
import java.util.Map; |
|||
@Controller |
|||
public class UfApiRuntimeVariable extends UfApiControllerBase { |
|||
@ResponseBody |
|||
@PostMapping("/api/runtime-variable/get") |
|||
public UfApiResponse get(@RequestBody Map<String, Object> params ) { |
|||
String key = (String)params.get("key"); |
|||
var value = UfMdbRuntimeVariable.getString(key); |
|||
assert value != null; |
|||
return success(Map.of("value", value)); |
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
package com.iflytop.digester.underframework.dao.model; |
|||
import com.iflytop.digester.underframework.dao.record.UfActiveRecord; |
|||
import com.iflytop.digester.underframework.dao.record.UfActiveRecordField; |
|||
|
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
public class UfMdbDictItem extends UfActiveRecord { |
|||
@UfActiveRecordField |
|||
public String groupKey; |
|||
|
|||
@UfActiveRecordField |
|||
public String groupName; |
|||
|
|||
@UfActiveRecordField |
|||
public String itemKey; |
|||
|
|||
@UfActiveRecordField |
|||
public String itemName; |
|||
|
|||
@UfActiveRecordField |
|||
public String itemValue; |
|||
|
|||
// get table name |
|||
public static String getTableName() { |
|||
return "app_dict_items"; |
|||
} |
|||
|
|||
// get items |
|||
public static List<UfMdbDictItem> getItems(String groupKey) { |
|||
return UfActiveRecord.find(UfMdbDictItem.class, Map.of("groupKey", groupKey)); |
|||
} |
|||
} |
@ -0,0 +1,67 @@ |
|||
package com.iflytop.digester.underframework.dao.model; |
|||
import com.iflytop.digester.underframework.dao.record.UfActiveRecord; |
|||
import com.iflytop.digester.underframework.dao.record.UfActiveRecordField; |
|||
import java.util.Map; |
|||
public class UfMdbRuntimeVariable extends UfActiveRecord { |
|||
@UfActiveRecordField |
|||
public String key; |
|||
|
|||
@UfActiveRecordField |
|||
public String value; |
|||
|
|||
// get table name |
|||
public static String getTableName() { |
|||
return "app_runtime_variables"; |
|||
} |
|||
|
|||
// build key |
|||
private static String buildKey(String key, Object ... args) { |
|||
StringBuilder keyBuilder = new StringBuilder(key); |
|||
for (Object arg : args) { |
|||
keyBuilder.append(".").append(arg.toString()); |
|||
} |
|||
return keyBuilder.toString(); |
|||
} |
|||
|
|||
// get location value |
|||
public static UfMdbRuntimeVariable getVariable(String key, Object ... args ) { |
|||
key = UfMdbRuntimeVariable.buildKey(key, args); |
|||
return UfActiveRecord.findOne(UfMdbRuntimeVariable.class, Map.of("key", key)); |
|||
} |
|||
|
|||
// get string |
|||
public static String getString(String name, Object ... args ) { |
|||
var variable = UfMdbRuntimeVariable.getVariable(name, args); |
|||
return null == variable ? null : variable.value; |
|||
} |
|||
|
|||
// get integer |
|||
public static Integer getInteger(String name, Object ... args ) { |
|||
var variable = UfMdbRuntimeVariable.getVariable(name, args); |
|||
return null == variable ? null : Integer.parseInt(variable.value); |
|||
} |
|||
|
|||
// set string |
|||
public static void setString(String value, String name, Object ... args ) { |
|||
var variable = UfMdbRuntimeVariable.getVariable(name, args); |
|||
if ( null == variable ) { |
|||
variable = new UfMdbRuntimeVariable(); |
|||
variable.key = UfMdbRuntimeVariable.buildKey(name, args); |
|||
} |
|||
variable.value = value; |
|||
variable.save(); |
|||
} |
|||
|
|||
// set integer |
|||
public static void setInteger(Integer value, String name, Object ... args ) { |
|||
UfMdbRuntimeVariable.setString(value.toString(), name, args); |
|||
} |
|||
|
|||
// remove |
|||
public static void remove(String name, Object ... args ) { |
|||
var variable = UfMdbRuntimeVariable.getVariable(name); |
|||
if ( null != variable ) { |
|||
variable.delete(); |
|||
} |
|||
} |
|||
} |
@ -1 +1 @@ |
|||
Subproject commit 1281f43be8a5de2f98d83c2a32506bb878eb5495 |
|||
Subproject commit 7f4d0b8bfe683b41e75233368ed1ec1e98c8c350 |
Write
Preview
Loading…
Cancel
Save
Reference in new issue