Using your gas implementation (great idea!) as a foundation, I optimized that idea a bit by building a custom js-script with Geminis help to modify the frontend a bit.
Adding this in your configuration.yaml:
frontend:
extra_module_url:
- /local/fix-energy-text.js
and this as a new file called fix-energy-text.js in /config/www/:
(function() {
const translations = {
'Gas': 'Wallbox',
'Gasverbrauch': 'Wallbox-Ladung'
};
const pathEV = "M19.77,7.23L19.78,7.22L16.06,3.5L15,4.56L17.11,6.67C16.17,7.03 15.5,7.93 15.5,9A2.5,2.5 0 0,0 18,11.5C18.36,11.5 18.69,11.42 19,11.29V18.5A1,1 0 0,1 18,19.5A1,1 0 0,1 17,18.5V14A2,2 0 0,0 15,12H14V5A2,2 0 0,0 12,3H6A2,2 0 0,0 4,5V21H14V13.5H15.5V18.5A2.5,2.5 0 0,0 18,21A2.5,2.5 0 0,0 20.5,18.5V9C20.5,8.31 20.22,7.68 19.77,7.23M18,10A1,1 0 0,1 17,9A1,1 0 0,1 18,8A1,1 0 0,1 19,9A1,1 0 0,1 18,10M8,18V13.5H6L10,6V11H12L8,18Z";
const colorChartreuse = "#7FFF00";
const colorChartreuseAlpha = "rgba(127, 255, 0, 0.5)";
function processNode(node) {
// 1. Texte (global)
if (node.nodeType === Node.TEXT_NODE) {
for (const [oldText, newText] of Object.entries(translations)) {
if (node.nodeValue.includes(oldText)) {
node.nodeValue = node.nodeValue.replace(new RegExp(oldText, 'g'), newText);
}
}
}
if (node.nodeType === Node.ELEMENT_NODE) {
// 2. CSS Variablen für Charts
if (node.tagName === 'HA-PANEL-ENERGY') {
node.style.setProperty('--energy-gas-color', colorChartreuse);
node.style.setProperty('--state-gas-color', colorChartreuse);
}
// 3. ICON-PFADE & ANIMATION (Suche über den Pfad-Inhalt als Anker)
if (node.tagName === 'path') {
const d = node.getAttribute('d') || "";
// Check A: Ist es die Flamme? (Identifikation über Pfad-Anfang)
if (d.startsWith("M17.66")) {
// Wir prüfen, ob dieser Pfad in einem "gas" Container liegt (DOM-Tree hochwandern)
if (node.closest('.gas') || node.getRootNode().host?.closest('.gas')) {
node.setAttribute('d', pathEV);
}
}
// Check B: Ist es die Animations-Schiene?
if (node.id === 'gas' || d === "M40 0 v30" || d === "M40 0v30") {
node.setAttribute('d', "M40 30 v-30");
node.style.stroke = colorChartreuse;
}
}
// 4. FARBEN (Tabellen & Kreise)
// Kreis-Container einfärben
if (node.classList && node.classList.contains('gas')) {
if (node.classList.contains('circle-container') || node.classList.contains('circle')) {
node.style.color = colorChartreuse;
node.style.borderColor = colorChartreuse;
}
// Animations-Punkt umfärben
if (node.tagName === 'circle') {
node.style.fill = colorChartreuse;
}
}
// Tabellen-Balken über Hex-Code identifizieren
const styleAttrib = node.getAttribute('style') || "";
if (styleAttrib.toLowerCase().includes('8e021b')) {
node.style.backgroundColor = styleAttrib.includes('7f') ? colorChartreuseAlpha : colorChartreuse;
node.style.borderColor = colorChartreuse;
}
// 5. Shadow-DOM Untersuchung
if (node.shadowRoot) {
processShadow(node.shadowRoot);
}
}
node.childNodes.forEach(processNode);
}
function processShadow(root) {
processNode(root);
if (!root._observed) {
const observer = new MutationObserver(() => processNode(root));
observer.observe(root, { childList: true, subtree: true });
root._observed = true;
}
}
setInterval(() => processNode(document.body), 1500);
})();
you can get an Energy Card that looks like this:
Of course you have to make it work with your language by replacing the “Gas” and “Gasverbrauch” with whatever it says in the dashboard in your language and with whatever you want it to say instead of “Wallbox” and “Wallboxverbrauch”. As long as there’s no 1st party way, I’m pretty happy with that workaround!
After saving the file, you have to restart HA and hard reload (without caches!) the website for the changes to apply!