A complete, high-performance automated monitoring system for utility-scale solar photovoltaic (PV) plants. This project integrates Local LLMs (Qwen 2.5 Coder) for deep forensic analysis, extracts real-time telemetry from VCOM (meteocontrol.com) every 15 minutes, and serves a reactive, WebSocket-driven dark-mode dashboard.
Tip
AI-Search Ready: This repository is optimized for LLM indexing (see llms.txt).
System Status: β Active Forensic Analysis | β Remote AI Agent (High Speed) | β Concurrent Telegram Bot | β Production-Stable Orchestrator
Seamlessly integrates Qwen 3.5 9B via local Ollama (localhost) for plant diagnostics:
- Deep CSV Correlation: Automatically scans historic CSVs to verify startup behavior (e.g., "Early Hours" production checks).
- Hardened Data Loading: Custom
load_csvhelper with auto-column stripping and encoding detection (UTF-8/Latin-1) to handle SCADA formatting quirks. - Data Collision Shield: Built-in retries and historical fallbacks to prevent crashes during concurrent file writes by the Watchdog.
-
Concurrency: Fully multi-threaded; handles dozens of simultaneous AI requests without freezing.
-
Quick Shortcuts: Instant commands like
/alerts,/daily, and/status. -
Instant Feedback: Immediate "β³ Thinking..." status while the local GPU processes complex logic.
-
Stable Reliability: Hot-reload is controlled (semi-automated) to prevent excessive restarts during long extraction cycles, ensuring the browser session remains stable.
- Python 3.9+ (tested on 3.10, 3.11, 3.12, 3.14)
- Windows (native batch scripting; Linux/macOS may require path adjustments)
- Network access to meteocontrol.com and a writable network share (or local
extracted_data/)
# Clone the repository
git clone https://github.com/MuhammadAbbasi/VCOM-Automation.git
cd VCOM-Automation
# Install dependencies
pip install -r requirements.txt
# Install Playwright browsers
playwright install chromium
# Setup Configuration
cp config.json.example config.json
cp user_settings.json.example user_settings.json
# Edit config.json and user_settings.json with your credentials and preferences- Copy Files: Transfer the entire project folder to the new system.
- Environment: Re-run the installation steps above.
- Data Preservation: If you want to keep your history, ensure you copy the
extracted_data/folder, specifically thedashboard_data_*.jsonfiles. - Hardware: Ensure the new system has at least 8GB RAM and stable network access for the browser automation.
# Start all three services (extraction, analysis, dashboard)
python run_monitor.pyThen open your browser:
http://localhost:8080
Logs into VCOM every 10 minutes and scrapes 6 metrics:
- PR (Performance Ratio), Potenza AC, Corrente DC, Temperatura, Resistenza Isolamento, Irraggiamento.
Universal Login & Session Shield: Automatically handles both legacy VCOM login and modern Keycloak flows. Includes automated session-expiry detection and real-time Bootstrap modal dismissal (DOM-stripping method) to prevent extraction stalls.
- Scans for 6 anomaly types.
- Downtime Filter: Events < 9 minutes are automatically ignored to reduce noise.
- Dynamic Daylight: Detects plant start time from production data.
- Health Matrix: 36-inverters Γ 4 LEDs (PR | Temp | DC | AC).
- Downtime Tracker: Tracks production interruptions based on user-configured duration limits.
- Dynamic Configuration: Front-end "βοΈ SETTINGS" modal saves configurations to
user_settings.jsonacross reboots. - Premium Mission Control UI: A high-fidelity "Plant Reference Manual" footer providing:
- Technical Specifications: Accurate site metadata (12.625 MWp, 808 strings, 3 TX stations).
- Diagnostic Matrix: A color-coded SCADA guide with luminous LED status indicators.
- System Metadata: Real-time visibility into the forensic engine and AI inference nodes.
Data Push: FastAPI WebSockets stream real-time JSON updates continuously without page reloads.
VCOM Automation/
βββ vcom_monitor.py β Extraction loop (10-min cycle)
βββ extraction_code/ β 6 metric scrapers (sync-Playwright)
β βββ base_monitor.py β Shared login, nav, helpers
β βββ pr_monitor.py
β βββ potenza_ac_monitor.py
β βββ corrente_dc_monitor.py
β βββ resistenza_monitor.py
β βββ temperatura_monitor.py
β βββ irraggiamento_monitor.py
βββ processor_watchdog_final.py β Forensic analyzer (ACTIVE v4.2)
βββ processor_watchdog*.py β Legacy versions (reference only)
βββ dashboard/
β βββ app.py β FastAPI server
β βββ static/
β βββ index.html β Premium Glassmorphism UI
β βββ app.js
β βββ style.css β Outfit Typography & Luminous Accents
βββ run_monitor.py β Orchestrator (all 3 services)
βββ extracted_data/ β Generated at runtime
β βββ PR_YYYY-MM-DD.xlsx
β βββ Potenza_AC_YYYY-MM-DD.xlsx
β βββ ... (4 more metrics)
β βββ extraction_status.json β Real-time ingestion progress
β βββ dashboard_data_YYYY-MM-DD.json
βββ requirements.txt
Data Flow:
VCOM (meteocontrol)
β
vcom_monitor.py (Playwright scraper)
β
extracted_data/*.xlsx (daily rolling files)
β
processor_watchdog_final.py (file watcher + analyzer)
β
dashboard_data_YYYY-MM-DD.json (JSON snapshots)
β
dashboard/app.py (FastAPI background task broadasts JSON via WebSocket)
β
http://localhost:8080 (Reactive dark-mode UI with dynamic settings)
# VCOM Credentials
VCOM_USER=your_username
VCOM_PASS=your_password
VCOM_SYSTEM_ID=2144635
# Optional: Custom URLs (defaults to production VCOM)
VCOM_URL=https://vcom.meteocontrol.com/vcom/
DASHBOARD_PORT=8080Security Note: .env is in .gitignore β never commit credentials.
Adjust these constants to tune alerting:
# Line ~58 in processor_watchdog_final.py
PR_THRESHOLD = 85.0 # % (normalize to 0-100)
TEMP_CRITICAL = 45.0 # Β°C
TEMP_WARNING = 40.0 # Β°C
AC_HEALTHY_MIN = 5000 # W (during daylight)
DAYLIGHT_START = 7.0 # hours (07:00)
DAYLIGHT_END = 19.0 # hours (19:00)DC current expectations vary by time of day:
- Morning (07:00-12:00): Green β₯10A, Yellow β₯2A
- Afternoon (12:00-19:00): Green β₯5A, Yellow β₯0.5A
- Off-hours: Grey (no generation expected)
This prevents false alerts for normal late-afternoon power decline.
- π’ Green β Healthy (all metrics within thresholds)
- π‘ Yellow β Warning / Sub-optimal (e.g., thermal warning or slight DC deviation)
- π΄ Red β Critical (e.g., inverter tripped or severe low PR)
- βͺ Slate Grey β Communications Lost (Distinguished from warnings)
- β« Dark Grey β Off-hours / No data
- PR: π’β₯x% | π‘β₯y% | π΄<y% (active after 30m stabilization, handled dynamically)
- Temperature: π’β€xΒ°C | π‘β€yΒ°C | π΄>yΒ°C
- AC Power: Evaluated relatively: π’>95% Plant Avg | π΄<95% Plant Avg. Exceptions granted for low-POA conditions (<50 W/mΒ²).
- DC Current: Deep string deviations detected dynamically by checking internal MPPTs and domain-levels.
The watchdog applies deep diagnostic rules in priority order:
| Rule | Condition | Severity |
|---|---|---|
| Low PR | PR < thresholds after 30m stabilization period | π΄ Critical |
| High Temp | Temperature > configured limit | π΄ Critical |
| DC String Loss | String fault/open circuit/underperformance detected via dynamic MPPT comparison | π΄/π‘ Fault/Warning |
| Comms Loss | Data missing (x) for entire component | π‘ Warning |
| Inverter Trip / AC Power Loss | AC output deviates >5% below the plant average during nominal POA | π΄ Critical |
Historical alarms feature a category drop-down filter, and consecutive alerts on the same inverter/rule are deduplicated dynamically.
python run_monitor.pyOutput:
============================================================
[ORCHESTRATOR] Mazara SCADA Monitor System Control
============================================================
[*] Root Directory: \\S01\get\...\VCOM Automation
[*] Launching WATCHDOG (Forensic Analysis)...
[*] Launching EXTRACTION (VCOM Browser Automation)...
[*] DASHBOARD must be run separately: 'python dashboard/app.py'
------------------------------------------------------------
[ORCHESTRATOR] Started WATCHDOG (pid=12345)
[ORCHESTRATOR] Started EXTRACTION (pid=12346)
Check real-time logs:
# Extraction logs (browser automation)
tail -f monitoring.log
# Watchdog logs (analysis)
tail -f watchdog.log
# Dashboard logs (FastAPI)
# (outputs to console)Issue: Browser doesn't open VCOM login page
- Fix: Check network connectivity. Verify
VCOM_URLin.envis reachable.
Issue: "Valori minimi non disponibili" popup blocks extraction
- Fix: This is normal β the code automatically dismisses it. Wait 2-3 seconds for data to load.
Issue: Dashboard shows all grey LEDs
- Fix: Normal during off-hours (19:00-07:00). Check that
extracted_data/contains today's Excel files.
Issue: Memory usage grows over time
- Fix: Logs and old JSON files accumulate. Manually clean
extracted_data/files older than 7 days.
Issue: Port 8080 already in use
- Fix: Change
DASHBOARD_PORT=8080in.envor kill the process:lsof -ti :8080 | xargs kill -9
| File | Purpose |
|---|---|
ANALYSIS_FIX_SUMMARY.md |
Problem/solution analysis, thresholds, and migration guide |
DATA_STRUCTURE_AND_ANALYSIS.md |
Comprehensive data format docs for all 6 metrics |
analysis_method.md |
Forensic rule definitions and implementation details |
SYSTEM_PROMPT.md |
Plant topology (36 inverters, 14 sensors, string mapping) |
README.md |
This file |
- Duration: ~2-5 minutes per 10-minute cycle
- Data Format: Excel (openpyxl append mode)
- CSV Conversion: Automatic (ExcelβCSV for faster analysis)
- Memory: ~200-400 MB (no massive merges)
- Duration: <5 seconds per analysis run
- Method: Potenza_AC master + on-demand metric lookups
- Communication Channel: Persistent FastAPI WebSocket
- Response Time: Real-time push logic immediately on payload build
- Supported Browsers: Chrome, Firefox, Safari, Edge (dark mode compatible)
- Credentials: Stored in
.env(git-ignored) - Sensitive Data: Excel/CSV files stored in
extracted_data/(git-ignored) - Dashboard: Local-only (port 8080, no auth required β use firewall rules for production)
- Browser Automation: Headless Chromium, screenshots saved to
errors/on failure
For production deployment:
- Use HTTPS reverse proxy (nginx, Apache)
- Add authentication (e.g., Basic Auth, OAuth)
- Restrict network access to internal subnets
- Implement log rotation and archival
- System ID: 2144635
- Inverters: 36 total (TX1-01 through TX3-12)
- Topology: 3 transformers (TX1, TX2, TX3), 12 inverters each
- DC Strings: 12 MPPT channels per inverter
- Environmental Sensors: 14 (irradiance, temperature, etc.)
- Excluded Devices: SunGrow SG350HX (filtered in extraction)
| File | Status | Use Case |
|---|---|---|
processor_watchdog_final.py |
β ACTIVE | Production analyzer |
processor_watchdog.py |
Legacy reference | |
processor_watchdog_v2/v3.py |
β Archived | Old attempts, do not use |
- Create
extraction_code/new_metric_monitor.py - Import
base_monitorhelpers - Implement
extract_new_metric(page) -> pd.DataFrame - Add to
METRICSlist invcom_monitor.py - Update watchdog rules in
processor_watchdog_final.py
# Test extraction (single cycle)
python vcom_monitor.py
# Test analysis (on existing data)
python processor_watchdog_final.py
# Test dashboard (standalone)
cd dashboard && python app.py- Reference Implementation: https://github.com/MuhammadAbbasi/SCADA_monitoring_automation
- VCOM Platform: https://vcom.meteocontrol.com
- Playwright Docs: https://playwright.dev/python/
For bugs, feature requests, or questions, open an issue on GitHub.
This project is provided as-is. Adapt and use freely, but ensure compliance with VCOM's terms of service and local regulations for SCADA monitoring.
Last Updated: 2026-04-22 System Status: β Production-hardened with high-fidelity footer, verified site metadata (12.625 MWp), session protection, and premium dashboard UI.