github marq24/ha-evcc 2025.12.1
BREAKING CHANGE: reduce object size of Forecast / Tariff attribute Information

latest releases: 2026.2.2, 2026.2.1, 2026.2.0...
one month ago

BREAKING CHANGE: Reduzed size of Forecast / Tariff attribute Information

As reported in #214 the initial approach to reduce the size of some entity attributes was not enough [see releases 2025.10.1/2/3/4/5/6]. So I have decided for a complete different approach to reduce the size of the JSON/DATA object that evcc backend is providing.

When you use the attributes (range or timeseries) of the following entities in your templates:

  • sensor.evcc_forecast_grid
  • sensor.evcc_forecast_solar
  • sensor.evcc_tariff_api_grid
  • sensor.evcc_tariff_api_solar

You must adjust your templates to be compatible with the new release - please continue reading for further details.

Some background Information

When the evcc backend is going to provide a time series of data points, then this will be done in a list of objects. Each object contain a start timestamp information (sometimes also a end timestamp) and the actual value. The timestamp information is a String like this 2025-12-06T00:00:00+01:00. When there are 400 data points in the list, this means, that there are at least 400 start time timestamp information (beside the actual values). This approach makes it very easy for a frontend to consume this data - with the downside, that the data structure is quite large.

In the previous releases the attempt was to keep this overall structure but reducing the length of a this time information string by concerting it to so called UNIX Timestamps (in the UTC-Timezone). This was working some sort of ok for the switch from 1h data points data to 15min data points (4x size). But when solar prognosis data is now available for +4 days, this approach is still failing.

So in this new release I have implemented a different approach to reduce the size of data of the range & timeseries data lists.

Instead of storing for each value the time, I will now store the start time of the first value and then only store the time delta in minutes between the points. So far this time delta is always 15min in my case - but it might happen in the future that this will change - so I want to keep the delta's in a second list.

So a evcc object like this:

{ "range": [
{"start":"2025-12-06T00:00:00+01:00","end":"2025-12-06T00:15:00+01:00","value":0},
{"start":"2025-12-06T00:15:00+01:00","end":"2025-12-06T00:30:00+01:00","value":1},
{"start":"2025-12-06T00:30:00+01:00","end":"2025-12-06T00:45:00+01:00","value":2},
{"start":"2025-12-06T00:45:00+01:00","end":"2025-12-06T01:00:00+01:00","value":3},
{"start":"2025-12-06T01:00:00+01:00","end":"2025-12-06T01:15:00+01:00","value":4}
]}

Will be converted to a structure in a home assistant attribute like this:

{"range": {
"start_utc": "2025-12-05T23:00:00+00:00"
"deltas_in_minutes": [15, 15, 15, 15]
"values": [0, 1, 2, 3, 4]
}}

I hope you see, the benefit size wise in this new structure.

Home assistant template examples working with the new structure

Getting the origin format / JSON [updated]
{%set json_data=state_attr('sensor.evcc_forecast_grid', 'rates')%}
{% set start_time = as_local(as_datetime(json_data['start_utc'])) %}
{% set deltas = json_data['deltas_in_minutes'] %}
{% set values = json_data['values'] %}
{% set ns = namespace(result=[]) %}
{% for i in range(values |length) %}
  {% set current_start = (start_time + timedelta(minutes=(deltas[:i]|sum))) %}
  {% set current_end = (current_start + timedelta(minutes=deltas[(i, deltas|length-1)|min])) %}
  {% set grid_entry = {
    'start': current_start.isoformat(),
    'end': current_end.isoformat(),
    'value': values[i]
  } %}
  {% set ns.result = ns.result + [grid_entry] %}
{% endfor %}
{{ ns.result }}
Getting current (now) value
{%set json_data=state_attr('sensor.evcc_forecast_grid', 'rates')%}
{% set total_minutes_since_start = (( now() - strptime(json_data['start_utc'], '%Y-%m-%dT%H:%M:%S%z')).total_seconds() // 60)|int %}
{% set tmp = namespace(total=0, index=0) %}
{% for delta in json_data['deltas_in_minutes'] %}
    {% if tmp.total < total_minutes_since_start %}
        {% set tmp.total = tmp.total + delta %}
        {% set tmp.index = tmp.index + 1 %}
    {% else %}
        {% break %}
    {% endif %}
{% endfor %}
{{json_data['values'][tmp.index]}}
Getting average value from series
{%set json_data=state_attr('sensor.evcc_forecast_solar', 'timeseries')%}
{{json_data['values']|sum / json_data['values']|length}}
Getting average value from (now)
{%set json_data=state_attr('sensor.evcc_forecast_solar', 'timeseries')%}
{% set total_minutes_since_start = (( now() - strptime(json_data['start_utc'], '%Y-%m-%dT%H:%M:%S%z')).total_seconds() // 60)|int %}
{% set tmp = namespace(total=0, index=0) %}
{% for delta in json_data['deltas_in_minutes'] %}
    {% if tmp.total < total_minutes_since_start %}
        {% set tmp.total = tmp.total + delta %}
        {% set tmp.index = tmp.index + 1 %}
    {% else %}
        {% break %}
    {% endif %}
{% endfor %}
{% set relevant_values = json_data['values'][tmp.index:] %}
{% set average_value = (relevant_values|sum) / relevant_values|length if relevant_values|length > 0 else 0 %}
{{ average_value }}

Rephrased Initial setup dialog

Thanks @olli-dot-dev to remind me in his YT Channel, that it might had been the time to rephrase my rant (after a year).

Please consider to support me

Thanks for the people who already did - that's highly appreciated! In the past weeks I had to invest plenty of my time in order to keep the Integration up to date with the latest changes as well as supporting the evcc development directly. And there might be just more that will come around the corner...

PayPal BuyMeCoffee GitHubSponsor Github Stars
If you haven't starred this integration in Github yet - please do so - TIA

Don't miss a new ha-evcc release

NewReleases is sending notifications on new releases.