From 926c3e2af262aa21cbc1f86005a5d9a01a55554f Mon Sep 17 00:00:00 2001 From: Ziver Koc Date: Sun, 26 Mar 2023 00:53:39 +0100 Subject: [PATCH] Improved MQTT Broker and added overview page --- .../se/hal/daemon/HalMulticastDnsDaemon.java | 18 +++++-- logging.properties | 1 + .../hal-mqtt/resources/web/mqtt_overview.tmpl | 23 +++++++++ .../se/hal/plugin/mqtt/HalMqttController.java | 26 +++++----- .../plugin/mqtt/page/MqttOverviewPage.java | 49 +++++++++++++++++++ .../src/se/hal/plugin/mqtt/plugin.json | 4 +- 6 files changed, 103 insertions(+), 18 deletions(-) create mode 100644 plugins/hal-mqtt/resources/web/mqtt_overview.tmpl create mode 100644 plugins/hal-mqtt/src/se/hal/plugin/mqtt/page/MqttOverviewPage.java diff --git a/hal-core/src/se/hal/daemon/HalMulticastDnsDaemon.java b/hal-core/src/se/hal/daemon/HalMulticastDnsDaemon.java index fe4f486c..36f7b4ee 100644 --- a/hal-core/src/se/hal/daemon/HalMulticastDnsDaemon.java +++ b/hal-core/src/se/hal/daemon/HalMulticastDnsDaemon.java @@ -11,16 +11,18 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.logging.Level; import java.util.logging.Logger; -import static se.hal.HalContext.CONFIG_DNS_LOCAL_DOMAIN; - public class HalMulticastDnsDaemon implements HalDaemon { private static final Logger logger = LogUtil.getLogger(); + private static HalMulticastDnsDaemon instance; private MulticastDnsServer server; @Override - public void initiate(ScheduledExecutorService executor) { + public synchronized void initiate(ScheduledExecutorService executor) { + if (instance != null) + return; + String localDomain = HalContext.getStringProperty(HalContext.CONFIG_DNS_LOCAL_DOMAIN, "hal.local"); if (!localDomain.isEmpty()) { @@ -30,6 +32,8 @@ public class HalMulticastDnsDaemon implements HalDaemon { server = new MulticastDnsServer(); server.addEntry(localDomain, InetAddress.getLocalHost()); server.start(); + + instance = this; } catch (IOException e) { logger.log(Level.SEVERE, "Was unable to start mDNS Server.", e); } @@ -38,4 +42,12 @@ public class HalMulticastDnsDaemon implements HalDaemon { } } + public void addDnsEntry(String name, InetAddress ip) { + server.addEntry(name, ip); + } + + + public static HalMulticastDnsDaemon getInstance() { + return instance; + } } diff --git a/logging.properties b/logging.properties index 91a7b8b4..2383112d 100644 --- a/logging.properties +++ b/logging.properties @@ -15,6 +15,7 @@ java.util.logging.FileHandler.formatter = zutil.log.CompactLogFormatter zutil.level = ALL zutil.db.bean.level = INFO +zutil.net.http.HttpServer.level = FINE zutil.net.http.page.HttpFilePage.level = INFO zutil.net.dns.MulticastDnsServer.level = FINE diff --git a/plugins/hal-mqtt/resources/web/mqtt_overview.tmpl b/plugins/hal-mqtt/resources/web/mqtt_overview.tmpl new file mode 100644 index 00000000..548070c3 --- /dev/null +++ b/plugins/hal-mqtt/resources/web/mqtt_overview.tmpl @@ -0,0 +1,23 @@ +

MQTT Overview

+ +
+
+
+
Published Topic Data
+
+ + + + + + {{#topics}} + + + + + {{/topics}} +
TopicPublished Data
{{.getKey()}}
{{.getValue()}}
+
+
+
+
\ No newline at end of file diff --git a/plugins/hal-mqtt/src/se/hal/plugin/mqtt/HalMqttController.java b/plugins/hal-mqtt/src/se/hal/plugin/mqtt/HalMqttController.java index f42a018c..c3c3e365 100644 --- a/plugins/hal-mqtt/src/se/hal/plugin/mqtt/HalMqttController.java +++ b/plugins/hal-mqtt/src/se/hal/plugin/mqtt/HalMqttController.java @@ -24,6 +24,7 @@ package se.hal.plugin.mqtt; +import se.hal.daemon.HalMulticastDnsDaemon; import se.hal.intf.*; import se.hal.plugin.mqtt.device.HalMqttDeviceConfig; import se.hal.plugin.mqtt.device.HalMqttDeviceData; @@ -44,7 +45,6 @@ import java.util.logging.Logger; public class HalMqttController implements HalAutostartController, MqttSubscriptionListener, HalEventController { private final Logger logger = LogUtil.getLogger(); - private MulticastDnsServer mDns; private MqttBroker mqttBroker; private HashMap topics = new HashMap<>(); @@ -57,13 +57,13 @@ public class HalMqttController implements HalAutostartController, MqttSubscripti @Override public void initialize() { try { - InetAddress serverIp = InetUtil.getLocalInet4Address().get(0); - - logger.info("Starting up mDNS Server"); - mDns = new MulticastDnsServer(); - mDns.addEntry("_mqtt._tcp.local", serverIp); - mDns.addEntry("_hal._tcp.local", serverIp); - mDns.start(); + if (HalMulticastDnsDaemon.getInstance() != null) { + logger.info("Register MQTT in mDNS"); + InetAddress serverIp = InetUtil.getLocalInet4Address().get(0); + HalMulticastDnsDaemon.getInstance().addDnsEntry("_mqtt._tcp.local", serverIp); + } else { + logger.info("mDNS not available"); + } logger.info("Starting up MQTT Server"); mqttBroker = new MqttBroker(); @@ -83,12 +83,6 @@ public class HalMqttController implements HalAutostartController, MqttSubscripti @Override public void close(){ - if (mDns != null) { - logger.info("Shutting down mDNS Server"); - mDns.close(); - mDns = null; - } - if (mqttBroker != null) { logger.info("Shutting down MQTT Server"); mqttBroker.close(); @@ -115,6 +109,10 @@ public class HalMqttController implements HalAutostartController, MqttSubscripti } } + public MqttBroker getBroker() { + return mqttBroker; + } + // -------------------------- // Hal Methods // -------------------------- diff --git a/plugins/hal-mqtt/src/se/hal/plugin/mqtt/page/MqttOverviewPage.java b/plugins/hal-mqtt/src/se/hal/plugin/mqtt/page/MqttOverviewPage.java new file mode 100644 index 00000000..d43d1017 --- /dev/null +++ b/plugins/hal-mqtt/src/se/hal/plugin/mqtt/page/MqttOverviewPage.java @@ -0,0 +1,49 @@ +package se.hal.plugin.mqtt.page; + +import se.hal.HalContext; +import se.hal.intf.HalAbstractControllerManager; +import se.hal.intf.HalWebPage; +import se.hal.plugin.mqtt.HalMqttController; +import zutil.io.file.FileUtil; +import zutil.net.mqtt.MqttBroker; +import zutil.net.mqtt.MqttSubscriptionListener; +import zutil.parser.Templator; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + + +public class MqttOverviewPage extends HalWebPage implements MqttSubscriptionListener { + private static final String TEMPLATE = HalContext.RESOURCE_WEB_ROOT + "/mqtt_overview.tmpl"; + + private Map topicData = new HashMap<>(); + + + public MqttOverviewPage() { + super("mqtt_overview"); + super.getRootNav().createSubNav("Settings").createSubNav(this.getId(), "MQTT Overview").setWeight(9_000); + + HalMqttController controller = HalAbstractControllerManager.getController(HalMqttController.class); + MqttBroker broker = controller.getBroker(); + broker.addGlobalSubscriber(this); + } + + + @Override + public synchronized void dataPublished(String topic, byte[] data) { + topicData.put(topic, new String(data, StandardCharsets.UTF_8)); + } + + @Override + public Templator httpRespond( + Map session, + Map cookie, + Map request) + throws Exception { + + Templator tmpl = new Templator(FileUtil.find(TEMPLATE)); + tmpl.set("topics", topicData.entrySet()); + return tmpl; + } +} diff --git a/plugins/hal-mqtt/src/se/hal/plugin/mqtt/plugin.json b/plugins/hal-mqtt/src/se/hal/plugin/mqtt/plugin.json index 4757ef30..5fecee3e 100644 --- a/plugins/hal-mqtt/src/se/hal/plugin/mqtt/plugin.json +++ b/plugins/hal-mqtt/src/se/hal/plugin/mqtt/plugin.json @@ -2,6 +2,8 @@ "version": 0.1, "name": "Hal-MQTT", "interfaces": [ - {"se.hal.intf.HalAutostartController": "se.hal.plugin.mqtt.HalMqttController"} + {"se.hal.intf.HalAutostartController": "se.hal.plugin.mqtt.HalMqttController"}, + + {"se.hal.intf.HalWebPage": "se.hal.plugin.mqtt.page.MqttOverviewPage"} ] } \ No newline at end of file