-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsailtrack-timesync
executable file
·72 lines (53 loc) · 2.18 KB
/
sailtrack-timesync
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
#!/usr/bin/env python3
# `sailtrack-timesync` - Python script that continuously listens to the `sensor/gps0` topic for a message that
# contains the `epoch` field, setting the system time accordingly to the received epoch. This is needed because the
# Raspberry Pi has no RTC clock built-in and will therefore lose track of the time and date as soon as it is shut
# down. Instead, SailTrack Radio has a built-in RTC clock for the GPS, and therefore it sends, along with the GPS
# data, the current time and date.
import json
import logging
import os
import time
from datetime import timedelta
from paho.mqtt.client import Client, CallbackAPIVersion
from timeloop import Timeloop
# -------------------------- Configuration -------------------------- #
TIMESYNC_DELTA_THRESHOLD = 1
LOG_PRINT_FREQ_HZ = 0.1
MQTT_CLIENT_ID = "sailtrack-timesync"
LOG_JOB_INTERVAL_MS = 1000 / LOG_PRINT_FREQ_HZ
# ------------------------------------------------------------------- #
received_epochs = 0
time_syncs = 0
delta = 0
def on_message_callback(client, userdata, message):
global received_epochs
global time_syncs
global delta
doc = json.loads(message.payload)
if "epoch" in doc and doc["epoch"]:
received_epochs += 1
delta = doc["epoch"] - int(time.time())
if abs(delta) > TIMESYNC_DELTA_THRESHOLD:
time.clock_settime(time.CLOCK_REALTIME, doc["epoch"])
time_syncs += 1
mqtt = Client(CallbackAPIVersion.VERSION1, MQTT_CLIENT_ID)
mqtt.username_pw_set("mosquitto", os.environ["SAILTRACK_GLOBAL_PASSWORD"])
mqtt.on_message = on_message_callback
mqtt.connect("localhost")
mqtt.loop_start()
mqtt.subscribe("sensor/gps0")
tl = Timeloop()
formatter = logging.Formatter("[%(levelname)s] %(message)s")
logging.getLogger("timeloop").handlers[0].setFormatter(formatter)
logger = logging.getLogger(MQTT_CLIENT_ID)
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger.addHandler(handler)
@tl.job(interval=timedelta(milliseconds=LOG_JOB_INTERVAL_MS))
def log_job():
logger.info(f"Received epochs: {received_epochs}, "
f"Time syncs: {time_syncs}, "
f"Delta: {delta}")
tl.start(block=True)