21 changed files with 475 additions and 67 deletions
-
24src/main/java/a8k/app/controler/api/v1/app/state/ConsumablesMgrControler.java
-
24src/main/java/a8k/app/controler/api/v1/app/ws/AppWebSocketEndpointMgr.java
-
1src/main/java/a8k/app/hardware/type/A8kEcode.java
-
1src/main/java/a8k/app/i18n/Internationalization.java
-
9src/main/java/a8k/app/service/lowerctrl/LiquidOperationCtrService.java
-
16src/main/java/a8k/app/service/mainctrl/AppConsumablesScanService.java
-
4src/main/java/a8k/app/service/mainctrl/MainFlowCtrlScheduler.java
-
9src/main/java/a8k/app/service/statemgr/ConsumablesMgrService.java
-
15src/main/java/a8k/app/service/statemgr/DeviceWorkStateMgrService.java
-
175src/main/java/a8k/app/service/statemgr/PreReactionStateMgr.java
-
41src/main/java/a8k/app/type/PreReactionGrid.java
-
36src/main/java/a8k/app/type/PreReactionGridGroup.java
-
29src/main/java/a8k/app/type/PreReactionPosState.java
-
20src/main/java/a8k/app/type/a8k/ConsumableType.java
-
1src/main/java/a8k/app/type/a8k/LittleBottleConsumableType.java
-
10src/main/java/a8k/app/type/a8k/pos/PreReactionPos.java
-
6src/main/java/a8k/app/utils/ProjectParamUtils.java
-
5src/main/java/a8k/extui/mgr/ExtApiPageGroupCfgMgr.java
-
20src/main/java/a8k/extui/page/debug/P02ConsumablesMgrDebugPage.java
-
84src/main/java/a8k/extui/page/debug/PreReactionPosStateMgrDebugPage.java
-
12src/main/java/a8k/extui/page/test/verification/P34LiquidOperationTestPage.java
@ -0,0 +1,175 @@ |
|||
package a8k.app.service.statemgr; |
|||
|
|||
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.container.LittBottleConsumablesInfo; |
|||
import a8k.app.type.a8k.pos.PreReactionPos; |
|||
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; |
|||
import org.springframework.scheduling.annotation.Scheduled; |
|||
import org.springframework.stereotype.Component; |
|||
import org.springframework.util.Assert; |
|||
|
|||
@Component |
|||
@Slf4j |
|||
@RequiredArgsConstructor |
|||
@EnableScheduling |
|||
public class PreReactionStateMgr { |
|||
|
|||
PreReactionPosState preReactionPosState = new PreReactionPosState(); |
|||
|
|||
public synchronized PreReactionPosState getPreReactionPosState() { |
|||
return ObjectUtil.cloneByStream(preReactionPosState); |
|||
} |
|||
|
|||
public synchronized PreReactionGridGroup getPreReactionGridGroupState(ConsumableGroup group) { |
|||
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group); |
|||
return ObjectUtil.cloneByStream(gridGroup); |
|||
} |
|||
|
|||
public synchronized boolean isHasReactionCompleted() { |
|||
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) { |
|||
if (gridGroup.isHasReactionCompleted) { |
|||
return true; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
public synchronized boolean isHasInReactionGrid() { |
|||
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) { |
|||
if (gridGroup.isHasInReactionGrid) { |
|||
return true; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
public synchronized PreReactionPos getReactionCompletedPos() { |
|||
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) { |
|||
if (gridGroup.isHasReactionCompleted) { |
|||
for (PreReactionGrid grid : gridGroup.grids) { |
|||
if (grid.state.equals(PreReactionGrid.State.REACTION_COMPLETED)) { |
|||
PreReactionPos pos = new PreReactionPos(); |
|||
pos.group = gridGroup.group; |
|||
pos.type = gridGroup.consumableType; |
|||
pos.index = grid.posIndex; |
|||
return pos; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public synchronized void changeReactionGridStateToReacting(PreReactionPos preReactionPos, Long totalReactionTimeMs) { |
|||
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; |
|||
} |
|||
|
|||
|
|||
public synchronized boolean isHasInUSEReactionGrid(ConsumableGroup group) { |
|||
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group); |
|||
if (gridGroup != null) { |
|||
return gridGroup.isHasInReactionGrid || gridGroup.isHasReactionCompleted; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
|
|||
public synchronized void installConsumable(ConsumableGroup group, LittBottleConsumablesInfo littBottleConsumablesInfo) { |
|||
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group); |
|||
Assert.notNull(gridGroup, "gridGroup != null"); |
|||
gridGroup.consumableType = littBottleConsumablesInfo.type; |
|||
gridGroup.isInstalled = true; |
|||
changeAllGridStateToIdle(gridGroup.group); |
|||
gridGroup.syncInfo(); |
|||
} |
|||
|
|||
public synchronized void unInstallConsumable(ConsumableGroup group) { |
|||
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group); |
|||
Assert.notNull(gridGroup, "gridGroup != null"); |
|||
gridGroup.isInstalled = false; |
|||
changeAllGridStateToIdle(gridGroup.group); |
|||
} |
|||
|
|||
public synchronized void resetAll() { |
|||
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) { |
|||
changeAllGridStateToIdle(gridGroup.group); |
|||
} |
|||
} |
|||
|
|||
// ********************************************************************************* |
|||
// PRIVATE METHODS |
|||
// ********************************************************************************* |
|||
|
|||
private void changeAllGridStateToIdle(ConsumableGroup group) { |
|||
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group); |
|||
Assert.notNull(gridGroup, "gridGroup != null"); |
|||
gridGroup.isHasInReactionGrid = false; |
|||
gridGroup.isHasReactionCompleted = false; |
|||
for (PreReactionGrid grid : gridGroup.grids) { |
|||
grid.state = PreReactionGrid.State.IDLE; |
|||
grid.startReactionTime = 0L; |
|||
grid.hasReactionTime = 0L; |
|||
grid.totalReactionTime = 0L; |
|||
} |
|||
} |
|||
|
|||
private PreReactionGridGroup getPreReactionGridGroup(ConsumableGroup group) { |
|||
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) { |
|||
if (gridGroup.group.equals(group)) { |
|||
return gridGroup; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
|
|||
private void autoRefreshPreReactionPosState(PreReactionGridGroup group) { |
|||
// update hasReactionTime |
|||
if (!group.isInstalled) { |
|||
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; |
|||
} |
|||
} else if (grid.state.equals(PreReactionGrid.State.REACTION_COMPLETED)) { |
|||
isHasReactionCompleted = true; |
|||
} |
|||
} |
|||
group.isHasInReactionGrid = isHasInReactionGrid; |
|||
group.isHasReactionCompleted = isHasReactionCompleted; |
|||
} |
|||
|
|||
@Scheduled(fixedDelay = 600) |
|||
synchronized private void autoRefreshPreReactionPosState() { |
|||
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) { |
|||
autoRefreshPreReactionPosState(gridGroup); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,41 @@ |
|||
package a8k.app.type; |
|||
|
|||
import a8k.app.type.a8k.ConsumableGroup; |
|||
import a8k.app.type.a8k.LittleBottleConsumableType; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
public class PreReactionGrid implements Serializable { |
|||
public enum State { |
|||
IDLE, |
|||
REACTING, |
|||
REACTION_COMPLETED, |
|||
} |
|||
|
|||
public State state; |
|||
public LittleBottleConsumableType consumableType; |
|||
public ConsumableGroup group; |
|||
public Integer posIndex; |
|||
public Long startReactionTime; |
|||
public Long hasReactionTime; |
|||
public Long totalReactionTime; |
|||
|
|||
PreReactionGrid(ConsumableGroup group, Integer posIndex) { |
|||
this.group = group; |
|||
this.posIndex = posIndex; |
|||
this.state = State.IDLE; |
|||
this.startReactionTime = 0L; |
|||
this.hasReactionTime = 0L; |
|||
this.totalReactionTime = 0L; |
|||
} |
|||
|
|||
public PreReactionGrid() { |
|||
this.group = ConsumableGroup.CG1; |
|||
this.posIndex = 0; |
|||
this.state = State.IDLE; |
|||
this.startReactionTime = 0L; |
|||
this.hasReactionTime = 0L; |
|||
this.totalReactionTime = 0L; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,36 @@ |
|||
package a8k.app.type; |
|||
|
|||
import a8k.app.type.a8k.ConsumableGroup; |
|||
import a8k.app.type.a8k.LittleBottleConsumableType; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
public class PreReactionGridGroup implements Serializable { |
|||
|
|||
public List<PreReactionGrid> grids; |
|||
public ConsumableGroup group; |
|||
public LittleBottleConsumableType consumableType = LittleBottleConsumableType.BufferSolution; |
|||
public Boolean isHasInReactionGrid = false; |
|||
public Boolean isHasReactionCompleted = false; |
|||
public Boolean isInstalled = false; |
|||
|
|||
public PreReactionGridGroup(ConsumableGroup group) { |
|||
grids = new ArrayList<>(); |
|||
for (int i = 0; i < 25; i++) { |
|||
grids.add(new PreReactionGrid(group, i)); |
|||
} |
|||
this.group = group; |
|||
} |
|||
|
|||
public PreReactionGridGroup() { |
|||
} |
|||
|
|||
public void syncInfo() { |
|||
for (PreReactionGrid grid : grids) { |
|||
grid.consumableType = this.consumableType; |
|||
} |
|||
} |
|||
|
|||
} |
@ -0,0 +1,29 @@ |
|||
package a8k.app.type; |
|||
|
|||
import a8k.app.type.a8k.ConsumableGroup; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
public class PreReactionPosState implements Serializable { |
|||
|
|||
public List<PreReactionGridGroup> preReactionGridGroups; |
|||
|
|||
|
|||
public PreReactionPosState() { |
|||
this.preReactionGridGroups = new ArrayList<>(); |
|||
for (ConsumableGroup group : ConsumableGroup.values()) { |
|||
preReactionGridGroups.add(new PreReactionGridGroup(group)); |
|||
} |
|||
} |
|||
|
|||
public PreReactionGridGroup getPreReactionGridGroup(ConsumableGroup group) { |
|||
for (PreReactionGridGroup preReactionGridGroup : preReactionGridGroups) { |
|||
if (preReactionGridGroup.group.equals(group)) { |
|||
return preReactionGridGroup; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
}; |
@ -1,12 +1,12 @@ |
|||
package a8k.app.type.a8k; |
|||
|
|||
/** |
|||
* 耗材类型 |
|||
* 耗材类型只有两类耗材 |
|||
* 1. 探测物质+大瓶缓冲液 |
|||
* 2. 小瓶缓冲液 |
|||
*/ |
|||
public enum ConsumableType { |
|||
ProbeSubstance,//探测物质+大瓶缓冲液 |
|||
SmallBottleBuffer,//小瓶缓冲液 |
|||
} |
|||
///** |
|||
// * 耗材类型 |
|||
// * 耗材类型只有两类耗材 |
|||
// * 1. 探测物质+大瓶缓冲液 |
|||
// * 2. 小瓶缓冲液 |
|||
// */ |
|||
//public enum ConsumableType { |
|||
// ProbeSubstance,//探测物质 |
|||
// SmallBottleBuffer,//小瓶缓冲液 |
|||
//} |
@ -0,0 +1,84 @@ |
|||
package a8k.extui.page.debug; |
|||
|
|||
import a8k.app.service.statemgr.PreReactionStateMgr; |
|||
import a8k.app.type.PreReactionGridGroup; |
|||
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.IncubationSubTank; |
|||
import a8k.extui.mgr.ExtApiPageMgr; |
|||
import a8k.extui.type.ExtApiStatu; |
|||
import jakarta.annotation.PostConstruct; |
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
@Component |
|||
@Slf4j |
|||
@RequiredArgsConstructor |
|||
public class PreReactionPosStateMgrDebugPage { |
|||
|
|||
private final PreReactionStateMgr preReactionStateMgr; |
|||
private final ExtApiPageMgr extApiPageMgr; |
|||
|
|||
@ExtApiStatu(name = "", group = "孵育盘1状态", order = 1) |
|||
public PreReactionGridGroup getGroup1() { |
|||
return preReactionStateMgr.getPreReactionGridGroupState(ConsumableGroup.CG1); |
|||
} |
|||
|
|||
@ExtApiStatu(name = "", group = "孵育盘2状态", order = 2) |
|||
public PreReactionGridGroup getGroup2() { |
|||
return preReactionStateMgr.getPreReactionGridGroupState(ConsumableGroup.CG2); |
|||
} |
|||
|
|||
@ExtApiStatu(name = "", group = "孵育盘3状态", order = 3) |
|||
public PreReactionGridGroup getGroup3() { |
|||
return preReactionStateMgr.getPreReactionGridGroupState(ConsumableGroup.CG3); |
|||
} |
|||
|
|||
@ExtApiStatu(name = "", group = "孵育盘4状态", order = 4) |
|||
public PreReactionGridGroup getGroup4() { |
|||
return preReactionStateMgr.getPreReactionGridGroupState(ConsumableGroup.CG4); |
|||
} |
|||
|
|||
@ExtApiStatu(name = "", group = "孵育盘5状态", order = 5) |
|||
public PreReactionGridGroup getGroup5() { |
|||
return preReactionStateMgr.getPreReactionGridGroupState(ConsumableGroup.CG5); |
|||
} |
|||
|
|||
@ExtApiStatu(name = "", group = "孵育盘6状态", order = 6) |
|||
public PreReactionGridGroup getGroup6() { |
|||
return preReactionStateMgr.getPreReactionGridGroupState(ConsumableGroup.CG6); |
|||
} |
|||
|
|||
public void installOne(ConsumableGroup group, LittleBottleConsumableType consumableType) { |
|||
LittBottleConsumablesInfo consumableInfo = new LittBottleConsumablesInfo(); |
|||
consumableInfo.type = consumableType; |
|||
preReactionStateMgr.installConsumable(group, consumableInfo); |
|||
} |
|||
|
|||
public void uninstall(ConsumableGroup group) { |
|||
preReactionStateMgr.unInstallConsumable(group); |
|||
} |
|||
|
|||
public void changeStateToReacting(ConsumableGroup group, Integer off, Integer reactionTimeS) { |
|||
|
|||
PreReactionPos pos = new PreReactionPos(); |
|||
pos.group = group; |
|||
pos.type = LittleBottleConsumableType.BufferSolution; |
|||
pos.index = off; |
|||
preReactionStateMgr.changeReactionGridStateToReacting(pos, reactionTimeS.longValue() * 1000); |
|||
} |
|||
|
|||
|
|||
@PostConstruct |
|||
void init() { |
|||
var page = extApiPageMgr.newPage(this); |
|||
page.newGroup("预反应位点状态管理(只在单元测试中使用)"); |
|||
page.addFunction("加载耗材", this::installOne); |
|||
page.addFunction("卸载耗材", this::uninstall); |
|||
page.addFunction("切换状态到反应中", this::changeStateToReacting); |
|||
extApiPageMgr.addPage(page); |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue