You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

407 lines
18 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 相当于天线默认目标地址为192.168.49.160,端口号为 8080
# 下行报文指上位机发送给接收机
import tkinter as tk
from threading import Thread
import socket
class ReceiveApp:
def __init__(self, window):
self.window = window
self.window.title("Receive端")
# 接收区域
self.recv_frame = tk.Frame(window)
self.recv_frame.pack(padx=10, pady=10)
self.recv_label = tk.Label(self.recv_frame, text="接收数据")
self.recv_label.pack()
self.recv_text = tk.Text(self.recv_frame, height=15, width=50)
self.recv_text.pack()
# 发送区域
self.send_frame = tk.Frame(window)
self.send_frame.pack(padx=10, pady=10)
self.style_label = tk.Label(self.send_frame, text="指令类型:")
self.style_label.pack(side=tk.LEFT)
self.style_entry = tk.Entry(self.send_frame)
self.style_entry.pack(side=tk.LEFT)
self.content_label = tk.Label(self.send_frame, text="指令内容:")
self.content_label.pack(side=tk.LEFT)
self.content_entry = tk.Entry(self.send_frame)
self.content_entry.pack(side=tk.LEFT)
#获取完整指令
self.all_msg = tk.Label(self.send_frame, text="完整指令:")
self.all_msg.pack(side=tk.LEFT)
self.all_msg = tk.Entry(self.send_frame)
self.all_msg.pack(side=tk.LEFT)
self.send_button = tk.Button(self.send_frame, text="发送", command=self.send_message)
self.send_button.pack(side=tk.LEFT)
self.sk = socket.socket(type=socket.SOCK_DGRAM)
self.sk.bind(("127.0.0.1", 9000))
# 开始接收数据的线程
self.thread = Thread(target=self.receive_data)
self.thread.daemon = True
self.thread.start()
# 下行报文18字节固定长度
"""帧格式:
0~3 帧头 BYTE[4] 4 固定为0x58443341
4 指令类型 UINT8 1 0x00:开始停止 0x01:工况查询 0x02:设备重置 0x03:授时指令 0x04:频率设置
0x05:本机地址设置 0x06:本机位置设置 0x07:开启关闭测试模式
5~14 指令内容 BYTE[10] 10 根据指令类型填充当指令类型为0x01、0x02时可不填充
15~17 帧尾 BYTE[3] 3 固定为0x334441
"""
def send_message(self):
# 1.创建udp对象
style = self.style_entry.get()
print(style)
content = self.content_entry.get()
print(content)
if style != "" or content != "":
head = "58443341"
tail = "334441"
msg = head + style + content + tail
else:
all_message = self.all_msg.get()
msg = all_message.split(" ")
msg = "".join(msg)
print(msg)
# sendto( 二进制字节流ip端口号 )
self.sk.sendto(msg.encode(), ("127.0.0.1", 5010))
def receive_data(self):
while True:
msg, addr = self.sk.recvfrom(1024)
message_to_display = "Received: " + msg.decode() + " from " + str(addr)
self.recv_text.insert(tk.END, message_to_display + "\n")
self.analysis_message(msg)
# 上行报文采用不定长帧
"""帧格式:
0~3 帧头 BYTE[4] 4 固定为0x58443341
4~7 流水号 UINT32 4 0x00000000~0xFFFFFFFF循环用于判断帧连续
8~13 时标(年月日时分秒) BYTE[6] 6 若报文类别为0x01、0x02、0x03此时间为FPGA采到第一bit数据时间或者第一个脉冲的起始时间若报文类别为0xFF此时间为组包时的时间
14~17 时标(秒内计数器) UINT32 4
18 报文类型 BYTE 1 0x01AIS通道1信息0x02AIS通道2信息0x03ACARS通道1信息0x04ACARS通道2信息0x05ACARS通道3信息0x06ACARS通道4信息0x07ADS-B信息0x08IFF信息0xFF工况。19~20数据长度UINT16 2指数据段的长度不包括帧头、帧尾和其它字段。
21~20+n 数据段 BYTE[n] n 根据报文类型区分
21+n~23+n 帧尾 BYTE[3] 3 固定为0x334441
"""
# 解析下行报文
def analysis_message(self, msg):
global water
getmessage = msg.decode()
# 如果帧头不是0x58443341则报文错误
if getmessage[0:8] != "58443341":
first_type = "错误类型:帧头错误"
self.recv_text.insert(tk.END, first_type + "\n")
return
#判断是否连续
Water = '{:08X}'.format(water)
water = water + 1
if getmessage[8:16] == Water:
k = "帧连续"
self.recv_text.insert(tk.END, k + "\n")
else:
k = "帧不连续,有漏帧"
self.recv_text.insert(tk.END, k + "\n")
#汇报时间
"""
授时指令内容:
0 年 UINT8 1 00-99对应0x00-0x63,基数为2000例如2001年对应0x01,2099年对应0x63。
1 月 UINT8 1 01-12对应0x01-0x0C
2 日 UINT8 1 01-31对应0x01-0x1F
3 时 UINT8 1 00-23对应0x00-0x17
4 分 UINT8 1 00-59对应0x00-0x3B
5 秒 UINT8 1 00-59对应0x00-0x3B
6-9 保留 UINT8 4
"""
year = int(getmessage[16:18], 16) + 2000
month = int(getmessage[18:20], 16)
day = int(getmessage[20:22], 16)
hour = int(getmessage[22:24], 16)
minute = int(getmessage[24:26], 16)
second = int(getmessage[26:28], 16)
self.recv_text.insert(tk.END, "当前时间为: " + str(year) + "" + str(month) + "" + str(day) + "" + str(
hour) + "" + str(minute) + "" + str(second) + "\n")
#秒内计数器
one = int(getmessage[28:30],16)
two = int(getmessage[30:32],16)
three = int(getmessage[32:34], 16)
four = int(getmessage[34:36], 16)
self.recv_text.insert(tk.END, "秒内计数器: " + str(one) + "." + str(two) + "." + str(three) + "." + str(four) + "\n")
#报文类型
if getmessage[36:38] == "01":
k = "AIS通道1信息"
self.recv_text.insert(tk.END,"报文类型:" + k + "\n")
elif getmessage[36:38] == "02":
k = "AIS通道2信息"
self.recv_text.insert(tk.END,"报文类型:" + k + "\n")
elif getmessage[36:38] == "02":
k = "ACARS通道1信息"
self.recv_text.insert(tk.END,"报文类型:" + k + "\n")
elif getmessage[36:38] == "02":
k = "ACARS通道2信息"
self.recv_text.insert(tk.END,"报文类型:" + k + "\n")
elif getmessage[36:38] == "02":
k = "ACARS通道3信息"
self.recv_text.insert(tk.END,"报文类型:" + k + "\n")
elif getmessage[36:38] == "02":
k = "ACARS通道4信息"
self.recv_text.insert(tk.END,"报文类型:" + k + "\n")
elif getmessage[36:38] == "02":
k = "ADS-B信息"
self.recv_text.insert(tk.END,"报文类型:" + k + "\n")
elif getmessage[36:38] == "02":
k = "IFF信息"
self.recv_text.insert(tk.END,"报文类型:" + k + "\n")
elif getmessage[36:38] == "02":
k = "工况"
self.recv_text.insert(tk.END,"报文类型:" + k + "\n")
else:
k = "错误"
self.recv_text.insert(tk.END,"报文类型:" + k + "\n")
#数据长度
self.recv_text.insert(tk.END, "数据长度:" + getmessage[38:42] + "\n")
#AIS信息
if True: #getmessage[36:38]=="01" or getmessage[36:38]=="02"
if getmessage[42:44] == "01" or getmessage[42:44] == "02" or getmessage[42:44] == "03":
k = "A类船位置报告消息"
self.recv_text.insert(tk.END, "消息ID" + k + "\n")
elif getmessage[42:44] == "05":
k = "A类船的静态消息"
self.recv_text.insert(tk.END, "消息ID" + k + "\n")
elif getmessage[42:44] == "12":
k = "B类船位置报告消息"
self.recv_text.insert(tk.END, "消息ID" + k + "\n")
elif getmessage[42:44] == "24":
k = "B类船的静态消息"
self.recv_text.insert(tk.END, "消息ID" + k + "\n")
else:
k = "错误"
self.recv_text.insert(tk.END, "消息ID" + k + "\n")
#用户ID
self.recv_text.insert(tk.END, "用户ID" + getmessage[44:54] + "\n")
#IMO编号
self.recv_text.insert(tk.END, "IMO编号" + getmessage[54:62] + "\n")
#呼号
self.recv_text.insert(tk.END, "呼号:" + getmessage[62:76] + "\n")
#船名
self.recv_text.insert(tk.END, "船名:" + getmessage[76:116] + "\n")
#船舶和货物类型
if getmessage[116:118] == "00":
k = "捕捞"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "01":
k = "拖船"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "02":
k = "拖船且推带长度超过200米或宽度超过25米"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "03":
k = "从事挖掘或水下作业"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "04":
k = "从事潜水作业"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "05":
k = "从事军事行动"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "06":
k = "帆船"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "07":
k = "游艇"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "21":
k = "运载DG、HS或者MP、IMO危险品或X2类污染物"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "32":
k = "运载DG、HS或者MP、IMO危险品或Y2类污染物"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "43":
k = "运载DG、HS或者MP、IMO危险品或Z2类污染物"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "50":
k = "引航船舶"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "51":
k = "搜救船舶"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "52":
k = "拖轮"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "53":
k = "港口补给船"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "54":
k = "安装有防污染设施或设备的船舶"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "55":
k = "执法船舶"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "58":
k = "医疗运输船舶"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "59":
k = "非武装冲突参与国的船舶和航空器"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "60":
k = "客轮"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "70":
k = "货轮"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
elif getmessage[116:118] == "80":
k = "油轮"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
else:
k = "错误"
self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n")
# 船舶宽度
self.recv_text.insert(tk.END, "船舶宽度:" + getmessage[118:122] + "\n")
# 船舶长度
self.recv_text.insert(tk.END, "船舶长度:" + getmessage[122:126] + "\n")
#预计到达时间
month = int(getmessage[126:128], 16)
day = int(getmessage[128:130], 16)
hour = int(getmessage[130:132], 16)
minute = int(getmessage[132:134], 16)
self.recv_text.insert(tk.END, "预计到达时间为: " + str(month) + "" + str(day) + "" + str(
hour) + "" + str(minute) + "" "\n")
#目前最大静态吃水
k = int(getmessage[134:136],16)
k = k / 10
self.recv_text.insert(tk.END, "目前最大静态吃水:" + str(k) + "\n")
#目的地
self.recv_text.insert(tk.END, "目的地:" + getmessage[136:176] + "\n")
#导航状态
if getmessage[176:178] == "00":
k = "发动机使用中"
self.recv_text.insert(tk.END, "导航状态:" + k + "\n")
elif getmessage[176:178] == "01":
k = "锚泊"
self.recv_text.insert(tk.END, "导航状态:" + k + "\n")
elif getmessage[176:178] == "02":
k = "未操纵"
self.recv_text.insert(tk.END, "导航状态:" + k + "\n")
elif getmessage[176:178] == "03":
k = "有限适航性"
self.recv_text.insert(tk.END, "导航状态:" + k + "\n")
elif getmessage[176:178] == "04":
k = "受船舶吃水限制"
self.recv_text.insert(tk.END, "导航状态:" + k + "\n")
elif getmessage[176:178] == "05":
k = "系泊"
self.recv_text.insert(tk.END, "导航状态:" + k + "\n")
elif getmessage[176:178] == "06":
k = "搁浅"
self.recv_text.insert(tk.END, "导航状态:" + k + "\n")
elif getmessage[176:178] == "07":
k = "从事捕捞"
self.recv_text.insert(tk.END, "导航状态:" + k + "\n")
elif getmessage[176:178] == "08":
k = "航行中"
self.recv_text.insert(tk.END, "导航状态:" + k + "\n")
elif getmessage[176:178] == "15":
k = "无效信息"
self.recv_text.insert(tk.END, "导航状态:" + k + "\n")
else:
k = "错误"
self.recv_text.insert(tk.END, "导航状态:" + k + "\n")
#地面航速
k = int(getmessage[178:182],16) / 10
self.recv_text.insert(tk.END, "地面航速:" + k + "\n")
#经纬度
get_longitude = getmessage[182:190]
if get_longitude[0:3] == "FFFF":
longitude = "无效"
else:
byte_string = bytes.fromhex(get_longitude)
longitude = int.from_bytes(byte_string, byteorder='little', signed=True)
if (longitude < 0):
long_tag = "南纬: "
longitude = str((0 - longitude) / 10000)
else:
long_tag = "北纬: "
longitude = str((longitude) / 10000)
get_latitude = getmessage[190:198]
if get_latitude[0:3] == "FFFF":
latitude = "无效"
else:
byte_string = bytes.fromhex(get_latitude)
latitude = int.from_bytes(byte_string, byteorder='little', signed=True)
if (latitude < 0):
lat_tag = " 西经: "
latitude = str((0 - latitude) / 10000)
else:
lat_tag = " 东经:"
latitude = str((latitude) / 10000)
if (longitude == "无效" or latitude == "无效"):
self.recv_text.insert(tk.END, "无效位置\n")
else:
self.recv_text.insert(tk.END, "本机位置为: " + str(long_tag) + str(longitude) + str(lat_tag) + str(
latitude) + "\n")
#地面航线
k = int(getmessage[198:202],16) / 10
self.recv_text.insert(tk.END, "地面航线:" + k + "\n")
# 实际航向
k = int(getmessage[202:206], 16)
self.recv_text.insert(tk.END, "实际航向:" + k + "\n")
#帧尾
if getmessage[206:212] != "334441":
last_type = "错误类型:帧尾错误"
self.recv_text.insert(tk.END, last_type + "\n")
return
if __name__ == "__main__":
water = 0
root = tk.Tk()
app = ReceiveApp(root)
root.mainloop()