fix: 新增太阳能网控添加接口。

This commit is contained in:
tianyongbao
2026-03-29 21:37:12 +08:00
parent c6a5148ac6
commit faa507f4bd
4 changed files with 265 additions and 3 deletions

View File

@@ -209,6 +209,8 @@ device-type:
water-quality-monitor: a15hA3oBPmB # TODO: 请替换为实际的水质检测仪 ProductKey water-quality-monitor: a15hA3oBPmB # TODO: 请替换为实际的水质检测仪 ProductKey
# 2-控制一体机 ProductKey请填写实际的 ProductKey # 2-控制一体机 ProductKey请填写实际的 ProductKey
control-integrated: a1Xj9dagTIx # TODO: 请替换为实际的控制一体机 ProductKey control-integrated: a1Xj9dagTIx # TODO: 请替换为实际的控制一体机 ProductKey
# 3-太阳能网控 ProductKey
solar-controller: a1ZLJkYlSjs
--- # 阿里云生活物联网平台(飞燕平台)配置 --- # 阿里云生活物联网平台(飞燕平台)配置
aliyun: aliyun:
living-iot: living-iot:

View File

@@ -24,10 +24,15 @@ public class DeviceTypeProperties {
*/ */
private String controlIntegrated; private String controlIntegrated;
/**
* 太阳能网控 ProductKey
*/
private String solarController;
/** /**
* 根据 ProductKey 判断设备类型 * 根据 ProductKey 判断设备类型
* @param productKey ProductKey * @param productKey ProductKey
* @return 设备类型: 1-水质检测仪, 2-控制一体机, null-未知类型 * @return 设备类型: 1-水质检测仪, 2-控制一体机, 3-太阳能网控, null-未知类型
*/ */
public Integer getDeviceTypeByProductKey(String productKey) { public Integer getDeviceTypeByProductKey(String productKey) {
if (productKey == null) { if (productKey == null) {
@@ -37,13 +42,15 @@ public class DeviceTypeProperties {
return 1; return 1;
} else if (productKey.equals(controlIntegrated)) { } else if (productKey.equals(controlIntegrated)) {
return 2; return 2;
} else if (productKey.equals(solarController)) {
return 3;
} }
return null; return null;
} }
/** /**
* 根据设备类型获取 ProductKey * 根据设备类型获取 ProductKey
* @param deviceType 1-水质检测仪, 2-控制一体机 * @param deviceType 1-水质检测仪, 2-控制一体机, 3-太阳能网控
* @return ProductKey * @return ProductKey
*/ */
public String getProductKeyByType(Integer deviceType) { public String getProductKeyByType(Integer deviceType) {
@@ -55,6 +62,8 @@ public class DeviceTypeProperties {
return waterQualityMonitor; return waterQualityMonitor;
case 2: case 2:
return controlIntegrated; return controlIntegrated;
case 3:
return solarController;
default: default:
return null; return null;
} }

View File

@@ -328,7 +328,7 @@ public class IotController extends BaseController {
@Operation(summary = "查询设备当前状态(从物联网平台)") @Operation(summary = "查询设备当前状态(从物联网平台)")
@GetMapping("/device/status") @GetMapping("/device/status")
public R<Integer> queryDeviceStatus( public R<Integer> queryDeviceStatus(
@Parameter(description = "设备类型1-水质检测仪, 2-控制一体机)") @RequestParam Integer devicetype, @Parameter(description = "设备类型1-水质检测仪, 2-控制一体机, 3-太阳能网控") @RequestParam Integer devicetype,
@Parameter(description = "设备编号/设备名称") @RequestParam String serialnum) { @Parameter(description = "设备编号/设备名称") @RequestParam String serialnum) {
try { try {
if (iotDeviceService == null) { if (iotDeviceService == null) {
@@ -1540,6 +1540,201 @@ public class IotController extends BaseController {
} }
} }
@Operation(summary = "添加设备(太阳能网控)")
@PostMapping("/device/add_device_solar_detector")
public R<Void> addDeviceSolarController(@RequestBody com.intc.iot.domain.bo.AddDeviceSolarControllerBo bo, @RequestParam Long rootUserId) {
try {
if (iotDeviceService == null) {
return R.fail("飞燕平台配置未启用");
}
if (deviceMapper == null) {
return R.fail("设备数据库服务未启用");
}
// 获取用户ID(从 URL 查询参数 rootUserId 获取)
if (rootUserId == null) {
return R.fail("根用户ID不能为空");
}
// 验证塘口是否存在且属于当前用户
if (bo.getPondId() != null && bo.getPondId() > 0 && pondMapper != null) {
long count = pondMapper.selectCount(
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Pond>()
.eq(Pond::getUserId, rootUserId)
.eq(Pond::getId, bo.getPondId())
);
if (count == 0) {
return R.fail("塘口不存在或无权限访问");
}
}
// 检查设备是否已被绑定
Device existDevice = deviceMapper.selectOne(
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
.eq(Device::getDeviceType, 3) // 3-太阳能网控
.eq(Device::getSerialNum, bo.getSerialNum())
);
if (existDevice != null && existDevice.getUserId() != null) {
return R.fail("该设备号已被绑定");
}
// 获取太阳能网控的 ProductKey
String productKey = deviceTypeProperties.getSolarController();
if (productKey == null || productKey.isEmpty()) {
return R.fail("未配置太阳能网控的 ProductKey");
}
// 查询设备基础信息
Map<String, Object> deviceInfo = iotDeviceService.findDeviceByProductKeyAndName(productKey, bo.getSerialNum());
if (deviceInfo == null || !Boolean.TRUE.equals(deviceInfo.get("success"))) {
return R.fail("设备不存在");
}
// 提取设备数据
Map<String, Object> data = (Map<String, Object>) deviceInfo.get("data");
if (data == null || !data.containsKey("deviceList")) {
return R.fail("设备信息格式异常");
}
java.util.List<?> deviceList = (java.util.List<?>) data.get("deviceList");
if (deviceList == null || deviceList.isEmpty()) {
return R.fail("设备不存在");
}
Object deviceObj = deviceList.get(0);
String iotId = null;
String status = null;
// 提取 iotId 和 status
if (deviceObj instanceof Map) {
Map<?, ?> deviceMap = (Map<?, ?>) deviceObj;
iotId = (String) deviceMap.get("iotId");
Object statusObj = deviceMap.get("status");
status = statusObj != null ? statusObj.toString() : null;
} else {
try {
iotId = (String) deviceObj.getClass().getMethod("getIotId").invoke(deviceObj);
Object statusObj = deviceObj.getClass().getMethod("getStatus").invoke(deviceObj);
status = statusObj != null ? statusObj.toString() : null;
} catch (Exception ex) {
log.error("无法从设备对象中获取信息: {}", ex.getMessage());
}
}
if (iotId == null || iotId.isEmpty()) {
return R.fail("设备 iotId 为空");
}
// 检查设备状态
if (status != null) {
if ("UNACTIVE".equalsIgnoreCase(status)) {
return R.fail("设备未激活");
}
if ("DISABLE".equalsIgnoreCase(status)) {
return R.fail("设备禁用");
}
}
// 获取设备属性
Map<String, Object> deviceProperties = iotDeviceService.queryDeviceProperties(iotId);
// 计算设备数量,用于生成设备名称
long deviceCount = deviceMapper.selectCount(
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
.eq(Device::getUserId, rootUserId)
.eq(Device::getDeviceType, 3)
);
// 创建或更新设备信息
Date now = new Date();
boolean isNew = (existDevice == null);
Device device = isNew ? new Device() : existDevice;
if (isNew) {
device.setIotId(iotId);
device.setSerialNum(bo.getSerialNum());
device.setDeviceType(3); // 3-太阳能网控
device.setDeadTime(new Date(now.getTime() + 365L * 24 * 60 * 60 * 1000)); // 一年后到期
}
// 设置基本信息
device.setUserId(rootUserId);
device.setDeviceName("太阳能网控" + (deviceCount + 1));
device.setBindTime(now);
device.setPondId(bo.getPondId() != null && bo.getPondId() > 0 ? bo.getPondId() : null);
device.setBatteryWarnCallOpen(bo.getBatteryWarnCallOpen());
device.setBatteryWarnCallNoDis(bo.getBatteryWarnCallNoDis());
device.setBatteryWarnLower(bo.getBatteryWarnLower());
// 解析并设置设备属性ICCID 等)
if (deviceProperties != null && Boolean.TRUE.equals(deviceProperties.get("success"))) {
Object propData = deviceProperties.get("data");
if (propData != null) {
try {
java.lang.reflect.Method getListMethod = propData.getClass().getMethod("getList");
Object listObj = getListMethod.invoke(propData);
if (listObj instanceof java.util.List) {
java.util.List<?> propList = (java.util.List<?>) listObj;
for (Object item : propList) {
if (item != null) {
try {
java.lang.reflect.Method getIdentifierMethod = item.getClass().getMethod("getIdentifier");
java.lang.reflect.Method getValueMethod = item.getClass().getMethod("getValue");
String attribute = (String) getIdentifierMethod.invoke(item);
Object value = getValueMethod.invoke(item);
if (attribute != null && value != null) {
switch (attribute) {
case "ICCID": // 物联网卡号
device.setIccId(value.toString());
break;
}
}
} catch (Exception ex) {
log.error("无法从 SDK 对象中获取属性: {}", ex.getMessage(), ex);
}
}
}
}
} catch (Exception ex) {
log.error("无法从 SDK 对象中获取属性列表: {}", ex.getMessage(), ex);
}
}
}
// 初始化警告码
int warnCode = 0;
// 如果设备离线,添加离线警告
if (status != null && "OFFLINE".equalsIgnoreCase(status)) {
warnCode |= 0x0080; // 设备离线
}
device.setWarnCode(warnCode);
// 验证 ICCID 是否存在
if (device.getIccId() == null || device.getIccId().isEmpty()) {
return R.fail("设备缺少物联网卡号(ICCID)");
}
// 添加绑定记录
addNewDeviceBindRecord(device, true);
// 保存到数据库
if (isNew) {
deviceMapper.insert(device);
log.info("新设备添加成功: userId={}, iotId={}, serialNum={}", rootUserId, iotId, bo.getSerialNum());
} else {
deviceMapper.updateById(device);
log.info("设备更新成功: userId={}, iotId={}, serialNum={}", rootUserId, iotId, bo.getSerialNum());
}
return R.ok();
} catch (Exception e) {
log.error("添加太阳能网控失败: {}", e.getMessage(), e);
return R.fail("添加太阳能网控失败: " + e.getMessage());
}
}
@Operation(summary = "设备校准") @Operation(summary = "设备校准")
@PostMapping("/device/calibrate") @PostMapping("/device/calibrate")
public R<Void> setCalibrate(@RequestBody DeviceCalibrateBo request) { public R<Void> setCalibrate(@RequestBody DeviceCalibrateBo request) {

View File

@@ -0,0 +1,56 @@
package com.intc.iot.domain.bo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 添加太阳能网控业务对象
*
* @author intc
*/
@Data
@Schema(description = "添加太阳能网控请求对象")
public class AddDeviceSolarControllerBo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 设备编号/序列号
*/
@Schema(description = "设备编号/序列号")
@NotBlank(message = "设备编号不能为空")
private String serialNum;
/**
* 塘口ID
*/
@Schema(description = "塘口ID")
private Long pondId;
/**
* 电量电话告警开关0-关闭, 1-开启)
*/
@Schema(description = "电量电话告警开关0-关闭, 1-开启)")
@NotNull(message = "电量电话告警开关不能为空")
private Long batteryWarnCallOpen;
/**
* 电量告警免打扰0-关闭, 1-开启)
*/
@Schema(description = "电量告警免打扰0-关闭, 1-开启)")
@NotNull(message = "电量告警免打扰不能为空")
private Long batteryWarnCallNoDis;
/**
* 电量电话告警下限(百分比)
*/
@Schema(description = "电量电话告警下限(百分比)")
@NotNull(message = "电量电话告警下限不能为空")
private Long batteryWarnLower;
}