a-tuoheng-device/src/main/java/com/ruoyi/device/service/impl/DjiService.java

191 lines
9.1 KiB
Java

package com.ruoyi.device.service.impl;
import com.ruoyi.device.domain.api.IAircraftDomain;
import com.ruoyi.device.domain.api.IDeviceDomain;
import com.ruoyi.device.domain.api.IDockAircraftDomain;
import com.ruoyi.device.domain.api.IDockDomain;
import com.ruoyi.device.domain.api.IThingsBoardDomain;
import com.ruoyi.device.domain.impl.DockDomainImpl;
import com.ruoyi.device.domain.impl.djimqtt.callback.IDockDataCallback;
import com.ruoyi.device.domain.impl.djimqtt.callback.IDroneDataCallback;
import com.ruoyi.device.domain.impl.djimqtt.config.DjiMqttClientConfig;
import com.ruoyi.device.service.config.DjiMqttProperties;
import com.ruoyi.device.domain.impl.djimqtt.handler.DjiMqttMessageHandler;
import com.ruoyi.device.domain.impl.djimqtt.manager.DjiMqttClientManager;
import com.ruoyi.device.domain.impl.djimqtt.model.DockData;
import com.ruoyi.device.domain.impl.djimqtt.model.DroneData;
import com.ruoyi.device.domain.model.Aircraft;
import com.ruoyi.device.domain.model.Device;
import com.ruoyi.device.domain.model.Dock;
import com.ruoyi.device.domain.model.DockAircraft;
import com.ruoyi.device.websocket.StatisticsWebSocket;
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 org.springframework.util.CollectionUtils;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@Service
@Slf4j
public class DjiService {
@Autowired
private DjiMqttClientManager clientManager;
@Autowired
private DjiMqttProperties mqttProperties;
@Autowired
private IDockDomain dockDomain;
@Autowired
private IDeviceDomain deviceDomain;
@Autowired
private IAircraftDomain aircraftDomain;
@Autowired
private IDockAircraftDomain dockAircraftDomain;
@Autowired
private IThingsBoardDomain thingsBoardDomain;
@Autowired
StatisticsWebSocket statisticsWebSocket;
@EventListener(ApplicationReadyEvent.class)
public void onApplicationReady() {
// 从配置文件读取配置
DjiMqttClientConfig config = DjiMqttClientConfig.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("dji-group")
.build();
// 创建客户端
String clientId = clientManager.createClient(config);
// 获取消息处理器
DjiMqttMessageHandler handler = clientManager.getHandler(clientId);
// 注册无人机数据回调
handler.registerDroneDataCallback(new IDroneDataCallback() {
@Override
public void onDroneData(DroneData droneData) {
if(droneData.getDeviceSn().startsWith("TH")){
return;
}
// log.info("droneData:{}", droneData);
// 判断是否是 state 触发
boolean isStateMessage = "state".equalsIgnoreCase(droneData.getMessageType());
// 更新 Dock 表的 lastActiveTime
log.info("准备查询设备: device_sn={}", droneData.getDeviceSn());
Device device = deviceDomain.selectDeviceByDeviceSn(droneData.getDeviceSn());
log.info("查询设备成功: device_sn={}, deviceId={}", droneData.getDeviceSn(), device != null ? device.getDeviceId() : null);
if(Objects.nonNull(device)) {
Aircraft aircraft = aircraftDomain.selectAircraftByDeviceId(device.getDeviceId());
if(Objects.nonNull(aircraft)) {
List<DockAircraft> aircrafts = dockAircraftDomain.selectDockAircraftByAircraftId(aircraft.getAircraftId());
if(!aircrafts.isEmpty()) {
for(DockAircraft dockAircraft : aircrafts) {
Dock dock = dockDomain.selectDockByDockId(dockAircraft.getDockId());
if(Objects.nonNull(dock)) {
dock.setLastActiveTime(new Date());
dockDomain.updateDock(dock);
// 如果是 state 消息,清除无人机和机场的 ThingsBoard 缓存并广播
if(isStateMessage) {
// 清除机场缓存
Device dockDevice = deviceDomain.selectDeviceByDeviceId(dock.getDeviceId());
if(Objects.nonNull(dockDevice) && Objects.nonNull(dockDevice.getIotDeviceId())) {
thingsBoardDomain.evictDeviceAttributesCache(dockDevice.getIotDeviceId());
thingsBoardDomain.evictDeviceTelemetryCache(dockDevice.getIotDeviceId());
}
thingsBoardDomain.evictDeviceAttributesCache(device.getIotDeviceId());
thingsBoardDomain.evictDeviceTelemetryCache(device.getIotDeviceId());
// 广播机场 ID
statisticsWebSocket.broadcast(String.valueOf(dock.getDockId()));
log.debug("已广播机场ID: dockId={}", dock.getDockId());
}
}
}
}
}
}
}
});
// 注册机场数据回调
handler.registerDockDataCallback(new IDockDataCallback() {
@Override
public void onDockData(DockData dockData) {
// log.info("dockData:{}", dockData);
// 判断是否是 state 触发
boolean isStateMessage = "state".equalsIgnoreCase(dockData.getMessageType());
// 如果是 state 消息,处理缓存清除和广播
if(isStateMessage) {
Device dockDevice = deviceDomain.selectDeviceByDeviceSn(dockData.getDeviceSn());
if(Objects.nonNull(dockDevice)) {
// 查找机场
Dock dock = dockDomain.selectDockByDeviceId(dockDevice.getDeviceId());
if(Objects.nonNull(dock)) {
// 清除机场设备的 ThingsBoard 缓存
if(Objects.nonNull(dockDevice.getIotDeviceId())) {
thingsBoardDomain.evictDeviceAttributesCache(dockDevice.getIotDeviceId());
thingsBoardDomain.evictDeviceTelemetryCache(dockDevice.getIotDeviceId());
// log.debug("已清除机场缓存: deviceSn={}, iotDeviceId={}", dockData.getDeviceSn(), dockDevice.getIotDeviceId());
}
// 清除机场关联的所有无人机缓存
List<DockAircraft> dockAircrafts = dockAircraftDomain.selectDockAircraftByDockId(dock.getDockId());
if(!dockAircrafts.isEmpty()) {
for(DockAircraft dockAircraft : dockAircrafts) {
Aircraft aircraft = aircraftDomain.selectAircraftByAircraftId(dockAircraft.getAircraftId());
if(Objects.nonNull(aircraft)) {
Device droneDevice = deviceDomain.selectDeviceByDeviceId(aircraft.getDeviceId());
if(Objects.nonNull(droneDevice) && Objects.nonNull(droneDevice.getIotDeviceId())) {
thingsBoardDomain.evictDeviceAttributesCache(droneDevice.getIotDeviceId());
thingsBoardDomain.evictDeviceTelemetryCache(droneDevice.getIotDeviceId());
// log.debug("已清除无人机缓存: aircraftId={}, iotDeviceId={}", aircraft.getAircraftId(), droneDevice.getIotDeviceId());
}
}
}
}
// 广播机场 ID
statisticsWebSocket.broadcast(String.valueOf(dock.getDockId()));
log.debug("已广播机场ID: dockId={}", dock.getDockId());
}
}
}
}
});
log.info("客户端已创建并注册回调");
}
}