From 16bdf3df9d3f92e3337dd6084259ff34f81f3c17 Mon Sep 17 00:00:00 2001 From: Dean Cording Date: Wed, 2 Mar 2022 15:15:37 +1000 Subject: [PATCH 1/3] Added systemd support for dish_grpc_mqtt --- dish_grpc_mqtt.py | 40 +++++++++++++++++++++++++++++++++-- systemd/starlink-mqtt.service | 12 +++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 systemd/starlink-mqtt.service diff --git a/dish_grpc_mqtt.py b/dish_grpc_mqtt.py index ccee65d..0fc4912 100644 --- a/dish_grpc_mqtt.py +++ b/dish_grpc_mqtt.py @@ -15,6 +15,8 @@ Where *id_value* is the *id* value from the dish status information. """ import logging +import os +import signal import sys import time import json @@ -32,6 +34,14 @@ import dish_common HOST_DEFAULT = "localhost" +class Terminated(Exception): + pass + + +def handle_sigterm(signum, frame): + # Turn SIGTERM into an exception so main loop can clean up + raise Terminated + def parse_args(): parser = dish_common.create_arg_parser(output_description="publish it to a MQTT broker", @@ -72,6 +82,29 @@ def parse_args(): else: parser.epilog += "\nSSL support options not available due to missing ssl module" + env_map = ( + ("MQTT_HOST", "hostname"), + ("MQTT_PORT", "port"), + ("MQTT_USERNAME", "username"), + ("MQTT_PASSWORD", "password"), + ("MQTT_SSL", "tls"), + ) + env_defaults = {} + for var, opt in env_map: + # check both set and not empty string + val = os.environ.get(var) + if val: + if var == "MQTT_SSL": + if val == "insecure": + env_defaults[opt] = False + elif val == "secure": + env_defaults[opt] = True + else: + env_defaults["ssl_ca_cert"] = val + else: + env_defaults[opt] = val + parser.set_defaults(**env_defaults) + opts = dish_common.run_arg_parser(parser, need_id=True) if opts.username is None and opts.password is not None: @@ -145,6 +178,8 @@ def main(): gstate = dish_common.GlobalState(target=opts.target) + signal.signal(signal.SIGTERM, handle_sigterm) + try: next_loop = time.monotonic() while True: @@ -155,10 +190,11 @@ def main(): time.sleep(next_loop - now) else: break + except Terminated: + pass finally: gstate.shutdown() - - sys.exit(rc) + sys.exit(rc) if __name__ == '__main__': diff --git a/systemd/starlink-mqtt.service b/systemd/starlink-mqtt.service new file mode 100644 index 0000000..5a11a4e --- /dev/null +++ b/systemd/starlink-mqtt.service @@ -0,0 +1,12 @@ +[Unit] +Description=Starlink GRPC to MQTT exporter +After=network.target + +[Service] +Type=simple +WorkingDirectory=/opt/starlink-grpc-tools/ +Environment=MQTT_HOST=localhost MQTT_PORT=1883 MQTT_USERNAME= MQTT_PASSORD= MQTT_SSL=false +ExecStart=/opt/starlink-grpc-tools/venv/bin/python3 dish_grpc_mqtt.py -t 10 status alert_detail + +[Install] +WantedBy=multi-user.target From 26437e00eaeb36eae87d45048d5bdacf97b7dddf Mon Sep 17 00:00:00 2001 From: Dean Cording Date: Wed, 2 Mar 2022 16:15:05 +1000 Subject: [PATCH 2/3] Typo fixed --- systemd/starlink-mqtt.service | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/systemd/starlink-mqtt.service b/systemd/starlink-mqtt.service index 5a11a4e..ab1b4ec 100644 --- a/systemd/starlink-mqtt.service +++ b/systemd/starlink-mqtt.service @@ -5,7 +5,7 @@ After=network.target [Service] Type=simple WorkingDirectory=/opt/starlink-grpc-tools/ -Environment=MQTT_HOST=localhost MQTT_PORT=1883 MQTT_USERNAME= MQTT_PASSORD= MQTT_SSL=false +Environment=MQTT_HOST=localhost MQTT_PORT=1883 MQTT_USERNAME= MQTT_PASSWORD= MQTT_SSL=false ExecStart=/opt/starlink-grpc-tools/venv/bin/python3 dish_grpc_mqtt.py -t 10 status alert_detail [Install] From 323fc26754a62fe005b233b80a2eabf10146b779 Mon Sep 17 00:00:00 2001 From: Dean Cording Date: Wed, 2 Mar 2022 21:22:01 +1000 Subject: [PATCH 3/3] Fix for NaN values on startup that upset Javascript JSON decoders --- dish_grpc_mqtt.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dish_grpc_mqtt.py b/dish_grpc_mqtt.py index 0fc4912..8f64878 100644 --- a/dish_grpc_mqtt.py +++ b/dish_grpc_mqtt.py @@ -20,6 +20,7 @@ import signal import sys import time import json +import math try: @@ -135,7 +136,9 @@ def loop_body(opts, gstate): if not "dish_{0}".format(category) in data: data["dish_{0}".format(category)] = {} - data["dish_{0}".format(category)].update({key: val}) + # Skip NaN values that occur on startup because they can upset Javascript JSON parsers + if not ((type(val) == float) and math.isnan(val)): + data["dish_{0}".format(category)].update({key: val}) def cb_add_sequence(key, val, category, _):