From 9be72d972c0680777f470e187df98d871badad2e Mon Sep 17 00:00:00 2001 From: Jakob Ketterl Date: Wed, 31 Jan 2024 02:06:33 +0100 Subject: [PATCH] add more options for mqtt --- owrx/config/defaults.py | 1 + owrx/controllers/settings/reporting.py | 25 +++++++++++++++-- owrx/form/input/__init__.py | 7 +++++ owrx/reporting/mqtt.py | 38 +++++++++++++++++++------- 4 files changed, 58 insertions(+), 13 deletions(-) diff --git a/owrx/config/defaults.py b/owrx/config/defaults.py index 0c33a085..3f9be5d0 100644 --- a/owrx/config/defaults.py +++ b/owrx/config/defaults.py @@ -177,4 +177,5 @@ defaultConfig = PropertyLayer( wsprnet_callsign="N0CALL", mqtt_enabled=False, mqtt_host="localhost", + mqtt_use_ssl=False, ).readonly() diff --git a/owrx/controllers/settings/reporting.py b/owrx/controllers/settings/reporting.py index 19336bd5..5fb5a3ec 100644 --- a/owrx/controllers/settings/reporting.py +++ b/owrx/controllers/settings/reporting.py @@ -2,7 +2,7 @@ from owrx.controllers.settings import SettingsFormController, SettingsBreadcrumb from owrx.form.section import Section from owrx.form.input.converter import OptionalConverter from owrx.form.input.aprs import AprsBeaconSymbols, AprsAntennaDirections -from owrx.form.input import TextInput, CheckboxInput, DropdownInput, NumberInput +from owrx.form.input import TextInput, CheckboxInput, DropdownInput, NumberInput, PasswordInput from owrx.form.input.validator import AddressAndOptionalPortValidator from owrx.breadcrumb import Breadcrumb, BreadcrumbItem @@ -29,7 +29,7 @@ class ReportingController(SettingsFormController): infotext="This callsign will be used to send data to the APRS-IS network", ), TextInput("aprs_igate_server", "APRS-IS server"), - TextInput("aprs_igate_password", "APRS-IS network password"), + PasswordInput("aprs_igate_password", "APRS-IS network password"), CheckboxInput( "aprs_igate_beacon", "Send the receiver position to the APRS-IS network", @@ -99,10 +99,29 @@ class ReportingController(SettingsFormController): ), TextInput( "mqtt_host", - "MQTT Broker address", + "Broker address", infotext="Addresss of the MQTT broker to send decodes to (address[:port])", validator=AddressAndOptionalPortValidator(), ), + TextInput( + "mqtt_client_id", + "Client ID", + converter=OptionalConverter(), + ), + TextInput( + "mqtt_user", + "Username", + converter=OptionalConverter(), + ), + PasswordInput( + "mqtt_password", + "Password", + converter=OptionalConverter(), + ), + CheckboxInput( + "mqtt_use_ssl", + "Use SSL", + ), TextInput( "mqtt_topic", "MQTT topic", diff --git a/owrx/form/input/__init__.py b/owrx/form/input/__init__.py index 3366b7ab..eb9588dc 100644 --- a/owrx/form/input/__init__.py +++ b/owrx/form/input/__init__.py @@ -112,6 +112,13 @@ class TextInput(Input): return TextConverter() +class PasswordInput(TextInput): + def input_properties(self, value, errors): + props = super().input_properties(value, errors) + props["type"] = "password" + return props + + class NumberInput(Input): def __init__(self, id, label, infotext=None, append="", converter: Converter = None, validator: Validator = None): super().__init__(id, label, infotext, converter=converter, validator=validator) diff --git a/owrx/reporting/mqtt.py b/owrx/reporting/mqtt.py index 4ef759bb..208f9f7c 100644 --- a/owrx/reporting/mqtt.py +++ b/owrx/reporting/mqtt.py @@ -16,35 +16,53 @@ class MqttReporter(Reporter): def __init__(self): pm = Config.get() - self.client = Client() self.topic = self.DEFAULT_TOPIC + self.client = self._getClient() self.subscriptions = [ - pm.wireProperty("mqtt_host", self._setHost), pm.wireProperty("mqtt_topic", self._setTopic), + pm.filter("mqtt_host", "mqtt_user", "mqtt_password", "mqtt_client_id", "mqtt_use_ssl").wire(self._reconnect) ] self.run = True threading.Thread(target=self._loop).start() + def _getClient(self): + pm = Config.get() + clientId = pm["mqtt_client_id"] if "mqtt_client_id" in pm else "" + client = Client(clientId) + + if "mqtt_user" in pm and "mqtt_password" in pm: + client.username_pw_set(pm["mqtt_user"], pm["mqtt_password"]) + + port = 1883 + if pm["mqtt_use_ssl"]: + client.tls_set() + port = 8883 + + parts = pm["mqtt_host"].split(":") + host = parts[0] + if len(parts) > 1: + port = int(parts[1]) + client.connect(host=host, port=port) + + return client + def _loop(self): # basic keepalive loop while self.run: self.client.loop() time.sleep(5) - def _setHost(self, host): - logger.debug("setting host to %s", host) - self.client.disconnect() - parts = host.split(":") - host = parts[0] - port = int(parts[1]) if len(parts) > 1 else 1883 - self.client.connect(host=host, port=port) - def _setTopic(self, topic): if topic is PropertyDeleted: self.topic = self.DEFAULT_TOPIC else: self.topic = topic + def _reconnect(self, *args, **kwargs): + old = self.client + self.client = self._getClient() + old.disconnect() + def stop(self): self.run = False self.client.disconnect()