Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import paho.mqtt.client as mqtt
import json
import base64
import socket
import datetime
import signal
import argparse
RTCM3_PREAMBLE = b'\xd3'
# Specify the host name and port number of the broker here.
MQTTBROKER_HOSTNAME = "localhost"
MQTTBROKER_PORT = 8883
# The port number on which in the rtkrcv is publishing the RTCM3 messages.
RTKRCV_SRV_HOST = "localhost"
RTKRCV_SRV_PORT = 11235
# The topic for the messages.
MQTT_RTCM3_TOPIC = "rtcm3"
# The client ID used for publish
MQTT_RTCM3_RELAY_ID = "rtcm3relay"
class MQTTRelay:
mqtt_client = None
sock = None
"""
create an MQTT client that connects to the broker
"""
def __init__(self, mqtthost, mqttport):
self.mqtt_client = mqtt.Client(client_id=MQTT_RTCM3_RELAY_ID, clean_session=True, userdata=None, transport='tcp')
self.mqtt_client.on_connect = self._mqtt_connect
self.mqtt_client.on_disconnect = self._mqtt_disconnect
self.mqtt_client.connect(mqtthost, mqttport)
print("Connected to MQTT Broker")
self.sock = None
# Specify the signal handlers.
signal.signal(signal.SIGINT, self.handle_exit)
signal.signal(signal.SIGTERM, self.handle_exit)
return
"""
Debug messages to show when connected
"""
def _mqtt_connect(self, client, obj, flags, rc):
return
"""
Do a clean disconnect
"""
def _mqtt_disconnect(self, client, userdata, rc=0):
print ("Disconnecting from the MQTT broker")
client.loop_stop()
return
# """
# Publish a message with the given topic .. Made it inline.
# """
# def publish_rtcm3(self, rtcm3_frame):
# self.mqtt_client.publish(topic=MQTT_RTCM3_TOPIC,
# payload=json.dumps({'rtcm3':rtcm3_frame, 'timestamp': datetime.datetime.now().timestamp()}))
# return
def handle_exit(self, signum, frame):
# Disconnect the client
self.sock.close()
self.mqtt_client.disconnect()
return
# """
# Read the log file and publish each RTCM3 frame in an individual message.
# """
# def rtcm3_relay_file(fname, publisher):
# print("Reading File Now")
# cnt = 0
# with open(fname, mode="rb") as bfile:
# # skip the first few bytes which are newline characters.
# data = bfile.read(1)
# while data != RTCM3_PREAMBLE:
# data = bfile.read(1)
# rtcm3_frame = bytes()
# rtcm3_frame += base64.encodebytes(data)
# while data != b"":
# cnt = cnt + 1
# data = bfile.read(1)
# print(data)
# if data == RTCM3_PREAMBLE:
# print("Found preamble")
# utf8_rtcm3_frame = rtcm3_frame.decode('utf-8')
# publisher.publish_rtcm3(utf8_rtcm3_frame)
# rtcm3_frame = bytes()
# rtcm3_frame += base64.encodebytes(data)
# print(cnt)
# return True
"""
Connect to the tcp server created by rtknavi/rtklib.
Read the rtcm3 frames, and publish each frame as a message.
"""
def rtcm3_relay_socket(self, srv_host, srv_port):
buff_size = 4096
rtcm3_frame = bytes()
first_preamble = True
try:
self.sock = socket.create_connection((srv_host, srv_port))
print ("Connected to RTKRCV tcp port. Relaying the RTCM3 messages now")
while True:
data = self.sock.recv(4096)
data = [bytes(data[i:i+1]) for i in range(len(data))]
for i in range(len(data)):
data_byte = data[i]
# This needs to be optimized. Currently, we create a message each time the preamble is seen.
# The correct way would be to fetch the length, and encode the payload up to the length.
if data_byte == RTCM3_PREAMBLE:
if first_preamble is False:
self.mqtt_client.publish(topic=MQTT_RTCM3_TOPIC,
json.dumps({'rtcm3':base64.b64encode(rtcm3_frame).decode('utf-8'),
'timestamp': datetime.datetime.now().timestamp()}))
#utf8_rtcm3_frame = base64.b64encode(rtcm3_frame).decode('utf-8')
#self.publish_rtcm3(utf8_rtcm3_frame)
first_preamble = False
rtcm3_frame = bytes()
rtcm3_frame += data_byte
except IOError:
pass
except Exception as e:
print(e)
return True
def main(mqtthost, mqttport, rtkhost, rtkport):
mqtt_relay = MQTTRelay(mqtthost, mqttport)
mqtt_relay.rtcm3_relay_socket(rtkhost, rtkport)
print ("Quitting")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('-r','--rtktcphost',
help="hostname where the rtrcv is exporting rtcm3 over tcp",
type=str)
parser.add_argument('-p', '--rtktcpport',
help="port number where the rtrcv is exporting rtcm3 over tcp",
type=int)
parser.add_argument('-b','--mqtthost',
help="hostname of the MQTT broker",
type=str)
parser.add_argument('-m', '--mqttport',
help="port number of the MQTT broker",
type=int)
args = parser.parse_args()
if None in [ args.rtktcphost, args.rtktcpport, args.mqtthost, args.mqttport ]:
parser.print_help()
else:
main(args.mqtthost, args.mqttport, args.rtktcphost, args.rtktcpport)