Skip to content

Commit 993b3b6

Browse files
author
Sebastian N.
committed
fixed labels; added max input power for pv string 2-4; add possibility to hide icon; some refactoring
1 parent 1cf682b commit 993b3b6

7 files changed

Lines changed: 98 additions & 50 deletions

File tree

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,12 @@ For the compact card, it’s enough to provide e.g. `battery_percentage`, `solar
147147
| `production` | boolean | Show production card | `true` |
148148
| `settings` | boolean | Show settings card | `true` |
149149
| `solar` | boolean | Show solar card | `true` |
150+
| `icon` | boolean | Show storage icon | `true` |
150151
| `compact` | boolean | Show compact version | `false` |
151-
| `max_input_power` | number | Maximum input power per input (W), for scaling P1/P2 bars | `600` |
152+
| `max_input_power` | number | Maximum input power for scaling P1 bar | `600` |
153+
| `max_input_power2` | number | Maximum input power for scaling P2 bar | `600` |
154+
| `max_input_power3` | number | Maximum input power for scaling P3 bar | `600` |
155+
| `max_input_power4` | number | Maximum input power for scaling P4 bar | `600` |
152156
| `p3_power` | string | PV string 3 sensor | `null`|
153157
| `p4_power` | string | PV string 4 sensor | `null`|
154158
| `last_update` | string | ISO 8601 string for last update | `n/a`|

b2500d-card.js

Lines changed: 63 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,8 @@ class B2500DCard extends LitElement {
219219
right:0; left:auto;
220220
background: rgb(84, 158,164);
221221
}
222-
.barlabels{ display:flex; justify-content:space-between; margin-top:8px; font-weight:400; color: #549EA4; }
223-
.barlabels .hint{ color: #549EA4; font-weight:400; font-size:12px; margin-top:2px }
222+
.barlabels{ display:flex; justify-content:space-around; margin-top:8px; font-weight:400; color: #549EA4; align-items: center; }
223+
.barlabels .hint{ color: #549EA4; font-weight:400; font-size:12px; margin-top:2px; }
224224
225225
.battery{
226226
display:flex; align-items:center; justify-content:center; padding:10px 0 4px;
@@ -384,6 +384,7 @@ class B2500DCard extends LitElement {
384384
settings: true,
385385
solar: true,
386386
compact: false,
387+
icon: true,
387388
...config
388389
};
389390
if (this._hass) {
@@ -533,7 +534,7 @@ class B2500DCard extends LitElement {
533534
const date = new Date(isoString);
534535

535536
const year = date.getFullYear();
536-
const month = String(date.getMonth() + 1).padStart(2, '0'); // Monate 0-11
537+
const month = String(date.getMonth() + 1).padStart(2, '0');
537538
const day = String(date.getDate()).padStart(2, '0');
538539
const hour = String(date.getHours()).padStart(2, '0');
539540
const minute = String(date.getMinutes()).padStart(2, '0');
@@ -544,40 +545,20 @@ class B2500DCard extends LitElement {
544545

545546

546547

547-
render() {
548-
if (this._configError) {
549-
return html`<ha-alert alert-type="error">${this._configError}</ha-alert>`;
550-
}
551-
552-
const solar = Number(this._solarPower);
553-
const output = Number(this._outputPower);
548+
//RENDER COMPACT
549+
_renderCompact(batteryClass){
550+
const percent = this._batteryPercent ?? 0;
554551

555-
const lang = this._hass?.language || "en";
556-
const batteryClass = solar > output && this._batteryPercent < 100
557-
? 'charging'
558-
: output > solar && this._batteryPercent > 0
559-
? 'discharging'
560-
: '';
561-
562-
563-
564-
if (this.config.compact) {
565-
const percent = this._batteryPercent ?? 0;
566-
567-
// Farbe bestimmen
568552
let color = "green";
569553
if (percent <= 19) {
570554
color = "red";
571555
} else if (percent <= 59) {
572556
color = "orange";
573557
}
574-
// Icon abhängig vom Prozentwert wählen (auf nächste 10 abrunden)
575558
let icon = "";
576559
if (percent >= 100) {
577-
// Sonderfall: 100% hat eigenes Icon
578560
icon = "mdi:battery";
579561
} else if (percent < 10) {
580-
// Unter 10% gibt es nur die Outline-Version
581562
icon = "mdi:battery-outline";
582563
} else {
583564
let level = Math.floor(percent / 10) * 10;
@@ -614,14 +595,52 @@ class B2500DCard extends LitElement {
614595
</div>
615596
</div>
616597
`;
598+
}
599+
600+
//RENDER UNIT
601+
_renderUnit(batteryClass){
602+
return html`
603+
<div class="unit">
604+
<div class="battery-bar">
605+
<div class="battery-fill ${batteryClass}" style="height:${Math.min(this._batteryPercent, 98)}%"></div>
606+
</div>
607+
</div>
608+
`
609+
}
610+
611+
612+
/////////////////
613+
// RENDER
614+
/////////////////
615+
render() {
616+
if (this._configError) {
617+
return html`<ha-alert alert-type="error">${this._configError}</ha-alert>`;
618+
}
619+
620+
const solar = Number(this._solarPower);
621+
const output = Number(this._outputPower);
622+
623+
const lang = this._hass?.language || "en";
624+
const batteryClass = solar > output && this._batteryPercent < 100
625+
? 'charging'
626+
: output > solar && this._batteryPercent > 0
627+
? 'discharging'
628+
: '';
629+
630+
if (this.config.compact) {
631+
return this._renderCompact(batteryClass);
617632
}
618633

619634
// Fallback: 600 wenn nix übergeben (standard beim b2500d)
620635
const maxInputPower = this.config.max_input_power || 600;
636+
const maxInputPower2 = this.config.max_input_power2 || 600;
637+
const maxInputPower3 = this.config.max_input_power3 || 600;
638+
const maxInputPower4 = this.config.max_input_power4 || 600;
639+
621640
const p1Pct = Math.round((this._p1 / maxInputPower) * 100);
622-
const p2Pct = Math.round((this._p2 / maxInputPower) * 100);
623-
const p3Pct = Math.round((this._p3 / maxInputPower) * 100);
624-
const p4Pct = Math.round((this._p4 / maxInputPower) * 100);
641+
const p2Pct = Math.round((this._p2 / maxInputPower2) * 100);
642+
const p3Pct = Math.round((this._p3 / maxInputPower3) * 100);
643+
const p4Pct = Math.round((this._p4 / maxInputPower4) * 100);
625644

626645

627646
const selectEntity = this._hass.states[`select.${this.config.device}_charging_mode`];
@@ -642,11 +661,7 @@ class B2500DCard extends LitElement {
642661
</div>
643662
644663
<!-- Unit mit Akku-Balken -->
645-
<div class="unit">
646-
<div class="battery-bar">
647-
<div class="battery-fill ${batteryClass}" style="height:${Math.min(this._batteryPercent, 98)}%"></div>
648-
</div>
649-
</div>
664+
${this.config.icon ? this._renderUnit(batteryClass):""}
650665
</div>
651666
652667
<section class="grid">
@@ -667,9 +682,9 @@ class B2500DCard extends LitElement {
667682
<div class="barwrap">
668683
<div class="bar"><div class="fill" style="width:${p1Pct}%"></div></div>
669684
<div class="bar ${this._p3 == null && this._p4 == null ? "r" : ""}"><div class="fill" style="width:${p2Pct}%"></div></div>
670-
${this._p3 != null ? html`<div class="bar r"><div class="fill" style="width:${p3Pct}%"></div></div>`
685+
${this._p3 != null ? html`<div class="bar"><div class="fill" style="width:${p3Pct}%"></div></div>`
671686
: ""}
672-
${this._p4 != null ? html`<div class="bar r"><div class="fill" style="width:${p4Pct}%"></div></div>`
687+
${this._p4 != null ? html`<div class="bar"><div class="fill" style="width:${p4Pct}%"></div></div>`
673688
: ""}
674689
</div>
675690
<div class="barlabels">
@@ -832,7 +847,7 @@ class B2500DCard extends LitElement {
832847
? html`<div class="divider"></div>`
833848
: html``;
834849
835-
// Switch
850+
836851
if (entity.entity_id.startsWith("switch.")) {
837852
return html`
838853
<div class="row">
@@ -854,7 +869,7 @@ class B2500DCard extends LitElement {
854869
`;
855870
}
856871
857-
// Select
872+
858873
if (entity.entity_id.startsWith("select.")) {
859874
return html`
860875
<div class="row">
@@ -882,7 +897,6 @@ class B2500DCard extends LitElement {
882897
`;
883898
}
884899
885-
// Fallback (read-only)
886900
return html`
887901
<div class="row">
888902
<div class="left">
@@ -927,15 +941,18 @@ class B2500DCardEditor extends LitElement {
927941

928942

929943
setConfig(config) {
930-
// Defaults behalten, damit Felder sichtbar sind
931944
this._config = {
932945
output: true,
933946
battery: true,
934947
production: true,
935948
settings: true,
936949
solar: true,
950+
icon: true,
937951
compact: false,
938952
max_input_power: 600,
953+
max_input_power2: 600,
954+
max_input_power3: 600,
955+
max_input_power4: 600,
939956
entities: {
940957
battery_percentage: "",
941958
battery_capacity: "",
@@ -960,7 +977,6 @@ class B2500DCardEditor extends LitElement {
960977

961978
const newConfig = { ...ev.detail.value };
962979

963-
// Wenn entities leer oder alle Werte leer, entfernen
964980
if (newConfig.entities) {
965981
const isEmpty = Object.values(newConfig.entities).every(
966982
(v) => v === null || v === undefined || v === ""
@@ -1028,13 +1044,16 @@ class B2500DCardEditor extends LitElement {
10281044
},
10291045
},
10301046
{ name: "compact", selector: { boolean: {} } },
1047+
{ name: "icon", selector: { boolean: {} } },
10311048
{ name: "solar", selector: { boolean: {} } },
10321049
{ name: "output", selector: { boolean: {} } },
10331050
{ name: "battery", selector: { boolean: {} } },
10341051
{ name: "production", selector: { boolean: {} } },
10351052
{ name: "settings", selector: { boolean: {} } },
1036-
{ name: "max_input_power", selector: { number: { min: 100, max: 5000, step: 50 } },
1037-
},
1053+
{ name: "max_input_power", selector: { number: { min: 100, max: 5000, step: 50 } }},
1054+
{ name: "max_input_power2", selector: { number: { min: 100, max: 5000, step: 50 } }},
1055+
{ name: "max_input_power3", selector: { number: { min: 100, max: 5000, step: 50 } }},
1056+
{ name: "max_input_power4", selector: { number: { min: 100, max: 5000, step: 50 } }},
10381057
];
10391058

10401059
return html`
@@ -1060,4 +1079,4 @@ window.customCards.push({
10601079
preview: false,
10611080
description: "Visualizing solar storage systems",
10621081

1063-
});
1082+
});

localize/de.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default {
2626
"device": "Geräte-ID (z. B. b2500d)",
2727
"entities": "Alternative Entitäten (Objekt)",
2828
"compact": "Kompakt-Ansicht",
29+
"icon": "Speicher Icon anzeigen",
2930
"solar": "Solar anzeigen",
3031
"output": "Ausgang anzeigen",
3132
"battery": "Batterie anzeigen",
@@ -38,8 +39,12 @@ export default {
3839
"device": "Gib die Geräte-Kurzbezeichnung an (nur ODER, nicht beides: device ODER entities).",
3940
"entities": "Alternativ: Objekt mit Entitäten (z. B. { \"solar_power\": \"sensor.x\" })",
4041
"compact": "Zeigt eine kompaktere Variante der Karte",
42+
"icon": "Blendet das Speicher Icon aus",
4143
"settings": "Wird nur angezeigt, wenn Geräte-ID verwendet wird",
42-
"max_input_power": "Maximale Eingangsleistung am Speicher pro Eingang",
44+
"max_input_power": "Maximale Eingangsleistung String 1",
45+
"max_input_power2": "Maximale Eingangsleistung String 2",
46+
"max_input_power3": "Maximale Eingangsleistung String 3",
47+
"max_input_power4": "Maximale Eingangsleistung String 4",
4348
"custom_settings" : "Füge hier deine benutzerdefinierten Einstellungen hinzu (nur Entitiy Modus)",
4449
}
4550
};

localize/en.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default {
2626
"device": "Device ID (e.g. b2500d)",
2727
"entities": "Alternative Entities (object)",
2828
"compact": "Compact View",
29+
"icon": "Show storage icon",
2930
"solar": "Show Solar",
3031
"output": "Show Output",
3132
"battery": "Show Battery",
@@ -38,8 +39,12 @@ export default {
3839
"device": "Enter the device short name (only ONE: either device OR entities).",
3940
"entities": "Alternative: object with entities (e.g. { \"solar_power\": \"sensor.x\" })",
4041
"compact": "Shows a more compact version of the card",
42+
"icon": "Hide the storage icon",
4143
"settings": "Only shown if device ID is used",
42-
"max_input_power": "Maximum input power per input of the storage system",
44+
"max_input_power": "Maximum input power string 1",
45+
"max_input_power2": "Maximum input power string 2",
46+
"max_input_power3": "Maximum input power string 3",
47+
"max_input_power4": "Maximum input power string 4",
4348
"custom_settings": "Add your custom settings here (entities mode only)",
4449
}
4550
};

localize/es.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default {
2626
"device": "ID del dispositivo (ej. b2500d)",
2727
"entities": "Entidades alternativas (objeto)",
2828
"compact": "Vista compacta",
29+
"icon": "Mostrar icono de almacenamiento",
2930
"solar": "Mostrar solar",
3031
"output": "Mostrar salida",
3132
"battery": "Mostrar batería",
@@ -38,8 +39,12 @@ export default {
3839
"device": "Introduce el nombre corto del dispositivo (solo UNO: device O entities).",
3940
"entities": "Alternativa: objeto con entidades (ej. { \"solar_power\": \"sensor.x\" })",
4041
"compact": "Muestra una versión más compacta de la tarjeta",
42+
"icon": "Ocultar icono de almacenamiento",
4143
"settings": "Solo se muestra si se utiliza la ID del dispositivo",
42-
"max_input_power": "Potencia máxima de entrada por cada entrada del sistema de almacenamiento",
44+
"max_input_power": "Potencia de entrada máxima cadena 1",
45+
"max_input_power2": "Potencia de entrada máxima cadena 2",
46+
"max_input_power3": "Potencia de entrada máxima cadena 3",
47+
"max_input_power4": "Potencia de entrada máxima cadena 4",
4348
"custom_settings": "Agrega tus ajustes personalizados aquí (solo modo entidades)",
4449
}
4550
};

localize/fr.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default {
2626
"device": "ID de l’appareil (ex. b2500d)",
2727
"entities": "Entités alternatives (objet)",
2828
"compact": "Vue compacte",
29+
"icon": "Afficher l’icône de stockage",
2930
"solar": "Afficher solaire",
3031
"output": "Afficher sortie",
3132
"battery": "Afficher batterie",
@@ -38,8 +39,12 @@ export default {
3839
"device": "Indiquez le nom abrégé de l’appareil (un seul : device OU entities).",
3940
"entities": "Alternative : objet avec entités (ex. { \"solar_power\": \"sensor.x\" })",
4041
"compact": "Affiche une version plus compacte de la carte",
42+
"icon": "Masquer l’icône de stockage",
4143
"settings": "Uniquement affiché si un ID d’appareil est utilisé",
42-
"max_input_power": "Puissance d’entrée maximale par entrée du système de stockage",
44+
"max_input_power": "Puissance d’entrée maximale chaîne 1",
45+
"max_input_power2": "Puissance d’entrée maximale chaîne 2",
46+
"max_input_power3": "Puissance d’entrée maximale chaîne 3",
47+
"max_input_power4": "Puissance d’entrée maximale chaîne 4",
4348
"custom_settings": "Ajoutez vos paramètres personnalisés ici (mode entités uniquement)",
4449
}
4550
};

localize/nl.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default {
2626
"device": "Device ID (bv. b2500d)",
2727
"entities": "Alternatieve entiteiten (object)",
2828
"compact": "Compacte weergave",
29+
"icon": "Opslagpictogram weergeven",
2930
"solar": "Toon zonne-energie",
3031
"output": "Toon uitvoer",
3132
"battery": "Toon batterij",
@@ -38,8 +39,12 @@ export default {
3839
"device": "Voer de korte naam van het apparaat in (slechts ÉÉN: of device OF entities).",
3940
"entities": "Alternatief: object met entiteiten (bv. { \"solar_power\": \"sensor.x\" })",
4041
"compact": "Toont een compactere versie van de kaart",
42+
"icon": "Opslagpictogram verbergen",
4143
"settings": "Alleen zichtbaar als een Device ID wordt gebruikt",
42-
"max_input_power": "Maximaal invoervermogen per ingang van het opslagsysteem",
44+
"max_input_power": "Maximaal ingangsvermogen string 1",
45+
"max_input_power2": "Maximaal ingangsvermogen string 2",
46+
"max_input_power3": "Maximaal ingangsvermogen string 3",
47+
"max_input_power4": "Maximaal ingangsvermogen string 4",
4348
"custom_settings": "Voeg hier je aangepaste instellingen toe (alleen in entities-modus)",
4449
}
4550
};

0 commit comments

Comments
 (0)