|
|
@ -1,13 +1,20 @@ |
|
|
|
package a8k.app.service.statemgr; |
|
|
|
|
|
|
|
import a8k.app.constant.AppConstant; |
|
|
|
import a8k.app.service.data.ProjInfoMgrService; |
|
|
|
import a8k.app.service.utils.ProjInfoUtils; |
|
|
|
import a8k.app.type.DeviceRunMode; |
|
|
|
import a8k.app.type.PreReactionGrid; |
|
|
|
import a8k.app.type.PreReactionGridGroup; |
|
|
|
import a8k.app.type.PreReactionPosState; |
|
|
|
import a8k.app.type.a8k.ConsumableGroup; |
|
|
|
import a8k.app.type.a8k.LittleBottleConsumableType; |
|
|
|
import a8k.app.type.a8k.container.LittBottleConsumablesInfo; |
|
|
|
import a8k.app.type.a8k.pos.PreReactionPos; |
|
|
|
import a8k.app.type.a8k.state.SampleInfo; |
|
|
|
import a8k.app.type.a8k.state.Tube; |
|
|
|
import a8k.app.type.exception.AppException; |
|
|
|
import cn.hutool.core.util.ObjectUtil; |
|
|
|
import cn.hutool.log.Log; |
|
|
|
import lombok.RequiredArgsConstructor; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.springframework.scheduling.annotation.EnableScheduling; |
|
|
@ -21,20 +28,84 @@ import org.springframework.util.Assert; |
|
|
|
@EnableScheduling |
|
|
|
public class PreReactionStateMgr { |
|
|
|
|
|
|
|
private final ProjInfoMgrService projInfoMgrService; |
|
|
|
private final GStateMgrService gStateMgrService; |
|
|
|
|
|
|
|
PreReactionPosState preReactionPosState = new PreReactionPosState(); |
|
|
|
|
|
|
|
public synchronized PreReactionPosState getPreReactionPosState() { |
|
|
|
public synchronized PreReactionPosState getPreReactionGridState() { |
|
|
|
return ObjectUtil.cloneByStream(preReactionPosState); |
|
|
|
} |
|
|
|
|
|
|
|
private PreReactionGridGroup buildFakePreReactionGridGroup(ConsumableGroup group) { |
|
|
|
PreReactionGridGroup gridGroup = new PreReactionGridGroup(group); |
|
|
|
gridGroup.group = group; |
|
|
|
if (group.off % 2 == 0) { |
|
|
|
gridGroup.installed = true; |
|
|
|
gridGroup.hasSomeGridInReacting = true; |
|
|
|
gridGroup.hasSomeGridReactedCompleted = true; |
|
|
|
} else { |
|
|
|
gridGroup.installed = false; |
|
|
|
gridGroup.hasSomeGridInReacting = false; |
|
|
|
gridGroup.hasSomeGridReactedCompleted = false; |
|
|
|
} |
|
|
|
gridGroup.consumableType = LittleBottleConsumableType.BufferSolution; |
|
|
|
try { |
|
|
|
gridGroup.projBriefInfo = ProjInfoUtils.buildProjBrefInfo(projInfoMgrService.getProjBuildInInfo(1)); |
|
|
|
} catch (AppException e) { |
|
|
|
throw new RuntimeException(e); |
|
|
|
} |
|
|
|
|
|
|
|
gridGroup.version = 10; |
|
|
|
for (int i = 0; i < AppConstant.CONSUMABLE_NUM; i++) { |
|
|
|
switch (i % 5) { |
|
|
|
case 0 -> { |
|
|
|
gridGroup.grids.get(i).state = PreReactionGrid.State.UNINSTALL; |
|
|
|
} |
|
|
|
case 1 -> { |
|
|
|
gridGroup.grids.get(i).state = PreReactionGrid.State.TO_BE_USED; |
|
|
|
} |
|
|
|
case 2 -> { |
|
|
|
gridGroup.grids.get(i).state = PreReactionGrid.State.REACTING; |
|
|
|
gridGroup.grids.get(i).sampleInfo.userid = "FAKE-UID-121"; |
|
|
|
gridGroup.grids.get(i).reactionRemainingTime = i * 60L; |
|
|
|
} |
|
|
|
case 3 -> { |
|
|
|
gridGroup.grids.get(i).state = PreReactionGrid.State.REACTION_COMPLETED; |
|
|
|
gridGroup.grids.get(i).sampleInfo.userid = "FAKE-UID-123"; |
|
|
|
} |
|
|
|
case 4 -> { |
|
|
|
gridGroup.grids.get(i).state = PreReactionGrid.State.USED; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return gridGroup; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public synchronized PreReactionGridGroup getPreReactionGridGroupState(ConsumableGroup group) { |
|
|
|
if (gStateMgrService.isInMode(DeviceRunMode.VirtualStateGenerateMode)) { |
|
|
|
return buildFakePreReactionGridGroup(group); |
|
|
|
} |
|
|
|
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group); |
|
|
|
return ObjectUtil.cloneByStream(gridGroup); |
|
|
|
} |
|
|
|
|
|
|
|
public synchronized Integer getPreReactionGridGroupVersion(ConsumableGroup group) { |
|
|
|
if (gStateMgrService.isInMode(DeviceRunMode.VirtualStateGenerateMode)) { |
|
|
|
return buildFakePreReactionGridGroup(group).version; |
|
|
|
} |
|
|
|
|
|
|
|
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group); |
|
|
|
if (gridGroup != null) { |
|
|
|
return gridGroup.version; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
public synchronized boolean isHasReactionCompleted() { |
|
|
|
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) { |
|
|
|
if (gridGroup.isHasReactionCompleted) { |
|
|
|
if (gridGroup.hasSomeGridReactedCompleted) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
@ -43,7 +114,7 @@ public class PreReactionStateMgr { |
|
|
|
|
|
|
|
public synchronized boolean isHasInReactionGrid() { |
|
|
|
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) { |
|
|
|
if (gridGroup.isHasInReactionGrid) { |
|
|
|
if (gridGroup.hasSomeGridInReacting) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
@ -52,7 +123,7 @@ public class PreReactionStateMgr { |
|
|
|
|
|
|
|
public synchronized PreReactionPos getReactionCompletedPos() { |
|
|
|
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) { |
|
|
|
if (gridGroup.isHasReactionCompleted) { |
|
|
|
if (gridGroup.hasSomeGridReactedCompleted) { |
|
|
|
for (PreReactionGrid grid : gridGroup.grids) { |
|
|
|
if (grid.state.equals(PreReactionGrid.State.REACTION_COMPLETED)) { |
|
|
|
PreReactionPos pos = new PreReactionPos(); |
|
|
@ -67,22 +138,36 @@ public class PreReactionStateMgr { |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
public synchronized void changeReactionGridStateToReacting(PreReactionPos preReactionPos, Long totalReactionTimeMs) { |
|
|
|
public synchronized void changeReactionGridStateToReacting(PreReactionPos preReactionPos, Tube fromTube, Integer off, Long totalReactionTimeS) { |
|
|
|
PreReactionGridGroup gridGroup = getPreReactionGridGroup(preReactionPos.group); |
|
|
|
Assert.notNull(gridGroup, "gridGroup != null"); |
|
|
|
var grid = gridGroup.grids.get(preReactionPos.index); |
|
|
|
grid.state = PreReactionGrid.State.REACTING; |
|
|
|
grid.totalReactionTime = totalReactionTimeS; |
|
|
|
grid.startReactionTime = System.currentTimeMillis() / 1000; |
|
|
|
grid.reactionRemainingTime = totalReactionTimeS; |
|
|
|
grid.projBuildinInfo = fromTube.getPreProcessContexts().get(off).getProjBuildinInfo(); |
|
|
|
grid.projExtInfoCard = fromTube.getPreProcessContexts().get(off).getProjExtInfoCard(); |
|
|
|
grid.sampleInfo = fromTube.getSampleInfo(); |
|
|
|
grid.bindIncubatorPos = fromTube.getPreProcessContexts().get(off).getIncubatorPos(); |
|
|
|
gridGroup.hasSomeGridInReacting = true; |
|
|
|
gridGroup.version++; |
|
|
|
} |
|
|
|
|
|
|
|
public synchronized void changeReactionGridStateToUsed(PreReactionPos preReactionPos) { |
|
|
|
PreReactionGridGroup gridGroup = getPreReactionGridGroup(preReactionPos.group); |
|
|
|
Assert.notNull(gridGroup, "gridGroup != null"); |
|
|
|
var grid = gridGroup.grids.get(preReactionPos.index); |
|
|
|
grid.state = PreReactionGrid.State.REACTING; |
|
|
|
grid.totalReactionTime = totalReactionTimeMs; |
|
|
|
grid.startReactionTime = System.currentTimeMillis(); |
|
|
|
grid.hasReactionTime = 0L; |
|
|
|
gridGroup.isHasInReactionGrid = true; |
|
|
|
grid.state = PreReactionGrid.State.USED; |
|
|
|
gridGroup.version++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public synchronized boolean isHasInUSEReactionGrid(ConsumableGroup group) { |
|
|
|
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group); |
|
|
|
if (gridGroup != null) { |
|
|
|
return gridGroup.isHasInReactionGrid || gridGroup.isHasReactionCompleted; |
|
|
|
return gridGroup.hasSomeGridInReacting || gridGroup.hasSomeGridReactedCompleted; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
@ -92,19 +177,40 @@ public class PreReactionStateMgr { |
|
|
|
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group); |
|
|
|
Assert.notNull(gridGroup, "gridGroup != null"); |
|
|
|
gridGroup.consumableType = littBottleConsumablesInfo.type; |
|
|
|
gridGroup.isInstalled = true; |
|
|
|
gridGroup.installed = true; |
|
|
|
changeAllGridStateToIdle(gridGroup.group); |
|
|
|
gridGroup.syncInfo(); |
|
|
|
gridGroup.version++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public synchronized void setConsumableNum(ConsumableGroup group, Integer num) { |
|
|
|
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group); |
|
|
|
Assert.notNull(gridGroup, "gridGroup != null"); |
|
|
|
gridGroup.syncInfo(); |
|
|
|
for (int i = 0; i < gridGroup.grids.size(); i++) { |
|
|
|
if (i < AppConstant.CONSUMABLE_NUM - num) { |
|
|
|
gridGroup.grids.get(i).state = PreReactionGrid.State.UNINSTALL; |
|
|
|
} else { |
|
|
|
gridGroup.grids.get(i).state = PreReactionGrid.State.TO_BE_USED; |
|
|
|
} |
|
|
|
} |
|
|
|
gridGroup.version++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public synchronized void unInstallConsumable(ConsumableGroup group) { |
|
|
|
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group); |
|
|
|
Assert.notNull(gridGroup, "gridGroup != null"); |
|
|
|
gridGroup.isInstalled = false; |
|
|
|
gridGroup.installed = false; |
|
|
|
changeAllGridStateToIdle(gridGroup.group); |
|
|
|
|
|
|
|
gridGroup.version++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public synchronized void resetAll() { |
|
|
|
|
|
|
|
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) { |
|
|
|
changeAllGridStateToIdle(gridGroup.group); |
|
|
|
} |
|
|
@ -115,19 +221,27 @@ public class PreReactionStateMgr { |
|
|
|
// ********************************************************************************* |
|
|
|
|
|
|
|
private void changeAllGridStateToIdle(ConsumableGroup group) { |
|
|
|
|
|
|
|
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group); |
|
|
|
Assert.notNull(gridGroup, "gridGroup != null"); |
|
|
|
gridGroup.isHasInReactionGrid = false; |
|
|
|
gridGroup.isHasReactionCompleted = false; |
|
|
|
gridGroup.hasSomeGridInReacting = false; |
|
|
|
gridGroup.hasSomeGridReactedCompleted = false; |
|
|
|
for (PreReactionGrid grid : gridGroup.grids) { |
|
|
|
grid.state = PreReactionGrid.State.IDLE; |
|
|
|
grid.startReactionTime = 0L; |
|
|
|
grid.hasReactionTime = 0L; |
|
|
|
grid.totalReactionTime = 0L; |
|
|
|
grid.state = PreReactionGrid.State.UNINSTALL; |
|
|
|
grid.startReactionTime = 0L; |
|
|
|
grid.reactionRemainingTime = 0L; |
|
|
|
grid.totalReactionTime = 0L; |
|
|
|
grid.bindIncubatorPos = null; |
|
|
|
grid.sampleInfo = new SampleInfo(); |
|
|
|
grid.projBuildinInfo = null; |
|
|
|
grid.projExtInfoCard = null; |
|
|
|
} |
|
|
|
gridGroup.version++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
private PreReactionGridGroup getPreReactionGridGroup(ConsumableGroup group) { |
|
|
|
|
|
|
|
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) { |
|
|
|
if (gridGroup.group.equals(group)) { |
|
|
|
return gridGroup; |
|
|
@ -138,32 +252,42 @@ public class PreReactionStateMgr { |
|
|
|
|
|
|
|
|
|
|
|
private void autoRefreshPreReactionPosState(PreReactionGridGroup group) { |
|
|
|
// update hasReactionTime |
|
|
|
if (!group.isInstalled) { |
|
|
|
if (!group.installed) |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
boolean isHasInReactionGrid = false; |
|
|
|
boolean isHasReactionCompleted = false; |
|
|
|
|
|
|
|
for (PreReactionGrid grid : group.grids) { |
|
|
|
if (grid.state.equals(PreReactionGrid.State.IDLE)) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
if (grid.state.equals(PreReactionGrid.State.REACTING)) { |
|
|
|
grid.hasReactionTime = System.currentTimeMillis() - grid.startReactionTime; |
|
|
|
if (grid.hasReactionTime < grid.totalReactionTime) { |
|
|
|
isHasInReactionGrid = true; |
|
|
|
} else { |
|
|
|
grid.state = PreReactionGrid.State.REACTION_COMPLETED; |
|
|
|
isHasReactionCompleted = true; |
|
|
|
switch (grid.state) { |
|
|
|
case UNINSTALL, TO_BE_USED, USED -> { |
|
|
|
} |
|
|
|
} else if (grid.state.equals(PreReactionGrid.State.REACTION_COMPLETED)) { |
|
|
|
isHasReactionCompleted = true; |
|
|
|
case REACTING -> { |
|
|
|
grid.reactionRemainingTime = grid.totalReactionTime - (System.currentTimeMillis() / 1000 - grid.startReactionTime); |
|
|
|
group.version++; |
|
|
|
|
|
|
|
//grid.reactionRemainingTime 发生改变时,不更新VERSION,否则上报频繁了 |
|
|
|
if (grid.reactionRemainingTime <= 0) { |
|
|
|
grid.state = PreReactionGrid.State.REACTION_COMPLETED; |
|
|
|
grid.reactionRemainingTime = 0L; |
|
|
|
isHasReactionCompleted = true; |
|
|
|
} else { |
|
|
|
isHasInReactionGrid = true; |
|
|
|
} |
|
|
|
} |
|
|
|
case REACTION_COMPLETED -> isHasReactionCompleted = true; |
|
|
|
} |
|
|
|
} |
|
|
|
group.isHasInReactionGrid = isHasInReactionGrid; |
|
|
|
group.isHasReactionCompleted = isHasReactionCompleted; |
|
|
|
|
|
|
|
if (group.hasSomeGridReactedCompleted != isHasReactionCompleted) { |
|
|
|
group.hasSomeGridReactedCompleted = isHasReactionCompleted; |
|
|
|
group.version++; |
|
|
|
} |
|
|
|
if (group.hasSomeGridInReacting != isHasInReactionGrid) { |
|
|
|
group.hasSomeGridInReacting = isHasInReactionGrid; |
|
|
|
group.version++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@Scheduled(fixedDelay = 600) |
|
|
|