fix: 联动控制:溶氧低于阈值时,自动打开增氧机测试bug修复。

This commit is contained in:
tianyongbao
2026-04-03 22:51:40 +08:00
parent 7bf5813b35
commit f252b94832

View File

@@ -2179,33 +2179,124 @@ public class DeviceDataHandler {
* <li>溶解氧 ≥ 上限且上限开关已开且未触发过:关闭联动开关,设置 isOxyUpperTrigger=1</li>
* <li>溶解氧 ≤ 上限-0.3且已触发过:重置 isOxyUpperTrigger=0</li>
* </ul>
* <p>
* 当塘口内有多台测氧仪时,以塘口内所有测氧仪的最低溶解氧值作为判断依据,
* 并对塘口内所有配置了联动控制的设备执行判断。
* </p>
*
* @param deviceName 设备名称serialNum
* @param dissolvedOxygen 当前溶解氧
* @param dissolvedOxygen 当前溶解氧值(本设备上报值,最终使用塘口最低值)
*/
private void handleLinkedCtrl(String deviceName, double dissolvedOxygen) {
try {
// 查询设备(需要 id 和 iotId
Device device = deviceMapper.selectOne(
// 查询当前设备(需要 id、iotId、pondId
Device currentDevice = deviceMapper.selectOne(
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
.eq(Device::getSerialNum, deviceName)
.select(Device::getId, Device::getIotId, Device::getSerialNum, Device::getDeviceName)
.select(Device::getId, Device::getIotId, Device::getSerialNum, Device::getDeviceName,
Device::getPondId, Device::getValueDissolvedOxygen)
.last("LIMIT 1")
);
if (device == null || device.getId() == null) {
if (currentDevice == null || currentDevice.getId() == null) {
return;
}
// 查询该设备的所有联动控制配置
// 先更新当前设备的实时溶解氧(确保后续取最低值时已包含本次上报值)
// 注意updateDeviceRealTimeData 在 handleLinkedCtrl 调用前已执行,此处直接使用传入值
// 确定实际用于联动判断的溶解氧值:
// 若设备属于某个塘口,则取该塘口内所有测氧仪的最低溶解氧值;否则直接使用本设备值
double effectiveDissolvedOxygen = dissolvedOxygen;
Long pondId = currentDevice.getPondId();
if (pondId != null) {
// 查询同塘口所有设备(包含溶解氧实时值),用本次上报值覆盖当前设备的库存值
List<Device> pondDevices = deviceMapper.selectList(
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
.eq(Device::getPondId, pondId)
.select(Device::getId, Device::getSerialNum, Device::getValueDissolvedOxygen,
Device::getIsOxygenUsed, Device::getDeviceType)
);
double minOxy = dissolvedOxygen; // 默认为本设备当前上报值
for (Device pd : pondDevices) {
// 仅统计水质检测仪(type=1)或开启溶氧检测的测控一体机(type=2 & isOxygenUsed=1)
boolean isDetector = (pd.getDeviceType() != null && pd.getDeviceType() == 1)
|| (pd.getDeviceType() != null && pd.getDeviceType() == 2
&& pd.getIsOxygenUsed() != null && pd.getIsOxygenUsed() == 1);
if (!isDetector) {
continue;
}
double oxy;
if (pd.getId().equals(currentDevice.getId())) {
// 当前设备使用本次最新上报值(库存值可能尚未刷新)
oxy = dissolvedOxygen;
} else {
if (pd.getValueDissolvedOxygen() == null) {
continue;
}
oxy = pd.getValueDissolvedOxygen();
}
if (oxy < minOxy) {
minOxy = oxy;
}
}
effectiveDissolvedOxygen = minOxy;
log.debug("[联动控制] 塘口={} 设备={} 本机溶解氧={}, 塘口最低溶解氧={}",
pondId, deviceName, dissolvedOxygen, effectiveDissolvedOxygen);
}
// 查询该塘口(或该设备)所有有联动控制配置的设备 ID
// 若在塘口内,需对塘口内所有设备的联动控制进行判断
List<Long> deviceIdsToCheck = new java.util.ArrayList<>();
if (pondId != null) {
// 查询同塘口内所有测氧仪设备 ID含联动控制配置的
List<Device> pondDetectors = deviceMapper.selectList(
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
.eq(Device::getPondId, pondId)
.select(Device::getId, Device::getIsOxygenUsed, Device::getDeviceType)
);
for (Device pd : pondDetectors) {
boolean isDetector = (pd.getDeviceType() != null && pd.getDeviceType() == 1)
|| (pd.getDeviceType() != null && pd.getDeviceType() == 2
&& pd.getIsOxygenUsed() != null && pd.getIsOxygenUsed() == 1);
if (isDetector) {
deviceIdsToCheck.add(pd.getId());
}
}
} else {
deviceIdsToCheck.add(currentDevice.getId());
}
if (deviceIdsToCheck.isEmpty()) {
return;
}
// 查询上述设备的所有联动控制配置
List<com.intc.fishery.domain.LinkedCtrl> linkedCtrls = linkedCtrlMapper.selectList(
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.intc.fishery.domain.LinkedCtrl>()
.eq(com.intc.fishery.domain.LinkedCtrl::getDeviceId, device.getId())
.in(com.intc.fishery.domain.LinkedCtrl::getDeviceId, deviceIdsToCheck)
);
if (linkedCtrls == null || linkedCtrls.isEmpty()) {
return;
}
// 预加载联动控制对应的控制器设备信息用于下发指令按设备ID缓存
java.util.Map<Long, Device> deviceCacheById = new java.util.HashMap<>();
deviceCacheById.put(currentDevice.getId(), currentDevice);
for (com.intc.fishery.domain.LinkedCtrl linkedCtrl : linkedCtrls) {
// 获取该联动控制所属设备(用于下发指令时获取 iotId
Long linkedDeviceId = linkedCtrl.getDeviceId();
Device device = deviceCacheById.computeIfAbsent(linkedDeviceId, id ->
deviceMapper.selectOne(
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
.eq(Device::getId, id)
.select(Device::getId, Device::getIotId, Device::getSerialNum, Device::getDeviceName)
.last("LIMIT 1")
)
);
if (device == null) {
continue;
}
// 查询该联动控制关联的所有开关
List<com.intc.fishery.domain.DeviceSwitch> switches = deviceSwitchMapper.selectList(
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.intc.fishery.domain.DeviceSwitch>()
@@ -2215,12 +2306,12 @@ public class DeviceDataHandler {
continue;
}
// 溶解氧下限联动:溶解氧 ≤ 下限就开启开关
// 溶解氧下限联动:塘口最低溶解氧 ≤ 下限就开启开关
if (linkedCtrl.getOxyLowerOpen() != null && linkedCtrl.getOxyLowerOpen() == 1
&& linkedCtrl.getOxyLowerValue() != null
&& dissolvedOxygen <= linkedCtrl.getOxyLowerValue()) {
log.info("[联动控制] 设备={} 溶解氧={} ≤ 下限={},开启开关",
deviceName, dissolvedOxygen, linkedCtrl.getOxyLowerValue());
&& effectiveDissolvedOxygen <= linkedCtrl.getOxyLowerValue()) {
log.info("[联动控制] 触发设备={} 塘口最低溶解氧={} ≤ 下限={},开启开关(本机上报={}",
deviceName, effectiveDissolvedOxygen, linkedCtrl.getOxyLowerValue(), dissolvedOxygen);
setDeviceSwitchLinkedOpen(device, switches, true);
}
@@ -2228,28 +2319,28 @@ public class DeviceDataHandler {
boolean isOxyUpperTrigger = linkedCtrl.getIsOxyUpperTrigger() != null
&& linkedCtrl.getIsOxyUpperTrigger() == 1;
if (isOxyUpperTrigger) {
// 已触发过:溶解氧降回 上限-0.3 则重置触发标志
// 已触发过:塘口最低溶解氧降回 上限-0.3 则重置触发标志
if (linkedCtrl.getOxyUpperValue() != null
&& dissolvedOxygen <= linkedCtrl.getOxyUpperValue() - 0.3) {
&& effectiveDissolvedOxygen <= linkedCtrl.getOxyUpperValue() - 0.3) {
com.intc.fishery.domain.LinkedCtrl updateCtrl = new com.intc.fishery.domain.LinkedCtrl();
updateCtrl.setId(linkedCtrl.getId());
updateCtrl.setIsOxyUpperTrigger(0);
linkedCtrlMapper.updateById(updateCtrl);
log.info("[联动控制] 设备={} 溶解氧={} 降回至 上限-0.3={},重置触发标志",
deviceName, dissolvedOxygen, linkedCtrl.getOxyUpperValue() - 0.3);
log.info("[联动控制] 触发设备={} 塘口最低溶解氧={} 降回至 上限-0.3={},重置触发标志",
deviceName, effectiveDissolvedOxygen, linkedCtrl.getOxyUpperValue() - 0.3);
}
} else {
// 未触发:溶解氧 ≥ 上限则关闭开关
// 未触发:塘口最低溶解氧 ≥ 上限则关闭开关
if (linkedCtrl.getOxyUpperOpen() != null && linkedCtrl.getOxyUpperOpen() == 1
&& linkedCtrl.getOxyUpperValue() != null
&& dissolvedOxygen >= linkedCtrl.getOxyUpperValue()) {
&& effectiveDissolvedOxygen >= linkedCtrl.getOxyUpperValue()) {
// 设置触发标志并关闭开关
com.intc.fishery.domain.LinkedCtrl updateCtrl = new com.intc.fishery.domain.LinkedCtrl();
updateCtrl.setId(linkedCtrl.getId());
updateCtrl.setIsOxyUpperTrigger(1);
linkedCtrlMapper.updateById(updateCtrl);
log.info("[联动控制] 设备={} 溶解氧={} ≥ 上限={},关闭开关",
deviceName, dissolvedOxygen, linkedCtrl.getOxyUpperValue());
log.info("[联动控制] 触发设备={} 塘口最低溶解氧={} ≥ 上限={},关闭开关",
deviceName, effectiveDissolvedOxygen, linkedCtrl.getOxyUpperValue());
setDeviceSwitchLinkedOpen(device, switches, false);
}
}