ESPHome modbus Growatt ShineWiFi-S

I have the same problem with MOD10ktl3-XH-BP.
With the original WiFi-X stick I can read/write the Register (3049) via the website.
With the custom flashed WiFi-X stick → ESP-Home → Home-Assistant I can’t read or write the register.

Now i tried this Code, and it does nothing with my MIN TL-XH.
Any Ideas?

button:
  - platform: template
    name: "Battery First"
    on_press:
      then:
          lambda: |-
            esphome::modbus_controller::ModbusController *controller = id(growatt);
            std::vector<uint16_t> on={0,23*256+59,1};
            std::vector<uint16_t> off={0,23*256+59,0};
            int size = on.size();

            ESP_LOGI("ModbusLambda","Enqueue Writes");
            //BF1
            controller->queue_command(esphome::modbus_controller::ModbusCommandItem::create_write_multiple_command(controller,1100,size,on));
            //LF1
            controller->queue_command(esphome::modbus_controller::ModbusCommandItem::create_write_multiple_command(controller,1110,size,off));
            //GF1
            controller->queue_command(esphome::modbus_controller::ModbusCommandItem::create_write_multiple_command(controller,1080,size,off));
            ESP_LOGI("ModbusLambda","Writes");

  - platform: template
    name: "Load First"
    on_press:
      then:
          lambda: |-
            esphome::modbus_controller::ModbusController *controller = id(growatt);
            std::vector<uint16_t> on={0,23*256+59,1};
            std::vector<uint16_t> off={0,23*256+59,0};
            int size = on.size();

            ESP_LOGI("ModbusLambda","Enqueue Writes");
            //BF1
            controller->queue_command(esphome::modbus_controller::ModbusCommandItem::create_write_multiple_command(controller,1100,size,off));
            //LF1
            controller->queue_command(esphome::modbus_controller::ModbusCommandItem::create_write_multiple_command(controller,1110,size,on));
            //GF1
            controller->queue_command(esphome::modbus_controller::ModbusCommandItem::create_write_multiple_command(controller,1080,size,off));
            ESP_LOGI("ModbusLambda","Writes");

  - platform: template
    name: "Grid First"
    on_press:
      then:
          lambda: |-
            esphome::modbus_controller::ModbusController *controller = id(growatt);
            std::vector<uint16_t> on={0,23*256+59,1};
            std::vector<uint16_t> off={0,23*256+59,0};
            int size = on.size();

            ESP_LOGI("ModbusLambda","Enqueue Writes");
            //BF1
            controller->queue_command(esphome::modbus_controller::ModbusCommandItem::create_write_multiple_command(controller,1100,size,off));
            //LF1
            controller->queue_command(esphome::modbus_controller::ModbusCommandItem::create_write_multiple_command(controller,1110,size,off));
            //GF1
            controller->queue_command(esphome::modbus_controller::ModbusCommandItem::create_write_multiple_command(controller,1080,size,on));
            ESP_LOGI("ModbusLambda","Writes");

Based on the knowledge in this topic I created a Growatt monitor using a m5stack-atom-s3-lite and rs232 base. I have an old Growatt inverter hence it works with the esphome growatt platform (no battery just solar) out of the box. Really happy that it works! It is even powered by pin9 on the connector as the rs232base has a chip to convert the 12v. Thanks to all who contributed to this topic!

This is what it looks like (need to tidy up the wires and connector):

3 Likes

Would it be possible to share your config for this? It seems like nobody shared their RS232 config and everyone works with RS485 modbus.

Regards,
Paul

Here’s the config I used with the RS232 base from m5stack:

esphome:
  name: growattpv1
  friendly_name: Growatt PV Inverter Zolder

esp32:
  board: esp32-s3-devkitc-1
  framework:
    type: arduino

  
# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: !secret api_encryption_key

ota:
  - platform: esphome
    password: !secret ota_password 

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

uart:
  - id: mod_bus
    tx_pin: 6
    rx_pin: 5
    baud_rate: 9600

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: growatt_solar
    protocol_version: RTU

    inverter_status:
      name: "Growatt Status Code"

    phase_a:
      voltage:
          name: "Growatt Voltage Phase A"
      current:
          name: "Growatt Current Phase A"
      active_power:
          name: "Growatt Power Phase A"
    phase_b:
      voltage:
          name: "Growatt Voltage Phase B"
      current:
          name: "Growatt Current Phase B"
      active_power:
          name: "Growatt Power Phase B"
    phase_c:
      voltage:
          name: "Growatt Voltage Phase C"
      current:
          name: "Growatt Current Phase C"
      active_power:
          name: "Growatt Power Phase C"

    pv1:
      voltage:
          name: "Growatt PV1 Voltage"
      current:
          name: "Growatt PV1 Current"
      active_power:
          name: "Growatt PV1 Active Power"

    pv2:
      voltage:
          name: "Growatt PV2 Voltage"
      current:
          name: "Growatt PV2 Current"
      active_power:
          name: "Growatt PV2 Active Power"

    active_power:
      name: "Growatt Grid Active Power"

    pv_active_power:
      name: "Growatt PV Active Power"

    frequency:
      name: "Growatt Frequency"

    energy_production_day:
      name: "Growatt Today's Generation"

    total_energy_production:
      name: "Growatt Total Energy Production"

    inverter_module_temp:
      name: "Growatt Inverter Module Temp"

I’m also trying to build a logger using a Wemos D1 mini, the RS485 converter and ESPHome. It was a puzzle to get it working, as the hardware TX and RX UART pins were not working. At the end I’ve chosen two other GPIO pins (GPIO4 and GPIO5) and this works! I only have the trouble that the Wemos is unexpectedly resetting a few times per day. And once per week it is fully crashing and the only way to resolve this is to uplug and replug the power.

I’ve changed the Wemos as I was thinking it might be a fault of the device. With the new Wemos the crases seem to occur less, but are still occuring. In the code you can see that I’ve disabled the logger on the UART, so that should not be the cause of the problem.

Is there anybody with a simlar problem? Or ideas how to debug this?

This is the code I’m using:

substitutions:
  device_name: "esp-growatt"
  friendly_name: "Growatt"
  fixed_ip: "192.168.200.34"

packages:
  common: !include includes/common.yaml

esphome:
  name: "${device_name}"
  friendly_name: "${friendly_name}"

esp8266:
  board: d1_mini

debug:
  update_interval: 5s

logger:
 level: DEBUG
 baud_rate: 0   


uart:
  id: mod_bus
  tx_pin: D5 #werkte niet op de standaard TX en RX pins (die schijnen al bezet te zijn)
  rx_pin: D6
  baud_rate: 9600

modbus:
  id: modbus1
  uart_id: mod_bus

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

sensor:
  - platform: growatt_solar
    protocol_version: RTU
    pv1:
      voltage:
          name: "Growatt DC Voltage - v2 GS"


  - platform: modbus_controller
    address: 0
    register_type: "read"
    internal: true
    accuracy_decimals: 0
    id: status

  - platform: modbus_controller
    name: "${friendly_name} DC Power" # zelfde waarde als 5
    address: 1
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    id: DC_power
    filters:
    - multiply: 0.1
        
  - platform: modbus_controller
    name: "${friendly_name} AC Power - Three/single phase grid output"
    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: "${friendly_name} AC Power"
    address: 35
    register_type: "read"
    unit_of_measurement: W
    device_class: power
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    id: AC_power
    filters:
    - multiply: 0.1
    

  - platform: modbus_controller
    name: "${friendly_name} Temperature"
    address: 93 #kan ook 3093 gebruiken, 94 is ook hetzelfde
    register_type: "read"
    unit_of_measurement: °C
    device_class: temperature
    icon: mdi:thermometer
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

  - platform: modbus_controller
    name: "${friendly_name} Temperature - v2"
    address: 97 #kan ook 3097 gebruiken
    register_type: "read"
    unit_of_measurement: °C
    device_class: temperature
    icon: mdi:thermometer
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

  - platform: modbus_controller
    name: "${friendly_name} DC Voltage"
    address: 3
    register_type: "read"
    unit_of_measurement: V
    device_class: voltage
    icon: mdi:sine-wave
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
    
  - platform: modbus_controller
    name: "${friendly_name} DC Input Current"
    address: 4
    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: "${friendly_name} AC Frequency"
    address: 37
    register_type: "read"
    unit_of_measurement: Hz
    icon: mdi:sine-wave
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.01
  
  - platform: modbus_controller
    name: "${friendly_name} AC Voltage"
    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: "${friendly_name} AC Output Current"
    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: "${friendly_name} Production Today"
    address: 53
    register_type: "read"
    unit_of_measurement: kWh
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
    - lambda: |
        if (x < 0) return {}; 
        else if (x > 100000) return {}; 
        else return x;
    
  - platform: modbus_controller
    name: "${friendly_name} Production Total"
    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
    - lambda: |
        if (x < 0) return {}; 
        else if (x > 100000) return {}; 
        else return x;

  - platform: template
    name: "Inverter efficiency"
    lambda: |-
      return((id(AC_power).state / id(DC_power).state) * 100);
    unit_of_measurement: '%'

  - platform: debug
    free:
      name: "Heap Free"
    fragmentation:
      name: "Heap Fragmentation"
    block:
      name: "Heap Max Block"
    loop_time:
      name: "Loop Time"



text_sensor:

  - platform: debug
    device:
      name: "Device Info"
    reset_reason:
      name: "Reset Reason"      


I use tx_pin: 1 and rx_pin: 3 also a wemos d1 mini - no problems for 2 years.

Will share my config when back from holiday.

1 Like

@RT1080 , thanks for sharing your experience, that would be great!

In the meanwhile I’ve included the logger component, there I learn that the reboots are caused by the ‘Hardware watchdog’ and ‘Software watchdog’ (not always the same). This is the info logged at the last reset:

2024.7.3|Flash: 4096kB Speed:40MHz Mode:DOUT|Chip: 0x007ce14a|SDK: 2.2.2-dev(38a443e)|Core: 3.1.2|Boot: 6|Mode: 1|CPU: 80|Flash: 0x0016405e|Reset: Software Watchdog|Fatal exception:4 flag:3 (Software Watchdog) epc1:0x4026c2c6 epc2:0x00000000 epc3:0x000000

Edit: issue is possibly fixed by connecting the RS485 to the 3.3V connector on the ESP device, instead of the 5V connector. Possibly a too high voltage on the GPIO pins caused these crashes

Have you seen my post from the MOD TL-XH (post 315). It uses the same registers. I have explained it quite detailed, but you couldt just try my code. It looks like the code you used here, but with other numbers in the vectors. I have explained my vectors in the text.

1 Like

any suggestions where to start if I want to change the values of some registers of a GROWATT SPH 4600 single phase inverter ?

Thanks

What you have? Hardware, code, registers…

SPH 4600 connected via modbus to Eastron SDM 630
and
also connected to via Modbus to Pi / Homeassistant

like here in the bottome part (upper Part AC cabling)

In the long term I want to move Home Assistant Pi into the middle by using a proxy which means 1 ModBus from Eastron SDM 630 via Pi 4 to the SPH4600
to be able to use the other modbus port on the SPH 4600 via Laptop etc

which you can find here

I want to control the registers for charging the battery to have control over the charging speed .

Currently I am running that manually with the SPH onboard times slots like “battery first” from 11 am to 3 pm .
But that is not working as I wanted cause the charging power is jumping constantly from 0 to 1800 W and back close to 0 in 3 or 5 steps , sometimes up to 3000 W even in constant sunshine instead of showing a straight line.

I usually then change the power rate to 35% which then pushes the charging up to 3200 to 3300 Watt based on growatt figures. 65% x 4600 = 3000 W from the panels used for dc charging the battery out of 4600 Watt possible, so 1600 Watt AC left.

But I want to get rid of the manual interaction and the timer that is required now.

The SPH 4600 has 2x 2.800 Wp strings, so each string overpanelled by 500 Wp.

Therefore I am asking cause I miss this feature.

Hi there,

Can you still use this code?

A tip for whoever is using this drawing. I had an issue of sudden watchdog resets of my ESP device. After a lot of troubleshooting (replacing the ESP device, trying ESP32, replacing the RS485 converter, changing GPIO ports, etc etc) I found out that the RS485 convertor should be connected to the 3.3V pin of the ESP instead of the 5V. By connecting it to the 5V it is crashing the ESP every now and then. Possibly because a too high voltage on the GPIO pins

1 Like

Hi guys,

this is my config for the following setting:

SPH4000TL BL-UP
ARK-2.5L-A1
Smart Meter TPM-C 3
Shinewifi-X WiFi-Stick

With this config you can control AC charge and Prefered Mode (Load First/Battery First):

substitutions:
  name: esphome-web-c04f7a
  friendly_name: GW

  
esphome:
  name: "growatt-wechselrichter"
  #on_loop:
    #then:
      #- lambda: delay(5);
      
esp8266:
  board: esp07s

#Enable logging
#logger:
  #baud_rate: 0

# Enable Home Assistant API
api:
  encryption:
    key: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

ota:
  - platform: esphome
    #safe_mode: true
    password: "XX"

wifi:
  ssid: WIFI SSID
  password: XX


  manual_ip:
    static_ip: 192.xxx.xxx.x
    gateway: 192.xxx.xxx.x
    subnet: 192.xxx.xxx.x
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "fallback"
    password: "XXXXXX"

captive_portal:


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
  tx_pin: 1
  rx_pin: 3
  baud_rate: 115200
  
modbus:
  id: modbus1
  uart_id: mod_bus
  
modbus_controller:
  - id: growatt
# the Modbus device addr
    address: 0x1
    modbus_id: modbus1
    setup_priority: -10  
    update_interval: 5s


sensor:


  - platform: wifi_signal
    name: "A-WLAN Signalstärke"
    #update_interval: 5s
   


  - platform: modbus_controller
    name: "GW Ausgangsleistung"
    address: 35
    register_type: "read"
    unit_of_measurement: W
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1


  - platform: modbus_controller
    name: "GW PV Strang 2 Erzeugung Heute"
    address: 63
    register_type: "read"
    unit_of_measurement: kW
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1



  - platform: modbus_controller
    name: "GW PV Strang 1 Erzeugung Heute"
    address: 59
    register_type: "read"
    unit_of_measurement: kW
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1


  - platform: modbus_controller
    name: "GW Strang 1 Leistung"
    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: "GW Strang 2 Leistung"
    address: 9
    register_type: "read"
    unit_of_measurement: W
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1


  - platform: modbus_controller
    name: "GW Power out Wechselrichter"
    address: 1031
    register_type: "read"
    unit_of_measurement: W
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 0
    filters:
    - multiply: 0.1


  - platform: modbus_controller
    name: "GW Batterie geladen Heute"
    address: 1056
    register_type: "read"
    unit_of_measurement: kWh
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1


  - platform: modbus_controller
    name: "GW Batterie entladen Heute"
    address: 1052
    register_type: "read"
    unit_of_measurement: kWh
    device_class: energy
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1



  - platform: modbus_controller
    name: "GW Batterie Ladezustand"
    address: 1014
    register_type: "read"
    unit_of_measurement: "%"
    device_class: POWER_FACTOR
    state_class: measurement
    entity_category: diagnostic
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 0
    filters:
    - multiply: 1



  - platform: modbus_controller
    name: "GW Batterie Entladeleistung Live"
    address: 1009
   
    register_type: "read"
    unit_of_measurement: W
    state_class: measurement
    device_class: power
    entity_category: diagnostic
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 0
    filters:
    - multiply: 0.1

  - platform: modbus_controller
    name: "GW Batterie Ladeleistung Live"
    address: 1011
    register_type: "read"
    unit_of_measurement: W
    state_class: measurement
    device_class: power
    entity_category: diagnostic
    icon: mdi:flash
    value_type: U_DWORD
    accuracy_decimals: 0
    filters:
    - multiply: 0.1

 


select:


      
  - platform: modbus_controller
    name: "GW Batterie Modus Load/Batterie/Netz"
    address: 1044
    value_type: U_WORD
    optionsmap:
      "Load First": 0
      "Battery First": 1
      "Grid First": 2

  - platform: modbus_controller
    name: "GW Batterie AC Laden Ein/AUS (nur im Modus Batt First)"
    icon: mdi:battery-charging-100
    address: 1092
    value_type: U_WORD
    optionsmap:
      "AC Laden AUS (gilt nur im Batt First Modus)": 0
      "AC Laden AN (gilt nur im Batt First Modus)": 1

Maybe it will be helpful for some people
kafisc

2 Likes

Hello everyone, I have gone through this thread several times over the month and sometimes it gets confusing. I am looking for something that works with my Growatt SPF 6000 ES, locally. I don’t mind getting rid of the Shine Wifi stick. The Open Inverter doesn’t support SPF yet and even the Solarx Modbus integration.

I had something earlier when I used to use SRNE (SRNE inverter integration help) and it worked perfectly. I hope I can get something similar to it.

Hardware, diagrams and code would be helpful. Thanks so much.

I’ve written about what I did in a blog post which basically summarises anything I wrote above, but puts it in one place as to how I got an ESP32 talking to and controlling a SPH6000 inverter. I hope it is useful.

1 Like

I doubt you will find much help here this way.
SPF 6000 ES are a total different beast afaik.
They are even using a specific and different protocol which I can choose inside my JK BMS: SPH or SPF

Open a topic and hope for the best.

That BLOG Link is a great one. I did not know you have the GBLI battery.

But that would mean that Growatt can not have changed that much regarding the canbus protocol cause those batteries are quite old. I have one bought - as used and for cheap where the BMS is not doing well, but I got a replacemend JK BMS which can replace the genuine one cause it has a JK BMS protocoll for the SPH series.

I wonder if your solution would work for the most recent ones too, the JK Inverter BMS for example.

And how do you connect that ESP - can I use the WiFi Stick in parallel too ?
I have read that you seem to use at least 2 pins of the serial port which I currently use for the Wifi stick or could I use both in parallel ?

Thanks for sharing

Hello, thanks for the heads-up. I just created one here.

1 Like