ESPHome modbus Growatt ShineWiFi-S

@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

That is really nice work!! Thank you for sharing!

Is the rs485 connected to the com port on pin 3 and 4? And the USB is only for power the TTL converter and the D1 mini? Or is the ground connected to the com plug also?

Correct, in my case, the USB is just for power.

The green/white wires are cut and don’t connect into the USB-A connector.
Instead, they connect the RS485 converter to pin 3&4 of the COM port.

Red and black take 5v from the USB-A, over to the D1-mini and the RS485 converter.

This was the RS485 converter I used: Stable UART Serial Port to RS485 Converter Function Module RS485 to TTL Module k | eBay

And this is how its wired:

I had previously tried the ESPHOME ‘growatt_solar’ sensor platform with this hardware.
On my 1500TL-X, it read one or two values. But most were NaN.
However, with the code here, it populates all values perfectly.

substitutions:
  device_name: growatt-mic-1500tl-x
  device_description: "Growatt Solar Inverter Monitoring"
  friendly_name: Growatt MIC 1500TL X

esphome:
  name: '${device_name}'
  comment: '${device_description}'
  
esp8266:
  board: d1_mini

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

ota:
  safe_mode: true
  reboot_timeout: 10min
  num_attempts: 5
  
web_server:
  port: 80
  auth:
    username: !secret esphome_web_username
    password: !secret esphome_web_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  # Optional manual IP

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: '${device_name}'
    password: !secret fallback_password
    
captive_portal:

time:
  - platform: homeassistant
    id: homeassistant_time

uart:
  id: mod_bus
  tx_pin: 1
  rx_pin: 3
  baud_rate: 9600
  #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  

sensor:
  - platform: modbus_controller
    name: "${device_name} DcPower"
    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: "${device_name} DcVoltage"
    address: 3
    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: "${device_name} DcInputCurrent"
    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: "${device_name} 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: "${device_name} AcVoltage"
    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: "${device_name} AcOutputCurrent"
    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: "${device_name} AcPower"
    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: "${device_name} EnergyToday"
    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
    
  - platform: modbus_controller
    name: "${device_name} EnergyTotal"
    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

    
  - platform: modbus_controller
    name: "${device_name} Temperature"
    address: 3093
    register_type: "read"
    unit_of_measurement: C
    device_class: temperature
    icon: mdi:thermometer
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    - multiply: 0.1

9 Likes

Internal: false needs to be added to all exposed sensors as of the last esphome version

Thank you for keeping an eye on the topic! In this case it is only about the homeassistant platform. So no worries.

Sure? It’s says All sensors. Not in line with the title of the issue

Yes im sure. The GitHub pr is a little misleading. I updated my device today and it is al fine😉

I found a way to upload to pvoutput.org, from home assistant.
PVOuput Uploader - #26 by rieschard

Next step is to do it in esphome. That shouldnt be too hard