Browse Source

update

tags/v0
zhaohe 1 year ago
parent
commit
83fd2b6b15
  1. 17
      src/main/java/a8k/appbase/A8kTubeType.java
  2. 21
      src/main/java/a8k/appbase/ProjectInfoSimple.java
  3. 38
      src/main/java/a8k/db/DBTableVersion.java
  4. 19
      src/main/java/a8k/db/ProjectColor.java
  5. 209
      src/main/java/a8k/db/ProjectInfo.java
  6. 4
      src/main/java/a8k/service/AddSampleService.java
  7. 92
      src/main/java/a8k/service/ProjectColorAllocer.java
  8. 4
      src/main/java/a8k/service/UIEventProcesser.java
  9. 1
      src/main/java/a8k/service/appeventbus/appevent/A8kCanBusOnConnectEvent.java
  10. 8
      src/main/java/a8k/service/appeventbus/appevent/A8kHardwareReport.java
  11. 8
      src/main/java/a8k/service/appeventbus/appevent/A8kStateChangeEvent.java
  12. 6
      src/main/java/a8k/service/appeventbus/appevent/AppEvent.java
  13. 2
      src/main/java/a8k/service/appeventbus/appevent/AppStepNotifyEvent.java
  14. 1
      src/main/java/a8k/service/appeventbus/appevent/AppWarningNotifyEvent.java
  15. 34
      src/main/java/a8k/service/base/A8kDeviceState.java
  16. 6
      src/main/java/a8k/service/base/BloodType.java
  17. 10
      src/main/java/a8k/service/base/consumable/ConsumableItemGroup.java
  18. 16
      src/main/java/a8k/service/base/consumable/ReactantItem.java
  19. 5
      src/main/java/a8k/service/base/consumable/TipGroupInfo.java
  20. 12
      src/main/java/a8k/service/base/plate/PlateState.java
  21. 23
      src/main/java/a8k/service/base/plate/ReactingPlateState.java
  22. 13
      src/main/java/a8k/service/base/reaction_result/ReactionResult.java
  23. 7
      src/main/java/a8k/service/base/sample/EmergencyPosState.java
  24. 6
      src/main/java/a8k/service/base/sample/EmergencySampleInfo.java
  25. 18
      src/main/java/a8k/service/base/sample/SampleInfo.java
  26. 8
      src/main/java/a8k/service/base/sample/Tube.java
  27. 12
      src/main/java/a8k/service/base/sample/TubeHolder.java
  28. 7
      src/main/java/a8k/service/base/sample/TubeHolderState.java
  29. 18
      src/main/java/a8k/service/base/sample/TubeState.java
  30. 8
      src/main/java/a8k/service/base/samplecfg/SampleTubeCfg.java
  31. 9
      src/main/java/a8k/service/base/samplecfg/SampleTubeHolderCfg.java
  32. 78
      src/main/java/a8k/service/ctrl_service/AppCtrlService.java
  33. 11
      src/main/java/a8k/service/hardware/SamplesPreProcessModuleCtrlService.java
  34. 76
      src/main/java/a8k/service/project_mgr/ProjectItemMgrService.java
  35. 158
      src/main/java/a8k/service/state_service/A8kStateMgrService.java
  36. 7
      src/main/resources/db/migration/V100_5__create_table_DBVersion.sql
  37. 8
      src/main/resources/db/migration/V100_6__create_table_ProjectColorTable.sql

17
src/main/java/a8k/appbase/A8kTubeType.java

@ -3,18 +3,15 @@ package a8k.appbase;
public enum A8kTubeType {
HighBlood("HighBlood", "0000"), //全血试管
ShortBlood("ShortBlood", "0000"), //全血试管
Mini("Mini", "1111"), //迷你试管
MiniBlood("MiniBlood", "2222"), //阳普管
BulletTube1P5("BulletTube1P5", "5555"),//子弹头试管1.5mL
BulletTube0P5("BulletTube0P5", "4444"); //子弹头试管0.5mL
BloodTube("0000"), //全血试管
ShortBloodTube("0000"), //全血试管
MiniTube("1111"), //迷你试管
MiniBlood("2222"), //阳普管
BulletTube1P5("5555"),//子弹头试管1.5mL
BulletTube0P5("4444"); //子弹头试管0.5mL
final public String scanCode;
final public String name;
A8kTubeType(String name, String scanCode) {
A8kTubeType(String scanCode) {
this.scanCode = scanCode;
this.name = name;
}
}

21
src/main/java/a8k/appbase/ProjectInfoSimple.java

@ -0,0 +1,21 @@
package a8k.appbase;
import a8k.db.ProjectInfo;
public class ProjectInfoSimple {
String projectName; //项目名称
String lotName; //批次名称
String expiryDate; //有效日期
public ProjectInfoSimple(String projectName, String lotName, String expiryDate) {
this.projectName = projectName;
this.lotName = lotName;
this.expiryDate = expiryDate;
}
public ProjectInfoSimple(ProjectInfo pinfo) {
this.projectName = pinfo.projectName;
this.lotName = pinfo.lotName;
this.expiryDate = pinfo.expiryDate;
}
}

38
src/main/java/a8k/db/DBTableVersion.java

@ -0,0 +1,38 @@
package a8k.db;
import com.iflytop.uf.UfActiveRecord;
import com.iflytop.uf.UfActiveRecordField;
import java.util.Map;
public class DBTableVersion extends UfActiveRecord {
@UfActiveRecordField
public String tableName;
@UfActiveRecordField
public Integer version;
public static String getTableName() {
return DBTableVersion.class.getSimpleName() + "Table";
}
public static void setTableVersion(String tableName, Integer version) {
var dbDataVersion = UfActiveRecord.findOne(DBTableVersion.class, Map.of("tableName", tableName));
if (null == dbDataVersion) {
dbDataVersion = new DBTableVersion();
dbDataVersion.tableName = tableName;
dbDataVersion.version = version;
dbDataVersion.save();
} else {
dbDataVersion.version = version;
dbDataVersion.save();
}
}
public static Integer getTableVersion(String tableName) {
var dbDataVersion = UfActiveRecord.findOne(DBTableVersion.class, Map.of("tableName", tableName));
if (null == dbDataVersion) {
return 0;
}
return dbDataVersion.version;
}
}

19
src/main/java/a8k/db/ProjectColor.java

@ -0,0 +1,19 @@
package a8k.db;
import com.iflytop.uf.UfActiveRecord;
import com.iflytop.uf.UfActiveRecordField;
public class ProjectColor extends UfActiveRecord {
@UfActiveRecordField
public String color;
@UfActiveRecordField
public String projectId;
@UfActiveRecordField
public Integer index;
public static String getTableName() {
return "ProjectColorTable";
}
}

209
src/main/java/a8k/db/ProjectInfo.java

@ -0,0 +1,209 @@
package a8k.db;
import com.iflytop.uf.UfActiveRecord;
import com.iflytop.uf.UfActiveRecordField;
//ref:https://iflytop1.feishu.cn/wiki/HvDlwbEWDi4fgkkL6qSc2iLGnte
public class ProjectInfo extends UfActiveRecord {
public static String getTableName() {
return "ProjectInfoTable";
}
@UfActiveRecordField
public Integer buildIn;//是否是内置如果是内置则不显示作为项目的默认值使用
@UfActiveRecordField
public String insertTime; //插入时间
@UfActiveRecordField
public String projectName; //项目名称
@UfActiveRecordField
public String lotName; //批次名称
@UfActiveRecordField
public String expiryDate; //有效日期
@UfActiveRecordField
public String projectCode; //项目名称代码
@UfActiveRecordField
public Integer palteCode; // 板条条码代码
@UfActiveRecordField
public Integer updateChipVersion; // 更新芯片版本号
@UfActiveRecordField
public Double QCPeakMinVal; // 质控峰最小值
@UfActiveRecordField
public Double QCPeakMaxVal; // 质控峰最大值 设置值x10最大不超过250000
@UfActiveRecordField
public Integer optType; //光学类型 光学类型(0=自动;1=F光学;2=T光学;3=F/T光学;其他=无效;)
@UfActiveRecordField
public Integer optFixedGainSetting; //光学固定增益设置
@UfActiveRecordField
public Integer optAreaPeakCount; //光学面积峰个数
@UfActiveRecordField
public Integer calculationDirection; //计算方向
@UfActiveRecordField
public Integer sampleType; //样本类型
@UfActiveRecordField
public Integer equipmentManufacturer; //设备厂商
@UfActiveRecordField
public Integer tOptIlluminationTime; //T光学持续光照时间
@UfActiveRecordField
public Integer incMultiInstruDataMerge; //是否包含多款仪器数据合并
@UfActiveRecordField
public Integer multiInstruDataMerge; //多款仪器数据合并
@UfActiveRecordField
public Integer wBloodSampleVol; //全血样本量
@UfActiveRecordField
public Integer serumSampleVol; //血清/血浆样本量
@UfActiveRecordField
public Integer tubeMixingCount; //试管混匀次数
@UfActiveRecordField
public Integer bufferBottleSize; //缓冲液瓶大小
@UfActiveRecordField
public Integer bufferBottleCapacity; //缓冲液瓶容量
@UfActiveRecordField
public Integer buffLiquidAspirMixingCnt; //缓冲液吸吐混匀次数
@UfActiveRecordField
public Integer buffLiquidAspirMixingVol; //缓冲液吐混混匀量
@UfActiveRecordField
public Integer buffLiquidReactionTime; //缓冲液反应时间
@UfActiveRecordField
public Integer reactionPlateReactionTime; //反应板反应时间
@UfActiveRecordField
public Integer reactionPlateDropletVol; //反应板滴样量
@UfActiveRecordField
public Integer resultDecimalPlaces; //结果小数点位数
@UfActiveRecordField
public Integer scanningRange; //扫描范围
//当前项目是几联卡项目
//项目1 结果曲线是否为分段函数
//项目2 结果曲线是否为分段函数
//项目3 结果曲线是否为分段函数
@UfActiveRecordField
public Integer projectNum; //当前项目是几联卡项目
@UfActiveRecordField
public Integer project1CurveType; //项目1 结果曲线是否为分段函数
@UfActiveRecordField
public Integer project2CurveType; //项目2 结果曲线是否为分段函数
@UfActiveRecordField
public Integer project3CurveType; //项目3 结果曲线是否为分段函数
//非分段函数
@UfActiveRecordField
public Integer p0FnX; //函数未知数是
@UfActiveRecordField
public Double p0FnXMin; //函数未知数下限闻值
@UfActiveRecordField
public Double p0FnXMax; //函数未知数上限闻值
@UfActiveRecordField
public Double p0FnSerumA; //A
@UfActiveRecordField
public Double p0FnSerumB; //B
@UfActiveRecordField
public Double p0FnSerumC; //C
@UfActiveRecordField
public Double p0FnSerumD; //D
@UfActiveRecordField
public Double p0FnRtSerumUpLimit; //结果上限
@UfActiveRecordField
public Double p0FnRtSerumLowLimit; //结果下限
@UfActiveRecordField
public Double p0FnBloodA; //A
@UfActiveRecordField
public Double p0FnBloodB; //B
@UfActiveRecordField
public Double p0FnBloodC; //C
@UfActiveRecordField
public Double p0FnBloodD; //D
@UfActiveRecordField
public Double p0FnRtBloodUpLimit; //结果上限
@UfActiveRecordField
public Double p0FnRtBloodLowLimit; //结果下限
//分段函数
@UfActiveRecordField
public Integer p0PwFnJudeX; //分界判断数据来源
@UfActiveRecordField
public Double p0PwFnJudeThres; //分界判断数据值
@UfActiveRecordField
public Double p0PwFnLCX; //低浓度未知数
@UfActiveRecordField
public Double p0PwFnHCX; //高浓度未知数
@UfActiveRecordField
public Double p0PwFnXMin; //函数未知数下限闻值
@UfActiveRecordField
public Double p0PwFnXMax; //函数未知数上限闻值
@UfActiveRecordField
public Double p0PwFnLCSerumA; //A
@UfActiveRecordField
public Double p0PwFnLCSerumB; //B
@UfActiveRecordField
public Double p0PwFnLCSerumC; //C
@UfActiveRecordField
public Double p0PwFnLCSerumD; //D
@UfActiveRecordField
public Double p0PwFnLCRtSerumUpLimit; //结果上限
@UfActiveRecordField
public Double p0PwFnLCRtSerumLowLimit; //结果下限
@UfActiveRecordField
public Double p0PwFnHCSerumA; //A
@UfActiveRecordField
public Double p0PwFnHCSerumB; //B
@UfActiveRecordField
public Double p0PwFnHCSerumC; //C
@UfActiveRecordField
public Double p0PwFnHCSerumD; //D
@UfActiveRecordField
public Double p0PwFnHCRtSerumUpLimit; //结果上限
@UfActiveRecordField
public Double p0PwFnHCRtSerumLowLimit; //结果下限
@UfActiveRecordField
public Double p0PwFnLCBloodA; //A
@UfActiveRecordField
public Double p0PwFnLCBloodB; //B
@UfActiveRecordField
public Double p0PwFnLCBloodC; //C
@UfActiveRecordField
public Double p0PwFnLCBloodD; //D
@UfActiveRecordField
public Double p0PwFnLCRtBloodUpLimit; //结果上限
@UfActiveRecordField
public Double p0PwFnLCRtBloodLowLimit; //结果下限
@UfActiveRecordField
public Double p0PwFnHCBloodA; //A
@UfActiveRecordField
public Double p0PwFnHCBloodB; //B
@UfActiveRecordField
public Double p0PwFnHCBloodC; //C
@UfActiveRecordField
public Double p0PwFnHCBloodD; //D
@UfActiveRecordField
public Double p0PwFnHCRtBloodUpLimit; //结果上限
@UfActiveRecordField
public Double p0PwFnHCRtBloodLowLimit; //结果下限
//结果
@UfActiveRecordField
public Integer ret1Unit; //单位
@UfActiveRecordField
public Integer ret2Unit; //单位
@UfActiveRecordField
public Integer ret3Unit; //单位
@UfActiveRecordField
public Double ret2UnitFnA; //
@UfActiveRecordField
public Double ret2UnitFnB; //
@UfActiveRecordField
public Double ret3UnitFnA; //
@UfActiveRecordField
public Double ret3UnitFnB; //
}

4
src/main/java/a8k/service/AddSampleService.java

@ -0,0 +1,4 @@
package a8k.service;
public class AddSampleService {
}

92
src/main/java/a8k/service/ProjectColorAllocer.java

@ -0,0 +1,92 @@
package a8k.service;
import a8k.db.DBTableVersion;
import a8k.db.ProjectColor;
import com.iflytop.uf.UfActiveRecord;
import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Component
public class ProjectColorAllocer {
final String[] colors = {
"#ff8283",
"#ffff81",
"#86ff86",
"#ffc491",
"#87f4ff",
"#9191ff",
};
static final Integer dbVersion = 1;
Integer colorIndexMax = 0;
ProjectColor dbGetProjectColor(String projId) {
return UfActiveRecord.findOne(ProjectColor.class, Map.of("projectId", projId));
}
List<ProjectColor> dbGetProjectColors() {
return UfActiveRecord.find(ProjectColor.class);
}
void dbEmptyProjectColors() {
var list = dbGetProjectColors();
for (var projColor : list) {
projColor.delete();
}
}
@PostConstruct
void init() {
//初始化项目颜色
Integer var = DBTableVersion.getTableVersion(ProjectColor.getTableName());
if (!dbVersion.equals(var)) {
initdbdata();
}
var allColors = dbGetProjectColors();
for (var projColor : allColors) {
if (projColor.index > colorIndexMax) {
colorIndexMax = projColor.index;
}
}
}
private void initdbdata() {
dbEmptyProjectColors();
for (String color : colors) {
var projColor = new ProjectColor();
projColor.projectId = "";
projColor.color = color;
projColor.index = 0;
projColor.save();
}
}
//项目颜色
public String getProjectColor(String projId) {
var projColor = dbGetProjectColor(projId);
if (projColor != null) {
colorIndexMax++;
projColor.index = colorIndexMax;
projColor.save();
return projColor.color;
}
var colors = dbGetProjectColors();
//找到index最小的颜色
ProjectColor minColor = null;
for (var color : colors) {
if (minColor == null || color.index < minColor.index) {
minColor = color;
}
}
assert minColor != null;
colorIndexMax++;
minColor.projectId = projId;
minColor.index = colorIndexMax;
minColor.save();
return minColor.color;
}
}

4
src/main/java/a8k/service/UIEventProcesser.java

@ -0,0 +1,4 @@
package a8k.service;
public class UIEventProcesser {
}

1
src/main/java/a8k/service/appeventbus/appevent/A8kCanBusOnConnectEvent.java

@ -2,5 +2,6 @@ package a8k.service.appeventbus.appevent;
public class A8kCanBusOnConnectEvent extends AppEvent {
public A8kCanBusOnConnectEvent() {
super(A8kCanBusOnConnectEvent.class.getSimpleName());
}
}

8
src/main/java/a8k/service/appeventbus/appevent/A8kHardwareReport.java

@ -7,11 +7,13 @@ import org.springframework.lang.NonNull;
* A8k底层硬件上报事件
*/
public class A8kHardwareReport extends AppEvent{
A8kPacket reportPacket;
public A8kHardwareReport(@NonNull A8kPacket packet) {}
public A8kHardwareReport(@NonNull A8kPacket packet) {
super(A8kHardwareReport.class.getSimpleName());
this.reportPacket = packet;
}
A8kPacket getReportPacket(){
public A8kPacket getReportPacket(){
return reportPacket;
}

8
src/main/java/a8k/service/appeventbus/appevent/A8kStateChangeEvent.java

@ -0,0 +1,8 @@
package a8k.service.appeventbus.appevent;
public class A8kStateChangeEvent extends AppEvent {
A8kStateChangeEvent(String displayInfo) {
super(A8kStateChangeEvent.class.getSimpleName());
}
}

6
src/main/java/a8k/service/appeventbus/appevent/AppEvent.java

@ -1,6 +1,8 @@
package a8k.service.appeventbus.appevent;
public class AppEvent {
public String name;
public AppEvent(String name) {
this.name = name;
}
}

2
src/main/java/a8k/service/appeventbus/appevent/AppStepNotifyEvent.java

@ -1,9 +1,11 @@
package a8k.service.appeventbus.appevent;
public class AppStepNotifyEvent extends AppEvent {
String displayInfo;
AppStepNotifyEvent(String displayInfo) {
super(AppStepNotifyEvent.class.getSimpleName());
this.displayInfo = displayInfo;
}

1
src/main/java/a8k/service/appeventbus/appevent/AppWarningNotifyEvent.java

@ -4,6 +4,7 @@ public class AppWarningNotifyEvent extends AppEvent {
String displayInfo;
AppWarningNotifyEvent(String displayInfo) {
super(AppWarningNotifyEvent.class.getSimpleName());
this.displayInfo = displayInfo;
}

34
src/main/java/a8k/service/base/A8kDeviceState.java

@ -0,0 +1,34 @@
package a8k.service.base;
import a8k.service.base.consumable.ConsumableItemGroup;
import a8k.service.base.plate.ReactingPlateState;
import a8k.service.base.reaction_result.ReactionResult;
import a8k.service.base.sample.EmergencyPosState;
import a8k.service.base.sample.SampleInfo;
import a8k.service.base.sample.TubeHolder;
import a8k.service.base.samplecfg.SampleTubeHolderCfg;
import java.util.ArrayList;
import java.util.List;
public class A8kDeviceState {
//耗材
public ConsumableItemGroup consumableItemGroup = null;
//急诊位状态
public EmergencyPosState emergencyPosState = EmergencyPosState.IDLE;
//急诊位样本信息
public SampleInfo emergencySampleInfo = null;
//急诊位反应结果
public ReactionResult emergencyResult = null;
//正在孵育的任务状态
public List<ReactingPlateState> incubatingPlateStates = null;
//当前正在被处理的试管架状态
public TubeHolder processingTubeHolder = null;
//温度
public Integer temperature;
//配置
public List<SampleTubeHolderCfg> cfgs = new ArrayList<>();
Boolean deviceInited = false; //设备是否初始化过
Boolean devicePoweredOffNormally = false; //设备是否正常关机
}

6
src/main/java/a8k/service/base/BloodType.java

@ -0,0 +1,6 @@
package a8k.service.base;
public enum BloodType {
WHOLE_BLOOD,
SERUM;
}

10
src/main/java/a8k/service/base/consumable/ConsumableItemGroup.java

@ -0,0 +1,10 @@
package a8k.service.base.consumable;
import java.util.Date;
public class ConsumableItemGroup {
public Date scanDate = new Date();
public ReactantItem[] reactantItems = new ReactantItem[6];
public TipGroupInfo[] tip = new TipGroupInfo[3];
}

16
src/main/java/a8k/service/base/consumable/ReactantItem.java

@ -0,0 +1,16 @@
package a8k.service.base.consumable;
//反应物,诸如反应板夹小瓶缓冲液大瓶缓冲液...
public class ReactantItem {
public String projId; //项目ID
public String lotVal; //批次号
public String color; //颜色
public Integer num = 0; //数量
public Boolean hasPlateClip = false; //是否有反应板夹 always true
public Boolean hasLargeBufferBottle = false; //是否有大瓶缓冲液
public Boolean hasSmallBufferBottle = false; //是否有小瓶缓冲液
public Boolean hasDetectionMaterial = false; //是否有探测物质
}

5
src/main/java/a8k/service/base/consumable/TipGroupInfo.java

@ -0,0 +1,5 @@
package a8k.service.base.consumable;
public class TipGroupInfo {
public Integer tipNum = 0;//剩余可用数量
}

12
src/main/java/a8k/service/base/plate/PlateState.java

@ -0,0 +1,12 @@
package a8k.service.base.plate;
public enum PlateState {
//赋予中
Incubating,
//孵育完成
Incubated,
//孵育异常
IncubateError,
//板条码异常
PlateCodeError,
}

23
src/main/java/a8k/service/base/plate/ReactingPlateState.java

@ -0,0 +1,23 @@
package a8k.service.base.plate;
import a8k.service.base.reaction_result.ReactionResult;
import a8k.service.base.sample.SampleInfo;
import a8k.service.base.sample.Tube;
import java.util.Date;
public class ReactingPlateState {
String sampleUUID; //样本UUID 系统自动生成
String projectId;//项目id
SampleInfo bindSample; //绑定的样本运行状态
Integer incubationPos; //孵育盘中的位置 0->19
Date startIncubatedTime; //开始孵育时间
Integer targetIncubatedTimeS; //目标孵育时间
PlateState plateState; //孵育盘状态
ReactionResult reactionResult; //反应结果
}

13
src/main/java/a8k/service/base/reaction_result/ReactionResult.java

@ -0,0 +1,13 @@
package a8k.service.base.reaction_result;
public class ReactionResult {
Boolean result0Error;
Boolean result1Error;
Boolean result2Error;
String result0;
String result1;
String result2;
}

7
src/main/java/a8k/service/base/sample/EmergencyPosState.java

@ -0,0 +1,7 @@
package a8k.service.base.sample;
public enum EmergencyPosState {
IDLE,//
PROCESSING,//
PROCESS_COMPLETE,//
}

6
src/main/java/a8k/service/base/sample/EmergencySampleInfo.java

@ -0,0 +1,6 @@
package a8k.service.base.sample;
public class EmergencySampleInfo {
}

18
src/main/java/a8k/service/base/sample/SampleInfo.java

@ -0,0 +1,18 @@
package a8k.service.base.sample;
import a8k.appbase.A8kTubeType;
import java.util.List;
public class SampleInfo {
A8kTubeType tubeType; //管子类型
String sampleUUID; //样本UUID 系统自动生成
String projectId; //项目id,用于查找项目相关信息
String sampleUDPID; //用户输入的样本ID不做逻辑只做展示
String sampleBarcodeID; //用于请求用户信息的条码ID
List<String> projectIds; //项目id,用于查找项目相关信息
}

8
src/main/java/a8k/service/base/sample/Tube.java

@ -0,0 +1,8 @@
package a8k.service.base.sample;
import a8k.appbase.A8kTubeType;
public class Tube {
TubeState tubeState = TubeState.EMPTY; //样本运行状态
SampleInfo sampleInfo; //样本信息
}

12
src/main/java/a8k/service/base/sample/TubeHolder.java

@ -0,0 +1,12 @@
package a8k.service.base.sample;
import a8k.appbase.A8kTubeType;
import a8k.service.base.BloodType;
public class TubeHolder {
public BloodType bloodType = BloodType.WHOLE_BLOOD; //血型
public A8kTubeType tubeHolderType = A8kTubeType.BloodTube; //管子类型
public TubeHolderState tubeHolderState = TubeHolderState.TubeHolderStateIdle; //管子状态
public Tube[] tubes = new Tube[10]; //管子
public Integer processingTubeIndex = -1; //当前管子索引
}

7
src/main/java/a8k/service/base/sample/TubeHolderState.java

@ -0,0 +1,7 @@
package a8k.service.base.sample;
public enum TubeHolderState {
TubeHolderStateIdle, //空闲
TubeHolderStateProcessing, //处理中
TubeHolderStateProcessed, //处理完成
}

18
src/main/java/a8k/service/base/sample/TubeState.java

@ -0,0 +1,18 @@
package a8k.service.base.sample;
public enum TubeState {
//
EMPTY,
//待处理
READY,
//预处理中
PRE_PROCESSING,
//待采样
TO_BE_SAMPLED,
//采样中
SAMPLING,
//采样完成
SAMPLED,
//处理完成
PROCESS_COMPLETE,
}

8
src/main/java/a8k/service/base/samplecfg/SampleTubeCfg.java

@ -0,0 +1,8 @@
package a8k.service.base.samplecfg;
import a8k.service.base.sample.SampleInfo;
import java.util.List;
public class SampleTubeCfg extends SampleInfo {
}

9
src/main/java/a8k/service/base/samplecfg/SampleTubeHolderCfg.java

@ -0,0 +1,9 @@
package a8k.service.base.samplecfg;
import a8k.appbase.A8kTubeType;
public class SampleTubeHolderCfg {
Boolean active;//是否激活
A8kTubeType tubeHolderType = A8kTubeType.BloodTube; //试管架类型
SampleTubeCfg[] sampleTubeCfgs = new SampleTubeCfg[10]; //试管配置
}

78
src/main/java/a8k/service/ctrl_service/AppCtrlService.java

@ -0,0 +1,78 @@
package a8k.service.ctrl_service;
import a8k.appbase.appret.AppRet;
import a8k.controler.engineer.utils.EngineerPageTab;
import a8k.controler.engineer.utils.EnginnerPageAction;
import a8k.service.ProjectColorAllocer;
import a8k.service.base.consumable.ConsumableItemGroup;
import a8k.service.base.consumable.ReactantItem;
import a8k.service.base.consumable.TipGroupInfo;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
@EngineerPageTab(name = "AppCtrlService")
@Component
public class AppCtrlService {
@Resource
ProjectColorAllocer projectColorAllocer;
@EnginnerPageAction(name = "初始化设备")
public AppRet<Object> initDevice() {
return AppRet.success();
}
//启动
@EnginnerPageAction(name = "启动")
public AppRet<Object> startProcess() {
return AppRet.success();
}
//暂停
@EnginnerPageAction(name = "暂停")
public AppRet<Object> pauseProcess() {
return AppRet.success();
}
//急停
@EnginnerPageAction(name = "急停")
public AppRet<Object> forceStopProcess() {
return AppRet.success();
}
//停止
@EnginnerPageAction(name = "停止")
public AppRet<Object> stopProcess() {
return AppRet.success();
}
//关机
@EnginnerPageAction(name = "关机")
public AppRet<Object> shutdown() {
return AppRet.success();
}
//扫描耗材
@EnginnerPageAction(name = "扫描耗材")
public AppRet<ConsumableItemGroup> scanningConsumables() {
ConsumableItemGroup var = new ConsumableItemGroup();
for (int i = 0; i < 6; i++) {
var.reactantItems[i] = new ReactantItem();
var.reactantItems[i].projId = "PROJECT_" + i;
var.reactantItems[i].lotVal = "LOT_" + i;
var.reactantItems[i].color = projectColorAllocer.getProjectColor(var.reactantItems[i].projId);
var.reactantItems[i].hasDetectionMaterial = i % 2 == 0;
var.reactantItems[i].hasSmallBufferBottle = i % 2 == 1;
var.reactantItems[i].hasLargeBufferBottle = i % 2 == 0;
}
var.tip[0] = new TipGroupInfo();
var.tip[1] = new TipGroupInfo();
var.tip[2] = new TipGroupInfo();
return AppRet.success(var);
}
}

11
src/main/java/a8k/service/hardware/SamplesPreProcessModuleCtrlService.java

@ -202,21 +202,16 @@ public class SamplesPreProcessModuleCtrlService implements HardwareCtrlModule {
/**
* 取试管帽,如果试管帽存在
* @param tubeType HighBlood,ShortBlood,Mini,MiniBlood,BulletTube1P5,BulletTube0P5
* @param highTube true/false
*/
@EnginnerPageAction(name = "取试管")
public AppRet<Boolean> takeTubeAndJudgeTubeExist(A8kTubeType tubeType) throws HardwareException, InterruptedException {
logger.info("takeTube tubeType:{}", tubeType);
public AppRet<Boolean> takeTubeAndJudgeTubeExist(Boolean highTube) throws HardwareException, InterruptedException {
/*
* 校验:
* 1.当前摇匀模组设计到的电机是否都处于待机位
*/
if (tubeType != A8kTubeType.HighBlood && tubeType != A8kTubeType.ShortBlood) {
return AppRet.fail(A8kEcode.TubeTypeNotSupport);
}
//Z轴在原点
if (!canBus.stepMotorReadIoState(MId.ShakeModGripperZM, 0)) {
throw new HardwareException(MId.ShakeModGripperZM, A8kEcode.MNotInZeroPos);
@ -237,7 +232,7 @@ public class SamplesPreProcessModuleCtrlService implements HardwareCtrlModule {
throw new HardwareException(MId.ShakeModClampingM, A8kEcode.MNotInZeroPos);
}
boolean isHighBlood = A8kTubeType.HighBlood.equals(tubeType);
boolean isHighBlood = highTube;
boolean tubeCapExist = true;
Integer gripperJudgeCapZPos = isHighBlood ? getGripperJudgeHTubeCapZPos() : getGripperJudgeSTubeCapZPos();
Integer gripperTakeTubeZPos = isHighBlood ? getGripperTakeHTubeZPos() : getGripperTakeSTubeZPos();

76
src/main/java/a8k/service/project_mgr/ProjectItemMgrService.java

@ -0,0 +1,76 @@
package a8k.service.project_mgr;
import a8k.appbase.AppEventListener;
import a8k.appbase.ProjectInfoSimple;
import a8k.appbase.appret.AppRet;
import a8k.controler.engineer.utils.EngineerPageTab;
import a8k.controler.engineer.utils.EnginnerPageAction;
import a8k.db.ProjectInfo;
import a8k.service.appeventbus.AppEventBusService;
import a8k.service.appeventbus.appevent.A8kHardwareReport;
import a8k.service.appeventbus.appevent.AppEvent;
import a8k.service.hardware.canbus.A8kCanBusService;
import a8k.service.hardware.canbus.protocol.A8kPacket;
import a8k.service.hardware.canbus.protocol.CmdId;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Component
@EngineerPageTab(name = "ProjectItemMgr")
public class ProjectItemMgrService implements AppEventListener {
static Logger logger = org.slf4j.LoggerFactory.getLogger(ProjectItemMgrService.class);
@Resource
A8kCanBusService canBus;
@Resource
AppEventBusService eventBus;
@PostConstruct
public void init() {
}
@Override public void onAppEvent(AppEvent event) {
if (event instanceof A8kHardwareReport canPacket) {
A8kPacket packet = canPacket.getReportPacket();
CmdId cmdId = CmdId.valueOf(packet.getCmdId());
if (CmdId.event_a8000_idcard_online.equals(cmdId)) {
logger.info("插入ID卡");
} else if (CmdId.event_a8000_idcard_offline.equals(cmdId)) {
logger.info("拔出ID卡");
}
}
}
ProjectInfo dbGetProjectInfo(String lotName) {
return ProjectInfo.findOne(ProjectInfo.class, Map.of("lotName", lotName));
}
List<ProjectInfoSimple> dbGetProjectInfos() {
var pinfos = ProjectInfo.find(ProjectInfo.class);
List<ProjectInfoSimple> result = new ArrayList<>();
for (var pinfo : pinfos) {
result.add(new ProjectInfoSimple(pinfo));
}
return result;
}
@EnginnerPageAction(name = "获取项目信息(简单)")
public AppRet<List<ProjectInfoSimple>> getProjectInfoSimple() {
return AppRet.success(dbGetProjectInfos());
}
}

158
src/main/java/a8k/service/state_service/A8kStateMgrService.java

@ -1,5 +1,7 @@
package a8k.service.state_service;
import a8k.controler.engineer.utils.EngineerPageTab;
import a8k.service.base.A8kDeviceState;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.iflytop.uf.UfActiveRecord;
@ -12,25 +14,22 @@ import org.springframework.boot.json.JacksonJsonParser;
import org.springframework.stereotype.Component;
@Component
@EngineerPageTab(name = "A8kStateMgrService")
public class A8kStateMgrService {
/*
* 该服务约定:
* 1. 前端只能读取该服务中的状态不能设置设置只能通过其他服务进行设置
*
*
*/
public static final Logger logger = LoggerFactory.getLogger(A8kStateMgrService.class);
public A8kDeviceState deviceState = new A8kDeviceState();
// AppUsr appusr; //用户是否登录
// AppUsr debugPageUsr; //调试页面用户是否登录
Boolean deviceInited = false; //设备是否初始化过
Boolean devicePoweredOffNormally = false; //设备是否正常关机
@PostConstruct
public void init() {
// @PostConstruct
// public void init() {
// var list = UfActiveRecord.find(A8kStateDB.class);
// if (list.isEmpty()) {
// updateA8kState(new A8kState());
@ -64,79 +63,76 @@ public class A8kStateMgrService {
// public boolean isDebugPageUsrLogin() {
// return debugPageUsr != null;
// }
// //
// // 设备初始化状态
// //
//
// 设备初始化状态
// /**
// * 机器是否初始化过
// * @return 机器是否初始化过
// */
// public boolean isDeviceInited() {
// return deviceInited;
// }
//
/**
* 机器是否初始化过
* @return 机器是否初始化过
*/
public boolean isDeviceInited() {
return deviceInited;
}
/**
* @return 返回上一次设备是否正常关机
*/
public boolean isTheDevicePoweredOffNormally() {
return devicePoweredOffNormally;
}
/**
* 设备初始化完成开机后设备初始化完成时候调用该方法
*/
public void setDeviceInited() {
this.deviceInited = true;
this.devicePoweredOffNormally = false;
A8kState state = getA8kState();
state.devicePoweredOffNormally = false;
updateA8kState(state);
}
public void setDevicePoweredOffNormally() {
this.devicePoweredOffNormally = true;
A8kState state = getA8kState();
state.devicePoweredOffNormally = true;
updateA8kState(state);
}
A8kState getA8kState() {
var one = UfActiveRecord.find(A8kStateDB.class).get(0);
assert one != null;
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.readValue(one.stateJson, A8kState.class);
} catch (JsonProcessingException e) {
assert false;
return null;
}
}
void updateA8kState(A8kState state) {
var list = UfActiveRecord.find(A8kStateDB.class);
A8kStateDB one;
if (list.isEmpty()) {
one = new A8kStateDB();
} else {
one = list.get(0);
}
ObjectMapper mapper = new ObjectMapper();
try {
one.stateJson = mapper.writeValueAsString(state);
one.save();
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
// /**
// * @return 返回上一次设备是否正常关机
// */
// public boolean isTheDevicePoweredOffNormally() {
// return devicePoweredOffNormally;
// }
//
// /**
// * 设备初始化完成开机后设备初始化完成时候调用该方法
// */
// public void setDeviceInited() {
// this.deviceInited = true;
// this.devicePoweredOffNormally = false;
//
// A8kState state = getA8kState();
// state.devicePoweredOffNormally = false;
// updateA8kState(state);
// }
//
// public void setDevicePoweredOffNormally() {
// this.devicePoweredOffNormally = true;
//
// A8kState state = getA8kState();
// state.devicePoweredOffNormally = true;
// updateA8kState(state);
// }
//
//
// A8kState getA8kState() {
// var one = UfActiveRecord.find(A8kStateDB.class).get(0);
// assert one != null;
//
// ObjectMapper mapper = new ObjectMapper();
// try {
// return mapper.readValue(one.stateJson, A8kState.class);
// } catch (JsonProcessingException e) {
// assert false;
// return null;
// }
// }
//
// void updateA8kState(A8kState state) {
// var list = UfActiveRecord.find(A8kStateDB.class);
//
// A8kStateDB one;
// if (list.isEmpty()) {
// one = new A8kStateDB();
// } else {
// one = list.get(0);
// }
//
// ObjectMapper mapper = new ObjectMapper();
//
// try {
// one.stateJson = mapper.writeValueAsString(state);
// one.save();
// } catch (JsonProcessingException e) {
// throw new RuntimeException(e);
// }
// }
//}

7
src/main/resources/db/migration/V100_5__create_table_DBVersion.sql

@ -0,0 +1,7 @@
CREATE TABLE "DBTableVersionTable"
(
"id" text NOT NULL,
"tableName" text,
"version" integer,
PRIMARY KEY ("id")
);

8
src/main/resources/db/migration/V100_6__create_table_ProjectColorTable.sql

@ -0,0 +1,8 @@
CREATE TABLE "ProjectColorTable"
(
"id" text NOT NULL,
"color" text,
"projectId" text,
"index" integer,
PRIMARY KEY ("id")
);
Loading…
Cancel
Save