Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
GeoFlyApi
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
GeoFly
GeoFlyApi
Commits
984de8bc
Commit
984de8bc
authored
Mar 12, 2026
by
tntxia
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'prod' of
http://git.raytue.com/GeoFly/GeoFlyApi
into prod
parents
7920a055
f43581be
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
82 additions
and
7 deletions
+82
-7
cloud-sdk/src/main/java/com/dji/sdk/mqtt/MqttTopicServiceImpl.java
+35
-5
sample/src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java
+16
-1
sample/src/main/java/com/dji/sample/manage/service/impl/SDKDeviceService.java
+30
-0
sample/src/main/resources/application.yml
+1
-1
No files found.
cloud-sdk/src/main/java/com/dji/sdk/mqtt/MqttTopicServiceImpl.java
View file @
984de8bc
...
@@ -28,8 +28,8 @@ public class MqttTopicServiceImpl implements IMqttTopicService {
...
@@ -28,8 +28,8 @@ public class MqttTopicServiceImpl implements IMqttTopicService {
public
void
subscribe
(
String
...
topics
)
{
public
void
subscribe
(
String
...
topics
)
{
Set
<
String
>
topicSet
=
new
HashSet
<>(
Arrays
.
asList
(
getSubscribedTopic
()));
Set
<
String
>
topicSet
=
new
HashSet
<>(
Arrays
.
asList
(
getSubscribedTopic
()));
for
(
String
topic
:
topics
)
{
for
(
String
topic
:
topics
)
{
if
(
topicSet
.
contains
(
topic
))
{
if
(
topicSet
.
contains
(
topic
)
||
isCoveredByWildcard
(
topicSet
,
topic
)
)
{
return
;
continue
;
}
}
subscribe
(
topic
,
1
);
subscribe
(
topic
,
1
);
}
}
...
@@ -38,7 +38,7 @@ public class MqttTopicServiceImpl implements IMqttTopicService {
...
@@ -38,7 +38,7 @@ public class MqttTopicServiceImpl implements IMqttTopicService {
@Override
@Override
public
void
subscribe
(
String
topic
,
int
qos
)
{
public
void
subscribe
(
String
topic
,
int
qos
)
{
Set
<
String
>
topicSet
=
new
HashSet
<>(
Arrays
.
asList
(
getSubscribedTopic
()));
Set
<
String
>
topicSet
=
new
HashSet
<>(
Arrays
.
asList
(
getSubscribedTopic
()));
if
(
topicSet
.
contains
(
topic
))
{
if
(
topicSet
.
contains
(
topic
)
||
isCoveredByWildcard
(
topicSet
,
topic
)
)
{
return
;
return
;
}
}
log
.
debug
(
"subscribe topic: {}"
,
topic
);
log
.
debug
(
"subscribe topic: {}"
,
topic
);
...
@@ -47,11 +47,41 @@ public class MqttTopicServiceImpl implements IMqttTopicService {
...
@@ -47,11 +47,41 @@ public class MqttTopicServiceImpl implements IMqttTopicService {
@Override
@Override
public
void
unsubscribe
(
String
...
topics
)
{
public
void
unsubscribe
(
String
...
topics
)
{
log
.
debug
(
"unsubscribe topic: {}"
,
Arrays
.
toString
(
topics
));
Set
<
String
>
currentTopics
=
new
HashSet
<>(
Arrays
.
asList
(
getSubscribedTopic
()));
adapter
.
removeTopic
(
topics
);
for
(
String
topic
:
topics
)
{
if
(!
currentTopics
.
contains
(
topic
))
{
continue
;
}
if
(
isCoveredByWildcard
(
currentTopics
,
topic
))
{
log
.
debug
(
"skip unsubscribe, topic {} is covered by wildcard"
,
topic
);
continue
;
}
log
.
debug
(
"unsubscribe topic: {}"
,
topic
);
adapter
.
removeTopic
(
topic
);
}
}
}
public
String
[]
getSubscribedTopic
()
{
public
String
[]
getSubscribedTopic
()
{
return
adapter
.
getTopic
();
return
adapter
.
getTopic
();
}
}
/**
* Check if a specific topic is already covered by a single-level wildcard (+) subscription.
* e.g. "thing/product/DRONE-001/osd" is covered by "thing/product/+/osd"
*/
private
boolean
isCoveredByWildcard
(
Set
<
String
>
existingTopics
,
String
topic
)
{
String
[]
parts
=
topic
.
split
(
"/"
);
if
(
parts
.
length
<
3
)
{
return
false
;
}
for
(
int
i
=
0
;
i
<
parts
.
length
;
i
++)
{
String
[]
wildcardParts
=
parts
.
clone
();
wildcardParts
[
i
]
=
"+"
;
String
wildcardTopic
=
String
.
join
(
"/"
,
wildcardParts
);
if
(
existingTopics
.
contains
(
wildcardTopic
))
{
return
true
;
}
}
return
false
;
}
}
}
sample/src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java
View file @
984de8bc
...
@@ -1698,7 +1698,20 @@ public class DeviceServiceImpl extends ServiceImpl<IDeviceMapper, DeviceEntity>
...
@@ -1698,7 +1698,20 @@ public class DeviceServiceImpl extends ServiceImpl<IDeviceMapper, DeviceEntity>
}
else
if
(
DeviceDomainEnum
.
REMOTER_CONTROL
==
dbDevice
.
getDomain
())
{
}
else
if
(
DeviceDomainEnum
.
REMOTER_CONTROL
==
dbDevice
.
getDomain
())
{
recoverGatewayOnline
(
dbDevice
);
recoverGatewayOnline
(
dbDevice
);
}
else
if
(
DeviceDomainEnum
.
DRONE
==
dbDevice
.
getDomain
())
{
}
else
if
(
DeviceDomainEnum
.
DRONE
==
dbDevice
.
getDomain
())
{
recoverDroneOnline
(
dbDevice
);
// 通过 child_sn 反查父设备(数据库中没有 parent_sn 字段,parentSn 只存在于 Redis)
List
<
DeviceDTO
>
parentDevices
=
this
.
getDevicesByParams
(
DeviceQueryParam
.
builder
().
childSn
(
deviceSn
).
build
());
if
(!
parentDevices
.
isEmpty
())
{
// 子设备无人机:通过父设备(机场/遥控器)恢复整个拓扑
DeviceDTO
parentDevice
=
parentDevices
.
get
(
0
);
log
.
info
(
"[Auto-Recovery] Drone {} is a sub-device, recovering via gateway {}"
,
deviceSn
,
parentDevice
.
getDeviceSn
());
recoverGatewayOnline
(
parentDevice
);
}
else
{
// 独立无人机:直接恢复
log
.
info
(
"[Auto-Recovery] Drone {} is an independent device, recovering directly"
,
deviceSn
);
recoverDroneOnline
(
dbDevice
);
}
}
}
}
}
...
@@ -1726,6 +1739,7 @@ public class DeviceServiceImpl extends ServiceImpl<IDeviceMapper, DeviceEntity>
...
@@ -1726,6 +1739,7 @@ public class DeviceServiceImpl extends ServiceImpl<IDeviceMapper, DeviceEntity>
}
}
DeviceDTO
dbDevice
=
dbDeviceOpt
.
get
();
DeviceDTO
dbDevice
=
dbDeviceOpt
.
get
();
log
.
info
(
"[Auto-Recovery] Recovering gateway {} and sub-device {}"
,
gatewaySn
,
deviceSn
);
GatewayManager
gatewayManager
=
SDKManager
.
registerDevice
(
gatewaySn
,
deviceSn
,
GatewayManager
gatewayManager
=
SDKManager
.
registerDevice
(
gatewaySn
,
deviceSn
,
dbGateway
.
getDomain
(),
dbGateway
.
getType
(),
dbGateway
.
getDomain
(),
dbGateway
.
getType
(),
dbGateway
.
getSubType
(),
dbGateway
.
getThingVersion
(),
dbDevice
.
getThingVersion
());
dbGateway
.
getSubType
(),
dbGateway
.
getThingVersion
(),
dbDevice
.
getThingVersion
());
...
@@ -1759,6 +1773,7 @@ public class DeviceServiceImpl extends ServiceImpl<IDeviceMapper, DeviceEntity>
...
@@ -1759,6 +1773,7 @@ public class DeviceServiceImpl extends ServiceImpl<IDeviceMapper, DeviceEntity>
if
(
DeviceDomainEnum
.
DRONE
!=
dbDevice
.
getDomain
())
{
if
(
DeviceDomainEnum
.
DRONE
!=
dbDevice
.
getDomain
())
{
return
;
return
;
}
}
log
.
info
(
"[Auto-Recovery] Recovering independent drone {}"
,
dbDevice
.
getDeviceSn
());
deviceRedisService
.
setDeviceOnline
(
dbDevice
);
deviceRedisService
.
setDeviceOnline
(
dbDevice
);
this
.
subDroneOnlineSubscribeTopic
(
dbDevice
.
getDeviceSn
());
this
.
subDroneOnlineSubscribeTopic
(
dbDevice
.
getDeviceSn
());
// deviceService.pushDeviceOnlineTopo(dbGateway.getWorkspaceId(), dbGateway.getDeviceSn(), dbDevice.getDeviceSn());
// deviceService.pushDeviceOnlineTopo(dbGateway.getWorkspaceId(), dbGateway.getDeviceSn(), dbDevice.getDeviceSn());
...
...
sample/src/main/java/com/dji/sample/manage/service/impl/SDKDeviceService.java
View file @
984de8bc
...
@@ -151,6 +151,7 @@ public class SDKDeviceService extends AbstractDeviceService {
...
@@ -151,6 +151,7 @@ public class SDKDeviceService extends AbstractDeviceService {
public
void
osdDock
(
TopicOsdRequest
<
OsdDock
>
request
,
MessageHeaders
headers
)
{
public
void
osdDock
(
TopicOsdRequest
<
OsdDock
>
request
,
MessageHeaders
headers
)
{
String
from
=
request
.
getFrom
();
String
from
=
request
.
getFrom
();
Optional
<
DeviceDTO
>
deviceOpt
=
deviceRedisService
.
getDeviceOnline
(
from
);
Optional
<
DeviceDTO
>
deviceOpt
=
deviceRedisService
.
getDeviceOnline
(
from
);
boolean
needsRecovery
=
deviceOpt
.
isEmpty
();
if
(
deviceOpt
.
isEmpty
()
||
!
StringUtils
.
hasText
(
deviceOpt
.
get
().
getWorkspaceId
()))
{
if
(
deviceOpt
.
isEmpty
()
||
!
StringUtils
.
hasText
(
deviceOpt
.
get
().
getWorkspaceId
()))
{
deviceOpt
=
deviceService
.
getDeviceBySn
(
from
);
deviceOpt
=
deviceService
.
getDeviceBySn
(
from
);
if
(
deviceOpt
.
isEmpty
())
{
if
(
deviceOpt
.
isEmpty
())
{
...
@@ -168,6 +169,11 @@ public class SDKDeviceService extends AbstractDeviceService {
...
@@ -168,6 +169,11 @@ public class SDKDeviceService extends AbstractDeviceService {
}
}
deviceRedisService
.
setDeviceOnline
(
device
);
deviceRedisService
.
setDeviceOnline
(
device
);
if
(
needsRecovery
&&
StringUtils
.
hasText
(
device
.
getWorkspaceId
()))
{
triggerDeviceAutoRecovery
(
from
);
}
fillDockOsd
(
from
,
request
.
getData
());
fillDockOsd
(
from
,
request
.
getData
());
deviceService
.
pushOsdDataToWeb
(
device
.
getWorkspaceId
(),
BizCodeEnum
.
DOCK_OSD
,
from
,
request
.
getData
());
deviceService
.
pushOsdDataToWeb
(
device
.
getWorkspaceId
(),
BizCodeEnum
.
DOCK_OSD
,
from
,
request
.
getData
());
...
@@ -177,6 +183,7 @@ public class SDKDeviceService extends AbstractDeviceService {
...
@@ -177,6 +183,7 @@ public class SDKDeviceService extends AbstractDeviceService {
public
void
osdDockDrone
(
TopicOsdRequest
<
OsdDockDrone
>
request
,
MessageHeaders
headers
)
{
public
void
osdDockDrone
(
TopicOsdRequest
<
OsdDockDrone
>
request
,
MessageHeaders
headers
)
{
String
from
=
request
.
getFrom
();
String
from
=
request
.
getFrom
();
Optional
<
DeviceDTO
>
deviceOpt
=
deviceRedisService
.
getDeviceOnline
(
from
);
Optional
<
DeviceDTO
>
deviceOpt
=
deviceRedisService
.
getDeviceOnline
(
from
);
boolean
needsRecovery
=
deviceOpt
.
isEmpty
();
if
(
deviceOpt
.
isEmpty
())
{
if
(
deviceOpt
.
isEmpty
())
{
deviceOpt
=
deviceService
.
getDeviceBySn
(
from
);
deviceOpt
=
deviceService
.
getDeviceBySn
(
from
);
if
(
deviceOpt
.
isEmpty
())
{
if
(
deviceOpt
.
isEmpty
())
{
...
@@ -191,6 +198,10 @@ public class SDKDeviceService extends AbstractDeviceService {
...
@@ -191,6 +198,10 @@ public class SDKDeviceService extends AbstractDeviceService {
DeviceDTO
device
=
deviceOpt
.
get
();
DeviceDTO
device
=
deviceOpt
.
get
();
deviceRedisService
.
setDeviceOnline
(
device
);
deviceRedisService
.
setDeviceOnline
(
device
);
if
(
needsRecovery
&&
StringUtils
.
hasText
(
device
.
getWorkspaceId
()))
{
triggerDeviceAutoRecovery
(
from
);
}
deviceRedisService
.
setDeviceOsd
(
from
,
request
.
getData
());
deviceRedisService
.
setDeviceOsd
(
from
,
request
.
getData
());
// 存放数据
// 存放数据
deviceDetailService
.
saveDeviceOsd
(
from
,
request
.
getData
());
deviceDetailService
.
saveDeviceOsd
(
from
,
request
.
getData
());
...
@@ -234,6 +245,7 @@ public class SDKDeviceService extends AbstractDeviceService {
...
@@ -234,6 +245,7 @@ public class SDKDeviceService extends AbstractDeviceService {
public
void
osdRemoteControl
(
TopicOsdRequest
<
OsdRemoteControl
>
request
,
MessageHeaders
headers
)
{
public
void
osdRemoteControl
(
TopicOsdRequest
<
OsdRemoteControl
>
request
,
MessageHeaders
headers
)
{
String
from
=
request
.
getFrom
();
String
from
=
request
.
getFrom
();
Optional
<
DeviceDTO
>
deviceOpt
=
deviceRedisService
.
getDeviceOnline
(
from
);
Optional
<
DeviceDTO
>
deviceOpt
=
deviceRedisService
.
getDeviceOnline
(
from
);
boolean
needsRecovery
=
deviceOpt
.
isEmpty
();
if
(
deviceOpt
.
isEmpty
()
||
!
StringUtils
.
hasText
(
deviceOpt
.
get
().
getWorkspaceId
()))
{
if
(
deviceOpt
.
isEmpty
()
||
!
StringUtils
.
hasText
(
deviceOpt
.
get
().
getWorkspaceId
()))
{
deviceOpt
=
deviceService
.
getDeviceBySn
(
from
);
deviceOpt
=
deviceService
.
getDeviceBySn
(
from
);
if
(
deviceOpt
.
isEmpty
())
{
if
(
deviceOpt
.
isEmpty
())
{
...
@@ -247,6 +259,10 @@ public class SDKDeviceService extends AbstractDeviceService {
...
@@ -247,6 +259,10 @@ public class SDKDeviceService extends AbstractDeviceService {
}
}
deviceRedisService
.
setDeviceOnline
(
device
);
deviceRedisService
.
setDeviceOnline
(
device
);
if
(
needsRecovery
&&
StringUtils
.
hasText
(
device
.
getWorkspaceId
()))
{
triggerDeviceAutoRecovery
(
from
);
}
OsdRemoteControl
data
=
request
.
getData
();
OsdRemoteControl
data
=
request
.
getData
();
deviceService
.
pushOsdDataToPilot
(
device
.
getWorkspaceId
(),
from
,
deviceService
.
pushOsdDataToPilot
(
device
.
getWorkspaceId
(),
from
,
new
DeviceOsdHost
()
new
DeviceOsdHost
()
...
@@ -261,6 +277,7 @@ public class SDKDeviceService extends AbstractDeviceService {
...
@@ -261,6 +277,7 @@ public class SDKDeviceService extends AbstractDeviceService {
public
void
osdRcDrone
(
TopicOsdRequest
<
OsdRcDrone
>
request
,
MessageHeaders
headers
)
{
public
void
osdRcDrone
(
TopicOsdRequest
<
OsdRcDrone
>
request
,
MessageHeaders
headers
)
{
String
from
=
request
.
getFrom
();
String
from
=
request
.
getFrom
();
Optional
<
DeviceDTO
>
deviceOpt
=
deviceRedisService
.
getDeviceOnline
(
from
);
Optional
<
DeviceDTO
>
deviceOpt
=
deviceRedisService
.
getDeviceOnline
(
from
);
boolean
needsRecovery
=
deviceOpt
.
isEmpty
();
if
(
deviceOpt
.
isEmpty
())
{
if
(
deviceOpt
.
isEmpty
())
{
deviceOpt
=
deviceService
.
getDeviceBySn
(
from
);
deviceOpt
=
deviceService
.
getDeviceBySn
(
from
);
if
(
deviceOpt
.
isEmpty
())
{
if
(
deviceOpt
.
isEmpty
())
{
...
@@ -275,6 +292,10 @@ public class SDKDeviceService extends AbstractDeviceService {
...
@@ -275,6 +292,10 @@ public class SDKDeviceService extends AbstractDeviceService {
deviceRedisService
.
setDeviceOnline
(
device
);
deviceRedisService
.
setDeviceOnline
(
device
);
if
(
needsRecovery
&&
StringUtils
.
hasText
(
device
.
getWorkspaceId
()))
{
triggerDeviceAutoRecovery
(
from
);
}
OsdRcDrone
data
=
request
.
getData
();
OsdRcDrone
data
=
request
.
getData
();
deviceService
.
pushOsdDataToPilot
(
device
.
getWorkspaceId
(),
from
,
deviceService
.
pushOsdDataToPilot
(
device
.
getWorkspaceId
(),
from
,
new
DeviceOsdHost
()
new
DeviceOsdHost
()
...
@@ -425,6 +446,15 @@ public class SDKDeviceService extends AbstractDeviceService {
...
@@ -425,6 +446,15 @@ public class SDKDeviceService extends AbstractDeviceService {
}
}
private
void
triggerDeviceAutoRecovery
(
String
deviceSn
)
{
log
.
warn
(
"[Auto-Recovery] OSD received from offline device {}, triggering online recovery"
,
deviceSn
);
try
{
deviceService
.
recoverDeviceOnline
(
deviceSn
);
}
catch
(
Exception
e
)
{
log
.
error
(
"[Auto-Recovery] Failed to recover device {}: {}"
,
deviceSn
,
e
.
getMessage
());
}
}
public
void
deviceOnlineAgain
(
String
workspaceId
,
String
gatewaySn
,
String
deviceSn
)
{
public
void
deviceOnlineAgain
(
String
workspaceId
,
String
gatewaySn
,
String
deviceSn
)
{
DeviceDTO
device
=
DeviceDTO
.
builder
().
loginTime
(
LocalDateTime
.
now
()).
deviceSn
(
deviceSn
).
build
();
DeviceDTO
device
=
DeviceDTO
.
builder
().
loginTime
(
LocalDateTime
.
now
()).
deviceSn
(
deviceSn
).
build
();
DeviceDTO
gateway
=
DeviceDTO
.
builder
()
DeviceDTO
gateway
=
DeviceDTO
.
builder
()
...
...
sample/src/main/resources/application.yml
View file @
984de8bc
...
@@ -112,7 +112,7 @@ mqtt:
...
@@ -112,7 +112,7 @@ mqtt:
cloud-sdk
:
cloud-sdk
:
mqtt
:
mqtt
:
# Topics that need to be subscribed when initially connecting to mqtt, multiple topics are divided by ",".
# Topics that need to be subscribed when initially connecting to mqtt, multiple topics are divided by ",".
inbound-topic
:
sys/product/+/status,thing/product/+/requests,/ai_info
inbound-topic
:
sys/product/+/status,thing/product/+/requests,
thing/product/+/osd,
/ai_info
url
:
url
:
manage
:
manage
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment