ESPHome modbus Growatt ShineWiFi-S

The growatt you have uses a shine-wifi X so the registers should be fine with the code for the wifi-X. When i have time I can search for the registers for your inverter specific. Else you can try the wifi-X module.

1 Like

I have a growatt wifi that is uploading to the growatt site. that works fine, but the growatt addon that is downloading from the growatt website is causing problems every time, i donā€™t get the values in the Energy dashboard.

So i decided the use the RS485 signal to import the values for the energy dasboard.
And this is now my problem.
I use the wifi stick to upload to server.growatt.com, and want to use the RS485 to download the inverter values for the energy dashboard.

1 Like

Hi,
Iā€˜m installing my 2KWp PV in the next few weeks and I choose a Growatt 2000 TL-X. Hope this works also with your code.

I want to set a export limitation. Does this code also allow to set registers? Or is this only for reading. I donā€˜t want to by a extra Modbus-Smartmeter only for setting a export Limitation because e I have a Shelly 3EM and want to use this with HomeAssistant / NodeRed to set a export limitation dynamically.

Best regards
Dominic

1 Like

Hi, I am looking for hints on this too. Should I first flash with the otti firmware? How to get started?

Connect the esp to a USB to serial adapter. Connect the serial adapter with your pc. Then upload the code with esphome. You can download the bin file and upload it with the esphome flasher Releases Ā· esphome/esphome-flasher Ā· GitHub

Or if you have a secure connection, you can upload the code in the browser.

@Dominic_bemila This is very interesting. I will look at that when I have some more spare time. I hope my inverter does support that function.

Hi, Iā€™m also interested in flashing my shine wifi x as an ESPHome device but, then I guess the connection to Growatt cloud server will be lost, is this true? @WilbertV Thanks for your answer.

That is correct. That was the first reason why I did it. Local/reliable connection with home assistant was the second.

Thanks @WilbertV , I understand your point of view but for me the perfect solution would be to keep the connection with Growatt servers (to have stored all current and historical data) but to be able to connect also locally and without any delay (for example via modbus), using this connection with HA.

Has anyone here installed this on an esp32 and connected it to the rs485 RJ45 port on their growatt ? while also leaving the stock dongle in place and have both working?

Iv managed to really confuse myself.

From my understanding modbus has 1 master and all else are slaves, but then if that is the case how is my setup working? I have the stock standard dongle working, and my pylons are connected to my spf5000es by the rs485 RJ45 port (only way I could get BMS talking when I started) I would assume the dongle is the master on modbus. In the case of BMS connected on rs485 instead of can, is the battery a slave on modbus or the invertor.

My plan is to to see if I can get my BMS working via the can port, and then hook up an esp32 to the rs485 to get real-time readings using esphome. Currently using the Grott integration which works well, but 5 minute updates are not cutting it for my automations in HA.

Also anyone managed to program the invertor through esphome, update setting etc

Tried an esp32 with my growatt spf5000es, as I donā€™t want to risk buggering my shine F dongle just yet,
figured the esp32 although overkill may be more stable due to the extra memory and cpu. connected by the usb mini to the usb A port where the dongle goes on inverter. My registers are correct, logs specify that itā€™s using the hardware uart0 but No comms. Tried both baud rates although shine F is 9600, any ideas?

That is a very interesting project. By reflashing the Shinestick I assume you lose cloud connection and more important update features I guess.
I have an SPH 3600 and a Shine-S connected to serial interface.
Do you think I can modify the Shine-X and connect it to the USB next to the Shine-S?

Hi, iā€™d like to get update my shinewifi-x for my inverter MIN-6000TL-XH and so add it and configure with home assistant, can you help me? I have doubts about the better way to do this!

I hope your replies!!!

Thanks a lot!!!

Other doubt, with the update is it possible to read information in real time?

Just thought Iā€™d share my configuration as well, based off of the excellent work of Wilbert (super bedankt!). I had some issues getting the right register definitions for my device. I have an SPH 4000TL3 BH and the cloud solution just wasnā€™t cutting it for me.

Please note that if you want to read too many modbus registers (at one point I had 3 register ranges with over 60 registers per range), the device WILL hang and reboot continuously (thanks to growattā€™s lovely 9600 baud!). Iā€™d love to look into the esp firmware and fix that (Iā€™m an embedded s/w dev after all, should be easy-peasy, right?)

I am still having one issue, Iā€™ve created a template sensor based on some of these growatt sensors, but itā€™s not showing up in my energy dashboard, anyone know whatā€™s going on? I replied to a similar issue discussion here: https://community.home-assistant.io/t/creating-a-template-energy-sensor-for-energy-dashboard/328404/8

And now my config:

EDIT: FYI, I bought a second ShineWifi-S stick for this, didnā€™t want to void warranty on the original one :slight_smile:

esphome:
  name: growatt

esp8266:
  board: esp07

# Enable Home Assistant API
api:
  encryption:
    key: <redacted>

ota:
  password: <redacted>

wifi:
  ssid: !secret wifi_ssid_ch
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Growatt Fallback Hotspot"
    password: <redacted>

captive_portal:

substitutions:
  devicename: growatt
  friendly_name: "Growatt 1 Inverter"

logger:
  level: DEBUG
  baud_rate: 0

web_server:
  port: 80

time:
  - platform: homeassistant
    id: homeassistant_time

output:
# Blue Led
  - id: light_bl
    platform: gpio
    pin: 16
# Green Led
  - id: light_gr
    platform: gpio
    pin: 0
# Red Led
  - id: light_rd
    platform: gpio
    pin: 2

uart:
  - id: mod_bus
    baud_rate: 9600
    tx_pin: GPIO1
    rx_pin: GPIO3

modbus:
  id: modbus1
  uart_id: mod_bus
  flow_control_pin: GPIO4

modbus_controller:
  - id: growatt
    address: 0x1
    modbus_id: modbus1
    setup_priority: -10

sensor:
  - platform: uptime
    name: "${devicename} Uptime Sensor"
    id: uptime_sensor
    update_interval: 60s

#RANGE1
  - platform: modbus_controller
    name: "${devicename} Total Power"
    address: 35
    register_type: "read"
    unit_of_measurement: kW
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 3
    filters:
    - multiply: 0.0001
  - platform: modbus_controller
    name: "${devicename} AcFrequency"
    address: 37
    register_type: "read"
    unit_of_measurement: Hz
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.01
  - platform: modbus_controller
    name: "${devicename} AcVoltage VAC1"
    address: 38
    register_type: "read"
    unit_of_measurement: V
    device_class: voltage
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} AcOutputCurrent IAC1"
    address: 39
    register_type: "read"
    unit_of_measurement: A
    device_class: current
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} AcPower PAC1"
    address: 40
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} AcVoltage VAC2"
    address: 42
    register_type: "read"
    unit_of_measurement: V
    device_class: voltage
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} AcOutputCurrent IAC2"
    address: 43
    register_type: "read"
    unit_of_measurement: A
    device_class: current
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} AcPower PAC2"
    address: 44
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} AcVoltage VAC3"
    address: 46
    register_type: "read"
    unit_of_measurement: V
    device_class: voltage
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} AcOutputCurrent IAC3"
    address: 47
    register_type: "read"
    unit_of_measurement: A
    device_class: current
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} AcPower PAC3"
    address: 48
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Total Energy Today"
    address: 53
    register_type: "read"
    unit_of_measurement: kWh
    state_class: total_increasing
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Total Energy Lifetime"
    address: 55
    register_type: "read"
    unit_of_measurement: kWh
    state_class: total_increasing
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

#RANGE2 (deleted because of issues)

#RANGE3
  - platform: modbus_controller
    name: "${devicename} Battery Discharging Power"
    address: 1009
    register_type: "read"
    unit_of_measurement: kW
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 3
    filters:
    - multiply: 0.0001
  - platform: modbus_controller
    name: "${devicename} Battery Charging Power"
    address: 1011
    register_type: "read"
    unit_of_measurement: kW
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 3
    filters:
    - multiply: 0.0001
  - platform: modbus_controller
    name: "${devicename} Battery Charge"
    address: 1014
    register_type: "read"
    unit_of_measurement: "%"
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 0
  - platform: modbus_controller
    name: "${devicename} Power to User 1"
    address: 1015
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Power to User 2"
    address: 1017
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Power to User 3"
    address: 1019
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Power to User Total"
    address: 1021
    register_type: "read"
    unit_of_measurement: kW
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 3
    filters:
    - multiply: 0.0001
  - platform: modbus_controller
    name: "${devicename} Power to Grid 1"
    address: 1023
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Power to Grid 2"
    address: 1025
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Power to Grid 3"
    address: 1027
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Power to Grid Total"
    address: 1029
    register_type: "read"
    unit_of_measurement: kW
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 3
    filters:
    - multiply: 0.0001
  - platform: modbus_controller
    name: "${devicename} INV Power to Local Load 1"
    address: 1031
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} INV Power to Local Load 2"
    address: 1033
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} INV Power to Local Load 3"
    address: 1035
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} INV Power to Local Load Total"
    address: 1037
    register_type: "read"
    unit_of_measurement: kW
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 3
    filters:
    - multiply: 0.0001
  - platform: modbus_controller
    name: "${devicename} Energy to User Today"
    address: 1044
    register_type: "read"
    unit_of_measurement: kWh
    state_class: total_increasing
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Energy to User Total"
    address: 1046
    register_type: "read"
    unit_of_measurement: kWh
    state_class: total_increasing
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Energy to Grid Today"
    address: 1048
    register_type: "read"
    unit_of_measurement: kWh
    state_class: total_increasing
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Energy to Grid Total"
    address: 1050
    register_type: "read"
    unit_of_measurement: kWh
    state_class: total_increasing
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Battery Discharge Today"
    address: 1052
    register_type: "read"
    unit_of_measurement: kWh
    state_class: total_increasing
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Battery Discharge Total"
    address: 1054
    register_type: "read"
    unit_of_measurement: kWh
    state_class: total_increasing
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Battery Charge Today"
    address: 1056
    register_type: "read"
    unit_of_measurement: kWh
    state_class: total_increasing
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Battery Charge Total"
    address: 1058
    register_type: "read"
    unit_of_measurement: kWh
    state_class: total_increasing
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Local Load Today"
    address: 1060
    register_type: "read"
    unit_of_measurement: kWh
    state_class: total_increasing
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  - platform: modbus_controller
    name: "${devicename} Local Load Total"
    address: 1062
    register_type: "read"
    unit_of_measurement: kWh
    state_class: total_increasing
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

Again, thanks for the excellent work!

2 Likes

it is sort of, i have pretty much got it down to a 5 seconds interval. I could not get it to skip updates on the diagnostic sensors so i have disabled them because i donā€™t want to spam the home assistant recorder by non relevant data. by skipping updates on the diagnostic sensors it skips also the AcPower and in my case one of the strings.

substitutions:
  device_description: Growatt Inverter
  friendly_name:  Growatt Inverter
  name: Growatt

esphome:
  name: growatt

esp8266:
  board: esp07s

# Enable logging
logger:
  baud_rate: 0
# Enable Home Assistant API
api:

ota:
  password: !secret ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: 192.168.30.30
    gateway: 192.168.30.1
    subnet: 255.255.255.0

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "${name} Fallback Hotspot"
    password: "Yourpassword"

captive_portal:

time:
  - platform: homeassistant
    id: homeassistant_time

output:
  - id: light_blauw
    platform: gpio
    pin: 16
  - id: light_groen
    platform: gpio
    pin: 0
  - id: light_rood
    platform: gpio
    pin: 2

uart:
  id: mod_bus
  tx_pin: 1
  rx_pin: 3
  baud_rate: 9600
  
modbus:
  id: modbus1
  uart_id: mod_bus
  
modbus_controller:
  - id: growatt
    address: 0x1
    modbus_id: modbus1
    update_interval: 5s
    setup_priority: -10  

# text_sensor:
#   - platform: template
#     name: "${name} Status"
#     icon: mdi:eye
#     entity_category: diagnostic
#     lambda: |-
#       if (id(status).state = 1) {
#         return {"Normal"};
#       } else if (id(status).state = 0)  {
#         return {"Waiting"};
#       } else {
#         return {"Fault!"};
#       }

sensor:
  - platform: modbus_controller
    name: "${name} AcPower"
    address: 16
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    state_class: measurement
    icon: mdi:solar-power
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

  - platform: modbus_controller
    name: "${name} EnergyToday"
    address: 26
    register_type: "read"
    unit_of_measurement: kWh
    device_class: energy
    icon: mdi:solar-power
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

  - platform: modbus_controller
    name: "${name} EnergyTotal"
    address: 28
    register_type: "read"
    unit_of_measurement: kWh
    state_class: total_increasing
    device_class: energy
    icon: mdi:solar-power
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

  - platform: modbus_controller
    name: "${name} Pv1 Power"
    address: 5
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

  - platform: modbus_controller
    name: "${name} Pv2 Power"
    address: 9
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

##     diagnostics    ##

  - platform: modbus_controller
    name: "${name} Temperature"
    address: 32
    register_type: "read"
    unit_of_measurement: Ā°C
    device_class: temperature
    entity_category: diagnostic
    icon: mdi:thermometer
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

  # - platform: modbus_controller
  #   address: 0
  #   register_type: "read"
  #   internal: true
  #   id: status
      
  # - platform: modbus_controller
  #   name: "${name} DcPower"
  #   address: 1
  #   register_type: "read"
  #   unit_of_measurement: W
  #   device_class: power
  #   entity_category: diagnostic
  #   disabled_by_default: true
  #   icon: mdi:flash
  #   value_type: U_DWORD
  #   accuracy_decimals: 1
  #   filters:
  #   - multiply: 0.1
    
  # - platform: modbus_controller
  #   name: "${name} DcVoltage"
  #   address: 3
  #   register_type: "read"
  #   unit_of_measurement: V
  #   device_class: voltage
  #   entity_category: diagnostic
  #   disabled_by_default: true
  #   icon: mdi:flash
  #   value_type: U_WORD
  #   accuracy_decimals: 1
  #   filters:
  #   - multiply: 0.1
    
  # - platform: modbus_controller
  #   name: "${name} DcInputCurrent"
  #   address: 4
  #   register_type: "read"
  #   unit_of_measurement: A
  #   device_class: current
  #   entity_category: diagnostic
  #   disabled_by_default: true
  #   icon: mdi:flash
  #   value_type: U_WORD
  #   accuracy_decimals: 1
  #   filters:
  #   - multiply: 0.1
    
  # - platform: modbus_controller
  #   name: "${name} AcFrequency"
  #   address: 13
  #   register_type: "read"
  #   unit_of_measurement: Hz
  #   entity_category: diagnostic
  #   disabled_by_default: true
  #   icon: mdi:flash
  #   value_type: U_WORD
  #   accuracy_decimals: 1
  #   filters:
  #   - multiply: 0.01
  
  # - platform: modbus_controller
  #   name: "${name} AcVoltage"
  #   address: 14
  #   register_type: "read"
  #   unit_of_measurement: V
  #   device_class: voltage
  #   entity_category: diagnostic
  #   disabled_by_default: true
  #   icon: mdi:flash
  #   value_type: U_WORD
  #   accuracy_decimals: 1
  #   filters:
  #   - multiply: 0.1
  
  # - platform: modbus_controller
  #   name: "${name} AcOutputCurrent"
  #   address: 15
  #   register_type: "read"
  #   unit_of_measurement: A
  #   device_class: current
  #   entity_category: diagnostic
  #   icon: mdi:flash
  #   value_type: U_WORD
  #   accuracy_decimals: 1
  #   filters:
  #   - multiply: 0.1

Is the DcVoltage and DcInputCurrent in pasarns code combined from pv1 and pv2?

Really interesting work you are doing.

Is it possible to send commands to the inverter e.g. set the inverter to AC-charge?

Hi, I am going to try that! I have ordered the D1 mini now. One question: I already have a Wifi-X dongle connected to the USB port, do you think the WifiX and your solution connected on the COM port would work together?

Thanks! :slight_smile:

1 Like

Hello! I have a Growatt SPF5000ES with shineF. I bought a shineX, to replace the original shineF, and flash-it with JohnGalt1717 last yaml. The flash works without problem. But I donā€™t receive any data. I have tried with 9600 and 115200 bauds. Please, do you have any solutions? Thanks!