Growatt Inverter Mode Switch

Hi there,

First of all - credits to @mjdyson, @KasperEdw, @muppet3000 and @indykoning for providing all the important pieces of the actual code. I too wanted to automate the charging of my Growatt battery, and without their work I wouldn’t be able to achieve that.

For the benefits of others in a similar situation, this is how I combined the different pieces together for my nightly routine (I am using HA running in Docker on Synology NAS):

  1. Installed AppDaemon and configured so it listens to my HA instance. I run AppDaemon in Docker, alongside my HA instance. AppDaemon with Docker — AppDaemon 4.2.1 documentation

  2. Deployed growattServer.py and set_charge_rate.py from mjdyson/ad-growatt (github.com) into …\appdaemon\conf\apps.

  3. Made sure that growattServer.py is referring to the right server URL; Growatt seems to have been switching between https://server.growatt.com/ and https://server-api.growatt.com/ recently.

  4. Next I modified the set_charge_rate.py module, so it better suited my needs (I wanted to call the set_charge_rate routine as a service from HA, only setting the Stop charging SoC %):

import growattServer
import appdaemon.plugins.hass.hassapi as hass

SET_CHARGE_RATE = 'SET_CHARGE_RATE'


class HouseBatteryCharge(hass.Hass):

  def initialize(self):
    self.listen_event(self.set_charge_rate, SET_CHARGE_RATE)


  def set_charge_rate(self, event, data, kwargs):

    stop_battery_soc = str(data['stop_battery_soc'])
...

Plus I added logging in various places of the ‘set_charge_rate’ function and made the #Stop charging SoC % the only variable in self.schedule_settings. I didn’t need any other variables, my charging time window is fixed by the cheaper night tariff provided by my energy supplier.

  1. The final piece of AppDaemon config was adding this entry into …\appdaemon\conf\apps\apps.yaml
set_charge_rate:
  module: set_charge_rate
  class: HouseBatteryCharge
  1. Then I configured HA to call my AppDaemon app - this 3-part blog was absolutely essential to understand how to do that: AppDaemon, next level home automation | Medium

  2. As a result, I added this entry into my HA scripts.yaml:

set_charge_rate:
  alias: Growatt Battery - Set Charge Rate
  sequence:
    - event: SET_CHARGE_RATE
      event_data:
        stop_battery_soc: "{{ stop_battery_soc }}"    
  1. Finally, in HA I configured a nightly automation which looks at the solar energy production forecast and then calls the script service (and passes the Stop charging SoC % as a variable), which then triggers the event, which AppDaemon is listening to and which then finally runs the set_charge_rate app. How to call the service and pass the variable:
- service: script.set_charge_rate
  data:
  stop_battery_soc: 70

Because the Growatt servers have been somewhat unreliable recently (even in the ShinePhone app I often get ‘Network Error’ and have to try several times to get the actual status), the automation makes the call twice (could be more frequently, if it runs OK it completes within 5 seconds). For ref, the complete automation logic:

alias: Set solar battery charging rate
description: ""
trigger:
  - platform: time
    at: "20:00:00"
condition: []
action:
  - repeat:
      count: 2
      sequence:
        - if:
            - type: is_energy
              condition: device
              device_id: 5c6093279048b524c3282a0040c49398
              entity_id: sensor.energy_production_tomorrow
              domain: sensor
              below: 10
              above: 0
          then:
            - service: script.set_charge_rate
              data:
                stop_battery_soc: 100
        - if:
            - type: is_energy
              condition: device
              device_id: 5c6093279048b524c3282a0040c49398
              entity_id: sensor.energy_production_tomorrow
              domain: sensor
              below: 20
              above: 10
          then:
            - service: script.set_charge_rate
              data:
                stop_battery_soc: 70
        - if:
            - type: is_energy
              condition: device
              device_id: 5c6093279048b524c3282a0040c49398
              entity_id: sensor.energy_production_tomorrow
              domain: sensor
              below: 30
              above: 20
          then:
            - service: script.set_charge_rate
              data:
                stop_battery_soc: 60
        - if:
            - type: is_energy
              condition: device
              device_id: 5c6093279048b524c3282a0040c49398
              entity_id: sensor.energy_production_tomorrow
              domain: sensor
              above: 30
          then:
            - service: script.set_charge_rate
              data:
                stop_battery_soc: 30
        - delay:
            hours: 0
            minutes: 1
            seconds: 0
            milliseconds: 0
mode: single

The sensor.energy_production_tomorrow is from Forecast.Solar integration.

Hope it helps!

PS I also run my own Grott instance, so have been wondering if it wouldn’t be more reliable to run the set_charge_rate against that. Not sure though whether is also listening to calls, or just forwarding calls from the inverter to growatt servers. I reckon it should be the former, but not sure.

1 Like