Skip to content

Commit

Permalink
Changes:
Browse files Browse the repository at this point in the history
Remove redundant name from log format
Update lora2mqtt to a non-blocking version
Fixed first boot settings
Revert to lighter SSH server: Dropbear
Fix topic parsing wrong setting
Change timesync behavior: from boot only sync to constant adjustments
  • Loading branch information
matteocarnelos committed May 3, 2022
1 parent 92ffbaa commit f060290
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 35 deletions.
10 changes: 5 additions & 5 deletions Automation_Custom_Script.sh
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
. /boot/dietpi/func/dietpi-globals

# Enable UART
G_CONFIG_INJECT "enable_uart=" "enable_uart=1" /boot/config.txt

# Remove unused components
G_EXEC rm /etc/systemd/system/dietpi-vpn.service
G_EXEC rm /etc/systemd/system/dietpi-cloudshell.service
/boot/dietpi/dietpi-software uninstall 0

# Install required packages
G_AGI telegraf
G_EXEC pip3 install paho-mqtt
G_EXEC pip3 install timeloop
G_EXEC pip3 install pyserial
G_EXEC pip3 install dpath
G_EXEC_OUTPUT=1 G_EXEC_OUTPUT_COL="\e[90m" G_EXEC pip3 install paho-mqtt timeloop pyserial dpath

# Enable services
G_CONFIG_INJECT "+ telegraf" "+ telegraf" /boot/dietpi/.dietpi-services_include_exclude
Expand All @@ -21,6 +20,7 @@ G_EXEC /boot/dietpi/dietpi-services dietpi_controlled sailtrack-lora2mqtt
G_EXEC /boot/dietpi/dietpi-services dietpi_controlled sailtrack-timesync

# Configure DietPi Banner
G_EXEC touch /boot/dietpi/.dietpi-banner
settings=(1 1 1 0 0 1 0 1 0 0 0 0 0 0 0 0)
for i in "${!settings[@]}"; do
G_CONFIG_INJECT "aENABLED\[$i]=" "aENABLED[$i]=${settings[$i]}" /boot/dietpi/.dietpi-banner
Expand Down
2 changes: 1 addition & 1 deletion dietpi.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ AUTO_SETUP_BACKUP_RESTORE=0

##### Software Options #####
# SSH server choice: 0=none/custom | -1=Dropbear | -2=OpenSSH
AUTO_SETUP_SSH_SERVER_INDEX=-2
AUTO_SETUP_SSH_SERVER_INDEX=-1

# Logging mode choice: 0=none/custom | -1=RAMlog 1h clear | -2=RAMlog 1h save clear | -3=rsyslog + logrotate
AUTO_SETUP_LOGGING_INDEX=-1
Expand Down
2 changes: 1 addition & 1 deletion rootfs/etc/sailtrack/sailtrack.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ username = mosquitto
password = dietpi

[log]
format = [%(name)s] [%(levelname)s] %(message)s
format = [%(levelname)s] %(message)s
2 changes: 1 addition & 1 deletion rootfs/etc/telegraf/telegraf.conf
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ omit_hostname = true
password = "${MQTT_PASSWORD}"
data_format = "json"
[[inputs.mqtt_consumer.topic_parsing]]
topic = "#"
topic = "+/+"
measurement = "_/measurement"
61 changes: 42 additions & 19 deletions sailtrack/sailtrack-lora2mqtt
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ from datetime import timedelta
from dpath.util import new
from paho.mqtt.client import Client
from serial import Serial
from timeloop import Timeloop

# -------------------------- Configuration -------------------------- #
from timeloop import Timeloop

LORA_READ_FREQ_HZ = 10
LOG_PRINT_FREQ_HZ = 0.1

MQTT_CLIENT_ID = "sailtrack-lora2mqtt"
CONFIG_FILE_PATH = "/etc/sailtrack/sailtrack.conf"

LORA_SERIAL_PORT_NAME = "/dev/ttyAMA0"
LORA_SERIAL_PORT_NAME = "/dev/serial0"
LORA_METRICS = (
("sensor/gps0", "fixType"),
("sensor/gps0", "epoch"),
Expand All @@ -30,12 +31,15 @@ LORA_METRICS = (
("sensor/imu0", "euler.z"),
)

LOG_JOB_INTERVAL_SEC = 1 / LOG_PRINT_FREQ_HZ
LORA_JOB_INTERVAL_MS = 1000 / LORA_READ_FREQ_HZ
LOG_JOB_INTERVAL_MS = 1000 / LOG_PRINT_FREQ_HZ

# ------------------------------------------------------------------- #

packet = ""
published_messages = 0
received_packets = 0
discarded_packets = 0


def on_publish_callback(client, userdata, mid):
Expand All @@ -49,32 +53,51 @@ mqtt = Client(MQTT_CLIENT_ID)
mqtt.username_pw_set(config["mqtt"]["username"], config["mqtt"]["password"])
mqtt.on_publish = on_publish_callback
mqtt.connect(config["mqtt"]["host"])
mqtt.loop_start()
tl = Timeloop()
formatter = logging.Formatter(config.get("log", "format", raw=True))
logging.getLogger("timeloop").handlers[0].setFormatter(formatter)
logger = logging.getLogger(MQTT_CLIENT_ID)
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter(config.get("log", "format", raw=True)))
handler.setFormatter(formatter)
logger.addHandler(handler)
ser = Serial(LORA_SERIAL_PORT_NAME)
tl.start()


@tl.job(interval=timedelta(seconds=LOG_JOB_INTERVAL_SEC))
def log_job():
logger.info(f"Published messages: {published_messages}, Received packets: {received_packets}")


ser.readline()
while True:
values = ser.readline().decode().split()
ser = Serial(LORA_SERIAL_PORT_NAME, timeout=0)


@tl.job(interval=timedelta(milliseconds=LORA_JOB_INTERVAL_MS))
def lora_job():
global packet
global received_packets
global discarded_packets
line = ser.readline()
if not line:
return
packet += line.decode()
if packet[-1] != "\n":
return
values = packet.split()
packet = ""
if len(values) != len(LORA_METRICS):
discarded_packets += 1
return
received_packets += 1
data = {}
for i, value in enumerate(values):
topic = LORA_METRICS[i][0]
name = LORA_METRICS[i][1]
if topic not in data:
data[topic] = {}
new(data[topic], name, value, separator=".")
for key, value in data.items():
mqtt.publish(key, json.dumps(value))
new(data[topic], name, eval(value), separator=".")
for topic, obj in data.items():
mqtt.publish(topic, json.dumps(obj))


@tl.job(interval=timedelta(milliseconds=LOG_JOB_INTERVAL_MS))
def log_job():
logger.info(f"Published messages: {published_messages}, "
f"Received packets: {received_packets}, "
f"Discarded packets: {discarded_packets}")


tl.start(block=True)
42 changes: 34 additions & 8 deletions sailtrack/sailtrack-timesync
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,39 @@ import json
import logging
import time
from configparser import ConfigParser
from datetime import timedelta

from paho.mqtt.client import Client
from timeloop import Timeloop

# -------------------------- Configuration -------------------------- #

TIMESYNC_DELTA_THRESHOLD = 1
LOG_PRINT_FREQ_HZ = 0.1

MQTT_CLIENT_ID = "sailtrack-timesync"
CONFIG_FILE_PATH = "/etc/sailtrack/sailtrack.conf"

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"]:
logger.info(f"Received epoch: {doc['epoch']}")
time.clock_settime(time.CLOCK_REALTIME, doc["epoch"])
logger.info("Time synced successfully!")
logger.info("Exiting...")
exit()
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


config = ConfigParser()
Expand All @@ -31,11 +45,23 @@ mqtt = Client(MQTT_CLIENT_ID)
mqtt.username_pw_set(config["mqtt"]["username"], config["mqtt"]["password"])
mqtt.on_message = on_message_callback
mqtt.connect(config["mqtt"]["host"])
mqtt.loop_start()
mqtt.subscribe("sensor/gps0")
tl = Timeloop()
formatter = logging.Formatter(config.get("log", "format", raw=True))
logging.getLogger("timeloop").handlers[0].setFormatter(formatter)
logger = logging.getLogger(MQTT_CLIENT_ID)
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter(config.get("log", "format", raw=True)))
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.info("Waiting for epoch...")
mqtt.loop_forever()


@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)

0 comments on commit f060290

Please sign in to comment.