18 changed files with 500 additions and 18 deletions
-
BINapp.db
-
9src/main/java/a8k/extapi_controler/ExtApiControler.java
-
8src/main/java/a8k/extapi_controler/pagecontrol/ExtApiTabConfig.java
-
7src/main/java/a8k/hardware/A8kCanBusService.java
-
5src/main/java/a8k/service/app/appctrl/AppDeviceCtrlService.java
-
2src/main/java/a8k/service/app/appctrl/AppMainFlowCtrlService.java
-
32src/main/java/a8k/service/app/appstate/SensorState.java
-
1src/main/java/a8k/service/app/appstate/type/OptScanModule.java
-
33src/main/java/a8k/service/app/background/BackgroudProcessCtrlService.java
-
79src/main/java/a8k/service/app/background/SensorDataUpdateService.java
-
85src/main/java/a8k/service/app/background/TemperatureCtrlService.java
-
81src/main/java/a8k/service/app/devicectrl/driver/TemperatureControlDriver.java
-
16src/main/java/a8k/service/app/devicectrl/driver/type/TemperatureControlerMid.java
-
41src/main/java/a8k/service/app/devicectrl/driver/type/TemperatureControlerRegIndex.java
-
67src/main/java/a8k/service/app/devicectrl/param/calibration/TemperatureCtrlParamCalibration.java
-
32src/main/java/a8k/service/app/devicectrl/param/param_mgr/TemperatureCtrlParamMgr.java
-
16src/main/java/a8k/service/app/devicectrl/param/type/TemperatureCtrlParam.java
-
2src/main/java/a8k/service/db/type/AppSetting.java
@ -0,0 +1,33 @@ |
|||
package a8k.service.app.background; |
|||
|
|||
import a8k.extapi_controler.utils.ExtApiFn; |
|||
import a8k.extapi_controler.utils.ExtApiTab; |
|||
import a8k.service.app.appdata.ProjIdCardInfoMgrService; |
|||
import a8k.type.exception.AppException; |
|||
import jakarta.annotation.Resource; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
@Component |
|||
@ExtApiTab(cfg = a8k.extapi_controler.pagecontrol.ExtApiTabConfig.BackgroudProcessCtrlService) |
|||
public class BackgroudProcessCtrlService { |
|||
|
|||
@Resource |
|||
ProjIdCardInfoMgrService projIdCardInfoMgrService; |
|||
@Resource |
|||
TemperatureCtrlService temperatureCtrlService; |
|||
@Resource |
|||
SensorDataUpdateService sensorDataUpdateService; |
|||
|
|||
|
|||
@ExtApiFn(name = "启动后台进程", group = "后台进程控制", order = 1) |
|||
synchronized public void startProcess() throws AppException { |
|||
temperatureCtrlService.startTemperatureControl(); |
|||
sensorDataUpdateService.startUpdate(); |
|||
} |
|||
|
|||
@ExtApiFn(name = "停止后台进程", group = "后台进程控制", order = 2) |
|||
synchronized public void stopProcess() throws AppException { |
|||
temperatureCtrlService.stopTemperatureControl(); |
|||
sensorDataUpdateService.stopUpdate(); |
|||
} |
|||
} |
@ -0,0 +1,79 @@ |
|||
package a8k.service.app.background; |
|||
|
|||
import a8k.hardware.A8kCanBusService; |
|||
import a8k.hardware.type.a8kcanprotocol.IOId; |
|||
import a8k.service.app.appstate.GStateService; |
|||
import a8k.service.app.appstate.type.OptScanModule; |
|||
import a8k.service.app.appstate.type.state.OptScanModuleState; |
|||
import a8k.service.app.devicectrl.driver.TemperatureControlDriver; |
|||
import a8k.type.exception.AppException; |
|||
import jakarta.annotation.Resource; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
@Component |
|||
@Slf4j |
|||
public class SensorDataUpdateService { |
|||
|
|||
@Resource |
|||
GStateService gStateService; |
|||
|
|||
@Resource |
|||
TemperatureControlDriver temperatureControlDriver; |
|||
|
|||
@Resource |
|||
A8kCanBusService canBus; |
|||
|
|||
Thread updateThread = null; |
|||
|
|||
public void startUpdate() { |
|||
if (updateThread != null) { |
|||
return; |
|||
} |
|||
|
|||
updateThread = new Thread(() -> { |
|||
while (true) { |
|||
try { |
|||
OptScanModuleState optScanModuleState = gStateService.getOptScanModule().getState(); |
|||
if (!optScanModuleState.equals(OptScanModuleState.EMPTY)) { |
|||
gStateService.getSensorState().setWasteBinFullFlag(false); |
|||
Thread.sleep(1000); |
|||
continue; |
|||
} |
|||
|
|||
canBus.setIOState(IOId.RecycleBinOverflowPPSPowerCtrl, true); |
|||
Thread.sleep(600);//等待光栅电源稳定 |
|||
Boolean wasteBinFullFlag = canBus.getIOState(IOId.RecycleBinOverflowPPS); |
|||
canBus.setIOState(IOId.RecycleBinOverflowPPSPowerCtrl, false); |
|||
|
|||
gStateService.getSensorState().setWasteBinFullFlag(wasteBinFullFlag); |
|||
|
|||
Thread.sleep(3000); |
|||
Double incubateBoxTemp = temperatureControlDriver.readIncubateBoxTemperature(); |
|||
gStateService.getSensorState().setIncubateBoxTemperature((int) (incubateBoxTemp + 0.5)); |
|||
|
|||
Double pbtemp = temperatureControlDriver.readPlateBoxTemperature(); |
|||
gStateService.getSensorState().setPboxTemperature((int) (pbtemp + 0.5)); |
|||
|
|||
|
|||
log.info("IncubateBoxTemperature: {}, PlateBoxTemperature: {}, WasteBinFullFlag: {}", incubateBoxTemp, pbtemp, wasteBinFullFlag); |
|||
} catch (InterruptedException e) { |
|||
break; |
|||
} catch (AppException e) { |
|||
log.error("Failed to read temperature data {}", e.getMessage()); |
|||
} |
|||
} |
|||
}); |
|||
updateThread.start(); |
|||
} |
|||
|
|||
public void stopUpdate() { |
|||
if (updateThread == null) { |
|||
return; |
|||
} |
|||
updateThread.interrupt(); |
|||
updateThread = null; |
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,85 @@ |
|||
package a8k.service.app.background; |
|||
|
|||
|
|||
import a8k.service.app.appsetting.AppSettingsMgr; |
|||
import a8k.service.app.devicectrl.driver.TemperatureControlDriver; |
|||
import a8k.service.db.type.AppSetting; |
|||
import a8k.service.test.state.VirtualDevice; |
|||
import a8k.type.exception.AppException; |
|||
import jakarta.annotation.PostConstruct; |
|||
import jakarta.annotation.Resource; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
@Component |
|||
@Slf4j |
|||
public class TemperatureCtrlService { |
|||
|
|||
|
|||
@Resource |
|||
TemperatureControlDriver temperatureControlDriver; |
|||
@Resource |
|||
VirtualDevice virtualDevice; |
|||
|
|||
@Resource |
|||
AppSettingsMgr appSettingsMgr; |
|||
|
|||
Integer temperature = 0; |
|||
Thread temperatureCtrlThread = null; |
|||
|
|||
@PostConstruct |
|||
public void init() { |
|||
// eventBus.regListener(this::onAppEvent); |
|||
} |
|||
|
|||
public void startTemperatureControl() throws AppException { |
|||
if (virtualDevice.isEnable()) { |
|||
return; |
|||
} |
|||
|
|||
if (temperatureCtrlThread != null) { |
|||
return; |
|||
} |
|||
|
|||
AppSetting setting = appSettingsMgr.getAppSettings(); |
|||
temperature = setting.getTemperature(); |
|||
temperatureControlDriver.startCtrlTemperature(temperature.doubleValue()); |
|||
|
|||
/* |
|||
* 启动线程,定时检查温度设定值,如果发生变化则调用温度控制器 |
|||
*/ |
|||
temperatureCtrlThread = new Thread(() -> { |
|||
while (true) { |
|||
try { |
|||
|
|||
Thread.sleep(1000); |
|||
Integer targetTemperature = appSettingsMgr.getAppSettings().getTemperature(); |
|||
if (!targetTemperature.equals(temperature)) { |
|||
temperature = targetTemperature; |
|||
temperatureControlDriver.startCtrlTemperature(temperature.doubleValue()); |
|||
} |
|||
|
|||
} catch (InterruptedException e) { |
|||
log.error("Temperature control thread interrupted"); |
|||
break; |
|||
} catch (AppException e) { |
|||
log.error("Temperature control error: {}", e.getMessage()); |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public void stopTemperatureControl() throws AppException { |
|||
if (virtualDevice.isEnable()) { |
|||
return; |
|||
} |
|||
|
|||
if (temperatureCtrlThread != null) { |
|||
temperatureCtrlThread.interrupt(); |
|||
temperatureCtrlThread = null; |
|||
} |
|||
temperatureControlDriver.stopCtrlTemperature(); |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,81 @@ |
|||
package a8k.service.app.devicectrl.driver; |
|||
|
|||
import a8k.hardware.A8kCanBusService; |
|||
import a8k.hardware.type.a8kcanprotocol.CmdId; |
|||
import a8k.service.app.devicectrl.driver.type.TemperatureControlerMid; |
|||
import a8k.service.app.devicectrl.driver.type.TemperatureControlerRegIndex; |
|||
import a8k.service.app.devicectrl.param.param_mgr.TemperatureCtrlParamMgr; |
|||
import a8k.service.app.devicectrl.param.type.TemperatureCtrlParam; |
|||
import a8k.type.exception.AppException; |
|||
import jakarta.annotation.Resource; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
@Component |
|||
@Slf4j |
|||
public class TemperatureControlDriver { |
|||
@Resource |
|||
A8kCanBusService canBus; |
|||
|
|||
Double incubatorTCMTempOffset = 0.0; |
|||
Double platesBoxTCMTempOffset = 0.0; |
|||
|
|||
@Resource |
|||
TemperatureCtrlParamMgr temperatureCtrlParamMgr; |
|||
|
|||
|
|||
public void startCtrlTemperature(Double temperature) throws AppException { |
|||
|
|||
incubatorTCMTempOffset = temperatureCtrlParamMgr.getParam(TemperatureCtrlParam.IncubatorTCMTempOffset); |
|||
platesBoxTCMTempOffset = temperatureCtrlParamMgr.getParam(TemperatureCtrlParam.PlatesBoxTCMTempOffset); |
|||
|
|||
Integer incubatorTCMSetTemp = (int) ((temperature + incubatorTCMTempOffset) * 10); |
|||
Integer platesBoxTCMSetTemp = (int) ((temperature + platesBoxTCMTempOffset) * 10); |
|||
|
|||
log.info("startCtrlTemperature {}", temperature); |
|||
log.info(" incubatorTCMSetTemp {}", incubatorTCMSetTemp); |
|||
log.info(" platesBoxTCMSetTemp {}", platesBoxTCMSetTemp); |
|||
|
|||
canBus.callcmd(TemperatureControlerMid.IncubatorTCM.mid, CmdId.temp_controler_start_hearting, incubatorTCMSetTemp); |
|||
canBus.callcmd(TemperatureControlerMid.PlatesBoxTCM.mid, CmdId.temp_controler_start_hearting, platesBoxTCMSetTemp); |
|||
} |
|||
|
|||
public void stopCtrlTemperature() throws AppException { |
|||
canBus.callcmd(TemperatureControlerMid.IncubatorTCM.mid, CmdId.temp_controler_stop_hearting); |
|||
canBus.callcmd(TemperatureControlerMid.PlatesBoxTCM.mid, CmdId.temp_controler_stop_hearting); |
|||
} |
|||
|
|||
public void testCtrlPeltierPower(TemperatureControlerMid mid, Integer val0To100) throws AppException { |
|||
canBus.callcmd(mid.mid, CmdId.temp_controler_set_peltier_power_level, val0To100); |
|||
} |
|||
|
|||
public void testCtrlFanLevel(TemperatureControlerMid mid, Integer val0To100) throws AppException { |
|||
canBus.callcmd(mid.mid, CmdId.temp_controler_set_fan_level, val0To100); |
|||
} |
|||
|
|||
public void testWaterPumpSpeed(TemperatureControlerMid mid, Integer val0To100) throws AppException { |
|||
canBus.callcmd(mid.mid, CmdId.temp_controler_set_pump_level, val0To100); |
|||
} |
|||
|
|||
public Double readIncubateBoxTemperature() throws AppException { |
|||
Integer readval = readReg(TemperatureControlerMid.IncubatorTCM, TemperatureControlerRegIndex.kreg_water_cooling_tmp_controler_temp0); |
|||
Double readvalDouble = readval / 10.0; |
|||
return readvalDouble - incubatorTCMTempOffset; |
|||
} |
|||
|
|||
public Double readPlateBoxTemperature() throws AppException { |
|||
Integer readval = readReg(TemperatureControlerMid.PlatesBoxTCM, TemperatureControlerRegIndex.kreg_water_cooling_tmp_controler_temp0); |
|||
Double readvalDouble = readval / 10.0; |
|||
return readvalDouble - platesBoxTCMTempOffset; |
|||
} |
|||
|
|||
public Integer readReg(TemperatureControlerMid mid, TemperatureControlerRegIndex regIndex) throws AppException { |
|||
return canBus.moduleGetReg(mid.mid, regIndex.regIndex); |
|||
} |
|||
|
|||
public void setReg(TemperatureControlerMid mid, TemperatureControlerRegIndex regIndex, Integer val) throws AppException { |
|||
canBus.moduleSetReg(mid.mid, regIndex.regIndex, val); |
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,16 @@ |
|||
package a8k.service.app.devicectrl.driver.type; |
|||
|
|||
import a8k.hardware.type.a8kcanprotocol.MId; |
|||
import org.springframework.util.Assert; |
|||
|
|||
public enum TemperatureControlerMid { |
|||
PlatesBoxTCM(MId.PlatesBoxTCM), |
|||
IncubatorTCM(MId.IncubatorTCM), |
|||
; |
|||
final public MId mid; |
|||
|
|||
TemperatureControlerMid(MId mid) { |
|||
Assert.isTrue(this.name().equals(mid.name()), "StepMotorMId init fail"); |
|||
this.mid = mid; |
|||
} |
|||
} |
@ -0,0 +1,41 @@ |
|||
package a8k.service.app.devicectrl.driver.type; |
|||
|
|||
import a8k.hardware.type.regindex.RegIndex; |
|||
import org.springframework.util.Assert; |
|||
|
|||
public enum TemperatureControlerRegIndex { |
|||
kreg_water_cooling_tmp_controler_pid_target(RegIndex.kreg_water_cooling_tmp_controler_pid_target), |
|||
kreg_water_cooling_tmp_controler_pid_nowoutput(RegIndex.kreg_water_cooling_tmp_controler_pid_nowoutput), |
|||
kreg_water_cooling_tmp_controler_pid_feedbackval(RegIndex.kreg_water_cooling_tmp_controler_pid_feedbackval), |
|||
kreg_water_cooling_tmp_controler_temp0(RegIndex.kreg_water_cooling_tmp_controler_temp0), |
|||
kreg_water_cooling_tmp_controler_temp1(RegIndex.kreg_water_cooling_tmp_controler_temp1), |
|||
kreg_water_cooling_tmp_controler_temp2(RegIndex.kreg_water_cooling_tmp_controler_temp2), |
|||
kreg_water_cooling_tmp_controler_temp3(RegIndex.kreg_water_cooling_tmp_controler_temp3), |
|||
kreg_water_cooling_tmp_controler_pid_kp(RegIndex.kreg_water_cooling_tmp_controler_pid_kp), |
|||
kreg_water_cooling_tmp_controler_pid_ki(RegIndex.kreg_water_cooling_tmp_controler_pid_ki), |
|||
kreg_water_cooling_tmp_controler_pid_kd(RegIndex.kreg_water_cooling_tmp_controler_pid_kd), |
|||
kreg_water_cooling_tmp_controler_pid_max_output(RegIndex.kreg_water_cooling_tmp_controler_pid_max_output), |
|||
kreg_water_cooling_tmp_controler_pid_min_output(RegIndex.kreg_water_cooling_tmp_controler_pid_min_output), |
|||
kreg_water_cooling_tmp_controler_pid_max_integral(RegIndex.kreg_water_cooling_tmp_controler_pid_max_integral), |
|||
kreg_water_cooling_tmp_controler_pid_min_integral(RegIndex.kreg_water_cooling_tmp_controler_pid_min_integral), |
|||
kreg_water_cooling_tmp_controler_pid_error_limit(RegIndex.kreg_water_cooling_tmp_controler_pid_error_limit), |
|||
kreg_water_cooling_tmp_controler_pid_compute_interval(RegIndex.kreg_water_cooling_tmp_controler_pid_compute_interval), |
|||
|
|||
; |
|||
public final RegIndex regIndex; |
|||
|
|||
TemperatureControlerRegIndex(RegIndex regIndex) { |
|||
Assert.isTrue(this.name().equals(regIndex.name()), "PipetteRegIndex name must be equal to RegIndex name"); |
|||
this.regIndex = regIndex; |
|||
} |
|||
|
|||
public static TemperatureControlerRegIndex valueOf(int val) { |
|||
TemperatureControlerRegIndex[] values = TemperatureControlerRegIndex.values(); |
|||
for (TemperatureControlerRegIndex regindex : values) { |
|||
if (regindex.regIndex.index == val) { |
|||
return regindex; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
} |
@ -0,0 +1,67 @@ |
|||
package a8k.service.app.devicectrl.param.calibration; |
|||
|
|||
|
|||
import a8k.extapi_controler.pagecontrol.ExtApiTabConfig; |
|||
import a8k.extapi_controler.utils.ExtApiFn; |
|||
import a8k.extapi_controler.utils.ExtApiTab; |
|||
import a8k.service.app.devicectrl.driver.TemperatureControlDriver; |
|||
import a8k.service.app.devicectrl.param.param_mgr.TemperatureCtrlParamMgr; |
|||
import a8k.service.app.devicectrl.param.type.TemperatureCtrlParam; |
|||
import a8k.type.exception.AppException; |
|||
import a8k.utils.ZJsonHelper; |
|||
import com.fasterxml.jackson.databind.node.ObjectNode; |
|||
import jakarta.annotation.Resource; |
|||
import org.slf4j.Logger; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
@ExtApiTab(cfg = ExtApiTabConfig.TemperatureCtrlParamCalibration) |
|||
@Component |
|||
public class TemperatureCtrlParamCalibration { |
|||
static Logger logger = org.slf4j.LoggerFactory.getLogger(TemperatureCtrlParamCalibration.class); |
|||
|
|||
|
|||
@Resource |
|||
TemperatureControlDriver temperatureControlDriver; |
|||
|
|||
@Resource |
|||
TemperatureCtrlParamMgr temperatureCtrlParamMgr; |
|||
|
|||
|
|||
@ExtApiFn(name = "获取所有参数", group = "基础", order = 1) |
|||
public Object getPoss() throws AppException { |
|||
return temperatureCtrlParamMgr.getParams(); |
|||
} |
|||
|
|||
|
|||
// 测试工具 |
|||
@ExtApiFn(name = "设置孵育盘温度偏差", group = "温度控制", order = 11) |
|||
public void setIncubatorBoxTemperatureOff(Double offset) throws AppException { |
|||
temperatureCtrlParamMgr.setParam(TemperatureCtrlParam.IncubatorTCMTempOffset, offset); |
|||
} |
|||
|
|||
@ExtApiFn(name = "设置板夹仓温度偏差", group = "温度控制", order = 12) |
|||
public void setPlatesBoxTCMTempOffset(Double offset) throws AppException { |
|||
temperatureCtrlParamMgr.setParam(TemperatureCtrlParam.PlatesBoxTCMTempOffset, offset); |
|||
} |
|||
|
|||
@ExtApiFn(name = "开始控制温度", group = "温度控制", order = 13) |
|||
public void startControlTemperature(Double temperature) throws AppException { |
|||
temperatureControlDriver.startCtrlTemperature(temperature); |
|||
} |
|||
|
|||
@ExtApiFn(name = "停止控制温度", group = "温度控制", order = 14) |
|||
public void stopControlTemperature() throws AppException { |
|||
temperatureControlDriver.stopCtrlTemperature(); |
|||
} |
|||
|
|||
//测量工具 |
|||
|
|||
@ExtApiFn(name = "读取温度", group = "传感状态", order = 21) |
|||
public Object readTemperature() throws AppException { |
|||
ObjectNode node = ZJsonHelper.createObjectNode(); |
|||
node.put("IncubatorBoxTemperature", temperatureControlDriver.readIncubateBoxTemperature()); |
|||
node.put("PlatesBoxTemperature", temperatureControlDriver.readPlateBoxTemperature()); |
|||
return node; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,32 @@ |
|||
package a8k.service.app.devicectrl.param.param_mgr; |
|||
|
|||
import a8k.service.app.devicectrl.param.param_mgr.base.ParamMgr; |
|||
import a8k.service.app.devicectrl.param.type.TemperatureCtrlParam; |
|||
import jakarta.annotation.PostConstruct; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
/** |
|||
* HBOT二维码扫描坐标参数 |
|||
*/ |
|||
@Component |
|||
public class TemperatureCtrlParamMgr extends ParamMgr { |
|||
static final Logger logger = LoggerFactory.getLogger(TemperatureCtrlParamMgr.class); |
|||
|
|||
@PostConstruct |
|||
void initialize() { |
|||
for (TemperatureCtrlParam pos : TemperatureCtrlParam.values()) { |
|||
setParamChName(pos, pos.chName); |
|||
} |
|||
} |
|||
|
|||
void setParam(TemperatureCtrlParam pos, Double value) { |
|||
super.setParam(pos, value); |
|||
} |
|||
|
|||
public Double getParam(TemperatureCtrlParam pos) { |
|||
return super.getParam(pos, Double.class); |
|||
} |
|||
} |
|||
|
@ -0,0 +1,16 @@ |
|||
package a8k.service.app.devicectrl.param.type; |
|||
|
|||
public enum TemperatureCtrlParam { |
|||
|
|||
|
|||
IncubatorTCMTempOffset("<孵育仓>温度偏移"), |
|||
PlatesBoxTCMTempOffset("<板夹仓>温度偏移"), |
|||
; |
|||
public final String chName; |
|||
|
|||
TemperatureCtrlParam(String chName) { |
|||
this.chName = chName; |
|||
} |
|||
|
|||
|
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue