11 KiB
LVX6048 Monitoring & Control via Home Assistant
Integration plan for monitoring (and eventually controlling) 2x LVX6048 inverters from Home Assistant via a Raspberry Pi running a Python poller that publishes to MQTT.
Continue dev from the Raspberry Pi.
Architecture
[LVX6048 #1] ──USB─┐
├──► [Raspberry Pi] ──MQTT──► [Home Assistant]
[LVX6048 #2] ──USB─┘ (mpp-solar/powermon (auto-discovers
Python daemon, ~40 entities
systemd service) per inverter)
Why USB (not RS485)
The LVX6048 is an MPP Solar / Voltronic-family unit. Its documented, supported comm path is USB-HID speaking the PI18 protocol (some firmware revisions also accept PI30). The RS485 port exists on the hardware but is undocumented for external monitoring on this model — it's primarily intended for parallel/BMS comms. Use USB.
Why mpp-solar
jblance/mpp-solar is the canonical Python package for this inverter family. It ships:
- PI18 / PI18LVX / PI30 / PI30MAX protocol drivers (all known query + set commands)
- A
powermondaemon for continuous polling - Built-in MQTT publisher with Home Assistant auto-discovery topic format — no HA YAML needed, entities appear automatically
Hardware Checklist
- Raspberry Pi (Pi 4 or Pi 5 recommended; Pi 3B+ works) running Raspberry Pi OS 64-bit
- microSD card (32GB+) or USB SSD
- 2x USB-A to USB-B cables (one per inverter; ~3ft typical — keep short, USB-HID is not spec'd for long runs)
- Pi physically located near the inverter cabinet
- Ethernet (preferred) or WiFi to reach the HA MQTT broker
- Existing MQTT broker running on HA (confirmed operational)
Step 1 — Base Pi Setup
sudo apt update && sudo apt upgrade -y
sudo apt install -y python3-pip python3-venv pipx git
pipx ensurepath
Reboot (or exec $SHELL) so pipx PATH takes effect.
Step 2 — Install mpp-solar
pipx install mpp-solar
# verify
mpp-solar --version
mpp-solar --listProtocols
Expect PI18, PI18LVX, PI18SV, PI30, PI30MAX in the protocol list.
Step 3 — Plug in Inverters & Identify Them
Connect inverter #1 first, alone, and run:
ls -l /dev/hidraw*
lsusb
dmesg | tail -20
Note the /dev/hidraw* device that appeared and the USB VID:PID (typical MPP Solar is 0665:5161 — confirm on your unit).
Grab the serial number for a stable udev rule:
udevadm info -a -n /dev/hidraw0 | grep -i serial | head -3
Write down SERIAL_A. Unplug #1, plug in #2, repeat to get SERIAL_B.
Step 4 — Smoke Test
With inverter #1 still plugged in, query it directly:
mpp-solar -p /dev/hidraw0 -P PI18 -c GS
GS is the PI18 "General Status" query. Expected output: battery voltage, SoC, PV watts, load watts, grid voltage, inverter mode, etc. If PI18 returns gibberish or CRC errors, try PI30:
mpp-solar -p /dev/hidraw0 -P PI30 -c QPIGS
Whichever protocol returns clean data → that's the one to use in the config below. Record which protocol worked.
Also grab rated info once:
mpp-solar -p /dev/hidraw0 -P PI18 -c PIRI # PI18 rated info
# or
mpp-solar -p /dev/hidraw0 -P PI30 -c QPIRI # PI30 rated info
Step 5 — Stable Device Names (udev)
Without this, /dev/hidraw0 and /dev/hidraw1 can swap on reboot, and the wrong inverter's data ends up under the wrong entity in HA.
As built on this CM5: the LVX6048 returns no USB serial string, so serial-based matching below is aspirational. We ended up matching by USB hub port instead — see
99-lvx6048.rulesandInstall.md§2.
Create /etc/udev/rules.d/99-lvx6048.rules:
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0665", ATTRS{idProduct}=="5161", ATTRS{serial}=="SERIAL_A", SYMLINK+="lvx6048-1", MODE="0660", GROUP="dialout"
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0665", ATTRS{idProduct}=="5161", ATTRS{serial}=="SERIAL_B", SYMLINK+="lvx6048-2", MODE="0660", GROUP="dialout"
Replace SERIAL_A / SERIAL_B and the VID:PID with the real values from Step 3. Then:
sudo usermod -aG dialout $USER
sudo udevadm control --reload-rules
sudo udevadm trigger
ls -l /dev/lvx6048-*
Both symlinks should be present. Log out / back in so the dialout group applies.
Step 6 — powermon Config
As built: the
ports:(plural) schema shown below does not work with current powermon — its config model allows exactly onedevice:per file. We ship one config file per inverter (powermon.yaml,powermon2.yaml) and run two systemd units. SeeInstall.md§4–6.
Create ~/.config/powermon/powermon.yaml (adjust MQTT creds and protocol name to match Step 4):
device:
name: lvx6048_pair
id: solar_lvx6048
mqttbroker:
name: <HA_MQTT_BROKER_IP>
port: 1883
username: <MQTT_USER>
password: <MQTT_PASSWORD>
adhoc_topic: powermon/adhoc
adhoc_result_topic: powermon/adhoc/results
api:
enabled: false
daemon:
type: systemd
keepalive: 60
ports:
- name: lvx1
type: usb
path: /dev/lvx6048-1
protocol: PI18 # confirmed in Step 4
commands:
- command: GS
trigger: { every: 5 }
outputs: { name: mqtt_ha, type: hass, tag: lvx6048_1 }
- command: PIRI
trigger: { every: 300 }
outputs: { name: mqtt_ha, type: hass, tag: lvx6048_1 }
- command: MOD
trigger: { every: 10 }
outputs: { name: mqtt_ha, type: hass, tag: lvx6048_1 }
- command: FWS
trigger: { every: 30 }
outputs: { name: mqtt_ha, type: hass, tag: lvx6048_1 }
- name: lvx2
type: usb
path: /dev/lvx6048-2
protocol: PI18
commands:
- command: GS
trigger: { every: 5 }
outputs: { name: mqtt_ha, type: hass, tag: lvx6048_2 }
- command: PIRI
trigger: { every: 300 }
outputs: { name: mqtt_ha, type: hass, tag: lvx6048_2 }
- command: MOD
trigger: { every: 10 }
outputs: { name: mqtt_ha, type: hass, tag: lvx6048_2 }
- command: FWS
trigger: { every: 30 }
outputs: { name: mqtt_ha, type: hass, tag: lvx6048_2 }
Command reference (PI18):
GS— General Status (voltages, currents, power, SoC, temps) → poll fastPIRI— Protocol / Rated Info (nameplate values) → poll slowMOD— Operating Mode (Grid / Battery / Fault / Standby) → poll mediumFWS— Fault / Warning Status → poll mediumET— Total Energy (lifetime kWh) → optional, add withevery: 60ED— Daily Energy → optional
Run it in the foreground once to confirm MQTT is flowing:
powermon -C ~/.config/powermon/powermon.yaml
In Home Assistant, go to Settings → Devices & Services → MQTT — two new devices (lvx6048_1, lvx6048_2) should appear with all their sensors auto-discovered.
Step 7 — systemd Service
Create /etc/systemd/system/powermon.service:
[Unit]
Description=powermon LVX6048 → MQTT bridge
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=pi
Group=dialout
ExecStart=/home/pi/.local/bin/powermon -C /home/pi/.config/powermon/powermon.yaml
Restart=on-failure
RestartSec=10
# Tolerate USB dropouts / HA broker restarts
StartLimitIntervalSec=300
StartLimitBurst=10
[Install]
WantedBy=multi-user.target
Adjust User= / paths if not running as pi. Enable:
sudo systemctl daemon-reload
sudo systemctl enable --now powermon.service
systemctl status powermon.service
journalctl -u powermon.service -f
Step 8 — Home Assistant Dashboard
Entities auto-appear. Minimum useful Lovelace card:
type: entities
title: Solar System
entities:
- sensor.lvx6048_1_battery_capacity # %
- sensor.lvx6048_1_battery_voltage # V
- sensor.lvx6048_1_pv_input_power # W
- sensor.lvx6048_1_ac_output_active_power # W
- sensor.lvx6048_1_grid_voltage # V
- sensor.lvx6048_1_inverter_heat_sink_temperature
- sensor.lvx6048_1_working_mode
- sensor.lvx6048_2_battery_capacity
- sensor.lvx6048_2_pv_input_power
- sensor.lvx6048_2_ac_output_active_power
- sensor.lvx6048_2_working_mode
Entity IDs will reflect the tag: values from the config. Exact names depend on protocol driver — check the MQTT integration page.
Recommended extras:
- Energy dashboard — map
ET(total lifetime energy) as a solar production source - Automation: alert when
working_modechanges toFaulton either unit - Utility meter helpers on
ac_output_active_powerfor daily/weekly kWh
Control (Deferred)
Once monitoring is stable, control commands are available via the same library. PI18 set commands include:
POP— Output source priority (SUB / SBU / etc.)PCP— Charger priority (Solar first / Solar+Utility / only Solar)MCHGC— Max total charging currentMUCHGC— Max utility charging currentPF— Restore defaults (careful)
Exposed in HA as button/select entities via powermon's MQTT command topic. Plan this as a separate phase after at least a week of stable monitoring data.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
Permission denied on /dev/hidraw* |
User not in dialout |
sudo usermod -aG dialout $USER, re-login |
| CRC errors / garbled output | Wrong protocol selected | Try PI30 instead of PI18 (or vice versa) |
| Device disappears after reboot | udev serial mismatch | Re-check udevadm info -a, verify serial string |
| Symlinks swap between units | Two units report same serial | Fall back to KERNELS=="1-1.2" USB-port matching |
| HA entities don't appear | MQTT discovery disabled or wrong prefix | Verify discovery: true in HA MQTT integration; default prefix is homeassistant/ |
| Entities appear but never update | powermon service not actually running | journalctl -u powermon.service -n 100 |
| One inverter works, other doesn't | Parallel-mode RS232 quirk | Query the master unit; the slave may not respond to USB queries while linked |
Parallel-mode caveat
The 2x LVX6048s are wired in parallel (per README.md). In parallel mode, some MPP Solar firmware only responds to USB/PI commands on the master unit — the slave echoes the master's data or returns errors. If Step 4 smoke tests show one unit timing out, check the LCD to see which is master. If only the master responds, a single poller gives you combined system data; per-unit telemetry may require the parallel/sync RJ45 cable's side-channel (undocumented) or firmware that doesn't gate slave comms.
Recommendation: do Step 4 on each inverter individually (unplug parallel comm cable, query via USB, replug) to confirm both respond. Then test again with parallel cable connected.
References
- jblance/mpp-solar — Python library
- powermon — daemon mode (split out of mpp-solar)
- Set commands on LVX6048 — discussion #344
- LVX6048WP user manual
- MPP Solar LVX6048 product page
- HA community — LVX6048 integration thread
- Connecting to LVX6048WP via USB with Raspberry Pi