From f09087378582556ecaaf1760e59df0258751aaaf Mon Sep 17 00:00:00 2001 From: zhaohe Date: Sat, 12 Oct 2024 20:30:42 +0800 Subject: [PATCH] update --- app.db | Bin 225280 -> 225280 bytes .../appctrl/mainflowctrl/CondtionMgrService.java | 14 +- .../mainflowctrl/MainFlowCtrlScheduler.java | 8 +- .../action/DO_CLEAR_ERROR_BEFORE_WORK.java | 3 +- .../action/DO_FINISH_TUBE_PROCESS.java | 99 ++++++++ .../action/DO_PROCESS_ERROR_PLATE.java | 27 ++- .../mainflowctrl/action/DO_PROCESS_ERROR_TUBE.java | 88 ------- .../app/appctrl/mainflowctrl/action/DO_RESUME.java | 1 + .../mainflowctrl/action/PLATE_OPT_SCAN.java | 14 +- .../action/PROCESS_INCUBATE_COMPLETED_PLATE.java | 33 ++- .../action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java | 5 +- .../action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java | 3 +- .../mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java | 19 +- .../mainflowctrl/action/SEQ4_PRE_PROCESS.java | 14 +- .../appctrl/mainflowctrl/action/SEQ5_PROCESS.java | 63 +++-- .../mainflowctrl/action/SEQ6_POST_PROCESS.java | 13 +- .../mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java | 10 +- .../mainflowctrl/base/A8kActionStepType.java | 2 +- .../appctrl/mainflowctrl/base/A8kStepAction.java | 4 + .../EmergencySamplePosStateMgrService.java | 2 +- .../a8k/service/app/appstate/GStateService.java | 8 +- .../app/appstate/OptScanModuleStateMgrService.java | 15 -- .../appstate/ProjectProcessContextMgrService.java | 261 ++++++++++++++------- .../app/appstate/type/IncubationSubTank.java | 7 + .../service/app/appstate/type/OptScanModule.java | 7 +- .../java/a8k/service/app/appstate/type/Tube.java | 15 +- .../a8k/service/app/appstate/type/TubeHolder.java | 6 +- .../app/appstate/type/state/ProjProcessState.java | 1 - .../a8k/service/db/DeviceStatisticDBService.java | 88 +++++++ .../java/a8k/service/db/type/DeviceStatistic.java | 10 + .../java/a8k/service/db/type/StatisticType.java | 6 + src/main/java/a8k/utils/ZSqliteJdbcHelper.java | 10 + src/main/java/a8k/utils/ZStringUtils.java | 46 ++++ 33 files changed, 617 insertions(+), 285 deletions(-) create mode 100644 src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java delete mode 100644 src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_TUBE.java create mode 100644 src/main/java/a8k/service/db/DeviceStatisticDBService.java create mode 100644 src/main/java/a8k/service/db/type/DeviceStatistic.java create mode 100644 src/main/java/a8k/service/db/type/StatisticType.java create mode 100644 src/main/java/a8k/utils/ZStringUtils.java diff --git a/app.db b/app.db index c2281b157c471e3f4d219ad45f2681f8ff5036d1..e7f507590ba827197fa01dea68ba4a77e965c33d 100644 GIT binary patch delta 8410 zcmeI2Yit}>6~|}B>wWKzlTfEPiQ_b(c2g(0cV>2HmbQu0JW12oN%LrG9KYfQHz9H3 zZD>O1&BSUeKtfHCu!KNJ(4+_iQmJ4O5(q(62`b)BTJLYqz4w34|DJm{S8kTB+$_D&v%L2WMNw>cs_^6$rQ_(eK|||(!<~3` zLjCT9_R?@Zt4=HW#?+tFmm9?q?TDJXI=Zl@aq6HprfLhj8?PVI20Aq5g~fj!(H6F* z7xtv#lN80Zu3pNlq*T4SqCPowX6Dl5+}!x2b9#KfK3Sigug^|LU%BV=2mjW+ula_) zfxiCPll^_OXX`VkX3h`x^*4XDbFx0u-&db`x*mS@@Wr{-tJ7!ei(fgUtxqkSSlHQs z!QH1W&OfSM*A{j(dX8(|socV@%u3ryCRxC3tN~keT38A*( zz+V$yaGYa%hxhLqe{lcs@J>pN(J?X{PuM0R=;+v%136_aieXp05R_5JF$j)9M#lyp z_K8w3D%MCO|`gZ6lxx zz(*p0zpO9<2T%`S{<>Cx*ees&S|~&nFRKN>o(RA{7?cwsDi|;U*c}0e?GQmJngwXR zWmkl#wg5RfKnF-FZ{c4s`~%P-G3EdRW}M2`M>3#m%mV+DsL|Rr}TR1#nOq=#^SrhpA@(SY+3w6=GT+Wz%IwZ8PrsG^M*705 z>$ybTD?!>&3%_?z>s#M9~kJJUrlNsVwzsFb+)1xl9UWBn(D3BTURq!_+ z2#hZRc^=>eGB5+yM_ur~2;(`v$Ak@^!L9=CM_sVL2;`Z*fGRcYXJCNT1qX~Up7nc- zgB=Y#kh)-kVTQquXA#f+J*ZkkH3v3GUGTv$Bp7c4@R$nT!oUfsyEDR=fvgqNvWO*i z8P?oeg|0iIP@t;^wbAv#HjL-%reI7wAtCGbfNAc4)Fi&H9%P|a5V{TpP_PLC|vTj(4VK!v90cVCbx~^Xe@)?4&Tj+XM5`&Z5VBG1}B|#Bg ziQ6Y1Lu)Nr2{ol%98@Ll+BV1I+t)dQ%?yTPs-H?<+?2-yMU>x%wM{Y&~2 zx}&Gdzb;=d&zHBC_0pe8-z;4$?J3<+yj6Uq$chgaR~6nVGz!la9x1HL|0Dmy{AcsW z^ZmKoxu52)<;HWHvhQVomR-!wWX-Ia`Bmo2nbVnCCX@b6`m5=4>HE{U&fj)^t#hvP zfzEvDcd3_BPo}n}3LWhC9oIX~cWmn@YHw;cw0UhvE2)1_UsmhtcD1bh5k?1ph}+v{ zmf=Z8(vY}o;t{WYTb&BH3vpK`Fj!|uLgKDUK(NYSEyV3F!0y zsRvBZsA8mo*IB4pmJz$DrU9+GQ9H)M7hyuqQUZfpAR%Wl9-(+-Ld}AYw024~G^>VP zSjd@=4P!|ys!%hRfKZ0oA0cNpp0RNT2stzHNEIVO&9sNG*4ZB~Km}Wkkh4<`Qw`)a zZKvu;RU_0)#Uq5_)>+8ek-*@Q2|2X{1ZRLyQxymcUDBf2*tN)pPh2H7jNPU^Ped<|$>o4()<55?#qEe`SBO=`Ys{tmWPk+aj|nMXxR96P39-wB z{GSVXF&;6om2n-PjwcM9U%V(k5hmcIWQ^mPNatW)lNZ8Bl%RO`=OR88Pc(N6*7^#d z9*dYYJa=A@^D<#IMYL)lW>m!UGQlt+on*O+Ps)fyU~l0f&Lt4xlxLK370<;ZQV+>h zJexpZNw|m~Z$~gM=lOC)4^-q#J0wKlAiNY$#}gJ#M+!Fu($xi5@nn3E zYB;$l<)t_sM=;xxZi2arQ*nrGS$OWe6ene(d3^=T1*wIH#YLPDM0o$fh_qZ>#qszc z!S`SO*I!)36Y)gV!TkqUaV!DBHpEr@Xaa%Lk&8ImB!d1M&pmXN#BX@GijOrBzx|d7 z>~&nk;|YXlBwOb%uHvII65O7M?`>%fS1+iz>6lM6zf;8ovS0{sR1U!K`|W6VdqhSs zA-NV8{ct>iPItclJ`#_ZSVAuPp?HGg{+Ww@upP0QyQ#Oj1XmS^-hhjOOds6X!U-H6 l1D<=~*$j^b&mcS%c=&%-pzsX%5C1*?c|&7pq~phH{|CuhIZOZm delta 285 zcmZp8z}xVEcY>6V%q#{526G@b17bb~2BxJGb&Qx~W;G_XCNOSIU|QnO!Oob>z^}z} ze>-0QQz#=F14C1EQ{MLUK&Dtmrl#EO$AXwNn3)(orhf=!YM#D3oM{IyTT>oT84xtb zHD!avw*$pN%CojhMKX!8a5m+zi<_G>w)0Q74`&kF?jOsvk!jKg79JO7eg^*Y{PXzp z`0b_(Brr8>Rurgb+Ri_j=_Ajw0w#g&j0>3l%WoH0!1Mu1PBsuwT=sy;0U;(XFe!n> t)EH>J5fEzwu@(?(0", ZStringUtils.leftAlignStr(key.step.name(), '-', 35)); + logger.info("Relate {} ", key.logCxtState()); beforeDoWhat(key.step); try { - logger.info("执行动作:{} ++++++++++++++++++++", key.step); key.doaction(); - logger.info("执行动作完成:{} +++++++", key.step); return new A8kErrorContext(key.step, null); } catch (AppException appe) { return new A8kErrorContext(key.step, appe.error); + } finally { + logger.info("{}------<", ZStringUtils.leftAlignStr(key.step.name(), '-', 35)); } + } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_CLEAR_ERROR_BEFORE_WORK.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_CLEAR_ERROR_BEFORE_WORK.java index 39165c6..76fd1a3 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_CLEAR_ERROR_BEFORE_WORK.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_CLEAR_ERROR_BEFORE_WORK.java @@ -27,7 +27,7 @@ public class DO_CLEAR_ERROR_BEFORE_WORK extends A8kStepAction { } @Resource - GStateService gstate; + GStateService gstate; @Resource CondtionMgrService cms; @Resource @@ -65,4 +65,5 @@ public class DO_CLEAR_ERROR_BEFORE_WORK extends A8kStepAction { A8kPublicResourceType.PlatesBoxModule ); } + } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java new file mode 100644 index 0000000..3205bc0 --- /dev/null +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java @@ -0,0 +1,99 @@ +package a8k.service.app.appctrl.mainflowctrl.action; + +import a8k.OS; +import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService; +import a8k.service.app.appctrl.mainflowctrl.base.A8kActionStepType; +import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction; +import a8k.service.app.appstate.GStateService; +import a8k.service.app.appstate.IncubationPlateStateMgrService; +import a8k.service.app.appstate.OptScanModuleStateMgrService; +import a8k.service.app.appstate.ProjectProcessContextMgrService; +import a8k.service.app.appstate.resource.A8kPublicResourceType; +import a8k.service.app.appstate.type.MainFlowCtrlState; +import a8k.service.app.appstate.type.Tube; +import a8k.service.app.appstate.type.state.TubeState; +import a8k.service.debug.AppDebugHelperService; +import a8k.type.exception.AppException; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 处理错误的试管 + */ +@Component +public class DO_FINISH_TUBE_PROCESS extends A8kStepAction { + static Logger logger = LoggerFactory.getLogger(DO_FINISH_TUBE_PROCESS.class); + + DO_FINISH_TUBE_PROCESS() { + super(A8kActionStepType.DO_FINISH_TUBE_PROCESS); + } + + @Resource + GStateService gstate; + @Resource + CondtionMgrService cms; + @Resource + IncubationPlateStateMgrService incubationPlateStateMgrService; + @Resource + OptScanModuleStateMgrService optScanModuleStateMgrService; + @Resource + AppDebugHelperService appDebugHelper; + @Resource + ProjectProcessContextMgrService projectProcessContextMgrService; + + + MainFlowCtrlState mfcs; + + @PostConstruct + void init() { + mfcs = gstate.mainFlowCtrlState; + } + + + @Override public void doaction() throws AppException { + //ProcessErrorBeforeContinue + + Tube tube = gstate.getCurProcessingTube(); + assert tube != null; + if(tube.getState().equals(TubeState.POST_PROCESSED)){ + projectProcessContextMgrService.finishedTubeProcess(); + return; + } + + if (appDebugHelper.isDebug()) { + logger.info("处理错误试管:{}", tube.getSampleId()); + logger.info("复位摇匀模组"); + OS.forceSleep(4000); + //复位摇匀模组 + logger.info("复位HBOT"); + //复位HBOT + OS.forceSleep(4000); + } + projectProcessContextMgrService.finishedTubeProcess(); + } + + @Override public Boolean checkCondition() { + Boolean cond1 = cms.isCanDoAction(); + Boolean cond2 = cms.isHasSomeErrorTubeToBeProcessed() || cms.isHasPostProcessedTube(); + return cond1 && cond2; + } + + @Override public List getResourceList() { + return List.of( + A8kPublicResourceType.ShakeModule, + A8kPublicResourceType.HBOT + ); + } + + @Override public String logCxtState() { + var tube = gstate.getCurProcessingTube(); + if (tube == null) + return ""; + return String.format("[sid: %s, tanpos: %s]", tube.getSampleId(), tube.getPos()); + } +} diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_PLATE.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_PLATE.java index de1a6ed..68013cd 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_PLATE.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_PLATE.java @@ -7,6 +7,7 @@ import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction; import a8k.service.app.appstate.GStateService; import a8k.service.app.appstate.IncubationPlateStateMgrService; import a8k.service.app.appstate.OptScanModuleStateMgrService; +import a8k.service.app.appstate.ProjectProcessContextMgrService; import a8k.service.app.appstate.resource.A8kPublicResourceType; import a8k.service.app.appstate.type.IncubationSubTank; import a8k.service.app.appstate.type.MainFlowCtrlState; @@ -33,15 +34,17 @@ public class DO_PROCESS_ERROR_PLATE extends A8kStepAction { } @Resource - GStateService gstate; + GStateService gstate; @Resource - CondtionMgrService cms; + CondtionMgrService cms; @Resource - IncubationPlateStateMgrService incubationPlateStateMgrService; + IncubationPlateStateMgrService incubationPlateStateMgrService; @Resource - OptScanModuleStateMgrService optScanModuleStateMgrService; + OptScanModuleStateMgrService optScanModuleStateMgrService; @Resource - AppDebugHelperService appDebugHelperService; + AppDebugHelperService appDebugHelperService; + @Resource + ProjectProcessContextMgrService projectProcessContextMgrService; MainFlowCtrlState mfcs; @@ -68,8 +71,8 @@ public class DO_PROCESS_ERROR_PLATE extends A8kStepAction { OS.forceSleep(3000); } // - optScanModuleStateMgrService.newPlateToOptScanPos(errorTank); - optScanModuleStateMgrService.dropPlate(); + projectProcessContextMgrService.newPlateToOptScanPos(errorTank); + projectProcessContextMgrService.dropPlate(); incubationPlateStateMgrService.resetIncubatorPos(errorTank.getPos()); } } @@ -82,6 +85,14 @@ public class DO_PROCESS_ERROR_PLATE extends A8kStepAction { } @Override public List getResourceList() { - return List.of(); + return List.of(A8kPublicResourceType.OPTModule, A8kPublicResourceType.IncubationPlateModule); + } + + @Override public String logCxtState() { + var errorTank = incubationPlateStateMgrService.getErrorPlate(); + if (errorTank == null) { + return ""; + } + return String.format("[sid: %s, proj: %s tanpos: %s]", errorTank.getSampleId(), errorTank.getProjIndex(), errorTank.getPos()); } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_TUBE.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_TUBE.java deleted file mode 100644 index 23101b2..0000000 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_TUBE.java +++ /dev/null @@ -1,88 +0,0 @@ -package a8k.service.app.appctrl.mainflowctrl.action; - -import a8k.OS; -import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService; -import a8k.service.app.appctrl.mainflowctrl.base.A8kActionStepType; -import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction; -import a8k.service.app.appstate.GStateService; -import a8k.service.app.appstate.IncubationPlateStateMgrService; -import a8k.service.app.appstate.OptScanModuleStateMgrService; -import a8k.service.app.appstate.ProjectProcessContextMgrService; -import a8k.service.app.appstate.resource.A8kPublicResourceType; -import a8k.service.app.appstate.type.MainFlowCtrlState; -import a8k.service.app.appstate.type.Tube; -import a8k.service.app.appstate.type.state.TubeState; -import a8k.service.debug.AppDebugHelperService; -import a8k.type.exception.AppException; -import jakarta.annotation.PostConstruct; -import jakarta.annotation.Resource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import java.util.List; - -/** - * 处理错误的试管 - */ -@Component -public class DO_PROCESS_ERROR_TUBE extends A8kStepAction { - static Logger logger = LoggerFactory.getLogger(DO_PROCESS_ERROR_TUBE.class); - - DO_PROCESS_ERROR_TUBE() { - super(A8kActionStepType.DO_PROCESS_ERROR_TUBE); - } - - @Resource - GStateService gstate; - @Resource - CondtionMgrService cms; - @Resource - IncubationPlateStateMgrService incubationPlateStateMgrService; - @Resource - OptScanModuleStateMgrService optScanModuleStateMgrService; - @Resource - AppDebugHelperService appDebugHelper; - @Resource - ProjectProcessContextMgrService projectProcessContextMgrService; - - - MainFlowCtrlState mfcs; - - @PostConstruct - void init() { - mfcs = gstate.mainFlowCtrlState; - } - - - @Override public void doaction() throws AppException { - //ProcessErrorBeforeContinue - - Tube tube = gstate.getCurProcessingTube(); - assert tube != null; - - if (appDebugHelper.isDebug()) { - logger.info("处理错误试管:{}", tube.getSampleId()); - logger.info("复位摇匀模组"); - OS.forceSleep(4000); - //复位摇匀模组 - logger.info("复位HBOT"); - //复位HBOT - OS.forceSleep(4000); - } - projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.PROCESS_COMPLETE); - } - - @Override public Boolean checkCondition() { - Boolean cond1 = cms.isCanDoAction(); - Boolean cond2 = cms.isHasSomeErrorTubeToBeProcessed(); - return cond1 && cond2; - } - - @Override public List getResourceList() { - return List.of( - A8kPublicResourceType.ShakeModule, - A8kPublicResourceType.HBOT - ); - } -} diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_RESUME.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_RESUME.java index c15cbbe..c5e5b39 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_RESUME.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_RESUME.java @@ -47,4 +47,5 @@ public class DO_RESUME extends A8kStepAction { @Override public List getResourceList() { return List.of(); } + } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PLATE_OPT_SCAN.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PLATE_OPT_SCAN.java index cd20628..f9de5de 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PLATE_OPT_SCAN.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PLATE_OPT_SCAN.java @@ -66,20 +66,17 @@ public class PLATE_OPT_SCAN extends A8kStepAction { OptScanModule optScanModule = gstate.getOptScanModule(); ProjProcessContext ctx = projectProcessContextMgrService.getProjProcessContext(optScanModule.getSampleId(), optScanModule.getProjIndex()); - optScanModuleStateMgrService.startScanPlate(); + projectProcessContextMgrService.startScanPlate(); logger.info("扫描板夹"); //记录扫描结果 if (appDebugHelper.isDebug()) { - logger.info("VIRTUAL_DO.扫描板夹成功"); OS.forceSleep(3000); } else { - } //修改板夹状态 - - projectProcessContextMgrService.changeContextStateTo(optScanModule.getSampleId(), optScanModule.getProjIndex(), ProjProcessState.FINISH); - optScanModuleStateMgrService.dropPlate(); + projectProcessContextMgrService.dropPlate(); + projectProcessContextMgrService.finishProcessProj(optScanModule.getSampleId(), optScanModule.getProjIndex()); reactionRecordMgrService.addRecord(ctx, new ReactionResult(ReactionResultStatus.SUCCESS, "12.8 mg/L"), new ReactionResult(ReactionResultStatus.ERROR_RESULT_OUT_OF_RANGE, "")); @@ -96,4 +93,9 @@ public class PLATE_OPT_SCAN extends A8kStepAction { A8kPublicResourceType.OPTModule ); } + + @Override public String logCxtState() { + OptScanModule optScanModule = gstate.getOptScanModule(); + return String.format("[sid: %s, proj:%s ]", optScanModule.getSampleId(), optScanModule.getProjInfoStr()); + } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PROCESS_INCUBATE_COMPLETED_PLATE.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PROCESS_INCUBATE_COMPLETED_PLATE.java index ad63e88..6693522 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PROCESS_INCUBATE_COMPLETED_PLATE.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PROCESS_INCUBATE_COMPLETED_PLATE.java @@ -7,9 +7,12 @@ import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction; import a8k.service.app.appstate.GStateService; import a8k.service.app.appstate.IncubationPlateStateMgrService; import a8k.service.app.appstate.OptScanModuleStateMgrService; +import a8k.service.app.appstate.ProjectProcessContextMgrService; import a8k.service.app.appstate.resource.A8kPublicResourceType; +import a8k.service.app.appstate.type.IncubationPlate; import a8k.service.app.appstate.type.IncubationSubTank; import a8k.service.app.appstate.type.MainFlowCtrlState; +import a8k.service.app.appstate.type.ProjProcessContext; import a8k.service.app.appstate.type.state.IncubationSubTankState; import a8k.service.debug.AppDebugHelperService; import a8k.type.exception.AppException; @@ -33,15 +36,17 @@ public class PROCESS_INCUBATE_COMPLETED_PLATE extends A8kStepAction { } @Resource - GStateService gstate; + GStateService gstate; @Resource - CondtionMgrService cms; + CondtionMgrService cms; @Resource - IncubationPlateStateMgrService incubationPlateStateMgrService; + IncubationPlateStateMgrService incubationPlateStateMgrService; @Resource - OptScanModuleStateMgrService optScanModuleStateMgrService; + OptScanModuleStateMgrService optScanModuleStateMgrService; @Resource - AppDebugHelperService appDebugHelper; + AppDebugHelperService appDebugHelper; + @Resource + ProjectProcessContextMgrService projectProcessContextMgrService; MainFlowCtrlState mfcs; @@ -51,24 +56,27 @@ public class PROCESS_INCUBATE_COMPLETED_PLATE extends A8kStepAction { mfcs = gstate.mainFlowCtrlState; } + IncubationSubTank getToBeProcessedTank() { + return incubationPlateStateMgrService.getOneExpiredPlate(); + } + @Override public void doaction() throws AppException { - IncubationSubTank tank = incubationPlateStateMgrService.getOneExpiredPlate(); + IncubationSubTank tank = getToBeProcessedTank(); if (tank == null) { return; } if (appDebugHelper.isDebug()) { - logger.info("VIRTUAL_DO.推出板夹到光学模组,{}", tank.getPos()); OS.forceSleep(3000); } - optScanModuleStateMgrService.newPlateToOptScanPos(tank); + projectProcessContextMgrService.newPlateToOptScanPos(tank); incubationPlateStateMgrService.resetIncubatorPos(tank.getPos()); } @Override public Boolean checkCondition() { Boolean cond1 = cms.isCanDoAction(); - Boolean cond2 = incubationPlateStateMgrService.isHasExpiredPlate(); + Boolean cond2 = getToBeProcessedTank() != null; Boolean cond3 = optScanModuleStateMgrService.isEmpty(); return cond1 && cond2 && cond3; } @@ -79,4 +87,11 @@ public class PROCESS_INCUBATE_COMPLETED_PLATE extends A8kStepAction { A8kPublicResourceType.IncubationPlateModule ); } + + @Override public String logCxtState() { + IncubationSubTank tank = getToBeProcessedTank(); + if (tank == null) + return ""; + return String.format("[sid:%s, proj:%s tanpos:%s]", tank.getSampleId(), tank.getProjInfoStr(), tank.getPos()); + } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java index 7425c4b..dfc3d18 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java @@ -5,7 +5,6 @@ import a8k.service.app.appstate.ProjectProcessContextMgrService; import a8k.service.app.appstate.type.Tube; import a8k.service.bases.AppEventBusService; import a8k.service.bases.appevent.AppWarningNotifyEvent; -import a8k.hardware.A8kCanBusService; import a8k.hardware.type.a8kcanprotocol.A8kEcode; import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService; import a8k.service.app.appctrl.TubeSettingMgrService; @@ -187,7 +186,7 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { } } //设置试管架状态 - tubeholder.state = TubeHolderState.PROCESSING; + tubeholder.setState(TubeHolderState.PROCESSING); //删除之前的试管架配置 tubeSettingMgrService.removeTubeHolderSetting(setting); return tubeholder; @@ -226,7 +225,7 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { } logger.info("更新试管架状态"); - projectProcessContextMgrService.addNewTubeHolder(tubeholder); + projectProcessContextMgrService.newTubeHolder(tubeholder); } @Override public Boolean checkCondition() { diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java index 545fb0e..cbb0002 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java @@ -72,7 +72,6 @@ public class SEQ2_SWITCH_TO_THE_NEXT_TUBE extends A8kStepAction { public void moveToNextTube(Integer tubeIndex) throws AppException { if (appDebugHelperService.isDebug()) { - logger.info("VIRTUAL.DO,移动到下一个试管:{}", tubeIndex); OS.forceSleep(1000); } else { sstc.moveTubeToPreProcessPos(tubeIndex); @@ -106,7 +105,7 @@ public class SEQ2_SWITCH_TO_THE_NEXT_TUBE extends A8kStepAction { logger.info("处理下一个试管:{}", nextProcessTube.getSampleId()); moveToNextTube(nextTubeIndex); } - projectProcessContextMgrService.changeTubeStateToPending(nextProcessTube); + projectProcessContextMgrService.pendingTube(nextProcessTube); } @Override public Boolean checkCondition() { diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java index 1bd9c60..9903671 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java @@ -57,10 +57,11 @@ public class SEQ3_APPLAY_RESOURCE extends A8kStepAction { @Override public void doaction() throws AppException { Tube tube = gstate.getCurProcessingTube(); + projectProcessContextMgrService.startPrepareRecourseOK(); assert tube != null; - boolean applyConsumable = projectProcessContextMgrService.takeConsumable(tube); - boolean applyTips = applyConsumable && projectProcessContextMgrService.takeTip(tube); - boolean applyIncubatorPos = applyTips && projectProcessContextMgrService.takeIncubatorPos(tube); + boolean applyConsumable = projectProcessContextMgrService.takeResourceConsumable(tube); + boolean applyTips = applyConsumable && projectProcessContextMgrService.takeResourceTip(tube); + boolean applyIncubatorPos = applyTips && projectProcessContextMgrService.takeResourceIncubatorPos(tube); if (!applyConsumable) { for (Integer projIndex : tube.getProjIndex()) { @@ -82,12 +83,12 @@ public class SEQ3_APPLAY_RESOURCE extends A8kStepAction { assert applyIncubatorPos; logger.info("Tube:{} 申请资源成功", tube.getSampleId()); - boolean assProjInfoSuc = projectProcessContextMgrService.checkAndAssignProjInfo(tube); + boolean assProjInfoSuc = projectProcessContextMgrService.prepareProjInfoData(tube); assert assProjInfoSuc; //创建项目处理上下文 - projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.RESOURCE_IS_READY); + projectProcessContextMgrService.prepareRecourseOK(); logger.info("apply resource ok"); } @@ -98,4 +99,12 @@ public class SEQ3_APPLAY_RESOURCE extends A8kStepAction { @Override public List getResourceList() { return List.of(A8kPublicResourceType.CurTubeProcessToken); } + + @Override public String logCxtState() { + var tube = gstate.getCurProcessingTube(); + if (tube == null) { + return ""; + } + return String.format("[sid: %s, proj: %s]", tube.getSampleId(), tube.getProjIndexStrList()); + } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java index 344d4ce..b605bd4 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java @@ -161,6 +161,7 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { // 2.取tip头 // 3.摇匀,脱帽 // + projectProcessContextMgrService.startTubePreProcessing(); Tube tube = gstate.getCurProcessingTube(); //准备反应板夹 @@ -187,10 +188,7 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { throw ebuilder.buildMutiErrorAppException(errors); } - projectProcessContextMgrService.changeContextStateTo(gstate.getCurProcessingTube(), ProjProcessState.PROCESS); - projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.PRE_PROCESSED); - projectProcessContextMgrService.changeTubeAssociatedReactionPlateStateTo(gstate.getCurProcessingTube(), IncubationSubTankState.WAITING_FOR_DROP); - logger.info("pre process success"); + projectProcessContextMgrService.tubePreProcessingOK(); } @@ -215,4 +213,12 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { OS.forceSleep(100); } } + + @Override public String logCxtState() { + var tube = gstate.getCurProcessingTube(); + if (tube == null) { + return ""; + } + return String.format("[sid: %s, proj: %s]", tube.getSampleId(), tube.getProjIndexStrList()); + } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java index 8eb2785..2667044 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java @@ -9,6 +9,7 @@ import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction; import a8k.service.app.appstate.*; import a8k.service.app.appstate.resource.A8kPublicResourceType; import a8k.service.app.appstate.type.MainFlowCtrlState; +import a8k.service.app.appstate.type.ProjProcessContext; import a8k.service.app.appstate.type.Tube; import a8k.service.app.appstate.type.state.TubeState; import a8k.type.exception.AppException; @@ -23,9 +24,9 @@ import java.util.concurrent.*; /** * - * 核对物料资源是否足够 - * TUBE - * TO_BE_PROCESSED --> PRE_PROCESSING + * 核对物料资源是否足够 + * TUBE + * TO_BE_PROCESSED --> PRE_PROCESSING */ @Component public class SEQ5_PROCESS extends A8kStepAction { @@ -36,17 +37,16 @@ public class SEQ5_PROCESS extends A8kStepAction { } @Resource - GStateService gstate; + GStateService gstate; @Resource - AppExceptionBuilder ebuilder; + AppExceptionBuilder ebuilder; @Resource - IncubationPlateStateMgrService incubationPlateStateMgrService; + IncubationPlateStateMgrService incubationPlateStateMgrService; @Resource - CondtionMgrService cms; + CondtionMgrService cms; @Resource ProjectProcessContextMgrService projectProcessContextMgrService; - MainFlowCtrlState state; @PostConstruct @@ -54,41 +54,54 @@ public class SEQ5_PROCESS extends A8kStepAction { state = gstate.mainFlowCtrlState; } - @Override public void doaction() throws AppException { + @Override + public void doaction() throws AppException { // - // 1.准备3份反应板夹 - // 2.取tip头 - // 3.摇匀,脱帽 + // 1.准备3份反应板夹 + // 2.取tip头 + // 3.摇匀,脱帽 // - projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.PROCESSING); - - Tube tube = gstate.getCurProcessingTube(); - logger.info("处理试管 {}", tube.getSampleId()); + var tube = gstate.getCurProcessingTube(); + projectProcessContextMgrService.startProcessTube(); OS.forceSleep(3000); - projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.PROCESSED); - projectProcessContextMgrService.changeTubeAssociatedReactionPlateStateToINCUBATING(gstate.getCurProcessingTube()); - projectProcessContextMgrService.changeContextStateTo(gstate.getCurProcessingTube(), ProjProcessState.INCUBATING); - } + List projList = tube.getProjIndex(); + for (Integer projIndex : projList) { + ProjProcessContext cxt = projectProcessContextMgrService.getProjProcessContext(tube.getSampleId(), + projIndex); + projectProcessContextMgrService.startIncubating(cxt); + } + projectProcessContextMgrService.processIngTubeOK(); + } - @Override public Boolean checkCondition() { + @Override + public Boolean checkCondition() { return cms.isTimeToProcessTube(); } - @Override public List getResourceList() { + @Override + public List getResourceList() { return List.of( A8kPublicResourceType.IncubationPlateModule, A8kPublicResourceType.HBOT, - A8kPublicResourceType.CurTubeProcessToken - ); + A8kPublicResourceType.CurTubeProcessToken); } // - // UTILS + // UTILS // void wait(Future future) { while (!future.isDone()) { OS.forceSleep(100); } } + + @Override + public String logCxtState() { + var tube = gstate.getCurProcessingTube(); + if (tube == null) { + return ""; + } + return String.format("[sid: %s, proj: %s]", tube.getSampleId(), tube.getProjIndexStrList()); + } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java index 3112520..cd889e1 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java @@ -60,10 +60,9 @@ public class SEQ6_POST_PROCESS extends A8kStepAction { } @Override public void doaction() throws AppException { - projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.POST_PROCESSING); - Tube tube = gstate.getCurProcessingTube(); + projectProcessContextMgrService.postProcessTube(); OS.forceSleep(3000); - projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.POST_PROCESSED); + projectProcessContextMgrService.postProcessTubeOK(); } @Override public Boolean checkCondition() { @@ -88,4 +87,12 @@ public class SEQ6_POST_PROCESS extends A8kStepAction { OS.forceSleep(100); } } + + @Override public String logCxtState() { + var tube = gstate.getCurProcessingTube(); + if (tube == null) { + return ""; + } + return String.format("[sid: %s, proj: %s]", tube.getSampleId(), tube.getProjIndexStrList()); + } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java index d5a158f..f4c0052 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java @@ -49,18 +49,18 @@ public class SEQ7_EJECT_TUBEHOLDER extends A8kStepAction { SST_HControler.ejectTubeHolder(); SST_HControler.moveTubeRackMoveToEnterPos(); } else { - logger.info("VIRTUAL.DO:弹出试管架"); } - gstate.getTubeHolder().state = TubeHolderState.IDLE; + gstate.getTubeHolder().setState(TubeHolderState.IDLE); } @Override public Boolean checkCondition() { //处于工作状态,试管架已经处于空闲状态,入料光电被触发 Boolean cond1 = cms.isCanDoAction(); - Boolean cond2 = gstate.getTubeHolder().state.equals(TubeHolderState.PROCESSING); - Boolean cond3 = cms.isNoMoreTubeToBeProcessed(); - return cond1 && cond2 && cond3; + Boolean cond2 = gstate.getTubeHolder().getState().equals(TubeHolderState.PROCESSING); + Boolean cond3 = cms.isCurTubeProcessCompleted(); + Boolean cond4 = !cms.isHasSometubesToBeProcessed(); + return cond1 && cond2 && cond3 && cond4; } @Override public List getResourceList() { diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kActionStepType.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kActionStepType.java index cfa70b3..2b60f0b 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kActionStepType.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kActionStepType.java @@ -23,6 +23,6 @@ public enum A8kActionStepType { //Error DO_CLEAR_ERROR_BEFORE_WORK,//在启动前,清除错误 - DO_PROCESS_ERROR_TUBE,//处理异常的样本 + DO_FINISH_TUBE_PROCESS,//处理异常的样本 DO_PROCESS_ERROR_PLATE,//处理异常的孵育盘 } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kStepAction.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kStepAction.java index 579a26e..7c2fda4 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kStepAction.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kStepAction.java @@ -37,4 +37,8 @@ public class A8kStepAction { return true; } + public String logCxtState() { + return ""; + } + } diff --git a/src/main/java/a8k/service/app/appstate/EmergencySamplePosStateMgrService.java b/src/main/java/a8k/service/app/appstate/EmergencySamplePosStateMgrService.java index 910447d..a92f0a4 100644 --- a/src/main/java/a8k/service/app/appstate/EmergencySamplePosStateMgrService.java +++ b/src/main/java/a8k/service/app/appstate/EmergencySamplePosStateMgrService.java @@ -79,7 +79,7 @@ public class EmergencySamplePosStateMgrService { tube.setProjInfo(projInfo); tube.setState(TubeState.TO_BE_PROCESSED); - projectProcessContextMgrService.addNewEmergencyTubeHolder(tube); + projectProcessContextMgrService.newEmergencyTube(tube); logger.info("添加紧急样本设置成功 {}", ZJsonHelper.objectToJson(tube)); } else if (tube.getState().equals(TubeState.TO_BE_PROCESSED)) { projectProcessContextMgrService.updateEmergencyTubeCfg(userid, sampleBarcode, bloodType, projInfo); diff --git a/src/main/java/a8k/service/app/appstate/GStateService.java b/src/main/java/a8k/service/app/appstate/GStateService.java index 08c1d06..7e880bc 100644 --- a/src/main/java/a8k/service/app/appstate/GStateService.java +++ b/src/main/java/a8k/service/app/appstate/GStateService.java @@ -60,8 +60,8 @@ public class GStateService { return consumableState; } - public synchronized void setTubeHolder(TubeHolder state) { - this.tubeHolder = state; + public synchronized void setTubeHolder(TubeHolder tubeHolder) { + this.tubeHolder = tubeHolder; } public synchronized TubeHolder getTubeHolder() { @@ -72,8 +72,4 @@ public class GStateService { return mainFlowCtrlState.workState.equals(A8kWorkState.WORKING); } - public TubeHolderState getTubeHolderState() { - return tubeHolder.state; - } - } diff --git a/src/main/java/a8k/service/app/appstate/OptScanModuleStateMgrService.java b/src/main/java/a8k/service/app/appstate/OptScanModuleStateMgrService.java index 938d150..d767b94 100644 --- a/src/main/java/a8k/service/app/appstate/OptScanModuleStateMgrService.java +++ b/src/main/java/a8k/service/app/appstate/OptScanModuleStateMgrService.java @@ -13,21 +13,6 @@ public class OptScanModuleStateMgrService { @Resource GStateService gstate; - synchronized public void newPlateToOptScanPos(IncubationSubTank tank) { - OptScanModule optScanModule = gstate.getOptScanModule(); - optScanModule.state = OptScanModuleState.PLATE_IS_READY; - optScanModule.syncCfg(tank); - } - - synchronized public void dropPlate() { - OptScanModule optScanModule = gstate.getOptScanModule(); - optScanModule.state = OptScanModuleState.EMPTY; - } - - synchronized public void startScanPlate() { - OptScanModule optScanModule = gstate.getOptScanModule(); - optScanModule.state = OptScanModuleState.SCANNING; - } synchronized public Boolean isEmpty() { OptScanModule optScanModule = gstate.getOptScanModule(); diff --git a/src/main/java/a8k/service/app/appstate/ProjectProcessContextMgrService.java b/src/main/java/a8k/service/app/appstate/ProjectProcessContextMgrService.java index 6619d43..577bd9b 100644 --- a/src/main/java/a8k/service/app/appstate/ProjectProcessContextMgrService.java +++ b/src/main/java/a8k/service/app/appstate/ProjectProcessContextMgrService.java @@ -1,14 +1,15 @@ package a8k.service.app.appstate; import a8k.service.app.appdata.AppProjInfoMgrService; -import a8k.service.app.appstate.type.ProjProcessContext; -import a8k.service.app.appstate.type.Tube; -import a8k.service.app.appstate.type.TubeHolder; +import a8k.service.app.appstate.type.*; import a8k.service.app.appstate.type.state.IncubationSubTankState; +import a8k.service.app.appstate.type.state.OptScanModuleState; import a8k.service.app.appstate.type.state.ProjProcessState; import a8k.service.app.appstate.type.state.TubeState; +import a8k.service.db.DeviceStatisticDBService; import a8k.service.db.SampleRecordDBService; import a8k.service.db.type.SampleRecord; +import a8k.service.db.type.StatisticType; import a8k.service.db.type.a8kidcard.zenum.A8kReactionFlowType; import a8k.type.ecode.AppError; import a8k.type.type.BloodType; @@ -36,44 +37,56 @@ public class ProjectProcessContextMgrService { IncubationPlateStateMgrService incubationPlateStateMgrService; @Resource AppProjInfoMgrService appProjInfoMgrService; + @Resource + DeviceStatisticDBService deviceStatisticDBService; List contexts = new ArrayList<>(); - private String generateSampleId(Integer tubePos, Boolean isEmergency) { + private String priGenerateSampleId(Integer tubePos, Boolean isEmergency) { String sampleid = ""; - Integer cnt = sampleRecordDBService.getRecordCntToday(); + Integer cnt = 0; Date date = new Date(); + if (isEmergency) { + cnt = deviceStatisticDBService.get(StatisticType.EmergencyTubeCnt); + } else { + cnt = deviceStatisticDBService.get(StatisticType.TubeHolderCnt); + } + SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd"); if (isEmergency) { sampleid = String.format("%s_%sE", sdf.format(date), cnt); } else { - sampleid = String.format("%s_%s", sdf.format(date), cnt); + sampleid = String.format("%s_%d%02d", sdf.format(date), cnt, tubePos + 1); } return sampleid; } - public void newSample(Tube tube) { - SampleRecord sampleRecord = new SampleRecord(); - sampleRecord.sampleid = generateSampleId(tube.getPos(), tube.getIsEmergency()); - sampleRecord.createDate = new Date(); - sampleRecord.bloodType = tube.getBloodType(); - sampleRecord.isEmergency = tube.getIsEmergency(); - sampleRecord.sampleBarcode = tube.getSampleBarcode(); - sampleRecord.userid = tube.getUserid(); - sampleRecord.projIndex = tube.getProjIndex(); - tube.setSampleId(sampleRecord.sampleid); - sampleRecordDBService.add(sampleRecord); + void priChangeReactionPlateStateTo(Tube tube, IncubationSubTankState state) { + var incubationState = gstate.getIncubationPlate(); + var subtanks = incubationState.subtanks; + List cxts = getTubeAssociatedProjContext(tube.getSampleId()); + for (ProjProcessContext cxt : cxts) { + subtanks[cxt.incubatorPos.off].state = state; + } + } + + void finishProcessProj(Tube tube, ProjProcessState state) { + List cxts = getTubeAssociatedProjContext(tube.getSampleId()); + for (ProjProcessContext cxt : cxts) { + cxt.state = state; + } } - private void newProjProcessContext(Tube tube) { + private void priNewProjProcessContext(Tube tube) { List projInfos = tube.getProjInfo(); for (ProjBriefInfo projInfo : projInfos) { ProjProcessContext projProcessContext = new ProjProcessContext(); projProcessContext.sampleId = tube.getSampleId(); + projProcessContext.state = ProjProcessState.INIT; projProcessContext.projIndex = projInfo.projIndex; projProcessContext.isHighTube = tube.getIsHighTube(); projProcessContext.isEmergency = tube.getIsEmergency(); @@ -89,7 +102,22 @@ public class ProjectProcessContextMgrService { } } - private void removeProjProcessContext(String sampleId) { + + public void priNewSample(Tube tube) { + SampleRecord sampleRecord = new SampleRecord(); + sampleRecord.sampleid = priGenerateSampleId(tube.getPos(), tube.getIsEmergency()); + sampleRecord.createDate = new Date(); + sampleRecord.bloodType = tube.getBloodType(); + sampleRecord.isEmergency = tube.getIsEmergency(); + sampleRecord.sampleBarcode = tube.getSampleBarcode(); + sampleRecord.userid = tube.getUserid(); + sampleRecord.projIndex = tube.getProjIndex(); + tube.setSampleId(sampleRecord.sampleid); + sampleRecordDBService.add(sampleRecord); + } + + + private void priRemoveProjProcessContext(String sampleId) { for (ProjProcessContext context : contexts) { if (context.sampleId.equals(sampleId)) { contexts.remove(context); @@ -144,17 +172,25 @@ public class ProjectProcessContextMgrService { * 添加新的试管架 * @param tubeholder 试管架 */ - synchronized public void addNewTubeHolder(TubeHolder tubeholder) { + synchronized public void newTubeHolder(TubeHolder tubeholder) { + deviceStatisticDBService.add(StatisticType.TubeHolderCnt, 1); + logger.info("添加新的试管架"); for (Tube tube : tubeholder.tubes) { - newSample(tube); - newProjProcessContext(tube); + if (tube.getState().equals(TubeState.EMPTY)) { + continue; + } + priNewSample(tube); + priNewProjProcessContext(tube); + logger.info(" 试管ID:{}", tube.getSampleId()); } gstate.setTubeHolder(tubeholder); } - synchronized public void addNewEmergencyTubeHolder(Tube tube) { - newSample(tube); - newProjProcessContext(tube); + synchronized public void newEmergencyTube(Tube tube) { + deviceStatisticDBService.add(StatisticType.EmergencyTubeCnt, 1); + priNewSample(tube); + priNewProjProcessContext(tube); + logger.info("添加新的急诊试管,试管ID:{}", tube.getSampleId()); } synchronized public void updateEmergencyTubeCfg(String userid, String sampleBarcode, BloodType bloodType, List projInfo) { @@ -165,8 +201,9 @@ public class ProjectProcessContextMgrService { tube.setSampleBarcode(sampleBarcode); tube.setProjInfo(projInfo); - removeProjProcessContext(tube.getSampleId()); - newProjProcessContext(tube); + priRemoveProjProcessContext(tube.getSampleId()); + priNewProjProcessContext(tube); + logger.info("更新急诊试管配置,试管ID:{}", tube.getSampleId()); } @@ -174,7 +211,23 @@ public class ProjectProcessContextMgrService { // List incubatorPoss = incubationPlateStateMgrService.takeIncubationIDLEPos(projs.size()); // List tips = consumablesMgrService.takeTip(projInfos.get(i).reactionFlowType); - synchronized public Boolean takeConsumable(Tube tube) { + + synchronized public void pendingTube(Tube tube) { + /** + * 挂起试管 + * @param nextProcessTube 下一个处理的试管 + */ + gstate.curProcessingTube = tube; + gstate.getCurProcessingTube().setState(TubeState.PENDING); + finishProcessProj(tube, ProjProcessState.PENDING); + } + + + synchronized public void startPrepareRecourseOK() { + } + + + synchronized public Boolean takeResourceConsumable(Tube tube) { for (Integer projIndex : tube.getProjIndex()) { ProjProcessContext cxt = getProjProcessContext(tube.getSampleId(), projIndex); assert cxt != null; @@ -186,7 +239,7 @@ public class ProjectProcessContextMgrService { return true; } - synchronized public Boolean takeIncubatorPos(Tube tube) { + synchronized public Boolean takeResourceIncubatorPos(Tube tube) { var incubationState = gstate.getIncubationPlate(); var subtanks = incubationState.subtanks; for (Integer projIndex : tube.getProjIndex()) { @@ -202,7 +255,7 @@ public class ProjectProcessContextMgrService { return true; } - synchronized public Boolean takeTip(Tube tube) { + synchronized public Boolean takeResourceTip(Tube tube) { for (Integer projIndex : tube.getProjIndex()) { ProjProcessContext cxt = getProjProcessContext(tube.getSampleId(), projIndex); assert cxt != null; @@ -215,19 +268,6 @@ public class ProjectProcessContextMgrService { return true; } - synchronized public Boolean checkAndAssignProjInfo(Tube tube) { - for (Integer projIndex : tube.getProjIndex()) { - ProjProcessContext cxt = getProjProcessContext(tube.getSampleId(), projIndex); - assert cxt != null; - cxt.projCfg = appProjInfoMgrService.getProjCfgByProjIndex(cxt.consumable.lotId); - if (cxt.projCfg == null) { - return false; - } - } - return true; - - } - synchronized public void bakAllTubeAResource(Tube tube) { for (Integer projIndex : tube.getProjIndex()) { ProjProcessContext cxt = getProjProcessContext(tube.getSampleId(), projIndex); @@ -247,28 +287,89 @@ public class ProjectProcessContextMgrService { } } - synchronized public void changeCurrentTubeStateTo(TubeState state) { - gstate.getCurProcessingTube().setState(state); + + synchronized public Boolean prepareProjInfoData(Tube tube) { + for (Integer projIndex : tube.getProjIndex()) { + ProjProcessContext cxt = getProjProcessContext(tube.getSampleId(), projIndex); + assert cxt != null; + cxt.projCfg = appProjInfoMgrService.getProjCfgByProjIndex(cxt.consumable.lotId); + if (cxt.projCfg == null) { + return false; + } + } + return true; } - synchronized public void changeTubeStateToPending(Tube tube) { - /** - * 挂起试管 - * @param nextProcessTube 下一个处理的试管 - */ - gstate.curProcessingTube = tube; - changeCurrentTubeStateTo(TubeState.PENDING); - changeContextStateTo(tube, ProjProcessState.PENDING); + synchronized public void prepareRecourseOK() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.RESOURCE_IS_READY); + finishProcessProj(tube, ProjProcessState.PROCESS); + } + synchronized public void startTubePreProcessing() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.PRE_PROCESSING); } - synchronized public void changeTubeAssociatedReactionPlateStateTo(Tube tube, IncubationSubTankState state) { - var incubationState = gstate.getIncubationPlate(); - var subtanks = incubationState.subtanks; - List cxts = getTubeAssociatedProjContext(tube.getSampleId()); - for (ProjProcessContext cxt : cxts) { - subtanks[cxt.incubatorPos.off].state = state; - } + synchronized public void tubePreProcessingOK() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.PRE_PROCESSED); + priChangeReactionPlateStateTo(tube, IncubationSubTankState.WAITING_FOR_DROP); + } + + + synchronized public void startProcessTube() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.PROCESSING); + } + + synchronized public void startIncubating(ProjProcessContext cxt) { + var subtanks = gstate.getIncubationPlate().subtanks; + cxt.state = ProjProcessState.INCUBATING; + subtanks[cxt.incubatorPos.off].state = IncubationSubTankState.INCUBATING; + subtanks[cxt.incubatorPos.off].startIncubatedTime = System.currentTimeMillis(); + subtanks[cxt.incubatorPos.off].incubatedTimeSec = cxt.projCfg.getReactionPlateIncubationTimeMin() * 60; + logger.info("{} 开始孵育,开始时间:{},孵育时间:{}s", subtanks[cxt.incubatorPos.off].getPos(), subtanks[cxt.incubatorPos.off].startIncubatedTime, + subtanks[cxt.incubatorPos.off].incubatedTimeSec); + } + + synchronized public void processIngTubeOK() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.PROCESSED); + } + + + synchronized public void postProcessTube() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.POST_PROCESSING); + } + + synchronized public void postProcessTubeOK() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.POST_PROCESSED); + } + + + synchronized public void newPlateToOptScanPos(IncubationSubTank tank) { + OptScanModule optScanModule = gstate.getOptScanModule(); + optScanModule.state = OptScanModuleState.PLATE_IS_READY; + optScanModule.syncCfg(tank); + } + + synchronized public void dropPlate() { + OptScanModule optScanModule = gstate.getOptScanModule(); + optScanModule.state = OptScanModuleState.EMPTY; + } + + synchronized public void startScanPlate() { + OptScanModule optScanModule = gstate.getOptScanModule(); + optScanModule.state = OptScanModuleState.SCANNING; + } + + synchronized public void finishProcessProj(String sampleId, Integer projIndex) { + ProjProcessContext cxt = getProjProcessContext(sampleId, projIndex); + assert cxt != null; + cxt.state = ProjProcessState.FINISH; } @@ -277,42 +378,24 @@ public class ProjectProcessContextMgrService { var subtanks = incubationState.subtanks; List cxts = getTubeAssociatedProjContext(tube.getSampleId()); - //设置 - changeCurrentTubeStateTo(TubeState.ERROR); + //设置试管状态为Error + gstate.getCurProcessingTube().setState(TubeState.ERROR); tube.setErrors(errors); + for (ProjProcessContext cxt : cxts) { - cxt.state = ProjProcessState.ERROR; - cxt.errors = errors; + //设置cxt状态为ERROR + cxt.state = ProjProcessState.ERROR; + cxt.errors = errors; + + //设置孵育子槽状态为ERROR subtanks[cxt.incubatorPos.off].state = IncubationSubTankState.ERROR; subtanks[cxt.incubatorPos.off].errors = errors; } } - - synchronized public void changeTubeAssociatedReactionPlateStateToINCUBATING(Tube tube) { - var incubationState = gstate.getIncubationPlate(); - var subtanks = incubationState.subtanks; - List cxts = getTubeAssociatedProjContext(tube.getSampleId()); - for (ProjProcessContext cxt : cxts) { - cxt.state = ProjProcessState.INCUBATING; - subtanks[cxt.incubatorPos.off].state = IncubationSubTankState.INCUBATING; - subtanks[cxt.incubatorPos.off].startIncubatedTime = System.currentTimeMillis(); - subtanks[cxt.incubatorPos.off].incubatedTimeSec = cxt.projCfg.getReactionPlateIncubationTimeMin() * 60; - logger.info("{} 开始孵育,开始时间:{},孵育时间:{}s", subtanks[cxt.incubatorPos.off].getPos(), subtanks[cxt.incubatorPos.off].startIncubatedTime, - subtanks[cxt.incubatorPos.off].incubatedTimeSec); - } + synchronized public void finishedTubeProcess() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.PROCESS_COMPLETE); } - synchronized public void changeContextStateTo(Tube tube, ProjProcessState state) { - List cxts = getTubeAssociatedProjContext(tube.getSampleId()); - for (ProjProcessContext cxt : cxts) { - cxt.state = state; - } - } - - synchronized public void changeContextStateTo(String sampleId, Integer projIndex, ProjProcessState state) { - ProjProcessContext cxt = getProjProcessContext(sampleId, projIndex); - assert cxt != null; - cxt.state = state; - } } diff --git a/src/main/java/a8k/service/app/appstate/type/IncubationSubTank.java b/src/main/java/a8k/service/app/appstate/type/IncubationSubTank.java index 7b0fb09..1a39f70 100644 --- a/src/main/java/a8k/service/app/appstate/type/IncubationSubTank.java +++ b/src/main/java/a8k/service/app/appstate/type/IncubationSubTank.java @@ -63,5 +63,12 @@ public class IncubationSubTank { errors.clear(); } + public String getProjInfoStr() { + if (projInfo == null) { + return "null"; + } + return String.format("%s(%d)", projInfo.projShotName, projInfo.projIndex); + } + } diff --git a/src/main/java/a8k/service/app/appstate/type/OptScanModule.java b/src/main/java/a8k/service/app/appstate/type/OptScanModule.java index 5b702f7..f107686 100644 --- a/src/main/java/a8k/service/app/appstate/type/OptScanModule.java +++ b/src/main/java/a8k/service/app/appstate/type/OptScanModule.java @@ -29,6 +29,11 @@ public class OptScanModule { this.isErrorPlate = tank.state.equals(IncubationSubTankState.ERROR); } - + public String getProjInfoStr() { + if (projInfo == null) { + return "null"; + } + return String.format("%s(%d)", projInfo.projShotName, projInfo.projIndex); + } } diff --git a/src/main/java/a8k/service/app/appstate/type/Tube.java b/src/main/java/a8k/service/app/appstate/type/Tube.java index 50836f7..a9152c2 100644 --- a/src/main/java/a8k/service/app/appstate/type/Tube.java +++ b/src/main/java/a8k/service/app/appstate/type/Tube.java @@ -32,10 +32,17 @@ public class Tube { return ProjBriefInfo.toPorjIndex(projInfo); } + public List getProjIndexStrList(){ + List projIndexStrList = new ArrayList<>(); + for (ProjBriefInfo info : projInfo) { + projIndexStrList.add(info.projShotName); + } + return projIndexStrList; + } + Tube(Integer pos) { - // ProjBriefInfo info = new ProjBriefInfo(1,"hscrp","CA","#FF0000"); - // projInfo.add(info); - // projInfo.add(info); - // projInfo.add(info); + this.pos = pos; } + + } diff --git a/src/main/java/a8k/service/app/appstate/type/TubeHolder.java b/src/main/java/a8k/service/app/appstate/type/TubeHolder.java index 48ee347..c0a5a43 100644 --- a/src/main/java/a8k/service/app/appstate/type/TubeHolder.java +++ b/src/main/java/a8k/service/app/appstate/type/TubeHolder.java @@ -3,11 +3,15 @@ package a8k.service.app.appstate.type; import a8k.service.app.appstate.type.state.TubeHolderState; import a8k.service.app.appstate.type.state.TubeState; import a8k.type.type.A8kTubeHolderType; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +@Data public class TubeHolder { public A8kTubeHolderType tubeHolderType = A8kTubeHolderType.BloodTube; //试管架类型 public Tube[] tubes = new Tube[10]; - public TubeHolderState state = TubeHolderState.IDLE; //处理状态 + TubeHolderState state = TubeHolderState.IDLE; //处理状态 public TubeHolder() { for (int i = 0; i < tubes.length; i++) { diff --git a/src/main/java/a8k/service/app/appstate/type/state/ProjProcessState.java b/src/main/java/a8k/service/app/appstate/type/state/ProjProcessState.java index 65f8160..a8c39c0 100644 --- a/src/main/java/a8k/service/app/appstate/type/state/ProjProcessState.java +++ b/src/main/java/a8k/service/app/appstate/type/state/ProjProcessState.java @@ -3,7 +3,6 @@ package a8k.service.app.appstate.type.state; public enum ProjProcessState { INIT, PENDING, - PREPARE_RESOUCE, PROCESS, INCUBATING, OPTSCAN, diff --git a/src/main/java/a8k/service/db/DeviceStatisticDBService.java b/src/main/java/a8k/service/db/DeviceStatisticDBService.java new file mode 100644 index 0000000..0167d8b --- /dev/null +++ b/src/main/java/a8k/service/db/DeviceStatisticDBService.java @@ -0,0 +1,88 @@ +package a8k.service.db; + +import a8k.service.app.appdata.UtilsProjectColorAllocer; +import a8k.service.db.type.DeviceStatistic; +import a8k.service.db.type.StatisticType; +import a8k.service.debug.AppDebugHelperService; +import a8k.utils.DateUtil; +import a8k.utils.ZDateUtils; +import a8k.utils.ZSqliteJdbcHelper; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import lombok.SneakyThrows; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; + +import java.sql.ResultSet; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +@Component +public class DeviceStatisticDBService { + private static final Logger logger = LoggerFactory.getLogger(DeviceStatisticDBService.class); + private static final String tableName = "zapp_a8k_statistic"; + private static Class tClass = DeviceStatistic.class; + + + @Resource + JdbcTemplate jdbcTemplate; + + @PostConstruct + void init() { + if (!ZSqliteJdbcHelper.isTableExist(jdbcTemplate, tableName)) { + ZSqliteJdbcHelper.createTable(jdbcTemplate, tableName, tClass); + } + } + + @SneakyThrows private DeviceStatistic rowMapper(ResultSet rs, int rowNum) { + return (DeviceStatistic) ZSqliteJdbcHelper.rowMapper(rs, tClass); + } + + public T queryForObject(String sql, RowMapper rowMapper, @Nullable Object... args) { + try { + return jdbcTemplate.queryForObject(sql, rowMapper, args); + } catch (Exception e) { + logger.error("queryForObject error: {}", e.getMessage()); + return null; + } + } + + public void add(StatisticType statisticType, Integer cnt) { + Date now = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + String today = sdf.format(now); + + List statisticList = jdbcTemplate.query("select * from " + tableName + " where statisticDate = ? and statisticType = ?", this::rowMapper, today, statisticType); + + if (statisticList.isEmpty()) { + DeviceStatistic statistic = new DeviceStatistic(); + statistic.statisticDate = today; + statistic.statisticType = statisticType; + statistic.cnt = cnt; + ZSqliteJdbcHelper.addObj(jdbcTemplate, tableName, tClass, statistic); + } else { + DeviceStatistic statistic = statisticList.get(0); + statistic.cnt += cnt; + ZSqliteJdbcHelper.updateObj(jdbcTemplate, tableName, tClass, statistic); + } + } + + public Integer get(StatisticType type) { + Date now = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + String today = sdf.format(now); + + List statisticList = jdbcTemplate.query("select * from " + tableName + " where statisticDate = ? and statisticType = ?", this::rowMapper, today, type); + if (statisticList.isEmpty()) { + return 0; + } else { + return statisticList.get(0).cnt; + } + } + +} diff --git a/src/main/java/a8k/service/db/type/DeviceStatistic.java b/src/main/java/a8k/service/db/type/DeviceStatistic.java new file mode 100644 index 0000000..1ea95f2 --- /dev/null +++ b/src/main/java/a8k/service/db/type/DeviceStatistic.java @@ -0,0 +1,10 @@ +package a8k.service.db.type; + +import java.util.Date; + +public class DeviceStatistic { + public int id; + public String statisticDate; + public StatisticType statisticType; + public Integer cnt; +} diff --git a/src/main/java/a8k/service/db/type/StatisticType.java b/src/main/java/a8k/service/db/type/StatisticType.java new file mode 100644 index 0000000..5615e01 --- /dev/null +++ b/src/main/java/a8k/service/db/type/StatisticType.java @@ -0,0 +1,6 @@ +package a8k.service.db.type; + +public enum StatisticType { + TubeHolderCnt, + EmergencyTubeCnt, +} diff --git a/src/main/java/a8k/utils/ZSqliteJdbcHelper.java b/src/main/java/a8k/utils/ZSqliteJdbcHelper.java index ed181b0..355f148 100644 --- a/src/main/java/a8k/utils/ZSqliteJdbcHelper.java +++ b/src/main/java/a8k/utils/ZSqliteJdbcHelper.java @@ -38,7 +38,13 @@ public class ZSqliteJdbcHelper { static public void createTable(JdbcTemplate jdbcTemplate, String tableName, Class tClass) { StringBuilder sql = new StringBuilder("create table " + tableName + " ("); + Boolean hasId = false; for (java.lang.reflect.Field field : tClass.getDeclaredFields()) { + if (field.getName().equals("id")) { + hasId = true; + } + + sql.append(" '").append(field.getName()).append("' "); if (field.getType().equals(Integer.class) || field.getType().equals(int.class)) { sql.append("integer,"); @@ -56,6 +62,10 @@ public class ZSqliteJdbcHelper { sql.append("text,"); } } + if(!hasId) { + throw new RuntimeException("id field not found in class " + tClass.getName()); + } + sql.append(" PRIMARY KEY ('id' DESC));"); jdbcTemplate.execute(sql.toString()); } diff --git a/src/main/java/a8k/utils/ZStringUtils.java b/src/main/java/a8k/utils/ZStringUtils.java new file mode 100644 index 0000000..a8ba2da --- /dev/null +++ b/src/main/java/a8k/utils/ZStringUtils.java @@ -0,0 +1,46 @@ +package a8k.utils; + +public class ZStringUtils { + static public String centerStr(String str, Character c, int len) { + if (str == null || str.length() >= len) { + return str; + } + int left = (len - str.length()) / 2; + int right = len - str.length() - left; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < left; i++) { + sb.append(c); + } + sb.append(str); + for (int i = 0; i < right; i++) { + sb.append(c); + } + return sb.toString(); + } + + static public String rightAlignStr(String str, Character c, int len) { + if (str == null || str.length() >= len) { + return str; + } + int right = len - str.length(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < right; i++) { + sb.append(c); + } + sb.append(str); + return sb.toString(); + } + + static public String leftAlignStr(String str, Character c, int len) { + if (str == null || str.length() >= len) { + return str; + } + int left = len - str.length(); + StringBuilder sb = new StringBuilder(); + sb.append(str); + for (int i = 0; i < left; i++) { + sb.append(c); + } + return sb.toString(); + } +}