Victron MPPT Solar Charge Controller Live Data with ESPHome and Custom Sensor

Data from a Victron can be read out via the VE.Bus.
The VE.Bus is connected to an ESP8266.
The measurement data are transmitted via MQTT.

A big thanks goes to KinDR007 who provided the ESPHome integration. :+1:

https://github.com/KinDR007/VictronMPPT-ESPHOME
Check out his site for more information and examples.

7 Likes

Thanks for this charing ! it saves my life after a long try without success

Thanks for posting, this is a big help for my camper project!

Hi guys,

short question:
is it really necessary to reduce the voltage from 5V to 3,3V in order to use it with the ESP32?
Did someone already tryed it with 5V?

I use a few liquid-detection sensors they work quite fine with 5V and the ESP32, so I’m just questioning if the additional part is necessary.

Many greetings,
Chris!

Brief question: Can I use the 5V from the VCC to power the Wemos on the 5V-Pin?

Update: My Victron MPPT 100/20 has also 5V, but it works quite fine with the ESP32, no voltage divider necessary!

Do you perhaps have a guide for me on hooking up my 15/75 mppt to esp32? I already flashed the ESP32 but the wiring part I am battling with

So the ESPHome is a substitute for the CerboGX ?

Hi everyone,
I have the problem that I keep getting 0 values back. I’ve already timed the query up and down. However, that doesn’t help. Does anyone have an idea what I can do?

Can you please share your wiring an esphome code for the ESP32 and the 100/20?

I tried on mine a lot but still dont work…

Hello
I got it working withiut errors.
secret was: update_interval: 5s

esphome:
  name: mppt15035

substitutions:
  name: mppt1535
  external_components_source: github://KinDR007/VictronMPPT-ESPHOME@main
  updates: 10s

esp32:
  board: esp32-c6-devkitm-1
  variant: esp32c6
  framework:
    type: esp-idf
    version: 5.3.1
    platform_version: 6.9.0

ota:
  - platform: esphome
    password: "pw"

logger:
  baud_rate: 0

api:

wifi:
  ssid: BRAINTUNING
  password: pw
  manual_ip:
    static_ip: 192.168.1.185
    gateway: 192.168.1.1
    subnet: 255.255.255.0

web_server:
  port: 80
  auth:
    username: admin
    password: pw

external_components:
  - source: ${external_components_source}
    refresh: 0s

uart:
  id: uart_0
#  tx_pin: D8  # Not connected! The communication is read-only
  rx_pin: GPIO4  # Connect this this GPIO and GND to the MPPT charger
  baud_rate: 19200
  rx_buffer_size: 256


victron:
  uart_id: uart_0
  id: victron0
  throttle: 5s

sensor:
  - platform: victron
    victron_id: victron0
    charging_mode_id:
      name: "${name} charging mode id"
    error_code:
      name: "${name} error code"
    yield_total:
      name: "${name} yield total"
    yield_today:
      name: "${name} yield today"
    max_power_today:
      name: "${name} max power today"
    yield_yesterday:
      name: "${name} yield yesterday"
    max_power_yesterday:
      name: "${name} max power yesterday"
    day_number:
      name: "${name} day number"
    battery_current:
      name: "${name} battery current"
    panel_power:
      name: "${name} panel power"
    battery_voltage:
      name: "${name} battery voltage"
    panel_voltage:
      name: "${name} panel voltage"


text_sensor:
  - platform: victron
    victron_id: victron0
    device_type:
      name: "${name} device type"
    serial_number:
      name: "${name} serial number"
    firmware_version_24bit:
      name: "${name} firmware version 24bit"
    charging_mode:
      name: "${name} charging mode"
    error:
      name: "${name} error"
    device_mode:
      name: "${name} device mode"

The log

INFO ESPHome 2025.4.2
INFO Reading configuration /config/esphome/espc6mppt.yaml...
INFO Updating https://github.com/KinDR007/VictronMPPT-ESPHOME.git@main
WARNING The selected ESP-IDF framework version is not the recommended one. If there are connectivity or build issues please remove the manual version.
WARNING The selected ESP-IDF framework version is not the recommended one. If there are connectivity or build issues please remove the manual version.
INFO Starting log output from 192.168.1.185 using esphome API
INFO Successfully connected to mppt15035 @ 192.168.1.185 in 0.211s
INFO Successful handshake with mppt15035 @ 192.168.1.185 in 0.022s
[19:29:41][I][app:100]: ESPHome version 2025.4.2 compiled on May 20 2025, 18:45:45
[19:29:41][C][wifi:600]: WiFi:
[19:29:41][C][wifi:428]:   Local MAC: 40:4C:CA:5E:9F:00
[19:29:41][C][wifi:433]:   SSID: 'BRAINTUNING'[redacted]
[19:29:41][C][wifi:436]:   IP Address: 192.168.1.185
[19:29:41][C][wifi:439]:   BSSID: 94:83:C4:4A:6D:2A[redacted]
[19:29:41][C][wifi:441]:   Hostname: 'mppt15035'
[19:29:41][C][wifi:443]:   Signal strength: -82 dB ▂▄▆█
[19:29:41][C][wifi:447]:   Channel: 11
[19:29:41][C][wifi:448]:   Subnet: 255.255.255.0
[19:29:41][C][wifi:449]:   Gateway: 192.168.1.1
[19:29:41][C][wifi:450]:   DNS1: 0.0.0.0
[19:29:41][C][wifi:451]:   DNS2: 0.0.0.0
[19:29:41][C][logger:177]: Logger:
[19:29:41][C][logger:178]:   Max Level: DEBUG
[19:29:41][C][logger:179]:   Initial Level: DEBUG
[19:29:41][C][logger:181]:   Log Baud Rate: 0
[19:29:41][C][logger:182]:   Hardware UART: USB_SERIAL_JTAG
[19:29:41][C][uart.idf:159]: UART Bus 0:
[19:29:41][C][uart.idf:161]:   RX Pin: GPIO4
[19:29:41][C][uart.idf:163]:   RX Buffer Size: 256
[19:29:41][C][uart.idf:165]:   Baud Rate: 19200 baud
[19:29:41][C][uart.idf:166]:   Data Bits: 8
[19:29:41][C][uart.idf:167]:   Parity: NONE
[19:29:41][C][uart.idf:168]:   Stop bits: 1
[19:29:41][C][victron:032]: Victron:
[19:29:41][C][victron:035]:   Max Power Yesterday 'mppt1535 max power yesterday'
[19:29:41][C][victron:035]:     Device Class: 'power'
[19:29:41][C][victron:035]:     State Class: ''
[19:29:41][C][victron:035]:     Unit of Measurement: 'W'
[19:29:41][C][victron:035]:     Accuracy Decimals: 0
[19:29:41][C][victron:035]:     Icon: 'mdi:power'
[19:29:41][C][victron:036]:   Max Power Today 'mppt1535 max power today'
[19:29:41][C][victron:036]:     Device Class: 'power'
[19:29:41][C][victron:036]:     State Class: ''
[19:29:41][C][victron:036]:     Unit of Measurement: 'W'
[19:29:41][C][victron:036]:     Accuracy Decimals: 0
[19:29:41][C][victron:036]:     Icon: 'mdi:power'
[19:29:41][C][victron:037]:   Yield Total 'mppt1535 yield total'
[19:29:41][C][victron:037]:     Device Class: 'energy'
[19:29:41][C][victron:037]:     State Class: 'total_increasing'
[19:29:41][C][victron:037]:     Unit of Measurement: 'Wh'
[19:29:41][C][victron:040]:     Icon: 'mdi:flash'
[19:29:41][C][web_server:285]: Web Server:
[19:29:41][C][web_server:286]:   Address: 192.168.1.185:80
[19:29:41][C][mdns:116]: mDNS:
[19:29:41][C][mdns:117]:   Hostname: mppt15035
[19:29:41][C][esphome.ota:073]: Over-The-Air updates:
[19:29:41][C][esphome.ota:074]:   Address: 192.168.1.185:3232
[19:29:41][C][esphome.ota:075]:   Version: 2
[19:29:41][C][esphome.ota:078]:   Password configured
[19:29:41][C][safe_mode:018]: Safe Mode:
[19:29:41][C][safe_mode:019]:   Boot considered successful after 60 seconds
[19:29:41][C][safe_mode:021]:   Invoke after 10 boot attempts
[19:29:41][C][safe_mode:022]:   Remain in safe mode for 300 seconds
[19:29:41][C][api:140]: API Server:
[19:29:41][C][api:141]:   Address: 192.168.1.185:6053
[19:29:41][C][api:145]:   Using noise encryption: NO
[19:29:44][D][sensor:093]: 'mppt1535 battery voltage': Sending state 27.78000 V with 3 decimals of accuracy
[19:29:44][D][sensor:093]: 'mppt1535 battery current': Sending state 6.00000 A with 3 decimals of accuracy
[19:29:44][D][sensor:093]: 'mppt1535 panel voltage': Sending state 123.79000 V with 3 decimals of accuracy
[19:29:44][D][sensor:093]: 'mppt1535 panel power': Sending state 172.00000 W with 0 decimals of accuracy
[19:29:44][D][sensor:093]: 'mppt1535 charging mode id': Sending state 3.00000  with 0 decimals of accuracy
[19:29:44][D][text_sensor:064]: 'mppt1535 charging mode': Sending state 'Bulk'
[19:29:44][D][sensor:093]: 'mppt1535 error code': Sending state 0.00000  with 0 decimals of accuracy
[19:29:44][D][text_sensor:064]: 'mppt1535 error': Sending state 'No error'
[19:29:44][D][sensor:093]: 'mppt1535 yield total': Sending state 3018910.00000 Wh with 0 decimals of accuracy
[19:29:44][D][sensor:093]: 'mppt1535 yield today': Sending state 5660.00000 Wh with 0 decimals of accuracy
[19:29:44][D][sensor:093]: 'mppt1535 max power today': Sending state 1031.00000 W with 0 decimals of accuracy
[19:29:44][D][sensor:093]: 'mppt1535 yield yesterday': Sending state 3440.00000 Wh with 0 decimals of accuracy
[19:29:44][D][sensor:093]: 'mppt1535 max power yesterday': Sending state 1010.00000 W with 0 decimals of accuracy
[19:29:44][D][sensor:093]: 'mppt1535 day number': Sending state 264.00000  with 0 decimals of accuracy
[19:29:47][D][esp-idf:000][wifi]: I (174688) wifi:
[19:29:47][D][esp-idf:000][wifi]: [ADDBA]RX DELBA, reason:39, delete tid:0, initiator:1(originator)
[19:29:47][D][esp-idf:000][wifi]: 

[19:29:47][D][esp-idf:000][wifi]: I (174690) wifi:
[19:29:47][D][esp-idf:000][wifi]: <ba-del>idx:0, tid:0
[19:29:47][D][esp-idf:000][wifi]: 

[19:29:47][D][esp-idf:000][wifi]: W (174694) wifi:
[19:29:47][D][esp-idf:000][wifi]: <ba-add>idx:0, ifx:0, tid:0, TAHI:0x1002a6d, TALO:0x4ac48394, (ssn:513, win:64, cur_ssn:513), CONF:0xc0000005
[19:29:47][D][esp-idf:000][wifi]: 

[19:29:49][D][sensor:093]: 'mppt1535 battery voltage': Sending state 27.78000 V with 3 decimals of accuracy
[19:29:49][D][sensor:093]: 'mppt1535 battery current': Sending state 6.10000 A with 3 decimals of accuracy
[19:29:49][D][sensor:093]: 'mppt1535 panel voltage': Sending state 123.77000 V with 3 decimals of accuracy
[19:29:49][D][sensor:093]: 'mppt1535 panel power': Sending state 173.00000 W with 0 decimals of accuracy
[19:29:49][D][sensor:093]: 'mppt1535 charging mode id': Sending state 3.00000  with 0 decimals of accuracy
[19:29:49][D][text_sensor:064]: 'mppt1535 charging mode': Sending state 'Bulk'
[19:29:49][D][sensor:093]: 'mppt1535 error code': Sending state 0.00000  with 0 decimals of accuracy
[19:29:49][D][text_sensor:064]: 'mppt1535 error': Sending state 'No error'
[19:29:49][D][sensor:093]: 'mppt1535 yield total': Sending state 3018910.00000 Wh with 0 decimals of accuracy
[19:29:49][D][sensor:093]: 'mppt1535 yield today': Sending state 5660.00000 Wh with 0 decimals of accuracy
[19:29:49][D][sensor:093]: 'mppt1535 max power today': Sending state 1031.00000 W with 0 decimals of accuracy
[19:29:49][D][sensor:093]: 'mppt1535 yield yesterday': Sending state 3440.00000 Wh with 0 decimals of accuracy
[19:29:49][D][sensor:093]: 'mppt1535 max power yesterday': Sending state 1010.00000 W with 0 decimals of accuracy
[19:29:49][D][sensor:093]: 'mppt1535 day number': Sending state 264.00000  with 0 decimals of accuracy
[19:29:53][D][esp-idf:000][wifi]: I (181037) wifi:
[19:29:53][D][esp-idf:000][wifi]: [ADDBA]RX DELBA, reason:39, delete tid:0, initiator:1(originator)
[19:29:53][D][esp-idf:000][wifi]:

After seeing this I got an ESP8266 connected to my charge controller and reporting to HA.

I’ve now ordered a Victron Shunt.

My question is - can I add the Shunt VE.bus to a different GPIO pin on that same ESP8266, or do I need to use a second ESP8266?

I’m planning on the same thing for a Victron Blue Smart Charger and a SmartShunt. The below config seems to be valid. You need two UARTs, two Victrons and then you can compile the sensor list accordingly.

external_components:
  - source: github://KinDR007/VictronMPPT-ESPHOME@main

uart:
  - id: uart_0
    tx_pin: 10  # Not used! The communication is read-only
    rx_pin: 11
    baud_rate: 19200
    rx_buffer_size: 256
  - id: uart_1
    tx_pin: 12  # Not used! The communication is read-only
    rx_pin: 13
    baud_rate: 19200
    rx_buffer_size: 256

victron:
  - id: victron0
    uart_id: uart_0
  - id: victron1
    uart_id: uart_1

sensor:
  - platform: victron
    victron_id: victron0
    panel_voltage:
      name: "Panel voltage 0"
    battery_voltage:
      name: "Battery voltage 0"
    battery_current:
      name: "Battery current 0"
  - platform: victron
    victron_id: victron1
    panel_voltage:
      name: "Panel voltage 1"
    battery_voltage:
      name: "Battery voltage 1"
    battery_current:
      name: "Battery current 1"

Yes, that’s what I’ve done following some Googling. Thanks.

When I’ve tidied up the code I’ll post it. I need to sort out which entities are available from the charger and the shunt and decide which ones I actually want. I’m also using it (ESPHome/ESP32 S3) to turn on a relay to go to mains charging for those dark days in winter.

Additionally, the ESP32 has an RGB LED which I thought I would get flashing different colours to indicate different states.

Hi do i configure different pins?