Tesla Powerwall use cases and automation sharing

Hiya.
Are you using the ‘Tesla Custom Integration’ via HACS? That’s the one which exposes all the options - the ‘native’ Powerwall integration has far fewer options (only Grid mode on and off as you describe).
You can have both on the same HA system should you wish (I do, although the native integration gets almost no use).

2 Likes

I’m also in the UK and have a similar set up to you (just 1 Powerwall, but expanding to two shortly).

My tethered cable Zappi charger is registered with Octopus as the intelligent device for Intelligent Go, rather than my EV.

I have found that unplugging my EV for five or ten minutes after an Off Peak Period, with the plug inserted back into the Zappi is registered with Octopus.

Octopus know how much energy the Zappi has provided, but not the state of charge of my EV, so when plugging the EV back in, it often triggers additional Off-Peak Periods that I can use to run my house, recharge my Powerwall, etc. even though my EV is fully charged!

Well worth doing - so I thought I’d let you know.

I’m using the ‘Octopus Energy Account Number Intelligent Dispatching’ sensor in HA as a trigger for ensuring my PW doesn’t dump its energy into my EV during an Off-Peak period (by turning Back-Up Reserve up to 100%).

As I’m allowed to export up to 6kW by the DNO, I had Tesla enable exporting on my instance of the Tesla App and have set a ‘Super-Peak Rate’ period on the App with a high export rate for 1 am to 3 am each night, plus a time based trigger in HA to knock my PW Back-Up Reserve down to 10%, during that period, so it can discharge to the grid.

This earns me about £1.50 each night at 15p per kWh, with enough time left to fully recharge the PW from 3 am to 5:30 am - £45 a month reduction on my bill, for the sake of a couple of additional automations - would recommend.

I wish there was a way to edit the PW Utility Plan periods via HA, then we could automate things to ensure our PW are fully charged ahead of an Octopus Savings Session and then dump everything down to our Back-Up Reserve levels, into the grid during these sessions earning the huge prices Octopus offer - £2 to £4 per KWh ! (at least £20 - £40 per session, double when I get my second PW).

I’d like to use home assistant to extend the life of my powerwalls. Specifically…

  1. limit max state of charge to 90%
  2. slow the charge rate off the grid

Is either possible?

  1. quite possible. set an automation that disables grid charging once the charge level reaches 90%.
  2. not directly, I don’t think you can do this. but the battery charges differently depending on which mode it is in. so far I have observed it charges at 1.8kW if it is in default (self-powered) mode, so you may try to use that.

honestly, I wouldn’t worry about either. the terms of the warranty suggest this will not be an issue and the drop in capacity might correlate to time of use rather than conditions of use.

  1. as far as I know, you can’t control this directly. but as I mentioned in the answer above, you can use self-powered mode to charge which from what I have observed, charges at 1.8kW rather than 5 (in my case);
  2. see above, I think this is the same point;
  3. there’s ways to coerce the battery to do this for you. the exporting needs the “assistance” of a planned rate schedule on the app;

I have scripts to set the battery in the following modes:

  • self-powered (default mode)
  • time based control
  • force charge
  • force discharge
  • prevent discharge

Then I use automations to swap modes as and when it works for me.

A short description of how I implemented homeassistant control of the Tesla Powerwall

This involves the two integrations currently available for the Powerwall, HACS Tesla Custom Integration (GitHub - alandtse/tesla: Tesla custom integration for Home Assistant. This requires a refresh token be generated by third-party apps to login.) and the Powerwall integration (Tesla Powerwall - Home Assistant). I use the latter for taking readings for the most part but the former for making changes.

Helper variables

My setup involves a selection of scripts and an input_select (powerwall_battery_custom_modes) helper entity to choose between them (mostly for UI purposes). The scripts can be triggered manually as a service call.

I also store a default backup reserve amount to use on the scripts when resetting the modes. (input_number.powerwall_battery_backup_reserve_operation)

Custom mode scripts

Powerwall Hold Charge:

  • Set backup reserve to current charge value
  • Set mode to self powered
  • Disable grid charging
  • Set energy exports to solar
  • Set helper selector to correct setting

If you have this mode enabled and the battery charges via solar power, then the set reserve value and the actual charge values will start to drift apart, meaning that the battery will be able to discharge back to the previously set reserve value. You can counter this by using an automation that updates the reserve value to the current charge if it increases whilst in this mode.

alias: Powerwall Mode Hold Charge
sequence:
  - service: number.set_value
    data:
      value: "{{ states('sensor.powerwall_battery_charge')|int }}"
    target:
      entity_id: number.powerwall_cloud_backup_reserve
  - service: select.select_option
    data:
      option: Self-Powered
    target:
      entity_id: select.powerwall_cloud_operation_mode
  - service: select.select_option
    data:
      option: "No"
    target:
      entity_id: select.powerwall_cloud_grid_charging
  - service: select.select_option
    data:
      option: Solar
    target:
      entity_id: select.powerwall_cloud_energy_exports
  - if:
      - condition: not
        conditions:
          - condition: state
            entity_id: input_select.powerwall_battery_custom_modes
            state: No discharge
    then:
      - service: input_select.select_option
        data:
          option: No discharge
        target:
          entity_id: input_select.powerwall_battery_custom_modes
mode: single
icon: mdi:battery-remove

Powerwall Mode Grid Charge:

  • Set backup reserve value to 100%
  • Set mode to time-based control
  • Enable grid charging
  • Set energy exports to solar
  • Set helper selector to correct setting
alias: Powerwall Mode Grid Charge
sequence:
  - service: number.set_value
    data:
      value: 100
    target:
      entity_id: number.powerwall_cloud_backup_reserve
  - service: select.select_option
    data:
      option: Time-Based Control
    target:
      entity_id: select.powerwall_cloud_operation_mode
  - service: select.select_option
    data:
      option: "Yes"
    target:
      entity_id: select.powerwall_cloud_grid_charging
  - service: select.select_option
    data:
      option: Solar
    target:
      entity_id: select.powerwall_cloud_energy_exports
  - if:
      - condition: not
        conditions:
          - condition: state
            entity_id: input_select.powerwall_battery_custom_modes
            state: Grid Charge
    then:
      - service: input_select.select_option
        data:
          option: Grid Charge
        target:
          entity_id: input_select.powerwall_battery_custom_modes
mode: single
icon: mdi:battery-plus

Powerwall Mode Force Export:

  • Set backup reserve to 0%
  • Set mode to time-based control
  • Disable grid charging
  • Set energy exports to everything
  • Set helper selector to correct setting

This script requires that the operator’s rate schedule be set on the tesla app with an export value high enough that if it were in time-based control with exporting enabled, the powerwall would be exporting. Effectively this relies on keeping the battery from exporting with the ‘energy exports’ setting set on ‘solar’ and flipping it to ‘everything’ when we want to trigger exporting.

alias: Powerwall Mode Force Export
sequence:
  - service: number.set_value
    data:
      value: "0"
    target:
      entity_id: number.powerwall_cloud_backup_reserve
  - service: select.select_option
    data:
      option: Time-Based Control
    target:
      entity_id: select.powerwall_cloud_operation_mode
  - service: select.select_option
    data:
      option: "No"
    target:
      entity_id: select.powerwall_cloud_grid_charging
  - service: select.select_option
    data:
      option: Everything
    target:
      entity_id: select.powerwall_cloud_energy_exports
  - if:
      - condition: not
        conditions:
          - condition: state
            entity_id: input_select.powerwall_battery_custom_modes
            state: Force Export
    then:
      - service: input_select.select_option
        data:
          option: Force Export
        target:
          entity_id: input_select.powerwall_battery_custom_modes
mode: single
icon: mdi:battery-minus-outline

Powerwall Time Based Solar:

  • Set backup reserve to helper value;
  • Set mode to time-based control
  • Disable grid charging
  • Set energy exports to solar
  • Set helper selector to correct setting

This mode will not export battery charge, only surplus solar power.

alias: Powerwall Mode Time based Solar
sequence:
  - service: number.set_value
    data:
      value: >-
        {{ states("input_number.powerwall_battery_backup_reserve_operation")|int
        }}
    target:
      entity_id: number.powerwall_cloud_backup_reserve
  - service: select.select_option
    data:
      option: Time-Based Control
    target:
      entity_id: select.powerwall_cloud_operation_mode
  - service: select.select_option
    data:
      option: "No"
    target:
      entity_id: select.powerwall_cloud_grid_charging
  - service: select.select_option
    data:
      option: Solar
    target:
      entity_id: select.powerwall_cloud_energy_exports
  - if:
      - condition: not
        conditions:
          - condition: state
            entity_id: input_select.powerwall_battery_custom_modes
            state: Time based solar
    then:
      - service: input_select.select_option
        data:
          option: Time based solar
        target:
          entity_id: input_select.powerwall_battery_custom_modes
mode: single

Powerwall Time Based Export:

  • Set backup reserve to helper value;
  • Set mode to time-based control
  • Disable grid charging
  • Set energy exports to everything
  • Set helper selector to correct setting

Same as time based solar but with grid exporting enabled. The battery will export as per the operator tariff and schedule settings set by yourself on the app.

alias: Powerwall Mode Time based Export
sequence:
  - service: number.set_value
    data:
      value: >-
        {{ states("input_number.powerwall_battery_backup_reserve_operation")|int
        }}
    target:
      entity_id: number.powerwall_cloud_backup_reserve
  - service: select.select_option
    data:
      option: Time-Based Control
    target:
      entity_id: select.powerwall_cloud_operation_mode
  - service: select.select_option
    data:
      option: "No"
    target:
      entity_id: select.powerwall_cloud_grid_charging
  - service: select.select_option
    data:
      option: Everything
    target:
      entity_id: select.powerwall_cloud_energy_exports
  - if:
      - condition: not
        conditions:
          - condition: state
            entity_id: input_select.powerwall_battery_custom_modes
            state: Time based export
    then:
      - service: input_select.select_option
        data:
          option: Time based export
        target:
          entity_id: input_select.powerwall_battery_custom_modes
mode: single

Powerwall Mode Time based Solar with daily export

This is a mode that I use, which is identical to time based solar, but if this mode is enabled instead of time based solar, there is an automation that triggers exporting of energy every day. It’s just a way of controlling this process. Yes, I could do this with a helper toggle.

alias: Powerwall Mode Time based Solar with daily export
sequence:
  - service: number.set_value
    data:
      value: >-
        {{ states("input_number.powerwall_battery_backup_reserve_operation")|int
        }}
    target:
      entity_id: number.powerwall_cloud_backup_reserve
  - service: select.select_option
    data:
      option: Time-Based Control
    target:
      entity_id: select.powerwall_cloud_operation_mode
  - service: select.select_option
    data:
      option: "No"
    target:
      entity_id: select.powerwall_cloud_grid_charging
  - service: select.select_option
    data:
      option: Solar
    target:
      entity_id: select.powerwall_cloud_energy_exports
  - if:
      - condition: not
        conditions:
          - condition: state
            entity_id: input_select.powerwall_battery_custom_modes
            state: Time based solar with daily export
    then:
      - service: input_select.select_option
        data:
          option: Time based solar with daily export
        target:
          entity_id: input_select.powerwall_battery_custom_modes
mode: single

These scripts form the basis of operating the powerwall. I have developed a massive automation (because I prefer to have fewer, but more complex automations) to mess about with the modes, depending on time of day, whether car needs charging, whether I want to export off the battery, whether I want a full charge in the morning, etc.

1 Like

The “Powerwall Mode Force Export” mode doesn’t seem to work for me-- it only exports any solar actively being generated, not any power from the batteries. Perhaps that’s because my energy provider does not allow it (as in, I don’t actually have the export everything option visible in my app)? I was hoping I could bypass that restriction with HA, but seems like that’s not the case.

Any thoughts/tips?

For exporting from the battery, the script won’t make anything happen that the powerwall would not do on its own. By this I mean it only sets the battery in a mode that nudges it into exporting, does not actually force anything.

In my case, I am allowed to export from the battery at up to 5kW as signed off by the DNO, I had to ask Tesla support to enable this feature (you have it if you have the control in the app for ‘Energy Exports’ which selects between ‘Solar’ and ‘Everything’).

The final piece of the puzzle is to ensure that at whichever time you turn on this script, the utility rate plan is setup so that the powerwall would have decided (on its own) to export. This is achieved by artificially setting a high export rate.

I have verified again that the powerwall charges at 1.8kW from the grid if it is set to ‘self-powered’ and at 5kW if it is on ‘time-based control’. I’ll adjust my scripts to select this option using a helper input.

If anybody is following - I have worked something else out:

  • if you set the export rate high enough in the tariff setting on the app, the powerwall will start exporting your solar generation whilst feeding the house off the battery.

I am not certain how useful this actually is unless the house consumption is very high and the battery will drain before the next low tariff time period… but there you go. One more data point.

I have been starting to think about trying to export my excess battery at the end of the day now it is starting to get sunnier using an automation like this.

The bit I am trying to work out is automating the level of battery it is safe to discharge to so I don’t run out and start using peak rate electricity.

Have you got anywhere with this or do you just set a time when you usually have enough to last until off peak starts?

Good info in this thread. Thank you.

@pjvenda I have a similar setup working with automations. My PW will export at the end of the day at a certain time based on battery % left.

As you know, to make this happen you need to adjust the utility rate in the app to make the sell price higher than the buy price. Have you found a way to automate this at all?

Something I have also noticed, hopefully I can explain this…on a (not very sunny) day say my battery % is at 75% mid afternoon. The PW will go into standby and the house will be fed from the grid.

I believe this is because the PW thinks it’s better off, for me financially, to pay the grid price and save the battery energy as later on in the day it can sell it for more than the grid is costing me now.

Hopefully that makes sense? Obviously the PW is actually right because of the utility rate numbers i’ve given it…but i’ve only given it artifically high sell prices as that’s the only way to force an export.

Arrgghhh :slight_smile:

So far I have been using a static number and a time of day to stop the export. This isn’t great…

I am drafting a way to work out a discharge rate against the current capacity, as in “for a given time of day, is the battery charge less than what I think I’ll need until the end of the day?” I’ll be using a couple of static variables to plot a linear ‘estimated’ discharge rate and an automation to make a decision as to whether start or stop exporting. This is my idea, I haven’t got to it yet.

I haven’t heard of a way to operate the tariff details outside the app unfortunately. Would be cool to be able to tweak it in real time :slight_smile:

Something I have also noticed, hopefully I can explain this…on a (not very sunny) day say my battery % is at 75% mid afternoon. The PW will go into standby and the house will be fed from the grid.

Happens to me too. My solution is to calculate how much of the house’s supply is grid or battery or solar. if grid supply is, say, >33% and the tariff rate is high, then I override the mode and switch it to self-powered.

I believe this is because the PW thinks it’s better off, for me financially, to pay the grid price and save the battery energy as later on in the day it can sell it for more than the grid is costing me now.

Agreed.

Another interesting and logical side effect is that the PW decides to not fully charge the battery if it estimates the next day’s solar generation forecast is enough to support demand and maintain charge to an extent.

1 Like

Ahh, I’d not considered the self powered mode. Thank you. I’ll look at automating that into something that works for me.

The overnight charging was brilliant for me previously. It was more accurate than the weather forcast! I’m now on an electrical tarriff that pays me more for exporting than the cheap rate of charging overnight so it’s better to charge to 100% every day.

1 Like

sample sensors for you:

    - name: "Powerwall Supply Grid"
      unique_id: cc51b527c8e776dea413062d28b9c71c58b6cfc6
      state: >
        {% if (states('sensor.powerwall_site_now')|float>0) -%}
          {% set grid=states('sensor.powerwall_site_now')|float*1000 -%}
        {% else %}
          {% set grid=0 %}
        {% endif %}
        {% set house=states('sensor.powerwall_load_now')|float*1000 -%}
        {% if ((grid*100)/house) > 40 %}
          True
        {% else %}
          False
        {% endif %}
      icon: mdi:transmission-tower
    - name: "Powerwall Supply Battery"
      unique_id: d2539aae51cd3f4bf65e71a43c92a2021f6bfd64
      state: >
        {% if (states('sensor.powerwall_battery_now')|float>0) -%}
          {% set bat=states('sensor.powerwall_battery_now')|float*1000 -%}
        {% else %}
          {% set bat=0 -%}
        {% endif %}
        {% set house=states('sensor.powerwall_load_now')|float*1000 -%}
        {% if ((bat*100)/house) > 30 %}
          True
        {% else %}
          False
        {% endif %}
      icon: mdi:battery
    - name: "Powerwall Supply Solar"
      unique_id: 4d8f72ede048f8e4c0b0eb0ad3bce234e7f63c32
      state: >
        {% if (states('sensor.powerwall_solar_now')|float>0) -%}
          {% set solar=states('sensor.powerwall_solar_now')|float*1000 -%}
        {% else %}
          {% set solar=0 -%}
        {% endif %}
        {% set house=states('sensor.powerwall_load_now')|float*1000 -%}
        {% if ((solar*100)/house) > 30 %}
          True
        {% else %}
          False
        {% endif %}
      icon: mdi:solar-power

Sample automation fragments:

(...)
trigger:
(...)
  - platform: state
    entity_id:
      - binary_sensor.powerwall_supply_grid
    for:
      hours: 0
      minutes: 2
      seconds: 0
    to: "on"
    id: grid-supply
    alias: Grid supply is feeding house (2m)
(...)
action:
  - choose:
(...)
      - conditions:
          - condition: trigger
            id:
              - grid-supply
          - condition: state
            entity_id: schedule.octopus_low_rate_schedule
            state: "off"
          - condition: not
            conditions:
              - condition: state
                entity_id: input_select.powerwall_battery_custom_modes
                state: Self-Powered
            alias: Powerwall mode is NOT self-powered
        sequence:
          - if:
              - condition: template
                value_template: >-
                  {{ (states('sensor.powerwall_battery_charge')|int >
                  states('sensor.powerwall_cloud_backup_reserve')|int+1 ) and
                  (states('sensor.powerwall_battery_charge')|int > 5) }}
            then:
              - service: script.powerwall_mode_default
                data: {}
              - service: notify.mob_verbose
                data:
                  title: Powerwall Discharge Control
                  message: >-
                    Grid supply is on, tariff is high rate, battery at {{
                    states('sensor.powerwall_battery_charge')|int }}% - set to
                    self-powered
            else:
              - service: notify.mob_verbose
                data:
                  title: Powerwall Discharge Control
                  message: >-
                    Grid supply is on, tariff is high rate, battery at reserve
                    {{ states('sensor.powerwall_battery_charge')|int }}%. No
                    action taken                
        alias: Grid supply is feeding house
(...)
1 Like

Have thought of a temporary solution until I can work out something better.

I am just going to set the Powerwall to start exporting for an hour at the start of the off peak period and then set it back to allowing import. As long as there is enough time left in your off peak slot to fully recharge the battery, then this should export most of your surplus, given the import/export rate of 5KW (or at least for me it is)

This way you are unlikely to import at peak rate.

I would prefer to export at peak times for the sake of the grid, but for now this will do.

Will be trying it for the first time tonight.

That should work. By then you know exactly how much you have left. This is a much simpler solution.

I would prefer to export at peak times for the sake of the grid, but for now this will do.

Which is exactly why I am trying to go the long way around, hence the complex calculations/estimations. I have the template code written now, just need to put it into sensors.

Sorry for the super later reply, but the reason this changes and then switches back is that setting this value in developer tools only change’s Home Assistant’s view (not the upstream service). The powerwall doesn’t get a service call to update, so it changes back next time there is a data update call.

The only way I was update to update the powerwall’s backup threshold was by using the HACS Tesla integration and a service call:

- alias: "Set min reserve"
  service: number.set_value
  target:
    entity_id: number.home_energy_gateway_backup_reserve
  data:
    value: 100

Using the same custom integration you can also set the backup mode (which roughly equates to the “charging speed”. Backup is quicker to pull power from the grid, "Self-Powered" is the default option.

- alias: 'Set Backup'
  service: select.select_option
  target:
    entity_id: select.home_energy_gateway_operation_mode
  data:
    option: "Backup"
2 Likes