integrated send mqtt message; optimised tui; logging added
This commit is contained in:
parent
011ee98477
commit
b3db98346f
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +1,6 @@
|
||||
[submodule "mqtt"]
|
||||
path = mqtt
|
||||
url = https://git.mount-mockery.de/pylib/mqtt.git
|
||||
[submodule "report"]
|
||||
path = report
|
||||
url = https://git.mount-mockery.de/pylib/report.git
|
||||
|
@ -1,19 +1,24 @@
|
||||
import argparse
|
||||
import config
|
||||
import getpass
|
||||
import json
|
||||
import logging
|
||||
import mqtt
|
||||
import re
|
||||
import report
|
||||
import time
|
||||
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.containers import Vertical
|
||||
from textual.widgets import Footer, Header, Input, RichLog
|
||||
from textual.widgets import Footer, Header, Input, RichLog, Button
|
||||
|
||||
try:
|
||||
from config import APP_NAME as ROOT_LOGGER_NAME
|
||||
except ImportError:
|
||||
ROOT_LOGGER_NAME = 'root'
|
||||
logger = logging.getLogger(ROOT_LOGGER_NAME)
|
||||
|
||||
|
||||
# TODO: Integrate sending of message (topic + payload)
|
||||
|
||||
class MqttReceiver(object):
|
||||
class MqttHandler(object):
|
||||
def __init__(self, app):
|
||||
self.app = app
|
||||
args = app.args
|
||||
@ -22,9 +27,18 @@ class MqttReceiver(object):
|
||||
self.mqtt_client = mqtt.mqtt_client('mqtt_sniffer', args.hostname, args.port, username=args.username, password=password)
|
||||
self.mqtt_client.add_callback("#", self.__rx__)
|
||||
|
||||
def __get_logger__(self, prefix, topic):
|
||||
return logging.getLogger(ROOT_LOGGER_NAME).getChild(prefix + '.' + topic.replace('/', '.'))
|
||||
|
||||
def __rx__(self, client, userdata, message):
|
||||
logger = self.__get_logger__('rx', message.topic)
|
||||
logger.debug("Received message: topic=%s, payload=%s type=%s", message.topic, repr(message.payload), repr(type(message.payload)))
|
||||
self.app.call_from_thread(self.app.add_log, message)
|
||||
|
||||
def send(self, topic, payload):
|
||||
logger = self.__get_logger__('tx', topic)
|
||||
logger.debug("Sending message: topic=%s, payload=%s type=%s", topic, repr(payload), repr(type(payload)))
|
||||
self.mqtt_client.send(topic, payload)
|
||||
|
||||
class MqttSniffer(App):
|
||||
"""a textual application for viewing mqtt messages."""
|
||||
@ -38,8 +52,11 @@ class MqttSniffer(App):
|
||||
self.args = args
|
||||
self.password = password
|
||||
#
|
||||
self.mqtt = None
|
||||
self.all_logs = []
|
||||
self.topic_filter = ""
|
||||
self.send_topic = ""
|
||||
self.send_payload = ""
|
||||
self.log_display = RichLog(highlight=True, markup=True)
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
@ -49,11 +66,14 @@ class MqttSniffer(App):
|
||||
yield self.log_display
|
||||
with Vertical(id="bottom-bar"):
|
||||
yield Input(placeholder="topic filter...", id="topic_filter")
|
||||
yield Input(placeholder="topic...", id="send_topic")
|
||||
yield Input(placeholder="payload...", id="send_payload")
|
||||
yield Button("Send", variant="success", id="send_button")
|
||||
yield Footer()
|
||||
|
||||
def on_mount(self) -> None:
|
||||
"""start the mqtt receiver."""
|
||||
MqttReceiver(self)
|
||||
self.mqtt = MqttHandler(self)
|
||||
|
||||
def add_log(self, record) -> None:
|
||||
"""Add new mqt messages and update the tui."""
|
||||
@ -74,15 +94,10 @@ class MqttSniffer(App):
|
||||
pass # No valid regular expression
|
||||
|
||||
if topic_match:
|
||||
try:
|
||||
payload = json.loads(record.payload)
|
||||
except:
|
||||
payload = record.payload.decode('utf-8')
|
||||
|
||||
message = (
|
||||
f"[[dim]{asctime}[/dim]] "
|
||||
f"[bold]{record.topic}[/bold] - "
|
||||
f"{repr(payload)}"
|
||||
f"{repr(record.payload)}"
|
||||
)
|
||||
|
||||
self.log_display.write(message)
|
||||
@ -94,14 +109,29 @@ class MqttSniffer(App):
|
||||
self._apply_filters_to_log(record)
|
||||
|
||||
def on_input_changed(self, message: Input.Changed) -> None:
|
||||
"""Update the filter and filtered messages after the user did changes."""
|
||||
"""Update the tui inputs and execute task, if requireed."""
|
||||
if message.input.id == "topic_filter":
|
||||
self.topic_filter = message.value
|
||||
|
||||
self._update_display()
|
||||
elif message.input.id == "send_topic":
|
||||
self.send_topic = message.value
|
||||
elif message.input.id == "send_payload":
|
||||
self.send_payload = message.value
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
"""Event handler called when a button is pressed."""
|
||||
if event.button.id == "send_button":
|
||||
if self.mqtt is not None:
|
||||
self.mqtt.send(self.send_topic, self.send_payload)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
#
|
||||
# Logging
|
||||
#
|
||||
if config.DEBUG:
|
||||
report.appLoggingConfigure(None, None, ((config.APP_NAME, logging.DEBUG), ), target_level=logging.WARNING, fmt=report.SHORT_FMT, host='localhost', port=19996)
|
||||
|
||||
#
|
||||
# Parse Arguments
|
||||
#
|
||||
|
1
report
Submodule
1
report
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 74e6f20d09cf76b3fbbdfa04c192b01708e50d5d
|
22
style.tcss
22
style.tcss
@ -2,16 +2,30 @@
|
||||
layout: vertical;
|
||||
overflow-y: scroll;
|
||||
scrollbar-gutter: stable;
|
||||
height: 89%;
|
||||
height: 1fr;
|
||||
}
|
||||
|
||||
#bottom-bar {
|
||||
layout: grid;
|
||||
grid-size: 1;
|
||||
height: 11%;
|
||||
grid-size: 4;
|
||||
grid-columns: 3fr 2fr 2fr 1fr;
|
||||
height: 4;
|
||||
border-top: solid $primary;
|
||||
}
|
||||
|
||||
#module_filter {
|
||||
#topic_filter {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#send_button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#send_topic {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#send_payload {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user