From 28ea71b647e1e40bc4701d9f8b7beda2540dfd68 Mon Sep 17 00:00:00 2001 From: rschoene <rene.schoene@tu-dresden.de> Date: Tue, 22 Jun 2021 19:37:43 +0200 Subject: [PATCH] add filtering --- main.py | 90 ++++++++++++++++++++++++++++++++++++++------------------ utils.py | 9 +++++- 2 files changed, 69 insertions(+), 30 deletions(-) diff --git a/main.py b/main.py index 0fbed9f..6902331 100644 --- a/main.py +++ b/main.py @@ -81,6 +81,7 @@ conversion_topics = { 'place-b/command': (cgv_connector_pb2.MergedSelection(), utils.format_command), 'place-b/reachability/arm1': (cgv_connector_pb2.Reachability(), utils.format_reachability), 'place-b/reachability/arm2': (cgv_connector_pb2.Reachability(), utils.format_reachability), + 'place-b/reachability/arm3': (cgv_connector_pb2.Reachability(), utils.format_reachability), } bytes_topics = [ @@ -174,7 +175,20 @@ app.layout = html.Div([ html.Button('Dummy Ready', id='send-dummy-ready', style=button_style_normal), ], className='row'), # dcc.Markdown("---"), - html.H3("MQTT Log"), + html.H2("Filtered MQTT Log"), + dcc.Textarea( + id='filtered-mqtt-log', + value="", + readOnly=True, + style={**textarea_style_normal, 'height': '400px', 'fontFamily': 'Consolas, monospace'} + ), + dcc.Checklist( + id='topics-to-filter', + options=[{'label': topic, 'value': topic} for topic in conversion_topics], + value=[topic for topic in conversion_topics], + labelStyle={'display': 'inline-block'} + ), + html.H2("MQTT Log"), dcc.Textarea( id='mqtt-log', value="", @@ -300,20 +314,29 @@ def send_complex(*_): @app.callback( + Output('filtered-mqtt-log', 'value'), Output('mqtt-log', 'value'), Output('javascriptLog', 'run'), + Output('topics-to-filter', 'options'), Input('every-1-second', 'n_intervals'), Input('clear-mqtt-log', 'n_clicks'), + Input('topics-to-filter', 'options'), + Input('topics-to-filter', 'value'), + State('filtered-mqtt-log', 'value'), State('mqtt-log', 'value'), State('should-scroll-mqtt-log', 'value') ) -def append_to_mqtt_log(_n_intervals, clear_n_clicks, value, should_scroll): +def append_to_mqtt_log(_n_intervals, clear_n_clicks, filter_options, topics_to_filter, + filtered_value, value, should_scroll): """ Periodically update mqtt log - :param _n_intervals: Unused value of intervals - :param clear_n_clicks: clear.n_clicks - :param value: current content of mqtt log - :param should_scroll: checkbox value whether to scroll to the end after update + :param (Input) _n_intervals: Unused value of intervals + :param (Input) clear_n_clicks: clear.n_clicks + :param (Input) filter_options: displayed topics to show in filtered log + :param (Input) topics_to_filter: topics to show in filtered log + :param (State) value: current content of mqtt log + :param (State) filtered_value: current content of filtered mqtt log + :param (State) should_scroll: checkbox value whether to scroll to the end after update :return: new content of mqtt log """ ctx = dash.callback_context @@ -322,34 +345,43 @@ def append_to_mqtt_log(_n_intervals, clear_n_clicks, value, should_scroll): trigger_id = ctx.triggered[0]['prop_id'].split('.')[0] if trigger_id == 'clear-mqtt-log': - return "", "" - - # assume trigger_id == 'every-1-second' - local_messages = [] - while not message_queue.empty(): - local_messages.append(message_queue.get_nowait()) - if local_messages: - if value: - value += "\n" - else: - value = "" - value += '\n'.join(local_messages) - # if max_topic.get_and_clear(): - # lines = value.split('\n') - # reformatted_lines = [] - # for line in lines: - # timestamp, topic, message = utils.parse_log_msg(line) - # print(f'{timestamp, topic, message}') - # reformatted_lines.append(utils.format_log_msg(topic, max_topic.max_mqtt_topic_length, - # message, timestamp=timestamp)) - # value = '\n'.join(reformatted_lines) + return "", "", "", filter_options + + if trigger_id == 'topics-to-filter': + filtered_value = "" + for line in value.split('\n'): + if utils.topic_match(topics_to_filter, line): + filtered_value += line + '\n' else: - return dash.no_update + # assume trigger_id == 'every-1-second' + local_messages = [] + while not message_queue.empty(): + local_messages.append(message_queue.get_nowait()) + if local_messages: + if value: + value += "\n" + else: + value = "" + value += '\n'.join(local_messages) + if not filtered_value: + filtered_value = "" + for msg in local_messages: + timestamp, topic, message = utils.parse_log_msg(msg) + topic = topic.replace(chr(65532), '') + topic_match = topic in topics_to_filter + if topic_match: + filtered_value += msg + "\n" + if topic not in filter_options: + filter_options.append({'label': topic, 'value': topic}) + else: + return dash.no_update log_cmd = ''' + var filtered_textarea = document.getElementById('filtered-mqtt-log'); + filtered_textarea.scrollTop = filtered_textarea.scrollHeight; var textarea = document.getElementById('mqtt-log'); textarea.scrollTop = textarea.scrollHeight; ''' if should_scroll else "" - return value, log_cmd + return filtered_value, value, log_cmd, filter_options @app.callback( diff --git a/utils.py b/utils.py index 89fc487..d4bcf48 100644 --- a/utils.py +++ b/utils.py @@ -30,12 +30,19 @@ def format_log_msg(topic: str, max_mqtt_topic_length: int, message: str, timesta def parse_log_msg(entry: str): - print("Parsing >", entry, "<") + # print("Parsing >", entry, "<") at_index = entry.index('@') bracket_index = entry.index(']') return entry[1:at_index].strip(), entry[at_index + 1:bracket_index].strip(), entry[bracket_index + 2:] +def topic_match(topics_to_filter, msg): + timestamp, topic, message = parse_log_msg(msg) + # replacing strange space characters + topic = topic.replace(chr(65532), '') + return topic in topics_to_filter + + def format_scene(scene: cgv_connector_pb2.Scene): result = "" for obj in scene.objects: -- GitLab