修改IOT代码,添加定时器测试是否可以获取到设备信息

This commit is contained in:
孙小云 2026-01-16 10:23:43 +08:00
parent 9fd9602718
commit e9630d60e5
5 changed files with 77 additions and 25 deletions

View File

@ -2,6 +2,7 @@ package com.ruoyi.device;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import com.ruoyi.common.security.annotation.EnableCustomConfig;
import com.ruoyi.common.security.annotation.EnableRyFeignClients;
@ -10,6 +11,7 @@ import com.ruoyi.common.security.annotation.EnableRyFeignClients;
*
* @author ruoyi
*/
@EnableScheduling
@EnableCustomConfig
@EnableRyFeignClients
@SpringBootApplication

View File

@ -3,30 +3,41 @@ package com.ruoyi.device.domain.impl;
import com.ruoyi.device.domain.api.IThingsBoardDomain;
import com.ruoyi.device.domain.model.thingsboard.*;
import com.ruoyi.device.domain.model.thingsboard.constants.DeviceAttributes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.thingsboard.rest.client.RestClient;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
/**
* ThingsBoard设备服务实现类
*/
@Component
public class ThingsBoardDomainImpl implements IThingsBoardDomain {
private static final Logger log = LoggerFactory.getLogger(ThingsBoardDomainImpl.class);
private final RestClient client;
private final int pageSize;
public ThingsBoardDomainImpl(RestClientManager clientManager) {
this(clientManager, 10);
}
public ThingsBoardDomainImpl(RestClientManager clientManager, int pageSize) {
/**
* 构造函数 - Spring 会自动装配
* @param clientManager RestClient 管理器
* @param pageSize 分页大小从配置文件读取默认值为 10
*/
public ThingsBoardDomainImpl(RestClientManager clientManager,
@Value("${thingsboard.page-size:10}") int pageSize) {
this.client = clientManager.getClient();
this.pageSize = pageSize;
}
@ -146,4 +157,46 @@ public class ThingsBoardDomainImpl implements IThingsBoardDomain {
log.warn("解析遥测数据失败: key={}, value={}, error={}", keyName, value, e.getMessage());
}
}
/**
* 定时任务每隔1分钟打印所有设备信息
* 执行时间每分钟的第0秒执行
*/
@Scheduled(cron = "0 * * * * ?")
public void printAllDevicesScheduled() {
try {
log.info("========== 开始执行定时任务:打印所有设备信息 ==========");
Iterable<List<DeviceInfo>> allDevices = getAllDevices();
int totalCount = 0;
for (List<DeviceInfo> deviceBatch : allDevices) {
for (DeviceInfo device : deviceBatch) {
// 获取设备属性以获取活跃状态
Boolean activeStatus = false;
try {
AttributeMap attributes = getDeviceAttributes(device.getId());
// 尝试从 AttributeMap 中获取 active 属性
Optional<Boolean> active = attributes.get(DeviceAttributes.ACTIVE);
if (active.isPresent()) {
activeStatus = active.get();
}
} catch (Exception e) {
log.debug("获取设备 {} 的活跃状态失败: {}", device.getId(), e.getMessage());
}
log.info("Device Name: {}, Device ID: {}, Device Type: {}, Active: {}",
device.getName(),
device.getId(),
device.getType(),
activeStatus);
totalCount++;
}
}
log.info("========== 定时任务执行完成,共打印 {} 个设备 ==========", totalCount);
} catch (Exception e) {
log.error("定时任务执行失败: {}", e.getMessage(), e);
}
}
}

View File

@ -2,19 +2,21 @@ package com.ruoyi.device.domain.model.thingsboard;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.thingsboard.rest.client.RestClient;
/**
* RestClient单例管理器
* RestClient管理器
* 提供全局唯一的RestClient实例避免重复创建连接
*
* 注意RestClient内部已经实现了token自动刷新和重新登录机制
* 本管理器主要用于全局共享同一个连接实例
*/
@Component
public class RestClientManager {
private static final Logger log = LoggerFactory.getLogger(RestClientManager.class);
private static volatile RestClientManager instance;
private volatile RestClient client;
private final String url;
@ -22,28 +24,19 @@ public class RestClientManager {
private final String password;
/**
* 私有构造函数
* 构造函数 - Spring 自动装配
* @param url ThingsBoard服务器地址默认 http://thingsboard-ce:8080
* @param username 用户名默认 tenant@thingsboard.org
* @param password 密码默认 tenant
*/
private RestClientManager(String url, String username, String password) {
public RestClientManager(@Value("${thingsboard.url:http://thingsboard-ce:8080}") String url,
@Value("${thingsboard.username:tenant@thingsboard.org}") String username,
@Value("${thingsboard.password:tenant}") String password) {
this.url = url;
this.username = username;
this.password = password;
}
/**
* 获取单例实例双重检查锁
*/
public static RestClientManager getInstance(String url, String username, String password) {
if (instance == null) {
synchronized (RestClientManager.class) {
if (instance == null) {
instance = new RestClientManager(url, username, password);
}
}
}
return instance;
}
/**
* 获取RestClient实例
* 懒加载第一次调用时才创建并登录

View File

@ -1,4 +1,6 @@
package com.ruoyi.device.domain.model.thingsboard;
package com.ruoyi.device.domain.model.thingsboard.constants;
import com.ruoyi.device.domain.model.thingsboard.AttributeKey;
/**
* 预定义的设备属性键

View File

@ -1,4 +1,6 @@
package com.ruoyi.device.domain.model.thingsboard;
package com.ruoyi.device.domain.model.thingsboard.constants;
import com.ruoyi.device.domain.model.thingsboard.TelemetryKey;
/**
* 预定义的设备遥测数据键