feat: 新功能开发,监测历史记录。微信和物联网平台,模块搭建。

This commit is contained in:
tianyongbao
2025-11-05 00:35:23 +08:00
parent 4d10d291a3
commit 8fd28e727e
38 changed files with 2099 additions and 49 deletions

View File

@@ -0,0 +1,42 @@
package com.intc.iot.service;
/**
* 设备数据服务接口
*
* @author intc
*/
public interface DeviceDataService {
/**
* 订阅设备属性上报
*
* @param iotId 设备ID
* @throws Exception 异常
*/
void subscribeDeviceProperties(String iotId) throws Exception;
/**
* 订阅设备事件上报
*
* @param iotId 设备ID
* @throws Exception 异常
*/
void subscribeDeviceEvents(String iotId) throws Exception;
/**
* 订阅所有设备数据
*
* @param productKey 产品Key
* @throws Exception 异常
*/
void subscribeAllDevices(String productKey) throws Exception;
/**
* 取消订阅设备数据
*
* @param iotId 设备ID
* @throws Exception 异常
*/
void unsubscribeDevice(String iotId) throws Exception;
}

View File

@@ -0,0 +1,70 @@
package com.intc.iot.service;
import java.util.Map;
/**
* 阿里云生活物联网平台(飞燕平台)设备管理服务
*
* @author intc
*/
public interface IotDeviceService {
/**
* 查询设备列表
*
* @param pageNo 页码
* @param pageSize 每页大小
* @return 设备列表
* @throws Exception 异常
*/
Map<String, Object> queryDeviceList(Integer pageNo, Integer pageSize) throws Exception;
/**
* 查询设备详情
*
* @param iotId 设备ID
* @return 设备详情
* @throws Exception 异常
*/
Map<String, Object> queryDeviceInfo(String iotId) throws Exception;
/**
* 查询设备属性
*
* @param iotId 设备ID
* @return 设备属性
* @throws Exception 异常
*/
Map<String, Object> queryDeviceProperties(String iotId) throws Exception;
/**
* 设置设备属性
*
* @param iotId 设备ID
* @param properties 属性JSON
* @return 设置结果
* @throws Exception 异常
*/
Map<String, Object> setDeviceProperty(String iotId, String properties) throws Exception;
/**
* 调用设备服务
*
* @param iotId 设备ID
* @param identifier 服务标识符
* @param args 参数
* @return 调用结果
* @throws Exception 异常
*/
Map<String, Object> invokeService(String iotId, String identifier, String args) throws Exception;
/**
* 解绑设备
*
* @param iotId 设备ID
* @return 解绑结果
* @throws Exception 异常
*/
Map<String, Object> unbindDevice(String iotId) throws Exception;
}

View File

@@ -0,0 +1,37 @@
package com.intc.iot.service;
/**
* MQTT 消息服务
*
* @author intc
*/
public interface MqttService {
/**
* 发布消息
*
* @param topic 主题
* @param payload 消息内容
* @param qos 服务质量等级0/1/2
* @throws Exception 异常
*/
void publish(String topic, String payload, int qos) throws Exception;
/**
* 订阅主题
*
* @param topic 主题
* @param qos 服务质量等级0/1/2
* @throws Exception 异常
*/
void subscribe(String topic, int qos) throws Exception;
/**
* 取消订阅
*
* @param topic 主题
* @throws Exception 异常
*/
void unsubscribe(String topic) throws Exception;
}

View File

@@ -0,0 +1,85 @@
package com.intc.iot.service.impl;
import cn.hutool.json.JSONUtil;
import com.intc.iot.service.DeviceDataService;
import com.intc.iot.service.MqttService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Service;
/**
* 设备数据服务实现
*
* @author intc
*/
@Slf4j
@Service
@RequiredArgsConstructor
@ConditionalOnBean(MqttClient.class)
public class DeviceDataServiceImpl implements DeviceDataService {
private final MqttService mqttService;
/**
* 飞燕平台设备属性上报 Topic 格式
* /sys/{productKey}/{deviceName}/thing/event/property/post
*/
private static final String PROPERTY_POST_TOPIC = "/sys/%s/%s/thing/event/property/post";
/**
* 飞燕平台设备事件上报 Topic 格式
* /sys/{productKey}/{deviceName}/thing/event/{eventIdentifier}/post
*/
private static final String EVENT_POST_TOPIC = "/sys/%s/%s/thing/event/+/post";
/**
* 所有设备属性上报 Topic使用通配符
* /sys/{productKey}/+/thing/event/property/post
*/
private static final String ALL_DEVICES_PROPERTY_TOPIC = "/sys/%s/+/thing/event/property/post";
@Override
public void subscribeDeviceProperties(String iotId) throws Exception {
// 注意:需要根据 iotId 获取 productKey 和 deviceName
// 这里简化处理,实际应该从数据库或缓存中查询
log.info("订阅设备属性上报IotId: {}", iotId);
// 示例:假设从设备信息中获取
// String productKey = getProductKeyByIotId(iotId);
// String deviceName = getDeviceNameByIotId(iotId);
// String topic = String.format(PROPERTY_POST_TOPIC, productKey, deviceName);
// mqttService.subscribe(topic, 1);
log.warn("请先实现 iotId 到 productKey/deviceName 的映射逻辑");
}
@Override
public void subscribeDeviceEvents(String iotId) throws Exception {
log.info("订阅设备事件上报IotId: {}", iotId);
// 类似属性订阅,需要映射关系
log.warn("请先实现 iotId 到 productKey/deviceName 的映射逻辑");
}
@Override
public void subscribeAllDevices(String productKey) throws Exception {
log.info("订阅产品下所有设备属性上报ProductKey: {}", productKey);
String topic = String.format(ALL_DEVICES_PROPERTY_TOPIC, productKey);
mqttService.subscribe(topic, 1);
log.info("成功订阅 Topic: {}", topic);
}
@Override
public void unsubscribeDevice(String iotId) throws Exception {
log.info("取消订阅设备数据IotId: {}", iotId);
// 需要取消对应的 Topic 订阅
log.warn("请先实现 iotId 到 productKey/deviceName 的映射逻辑");
}
}

View File

@@ -0,0 +1,125 @@
package com.intc.iot.service.impl;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.iot.model.v20180120.*;
import com.intc.iot.config.AliyunIotProperties;
import com.intc.iot.service.IotDeviceService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* 阿里云生活物联网平台(飞燕平台)设备管理服务实现
*
* @author intc
*/
@Slf4j
@Service
@RequiredArgsConstructor
@ConditionalOnBean(IAcsClient.class)
public class IotDeviceServiceImpl implements IotDeviceService {
private final IAcsClient acsClient;
private final AliyunIotProperties iotProperties;
@Override
public Map<String, Object> queryDeviceList(Integer pageNo, Integer pageSize) throws Exception {
log.info("查询设备列表,页码: {}, 每页大小: {}", pageNo, pageSize);
QueryDeviceRequest request = new QueryDeviceRequest();
request.setCurrentPage(pageNo);
request.setPageSize(pageSize);
QueryDeviceResponse response = acsClient.getAcsResponse(request);
Map<String, Object> result = new HashMap<>();
result.put("success", response.getSuccess());
result.put("data", response.getData());
result.put("total", response.getTotal());
return result;
}
@Override
public Map<String, Object> queryDeviceInfo(String iotId) throws Exception {
log.info("查询设备详情IotId: {}", iotId);
QueryDeviceDetailRequest request = new QueryDeviceDetailRequest();
request.setIotId(iotId);
QueryDeviceDetailResponse response = acsClient.getAcsResponse(request);
Map<String, Object> result = new HashMap<>();
result.put("success", response.getSuccess());
result.put("data", response.getData());
return result;
}
@Override
public Map<String, Object> queryDeviceProperties(String iotId) throws Exception {
log.info("查询设备属性IotId: {}", iotId);
QueryDevicePropertyStatusRequest request = new QueryDevicePropertyStatusRequest();
request.setIotId(iotId);
QueryDevicePropertyStatusResponse response = acsClient.getAcsResponse(request);
Map<String, Object> result = new HashMap<>();
result.put("success", response.getSuccess());
result.put("data", response.getData());
return result;
}
@Override
public Map<String, Object> setDeviceProperty(String iotId, String properties) throws Exception {
log.info("设置设备属性IotId: {}, Properties: {}", iotId, properties);
SetDevicePropertyRequest request = new SetDevicePropertyRequest();
request.setIotId(iotId);
request.setItems(properties);
SetDevicePropertyResponse response = acsClient.getAcsResponse(request);
Map<String, Object> result = new HashMap<>();
result.put("success", response.getSuccess());
result.put("data", response.getData());
return result;
}
@Override
public Map<String, Object> invokeService(String iotId, String identifier, String args) throws Exception {
log.info("调用设备服务IotId: {}, Identifier: {}", iotId, identifier);
InvokeThingServiceRequest request = new InvokeThingServiceRequest();
request.setIotId(iotId);
request.setIdentifier(identifier);
request.setArgs(args);
InvokeThingServiceResponse response = acsClient.getAcsResponse(request);
Map<String, Object> result = new HashMap<>();
result.put("success", response.getSuccess());
result.put("data", response.getData());
return result;
}
@Override
public Map<String, Object> unbindDevice(String iotId) throws Exception {
log.info("解绑设备IotId: {}", iotId);
// 注: 通用IoT SDK没有直接的解绑接口这里使用删除设备
DeleteDeviceRequest request = new DeleteDeviceRequest();
request.setIotId(iotId);
DeleteDeviceResponse response = acsClient.getAcsResponse(request);
Map<String, Object> result = new HashMap<>();
result.put("success", response.getSuccess());
result.put("errorMessage", response.getErrorMessage());
return result;
}
}

View File

@@ -0,0 +1,87 @@
package com.intc.iot.service.impl;
import com.intc.iot.handler.DeviceDataHandler;
import com.intc.iot.service.MqttService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttMessageListener;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Service;
/**
* MQTT 消息服务实现
*
* @author intc
*/
@Slf4j
@Service
@RequiredArgsConstructor
@ConditionalOnBean(MqttClient.class)
public class MqttServiceImpl implements MqttService {
private final MqttClient mqttClient;
@Autowired(required = false)
private DeviceDataHandler deviceDataHandler;
@Override
public void publish(String topic, String payload, int qos) throws Exception {
if (!mqttClient.isConnected()) {
log.warn("MQTT 客户端未连接,尝试重连...");
mqttClient.reconnect();
}
MqttMessage message = new MqttMessage(payload.getBytes());
message.setQos(qos);
message.setRetained(false);
mqttClient.publish(topic, message);
log.info("MQTT 消息发布成功Topic: {}, Payload: {}", topic, payload);
}
@Override
public void subscribe(String topic, int qos) throws Exception {
if (!mqttClient.isConnected()) {
log.warn("MQTT 客户端未连接,尝试重连...");
mqttClient.reconnect();
}
mqttClient.subscribe(topic, qos, new IMqttMessageListener() {
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
String payload = new String(message.getPayload());
log.info("收到 MQTT 消息Topic: {}, Payload: {}", topic, payload);
// 根据 Topic 类型分发处理
if (deviceDataHandler != null) {
if (topic.contains("/thing/event/property/post")) {
// 设备属性上报
deviceDataHandler.handlePropertyPost(topic, payload);
} else if (topic.contains("/thing/event/") && topic.endsWith("/post")) {
// 设备事件上报
deviceDataHandler.handleEventPost(topic, payload);
} else {
log.debug("未匹配的 Topic 类型: {}", topic);
}
}
}
});
log.info("MQTT 主题订阅成功Topic: {}", topic);
}
@Override
public void unsubscribe(String topic) throws Exception {
if (!mqttClient.isConnected()) {
log.warn("MQTT 客户端未连接");
return;
}
mqttClient.unsubscribe(topic);
log.info("MQTT 主题取消订阅成功Topic: {}", topic);
}
}