Browse Source

update

tags/v0
zhaohe 7 months ago
parent
commit
98bb9264d7
  1. 2
      src/main/java/a8k/app/a8ktype/state/SampleInfo.java
  2. 8
      src/main/java/a8k/app/service/mainctrl/mainflowctrl/MainFlowCtrlScheduler.java
  3. 19
      src/main/java/a8k/app/service/mainctrl/mainflowctrl/processer/MainFlowStateChangeProcesser.java
  4. 8
      src/main/java/a8k/app/service/statemgr/ConsumablesMgrService.java
  5. 8
      src/main/java/a8k/extui/mgr/ExtApiPageGroupCfgMgr.java
  6. 289
      src/main/java/a8k/extui/page/extapp/OptFullFlowVerificationPage.java

2
src/main/java/a8k/app/a8ktype/state/SampleInfo.java

@ -9,7 +9,7 @@ public class SampleInfo implements Serializable {
public String sampleId = ""; //样本ID-系统生成-唯一标识一个样本
public Boolean isHighTube = false;
public Boolean isEmergency = false;
public BloodType bloodType = BloodType.WHOLE_BLOOD; //血液类型
public BloodType bloodType = BloodType.SERUM_OR_PLASMA; //血液类型
public String sampleBarcode = ""; //用于请求用户信息的条码ID
public String userid = ""; //用户输入的样本ID不做逻辑只做展示

8
src/main/java/a8k/app/service/mainctrl/mainflowctrl/MainFlowCtrlScheduler.java

@ -280,6 +280,14 @@ public class MainFlowCtrlScheduler implements ApplicationListener<ApplicationSta
changeWorkState(A8kWorkState.WORKING);
}
} else if (state.stopActionPending) {
if (state.workState != A8kWorkState.IDLE) {
changeWorkState(A8kWorkState.IDLE);
}

19
src/main/java/a8k/app/service/mainctrl/mainflowctrl/processer/MainFlowStateChangeProcesser.java

@ -1,7 +1,9 @@
package a8k.app.service.mainctrl.mainflowctrl.processer;
import a8k.app.service.mainctrl.TubeHolderSettingMgrService;
import a8k.app.service.mainctrl.mainflowctrl.base.IMainFlowStateChangeProcesser;
import a8k.app.service.mainctrl.mainflowctrl.base.MainFlowProcesser;
import a8k.app.service.statemgr.ConsumablesMgrService;
import a8k.app.service.statemgr.IncubationPlateStateMgrService;
import a8k.app.service.statemgr.ProjectContextMgrService;
import a8k.app.service.statemgr.TubeStateMgrService;
@ -34,6 +36,8 @@ public class MainFlowStateChangeProcesser implements IMainFlowStateChangeProcess
IncubationPlateStateMgrService incubationPlateStateMgrService;
@Resource
TubeStateMgrService tubeStateMgrService;
@Resource
ConsumablesMgrService consumablesMgrService;
@Resource
ProjectContextMgrService projectContextMgrService;
@ -53,7 +57,9 @@ public class MainFlowStateChangeProcesser implements IMainFlowStateChangeProcess
virtualDevice.doVirtualThings("清空设备");
return;
}
//光学模组清空
optScanModuleCtrlService.dropPlate();
//弹出所有孵育盘
ejectAllPlates();
//弹出试管架
tubeFeedingCtrlService.ejectTubeHolder();
@ -61,15 +67,20 @@ public class MainFlowStateChangeProcesser implements IMainFlowStateChangeProcess
hbotMoveExCtrlService.dropTip();
//hbot快速归零
hbotMoveExCtrlService.moveQuickToZero();
incubationPlateStateMgrService.resetAll();
tubeStateMgrService.resetAll();
}
@Override
public void onStop() throws AppException {
//物理清空设备
doClearDevice();
//清空孵育盘状态
incubationPlateStateMgrService.resetAll();
//清空试管状态
tubeStateMgrService.resetAll();
//清空项目上下文
projectContextMgrService.clearCxts();
//恢复耗材预定状态
consumablesMgrService.bakAllReserveConsumable();
}
@Override

8
src/main/java/a8k/app/service/statemgr/ConsumablesMgrService.java

@ -285,6 +285,14 @@ public class ConsumablesMgrService {
priSetConsumableGroupNum(consumable.getGroup(), num, reserveNum);
}
synchronized public void bakAllReserveConsumable() {
for (var group : ConsumableGroup.values()) {
cState.reactionPlateGroup[group.off].reserveNum = 0;
cState.larBottleGroup[group.off].reserveNum = 0;
cState.littBottleGroup[group.off].reserveNum = 0;
}
}
//
// PRIVATE

8
src/main/java/a8k/extui/mgr/ExtApiPageGroupCfgMgr.java

@ -2,6 +2,7 @@ package a8k.extui.mgr;
import a8k.app.utils.ZList;
import a8k.extui.page.debug.*;
import a8k.extui.page.extapp.*;
import a8k.extui.page.extsetting.db.DeviceActionParameterSettingPage;
import a8k.extui.page.extsetting.db.ProjInfoMgrPage;
import a8k.extui.page.extsetting.db.ReactionRecordMgrDebugPage;
@ -13,15 +14,11 @@ import a8k.extui.page.test.driver.LowLevelBoardVersionPreviewPage;
import a8k.extui.page.test.codetest.OptFormulaTestPage;
import a8k.extui.page.test.codetest.OptFormulaTestPageV2;
import a8k.extui.page.test.driver.PipetteCtrlDriverPage;
import a8k.extui.page.extapp.A8kOptVerification;
import a8k.extui.page.test.frond_end_test.FakeReactionRecordGeneratorPage;
import a8k.extui.page.test.frond_end_test.VirtualEventGeneratorPage;
import a8k.extui.page.extapp.OptModuleParamCalibration;
import a8k.extui.page.extsetting.pos_calibration.*;
import a8k.extui.page.test.stress_test.PipetteGunStressTest;
import a8k.extui.page.extapp.P01PipetteGunVerification;
import a8k.extui.page.extapp.P02A8kTemperaturaVerfication;
import a8k.extui.page.test.verification.*;
import a8k.extui.page.test.verification.P34LiquidOperationTestPage;
import a8k.extui.page.test.verification.P10ProjejIDCardTestPage;
@ -129,7 +126,8 @@ public class ExtApiPageGroupCfgMgr {
new Menu("高级应用", ZList.of(
new Menu("光学标定与验证", ZList.of(
new Menu(A8kOptVerification.class, "光学模组验证"),
new Menu(OptModuleParamCalibration.class, "光学模块参数校准")
new Menu(OptModuleParamCalibration.class, "光学模块参数校准"),
new Menu(OptFullFlowVerificationPage.class,"快速项目检测")
)),
new Menu("验证(过检专用)", ZList.of(
new Menu(P01PipetteGunVerification.class, "移液枪验证"),

289
src/main/java/a8k/extui/page/extapp/OptFullFlowVerificationPage.java

@ -0,0 +1,289 @@
package a8k.extui.page.extapp;
import a8k.OS;
import a8k.app.a8kproj.A8kReactionResultComputer;
import a8k.app.a8kproj.optalgo.type.OptScanResult;
import a8k.app.a8ktype.device.*;
import a8k.app.a8ktype.exception.AppException;
import a8k.app.a8ktype.param.type.A8kSamplePos;
import a8k.app.a8ktype.state.SampleInfo;
import a8k.app.a8ktype.type.ReactionResult;
import a8k.app.a8ktype.type.TubeHolderScanResult;
import a8k.app.dao.db.type.ProjExtInfoCard;
import a8k.app.dao.db.type.a8kidcard.zenum.A8kReactionFlowType;
import a8k.app.hardware.driver.PipetteCtrlDriver;
import a8k.app.service.bases.AppEventBusService;
import a8k.app.service.bases.FrontEndMessageBoxAndEventMgr;
import a8k.app.service.data.ProjIdCardInfoMgrService;
import a8k.app.service.data.ProjInfoMgrService;
import a8k.app.service.data.ReactionRecordMgrService;
import a8k.app.service.lowerctrl.*;
import a8k.app.utils.ProjBuildinInfo;
import a8k.app.utils.ProjInfo;
import a8k.app.utils.ProjInfoReader;
import a8k.app.utils.ZDateUtils;
import a8k.extui.mgr.ExtApiPageMgr;
import a8k.extui.type.ExtApiStatu;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component
public class OptFullFlowVerificationPage {
@Resource
TubeFeedingCtrlService tubeFeedingCtrlService;
@Resource
TubePreProcesModuleExCtrlService tubePreProcesModuleExCtrlService;
TubeHolderScanResult tubeHolderScanResult;
@Resource
PlateBoxCtrlService plateBoxCtrlService;
@Resource
OptScanModuleCtrlService optScanModuleCtrlService;
@Resource
PipetteCtrlDriver pipetteCtrlDriver;
@Resource
HbotMoveExCtrlService hbotMoveExCtrlService;
@Resource
LiquidOperationCtrlService liquidOperationCtrlService;
@Resource
TurnableMoveCtrlService turnableMoveCtrlService;
@Resource
ProjIdCardInfoMgrService projIdCardInfoMgrService;
@Resource
ProjInfoMgrService projInfoMgrService;
@Resource
AppEventBusService appEventBusService;
@Resource
FrontEndMessageBoxAndEventMgr frontEndMessageBoxAndEventMgr;
@Autowired
private ReactionRecordMgrService reactionRecordMgrService;
//
//Config
//
static public class Context {
public SampleInfo sampleInfo = new SampleInfo();
public ProjBuildinInfo projBuildinInfo;
public ProjExtInfoCard projExtInfoCard;
public A8kSamplePos samplePos = A8kSamplePos.EmergencyTubePos;
public ConsumableGroup consumableGroup = ConsumableGroup.CG1;
public Integer consumablePosOff = 0;
public IncubatorPos incubatorPos = IncubatorPos.SPACE01;
public List<ReactionResult> results = new ArrayList<>();
public Boolean isInit = false;
}
static public class State {
public Integer incubateRemainTime;
}
Context cxt = new Context();
State state = new State();
@ExtApiStatu(name = "", group = "样本信息", order = 1, minWidth = "33.3%")
public SampleInfo showSampleInfo() {
return cxt.sampleInfo;
}
@ExtApiStatu(name = "", group = "项目信息", order = 2, minWidth = "33.3%")
public ProjBuildinInfo showProjInfo() {
return cxt.projBuildinInfo;
}
@ExtApiStatu(name = "", group = "项目卡信息", order = 3, minWidth = "33.3%")
public ProjExtInfoCard showProjExtInfoCard() {
return cxt.projExtInfoCard;
}
@ExtApiStatu(name = "", group = "上下文", order = 4, minWidth = "33.3%")
public Object showConsumableInfo() {
return Map.<String, Object>of(
"耗材位置", String.format("%s-%d", cxt.consumableGroup, cxt.consumablePosOff),
"孵育盘位置", cxt.incubatorPos,
"取样位置", cxt.samplePos,
"样本信息是否初始化", cxt.isInit
);
}
@ExtApiStatu(name = "", group = "状态", order = 5, minWidth = "33.3%")
public State showState() {
return state;
}
@ExtApiStatu(name = "", group = "结果", order = 6, minWidth = "33.3%")
public List<ReactionResult> showResults() {
return cxt.results;
}
Integer tippos = 0;
void takeTip() throws AppException {
Boolean takeTip = false;
for (int i = 0; i < 10; i++) {
tippos = tippos % 120;
takeTip = hbotMoveExCtrlService.takeTipNoCheck(TipGroup.TipG1, tippos);
if (takeTip) {
break;
}
tippos++;
}
if (!takeTip) {
throw AppException.ofAECodeError("取Tip失败");
}
}
public void clearDevice() throws AppException {
optScanModuleCtrlService.dropPlate();
optScanModuleCtrlService.pullPlate(IncubatorPos.SPACE01);
optScanModuleCtrlService.dropPlate();
}
void prepareReactionPlate() throws AppException {
plateBoxCtrlService.pushPlateQuick(cxt.consumableGroup, cxt.incubatorPos);
}
void procesSample() throws AppException {
liquidOperationCtrlService.setProjContext(cxt.projBuildinInfo, cxt.projExtInfoCard);
if (!hbotMoveExCtrlService.isHasTip())
takeTip();
if (cxt.projBuildinInfo.reactionFlowType.equals(A8kReactionFlowType.SampleAndBS)) {
//param 小瓶缓冲液位置
var preReactionPos = new PreReactionPos(ConsumableType.SmallBottleBuffer, cxt.consumableGroup, cxt.consumablePosOff);
//param 取样量
Integer sampleVol = ProjInfoReader.getSampleVol(cxt.projBuildinInfo, cxt.projExtInfoCard, cxt.sampleInfo.bloodType);
//action ->刺破
liquidOperationCtrlService.pirceLittleBuffer(preReactionPos);
//action ->取样
liquidOperationCtrlService.takeSample(cxt.samplePos, preReactionPos, sampleVol);
//action ->孵育盘移动到吐液位置
turnableMoveCtrlService.trunableMoveToDropLiquidPos(cxt.incubatorPos); //
//action ->取反应液到反应板上
liquidOperationCtrlService.takePreReactionLiquidToLiquid(preReactionPos); //
} else if (cxt.projBuildinInfo.reactionFlowType.equals(A8kReactionFlowType.SampleAndBSAndProbeSubstance)) {
//param 探测物位置
var preReactionPos = new PreReactionPos(ConsumableType.ProbeSubstance, cxt.consumableGroup, cxt.consumablePosOff);
//param 取样量
Integer sampleVol = ProjInfoReader.getSampleVol(cxt.projBuildinInfo, cxt.projExtInfoCard, cxt.sampleInfo.bloodType);
//action ->取大瓶缓冲液到探测物质
liquidOperationCtrlService.takeLargeBottleBufferLiquidToProbeSubstance(
LargeBufferPos.of(cxt.consumableGroup), preReactionPos, cxt.projBuildinInfo.bigBufferSampleUl);
//action ->取样品
liquidOperationCtrlService.takeSample(cxt.samplePos, preReactionPos, sampleVol);
//action ->孵育盘移动到吐液位置
turnableMoveCtrlService.trunableMoveToDropLiquidPos(cxt.incubatorPos); //
//action ->取反应液到反应板上
liquidOperationCtrlService.takePreReactionLiquidToLiquid(preReactionPos); //
}
}
void incubate() throws AppException {
//等待孵育完成
state.incubateRemainTime = cxt.projBuildinInfo.reactionPlateIncubationTimeMin * 60;
while (state.incubateRemainTime > 0) {
state.incubateRemainTime -= 1;
OS.forceSleep(1000);
}
frontEndMessageBoxAndEventMgr.showInfo("孵育完成");
}
void pullAndScan() throws AppException {
optScanModuleCtrlService.pullPlate(cxt.incubatorPos);
ProjInfo projInfo = new ProjInfo();
projInfo.buildIn = cxt.projBuildinInfo;
projInfo.ext = cxt.projExtInfoCard;
List<OptScanResult> optScanResults = new ArrayList<>();
for (int i = 0; i < cxt.projBuildinInfo.subProjNum; i++) {
var optScanResult = optScanModuleCtrlService.optScan(cxt.projBuildinInfo, i);
ReactionResult result = A8kReactionResultComputer.optComputeResult(cxt.sampleInfo, projInfo, i, optScanResult.analysResult);
cxt.results.add(result);
optScanResults.add(optScanResult);
}
reactionRecordMgrService.addRecord(cxt.sampleInfo, projInfo, optScanResults, cxt.results);
}
public void initSampleInfo() throws AppException {
cxt.sampleInfo.sampleId = ZDateUtils.toID(new Date());
cxt.sampleInfo.userid = cxt.sampleInfo.sampleId;
cxt.sampleInfo.sampleBarcode = cxt.sampleInfo.sampleId;
cxt.sampleInfo.bloodType = BloodType.SERUM_OR_PLASMA;
cxt.sampleInfo.isHighTube = false;
cxt.sampleInfo.isEmergency = true;
cxt.projExtInfoCard = projIdCardInfoMgrService.getMountedProjInfoCard();
Assert.notNull(cxt.projExtInfoCard, "请插入项目卡");
cxt.projBuildinInfo = projInfoMgrService.getProjBuildInInfo(cxt.projExtInfoCard.projId);
cxt.isInit = true;
cxt.incubatorPos = IncubatorPos.SPACE01;
cxt.consumableGroup = ConsumableGroup.CG1;
cxt.consumablePosOff = 0;
}
public void startProcessSample(Boolean scanOnly) throws AppException {
initSampleInfo();
clearDevice();
frontEndMessageBoxAndEventMgr.showInfo("反应板准备");
prepareReactionPlate();
if (!scanOnly) {
frontEndMessageBoxAndEventMgr.showInfo("样本处理");
procesSample();
frontEndMessageBoxAndEventMgr.showInfo("孵育");
incubate();
}
frontEndMessageBoxAndEventMgr.showInfo("扫描");
pullAndScan();
frontEndMessageBoxAndEventMgr.showInfo("丢板");
optScanModuleCtrlService.dropPlate();
frontEndMessageBoxAndEventMgr.showInfo("结束");
}
public void sampleAndIncubateAndScan() throws AppException {
startProcessSample(false);
}
public void scanOnly(Integer scanTimes) throws AppException {
for (int i = 0; i < scanTimes; i++) {
startProcessSample(true);
}
}
@Resource
ExtApiPageMgr extApiPageMgr;
@PostConstruct
public void init() {
var page = extApiPageMgr.newPage(this);
page.addFunction("取样.孵育.扫描", this::sampleAndIncubateAndScan);
page.addFunction("只扫描", this::scanOnly);
extApiPageMgr.addPage(page);
}
}
Loading…
Cancel
Save