Skip to content

CervezaStallone/XY-MD02_WebApp

XY-MD02 WebApp

A professional real-time climate monitoring dashboard application for the XY-MD02 sensor that reads, visualizes, and analyzes Modbus RTU data.

Features

  • Real-time monitoring: Live charts with automatic updates (1 second interval)
  • Historical data: Persistent storage in SQLite database with time filters (1 min to 6 months)
  • Database optimizations: Table-per-day partitioning, WAL mode, batch inserts for multi-year operation
  • Data retention: Configurable automatic cleanup of old data
  • Multiple measurements:
    • Temperature (°C)
    • Humidity (%)
    • Dew Point (calculated)
    • Absolute Humidity (g/m³)
    • Humidex (scientific comfort index)
    • Comfort Score (0-6, based on Humidex)
  • Psychrometric chart: Mollier diagram with live indicator and comfort zone visualization
  • Historical data replay: Time-travel through data with preset buttons or custom date/time selection
  • Interactive slider: Live updates while dragging for smooth historical navigation
  • Scientific analysis: Humidex formula according to Environment Canada standard
  • Multilingual: 5 languages fully supported (Dutch, English, German, French, Spanish)
  • Professional UI: Modern dashboard with gradient header and card-based layout
  • Zoom persistence: Graph zoom stays preserved during live updates
  • Robust: Extensive input validation and error handling
  • Configurable: All settings via .env file

Screenshots

Live Graphs

Live Graphs Real-time monitoring of temperature, humidity, dew point and absolute humidity with automatic updates

Psychrometric Chart (Mollier)

Mollier Diagram Interactive Mollier diagram with saturation line, RH curves, comfort zone and live indicator

Historical Data Selection

Date Picker Modal with preset buttons and custom date/time picker for historical data analysis

Requirements

  • Python 3.8+
  • Modbus RTU device (RS485)
  • Windows, Linux or macOS

Installation

  1. Clone the repository
git clone <repository-url>
cd XY-MD02_WebApp
  1. Create a virtual environment
python -m venv .venv
  1. Activate the virtual environment

Windows PowerShell:

.\.venv\Scripts\Activate.ps1

Windows CMD:

.venv\Scripts\activate.bat

Linux/macOS:

source .venv/bin/activate
  1. Install dependencies
pip install -r requirements.txt
  1. Configure the application

Copy the example configuration file:

cp .env.example .env

Adjust the settings in .env:

# Modbus Settings
MODBUS_PORT=COM11
MODBUS_SLAVE_ID=1
MODBUS_BAUDRATE=9600
MODBUS_BYTESIZE=8
MODBUS_PARITY=N
MODBUS_STOPBITS=1
MODBUS_TIMEOUT=1
MODBUS_FUNCTION_CODE=4
MODBUS_REGISTER_TEMP=1
MODBUS_REGISTER_HUMIDITY=2

# Database Settings
DATABASE_FILE=src/modbus_sensor_data.db
DATA_RETENTION_DAYS=0

# Application Settings
APP_HOST=127.0.0.1
APP_PORT=8050
APP_DEBUG=False
DEBUG_LOGGING=False
TIMEZONE=Europe/Amsterdam
DEFAULT_LANGUAGE=EN
  1. Start the application
python app.py

The application is now available at: http://127.0.0.1:8050/

Project Structure

XY-MD02_WebApp/
├── app.py                      # Main entry point (45 lines)
├── database.py                 # Database operations, partitioning, WAL mode
├── modbus_reader.py            # Modbus RTU communication, batch buffering
├── psychrometric.py            # Mollier diagram generation
├── callbacks.py                # Dash callbacks (7 functions)
├── layout.py                   # HTML layout and CSS styling
├── translations.py             # Multilingual system (NL/EN)
├── test_app.py                 # Automated test suite (15 tests)
├── .env                        # Configuration (not in git)
├── .env.example                # Example configuration
├── requirements.txt            # Python dependencies
├── .gitignore                  # Git exclude rules
├── README.md                   # This file
└── src/                        # Data directory
    └── modbus_sensor_data.db   # SQLite database (not in git)

Configuration

Modbus Settings

  • MODBUS_PORT: Serial port (e.g. COM11, /dev/ttyUSB0)
  • MODBUS_SLAVE_ID: Slave ID of the device
  • MODBUS_BAUDRATE: Baudrate (9600, 19200, etc.)
  • MODBUS_BYTESIZE: Number of data bits (8)
  • MODBUS_PARITY: Parity bit (N = None, E = Even, O = Odd)
  • MODBUS_STOPBITS: Stop bits (1, 2)
  • MODBUS_TIMEOUT: Timeout in seconds
  • MODBUS_FUNCTION_CODE: Modbus function code (4 = Read Input Registers)
  • MODBUS_REGISTER_TEMP: Register number for temperature
  • MODBUS_REGISTER_HUMIDITY: Register number for humidity

Database Settings

  • DATABASE_FILE: Path to the SQLite database file
  • DATA_RETENTION_DAYS: Data retention in days (0 = infinite, otherwise number of days to keep data)

Application Settings

  • APP_HOST: Server host IP (127.0.0.1 for local)
  • APP_PORT: Server port (8050)
  • APP_DEBUG: Debug mode (True/False)
  • DEBUG_LOGGING: Enable verbose debug logging to console (True/False, default: False)
  • TIMEZONE: Timezone for timestamp display (e.g., Europe/Amsterdam, America/New_York)
  • DEFAULT_LANGUAGE: Default UI language (EN, NL, DE, FR, ES, default: EN)

Adding a New Language

  1. Open translations.py

  2. Add the language to LANGUAGE_NAMES:

LANGUAGE_NAMES = {
    'nl': 'Nederlands',
    'en': 'English',
    'de': 'Deutsch'  # New!
}
  1. Add the translations to TRANSLATIONS:
TRANSLATIONS = {
    'nl': { ... },
    'en': { ... },
    'de': {
        'title': 'Modbus Klimamonitor',
        'temperature': 'Temperatur',
        'humidity': 'Luftfeuchtigkeit',
        # ... all other keys
    }
}

The dropdown will be updated automatically!

Comfort Score & Humidex

The application uses the Humidex (Humidity Index) for scientific comfort calculation according to Environment Canada standard.

Humidex Formula

Humidex = T + 0.5555 × (e - 10)

where:

  • T = temperature in °C
  • e = vapor pressure saturation in hPa (calculated via dew point)

Comfort classification based on Humidex:

  • < 20: Too cold - Score 0
  • 20-27: Comfortably cool - Score 4
  • 27-30: Comfortable - Score 5
  • 30-35: Optimally comfortable - Score 6
  • 35-40: Some discomfort - Score 3
  • 40-46: Great discomfort, avoid physical exertion - Score 2
  • 46-54: Dangerous, heat cramps possible - Score 1
  • > 54: Heat stroke imminent - Score 0

Mollier Diagram (Psychrometric Chart)

The application displays an interactive psychrometric chart with:

  • Saturation line: 100% relative humidity curve
  • RH lines: 10%, 20%, ..., 90% relative humidity
  • Comfort zone: Marked area (20-26°C, 30-60% RH)
  • Live indicator: Real-time position of current climate condition (red star)
  • Historical marker: Orange marker when using historical replay
  • Humidity ratio: Y-axis shows absolute humidity in g water / kg dry air
  • Zoom & Pan: Full Plotly interactivity for detailed analysis

This diagram helps to see at a glance whether the climate condition is within the comfort zone and how it relates to saturation limits.

Historical Data Replay

The application offers advanced historical data analysis with two input methods:

Preset Buttons (Quick selection)

  • 5 min - Last 5 minutes
  • 10 min - Last 10 minutes
  • 30 min - Last 30 minutes
  • 1 hour - Last hour
  • 2 hours - Last 2 hours
  • 6 hours - Last 6 hours
  • 12 hours - Last 12 hours
  • 24 hours - Last day
  • 2 days - Last 2 days
  • Week - Last week
  • Month - Last month

Custom Range (Precision selection)

  • Click the "Custom..." button to open a modal
  • Choose start date and time (hour:minute)
  • Choose end date and time (hour:minute)
  • Supports same day selection for start and end
  • Hour selection: 0-23
  • Minute selection: 0-59

Timeline Slider

  • After selecting a period, an interactive slider appears
  • Drag the slider to "travel" back through time
  • Live updates while dragging: Chart updates immediately without releasing mouse
  • The psychrometric chart shows the climate condition position at that moment
  • Timestamp is displayed live in DD-MM HH:MM format

Usage:

  1. Click a preset button for quick analysis
  2. Or click "Custom..." for specific date/time selection
  3. Use the slider to navigate through historical data
  4. See how the climate condition changed over time in the Mollier diagram

Database Architecture

Optimizations

The application uses advanced SQLite optimizations for multi-year continuous operation:

Table-per-day Partitioning:

  • Dynamic table creation: measurements_YYYYMMDD (e.g. measurements_20251205)
  • Automatic table switching at midnight
  • UNION ALL queries across relevant day-tables
  • Smart table selection based on timerange
  • Instant cleanup via DROP TABLE (milliseconds vs minutes for DELETE+VACUUM)

Write Optimizations:

  • WAL mode (Write-Ahead Logging) for better concurrent performance
  • PRAGMA synchronous=NORMAL for faster commits
  • PRAGMA temp_store=MEMORY for temporary data in RAM
  • Batch inserts: 30-measurement buffer (30 seconds)
  • Persistent connection pooling in Modbus thread
  • 97% reduction in write transactions (86k/day → 2.9k/day)

Storage Optimizations:

  • Integer epoch timestamps instead of TEXT datetime (50% space saving)
  • Indexed timestamp columns per table
  • Configurable data retention with automatic cleanup

Performance Benefits:

  • Queries only scan relevant days (not entire database)
  • 10-100× faster batch inserts vs per-second commits
  • No table bloat over time due to partitioning
  • Sub-millisecond table drops for old data
  • Linear performance independent of dataset size

Database Schema (per table)

CREATE TABLE measurements_YYYYMMDD (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    timestamp INTEGER NOT NULL,  -- Unix epoch timestamp
    temperature REAL NOT NULL,
    humidity REAL NOT NULL,
    dewpoint REAL,
    absolute_humidity REAL
);
CREATE INDEX idx_measurements_YYYYMMDD_timestamp ON measurements_YYYYMMDD(timestamp);

Testing

The application includes an automated test suite:

python test_app.py

Test Coverage:

  • Calculations: Dew point, absolute humidity, Humidex formulas
  • Database: CRUD operations, queries, partitioned tables, integer timestamps
  • Translations: NL/EN key parity and completeness
  • Psychrometric chart: Chart generation, multi-language support
  • Data validation: Temperature and humidity ranges
  • Production database: Database existence and structure verification

All 15 tests must pass before committing new features.

Development

Generating requirements.txt

pip freeze > requirements.txt

Code Structure (Modular Architecture)

The codebase has been modularized for better maintainability:

  • app.py (45 lines): Clean entry point with app initialization
  • database.py (190 lines): Table-per-day partitioning, WAL mode, UNION queries, cleanup
  • modbus_reader.py (185 lines): Modbus RTU communication, batch buffering, validation
  • psychrometric.py (317 lines): Mollier diagram generation (current + historical)
  • callbacks.py (636 lines): 7 Dash callbacks for UI interaction
  • layout.py: UI components, modal system, styling
  • translations.py: Translation system (NL/EN)
  • test_app.py (320 lines): Automated test suite (15 tests)

Dependency Flow:

app.py
├── database.py (standalone)
├── modbus_reader.py → database.py
├── psychrometric.py → translations.py
├── callbacks.py → database.py, psychrometric.py, translations.py
└── layout.py → translations.py

Troubleshooting

Modbus connection problems

  • Check if the serial port is correct (MODBUS_PORT in .env)
  • Verify the baudrate and other serial settings
  • Check the register numbers in the device documentation

Database errors

  • Ensure the src/ folder exists
  • Check write permissions in the project folder

Port already in use

  • Change APP_PORT in .env to another port

License

This project is open source and available under the MIT License.

About

Professional real-time climate monitoring dashboard for XY-MD02 Modbus sensor with SQLite database, psychrometric charts, and 5-language support

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages