Electricity cost and solar compensation calculation for spain

Hi,

not as fancy as most of the projects in this category, as it is just using some standard home assistant integrations, but it took me a while to figure everything out so I thought I’d better save time to others. This configuration will allow you to:

  • Create an entity showing what is the current tarif (P1 Punta, P2 Plana, P3 Valle)
  • Assign a cost to each tarif as well as the price of the energy you sell from lovelace
  • Know how much money is your next electricity bill going to cost you
  • Know how much money did your last bill cost, so you can check it out when the bill actually arrives
  • Take into account the exported energy as well as the inported energy if you have some sort of self-production at home

imagen

The problem with the energy dashboard is that it takes into account the total energy imported and the total energy exported. However in Spain we get billed based on the difference hour by hour. That means that, for a given hour, if you import 3kWh and export 2kWh you only get charged for 1kWh. And of course, if you import 2kWh and export 3kWh you only get compensated for 1kWh.

Requirements:

  • A standard 2.0TD tarif
  • An energy meter that shows a reading in kWh in home assistant for whatever cost you want to monitor. In my case I have the total energy consumption of my house, but you can monitor single devices if you prefer.
  • If you have solar panels, you will need to setup a net energy balance sensor which contains the difference between the imported and exported energies.

How it works:

  1. Some input numbers allow to set the price for each tarif(named punta, pla, vall)
  2. An input number keeps the current bills cost (named factura_actual)
  3. Another input number keeps the last bill’s cost (named factura_anterior)
  4. An automation calculates the price on each hour based on the input number values, the time, a workday sensor, and the energy consumed/produced
  5. Another automation stores the value at the end of the month into the factura_anterior input number

Two template sensors are provided that allow to have the input_numbers of the current and previous bill as read-only sensors in the frontend

# Some input number helpers to introduce the costs
input_number:
  punta:
    name: Preu punta (P1)
    min: 0
    max: 1
    unit_of_measurement: €/kWh
    mode: box
    icon: mdi:arrow-up-bold
  pla:
    name: Preu pla (P2)
    min: 0
    max: 1
    unit_of_measurement: €/kWh
    mode: box
    icon: mdi:arrow-right-bold
  vall:
    name: Preu vall (P3)
    min: 0
    max: 1
    unit_of_measurement: €/kWh
    mode: box
    icon: mdi:arrow-down-bold

# Put here the price your energy company pays you for the electricity you export
  compensacio:
    name: Preu compensació
    min: 0
    max: 1
    unit_of_measurement: €/kWh
    mode: box
    icon: mdi:solar-panel
# Price of the ongoing bill
  factura_actual:
    name: "Import provisional propera factura"
    min: -2000
    max: 2000
    step: 0.001
    icon: mdi:currency-eur
# Price of the next bill
  factura_anterior:
    name: "Import definitiu factura anterior"
    min: -2000
    max: 2000
    step: 0.001
    icon: mdi:currency-eur

# Electricity price is different on holidays. Viernes Sant is considered labour for that matter
binary_sensor:
  - name: "Festius Espanya"
    platform: workday
    country: ES
    remove_holidays:
      - "Viernes Santo"


template:
  - sensor:
    # Calculate the current electricity cost price based on time and holiday
    - name: "Tarifa elèctrica"
      unit_of_measurement: €/kWh
      icon: >
        {% set punta = "mdi:arrow-up-bold" %}
        {% set pla = "mdi:arrow-right-bold" %}
        {% set vall = "mdi:arrow-down-bold" %}
        {% set laborable = is_state('binary_sensor.festius_espanya', 'on') %}
        {% set hora = now().hour %}
        {% if not(laborable) %}
          {{ vall }}
        {% else %}
          {% if (hora < 8)%}
            {{ vall }}
          {% elif (hora < 10) %}
            {{ pla }}
          {% elif (hora < 14) %}
            {{ punta }}
          {% elif (hora < 18) %}
            {{ pla }}
          {% elif (hora < 22) %}
            {{ punta }}
          {% else %}
            {{ pla }}
          {% endif %}
        {% endif %}
      state: >
        {% set punta = states('input_number.punta') | float %}
        {% set vall = states('input_number.vall') | float %}
        {% set pla = states('input_number.pla') | float %}
        {% set laborable = is_state('binary_sensor.festius_espanya', 'on') %}
        {% set hora = now().hour %}
        {% if not(laborable) %}
          {{ vall }}
        {% else %}
          {% if (hora < 8)%}
            {{ vall }}
          {% elif (hora < 10) %}
            {{ pla }}
          {% elif (hora < 14) %}
            {{ punta }}
          {% elif (hora < 18) %}
            {{ pla }}
          {% elif (hora < 22) %}
            {{ punta }}
          {% else %}
            {{ pla }}
          {% endif %}
        {% endif %}

    # Read only version of the current bill cost. Use this in your frontend to avoid edditing the value accidentally
    - name: "Import factura actual"
      icon: mdi:currency-eur
      unit_of_measurement: "€"
      device_class: monetary
      state: >
        {{ states("input_number.factura_actual") | round(2) }}
    # Read only version of the previous bill cost. Use this in your frontend to avoid edditing the value accidentally
    - name: "Import factura anterior"
      icon: mdi:currency-eur
      unit_of_measurement: "€"
      device_class: monetary
      state: >
        {{ states("input_number.factura_anterior") | round(2) }}


automation:
# Add or substract cost at the end of the hour. sensor.excedent_hora is the energy consumption measurement in kW/h. Positive means you exported more energy than imported.
  - alias: "Acumular cost de l'hora actual a la factura"
    id: acumular_cost_a_factura
    trigger:
      - platform: time_pattern
        minutes: 59
        seconds: 55
    action:
      - service: input_number.set_value
        data:
          entity_id: input_number.factura_actual
          value: >
            {% set excedent = states("sensor.excedent_hora") | float %}
            {% set factura_acumulada = states("input_number.factura_actual") | float %}
            {% set tarifa_electrica = states("sensor.tarifa_electrica") | float %}
            {% set tarifa_compensacio = states("input_number.compensacio") | float %}
            {% if is_number(excedent) %}
              {% if excedent < 0 %}
                {{ factura_acumulada + excedent * tarifa_electrica }}
              {% else %}
                {{ factura_acumulada + excedent * tarifa_compensacio }}
              {% endif %}
            {% endif %}
# Store price at the end of the month and start all over
  - alias: "Resetejar la factura a l'inici del mes"
    id: reiniciar_factura
    trigger:
      - platform: time_pattern
        hours: "0"
        minutes: "0"
        seconds: "5"
    condition:
      - condition: template
        value_template: "{{ now().day == 1 }}"
    action:
      - service: input_number.set_value
        data:
          entity_id: input_number.factura_anterior
          value: >
            {{ states("input_number.factura_actual") | float }}
      - service: input_number.set_value
        data:
          entity_id: input_number.factura_actual
          value: 0

And a suggestion for the frontend:

  - title: "Electricitat"
    path: "electricitat"
    icon: mdi:flash
    cards:
    - type: vertical-stack
      cards:
        - type: horizontal-stack
          cards:
            - type: gauge
              entity: sensor.excedent_hora
              name: "Excedent de l'hora actual"
              min: -3
              max: 3
              needle: True
              severity:
                green: 0
                yellow: -0.5
                red: -3
            - type: gauge
              entity: sensor.import_factura_actual
              name: "Import factura actual"
              min: -10
              max: 10
              needle: True
              severity:
                green: 0
                yellow: -2
                red: -10
    - type: vertical-stack
      cards:
      - type: entities
        title: Tarifes
        icon: mdi:currency-eur
        entities:
          - sensor.tarifa_electrica
          - input_number.punta
          - input_number.pla
          - input_number.vall
          - input_number.compensacio
      - type: entities
        title: Factures
        icon: mdi:currency-eur
        entities:
          - sensor.import_factura_actual
          - sensor.import_factura_anterior

Enjoy!

3 Likes

Hy!
Im really interested in this. But I dont know how integrate in my installation. When I put your code in the developer tools, give me this error:
ValueError: Template error: float got invalid input ‘unknown’ when rendering template 'input_number:

Some idea? really I never put a template in my home assistant yet…

Hi,

The input number section does not go into the templete editor. It goes into your configuration.yaml

You can also define those in the GUI in Configuration > devices > helpers:

Before checking anything in the template editor you need to define the input numbers (GUI or configuration.yaml) and the binary sensor ‘workday’ (only configuration.yaml). Then you can check the template sensors before adding them to configuration.yaml.

You will alsoneedto change sensor.excedent_hora with the name of the sensor that has the energy consumption of the last hour. Maybe you need an utility metter (Utility Meter - Home Assistant) for that

Finally, you can define the automations in the GUI or in configuration.yaml (Configuration.yaml - Home Assistant)

In summary: copy the first block of code into configuration.yaml (maybe you will have to merge it with what you already have because you can’t have 2 blocks with the same name) and the second block into ui-lovelace.yaml or add the cards manually if you configure your dashboard with the GUI.

Good luck!

Thanks Jesus!

I will try later or tomorrow.

Bona nit! :slight_smile:

Ok, I almost finish. One last thing… I understand that “excedent” will be negative if my solar panels produce more than I spend, true? and positive if I spend more than I produce ?

have you thought about also introducing consumption by power?

Thanks again!
(which electric company do you use?)