修改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.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; 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.EnableCustomConfig;
import com.ruoyi.common.security.annotation.EnableRyFeignClients; import com.ruoyi.common.security.annotation.EnableRyFeignClients;
@ -10,6 +11,7 @@ import com.ruoyi.common.security.annotation.EnableRyFeignClients;
* *
* @author ruoyi * @author ruoyi
*/ */
@EnableScheduling
@EnableCustomConfig @EnableCustomConfig
@EnableRyFeignClients @EnableRyFeignClients
@SpringBootApplication @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.api.IThingsBoardDomain;
import com.ruoyi.device.domain.model.thingsboard.*; import com.ruoyi.device.domain.model.thingsboard.*;
import com.ruoyi.device.domain.model.thingsboard.constants.DeviceAttributes;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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.rest.client.RestClient;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
/** /**
* ThingsBoard设备服务实现类 * ThingsBoard设备服务实现类
*/ */
@Component
public class ThingsBoardDomainImpl implements IThingsBoardDomain { public class ThingsBoardDomainImpl implements IThingsBoardDomain {
private static final Logger log = LoggerFactory.getLogger(ThingsBoardDomainImpl.class); private static final Logger log = LoggerFactory.getLogger(ThingsBoardDomainImpl.class);
private final RestClient client; private final RestClient client;
private final int pageSize; private final int pageSize;
public ThingsBoardDomainImpl(RestClientManager clientManager) { /**
this(clientManager, 10); * 构造函数 - Spring 会自动装配
} * @param clientManager RestClient 管理器
* @param pageSize 分页大小从配置文件读取默认值为 10
public ThingsBoardDomainImpl(RestClientManager clientManager, int pageSize) { */
public ThingsBoardDomainImpl(RestClientManager clientManager,
@Value("${thingsboard.page-size:10}") int pageSize) {
this.client = clientManager.getClient(); this.client = clientManager.getClient();
this.pageSize = pageSize; this.pageSize = pageSize;
} }
@ -146,4 +157,46 @@ public class ThingsBoardDomainImpl implements IThingsBoardDomain {
log.warn("解析遥测数据失败: key={}, value={}, error={}", keyName, value, e.getMessage()); 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.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.thingsboard.rest.client.RestClient; import org.thingsboard.rest.client.RestClient;
/** /**
* RestClient单例管理器 * RestClient管理器
* 提供全局唯一的RestClient实例避免重复创建连接 * 提供全局唯一的RestClient实例避免重复创建连接
* *
* 注意RestClient内部已经实现了token自动刷新和重新登录机制 * 注意RestClient内部已经实现了token自动刷新和重新登录机制
* 本管理器主要用于全局共享同一个连接实例 * 本管理器主要用于全局共享同一个连接实例
*/ */
@Component
public class RestClientManager { public class RestClientManager {
private static final Logger log = LoggerFactory.getLogger(RestClientManager.class); private static final Logger log = LoggerFactory.getLogger(RestClientManager.class);
private static volatile RestClientManager instance;
private volatile RestClient client; private volatile RestClient client;
private final String url; private final String url;
@ -22,28 +24,19 @@ public class RestClientManager {
private final String password; 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.url = url;
this.username = username; this.username = username;
this.password = password; 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实例 * 获取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;
/** /**
* 预定义的设备遥测数据键 * 预定义的设备遥测数据键