fix: 微信小程序接口对接修改,联调测试问题修复。
This commit is contained in:
@@ -47,13 +47,6 @@ public class AliyunIotProperties {
|
||||
*/
|
||||
private String categoryKey;
|
||||
|
||||
/**
|
||||
* 设备类型到产品Key的映射
|
||||
* 1: 水质检测仪
|
||||
* 2: 控制一体机
|
||||
*/
|
||||
private DeviceTypeMapping deviceType = new DeviceTypeMapping();
|
||||
|
||||
/**
|
||||
* MQTT 配置(可选,用于设备直连)
|
||||
*/
|
||||
@@ -165,47 +158,4 @@ public class AliyunIotProperties {
|
||||
private Integer reconnectDelay = 30000;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备类型映射配置
|
||||
*/
|
||||
@Data
|
||||
public static class DeviceTypeMapping {
|
||||
/**
|
||||
* 水质检测仪 ProductKey
|
||||
*/
|
||||
private String waterQualityMonitor;
|
||||
|
||||
/**
|
||||
* 控制一体机 ProductKey
|
||||
*/
|
||||
private String controlIntegrated;
|
||||
|
||||
/**
|
||||
* 控制器 ProductKey (别名,指向 controlIntegrated)
|
||||
* @return ProductKey
|
||||
*/
|
||||
public String getController() {
|
||||
return controlIntegrated;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据设备类型获取 ProductKey
|
||||
* @param deviceType 1-水质检测仪, 2-控制一体机
|
||||
* @return ProductKey
|
||||
*/
|
||||
public String getProductKeyByType(Integer deviceType) {
|
||||
if (deviceType == null) {
|
||||
return null;
|
||||
}
|
||||
switch (deviceType) {
|
||||
case 1:
|
||||
return waterQualityMonitor;
|
||||
case 2:
|
||||
return controlIntegrated;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.intc.iot.constant;
|
||||
|
||||
/**
|
||||
* 物联网平台设备属性名称常量
|
||||
*
|
||||
* @author intc
|
||||
* @date 2026-01-14
|
||||
*/
|
||||
public class IOTPropertyName {
|
||||
|
||||
private IOTPropertyName() {
|
||||
}
|
||||
|
||||
// ========== 水质检测仪属性 ==========
|
||||
/**
|
||||
* 物联网卡号
|
||||
*/
|
||||
public static final String ICCID = "ICCID";
|
||||
|
||||
/**
|
||||
* 溶解氧
|
||||
*/
|
||||
public static final String DISSOLVED_OXYGEN = "dissolvedOxygen";
|
||||
|
||||
/**
|
||||
* PH值
|
||||
*/
|
||||
public static final String PH = "PH";
|
||||
|
||||
/**
|
||||
* 水温
|
||||
*/
|
||||
public static final String CURRENT_TEMPERATURE = "currentTemperature";
|
||||
|
||||
/**
|
||||
* 饱和度
|
||||
*/
|
||||
public static final String DOSAT = "dosat";
|
||||
|
||||
/**
|
||||
* 故障码
|
||||
*/
|
||||
public static final String ERROR_CODE = "errorCode";
|
||||
|
||||
/**
|
||||
* 校准检测
|
||||
*/
|
||||
public static final String T_CORRECT = "Tcorrect";
|
||||
|
||||
/**
|
||||
* 盐度
|
||||
*/
|
||||
public static final String SALINITY = "salinity";
|
||||
|
||||
/**
|
||||
* 盐度设置
|
||||
*/
|
||||
public static final String SALINITY_SET = "salinitySet";
|
||||
|
||||
/**
|
||||
* 参比值
|
||||
*/
|
||||
public static final String T_REFERENCE = "Treference";
|
||||
|
||||
/**
|
||||
* 荧光值
|
||||
*/
|
||||
public static final String T_FLUORESCENCE = "Tfluorescence";
|
||||
|
||||
/**
|
||||
* 相位差
|
||||
*/
|
||||
public static final String PHASE_DIFFERENCE = "Phasedifference";
|
||||
|
||||
/**
|
||||
* 设备校准
|
||||
*/
|
||||
public static final String CORRECT = "correct";
|
||||
|
||||
// ========== 控制器属性 ==========
|
||||
/**
|
||||
* 控制器额定电压
|
||||
*/
|
||||
public static final String RATED_VOLTAGE = "rated_voltage";
|
||||
|
||||
/**
|
||||
* 控制器开关定时控制(前缀)
|
||||
*/
|
||||
public static final String LOCAL_TIMER_SWITCH = "localTimer_switch";
|
||||
|
||||
/**
|
||||
* 控制器开关(前缀)
|
||||
*/
|
||||
public static final String SWITCH_INDEX = "Switch";
|
||||
|
||||
/**
|
||||
* 控制器开关额定电流(前缀)
|
||||
*/
|
||||
public static final String RATING_SWITCH_INDEX = "rating_switch";
|
||||
|
||||
/**
|
||||
* 控制器传感器故障码
|
||||
*/
|
||||
public static final String SENSOR_ERROR_CODE = "sensorErrorCode";
|
||||
}
|
||||
@@ -5,10 +5,21 @@ import com.intc.common.mybatis.core.page.PageQuery;
|
||||
import com.intc.common.mybatis.core.page.TableDataInfo;
|
||||
import com.intc.common.satoken.utils.LoginHelper;
|
||||
import com.intc.common.web.core.BaseController;
|
||||
import com.intc.common.core.config.properties.DeviceTypeProperties;
|
||||
import com.intc.fishery.domain.Device;
|
||||
import com.intc.fishery.domain.DeviceSwitch;
|
||||
import com.intc.fishery.domain.TimingCtrl;
|
||||
import com.intc.fishery.domain.Pond;
|
||||
import com.intc.fishery.domain.LinkedCtrl;
|
||||
import com.intc.fishery.domain.DeviceCorrectRecord;
|
||||
import com.intc.fishery.domain.AquUser;
|
||||
import com.intc.fishery.domain.bo.*;
|
||||
import com.intc.fishery.domain.vo.DeviceSwitchVo;
|
||||
import com.intc.fishery.mapper.DeviceMapper;
|
||||
import com.intc.fishery.mapper.PondMapper;
|
||||
import com.intc.iot.config.AliyunIotProperties;
|
||||
import com.intc.fishery.mapper.DeviceSwitchMapper;
|
||||
import com.intc.fishery.mapper.DeviceCorrectRecordMapper;
|
||||
import com.intc.fishery.mapper.TimingCtrlMapper;
|
||||
import com.intc.iot.domain.bo.AddDeviceControllerBo;
|
||||
import com.intc.iot.domain.bo.AddDeviceDetectorBo;
|
||||
import com.intc.iot.domain.bo.DeviceCalibrateBo;
|
||||
@@ -27,12 +38,15 @@ import com.intc.iot.service.WarnCallNoticeService;
|
||||
import com.intc.iot.utils.AliyunAmqpSignUtil;
|
||||
import com.intc.iot.utils.ControllerHelper;
|
||||
import com.intc.iot.service.IotCloudService;
|
||||
import com.intc.iot.constant.IOTPropertyName;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Date;
|
||||
@@ -50,7 +64,7 @@ import java.util.Map;
|
||||
@Tag(name = "生活物联网平台管理", description = "阿里云飞燕平台对接接口")
|
||||
public class IotController extends BaseController {
|
||||
|
||||
private final AliyunIotProperties aliyunIotProperties;
|
||||
private final DeviceTypeProperties deviceTypeProperties;
|
||||
|
||||
@Autowired(required = false)
|
||||
private IotDeviceService iotDeviceService;
|
||||
@@ -86,13 +100,13 @@ public class IotController extends BaseController {
|
||||
private PondMapper pondMapper;
|
||||
|
||||
@Autowired(required = false)
|
||||
private com.intc.fishery.mapper.DeviceSwitchMapper deviceSwitchMapper;
|
||||
private DeviceSwitchMapper deviceSwitchMapper;
|
||||
|
||||
@Autowired(required = false)
|
||||
private com.intc.fishery.mapper.DeviceCorrectRecordMapper deviceCorrectRecordMapper;
|
||||
private DeviceCorrectRecordMapper deviceCorrectRecordMapper;
|
||||
|
||||
@Autowired(required = false)
|
||||
private com.intc.fishery.mapper.TimingCtrlMapper timingCtrlMapper;
|
||||
private TimingCtrlMapper timingCtrlMapper;
|
||||
|
||||
@Autowired(required = false)
|
||||
private IotCloudService iotCloudService;
|
||||
@@ -305,7 +319,7 @@ public class IotController extends BaseController {
|
||||
}
|
||||
|
||||
// 根据设备类型获取 ProductKey
|
||||
String productKey = aliyunIotProperties.getDeviceType().getProductKeyByType(devicetype);
|
||||
String productKey = deviceTypeProperties.getProductKeyByType(devicetype);
|
||||
if (productKey == null || productKey.isEmpty()) {
|
||||
return R.fail("未配置该设备类型的 ProductKey,请检查配置文件(deviceType: " + devicetype + ")");
|
||||
}
|
||||
@@ -722,9 +736,9 @@ public class IotController extends BaseController {
|
||||
// 验证塘口是否存在且属于当前用户
|
||||
if (bo.getPondId() != null && bo.getPondId() > 0 && pondMapper != null) {
|
||||
long count = pondMapper.selectCount(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.intc.fishery.domain.Pond>()
|
||||
.eq(com.intc.fishery.domain.Pond::getUserId, userId)
|
||||
.eq(com.intc.fishery.domain.Pond::getId, bo.getPondId())
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Pond>()
|
||||
.eq(Pond::getUserId, userId)
|
||||
.eq(Pond::getId, bo.getPondId())
|
||||
);
|
||||
if (count == 0) {
|
||||
return R.fail("塘口不存在或无权限访问");
|
||||
@@ -742,7 +756,7 @@ public class IotController extends BaseController {
|
||||
}
|
||||
|
||||
// 获取控制器的 ProductKey
|
||||
String productKey = aliyunIotProperties.getDeviceType().getControlIntegrated();
|
||||
String productKey = deviceTypeProperties.getControlIntegrated();
|
||||
if (productKey == null || productKey.isEmpty()) {
|
||||
return R.fail("未配置测控一体机的 ProductKey");
|
||||
}
|
||||
@@ -944,9 +958,9 @@ public class IotController extends BaseController {
|
||||
device.setTempWarnCallNoDis(0);
|
||||
|
||||
// 创建开关列表
|
||||
java.util.List<com.intc.fishery.domain.DeviceSwitch> switches = new java.util.ArrayList<>();
|
||||
java.util.List<DeviceSwitch> switches = new java.util.ArrayList<>();
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
com.intc.fishery.domain.DeviceSwitch deviceSwitch = new com.intc.fishery.domain.DeviceSwitch();
|
||||
DeviceSwitch deviceSwitch = new DeviceSwitch();
|
||||
deviceSwitch.setIndex(i);
|
||||
deviceSwitch.setSwitchName(device.getDeviceName() + "_开关_" + i);
|
||||
deviceSwitch.setConnectVoltageType(bo.getInputVoltage());
|
||||
@@ -1089,7 +1103,7 @@ public class IotController extends BaseController {
|
||||
}
|
||||
|
||||
// 保存开关信息
|
||||
for (com.intc.fishery.domain.DeviceSwitch deviceSwitch : switches) {
|
||||
for (DeviceSwitch deviceSwitch : switches) {
|
||||
deviceSwitch.setDeviceId(device.getId());
|
||||
deviceSwitchMapper.insert(deviceSwitch);
|
||||
}
|
||||
@@ -1119,7 +1133,7 @@ public class IotController extends BaseController {
|
||||
/**
|
||||
* 解析开关电压电流数据
|
||||
*/
|
||||
private void parseSwitchVoltCur(String json, com.intc.fishery.domain.DeviceSwitch deviceSwitch) {
|
||||
private void parseSwitchVoltCur(String json, DeviceSwitch deviceSwitch) {
|
||||
try {
|
||||
// 清理JSON字符串
|
||||
json = json.replace("\"{", "{").replace("}\"", "}").replace("\\", "");
|
||||
@@ -1156,9 +1170,9 @@ public class IotController extends BaseController {
|
||||
// 验证塘口是否存在且属于当前用户
|
||||
if (bo.getPondId() != null && bo.getPondId() > 0 && pondMapper != null) {
|
||||
long count = pondMapper.selectCount(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.intc.fishery.domain.Pond>()
|
||||
.eq(com.intc.fishery.domain.Pond::getUserId, userId)
|
||||
.eq(com.intc.fishery.domain.Pond::getId, bo.getPondId())
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Pond>()
|
||||
.eq(Pond::getUserId, userId)
|
||||
.eq(Pond::getId, bo.getPondId())
|
||||
);
|
||||
if (count == 0) {
|
||||
return R.fail("塘口不存在或无权限访问");
|
||||
@@ -1176,7 +1190,7 @@ public class IotController extends BaseController {
|
||||
}
|
||||
|
||||
// 获取水质检测仪的 ProductKey
|
||||
String productKey = aliyunIotProperties.getDeviceType().getWaterQualityMonitor();
|
||||
String productKey = deviceTypeProperties.getWaterQualityMonitor();
|
||||
if (productKey == null || productKey.isEmpty()) {
|
||||
return R.fail("未配置水质检测仪的 ProductKey");
|
||||
}
|
||||
@@ -1478,7 +1492,7 @@ public class IotController extends BaseController {
|
||||
|
||||
// 创建校准记录
|
||||
if (deviceCorrectRecordMapper != null) {
|
||||
com.intc.fishery.domain.DeviceCorrectRecord correctRecord = new com.intc.fishery.domain.DeviceCorrectRecord();
|
||||
DeviceCorrectRecord correctRecord = new DeviceCorrectRecord();
|
||||
correctRecord.setDeviceId(device.getId());
|
||||
correctRecord.setUserId(userId);
|
||||
correctRecord.setSerialNum(device.getSerialNum());
|
||||
@@ -1669,9 +1683,9 @@ public class IotController extends BaseController {
|
||||
|
||||
// 更新关联开关的接线方式
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getDeviceId, request.getId())
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getConnectVoltageType, request.getVoltageType())
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<DeviceSwitch>()
|
||||
.eq(DeviceSwitch::getDeviceId, request.getId())
|
||||
.set(DeviceSwitch::getConnectVoltageType, request.getVoltageType())
|
||||
);
|
||||
|
||||
String voltageDesc = ControllerHelper.getVoltageDescription(request.getVoltageType());
|
||||
@@ -1693,7 +1707,7 @@ public class IotController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "开关开启/关闭控制")
|
||||
@PutMapping("/switch/turn_switch")
|
||||
public R<Void> turnSwitch(@RequestBody com.intc.fishery.domain.bo.ReqTurnOpen request) {
|
||||
public R<Void> turnSwitch(@RequestBody ReqTurnOpen request) {
|
||||
try {
|
||||
if (deviceSwitchMapper == null || deviceMapper == null) {
|
||||
return R.fail("系统配置未完成");
|
||||
@@ -1704,7 +1718,7 @@ public class IotController extends BaseController {
|
||||
Integer targetStatus = request.getIsOpen();
|
||||
|
||||
// 查询开关信息
|
||||
com.intc.fishery.domain.DeviceSwitch deviceSwitch = deviceSwitchMapper.selectById(switchId);
|
||||
DeviceSwitch deviceSwitch = deviceSwitchMapper.selectById(switchId);
|
||||
if (deviceSwitch == null) {
|
||||
return R.fail("开关不存在");
|
||||
}
|
||||
@@ -1751,7 +1765,7 @@ public class IotController extends BaseController {
|
||||
|
||||
// 构造IoT属性
|
||||
Map<String, Object> properties = new java.util.HashMap<>();
|
||||
properties.put("switchIndex" + deviceSwitch.getIndex(), targetStatus);
|
||||
properties.put(IOTPropertyName.SWITCH_INDEX + deviceSwitch.getIndex(), targetStatus);
|
||||
|
||||
// 调用物联网服务设置属性
|
||||
boolean success = iotCloudService.setProperty(device.getIotId(), properties, true, 2);
|
||||
@@ -1761,15 +1775,15 @@ public class IotController extends BaseController {
|
||||
|
||||
// 更新数据库中的开关状态和最后操作时间
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getIsOpen, targetStatus)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getLastTurnTime, new Date())
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<DeviceSwitch>()
|
||||
.eq(DeviceSwitch::getId, switchId)
|
||||
.set(DeviceSwitch::getIsOpen, targetStatus)
|
||||
.set(DeviceSwitch::getLastTurnTime, new Date())
|
||||
);
|
||||
|
||||
// 记录操作日志
|
||||
String operation = targetStatus == 1 ? "开启" : "关闭";
|
||||
log.info("开关操作:{}({})的开关{}:{}",
|
||||
log.info("开关操作:{}({})的开关{}:{}",
|
||||
device.getDeviceName(), device.getSerialNum(), deviceSwitch.getSwitchName(), operation);
|
||||
|
||||
return R.ok();
|
||||
@@ -1787,7 +1801,7 @@ public class IotController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "设置塘口所有开关状态")
|
||||
@PutMapping("/switch/turn_pond_switch")
|
||||
public R<Void> turnPondSwitch(@RequestBody com.intc.fishery.domain.bo.ReqTurnOpen request) {
|
||||
public R<Void> turnPondSwitch(@RequestBody ReqTurnOpen request) {
|
||||
try {
|
||||
if (deviceSwitchMapper == null || deviceMapper == null) {
|
||||
return R.fail("系统配置未完成");
|
||||
@@ -1798,30 +1812,30 @@ public class IotController extends BaseController {
|
||||
Integer targetStatus = request.getIsOpen();
|
||||
|
||||
// 查询塘口下所有开关信息(包括关联的设备信息)
|
||||
com.github.yulichang.wrapper.MPJLambdaWrapper<com.intc.fishery.domain.DeviceSwitch> wrapper =
|
||||
new com.github.yulichang.wrapper.MPJLambdaWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.selectAll(com.intc.fishery.domain.DeviceSwitch.class)
|
||||
com.github.yulichang.wrapper.MPJLambdaWrapper<DeviceSwitch> wrapper =
|
||||
new com.github.yulichang.wrapper.MPJLambdaWrapper<DeviceSwitch>()
|
||||
.selectAll(DeviceSwitch.class)
|
||||
.selectAs(Device::getUserId, "userId")
|
||||
.selectAs(Device::getIotId, "iotId")
|
||||
.selectAs(Device::getSerialNum, "serialNum")
|
||||
.selectAs(Device::getDeviceName, "deviceName")
|
||||
.selectAs(Device::getWarnCode, "warnCode")
|
||||
.selectAs(Device::getDeadTime, "deadTime")
|
||||
.leftJoin(Device.class, Device::getId, com.intc.fishery.domain.DeviceSwitch::getDeviceId)
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getPondId, pondId);
|
||||
.leftJoin(Device.class, Device::getId, DeviceSwitch::getDeviceId)
|
||||
.eq(DeviceSwitch::getPondId, pondId);
|
||||
|
||||
java.util.List<com.intc.fishery.domain.vo.DeviceSwitchVo> listSwitch =
|
||||
deviceSwitchMapper.selectJoinList(com.intc.fishery.domain.vo.DeviceSwitchVo.class, wrapper);
|
||||
java.util.List<DeviceSwitchVo> listSwitch =
|
||||
deviceSwitchMapper.selectJoinList(DeviceSwitchVo.class, wrapper);
|
||||
|
||||
if (listSwitch == null || listSwitch.isEmpty()) {
|
||||
return R.fail("该塘口下没有开关");
|
||||
}
|
||||
|
||||
// 按设备IotId分组,并过滤不符合条件的开关
|
||||
Map<String, java.util.List<com.intc.fishery.domain.vo.DeviceSwitchVo>> iotIdSwitchMap =
|
||||
Map<String, java.util.List<DeviceSwitchVo>> iotIdSwitchMap =
|
||||
new java.util.HashMap<>();
|
||||
|
||||
for (com.intc.fishery.domain.vo.DeviceSwitchVo switchVo : listSwitch) {
|
||||
|
||||
for (DeviceSwitchVo switchVo : listSwitch) {
|
||||
// 权限验证
|
||||
if (switchVo.getUserId() == null || !switchVo.getUserId().equals(userId)) {
|
||||
return R.fail("开关不存在或无权限访问");
|
||||
@@ -1866,23 +1880,23 @@ public class IotController extends BaseController {
|
||||
|
||||
// 按设备批量设置开关状态
|
||||
java.util.Set<Long> successSwitchIds = new java.util.HashSet<>();
|
||||
java.util.List<com.intc.fishery.domain.vo.DeviceSwitchVo> successSwitches = new java.util.ArrayList<>();
|
||||
java.util.List<DeviceSwitchVo> successSwitches = new java.util.ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, java.util.List<com.intc.fishery.domain.vo.DeviceSwitchVo>> entry : iotIdSwitchMap.entrySet()) {
|
||||
for (Map.Entry<String, java.util.List<DeviceSwitchVo>> entry : iotIdSwitchMap.entrySet()) {
|
||||
String iotId = entry.getKey();
|
||||
java.util.List<com.intc.fishery.domain.vo.DeviceSwitchVo> switches = entry.getValue();
|
||||
java.util.List<DeviceSwitchVo> switches = entry.getValue();
|
||||
|
||||
// 构造该设备的所有开关属性
|
||||
Map<String, Object> properties = new java.util.HashMap<>();
|
||||
for (com.intc.fishery.domain.vo.DeviceSwitchVo switchVo : switches) {
|
||||
properties.put("switchIndex" + switchVo.getIndex(), targetStatus);
|
||||
for (DeviceSwitchVo switchVo : switches) {
|
||||
properties.put(IOTPropertyName.SWITCH_INDEX + switchVo.getIndex(), targetStatus);
|
||||
}
|
||||
|
||||
// 调用物联网服务设置属性
|
||||
boolean success = iotCloudService.setProperty(iotId, properties, false, 0);
|
||||
if (success) {
|
||||
// 记录成功的开关ID
|
||||
for (com.intc.fishery.domain.vo.DeviceSwitchVo switchVo : switches) {
|
||||
for (DeviceSwitchVo switchVo : switches) {
|
||||
successSwitchIds.add(switchVo.getId());
|
||||
successSwitches.add(switchVo);
|
||||
}
|
||||
@@ -1892,15 +1906,15 @@ public class IotController extends BaseController {
|
||||
// 批量更新数据库中成功设置的开关状态
|
||||
if (!successSwitchIds.isEmpty()) {
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.in(com.intc.fishery.domain.DeviceSwitch::getId, successSwitchIds)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getIsOpen, targetStatus)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getLastTurnTime, new Date())
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<DeviceSwitch>()
|
||||
.in(DeviceSwitch::getId, successSwitchIds)
|
||||
.set(DeviceSwitch::getIsOpen, targetStatus)
|
||||
.set(DeviceSwitch::getLastTurnTime, new Date())
|
||||
);
|
||||
|
||||
// 记录操作日志
|
||||
String operation = targetStatus == 1 ? "开启" : "关闭";
|
||||
for (com.intc.fishery.domain.vo.DeviceSwitchVo switchVo : successSwitches) {
|
||||
for (DeviceSwitchVo switchVo : successSwitches) {
|
||||
log.info("开关操作:{}({})的开关{}:{}",
|
||||
switchVo.getDeviceName(), switchVo.getSerialNum(), switchVo.getSwitchName(), operation);
|
||||
}
|
||||
@@ -1921,7 +1935,7 @@ public class IotController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "设置开关额定电流")
|
||||
@PutMapping("/switch/electric_set")
|
||||
public R<Void> updateElectricSet(@RequestBody com.intc.fishery.domain.bo.ReqSwitchElectricSet request) {
|
||||
public R<Void> updateElectricSet(@RequestBody ReqSwitchElectricSet request) {
|
||||
try {
|
||||
if (deviceSwitchMapper == null || deviceMapper == null) {
|
||||
return R.fail("系统配置未完成");
|
||||
@@ -1932,7 +1946,7 @@ public class IotController extends BaseController {
|
||||
Double electric = request.getElectric();
|
||||
|
||||
// 查询开关信息
|
||||
com.intc.fishery.domain.DeviceSwitch deviceSwitch = deviceSwitchMapper.selectById(switchId);
|
||||
DeviceSwitch deviceSwitch = deviceSwitchMapper.selectById(switchId);
|
||||
if (deviceSwitch == null) {
|
||||
return R.fail("开关不存在");
|
||||
}
|
||||
@@ -1956,7 +1970,7 @@ public class IotController extends BaseController {
|
||||
}
|
||||
|
||||
// 检查额定电流值是否已改变(精度0.001)
|
||||
if (deviceSwitch.getRateElectricValue() != null
|
||||
if (deviceSwitch.getRateElectricValue() != null
|
||||
&& Math.abs(deviceSwitch.getRateElectricValue() - electric) < 0.001) {
|
||||
return R.ok();
|
||||
}
|
||||
@@ -1983,9 +1997,9 @@ public class IotController extends BaseController {
|
||||
|
||||
// 更新数据库中的额定电流值
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getRateElectricValue, electric)
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<DeviceSwitch>()
|
||||
.eq(DeviceSwitch::getId, switchId)
|
||||
.set(DeviceSwitch::getRateElectricValue, electric)
|
||||
);
|
||||
|
||||
// 记录操作日志
|
||||
@@ -2007,7 +2021,7 @@ public class IotController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "修改开关输出电压类型")
|
||||
@PutMapping("/switch/update_voltage_type")
|
||||
public R<Void> updateConnectVoltageType(@RequestBody com.intc.fishery.domain.bo.ReqSetVoltageType request) {
|
||||
public R<Void> updateConnectVoltageType(@RequestBody ReqSetVoltageType request) {
|
||||
try {
|
||||
if (deviceSwitchMapper == null || deviceMapper == null) {
|
||||
return R.fail("系统配置未完成");
|
||||
@@ -2018,9 +2032,9 @@ public class IotController extends BaseController {
|
||||
Integer voltageType = request.getVoltageType();
|
||||
|
||||
// 查询开关信息(包括关联的设备信息)
|
||||
com.github.yulichang.wrapper.MPJLambdaWrapper<com.intc.fishery.domain.DeviceSwitch> wrapper =
|
||||
new com.github.yulichang.wrapper.MPJLambdaWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.selectAll(com.intc.fishery.domain.DeviceSwitch.class)
|
||||
com.github.yulichang.wrapper.MPJLambdaWrapper<DeviceSwitch> wrapper =
|
||||
new com.github.yulichang.wrapper.MPJLambdaWrapper<DeviceSwitch>()
|
||||
.selectAll(DeviceSwitch.class)
|
||||
.selectAs(Device::getUserId, "userId")
|
||||
.selectAs(Device::getIotId, "iotId")
|
||||
.selectAs(Device::getSerialNum, "serialNum")
|
||||
@@ -2029,11 +2043,11 @@ public class IotController extends BaseController {
|
||||
.selectAs(Device::getInputVoltage, "inputVoltage")
|
||||
.selectAs(Device::getWarnCode, "warnCode")
|
||||
.selectAs(Device::getDeadTime, "deadTime")
|
||||
.leftJoin(Device.class, Device::getId, com.intc.fishery.domain.DeviceSwitch::getDeviceId)
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId);
|
||||
.leftJoin(Device.class, Device::getId, DeviceSwitch::getDeviceId)
|
||||
.eq(DeviceSwitch::getId, switchId);
|
||||
|
||||
com.intc.fishery.domain.vo.DeviceSwitchVo switchVo =
|
||||
deviceSwitchMapper.selectJoinOne(com.intc.fishery.domain.vo.DeviceSwitchVo.class, wrapper);
|
||||
DeviceSwitchVo switchVo =
|
||||
deviceSwitchMapper.selectJoinOne(DeviceSwitchVo.class, wrapper);
|
||||
|
||||
if (switchVo == null) {
|
||||
return R.fail("开关不存在");
|
||||
@@ -2092,9 +2106,9 @@ public class IotController extends BaseController {
|
||||
|
||||
// 更新数据库中的电压类型
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getConnectVoltageType, voltageType)
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<DeviceSwitch>()
|
||||
.eq(DeviceSwitch::getId, switchId)
|
||||
.set(DeviceSwitch::getConnectVoltageType, voltageType)
|
||||
);
|
||||
|
||||
// 记录操作日志
|
||||
@@ -2141,7 +2155,7 @@ public class IotController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "修改开关所属塘口")
|
||||
@PutMapping("/switch/update_pond")
|
||||
public R<Void> updateSwitchPond(@RequestBody com.intc.fishery.domain.bo.ReqChangePond request) {
|
||||
public R<Void> updateSwitchPond(@RequestBody ReqChangePond request) {
|
||||
try {
|
||||
if (deviceSwitchMapper == null || pondMapper == null || deviceMapper == null) {
|
||||
return R.fail("系统配置未完成");
|
||||
@@ -2152,21 +2166,21 @@ public class IotController extends BaseController {
|
||||
Long pondId = request.getPondId();
|
||||
|
||||
// 查询开关信息,包括关联的设备和塘口信息
|
||||
com.github.yulichang.wrapper.MPJLambdaWrapper<com.intc.fishery.domain.DeviceSwitch> wrapper =
|
||||
new com.github.yulichang.wrapper.MPJLambdaWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.selectAll(com.intc.fishery.domain.DeviceSwitch.class)
|
||||
com.github.yulichang.wrapper.MPJLambdaWrapper<DeviceSwitch> wrapper =
|
||||
new com.github.yulichang.wrapper.MPJLambdaWrapper<DeviceSwitch>()
|
||||
.selectAll(DeviceSwitch.class)
|
||||
.selectAs(Device::getDeviceName, "deviceName")
|
||||
.selectAs(Device::getSerialNum, "serialNum")
|
||||
.selectAs(Device::getIotId, "iotId")
|
||||
.selectAs(Device::getWarnCode, "warnCode")
|
||||
.selectAs(com.intc.fishery.domain.Pond::getPondName, "pondName")
|
||||
.leftJoin(Device.class, Device::getId, com.intc.fishery.domain.DeviceSwitch::getDeviceId)
|
||||
.leftJoin(com.intc.fishery.domain.Pond.class, com.intc.fishery.domain.Pond::getId, com.intc.fishery.domain.DeviceSwitch::getPondId)
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId);
|
||||
.selectAs(Pond::getPondName, "pondName")
|
||||
.leftJoin(Device.class, Device::getId, DeviceSwitch::getDeviceId)
|
||||
.leftJoin(Pond.class, Pond::getId, DeviceSwitch::getPondId)
|
||||
.eq(DeviceSwitch::getId, switchId);
|
||||
|
||||
DeviceSwitchVo vo = deviceSwitchMapper.selectJoinOne(
|
||||
DeviceSwitchVo.class, wrapper);
|
||||
|
||||
com.intc.fishery.domain.vo.DeviceSwitchVo vo = deviceSwitchMapper.selectJoinOne(
|
||||
com.intc.fishery.domain.vo.DeviceSwitchVo.class, wrapper);
|
||||
|
||||
if (vo == null) {
|
||||
return R.fail("开关不存在");
|
||||
}
|
||||
@@ -2186,30 +2200,30 @@ public class IotController extends BaseController {
|
||||
if (device != null && com.intc.common.core.utils.StringUtils.isNotBlank(device.getIotId())) {
|
||||
// 检查设备是否在线(通过判断warnCode判断设备状态)
|
||||
boolean isOnline = device.getWarnCode() != null && device.getWarnCode() != 99;
|
||||
|
||||
|
||||
if (isOnline && iotCloudService != null) {
|
||||
try {
|
||||
// 构造清空定时控制的属性
|
||||
Map<String, Object> properties = new java.util.HashMap<>();
|
||||
// 清空定时器:localTimer_switch{Index}
|
||||
properties.put("localTimer_switch" + vo.getIndex(), java.util.Collections.emptyList());
|
||||
|
||||
|
||||
// 如果开关是打开状态,需要关闭它
|
||||
if (vo.getIsOpen() != null && vo.getIsOpen() == 1) {
|
||||
// 关闭开关:switchIndex{Index} = 0
|
||||
properties.put("switchIndex" + vo.getIndex(), 0);
|
||||
|
||||
// 关闭开关:Switch{Index} = 0
|
||||
properties.put(IOTPropertyName.SWITCH_INDEX + vo.getIndex(), 0);
|
||||
|
||||
// 更新数据库中的开关状态
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getIsOpen, 0)
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<DeviceSwitch>()
|
||||
.eq(DeviceSwitch::getId, switchId)
|
||||
.set(DeviceSwitch::getIsOpen, 0)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// 调用物联网服务设置属性
|
||||
boolean success = iotCloudService.setProperty(device.getIotId(), properties, false, 0);
|
||||
|
||||
|
||||
if (success) {
|
||||
log.info("成功通过物联网服务清空开关定时控制和关闭开关, switchId={}", switchId);
|
||||
} else {
|
||||
@@ -2220,53 +2234,53 @@ public class IotController extends BaseController {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 删除该开关的所有定时控制记录
|
||||
if (timingCtrlMapper != null) {
|
||||
timingCtrlMapper.delete(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.intc.fishery.domain.TimingCtrl>()
|
||||
.eq(com.intc.fishery.domain.TimingCtrl::getSwitchId, switchId)
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<TimingCtrl>()
|
||||
.eq(TimingCtrl::getSwitchId, switchId)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
log.info("已清除开关ID={}的定时控制数据", switchId);
|
||||
}
|
||||
|
||||
// 处理新塘口分配
|
||||
if (pondId != null && pondId > 0) {
|
||||
// 验证塘口是否存在
|
||||
com.intc.fishery.domain.Pond pond = pondMapper.selectById(pondId);
|
||||
Pond pond = pondMapper.selectById(pondId);
|
||||
if (pond == null) {
|
||||
return R.fail("塘口不存在");
|
||||
}
|
||||
|
||||
// 更新开关的塘口ID,并清空联动控制ID
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getPondId, pondId)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getLinkedCtrlId, null)
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<DeviceSwitch>()
|
||||
.eq(DeviceSwitch::getId, switchId)
|
||||
.set(DeviceSwitch::getPondId, pondId)
|
||||
.set(DeviceSwitch::getLinkedCtrlId, null)
|
||||
);
|
||||
|
||||
// 记录操作日志
|
||||
if (oldPondId != null) {
|
||||
log.info("开关操作:{}({})的开关{},转移到塘口:{}",
|
||||
log.info("开关操作:{}({})的开关{},转移到塘口:{}",
|
||||
vo.getDeviceName(), vo.getSerialNum(), vo.getSwitchName(), pond.getPondName());
|
||||
} else {
|
||||
log.info("开关操作:{}({})的开关{},分配到塘口:{}",
|
||||
log.info("开关操作:{}({})的开关{},分配到塘口:{}",
|
||||
vo.getDeviceName(), vo.getSerialNum(), vo.getSwitchName(), pond.getPondName());
|
||||
}
|
||||
} else if (oldPondId != null) {
|
||||
// 移除塘口分配
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getPondId, null)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getLinkedCtrlId, null)
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<DeviceSwitch>()
|
||||
.eq(DeviceSwitch::getId, switchId)
|
||||
.set(DeviceSwitch::getPondId, null)
|
||||
.set(DeviceSwitch::getLinkedCtrlId, null)
|
||||
);
|
||||
|
||||
// 记录操作日志
|
||||
log.info("开关操作:{}({})的开关{} 从 {} 移除",
|
||||
log.info("开关操作:{}({})的开关{} 从 {} 移除",
|
||||
vo.getDeviceName(), vo.getSerialNum(), vo.getSwitchName(), oldPondName);
|
||||
}
|
||||
|
||||
@@ -2276,4 +2290,347 @@ public class IotController extends BaseController {
|
||||
return R.fail("修改失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置定时控制开关
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Operation(summary = "设置定时控制开关")
|
||||
@PostMapping("/timingCtrl/update")
|
||||
public R<Void> setTimeCtrlOpen(
|
||||
@Validated @org.springframework.web.bind.annotation.RequestBody ReqTurnOpen request) {
|
||||
|
||||
try {
|
||||
// 查询定时控制信息
|
||||
TimingCtrl timingCtrl = timingCtrlMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<TimingCtrl>()
|
||||
.eq(TimingCtrl::getId, request.getId())
|
||||
.select(TimingCtrl::getId,
|
||||
TimingCtrl::getIsOpen,
|
||||
TimingCtrl::getLoopType,
|
||||
TimingCtrl::getSwitchId,
|
||||
TimingCtrl::getOpenTime,
|
||||
TimingCtrl::getCloseTime)
|
||||
);
|
||||
|
||||
if (timingCtrl == null) {
|
||||
return R.fail("定时控制不存在");
|
||||
}
|
||||
|
||||
// 如果状态相同,无需更新
|
||||
if (timingCtrl.getIsOpen().intValue() == request.getIsOpen()) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
// 如果是启用且循环类型为1(每天循环),验证当前时间不在定时范围内
|
||||
if (request.getIsOpen() == 1 && timingCtrl.getLoopType() != null && timingCtrl.getLoopType() == 1) {
|
||||
Date now = new Date();
|
||||
java.util.Calendar calendar = java.util.Calendar.getInstance();
|
||||
calendar.setTime(now);
|
||||
int currentHour = calendar.get(java.util.Calendar.HOUR_OF_DAY);
|
||||
int currentMinute = calendar.get(java.util.Calendar.MINUTE);
|
||||
|
||||
java.util.Calendar openCal = java.util.Calendar.getInstance();
|
||||
openCal.setTime(timingCtrl.getOpenTime());
|
||||
int openHour = openCal.get(java.util.Calendar.HOUR_OF_DAY);
|
||||
int openMinute = openCal.get(java.util.Calendar.MINUTE);
|
||||
|
||||
java.util.Calendar closeCal = java.util.Calendar.getInstance();
|
||||
closeCal.setTime(timingCtrl.getCloseTime());
|
||||
int closeHour = closeCal.get(java.util.Calendar.HOUR_OF_DAY);
|
||||
int closeMinute = closeCal.get(java.util.Calendar.MINUTE);
|
||||
|
||||
int currentTimeInMinutes = currentHour * 60 + currentMinute;
|
||||
int openTimeInMinutes = openHour * 60 + openMinute;
|
||||
int closeTimeInMinutes = closeHour * 60 + closeMinute;
|
||||
|
||||
if (currentTimeInMinutes >= openTimeInMinutes && currentTimeInMinutes <= closeTimeInMinutes) {
|
||||
return R.fail("开启失败");
|
||||
}
|
||||
}
|
||||
|
||||
// 查询开关和设备信息
|
||||
DeviceSwitch deviceSwitch = deviceSwitchMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<DeviceSwitch>()
|
||||
.eq(DeviceSwitch::getId, timingCtrl.getSwitchId())
|
||||
.select(DeviceSwitch::getId,
|
||||
DeviceSwitch::getDeviceId,
|
||||
DeviceSwitch::getIndex,
|
||||
DeviceSwitch::getSwitchName)
|
||||
);
|
||||
|
||||
if (deviceSwitch == null) {
|
||||
return R.fail("定时控制不存在");
|
||||
}
|
||||
|
||||
// 查询设备信息
|
||||
Device device = deviceMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, deviceSwitch.getDeviceId())
|
||||
.select(Device::getId, Device::getUserId, Device::getDeviceName,
|
||||
Device::getIotId, Device::getSerialNum, Device::getWarnCode, Device::getDeadTime)
|
||||
);
|
||||
|
||||
if (device == null) {
|
||||
return R.fail("定时控制不存在");
|
||||
}
|
||||
|
||||
// 检查设备是否过期
|
||||
if (device.getDeadTime() != null && device.getDeadTime().before(new Date())) {
|
||||
return R.fail("设备服务已过期");
|
||||
}
|
||||
|
||||
// // 检查设备是否离线(warnCode & 0x0080)
|
||||
// if (device.getWarnCode() != null && (device.getWarnCode() & 0x0080) != 0) {
|
||||
// return R.fail("设备离线或关机");
|
||||
// }
|
||||
|
||||
// 查询该开关的所有定时控制
|
||||
java.util.List<TimingCtrl> allTimingCtrls = timingCtrlMapper.selectList(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<TimingCtrl>()
|
||||
.eq(TimingCtrl::getSwitchId, timingCtrl.getSwitchId())
|
||||
);
|
||||
|
||||
// 更新当前定时控制的状态
|
||||
for (TimingCtrl tc : allTimingCtrls) {
|
||||
if (tc.getId().equals(request.getId())) {
|
||||
tc.setIsOpen(request.getIsOpen().longValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 调用设置属性方法
|
||||
boolean success = setPropertyTimeCtrl(deviceSwitch, device, allTimingCtrls, request.getId());
|
||||
if (!success) {
|
||||
return R.fail("设置定时控制失败");
|
||||
}
|
||||
|
||||
// 更新数据库
|
||||
timingCtrlMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<TimingCtrl>()
|
||||
.eq(TimingCtrl::getId, request.getId())
|
||||
.set(TimingCtrl::getIsOpen, request.getIsOpen().longValue())
|
||||
.set(TimingCtrl::getOpenTime, timingCtrl.getOpenTime())
|
||||
.set(TimingCtrl::getCloseTime, timingCtrl.getCloseTime())
|
||||
);
|
||||
|
||||
// TODO: 记录操作日志
|
||||
String operation = request.getIsOpen() == 1 ? "启用" : "停用";
|
||||
log.info("开关定时控制:{}({}){}d定时控制。",
|
||||
device.getDeviceName(), deviceSwitch.getSwitchName(), operation);
|
||||
|
||||
return R.ok();
|
||||
} catch (Exception e) {
|
||||
log.error("设置定时控制开关失败: {}", e.getMessage(), e);
|
||||
return R.fail("设置失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置设备定时控制属性
|
||||
*
|
||||
* @param deviceSwitch 开关信息
|
||||
* @param device 设备信息
|
||||
* @param allTimingCtrls 该开关的所有定时控制
|
||||
* @param timeCtrlId 当前操作的定时控制ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
private boolean setPropertyTimeCtrl(
|
||||
DeviceSwitch deviceSwitch,
|
||||
Device device,
|
||||
java.util.List<TimingCtrl> allTimingCtrls,
|
||||
Long timeCtrlId) {
|
||||
|
||||
try {
|
||||
java.util.List<Object> listTimingCtrl = new java.util.ArrayList<>();
|
||||
Map<String, Object> properties = new java.util.HashMap<>();
|
||||
|
||||
Date dateToday = new Date();
|
||||
java.util.Calendar calendar = java.util.Calendar.getInstance();
|
||||
calendar.setTime(dateToday);
|
||||
calendar.set(java.util.Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(java.util.Calendar.MINUTE, 0);
|
||||
calendar.set(java.util.Calendar.SECOND, 0);
|
||||
calendar.set(java.util.Calendar.MILLISECOND, 0);
|
||||
Date todayStart = calendar.getTime();
|
||||
|
||||
Date now = new Date();
|
||||
|
||||
for (TimingCtrl timingCtrl : allTimingCtrls) {
|
||||
Date onTime = timingCtrl.getOpenTime();
|
||||
Date offTime = timingCtrl.getCloseTime();
|
||||
|
||||
// 如果是当前启用的定时控制,重新计算时间
|
||||
if (timeCtrlId.equals(timingCtrl.getId()) && timingCtrl.getIsOpen() != null && timingCtrl.getIsOpen() == 1) {
|
||||
java.util.Calendar onCal = java.util.Calendar.getInstance();
|
||||
onCal.setTime(todayStart);
|
||||
java.util.Calendar tempCal = java.util.Calendar.getInstance();
|
||||
tempCal.setTime(onTime);
|
||||
onCal.set(java.util.Calendar.HOUR_OF_DAY, tempCal.get(java.util.Calendar.HOUR_OF_DAY));
|
||||
onCal.set(java.util.Calendar.MINUTE, tempCal.get(java.util.Calendar.MINUTE));
|
||||
onTime = onCal.getTime();
|
||||
|
||||
java.util.Calendar offCal = java.util.Calendar.getInstance();
|
||||
offCal.setTime(todayStart);
|
||||
tempCal.setTime(offTime);
|
||||
offCal.set(java.util.Calendar.HOUR_OF_DAY, tempCal.get(java.util.Calendar.HOUR_OF_DAY));
|
||||
offCal.set(java.util.Calendar.MINUTE, tempCal.get(java.util.Calendar.MINUTE));
|
||||
offTime = offCal.getTime();
|
||||
|
||||
// 如果开启时间小于当前时间,加1天
|
||||
if (onTime.before(now)) {
|
||||
onCal.add(java.util.Calendar.DAY_OF_MONTH, 1);
|
||||
onTime = onCal.getTime();
|
||||
}
|
||||
|
||||
// 如果关闭时间小于当前时间,加1天
|
||||
if (offTime.before(now)) {
|
||||
offCal.add(java.util.Calendar.DAY_OF_MONTH, 1);
|
||||
offTime = offCal.getTime();
|
||||
}
|
||||
|
||||
// 如果开启时间大于关闭时间,关闭时间加1天
|
||||
if (onTime.after(offTime)) {
|
||||
offCal.add(java.util.Calendar.DAY_OF_MONTH, 1);
|
||||
offTime = offCal.getTime();
|
||||
}
|
||||
|
||||
// 如果当前时间在定时范围内,返回失败
|
||||
if (!now.before(onTime) && !now.after(offTime)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 更新定时控制的时间
|
||||
timingCtrl.setOpenTime(onTime);
|
||||
timingCtrl.setCloseTime(offTime);
|
||||
}
|
||||
|
||||
// 转换为UTC Unix时间戳(秒)
|
||||
long onUnixStamp = onTime.getTime() / 1000;
|
||||
long offUnixStamp = offTime.getTime() / 1000;
|
||||
|
||||
// 构建定时控制对象
|
||||
Map<String, Object> timeCtrl = new java.util.HashMap<>();
|
||||
timeCtrl.put("timerMode", timingCtrl.getLoopType() != null ? timingCtrl.getLoopType() - 1 : 0);
|
||||
timeCtrl.put("isValid", timingCtrl.getIsOpen() != null && timingCtrl.getIsOpen() == 1 ? 1 : 0);
|
||||
timeCtrl.put("onTime", String.valueOf(onUnixStamp));
|
||||
timeCtrl.put("offTime", String.valueOf(offUnixStamp));
|
||||
|
||||
listTimingCtrl.add(timeCtrl);
|
||||
}
|
||||
|
||||
// 设置属性
|
||||
properties.put(IOTPropertyName.LOCAL_TIMER_SWITCH + deviceSwitch.getIndex(), listTimingCtrl);
|
||||
|
||||
// 调用IoT服务设置属性0
|
||||
return iotCloudService.setProperty(device.getIotId(), properties, false, 0);
|
||||
} catch (Exception e) {
|
||||
log.error("设置定时控制属性失败: {}", e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除定时控制
|
||||
*
|
||||
* @param request 请求对象(包含定时控制ID)
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Operation(summary = "删除定时控制")
|
||||
@DeleteMapping("/timingCtrl/delete")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<Void> deleteTimeCtrl(
|
||||
@Validated @RequestBody ReqId request) {
|
||||
|
||||
try {
|
||||
Long userId = LoginHelper.getUserId();
|
||||
|
||||
// 查询定时控制基本信息
|
||||
TimingCtrl dbTimeCtrl = timingCtrlMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<TimingCtrl>()
|
||||
.eq(TimingCtrl::getId, request.getId())
|
||||
.select(TimingCtrl::getId,
|
||||
TimingCtrl::getIsOpen,
|
||||
TimingCtrl::getSwitchId)
|
||||
);
|
||||
|
||||
if (dbTimeCtrl == null) {
|
||||
return R.fail("定时控制不存在");
|
||||
}
|
||||
|
||||
// 查询开关信息及关联的设备信息
|
||||
DeviceSwitch deviceSwitch = deviceSwitchMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<DeviceSwitch>()
|
||||
.eq(DeviceSwitch::getId, dbTimeCtrl.getSwitchId())
|
||||
.select(DeviceSwitch::getId,
|
||||
DeviceSwitch::getDeviceId,
|
||||
DeviceSwitch::getIndex,
|
||||
DeviceSwitch::getSwitchName)
|
||||
);
|
||||
|
||||
if (deviceSwitch == null) {
|
||||
return R.fail("定时控制不存在");
|
||||
}
|
||||
|
||||
// 查询设备信息
|
||||
Device device = deviceMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, deviceSwitch.getDeviceId())
|
||||
.select(Device::getId, Device::getUserId, Device::getDeviceName,
|
||||
Device::getIotId, Device::getSerialNum, Device::getWarnCode, Device::getDeadTime)
|
||||
);
|
||||
|
||||
// 权限验证
|
||||
if (device == null || device.getUserId() == null || !device.getUserId().equals(userId)) {
|
||||
return R.fail("定时控制不存在");
|
||||
}
|
||||
|
||||
// 检查设备是否过期
|
||||
if (device.getDeadTime() != null && device.getDeadTime().before(new Date())) {
|
||||
return R.fail("设备服务已过期");
|
||||
}
|
||||
|
||||
// // 检查设备是否离线(warnCode & 0x0080)
|
||||
// if (device.getWarnCode() != null && (device.getWarnCode() & 0x0080) != 0) {
|
||||
// return R.fail("设备离线或关机");
|
||||
// }
|
||||
|
||||
// 查询该开关的所有定时控制
|
||||
java.util.List<TimingCtrl> allTimingCtrls = timingCtrlMapper.selectList(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<TimingCtrl>()
|
||||
.eq(TimingCtrl::getSwitchId, dbTimeCtrl.getSwitchId())
|
||||
);
|
||||
|
||||
// 从列表中移除要删除的定时控制,并将其 isOpen 设置为 0
|
||||
for (TimingCtrl tc : allTimingCtrls) {
|
||||
if (tc.getId().equals(request.getId())) {
|
||||
tc.setIsOpen(0L);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 调用设置属性方法,将更新后的定时控制列表同步到设备
|
||||
boolean success = setPropertyTimeCtrl(deviceSwitch, device, allTimingCtrls, request.getId());
|
||||
if (!success) {
|
||||
return R.fail("设置定时控制失败");
|
||||
}
|
||||
|
||||
// 从数据库中删除定时控制记录
|
||||
int deleteCount = timingCtrlMapper.deleteById(request.getId());
|
||||
if (deleteCount == 0) {
|
||||
return R.fail("删除失败");
|
||||
}
|
||||
|
||||
// 记录操作日志
|
||||
log.info("开关定时控制:{}({})删除定时控制。",
|
||||
device.getDeviceName(), deviceSwitch.getSwitchName());
|
||||
|
||||
return R.ok();
|
||||
} catch (Exception e) {
|
||||
log.error("删除定时控制失败: {}", e.getMessage(), e);
|
||||
return R.fail("删除失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user