ESPHome modbus Growatt ShineWiFi-S

In the opening post is a link where you can find pictures. I wanted to do a how to for the ShineWifi-s but can’t find the time yet. I can walk you through it though, if you want.

That would be great!
So I’ll start with soldering pin headers on tx, rx, grnd and 3.3v. Also solder a 1K resistance to sw1 and gpio0?
It’s been a long while since I flashed something that hasnt got a usb slot, like sonoff

You don’t have to solder anything. Get 5 male to female jumpers. Connect the female side to your serial adapter and the male side you poke to the holes of the board. Connect gpio0 to the common ground. On the board, make sure that the pins are in a angle before you plug in the USB side of the adapter. That way it connects to the tin pad. Ready to flash

And then just flash the esphome script you provided? Easy as that?

Yes Sir, Check the wifi credentials and if you have more sticks/inverters, give it a different name. Thats it.

It worked! The wiring was tricky, I’d advise soldering anyway.
After several attempts I got it uploaded. It’s now collecting data.

Thanks for sharing!

It would be nice if we could upload to pvoutput without home assistant in the middle

Glad it worked! Thank you for report it back. Pvoutput can be done with Arduino and maybe with the esphome http request, but I haven’t done something like that yet. There is a way to let home assistant or an other platform report to pvoutput, but than you have a man in the middle.

@pasarn Would you like to try the status sensor on the X? On the S it is looking like this and the modbus code should be the same.

Schermafbeelding 2022-04-14 om 17.41.16

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
    address: 0
    register_type: "read"
    internal: true
    id: status

So I decided to desolder the ESP07 from the ShineWifi-F that I have and put in a ESP-12. That works fine but the values are insane. (I think off by many orders of magnitude.)

I’m using the setup here: Growatt Solar — ESPHome

Here’s what I’m getting:

Name State Actions
Growatt Current Phase A 0.00 A
Growatt Current Phase B 495.50 A
Growatt Current Phase C 600.00 A
Growatt Frequency 0.00 Hz
Growatt Grid Active Power 26 W
Growatt Inverter Module Temp 15.1 °C
Growatt PV Active Power 19654246 W
Growatt PV1 Active Power 0 W
Growatt PV1 Current 98.00 A
Growatt PV1 Voltage 0.00 V
Growatt Power Phase A 584 W
Growatt Power Phase B 0 W
Growatt Power Phase C 19 W
Growatt Status Code 12
Growatt Today’s Generation 1114112.00 kWh
Growatt Total Energy Production 0 kWh
Growatt Voltage Phase A 0.00 V
Growatt Voltage Phase B 7.50 V
Growatt Voltage Phase C 240.90 V

I’d say that the current on phases is just wrong, because it’s single phase, but could be 4.8 and 6.0 because there is nothing hooked up but even that sounds high. Might be off by 1000 and be 0.48 and 0.60

Frequency just isn’t set.

The Inverter Module Temp is probably right.

PV Active power is probably off by 1000 as well. The current for PV1 is probably off by a factor of 10.

Etc.

Phase C voltage is the only one accurate.

Suggestions on how to clean this up?

I’ll try tomorrow. What and when will give it a waiting or fault message?

Maybe a dumb answer from a noob, but my first guess is that some of the pins might be swapped because of a different pinout?

@JohnGalt1717 Wow you’re a hero! What is your inverter type? I did not succeed with the building esphome growatt integration.

The ESP07 and ESP12 have the same pin outs, but thanks!

1 Like

@JohnGalt1717 I would try the shine x code GitHub - WilbertVerhoeff/Growatt: Growatt ShineWifi modbus with ESPHome code to run native in Home Assistant that one is also with a USB connection

SFP 5000 US is the model No

To be clear this is me hacking a ShineWifi-F. I haven’t hooked it up via Serial yet. I was trying to avoid that and I’d much rather use canbus for that if possible because then I can get the data from all 6 of my units AND my BMSes over the same cable with a single chip. Anyone that has insight into getting CanBus working I’d be very happy!

This configuration gets me close:

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: uart1
    baud_rate: 9600
    tx_pin: GPIO1
    rx_pin: GPIO3

modbus:
  uart_id: uart1
  flow_control_pin: GPIO4

sensor:
  - platform: growatt_solar
    update_interval: 10s

    inverter_status:
      name: "${device_name} Status Code"

    phase_c:
      voltage:
          name: "${device_name} AC Voltage"
      current:
          name: "${device_name} AC Current"
          filters:
            - multiply: 0.001
      active_power:
          name: "${device_name} AC Power"

    pv1:
      voltage:
          name: "${device_name} PV Voltage"
      current:
          name: "${device_name} PV Current"
          filters:
            - multiply: 0.1
      active_power:
          name: "${device_name} PV Active Power"

    active_power:
      name: "${device_name} Grid Active Power"

    pv_active_power:
      name: "${device_name} PV Active Power"

    frequency:
      name: "${device_name} Frequency"

    energy_production_day:
      name: "${device_name} Today's Generation"
      filters:
        - multiply: 0.00001

Doesn’t give me the PV voltage, nor active power sadly. Also doesn’t give the AC frequency but I know what that is…

The ShineF code on there gets you to the same spot with the 5000 US as just using the integration… May just be other modbus stuff for the SFP 5000 US than the standard…

Wow, impressive setup! Would love to know more about that!
I think I have found the documentation Growatt OffGrid SPF5000 Modbus RS485 RTU Protocol - PDF Free Download
maybe for the total setup (I had a fast read) Please let me know if we can chat sometime somewhere

I’m not a big modbus guy, but I might have to be I guess… I can see the request calls for it in there.

My other issue is that what I posted gets the esphome web portal for the device to show the right kW but then home assistant is showing it 1000x larger because it thinks it’s getting watts…

Update: See below. Better version.

Archived.

So this works (mostly, still tweaking but input requested) for the SPF-5000 ES/US. It should work with all Shine devices if you can flash them. I got it working by replacing the 07 chip on the -F with a 12F. I suspect you can do the same on all of them.

Next up, I’m working on getting multiple inverters over a single wifi dongle…

Edit You need one wifi dongle per unit. And here is the final version that works properly with the energy functionality in Home Assistant.

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

esphome:
  name: ${device_name}
  platform: ESP8266
  board: esp01_1m  
  
# Enable Home Assistant API
api:

ota:
  password: !secret esphome_ota_password

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

captive_portal:

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  


text_sensor:
  - platform: template
    name: "${friendly_name} Status"
    icon: mdi:eye
    entity_category: diagnostic
    lambda: |-
      if ((id(status).state) == 1) {
        return {"Normal"};
      } else if ((id(status).state) == 0)  {
        return {"Standby"};
      } else if ((id(status).state) == 2)  {
        return {"Discharge"};
      } else if ((id(status).state) == 3)  {
        return {"Fault"};
      } else if ((id(status).state) == 4)  {
        return {"Flash"};
      } else if ((id(status).state) == 5)  {
        return {"PV Charging"};
      } else if ((id(status).state) == 6)  {
        return {"AC Charging"};
      } else if ((id(status).state) == 7)  {
        return {"Combined Charging"};
      } else if ((id(status).state) == 8)  {
        return {"Combined Charging & Bypass"};
      } else if ((id(status).state) == 9)  {
        return {"PV Charging & Bypass"};
      } else if ((id(status).state) == 10)  {
        return {"AC Charging & Bypass"};
      } else if ((id(status).state) == 11)  {
        return {"Bypass"};
      } else if (id(status).state == 12)  {
        return {"PV Charge and Discharge"};
      } else {
        return {"Unknown"};
      }

sensor:
  - platform: wifi_signal
    name: "WiFi Signal Sensor"
    update_interval: 60s
    
  - platform: modbus_controller
    address: 0
    register_type: "read"
    internal: true
    accuracy_decimals: 0
    id: status
    
  - platform: modbus_controller
    name: "${friendly_name}  Solar Energy Today"
    address: 49
    register_type: "read"
    unit_of_measurement: Wh
    device_class: energy
    state_class: total_increasing
    icon: mdi:solar-power
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.01    

  - platform: modbus_controller
    name: "${friendly_name} AC Charge Energy Today"
    address: 57
    register_type: "read"
    unit_of_measurement: Wh
    device_class: energy
    state_class: total_increasing
    icon: mdi:solar-power
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1    

  - platform: modbus_controller
    name: "${friendly_name} AC Ouput Energy Today"
    address: 65
    register_type: "read"
    unit_of_measurement: Wh
    device_class: energy
    state_class: total_increasing
    icon: mdi:solar-power
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1    

  - platform: modbus_controller
    name: "${friendly_name} Solar Voltage"
    address: 1
    register_type: "read"
    unit_of_measurement: V
    device_class: voltage
    state_class: measurement
    entity_category: diagnostic
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
    
  - platform: modbus_controller
    name: "${friendly_name} Solar Current"
    address: 7
    register_type: "read"
    unit_of_measurement: A
    device_class: current
    state_class: measurement
    entity_category: diagnostic
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

  - platform: modbus_controller
    name: "${friendly_name} Solar Power"
    address: 3
    register_type: "read"
    unit_of_measurement: W
    state_class: measurement
    device_class: energy
    icon: mdi:solar-power
    value_type: U_DWORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1    
    
  - platform: modbus_controller
    name: "${friendly_name} AC Output Hz"
    address: 23
    register_type: "read"
    unit_of_measurement: Hz
    entity_category: diagnostic
    state_class: measurement
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.01
  
  - platform: modbus_controller
    name: "${friendly_name} AC Output Voltage"
    address: 22
    register_type: "read"
    unit_of_measurement: V
    device_class: voltage
    state_class: measurement
    entity_category: diagnostic
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

  - platform: modbus_controller
    name: "${friendly_name} AC Output Current"
    address: 34
    register_type: "read"
    unit_of_measurement: A
    device_class: current
    state_class: measurement
    entity_category: diagnostic
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

  - platform: modbus_controller
    name: "${friendly_name} AC Output Power"
    address: 69
    register_type: "read"
    unit_of_measurement: W
    device_class: current
    state_class: measurement
    entity_category: diagnostic
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
  
  - platform: modbus_controller
    name: "${friendly_name} AC Input Hz"
    address: 21
    register_type: "read"
    unit_of_measurement: Hz
    entity_category: diagnostic
    state_class: measurement
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.01

  - platform: modbus_controller
    name: "${friendly_name} AC Input Voltage"
    address: 20
    register_type: "read"
    unit_of_measurement: V
    device_class: voltage
    state_class: measurement
    entity_category: diagnostic
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

  - platform: modbus_controller
    name: "${friendly_name} AC Input Current"
    address: 15
    register_type: "read"
    unit_of_measurement: A
    device_class: current
    state_class: measurement
    entity_category: diagnostic
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

  - platform: modbus_controller
    name: "${friendly_name} AC Charge Current"
    address: 68
    register_type: "read"
    unit_of_measurement: A
    device_class: current
    entity_category: diagnostic
    state_class: measurement
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
    
  - platform: modbus_controller
    name: "${friendly_name} AC Input Power"
    address: 36
    register_type: "read"
    unit_of_measurement: W
    device_class: current
    entity_category: diagnostic
    state_class: measurement
    icon: mdi:flash
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.01


  - platform: modbus_controller
    name: "${friendly_name} Inverter Temperature"
    address: 25
    register_type: "read"
    unit_of_measurement: °C
    device_class: temperature
    entity_category: diagnostic
    state_class: measurement
    icon: mdi:thermometer
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
    
  - platform: modbus_controller
    name: "${friendly_name} PV Temperature"
    address: 32
    register_type: "read"
    unit_of_measurement: °C
    device_class: temperature
    state_class: measurement
    entity_category: diagnostic
    icon: mdi:thermometer
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1
2 Likes

Great work bringing this to ESPHOME :smiley:

My use case may be obvious or off-topic. And if so, I apologise, but in case it is useful to know…
This code also worked for me on my 1500TL-X, without owning a Shine Wifi module.
It works via the inverter’s COM and an off-the-shelf ESP, like the D1-Mini.

I just used the Shine-X code, with the baud rate changed back to 9600.

I have a Growatt MIC 1500TL-X
I do not have a Shine Wifi module

So I made my cable using:

  • A D1 Mini
  • An RS485/TTL converter
  • An old USB-A cable
  • The COM connector which was supplied with the Inverter

Very pleased with it.
Cheers :+1:

3 Likes