diff --git a/app/src/mqtt.py b/app/src/mqtt.py index 0d33cac..e106ed2 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() @@ -82,8 +91,11 @@ class Mqtt(metaclass=Singleton): async for message in self.__client.messages: await self.dispatch_msg(message) + self.received += 1 except aiomqtt.MqttError: + self.ctime = None + if Config.is_default('mqtt'): logger_mqtt.info( "MQTT is unconfigured; Check your config.toml!") @@ -101,6 +113,7 @@ 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()}") diff --git a/app/src/web/mqtt_table.py b/app/src/web/mqtt_table.py new file mode 100644 index 0000000..44ef0bc --- /dev/null +++ b/app/src/web/mqtt_table.py @@ -0,0 +1,83 @@ +from inverter_base import InverterBase +from quart import render_template +from quart_babel import format_datetime, _ +from infos import Infos +from mqtt import Mqtt + +from . import web + + +def _get_device_icon(client_mode: bool): + '''returns the icon for the device conntection''' + if client_mode: + return 'fa-download fa-rotate-180' + + return 'fa-upload fa-rotate-180' + + +def _get_cloud_icon(emu_mode: bool): + '''returns the icon for the cloud conntection''' + if emu_mode: + return 'fa-cloud-arrow-up-alt' + + return 'fa-cloud' + + +def _get_row(inv: InverterBase): + '''build one row for the connection table''' + client_mode = inv.client_mode + inv_serial = inv.local.stream.inv_serial + icon1 = _get_device_icon(client_mode) + ip1, port1 = inv.addr + icon2 = '' + ip2 = '--' + port2 = '--' + + if inv.remote.ifc: + ip2, port2 = inv.remote.ifc.r_addr + icon2 = _get_cloud_icon(client_mode) + + row = [] + row.append(f' {ip1}:{port1}') + row.append(f' {ip1}') + row.append(inv_serial) + row.append(f' {ip2}:{port2}') + row.append(f' {ip2}') + return row + + +def get_table_data(): + '''build the connection table''' + table = { + "col_classes": [ + "w3-hide-small w3-hide-medium", "w3-hide-large", + "", + "w3-hide-small w3-hide-medium", "w3-hide-large", + ], + "thead": [[ + _('Device-IP:Port'), _('Device-IP'), + _("Serial-No"), + _("Cloud-IP:Port"), _("Cloud-IP") + ]], + "tbody": [] + } + for inverter in InverterBase: + table['tbody'].append(_get_row(inverter)) + + return table + + +@web.route('/mqtt-fetch') +async def mqtt_fetch(): + mqtt = Mqtt() + 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["conn-table"] = await render_template('templ_conn_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/empty.html.j2 b/app/src/web/templates/empty.html.j2 deleted file mode 100644 index 060dc0f..0000000 --- a/app/src/web/templates/empty.html.j2 +++ /dev/null @@ -1,9 +0,0 @@ -{% extends 'base.html.j2' %} - -{% block title %} TSUN Proxy - View {% endblock title%} -{% block menu2_class %}w3-blue{% endblock %} -{% block content %} -{% endblock content%} - -{% block footer %}{% endblock footer %} - diff --git a/app/src/web/templates/page_mqtt.html.j2 b/app/src/web/templates/page_mqtt.html.j2 new file mode 100644 index 0000000..6ca8c58 --- /dev/null +++ b/app/src/web/templates/page_mqtt.html.j2 @@ -0,0 +1,52 @@ +{% extends 'base.html.j2' %} + +{% block title %} TSUN Proxy - MQTT Status {% endblock title%} +{% block menu2_class %}w3-blue{% endblock %} +{% block headline %}  {{_('MQTT Overview')}}{% endblock headline %} +{% block content %} +
+
+
+
+
+
+

-

+
+
+

{{_('MQTT Connect Time')}}

+
{{_('Forwarding data to cloud')}}
+
+
+
+
+
+
+
+
+

-

+
+
+

{{_('MQTT Published Topics')}}

+
{{_('Established from device to proxy')}}
+
+
+
+
+
+
+
+
+

-

+
+
+

{{_('MQTT Received Topics')}}

+
{{_('Established from proxy to device')}}
+
+
+
+
+ +{% endblock content%} + +{% block footer %}{% endblock footer %} +