Control Growatt SPA battery / inverter with Octopus - tutorial

Feel free to move this if this is in the wrong place.

I have read a LOT of articles for people trying to control the Growatt inverters, from using Modbus, AppDaemon, Node Red etc etc, but this is how I got mine working and working perfectly.

Step 1. (if you want to trigger via Octopus rates - optional)

Install and configure Octopus energy for your account

Step 2. Set battery up as a switch

switch:
  - platform: command_line
    switches:

      battery_settings:
        friendly_name: Battery Switch
        command_on: >
          curl -request POST -i -c cookies.txt -d "op=spaSetApi&param1=100&param2=100&param3=00&param4=00&param5=23&param6=59&param7=1&param8=00&param9=00&param10=00&param11=00&param12=0&param13=00&param14=00&param15=00&param16=00&param17=0&serialNum={serial}&type=spa_ac_charge_time_period" https://server-api.growatt.com/newTcpsetAPI.do
        command_off: >
          curl -request POST -i -c cookies.txt -d "op=spaSetApi&param1=100&param2=100&param3=00&param4=00&param5=23&param6=59&param7=0&param8=00&param9=00&param10=00&param11=00&param12=0&param13=00&param14=00&param15=00&param16=00&param17=0&serialNum={serial}&type=spa_ac_charge_time_period" https://server-api.growatt.com/newTcpsetAPI.do
        value_template: >
          {{value_json.success}}

Step 3. Automation (to trigger battery by current rate)

alias: Battery Charging
description: ""
trigger:
  - platform: state
    entity_id:
      - sensor.agile_current_rate
condition:
  - condition: or
    conditions:
      - condition: template
        value_template: |2
            {{ states('sensor.agile_current_rate' ) | float  < 0.01 }}
      - condition: and
        conditions:
          - condition: template
            value_template: "  {{ states('sensor.agile_current_rate' ) | float  <= states('sensor.agile_next_rate' ) | float }}"
          - condition: template
            value_template: "  {{ states('sensor.agile_current_rate' ) | float  < states('sensor.agile_avg_rate' ) | float }}"
action:
  - service: switch.turn_on
    data: {}
    target:
      entity_id: switch.battery_settings
mode: single

I’m new to this, only been using Home Assistant as couple weeks, so if this helps great, if you find any ways to make this better, please let me know. thanks

Hi Cole,

Thanks for this, I’m trying to get this working. All I actually want to is get my battery to charge when and event happens. So basically batt first with times set.

I can’t seem to get this working using this code. I also can’t see where the API login is to make this call?

Any help would be much appreicated.
Thanks

1 Like

I have a log in command that runs all the time in the background which creates and updated the cookies files using the following

`

  • platform: command_line
    name: “batterylogin”
    command: “curl --request POST -c /config/cookies.txt --data ‘userName=YOUREMAIL&password=YOURENCODEDPASSWORD’ https://server-api.growatt.com/newTwoLoginAPI.do”
    scan_interval: 600
    json_attributes:
    - back
    value_template: ‘{{ value_json.back.success }}’`

drop me a message and I will try to help you with it.

thanks

Thanks Cole,

I take it you add this code in the configuration.yaml file.

Do you need to put switch before it or anything like that?

Thanks

James

Yes, my config looks something like this


switch:
  - platform: command_line
    switches:
      battery_settings:
        friendly_name: Battery Switch
        command_on: >
          curl --request POST blar blar
        command_off: >
          curl --request POST blar blar
        value_template: >
          {{value_json.success}}
      battery_dump:
        friendly_name: Battery Dump
        command_on: >
          curl --request POST blar blar
        command_off: >
          curl --request POST blar blar
        value_template: >
          {{value_json.success}}
      battery_load_first:
        friendly_name: Store Battery
        command_on: >
          curl --request POST blar blar
        command_off: >
          curl --request POST blar blar
        value_template: >
          {{value_json.success}}

hope this helps.

Hi

This is awesome, just what I was looking for! I have Growatt setup too but still waiting for my Agile signup, will be having a play with this over the weekend in preparation :slight_smile:

Any chance could share the full post request details for the battery switches you have above please - I’m assuming you just captured these from the web portal with chrome dev tools or something?

Thanks

Sorry for the delay, still not getting notifications, this is my set up

switch:
  - platform: command_line
    switches:
      battery_settings:
        friendly_name: Battery Switch
        command_on: >
          curl --request POST -c /config/cookies.txt --data 'userName=USER&password=PASSWORD' https://server-api.growatt.com/newTwoLoginAPI.do && curl -request POST -i -b cookies.txt -d "op=spaSetApi&param1=100&param2=100&param3=00&param4=00&param5=23&param6=59&param7=1&param8=00&param9=00&param10=00&param11=00&param12=0&param13=00&param14=00&param15=00&param16=00&param17=0&serialNum=SERIALNO&type=spa_ac_charge_time_period" https://server-api.growatt.com/newTcpsetAPI.do
        command_off: >
          curl --request POST -c /config/cookies.txt --data 'userName=USER&password=PASSWORD' https://server-api.growatt.com/newTwoLoginAPI.do && curl -request POST -i -b cookies.txt -d "op=spaSetApi&param1=100&param2=100&param3=00&param4=00&param5=23&param6=59&param7=0&param8=00&param9=00&param10=00&param11=00&param12=0&param13=00&param14=00&param15=00&param16=00&param17=0&serialNum=SERIALNO&type=spa_ac_charge_time_period" https://server-api.growatt.com/newTcpsetAPI.do
        value_template: >
          {{value_json.success}}
      battery_dump:
        friendly_name: Battery Dump
        command_on: >
          curl --request POST -c /config/cookies.txt --data 'userName=USER&password=PASSWORD' https://server-api.growatt.com/newTwoLoginAPI.do && curl -request POST -i -b cookies.txt -d "op=spaSetApi&param1=100&param2=10&param3=00&param4=00&param5=23&param6=59&param7=1&param8=00&param9=00&param10=00&param11=00&param12=0&param13=00&param14=00&param15=00&param16=00&param17=0&serialNum=SERIALNO&type=spa_ac_discharge_time_period" https://server-api.growatt.com/newTcpsetAPI.do
        command_off: >
          curl --request POST -c /config/cookies.txt --data 'userName=USER&password=PASSWORD' https://server-api.growatt.com/newTwoLoginAPI.do && curl -request POST -i -b cookies.txt -d "op=spaSetApi&param1=100&param2=10&param3=00&param4=00&param5=00&param6=00&param7=0&param8=00&param9=00&param10=00&param11=00&param12=0&param13=00&param14=00&param15=00&param16=00&param17=0&serialNum=SERIALNO&type=spa_ac_discharge_time_period" https://server-api.growatt.com/newTcpsetAPI.do
        value_template: >
          {{value_json.success}}
      battery_load_first:
        friendly_name: Store Battery
        command_on: >
          curl --request POST -c /config/cookies.txt --data 'userName=USER&password=PASSWORD' https://server-api.growatt.com/newTwoLoginAPI.do && curl -request POST -i -b cookies.txt -d "op=spaSetApi&param1=00&param2=01&param3=23&param4=59&param5=1&param6=00&param7=00&param8=00&param9=00&param10=0&param11=00&param12=00&param13=00&param14=00&param15=0&serialNum=SERIALNO&type=spa_load_flast" https://server-api.growatt.com/newTcpsetAPI.do
        command_off: >
          curl --request POST -c /config/cookies.txt --data 'userName=USER&password=PASSWORD' https://server-api.growatt.com/newTwoLoginAPI.do && curl -request POST -i -b cookies.txt -d "op=spaSetApi&param1=00&param2=00&param3=00&param4=00&param5=0&param6=00&param7=00&param8=00&param9=00&param10=0&param11=00&param12=00&param13=00&param14=00&param15=0&serialNum=SERIALNO&type=spa_load_flast" https://server-api.growatt.com/newTcpsetAPI.do
        value_template: >
          {{value_json.success}}

[quote=“coleburg, post:3, topic:492336”]
I sorted the code out now but I get this error:

Logger: homeassistant.components.command_line
Source: components/command_line/init.py:54
Integration: command_line (documentation, issues)
First occurred: 12:57:14 (7 occurrences)
Last logged: 13:03:15

Command failed (with return code 127): “curl --request POST -c /config/cookies.txt --data ‘[email protected]&password=<encodedpassword’ 登录页面

Found the missing link…

sensor:
- platform: command_line

    name: “batterylogin”

    command: “curl --request POST -c /config/cookies.txt --data ‘userName=YOUREMAIL&password=YOURENCODEDPASSWORD’ https://server-api.growatt.com/newTwoLoginAPI.do 4”

    scan_interval: 600

    json_attributes:

    - back

    value_template: ‘{{ value_json.back.success }}’`
1 Like

Would really like some help with this.

I added the code to configuration.yaml but unsure what to do with the battery.login code

Could you please be as basic as possible as I was getting errors adding it to configuration.yaml

I ended up going for Solar assistant and controlling the inverter through HA automation

1 Like

@daknightuk hey :wave:
Are you able to share the automations you have for growatt/Solar Assistant/HA?
It’s the combination I use as well.

alias: Charge Growatt Battery based on the helper times
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.growatt_battery_charge_schedule
condition:
  - condition: numeric_state
    entity_id: input_number.battery_max_charge
    above: 0
action:
  - choose:
      - conditions:
          - condition: state
            entity_id: binary_sensor.growatt_battery_charge_schedule
            state: "on"
            for:
              hours: 0
              minutes: 0
              seconds: 0
        sequence:
          - service: input_text.set_value
            data:
              value: Scheduled Started
            target:
              entity_id:
                - input_text.battery_status
          - service: select.select_option
            target:
              entity_id:
                - select.battery_first_grid_charge
            data:
              option: Enabled
          - service: select.select_option
            data:
              option: Battery first
            target:
              entity_id: select.output_source_priority
          - service: input_text.set_value
            data:
              value: Scheduled Charge
            target:
              entity_id:
                - input_text.battery_status
      - conditions:
          - condition: state
            entity_id: binary_sensor.growatt_battery_charge_schedule
            state: "off"
            for:
              hours: 0
              minutes: 0
              seconds: 0
        sequence:
          - service: select.select_option
            target:
              entity_id:
                - select.battery_first_grid_charge
            data:
              option: Disabled
          - service: select.select_option
            data:
              option: Load first
            target:
              entity_id: select.output_source_priority
          - service: input_text.set_value
            data:
              value: Scheduled Ended
            target:
              entity_id:
                - input_text.battery_status
mode: single
alias: >-
  At 6pm look at the forecast for tomorows Sun then adjust the battery max
  charge helper according to built in scale
description: ""
trigger:
  - platform: time
    at: "18:00:00"
condition: []
action:
  - service: input_number.set_value
    data_template:
      entity_id: input_number.battery_max_charge
      value: >
        {% set forecast = states('sensor.solcast_forecast_tomorrow') | float %}
        {% if forecast <= 2 %}
          100
        {% elif forecast <= 3 %}
          90
        {% elif forecast <= 4 %}
          77
        {% elif forecast <= 5 %}
          66
        {% elif forecast <= 6 %}
          55
        {% elif forecast <= 7 %}
          44
        {% elif forecast <= 8 %}
          32
        {% else %}
          10
        {% endif %}
  - service: persistent_notification.create
    data:
      message: Battery Set
mode: single
alias: Stop charging when battery reaches max value
description: ""
trigger:
  - platform: time_pattern
    seconds: "59"
condition:
  - condition: numeric_state
    entity_id: sensor.battery_state_of_charge
    above: input_number.battery_max_charge
action:
  - service: select.select_option
    target:
      entity_id:
        - select.battery_first_grid_charge
    data:
      option: Disabled
  - service: select.select_option
    data:
      option: Load first
    target:
      entity_id: select.output_source_priority
  - service: input_text.set_value
    data:
      value: Target Charge Reached
    target:
      entity_id:
        - input_text.battery_status
mode: single