I have this defined in a sensors.yaml file and in configuration.yaml a line
sensor: !include sensors.yaml
I have this defined in a sensors.yaml file and in configuration.yaml a line
sensor: !include sensors.yaml
and then the sensor shows under “Helpers” in the UI?
I think (s)he means the data type is different between yours and the original sensor (indicated by the dashes)
Yes, but that does not matter. You can even make it output similar to the solcast sensor by modifying {% set output_item = {time:sum_value} %}
to {% set output_item = {'period_start': time, 'pv_wh_estimate':sum_value} %}
i.e.
- period_start: '2024-06-10T07:00:00+02:00'
pv_wh_estimate: 770.25
- period_start: '2024-06-10T08:00:00+02:00'
pv_wh_estimate: 1860.5
- period_start: '2024-06-10T09:00:00+02:00'
pv_wh_estimate: 3024.25
- period_start: '2024-06-10T10:00:00+02:00'
pv_wh_estimate: 4023.75
Your one is a list and the other is dictanory.
I have no idea with this grab of jinja2 dsl how to cast or create a dic instead of a list
I don’t have multiple PV arrays so I can’t test but does something like this work? I’m a beginner at Jinja/templating (obviously adapt for wh_period, etc; this is an example for watts):
{% set sensor1 = state_attr('sensor.energy_production_today_2', 'watts') %}
{% set sensor2 = state_attr('sensor.energy_production_today_3', 'watts') %}
{% set ns = namespace(output={}) %}
{% for time, value in sensor1.items() %}
{% set ns.output = dict({time: value}, **ns.output) %}
{% endfor %}
{% for time, value in sensor2.items() %}
{% if time in ns.output %}
{% set ns.output = dict({time: ns.output[time] + value}, **ns.output) %}
{% else %}
{% set ns.output = dict({time: value}, **ns.output) %}
{% endif %}
{% endfor %}
{{ ns.output }}
Edit: Jinja is really ugly and I hate it.
Yes that works
- platform: template
sensors:
energy_production_today_sum:
friendly_name: "Energy Production Today Sum"
unit_of_measurement: "kWh"
device_class: energy
value_template: >-
{% set sensor1 = states('sensor.energy_production_today_2') |float %}
{% set sensor2 = states('sensor.energy_production_today_3') |float %}
{% set total_watts = sensor1 + sensor2 %}
{{ total_watts }}
attribute_templates:
watts: >-
{% set sensor1 = state_attr('sensor.energy_production_today_2', 'watts') %}
{% set sensor2 = state_attr('sensor.energy_production_today_3', 'watts') %}
{% set ns = namespace(output={}) %}
{% for time, value in sensor1.items() %}
{% set ns.output = dict({time: value}, **ns.output) %}
{% endfor %}
{% for time, value in sensor2.items() %}
{% if time in ns.output %}
{% set ns.output = dict({time: ns.output[time] + value}, **ns.output) %}
{% else %}
{% set ns.output = dict({time: value}, **ns.output) %}
{% endif %}
{% endfor %}
{{ ns.output }}
wh_period: >-
{% set sensor1 = state_attr('sensor.energy_production_today_2', 'wh_period') %}
{% set sensor2 = state_attr('sensor.energy_production_today_3', 'wh_period') %}
{% set ns = namespace(output={}) %}
{% for time, value in sensor1.items() %}
{% set ns.output = dict({time: value}, **ns.output) %}
{% endfor %}
{% for time, value in sensor2.items() %}
{% if time in ns.output %}
{% set ns.output = dict({time: ns.output[time] + value}, **ns.output) %}
{% else %}
{% set ns.output = dict({time: value}, **ns.output) %}
{% endif %}
{% endfor %}
{{ ns.output }}
This is a poll for how to handle the multiple PV array case:
configuration.yaml
Context, the support is already implemented in Implement support for multiple PV arrays by rany2 · Pull Request #8 · rany2/open-meteo-solar-forecast · GitHub but needs changes on the HA side.
@rany and @slipx06
Did not work for me. This looks to work for me:
sensor:
- name: "energy_production_today_all"
state: >
{{ (states('sensor.energy_production_today') | float(default=0) + states('sensor.energy_production_today_2') | float(default=0)) | round(2) }}
unit_of_measurement: "kWh"
device_class: energy
attributes:
watts: >-
{% set sensor1 = state_attr('sensor.energy_production_today', 'watts') %}
{% set sensor2 = state_attr('sensor.energy_production_today_2', 'watts') %}
{% set ns = namespace(output={}) %}
{% for time, value in sensor1.items() %}
{% set sum_value = value + sensor2[time] %}
{% set ns.output = dict({time: sum_value}, **ns.output) %}
{% endfor %}
{{ ns.output }}
wh_period: >-
{% set sensor1 = state_attr('sensor.energy_production_today', 'wh_period') %}
{% set sensor2 = state_attr('sensor.energy_production_today_2', 'wh_period') %}
{% set ns = namespace(output={}) %}
{% for time, value in sensor1.items() %}
{% set sum_value = value + sensor2[time] %}
{% set ns.output = dict({time: sum_value}, **ns.output) %}
{% endfor %}
{{ ns.output }}
Thanks for the hints
For the new peaktime I did also something ugly but work so far:
- name: "power_highest_peak_time_today_all"
state: >
{%set watts=states.sensor.energy_production_today_all.attributes['watts']%}
{%set highestWatt=namespace(value=0) %}
{%set endDate=namespace(value=0) %}
{%for date in watts %}
{%set watt = watts[date]%}
{%if watt>highestWatt.value%}
{%set highestWatt.value = watt%}
{%set endDate.value = date%}
{% endif %}
{% endfor %}
{{endDate.value}}
device_class: timestamp
@rany so iam happy with configuration.yaml it works
Maybe anybody have an idea why the overall kwh in the apex chart is not working
Just keep in mind that sensor2[time]
might not exist in some rare cases so you should make it default to 0 somehow.
This error originated from a custom integration.
Logger: custom_components.open_meteo_solar_forecast
Source: helpers/update_coordinator.py:312
integration: Open-Meteo Solar Forecast (documentation, issues)
First occurred: June 10, 2024 at 20:01:00 (1138 occurrences)
Last logged: 02:00:00
Unexpected error fetching open_meteo_solar_forecast data
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 312, in _async_refresh
self.data = await self._async_update_data()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/open_meteo_solar_forecast/coordinator.py", line 63, in _async_update_data
return await self.forecast.estimate()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/open_meteo_solar_forecast/open_meteo_solar_forecast.py", line 155, in estimate
data = await self._request(
^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/open_meteo_solar_forecast/open_meteo_solar_forecast.py", line 122, in _request
raise OpenMeteoSolarForecastRatelimitError("Rate limit exceeded")
open_meteo_solar_forecast.exceptions.OpenMeteoSolarForecastRatelimitError: Rate limit exceeded
1138 occurrences, it means there are 1138 api calls in 6 hours?
No it just retries until the rate limit is lifted, after it succeeds it polls the API every 30mins. I could make my personal Open-Meteo instance available to others for use if needed.
It’s caused by your IP being shared with others, Open-Meteo is popular outside of HA (apps like Breezy Weather use it) so you probably have a neighbor that’s into FOSS services.
ok good to know then i have to look how make a default value or is this possible to handle in the library?
What does it mean that my IP is being shared with others? Could it be because I am using cloudflared for remote access to home assistant? I would be glad if you could help me find a solution for this issue.
It’s really unrelated to this integration but I’ll explain in simple terms. Basically because there are only ~4B public IPv4 addresses available (and >8B people, servers, devices, etc) ISPs are forced to basically use something like NAT44 so that all their users could access the IPv4 internet. One of the many issues with technologies like NAT44 is that it means that a large chunk of the ISP’s users (sometimes even an entire city) would share the same IPv4 address. That is why your Open-Meteo quota is exhausted so quickly, there are other people also using Open-Meteo with the same public IPv4 address.
I’ve opened a discussion on GitHub to ask if API keys could be made available for free users, this way the quota is per-API key not IP address: API keys for the free Open-Meteo API · open-meteo/open-meteo · Discussion #843 · GitHub. If it doesn’t work (I’m 99% sure it’ll be rejected) I could just make my own personal instance available, I feel like I would probably be able to cope with the load.
Thank you for your explanation. I thought there could only be one public ip-address at the same time. I think there is no way for me to solve this problem, is it? It would be great if you could offer a solution. I tink 10 daily calls per instance (I have got four) should be enough at it was with solcast either.
I tried to use 4 Sensors to sum up but I get the following errors, perhaps you can help me out:
TemplateError('TypeError: unsupported operand type(s) for +: 'int' and 'dict'') while processing template 'Template<template=({% set sensor1 = state_attr('sensor.energy_production_today_8', 'watts') %} {% set sensor2 = state_attr('sensor.energy_production_today_9', 'watts') %} {% set sensor3 = state_attr('sensor.energy_production_today_10', 'watts') %} {% set sensor4 = state_attr('sensor.energy_production_today_11', 'watts') %} {% set ns = namespace(output={}) %} {% for time, value in sensor1.items() %} {% set sum_value = value + sensor2 + sensor3 + sensor4[time] %} {% set ns.output = dict({time: sum_value}, **ns.output) %} {% endfor %} {{ ns.output }}) renders=4>' for attribute 'watts' in entity 'sensor.energy_production_today_all'
TemplateError('TypeError: unsupported operand type(s) for +: 'float' and 'dict'') while processing template 'Template<template=({% set sensor1 = state_attr('sensor.energy_production_today_8', 'wh_period') %} {% set sensor2 = state_attr('sensor.energy_production_today_9', 'wh_period') %} {% set sensor3 = state_attr('sensor.energy_production_today_10', 'wh_period') %} {% set sensor4 = state_attr('sensor.energy_production_today_11', 'wh_period') %} {% set ns = namespace(output={}) %} {% for time, value in sensor1.items() %} {% set sum_value = value + sensor2 + sensor3 + sensor4[time] %} {% set ns.output = dict({time: sum_value}, **ns.output) %} {% endfor %} {{ ns.output }}) renders=4>' for attribute 'wh_period' in entity 'sensor.energy_production_today_all'
Maybe if you send the yaml code:
I see sensor 3 in the error code, but I see in my post no sensor3 here:
So if you have 4 sensor you have todo more sums
Apex Charts are nice, plotly graphs are better
You’ll need to create some template sensors so its not a straight drop in.
type: custom:plotly-graph
hours_to_show: 4d
time_offset: 2.5d
refresh_interval: auto
entities:
- entity: sensor.sunsynk_solar_power
name: Solar Power
line:
color: rgb(255, 155, 48)
shape: spline
width: 1
fill: tozeroy
fillcolor: rgba(255, 155, 48, 0.3)
yaxis: y3
show_value: false
showlegend: false
- entity: sensor.energy_production_today_sum
line:
color: rgb(125, 125, 125)
shape: spline
fill: tozeroy
filters:
- fn: |
({meta}) => ({
xs: meta.wh_period.map(({ start }) => new Date(start)),
ys: meta.wh_period.map(({ value }) => value),
})
yaxis: y1
showlegend: true
- entity: sensor.energy_production_tomorrow_sum
line:
color: rgb(90,90,90)
shape: spline
fill: tozeroy
filters:
- fn: |
({meta}) => ({
xs: meta.wh_period.map(({ start }) => new Date(start)),
ys: meta.wh_period.map(({ value }) => value),
})
yaxis: y1
- entity: sensor.energy_production_d2_sum
line:
color: rgb(50,50,50)
shape: spline
fill: tozeroy
filters:
- fn: |
({meta}) => ({
xs: meta.wh_period.map(({ start }) => new Date(start)),
ys: meta.wh_period.map(({ value }) => value),
})
yaxis: y1
showlegend: true
- entity: sensor.sunsynk_battery_soc
name: Battery
line:
color: red
shape: spline
width: 1
yaxis: y2
show_value: true
showlegend: false
visible: true
- entity: ''
name: Now
yaxis: y9
showlegend: false
line:
width: 2
dash: dot
color: aqua
x: $ex [Date.now(), Date.now()]
'y':
- 0
- 1
layout:
height: 400
margin:
t: 55
l: 50
showlegend: false
legend:
x: 0.1
'y': -0.8
yaxis2:
range:
- 20
- 105
fixedrange: true
annotations:
- text: |-
$fn ({hass}) =>
"<span style='font-size: 24px;'><span style='color: orange'>"
+ Number(hass.states['sensor.energy_production_tomorrow_sum'].state).toFixed(1) + "</span></span>kWh<br>"
+ "</span><span style=''>Forecast Today</span><br>"
xref: x domain
yref: y domain
xanchor: center
yanchor: center
x: 0.06
'y': 1.2
showarrow: false
- text: |-
$fn ({hass}) =>
"<span style='font-size: 24px;'><span style='color: dodgerblue'>"
+ Number(hass.states['sensor.meteo_energy_production_today_remaining'].state).toFixed(1) + "</span></span>kWh<br>"
+ "</span><span style=''>Remaining</span><br>"
xref: x domain
yref: y domain
xanchor: center
yanchor: center
x: 0.28
'y': 1.2
showarrow: false
- text: |-
$fn ({hass}) =>
"<span style='font-size: 24px;'><span style='color: '>"
+ Number(hass.states['sensor.energy_production_tomorrow_sum'].state).toFixed(1) + "</span></span>kWh<br>"
+ "</span><span style=''>Forecast Tomorrow</span><br>"
xref: x domain
yref: y domain
xanchor: center
yanchor: center
x: 0.5
'y': 1.2
showarrow: false
- text: |-
$fn ({hass}) =>
"<span style='font-size: 24px;'><span style='color: white'>"
+ Number(hass.states['sensor.energy_production_d2_sum'].state).toFixed(1) + "</span></span>kWh<br>"
+ "</span><span style=''>Forecast Day 2</span><br>"
xref: x domain
yref: y domain
xanchor: center
yanchor: center
x: 0.72
'y': 1.2
showarrow: false
- text: |-
$fn ({hass}) =>
"<span style='font-size: 24px;'><span style='color: red'>"
+ Number(hass.states['sensor.sunsynk_battery_soc'].state) + "</span></span>%<br>"
+ "</span><span style=''>SOC</span><br>"
xref: x domain
yref: y domain
xanchor: center
yanchor: center
x: 0.94
'y': 1.2
showarrow: false
config:
scrollZoom: false
If you are using the sensors provided by the integration you can replace the filters that generates the data i.e:
Replace
filters:
- fn: |
({meta}) => ({
xs: meta.wh_period.map(({ start }) => new Date(start)),
ys: meta.wh_period.map(({ value }) => value),
})
with
filters:
- fn: |
({meta}) => {
const entries = Object.entries(meta.wh_period);
const xs = entries.map(([start, _]) => new Date(start));
const ys = entries.map(([_, value]) => value);
return { xs, ys };
}
Here is my code for today and tomorrow for 4 sensors but something is wrong.
- sensor:
- name: "energy_production_today_all"
state: >
{{ (states('sensor.energy_production_today_8') | float(default=0) + states('sensor.energy_production_today_9') | float(default=0) + states('sensor.energy_production_today_10') | float(default=0) + states('sensor.energy_production_today_11') | float(default=0)) | round(2) }}
unit_of_measurement: "kWh"
device_class: energy
attributes:
watts: >-
{% set sensor1 = state_attr('sensor.energy_production_today_8', 'watts') %}
{% set sensor2 = state_attr('sensor.energy_production_today_9', 'watts') %}
{% set sensor3 = state_attr('sensor.energy_production_today_10', 'watts') %}
{% set sensor4 = state_attr('sensor.energy_production_today_11', 'watts') %}
{% set ns = namespace(output={}) %}
{% for time, value in sensor1.items() %}
{% set sum_value = value + sensor2 + sensor3 + sensor4[time] %}
{% set ns.output = dict({time: sum_value}, **ns.output) %}
{% endfor %}
{{ ns.output }}
wh_period: >-
{% set sensor1 = state_attr('sensor.energy_production_today_8', 'wh_period') %}
{% set sensor2 = state_attr('sensor.energy_production_today_9', 'wh_period') %}
{% set sensor3 = state_attr('sensor.energy_production_today_10', 'wh_period') %}
{% set sensor4 = state_attr('sensor.energy_production_today_11', 'wh_period') %}
{% set ns = namespace(output={}) %}
{% for time, value in sensor1.items() %}
{% set sum_value = value + sensor2 + sensor3 + sensor4[time] %}
{% set ns.output = dict({time: sum_value}, **ns.output) %}
{% endfor %}
{{ ns.output }}
- sensor:
- name: "energy_production_tomorrow_all"
state: >
{{ (states('sensor.energy_production_tomorrow_8') | float(default=0) + states('sensor.energy_production_tomorrow_9') | float(default=0) + states('sensor.energy_production_tomorrow_10') | float(default=0) + states('sensor.energy_production_tomorrow_11') | float(default=0)) | round(2) }}
unit_of_measurement: "kWh"
device_class: energy
attributes:
watts: >-
{% set sensor1 = state_attr('sensor.energy_production_tomorrow_8', 'watts') %}
{% set sensor2 = state_attr('sensor.energy_production_tomorrow_9', 'watts') %}
{% set sensor3 = state_attr('sensor.energy_production_tomorrow_10', 'watts') %}
{% set sensor4 = state_attr('sensor.energy_production_tomorrow_11', 'watts') %}
{% set ns = namespace(output={}) %}
{% for time, value in sensor1.items() %}
{% set sum_value = value + sensor2 + sensor3 + sensor4[time] %}
{% set ns.output = dict({time: sum_value}, **ns.output) %}
{% endfor %}
{{ ns.output }}
wh_period: >-
{% set sensor1 = state_attr('sensor.energy_production_tomorrow_8', 'wh_period') %}
{% set sensor2 = state_attr('sensor.energy_production_tomorrow_9', 'wh_period') %}
{% set sensor3 = state_attr('sensor.energy_production_tomorrow_10', 'wh_period') %}
{% set sensor4 = state_attr('sensor.energy_production_tomorrow_11', 'wh_period') %}
{% set ns = namespace(output={}) %}
{% for time, value in sensor1.items() %}
{% set sum_value = value + sensor2 + sensor3 + sensor4[time] %}
{% set ns.output = dict({time: sum_value}, **ns.output) %}
{% endfor %}
{{ ns.output }}