Browse Source

耗材不足时通知前台

master
sige 2 years ago
parent
commit
5a9c1bdb15
  1. 15
      src/main/java/com/dreamworks/boditech/controller/DeviceController.java
  2. 7
      src/main/java/com/dreamworks/boditech/driver/consumable/CsmBufferTubeManager.java
  3. 58
      src/main/java/com/dreamworks/boditech/driver/consumable/CsmLargeBufferTubeManager.java
  4. 32
      src/main/java/com/dreamworks/boditech/driver/task/Executor.java
  5. 8
      src/main/java/com/dreamworks/boditech/driver/task/TaskLoad.java
  6. 11
      src/main/java/com/dreamworks/boditech/driver/task/TaskStartReset.java
  7. 43
      src/main/java/com/dreamworks/boditech/driver/task/TaskTestBase.java
  8. 2
      src/main/java/com/dreamworks/boditech/driver/task/step/Step.java
  9. 7
      src/main/java/com/dreamworks/boditech/driver/task/step/StepBase.java
  10. 18
      src/main/java/com/dreamworks/boditech/driver/task/step/StepPretreatment.java
  11. 13
      src/main/java/com/dreamworks/boditech/driver/task/step/StepPuncture.java
  12. 33
      src/main/java/com/dreamworks/boditech/driver/task/step/StepSampling.java
  13. 24
      src/main/java/com/dreamworks/boditech/service/WebsocketServerService.java
  14. 5
      src/main/java/com/dreamworks/boditech/utils/AppError.java

15
src/main/java/com/dreamworks/boditech/controller/DeviceController.java

@ -167,7 +167,20 @@ public class DeviceController extends BaseController {
status = executor.getWorkingStatus(); status = executor.getWorkingStatus();
statusName = I18n.t("device.status." + status); statusName = I18n.t("device.status." + status);
} }
return this.success(Map.of("status", status, "statusName", statusName));
return this.success(Map.of(
"status", status,
"statusName", statusName
));
}
@ResponseBody
@PostMapping("/api/device/executor-status-get")
public ApiResponse executorStatusGet() {
Executor executor = this.deviceService.getTaskExecutor();
if ( null == executor ) {
return this.success(Map.of("status", 0));
}
return this.success(Map.of("status",executor.getStatus()));
} }
@ResponseBody @ResponseBody

7
src/main/java/com/dreamworks/boditech/driver/consumable/CsmBufferTubeManager.java

@ -2,6 +2,9 @@ package com.dreamworks.boditech.driver.consumable;
import com.dreamworks.boditech.driver.Device; import com.dreamworks.boditech.driver.Device;
import com.dreamworks.boditech.driver.entity.ParamBufferTubeUpdateByBox; import com.dreamworks.boditech.driver.entity.ParamBufferTubeUpdateByBox;
import com.dreamworks.boditech.entity.Project; import com.dreamworks.boditech.entity.Project;
import com.dreamworks.boditech.utils.AppError;
import com.dreamworks.boditech.utils.AppRuntimeException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -82,7 +85,7 @@ public class CsmBufferTubeManager {
// tube alloc by project name // tube alloc by project name
public CsmBufferTube tubeAllocByProject(Project project) { public CsmBufferTube tubeAllocByProject(Project project) {
for ( CsmBufferTubeBox box : this.bufferTubeBoxes ) { for ( CsmBufferTubeBox box : this.bufferTubeBoxes ) {
if ( !box.isProjectMatched(project) ) {
if ( 0 >= box.tubeAmount || !box.isProjectMatched(project) ) {
continue; continue;
} }
box.tubeAmount --; box.tubeAmount --;
@ -92,7 +95,7 @@ public class CsmBufferTubeManager {
tube.index = box.tubeAmount; tube.index = box.tubeAmount;
return tube; return tube;
} }
throw new RuntimeException("no buffer tube available for project " + project.name);
throw new AppRuntimeException(AppError.TASK_BUFFER_TUBE_ALLOC_FAILED);
} }
// get device // get device

58
src/main/java/com/dreamworks/boditech/driver/consumable/CsmLargeBufferTubeManager.java

@ -3,6 +3,9 @@ import com.dreamworks.boditech.driver.Device;
import com.dreamworks.boditech.driver.entity.ParamBufferTubeUpdateByBox; import com.dreamworks.boditech.driver.entity.ParamBufferTubeUpdateByBox;
import com.dreamworks.boditech.driver.entity.ParamLargeBufferTubeUpdate; import com.dreamworks.boditech.driver.entity.ParamLargeBufferTubeUpdate;
import com.dreamworks.boditech.entity.Project; import com.dreamworks.boditech.entity.Project;
import com.dreamworks.boditech.utils.AppError;
import com.dreamworks.boditech.utils.AppRuntimeException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -39,6 +42,7 @@ public class CsmLargeBufferTubeManager {
for ( int i=0; i<6; i++ ) { for ( int i=0; i<6; i++ ) {
CsmLargeBufferTube tube = new CsmLargeBufferTube(this); CsmLargeBufferTube tube = new CsmLargeBufferTube(this);
tube.index = i; tube.index = i;
tube.amount = 0;
this.largeBufferTubes.add(tube); this.largeBufferTubes.add(tube);
} }
} }
@ -91,54 +95,14 @@ public class CsmLargeBufferTubeManager {
tube.amount = param.tubeAmount; tube.amount = param.tubeAmount;
} }
// get large buffer tube
public CsmLargeBufferTube getTubeByProjectName( String projectName ) {
CsmLargeBufferTube tube = null;
for ( CsmLargeBufferTube tmp : this.largeBufferTubes ) {
// if ( !tmp.projectName.equals(projectName) ) {
// continue ;
// }
if ( tmp.isEmpty() ) {
continue;
// large buffer tube update
public CsmLargeBufferTube allocByProject( Project project ) {
for ( CsmLargeBufferTube tube : this.largeBufferTubes ) {
if ( 0 >= tube.amount || !tube.isProjectMatched(project) ) {
continue ;
} }
tube = tmp;
break;
}
if ( null == tube ) {
throw new RuntimeException("no large buffer tube");
return tube;
} }
return tube;
throw new AppRuntimeException(AppError.TASK_LARGE_BUFFER_TUBE_ALLOC_FAILED);
} }
} }

32
src/main/java/com/dreamworks/boditech/driver/task/Executor.java

@ -31,6 +31,8 @@ public class Executor implements Runnable {
public String workingStatus = "WAIT_FOR_TUBE_RACK"; public String workingStatus = "WAIT_FOR_TUBE_RACK";
// incubator wait task // incubator wait task
private Task incubatorWaitTask = null; private Task incubatorWaitTask = null;
// resource wait task
private Task resourceWaitTask = null;
/** /**
* execute single task on device * execute single task on device
@ -55,6 +57,8 @@ public class Executor implements Runnable {
public void run() { public void run() {
LOG.info("task executor start"); LOG.info("task executor start");
this.status = Executor.STATUS_RUNNING; this.status = Executor.STATUS_RUNNING;
this.workingStatus = "EXECUTING";
this.device.websocketServerService.log("Task Executor Started");
while (!Objects.equals(this.status, Executor.STATUS_STOP_REQUEST)) { while (!Objects.equals(this.status, Executor.STATUS_STOP_REQUEST)) {
Task task = this.findExecutableTask(); Task task = this.findExecutableTask();
@ -86,6 +90,7 @@ public class Executor implements Runnable {
this.status = Executor.STATUS_STOPPED; this.status = Executor.STATUS_STOPPED;
this.workingStatus = "STOPPED"; this.workingStatus = "STOPPED";
LOG.info("task executor stop"); LOG.info("task executor stop");
this.device.websocketServerService.log("Task Executor Stopped");
} }
/** /**
@ -166,6 +171,8 @@ public class Executor implements Runnable {
// stop executor // stop executor
public void stop() { public void stop() {
LOG.info("task executor stop : start"); LOG.info("task executor stop : start");
this.device.websocketServerService.log("Task Executor Stopping");
for ( Task task : this.tasks ) { for ( Task task : this.tasks ) {
task.stop(); task.stop();
} }
@ -181,6 +188,8 @@ public class Executor implements Runnable {
*/ */
public void pause() { public void pause() {
LOG.info("task executor pause : start"); LOG.info("task executor pause : start");
this.device.websocketServerService.log("Task Executor Pausing");
this.status = Executor.STATUS_PAUSE_REQUEST; this.status = Executor.STATUS_PAUSE_REQUEST;
synchronized (this.tasks) { synchronized (this.tasks) {
this.tasks.notifyAll(); this.tasks.notifyAll();
@ -192,17 +201,28 @@ public class Executor implements Runnable {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
this.workingStatus = "PAUSED";
LOG.info("task executor pause : end"); LOG.info("task executor pause : end");
this.device.websocketServerService.log("Task Executor Paused");
} }
// resume executor // resume executor
public void resume() { public void resume() {
LOG.info("task executor resume : start"); LOG.info("task executor resume : start");
this.device.websocketServerService.log("Task Executor Resuming");
if ( null != this.resourceWaitTask ) {
this.resourceWaitTask.setStatus(Task.STATUS_READY);
this.resourceWaitTask = null;
}
this.status = Executor.STATUS_RUNNING; this.status = Executor.STATUS_RUNNING;
synchronized (this.tasks) { synchronized (this.tasks) {
this.tasks.notifyAll(); this.tasks.notifyAll();
} }
LOG.info("task executor resume : end"); LOG.info("task executor resume : end");
this.device.websocketServerService.log("Task Executor Resumed");
} }
// append task // append task
@ -231,6 +251,7 @@ public class Executor implements Runnable {
// wait for incubator slot // wait for incubator slot
public void waitForIncubatorSlot( Task task ) { public void waitForIncubatorSlot( Task task ) {
LOG.info("task executor wait for incubator slot"); LOG.info("task executor wait for incubator slot");
this.device.websocketServerService.log("Task Executor Waiting For Incubator Slot");
this.status = Executor.STATUS_PAUSED; this.status = Executor.STATUS_PAUSED;
this.incubatorWaitTask = task; this.incubatorWaitTask = task;
} }
@ -241,10 +262,19 @@ public class Executor implements Runnable {
return ; return ;
} }
LOG.info("task executor incubator slot available"); LOG.info("task executor incubator slot available");
this.device.websocketServerService.log("Task Executor Incubator Slot Available");
this.status = Executor.STATUS_RUNNING; this.status = Executor.STATUS_RUNNING;
this.incubatorWaitTask.setStatus(Task.STATUS_READY); this.incubatorWaitTask.setStatus(Task.STATUS_READY);
this.incubatorWaitTask = null; this.incubatorWaitTask = null;
} }
// public void waitForConsumable( Task task );
// wait for consumable resource
public void waitForConsumableResource( Task task, Exception e ) {
LOG.info("task executor wait for consumable resource");
this.device.websocketServerService.log("Task Executor Waiting For Consumable Resource");
this.workingStatus = "WAIT_FOR_CONSUMABLE_RESOURCE";
this.status = Executor.STATUS_PAUSED;
this.resourceWaitTask = task;
this.device.websocketServerService.emit("deviceWaitForConsumableResource", e);
}
} }

8
src/main/java/com/dreamworks/boditech/driver/task/TaskLoad.java

@ -1,9 +1,6 @@
package com.dreamworks.boditech.driver.task; package com.dreamworks.boditech.driver.task;
import com.dreamworks.boditech.driver.Device; import com.dreamworks.boditech.driver.Device;
import com.dreamworks.boditech.driver.actuator.ActArmXY;
import com.dreamworks.boditech.driver.actuator.ActCodeScanner;
import com.dreamworks.boditech.driver.actuator.ActModuleTestCardBoxCase;
import com.dreamworks.boditech.driver.actuator.ActuatorModule;
import com.dreamworks.boditech.driver.actuator.*;
import com.dreamworks.boditech.entity.Project; import com.dreamworks.boditech.entity.Project;
import com.dreamworks.boditech.utils.AppError; import com.dreamworks.boditech.utils.AppError;
import com.dreamworks.boditech.utils.AppRuntimeException; import com.dreamworks.boditech.utils.AppRuntimeException;
@ -25,6 +22,9 @@ public class TaskLoad extends TaskBase {
this.armXY = (ActArmXY)device.getActuator(ActuatorModule.ARM_XY); this.armXY = (ActArmXY)device.getActuator(ActuatorModule.ARM_XY);
this.codeScanner = (ActCodeScanner)device.getActuator(ActuatorModule.ARM_Z_SCANNER); this.codeScanner = (ActCodeScanner)device.getActuator(ActuatorModule.ARM_Z_SCANNER);
ActMotor testCardBoxMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_CARD_BOX_MOTOR);
testCardBoxMotor.reset();
try { try {
this.testCardLoad(executor); this.testCardLoad(executor);
this.bufferTubeLoad(executor); this.bufferTubeLoad(executor);

11
src/main/java/com/dreamworks/boditech/driver/task/TaskStartReset.java

@ -5,6 +5,8 @@ import com.dreamworks.boditech.driver.actuator.*;
import com.dreamworks.boditech.driver.entity.IncubatorSlot; import com.dreamworks.boditech.driver.entity.IncubatorSlot;
import com.dreamworks.boditech.driver.entity.WsMessageEvent; import com.dreamworks.boditech.driver.entity.WsMessageEvent;
import com.dreamworks.boditech.service.AccountService; import com.dreamworks.boditech.service.AccountService;
import com.dreamworks.boditech.utils.AppError;
import com.dreamworks.boditech.utils.AppRuntimeException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -18,6 +20,8 @@ public class TaskStartReset extends TaskBase {
public static final Integer MODE_ERROR = 1; public static final Integer MODE_ERROR = 1;
// logger // logger
private static final Logger LOG = LoggerFactory.getLogger(TaskStartReset.class); private static final Logger LOG = LoggerFactory.getLogger(TaskStartReset.class);
// is executing
private static Boolean isExecuting = false;
// reset mode // reset mode
public Integer mode = MODE_NORMAL; public Integer mode = MODE_NORMAL;
// device instance // device instance
@ -31,8 +35,12 @@ public class TaskStartReset extends TaskBase {
@Override @Override
public void execute(Executor executor) { public void execute(Executor executor) {
long startTime = System.currentTimeMillis();
if ( TaskStartReset.isExecuting ) {
throw new AppRuntimeException(AppError.DEVICE_START_RESET_EXECUTING);
}
TaskStartReset.isExecuting = true;
long startTime = System.currentTimeMillis();
this.device = executor.getDevice(); this.device = executor.getDevice();
this.analysisPushMotor = (ActMotor)device.getActuator(ActuatorModule.ANALYSIS_PUSH_MOTOR); this.analysisPushMotor = (ActMotor)device.getActuator(ActuatorModule.ANALYSIS_PUSH_MOTOR);
this.analysisScanMotor = (ActMotor)device.getActuator(ActuatorModule.ANALYSIS_SCAN_MOTOR); this.analysisScanMotor = (ActMotor)device.getActuator(ActuatorModule.ANALYSIS_SCAN_MOTOR);
@ -117,6 +125,7 @@ public class TaskStartReset extends TaskBase {
this.device.testService.cancelAllTasks(); this.device.testService.cancelAllTasks();
this.device.setIsReady(true); this.device.setIsReady(true);
TaskStartReset.isExecuting = false;
LOG.info("[reset] task finished, cost {}s", (System.currentTimeMillis() - startTime)/1000.00); LOG.info("[reset] task finished, cost {}s", (System.currentTimeMillis() - startTime)/1000.00);
} }

43
src/main/java/com/dreamworks/boditech/driver/task/TaskTestBase.java

@ -10,6 +10,7 @@ import com.dreamworks.boditech.driver.task.step.StepManager;
import com.dreamworks.boditech.entity.Project; import com.dreamworks.boditech.entity.Project;
import com.dreamworks.boditech.entity.MdbTest; import com.dreamworks.boditech.entity.MdbTest;
import com.dreamworks.boditech.entity.TestStepLogEntry; import com.dreamworks.boditech.entity.TestStepLogEntry;
import com.dreamworks.boditech.utils.AppRuntimeException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -114,10 +115,6 @@ abstract public class TaskTestBase extends TaskBase implements TaskTest {
return true; return true;
} }
if ( !this.waitForResource() ) {
return false;
}
Device device = this.taskExecutor.getDevice(); Device device = this.taskExecutor.getDevice();
if ( null == this.projectId ) { if ( null == this.projectId ) {
throw new RuntimeException("project id must be set before execute"); throw new RuntimeException("project id must be set before execute");
@ -126,16 +123,32 @@ abstract public class TaskTestBase extends TaskBase implements TaskTest {
this.steps = StepManager.buildSteps(this.project.steps); this.steps = StepManager.buildSteps(this.project.steps);
this.stepIndex = 0; this.stepIndex = 0;
this.postSteps = new ArrayList<>(); this.postSteps = new ArrayList<>();
this.reactionTube = device.bufferTubes.tubeAllocByProject(this.project);
this.test = new MdbTest(); this.test = new MdbTest();
this.beforeTaskExecute(this.test); this.beforeTaskExecute(this.test);
if ( !this.taskResourceAlloc() ) {
return false;
}
device.testService.insert(this.test); device.testService.insert(this.test);
return true; return true;
} }
// wait for resource // wait for resource
private Boolean waitForResource() {
private Boolean taskResourceAlloc() {
// 小缓冲液
try {
this.reactionTube = device.bufferTubes.tubeAllocByProject(this.project);
} catch ( AppRuntimeException e ) {
this.steps.clear();
this.steps = null;
this.taskExecutor.waitForConsumableResource(this, e);
this.setStatus(Task.STATUS_WAITING);
return false;
}
// 孵育盘卡位
ActIncubator incubator = (ActIncubator) this.device.getActuator(ActuatorModule.INCUBATOR_MOTOR); ActIncubator incubator = (ActIncubator) this.device.getActuator(ActuatorModule.INCUBATOR_MOTOR);
if ( !incubator.hasFreeSlot() ) { if ( !incubator.hasFreeSlot() ) {
this.taskExecutor.waitForIncubatorSlot(this); this.taskExecutor.waitForIncubatorSlot(this);
@ -143,6 +156,18 @@ abstract public class TaskTestBase extends TaskBase implements TaskTest {
return false; return false;
} }
// 其他资源
for ( Step step : this.steps ) {
try {
step.resourcePreAlloc(this.taskExecutor, this);
} catch ( Exception e ) {
this.steps.clear();
this.steps = null;
this.taskExecutor.waitForConsumableResource(this, e);
this.setStatus(Task.STATUS_WAITING);
return false;
}
}
return true; return true;
} }
@ -157,7 +182,11 @@ abstract public class TaskTestBase extends TaskBase implements TaskTest {
TestStepLogEntry logEntry = new TestStepLogEntry(); TestStepLogEntry logEntry = new TestStepLogEntry();
logEntry.stepName = step.getActionName(); logEntry.stepName = step.getActionName();
logEntry.stepOptions = step.getStepNode().toString(); logEntry.stepOptions = step.getStepNode().toString();
LOG.info("step start: ({}) => {}", logEntry.stepName, logEntry.stepOptions);
String logMsg = String.format("[task #%d] step (%s) : %s", this.test.id, logEntry.stepName, logEntry.stepOptions);
LOG.info(logMsg);
this.device.websocketServerService.log(logMsg);
this.device.testService.logStepStart(this.test, logEntry); this.device.testService.logStepStart(this.test, logEntry);
step.execute(this.taskExecutor, this); step.execute(this.taskExecutor, this);
this.device.testService.logStepEnd(logEntry); this.device.testService.logStepEnd(logEntry);

2
src/main/java/com/dreamworks/boditech/driver/task/step/Step.java

@ -19,4 +19,6 @@ public interface Step {
JsonNode getStepNode(); JsonNode getStepNode();
void stop(); void stop();
void resourcePreAlloc(Executor executor, Task task);
} }

7
src/main/java/com/dreamworks/boditech/driver/task/step/StepBase.java

@ -1,4 +1,6 @@
package com.dreamworks.boditech.driver.task.step; package com.dreamworks.boditech.driver.task.step;
import com.dreamworks.boditech.driver.task.Executor;
import com.dreamworks.boditech.driver.task.Task;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
@ -46,4 +48,9 @@ abstract public class StepBase implements Step {
public void stop() { public void stop() {
// nothing to do here as default, override this method if needed // nothing to do here as default, override this method if needed
} }
// check resource requirement
public void resourcePreAlloc(Executor executor, Task task) {
// nothing to do here as default, override this method if needed
}
} }

18
src/main/java/com/dreamworks/boditech/driver/task/step/StepPretreatment.java

@ -30,6 +30,21 @@ public class StepPretreatment extends StepBase {
// has uncapped // has uncapped
private boolean hasUncapped = false; private boolean hasUncapped = false;
// pipette tip to mix sample
private CsmPipetteTip pipetteTip;
@Override
public void resourcePreAlloc(Executor executor, Task task) {
super.resourcePreAlloc(executor,task);
TaskTest taskTest = (TaskTest)task;
CsmSampleTube tube = taskTest.getSampleTube();
MdbTestTube testTube = executor.getDevice().testService.testTubeFindByKey(tube.type);
if ( this.shaking && Objects.equals(MdbTestTube.MIX_TYPE_PIPETTE, testTube.mixType) ) {
this.pipetteTip = executor.getDevice().pipetteTips.tipAlloc();
}
}
@Override @Override
public void execute(Executor executor, Task task) { public void execute(Executor executor, Task task) {
this.taskTest = (TaskTest)task; this.taskTest = (TaskTest)task;
@ -67,8 +82,7 @@ public class StepPretreatment extends StepBase {
ActMotor armZMotor = (ActMotor)device.getActuator(ActuatorModule.ARM_Z_MOTOR); ActMotor armZMotor = (ActMotor)device.getActuator(ActuatorModule.ARM_Z_MOTOR);
CsmSampleTube sampleTube = this.taskTest.getSampleTube(); CsmSampleTube sampleTube = this.taskTest.getSampleTube();
CsmPipetteTip tip = device.pipetteTips.tipAlloc();
pipette.useTip(tip);
pipette.useTip(this.pipetteTip);
armXY.moveTo(sampleTube.getLocationX(), sampleTube.getLocationY()); armXY.moveTo(sampleTube.getLocationX(), sampleTube.getLocationY());
armZMotor.moveTo(sampleTube.getLocationZ()); armZMotor.moveTo(sampleTube.getLocationZ());

13
src/main/java/com/dreamworks/boditech/driver/task/step/StepPuncture.java

@ -14,6 +14,15 @@ public class StepPuncture extends StepBase {
@JsonProperty("tubeType") @JsonProperty("tubeType")
public String tubeType; public String tubeType;
// pipette tip to puncture
private CsmPipetteTip pipetteTip;
@Override
public void resourcePreAlloc(Executor executor, Task task) {
super.resourcePreAlloc(executor, task);
this.pipetteTip = executor.getDevice().pipetteTips.tipAlloc();
}
@Override @Override
public void execute(Executor executor, Task task) { public void execute(Executor executor, Task task) {
Device device = executor.getDevice(); Device device = executor.getDevice();
@ -23,8 +32,7 @@ public class StepPuncture extends StepBase {
TaskTest taskTest = (TaskTest)task; TaskTest taskTest = (TaskTest)task;
// 01. 拾取TIP头 // 01. 拾取TIP头
CsmPipetteTip tip = device.pipetteTips.tipAlloc();
pipette.useTip(tip);
pipette.useTip(this.pipetteTip);
// 04. 移动到穿刺区域 // 04. 移动到穿刺区域
CsmBufferTube bufferTube = taskTest.getReactionTube(); CsmBufferTube bufferTube = taskTest.getReactionTube();
@ -35,5 +43,6 @@ public class StepPuncture extends StepBase {
// 06. 上升到准备区域 // 06. 上升到准备区域
armZMotor.moveTo(0); armZMotor.moveTo(0);
pipette.dropTip();
} }
} }

33
src/main/java/com/dreamworks/boditech/driver/task/step/StepSampling.java

@ -28,6 +28,27 @@ public class StepSampling extends StepBase {
// pipette // pipette
private ActPipette pipette; private ActPipette pipette;
// resource : pipette tip
private CsmPipetteTip pipetteTip;
// resource : test card
private CsmTestCard testcard;
// resource : large buffer tube
private CsmLargeBufferTube largeBufferTube;
@Override
public void resourcePreAlloc(Executor executor, Task task) {
super.resourcePreAlloc(executor, task);
TaskTest taskTest = (TaskTest)task;
this.pipetteTip = executor.getDevice().pipetteTips.tipAlloc();
if ( this.submit ) {
this.testcard = executor.getDevice().testCards.cardAllocByProject(taskTest.getProject());
}
if ( "LargeBufferTube".equals(this.source) ) {
this.largeBufferTube = executor.getDevice().largeBufferTubes.allocByProject(taskTest.getProject());
}
}
@Override @Override
public void execute(Executor executor, Task task) { public void execute(Executor executor, Task task) {
Device device = executor.getDevice(); Device device = executor.getDevice();
@ -41,11 +62,7 @@ public class StepSampling extends StepBase {
this.setupTestcard(device); this.setupTestcard(device);
} }
// 如果没有TIP头则拾取TIP头
if ( !this.pipette.getHasTip() ) {
CsmPipetteTip tip = device.pipetteTips.tipAlloc();
this.pipette.useTip(tip);
}
this.pipette.useTip(this.pipetteTip);
// 1. 获取样本 // 1. 获取样本
if ( "Sample".equals(this.source) ) { if ( "Sample".equals(this.source) ) {
@ -95,8 +112,7 @@ public class StepSampling extends StepBase {
incubator.lockSlot(testCardSlot.getIndex()); incubator.lockSlot(testCardSlot.getIndex());
// 获取测试板 // 获取测试板
CsmTestCard testcard = device.testCards.cardAllocByProject(this.taskTest.getProject());
testCardBoxMotor.moveTo(testcard.getLocation());
testCardBoxMotor.moveTo(this.testcard.getLocation());
testCardFeedMotor.moveTo("testCardPushDepth"); testCardFeedMotor.moveTo("testCardPushDepth");
testCardFeedMotor.moveTo("testCardPushStandby"); testCardFeedMotor.moveTo("testCardPushStandby");
@ -117,8 +133,7 @@ public class StepSampling extends StepBase {
// get reagent from large buffer tube // get reagent from large buffer tube
private void getReagentFromLargeBufferTube( Device device ) { private void getReagentFromLargeBufferTube( Device device ) {
CsmLargeBufferTube tube = device.largeBufferTubes.getTubeByProjectName(this.taskTest.getProjectName());
CsmLargeBufferTube tube = this.largeBufferTube;
this.armXY.moveTo(tube.getLocationX(), tube.getLocationY()); this.armXY.moveTo(tube.getLocationX(), tube.getLocationY());
this.armZMotor.moveTo(tube.getLocationZ()); this.armZMotor.moveTo(tube.getLocationZ());
this.pipette.aspiration(this.amount); this.pipette.aspiration(this.amount);

24
src/main/java/com/dreamworks/boditech/service/WebsocketServerService.java

@ -1,4 +1,5 @@
package com.dreamworks.boditech.service; package com.dreamworks.boditech.service;
import com.dreamworks.boditech.utils.MyCommon;
import com.dreamworks.boditech.utils.MyWsServerConnection; import com.dreamworks.boditech.utils.MyWsServerConnection;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@ -6,6 +7,8 @@ import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
@Service @Service
public class WebsocketServerService { public class WebsocketServerService {
// connections // connections
@ -38,4 +41,25 @@ public class WebsocketServerService {
} }
this.send(json); this.send(json);
} }
// emit event
public void emit( String name, Object data ) {
Map<String,Object> event = Map.of(
"type", "event",
"name", name,
"data", data
);
this.send(event);
}
// emit event
public void emit( String name ) {
this.emit(name, false);
}
// log to frontend
public void log( String message, Object ... params) {
Map<String,Object> event = Map.of("type", "log", "data", message);
this.send(event);
}
} }

5
src/main/java/com/dreamworks/boditech/utils/AppError.java

@ -16,6 +16,10 @@ public enum AppError {
INCUBATOR_NO_FREE_SLOT, INCUBATOR_NO_FREE_SLOT,
TEST_TUBE_RACK_TYPE_NOT_SUPPORTED, TEST_TUBE_RACK_TYPE_NOT_SUPPORTED,
// task
TASK_BUFFER_TUBE_ALLOC_FAILED,
TASK_LARGE_BUFFER_TUBE_ALLOC_FAILED,
// device // device
DEVICE_BUSY, DEVICE_BUSY,
DEVICE_ALREADY_STARTED, DEVICE_ALREADY_STARTED,
@ -24,4 +28,5 @@ public enum AppError {
DEVICE_NOT_STARTED, DEVICE_NOT_STARTED,
DEVICE_STOP_FAILED, DEVICE_STOP_FAILED,
DEVICE_EXECUTING_REQUIRED, DEVICE_EXECUTING_REQUIRED,
DEVICE_START_RESET_EXECUTING,
} }
Loading…
Cancel
Save