Skip to content

[ESP32] Add Web-Based TLV Log Visualization Tool for Collected Diagnostics in Temperature Measurement app #38829

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions examples/temperature-measurement-app/esp32/parser/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Matter TLV Log Visualizer

This tool provides a web-based interface for visualizing and analyzing TLV
(Tag-Length-Value) log data from Matter devices. It consists of a Python Flask
server for parsing TLV files and a web app for visualization.

## Features

- Upload and parse TLV log files
- Interactive charts and visualizations
- Timeline view of PAKE/Sigma messages
- Statistical analysis of log data
- Detailed table view of all entries

## Requirements

- Python 3.6+
- Matter SDK (CHIP)
- Flask web server

## Installation

1. Install the required Python packages:

```
pip install -r requirements.txt
```

2. Set the `CHIP_HOME` environment variable to point to your Matter (CHIP) SDK
installation:
```
export CHIP_HOME=/path/to/connectedhomeip
```

## Usage

1. Start the server:

```
python tlv_server.py
```

2. Open a web browser and navigate to:

```
http://localhost:8000
```

3. Upload a TLV log file or paste log data manually.

4. View visualizations across different tabs:
- Overview: Summary of message types
- Timeline: PAKE/Sigma message sequence
- All Entries: Complete table of log entries
- Statistics: Detailed analysis of the data

## Data Format

The tool expects TLV data with the following structure:

- Timestamp (tag 0)
- Label (tag 1)
- Value (tag 2)

## Troubleshooting

If you encounter import errors related to `chip.tlv`, ensure:

1. The `CHIP_HOME` environment variable is set correctly
2. The Matter SDK is properly installed
3. The Python path includes the Matter controller directory
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
flask==2.0.1
werkzeug==2.0.1
73 changes: 73 additions & 0 deletions examples/temperature-measurement-app/esp32/parser/tlv_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import os
import sys

from flask import Flask, jsonify, request, send_from_directory
from werkzeug.utils import secure_filename

CHIP_HOME = os.getenv("CHIP_HOME")

if not CHIP_HOME:
print("Error: Please set the CHIP_HOME environment variable.")
sys.exit(1)

sys.path.insert(0, os.path.join(CHIP_HOME, 'src/controller/python'))
try:
from chip.tlv import TLVReader
except ImportError:
print("chip.tlv module not found. Ensure CHIP_HOME is set correctly.")
sys.exit(1)

app = Flask(__name__)

UPLOAD_FOLDER = '/tmp'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER


@app.route('/')
def index():
"""Serve the HTML page"""
return send_from_directory('.', 'tlv_viewer.html')


@app.route('/parse_tlv', methods=['POST'])
def parse_tlv():
"""Handle TLV file uploads and return parsed data"""
if 'tlv_file' not in request.files:
return jsonify({'error': 'No file part'}), 400

file = request.files['tlv_file']
if file.filename == '':
return jsonify({'error': 'No selected file'}), 400

filename = secure_filename(file.filename)
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(file_path)

try:
with open(file_path, 'rb') as f:
binary_data = f.read()

binary_data = bytes([0x17]) + binary_data + bytes([0x18])

t = TLVReader(binary_data)
data = t.get()

entries = []
for tag, entry in data['Any']:
entries.append(entry)

formatted_entries = []
for entry in entries:
formatted_entries.append({
'timestamp': entry.get(0, 0),
'label': entry.get(1, ''),
'value': entry.get(2, '')
})

return jsonify(formatted_entries)
except Exception as e:
return jsonify({'error': str(e)}), 500


if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000, debug=True)
Loading
Loading