Browse Source

试管架任务执行

master
sige 2 years ago
parent
commit
848b09b443
  1. 40
      src/main/java/com/dreamworks/boditech/controller/DeviceController.java
  2. 1
      src/main/java/com/dreamworks/boditech/controller/TestController.java
  3. 12
      src/main/java/com/dreamworks/boditech/driver/actuator/ActIncubator.java
  4. 1
      src/main/java/com/dreamworks/boditech/driver/task/TaskTestEmergency.java
  5. 3
      src/main/java/com/dreamworks/boditech/driver/task/TaskTestRegular.java
  6. 8
      src/main/java/com/dreamworks/boditech/driver/task/TaskTestTubeRackPrepare.java
  7. 5
      src/main/java/com/dreamworks/boditech/driver/task/step/StepSampling.java
  8. 3
      src/main/java/com/dreamworks/boditech/entity/MdbEmergencyTestTask.java
  9. 12
      src/main/java/com/dreamworks/boditech/entity/MdbTestTubeRackTestTask.java
  10. 6
      src/main/java/com/dreamworks/boditech/entity/MdbTestTubeRackTestTaskTube.java
  11. 6
      src/main/java/com/dreamworks/boditech/mapper/TestTubeRackTestTaskMapper.java
  12. 18
      src/main/java/com/dreamworks/boditech/mapper/TestTubeRackTestTaskTubeMapper.java
  13. 82
      src/main/java/com/dreamworks/boditech/service/TestService.java
  14. 4
      src/main/java/com/dreamworks/boditech/utils/AppError.java

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

@ -6,6 +6,7 @@ import com.dreamworks.boditech.driver.actuator.ActModuleIncubatorTemperature;
import com.dreamworks.boditech.driver.actuator.ActModuleTestCardBoxCaseTemperature;
import com.dreamworks.boditech.driver.actuator.ActuatorModule;
import com.dreamworks.boditech.driver.entity.*;
import com.dreamworks.boditech.entity.MdbTestTubeRackTestTask;
import com.dreamworks.boditech.service.DeviceService;
import com.dreamworks.boditech.utils.I18n;
import jakarta.annotation.Resource;
@ -364,43 +365,4 @@ public class DeviceController extends BaseController {
"status", "EMPTY"
));
}
@ResponseBody
@PostMapping("/api/device/test-tube-rack-status-get")
public ApiResponse testTubeRackStatusGet() {
List<String> statusList = List.of("FINISHED","FINISHED","FINISHED","FINISHED","EXECUTING","WAITING","WAITING","WAITING","WAITING","WAITING");
List<Map<String,Object>> tubes = new ArrayList<>();
for ( int i=0; i<10; i++ ) {
List<Map<String,Object>> tasks = new ArrayList<>();
tasks.add(Map.of(
"projectColor", "red",
"projectName", "hsCRP",
"projectId", "01"
));
tasks.add(Map.of(
"projectColor", "green",
"projectName", "hsCRP",
"projectId", "01"
));
tasks.add(Map.of(
"projectColor", "blue",
"projectName", "hsCRP",
"projectId", "01"
));
Map<String,Object> tube = new HashMap<>();
tube.put("index", Integer.toString(i));
tube.put("status", statusList.get(i));
tube.put("sampleUID", "016");
tube.put("sampleType","WB");
tube.put("projects",tasks);
tubes.add(tube);
}
return this.success(Map.of(
"type" , "AUTO",
"tubes", tubes
));
}
}

1
src/main/java/com/dreamworks/boditech/controller/TestController.java

@ -186,7 +186,6 @@ public class TestController extends BaseController {
Map<String, Object> projectItem = MyCommon.objectToMap(project);
projectItem.remove("steps");
projectList.add(projectItem);
projectIds.add(projectId);
}
tubeItem.put("projects", projectList);
tubeItem.put("projectIds", projectIds);

12
src/main/java/com/dreamworks/boditech/driver/actuator/ActIncubator.java

@ -1,15 +1,20 @@
package com.dreamworks.boditech.driver.actuator;
import com.dreamworks.boditech.driver.Device;
import com.dreamworks.boditech.driver.entity.IncubatorSlot;
import com.dreamworks.boditech.utils.AppError;
import com.dreamworks.boditech.utils.AppRuntimeException;
import com.dreamworks.boditech.utils.MyCommon;
public class ActIncubator extends ActMotor {
// slots
private final IncubatorSlot[] slots;
// alloc index
private Integer allocStartIndex = 0;
// constructor
public ActIncubator(Integer mid, Device device) {
super(mid, device);
this.allocStartIndex = 0;
this.slots = new IncubatorSlot[20];
for ( int i = 0; i < 20; i++ ) {
IncubatorSlot slot = new IncubatorSlot(this);
@ -30,13 +35,14 @@ public class ActIncubator extends ActMotor {
}
// get free slot
public IncubatorSlot getFreeSlot() {
for ( int i = 0; i < 20; i++ ) {
public IncubatorSlot allocSlot() {
for ( int i = this.allocStartIndex; i < 20; i++ ) {
if ( this.slots[i].isFree ) {
this.allocStartIndex = (i + 1) % 20;
return this.slots[i];
}
}
return null;
throw new AppRuntimeException(AppError.INCUBATOR_NO_FREE_SLOT);
}
// lock slot

1
src/main/java/com/dreamworks/boditech/driver/task/TaskTestEmergency.java

@ -23,6 +23,7 @@ public class TaskTestEmergency extends TaskTestBase {
test.projectId = this.project.id;
test.projectName = this.project.name;
test.tubeType = CsmSampleTube.TYPE_EPP05;
test.tubeIndex = this.mdbTask.index;
test.sampleUid = this.mdbTask.sampleUid;
test.sampleType = this.mdbTask.sampleType;
if ( test.sampleType.isEmpty() ) {

3
src/main/java/com/dreamworks/boditech/driver/task/TaskTestRegular.java

@ -24,6 +24,9 @@ public class TaskTestRegular extends TaskTestBase {
@Override
protected void beforeTaskExecute(MdbTest test) {
// start tube test
this.taskExecutor.getDevice().testService.regularTaskTubeStart(this.mdbTask, this.tube);
// setup test info
test.taskType = "regular";
test.barCode = this.tube.barCode;

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

@ -77,6 +77,7 @@ public class TaskTestTubeRackPrepare extends TaskBase {
if ( this.mdbTask.tubeType.isEmpty() ) {
// @TODO : 试管为空需要扫描试管架了
this.mdbTask.tubeType = "BloodTube5ml";
this.testService.regularTaskUpdate(this.mdbTask);
}
// 04. 扫描完成后推送到预备区域
@ -86,6 +87,7 @@ public class TaskTestTubeRackPrepare extends TaskBase {
TaskBatchTubeExit exitTask = new TaskBatchTubeExit();
executor.appendTask(exitTask);
this.testService.regularTaskStart(this.mdbTask);
this.setStatus(Task.STATUS_FINISHED);
}
@ -94,6 +96,8 @@ public class TaskTestTubeRackPrepare extends TaskBase {
List<MdbTestTubeRackTestTaskTube> tubes = this.testService.testTubeRackTaskTubeListByRackId(this.mdbTask.id);
for (MdbTestTubeRackTestTaskTube tube : tubes) {
if ( !this.testTubeExistsStatus[tube.index] ) {
tube.status = MdbTestTubeRackTestTaskTube.STATUS_IGNORED;
this.testService.regularTaskTubeStatusUpdate(tube);
continue;
}
@ -105,6 +109,8 @@ public class TaskTestTubeRackPrepare extends TaskBase {
if ( projectIds.isEmpty() ) {
// @TODO : 如果这里为空那么就需要从 LIS 获取信息了, 这里先假设为 hsCRP ~~~
projectIds = List.of(1);
tube.projectIds = MyCommon.objectToJson(projectIds);
this.testService.regularTaskTubeUpdate(tube);
}
for (Integer projectId : projectIds) {
TaskTestRegular task = new TaskTestRegular();
@ -115,7 +121,7 @@ public class TaskTestTubeRackPrepare extends TaskBase {
}
tube.status = MdbTestTubeRackTestTaskTube.STATUS_WAITING;
this.testService.testTubeRackTaskTubeStatusUpdate(tube);
this.testService.regularTaskTubeStatusUpdate(tube);
}
}

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

@ -90,10 +90,7 @@ public class StepSampling extends StepBase {
ActMotor testCardFeedMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_CARD_FEED_MOTOR);
// 获取空闲位置
IncubatorSlot testCardSlot = incubator.getFreeSlot();
if ( null == testCardSlot ) {
throw new RuntimeException("no slot available");
}
IncubatorSlot testCardSlot = incubator.allocSlot();
incubator.moveTo(testCardSlot.getEnterLocation());
incubator.lockSlot(testCardSlot.getIndex());

3
src/main/java/com/dreamworks/boditech/entity/MdbEmergencyTestTask.java

@ -4,6 +4,9 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.List;
public class MdbEmergencyTestTask {
// project detect type : auto
@JsonIgnore
public static final String PROJECT_DETECT_TYPE_AUTO = "AUTO";
// status : executing
@JsonIgnore
public static final String STATUS_EXECUTING = "EXECUTING";

12
src/main/java/com/dreamworks/boditech/entity/MdbTestTubeRackTestTask.java

@ -1,5 +1,17 @@
package com.dreamworks.boditech.entity;
import com.fasterxml.jackson.annotation.JsonIgnore;
public class MdbTestTubeRackTestTask {
@JsonIgnore
public static final String STATUS_WAITING = "WAITING";
@JsonIgnore
public static final String STATUS_EXECUTING = "EXECUTING";
@JsonIgnore
public static final String STATUS_FINISHED = "FINISHED";
@JsonIgnore
public static final String STATUS_CANCELED = "CANCELED";
@JsonIgnore
public static final String STATUS_ERROR = "ERROR";
public Integer id;
public String status;
public String tubeTypeDetectType;

6
src/main/java/com/dreamworks/boditech/entity/MdbTestTubeRackTestTaskTube.java

@ -8,6 +8,8 @@ public class MdbTestTubeRackTestTaskTube {
public final static String STATUS_EXECUTING = "EXECUTING";
// status : finished
public final static String STATUS_FINISHED = "FINISHED";
// status : ignored
public final static String STATUS_IGNORED = "IGNORED";
// id
public Integer id;
@ -31,4 +33,8 @@ public class MdbTestTubeRackTestTaskTube {
public Boolean attenuation;
// status
public String status;
// execute started at
public Long execStartedAt;
// execute finished at
public Long execFinishedAt;
}

6
src/main/java/com/dreamworks/boditech/mapper/TestTubeRackTestTaskMapper.java

@ -46,4 +46,10 @@ public interface TestTubeRackTestTaskMapper {
@Select("SELECT * FROM btd_test_tube_rack_test_tasks WHERE status = 'EXECUTING' ORDER BY id ASC LIMIT 1")
MdbTestTubeRackTestTask findCurrentTask();
@Update("UPDATE btd_test_tube_rack_test_tasks SET status = #{status}, execStartedAt = #{execStartedAt} WHERE id = #{id}")
void testStart( MdbTestTubeRackTestTask task );
@Update("UPDATE btd_test_tube_rack_test_tasks SET status = #{status}, execFinishedAt = #{execFinishedAt} WHERE id = #{id}")
void testFinish( MdbTestTubeRackTestTask task );
}

18
src/main/java/com/dreamworks/boditech/mapper/TestTubeRackTestTaskTubeMapper.java

@ -21,4 +21,22 @@ public interface TestTubeRackTestTaskTubeMapper {
@Update("UPDATE btd_test_tube_rack_test_task_tubes SET status = #{status} WHERE id = #{id}")
void statusUpdate( MdbTestTubeRackTestTaskTube tube );
@Update("UPDATE btd_test_tube_rack_test_task_tubes SET status = #{status}, execFinishedAt = #{execFinishedAt} WHERE id = #{id}")
void testEnd( MdbTestTubeRackTestTaskTube tube );
@Select("SELECT COUNT(*) FROM btd_test_tube_rack_test_task_tubes WHERE rackId = #{rackId} AND status = #{status}")
Integer countByRackIdAndStatus(Integer rackId, String status);
@Select("SELECT COUNT(*) FROM btd_test_tube_rack_test_task_tubes WHERE rackId = #{rackId}")
Integer countByRackId(Integer rackId);
@Update("UPDATE btd_test_tube_rack_test_task_tubes SET status = #{status}, execStartedAt = #{execStartedAt} WHERE id = #{id}")
void testStart( MdbTestTubeRackTestTaskTube tube );
@Update("UPDATE btd_test_tube_rack_test_task_tubes SET " +
"projectIds = #{projectIds} " +
"WHERE id = #{id}"
)
void update(MdbTestTubeRackTestTaskTube tube);
}

82
src/main/java/com/dreamworks/boditech/service/TestService.java

@ -9,6 +9,8 @@ import com.dreamworks.boditech.entity.parameter.ParamTestSearch;
import com.dreamworks.boditech.entity.parameter.ParamTestTubeRackTaskSave;
import com.dreamworks.boditech.entity.parameter.ParamTestTubeRackTaskSaveTube;
import com.dreamworks.boditech.mapper.*;
import com.dreamworks.boditech.utils.AppError;
import com.dreamworks.boditech.utils.AppRuntimeException;
import com.dreamworks.boditech.utils.MyCommon;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
@ -18,6 +20,7 @@ import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Objects;
@Service
public class TestService {
@ -43,18 +46,26 @@ public class TestService {
// fetch task from database
public List<Task> fetchTask() {
// find emergency task first
// MdbEmergencyTestTask test = this.emergencyTestTaskMapper.findExecutableTask();
// if ( null != test ) {
// List<Integer> projectIds = (List<Integer>)MyCommon.jsonToObject(test.projectIds, List.class);
// List<Task> tasks = new ArrayList<>();
// for (Integer projectId : projectIds) {
// TaskTestEmergency task = new TaskTestEmergency();
// task.setMdbEmergencyTestTask(test);
// task.setProjectId(projectId);
// tasks.add(task);
// }
// return tasks;
// }
MdbEmergencyTestTask test = this.emergencyTestTaskMapper.findExecutableTask();
if ( null != test ) {
List<Integer> projectIds = (List<Integer>)MyCommon.jsonToObject(test.projectIds, List.class);
if (Objects.equals(test.projectDetectType, MdbEmergencyTestTask.PROJECT_DETECT_TYPE_AUTO)) {
// @TODO : 这里需要从 LIS 获取项目信息之类的数据了 这里先模拟个hsCRP
projectIds = List.of(1);
test.sampleType = "WB";
}
if ( projectIds.isEmpty() ) {
throw new AppRuntimeException(AppError.TEST_NO_PROJECT_ASSIGNED);
}
List<Task> tasks = new ArrayList<>();
for (Integer projectId : projectIds) {
TaskTestEmergency task = new TaskTestEmergency();
task.setMdbEmergencyTestTask(test);
task.setProjectId(projectId);
tasks.add(task);
}
return tasks;
}
// find test tube rack task
MdbTestTubeRackTestTask rack = this.testTubeRackTestTaskMapper.findExecutableTask();
@ -142,11 +153,6 @@ public class TestService {
return this.testTubeRackTestTaskTubeMapper.findAllByRackId(rackId);
}
// test tube rack task tube status update
public void testTubeRackTaskTubeStatusUpdate( MdbTestTubeRackTestTaskTube tube ) {
this.testTubeRackTestTaskTubeMapper.statusUpdate(tube);
}
// test tube rack task delete
public void testTubeRackTaskDeleteById(Integer id) {
this.actionLog.log("test-tube-rack-task.delete", id);
@ -247,9 +253,49 @@ public class TestService {
return this.testTubeRackTestTaskMapper.findCurrentTask();
}
// update test tube rack task
public void regularTaskUpdate( MdbTestTubeRackTestTask task ) {
this.testTubeRackTestTaskMapper.update(task);
}
// regular task start
public void regularTaskStart( MdbTestTubeRackTestTask task ) {
task.status = MdbTestTubeRackTestTask.STATUS_EXECUTING;
task.execStartedAt = System.currentTimeMillis();
this.testTubeRackTestTaskMapper.testStart(task);
}
// regular task tube update
public void regularTaskTubeUpdate( MdbTestTubeRackTestTaskTube tube ) {
this.testTubeRackTestTaskTubeMapper.update(tube);
}
// test tube rack task tube status update
public void regularTaskTubeStatusUpdate( MdbTestTubeRackTestTaskTube tube ) {
this.testTubeRackTestTaskTubeMapper.statusUpdate(tube);
}
// regular task tube start
public void regularTaskTubeStart( MdbTestTubeRackTestTask task, MdbTestTubeRackTestTaskTube tube ) {
tube.status = MdbTestTubeRackTestTaskTube.STATUS_EXECUTING;
tube.execStartedAt = System.currentTimeMillis();
this.testTubeRackTestTaskTubeMapper.testStart(tube);
}
// emergency task end
public void regularTaskTubeEnd( MdbTestTubeRackTestTask task, MdbTestTubeRackTestTaskTube tube ) {
// @TODO : implement this method later
tube.status = MdbTestTubeRackTestTaskTube.STATUS_FINISHED;
tube.execFinishedAt = System.currentTimeMillis();
this.testTubeRackTestTaskTubeMapper.testEnd(tube);
Integer finishedCount = this.testTubeRackTestTaskTubeMapper.countByRackIdAndStatus(task.id, MdbTestTubeRackTestTaskTube.STATUS_FINISHED);
Integer ignoredCount = this.testTubeRackTestTaskTubeMapper.countByRackIdAndStatus(task.id, MdbTestTubeRackTestTaskTube.STATUS_IGNORED);
Integer totalCount = this.testTubeRackTestTaskTubeMapper.countByRackId(task.id);
if ( finishedCount + ignoredCount >= totalCount ) {
task.status = MdbTestTubeRackTestTask.STATUS_FINISHED;
task.execFinishedAt = System.currentTimeMillis();
this.testTubeRackTestTaskMapper.testFinish(task);
}
}
// emergency task cancel

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

@ -3,6 +3,9 @@ public enum AppError {
// account
ACCOUNT_LOGIN_INVALID_ACCOUNT_OR_PIN_CODE,
// test
TEST_NO_PROJECT_ASSIGNED,
// project
PROJECT_CODE_NOT_ACTIVE,
PROJECT_CODE_ALREADY_ACTIVE,
@ -10,6 +13,7 @@ public enum AppError {
TEST_TUBE_RACK_FEED_RACK_NOT_FOUND,
TEST_CARD_BOX_CASE_COVER_NOT_CLOSED,
INCUBATOR_NO_FREE_SLOT,
// device
DEVICE_BUSY

Loading…
Cancel
Save