Releases: sm26449/fronius-modbus-mqtt
v1.8.0 — Per-inverter power-limit control
Highlights
New: per-inverter power-limit control modal in the monitoring dashboard. Click Set in the Control column of any inverter row to open a modal with a slider, an Advanced section for revert_timeout and ramp_time, plus Apply / Restore 100% / Cancel. The same 11-step safety pipeline as the MQTT command path — rate limit, range validation, read-back verification, auto-revert.
License change. This release switches from MIT to PolyForm Noncommercial 1.0.0. Personal, research, educational and noncommercial-organization use remains free; commercial use now requires a separate written license from the author with an attribution requirement. Pre-1.8.0 releases remain MIT for users who obtained them at that time. See LICENSE and NOTICE.
Pre-built multi-arch image on GHCR. Pull directly without building:
docker pull ghcr.io/sm26449/fronius-modbus-mqtt:1.8.0
Tags: 1.8.0, 1.8, 1, latest. Architectures: linux/amd64, linux/arm64 (Raspberry Pi 4/5 supported).
Added
- Per-inverter power-limit control in the dashboard (slider + numeric input, Advanced section, refetch on open, JS-driven auto-refresh that pauses while the modal is open). Full reference in
docs/POWER_LIMIT_CONTROL.md. - New endpoints (only registered when
write.enabled=true):POST /api/inverter/{id}/power_limit— body{limit_pct, revert_timeout?, ramp_time?}POST /api/inverter/{id}/restoreGET /api/data— alias of?view=json
DevicePoller.get_latest_controls()/get_active_override()— cached live readback so the dashboard shows the currentWMaxLim_Pctper inverter without an out-of-band Modbus read.controls_updated_atexposed in JSON; the modal renders a(read N s ago)staleness note (relevant during night/sleep mode).write.command_queue_sizeconfig option (default 50; was hardcoded 10). Override viaWRITE_COMMAND_QUEUE_SIZE.docs/POWER_LIMIT_CONTROL.mdanddocs/MONITORING.mdreference documentation.
Changed
- License: MIT → PolyForm Noncommercial 1.0.0. See LICENSE, NOTICE.
- README Quick Start now leads with the pre-built GHCR image; clone-and-build is "Path B".
Hardening (from internal review)
_active_limits/_auto_revert_timersmutations and reads serialized by a new_write_state_lock(race between the poller thread and HTTP/MQTT command handlers).- JSON payload embedded in the dashboard HTML neutralizes
</to<\/(defence in depth against future string fields breaking out of<script type="application/json">). - Modal fetches
/api/dataon open so values aren't stale after a long-open modal. - Pydantic 422 validation errors are surfaced from
detail[]instead of being flattened toHTTP 422.
CI
- New GitHub Actions workflow (
.github/workflows/docker-publish.yml) builds multi-arch images on everyv*tag and publishes to GHCR. Future releases ship withgit tag -a vX.Y.Z && git push --tags.
Pull / Run
docker pull ghcr.io/sm26449/fronius-modbus-mqtt:1.8.0See the README Quick Start for a minimal docker-compose.yml.
Full changelog: see CHANGELOG.md.
Diff: v1.7.0...v1.8.0.
v1.7.0 — Built-in HTTP Monitoring Dashboard
Built-in HTTP Monitoring Dashboard
New FastAPI-based monitoring server running as a daemon thread for runtime observability.
Endpoints
GET /→ HTML dashboard (dark theme, auto-refresh 30s)GET /?view=json→ JSON API with full runtime state
Dashboard Features
- Status cards: Modbus TCP, MQTT, InfluxDB, Modbus Write, System (memory, threads)
- Devices table: model, serial number, online/offline status, last seen, error count
- Log viewer: scrollable, last 24h, newest first (max 500 lines)
- Status indicators: green/red dots for connection state
Configuration
monitoring:
enabled: true
port: 8080Or via environment: MONITORING_ENABLED=true
Docker
ports:
- "8082:8080" # inverters
- "8083:8080" # meterDependencies
fastapi,uvicorn,psutil(added to requirements.txt)
v1.6.0 — Inverter Power Limit Control
Highlights
Inverter Power Limit Control via Modbus TCP Write — Control inverter output power (WMaxLimPct) through MQTT commands with an 11-step safety write protocol.
New Features
- Power Limit Control — Set/restore inverter power limits via MQTT (
fronius/inverter/{id}/cmd/set_power_limit) - 11-step safety protocol — Connection reset, pre-write verification, atomic write, post-write read-back, rate limiting, auto-revert
- Software auto-revert — Automatically restore 100% after configurable timeout (default 1h)
- Hardware-level revert —
revert_timeoutparameter sets inverter-side fallback via WMaxLim_RvrtTms register - Vendor status code —
vendor_status_codeandvendor_status_descriptionpersisted to InfluxDB
Bug Fixes
- WMaxLim_Ena stuck on restore — Restoring to 100% now sets
WMaxLim_Ena=0; previously leftEna=1which kept inverter in THROTTLED status even at full capacity - Shutdown race condition — Poller thread stopped before power limit restore (prevents concurrent Modbus access)
- MPPT float noise —
_parse_mppt_module_optimizednow rounds negative scale factors (e.g. 5.050000000000001 → 5.05) - IEEE 754 float noise —
RegisterParser.apply_scale_factor()rounds results for negative scale factors - Disconnect robustness —
FroniusModbusClient.disconnect()tolerant to already-stopped poller
Safety
- Disabled by default — requires
write.enabled: true - All writes through existing DevicePoller connection (no separate connections)
- Rate limited: min 30s between writes per device
- Range validation: configurable min/max (default 10%-100%)
- Clean restore:
WMaxLim_Ena=0when restoring to 100% (inverter returns to MPPT) - Bounded command queue (maxsize=10)
- Graceful shutdown restores all active limits to 100%
Configuration
write:
enabled: false
min_power_limit_pct: 10
max_power_limit_pct: 100
rate_limit_seconds: 30
auto_revert_seconds: 3600
stabilization_delay: 2.0Full changelog: CHANGELOG.md
v1.3.1
[1.3.1] - 2026-02-26
Added
- InfluxDB Event Detail Persistence
- New
events_jsonfield infronius_invertermeasurement - Stores decoded fault event codes, descriptions, and event class as compact JSON
- Enables Grafana alerting and historical analysis of inverter fault events
- Only written when events are active (no empty JSON stored)
- New
Fixed
- Moved
jsonimport to module level ininfluxdb_publisher.py(was incorrectly inside conditional block)
Changed
- Updated InfluxDB measurement documentation in README with complete field list
- Complete README with all environment variables, project structure, and InfluxDB fields
- Added
INFLUXDB_SCHEMA.mdwith full schema reference, example Flux queries, and write configuration - Version bump to 1.3.1 in
__init__.pyandDockerfile
