diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDeviceRegisterManager.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDeviceRegisterManager.java index 8ace6af..8ba580a 100644 --- a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDeviceRegisterManager.java +++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDeviceRegisterManager.java @@ -42,16 +42,6 @@ public class DiDeviceRegisterManager { } } - // reset register to default value - public void resetAllByModuleId( Integer mid ) { - for ( DiDeviceRegister register : this.registers.values() ) { - if ( register.mid.equals(mid) ) { - LOG.info("[Register:${}] {}@{} = {}", register.key, register.index, register.mid, register.defaultValue); - this.device.call(DiCommand.MODULE_SET_REG, register.mid, register.index, register.defaultValue); - } - } - } - // get actuator public void get( String id ) { this.registers.get(id); @@ -62,4 +52,13 @@ public class DiDeviceRegisterManager { DiCommandResponse response = this.device.call(DiCommand.MODULE_GET_REG, mid, index); return response.readInteger(0); } + + // get value + public Integer getValue( String id ) { + DiDeviceRegister reg = this.registers.get(id); + if ( null == reg ) { + throw new RuntimeException("Invalid register id: " + id); + } + return this.getValue(reg.mid, reg.index); + } } diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/connection/DiConSerialPort.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/connection/DiConSerialPort.java index 4dfdfb5..c0558e9 100644 --- a/src/src/main/java/com/my/graphiteDigesterBg/diframe/connection/DiConSerialPort.java +++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/connection/DiConSerialPort.java @@ -147,7 +147,7 @@ public class DiConSerialPort implements DiDeviceConnection { } @Override - public void call(DiCommandRequest request) { + synchronized public void call(DiCommandRequest request) { Boolean commandLogEnable = this.device.getConfig("connection.commandLogEnable", Boolean.class); this.requests.add(request); diff --git a/src/src/main/java/com/my/graphiteDigesterBg/move/MoveHeatPlateSlotHeating.java b/src/src/main/java/com/my/graphiteDigesterBg/move/MoveHeatPlateSlotHeating.java new file mode 100644 index 0000000..e0fa490 --- /dev/null +++ b/src/src/main/java/com/my/graphiteDigesterBg/move/MoveHeatPlateSlotHeating.java @@ -0,0 +1,93 @@ +package com.my.graphiteDigesterBg.move; +import com.my.graphiteDigesterBg.diframe.DiTaskMoveBase; +import com.my.graphiteDigesterBg.resource.ResHeatingTubeRackSlot; +import com.my.graphiteDigesterBg.resource.ResHeatingTubeRackSlotManager; +import java.util.Timer; +import java.util.TimerTask; +public class MoveHeatPlateSlotHeating extends DiTaskMoveBase { + // finish callback + public interface FinishCallback { + void callback(); + } + + // slot index + public Integer slotIndex; + // temperature + public Integer temperature; + // duration + public Integer duration; + // done callback + private FinishCallback finishCallback; + // slot + private ResHeatingTubeRackSlot slot; + // is heating on + private Boolean isHeatingOn; + + @Override + public void run() { + var slotMan = this.getResourceManager(ResHeatingTubeRackSlotManager.class); + this.slot = slotMan.getSlotByIndex(this.slotIndex); + this.slot.destTemperature = this.temperature * 100; + this.slot.heatingDuration = this.duration * 60; + this.slot.heatingStartedAt = null; + this.slot.isHeating = true; + this.isHeatingOn = false; + + String message = String.format("试管架%d : 开始加热", this.slotIndex); + this.getDevice().getRuntimeVariables().setString(message, "StatusMessage"); + this.heating(); + } + + // on done + public void onFinish( FinishCallback callback ) { + this.finishCallback = callback; + } + + // heating + public void heating() { + String heaterKey = "HeatPlateSlotHeater" + this.slotIndex; + // 如果温度低于目标温度,打开加热器 + if ( this.slot.temperature < this.slot.destTemperature ) { + if ( !this.isHeatingOn ) { + this.getDevice().getIO().setValue(heaterKey, 1); + this.isHeatingOn = true; + } + this.heatingContinue(); + return ; + } + + // 如果温度高于目标温度,关闭加热器 + if ( this.isHeatingOn ) { + this.getDevice().getIO().setValue(heaterKey, 0); + this.isHeatingOn = false; + } + + // 开始计时 + if ( null == this.slot.heatingStartedAt ) { + this.slot.heatingStartedAt = (int)(System.currentTimeMillis()/1000); + } + + // 检查时间到了没有 ~~~ + var duration = System.currentTimeMillis()/1000 - this.slot.heatingStartedAt; + if ( duration > this.slot.heatingDuration ) { + String message = String.format("试管架%d : 加热完成", this.slotIndex); + this.getDevice().getRuntimeVariables().setString(message, "StatusMessage"); + this.slot.isHeating = false; + this.finishCallback.callback(); + return ; + } + + this.heatingContinue(); + } + + // continue heating + private void heatingContinue() { + var timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + MoveHeatPlateSlotHeating.this.heating(); + } + }, 5000); + } +} diff --git a/src/src/main/java/com/my/graphiteDigesterBg/resource/ResHeatingTubeRackSlot.java b/src/src/main/java/com/my/graphiteDigesterBg/resource/ResHeatingTubeRackSlot.java index deffbc8..bcf965a 100644 --- a/src/src/main/java/com/my/graphiteDigesterBg/resource/ResHeatingTubeRackSlot.java +++ b/src/src/main/java/com/my/graphiteDigesterBg/resource/ResHeatingTubeRackSlot.java @@ -1,16 +1,8 @@ package com.my.graphiteDigesterBg.resource; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.my.graphiteDigesterBg.MyDevice; -import com.my.graphiteDigesterBg.diframe.DiTask; -import com.my.graphiteDigesterBg.diframe.actuator.DiActMotor; -import com.my.graphiteDigesterBg.diframe.actuator.DiActServo; -import com.my.graphiteDigesterBg.task.TaskDigestion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import java.util.ArrayList; import java.util.List; - public class ResHeatingTubeRackSlot { // logger public static final Logger LOG = LoggerFactory.getLogger(ResHeatingTubeRackSlot.class); @@ -110,21 +102,4 @@ public class ResHeatingTubeRackSlot { public Boolean getIsHeating() { return this.isHeating; } - - // get cover servo - @JsonIgnore - public DiActServo getCoverServo() { - String servoKey = "heatSlot" + this.index.toString() + "CoverServo"; - return (DiActServo) this.manager.getDevice().getActuators().get(servoKey); - } - - // open cover - public void coverOpen() { - this.getCoverServo().moveTo(1000); - } - - // close cover - public void coverClose() { - this.getCoverServo().moveTo(2047); - } } diff --git a/src/src/main/java/com/my/graphiteDigesterBg/resource/ResHeatingTubeRackSlotManager.java b/src/src/main/java/com/my/graphiteDigesterBg/resource/ResHeatingTubeRackSlotManager.java index d5b1751..dc4f540 100644 --- a/src/src/main/java/com/my/graphiteDigesterBg/resource/ResHeatingTubeRackSlotManager.java +++ b/src/src/main/java/com/my/graphiteDigesterBg/resource/ResHeatingTubeRackSlotManager.java @@ -1,11 +1,13 @@ package com.my.graphiteDigesterBg.resource; import com.my.graphiteDigesterBg.diframe.DiResourceManagerBase; import com.my.graphiteDigesterBg.diframe.ResourceManager; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.*; @ResourceManager(name="HeatingTubeRackSlot") public class ResHeatingTubeRackSlotManager extends DiResourceManagerBase { + // logger + public static final Logger LOG = LoggerFactory.getLogger(ResHeatingTubeRackSlotManager.class); // slots private final List slots; // error slot index @@ -26,6 +28,24 @@ public class ResHeatingTubeRackSlotManager extends DiResourceManagerBase { this.errorSlotIndex = this.getDevice().getEnv().getProperty("app.errorSlotIndex",Integer.class); assert Objects.nonNull(this.errorSlotIndex); this.slots.get(this.errorSlotIndex).setupAsErrorSlot(); + + // start a timer task to refresh slot temperature every 5 seconds + var timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + ResHeatingTubeRackSlotManager.this.refreshSlotTemperature(); + } + }, 0, 5000); + } + + // refresh slot temperature + public void refreshSlotTemperature() { + var registers = this.getDevice().getRegisters(); + for (ResHeatingTubeRackSlot slot : this.slots) { + slot.temperature = registers.getValue("HeatingPlateSlotTemperature" + slot.index); + LOG.info("[Heating Slot {}] temperature: {}", slot.index, slot.temperature); + } } // get resource data diff --git a/src/src/main/java/com/my/graphiteDigesterBg/step/StepHeating.java b/src/src/main/java/com/my/graphiteDigesterBg/step/StepHeating.java index 1b561df..e8cd3a3 100644 --- a/src/src/main/java/com/my/graphiteDigesterBg/step/StepHeating.java +++ b/src/src/main/java/com/my/graphiteDigesterBg/step/StepHeating.java @@ -2,12 +2,10 @@ package com.my.graphiteDigesterBg.step; import com.my.graphiteDigesterBg.diframe.DiTask; import com.my.graphiteDigesterBg.diframe.DiTaskStepBase; import com.my.graphiteDigesterBg.diframe.TaskStep; -import com.my.graphiteDigesterBg.resource.ResHeatingTubeRackSlotManager; +import com.my.graphiteDigesterBg.move.MoveHeatPlateSlotHeating; import com.my.graphiteDigesterBg.task.TaskDigestion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Timer; -import java.util.TimerTask; @TaskStep(name="Heating") public class StepHeating extends DiTaskStepBase { // logger @@ -16,28 +14,20 @@ public class StepHeating extends DiTaskStepBase { public Integer temperature; // duration in seconds public Integer duration; - // timer - private Timer timer; @Override public void run() { var task = this.getTask(TaskDigestion.class); - var slotMan = task.getDevice().getResource().getManager(ResHeatingTubeRackSlotManager.class); - var slot = slotMan.getSlotByIndex(task.slotIndex); - slot.destTemperature = this.temperature; - slot.heatingDuration = this.duration * 60; - slot.heatingStartedAt = (int)(System.currentTimeMillis()/1000); - slot.heatingOn(); - task.setStatus(DiTask.TaskStatus.WAITING); - TimerTask timerTask = new TimerTask() { - @Override - public void run() { - slot.heatingOff(); - task.setStatus(DiTask.TaskStatus.READY); - } - }; - this.timer = new Timer(); - this.timer.schedule(timerTask, this.duration * 1000 * 60); + var heating = new MoveHeatPlateSlotHeating(); + heating.slotIndex = task.slotIndex; + heating.temperature = this.temperature; + heating.duration = this.duration * 60; + heating.setDevice(task.getDevice()); + heating.onFinish(() -> { + task.setStatus(DiTask.TaskStatus.READY); + }); + heating.run(); + task.setStatus(DiTask.TaskStatus.WAITING); } } diff --git a/src/src/main/java/com/my/graphiteDigesterBg/task/TaskHeating.java b/src/src/main/java/com/my/graphiteDigesterBg/task/TaskHeating.java index 68c36cd..bb32001 100644 --- a/src/src/main/java/com/my/graphiteDigesterBg/task/TaskHeating.java +++ b/src/src/main/java/com/my/graphiteDigesterBg/task/TaskHeating.java @@ -3,11 +3,8 @@ import com.my.graphiteDigesterBg.diframe.DiTask; import com.my.graphiteDigesterBg.diframe.DiTaskBase; import com.my.graphiteDigesterBg.diframe.Task; import com.my.graphiteDigesterBg.model.MdbOperationLog; -import com.my.graphiteDigesterBg.resource.ResHeatingTubeRackSlotManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import com.my.graphiteDigesterBg.move.MoveHeatPlateSlotHeating; import java.util.Timer; -import java.util.TimerTask; @Task(name="Heating") public class TaskHeating extends DiTaskBase { // slot index @@ -23,27 +20,15 @@ public class TaskHeating extends DiTaskBase { public void run() { MdbOperationLog.log(this.getUser(), "试管架%d : 样本加热 温度=%d, 时间=%d", this.slotIndex, this.temperature, this.duration); - var slotMan = this.getResourceManager(ResHeatingTubeRackSlotManager.class); - var slot = slotMan.getSlotByIndex(this.slotIndex); - slot.destTemperature = this.temperature; - slot.heatingDuration = this.duration * 60; - slot.heatingStartedAt = (int)(System.currentTimeMillis()/1000); - - slot.isHeating = true; - String heaterKey = "HeatPlateSlotHeater" + this.slotIndex; - this.getDevice().getIO().setValue(heaterKey, 1); - + var heating = new MoveHeatPlateSlotHeating(); + heating.slotIndex = this.slotIndex; + heating.temperature = this.temperature; + heating.duration = this.duration; + heating.setDevice(this.getDevice()); + heating.onFinish(() -> { + this.setStatus(DiTask.TaskStatus.FINISHED); + }); + heating.run(); this.setStatus(DiTask.TaskStatus.WAITING); - TimerTask timerTask = new TimerTask() { - @Override - public void run() { - TaskHeating.this.getDevice().getIO().setValue(heaterKey, 0); - slot.isHeating = false; - TaskHeating.this.setStatus(TaskStatus.FINISHED); - } - }; - - this.timer = new Timer(); - this.timer.schedule(timerTask, this.duration * 1000 * 60); } } diff --git a/src/src/main/resources/device.yml b/src/src/main/resources/device.yml index feb2fae..88b8abe 100644 --- a/src/src/main/resources/device.yml +++ b/src/src/main/resources/device.yml @@ -400,6 +400,9 @@ io : # device registers registers : - # 加热盘 Slot Cover - - {key: "HeatingPlateSlot1CoverServeMotorDefaultVelocity" , mid : 12, index : 1054, defaultValue : 150} - - {key: "HeatingPlateSlot1CoverServeMotorDefaultTorque" , mid : 12, index : 1077, defaultValue : 330} \ No newline at end of file + # 加热盘 Slot 温度 + - {key: "HeatingPlateSlotTemperature0", mid: 80, index: 201, defaultValue: 0} + - {key: "HeatingPlateSlotTemperature1", mid: 80, index: 200, defaultValue: 0} + - {key: "HeatingPlateSlotTemperature2", mid: 80, index: 202, defaultValue: 0} + - {key: "HeatingPlateSlotTemperature3", mid: 80, index: 203, defaultValue: 0} + - {key: "HeatingPlateSlotTemperature4", mid: 80, index: 204, defaultValue: 0} diff --git a/src/web/src/pages/main/contents/OperationTubeRackTemperature.vue b/src/web/src/pages/main/contents/OperationTubeRackTemperature.vue index 0759c67..3e876a9 100644 --- a/src/web/src/pages/main/contents/OperationTubeRackTemperature.vue +++ b/src/web/src/pages/main/contents/OperationTubeRackTemperature.vue @@ -10,7 +10,7 @@
-

{{ tubeRackSlot.temperature || '---' }}℃

+

{{ tubeRackSlot.temperature / 100 }}℃

A - {{ tubeRackSlot.index + 1 }}