diff --git a/app/src/mqtt.py b/app/src/mqtt.py
index 0d33cac..cab0766 100644
--- a/app/src/mqtt.py
+++ b/app/src/mqtt.py
@@ -7,13 +7,18 @@ from modbus import Modbus
from messages import Message
from cnf.config import Config
from singleton import Singleton
+from datetime import datetime
+
logger_mqtt = logging.getLogger('mqtt')
class Mqtt(metaclass=Singleton):
- __client = None
+ __client: aiomqtt.Client = None
__cb_mqtt_is_up = None
+ ctime = None
+ published: int = 0
+ received: int = 0
def __init__(self, cb_mqtt_is_up):
logger_mqtt.debug('MQTT: __init__')
@@ -52,6 +57,7 @@ class Mqtt(metaclass=Singleton):
| int | float | None = None) -> None:
if self.__client:
await self.__client.publish(topic, payload)
+ self.published += 1
async def __loop(self) -> None:
mqtt = Config.get('mqtt')
@@ -69,6 +75,9 @@ class Mqtt(metaclass=Singleton):
try:
async with self.__client:
logger_mqtt.info('MQTT broker connection established')
+ self.ctime = datetime.now()
+ self.published = 0
+ self.received = 0
if self.__cb_mqtt_is_up:
await self.__cb_mqtt_is_up()
@@ -84,6 +93,8 @@ class Mqtt(metaclass=Singleton):
await self.dispatch_msg(message)
except aiomqtt.MqttError:
+ self.ctime = None
+
if Config.is_default('mqtt'):
logger_mqtt.info(
"MQTT is unconfigured; Check your config.toml!")
@@ -101,11 +112,14 @@ class Mqtt(metaclass=Singleton):
return
except Exception:
# self.inc_counter('SW_Exception') # fixme
+ self.ctime = None
logger_mqtt.error(
f"Exception:\n"
f"{traceback.format_exc()}")
async def dispatch_msg(self, message):
+ self.received += 1
+
if message.topic.matches(self.ha_status_topic):
status = message.payload.decode("UTF-8")
logger_mqtt.info('Home-Assistant Status:'
diff --git a/app/src/server.py b/app/src/server.py
index 32c06aa..f9f8206 100644
--- a/app/src/server.py
+++ b/app/src/server.py
@@ -145,6 +145,10 @@ def main(): # pragma: no cover
serv_name = os.getenv('SERVICE_NAME', 'proxy')
version = os.getenv('VERSION', 'unknown')
+ @app.context_processor
+ def utility_processor():
+ return dict(version=version)
+
setattr(logging.handlers, "log_path", args.log_path)
setattr(logging.handlers, "log_backups", args.log_backups)
os.makedirs(args.log_path, exist_ok=True)
diff --git a/app/src/web/conn_table.py b/app/src/web/conn_table.py
index 62c52f7..ae6fe38 100644
--- a/app/src/web/conn_table.py
+++ b/app/src/web/conn_table.py
@@ -48,6 +48,7 @@ def _get_row(inv: InverterBase):
def get_table_data():
'''build the connection table'''
table = {
+ "headline": _('Connections'),
"col_classes": [
"w3-hide-small w3-hide-medium", "w3-hide-large",
"",
@@ -75,7 +76,7 @@ async def data_fetch():
"proxy-cnt": f"
{Infos.get_counter('ProxyMode_Cnt')}
",
"emulation-cnt": f"{Infos.get_counter('EmuMode_Cnt')}
",
}
- data["conn-table"] = await render_template('templ_conn_table.html.j2',
+ data["conn-table"] = await render_template('templ_table.html.j2',
table=get_table_data())
data["notes-list"] = await render_template('templ_notes_list.html.j2')
diff --git a/app/src/web/log_files.py b/app/src/web/log_files.py
index fccbd7e..772e292 100644
--- a/app/src/web/log_files.py
+++ b/app/src/web/log_files.py
@@ -40,7 +40,6 @@ async def file_fetch():
data["file-list"] = await render_template('templ_log_files_list.html.j2',
dir_list=get_list_data())
- data["notes-list"] = await render_template('templ_notes_list.html.j2')
return data
diff --git a/app/src/web/mqtt_table.py b/app/src/web/mqtt_table.py
new file mode 100644
index 0000000..fcd0477
--- /dev/null
+++ b/app/src/web/mqtt_table.py
@@ -0,0 +1,58 @@
+from inverter_base import InverterBase
+from quart import render_template
+from quart_babel import format_datetime, _
+from mqtt import Mqtt
+
+from . import web
+
+
+def _get_row(inv: InverterBase):
+ '''build one row for the connection table'''
+ entity_prfx = inv.entity_prfx
+ inv_serial = inv.local.stream.inv_serial
+ node_id = inv.local.stream.node_id
+ sug_area = inv.local.stream.sug_area
+
+ row = []
+ row.append(inv_serial)
+ row.append(entity_prfx+node_id)
+ row.append(sug_area)
+ return row
+
+
+def get_table_data():
+ '''build the connection table'''
+ table = {
+ "headline": _('MQTT devices'),
+ "col_classes": [
+ "",
+ "",
+ "",
+ ],
+ "thead": [[
+ _("Serial-No"),
+ _('Node-ID'),
+ _('HA-Area'),
+ ]],
+ "tbody": []
+ }
+ for inverter in InverterBase:
+ table['tbody'].append(_get_row(inverter))
+
+ return table
+
+
+@web.route('/mqtt-fetch')
+async def mqtt_fetch():
+ mqtt = Mqtt(None)
+ ctime = format_datetime(dt=mqtt.ctime, format='short')
+ data = {
+ "update-time": format_datetime(format="medium"),
+ "mqtt-ctime": f"{ctime}
",
+ "mqtt-tx": f"{mqtt.published}
",
+ "mqtt-rx": f"{mqtt.received}
",
+ }
+ data["mqtt-table"] = await render_template('templ_table.html.j2',
+ table=get_table_data())
+
+ return data
diff --git a/app/src/web/pages.py b/app/src/web/pages.py
index b16c189..f365239 100644
--- a/app/src/web/pages.py
+++ b/app/src/web/pages.py
@@ -11,9 +11,11 @@ async def index():
fetch_url=url_for('.data_fetch'))
-@web.route('/page')
-async def empty():
- return await render_template('empty.html.j2')
+@web.route('/mqtt')
+async def mqtt():
+ return await render_template(
+ 'page_mqtt.html.j2',
+ fetch_url=url_for('.mqtt_fetch'))
@web.route('/logging')
diff --git a/app/src/web/templates/base.html.j2 b/app/src/web/templates/base.html.j2
index 55f8e3c..34b6f57 100644
--- a/app/src/web/templates/base.html.j2
+++ b/app/src/web/templates/base.html.j2
@@ -41,12 +41,12 @@