diff --git a/app.db b/app.db index 2a0951e..8930bb7 100644 Binary files a/app.db and b/app.db differ diff --git a/src/main/java/com/iflytop/a800/device/Incubator.java b/src/main/java/com/iflytop/a800/device/Incubator.java index 74a4c40..b5902c2 100644 --- a/src/main/java/com/iflytop/a800/device/Incubator.java +++ b/src/main/java/com/iflytop/a800/device/Incubator.java @@ -1,9 +1,14 @@ package com.iflytop.a800.device; +import com.fasterxml.jackson.databind.JsonNode; +import com.iflytop.a800.EventMan; import com.iflytop.a800.resource.IncubatorSlot; import com.iflytop.a800.resource.TestCard; import com.iflytop.uf.UfActuatorCmdExecutor; import com.iflytop.uf.UfCmdSnippetExecutor; import com.iflytop.uf.model.UfMdbOption; +import com.iflytop.uf.model.UfMdbRuntimeVariable; +import com.iflytop.uf.util.UfCommon; +import com.iflytop.uf.util.UfJsonHelper; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -12,9 +17,15 @@ public class Incubator extends DeviceComponent { private final List slots; // 槽位起始索引 private Integer slotStartIndex = 0; + // 目标温度 + public Integer destTemperature = null; + // 是否正在加热 + private Boolean isHeatingOn = false; // 构造函数 public Incubator() { + this.destTemperature = null; + this.isHeatingOn = false; this.slotStartIndex = 0; this.slots = new ArrayList<>(); for ( int i = 0; i < 20; i++ ) { @@ -24,6 +35,83 @@ public class Incubator extends DeviceComponent { } } + // 获取当前温度 + public Double getCurrentTemperature() { + String incubatorTempStr = UfActuatorCmdExecutor.execute("IncubatorTempCtrl", "read_temperature"); + int intTemp = Integer.parseInt(incubatorTempStr); + return (Double)(intTemp / 10.0); + } + + // 等待温度到达指定温度 + public void waitForTemperature( Integer temp ) { + if ( 0 == temp ) { + return ; + } + + this.heatingStart(); + + int destTemp = temp * 10; + int pmValue = UfMdbOption.getInteger("IncubatorTemperaturePmValue", 0); + do { + int curTemp = (int)(this.getCurrentTemperature() * 10); + if ( curTemp - pmValue < destTemp && destTemp < curTemp + pmValue ) { + break; + } + UfCommon.delay(1000); + } while ( true ); + } + + // 加热 + public void heatingStart() { + if ( this.isHeatingOn ) { + return ; + } + + String temp = this.destTemperature.toString(); + UfActuatorCmdExecutor.execute("IncubatorTempCtrl", "temp_controler_start_hearting", temp); + this.isHeatingOn = true; + } + + // 停止加热 + public void heatingStop() { + if ( !this.isHeatingOn ) { + return ; + } + UfActuatorCmdExecutor.execute("IncubatorTempCtrl", "temp_controler_stop_hearting"); + this.isHeatingOn = false; + } + + // 通过运行时变量清理测试卡 + public void cleanupByRuntimeVariableSlotStatus() { + var scanner = Device.getInstance().scanner; + var listString = UfMdbRuntimeVariable.getString("IncubatorSlotCardStatus", "[]"); + var listJson = UfJsonHelper.jsonToNode(listString); + for (JsonNode item : listJson) { + int index = item.get("index").asInt(); + boolean hasCard = item.get("hasCard").asBoolean(); + if ( !hasCard ) { + continue; + } + + var slot = new IncubatorSlot(); + slot.index = index; + this.exitCardToScanner(slot); + scanner.dropCard(); + } + } + + // 刷新运行时变量状态 + private void refreshRuntimeVariableSlotStatus() { + List> status = new ArrayList<>(); + for ( int i = 0; i < 20; i++ ) { + var slot = this.slots.get(i); + status.add(Map.of("index", i, "hasCard", null != slot.card)); + } + + var list = UfJsonHelper.objectToJson(status); + UfMdbRuntimeVariable.setString("IncubatorSlotCardStatus", list); + } + // 移动至提交位置 public void moveToCommitPos( IncubatorSlot slot ) { Integer commitStartPos = UfMdbOption.getInteger("IncubatorSlotCommitStartPos"); @@ -50,6 +138,9 @@ public class Incubator extends DeviceComponent { throw new RuntimeException("无可用孵育盘槽位"); } + slot.card = card; + this.refreshRuntimeVariableSlotStatus(); + Integer boxPos = UfMdbOption.getInteger(String.format("TestCardWarehouseBox.%d", card.boxIndex)); Integer slotStartPos = UfMdbOption.getInteger("IncubatorSlotStartPos"); Integer slotDistance = UfMdbOption.getInteger("IncubatorSlotDistance"); @@ -64,7 +155,6 @@ public class Incubator extends DeviceComponent { "commit", commitPos ); UfCmdSnippetExecutor.execute("IncubatorTestCardPushIn", params); - slot.card = card; this.unlock(lock); return slot; @@ -78,5 +168,15 @@ public class Incubator extends DeviceComponent { Map params = Map.of("slot", slotPos); UfCmdSnippetExecutor.execute("IncubatorTestCardExitToScanner", params); slot.card = null; + this.refreshRuntimeVariableSlotStatus(); + + // 当所有测试卡退出后, 关掉加热 + boolean hasTestCard = false; + for ( var tmpSlot : this.slots ) { + hasTestCard = hasTestCard || tmpSlot.card != null; + } + if ( !hasTestCard ) { + this.heatingStop(); + } } } diff --git a/src/main/java/com/iflytop/a800/task/TubeTestTask.java b/src/main/java/com/iflytop/a800/task/TubeTestTask.java index c0a7458..9e718f9 100644 --- a/src/main/java/com/iflytop/a800/task/TubeTestTask.java +++ b/src/main/java/com/iflytop/a800/task/TubeTestTask.java @@ -83,6 +83,9 @@ public class TubeTestTask extends TaskBase { this.test.isSamplingFinished = "no"; this.test.save(); + // 等待孵育盘温度 + device.incubator.waitForTemperature(this.project.temperature); + // 移动试管架 if ( !UfMdbDictItem.match("TUBE_TYPE", "EMERGENCY", this.tube.type) ) { Integer testStartPos = UfMdbOption.getInteger("TubeRackTubeTestStartPos");