修改IThingsBoardDomain.java
This commit is contained in:
parent
2521bca9ae
commit
8f0d69b42f
|
|
@ -107,4 +107,40 @@ public interface IThingsBoardDomain {
|
||||||
* @param deviceId 设备ID
|
* @param deviceId 设备ID
|
||||||
*/
|
*/
|
||||||
void evictDeviceTelemetryCache(String deviceId);
|
void evictDeviceTelemetryCache(String deviceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据设备ID获取拓恒设备的所有属性
|
||||||
|
* 只返回已注册的属性键对应的数据,未注册的键会被忽略
|
||||||
|
*
|
||||||
|
* @param deviceId 设备ID
|
||||||
|
* @return 类型安全的属性映射
|
||||||
|
*/
|
||||||
|
AttributeMap getTuohengDeviceAttributes(String deviceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据设备ID获取拓恒设备的所有遥测数据
|
||||||
|
* 只返回已注册的遥测键对应的数据,未注册的键会被忽略
|
||||||
|
*
|
||||||
|
* @param deviceId 设备ID
|
||||||
|
* @return 类型安全的遥测数据映射
|
||||||
|
*/
|
||||||
|
TelemetryMap getTuohengDeviceTelemetry(String deviceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据设备ID获取拓恒设备的预定义属性
|
||||||
|
* 只返回在 TuohengDeviceAttributes 中预定义的属性
|
||||||
|
*
|
||||||
|
* @param deviceId 设备ID
|
||||||
|
* @return 类型安全的属性映射,只包含预定义的属性
|
||||||
|
*/
|
||||||
|
AttributeMap getPredefinedTuohengDeviceAttributes(String deviceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据设备ID获取拓恒设备的预定义遥测数据
|
||||||
|
* 只返回在 TuohengDeviceTelemetry 中预定义的遥测数据
|
||||||
|
*
|
||||||
|
* @param deviceId 设备ID
|
||||||
|
* @return 类型安全的遥测数据映射,只包含预定义的遥测数据
|
||||||
|
*/
|
||||||
|
TelemetryMap getPredefinedTuohengDeviceTelemetry(String deviceId);
|
||||||
}
|
}
|
||||||
|
|
@ -6,6 +6,8 @@ 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 com.ruoyi.device.domain.model.thingsboard.constants.DeviceAttributes;
|
||||||
import com.ruoyi.device.domain.model.thingsboard.constants.DeviceTelemetry;
|
import com.ruoyi.device.domain.model.thingsboard.constants.DeviceTelemetry;
|
||||||
|
import com.ruoyi.device.domain.model.thingsboard.tuoheng.constants.TuohengDeviceAttributes;
|
||||||
|
import com.ruoyi.device.domain.model.thingsboard.tuoheng.constants.TuohengDeviceTelemetry;
|
||||||
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.beans.factory.annotation.Value;
|
||||||
|
|
@ -340,4 +342,124 @@ public class ThingsBoardDomainImpl implements IThingsBoardDomain {
|
||||||
public void evictDeviceTelemetryCache(String deviceId) {
|
public void evictDeviceTelemetryCache(String deviceId) {
|
||||||
// 空实现,仅用于清除缓存
|
// 空实现,仅用于清除缓存
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Cacheable(value = DeviceCacheConfig.THINGSBOARD_ATTRIBUTES_CACHE, key = "'tuoheng_' + #deviceId", unless = "#result == null || #result.isEmpty()")
|
||||||
|
public AttributeMap getTuohengDeviceAttributes(String deviceId) {
|
||||||
|
AttributeMap attributeMap = new AttributeMap();
|
||||||
|
|
||||||
|
try {
|
||||||
|
DeviceId deviceIdObj = new DeviceId(UUID.fromString(deviceId));
|
||||||
|
|
||||||
|
List<String> attributeKeys = client.getAttributeKeys(deviceIdObj);
|
||||||
|
if (attributeKeys == null || attributeKeys.isEmpty()) {
|
||||||
|
log.debug("拓恒设备 {} 没有属性", deviceId);
|
||||||
|
return attributeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<AttributeKvEntry> attributeKvEntries = client.getAttributeKvEntries(deviceIdObj, attributeKeys);
|
||||||
|
if (attributeKvEntries == null || attributeKvEntries.isEmpty()) {
|
||||||
|
log.debug("拓恒设备 {} 的属性值为空", deviceId);
|
||||||
|
return attributeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (AttributeKvEntry entry : attributeKvEntries) {
|
||||||
|
parseAndPutAttribute(attributeMap, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取拓恒设备属性失败: deviceId={}, error={}", deviceId, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return attributeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Cacheable(value = DeviceCacheConfig.THINGSBOARD_TELEMETRY_CACHE, key = "'tuoheng_' + #deviceId", unless = "#result == null || #result.isEmpty()")
|
||||||
|
public TelemetryMap getTuohengDeviceTelemetry(String deviceId) {
|
||||||
|
TelemetryMap telemetryMap = new TelemetryMap();
|
||||||
|
|
||||||
|
try {
|
||||||
|
DeviceId deviceIdObj = new DeviceId(UUID.fromString(deviceId));
|
||||||
|
|
||||||
|
List<String> timeseriesKeys = client.getTimeseriesKeys(deviceIdObj);
|
||||||
|
if (timeseriesKeys == null || timeseriesKeys.isEmpty()) {
|
||||||
|
log.debug("拓恒设备 {} 没有遥测数据", deviceId);
|
||||||
|
return telemetryMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<TsKvEntry> latestTimeseries = client.getLatestTimeseries(deviceIdObj, timeseriesKeys);
|
||||||
|
if (latestTimeseries == null || latestTimeseries.isEmpty()) {
|
||||||
|
log.debug("拓恒设备 {} 的遥测数据为空", deviceId);
|
||||||
|
return telemetryMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (TsKvEntry entry : latestTimeseries) {
|
||||||
|
parseAndPutTelemetry(telemetryMap, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取拓恒设备遥测数据失败: deviceId={}, error={}", deviceId, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return telemetryMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AttributeMap getPredefinedTuohengDeviceAttributes(String deviceId) {
|
||||||
|
// 先获取所有属性(已经处理了异常情况)
|
||||||
|
AttributeMap allAttributes = getTuohengDeviceAttributes(deviceId);
|
||||||
|
|
||||||
|
// 创建新的 AttributeMap 只包含预定义的键
|
||||||
|
AttributeMap predefinedAttributes = new AttributeMap();
|
||||||
|
|
||||||
|
// 获取预定义的键名称集合
|
||||||
|
List<String> predefinedKeyNames = TuohengDeviceAttributes.getPredefinedKeys()
|
||||||
|
.stream()
|
||||||
|
.map(AttributeKey::getName)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
// 过滤:只保留预定义的键
|
||||||
|
for (AttributeKey<?> key : allAttributes.keySet()) {
|
||||||
|
if (predefinedKeyNames.contains(key.getName())) {
|
||||||
|
// 复制到新的 map
|
||||||
|
allAttributes.get(key).ifPresent(value -> {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
AttributeKey<Object> objKey = (AttributeKey<Object>) key;
|
||||||
|
predefinedAttributes.put(objKey, value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return predefinedAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TelemetryMap getPredefinedTuohengDeviceTelemetry(String deviceId) {
|
||||||
|
// 先获取所有遥测数据(已经处理了 null 值问题)
|
||||||
|
TelemetryMap allTelemetry = getTuohengDeviceTelemetry(deviceId);
|
||||||
|
|
||||||
|
// 创建新的 TelemetryMap 只包含预定义的键
|
||||||
|
TelemetryMap predefinedTelemetry = new TelemetryMap();
|
||||||
|
|
||||||
|
// 获取预定义的键名称集合
|
||||||
|
List<String> predefinedKeyNames = TuohengDeviceTelemetry.getPredefinedKeys()
|
||||||
|
.stream()
|
||||||
|
.map(TelemetryKey::getName)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
// 过滤:只保留预定义的键
|
||||||
|
for (TelemetryKey<?> key : allTelemetry.keySet()) {
|
||||||
|
if (predefinedKeyNames.contains(key.getName())) {
|
||||||
|
// 复制到新的 map
|
||||||
|
allTelemetry.get(key).ifPresent(telemetryValue -> {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
TelemetryKey<Object> objKey = (TelemetryKey<Object>) key;
|
||||||
|
predefinedTelemetry.put(objKey, telemetryValue.getValue(), telemetryValue.getTimestamp());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return predefinedTelemetry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,172 @@
|
||||||
|
package com.ruoyi.device.domain.model.thingsboard.tuoheng.constants;
|
||||||
|
|
||||||
|
import com.ruoyi.device.domain.model.thingsboard.AttributeKey;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拓恒设备属性键
|
||||||
|
* 使用类型安全的方式定义拓恒设备专用属性
|
||||||
|
*/
|
||||||
|
public class TuohengDeviceAttributes {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公用服务端属性
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 最后连接时间 - Long
|
||||||
|
public static final AttributeKey<Long> LAST_CONNECT_TIME = AttributeKey.of(
|
||||||
|
"lastConnectTime",
|
||||||
|
Long.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).longValue();
|
||||||
|
}
|
||||||
|
return Long.parseLong(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 是否激活 - Boolean
|
||||||
|
public static final AttributeKey<Boolean> ACTIVE = AttributeKey.of(
|
||||||
|
"active",
|
||||||
|
Boolean.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Boolean) {
|
||||||
|
return (Boolean) value;
|
||||||
|
}
|
||||||
|
return Boolean.parseBoolean(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 最后活动时间 - Long
|
||||||
|
public static final AttributeKey<Long> LAST_ACTIVITY_TIME = AttributeKey.of(
|
||||||
|
"lastActivityTime",
|
||||||
|
Long.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).longValue();
|
||||||
|
}
|
||||||
|
return Long.parseLong(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 最后断开连接时间 - Long
|
||||||
|
public static final AttributeKey<Long> LAST_DISCONNECT_TIME = AttributeKey.of(
|
||||||
|
"lastDisconnectTime",
|
||||||
|
Long.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).longValue();
|
||||||
|
}
|
||||||
|
return Long.parseLong(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公用客户端属性 (无需配置)
|
||||||
|
*/
|
||||||
|
// 连接器类型 - String
|
||||||
|
public static final AttributeKey<String> CONNECTOR_TYPE = AttributeKey.of(
|
||||||
|
"connectorType",
|
||||||
|
String.class,
|
||||||
|
value -> value != null ? value.toString() : null
|
||||||
|
);
|
||||||
|
|
||||||
|
// 连接器名称 - String (值为 "tuoheng")
|
||||||
|
public static final AttributeKey<String> CONNECTOR_NAME = AttributeKey.of(
|
||||||
|
"connectorName",
|
||||||
|
String.class,
|
||||||
|
value -> value != null ? value.toString() : null
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拓恒机场特有属性 (来自 /topic/v1/airportNest/+/realTime/basic)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 机场ID - String
|
||||||
|
public static final AttributeKey<String> AIRPORT_ID = AttributeKey.of(
|
||||||
|
"airportID",
|
||||||
|
String.class,
|
||||||
|
value -> value != null ? value.toString() : null
|
||||||
|
);
|
||||||
|
|
||||||
|
// MAC地址 - String
|
||||||
|
public static final AttributeKey<String> MAC = AttributeKey.of(
|
||||||
|
"mac",
|
||||||
|
String.class,
|
||||||
|
value -> value != null ? value.toString() : null
|
||||||
|
);
|
||||||
|
|
||||||
|
// 软件版本 - String
|
||||||
|
public static final AttributeKey<String> SOFTWARE_VERSION = AttributeKey.of(
|
||||||
|
"software_version",
|
||||||
|
String.class,
|
||||||
|
value -> value != null ? value.toString() : null
|
||||||
|
);
|
||||||
|
|
||||||
|
// 硬件版本 - String
|
||||||
|
public static final AttributeKey<String> HARDWARE_VERSION = AttributeKey.of(
|
||||||
|
"hardware_version",
|
||||||
|
String.class,
|
||||||
|
value -> value != null ? value.toString() : null
|
||||||
|
);
|
||||||
|
|
||||||
|
// 发送者标识 - String
|
||||||
|
public static final AttributeKey<String> SENDER = AttributeKey.of(
|
||||||
|
"sender",
|
||||||
|
String.class,
|
||||||
|
value -> value != null ? value.toString() : null
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拓恒无人机特有属性 (来自 /topic/v1/airportDrone/+/realTime/data)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 设备ID - String
|
||||||
|
public static final AttributeKey<String> DEVICE_ID = AttributeKey.of(
|
||||||
|
"deviceid",
|
||||||
|
String.class,
|
||||||
|
value -> value != null ? value.toString() : null
|
||||||
|
);
|
||||||
|
|
||||||
|
private TuohengDeviceAttributes() {
|
||||||
|
// 工具类,禁止实例化
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有预定义的属性键
|
||||||
|
*
|
||||||
|
* @return 预定义的属性键列表
|
||||||
|
*/
|
||||||
|
public static List<AttributeKey<?>> getPredefinedKeys() {
|
||||||
|
return Arrays.asList(
|
||||||
|
CONNECTOR_TYPE,
|
||||||
|
CONNECTOR_NAME,
|
||||||
|
LAST_CONNECT_TIME,
|
||||||
|
ACTIVE,
|
||||||
|
LAST_ACTIVITY_TIME,
|
||||||
|
LAST_DISCONNECT_TIME,
|
||||||
|
AIRPORT_ID,
|
||||||
|
MAC,
|
||||||
|
SOFTWARE_VERSION,
|
||||||
|
HARDWARE_VERSION,
|
||||||
|
SENDER,
|
||||||
|
DEVICE_ID
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化所有属性键
|
||||||
|
* 确保所有静态字段被加载和注册
|
||||||
|
*/
|
||||||
|
public static void init() {
|
||||||
|
// 这个方法的存在是为了触发类的静态初始化
|
||||||
|
// 当调用此方法时,所有静态字段都会被初始化
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,633 @@
|
||||||
|
package com.ruoyi.device.domain.model.thingsboard.tuoheng.constants;
|
||||||
|
|
||||||
|
import com.ruoyi.device.domain.model.thingsboard.TelemetryKey;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拓恒设备遥测数据键
|
||||||
|
* 使用类型安全的方式定义拓恒设备专用遥测数据
|
||||||
|
*/
|
||||||
|
public class TuohengDeviceTelemetry {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 机场心跳数据 (来自 /topic/v1/airportNest/+/realTime/basic)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 在线状态 - String (online/offline)
|
||||||
|
public static final TelemetryKey<String> STATUS = TelemetryKey.of(
|
||||||
|
"status",
|
||||||
|
String.class,
|
||||||
|
value -> value != null ? value.toString() : null
|
||||||
|
);
|
||||||
|
|
||||||
|
// 发送时间戳 - Long
|
||||||
|
public static final TelemetryKey<Long> SEND_TIMESTAMP = TelemetryKey.of(
|
||||||
|
"send_timestamp",
|
||||||
|
Long.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).longValue();
|
||||||
|
}
|
||||||
|
return Long.parseLong(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 气象数据 (来自 /topic/v1/airportNest/+/realTime/data)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 降雨量 - Double
|
||||||
|
public static final TelemetryKey<Double> WEATHER_RAINFALL = TelemetryKey.of(
|
||||||
|
"weather_rainfall",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 风力等级 - Double
|
||||||
|
public static final TelemetryKey<Double> WEATHER_WIND_LEVEL = TelemetryKey.of(
|
||||||
|
"weather_windLevel",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 风向 - Double
|
||||||
|
public static final TelemetryKey<Double> WEATHER_WIND_DIR = TelemetryKey.of(
|
||||||
|
"weather_windDir",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 风速 - Double
|
||||||
|
public static final TelemetryKey<Double> WEATHER_WIND_SPEED = TelemetryKey.of(
|
||||||
|
"weather_windSpeed",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 降雨标志 - Integer
|
||||||
|
public static final TelemetryKey<Integer> WEATHER_RAIN_FLAG = TelemetryKey.of(
|
||||||
|
"weather_rainFlag",
|
||||||
|
Integer.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
return Integer.parseInt(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 风向角度 - Double
|
||||||
|
public static final TelemetryKey<Double> WEATHER_WIND_ANGLE = TelemetryKey.of(
|
||||||
|
"weather_windAngle",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电池数据 (来自 /topic/v1/airportNest/+/realTime/data)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 电池电量百分比 - Integer
|
||||||
|
public static final TelemetryKey<Integer> BATTERY_LEVEL = TelemetryKey.of(
|
||||||
|
"battery_level",
|
||||||
|
Integer.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
return Integer.parseInt(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 电池健康度 - Integer
|
||||||
|
public static final TelemetryKey<Integer> BATTERY_HEALTH = TelemetryKey.of(
|
||||||
|
"battery_health",
|
||||||
|
Integer.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
return Integer.parseInt(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 总电压 - Double
|
||||||
|
public static final TelemetryKey<Double> BATTERY_TOTAL_VOLTAGE = TelemetryKey.of(
|
||||||
|
"battery_totalVoltage",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 电芯温度 - Double
|
||||||
|
public static final TelemetryKey<Double> BATTERY_CELL_TEMP = TelemetryKey.of(
|
||||||
|
"battery_cellTemp",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// MOS温度 - Double
|
||||||
|
public static final TelemetryKey<Double> BATTERY_MOS_TEMP = TelemetryKey.of(
|
||||||
|
"battery_mosTemp",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 循环次数 - Integer
|
||||||
|
public static final TelemetryKey<Integer> BATTERY_NUM_CYCLES = TelemetryKey.of(
|
||||||
|
"battery_num_cycles",
|
||||||
|
Integer.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
return Integer.parseInt(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 放电电流 - Double
|
||||||
|
public static final TelemetryKey<Double> BATTERY_DISCHARGE_CURRENT = TelemetryKey.of(
|
||||||
|
"battery_discharge_current",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 充电状态 - Integer
|
||||||
|
public static final TelemetryKey<Integer> BATTERY_B_CHARGING = TelemetryKey.of(
|
||||||
|
"battery_bCharging",
|
||||||
|
Integer.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
return Integer.parseInt(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 舱内传感器数据 (来自 /topic/v1/airportNest/+/realTime/data)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 舱内湿度 - Double
|
||||||
|
public static final TelemetryKey<Double> NEST_INNER_HUM = TelemetryKey.of(
|
||||||
|
"nest_innerHum",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 舱内温度 - Double
|
||||||
|
public static final TelemetryKey<Double> NEST_INNER_TEMP = TelemetryKey.of(
|
||||||
|
"nest_innerTemp",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 充电器数据 (来自 /topic/v1/airportNest/+/realTime/data)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 充电电流 - Double
|
||||||
|
public static final TelemetryKey<Double> CHARGER_CURRENT = TelemetryKey.of(
|
||||||
|
"charger_current",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 充电电压 - Double
|
||||||
|
public static final TelemetryKey<Double> CHARGER_VOLTAGE = TelemetryKey.of(
|
||||||
|
"charger_voltage",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 充电容量 - Double
|
||||||
|
public static final TelemetryKey<Double> CHARGER_CAPACITY = TelemetryKey.of(
|
||||||
|
"charger_capacity",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 充电状态 - Integer
|
||||||
|
public static final TelemetryKey<Integer> CHARGER_B_CHARGING = TelemetryKey.of(
|
||||||
|
"charger_bCharging",
|
||||||
|
Integer.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
return Integer.parseInt(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机位置信息 (来自 /topic/v1/airportDrone/+/realTime/data)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 纬度 - Double
|
||||||
|
public static final TelemetryKey<Double> LATITUDE = TelemetryKey.of(
|
||||||
|
"latitude",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 经度 - Double
|
||||||
|
public static final TelemetryKey<Double> LONGITUDE = TelemetryKey.of(
|
||||||
|
"longitude",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 相对高度 - Double
|
||||||
|
public static final TelemetryKey<Double> ALTITUDE = TelemetryKey.of(
|
||||||
|
"altitude",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 绝对高度 - Double
|
||||||
|
public static final TelemetryKey<Double> ALTITUDE_ASL = TelemetryKey.of(
|
||||||
|
"altitude_asl",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机姿态信息 (来自 /topic/v1/airportDrone/+/realTime/data)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 横滚角 - Double
|
||||||
|
public static final TelemetryKey<Double> ROLL = TelemetryKey.of(
|
||||||
|
"roll",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 俯仰角 - Double
|
||||||
|
public static final TelemetryKey<Double> PITCH = TelemetryKey.of(
|
||||||
|
"pitch",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 偏航角 - Double
|
||||||
|
public static final TelemetryKey<Double> YAW = TelemetryKey.of(
|
||||||
|
"yaw",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机速度信息 (来自 /topic/v1/airportDrone/+/realTime/data)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 水平速度 - Double
|
||||||
|
public static final TelemetryKey<Double> HORIZONTAL_SPEED = TelemetryKey.of(
|
||||||
|
"horizontal_speed",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 垂直速度 - Double
|
||||||
|
public static final TelemetryKey<Double> VERTICAL_SPEED = TelemetryKey.of(
|
||||||
|
"vertical_speed",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机电池信息 (来自 /topic/v1/airportDrone/+/realTime/data)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 剩余电量 - Integer
|
||||||
|
public static final TelemetryKey<Integer> BATTERY_REMAIN = TelemetryKey.of(
|
||||||
|
"battery_remain",
|
||||||
|
Integer.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
return Integer.parseInt(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 电压 - Double
|
||||||
|
public static final TelemetryKey<Double> VOLTAGE = TelemetryKey.of(
|
||||||
|
"voltage",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机GPS信息 (来自 /topic/v1/airportDrone/+/realTime/data)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// GPS信号强度 - Integer
|
||||||
|
public static final TelemetryKey<Integer> GPS_SIGNAL = TelemetryKey.of(
|
||||||
|
"gps_signal",
|
||||||
|
Integer.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
return Integer.parseInt(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 卫星数量 - Integer
|
||||||
|
public static final TelemetryKey<Integer> SAT_COUNT = TelemetryKey.of(
|
||||||
|
"sat_count",
|
||||||
|
Integer.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
return Integer.parseInt(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机飞行状态 (来自 /topic/v1/airportDrone/+/realTime/data)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 飞行模式 - String
|
||||||
|
public static final TelemetryKey<String> MODE = TelemetryKey.of(
|
||||||
|
"mode",
|
||||||
|
String.class,
|
||||||
|
value -> value != null ? value.toString() : null
|
||||||
|
);
|
||||||
|
|
||||||
|
// 解锁状态 - String
|
||||||
|
public static final TelemetryKey<String> ARMED = TelemetryKey.of(
|
||||||
|
"armed",
|
||||||
|
String.class,
|
||||||
|
value -> value != null ? value.toString() : null
|
||||||
|
);
|
||||||
|
|
||||||
|
// 飞行时间 - Integer
|
||||||
|
public static final TelemetryKey<Integer> FLIGHT_TIME = TelemetryKey.of(
|
||||||
|
"flight_time",
|
||||||
|
Integer.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
return Integer.parseInt(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 飞行里程 - Double
|
||||||
|
public static final TelemetryKey<Double> MILEAGE = TelemetryKey.of(
|
||||||
|
"mileage",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 距离返航点距离 - Double
|
||||||
|
public static final TelemetryKey<Double> DISTANCE_TO_HOME = TelemetryKey.of(
|
||||||
|
"distance_to_home",
|
||||||
|
Double.class,
|
||||||
|
value -> {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
private TuohengDeviceTelemetry() {
|
||||||
|
// 工具类,禁止实例化
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有预定义的遥测键
|
||||||
|
*
|
||||||
|
* @return 预定义的遥测键列表
|
||||||
|
*/
|
||||||
|
public static List<TelemetryKey<?>> getPredefinedKeys() {
|
||||||
|
return Arrays.asList(
|
||||||
|
// 机场心跳数据
|
||||||
|
STATUS,
|
||||||
|
SEND_TIMESTAMP,
|
||||||
|
// 气象数据
|
||||||
|
WEATHER_RAINFALL,
|
||||||
|
WEATHER_WIND_LEVEL,
|
||||||
|
WEATHER_WIND_DIR,
|
||||||
|
WEATHER_WIND_SPEED,
|
||||||
|
WEATHER_RAIN_FLAG,
|
||||||
|
WEATHER_WIND_ANGLE,
|
||||||
|
// 电池数据
|
||||||
|
BATTERY_LEVEL,
|
||||||
|
BATTERY_HEALTH,
|
||||||
|
BATTERY_TOTAL_VOLTAGE,
|
||||||
|
BATTERY_CELL_TEMP,
|
||||||
|
BATTERY_MOS_TEMP,
|
||||||
|
BATTERY_NUM_CYCLES,
|
||||||
|
BATTERY_DISCHARGE_CURRENT,
|
||||||
|
BATTERY_B_CHARGING,
|
||||||
|
// 舱内传感器数据
|
||||||
|
NEST_INNER_HUM,
|
||||||
|
NEST_INNER_TEMP,
|
||||||
|
// 充电器数据
|
||||||
|
CHARGER_CURRENT,
|
||||||
|
CHARGER_VOLTAGE,
|
||||||
|
CHARGER_CAPACITY,
|
||||||
|
CHARGER_B_CHARGING,
|
||||||
|
// 无人机位置信息
|
||||||
|
LATITUDE,
|
||||||
|
LONGITUDE,
|
||||||
|
ALTITUDE,
|
||||||
|
ALTITUDE_ASL,
|
||||||
|
// 无人机姿态信息
|
||||||
|
ROLL,
|
||||||
|
PITCH,
|
||||||
|
YAW,
|
||||||
|
// 无人机速度信息
|
||||||
|
HORIZONTAL_SPEED,
|
||||||
|
VERTICAL_SPEED,
|
||||||
|
// 无人机电池信息
|
||||||
|
BATTERY_REMAIN,
|
||||||
|
VOLTAGE,
|
||||||
|
// 无人机GPS信息
|
||||||
|
GPS_SIGNAL,
|
||||||
|
SAT_COUNT,
|
||||||
|
// 无人机飞行状态
|
||||||
|
MODE,
|
||||||
|
ARMED,
|
||||||
|
FLIGHT_TIME,
|
||||||
|
MILEAGE,
|
||||||
|
DISTANCE_TO_HOME
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化所有遥测键
|
||||||
|
* 确保所有静态字段被加载和注册
|
||||||
|
*/
|
||||||
|
public static void init() {
|
||||||
|
// 这个方法的存在是为了触发类的静态初始化
|
||||||
|
// 当调用此方法时,所有静态字段都会被初始化
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue