fix: 定时任务,新增回查逻辑。

This commit is contained in:
tianyongbao
2026-03-23 23:33:54 +08:00
parent 18a16dce35
commit 0526aefb01

View File

@@ -56,6 +56,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
@@ -2678,10 +2679,101 @@ public class IotController extends BaseController {
}
// 设置属性
properties.put(IOTPropertyName.LOCAL_TIMER_SWITCH + deviceSwitch.getIndex(), listTimingCtrl);
String propertyKey = IOTPropertyName.LOCAL_TIMER_SWITCH + deviceSwitch.getIndex();
properties.put(propertyKey, listTimingCtrl);
// 调用IoT服务设置属性0
return iotCloudService.setProperty(device.getIotId(), properties, false, 0);
// 调用IoT服务设置属性
boolean setOk = iotCloudService.setProperty(device.getIotId(), properties, false, 0);
if (!setOk) {
return false;
}
// 回查验证等待设备上报最多重试3次每次间隔1秒
// 找到当前操作的定时控制项,确定期望的 isValid 值
int expectedIsValid = 0;
int targetIdx = -1;
for (int i = 0; i < allTimingCtrls.size(); i++) {
if (timeCtrlId.equals(allTimingCtrls.get(i).getId())) {
TimingCtrl targetCtrl = allTimingCtrls.get(i);
expectedIsValid = (targetCtrl.getIsOpen() != null && targetCtrl.getIsOpen() == 1) ? 1 : 0;
targetIdx = i;
break;
}
}
if (targetIdx < 0) {
// 找不到目标项(如删除场景),直接认为成功
return true;
}
for (int retry = 0; retry < 3; retry++) {
try {
Thread.sleep(1000L);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
return false;
}
try {
Map<String, Object> queryResult = iotCloudService.getDeviceProperties(device.getIotId());
if (queryResult == null || !Boolean.TRUE.equals(queryResult.get("success"))) {
log.warn("[TimerCtrl] 回查设备属性失败, retry={}", retry);
continue;
}
Object propData = queryResult.get("data");
if (propData == null) continue;
// 从返回属性列表中找 localTimer_switchX
List<?> propList = null;
if (propData instanceof Map) {
Object listObj = ((Map<?, ?>) propData).get("list");
if (listObj instanceof List) propList = (List<?>) listObj;
} else {
try {
Object listObj = propData.getClass().getMethod("getList").invoke(propData);
if (listObj instanceof List) propList = (List<?>) listObj;
} catch (Exception ignored) {}
}
if (propList == null) continue;
boolean matched = false;
for (Object item : propList) {
String attr = null;
Object val = null;
try {
attr = (String) item.getClass().getMethod("getIdentifier").invoke(item);
val = item.getClass().getMethod("getValue").invoke(item);
} catch (Exception ignored) {}
if (!propertyKey.equals(attr) || val == null) continue;
// val 是 JSON 数组字符串,解析后按 targetIdx 取对应项的 isValid
try {
cn.hutool.json.JSONArray jsonArray = cn.hutool.json.JSONUtil.parseArray(val.toString());
if (targetIdx < jsonArray.size()) {
cn.hutool.json.JSONObject jsonItem = jsonArray.getJSONObject(targetIdx);
int actualIsValid = jsonItem.getInt("isValid", -1);
if (actualIsValid == expectedIsValid) {
log.info("[TimerCtrl] 回查确认设备已收到定时控制设置, iotId={}, key={}, isValid={}",
device.getIotId(), propertyKey, actualIsValid);
return true;
}
}
} catch (Exception e2) {
log.warn("[TimerCtrl] 解析回查定时列表失败: {}", e2.getMessage());
}
matched = true;
break;
}
if (!matched) {
log.warn("[TimerCtrl] 回查未找到属性 key={}, retry={}", propertyKey, retry);
} else {
log.warn("[TimerCtrl] 回查属性未匹配预期, retry={}, expectedIsValid={}", retry, expectedIsValid);
}
} catch (Exception qe) {
log.warn("[TimerCtrl] 回查查询异常, retry={}, err={}", retry, qe.getMessage());
}
}
log.warn("[TimerCtrl] 回查重试完毕仍未确认设备收到, iotId={}, key={}", device.getIotId(), propertyKey);
return false;
} catch (Exception e) {
log.error("设置定时控制属性失败: {}", e.getMessage(), e);
return false;