The default for the apexcharts curve option is smooth which draws a curve between the points. Not ideal when your last point was 12 hours ago. The other options are straight (direct line between points) or stepline (flat line until next point then straight up or down).
Only the last option will not introduce the issue but it’s not the best looking.
I think if the template sensor is forced to update every minute like I have done with now() in the template above it should fix the issue. As there will be a point every 60 seconds even when the value is stuck at 0 for the whole night. I’ll let you know if it works in 12 hours or so.
I will try the adding of a small random number if 0.
state: >
{% set force_update = now() %}
{% if state_attr('sensor.solcast_forecast_data', 'forecasts')[0].pv_estimate|default('variable is not defined')|round(2) == 0 %}
{{ range(-100,100)|random / 100000 }}
{% else %}
{{ state_attr('sensor.solcast_forecast_data', 'forecasts')[0].pv_estimate|default('variable is not defined')|round(2) }}
{% endif %}
The other issue is that the simple integrations for for the today and tomorrow energy forecast sensors are often very inaccurate. Like +/-200% inaccurate - even when my actual power follows the forecast power graph closely.
I can see what the template is trying to do, it’s a half hour power prediction, so divide the power by two and add it to the total energy. But when I do this manually using the forecast power data visible in the graph I get a much more accurate answer (±10%). As the power data seems correct I’m assuming it is the date range selection that is at fault. Not sure why you need to replace the TZ info and the predictions appear to be in UTC anyway ( period_end: '2021-09-09T23:30:00.0000000Z' ), and you seem to be comparing it to the local date.
state: >
{% set ns = namespace (fc_tommorrow = 0) %}
{% for forecast in state_attr('sensor.solcast_forecast_data', 'forecasts')|default('variable is not defined') %}
{% set daydiff = as_local(strptime(forecast.period_end, '%Y-%m-%dT%H:%M:%S.%f0Z').replace(tzinfo=utcnow().tzinfo)).date() - as_local(utcnow()).date() %}
{% if daydiff.days == 1 %}
{% set ns.fc_tommorrow = ns.fc_tommorrow + (forecast.pv_estimate/2)|float %}
{%- endif %}
{%- endfor %}
{{ ns.fc_tommorrow|round(2) }}
How did you get them to stack? I have your same original problem where the forecast graphs for the three pv_estimates show, but only one historical (not the 10 or 90).
type: custom:apexcharts-card
graph_span: 36h
span:
start: day
offset: '-6h'
header:
show: true
title: Solar Production vs. forecast
show_states: true
now:
show: true
label: now
apex_config:
legend:
show: false
series:
- entity: sensor.goodwe_ppv
stroke_width: 2
show:
extremas: false
color: '#FFF700'
name: Actual
unit: W
fill_raw: last
extend_to_end: false
group_by:
func: avg
duration: 30min
- entity: sensor.solcast_forecast_data
stroke_width: 2
show:
extremas: false
color: '#3498DB'
transform: return x * 1000;
name: Forecast
unit: W
fill_raw: last
extend_to_end: false
- entity: sensor.solcast_forecast_10
stroke_width: 2
show:
extremas: false
in_header: false
color: '#797D7F'
transform: return x * 1000;
name: Forecast 10
unit: W
fill_raw: last
extend_to_end: false
opacity: 0.4
- entity: sensor.solcast_forecast_90
stroke_width: 2
show:
extremas: false
in_header: false
color: '#797D7F'
transform: return x * 1000;
name: Forecast 90
unit: W
fill_raw: last
extend_to_end: false
opacity: 0.4
- entity: sensor.solcast_forecast_data
stroke_width: 2
show:
extremas: false
in_header: false
color: '#E74C3C'
type: line
extend_to_end: false
unit: W
data_generator: |
return entity.attributes.forecasts.map((entry) => {
return [new Date(entry.period_end), entry.pv_estimate*1000];
});
- entity: sensor.solcast_forecast_data
stroke_width: 2
show:
extremas: false
in_header: false
color: '#797D7F'
type: line
extend_to_end: false
unit: W
opacity: 0.4
data_generator: |
return entity.attributes.forecasts.map((entry) => {
return [new Date(entry.period_end), entry.pv_estimate10*1000];
});
- entity: sensor.solcast_forecast_data
stroke_width: 2
show:
extremas: false
in_header: false
color: '#797D7F'
type: line
extend_to_end: false
unit: W
opacity: 0.4
data_generator: |
return entity.attributes.forecasts.map((entry) => {
return [new Date(entry.period_end), entry.pv_estimate90*1000];
});
Just use the additional 10/90 sensors for historic data and then I guess you already have the additional data_generator sensors to get them for forecast.
I’ve added your sensor code, and most things look great. Thank you! Unless I’m missing something, though, there does seem to be one anomaly - the forecast power for the next 24 hours. I’ve attached a screenshot. This was taken at around 18.25 local time. Figures look very sane, except that the figure for the next 24 hours seems to be just double that for tomorrow. There could well be something I’m not understanding here though, because one measurement is energy, and the other power.
@safepay wondering whether you’ve looked into it. Seems to do most of what is implemented in this thread, with the exception of 10/90% probabilities, with the added advantage that it integrates with the Energy component, so the forecast shows on Energy’s solar graph.