Hi,
Vous avez des panneaux photovoltaïques et des batteries et vous voulez un design un peu plus plaisant que ce qui existe de base sur HA ?
Je vous présente une petite adaptation de la fabuleuse Bubble-Card (merci @Clooos) dans un système de production/stockage d’énergie; Ici avec le système Zendure à adapter à votre système et à vos sensors…
Cettet adaptation de Bubble-card a été reprise ici et là par @Julien_Galliot qui a bien aimé ce format semble-t-il et qui présente très bien l’intégration de Zendure dans HA via ioBroker ou via l’add-on développé par @FireSon que je teste également.
Pour ceux qui sont intéressés, vous devriez pouvoir facilement reproduire ce genre de dashboard avec la Bubble-Card, Card-mod et les quelques ajustements ci-dessous.
Pour les différentes possibilités de la Bubble Card, voir ici : [ CARTE ] Bubble Card - Des pop-up et une collection de cartes minimalistes
Le code est sûrement perfectible, n’hésitez pas
Zendure Flow — flèche rouge/verte dynamique selon le sens de la batterie
Pretez attention au clip-path
qui dessine la flèche selon le flux de la batterie — vous pouvez créer votre propre flèche ou autre forme, voir ici
🧩 Template sensor flow (calcul du flux)
- sensor:
- name: "Zen Flow batt (W)"
unique_id: "zen_flow"
unit_of_measurement: "W"
state_class: measurement
state: >
{% set input = states('sensor.io_zen_recoit_w') | float(0) %}
{% set output = states('sensor.io_zen_envoie_w') | float(0) %}
{{ input - output }}
availability: >
{{ states('sensor.io_zen_recoit_w') not in ['unavailable', 'unknown'] and
states('sensor.io_zen_envoie_w') not in ['unavailable', 'unknown'] }}
device_class: power
🎨 Bubble Card Flow Batterie (trick css)
type: custom:bubble-card
card_type: button
button_type: state
entity: sensor.zen_flow
styles: |-
:host {
--color-negative: #ad2b2b;
--color-positive: #5F730B;
--color-neutral: #4D4D4D;
--color-zero-line: #FFFFFF;
}
.bubble-button-card-container {
position: relative;
border-radius: 8px;
height: 20px;
overflow: hidden;
}
.bubble-button-card-container::before {
content: '';
position: absolute;
top: 0;
height: 100%;
width: 2px;
left: 50%;
background: var(--color-zero-line);
z-index: 2;
transform: translateX(-50%);
}
.bubble-button-card-container::after {
content: '';
position: absolute;
top: 0;
height: 100%;
display: ${hass.states['sensor.zen_flow'].state == -10 ? 'none' : 'block'};
width: max(calc(${Math.abs(hass.states['sensor.zen_flow'].state) / 1500 * 50}%),
${(""+Math.round(hass.states['sensor.zen_flow'].state)).length * 10 + 20}px);
left: ${hass.states['sensor.zen_flow'].state < 0
? 'calc(50% - max(calc(' + (Math.abs(hass.states['sensor.zen_flow'].state) / 1500 * 50) + '%), ' + ((""+Math.round(hass.states['sensor.zen_flow'].state)).length * 10 + 20) + 'px))'
: '50%'};
background: ${hass.states['sensor.zen_flow'].state < 0 ? 'var(--color-negative)' : 'var(--color-positive)'};
z-index: 1;
clip-path: ${hass.states['sensor.zen_flow'].state < 0
? 'polygon(40% 0%, 40% 20%, 100% 20%, 100% 80%, 40% 80%, 40% 100%, 0% 50%)'
: 'polygon(40% 0%, 40% 20%, 0 20%, 0 80%, 40% 80%, 40% 100%, 100% 50%)'};
}
ha-card::after {
position: absolute;
top: 50%;
left: ${hass.states['sensor.zen_flow'].state < 0
? 'calc(50% - max(calc(' + (Math.abs(hass.states['sensor.zen_flow'].state) / 1500 * 50) + '%), ' + ((""+Math.round(hass.states['sensor.zen_flow'].state)).length * 10 + 20) + 'px) / 2)'
: 'calc(50% + max(calc(' + (Math.abs(hass.states['sensor.zen_flow'].state) / 1500 * 50) + '%), ' + ((""+Math.round(hass.states['sensor.zen_flow'].state)).length * 10 + 20) + 'px) / 2)'};
transform: translate(-50%, -50%);
padding: 2px 10px;
border-radius: 25px;
border: 0;
color: #fff;
content: "${Math.round(state)} W";
background: none;
text-align: center;
display: block;
z-index: 3;
}
card_mod:
style: |
ha-icon {
color: {% if states('sensor.zen_flow') | float(0) < 0 %} var(--color-negative)
{% else %} var(--color-positive) {% endif %} !important;
}
icon: ""
name: Flux-batterie
sub_button: []
card_layout: large
slider_live_update: true
show_state: false
show_attribute: false
show_last_changed: false
force_icon: false
grid_options:
columns: 12
rows: 1
scrolling_effect: false
show_icon: true
show_name: false
double_tap_action:
action: more-info
hold_action:
action: more-info
tap_action:
action: navigate
navigation_path: "#shelly"
Production PV (avec météo animée via les icônes de lovelace-meteofrance-weather-card
)
🌤️ Bubble Card PV avec icône météo animée
type: custom:bubble-card
card_type: button
button_type: state
animated_icons: true
entity: sensor.zendure_pv_total
styles: |-
:host {
--color-ok: #bfac1a;
--color-background: var(--bubble-button-main-background-color, var(--bubble-main-background-color, var(--background-color-2, var(--secondary-background-color))));
--color-notification-bubble: #bfac1a;
--color-bar: var(--color-ok);
--progress: ${Math.round((Number(state) < 2200 ? Number(state) : 2200) / 2200 * 100)}%;
}
ha-icon {
background-image: url("/local/community/lovelace-meteofrance-weather-card/icons/${
hass.states['sensor.meteo_ponderee'].state === 'clear-day' ? 'day.svg' :
hass.states['sensor.meteo_ponderee'].state === 'clear-night' ? 'night.svg' :
hass.states['sensor.meteo_ponderee'].state === 'partlycloudy' ? 'cloudy-day-3.svg' :
hass.states['sensor.meteo_ponderee'].state === 'partly-cloudy-day' ? 'cloudy-day-3.svg' :
hass.states['sensor.meteo_ponderee'].state === 'partly-cloudy-night' ? 'cloudy-night-3.svg' :
hass.states['sensor.meteo_ponderee'].state === 'cloudy' ? 'cloudy.svg' :
hass.states['sensor.meteo_ponderee'].state === 'fog' ? 'fog.svg' :
hass.states['sensor.meteo_ponderee'].state === 'windy' ? 'windy.svg' :
hass.states['sensor.meteo_ponderee'].state === 'windy-variant' ? 'windy-night.svg' :
hass.states['sensor.meteo_ponderee'].state === 'hail' ? 'snowy-rainy.svg' :
hass.states['sensor.meteo_ponderee'].state === 'lightning' ? 'thunder.svg' :
hass.states['sensor.meteo_ponderee'].state === 'lightning-rainy' ? 'lightning-rainy.svg' :
hass.states['sensor.meteo_ponderee'].state === 'rainy' ? 'rainy-5.svg' :
hass.states['sensor.meteo_ponderee'].state === 'rainy-5' ? 'rainy-5.svg' :
hass.states['sensor.meteo_ponderee'].state === 'rainy-6' ? 'rainy-6.svg' :
hass.states['sensor.meteo_ponderee'].state === 'rainy-7' ? 'rainy-7.svg' :
hass.states['sensor.meteo_ponderee'].state === 'snowy' ? 'snowy-6.svg' :
hass.states['sensor.meteo_ponderee'].state === 'snowy-rainy' ? 'snowy-rainy.svg' :
hass.states['sensor.meteo_ponderee'].state === 'exceptional' ? 'lightning-rainy.svg' :
'day.svg'
}");
background-size: calc(130%);
background-repeat: no-repeat;
background-position: center;
mask-image: none;
-webkit-mask-image: none;
width: 40px;
height: 40px;
opacity: 0.6!important;
}
.bubble-button-card-container {
background: var(--color-background) !important;
position: relative;
}
.bubble-button-card-container::before {
content: "";
position: absolute;
left: 0;
top: 0;
height: 100%;
width: var(--progress) !important;
background: var(--color-bar) !important;
z-index: 0;
}
@keyframes rotatePulse {
0% { transform: rotate(0deg) scale(1); }
50% { transform: rotate(180deg) scale(1.1); }
100% { transform: rotate(360deg) scale(1); }
}
name: Prod PV
icon: url("/local/community/lovelace-meteofrance-weather-card/icons/day.svg")
sub_button: []
layout_options:
grid_columns: 2
grid_rows: 1
card_layout: large
Affichage des jours Tempo RTE + prix EDF
📘 Stack Bubble RTE (bleu/blanc/rouge + prix)
type: horizontal-stack
cards:
- type: custom:bubble-card
show_state: false
show_attribute: false
show_last_changed: false
force_icon: false
sub_button: []
show_icon: false
scrolling_effect: false
card_layout: large
icon: mdi:calendar-today
name: Aujourd'hui
button_type: state
styles: |-
.bubble-button-card-container {
#background: ${state === 'rouge' ? 'red' : ''} 'red' !important;
#background-color: rgb(71,19,37);
background: ${hass.states['sensor.rte_tempo_couleur_actuelle'].state === 'Rouge'
? 'rgb(142, 35, 35)'
: hass.states['sensor.rte_tempo_couleur_actuelle'].state === 'Blanc'
? 'rgb(201, 191, 191)'
: hass.states['sensor.rte_tempo_couleur_actuelle'].state === 'Bleu'
? 'rgb(15, 117, 137)'
: ''} !important;
border-radius: 32px 0 0 32px !important;
}
attribute: friendly_name
show_name: true
card_type: button
entity: sensor.rte_tempo_couleur_actuelle_visuel
- type: custom:bubble-card
show_state: false
show_attribute: false
show_last_changed: false
force_icon: false
sub_button:
- entity: sensor.rte_tempo_prochaine_couleur_format
show_icon: false
show_state: true
state_background: false
show_background: false
- entity: sensor.edf_tempo_prix_actuel
show_icon: false
state_background: false
show_background: false
show_state: true
show_icon: false
scrolling_effect: false
card_layout: large-2-rows
icon: mdi:calendar-today
name: " "
button_type: state
styles: |-
.bubble-button-card-container {
border-radius: 0 0 0 0 !important;
}
.name-without-icon {
margin-left: 1px !important;
}
attribute: friendly_name
show_name: false
card_type: button
entity: sensor.rte_tempo_prochaine_couleur_format
- type: custom:bubble-card
show_state: true
show_attribute: false
show_last_changed: false
force_icon: false
sub_button: []
show_icon: false
scrolling_effect: false
card_layout: large
icon: mdi:calendar-today
name: " Restants"
button_type: state
styles: |-
.bubble-button-card-container {
border-radius: 0 0 0 0 !important;
}
attribute: friendly_name
show_name: true
columns: 2
rows: 2
card_type: button
entity: sensor.rte_tempo_cycle_jours_restants_rouge
- type: custom:bubble-card
show_state: false
show_attribute: false
show_last_changed: false
force_icon: false
sub_button: []
show_icon: false
scrolling_effect: false
card_layout: large
icon: mdi:calendar-today
name: demain
button_type: state
styles: |-
.bubble-button-card-container {
#background: rgb(206, 30, 30) !important;
background: ${hass.states['sensor.rte_tempo_prochaine_couleur'].state === 'Rouge'
? 'rgb(142, 35, 35)'
: hass.states['sensor.rte_tempo_prochaine_couleur'].state === 'Blanc'
? 'rgb(201, 191, 191)'
: hass.states['sensor.rte_tempo_prochaine_couleur'].state === 'Bleu'
? 'rgb(15, 117, 137)'
: ''} !important;
border-radius: 0 32px 32px 0 !important;
}
attribute: friendly_name
show_name: true
columns: 2
rows: 2
card_type: button
entity: sensor.rte_tempo_prochaine_couleur_visuel
Affichage en dégradé (gradient) pour pièces ou zones
🏡 Carte à fond rayé pour zones personnalisées (petit trick css)
type: horizontal-stack
cards:
- type: custom:bubble-card
entity: sensor.shelly_3em_c_power
card_mod:
style: >
.bubble-button-background {
background: linear-gradient(45deg, #72500b 1%, #fff 1%, #fff 49%,
#72500b 49%, #72500b 51%, #fff 51%, #fff 99%, #72500b 99%);
background-size: 10px 10px;
background-position: 0 0;
}
- type: custom:bubble-card
entity: sensor.conso_maison_instant_w
card_mod:
style: >
.bubble-button-background {
background: linear-gradient(45deg, #72500b 1%, #fff 1%, #fff 49%,
#72500b 49%, #72500b 51%, #fff 51%, #fff 99%, #72500b 99%);
background-size: 10px 10px;
background-position: 0 0;
}