2026-02-10 10:51:42 +08:00
|
|
|
package com.ruoyi.device.service.impl;
|
|
|
|
|
|
2026-02-10 12:26:52 +08:00
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
2026-02-10 10:51:42 +08:00
|
|
|
import com.ruoyi.device.domain.api.IDockAircraftDomain;
|
|
|
|
|
import com.ruoyi.device.domain.api.IDockDomain;
|
|
|
|
|
import com.ruoyi.device.domain.api.IAircraftDomain;
|
|
|
|
|
import com.ruoyi.device.domain.api.IDeviceDomain;
|
2026-02-10 12:26:52 +08:00
|
|
|
import com.ruoyi.device.domain.impl.tuohengmqtt.callback.ITuohengEventsCallback;
|
|
|
|
|
import com.ruoyi.device.domain.impl.tuohengmqtt.callback.ITuohengOsdCallback;
|
|
|
|
|
import com.ruoyi.device.domain.impl.tuohengmqtt.callback.ITuohengRealTimeDataCallback;
|
2026-02-10 10:51:42 +08:00
|
|
|
import com.ruoyi.device.domain.impl.tuohengmqtt.config.TuohengMqttClientConfig;
|
|
|
|
|
import com.ruoyi.device.domain.impl.tuohengmqtt.handler.TuohengMqttMessageHandler;
|
|
|
|
|
import com.ruoyi.device.domain.impl.tuohengmqtt.manager.TuohengMqttClientManager;
|
|
|
|
|
import com.ruoyi.device.domain.impl.tuohengmqtt.model.AirportOsdData;
|
|
|
|
|
import com.ruoyi.device.domain.impl.tuohengmqtt.model.EventsData;
|
2026-02-10 12:26:52 +08:00
|
|
|
import com.ruoyi.device.domain.impl.tuohengmqtt.model.TuohengRealTimeData;
|
2026-02-10 10:51:42 +08:00
|
|
|
import com.ruoyi.device.domain.model.Aircraft;
|
|
|
|
|
import com.ruoyi.device.domain.model.Device;
|
|
|
|
|
import com.ruoyi.device.domain.model.Dock;
|
2026-02-10 12:26:52 +08:00
|
|
|
import com.ruoyi.device.domain.model.DockAircraft;
|
2026-02-10 10:51:42 +08:00
|
|
|
import com.ruoyi.device.service.config.TuohengMqttProperties;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
|
|
|
|
import org.springframework.context.event.EventListener;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
@Service
|
|
|
|
|
@Slf4j
|
|
|
|
|
public class TuohengService {
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private TuohengMqttClientManager clientManager;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private TuohengMqttProperties mqttProperties;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private IDockAircraftDomain dockAircraftDomain;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private IDockDomain dockDomain;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private IAircraftDomain aircraftDomain;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private IDeviceDomain deviceDomain;
|
|
|
|
|
|
|
|
|
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
|
|
|
|
|
@EventListener(ApplicationReadyEvent.class)
|
|
|
|
|
public void onApplicationReady() {
|
|
|
|
|
TuohengMqttClientConfig config = TuohengMqttClientConfig.builder()
|
|
|
|
|
.host(mqttProperties.getHost())
|
|
|
|
|
.port(mqttProperties.getPort())
|
|
|
|
|
.clientId(mqttProperties.getClientId())
|
|
|
|
|
.username(mqttProperties.getUsername())
|
|
|
|
|
.password(mqttProperties.getPassword())
|
|
|
|
|
.connectionTimeout(mqttProperties.getConnectionTimeout())
|
|
|
|
|
.keepAliveInterval(mqttProperties.getKeepAliveInterval())
|
|
|
|
|
.autoReconnect(mqttProperties.getAutoReconnect())
|
|
|
|
|
.cleanSession(mqttProperties.getCleanSession())
|
|
|
|
|
.useSharedSubscription(true)
|
|
|
|
|
.sharedGroupName("tuoheng-group")
|
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
clientManager.initClient(config);
|
|
|
|
|
|
|
|
|
|
TuohengMqttMessageHandler handler = clientManager.getHandler();
|
|
|
|
|
|
|
|
|
|
Map<String, String> mapping = loadAirportDroneMapping();
|
|
|
|
|
|
2026-02-10 12:26:52 +08:00
|
|
|
handler.registerRealTimeDataCallback(new ITuohengRealTimeDataCallback() {
|
2026-02-10 10:51:42 +08:00
|
|
|
@Override
|
2026-02-10 12:26:52 +08:00
|
|
|
public void onRealTimeData(String deviceSn, TuohengRealTimeData data) {
|
|
|
|
|
log.info("========== 收到拓恒实时数据 ==========");
|
|
|
|
|
log.info("设备SN: {}", deviceSn);
|
2026-02-10 10:51:42 +08:00
|
|
|
try {
|
|
|
|
|
log.info("数据内容: {}", objectMapper.writeValueAsString(data));
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("序列化数据失败", e);
|
|
|
|
|
}
|
|
|
|
|
log.info("=====================================");
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2026-02-10 12:26:52 +08:00
|
|
|
handler.registerOsdCallback(new ITuohengOsdCallback() {
|
2026-02-10 10:51:42 +08:00
|
|
|
@Override
|
2026-02-10 12:26:52 +08:00
|
|
|
public void onOsdData(String deviceSn, AirportOsdData data) {
|
|
|
|
|
log.info("========== 收到拓恒OSD数据 ==========");
|
|
|
|
|
log.info("设备SN: {}", deviceSn);
|
2026-02-10 10:51:42 +08:00
|
|
|
try {
|
|
|
|
|
log.info("数据内容: {}", objectMapper.writeValueAsString(data));
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("序列化数据失败", e);
|
|
|
|
|
}
|
|
|
|
|
log.info("=====================================");
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2026-02-10 12:26:52 +08:00
|
|
|
handler.registerEventsCallback(new ITuohengEventsCallback() {
|
2026-02-10 10:51:42 +08:00
|
|
|
@Override
|
2026-02-10 12:26:52 +08:00
|
|
|
public void onEventsData(String deviceSn, EventsData data) {
|
|
|
|
|
log.info("========== 收到拓恒Events数据 ==========");
|
|
|
|
|
log.info("设备SN: {}", deviceSn);
|
2026-02-10 10:51:42 +08:00
|
|
|
try {
|
|
|
|
|
log.info("数据内容: {}", objectMapper.writeValueAsString(data));
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("序列化数据失败", e);
|
|
|
|
|
}
|
|
|
|
|
log.info("=====================================");
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
log.info("TuohengService 初始化完成,已注册所有回调");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Map<String, String> loadAirportDroneMapping() {
|
|
|
|
|
Map<String, String> mapping = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
List<DockAircraft> dockAircraftList = dockAircraftDomain.selectDockAircraftList(new DockAircraft());
|
|
|
|
|
|
|
|
|
|
for (DockAircraft dockAircraft : dockAircraftList) {
|
|
|
|
|
Dock dock = dockDomain.selectDockByDockId(dockAircraft.getDockId());
|
|
|
|
|
Aircraft aircraft = aircraftDomain.selectAircraftByAircraftId(dockAircraft.getAircraftId());
|
|
|
|
|
|
|
|
|
|
if (dock != null && aircraft != null) {
|
|
|
|
|
Device dockDevice = deviceDomain.selectDeviceByDeviceId(dock.getDeviceId());
|
|
|
|
|
Device aircraftDevice = deviceDomain.selectDeviceByDeviceId(aircraft.getDeviceId());
|
|
|
|
|
|
|
|
|
|
if (dockDevice != null && aircraftDevice != null) {
|
|
|
|
|
String airportSn = dockDevice.getDeviceSn();
|
|
|
|
|
String droneSn = aircraftDevice.getDeviceSn();
|
2026-02-10 10:54:54 +08:00
|
|
|
|
2026-02-10 10:51:42 +08:00
|
|
|
if (airportSn != null && droneSn != null) {
|
2026-02-10 10:54:54 +08:00
|
|
|
if (airportSn.startsWith("THJS") || droneSn.startsWith("THJS")) {
|
|
|
|
|
log.debug("跳过大疆设备 - 机场SN: {}, 无人机SN: {}", airportSn, droneSn);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2026-02-10 10:51:42 +08:00
|
|
|
mapping.put(airportSn, droneSn);
|
|
|
|
|
log.info("加载机场-无人机映射: {} -> {}", airportSn, droneSn);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
log.info("从数据库加载机场-无人机映射完成,共 {} 条记录", mapping.size());
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("从数据库加载机场-无人机映射失败", e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mapping;
|
|
|
|
|
}
|
|
|
|
|
}
|