type: sections
max_columns: 4
title: Test
path: test
subview: false
icon: mdi:test-tube
sections:
- type: grid
cards:
- type: horizontal-stack
cards:
- type: custom:button-card
icon: mdi:chevron-left
name: Zurück
styles:
card:
- background: "linear-gradient(180deg, #FFFFFF, #A7D8F1);"
- border-radius: 14px
- padding: 12px
- box-shadow: 0 4px 10px rgba(0,0,0,0.2)
- height: 70px
- width: 140px
tap_action:
action: call-service
service: input_number.increment
service_data:
entity_id: input_number.sfml_day_offset
- type: custom:button-card
entity: sensor.sfml_display_date
show_icon: false
show_name: true
name: "[[[ return states['sensor.sfml_display_date'].state; ]]]"
styles:
card:
- background: "linear-gradient(180deg, #FFFFFF, #A7D8F1);"
- border-radius: 14px
- padding: 12px
- box-shadow: 0 4px 10px rgba(0,0,0,0.2)
- height: 70px
- width: 140px
name:
- font-size: 16px
- font-weight: bold
tap_action:
action: call-service
service: input_number.set_value
service_data:
entity_id: input_number.sfml_day_offset
value: 0
- type: custom:button-card
icon: mdi:chevron-right
name: Vorwärts
styles:
card:
- background: "linear-gradient(180deg, #FFFFFF, #A7D8F1);"
- border-radius: 14px
- padding: 12px
- box-shadow: 0 4px 10px rgba(0,0,0,0.2)
- height: 70px
- width: 140px
tap_action:
action: call-service
service: input_number.decrement
service_data:
entity_id: input_number.sfml_day_offset
- type: vertical-stack
cards:
- type: vertical-stack
cards:
- type: conditional
conditions:
- condition: numeric_state
entity: input_number.sfml_day_offset
below: 1
card:
type: custom:config-template-card
entities:
- sensor.sfml_stats_gesamt
- sensor.pv_ertrag_pro_tag_insgesamt
- input_number.sfml_day_offset
card:
type: custom:apexcharts-card
header:
title: PV-Prognose und Ertrag
show: true
standard_format: true
show_states: true
colorize_states: true
apex_config:
chart:
type: line
height: 1
sparkline:
enabled: true
yaxis:
- show: false
xaxis:
show: false
legend:
show: false
series:
- entity: sensor.pv_ertrag_pro_tag_insgesamt
name: Ertrag
color: orange
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), parseFloat(entity.state)]];
- entity: sensor.sfml_stats_gesamt
name: Prognose heute
color: grey
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: >
return [[new Date(),
parseFloat(entity.attributes.prediction_total)]];
- entity: sensor.sfml_stats_gesamt
name: Genauigkeit
color: green
float_precision: 0
unit: " %"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: >
return [[new Date(),
parseFloat(entity.attributes.accuracy)]];
card_mod:
style: |
ha-card {
background: transparent !important;
box-shadow: none !important;
border: none !important;
padding: 2px 8px;
font-size: 14px;
border-radius: 12px;
}
- type: conditional
conditions:
- condition: numeric_state
entity: input_number.sfml_day_offset
above: 0
card:
type: custom:config-template-card
entities:
- sensor.sfml_stats_gesamt_history
- input_number.sfml_day_offset
card:
type: custom:apexcharts-card
header:
title: PV-Prognose und Ertrag
show: true
standard_format: true
show_states: true
colorize_states: true
apex_config:
chart:
type: line
height: 1
sparkline:
enabled: true
yaxis:
- show: false
xaxis:
show: false
legend:
show: false
series:
- entity: sensor.sfml_stats_gesamt_history
name: Ertrag
color: orange
yaxis_id: header_only
show:
legend_value: true
in_header: true
in_chart: false
data_generator: >
const offset =
parseInt(hass.states['input_number.sfml_day_offset'].state
|| '0'); const sel = new Date();
sel.setDate(sel.getDate() - offset); const pad = n =>
String(n).padStart(2,'0'); const dk =
sel.getFullYear() + '-' + pad(sel.getMonth()+1) + '-'
+ pad(sel.getDate()); const hist =
entity.attributes.history_data ?
JSON.parse(entity.attributes.history_data) : {}; let
day = hist[dk]; if (!day) return [[new Date(),0]]; day
= typeof day === 'string' ? JSON.parse(day) : day;
const total_actual = day.reduce((sum,e)=> sum +
(e.actual!==null?e.actual:0),0); return [[new Date(),
Math.round(total_actual*10)/10]];
- entity: sensor.sfml_stats_gesamt_history
name: Prognose
color: grey
yaxis_id: header_only
show:
legend_value: true
in_header: true
in_chart: false
data_generator: >
const offset =
parseInt(hass.states['input_number.sfml_day_offset'].state
|| '0'); const sel = new Date();
sel.setDate(sel.getDate() - offset); const pad = n =>
String(n).padStart(2,'0'); const dk =
sel.getFullYear() + '-' + pad(sel.getMonth()+1) + '-'
+ pad(sel.getDate()); const hist =
entity.attributes.history_data ?
JSON.parse(entity.attributes.history_data) : {}; let
day = hist[dk]; if (!day) return [[new Date(),0]]; day
= typeof day === 'string' ? JSON.parse(day) : day;
const total_pred = day.reduce((sum,e)=> sum +
(e.pred!==null?e.pred:0),0); return [[new Date(),
Math.round(total_pred*10)/10]];
- entity: sensor.sfml_stats_gesamt_history
name: Genauigkeit
color: green
unit: " %"
yaxis_id: header_only
show:
legend_value: true
in_header: true
in_chart: false
data_generator: >
const offset =
parseInt(hass.states['input_number.sfml_day_offset'].state
|| '0'); const sel = new Date();
sel.setDate(sel.getDate() - offset); const pad = n =>
String(n).padStart(2,'0'); const dk =
sel.getFullYear() + '-' + pad(sel.getMonth()+1) + '-'
+ pad(sel.getDate()); const hist =
entity.attributes.history_data ?
JSON.parse(entity.attributes.history_data) : {}; let
day = hist[dk]; if (!day) return [[new Date(),0]]; day
= typeof day === 'string' ? JSON.parse(day) : day;
const total_actual = day.reduce((sum,e)=> sum +
(e.actual!==null?e.actual:0),0); const total_pred =
day.reduce((sum,e)=> sum +
(e.pred!==null?e.pred:0),0); const accuracy =
total_actual ? Math.max(0, Math.min(100, Math.round((1
- Math.abs(total_actual -
total_pred)/total_actual)*100))) : 0; return [[new
Date(), accuracy]];
card_mod:
style: |
ha-card {
background: transparent !important;
box-shadow: none !important;
border: none !important;
padding: 2px 8px;
font-size: 14px;
border-radius: 12px;
}
grid_options:
columns: 48
rows: auto
- type: vertical-stack
cards:
- type: conditional
conditions:
- condition: numeric_state
entity: input_number.sfml_day_offset
below: 1
card:
type: custom:config-template-card
entities:
- sensor.sun_next_rising
- sensor.sun_next_setting
- sensor.none_beste_stunde
card:
type: custom:apexcharts-card
header:
title: " "
show: false
standard_format: true
show_states: true
colorize_states: true
graph_span: |-
${(() => {
const rise = new Date(states['sensor.sun_next_rising'].state);
const set = new Date(states['sensor.sun_next_setting'].state);
const now = new Date();
if (rise.getDate() !== now.getDate()) rise.setDate(rise.getDate() - 1);
if (set.getDate() !== now.getDate()) set.setDate(set.getDate() - 1);
// +2h vorne und +2h hinten = +240 Minuten
const diffMinutes = Math.round((set - rise) / 60000) + 240;
return diffMinutes + "m";
})()}
span:
start: day
offset: |-
${(() => {
const rise = new Date(states['sensor.sun_next_rising'].state);
const now = new Date();
if (rise.getDate() !== now.getDate()) rise.setDate(rise.getDate() - 1);
// 2h früher starten
const minutes = (rise.getHours() * 60 + rise.getMinutes()) - 120;
return "+" + minutes + "m";
})()}
now:
show: true
color: gold
apex_config:
markers:
size:
- 0
- 0
- 0
- 8
fill:
type: gradient
gradient:
shade: light
type: vertical
shadeIntensity: 0.2
opacityFrom: 1
opacityTo: 0.1
stops:
- 0
- 100
chart:
background: transparent
height: 250
zoom:
enabled: true
type: x
autoScaleYaxis: true
toolbar:
show: true
tools:
zoom: true
zoomin: true
zoomout: true
pan: true
reset: true
download: false
tooltip:
enabled: true
shared: false
intersect: false
followCursor: true
x:
show: true
fixed:
enabled: false
legend:
show: true
xaxis:
type: datetime
labels:
datetimeUTC: false
format: HH:mm
annotations:
xaxis:
- x: |-
${(() => {
const r = new Date(states['sensor.sun_next_rising'].state);
const n = new Date();
if (r.getDate() !== n.getDate()) r.setDate(r.getDate() - 1);
return r.getTime();
})()}
borderColor: gold
label:
text: ☀️ Aufgang
style:
color: black
background: gold
- x: |-
${(() => {
const s = new Date(states['sensor.sun_next_setting'].state);
const n = new Date();
if (s.getDate() !== n.getDate()) s.setDate(s.getDate() - 1);
return s.getTime();
})()}
borderColor: orange
label:
text: 🌙 Untergang
style:
color: black
background: orange
- x: |-
${(() => {
const best = states['sensor.none_beste_stunde'].state;
if (!best || best === 'unknown') return null;
const [hour, minute] = best.split(':').map(Number);
const d = new Date();
d.setHours(hour, minute || 0, 0, 0);
return d.getTime();
})()}
x2: |-
${(() => {
const best = states['sensor.none_beste_stunde'].state;
if (!best || best === 'unknown') return null;
const [hour, minute] = best.split(':').map(Number);
const d = new Date();
d.setHours(hour + 1, minute || 0, 0, 0);
return d.getTime();
})()}
fillColor: rgba(0, 255, 0, 0.2)
opacity: 1
label:
text: ⭐ Beste Stunde
style:
background: rgba(0, 255, 0, 0.4)
color: black
all_series_config:
type: area
opacity: 0.9
stroke_width: 2
yaxis:
- id: kW
show: true
min: 0
apex_config:
tickAmount: 5
title:
text: kWh
- id: accuracy_axis
show: false
min: 0
max: 100
- id: sun
opposite: true
apex_config:
title:
text: Sonnenstand
show: true
min: 0
max: 90
series:
- entity: sensor.gesamt_pv_leistung
name: Tatsächlich
float_precision: 3
color: orange
stroke_width: 2
opacity: 0.6
yaxis_id: kW
unit: kW
transform: return x/1000;
extend_to: now
show:
legend_value: false
in_header: false
group_by:
func: avg
duration: 5m
- entity: sensor.sfml_stats_gesamt
name: Prognose
color: grey
opacity: 0.3
stroke_width: 2
yaxis_id: kW
unit: " kWh"
extend_to: false
show:
legend_value: false
in_header: false
data_generator: |
var today = new Date();
var data = JSON.parse(entity.attributes.hourly_data);
return data.map((entry) => {
var date = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate(),
entry.hour,
30
);
return [date, entry.pred];
});
- entity: sensor.pv_ertrag_pro_tag_insgesamt
name: Ertrag
yaxis_id: accuracy_axis
color: orange
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), parseFloat(entity.state)]];
- entity: sensor.sfml_stats_gesamt
name: Prognose heute
yaxis_id: accuracy_axis
color: grey
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: >
return [[new Date(),
entity.attributes.prediction_total]];
- entity: sensor.sun_solar_elevation
name: Sonnenhöhe
type: line
color: gold
stroke_width: 2
yaxis_id: sun
extend_to: false
show:
legend_value: false
in_header: false
in_legend: true
group_by:
func: avg
duration: 10m
- entity: sensor.sun_solar_elevation
name: Sonnenpunkt
type: line
yaxis_id: sun
extend_to: false
color: gold
stroke_width: 0
show:
legend_value: false
in_header: false
in_legend: false
data_generator: |
return [[Date.now(), Number(entity.state)]];
card_mod:
style: |
ha-card {
background: transparent !important;
box-shadow: none !important;
border: none !important;
padding: 1px;
margin-top: -30px;
font-size: 11px;
border-radius: 12px;
margin-top: -10px;
}
- type: conditional
conditions:
- condition: numeric_state
entity: input_number.sfml_day_offset
above: 0
card:
type: custom:config-template-card
entities:
- sensor.sun_next_rising
- sensor.sun_next_setting
- input_number.sfml_day_offset
card:
type: custom:apexcharts-card
grid_options:
columns: full
header:
title: " "
show: false
standard_format: true
show_states: true
colorize_states: true
graph_span: |-
${(() => {
const rise = new Date(states['sensor.sun_next_rising'].state);
const set = new Date(states['sensor.sun_next_setting'].state);
const now = new Date();
if (rise.getDate() !== now.getDate()) rise.setDate(rise.getDate() - 1);
if (set.getDate() !== now.getDate()) set.setDate(set.getDate() - 1);
// Aufgang -2h bis Untergang +2h
const diffMinutes = Math.round((set - rise) / 60000) + 240;
return diffMinutes + "m";
})()}
span:
start: day
offset: |-
${(() => {
const rise = new Date(states['sensor.sun_next_rising'].state);
const now = new Date();
if (rise.getDate() !== now.getDate()) rise.setDate(rise.getDate() - 1);
// Start = Aufgang -2h
const minutes = (rise.getHours() * 60 + rise.getMinutes()) - 120;
return "+" + minutes + "m";
})()}
apex_config:
chart:
background: transparent
height: 250
zoom:
enabled: true
type: x
autoScaleYaxis: true
toolbar:
show: true
tools:
zoom: true
zoomin: true
zoomout: true
pan: true
reset: true
download: false
fill:
type: gradient
gradient:
shade: light
type: vertical
shadeIntensity: 0.2
opacityFrom: 1
opacityTo: 0.1
stops:
- 0
- 100
xaxis:
type: datetime
labels:
datetimeUTC: false
format: HH:mm
annotations:
xaxis:
- x: |-
${(() => {
const r = new Date(states['sensor.sun_next_rising'].state);
const n = new Date();
if (r.getDate() !== n.getDate()) r.setDate(r.getDate() - 1);
return r.getTime();
})()}
borderColor: gold
label:
text: ☀️ Aufgang
style:
color: black
background: gold
- x: |-
${(() => {
const s = new Date(states['sensor.sun_next_setting'].state);
const n = new Date();
if (s.getDate() !== n.getDate()) s.setDate(s.getDate() - 1);
return s.getTime();
})()}
borderColor: orange
label:
text: 🌙 Untergang
style:
color: black
background: orange
legend:
show: true
all_series_config:
type: area
opacity: 0.9
stroke_width: 2
yaxis:
- id: kW
show: true
min: 0
apex_config:
tickAmount: 5
title:
text: kWh (DC)
- id: header_only
show: false
series:
- entity: sensor.sfml_stats_gesamt_history
name: Tatsächlich
color: orange
stroke_width: 2
opacity: 0.6
yaxis_id: kW
unit: kW
extend_to: false
show:
legend_value: false
in_header: false
data_generator: >
var offset =
parseInt(hass.states['input_number.sfml_day_offset']?.state
|| '0'); var sel = new Date();
sel.setDate(sel.getDate() - offset); var pad = n =>
String(n).padStart(2,'0'); var dk = sel.getFullYear()
+ '-' + pad(sel.getMonth()+1) + '-' +
pad(sel.getDate()); var now = new Date(); var y =
now.getFullYear(), m = now.getMonth(), d =
now.getDate(); var hist = typeof
entity.attributes.history_data === 'string'
? JSON.parse(entity.attributes.history_data)
: entity.attributes.history_data;
var day = hist ? hist[dk] : null; if (!day) return
[[new Date(y,m,d,0,0),0],[new Date(y,m,d,23,59),0]];
day = typeof day === 'string' ? JSON.parse(day) : day;
var pts = [[new Date(y,m,d,0,0),0]];
day.forEach(function(e){
if (e.actual !== null && e.actual !== undefined)
pts.push([new Date(y,m,d,e.hour,30), e.actual]);
}); pts.push([new Date(y,m,d,23,59),0]); return pts;
- entity: sensor.sfml_stats_gesamt_history
name: Prognose
color: grey
opacity: 0.3
stroke_width: 2
yaxis_id: kW
unit: " kWh"
extend_to: false
show:
legend_value: false
in_header: false
data_generator: >
var offset =
parseInt(hass.states['input_number.sfml_day_offset']?.state
|| '0'); var sel = new Date();
sel.setDate(sel.getDate() - offset); var pad = n =>
String(n).padStart(2,'0'); var dk = sel.getFullYear()
+ '-' + pad(sel.getMonth()+1) + '-' +
pad(sel.getDate()); var now = new Date(); var y =
now.getFullYear(), m = now.getMonth(), d =
now.getDate(); var hist = typeof
entity.attributes.history_data === 'string'
? JSON.parse(entity.attributes.history_data)
: entity.attributes.history_data;
var day = hist ? hist[dk] : null; if (!day) return
[[new Date(y,m,d,0,0),0],[new Date(y,m,d,23,59),0]];
day = typeof day === 'string' ? JSON.parse(day) : day;
var pts = [[new Date(y,m,d,0,0),0]];
day.forEach(function(e){
pts.push([new Date(y,m,d,e.hour,30), e.pred]);
}); pts.push([new Date(y,m,d,23,59),0]); return pts;
- entity: sensor.sfml_stats_gesamt_history
yaxis_id: header_only
name: Ertrag
color: orange
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: >
var offset =
parseInt(hass.states['input_number.sfml_day_offset']?.state
|| '0'); var sel = new Date();
sel.setDate(sel.getDate() - offset); var pad = n =>
String(n).padStart(2,'0'); var dk = sel.getFullYear()
+ '-' + pad(sel.getMonth()+1) + '-' +
pad(sel.getDate()); var hist = typeof
entity.attributes.history_data === 'string'
? JSON.parse(entity.attributes.history_data)
: entity.attributes.history_data;
var day = hist ? hist[dk] : null; if (!day) return
[[new Date(), 0]]; day = typeof day === 'string' ?
JSON.parse(day) : day; var total =
day.reduce(function(s,e){ return s + (e.actual || 0);
},0); return [[new Date(), Math.round(total * 10) /
10]];
- entity: sensor.sfml_stats_gesamt_history
yaxis_id: header_only
name: Prognose
color: grey
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: >
var offset =
parseInt(hass.states['input_number.sfml_day_offset']?.state
|| '0'); var sel = new Date();
sel.setDate(sel.getDate() - offset); var pad = n =>
String(n).padStart(2,'0'); var dk = sel.getFullYear()
+ '-' + pad(sel.getMonth()+1) + '-' +
pad(sel.getDate()); var hist = typeof
entity.attributes.history_data === 'string'
? JSON.parse(entity.attributes.history_data)
: entity.attributes.history_data;
var day = hist ? hist[dk] : null; if (!day) return
[[new Date(), 0]]; day = typeof day === 'string' ?
JSON.parse(day) : day; var total =
day.reduce(function(s,e){ return s + (e.pred || 0);
},0); return [[new Date(), Math.round(total * 10) /
10]];
- entity: input_number.sfml_day_offset
yaxis_id: header_only
name: _trigger
show:
in_chart: false
in_header: false
legend_value: false
data_generator: |
return [];
card_mod:
style: |
ha-card {
background: transparent !important;
box-shadow: none !important;
border: none !important;
padding: 1px;
margin-top: -30px;
font-size: 11px;
border-radius: 12px;
margin-top: -10px;
}
grid_options:
columns: 48
rows: auto
- type: custom:config-template-card
entities:
- sensor.sun_next_rising
- sensor.sun_next_setting
card:
type: custom:apexcharts-card
header:
title: Nordseite
show: true
standard_format: true
show_states: true
colorize_states: true
graph_span: |-
${(() => {
const rise = new Date(states['sensor.sun_next_rising'].state);
const set = new Date(states['sensor.sun_next_setting'].state);
const now = new Date();
if (rise.getDate() !== now.getDate()) rise.setDate(rise.getDate() - 1);
if (set.getDate() !== now.getDate()) set.setDate(set.getDate() - 1);
const diffMinutes = Math.round((set - rise) / 60000) + 240;
return diffMinutes + "m";
})()}
span:
start: day
offset: |-
${(() => {
const rise = new Date(states['sensor.sun_next_rising'].state);
const now = new Date();
if (rise.getDate() !== now.getDate()) rise.setDate(rise.getDate() - 1);
const minutes = (rise.getHours() * 60 + rise.getMinutes()) - 120;
return "+" + minutes + "m";
})()}
now:
show: true
color: gold
apex_config:
xaxis:
type: datetime
labels:
datetimeUTC: false
format: HH:mm
markers:
size:
- 0
- 0
- 0
- 8
fill:
type: gradient
gradient:
shade: light
type: vertical
shadeIntensity: 0.2
opacityFrom: 1
opacityTo: 0.1
stops:
- 0
- 100
chart:
height: 250px
zoom:
enabled: true
type: x
autoScaleYaxis: true
toolbar:
show: true
tools:
zoom: true
zoomin: true
zoomout: true
pan: true
reset: true
download: false
tooltip:
enabled: true
shared: false
intersect: false
followCursor: true
x:
show: true
fixed:
enabled: false
legend:
show: true
annotations:
xaxis:
- x: |-
${(() => {
const r = new Date(states['sensor.sun_next_rising'].state);
const n = new Date();
if (r.getDate() !== n.getDate()) r.setDate(r.getDate() - 1);
return r.getTime();
})()}
borderColor: gold
label:
text: ☀️ Aufgang
style:
color: black
background: gold
- x: |-
${(() => {
const s = new Date(states['sensor.sun_next_setting'].state);
const n = new Date();
if (s.getDate() !== n.getDate()) s.setDate(s.getDate() - 1);
return s.getTime();
})()}
borderColor: orange
label:
text: 🌙 Untergang
style:
color: black
background: orange
- x: ${Date.now()}
borderColor: gold
all_series_config:
type: area
opacity: 0.9
stroke_width: 2
yaxis:
- id: kW
show: true
min: 0
apex_config:
tickAmount: 5
title:
text: kWh
- id: accuracy_axis
show: false
min: 0
max: 100
- id: sun
opposite: true
show: true
min: 0
max: 90
apex_config:
title:
text: Sonnenstand
series:
- entity: sensor.growatt_sph_esp32_power_pv_1
name: Tatsächlich
float_precision: 3
color: orange
stroke_width: 2
opacity: 0.6
yaxis_id: kW
unit: kW
transform: return x/1000;
extend_to: now
show:
legend_value: false
in_header: false
group_by:
func: avg
duration: 5m
- entity: sensor.sfml_stats_pv_nordseite
name: Prognose
color: grey
opacity: 0.3
stroke_width: 2
yaxis_id: kW
unit: " kWh"
extend_to: false
show:
legend_value: false
in_header: false
data_generator: |
var today = new Date();
var data = JSON.parse(entity.attributes.hourly_data);
return data.map((entry) => {
var date = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate(),
entry.hour,
30
);
return [date, entry.pred];
});
- entity: sensor.energie_pv_1_tag
name: Ertrag
yaxis_id: accuracy_axis
color: orange
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), parseFloat(entity.state)]];
- entity: sensor.sfml_stats_pv_nordseite
name: Prognose heute
yaxis_id: accuracy_axis
color: grey
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), entity.attributes.prediction_total]];
- entity: sensor.sfml_stats_pv_nordseite
name: Genauigkeit
yaxis_id: accuracy_axis
color: green
float_precision: 0
unit: " %"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), entity.attributes.accuracy]];
- entity: sensor.sun_solar_elevation
name: Sonnenhöhe
type: line
color: gold
stroke_width: 2
yaxis_id: sun
extend_to: false
show:
legend_value: false
in_header: false
in_legend: true
group_by:
func: avg
duration: 10m
- entity: sensor.sun_solar_elevation
name: Sonnenpunkt
type: line
yaxis_id: sun
extend_to: false
color: gold
stroke_width: 0
show:
legend_value: false
in_header: false
in_legend: false
data_generator: |
return [[Date.now(), Number(entity.state)]];
card_mod:
style: |
ha-card {
background: transparent !important;
box-shadow: none !important;
border: none !important;
padding: 1px;
font-size: 11px;
border-radius: 12px;
margin-top: -10px;
}
grid_options:
columns: 16
rows: auto
- type: custom:config-template-card
entities:
- sensor.sun_next_rising
- sensor.sun_next_setting
card:
type: custom:apexcharts-card
header:
title: Südseite
show: true
standard_format: true
show_states: true
colorize_states: true
graph_span: |-
${(() => {
const rise = new Date(states['sensor.sun_next_rising'].state);
const set = new Date(states['sensor.sun_next_setting'].state);
const now = new Date();
if (rise.getDate() !== now.getDate()) rise.setDate(rise.getDate() - 1);
if (set.getDate() !== now.getDate()) set.setDate(set.getDate() - 1);
const diffMinutes = Math.round((set - rise) / 60000) + 240;
return diffMinutes + "m";
})()}
span:
start: day
offset: |-
${(() => {
const rise = new Date(states['sensor.sun_next_rising'].state);
const now = new Date();
if (rise.getDate() !== now.getDate()) rise.setDate(rise.getDate() - 1);
const minutes = (rise.getHours() * 60 + rise.getMinutes()) - 120;
return "+" + minutes + "m";
})()}
now:
show: true
color: gold
apex_config:
xaxis:
type: datetime
labels:
datetimeUTC: false
format: HH:mm
markers:
size:
- 0
- 0
- 0
- 8
fill:
type: gradient
gradient:
shade: light
type: vertical
shadeIntensity: 0.2
opacityFrom: 1
opacityTo: 0.1
stops:
- 0
- 100
chart:
height: 250px
zoom:
enabled: true
type: x
autoScaleYaxis: true
toolbar:
show: true
tools:
zoom: true
zoomin: true
zoomout: true
pan: true
reset: true
download: false
tooltip:
enabled: true
shared: false
intersect: false
followCursor: true
x:
show: true
fixed:
enabled: false
legend:
show: true
annotations:
xaxis:
- x: |-
${(() => {
const r = new Date(states['sensor.sun_next_rising'].state);
const n = new Date();
if (r.getDate() !== n.getDate()) r.setDate(r.getDate() - 1);
return r.getTime();
})()}
borderColor: gold
label:
text: ☀️ Aufgang
style:
color: black
background: gold
- x: |-
${(() => {
const s = new Date(states['sensor.sun_next_setting'].state);
const n = new Date();
if (s.getDate() !== n.getDate()) s.setDate(s.getDate() - 1);
return s.getTime();
})()}
borderColor: orange
label:
text: 🌙 Untergang
style:
color: black
background: orange
all_series_config:
type: area
opacity: 0.9
stroke_width: 2
yaxis:
- id: kW
show: true
min: 0
apex_config:
tickAmount: 5
title:
text: kWh
- id: accuracy_axis
show: false
min: 0
max: 100
- id: sun
opposite: true
show: true
min: 0
max: 90
apex_config:
title:
text: Sonnenstand
series:
- entity: sensor.growatt_sph_esp32_power_pv_2
name: Tatsächlich
float_precision: 3
color: orange
stroke_width: 2
opacity: 0.6
yaxis_id: kW
unit: kW
transform: return x/1000;
extend_to: now
show:
legend_value: false
in_header: false
group_by:
func: avg
duration: 5m
- entity: sensor.sfml_stats_pv_sudseite
name: Prognose
color: grey
opacity: 0.3
stroke_width: 2
yaxis_id: kW
unit: " kWh"
extend_to: false
show:
legend_value: false
in_header: false
data_generator: |
var today = new Date();
var data = JSON.parse(entity.attributes.hourly_data);
return data.map((entry) => {
var date = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate(),
entry.hour,
30
);
return [date, entry.pred];
});
- entity: sensor.energie_pv_2_tag
name: Ertrag
yaxis_id: accuracy_axis
color: orange
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), parseFloat(entity.state)]];
- entity: sensor.sfml_stats_pv_sudseite
name: Prognose heute
yaxis_id: accuracy_axis
color: grey
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), entity.attributes.prediction_total]];
- entity: sensor.sfml_stats_pv_sudseite
name: Genauigkeit
yaxis_id: accuracy_axis
color: green
float_precision: 0
unit: " %"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), entity.attributes.accuracy]];
- entity: sensor.sun_solar_elevation
name: Sonnenhöhe
type: line
color: gold
stroke_width: 2
yaxis_id: sun
extend_to: false
show:
legend_value: false
in_header: false
in_legend: true
group_by:
func: avg
duration: 10m
- entity: sensor.sun_solar_elevation
name: Sonnenpunkt
type: line
yaxis_id: sun
extend_to: false
color: gold
stroke_width: 0
show:
legend_value: false
in_header: false
in_legend: false
data_generator: |
return [[Date.now(), Number(entity.state)]];
card_mod:
style: |
ha-card {
background: transparent !important;
box-shadow: none !important;
border: none !important;
padding: 1px;
font-size: 11px;
border-radius: 12px;
margin-top: -10px;
}
grid_options:
columns: 16
rows: auto
- type: custom:config-template-card
entities:
- sensor.sun_next_rising
- sensor.sun_next_setting
card:
type: custom:apexcharts-card
header:
title: Carport
show: true
standard_format: true
show_states: true
colorize_states: true
graph_span: |-
${(() => {
const rise = new Date(states['sensor.sun_next_rising'].state);
const set = new Date(states['sensor.sun_next_setting'].state);
const now = new Date();
if (rise.getDate() !== now.getDate()) rise.setDate(rise.getDate() - 1);
if (set.getDate() !== now.getDate()) set.setDate(set.getDate() - 1);
const diffMinutes = Math.round((set - rise) / 60000) + 240;
return diffMinutes + "m";
})()}
span:
start: day
offset: |-
${(() => {
const rise = new Date(states['sensor.sun_next_rising'].state);
const now = new Date();
if (rise.getDate() !== now.getDate()) rise.setDate(rise.getDate() - 1);
const minutes = (rise.getHours() * 60 + rise.getMinutes()) - 120;
return "+" + minutes + "m";
})()}
now:
show: true
color: gold
apex_config:
xaxis:
type: datetime
labels:
datetimeUTC: false
format: HH:mm
markers:
size:
- 0
- 0
- 0
- 8
fill:
type: gradient
gradient:
shade: light
type: vertical
shadeIntensity: 0.2
opacityFrom: 1
opacityTo: 0.1
stops:
- 0
- 100
chart:
height: 250px
zoom:
enabled: true
type: x
autoScaleYaxis: true
toolbar:
show: true
tools:
zoom: true
zoomin: true
zoomout: true
pan: true
reset: true
download: false
tooltip:
enabled: true
shared: false
intersect: false
followCursor: true
x:
show: true
fixed:
enabled: false
legend:
show: true
annotations:
xaxis:
- x: |-
${(() => {
const r = new Date(states['sensor.sun_next_rising'].state);
const n = new Date();
if (r.getDate() !== n.getDate()) r.setDate(r.getDate() - 1);
return r.getTime();
})()}
borderColor: gold
label:
text: ☀️ Aufgang
style:
color: black
background: gold
- x: |-
${(() => {
const s = new Date(states['sensor.sun_next_setting'].state);
const n = new Date();
if (s.getDate() !== n.getDate()) s.setDate(s.getDate() - 1);
return s.getTime();
})()}
borderColor: orange
label:
text: 🌙 Untergang
style:
color: black
background: orange
all_series_config:
type: area
opacity: 0.9
stroke_width: 2
yaxis:
- id: kW
show: true
min: 0
apex_config:
tickAmount: 5
title:
text: kWh
- id: accuracy_axis
show: false
min: 0
max: 100
- id: sun
opposite: true
show: true
min: 0
max: 90
apex_config:
title:
text: Sonnenstand
series:
- entity: sensor.pv_carport_switch_0_power
name: Tatsächlich
float_precision: 3
color: orange
stroke_width: 2
opacity: 0.6
yaxis_id: kW
unit: kW
transform: return x/1000;
extend_to: now
show:
legend_value: false
in_header: false
group_by:
func: avg
duration: 5m
- entity: sensor.sfml_stats_pv_carport
name: Prognose
color: grey
opacity: 0.3
stroke_width: 2
yaxis_id: kW
unit: " kWh"
extend_to: false
show:
legend_value: false
in_header: false
data_generator: |
var today = new Date();
var data = JSON.parse(entity.attributes.hourly_data);
return data.map((entry) => {
var date = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate(),
entry.hour,
30
);
return [date, entry.pred];
});
- entity: sensor.daily_energy_pv_carport
name: Ertrag
yaxis_id: accuracy_axis
color: orange
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), parseFloat(entity.state)]];
- entity: sensor.sfml_stats_pv_carport
name: Prognose heute
yaxis_id: accuracy_axis
color: grey
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), entity.attributes.prediction_total]];
- entity: sensor.sfml_stats_pv_carport
name: Genauigkeit
yaxis_id: accuracy_axis
color: green
float_precision: 0
unit: " %"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), entity.attributes.accuracy]];
- entity: sensor.sun_solar_elevation
name: Sonnenhöhe
type: line
color: gold
stroke_width: 2
yaxis_id: sun
extend_to: false
show:
legend_value: false
in_header: false
in_legend: true
group_by:
func: avg
duration: 10m
- entity: sensor.sun_solar_elevation
name: Sonnenpunkt
type: line
yaxis_id: sun
extend_to: false
color: gold
stroke_width: 0
show:
legend_value: false
in_header: false
in_legend: false
data_generator: |
return [[Date.now(), Number(entity.state)]];
card_mod:
style: |
ha-card {
background: transparent !important;
box-shadow: none !important;
border: none !important;
padding: 1px;
font-size: 11px;
border-radius: 12px;
margin-top: -10px;
}
grid_options:
columns: 16
rows: auto
- type: custom:config-template-card
entities:
- sensor.sun_next_rising
- sensor.sun_next_setting
card:
type: custom:apexcharts-card
header:
title: Gartenhütte
show: true
standard_format: true
show_states: true
colorize_states: true
graph_span: |-
${(() => {
const rise = new Date(states['sensor.sun_next_rising'].state);
const set = new Date(states['sensor.sun_next_setting'].state);
const now = new Date();
if (rise.getDate() !== now.getDate()) rise.setDate(rise.getDate() - 1);
if (set.getDate() !== now.getDate()) set.setDate(set.getDate() - 1);
const diffMinutes = Math.round((set - rise) / 60000) + 240;
return diffMinutes + "m";
})()}
span:
start: day
offset: |-
${(() => {
const rise = new Date(states['sensor.sun_next_rising'].state);
const now = new Date();
if (rise.getDate() !== now.getDate()) rise.setDate(rise.getDate() - 1);
const minutes = (rise.getHours() * 60 + rise.getMinutes()) - 120;
return "+" + minutes + "m";
})()}
now:
show: true
color: gold
apex_config:
xaxis:
type: datetime
labels:
datetimeUTC: false
format: HH:mm
markers:
size:
- 0
- 0
- 0
- 8
fill:
type: gradient
gradient:
shade: light
type: vertical
shadeIntensity: 0.2
opacityFrom: 1
opacityTo: 0.1
stops:
- 0
- 100
chart:
height: 250px
zoom:
enabled: true
type: x
autoScaleYaxis: true
toolbar:
show: true
tools:
zoom: true
zoomin: true
zoomout: true
pan: true
reset: true
download: false
tooltip:
enabled: true
shared: false
intersect: false
followCursor: true
x:
show: true
fixed:
enabled: false
legend:
show: true
annotations:
xaxis:
- x: |-
${(() => {
const r = new Date(states['sensor.sun_next_rising'].state);
const n = new Date();
if (r.getDate() !== n.getDate()) r.setDate(r.getDate() - 1);
return r.getTime();
})()}
borderColor: gold
label:
text: ☀️ Aufgang
style:
color: black
background: gold
- x: |-
${(() => {
const s = new Date(states['sensor.sun_next_setting'].state);
const n = new Date();
if (s.getDate() !== n.getDate()) s.setDate(s.getDate() - 1);
return s.getTime();
})()}
borderColor: orange
label:
text: 🌙 Untergang
style:
color: black
background: orange
all_series_config:
type: area
opacity: 0.9
stroke_width: 2
yaxis:
- id: kW
show: true
min: 0
apex_config:
tickAmount: 5
title:
text: kWh
- id: accuracy_axis
show: false
min: 0
max: 100
- id: sun
opposite: true
show: true
min: 0
max: 90
apex_config:
title:
text: Sonnenstand
series:
- entity: sensor.pv_gartenhuette_switch_0_power
name: Tatsächlich
float_precision: 3
color: orange
stroke_width: 2
opacity: 0.6
yaxis_id: kW
unit: kW
transform: return x/1000;
extend_to: now
show:
legend_value: false
in_header: false
group_by:
func: avg
duration: 5m
- entity: sensor.sfml_stats_pv_gartenhutte
name: Prognose
color: grey
opacity: 0.3
stroke_width: 2
yaxis_id: kW
unit: " kWh"
extend_to: false
show:
legend_value: false
in_header: false
data_generator: |
var today = new Date();
var data = JSON.parse(entity.attributes.hourly_data);
return data.map((entry) => {
var date = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate(),
entry.hour,
30
);
return [date, entry.pred];
});
- entity: sensor.daily_energy_pv_gartenhuette
name: Ertrag
yaxis_id: accuracy_axis
color: orange
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), parseFloat(entity.state)]];
- entity: sensor.sfml_stats_pv_gartenhutte
name: Prognose heute
yaxis_id: accuracy_axis
color: grey
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), entity.attributes.prediction_total]];
- entity: sensor.sfml_stats_pv_gartenhutte
name: Genauigkeit
yaxis_id: accuracy_axis
color: green
float_precision: 0
unit: " %"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), entity.attributes.accuracy]];
- entity: sensor.sun_solar_elevation
name: Sonnenhöhe
type: line
color: gold
stroke_width: 2
yaxis_id: sun
extend_to: false
show:
legend_value: false
in_header: false
in_legend: true
group_by:
func: avg
duration: 10m
- entity: sensor.sun_solar_elevation
name: Sonnenpunkt
type: line
yaxis_id: sun
extend_to: false
color: gold
stroke_width: 0
show:
legend_value: false
in_header: false
in_legend: false
data_generator: |
return [[Date.now(), Number(entity.state)]];
card_mod:
style: |
ha-card {
background: transparent !important;
box-shadow: none !important;
border: none !important;
padding: 1px;
font-size: 11px;
border-radius: 12px;
margin-top: -10px;
}
grid_options:
columns: 16
rows: auto
- type: custom:config-template-card
entities:
- sensor.sun_next_rising
- sensor.sun_next_setting
card:
type: custom:apexcharts-card
header:
title: Pool
show: true
standard_format: true
show_states: true
colorize_states: true
graph_span: |-
${(() => {
const rise = new Date(states['sensor.sun_next_rising'].state);
const set = new Date(states['sensor.sun_next_setting'].state);
const now = new Date();
if (rise.getDate() !== now.getDate()) rise.setDate(rise.getDate() - 1);
if (set.getDate() !== now.getDate()) set.setDate(set.getDate() - 1);
const diffMinutes = Math.round((set - rise) / 60000) + 240;
return diffMinutes + "m";
})()}
span:
start: day
offset: |-
${(() => {
const rise = new Date(states['sensor.sun_next_rising'].state);
const now = new Date();
if (rise.getDate() !== now.getDate()) rise.setDate(rise.getDate() - 1);
const minutes = (rise.getHours() * 60 + rise.getMinutes()) - 120;
return "+" + minutes + "m";
})()}
now:
show: true
color: gold
apex_config:
xaxis:
type: datetime
labels:
datetimeUTC: false
format: HH:mm
markers:
size:
- 0
- 0
- 0
- 8
fill:
type: gradient
gradient:
shade: light
type: vertical
shadeIntensity: 0.2
opacityFrom: 1
opacityTo: 0.1
stops:
- 0
- 100
chart:
height: 250px
zoom:
enabled: true
type: x
autoScaleYaxis: true
toolbar:
show: true
tools:
zoom: true
zoomin: true
zoomout: true
pan: true
reset: true
download: false
tooltip:
enabled: true
shared: false
intersect: false
followCursor: true
x:
show: true
fixed:
enabled: false
legend:
show: true
annotations:
xaxis:
- x: |-
${(() => {
const r = new Date(states['sensor.sun_next_rising'].state);
const n = new Date();
if (r.getDate() !== n.getDate()) r.setDate(r.getDate() - 1);
return r.getTime();
})()}
borderColor: gold
label:
text: ☀️ Aufgang
style:
color: black
background: gold
- x: |-
${(() => {
const s = new Date(states['sensor.sun_next_setting'].state);
const n = new Date();
if (s.getDate() !== n.getDate()) s.setDate(s.getDate() - 1);
return s.getTime();
})()}
borderColor: orange
label:
text: 🌙 Untergang
style:
color: black
background: orange
all_series_config:
type: area
opacity: 0.9
stroke_width: 2
yaxis:
- id: kW
show: true
min: 0
apex_config:
tickAmount: 5
title:
text: kWh
- id: accuracy_axis
show: false
min: 0
max: 100
- id: sun
opposite: true
show: true
min: 0
max: 90
apex_config:
title:
text: Sonnenstand
series:
- entity: sensor.shelly_pv_pool_switch_0_power_numeric
name: Tatsächlich
float_precision: 3
color: orange
stroke_width: 2
opacity: 0.6
yaxis_id: kW
unit: kW
transform: return x/1000;
extend_to: now
show:
legend_value: false
in_header: false
group_by:
func: avg
duration: 5m
- entity: sensor.sfml_stats_pv_pool
name: Prognose
color: grey
opacity: 0.3
stroke_width: 2
yaxis_id: kW
unit: " kWh"
extend_to: false
show:
legend_value: false
in_header: false
data_generator: |
var today = new Date();
var data = JSON.parse(entity.attributes.hourly_data);
return data.map((entry) => {
var date = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate(),
entry.hour,
30
);
return [date, entry.pred];
});
- entity: sensor.daily_energy_pv_pool
name: Ertrag
yaxis_id: accuracy_axis
color: orange
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), parseFloat(entity.state)]];
- entity: sensor.sfml_stats_pv_pool
name: Prognose heute
yaxis_id: accuracy_axis
color: grey
float_precision: 1
unit: " kWh"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), entity.attributes.prediction_total]];
- entity: sensor.sfml_stats_pv_pool
name: Genauigkeit
yaxis_id: accuracy_axis
color: green
float_precision: 0
unit: " %"
show:
legend_value: true
in_header: true
in_chart: false
data_generator: |
return [[new Date(), entity.attributes.accuracy]];
- entity: sensor.sun_solar_elevation
name: Sonnenhöhe
type: line
color: gold
stroke_width: 2
yaxis_id: sun
extend_to: false
show:
legend_value: false
in_header: false
in_legend: true
group_by:
func: avg
duration: 10m
- entity: sensor.sun_solar_elevation
name: Sonnenpunkt
type: line
yaxis_id: sun
extend_to: false
color: gold
stroke_width: 0
show:
legend_value: false
in_header: false
in_legend: false
data_generator: |
return [[Date.now(), Number(entity.state)]];
card_mod:
style: |
ha-card {
background: transparent !important;
box-shadow: none !important;
border: none !important;
padding: 1px;
font-size: 11px;
border-radius: 12px;
margin-top: -10px;
}
grid_options:
columns: 16
rows: auto
- type: entities
entities:
- entity: sensor.none_produktionszeit_heute
- entity: sensor.solar_forecast_ml_ml_metrics
- entity: sensor.solar_forecast_ml_physics_samples
- entity: sensor.solar_forecast_ml_active_prediction_model
- entity: sensor.solar_forecast_ml_ki_drift_status
- entity: sensor.solar_forecast_ml_o_genauigkeit_30_tage
- entity: sensor.solar_forecast_ml_ai_rmse
grid_options:
columns: 10
rows: auto
card_mod:
style: |
ha-card {
background: transparent;
border: none;
padding: 1px;
font-size: 11px; /* Basisgröße */
}
- type: markdown
content: >-
| Stunde | Verlust | Ursache |
| :--- | ---: | :--- |
{% set icons = {
'🌙 Nacht': '🌙',
'❄️ Schnee': '❄️',
'❄️ Frost': '❄️',
'☁️ Wolken': '☁️',
'🏠 Verschattung': '🏠',
'🌅 Tiefer Sonnenstand': '🌅',
'☀️ Besser als Prognose': '☀️'
} -%}
{%- for item in state_attr('sensor.solar_forecast_ml_schatten_heute',
'hourly_breakdown') %}
{%- set cause =
'🌙 Nacht' if item.root_cause == 'Nacht' else
'❄️ Schnee' if item.root_cause == 'Schnee' or item.snow_covered else
'❄️ Frost' if item.root_cause == 'Frost' else
'☁️ Wolken' if item.root_cause == 'Wolken' else
'🏠 Verschattung' if item.root_cause == 'Mögliche Verschattung' else
'🌅 Tiefer Sonnenstand' if item.root_cause == 'Tiefer Sonnenstand' else
'🔝 Besser als Prognose' if item.root_cause == 'Klarer als Prognose' else
'🆗 Normale Schwankung' if item.root_cause == 'Normale Schwankung' else
'🔎 ' ~ (item.root_cause | replace('_',' '))
-%}
{%- set icon = icons.get(cause, '') -%}
| {{ '%02d' | format(item.hour) }}:00 | {{ item.shadow_percent }}% |
{{ icon }} {{ cause | replace(icon ~ ' ', '') }} |
{% endfor %}
grid_options:
columns: 6
rows: 6
text_only: true
card_mod:
style: |
ha-card {
background: transparent;
border: none;
padding: 1px;
margin-left: 10px;
font-size: 11px; /* Basisgröße */
}
column_span: 4
- type: grid
cards:
- type: custom:apexcharts-card
graph_span: 70d
span:
end: day
header:
show: true
title: PV Produktion vs. Prognose + Abweichung
show_states: true
colorize_states: true
apex_config:
chart:
height: 350
toolbar:
show: true
tools:
download: false
selection: true
zoom: true
zoomin: true
zoomout: true
pan: true
reset: true
zoom:
enabled: true
type: x
autoScaleYaxis: true
timezone: Europe/Vienna
xaxis:
type: datetime
labels:
datetimeUTC: false
legend:
show: false
grid:
borderColor: rgba(150,150,150,0.15)
strokeDashArray: 3
plotOptions:
bar:
borderRadius: 5
columnWidth: 60%
fill:
type: gradient
gradient:
shade: light
type: vertical
shadeIntensity: 0.5
opacityFrom: 1
opacityTo: 0.7
stops:
- 0
- 100
stroke:
curve: smooth
annotations:
yaxis:
- "y": 26
yAxisIndex: 1
borderColor: "#000000"
strokeDashArray: 4
strokeWidth: 2
series:
- entity: sensor.pv_ertrag_pro_tag_insgesamt
name: PV Ertrag
type: column
color: "#FFA500"
stroke_width: 0
yaxis_id: energy
group_by:
duration: 1d
func: max
- entity: sensor.none_prognose_heute
name: Prognose
type: column
color: black
stroke_width: 0
yaxis_id: energy
group_by:
duration: 1d
func: last
- entity: sensor.pv_forecast_deviation_percent_solar_forecast_ml
name: Abweichung
type: line
color: "#2e7d32"
stroke_width: 3
extend_to: false
yaxis_id: abweichung
group_by:
duration: 1d
func: last
yaxis:
- id: energy
decimals: 0
apex_config:
title:
text: Energieertrag (kWh)
- id: abweichung
opposite: true
decimals: 0
min: -50
max: 50
apex_config:
title:
text: Abweichung (%) zur Prognose
card_mod:
style: |
ha-card {
background: transparent !important;
box-shadow: none !important;
margin-top: -1px;
font-size: 11px;
}
grid_options:
columns: 48
rows: 7
column_span: 4
background:
opacity: 80
alignment: center
size: cover
repeat: repeat
attachment: fixed
image:
media_content_id: media-source://image_upload/1f945a4a5ec908dbd37d742ccacf09a8
media_content_type: image/png
metadata:
title: ChatGPT Image 18. Feb. 2026, 20_23_45.png
thumbnail: /api/image/serve/1f945a4a5ec908dbd37d742ccacf09a8/256x256
media_class: image
navigateIds:
- {}
- media_content_type: app
media_content_id: media-source://image_upload
cards: []
Das ist der Code des gesamten Dashboards. Sorry fürs Offtopic hier @Tom-HA .