All notable user-facing changes in PowerScraper since the transition from the legacy Python implementation (commit 2c2227e5fbb7957aed1c77ad66eb0986f63ecfbf) are documented below.
- MQTT Driver & Forwarder Reconnection:
- Added automatic re-subscription on
ConnAckacross all MQTT drivers (mqtt_inverter,mqtt_meter,solax_modbus,solax_g3,solax_g4),MQTTForwarder, andPowerManagerto prevent telemetry loss following broker restarts or TCP reconnects. - Reduced disconnect backoff delay from 5s to 500ms for rapid session recovery.
- Set
driver_typeand populatedraw_metricsinInverterStatusfor MQTT Inverters so live registers display correctly in the Web UI Register Viewer modal.
- Added automatic re-subscription on
- Solax Inverter Advanced Configuration (Gen 3 & V2.50):
- Added full read/write support for all Modbus Function Code
0x06writable registers for Solax Gen 3 (V3.21) and older V2.50 inverters. - Dynamically generate configuration UI based on driver capabilities to ensure 100% exposure of writable hardware parameters.
- Implemented an auto-generated "⚙️ Other Settings" section for any unmapped write-only registers.
- Fixed API omissions to force-expose writable registers even if omitted from core telemetry reads.
- Added full read/write support for all Modbus Function Code
- UI Improvements:
- Restructured Charge and Discharge Window End time inputs to their own rows for better legibility.
- Configurable Auto Mode Energy Cost Margin Control:
- Added running calculation of stored battery energy unit cost based on charging sources (export price for solar charging, import price for grid charging).
- Added
auto_cost_margin(auto-cost-margin) configuration parameter toSolaxBatteryControlConfig(c/kWh). - Configured Auto mode regulation in both
PowerManagerlive control and historical simulation (auto.rs) to suppress battery discharging whenever stored battery unit cost + margin exceeds the current grid import price.
- Nagios / NEMS Compatible Health API Endpoints (
/health&/api/health):- Added REST endpoints that check telemetry freshness across all configured battery inverters.
- Returns
HTTP 200 OK("status": "healthy") when all battery inverters are online and updated within the last 60 seconds. - Returns
HTTP 503 Service Unavailable("status": "unhealthy") when any configured battery inverter is offline or stale (>60s since telemetry update), triggering standard Nagioscheck_httpCRITICAL alerts. - Returns detailed JSON payload containing status, epoch timestamp, total battery inverter count, healthy inverter count, and per-inverter update metrics.
- Nagios & NEMS Linux Integration:
- Configured and verified active service check
PowerScraper Healthon NEMS Linux server (root@monitor.lan).
- Configured and verified active service check
- History Chart Redesign & Unit Standardization:
- Standardized Solar Generation, Battery Power, Grid Power, and Household Usage history graphs to display in kW instead of Watts.
- Converted Battery Capacity history graph from percentage (%) to stored energy in kWh using inferred capacity or configured battery rating.
- Added stacked per-PV array rendering (PV1, PV2) on Solar Generation graph.
- Added split color coding on Grid Power graph: Green for feed-in (<0 kW) and Red for grid draw (>0 kW).
- Added smooth Green-to-Red color gradation to Household Usage graph.
- Added conditional hiding of PV array details in Location tab and History charts when an inverter has 'no pv' enabled.
- Server-Side Telemetry Decimation & Profiling:
- Implemented server-side mean-average bucket decimation using the
max_pixelsparameter to avoid over-fetching telemetry data. - Added microsecond profiling logs and
Server-TimingHTTP response headers (db,decimate,format,total).
- Implemented server-side mean-average bucket decimation using the
- Automatic Pre-Fetch Telemetry Flush:
- Added thread-safe
PENDING_HISTORYbuffer indatabase.rs. - Automatically flushes all pending in-memory telemetry to SQLite DB prior to serving
/api/historyqueries. - Flushes pending telemetry to SQLite on process shutdown, signal receipt (SIGTERM, SIGINT), and via
libc::atexithook.
- Added thread-safe
- Database Schema & Indexing:
- Split
telemetry_historytopic intodeviceandfieldcolumns with compound indicesidx_telemetry_history_field_timestampandidx_telemetry_history_device_field_timestamp. - Added non-blocking batched schema migration (
LIMIT 50000) on startup to prevent SQLite database locks. - Replaced serde_json allocations with zero-copy
TelemetryRecordRefserialization, reducing/api/historyquery duration from >4.6s to ~30ms (~160x speedup).
- Split
- SolaX Inverter Remote Control & Sign Alignments:
- Aligned Gen 3 (
solax_g3.rs) command writing for Holding Register0x0052with the0.xPythonSolaxXHybridModbusimplementation (passing target power as two's complement without extra negation). - Fixed battery power telemetry sign reporting across
solax_g3.rsandsolax_g4.rsby negating Input Register0x0016(-i16_a(0x16)), ensuring telemetry maps to PowerScraper's system-wide convention (battery_power > 0= Discharging). - Restored battery power telemetry negation in
solax_modbus.rs(-signed16_a(0x16)) for Gen 2 SK-SU inverters. - Corrected 32-bit Modbus word ordering (
high_word,low_word) forActivePowerTarget(0x007E) insolax_g4.rs.
- Aligned Gen 3 (
- Modbus Quiet Time & Rate Limiting: Added 200ms quiet-time inter-frame delays between consecutive Modbus write instructions to prevent packet drops.
- Inverter Identification Documentation: Added hardware generation matrix and serial prefix lookup table (
docs/inverters.md).
- Solax X-Hybrid Telemetry Expansion: Added parsing for missing Modbus input registers on X-Hybrid inverters (including Bus Voltage, DC Voltage Fault, Overload Fault, Battery Voltage Fault, BMS Connected, and Run Mode 2).
- EmonCMS Payload Serialization: Parse stringified metric values to their correct JSON numeric (integers, floats) and boolean types before submitting. This resolves the issue where EmonCMS rejected the payloads and stopped updating feeds.
- Web-Configurable Battery Charge Hysteresis: Added global and period-specific hysteresis options to prevent battery charging/discharging hunting (oscillation) near the minimum SOC limits (addresses issue #23).
- Hysteresis State Machine & Simulation Validation: Added a stateful
low_capacity_statetracker in the livePowerManagerloop and aligned the simulation run loop insrc/simulation/auto.rs. - Automated Tests for Hysteresis: Implemented comprehensive unit tests verifying state transitions of hysteresis logic, simulation engine accuracy, and Playwright UI config reload verification.
- Systemd Notify/Watchdog Protocol: Implemented native
sd_notifyintegration using raw Unix datagram sockets. The daemon now signalsREADY=1after startup, pingsWATCHDOG=1every 30 seconds when telemetry is healthy, and sendsSTOPPING=1on clean shutdown — enabling systemd to automatically detect and restart deadlocked or frozen processes. - SQLite WAL Checkpointing: Added
PRAGMA wal_checkpoint(TRUNCATE)after config saves and telemetry flushes to compact the WAL file and prevent unbounded storage growth on embedded targets.
- Systemd Service Type: Changed from
Type=simpletoType=notifywithWatchdogSec=180in the packaged service file. - Database Directory Permissions: Tightened
/var/lib/powerscraperfrom755to750to protect stored MQTT credentials and API tokens.
- REST API oneshot testing: Extracted Axum
Routerbuilder intobuild_web_appto allow rigorous programmatic requests testing (400 Bad Request, 404 Not Found, 415 Unsupported Media Type, and 422 Unprocessable Entity payload handling). - Database Write Error Fail-Safe tests: Expanded unit testing in
src/database.rsto verify rusqlite write failure recovery by passing directory paths to SQLite connections. - E2E Playwright test expansions: Added Test Cases 11 through 15 verifying historical simulation result cards, genetic algorithm model parameters tuning via SSE progress stream, dynamic capacity calculations on PV arrays, solar orientation inference correlation grid, and tariff Time-Of-Use periods.
- Mock Telemetry Seeding: Updated test server startup sequence to generate and seed a 1440-record double-peak household load, solar yield curve, battery charging, and flat electricity pricing data to enable simulation E2E tests.
- Test Coverage Expansion: Added extensive unit and integration tests across core configurations, tariff management, EmonCMS and InfluxDB telemetry forwarders, solar orientation inference, and evolved heuristics. Evaluated and justified untestable boundaries.
- SolaX Generation 4 (G4) Modbus Driver: Custom driver supporting the 32-bit Virtual Power Plant (VPP) active power holding registers (
0x007C,0x007E,0x0088). - SolaX Generation 3 (G3) Modbus Driver: Custom driver supporting 16-bit remote control overrides and watchdog keepalives using sparse input block queries to avoid illegal address exceptions.
- Mains Meter Watchdog Config: Watchdog timeout settings are now exposed directly on the Web UI Settings tab and saved to the database.
- Python Configuration Migration: Added automated TOML-to-database seeding on startup and an Import Config file upload button in the Web Dashboard for seamless migration.
- Pre-commit Hook Auto-Sync: The pre-commit hook now runs
cargo metadataand stagesCargo.lockautomatically to ensure version consistency.
- Top-up Period Charge Targets: Min-SoC charging logic now evaluates target thresholds as the maximum of the period's min-charge and the inverter's baseline hard floor limit (e.g., proper grid charging behavior during TOU windows).
- Realtime Modbus RTU Threading: Moved SDM630 and DTSU666 serial drivers to dedicated OS threads running with realtime priority (
SCHED_FIFO/ nice-20) to eliminate grid telemetry latency. - Lookahead MPC Reserve: Added support for grid pre-charging under demand tariffs in simulation.
- SQLite Database Layer: Factored out all direct query logic into a repository module leveraging WAL (Write-Ahead Logging) mode and busy timeouts.
- Tuning Execution: Parallelized the evolutionary parameter optimization in native Rust, replacing the slow Python child process executor.
- Full Rust Port: Rewrote the entire backend from Python/Twisted to Rust/Tokio, achieving a 10x reduction in memory footprint and massive performance enhancements.
- Advanced Simulation Engine: Native simulator with support for Lookahead MPC, Adaptive Peak Shaving, and Evolved Heuristic strategies.
- Web Dashboard UI: A premium, responsive single-page dashboard displaying live power flows, system stats, Amber pricing, and historical simulation graphs.
- MQTT Power Meter Bridge: Support for Shelly and custom ESPHome meters.
- Home Assistant Auto-Discovery: Automatically publishes MQTT discovery payloads for all entities.
- Tariff Manager: Live pricing models supporting Flat rates, Time-Of-Use schedules, and real-time Amber API price tracking.
- Debian Packaging: Integrated building scripts for packaging
.debfiles for local (amd64) or target (arm64) deployments.