Introduction
Since I set up my Homeassistant I faced a big problem: The native graph cards offer barely any customization options and I have very clear opinion on how my graphs must look, so Apexcharts card was one of the first additions I downloaded from HACS. Having a possibility to display different time periods and comparing data was another requirement. I found that the native energy-date-selection card provides the necessary controls but does’nt expose its state in a straight forward way, so I went for a different solution.
Recently I went back to this initial idea of using the energy-date-selection card and actually found a way to make it work. I want to share this way here since I think other might find it useful but be aware that making it fully work requires some skills because it needs a modified third-party frontend module.
Prerequisites
Like already said I am using the Apexcharts card from RomRider. I also got it to work with the Plotly graph card from dbuezas and can share this as well if requested. The functionality is mostly achieved using the config-template-card from iantrich but to get the plot to immediately react on date changes like I already said a modification is required. You can find this modification along with some further in the priv branch of my fork. I also use the lovelace-card-mod from thomasloven but this is optional as it just tweaks the looks a little bit.
Result
The core of this solution is its functionality, not its looks, but just as an example I want to share the main graph of my Overview dashboard which is controlled by the energy-date-selection card on top of it:
Configuration
This is the YAML code of the example plot:
- type: energy-date-selection
collection_key: energy_electricity_overview
card_mod:
style: '.card-content { padding: 8px 8px 8px 16px; }'
- type: custom:config-template-card
variables:
AVAILABLE: '{{ hass.connection?._energy_electricity_overview !== undefined }}'
STARTDATE: '{{ hass.connection?._energy_electricity_overview?.start }}'
ENDDATE: '{{ hass.connection?._energy_electricity_overview?.end }}'
NOW: '{{ new Date() }}'
ENDDAY: '{{ new Date(vars["NOW"].getFullYear(), vars["NOW"].getMonth(), vars["NOW"].getDate(), 23, 59, 59) }}'
TIMEZONE_OFFSET_STARTDATE: '{{ vars["AVAILABLE"] ? vars["STARTDATE"].getTimezoneOffset() * 60000 : 0 }}'
TIMEZONE_OFFSET_ENDDATE: '{{ vars["AVAILABLE"] ? vars["ENDDATE"].getTimezoneOffset() * 60000 : 0 }}'
TIMEZONE_OFFSET_ENDDAY: '{{ vars["ENDDAY"].getTimezoneOffset() * 60000 }}'
OFFSET: '{{ vars["AVAILABLE"] ? Math.round((vars["ENDDATE"].getTime() - vars["TIMEZONE_OFFSET_ENDDATE"] - vars["ENDDAY"].getTime() + vars["TIMEZONE_OFFSET_ENDDAY"]) / 3600000) : 0 }}'
OFFSET_STRING: '{{ ("+" + String(vars["OFFSET"]) + "h").replace("+-", "-") }}'
SPAN: '{{ vars["AVAILABLE"] ? Math.round((vars["ENDDATE"].getTime() - vars["TIMEZONE_OFFSET_ENDDATE"] - vars["STARTDATE"].getTime() + vars["TIMEZONE_OFFSET_STARTDATE"]) / 3600000) : 24 }}'
SPAN_STRING: '{{ vars["SPAN"] + "h" }}'
PERIOD: '{{ vars["SPAN"] >= 2160 ? "day" : (vars["SPAN"] >= 672 ? "hour" : "5minute") }}'
TYPE: '{{ vars["SPAN"] >= 672 ? "column" : "area" }}'
BUILDENTITIESCONFIGAPEXCHARTS: |
(entitiesbase, compare = "") => {
var entities = [];
if (compare)
entities.push(...entitiesbase.map((entry) => (
{...entry, offset: "-" + compare, opacity: 0.5, show: {...(entry?.show ?? {}), in_header: false, name_in_header: false, legend_value: false}}
)));
entities.push(...entitiesbase); return entities;
}
SERIES: |
BUILDENTITIESCONFIGAPEXCHARTS([
{ entity: "sensor.production_power", name: "Production" },
{ entity: "sensor.battery_power", name: "Battery" },
{ entity: "sensor.consumption_power", name: "Consumption" },
{ entity: "sensor.self_use_power", name: "Self-Use", show: { hidden_by_default: true } },
{ entity: "sensor.feed_in_power", name: "Feed-In", show: { hidden_by_default: true } },
{ entity: "sensor.purchase_power", name: "Purchase", show: { hidden_by_default: true } },
], hass.connection?._energy_electricity_overview?.compare === "previous" ? vars["SPAN_STRING"] : "")
entities:
- _energy_electricity_overview
card:
type: custom:apexcharts-card
update_interval: 1min
experimental:
hidden_by_default: true
color_list: ["green", "blue", "red", "darkcyan", "orange", "purple"]
all_series_config:
extend_to: false
stroke_width: 2
type: ${TYPE}
statistics:
type: mean
period: ${PERIOD}
graph_span: ${SPAN_STRING}
span:
end: day
offset: ${OFFSET_STRING}
apex_config:
chart:
height: 602px
toolbar:
show: true
title:
text: Powers
floating: true
offsetX: 6
offsetY: 5
style:
fontSize: 16px
fontWeight: 500
fontFamily: Roboto,Noto,sans-serif
color: '#727272'
legend:
position: top
offsetX: 100
offsetY: 10
fill:
type: gradient
gradient:
type: vertical
shadeIntensity: 0
opacityFrom: 0.7
opacityTo: 0.3
yaxis:
decimalsInFloat: 0
tooltip:
x:
format: d. MMM yyyy HH:mm:ss
series: ${SERIES}
Limitations
Like already said, a custom version of the config-template-card frontend module is required. It will work without it but it will not react on changes of the energy-date-selection card immediately. Unfortunately, I could’nt find a way to make it work without.
The compare functionality is also implemented but looks kinda bad with the series type area, so everywhere I actually use it I use the series type line instead.
If you have any questions / suggestions etc. please feel free to ask.
