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):
-
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
-
Deployed growattServer.py and set_charge_rate.py from mjdyson/ad-growatt (github.com) into …\appdaemon\conf\apps.
-
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.
-
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.
- 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
-
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
-
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 }}"
- 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.