wow, I just found this thread!
I’ve been doing this all by hand, and it’s great to be able to add this to home assistant! I wonder if someone might make this into a HACS module someday?
I posted this one, but it wasn’t the same as the one you quoted above:
import teslapy
tesla = teslapy.Tesla('<insert email address here>')
if not tesla.authorized:
print('Use browser to login. Page Not Found will be shown at success.')
print('Open this URL: ' + tesla.authorization_url())
tesla.fetch_token(authorization_response=input('Enter URL after authentication: '))
vehicles = tesla.vehicle_list()
print(vehicles[0])
tesla.close()
The Tesla Custom Integration is now available for testing and provides control and monitoring over Tesla vehicles as well as energy products including powerwall, allowing changing operating mode, backup reserve. This is a breaking change if you already have the integration installed.
This rewrite greatly simplifies authentication using the standard HA config flow, so you no longer need shell commands and copying json files around!
You can install by including as a custom repository in
You need to install the dev version:
Happy to take comments here, but please raise any issues in GitHub.
somebody fetch this man a beverage
I’m installing now to test!
Alright!
I’ve got it all plugged in!
now it’s time to setup some automations to charge after midnight, and discharge after 4pm!
Great work,
Charging at midnight is easy, either increase the backup reserve % or switch the operation mode to ‘Backup’.
Discharging on demand is a bit more problematic
The ‘Grid Charging’ selector doesn’t start discharging, it only allows it if your Time Based Controls are wanting to discharge to the grid. Have a look at this article. EMHASS: An Energy Management for Home Assistant - #57 by markpurcell
I don’t suppose the code for this panel is available somewhere? I’m aiming to do something very similar - basically turn on TOU charge/discharge as a toggle, and I’d like all the threshholds to be static like you’ve got here.
I’ve been doing it manually using the app until now.
just past midnight, i slide the reserve to 100%, and turn grid charging on, then I go to bed.
when I get up, I turn the reserve back down to 5% and I turn grid charging off. It’s currently in TOU mode, so when 4pm hits, it dumps all the juice from the battery into the grid during the highest buyback price.
So in theory as long as I can just set the times up, it’ll be basically fire and forget!
I can only do that til Nov 1, the ‘season’ changes, and the rates fall dramatically to within a cent or two between peak/off peak/super off peak, so it’s only ‘worth it’ to do it here during the summer.
Well yes and no, the automatons are mainly from @BruceH5200 here: bruces_homeassistant_config/packages/systems/tesla_powerwall at master · B-Hartley/bruces_homeassistant_config · GitHub
I made manual input helpers before I had my PW installed to try to add more manual input, but in the end it we a bit futile so I removed the ones that are hard coded in to the automation. Then created a manual toggle for autonomous (0% res, 100% back-up) when turned on and 5% res, 95% back-up when turned off.
Here is Bruces’ automation that calculates over night charging levels (extracted from the above link) we are both UK based and using Octopus Energy tariffs (OctopusGo):
automation:
- id: calculate_max_powerwall_charge_price
alias: "Powerwall work out what prices to charge below"
trace:
stored_traces: 15
mode: single
description: >
Work out what price to charge below based on charge level, target and prices
Assumptions:
Powerwall useable Capacity: 13.2 kWh
Max Charge Level is (13.2 - (solar_forecast - tomorrow_solar_threshold) + overnight_usage)/13.2
ChargeRate = 3.6 kW
trigger:
# Forecast.Solar goes to zero between 11(:30) and 00:00 ???
- platform: time
id: 'time'
at:
- '21:00:00'
- '22:15:00'
- '00:25:00'
- '02:35:00'
- '04:45:00'
- platform: homeassistant
id: 'start'
event: start
- platform: event
id: 'reload'
event_type: automation_reloaded
condition:
# Forecast should never be zero, so zero would show error ?
- condition: numeric_state
entity_id: sensor.solcast_forecast_today
above: 0
- condition: numeric_state
entity_id: sensor.solcast_forecast_tomorrow
above: 0
- condition: state
entity_id: sensor.enphase_status
state: "Sleep"
#### This is where I tried to make the hard coded inputs, user changeable from the UI ####
# variables:
# - overnight_usage_percent: "={{ states('input_number.overnight_usage_percent') | int(default=0) }}"
# - tomorrow_solar_threshold: "={{ states('input_number.tomorrow_solar_threshold') | int(default=0) }}"
# - go_tomorrow_solar_threshold: "={{ states('input_number.go_tomorrow_solar_threshold') | int(default=0) }}"
# - charge_rate: 3.6
# - powerwall_capacity: 13.2
# - percentage_per_half_hour: "={{ states('input_number.percentage_per_half_hour') }}"
#{% set percentage_per_half_hour = (100*(charge_rate/2.0)/powerwall_capacity) %}
variables:
overnight_usage_percent: 35.0
tomorrow_solar_threshold: 8.0
go_tomorrow_solar_threshold: 12.0
charge_rate: 3.6
powerwall_capacity: 13.2
percentage_per_half_hour: 13.6
action:
- choose:
- conditions:
- condition: state
entity_id: input_boolean.go_tariff
state: 'on'
sequence:
- alias: "Update Solcast Forecast"
event: solcast_update_all_forecasts
- delay: 30
- service: input_number.set_value
target:
entity_id: input_number.overnight_powerwall_max_charge
data:
value: "{% set solar_forecast = (states('sensor.solcast_forecast_tomorrow')|float(0)) if now().strftime('%-H')|int(0) > 12 else (states('sensor.solcast_forecast_today')|float(0)) %}{{ ([0,[(100 * (powerwall_capacity - (solar_forecast - go_tomorrow_solar_threshold))) / powerwall_capacity,100]|min]|max)|int(0) }}"
- service: input_number.set_value
target:
entity_id: input_number.powerwall_charge_below_x_pence
data:
value: 8
- service: telegram_bot.send_message
data:
target: !secret telegram_chat_id_chris
title: "Solar Today/Tomorrow: {{ states('sensor.solcast_forecast_today')|int(0) }}/{{states('sensor.solcast_forecast_tomorrow')|int(0) }}kWh"
message: >
{% set charge_slots_needed = (0.5 + (((states('input_number.overnight_powerwall_max_charge')|float(0)) + overnight_usage_percent - (states('sensor.powerwall_charge')|float(0)) )/percentage_per_half_hour))|int(0) %}
Powerwall Charge Level: {{ states('sensor.powerwall_charge')|int(0) }}%
{% if charge_slots_needed > 0 %}Powerwall Charging overnight to {{ states('input_number.overnight_powerwall_max_charge')|int(0) }}%
{{ charge_slots_needed }} half hour periods.
Max Price of 7.5p. Total Cost GBP{{ ( charge_slots_needed * 0.075) }}{% endif %}
- conditions: "{{ states.octopusagile.rates == none or (states.octopusagile.rates.attributes.values()|count) < 34 or (states.octopusagile.rates.attributes.values()|count) > 52 or (states('sensor.solcast_forecast_tomorrow')|int(0)) == 0 }}"
sequence:
- service: notify.telegram_chris
data:
title: "Powerwall: Error"
message: "Error setting overnight charging price, will try again within the next half hour."
default:
- alias: "Update Solcast Forecast"
event: solcast_update_all_forecasts
- delay: 30
- service: input_number.set_value
target:
entity_id: input_number.overnight_powerwall_max_charge
data:
value: "{% set solar_forecast = (states('sensor.solcast_forecast_tomorrow')|float(0)) if now().strftime('%-H')|int(0) > 12 else (states('sensor.solcast_forecast_today')|float(0)) %}{{ ([0,[(100 * (powerwall_capacity - (solar_forecast - tomorrow_solar_threshold))) / powerwall_capacity,100]|min]|max)|int(0) }}"
- service: input_number.set_value
target:
entity_id: input_number.powerwall_charge_below_x_pence
data:
# Take the 20 last prices for the list (next 10 hours), sort them by price and take the 8th for example if 4 hours charging (80% charging) is required.
value: "{% set howmanyrates = 18 if now().strftime('%-H')|int(0) > 12 else (18-now().strftime('%-H')|int(0)) %}{% set solar_forecast = (states('sensor.solcast_forecast_tomorrow')|float(0)) if now().strftime('%-H')|int(0) > 12 else (states('sensor.solcast_forecast_today')|float(0)) %}{% set rates = states.octopusagile.rates.attributes.values()|list %}{% set octopusrates = rates[-howmanyrates:]|sort %}{% set charge_slots_needed = (0.5 + (((states('input_number.overnight_powerwall_max_charge')|float(0)) + overnight_usage_percent - (states('sensor.powerwall_charge')|float(0)) )/percentage_per_half_hour))|int(0) %}{% if charge_slots_needed == 0 %}0.0{% else %}{{ (octopusrates[charge_slots_needed -1]|float(0) ) }}{% endif %}"
- service: telegram_bot.send_message
data:
target: !secret telegram_chat_id_chris
title: "Solar Today/Tomorrow: {{ states('sensor.solcast_forecast_today')|int(0) }}/{{states('sensor.solcast_forecast_tomorrow')|int(0) }}kWh"
message: >
{% set charge_slots_needed = (0.5 + (((states('input_number.overnight_powerwall_max_charge')|float(0)) + overnight_usage_percent - (states('sensor.powerwall_charge')|float(0)) )/percentage_per_half_hour))|int(0) %}
Powerwall Charge Level: {{ states('sensor.powerwall_charge')|int(0) }}%
{% if charge_slots_needed > 0 %}Powerwall Charging overnight to {{ states('input_number.overnight_powerwall_max_charge')|int(0) }}%
{{ charge_slots_needed }} half hour periods.
Max Price of {{ states('input_number.powerwall_charge_below_x_pence') }}p. Total Cost GBP{{ ( charge_slots_needed * 0.075) }}{% endif %}
And this automation for setting charge level and mode:
alias: "Powerwall: Set reserve level and mode"
description: |
Set powerwall reserve and mode
trigger:
- platform: time
id: time
at:
- "06:30:05"
- "14:00:05"
- "15:00:05"
- "15:59:55"
- platform: numeric_state
id: below25
entity_id: sensor.powerwall_charge_corrected
below: 25
- platform: numeric_state
id: above25
entity_id: sensor.powerwall_charge_corrected
above: 25
- platform: numeric_state
id: above50
entity_id: sensor.powerwall_charge_corrected
above: 50
- platform: numeric_state
id: below45
entity_id: sensor.powerwall_charge_corrected
below: 45
- platform: state
id: states
entity_id:
- binary_sensor.go_cheap
- binary_sensor.power_hour
- binary_sensor.agile_peak
- binary_sensor.agile_plunge
- input_number.overnight_powerwall_max_charge
- binary_sensor.powerwall_at_or_below_max_charge_cost_and_charge_limit
- sensor.zappi_car_mode
- platform: homeassistant
id: start
event: start
- platform: event
id: reload
event_type: automation_reloaded
condition: []
action:
- choose:
- conditions:
condition: or
conditions:
- condition: state
entity_id: binary_sensor.power_hour
state: "on"
- condition: state
entity_id: binary_sensor.agile_plunge
state: "on"
- condition: state
entity_id: >-
binary_sensor.powerwall_at_or_below_max_charge_cost_and_charge_limit
state: "on"
sequence:
- service: tesla_gateway.set_operation
data:
real_mode: backup
- conditions:
condition: state
entity_id: binary_sensor.agile_peak
state: "on"
sequence:
- service: input_number.set_value
target:
entity_id: input_number.powerwall_reserve_requested
data:
value: 1
- service: tesla_gateway.set_operation
data:
real_mode: self_consumption
backup_reserve_percent: 1
- conditions:
- condition: state
entity_id: >-
binary_sensor.powerwall_at_or_below_max_charge_cost_and_charge_limit
state: "off"
- condition: state
entity_id: sensor.enphase_status
state: Sleep
- condition: state
entity_id: input_boolean.freeze_power_when_cars_charging
state: "on"
- condition: or
conditions:
- condition: state
entity_id: sensor.zappi_car_mode
state: Fast
sequence:
- service: tesla_gateway.set_operation
data:
real_mode: self_consumption
backup_reserve_percent: "{{ states('sensor.powerwall_charge')|int(default=0) }}"
- service: input_number.set_value
target:
entity_id: input_number.powerwall_reserve_requested
data:
value: "{{ states('sensor.powerwall_charge')|int(default=0) }}"
- conditions:
- condition: state
entity_id: binary_sensor.go_cheap
state: "on"
sequence:
- service: tesla_gateway.set_operation
data:
real_mode: self_consumption
backup_reserve_percent: 35
enabled: false
- service: input_number.set_value
target:
entity_id: input_number.powerwall_reserve_requested
data:
value: 35
enabled: false
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.solcast_forecast_today
below: 8
sequence:
- service: input_number.set_value
data:
value: 100
target:
entity_id: input_number.overnight_powerwall_max_charge
- conditions:
- condition: numeric_state
entity_id: sensor.solcast_forecast_today
above: 8
below: 12
sequence:
- service: input_number.set_value
data:
value: 80
target:
entity_id: input_number.overnight_powerwall_max_charge
- conditions:
- condition: numeric_state
entity_id: sensor.solcast_forecast
above: 12
below: 14
sequence:
- service: input_number.set_value
data:
value: 70
target:
entity_id: input_number.overnight_powerwall_max_charge
- conditions:
- condition: numeric_state
entity_id: sensor.solcast_forecast
above: 14
below: 18
sequence:
- service: input_number.set_value
data:
value: 60
target:
entity_id: input_number.overnight_powerwall_max_charge
- conditions:
- condition: numeric_state
entity_id: sensor.solcast_forecast
above: 18
sequence:
- service: input_number.set_value
data:
value: 50
target:
entity_id: input_number.overnight_powerwall_max_charge
- conditions:
- condition: state
entity_id: input_boolean.go_tariff
state: "off"
- condition: state
entity_id: >-
binary_sensor.powerwall_at_or_below_max_charge_cost_and_charge_limit
state: "off"
- condition: time
after: "00:30:00"
before: "04:30:00"
sequence:
- service: tesla_gateway.set_operation
data:
real_mode: self_consumption
backup_reserve_percent: >-
{{ [ states('sensor.powerwall_charge')|int(default=0) ,
states('input_number.overnight_powerwall_max_charge')|int(default=0)]|min
}}
- service: input_number.set_value
target:
entity_id: input_number.powerwall_reserve_requested
data:
value: >-
{{ [ states('sensor.powerwall_charge')|int(default=0) ,
states('input_number.overnight_powerwall_max_charge')|int(default=0)]|min
}}
- conditions:
- condition: state
entity_id: input_boolean.go_tariff
state: "off"
- condition: time
after: "14:00:00"
before: "14:59:59"
- condition: numeric_state
entity_id: sensor.powerwall_charge
below: 25
sequence:
- service: tesla_gateway.set_operation
data:
real_mode: backup
- conditions:
- condition: state
entity_id: input_boolean.go_tariff
state: "off"
- condition: time
after: "15:00:00"
before: "15:59:30"
- condition: numeric_state
entity_id: sensor.powerwall_charge
below: 50
sequence:
- service: tesla_gateway.set_operation
data:
real_mode: backup
default:
- service: input_number.set_value
target:
entity_id: input_number.powerwall_reserve_requested
data:
value: "{{ [ states('sensor.powerwall_charge')|int(default=0) , 5]|min }}"
- service: tesla_gateway.set_operation
data:
real_mode: self_consumption
backup_reserve_percent: "{{ [ states('sensor.powerwall_charge')|int(default=0) , 5]|min }}"
mode: queued
trace:
stored_traces: 15
This is my current UI controls:
I also incorporated my own 5 choice decision tree in to the automation which will set the charge level according to the next days Solarcast prediction:
alias: "Powerwall: Set reserve level and mode2"
description: Set Powerwall Max Overnight Charge % at 21:00
trigger:
- platform: time
at: "21:00:00"
condition: []
action:
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.solcast_forecast_tomorrow
below: 8
sequence:
- service: input_number.set_value
data:
value: 100
target:
entity_id: input_number.overnight_powerwall_max_charge
- conditions:
- condition: numeric_state
entity_id: sensor.solcast_forecast_tomorrow
above: 8
below: 12
value_template: ""
sequence:
- service: input_number.set_value
data:
value: 80
target:
entity_id: input_number.overnight_powerwall_max_charge
- conditions:
- condition: numeric_state
entity_id: sensor.solcast_forecast_tomorrow
above: 12
below: 14
sequence:
- service: input_number.set_value
data:
value: 70
target:
entity_id: input_number.overnight_powerwall_max_charge
- conditions:
- condition: numeric_state
entity_id: sensor.solcast_forecast_tomorrow
above: 14
below: 18
sequence:
- service: input_number.set_value
data:
value: 60
target:
entity_id: input_number.overnight_powerwall_max_charge
- conditions:
- condition: numeric_state
entity_id: sensor.solcast_forecast_tomorrow
above: 18
sequence:
- service: input_number.set_value
data:
value: 50
target:
entity_id: input_number.overnight_powerwall_max_charge
trace:
stored_traces: 10
mode: single
this is awsome, thank you!
Hi just installed the great looking Tesla Custom Integration component through HACS (dev version), have powerwall no car, used the [Chromium Tesla Token Generator] in the setup but all I get is “Integration
Failed to set up” check the logs. but there is nothing in the logs, am I missing something?
Can this co-exist with the official HA tesla integration or do I need to remove that?
Are you sure that you installed the “dev” version when in HACS? Go back in to hacs and select re-download but make sure to use the drop down menu for the version and scroll to bottom of the list to “dev”.
If you mean the https://www.home-assistant.io/integrations/powerwall then yes they can coexist. The powerwall integration polls your device direct over your local area network (localAPI). The Tesla Custom Integration from HACS polls the Tesla server in the cloud (cloudAPI - using the same data as the Tesla Ap).
Generally in Home Assistant we prefer localAPI over cloudAPI, but in the case of Tesla they have removed all control from the localAPI.
As to your specific authentication issues, it would be best to enable debug for your integration and see what is coming back through the logs.
You can enable debugging with the following lines in configuration.yaml
logger:
default: warning
logs:
teslajsonpy: debug
custom_components.tesla_custom: debug
Thanks all, so it looks like a HACS issues firstly I had installed the latest version then gone back and updated to dev version. That seems to be the issue. I deleted the full HACS install and started again and worked first time.
Thanks for this defiantly need to do some automation of my PW charging new to this only had the PW since Sept, its on time-based control and done pretty well so far on using solar and charging overnight when needed. However last night it didn’t bother charging and today no chance the solar and battery are going to see the day out, tesla algo. not that great then
Install Solcast and then you will have Fairly accurate forecast of the super available in your area. You have to create a Solarcast account and get the API from the website to use in the integration. The sensors in HA will all be created as default names and same as used in Bruces automatons.
On my 5 choice automation above that one is triggered at 21:00 and looks at “sensor.solcast_tomorrow_forecast” and sets the PW charge level accordingly. You may need to adjust the solar predictions against required charge % based on your home loads and consumption. My standing loads runs 24/7 at around 450wh and my consumption is high when there is solar as other automatons switch on additional electrical loads. But like today’s forecast is less that 8kWh so all non essential electrical loads are left off all day to preserve the PW SOC as long as possible.
Your use case sounds like a great candidate for using the EMHASS: Energy Management for Home Assistant add on.
EMHASS uses a linear programming model to optimise energy usage by continuously calculating when to switch deferrable loads throughout your house. I use it to schedule my home battery and EV charging, various other systems (hot water, air conditioning, pool pumps and heating). EMHASS considers forecasts for your household load, solar production as well as the buy/ sell price for electricity. If I have a low solar production day forecast it will defer loads to the next 24 hours.
Here is my household optimisation sensors created for the next 24 hours, HA reruns the optimisation every minute as my variable pricing changes that quickly. I use these sensors in automations for my devices to switch them at the appropriate timing.
You can see in the dark blue when my battery is scheduled to charge or export to the grid - after 5pm you can see a big export block as that is when my export tariff is highest and EMHASS has calculated exactly how much I can export, but keep the house running overnight.
You can see on the dark green when it is best to export to the grid, for today’s plan there is no grid import required. You can see the light green the charging profile for my EV for the day. You can see my pool heater isn’t scheduled as it’s run hours are set to only run when the value of my solar exports are extremely_low (< 5¢/ kWh) and I want to maximise self consumption. You can see my standing load in light purple which is based off the average standing load for the last couple of days.
There is some complexity in setting up the add-on, but the Author is very responsive and claims an 8-10% improvement in efficiency. I’m probably seeing higher efficiency as optimising quickly for my changes in my variable pricing gives me a high operational benefits (financial, environmental, sustainable).
Hi Mark,
I tried to set up before and again tonight but I can’t get past the web ui fails to open. I set up a port forwarding rule to use 5005 external port and direct to my HA ip address:5000 but no joy.
Also in the configuration as soon as I try to change the monetary values from the default the entry forms go red and it doesn’t accept my values. I’m trying to enter then looks this:
Peak rate: 0.3100
Off peak: 0.0750
Sell: 0.0410
Happy to work with you to get this working.
I presume you are using the add-on?
Do you need the port forwarding, can you just setup EMHASS to use port 5005? Can you access your HomeAssistant via you LAN?
I don’t actually use the dialogue for cost entry, but just tried and see what you mean, so there is a bug - @davidusb . A workaround is to switch configuration to yaml where you can edit, save and restart add-on.
It might also make sense to switch this discussion over to EMHASS add-on: An energy management optimization add-on for Home Assistant OS and supervised