|
@ -22,6 +22,8 @@ import lombok.RequiredArgsConstructor; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
import org.springframework.stereotype.Service; |
|
|
import org.springframework.stereotype.Service; |
|
|
|
|
|
|
|
|
|
|
|
import java.math.BigDecimal; |
|
|
|
|
|
import java.math.RoundingMode; |
|
|
import java.util.ArrayList; |
|
|
import java.util.ArrayList; |
|
|
import java.util.List; |
|
|
import java.util.List; |
|
|
import java.util.concurrent.CompletableFuture; |
|
|
import java.util.concurrent.CompletableFuture; |
|
@ -44,101 +46,31 @@ public class ChannelCtrlService { |
|
|
* 开始加液 |
|
|
* 开始加液 |
|
|
*/ |
|
|
*/ |
|
|
public void solutionAddStart() { |
|
|
public void solutionAddStart() { |
|
|
if(deviceState.isSolutionAdding()){ |
|
|
|
|
|
|
|
|
if (deviceState.isSolutionAdding()) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
CompletableFuture.runAsync(() -> { |
|
|
CompletableFuture.runAsync(() -> { |
|
|
List<ChannelState> channelStateList = deviceState.filterChannelStatesIsSelected(); |
|
|
List<ChannelState> channelStateList = deviceState.filterChannelStatesIsSelected(); |
|
|
try { |
|
|
try { |
|
|
|
|
|
List<CommandFuture> valveOpenDeviceCommandFutureList = new ArrayList<>(); |
|
|
for (ChannelState channelState : channelStateList) { |
|
|
for (ChannelState channelState : channelStateList) { |
|
|
channelState.setStateCode(ChannelStateCode.ADD); |
|
|
channelState.setStateCode(ChannelStateCode.ADD); |
|
|
|
|
|
|
|
|
|
|
|
DeviceCommand valveOpenDeviceCommand = getValveOpenCommandByChannel(channelState.getChannelCode()); |
|
|
|
|
|
valveOpenDeviceCommandFutureList.add(deviceCommandService.sendCommand(valveOpenDeviceCommand)); |
|
|
} |
|
|
} |
|
|
|
|
|
CommandUtil.wait(valveOpenDeviceCommandFutureList); |
|
|
if (SolutionAddMode.AUTO.equals(deviceState.getMode())) {//自动模式 |
|
|
if (SolutionAddMode.AUTO.equals(deviceState.getMode())) {//自动模式 |
|
|
while (!deviceState.isSolutionAddStop()) { |
|
|
while (!deviceState.isSolutionAddStop()) { |
|
|
List<CommandFuture> commandFutureList = new ArrayList<>(); |
|
|
|
|
|
for (ChannelState channelState : channelStateList) { |
|
|
|
|
|
//打开阀门 |
|
|
|
|
|
DeviceCommand valveOpenDeviceCommand = getValveOpenCommandByChannel(channelState.getChannelCode()); |
|
|
|
|
|
CommandFuture valveOpenCommandFuture = deviceCommandService.sendCommand(valveOpenDeviceCommand); |
|
|
|
|
|
CommandUtil.wait(valveOpenCommandFuture); |
|
|
|
|
|
|
|
|
|
|
|
DeviceCommand currentPositionDeviceCommand = getPumpPositionCommandByChannel(channelState.getChannelCode()); |
|
|
|
|
|
CommandFuture currentPositionCommandFuture = deviceCommandService.sendCommand(currentPositionDeviceCommand); |
|
|
|
|
|
CommandUtil.wait(currentPositionCommandFuture); |
|
|
|
|
|
Double currentPosition = currentPositionCommandFuture.getResponseResult().getJSONObject("data").getDouble("position"); |
|
|
|
|
|
channelState.setPumpPositionCache(currentPosition); |
|
|
|
|
|
|
|
|
|
|
|
Formulation formulation = formulationService.getOne(new LambdaQueryWrapper<Formulation>().eq(Formulation::getSolutionId, channelState.getSolutionId()) |
|
|
|
|
|
.eq(Formulation::getConcentration, channelState.getConcentration()).eq(Formulation::getVolume, channelState.getTargetVolume()).last("limit 1")); |
|
|
|
|
|
DeviceCommand deviceCommand = getPumpMoveByCommandByChannel(channelState.getChannelCode(), formulation.getRevolutions()); |
|
|
|
|
|
commandFutureList.add(deviceCommandService.sendCommand(deviceCommand)); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
CommandUtil.wait(commandFutureList); |
|
|
|
|
|
|
|
|
|
|
|
for (ChannelState channelState : channelStateList) {//与缓存的位置比较计算加液量 |
|
|
|
|
|
DeviceCommand currentPositionDeviceCommand = getPumpPositionCommandByChannel(channelState.getChannelCode()); |
|
|
|
|
|
CommandFuture currentPositionCommandFuture = deviceCommandService.sendCommand(currentPositionDeviceCommand); |
|
|
|
|
|
CommandUtil.wait(currentPositionCommandFuture); |
|
|
|
|
|
Double currentPosition = currentPositionCommandFuture.getResponseResult().getJSONObject("data").getDouble("position"); |
|
|
|
|
|
Formulation formulation = formulationService.getOne(new LambdaQueryWrapper<Formulation>().eq(Formulation::getSolutionId, channelState.getSolutionId()) |
|
|
|
|
|
.eq(Formulation::getConcentration, channelState.getConcentration()).eq(Formulation::getVolume, channelState.getTargetVolume()).last("limit 1")); |
|
|
|
|
|
Double dispensedVolume = calculateActualSolutionDispensedVolume(channelState.getPumpPositionCache(), currentPosition, formulation); |
|
|
|
|
|
log.info("实际加液量:{}", dispensedVolume); |
|
|
|
|
|
double currentVolume = channelState.getCurrentVolume() - dispensedVolume; |
|
|
|
|
|
if (currentVolume < 0) { |
|
|
|
|
|
currentVolume = 0; |
|
|
|
|
|
} |
|
|
|
|
|
channelState.setCurrentVolume(currentVolume); |
|
|
|
|
|
Channel channel = channelService.getOne(new LambdaQueryWrapper<>(new Channel()).eq(Channel::getCode, channelState.getChannelCode())); |
|
|
|
|
|
channel.setCurrentVolume(currentVolume); |
|
|
|
|
|
channelService.updateById(channel); |
|
|
|
|
|
AuditRecord auditRecord = new AuditRecord(deviceState.getCurrentUser().getId(), deviceState.getCurrentUser().getNickname(), channelState.getSolutionId(), |
|
|
|
|
|
channelState.getSolutionName(), formulation.getConcentration(), channelState.getChannelCode().name(), dispensedVolume); |
|
|
|
|
|
auditRecordService.saveOrUpdate(auditRecord); |
|
|
|
|
|
|
|
|
handleSolutionAdd(channelStateList); |
|
|
|
|
|
handleCalculateActualDispensedVolume(channelStateList); |
|
|
|
|
|
if (!deviceState.isSolutionAddStop()) { |
|
|
|
|
|
Thread.sleep(deviceState.getDelay() * 1000L); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Thread.sleep(deviceState.getDelay() * 1000L); |
|
|
|
|
|
} |
|
|
} |
|
|
} else if (SolutionAddMode.CLICK.equals(deviceState.getMode())) {//点动模式 |
|
|
} else if (SolutionAddMode.CLICK.equals(deviceState.getMode())) {//点动模式 |
|
|
List<CommandFuture> commandFutureList = new ArrayList<>(); |
|
|
|
|
|
for (ChannelState channelState : channelStateList) { |
|
|
|
|
|
//打开阀门 |
|
|
|
|
|
DeviceCommand valveOpenDeviceCommand = getValveOpenCommandByChannel(channelState.getChannelCode()); |
|
|
|
|
|
CommandFuture valveOpenCommandFuture = deviceCommandService.sendCommand(valveOpenDeviceCommand); |
|
|
|
|
|
CommandUtil.wait(valveOpenCommandFuture); |
|
|
|
|
|
|
|
|
|
|
|
Formulation formulation = formulationService.getOne(new LambdaQueryWrapper<Formulation>().eq(Formulation::getSolutionId, channelState.getSolutionId()) |
|
|
|
|
|
.eq(Formulation::getConcentration, channelState.getConcentration()).eq(Formulation::getVolume, channelState.getTargetVolume()).last("limit 1")); |
|
|
|
|
|
DeviceCommand deviceCommand = getPumpMoveByCommandByChannel(channelState.getChannelCode(), formulation.getRevolutions()); |
|
|
|
|
|
commandFutureList.add(deviceCommandService.sendCommand(deviceCommand)); |
|
|
|
|
|
AuditRecord auditRecord = new AuditRecord(deviceState.getCurrentUser().getId(), deviceState.getCurrentUser().getNickname(), channelState.getSolutionId(), |
|
|
|
|
|
channelState.getSolutionName(), formulation.getConcentration(), channelState.getChannelCode().name(), channelState.getTargetVolume()); |
|
|
|
|
|
auditRecordService.saveOrUpdate(auditRecord); |
|
|
|
|
|
} |
|
|
|
|
|
CommandUtil.wait(commandFutureList); |
|
|
|
|
|
|
|
|
|
|
|
for (ChannelState channelState : channelStateList) {//与缓存的位置比较计算加液量 |
|
|
|
|
|
DeviceCommand currentPositionDeviceCommand = getPumpPositionCommandByChannel(channelState.getChannelCode()); |
|
|
|
|
|
CommandFuture currentPositionCommandFuture = deviceCommandService.sendCommand(currentPositionDeviceCommand); |
|
|
|
|
|
CommandUtil.wait(currentPositionCommandFuture); |
|
|
|
|
|
Double currentPosition = currentPositionCommandFuture.getResponseResult().getJSONObject("data").getDouble("position"); |
|
|
|
|
|
Formulation formulation = formulationService.getOne(new LambdaQueryWrapper<Formulation>().eq(Formulation::getSolutionId, channelState.getSolutionId()) |
|
|
|
|
|
.eq(Formulation::getConcentration, channelState.getConcentration()).eq(Formulation::getVolume, channelState.getTargetVolume()).last("limit 1")); |
|
|
|
|
|
Double dispensedVolume = calculateActualSolutionDispensedVolume(channelState.getPumpPositionCache(), currentPosition, formulation); |
|
|
|
|
|
log.info("实际加液量:{}", dispensedVolume); |
|
|
|
|
|
double currentVolume = channelState.getCurrentVolume() - dispensedVolume; |
|
|
|
|
|
if (currentVolume < 0) { |
|
|
|
|
|
currentVolume = 0; |
|
|
|
|
|
} |
|
|
|
|
|
channelState.setCurrentVolume(currentVolume); |
|
|
|
|
|
Channel channel = channelService.getOne(new LambdaQueryWrapper<>(new Channel()).eq(Channel::getCode, channelState.getChannelCode())); |
|
|
|
|
|
channel.setCurrentVolume(currentVolume); |
|
|
|
|
|
channelService.updateById(channel); |
|
|
|
|
|
AuditRecord auditRecord = new AuditRecord(deviceState.getCurrentUser().getId(), deviceState.getCurrentUser().getNickname(), channelState.getSolutionId(), |
|
|
|
|
|
channelState.getSolutionName(), formulation.getConcentration(), channelState.getChannelCode().name(), dispensedVolume); |
|
|
|
|
|
auditRecordService.saveOrUpdate(auditRecord); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
handleSolutionAdd(channelStateList); |
|
|
|
|
|
handleCalculateActualDispensedVolume(channelStateList); |
|
|
} |
|
|
} |
|
|
} catch (Exception e) { |
|
|
} catch (Exception e) { |
|
|
throw new RuntimeException(e); |
|
|
throw new RuntimeException(e); |
|
@ -331,6 +263,62 @@ public class ChannelCtrlService { |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//=================================================私有================================================================================== |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 进行加液 |
|
|
|
|
|
*/ |
|
|
|
|
|
private void handleSolutionAdd(List<ChannelState> channelStateList) throws Exception { |
|
|
|
|
|
List<CommandFuture> pumpMoveByCommandFutureList = new ArrayList<>(); |
|
|
|
|
|
for (ChannelState channelState : channelStateList) { |
|
|
|
|
|
pumpPositionCache(channelState); |
|
|
|
|
|
Formulation formulation = formulationService.getOne(new LambdaQueryWrapper<Formulation>().eq(Formulation::getSolutionId, channelState.getSolutionId()) |
|
|
|
|
|
.eq(Formulation::getConcentration, channelState.getConcentration()).eq(Formulation::getVolume, channelState.getTargetVolume()).last("limit 1")); |
|
|
|
|
|
DeviceCommand deviceCommand = getPumpMoveByCommandByChannel(channelState.getChannelCode(), formulation.getRevolutions()); |
|
|
|
|
|
pumpMoveByCommandFutureList.add(deviceCommandService.sendCommand(deviceCommand)); |
|
|
|
|
|
} |
|
|
|
|
|
CommandUtil.wait(pumpMoveByCommandFutureList); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 缓存当前位置 |
|
|
|
|
|
*/ |
|
|
|
|
|
private void pumpPositionCache(ChannelState channelState) throws Exception { |
|
|
|
|
|
DeviceCommand currentPositionDeviceCommand = getPumpPositionCommandByChannel(channelState.getChannelCode()); |
|
|
|
|
|
CommandFuture currentPositionCommandFuture = deviceCommandService.sendCommand(currentPositionDeviceCommand); |
|
|
|
|
|
CommandUtil.wait(currentPositionCommandFuture); |
|
|
|
|
|
Double currentPosition = currentPositionCommandFuture.getResponseResult().getJSONObject("data").getDouble("position"); |
|
|
|
|
|
channelState.setPumpPositionCache(currentPosition); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 处理实际加液计算 |
|
|
|
|
|
*/ |
|
|
|
|
|
private void handleCalculateActualDispensedVolume(List<ChannelState> channelStateList) throws Exception { |
|
|
|
|
|
for (ChannelState channelState : channelStateList) {//与缓存的位置比较计算加液量 |
|
|
|
|
|
DeviceCommand currentPositionDeviceCommand = getPumpPositionCommandByChannel(channelState.getChannelCode()); |
|
|
|
|
|
CommandFuture currentPositionCommandFuture = deviceCommandService.sendCommand(currentPositionDeviceCommand); |
|
|
|
|
|
CommandUtil.wait(currentPositionCommandFuture); |
|
|
|
|
|
Double currentPosition = currentPositionCommandFuture.getResponseResult().getJSONObject("data").getDouble("position"); |
|
|
|
|
|
Formulation formulation = formulationService.getOne(new LambdaQueryWrapper<Formulation>().eq(Formulation::getSolutionId, channelState.getSolutionId()) |
|
|
|
|
|
.eq(Formulation::getConcentration, channelState.getConcentration()).eq(Formulation::getVolume, channelState.getTargetVolume()).last("limit 1")); |
|
|
|
|
|
double dispensedVolume = calculateActualSolutionDispensedVolume(channelState.getPumpPositionCache(), currentPosition, formulation); |
|
|
|
|
|
double currentVolume = channelState.getCurrentVolume() - dispensedVolume; |
|
|
|
|
|
BigDecimal bd = BigDecimal.valueOf(currentVolume); |
|
|
|
|
|
double roundedCurrentVolume = bd.setScale(2, RoundingMode.HALF_UP).doubleValue(); |
|
|
|
|
|
log.info("旧位置与新位置:{},{}", channelState.getPumpPositionCache(), currentPosition); |
|
|
|
|
|
log.info("实际加液量:{}", dispensedVolume); |
|
|
|
|
|
channelState.setCurrentVolume(roundedCurrentVolume); |
|
|
|
|
|
Channel channel = channelService.getOne(new LambdaQueryWrapper<>(new Channel()).eq(Channel::getCode, channelState.getChannelCode())); |
|
|
|
|
|
channel.setCurrentVolume(roundedCurrentVolume); |
|
|
|
|
|
channelService.updateById(channel); |
|
|
|
|
|
AuditRecord auditRecord = new AuditRecord(deviceState.getCurrentUser().getId(), deviceState.getCurrentUser().getNickname(), channelState.getSolutionId(), |
|
|
|
|
|
channelState.getSolutionName(), formulation.getConcentration(), channelState.getChannelCode().name(), roundedCurrentVolume); |
|
|
|
|
|
auditRecordService.saveOrUpdate(auditRecord); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 计算实际出液量 |
|
|
* 计算实际出液量 |
|
|
* |
|
|
* |
|
@ -341,7 +329,7 @@ public class ChannelCtrlService { |
|
|
* - revolutions 目标加液对应的旋转圈数 |
|
|
* - revolutions 目标加液对应的旋转圈数 |
|
|
* @return double 实际出液量 |
|
|
* @return double 实际出液量 |
|
|
*/ |
|
|
*/ |
|
|
public double calculateActualSolutionDispensedVolume(Double beforePosition, Double afterPosition, Formulation formulation) { |
|
|
|
|
|
|
|
|
private double calculateActualSolutionDispensedVolume(Double beforePosition, Double afterPosition, Formulation formulation) { |
|
|
if (beforePosition == null || afterPosition == null) { |
|
|
if (beforePosition == null || afterPosition == null) { |
|
|
throw new IllegalArgumentException("加液前/后位置参数不能为空"); |
|
|
throw new IllegalArgumentException("加液前/后位置参数不能为空"); |
|
|
} |
|
|
} |
|
@ -351,7 +339,7 @@ public class ChannelCtrlService { |
|
|
throw new IllegalArgumentException("Formulation 或其字段 volume/revolutions 不能为空"); |
|
|
throw new IllegalArgumentException("Formulation 或其字段 volume/revolutions 不能为空"); |
|
|
} |
|
|
} |
|
|
Integer pumpConversionFactor = systemConfigService.getValueByKeyToInteger(SystemConfigKey.PUMP_CONVERSION_FACTOR); |
|
|
Integer pumpConversionFactor = systemConfigService.getValueByKeyToInteger(SystemConfigKey.PUMP_CONVERSION_FACTOR); |
|
|
int deltaRevolutions = (int) (((afterPosition - beforePosition) / pumpConversionFactor)); |
|
|
|
|
|
|
|
|
double deltaRevolutions = (((afterPosition - beforePosition) / pumpConversionFactor)); |
|
|
double targetVolume = formulation.getVolume(); |
|
|
double targetVolume = formulation.getVolume(); |
|
|
double targetRevs = formulation.getRevolutions(); |
|
|
double targetRevs = formulation.getRevolutions(); |
|
|
if (targetRevs == 0) { |
|
|
if (targetRevs == 0) { |
|
|