add more options for mqtt

This commit is contained in:
Jakob Ketterl 2024-01-31 02:06:33 +01:00
parent d0caf27672
commit 9be72d972c
4 changed files with 58 additions and 13 deletions

View file

@ -177,4 +177,5 @@ defaultConfig = PropertyLayer(
wsprnet_callsign="N0CALL",
mqtt_enabled=False,
mqtt_host="localhost",
mqtt_use_ssl=False,
).readonly()

View file

@ -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",

View file

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

View file

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