missing files

This commit is contained in:
2026-05-21 11:12:07 +02:00
parent 25522a3af9
commit 8a0331ed75
12 changed files with 1658 additions and 784 deletions
+351 -115
View File
@@ -58,85 +58,269 @@
},
{
"type": "custom:apexcharts-card",
"update_interval": "5m",
"graph_span": "48h",
"span": {
"start": "day"
},
"experimental": {
"hidden_by_default": true
},
"header": {
"show": true,
"show_states": false,
"standard_format": true,
"disable_actions": true
"title": "Preisniveau",
"show_states": false
},
"now": {
"show": true,
"color": "#ffffff"
},
"all_series_config": {
"float_precision": 2
},
"apex_config": {
"chart": {
"animations": {
"enabled": false
},
"toolbar": {
"show": false
},
"zoom": {
"enabled": false
}
},
"stroke": {
"curve": "stepline",
"dashArray": [
0,
0,
0,
0,
0,
0,
0,
4
]
},
"fill": {
"type": "gradient",
"opacity": 0.45,
"gradient": {
"shade": "light",
"type": "vertical",
"shadeIntensity": 0.2,
"opacityFrom": [
0.5,
0.7,
0.7,
0.7,
0.7,
0.7,
0.7,
0
],
"opacityTo": 0.25,
"stops": [
50,
100
]
}
},
"dataLabels": {
"enabled": false
},
"legend": {
"show": false
"show": true,
"position": "bottom",
"horizontalAlign": "center",
"markers": {
"size": 0
},
"itemMargin": {
"horizontal": 15
}
},
"grid": {
"show": true,
"borderColor": "rgba(144, 164, 174, 0.35)",
"strokeDashArray": 0,
"xaxis": {
"lines": {
"show": false
}
},
"yaxis": {
"lines": {
"show": true
}
}
},
"markers": {
"size": 0,
"hover": {
"size": 3
},
"showNullDataPoints": false
},
"tooltip": {
"enabled": true,
"shared": true,
"enabledOnSeries": [
2,
3,
4,
5,
6
],
"marker": {
"show": false
},
"x": {
"show": false
}
}
},
"yaxis": [
{
"id": "price",
"min": "~0.1",
"max": "~0.4",
"align_to": 1,
"decimals": 2
"min": 0,
"max": 40,
"apex_config": {
"title": {
"text": "ct/kWh"
},
"decimalsInFloat": 0,
"forceNiceScale": true,
"showAlways": true,
"tickAmount": 4
}
},
{
"id": "energy",
"id": "highlight",
"min": 0,
"max": 1,
"show": false,
"opposite": true,
"align_to": 100,
"decimals": 0
"apex_config": {
"forceNiceScale": true,
"tickAmount": 4
}
}
],
"chart_type": "line",
"show": {
"last_updated": true
},
"graph_span": "1.5d",
"span": {
"start": "day"
},
"now": {
"show": true,
"label": "Jetzt"
},
"experimental": {
"color_threshold": true
},
"series": [
{
"entity": "sensor.epex_spot_data_total_price",
"yaxis_id": "price",
"stroke_width": 2,
"entity": "sun.sun",
"name": "▼ Bestpreis-Zeitraum",
"type": "area",
"color": "rgba(46, 204, 113, 0.05)",
"yaxis_id": "highlight",
"stroke_width": 0,
"show": {
"legend_value": false
"legend_value": false,
"in_header": false,
"in_legend": true
},
"data_generator": "const ed=new Date(); ed.setDate(ed.getDate()+3); ed.setHours(0,0,0,0); const es=ed.getFullYear()+'-'+String(ed.getMonth()+1).padStart(2,'0')+'-'+String(ed.getDate()).padStart(2,'0')+' 00:00:00'; const r=await hass.callWS({type:'call_service',domain:'tibber',service:'get_prices',return_response:true,service_data:{end:es}}); const a=r.response.prices.Zuhause.map(p=>({ts:new Date(p.start_time).getTime(),ct:Math.round(p.price*10000)/100})); const cts=a.map(p=>p.ct); const m=cts.reduce((x,y)=>x+y,0)/cts.length; const sd=Math.sqrt(cts.map(c=>(c-m)**2).reduce((x,y)=>x+y,0)/cts.length); const tC=m-0.5*sd; return a.map(p=>[p.ts,p.ct<tC?1:null]);"
},
{
"entity": "sun.sun",
"name": "▲ Spitzenpreis-Zeitraum",
"type": "area",
"color": "rgba(231, 76, 60, 0.06)",
"yaxis_id": "highlight",
"stroke_width": 0,
"show": {
"legend_value": false,
"in_header": false,
"in_legend": true,
"hidden_by_default": true
},
"data_generator": "const ed=new Date(); ed.setDate(ed.getDate()+3); ed.setHours(0,0,0,0); const es=ed.getFullYear()+'-'+String(ed.getMonth()+1).padStart(2,'0')+'-'+String(ed.getDate()).padStart(2,'0')+' 00:00:00'; const r=await hass.callWS({type:'call_service',domain:'tibber',service:'get_prices',return_response:true,service_data:{end:es}}); const a=r.response.prices.Zuhause.map(p=>({ts:new Date(p.start_time).getTime(),ct:Math.round(p.price*10000)/100})); const cts=a.map(p=>p.ct); const m=cts.reduce((x,y)=>x+y,0)/cts.length; const sd=Math.sqrt(cts.map(c=>(c-m)**2).reduce((x,y)=>x+y,0)/cts.length); const tE=m+0.5*sd; return a.map(p=>[p.ts,p.ct>=tE?1:null]);"
},
{
"entity": "sun.sun",
"name": "Sehr günstig",
"type": "area",
"color": "#2ecc71",
"yaxis_id": "price",
"stroke_width": 1.5,
"show": {
"legend_value": false,
"in_header": false,
"in_legend": false
},
"data_generator": "const ed=new Date(); ed.setDate(ed.getDate()+3); ed.setHours(0,0,0,0); const es=ed.getFullYear()+'-'+String(ed.getMonth()+1).padStart(2,'0')+'-'+String(ed.getDate()).padStart(2,'0')+' 00:00:00'; const r=await hass.callWS({type:'call_service',domain:'tibber',service:'get_prices',return_response:true,service_data:{end:es}}); const a=r.response.prices.Zuhause.map(p=>({ts:new Date(p.start_time).getTime(),ct:Math.round(p.price*10000)/100})); const cts=a.map(p=>p.ct); const m=cts.reduce((x,y)=>x+y,0)/cts.length; const sd=Math.sqrt(cts.map(c=>(c-m)**2).reduce((x,y)=>x+y,0)/cts.length); const tVC=m-1.5*sd; return a.map((p,i)=>{\n const here=p.ct<tVC;\n const prev=i>0&&a[i-1].ct<tVC;\n const next=i<a.length-1&&a[i+1].ct<tVC;\n return [p.ts,(here||prev||next)?p.ct:null];\n});"
},
{
"entity": "sun.sun",
"name": "Günstig",
"type": "area",
"color": "#27ae60",
"yaxis_id": "price",
"stroke_width": 1.5,
"show": {
"legend_value": false,
"in_header": false,
"in_legend": false
},
"data_generator": "const ed=new Date(); ed.setDate(ed.getDate()+3); ed.setHours(0,0,0,0); const es=ed.getFullYear()+'-'+String(ed.getMonth()+1).padStart(2,'0')+'-'+String(ed.getDate()).padStart(2,'0')+' 00:00:00'; const r=await hass.callWS({type:'call_service',domain:'tibber',service:'get_prices',return_response:true,service_data:{end:es}}); const a=r.response.prices.Zuhause.map(p=>({ts:new Date(p.start_time).getTime(),ct:Math.round(p.price*10000)/100})); const cts=a.map(p=>p.ct); const m=cts.reduce((x,y)=>x+y,0)/cts.length; const sd=Math.sqrt(cts.map(c=>(c-m)**2).reduce((x,y)=>x+y,0)/cts.length); const tVC=m-1.5*sd; const tC=m-0.5*sd; return a.map((p,i)=>{\n const here=p.ct>=tVC&&p.ct<tC;\n const prev=i>0&&a[i-1].ct>=tVC&&a[i-1].ct<tC;\n const next=i<a.length-1&&a[i+1].ct>=tVC&&a[i+1].ct<tC;\n return [p.ts,(here||prev||next)?p.ct:null];\n});"
},
{
"entity": "sun.sun",
"name": "Normal",
"type": "area",
"color": "#f1c40f",
"yaxis_id": "price",
"stroke_width": 1.5,
"show": {
"legend_value": false,
"in_header": false,
"in_legend": false
},
"data_generator": "const ed=new Date(); ed.setDate(ed.getDate()+3); ed.setHours(0,0,0,0); const es=ed.getFullYear()+'-'+String(ed.getMonth()+1).padStart(2,'0')+'-'+String(ed.getDate()).padStart(2,'0')+' 00:00:00'; const r=await hass.callWS({type:'call_service',domain:'tibber',service:'get_prices',return_response:true,service_data:{end:es}}); const a=r.response.prices.Zuhause.map(p=>({ts:new Date(p.start_time).getTime(),ct:Math.round(p.price*10000)/100})); const cts=a.map(p=>p.ct); const m=cts.reduce((x,y)=>x+y,0)/cts.length; const sd=Math.sqrt(cts.map(c=>(c-m)**2).reduce((x,y)=>x+y,0)/cts.length); const tC=m-0.5*sd; const tE=m+0.5*sd; return a.map((p,i)=>{\n const here=p.ct>=tC&&p.ct<tE;\n const prev=i>0&&a[i-1].ct>=tC&&a[i-1].ct<tE;\n const next=i<a.length-1&&a[i+1].ct>=tC&&a[i+1].ct<tE;\n return [p.ts,(here||prev||next)?p.ct:null];\n});"
},
{
"entity": "sun.sun",
"name": "Teuer",
"type": "area",
"color": "#e67e22",
"yaxis_id": "price",
"stroke_width": 1.5,
"show": {
"legend_value": false,
"in_header": false,
"in_legend": false
},
"data_generator": "const ed=new Date(); ed.setDate(ed.getDate()+3); ed.setHours(0,0,0,0); const es=ed.getFullYear()+'-'+String(ed.getMonth()+1).padStart(2,'0')+'-'+String(ed.getDate()).padStart(2,'0')+' 00:00:00'; const r=await hass.callWS({type:'call_service',domain:'tibber',service:'get_prices',return_response:true,service_data:{end:es}}); const a=r.response.prices.Zuhause.map(p=>({ts:new Date(p.start_time).getTime(),ct:Math.round(p.price*10000)/100})); const cts=a.map(p=>p.ct); const m=cts.reduce((x,y)=>x+y,0)/cts.length; const sd=Math.sqrt(cts.map(c=>(c-m)**2).reduce((x,y)=>x+y,0)/cts.length); const tE=m+0.5*sd; const tVE=m+1.5*sd; return a.map((p,i)=>{\n const here=p.ct>=tE&&p.ct<tVE;\n const prev=i>0&&a[i-1].ct>=tE&&a[i-1].ct<tVE;\n const next=i<a.length-1&&a[i+1].ct>=tE&&a[i+1].ct<tVE;\n return [p.ts,(here||prev||next)?p.ct:null];\n});"
},
{
"entity": "sun.sun",
"name": "Sehr teuer",
"type": "area",
"color": "#e74c3c",
"yaxis_id": "price",
"stroke_width": 1.5,
"show": {
"legend_value": false,
"in_header": false,
"in_legend": false
},
"data_generator": "const ed=new Date(); ed.setDate(ed.getDate()+3); ed.setHours(0,0,0,0); const es=ed.getFullYear()+'-'+String(ed.getMonth()+1).padStart(2,'0')+'-'+String(ed.getDate()).padStart(2,'0')+' 00:00:00'; const r=await hass.callWS({type:'call_service',domain:'tibber',service:'get_prices',return_response:true,service_data:{end:es}}); const a=r.response.prices.Zuhause.map(p=>({ts:new Date(p.start_time).getTime(),ct:Math.round(p.price*10000)/100})); const cts=a.map(p=>p.ct); const m=cts.reduce((x,y)=>x+y,0)/cts.length; const sd=Math.sqrt(cts.map(c=>(c-m)**2).reduce((x,y)=>x+y,0)/cts.length); const tVE=m+1.5*sd; return a.map((p,i)=>{\n const here=p.ct>=tVE;\n const prev=i>0&&a[i-1].ct>=tVE;\n const next=i<a.length-1&&a[i+1].ct>=tVE;\n return [p.ts,(here||prev||next)?p.ct:null];\n});"
},
{
"entity": "sun.sun",
"name": "Keine Daten",
"type": "line",
"extend_to": false,
"data_generator": "return entity.attributes.data.map((entry) => {\n return [new Date(entry.start_time), entry.price_per_kwh];\n});\n",
"curve": "stepline",
"color_threshold": [
{
"value": 0.1,
"color": "blue"
},
{
"value": 0.2,
"color": "cyan"
},
{
"value": 0.25,
"color": "green"
},
{
"value": 0.3,
"color": "yellow"
},
{
"value": 0.35,
"color": "orange"
},
{
"value": 0.4,
"color": "red"
}
]
"color": "#546e7a",
"yaxis_id": "price",
"stroke_width": 1,
"show": {
"legend_value": false,
"in_header": false,
"in_legend": false
},
"data_generator": "const ed=new Date(); ed.setDate(ed.getDate()+3); ed.setHours(0,0,0,0); const es=ed.getFullYear()+'-'+String(ed.getMonth()+1).padStart(2,'0')+'-'+String(ed.getDate()).padStart(2,'0')+' 00:00:00'; const r=await hass.callWS({type:'call_service',domain:'tibber',service:'get_prices',return_response:true,service_data:{end:es}}); const prices=r.response.prices.Zuhause; const known=new Set(prices.map(p=>new Date(p.start_time).getTime())); const cts=prices.map(p=>Math.round(p.price*10000)/100); const avg=Math.round(cts.reduce((x,y)=>x+y,0)/cts.length*10)/10; const start=new Date(); start.setHours(0,0,0,0); const result=[]; for(let i=0;i<192;i++){\n const ts=start.getTime()+i*15*60*1000;\n result.push([ts,known.has(ts)?null:avg]);\n} return result;"
}
]
},
@@ -203,8 +387,44 @@
},
"grid": {
"entity": {
"consumption": "sensor.powerocean_hj37zdh5zg5w0109_netz_zu_haus",
"production": "sensor.powerocean_hj37zdh5zg5w0109_solar_zu_netz"
"0": "s",
"1": "e",
"2": "n",
"3": "s",
"4": "o",
"5": "r",
"6": ".",
"7": "t",
"8": "i",
"9": "b",
"10": "b",
"11": "e",
"12": "r",
"13": "_",
"14": "p",
"15": "u",
"16": "l",
"17": "s",
"18": "e",
"19": "_",
"20": "z",
"21": "u",
"22": "h",
"23": "a",
"24": "u",
"25": "s",
"26": "e",
"27": "_",
"28": "l",
"29": "e",
"30": "i",
"31": "s",
"32": "t",
"33": "u",
"34": "n",
"35": "g",
"consumption": "sensor.tibber_pulse_zuhause_leistung",
"production": "sensor.tibber_pulse_zuhause_einspeiseleistung"
},
"secondary_info": {},
"use_metadata": false,
@@ -213,7 +433,7 @@
"display_state": "two_way"
},
"solar": {
"entity": "sensor.powerocean_hj37zdh5zg5w0109_solarertrag_mppt",
"entity": "sensor.powerocean_hj37zdh5zg5w0109_solar_gesamtleistung",
"display_zero_state": true,
"secondary_info": {},
"color_value": false,
@@ -246,7 +466,7 @@
"secondary_info": {}
},
{
"entity": "sensor.charger_ac31zeh4ag130052_evpwr",
"entity": "sensor.charger_ac31zeh4ag130052_ladebox_leistung",
"secondary_info": {},
"name": "Wallbox",
"icon": "mdi:car",
@@ -302,16 +522,6 @@
"icon": "mdi:water-alert",
"icon_color": "{{ 'red' if is_state('binary_sensor.technikraum_wassermelder_water_leak','on')\n or is_state('binary_sensor.wc_wassermelder_water_leak','on')\n or is_state('binary_sensor.kuche_wassermelder_water_leak','on')\n else 'green' }}\n",
"content": "{% if is_state('binary_sensor.technikraum_wassermelder_water_leak','on') %}\n Wasser Technikraum!\n{% elif is_state('binary_sensor.wc_wassermelder_water_leak','on') %}\n Wasser WC!\n{% elif is_state('binary_sensor.kuche_wassermelder_water_leak','on') %}\n Wasser Küche!\n{% else %}\n Trocken\n{% endif %}\n"
},
{
"type": "template",
"icon": "mdi:heat-pump-outline",
"icon_color": "{{ 'red' if is_state('binary_sensor.nibe_s1255_6_e_em_3x400v_alarm','on')\n else 'green' }}\n",
"content": "{{ 'WP Alarm!' if is_state('binary_sensor.nibe_s1255_6_e_em_3x400v_alarm','on')\n else 'WP ok' }}\n",
"tap_action": {
"action": "more-info",
"entity": "binary_sensor.nibe_s1255_6_e_em_3x400v_alarm"
}
}
]
}
@@ -425,10 +635,72 @@
"hide_time_range": true,
"use_summary": false
},
{
"type": "custom:mushroom-title-card",
"title": "🏊 Whirlpool"
},
{
"type": "custom:mushroom-climate-card",
"entity": "climate.spa_thermostat",
"name": "Whirlpool",
"show_temperature_control": true,
"hvac_modes": [
"heat",
"off"
],
"fill_container": true,
"grid_options": {
"columns": 6,
"rows": 2
},
"tap_action": {
"action": "more-info"
}
},
{
"type": "custom:mushroom-chips-card",
"chips": [
{
"type": "template",
"icon": "mdi:ph",
"content": "{{ states('sensor.whirlpool_ph') | float | round(1) }}",
"icon_color": "blue"
},
{
"type": "template",
"icon": "mdi:water-percent",
"content": "{{ states('sensor.whirlpool_oxydo_reduktionspotenzial') | int }} mV",
"icon_color": "purple"
}
],
"alignment": "center",
"grid_options": {
"columns": 6,
"rows": 1
}
},
{
"type": "custom:mushroom-title-card",
"title": "♨️ Wärme & Wasser"
},
{
"type": "custom:mushroom-climate-card",
"entity": "climate.climate_system_s1",
"name": "Heizung",
"show_temperature_control": true,
"hvac_modes": [],
"fill_container": true,
"grid_options": {
"columns": 6,
"rows": 2
},
"tap_action": {
"action": "more-info"
},
"icon": "mdi:heat-pump",
"layout": "vertical",
"collapsible_controls": true
},
{
"type": "custom:mushroom-chips-card",
"alignment": "center",
@@ -449,52 +721,16 @@
"icon": "mdi:gauge-full"
},
{
"type": "entity",
"entity": "climate.climate_system_s1",
"icon": "mdi:heat-pump-outline"
},
{
"type": "entity",
"icon": "mdi:heat-pump-outline"
"type": "template",
"icon": "mdi:heat-pump-outline",
"icon_color": "{{ 'red' if is_state('binary_sensor.nibe_s1255_6_e_em_3x400v_alarm','on')\n else 'green' }}\n",
"content": "{{ 'WP Alarm!' if is_state('binary_sensor.nibe_s1255_6_e_em_3x400v_alarm','on')\n else 'WP ok' }}\n"
}
]
},
{
"type": "custom:mushroom-title-card",
"title": "🏊 Whirlpool"
},
{
"type": "custom:mushroom-climate-card",
"entity": "climate.spa_thermostat",
"name": "Whirlpool",
"show_temperature_control": true,
"hvac_modes": [
"heat",
"off"
],
"fill_container": true,
"grid_options": {
"columns": 12,
"rows": 2
"columns": 6,
"rows": "auto"
}
},
{
"type": "custom:mushroom-chips-card",
"chips": [
{
"type": "template",
"icon": "mdi:ph",
"content": "{{ states('sensor.whirlpool_ph') | float | round(1) }}",
"icon_color": "blue"
},
{
"type": "template",
"icon": "mdi:water-percent",
"content": "{{ states('sensor.whirlpool_oxydo_reduktionspotenzial') | int }} mV",
"icon_color": "purple"
}
],
"alignment": "center"
}
]
},