Files
invertergui/README.md
Nathan Coad e700239764
All checks were successful
continuous-integration/drone/push Build is passing
add capability to restrict remote panel modes
2026-02-19 15:55:20 +11:00

773 lines
30 KiB
Markdown

# Inverter GUI
[Repository](https://git.coadcorp.com/nathan/invertergui) | [Container Image](https://registry.coadcorp.com/nathan/invertergui)
The invertergui allows the monitoring of a [Victron Multiplus](https://www.victronenergy.com/inverters-chargers/multiplus-12v-24v-48v-800va-3kva) via the [MK3/MK2 USB](https://www.victronenergy.com/accessories/interface-mk3-usb) or the MK2 RS232.
The [`registry.coadcorp.com/nathan/invertergui`](https://registry.coadcorp.com/nathan/invertergui) container image is a build of this repository.
The code has been updated to support more of the protocol published by Victron at https://www.victronenergy.com/upload/documents/Technical-Information-Interfacing-with-VE-Bus-products-MK2-Protocol-3-14.pdf
## Acknowledgements
This project is based on the original open source `invertergui` project by Hendrik van Wyk and contributors:
- Original repository: https://github.com/diebietse/invertergui
- Home Assistant `victron-mk3-hass` inspiration: https://github.com/j9brown/victron-mk3-hass
## Demo
![demo](./invertergui_demo.gif "Invertergui Demo")
## Quick Start
```console
docker run --name invertergui --device /dev/ttyUSB0:/dev/ttyUSB0 -p 8080:8080 registry.coadcorp.com/nathan/invertergui:latest
```
## Requirements
This project makes use of [Go Modules](https://github.com/golang/go/wiki/Modules). The minimum supported version for Go is 1.22
## Driver API: Metadata + Safe Transactions
The MK2 driver now includes a metadata and transaction safety layer via the
`mk2driver.MetadataControl` interface:
- Register metadata lookup (`RegisterMetadata`, `ListRegisterMetadata`)
- Generic register reads by kind/id (`ReadRegister`)
- Transactional writes with retry and verify (`WriteRegister`)
`WriteRegister` supports:
- `ReadBeforeWrite`
- `VerifyAfterWrite`
- configurable retry count and delay
This layer is additive and does not replace existing `WriteSetting`, `WriteRAMVar`,
or panel control APIs.
## Advanced Control + Orchestration Features
The codebase now includes:
- Full MK2 command-path coverage in driver APIs for:
- `0x0E` device state read/write
- register read by id (`0x30`, `0x31`)
- selected read/write flows (`0x32`, `0x33`, `0x34`, `0x35`)
- RAM var metadata/info (`0x36`)
- write-by-id flows (`0x37`, `0x38`)
- Register metadata with `unit`, `min/max`, `scale`, `writable`, and `safety_class`.
- Transaction-safe writes with read-before-write, verify-after-write, retry/backoff, and timeout classes.
- Snapshot/diff/restore register workflows with rollback on partial restore failure.
- Alarm engine with LED/state alarms + command-failure alarms, including debounce and clear behavior.
- Venus-like derived operating state model: `Off`, `Inverter`, `Charger`, `Passthru`, `Fault`.
- Historical counters for energy and availability:
- `energy_in_wh`, `energy_out_wh`
- battery charge/discharge Wh
- uptime seconds
- fault count + last fault timestamp
- Multi-device orchestration fields and topics:
- `device_id`, `instance_id`, `phase`, `phase_group`
- per-device topics and phase-group fanout topics
- Command arbitration/policy layer:
- single serialized write path
- lockout windows
- source tagging (`ui`, `mqtt`, `automation`)
- max current guardrail + mode rate limit + maintenance/read-only profiles
- Venus-compatible MQTT mode (`N/...` + optional `W/...`) for HA/Node-RED/VRM-style workflows.
- Guide-style Victron ESS MQTT paths (`settings/0/Settings/CGwacs/*`) with `victron/N/...` and `victron/W/...` prefix compatibility.
- Structured diagnostics bundle topics with protocol traces, recent command history, and health score.
## Getting started
```bash
Usage:
invertergui [OPTIONS]
Application Options:
--address= The IP/DNS and port of the machine that the application is running on. (default: :8080) [$ADDRESS]
--read_only Disable all write operations and run in monitoring-only mode. [$READ_ONLY]
--data.source= Set the source of data for the inverter gui. "serial", "tcp" or "mock" (default: serial) [$DATA_SOURCE]
--data.host= Host to connect when source is set to tcp. (default: localhost:8139) [$DATA_HOST]
--data.device= TTY device to use when source is set to serial. (default: /dev/ttyUSB0) [$DATA_DEVICE]
--cli.enabled Enable CLI output. [$CLI_ENABLED]
--mqtt.enabled Enable MQTT publishing. [$MQTT_ENABLED]
--mqtt.broker= Set the host port and scheme of the MQTT broker. (default: tcp://localhost:1883) [$MQTT_BROKER]
--mqtt.client_id= Set the client ID for the MQTT connection. (default: inverter-gui) [$MQTT_CLIENT_ID]
--mqtt.topic= Set the MQTT topic updates published to. (default: invertergui/updates) [$MQTT_TOPIC]
--mqtt.command_topic= Set the MQTT topic that receives write commands for Victron settings/RAM variables. (default: invertergui/settings/set) [$MQTT_COMMAND_TOPIC]
--mqtt.status_topic= Set the MQTT topic where write command status updates are published. (default: invertergui/settings/status) [$MQTT_STATUS_TOPIC]
--mqtt.device_id= Set logical device ID used for per-device orchestration topics. (default: invertergui) [$MQTT_DEVICE_ID]
--mqtt.history_size= Number of samples retained for rolling history summaries. (default: 120) [$MQTT_HISTORY_SIZE]
--mqtt.instance_id= Device instance ID for multi-device orchestration and Venus compatibility. (default: 0) [$MQTT_INSTANCE_ID]
--mqtt.phase= Electrical phase label for this instance (L1/L2/L3). (default: L1) [$MQTT_PHASE]
--mqtt.phase_group= Grouping key for parallel/3-phase system aggregation topics. (default: default) [$MQTT_PHASE_GROUP]
--mqtt.ha.enabled Enable Home Assistant MQTT discovery integration. [$MQTT_HA_ENABLED]
--mqtt.ha.discovery_prefix= Set Home Assistant MQTT discovery prefix. (default: homeassistant) [$MQTT_HA_DISCOVERY_PREFIX]
--mqtt.ha.node_id= Set Home Assistant node ID used for discovery topics and unique IDs. (default: invertergui) [$MQTT_HA_NODE_ID]
--mqtt.ha.device_name= Set Home Assistant device display name. (default: Victron Inverter) [$MQTT_HA_DEVICE_NAME]
--mqtt.venus.enabled Enable Venus-style MQTT compatibility topics (N/W model). [$MQTT_VENUS_ENABLED]
--mqtt.venus.portal_id= Set Venus portal ID segment used in N/W topics. (default: invertergui) [$MQTT_VENUS_PORTAL_ID]
--mqtt.venus.service= Set Venus service segment used in N/W topics. (default: vebus/257) [$MQTT_VENUS_SERVICE]
--mqtt.venus.subscribe_writes Subscribe to Venus W/... topics and map to MK2 commands. [$MQTT_VENUS_SUBSCRIBE_WRITES]
--mqtt.venus.topic_prefix= Optional topic prefix before Venus N/W topics, e.g. victron. [$MQTT_VENUS_TOPIC_PREFIX]
--mqtt.venus.guide_compat Enable guide-style settings/0/Settings/CGwacs compatibility paths. [$MQTT_VENUS_GUIDE_COMPAT]
--mqtt.username= Set the MQTT username [$MQTT_USERNAME]
--mqtt.password= Set the MQTT password [$MQTT_PASSWORD]
--mqtt.password-file= Path to a file containing the MQTT password [$MQTT_PASSWORD_FILE]
--control.profile= Write policy profile: normal, maintenance, or read_only. (default: normal) [$CONTROL_PROFILE]
--control.max_current_limit= Optional max AC current limit guardrail in amps (0 disables). (default: 0) [$CONTROL_MAX_CURRENT_LIMIT]
--control.mode_change_min_interval= Minimum time between mode changes. (default: 3s) [$CONTROL_MODE_CHANGE_MIN_INTERVAL]
--control.lockout_window= Post-command lockout window for command arbitration. (default: 0s) [$CONTROL_LOCKOUT_WINDOW]
--control.allowed_panel_modes= Comma-separated allowlist of remote panel modes. Supported values: on, off, charger_only, inverter_only. Empty allows all modes. [$CONTROL_ALLOWED_PANEL_MODES]
--loglevel= The log level to generate logs at. ("panic", "fatal", "error", "warn", "info", "debug", "trace") (default: info) [$LOGLEVEL]
Help Options:
-h, --help Show this help message
```
### Read-Only Mode
Set `READ_ONLY=true` (or `--read_only`) to disable all write operations.
When read-only mode is enabled, the app still monitors and publishes telemetry, but it will not send commands to the Victron device.
This affects:
- MQTT command handling (`--mqtt.command_topic` commands are ignored)
- Web UI control actions (`POST /api/remote-panel/state` and `POST /api/remote-panel/standby`)
### Remote Panel Mode Allowlist
Set `CONTROL_ALLOWED_PANEL_MODES` (or `--control.allowed_panel_modes`) to restrict which
remote panel modes can be selected from Web UI, MQTT, Home Assistant, and Venus-compatible
write paths.
Supported values:
- `on`
- `off`
- `charger_only`
- `inverter_only`
Use a comma-separated list. Empty means all modes are allowed.
Example:
- `CONTROL_ALLOWED_PANEL_MODES=off,charger_only`
Example `docker-compose.yml` snippet:
```yaml
services:
invertergui:
image: registry.coadcorp.com/nathan/invertergui:latest
environment:
READ_ONLY: "true"
CONTROL_ALLOWED_PANEL_MODES: "off,charger_only"
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"
command: ["--mqtt.enabled", "--mqtt.broker=tcp://192.168.1.1:1883", "--loglevel=info"]
```
### Home Assistant Guide-Style ESS Control
To mimic the Victron community ESS control approach (MQTT `N/...` state + `W/...` writes under `settings/0/Settings/CGwacs/...`):
1. Start invertergui with:
- `MQTT_VENUS_ENABLED=true`
- `MQTT_VENUS_GUIDE_COMPAT=true`
- `MQTT_VENUS_TOPIC_PREFIX=victron`
- `MQTT_VENUS_PORTAL_ID=invertergui` (or your chosen portal id)
2. In Home Assistant:
- Use the included custom integration (`custom_components/victron_mk2_mqtt`) which now exposes ESS-style entities and service calls.
- Or use `homeassistant/packages/invertergui_mqtt.yaml`, which includes guide-style MQTT entities:
- `number.victron_ess_grid_setpoint`
- `number.victron_ess_max_charge_power`
- `number.victron_ess_max_discharge_power`
- `switch.victron_ess_optimized_mode`
Compatibility note:
- MK2/VE.Bus does not expose every Venus ESS feature one-to-one. This project maps ESS-style commands onto available MK2 controls (mode/current-limit/policy-safe behavior) to provide similar Home Assistant control flow.
## Port 8080
The default HTTP server port is hosted on port 8080. This exposes the HTTP server that hosts the:
- Web GUI
- Munin Plugin
- Prometheus Monitor
### Web GUI
The GUI location is at the root (http://localhost:8080/) of the HTTP server.
Example output:
```
Date: Mon, 17 Dec 2018 18:14:51 +0000
LEDs:
Mains
Float
Output Current: 1.580 A
Output Voltage: 227.830 V
Output Frequency: 50.026 Hz
Output Power: 359.971 VA
Input Current: 1.750 A
Input Voltage: 227.830 V
Input Frequency: 50.103 Hz
Input Power: 398.703 VA
Input - Output Power: 38.731 VA
Battery Current: -0.050 A
Battery Voltage: 13.170 V
Battery Power: -0.659 W
Battery Charge: 100.000 %
```
The web UI also includes a **Remote Panel Control** section for:
- Remote Panel Mode (`on`, `off`, `charger_only`, `inverter_only`)
- Remote Panel Current Limit (AC input current limit in amps)
- Remote Panel Standby (prevent sleep while turned off)
The combined mode + current limit action maps to the same behavior as
`set_remote_panel_state` in `victron-mk3`.
The backing HTTP API endpoints are:
- `GET/POST /api/remote-panel/state`
- `GET/POST /api/remote-panel/standby`
### Munin
The Munin plugin location is at /munin (http://localhost:8080/munin).
Example output:
```
multigraph in_batvolt
volt.value 13.154
multigraph in_batcharge
charge.value 100.000
multigraph in_batcurrent
current.value -0.092
multigraph in_batpower
power.value -1.209
multigraph in_mainscurrent
currentin.value 1.860
currentout.value 1.676
multigraph in_mainsvoltage
voltagein.value 225.786
voltageout.value 225.786
multigraph in_mainspower
powerin.value 419.945
powerout.value 378.372
multigraph in_mainsfreq
freqin.value 50.361
freqout.value 50.026
```
### Prometheus
The Prometheus endpoint is at the default /metrics path (http://localhost:8080/metrics).
Sample Prometheus yaml entry:
```yml
- job_name: "victron"
static_configs:
- targets: ["localhost:8080"]
```
The metrics that are tracked:
```
# HELP battery_charge_percentage Remaining battery charge.
# TYPE battery_charge_percentage gauge
battery_charge_percentage 100
# HELP battery_current_a Battery current.
# TYPE battery_current_a gauge
battery_current_a -0.06
# HELP battery_power_w Battery power.
# TYPE battery_power_w gauge
battery_power_w -0.7896
# HELP battery_voltage_v Voltage of the battery.
# TYPE battery_voltage_v gauge
battery_voltage_v 13.16
# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 5.3183e-05
go_gc_duration_seconds{quantile="0.25"} 0.000116
go_gc_duration_seconds{quantile="0.5"} 0.000156305
go_gc_duration_seconds{quantile="0.75"} 0.000313721
go_gc_duration_seconds{quantile="1"} 0.044886879
go_gc_duration_seconds_sum 0.394171418
go_gc_duration_seconds_count 58
# HELP go_goroutines Number of goroutines that currently exist.
# TYPE go_goroutines gauge
go_goroutines 8
# HELP go_info Information about the Go environment.
# TYPE go_info gauge
go_info{version="go1.11.3"} 1
# HELP go_memstats_alloc_bytes Number of bytes allocated and still in use.
# TYPE go_memstats_alloc_bytes gauge
go_memstats_alloc_bytes 3.21496e+06
# HELP go_memstats_alloc_bytes_total Total number of bytes allocated, even if freed.
# TYPE go_memstats_alloc_bytes_total counter
go_memstats_alloc_bytes_total 1.7361072e+08
# HELP go_memstats_buck_hash_sys_bytes Number of bytes used by the profiling bucket hash table.
# TYPE go_memstats_buck_hash_sys_bytes gauge
go_memstats_buck_hash_sys_bytes 1.451092e+06
# HELP go_memstats_frees_total Total number of frees.
# TYPE go_memstats_frees_total counter
go_memstats_frees_total 263807
# HELP go_memstats_gc_cpu_fraction The fraction of this program's available CPU time used by the GC since the program started.
# TYPE go_memstats_gc_cpu_fraction gauge
go_memstats_gc_cpu_fraction 0.00018297252897512647
# HELP go_memstats_gc_sys_bytes Number of bytes used for garbage collection system metadata.
# TYPE go_memstats_gc_sys_bytes gauge
go_memstats_gc_sys_bytes 2.37568e+06
# HELP go_memstats_heap_alloc_bytes Number of heap bytes allocated and still in use.
# TYPE go_memstats_heap_alloc_bytes gauge
go_memstats_heap_alloc_bytes 3.21496e+06
# HELP go_memstats_heap_idle_bytes Number of heap bytes waiting to be used.
# TYPE go_memstats_heap_idle_bytes gauge
go_memstats_heap_idle_bytes 6.2537728e+07
# HELP go_memstats_heap_inuse_bytes Number of heap bytes that are in use.
# TYPE go_memstats_heap_inuse_bytes gauge
go_memstats_heap_inuse_bytes 3.981312e+06
# HELP go_memstats_heap_objects Number of allocated objects.
# TYPE go_memstats_heap_objects gauge
go_memstats_heap_objects 5588
# HELP go_memstats_heap_released_bytes Number of heap bytes released to OS.
# TYPE go_memstats_heap_released_bytes gauge
go_memstats_heap_released_bytes 0
# HELP go_memstats_heap_sys_bytes Number of heap bytes obtained from system.
# TYPE go_memstats_heap_sys_bytes gauge
go_memstats_heap_sys_bytes 6.651904e+07
# HELP go_memstats_last_gc_time_seconds Number of seconds since 1970 of last garbage collection.
# TYPE go_memstats_last_gc_time_seconds gauge
go_memstats_last_gc_time_seconds 1.5450709952576678e+09
# HELP go_memstats_lookups_total Total number of pointer lookups.
# TYPE go_memstats_lookups_total counter
go_memstats_lookups_total 0
# HELP go_memstats_mallocs_total Total number of mallocs.
# TYPE go_memstats_mallocs_total counter
go_memstats_mallocs_total 269395
# HELP go_memstats_mcache_inuse_bytes Number of bytes in use by mcache structures.
# TYPE go_memstats_mcache_inuse_bytes gauge
go_memstats_mcache_inuse_bytes 3456
# HELP go_memstats_mcache_sys_bytes Number of bytes used for mcache structures obtained from system.
# TYPE go_memstats_mcache_sys_bytes gauge
go_memstats_mcache_sys_bytes 16384
# HELP go_memstats_mspan_inuse_bytes Number of bytes in use by mspan structures.
# TYPE go_memstats_mspan_inuse_bytes gauge
go_memstats_mspan_inuse_bytes 27208
# HELP go_memstats_mspan_sys_bytes Number of bytes used for mspan structures obtained from system.
# TYPE go_memstats_mspan_sys_bytes gauge
go_memstats_mspan_sys_bytes 32768
# HELP go_memstats_next_gc_bytes Number of heap bytes when next garbage collection will take place.
# TYPE go_memstats_next_gc_bytes gauge
go_memstats_next_gc_bytes 4.194304e+06
# HELP go_memstats_other_sys_bytes Number of bytes used for other system allocations.
# TYPE go_memstats_other_sys_bytes gauge
go_memstats_other_sys_bytes 775332
# HELP go_memstats_stack_inuse_bytes Number of bytes in use by the stack allocator.
# TYPE go_memstats_stack_inuse_bytes gauge
go_memstats_stack_inuse_bytes 589824
# HELP go_memstats_stack_sys_bytes Number of bytes obtained from system for stack allocator.
# TYPE go_memstats_stack_sys_bytes gauge
go_memstats_stack_sys_bytes 589824
# HELP go_memstats_sys_bytes Number of bytes obtained from system.
# TYPE go_memstats_sys_bytes gauge
go_memstats_sys_bytes 7.176012e+07
# HELP go_threads Number of OS threads created.
# TYPE go_threads gauge
go_threads 10
# HELP mains_current_in_a Mains current flowing into inverter
# TYPE mains_current_in_a gauge
mains_current_in_a 2.17
# HELP mains_current_out_a Mains current flowing out of inverter
# TYPE mains_current_out_a gauge
mains_current_out_a 2
# HELP mains_freq_in_hz Mains frequency at inverter input
# TYPE mains_freq_in_hz gauge
mains_freq_in_hz 50.36082474226804
# HELP mains_freq_out_hz Mains frequency at inverter output
# TYPE mains_freq_out_hz gauge
mains_freq_out_hz 50.153452685421996
# HELP mains_power_in_va Mains power in
# TYPE mains_power_in_va gauge
mains_power_in_va 491.6352
# HELP mains_power_out_va Mains power out
# TYPE mains_power_out_va gauge
mains_power_out_va 453.12
# HELP mains_voltage_in_v Mains voltage at input of inverter
# TYPE mains_voltage_in_v gauge
mains_voltage_in_v 226.56
# HELP mains_voltage_out_v Mains voltage at output of inverter
# TYPE mains_voltage_out_v gauge
mains_voltage_out_v 226.56
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 39.73
# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
process_max_fds 1.048576e+06
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 8
# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 1.2742656e+07
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1.54506833485e+09
# HELP process_virtual_memory_bytes Virtual memory size in bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 1.15101696e+08
```
### MQTT
The MQTT client will publish updates to the given broker at the set topic.
#### MQTT Configuration Options
```bash
--mqtt.enabled Enable MQTT publishing. [$MQTT_ENABLED]
--mqtt.broker= Set the host port and scheme of the MQTT broker. (default: tcp://localhost:1883) [$MQTT_BROKER]
--mqtt.client_id= Set the client ID for the MQTT connection. (default: inverter-gui) [$MQTT_CLIENT_ID]
--mqtt.topic= Set the MQTT topic updates published to. (default: invertergui/updates) [$MQTT_TOPIC]
--mqtt.command_topic= Set the MQTT topic that receives write commands for Victron settings/RAM variables. (default: invertergui/settings/set) [$MQTT_COMMAND_TOPIC]
--mqtt.status_topic= Set the MQTT topic where write command status updates are published. (default: invertergui/settings/status) [$MQTT_STATUS_TOPIC]
--mqtt.device_id= Set logical device ID used for per-device orchestration topics. (default: invertergui) [$MQTT_DEVICE_ID]
--mqtt.history_size= Number of samples retained for rolling history summaries. (default: 120) [$MQTT_HISTORY_SIZE]
--mqtt.ha.enabled Enable Home Assistant MQTT discovery integration. [$MQTT_HA_ENABLED]
--mqtt.ha.discovery_prefix= Set Home Assistant MQTT discovery prefix. (default: homeassistant) [$MQTT_HA_DISCOVERY_PREFIX]
--mqtt.ha.node_id= Set Home Assistant node ID used for discovery topics and unique IDs. (default: invertergui) [$MQTT_HA_NODE_ID]
--mqtt.ha.device_name= Set Home Assistant device display name. (default: Victron Inverter) [$MQTT_HA_DEVICE_NAME]
--mqtt.venus.enabled Enable Venus-style MQTT compatibility topics (N/W model). [$MQTT_VENUS_ENABLED]
--mqtt.venus.portal_id= Set Venus portal ID segment used in N/W topics. (default: invertergui) [$MQTT_VENUS_PORTAL_ID]
--mqtt.venus.service= Set Venus service segment used in N/W topics. (default: vebus/257) [$MQTT_VENUS_SERVICE]
--mqtt.venus.subscribe_writes Subscribe to Venus W/... topics and map to MK2 commands. [$MQTT_VENUS_SUBSCRIBE_WRITES]
--mqtt.username= Set the MQTT username [$MQTT_USERNAME]
--mqtt.password= Set the MQTT password [$MQTT_PASSWORD]
--mqtt.password-file= Path to a file containing the MQTT password [$MQTT_PASSWORD_FILE]
```
Related global option:
```bash
--read_only Disable all write operations and run in monitoring-only mode. [$READ_ONLY]
```
The MQTT client can be enabled by setting the environment variable `MQTT_ENABLED=true` or flag `--mqtt.enabled`.
All MQTT configuration can be done via flags or as environment variables.
The URI for the broker can be configured format should be `scheme://host:port`, where "scheme" is one of "tcp", "ssl", or "ws".
When `--mqtt.command_topic` is configured, the application subscribes to that topic and accepts JSON write commands.
The recommended command for inverter control follows the same model used by `victron-mk3`:
```json
{
"request_id": "optional-correlation-id",
"kind": "panel_state",
"switch": "on",
"current_limit": 16.5
}
```
`switch` supports `charger_only`, `inverter_only`, `on`, and `off` (or numeric values `1..4`).
`current_limit` is in amps and optional. If omitted, only the switch state is changed.
To update only the current limit (while preserving the last known mode), send:
```json
{
"kind": "panel_state",
"current_limit": 12.0
}
```
If no prior mode is known (for example on a fresh broker state), this command is rejected until a mode command is sent once.
Standby can be controlled with:
```json
{
"kind": "standby",
"standby": true
}
```
Low-level writes are still supported:
```json
{
"kind": "setting",
"id": 15,
"value": 1
}
```
`kind` supports `panel_state`, `setting`, and `ram_var` (with aliases for each).
The result is published to `--mqtt.status_topic` with status `ok` or `error`.
### MQTT Device Orchestration Topics
For multi-device deployments on one MQTT broker, `invertergui` now also publishes
device-scoped orchestration topics under:
- `{topic-root}/devices/{device_id}/state`
- `{topic-root}/devices/{device_id}/history/summary`
- `{topic-root}/devices/{device_id}/alarms/active`
Set `--mqtt.device_id` (or `MQTT_DEVICE_ID`) per inverter instance so each instance
publishes to a unique device path.
Rolling history depth for the summary window is set by `--mqtt.history_size`.
### Venus-Style MQTT Compatibility
Enable Venus-compatible topics with:
```bash
--mqtt.venus.enabled
```
When enabled, `invertergui` publishes Venus-style notifications to:
- `N/{portal_id}/{service}/...`
Defaults:
- `portal_id`: `invertergui` (`--mqtt.venus.portal_id`)
- `service`: `vebus/257` (`--mqtt.venus.service`)
Published paths include common VE.Bus style values such as:
- `Dc/0/Voltage`, `Dc/0/Current`, `Dc/0/Power`, `Soc`
- `Ac/ActiveIn/L1/V`, `Ac/ActiveIn/L1/I`, `Ac/ActiveIn/L1/F`, `Ac/ActiveIn/L1/P`
- `Ac/Out/L1/V`, `Ac/Out/L1/I`, `Ac/Out/L1/F`, `Ac/Out/L1/P`
- alarm paths (`Alarms/LowBattery`, `Alarms/HighTemperature`, `Alarms/Overload`, `Alarms/Communication`)
Optional write compatibility can be enabled with:
```bash
--mqtt.venus.subscribe_writes
```
This subscribes to:
- `W/{portal_id}/{service}/#`
and maps supported write paths to MK2 control operations:
- `Mode` -> remote panel mode
- `Ac/ActiveIn/CurrentLimit` -> remote panel current limit
- `Settings/Standby` / `RemotePanel/Standby` -> standby control
### Home Assistant
Enable Home Assistant auto-discovery with:
```bash
--mqtt.ha.enabled
```
When enabled, `invertergui` publishes retained discovery payloads and availability under:
- `{topic-root}/homeassistant/availability` (`online`/`offline`)
- `{discovery_prefix}/sensor/{node_id}/.../config`
- `{discovery_prefix}/binary_sensor/{node_id}/.../config`
- `{discovery_prefix}/select/{node_id}/remote_panel_mode/config` (if command topic is configured)
- `{discovery_prefix}/number/{node_id}/remote_panel_current_limit/config` (if command topic is configured)
- `{discovery_prefix}/switch/{node_id}/remote_panel_standby/config` (if command topic is configured)
The discovered entities include battery/input/output sensors, a data-valid diagnostic binary sensor,
plus remote panel controls for:
- `Remote Panel Mode` (`on`, `off`, `charger_only`, `inverter_only`)
- `Remote Panel Current Limit` (AC input current limit in amps)
- `Remote Panel Standby` (prevent device sleep while off)
The combined mode + current limit behavior is provided through the `panel_state` MQTT command kind,
which mirrors `victron_mk3.set_remote_panel_state`.
### Home Assistant Custom Component (MQTT)
This repository also includes a custom Home Assistant integration at:
- `custom_components/victron_mk2_mqtt`
This component is useful if you want HA entities/services that are explicitly tied to
`invertergui` MQTT topics, instead of relying only on MQTT auto-discovery entities.
If you use this custom component, you can disable `--mqtt.ha.enabled` in `invertergui`
to avoid duplicate entities created by MQTT discovery.
Install via HACS:
1. Add the integration repository in Home Assistant:
[![Open your Home Assistant instance and open this repository inside the Home Assistant Community Store.](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?owner=nathan&repository=invertergui&category=integration)
2. Install `Victron MK2 MQTT` from HACS.
3. Restart Home Assistant.
4. Add the YAML configuration shown below.
If you are not mirroring this repo to GitHub, use the manual install method below.
Manual install (alternative):
```text
<home-assistant-config>/custom_components/victron_mk2_mqtt
```
Then add YAML config:
```yaml
victron_mk2_mqtt:
name: Victron Inverter
state_topic: invertergui/updates
command_topic: invertergui/settings/set
status_topic: invertergui/settings/status
# topic_root is optional; defaults to state_topic root (for example "invertergui")
# topic_root: invertergui
```
Provided entities include:
- Telemetry sensors (battery/input/output voltage/current/frequency and derived power)
- `Remote Panel Mode` (`charger_only`, `inverter_only`, `on`, `off`)
- `Remote Panel Current Limit` (A)
- `Remote Panel Standby`
- Diagnostic entities (`Data Valid`, `Last Command Error`)
Service exposed by the integration:
- `victron_mk2_mqtt.set_remote_panel_state`
Example service call:
```yaml
service: victron_mk2_mqtt.set_remote_panel_state
data:
mode: on
current_limit: 16.0
```
### Home Assistant MQTT-Only Dashboard (No Duplicate Entities)
If you want the same control/telemetry experience but only via MQTT (without duplicate
entities from discovery/custom integrations), use the packaged Home Assistant files:
- MQTT entity + control package: `homeassistant/packages/invertergui_mqtt.yaml`
- Lovelace dashboard: `homeassistant/dashboards/invertergui_mqtt_dashboard.yaml`
The package assumes default topics (`invertergui/updates`, `invertergui/settings/set`,
`invertergui/settings/status`). If you use custom MQTT topics, update those values in
`homeassistant/packages/invertergui_mqtt.yaml`.
Recommended for this mode:
- Disable MQTT discovery output from `invertergui` (`--mqtt.ha.enabled=false`)
- Do not enable the `victron_mk2_mqtt` custom component at the same time
1. Ensure HA packages are enabled (if not already):
```yaml
homeassistant:
packages: !include_dir_named packages
```
2. Copy package file to your HA config:
```text
<home-assistant-config>/packages/invertergui_mqtt.yaml
```
3. Copy dashboard file to your HA config:
```text
<home-assistant-config>/dashboards/invertergui_mqtt_dashboard.yaml
```
4. Register the dashboard (YAML mode example):
```yaml
lovelace:
mode: storage
dashboards:
invertergui-victron:
mode: yaml
title: Victron MQTT
icon: mdi:flash
show_in_sidebar: true
filename: dashboards/invertergui_mqtt_dashboard.yaml
```
5. Restart Home Assistant.
## TTY Device
The intertergui application makes use of a serial tty device to monitor the Multiplus.
Example
```
-dev=/dev/ttyUSB0
```
## Nginx Proxy
The following configuration works for Nginx to allow the `invertergui` to be proxied.
When using a stand HTTP or HTTPS port to expose the gui:
```Ini
location /invertergui {
return 302 /invertergui/;
}
location /invertergui/ {
proxy_pass http://localhost:8080/;
proxy_set_header Host $host;
}
location /invertergui/ws {
proxy_pass http://localhost:8080/ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
proxy_set_header Host $host;
proxy_set_header Referer $http_referer;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
}
```
When using a non-stand HTTP or HTTPS port to expose the gui change the HTTP Host description:
```Ini
proxy_set_header Host $host:$server_port;
```
The last four lines are optional, but is useful when debugging and logging connections:
```Ini
proxy_set_header Referer $http_referer;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
```
## Grafana
This repos includes a [Grafana](https://grafana.com/) dashboard in the [grafana folder](./grafana/prometheus-dashboard.json) that you can import. This is useful if you are using prometheus to log your data and want to display it in a nice way.
![grafana](./grafana/dashboard.png "Grafana Dashboard")