reptilex / tesla-style-solar-power-card

Home assistant power card mimicking the one tesla provides for the powerwall app.
226 stars 59 forks source link

stock template does not work with Tesla Virtual Power Plant #99

Open neildsb opened 2 years ago

neildsb commented 2 years ago

Magnificent work, I have a little bug, the animations and figures do not work when exporting the battery to the grid; hope this helps?

https://www.tesla.com/en_gb/tesla-energy-plan

image

reptilex commented 2 years ago

Hmm, can you post your card config? And maybe also your templates?

neildsb commented 2 years ago

I have the stock templates, I think basically it struggles with battery to grid concept -

template:

reptilex commented 2 years ago

The custom template does not have a tesla_card_battery_to_grid entity and doesn't have a configuration for the card to do this. I have no tesla powerwall therefore I cannot give you any indications. Please ask in the forum. Or look at my post, I think somebody already solved it there.

Avatar1976 commented 2 years ago

@neildsb left comments with a solution to this in the issue around it stopped working from core 2022.2.

reptilex commented 2 years ago

@Avatar1976 which template of that thread should I use to update the docs?

purcell-lab commented 2 years ago

This issue isn't confined to just VPP users, outside of the US many times your powerwall can export directly to the grid.

Fortunately help is at hand and https://github.com/AviadorLP has solved this issue for us at #96, though a complex set of templates which map the flows dependent on input/export & charging/discharging states.

I have now adapted this for the powerwall and my templates and configuration is below, which now correctly shows grid2battery and battery2grid flows and should work without modification for other powerwall users.

# Templates for Actual Powerflow transfer charts (APF - Actual PowerFlow)
#
# For the math to add up a new Real House Load must be calculated and used, witch includes
# the inverter consumption and excludes rounding errors and corrects inaccurate power readings.
#
# It never made sense that inbound power sometimes does not equal outbound power. This fixes it!
#
# Developed by AviadorLP
#
# Just replace the 4 words below "ReplaceWithYourSensor" with your specific sensors,
# for grid, house, solar and battery entities, example "sensor.powerwall_load_now" 
#
# If your sensor is negative when it should be positive replace that complete line with
#         state: "{{ 0 - states('ReplaceWithYourSensor')|int(default=0) }}"
#
# If you don't have a battery replace that complete line with
#         state: "{{ 0 }}"

template:
  - sensor:
# grid sensor must be negative when importing and positive when exporting
# which is the opposite of what powerwall reports, hence the '0 -'
    - name: APF Grid Entity
      device_class: power
      state_class: measurement
      unit_of_measurement: W
      state: "{{ (0 - states('sensor.powerwall_site_now')|float(0)*1000)|int(0) }}"

# sensor must always be 0 or positive (i think they always are)
    - name: APF House Entity
      device_class: power
      state_class: measurement
      unit_of_measurement: W
      state: "{{ (states('sensor.powerwall_load_now')|float(0)*1000)|int(0) }}"

# sensor must always be 0 or positive (i think they always are)
    - name: APF Generation Entity
      device_class: power
      state_class: measurement
      unit_of_measurement: W
      state: "{{ (states('sensor.powerwall_solar_now')|float(0)*1000)|int(0) }}"

# battery sensor must be positive when charging and negative when discharging
# which is the opposite of what powerwall reports, hence the '0 -'
    - name: APF Battery Entity
      device_class: power
      state_class: measurement
      unit_of_measurement: W
      state: "{{ (0 - states('sensor.powerwall_battery_now')|float(0)*1000)|int(0) }}"

# Required to reduce code later on
    - name: APF Grid Import
      device_class: power
      state_class: measurement
      unit_of_measurement: W
      state: >
        {% if states('sensor.apf_grid_entity')|int(default=0) < 0 %}
          {{ states('sensor.apf_grid_entity')|int(default=0)|abs }}
        {% else %}
          0
        {% endif %}

#   Inverter consumption and power losses due to Inverter transfers and power conversions (AC/DC)
#   excludes rounding errors made worst by the fact that some inverters round all sensors readings to INT
#   Occasionally this might be negative probably due to cumulative errors in not so accurate power readings.
    - name: APF Inverter Power Consumption
      device_class: power
      state_class: measurement
      unit_of_measurement: W
      state: "{{ states('sensor.apf_generation_entity')|int(default=0) - states('sensor.apf_battery_entity')|int(default=0) - states('sensor.apf_house_entity')|int(default=0) - states('sensor.apf_grid_entity')|int(default=0) }}"

# Real House Load Includes Inverter consumption and transfer conversions and losses and rounding errors.
# It never made sense that inbound power sometimes does not equal outbound power. This fixes it!
    - name: APF Real House Load
      device_class: power
      state_class: measurement
      unit_of_measurement: W
      state: "{{ states('sensor.apf_house_entity')|int(default=0) + states('sensor.apf_inverter_power_consumption')|int(default=0) }}"
      icon: mdi:home-lightning-bolt

    - name: APF Grid2House
      device_class: power
      state_class: measurement
      unit_of_measurement: W
      state:  >
        {% if states('sensor.apf_grid_import')|int(default=0) > states('sensor.apf_real_house_load')|int(default=0) %}
          {{ states('sensor.apf_real_house_load')|int(default=0) }}
        {% else %}
          {{ states('sensor.apf_grid_import')|int(default=0) }}
        {% endif %}

    - name: APF Grid2Batt
      device_class: power
      state_class: measurement
      unit_of_measurement: W
      state: >
        {% if states('sensor.apf_grid_import')|int(default=0) > states('sensor.apf_real_house_load')|int(default=0) %}
          {{ states('sensor.apf_grid_import')|int(default=0) - states('sensor.apf_real_house_load')|int(default=0) }}
        {% else %}
          0
        {% endif %}

    - name: APF Batt2House
      device_class: power
      state_class: measurement
      unit_of_measurement: W
      state: >
        {% if states('sensor.apf_battery_entity')|int(default=0) < 0 %}
          {% if states('sensor.apf_battery_entity')|int(default=0)|abs > states('sensor.apf_real_house_load')|int(default=0) %}
            {{ states('sensor.apf_real_house_load')|int(default=0) }}
          {% else %}
            {{ states('sensor.apf_battery_entity')|int(default=0)|abs }}
          {% endif %}
        {% else %}
          0
        {% endif %}

# This might be called house to grid, and can happen in rare circumstances,
# like when the inverter is not able to do a precise adjustment of power fast enough
# or when you want to force a discharge of the battery or something...
# But it only happens with battery or other power generator users.
    - name: APF Batt2Grid
      device_class: power
      state_class: measurement
      unit_of_measurement: W
      state: >
        {% if states('sensor.apf_battery_entity')|int(default=0) < 0 %}
          {% if states('sensor.apf_battery_entity')|int(default=0)|abs > states('sensor.apf_real_house_load')|int(default=0) %}
            {{ states('sensor.apf_battery_entity')|int(default=0)|abs - states('sensor.apf_real_house_load')|int(default=0) }}
          {% else %}
            0
          {% endif %}
        {% else %}
          0
        {% endif %}

    - name: APF Solar2Grid
      device_class: power
      state_class: measurement
      unit_of_measurement: W
      state: >
        {% if states('sensor.apf_grid_entity')|int(default=0) > states('sensor.apf_batt2grid')|int(default=0) %}
          {{ states('sensor.apf_grid_entity')|int(default=0) - states('sensor.apf_batt2grid')|int(default=0) }}
        {% else %}
          0
        {% endif %}

    - name: APF Solar2House
      device_class: power
      state_class: measurement
      unit_of_measurement: W
      state: >
        {% if states('sensor.apf_generation_entity')|int(default=0) > 0 and states('sensor.apf_real_house_load')|int(default=0) > states('sensor.apf_batt2house')|int(default=0) + states('sensor.apf_grid_import')|int(default=0) %}
          {% if states('sensor.apf_generation_entity')|int(default=0) > states('sensor.apf_real_house_load')|int(default=0) - states('sensor.apf_batt2house')|int(default=0) - states('sensor.apf_grid2house')|int(default=0) %}
            {{ states('sensor.apf_real_house_load')|int(default=0) - states('sensor.apf_batt2house')|int(default=0) - states('sensor.apf_grid2house')|int(default=0) }}
          {% else %}
            {{ states('sensor.apf_generation_entity')|int(default=0) }}
          {% endif %}
        {% else %}
          0
        {% endif %}

    - name: APF Solar2Batt
      device_class: power
      state_class: measurement
      unit_of_measurement: W
      state: >
        {% if states('sensor.apf_generation_entity')|int(default=0) > 0 and states('sensor.apf_battery_entity')|int(default=0) > 0 %}
          {% if states('sensor.apf_battery_entity')|int(default=0) > states('sensor.apf_grid2batt')|int(default=0) %}
            {% if states('sensor.apf_generation_entity')|int(default=0) - states('sensor.apf_solar2house')|int(default=0) > states('sensor.apf_battery_entity')|int(default=0) - states('sensor.apf_grid2batt')|int(default=0) %}
              {{ states('sensor.apf_battery_entity')|int(default=0) - states('sensor.apf_grid2batt')|int(default=0) }}
            {% else %}
              {{ states('sensor.apf_generation_entity')|int(default=0) - states('sensor.apf_solar2house')|int(default=0) - states('sensor.apf_solar2grid')|int(default=0) }}
            {% endif %}
          {% else %}
            0
          {% endif %}
        {% else %}
          0
        {% endif %}

Reload templates and then configure the tesla-style-card as follows:

type: custom:tesla-style-solar-power-card
name: Actual Power Flow
grid_to_house_entity: sensor.apf_grid2house
grid_to_battery_entity: sensor.apf_grid2batt
generation_to_grid_entity: sensor.apf_solar2grid
generation_to_battery_entity: sensor.apf_solar2batt
generation_to_house_entity: sensor.apf_solar2house
battery_to_house_entity: sensor.apf_batt2house
battery_to_grid_entity: sensor.apf_batt2grid
grid_entity: sensor.apf_grid_entity
house_entity: sensor.apf_real_house_load
generation_entity: sensor.apf_generation_entity
battery_entity: sensor.apf_battery_entity
neildsb commented 2 years ago

testing now, thanks for all your help!!

neildsb commented 2 years ago

charging battery from the grid is good, roll-on 4pm BST for battery to grid dump -

image

purcell-lab commented 2 years ago

My dump to grid worked well tonight.

Screenshot_20220422-175159

neildsb commented 2 years ago

My dump to grid worked well tonight.

Screenshot_20220422-175159

sorry for so many questions, how did you display the kWh in the bubbles?

purcell-lab commented 2 years ago

sorry for so many questions, how did you display the kWh in the bubbles?

No problem.

You create three utility meters which reset daily, this is now easy with the new helpers; solar production, house consumption and grid consumption. Then use those new sensors for the extra_entity text which displays at the top of each bubble.

Screenshot_20220422-190400 Screenshot_20220422-190336 Screenshot_20220422-190314

neildsb commented 2 years ago

thank you so much!! RTFM Neil - it's all in the readme, I have also copied your display parameters by showing Watts over kW

neildsb commented 2 years ago

'A' ok so far, looking good

image