# -*- coding: utf-8 -*-
|
|
#!/usr/bin/python
|
import paho.mqtt.client as mqtt
|
import json
|
import time
|
import threading
|
import traceback
|
import db_operate
|
from linkListUtil import Node, LinkedList
|
from shapelyUtil import ShapelyUtil
|
from queue import Queue
|
|
def gettime():
|
time1=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
|
return time1
|
|
# 订阅服务器(中兴无人机的消息服务器)地址 #mqtt server URL:mqtt://7.65.210.186:1883 username:sanss password:123456 topic:rid/uav
|
host = '10.7.145.30'
|
port = 1884
|
username = 'sanss'
|
password = '123456'
|
arr_topic = ['rid/uav']
|
|
# 发送服务器(服务器62)配置 # 172.16.2.76 1883 endpoint 321123
|
send_host = '172.16.2.76'
|
send_port = 1883
|
send_username = 'endpoint'
|
send_password = '321123'
|
send_topic = ['uavAddObj','uavAddTrack','uavRemoveObj']
|
|
#全局数据定义:
|
object_dict = {}
|
objs = LinkedList()
|
data_queue = Queue()
|
db_data_queue = Queue()
|
# [[121.506064, 31.212161],[121.502294, 31.212988],[121.503238, 31.215669],[121.503828, 31.218579],[121.5024, 31.221577],[121.506519, 31.234141],[121.507887, 31.218478],[121.507595, 31.215546],[121.505041, 31.210298,]]
|
#shapeUtil = ShapelyUtil([[121.497272, 31.208397],[121.506529, 31.205425],[121.510571, 31.224502],[121.495167, 31.221426]])
|
shapeUtil = ShapelyUtil([[121.501106,31.223485],[121.505473,31.223778],[121.507622,31.219178],[121.507838,31.217541],[121.507721,31.216351],[121.506934,31.214187],[121.505682,31.21227],[121.504602,31.210381],[121.504053,31.209363],[121.50158,31.211439],[121.50277,31.213707],[121.503714,31.21566],[121.5038,31.216795],[121.503908,31.217588],[121.503699,31.218523],[121.502979,31.220407],[121.502423,31.221324]])
|
shapeUtil_df = ShapelyUtil([[121.469388,31.065589],[121.47505698,31.06620010],[121.4718852,31.08004342],[121.4659318,31.07932891]])
|
shapeUtil_dy = ShapelyUtil([[121.342248,30.814109],[121.335855,30.843758],[121.374132,30.849655],[121.38213,30.819001]])
|
|
# MQTT连接成功回调
|
def on_connect(client, userdata, flags, respons_code):
|
print(f"连接状态码: {respons_code}")
|
if respons_code == 0:
|
print('Connection Succeed!')
|
for topic in arr_topic:
|
client.subscribe(topic)
|
else:
|
print(f"Connect Error status {respons_code}")
|
|
# MQTT断开连接回调
|
def on_disconnect(client, userdata, rc):
|
print(f"断开连接,状态码: {rc}")
|
if rc != 0:
|
print("意外断开,尝试重连...")
|
|
# MQTT收到消息回调,仅入队,逻辑后移
|
def on_message(client, userdata, msg):
|
try:
|
jsondata = json.loads(msg.payload)
|
data_queue.put(jsondata)
|
except Exception as e:
|
print("on_message 解析错误:", e)
|
traceback.print_exc()
|
|
# 独立线程:处理数据逻辑
|
def data_processor_(data_queue: Queue, client, db_data_queue):
|
while True:
|
jsondata = data_queue.get()
|
if 'remoteId' not in jsondata or not jsondata['remoteId']:
|
return None # 无 remoteId 则忽略
|
try:
|
remote = jsondata['remoteId']
|
position = remote['position']
|
timestamp = remote['timestamp'] / 1000 # 微秒转毫秒
|
recv_time = int(time.time())
|
# \"position\":{\"x\":121.475845,\"y\":31.06572,\"z\":16.0},\"speedHorizontal\":5.0,\"speedVertical\":0.0,\"timestamp\":1745911833687349,\"uasId\":\"1581F5FHD238R00D8LJ6\"
|
obj = {
|
'object_id': remote['uasId'],
|
'lng': float(position['x']),
|
'lat': float(position['y']),
|
'height': float(position['z']),
|
'speed': float(remote['speedHorizontal']), # 水平速度
|
'velocityH': float(remote['speedHorizontal']),
|
'velocityV': float(remote['speedVertical']),
|
'headH': float(remote['direction']),
|
'direction': float(remote['direction']),
|
'recvtime': recv_time,
|
'second': int(timestamp),
|
'isInside': 0,
|
'region': 0,
|
'time': time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(recv_time)),
|
'is_track': 0
|
}
|
# obj['lng'] = 121.475845
|
# obj['lat'] = 31.06572
|
# obj['height'] = 16.0
|
# obj['velocityH'] = 5.0
|
# 区域判断
|
# if shapeUtil.isInPolygon(obj['lng'], obj['lat']):
|
# obj['isInside'] = 1
|
# obj['region'] = 1
|
# elif shapeUtil_df.isInPolygon(obj['lng'], obj['lat']):
|
# obj['isInside'] = 1
|
# obj['region'] = 2
|
# elif shapeUtil_dy.isInPolygon(obj['lng'], obj['lat']):
|
# obj['isInside'] = 1
|
# obj['region'] = 3
|
|
node = objs.find_by_value(obj['object_id'])
|
if node is None:
|
objs.insert_value_to_head(obj['object_id'], [obj])
|
node = objs.find_by_value(obj['object_id'])
|
#db_data_queue.put(obj)
|
else :
|
obj0 = node.track[0]
|
obj['is_track'] = 1
|
obj['direction'] = shapeUtil.angle(obj0['lat'], obj0['lng'], obj['lat'], obj['lng'])
|
node.track.append(obj)
|
#if obj['isInside'] == 1:
|
client.publish(send_topic[1] if len(node.track)>1 else send_topic[0], json.dumps(obj))
|
except Exception as e:
|
print("解析无人机数据异常:", e)
|
traceback.print_exc()
|
return None
|
|
|
def monitor_list_(linked_list: LinkedList, client: mqtt.Client, db_data_queue):
|
p = linked_list.head
|
countBoat = 0
|
while True:
|
if p is None:
|
#print(f"当前区域内船舶数量:{countBoat}: ")
|
p = linked_list.head
|
countBoat = 0
|
continue
|
try:
|
item = p.item
|
track = p.track
|
p = p.next
|
if abs(int(track[-1]['recvtime']) - int(time.time())) > 5 :
|
client.publish(send_topic[2],json.dumps(track[-1]))
|
track[-1]['isInside'] = -1
|
linked_list.delete_by_value(item, track)
|
#db_data_queue.put(track)
|
countBoat = countBoat+1 if track[-1]['isInside'] == 1 else countBoat
|
except Exception as e:
|
print(f"监控异常: {e}")
|
|
def queueListen_(db_data_queue):
|
while True:
|
data = db_data_queue.get()
|
if data is None:
|
continue
|
#db_operate.bt_cy_save(data)
|
|
def messageListen(data_queue):
|
f1 = open("uav.txt", 'w', encoding='UTF-8')
|
while True:
|
data = data_queue.get()
|
if data is None:
|
continue
|
f1.writelines(data)
|
f1.close()
|
|
|
def main():
|
# 初始化 MQTT
|
client = mqtt.Client()
|
client.username_pw_set(username, password)
|
client.on_connect = on_connect
|
client.on_message = on_message
|
client.on_disconnect = on_disconnect
|
client.connect(host, port, keepalive=60)
|
client.loop_start()
|
|
# 初始化 发送 MQTT 客户端
|
send_client = mqtt.Client()
|
send_client.username_pw_set(send_username, send_password)
|
send_client.connect(send_host, send_port, keepalive=60)
|
send_client.loop_start()
|
|
# 启动处理线程
|
threading.Thread(target=data_processor_, args=(data_queue, send_client, db_data_queue), daemon=True).start()
|
threading.Thread(target=monitor_list_, args=(objs, send_client, db_data_queue), daemon=True).start()
|
#threading.Thread(target=queueListen_, args=(db_data_queue,), daemon=True).start()
|
|
# 主线程挂起
|
while True:
|
time.sleep(1)
|
|
|
if __name__ == '__main__':
|
#print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(1712900732)))
|
main()
|