QuarkSolution
(Meghadeep Roy Chowdhury)
November 28, 2025, 4:08pm
1
My distributor has different charges for different usage of real energy (kWh) in a month, and I have net metering, so my grid exports need to be subtracted from my grid imports to calculate my total cost. Since Home Assistant has no such configuration for net metering (which is strange, since net metering is widely practiced in many countries, and is a huge reason people want to install solar panels in the first place), I had to create a template sensor to calculate the monthly total costs. This is what I have in my configuration file:
# Templates
template:
- sensor:
- name: Monthly Net Energy Import
unit_of_measurement: "kWh"
default_entity_id: sensor.net_real_energy_import
unique_id: net_real_energy_import
state: "{{ (states('sensor.monthly_energy_import')|float) - (states('sensor.monthly_energy_export')|float)|round(1) }}"
- sensor:
- name: Monthly Net Energy Cost
unit_of_measurement: INR
default_entity_id: sensor.net_energy_cost
unique_id: net_energy_cost
device_class: monetary
state: >
{% set grid = states('sensor.net_real_energy_import')| float %}
{% if grid|float <= 25 %}
{{ (grid * 5.18 ) | float(0)|round(2) }}
{% elif grid|float > 25 and grid|float <= 60 %}
{{ (25 * 5.18 + (grid - 25) * 5.69 ) | float(0)|round(2) }}
{% elif grid|float > 60 and grid|float <= 100 %}
{{ (25 * 5.18 + 35 * 5.69 + (grid - 60) * 6.70 ) | float(0)|round(2) }}
{% elif grid|float > 100 and grid|float <= 150 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + (grid - 100) * 7.45 ) | float(0)|round(2) }}
{% elif grid|float > 150 and grid|float <= 200 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + 50 * 7.45 + (grid - 150) * 7.62 ) | float(0)|round(2) }}
{% elif grid|float > 200 and grid|float <= 300 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + 50 * 7.45 + 50 * 7.62 + (grid - 200) * 7.62 ) | float(0)|round(2) }}
{% elif grid|float > 300 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + 50 * 7.45 + 50 * 7.62 + 100 * 7.62 + (grid - 300) * 9.21 ) | float(0)|round(2) }}
{%else%}
off
{% endif %}
The first template sensor calculates the net import from the grid in a month. sensor.monthly_energy_import and sensor.monthly_energy_export are utility meter helpers that calculate my monthly grid import and monthly grid export, and resets according to my billing cycle, so the template sensor also resets monthly.
The second template sensor calculates the actual monthly energy cost according to my distributor’s tariff.
But in the Energy Dashboard, I cannot choose this entity as my total cost sensor.
My template sensor does not show up in this drop down. Home Assistant is recording the statistics of the template sensor, so the troubleshooting link did not help. What am I doing wrong? I’m certain it’s something so trivial that I’m missing it.
QuarkSolution
(Meghadeep Roy Chowdhury)
November 28, 2025, 4:31pm
2
It was indeed trivial. The sensor needed the total state_class. With this in my config file, I could select the net energy cost template sensor in my Energy Dashboard.
# Templates
template:
- sensor:
- name: Monthly Net Energy Import
unit_of_measurement: "kWh"
default_entity_id: sensor.net_real_energy_import
unique_id: net_real_energy_import
device_class: energy
state_class: total
state: "{{ (states('sensor.monthly_energy_import')|float) - (states('sensor.monthly_energy_export')|float)|round(1) }}"
- sensor:
- name: Monthly Net Energy Cost
unit_of_measurement: INR
default_entity_id: sensor.net_energy_cost
unique_id: net_energy_cost
device_class: monetary
state_class: total
state: >
{% set grid = states('sensor.net_real_energy_import')| float %}
{% if grid|float <= 25 %}
{{ (grid * 5.18 ) | float(0)|round(2) }}
{% elif grid|float > 25 and grid|float <= 60 %}
{{ (25 * 5.18 + (grid - 25) * 5.69 ) | float(0)|round(2) }}
{% elif grid|float > 60 and grid|float <= 100 %}
{{ (25 * 5.18 + 35 * 5.69 + (grid - 60) * 6.70 ) | float(0)|round(2) }}
{% elif grid|float > 100 and grid|float <= 150 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + (grid - 100) * 7.45 ) | float(0)|round(2) }}
{% elif grid|float > 150 and grid|float <= 200 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + 50 * 7.45 + (grid - 150) * 7.62 ) | float(0)|round(2) }}
{% elif grid|float > 200 and grid|float <= 300 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + 50 * 7.45 + 50 * 7.62 + (grid - 200) * 7.62 ) | float(0)|round(2) }}
{% elif grid|float > 300 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + 50 * 7.45 + 50 * 7.62 + 100 * 7.62 + (grid - 300) * 9.21 ) | float(0)|round(2) }}
{%else%}
off
{% endif %}
EDIT: Just to round this out, I changed my template sensors to align more with how Home Assistant expects its energy data. These template sensors help me calculate the most important aspects of my solar installation, in case it helps somebody else:
# Templates
template:
- sensor:
- name: Monthly Net Energy Import
unit_of_measurement: "kWh"
icon: mdi:lightning-bolt-circle
default_entity_id: sensor.net_real_energy_import
unique_id: net_real_energy_import
device_class: energy
state_class: total
state: "{{ (states('sensor.monthly_energy_import')|float) - (states('sensor.monthly_energy_export')|float) }}"
- sensor:
- name: Monthly Net Energy Cost
unit_of_measurement: INR
icon: mdi:cash-multiple
default_entity_id: sensor.net_energy_cost
unique_id: net_energy_cost
device_class: monetary
state_class: total
state: >
{% set grid = states('sensor.net_real_energy_import')| float %}
{% if grid|float <= 25 %}
{{ (grid * 5.18 ) | float(0)|round(2) }}
{% elif grid|float > 25 and grid|float <= 60 %}
{{ (25 * 5.18 + (grid - 25) * 5.69 ) | float(0)|round(2) }}
{% elif grid|float > 60 and grid|float <= 100 %}
{{ (25 * 5.18 + 35 * 5.69 + (grid - 60) * 6.70 ) | float(0)|round(2) }}
{% elif grid|float > 100 and grid|float <= 150 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + (grid - 100) * 7.45 ) | float(0)|round(2) }}
{% elif grid|float > 150 and grid|float <= 200 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + 50 * 7.45 + (grid - 150) * 7.62 ) | float(0)|round(2) }}
{% elif grid|float > 200 and grid|float <= 300 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + 50 * 7.45 + 50 * 7.62 + (grid - 200) * 7.62 ) | float(0)|round(2) }}
{% elif grid|float > 300 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + 50 * 7.45 + 50 * 7.62 + 100 * 7.62 + (grid - 300) * 9.21 ) | float(0)|round(2) }}
{%else%}
off
{% endif %}
- sensor:
- name: Monthly Gross Energy Cost
unit_of_measurement: INR
icon: mdi:cash-multiple
default_entity_id: sensor.gross_energy_cost
unique_id: gross_energy_cost
device_class: monetary
state_class: total
state: >
{% set grid = states('sensor.monthly_energy_import')| float %}
{% if grid|float <= 25 %}
{{ (grid * 5.18 ) | float(0)|round(2) }}
{% elif grid|float > 25 and grid|float <= 60 %}
{{ (25 * 5.18 + (grid - 25) * 5.69 ) | float(0)|round(2) }}
{% elif grid|float > 60 and grid|float <= 100 %}
{{ (25 * 5.18 + 35 * 5.69 + (grid - 60) * 6.70 ) | float(0)|round(2) }}
{% elif grid|float > 100 and grid|float <= 150 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + (grid - 100) * 7.45 ) | float(0)|round(2) }}
{% elif grid|float > 150 and grid|float <= 200 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + 50 * 7.45 + (grid - 150) * 7.62 ) | float(0)|round(2) }}
{% elif grid|float > 200 and grid|float <= 300 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + 50 * 7.45 + 50 * 7.62 + (grid - 200) * 7.62 ) | float(0)|round(2) }}
{% elif grid|float > 300 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + 50 * 7.45 + 50 * 7.62 + 100 * 7.62 + (grid - 300) * 9.21 ) | float(0)|round(2) }}
{%else%}
off
{% endif %}
- sensor:
- name: Monthly Solar Revenue
unit_of_measurement: INR
icon: mdi:cash-multiple
default_entity_id: sensor.solar_revenue
unique_id: solar_revenue
device_class: monetary
state_class: total
state: "{{ (states('sensor.gross_energy_cost')|float) - (states('sensor.net_energy_cost')|float) }}"
- sensor:
- name: Monthly Estimated Consumption Cost
unit_of_measurement: INR
icon: mdi:cash-multiple
default_entity_id: sensor.estimated_consumption_cost
unique_id: estimated_consumption_cost
device_class: monetary
state_class: total
state: >
{% set grid = states('sensor.monthly_energy_import')| float + states('sensor.monthly_solar_generation')|float - states('sensor.monthly_energy_export')|float %}
{% if grid|float <= 25 %}
{{ (grid * 5.18 ) | float(0)|round(2) }}
{% elif grid|float > 25 and grid|float <= 60 %}
{{ (25 * 5.18 + (grid - 25) * 5.69 ) | float(0)|round(2) }}
{% elif grid|float > 60 and grid|float <= 100 %}
{{ (25 * 5.18 + 35 * 5.69 + (grid - 60) * 6.70 ) | float(0)|round(2) }}
{% elif grid|float > 100 and grid|float <= 150 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + (grid - 100) * 7.45 ) | float(0)|round(2) }}
{% elif grid|float > 150 and grid|float <= 200 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + 50 * 7.45 + (grid - 150) * 7.62 ) | float(0)|round(2) }}
{% elif grid|float > 200 and grid|float <= 300 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + 50 * 7.45 + 50 * 7.62 + (grid - 200) * 7.62 ) | float(0)|round(2) }}
{% elif grid|float > 300 %}
{{ (25 * 5.18 + 35 * 5.69 + 40 * 6.70 + 50 * 7.45 + 50 * 7.62 + 100 * 7.62 + (grid - 300) * 9.21 ) | float(0)|round(2) }}
{%else%}
off
{% endif %}
- sensor:
- name: Monthly Solar Return on Investment
unit_of_measurement: INR
icon: mdi:cash-multiple
default_entity_id: sensor.solar_return
unique_id: solar_return
device_class: monetary
state_class: total
state: "{{ (states('sensor.estimated_consumption_cost')|float) - (states('sensor.net_energy_cost')|float) }}"
This assumes you have three utility meter helpers configured to track your monthly grid import, monthly grid export, and monthly solar generation. Since the utility meter helpers are all reset on the same day (it follows my billing cycle with my distributor), the template sensors automatically reset themselves.