Programmatically read data from your Solar Inverter (Voltronic, Axpert, Mppsolar PIP, Voltacon, Effekta etc) and interface with Home Assistant via MQTT - Works with RS232 & USB!

Hi,

I just plugged an USB cable into the inverter and my RaspberryPi running debian.
Ubuntu is a debian derivate and this python code should run on your laptop too.

import time

import hidapi as hid


def communicate_with_hid_device(vendor_id, product_id, command_str):
    try:
        device = hid.Device(vendor_id=vendor_id, product_id=product_id)
        print("Device opened.")
        device.nonblocking = True

        command_bytes = command_str.encode('ascii')
        device.write(command_bytes)
        print(f"command sent: {command_bytes}")

        time.sleep(1)
        response = device.read(64)
        if response:
            print(f"Response: {bytes(response).decode(errors='ignore')}")
        else:
            print("Got no response")

        device.close()

    except Exception as e:
        print(f"Fehler bei der HID-Kommunikation: {e}")

if __name__ == "__main__":
    vendor_id = 0x0665  # Cypress Semiconductor
    product_id = 0x5161  # USB to Serial
    command = "QPIGS\r"  # Beispielbefehl als String

    communicate_with_hid_device(vendor_id, product_id, command)

This is just a test script.

Hope it will help.

Ciao
bama

Hi,
I’m using an Voltronic (EASUN branded) since 12 months. And it is the second USB serial device that is been killed by it … Suddenly, I don’t receive any data on the voltronic-mqtt container, and when I plug the USB serial device into my computer, it isn’t detected anymore …

Has anyone experencied such a problem?

Dear Joubert,
I connected an ESP8266 connected to the serial (RS232 cable) of an EASUN 8kW Hybrid Inverter and I read correctly the inverter status parameters.

To setup pipsolar current_max_ac_charging_current I adapted your suggested approach and code (see my code).

Now it happens that only in some cases of selected helper values ​​the current_max_ac_charging_current
is recorded in the inverter, in other cases a very different value is transmitted and since it does not belong to the set of allowed values, it is not recorded. Here is the list:

Helper: 2, 10, 20, 30, 40,50, 60, 70,80, 90,100,110,120 Amps
Registration: 153,218,139,188,185,56,103,152,12,131,100,110,120 Amps

Note that only in the cases of setup higher than 100: 100A, 110A, 120A the values ​​are registered in the inverter.

Can You help me ?

Here is the Logs of unsuccessful & successful registration:

[14:00:00][D][main:238]: STARTING VARIABLE ACCurrent
[14:00:00][D][pipsolar.output:015]: Will write: MUCHGC020 out of value 20.000000 / 20
[14:00:00][D][pipsolar:860]: got command: MUCHGC020
[14:00:00][D][pipsolar:851]: Command queued successfully: MUCHGC020 with length 9 at position 0
[14:00:00][D][main:063]: VARIABLE ACCurrent ENDS
[14:00:00][D][uart_debug:158]: >>> “MUCHGC020\xF3\xF1\r”
[14:00:00][D][pipsolar:811]: Sending command from queue: MUCHGC020 with length 9
[14:00:00][W][component:237]: Component esphome.coroutine took a long time for an operation (66 ms).
[14:00:00][W][component:238]: Components should block for at most 30 ms.
[14:00:00][D][uart_debug:158]: <<< “(NAKss\r”
[14:00:00][D][pipsolar:043]: response length for command OK
[14:00:00][D][pipsolar:776]: checking crc on incoming message
[14:00:00][D][pipsolar:779]: CRC OK
[14:00:00][D][pipsolar:049]: command not successful

[14:25:47][D][main:238]: STARTING VARIABLE ACCurrent
[14:25:47][D][pipsolar.output:015]: Will write: MUCHGC0100 out of value 100.000000 / 100
[14:25:47][D][pipsolar:860]: got command: MUCHGC0100
[14:25:47][D][pipsolar:851]: Command queued successfully: MUCHGC0100 with length 10 at position 1
[14:25:47][D][main:063]: VARIABLE ACCurrent ENDS
[14:25:47][D][uart_debug:158]: >>> “MUCHGC0100A\r”
[14:25:47][D][pipsolar:811]: Sending command from queue: MUCHGC0100 with length 10
[14:25:47][W][component:237]: Component esphome.coroutine took a long time for an operation (70 ms).
[14:25:47][W][component:238]: Components should block for at most 30 ms.
[14:25:47][D][uart_debug:158]: <<< “(ACK9 \r”
[14:25:47][D][pipsolar:043]: response length for command OK
[14:25:47][D][pipsolar:776]: checking crc on incoming message
[14:25:47][D][pipsolar:779]: CRC OK
[14:25:47][D][pipsolar:047]: command successful

[14:25:56][D][main:238]: STARTING VARIABLE ACCurrent
[14:25:56][D][pipsolar.output:015]: Will write: MUCHGC010 out of value 10.000000 / 10
[14:25:56][D][pipsolar:860]: got command: MUCHGC010
[14:25:56][D][pipsolar:851]: Command queued successfully: MUCHGC010 with length 9 at position 2
[14:25:56][D][main:063]: VARIABLE ACCurrent ENDS
[14:25:56][D][pipsolar:776]: checking crc on incoming message
[14:25:56][D][pipsolar:779]: CRC OK
[14:25:56][D][pipsolar:483]: Decode QFLAG
[14:25:56][D][uart_debug:158]: >>> “MUCHGC010\xA6\xA2\r”
[14:25:56][D][pipsolar:811]: Sending command from queue: MUCHGC010 with length 9
[14:25:56][W][component:237]: Component esphome.coroutine took a long time for an operation (64 ms).
[14:25:56][W][component:238]: Components should block for at most 30 ms.
[14:25:57][D][uart_debug:158]: <<< “(NAKss\r”
[14:25:57][D][pipsolar:043]: response length for command OK
[14:25:57][D][pipsolar:776]: checking crc on incoming message
[14:25:57][D][pipsolar:779]: CRC OK
[14:25:57][D][pipsolar:049]: command not successful

================================

Here is a fragment of ESPHOME code:
</>
api:
services:
- service: ac_grid_current
variables:
ACCurent: float
then:
- logger.log: “STARTING VARIABLE ACCurrent”
- output.pipsolar.set_level:
id: pipsolar_current_max_ac_charging_current
value: !lambda ‘return ACCurent;’
- logger.log: “VARIABLE ACCurrent ENDS”
output:

  • platform: pipsolar
    pipsolar_id: inverter0
    current_max_ac_charging_current:
    possible_values:
    • 2
    • 10
    • 20
    • 30
    • 40
    • 50
    • 60
    • 70
    • 80
    • 90
    • 100
    • 110
    • 120
      id: pipsolar_current_max_ac_charging_current
      </>
      ================================
      Here is the AUTOMATION:
      </>
  • id: ‘162702835999’
    alias: inverter Setting max charging Current
    description: ‘’
    trigger:
    • platform: state
      entity_id: input_select.setting_max_charging_current
      condition:
      action:
    • service: esphome.pipsolar_ac_grid_current
      data:
      ACCurent: “{% if is_state("input_select.setting_max_charging_current", "
      2 Amp") %}\n 2 \n{% elif is_state("input_select.setting_max_charging_current"
      , "10 Amp") %}\n 10 \n{% elif is_state("input_select.setting_max_charging_current"
      , "20 Amp") %}\n 20 \n{% elif is_state("input_select.setting_max_charging_current"
      , "30 Amp") %}\n 30 \n{% elif is_state("input_select.setting_max_charging_current"
      , "40 Amp") %}\n 40 \n{% elif is_state("input_select.setting_max_charging_current"
      , "50 Amp") %}\n 50 \n{% elif is_state("input_select.setting_max_charging_current"
      , "60 Amp") %}\n 60 \n{% elif is_state("input_select.setting_max_charging_current"
      , "70 Amp") %}\n 70 \n{% elif is_state("input_select.setting_max_charging_current"
      , "80 Amp") %}\n 80 \n{% elif is_state("input_select.setting_max_charging_current"
      , "90 Amp") %}\n 90 \n{% elif is_state("input_select.setting_max_charging_current"
      , "100 Amp") %}\n 100 \n{% elif is_state("input_select.setting_max_charging_current"
      , "110 Amp") %}\n 110 \n{% elif is_state("input_select.setting_max_charging_current"
      , "120 Amp") %}\n 120 \n{% endif %}\n”
      mode: single
      </>
      ================================

And the Helper:
input_select.setting_max_charging_current with the values of
2 Amp, 10 Amp, 20 Amp, 30 Amp,40 Amp,50 Amp,60 Amp,70 Amp,80 Amp,90 Amp,100 Amp,1100 Amp,120 Amp

Yes, me too.
yes I also have an EASUN hybrid inverter with a broken USB type C port. However I use the RS232 serial port connected to a RS232-TTL adapter (10 pieces for €12) + a few € ESP8266 which gives me Wifi connection.
Not using mqtt but ESPHOME from HA.

Nice !
Can you please share your ESPHOME config and RS232-TTL to ESP8266 pinout?

Prova questo (try this)

Have been able to setup “current_max_charging_current” with the same config of my post as per above. Unfortunately till not able to setup “current_max_ac_charging_current”.

After years of experimenting with solutions from this topic, I finally wrote my own. It’s been running great for months, and I’ve shared it in a new topic: Voltronic Solar Inverter to Home Assistant via MQTT with docker-voltronic-mqtt.

Please check it out and share your thoughts!

My setup is an MPPSolar MPI 10K, a Raspberry Pi 4 nearby and Home Assistant on a server in my home network.
I run GitHub - fl4p/batmon-ha: Add-on for Home Assistant to connect JK, JBD, Daly, ANT, SOK and Supervolt BMS via Bluetooth on the Pi to monitor my battery vis BT, which works perfectly with full visibility of the all relevant data in my HA UI.
In parallel I started the GitHub - ned-kelly/docker-voltronic-homeassistant: Programmatically read data from your Voltronic, Axpert, Mppsolar PIP, Voltacon, Effekta etc Inverter and send it to Home Assistant via MQTT - Works with RS232 & USB! which leads to a visibility of all sensors in my HA UI. But no values.
I use the USB connection to the MPI 10K. Apparently the USB works works to communicate using SolarPower SW on a Win11 laptop.
Alternatively I tried the catalinbordan fork without any positive change.
Testing the communication leads to:
Mon Jan 6 14:17:23 2025 INVERTER: Debug set
Mon Jan 6 14:17:23 2025 DEBUG: Current CRC: 49 C1
Mon Jan 6 14:17:23 2025 DEBUG: Send buffer hex bytes: ( 51 4d 4f 44 49 c1 0d )
Mon Jan 6 14:17:23 2025 DEBUG: Write command failed, error number 32 was returned
Mon Jan 6 14:17:24 2025 DEBUG: Write command failed, error number 32 was returned

Has anyone a idea, how to approach this?

Thanks for publishing your hard work!
I was wondering

Can I make it work with Venus OS?
Or do you know a project that does this?

(Axpert king 3kv)

Anyone got this (or similar approach) to work with Hypontech hybrid inverters?

For Max Power (Axpert/Voltronic) i obtained PV2 Data.

[2025-09-01 12:08:19] - [monitor.py] - [ serial_command ]: END (split-cr-padded)

[2025-09-01 12:08:19] - LOG - PARTS OF QPIGS2: 17.6 220.8 03898 ò#

[QPIGS2] PV2 Current(A)=17.6, PV2 Voltage(V)=220.8, PV2 Power(W)=3898.0

[2025-09-01 12:08:19] - [monitor.py] - [get_qpigs2]: END

Using

def _write_split_cr_padded(fd: int, buf: bytes):
cmd_crc, cr = buf[:-1], buf[-1:]
os.write(fd, cmd_crc)
os.write(fd, cr + b’\x00’ * 7)

Hi,

This is epic!

I have two paralleled 5048MG inverters and a Victron SmartShunt, currently using RPi4 management solution called ICC with a USB cable to one 5048MG and a ve.direct USB to the shunt.

So I have mosquitto and home assistant installed and I currently take inverter and shunt data into HASS via MQTT.

The Pi is 30 metres away (in a steel enclosure with the inverters) from the HASS server with only ethernet connectivity, I can’t add any new cables, I could use the physical CAT5A cable to do a “raw” connection with a USB extender or serial.

I’d prefer to relocate the Pi out of the inverter enclosure as it gets pretty hot in there.

Can this integration support two connections into two paralleled inverters?

How could I support my shunt data?

Bonus points for fanpico support as I would like to add some temp/fan monitoring to the inverter enclosure.

How would you cover that 30 metre distance?

  • Just have a PI in the enclosure
  • USB over IP
  • USB over CAT5A
  • 4x serial over CAT5A (fanpico & ve.direct are TTL)
  • Something else

Thanks.

Hi, did you manage to get the USB connection working?

Not similar but for Hypontech I use their cloud API to create a custom integration GitHub - jcisio/hypontech-homeassistant: Hypontech integration for Home Assistant

@catalinbordan I’m using your code which works fine with my PowerMaster Inverter but I just replaced the Inverter with a Datouboss 11kW which is RS232/RJ45 based and unfortunately, this doesn’t work anymore. I receive data from RS232 but get this error:

And with cat /dev/ttyUSB0:

Hello, I’m sorry for you, but I don’t know how to help you.