This commit is contained in:
parent
ff22ce08ca
commit
c79c2d4d5b
|
|
@ -6,6 +6,7 @@ import com.ruoyi.device.domain.convert.DeviceConvert;
|
||||||
import com.ruoyi.device.domain.model.Device;
|
import com.ruoyi.device.domain.model.Device;
|
||||||
import com.ruoyi.device.mapper.DeviceMapper;
|
import com.ruoyi.device.mapper.DeviceMapper;
|
||||||
import com.ruoyi.device.mapper.entity.DeviceEntity;
|
import com.ruoyi.device.mapper.entity.DeviceEntity;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.cache.annotation.Caching;
|
import org.springframework.cache.annotation.Caching;
|
||||||
|
|
@ -19,6 +20,7 @@ import java.util.List;
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
* @date 2026-01-16
|
* @date 2026-01-16
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class DeviceDomainImpl implements IDeviceDomain
|
public class DeviceDomainImpl implements IDeviceDomain
|
||||||
{
|
{
|
||||||
|
|
@ -57,8 +59,11 @@ public class DeviceDomainImpl implements IDeviceDomain
|
||||||
@Cacheable(value = DeviceCacheConfig.DEVICE_CACHE, key = "'sn:' + #deviceSn", unless = "#result == null")
|
@Cacheable(value = DeviceCacheConfig.DEVICE_CACHE, key = "'sn:' + #deviceSn", unless = "#result == null")
|
||||||
public Device selectDeviceByDeviceSn(String deviceSn)
|
public Device selectDeviceByDeviceSn(String deviceSn)
|
||||||
{
|
{
|
||||||
|
log.info("查询设备 by device_sn: {}", deviceSn);
|
||||||
DeviceEntity entity = deviceMapper.selectDeviceByDeviceSn(deviceSn);
|
DeviceEntity entity = deviceMapper.selectDeviceByDeviceSn(deviceSn);
|
||||||
return DeviceConvert.from(entity);
|
Device result = DeviceConvert.from(entity);
|
||||||
|
log.info("查询设备结果: device_sn={}, result={}", deviceSn, result != null ? result.getDeviceId() : "null");
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,9 @@ public class DjiService {
|
||||||
boolean isStateMessage = "state".equalsIgnoreCase(droneData.getMessageType());
|
boolean isStateMessage = "state".equalsIgnoreCase(droneData.getMessageType());
|
||||||
|
|
||||||
// 更新 Dock 表的 lastActiveTime
|
// 更新 Dock 表的 lastActiveTime
|
||||||
|
log.info("准备查询设备: device_sn={}", droneData.getDeviceSn());
|
||||||
Device device = deviceDomain.selectDeviceByDeviceSn(droneData.getDeviceSn());
|
Device device = deviceDomain.selectDeviceByDeviceSn(droneData.getDeviceSn());
|
||||||
|
log.info("查询设备成功: device_sn={}, deviceId={}", droneData.getDeviceSn(), device != null ? device.getDeviceId() : null);
|
||||||
if(Objects.nonNull(device)) {
|
if(Objects.nonNull(device)) {
|
||||||
Aircraft aircraft = aircraftDomain.selectAircraftByDeviceId(device.getDeviceId());
|
Aircraft aircraft = aircraftDomain.selectAircraftByDeviceId(device.getDeviceId());
|
||||||
if(Objects.nonNull(aircraft)) {
|
if(Objects.nonNull(aircraft)) {
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,14 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
|
@ -67,6 +69,9 @@ public class SynService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IDockGroupDomain dockGroupDomain;
|
private IDockGroupDomain dockGroupDomain;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private StringRedisTemplate redisTemplate;
|
||||||
|
|
||||||
public SynService(IThingsBoardDomain iThingsBoardDomain) {
|
public SynService(IThingsBoardDomain iThingsBoardDomain) {
|
||||||
this.iThingsBoardDomain = iThingsBoardDomain;
|
this.iThingsBoardDomain = iThingsBoardDomain;
|
||||||
}
|
}
|
||||||
|
|
@ -127,7 +132,49 @@ public class SynService {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分布式锁
|
||||||
|
*
|
||||||
|
* @param lockKey 锁的key
|
||||||
|
* @param lockValue 锁的value(用于释放锁时验证)
|
||||||
|
* @param expireTime 锁的过期时间(秒)
|
||||||
|
* @return true表示获取锁成功,false表示获取锁失败
|
||||||
|
*/
|
||||||
|
private boolean tryLock(String lockKey, String lockValue, long expireTime) {
|
||||||
|
if (redisTemplate == null) {
|
||||||
|
log.warn("Redis未配置,跳过分布式锁,使用本地同步");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, expireTime, TimeUnit.SECONDS);
|
||||||
|
return Boolean.TRUE.equals(result);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取分布式锁失败: lockKey={}, error={}", lockKey, e.getMessage(), e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 释放分布式锁
|
||||||
|
*
|
||||||
|
* @param lockKey 锁的key
|
||||||
|
* @param lockValue 锁的value(用于验证是否是自己持有的锁)
|
||||||
|
*/
|
||||||
|
private void releaseLock(String lockKey, String lockValue) {
|
||||||
|
if (redisTemplate == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
String currentValue = redisTemplate.opsForValue().get(lockKey);
|
||||||
|
if (lockValue.equals(currentValue)) {
|
||||||
|
redisTemplate.delete(lockKey);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("释放分布式锁失败: lockKey={}, error={}", lockKey, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定时任务:同步基础表数据
|
* 定时任务:同步基础表数据
|
||||||
|
|
@ -335,11 +382,53 @@ public class SynService {
|
||||||
log.info("开始同步设备: iotDeviceId={}, deviceName={}, deviceType={}, gatewayId={}",
|
log.info("开始同步设备: iotDeviceId={}, deviceName={}, deviceType={}, gatewayId={}",
|
||||||
iotDeviceId, deviceName, deviceType, gatewayId);
|
iotDeviceId, deviceName, deviceType, gatewayId);
|
||||||
|
|
||||||
// 查询设备是否已存在
|
// 查询设备是否已存在(通过 iotDeviceId)
|
||||||
Device existingDevice = deviceDomain.selectDeviceByIotDeviceId(iotDeviceId);
|
Device existingDevice = deviceDomain.selectDeviceByIotDeviceId(iotDeviceId);
|
||||||
|
|
||||||
|
// 如果通过 iotDeviceId 未找到,再检查 device_sn 是否已存在
|
||||||
if (existingDevice == null) {
|
if (existingDevice == null) {
|
||||||
// 设备不存在,插入新设备
|
Device existingDeviceBySn = deviceDomain.selectDeviceByDeviceSn(deviceSn);
|
||||||
|
if (existingDeviceBySn != null) {
|
||||||
|
log.warn("设备SN已存在但iotDeviceId不同: deviceSn={}, existingIotDeviceId={}, newIotDeviceId={}",
|
||||||
|
deviceSn, existingDeviceBySn.getIotDeviceId(), iotDeviceId);
|
||||||
|
// 返回已存在的设备ID,避免重复插入
|
||||||
|
return existingDeviceBySn.getDeviceId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingDevice == null) {
|
||||||
|
// 设备不存在,使用分布式锁防止并发插入
|
||||||
|
String lockKey = "device:sync:lock:" + deviceSn;
|
||||||
|
String lockValue = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
// 尝试获取锁,最多等待3秒
|
||||||
|
boolean locked = tryLock(lockKey, lockValue, 10);
|
||||||
|
if (!locked) {
|
||||||
|
log.warn("获取设备同步锁失败,可能有其他线程正在同步该设备: deviceSn={}", deviceSn);
|
||||||
|
// 等待一小段时间后重新查询,可能已经被其他线程插入
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
Device retryDevice = deviceDomain.selectDeviceByDeviceSn(deviceSn);
|
||||||
|
if (retryDevice != null) {
|
||||||
|
log.info("重新查询到设备: deviceSn={}, deviceId={}", deviceSn, retryDevice.getDeviceId());
|
||||||
|
return retryDevice.getDeviceId();
|
||||||
|
}
|
||||||
|
log.error("获取锁失败且重新查询也未找到设备: deviceSn={}", deviceSn);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 双重检查:获取锁后再次查询,防止重复插入
|
||||||
|
Device doubleCheckDevice = deviceDomain.selectDeviceByDeviceSn(deviceSn);
|
||||||
|
if (doubleCheckDevice != null) {
|
||||||
|
log.info("双重检查发现设备已存在: deviceSn={}, deviceId={}", deviceSn, doubleCheckDevice.getDeviceId());
|
||||||
|
return doubleCheckDevice.getDeviceId();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 插入新设备
|
||||||
Device newDevice = new Device();
|
Device newDevice = new Device();
|
||||||
newDevice.setDeviceName(deviceName);
|
newDevice.setDeviceName(deviceName);
|
||||||
newDevice.setIotDeviceId(iotDeviceId);
|
newDevice.setIotDeviceId(iotDeviceId);
|
||||||
|
|
@ -360,6 +449,10 @@ public class SynService {
|
||||||
log.info("插入新设备成功: iotDeviceId={}, deviceName={}, deviceType={}, 返回deviceId={}",
|
log.info("插入新设备成功: iotDeviceId={}, deviceName={}, deviceType={}, 返回deviceId={}",
|
||||||
iotDeviceId, deviceName, deviceType, deviceId);
|
iotDeviceId, deviceName, deviceType, deviceId);
|
||||||
return deviceId;
|
return deviceId;
|
||||||
|
} finally {
|
||||||
|
// 释放锁
|
||||||
|
releaseLock(lockKey, lockValue);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 设备已存在,检查是否需要更新
|
// 设备已存在,检查是否需要更新
|
||||||
boolean needUpdate = false;
|
boolean needUpdate = false;
|
||||||
|
|
@ -776,8 +869,50 @@ public class SynService {
|
||||||
List<Device> existingDevices = deviceDomain.selectDeviceList(queryDevice);
|
List<Device> existingDevices = deviceDomain.selectDeviceList(queryDevice);
|
||||||
Device existingDevice = (existingDevices != null && !existingDevices.isEmpty()) ? existingDevices.get(0) : null;
|
Device existingDevice = (existingDevices != null && !existingDevices.isEmpty()) ? existingDevices.get(0) : null;
|
||||||
|
|
||||||
|
// 如果通过 iotDeviceId + deviceType 未找到,再检查 device_sn 是否已存在
|
||||||
if (existingDevice == null) {
|
if (existingDevice == null) {
|
||||||
// 设备不存在,插入新设备
|
Device existingDeviceBySn = deviceDomain.selectDeviceByDeviceSn(deviceSn);
|
||||||
|
if (existingDeviceBySn != null) {
|
||||||
|
log.warn("拓恒设备SN已存在但iotDeviceId或deviceType不同: deviceSn={}, existingIotDeviceId={}, existingDeviceType={}, newIotDeviceId={}, newDeviceType={}",
|
||||||
|
deviceSn, existingDeviceBySn.getIotDeviceId(), existingDeviceBySn.getDeviceType(), iotDeviceId, deviceType.getCode());
|
||||||
|
// 返回已存在的设备ID,避免重复插入
|
||||||
|
return existingDeviceBySn.getDeviceId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingDevice == null) {
|
||||||
|
// 设备不存在,使用分布式锁防止并发插入
|
||||||
|
String lockKey = "device:sync:lock:" + deviceSn;
|
||||||
|
String lockValue = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
// 尝试获取锁
|
||||||
|
boolean locked = tryLock(lockKey, lockValue, 10);
|
||||||
|
if (!locked) {
|
||||||
|
log.warn("获取拓恒设备同步锁失败,可能有其他线程正在同步该设备: deviceSn={}", deviceSn);
|
||||||
|
// 等待后重新查询
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
Device retryDevice = deviceDomain.selectDeviceByDeviceSn(deviceSn);
|
||||||
|
if (retryDevice != null) {
|
||||||
|
log.info("重新查询到拓恒设备: deviceSn={}, deviceId={}", deviceSn, retryDevice.getDeviceId());
|
||||||
|
return retryDevice.getDeviceId();
|
||||||
|
}
|
||||||
|
log.error("获取锁失败且重新查询也未找到拓恒设备: deviceSn={}", deviceSn);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 双重检查
|
||||||
|
Device doubleCheckDevice = deviceDomain.selectDeviceByDeviceSn(deviceSn);
|
||||||
|
if (doubleCheckDevice != null) {
|
||||||
|
log.info("双重检查发现拓恒设备已存在: deviceSn={}, deviceId={}", deviceSn, doubleCheckDevice.getDeviceId());
|
||||||
|
return doubleCheckDevice.getDeviceId();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 插入新设备
|
||||||
Device newDevice = new Device();
|
Device newDevice = new Device();
|
||||||
newDevice.setDeviceName(deviceName);
|
newDevice.setDeviceName(deviceName);
|
||||||
newDevice.setIotDeviceId(iotDeviceId);
|
newDevice.setIotDeviceId(iotDeviceId);
|
||||||
|
|
@ -795,6 +930,10 @@ public class SynService {
|
||||||
log.info("插入新拓恒设备成功: iotDeviceId={}, deviceName={}, deviceType={}, deviceSn={}, 返回deviceId={}",
|
log.info("插入新拓恒设备成功: iotDeviceId={}, deviceName={}, deviceType={}, deviceSn={}, 返回deviceId={}",
|
||||||
iotDeviceId, deviceName, deviceType, deviceSn, deviceId);
|
iotDeviceId, deviceName, deviceType, deviceSn, deviceId);
|
||||||
return deviceId;
|
return deviceId;
|
||||||
|
} finally {
|
||||||
|
// 释放锁
|
||||||
|
releaseLock(lockKey, lockValue);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 设备已存在,检查是否需要更新
|
// 设备已存在,检查是否需要更新
|
||||||
boolean needUpdate = false;
|
boolean needUpdate = false;
|
||||||
|
|
|
||||||
|
|
@ -194,47 +194,83 @@ public class TuohengBufferDeviceImpl implements IBufferDeviceService {
|
||||||
*/
|
*/
|
||||||
private void fillTuohengDockDetail(DockDetailDTO dto, String iotDeviceId) {
|
private void fillTuohengDockDetail(DockDetailDTO dto, String iotDeviceId) {
|
||||||
try {
|
try {
|
||||||
|
log.info("========== 开始填充拓恒机场详情 ==========");
|
||||||
|
log.info("iotDeviceId: {}", iotDeviceId);
|
||||||
|
|
||||||
// 获取拓恒设备属性
|
// 获取拓恒设备属性
|
||||||
AttributeMap attributes = thingsBoardDomain.getPredefinedTuohengDeviceAttributes(iotDeviceId);
|
AttributeMap attributes = thingsBoardDomain.getPredefinedTuohengDeviceAttributes(iotDeviceId);
|
||||||
|
log.info("拓恒设备属性数据: {}", attributes);
|
||||||
|
|
||||||
// 获取拓恒设备遥测数据
|
// 获取拓恒设备遥测数据
|
||||||
TelemetryMap telemetry = thingsBoardDomain.getPredefinedTuohengDeviceTelemetry(iotDeviceId);
|
TelemetryMap telemetry = thingsBoardDomain.getPredefinedTuohengDeviceTelemetry(iotDeviceId);
|
||||||
|
log.info("拓恒设备遥测数据: {}", telemetry);
|
||||||
|
|
||||||
// 设置在线状态
|
// 设置在线状态
|
||||||
Boolean isActive = attributes.get(TuohengDeviceAttributes.ACTIVE).orElse(false);
|
Boolean isActive = attributes.get(TuohengDeviceAttributes.ACTIVE).orElse(false);
|
||||||
|
log.info("设备在线状态 ACTIVE: {}", isActive);
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
telemetry.get(TuohengDeviceTelemetry.STATUS).ifPresent(statusValue -> {
|
telemetry.get(TuohengDeviceTelemetry.STATUS).ifPresent(statusValue -> {
|
||||||
String status = statusValue.getValue();
|
String status = statusValue.getValue();
|
||||||
dto.setDockStatus("online".equals(status) ? "IDLE" : "OFFLINE");
|
log.info("STATUS 遥测值: {}", status);
|
||||||
|
String dockStatus = "online".equals(status) ? "IDLE" : "OFFLINE";
|
||||||
|
dto.setDockStatus(dockStatus);
|
||||||
|
log.info("设置机场状态: {}", dockStatus);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
dto.setDockStatus("OFFLINE");
|
dto.setDockStatus("OFFLINE");
|
||||||
|
log.info("设备离线,设置机场状态为 OFFLINE");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置舱内温度和湿度
|
// 设置舱内温度和湿度
|
||||||
|
log.info("---------- 解析舱内环境数据 ----------");
|
||||||
telemetry.get(TuohengDeviceTelemetry.NEST_INNER_TEMP)
|
telemetry.get(TuohengDeviceTelemetry.NEST_INNER_TEMP)
|
||||||
.ifPresent(value -> dto.setCabinTemperature(value.getValue()));
|
.ifPresent(value -> {
|
||||||
|
log.info("NEST_INNER_TEMP 舱内温度: {}", value.getValue());
|
||||||
|
dto.setCabinTemperature(value.getValue());
|
||||||
|
});
|
||||||
telemetry.get(TuohengDeviceTelemetry.NEST_INNER_HUM)
|
telemetry.get(TuohengDeviceTelemetry.NEST_INNER_HUM)
|
||||||
.ifPresent(value -> dto.setCabinHumidity(value.getValue()));
|
.ifPresent(value -> {
|
||||||
|
log.info("NEST_INNER_HUM 舱内湿度: {}", value.getValue());
|
||||||
|
dto.setCabinHumidity(value.getValue());
|
||||||
|
});
|
||||||
|
|
||||||
// 设置环境数据
|
// 设置环境数据
|
||||||
|
log.info("---------- 解析气象数据 ----------");
|
||||||
telemetry.get(TuohengDeviceTelemetry.NEST_INNER_TEMP)
|
telemetry.get(TuohengDeviceTelemetry.NEST_INNER_TEMP)
|
||||||
.ifPresent(value -> dto.setEnvironmentTemperature(value.getValue()));
|
.ifPresent(value -> {
|
||||||
|
log.info("环境温度(使用舱内温度): {}", value.getValue());
|
||||||
|
dto.setEnvironmentTemperature(value.getValue());
|
||||||
|
});
|
||||||
telemetry.get(TuohengDeviceTelemetry.WEATHER_WIND_SPEED)
|
telemetry.get(TuohengDeviceTelemetry.WEATHER_WIND_SPEED)
|
||||||
.ifPresent(value -> dto.setWindSpeed(value.getValue()));
|
.ifPresent(value -> {
|
||||||
|
log.info("WEATHER_WIND_SPEED 风速: {}", value.getValue());
|
||||||
|
dto.setWindSpeed(value.getValue());
|
||||||
|
});
|
||||||
telemetry.get(TuohengDeviceTelemetry.WEATHER_RAINFALL)
|
telemetry.get(TuohengDeviceTelemetry.WEATHER_RAINFALL)
|
||||||
.ifPresent(value -> dto.setRainfall(value.getValue()));
|
.ifPresent(value -> {
|
||||||
|
log.info("WEATHER_RAINFALL 降雨量: {}", value.getValue());
|
||||||
|
dto.setRainfall(value.getValue());
|
||||||
|
});
|
||||||
|
|
||||||
// 设置电池信息
|
// 设置电池信息
|
||||||
|
log.info("---------- 解析电池数据 ----------");
|
||||||
telemetry.get(TuohengDeviceTelemetry.BATTERY_LEVEL)
|
telemetry.get(TuohengDeviceTelemetry.BATTERY_LEVEL)
|
||||||
.ifPresent(value -> dto.setCapacity_percent(value.getValue()));
|
.ifPresent(value -> {
|
||||||
|
log.info("BATTERY_LEVEL 电池电量: {}", value.getValue());
|
||||||
|
dto.setCapacity_percent(value.getValue());
|
||||||
|
});
|
||||||
|
|
||||||
// 设置充电状态
|
// 设置充电状态
|
||||||
telemetry.get(TuohengDeviceTelemetry.BATTERY_B_CHARGING)
|
telemetry.get(TuohengDeviceTelemetry.BATTERY_B_CHARGING)
|
||||||
.ifPresent(value -> {
|
.ifPresent(value -> {
|
||||||
dto.setChargingStatus(value.getValue() == 1 ? "CHARGING" : "FREE");
|
log.info("BATTERY_B_CHARGING 充电状态原始值: {}", value.getValue());
|
||||||
|
String chargingStatus = value.getValue() == 1 ? "CHARGING" : "FREE";
|
||||||
|
dto.setChargingStatus(chargingStatus);
|
||||||
|
log.info("设置充电状态: {}", chargingStatus);
|
||||||
});
|
});
|
||||||
|
|
||||||
log.debug("拓恒机场详情填充完成: iotDeviceId={}", iotDeviceId);
|
log.info("拓恒机场详情填充完成: iotDeviceId={}, dockStatus={}", iotDeviceId, dto.getDockStatus());
|
||||||
|
log.info("========== 拓恒机场详情填充结束 ==========");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("填充拓恒机场详情失败: iotDeviceId={}, error={}", iotDeviceId, e.getMessage(), e);
|
log.error("填充拓恒机场详情失败: iotDeviceId={}, error={}", iotDeviceId, e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
@ -248,23 +284,33 @@ public class TuohengBufferDeviceImpl implements IBufferDeviceService {
|
||||||
*/
|
*/
|
||||||
private void fillTuohengAircraftStatus(DockDetailDTO dto, String aircraftIotDeviceId) {
|
private void fillTuohengAircraftStatus(DockDetailDTO dto, String aircraftIotDeviceId) {
|
||||||
try {
|
try {
|
||||||
|
log.info("========== 开始填充拓恒无人机状态(机场详情中) ==========");
|
||||||
|
log.info("aircraftIotDeviceId: {}", aircraftIotDeviceId);
|
||||||
|
|
||||||
// 获取拓恒无人机遥测数据
|
// 获取拓恒无人机遥测数据
|
||||||
TelemetryMap telemetry = thingsBoardDomain.getPredefinedTuohengDeviceTelemetry(aircraftIotDeviceId);
|
TelemetryMap telemetry = thingsBoardDomain.getPredefinedTuohengDeviceTelemetry(aircraftIotDeviceId);
|
||||||
|
log.info("拓恒无人机遥测数据: {}", telemetry);
|
||||||
|
|
||||||
// 设置无人机状态 - 根据 armed 状态判断
|
// 设置无人机状态 - 根据 armed 状态判断
|
||||||
telemetry.get(TuohengDeviceTelemetry.ARMED).ifPresent(armedValue -> {
|
telemetry.get(TuohengDeviceTelemetry.ARMED).ifPresent(armedValue -> {
|
||||||
String armed = armedValue.getValue();
|
String armed = armedValue.getValue();
|
||||||
|
log.info("ARMED 解锁状态原始值: {}", armed);
|
||||||
if ("true".equals(armed) || "1".equals(armed)) {
|
if ("true".equals(armed) || "1".equals(armed)) {
|
||||||
dto.setAircraftStatus("IN_MISSION"); // 解锁状态表示在任务中
|
dto.setAircraftStatus("IN_MISSION"); // 解锁状态表示在任务中
|
||||||
|
log.info("设置无人机状态: IN_MISSION (任务中)");
|
||||||
} else {
|
} else {
|
||||||
dto.setAircraftStatus("POWER_ON_IN_CABIN"); // 未解锁表示在舱内待机
|
dto.setAircraftStatus("POWER_ON_IN_CABIN"); // 未解锁表示在舱内待机
|
||||||
|
log.info("设置无人机状态: POWER_ON_IN_CABIN (舱内待机)");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 设置作业架次 - 暂时设置为0,拓恒设备可能没有这个数据
|
// 设置作业架次 - 暂时设置为0,拓恒设备可能没有这个数据
|
||||||
dto.setMissionCount(0);
|
dto.setMissionCount(0);
|
||||||
|
log.info("设置作业架次: 0 (拓恒设备暂无此数据)");
|
||||||
|
|
||||||
log.debug("拓恒无人机状态填充完成: aircraftIotDeviceId={}", aircraftIotDeviceId);
|
log.info("拓恒无人机状态填充完成: aircraftIotDeviceId={}, aircraftStatus={}",
|
||||||
|
aircraftIotDeviceId, dto.getAircraftStatus());
|
||||||
|
log.info("========== 拓恒无人机状态填充结束 ==========");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("填充拓恒无人机状态失败: aircraftIotDeviceId={}, error={}",
|
log.error("填充拓恒无人机状态失败: aircraftIotDeviceId={}, error={}",
|
||||||
aircraftIotDeviceId, e.getMessage(), e);
|
aircraftIotDeviceId, e.getMessage(), e);
|
||||||
|
|
@ -279,45 +325,71 @@ public class TuohengBufferDeviceImpl implements IBufferDeviceService {
|
||||||
*/
|
*/
|
||||||
private void fillTuohengAircraftDetail(AircraftDetailDTO dto, String iotDeviceId) {
|
private void fillTuohengAircraftDetail(AircraftDetailDTO dto, String iotDeviceId) {
|
||||||
try {
|
try {
|
||||||
|
log.info("========== 开始填充拓恒无人机详情 ==========");
|
||||||
|
log.info("iotDeviceId: {}", iotDeviceId);
|
||||||
|
|
||||||
// 获取拓恒设备属性
|
// 获取拓恒设备属性
|
||||||
AttributeMap attributes = thingsBoardDomain.getPredefinedTuohengDeviceAttributes(iotDeviceId);
|
AttributeMap attributes = thingsBoardDomain.getPredefinedTuohengDeviceAttributes(iotDeviceId);
|
||||||
|
log.info("拓恒无人机属性数据: {}", attributes);
|
||||||
|
|
||||||
// 获取拓恒设备遥测数据
|
// 获取拓恒设备遥测数据
|
||||||
TelemetryMap telemetry = thingsBoardDomain.getPredefinedTuohengDeviceTelemetry(iotDeviceId);
|
TelemetryMap telemetry = thingsBoardDomain.getPredefinedTuohengDeviceTelemetry(iotDeviceId);
|
||||||
|
log.info("拓恒无人机遥测数据: {}", telemetry);
|
||||||
|
|
||||||
// 设置无人机状态
|
// 设置无人机状态
|
||||||
|
log.info("---------- 解析无人机状态 ----------");
|
||||||
telemetry.get(TuohengDeviceTelemetry.ARMED).ifPresent(armedValue -> {
|
telemetry.get(TuohengDeviceTelemetry.ARMED).ifPresent(armedValue -> {
|
||||||
String armed = armedValue.getValue();
|
String armed = armedValue.getValue();
|
||||||
|
log.info("ARMED 解锁状态: {}", armed);
|
||||||
if ("true".equals(armed) || "1".equals(armed)) {
|
if ("true".equals(armed) || "1".equals(armed)) {
|
||||||
dto.setAircraftStatus("IN_MISSION");
|
dto.setAircraftStatus("IN_MISSION");
|
||||||
|
log.info("设置无人机状态: IN_MISSION");
|
||||||
} else {
|
} else {
|
||||||
dto.setAircraftStatus("POWER_ON_IN_CABIN");
|
dto.setAircraftStatus("POWER_ON_IN_CABIN");
|
||||||
|
log.info("设置无人机状态: POWER_ON_IN_CABIN");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 设置作业架次 - 暂时设置为0
|
// 设置作业架次 - 暂时设置为0
|
||||||
dto.setMissionCount(0);
|
dto.setMissionCount(0);
|
||||||
|
log.info("设置作业架次: 0");
|
||||||
|
|
||||||
// 设置GPS信号
|
// 设置GPS信号
|
||||||
|
log.info("---------- 解析GPS数据 ----------");
|
||||||
telemetry.get(TuohengDeviceTelemetry.SAT_COUNT)
|
telemetry.get(TuohengDeviceTelemetry.SAT_COUNT)
|
||||||
.ifPresent(value -> dto.setGpsSignal(value.getValue()));
|
.ifPresent(value -> {
|
||||||
|
log.info("SAT_COUNT 卫星数量: {}", value.getValue());
|
||||||
|
dto.setGpsSignal(value.getValue());
|
||||||
|
});
|
||||||
|
|
||||||
// 设置电池信息
|
// 设置电池信息
|
||||||
|
log.info("---------- 解析电池数据 ----------");
|
||||||
telemetry.get(TuohengDeviceTelemetry.BATTERY_REMAIN)
|
telemetry.get(TuohengDeviceTelemetry.BATTERY_REMAIN)
|
||||||
.ifPresent(value -> dto.setBatteryLevel(value.getValue()));
|
.ifPresent(value -> {
|
||||||
|
log.info("BATTERY_REMAIN 剩余电量: {}", value.getValue());
|
||||||
|
dto.setBatteryLevel(value.getValue());
|
||||||
|
});
|
||||||
|
|
||||||
telemetry.get(TuohengDeviceTelemetry.VOLTAGE)
|
telemetry.get(TuohengDeviceTelemetry.VOLTAGE)
|
||||||
.ifPresent(value -> {
|
.ifPresent(value -> {
|
||||||
|
log.info("VOLTAGE 电压原始值: {}", value.getValue());
|
||||||
Double voltage = value.getValue();
|
Double voltage = value.getValue();
|
||||||
if (voltage != null) {
|
if (voltage != null) {
|
||||||
dto.setVoltage(voltage.intValue());
|
dto.setVoltage(voltage.intValue());
|
||||||
|
log.info("VOLTAGE 电压转换后: {}", voltage.intValue());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 设置飞行时长(秒)
|
// 设置飞行时长(秒)
|
||||||
|
log.info("---------- 解析飞行数据 ----------");
|
||||||
telemetry.get(TuohengDeviceTelemetry.FLIGHT_TIME)
|
telemetry.get(TuohengDeviceTelemetry.FLIGHT_TIME)
|
||||||
.ifPresent(value -> dto.setFlightDuration(value.getValue()));
|
.ifPresent(value -> {
|
||||||
|
log.info("FLIGHT_TIME 飞行时长(秒): {}", value.getValue());
|
||||||
|
dto.setFlightDuration(value.getValue());
|
||||||
|
});
|
||||||
|
|
||||||
log.debug("拓恒无人机详情填充完成: iotDeviceId={}", iotDeviceId);
|
log.info("拓恒无人机详情填充完成: iotDeviceId={}, aircraftStatus={}", iotDeviceId, dto.getAircraftStatus());
|
||||||
|
log.info("========== 拓恒无人机详情填充结束 ==========");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("填充拓恒无人机详情失败: iotDeviceId={}, error={}", iotDeviceId, e.getMessage(), e);
|
log.error("填充拓恒无人机详情失败: iotDeviceId={}, error={}", iotDeviceId, e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<select id="selectDeviceByDeviceSn" parameterType="String" resultMap="DeviceResult">
|
<select id="selectDeviceByDeviceSn" parameterType="String" resultMap="DeviceResult">
|
||||||
<include refid="selectDeviceVo"/>
|
<include refid="selectDeviceVo"/>
|
||||||
where device_sn = #{deviceSn}
|
where device_sn = #{deviceSn}
|
||||||
|
order by create_time desc
|
||||||
|
limit 1
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectDeviceList" parameterType="com.ruoyi.device.mapper.entity.DeviceEntity" resultMap="DeviceResult">
|
<select id="selectDeviceList" parameterType="com.ruoyi.device.mapper.entity.DeviceEntity" resultMap="DeviceResult">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue