Hi folks,
I’m new to templating (and coding in general), so there is likely an easy way to do what I am tryting to acheive. But Googling and searching hasn’t yielded an answer (or, not one that my baby-coding-brain recognised was applicable).
TL:DR question:
How can I create a template sensor that outputs a list of values, that is the sum of values of list items from 2 separate template sensors, if the corresponding value in another attribute list for each template sensor matches (e.g. the first value of template 1
attribute 1
and template 2
attribute 1
match, so give me a list entry in the new template sensor that is template 1
attribute 2
+ template 2
attribute 2
)
- Maybe think of it ike an Excel vlookup using the value of
attribute 1
as the “key”, and summing the corresponding values?
Longer version of intention, context, and background:
- Overall intention: To create merged solar power forecast data to use in Home Assistant automations and as inputs into other template sensors
- Specific intention now: I want to create a template sensor with 2 attributes:
period_end_combined
andpv_estimate_combined
. - This template sensor will pull data from 2 existing (and working!) template sensors
- The
unique_id
s of these 2 existing template sensors aresolcast_forecast_data_se
andsolcast_forecast_ data_nw
(which report transformed API data for predicted solar power for a split array - one facing south-east, the other north-west) - These template sensors each contain 2 attributes:
period_end
andpv_estimate
- Each of these attributes contains a list of values. These values are “matched” between the lists, in that they were parsed from returned objects of an API request. I doubt that they are actually “linked” in any way, but the values in the first row of the list go together, as do the second row, third, etc.
- The
- There is an equal count of values for each of the two attributes within the same template sensor, but a different count of values in attributes between the 2 template sensors, for reasons.
- There may also be an overlap, but not an identical replication, of the
period_end
list values stored in each of the parent templates’ attribute, for other reasons. This is why I want to “match” on those values. - The new template sensor should have 2 attributes:
period_end_combined
andpv_estimate_combined
period_end_combined
will be a list of theperiod_end
values when they appeared in both of the attribute listed values of the parent template sensors (solcast_forecast_data_se
andsolcast_forecast_data_nw
) - basically, used as a “key” to match.pv_estimate_combined
will be the sum of the “corresponding” values in each of the parent template sensors’pv_estimate
attribute value list
Help?
I am also very happy to hear other approaches to the whole problem. However, the next step is to output the 2 lists (each _combined
attribute) in a CSV, so an array won’t work as the output. But maybe as part of the processing?
YAML code:
Final template sensor summing the listed values in attributes of 2 parent templates where their corresponding value in another attribute matches between the two parents:
…no idea. I assume it will include something about for i in range
, maybe match
, some map(stateattr() )
, but I honestly have no idea. I’m too baby.
“Parent” template sensors:
- platform: template
sensors:
# South-East template sensor
solcast_24hrs_forecast_se:
unique_id: "solcast_24hrs_forecast_se"
value_template: "OK"
attribute_templates:
pv_estimate: >-
{%- set pv_estimate = state_attr('sensor.solcast_forecast_data_se', 'forecasts') | map(attribute='pv_estimate') | list %}
{%- set values_all = namespace(all=[]) %}
{% for i in range(pv_estimate | length) %}
{%- set v = (pv_estimate[i] | float |multiply(1000) ) | int(0) %}
{%- set values_all.all = values_all.all + [ v ] %}
{%- endfor %} {{ (values_all.all) }}
period_end: >-
{{ (state_attr('sensor.solcast_forecast_data_se', 'forecasts') | map(attribute='period_end') | list) }}
# North-West template sensor
solcast_24hrs_forecast_nw:
unique_id: "solcast_24hrs_forecast_nw"
value_template: "OK"
attribute_templates:
pv_estimate: >-
{%- set pv_estimate = state_attr('sensor.solcast_forecast_data_nw', 'forecasts') | map(attribute='pv_estimate') | list %}
{%- set values_all = namespace(all=[]) %}
{% for i in range(pv_estimate | length) %}
{%- set v = (pv_estimate[i] | float |multiply(1000) ) | int(0) %}
{%- set values_all.all = values_all.all + [ v ] %}
{%- endfor %} {{ (values_all.all) }}
period_end: >-
{{ (state_attr('sensor.solcast_forecast_data_nw', 'forecasts') | map(attribute='period_end') | list) }}
Output of parent template sensors, taken from Developer Tools → States [Attributes] (same format for each, trimmed):
pv_estimate: 56, 65, 66, 69, 524, 1195, 1839, 2429, 3003, 3484, 3890, 4244, 4507, 4681, 4826, 4855, 4835, 4765, 4580, 4337, 4037, 3627, 3154, 2588, 1925, 1175, 132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22
period_end: 2025-01-30T21:00:00.0000000Z, 2025-01-30T21:30:00.0000000Z, 2025-01-30T22:00:00.0000000Z, 2025-01-30T22:30:00.0000000Z, 2025-01-30T23:00:00.0000000Z, 2025-01-30T23:30:00.0000000Z, 2025-01-31T00:00:00.0000000Z, 2025-01-31T00:30:00.0000000Z, 2025-01-31T01:00:00.0000000Z, 2025-01-31T01:30:00.0000000Z, 2025-01-31T02:00:00.0000000Z, 2025-01-31T02:30:00.0000000Z, 2025-01-31T03:00:00.0000000Z, 2025-01-31T03:30:00.0000000Z, 2025-01-31T04:00:00.0000000Z, 2025-01-31T04:30:00.0000000Z, 2025-01-31T05:00:00.0000000Z
...
Further background code, if it helps at all…
One of the 2 Rest sensors that get the data that the “parent” template sensors process:
sensor:
# South-East REST sensor:
- platform: rest
name: Solcast forecast data SE
unique_id: "solcast_forecast_data_se"
resource: https://api.solcast.com.au/rooftop_sites/RooftopIDNotTelling/forecasts?format=json
headers:
Authorization: Bearer NotTelling
method: GET
device_class: power
force_update: true
json_attributes:
- forecasts
value_template: "OK"
unit_of_measurement: "kW"
scan_interval: 86400000 # This is a huge number on purpose
Returned JSON for REST sensor (sample):
{
"forecasts": [
{
"pv_estimate": 3.31,
"pv_estimate10": 3.0949,
"pv_estimate90": 3.31,
"period_end": "2025-01-26T00:30:00.0000000Z",
"period": "PT30M"
},
{
"pv_estimate": 3.3267,
"pv_estimate10": 3.0437,
"pv_estimate90": 3.3267,
"period_end": "2025-01-26T01:00:00.0000000Z",
"period": "PT30M"
},
{
"pv_estimate": 3.0302,
"pv_estimate10": 2.379,
"pv_estimate90": 3.3311,
"period_end": "2025-01-26T01:30:00.0000000Z",
"period": "PT30M"
},
]
}