Salut, tu passes par un stack-in-card puis un horizontal-stack puis un vertical-stack avec des button-card, une flex-horseshoe-card et du card-mod pour compliquer encore tout ça… Tu pouvais faire beaucoup plus simple avec une seule button-card et des custom_fields (dont un avec ta flex-horseshoe-card) qui te permettrait de gérer les positionnements au pixel près.
Un exemple de button-card avec de multiples custom_fields dont l’emplacement sur la carte peut être réglé au pixel près :
et le code :
type: custom:button-card
aspect_ratio: 4/3.5
custom_fields:
fond:
card:
type: custom:button-card
styles:
card:
- background-color: rgba(255,255,255,0.0)
- border: none
tap_action:
action: none
hold_action:
action: none
ncarte:
card:
type: custom:button-card
name: Salon
styles:
name:
- font-size: 1.4em
- font-weight: bold
- justify-self: start
- color: rgba(0,0,0,0.6)
card:
- background-color: rgba(255,255,255,0.0)
- border: none
tap_action:
action: none
hold_action:
action: none
eclairage:
card:
type: custom:button-card
name: 'Éclairage :'
styles:
name:
- font-size: 1.0em
- font-weight: bold
- color: rgba(0,0,0,0.6)
- justify-self: start
card:
- background-color: rgba(255,255,255,0.0)
- border: none
nplafonnier:
card:
type: custom:button-card
name: Plafonnier
styles:
name:
- font-size: 0.7em
- font-weight: bold
- color: rgba(0,0,0,0.6)
card:
- background-color: rgba(255,255,255,0.0)
- border-radius: 0%
- border: none
tap_action:
action: none
hold_action:
action: none
plafonnier:
card:
type: custom:button-card
size: 80%
entity: light.salon_plafonnier
icon: phu:ceiling-fugato-three
show_name: false
state:
- value: 'off'
styles:
icon:
- color: dimgray
card:
- box-shadow: none
- border-radius: 50%
- background-color: rgba(242,242,242,0.7)
- width: 48px
- height: 48px
- value: 'on'
styles:
icon:
- color: rgb(255,255,128)
card:
- border-radius: 50%
- box-shadow: 0px 0px 6px 3px rgba(255,255,128,0.8)
- background-color: rgba(0,0,0,0.5)
- width: 48px
- height: 48px
nlampadaire:
card:
type: custom:button-card
name: Lampadaire
styles:
name:
- font-size: 0.7em
- font-weight: bold
- color: rgba(0,0,0,0.6)
card:
- background-color: rgba(255,255,255,0.0)
- border-radius: 0%
- border: none
tap_action:
action: none
hold_action:
action: none
lampadaire:
card:
type: custom:button-card
size: 85%
entity: light.salon_lampadaire
icon: mdi:floor-lamp-torchiere
show_name: false
state:
- value: 'off'
styles:
icon:
- color: dimgray
card:
- box-shadow: none
- border-radius: 50%
- background-color: rgba(242,242,242,0.7)
- width: 48px
- height: 48px
- value: 'on'
styles:
icon:
- color: rgb(255,255,128)
card:
- border-radius: 50%
- box-shadow: 0px 0px 6px 3px rgba(255,255,128,0.8)
- background-color: rgba(0,0,0,0.5)
- width: 48px
- height: 48px
nlampe_poele:
card:
type: custom:button-card
name: Lampe<br/>(poële)
styles:
name:
- font-size: 0.7em
- font-weight: bold
- color: rgba(0,0,0,0.6)
card:
- background-color: rgba(255,255,255,0.0)
- border-radius: 0%
- border: none
tap_action:
action: none
hold_action:
action: none
lampe_poele:
card:
type: custom:button-card
size: 85%
entity: light.salon_lampe_poele
icon: mdi:lamp
show_name: false
state:
- value: 'off'
styles:
icon:
- color: dimgray
card:
- box-shadow: none
- border-radius: 50%
- background-color: rgba(242,242,242,0.7)
- width: 48px
- height: 48px
- value: 'on'
styles:
icon:
- color: rgb(255,255,128)
card:
- border-radius: 50%
- box-shadow: 0px 0px 6px 3px rgba(255,255,128,0.8)
- background-color: rgba(0,0,0,0.5)
- width: 48px
- height: 48px
nlampe_biblio:
card:
type: custom:button-card
name: Lampe<br/>(bibliothèque)
styles:
name:
- font-size: 0.7em
- font-weight: bold
- color: rgba(0,0,0,0.6)
card:
- background-color: rgba(255,255,255,0.0)
- border-radius: 0%
- border: none
tap_action:
action: none
hold_action:
action: none
lampe_biblio:
card:
type: custom:button-card
size: 85%
entity: light.salon_lampe_bibliotheque
icon: mdi:lamp
show_name: false
state:
- value: 'off'
styles:
icon:
- color: dimgray
card:
- box-shadow: none
- border-radius: 50%
- background-color: rgba(242,242,242,0.7)
- width: 48px
- height: 48px
- value: 'on'
styles:
icon:
- color: rgb(255,255,128)
card:
- border-radius: 50%
- box-shadow: 0px 0px 6px 3px rgba(255,255,128,0.8)
- background-color: rgba(0,0,0,0.5)
- width: 48px
- height: 48px
temp_value:
card:
type: custom:button-card
entity: sensor.echo_salon_temperature
show_name: false
show_icon: false
show_state: true
tap_action: none
styles:
state:
- font-size: 0.82em
- font-weight: bold
- color: dimgray
- justify-self: end
- padding-right: 3%
card:
- background-color: rgba(255,255,255,0.5)
temp:
card:
type: custom:button-card
aspect_ratio: 1/1
show_name: false
show_icon: false
styles:
card:
- opacity: 1
- background-image: url(/local/images/icones/temperature.png)
- background-size: cover
- background-position: center
- background-color: rgba(0,0,0,0.0)
- border: none
ambiances:
card:
type: custom:button-card
name: 'Ambiances :'
styles:
name:
- font-size: 1.0em
- font-weight: bold
- color: rgba(0,0,0,0.6)
- justify-self: start
card:
- background-color: rgba(255,255,255,0.0)
- border: none
ndiner:
card:
type: custom:button-card
name: Dîner<br/>salon
styles:
name:
- font-size: 0.7em
- font-weight: bold
- color: rgba(0,0,0,0.6)
card:
- background-color: rgba(255,255,255,0.0)
- border-radius: 0%
- border: none
tap_action:
action: none
hold_action:
action: none
diner:
card:
type: custom:button-card
size: 80%
icon: mdi:silverware-clean
show_name: false
styles:
icon:
- color: dimgray
card:
- box-shadow: none
- border-radius: 50%
- background-color: rgba(242,242,242,0.7)
- width: 48px
- height: 48px
tap_action:
action: call-service
service: script.diner_salon
ntv:
card:
type: custom:button-card
name: Regarder la<br/>télévision
styles:
name:
- font-size: 0.7em
- font-weight: bold
- color: rgba(0,0,0,0.6)
card:
- background-color: rgba(255,255,255,0.0)
- border-radius: 0%
- border: none
tap_action:
action: none
hold_action:
action: none
tv:
card:
type: custom:button-card
size: 80%
icon: mdi:television-shimmer
show_name: false
styles:
icon:
- color: dimgray
card:
- box-shadow: none
- border-radius: 50%
- background-color: rgba(242,242,242,0.7)
- width: 48px
- height: 48px
tap_action:
action: call-service
service: script.ambiance_television
neteindre:
card:
type: custom:button-card
name: Tout<br/>éteindre
styles:
name:
- font-size: 0.7em
- font-weight: bold
- color: rgba(0,0,0,0.6)
card:
- background-color: rgba(255,255,255,0.0)
- border-radius: 0%
- border: none
tap_action:
action: none
hold_action:
action: none
eteindre:
card:
type: custom:button-card
size: 70%
icon: mdi:lightbulb-group-off
show_name: false
styles:
icon:
- color: dimgray
card:
- box-shadow: none
- border-radius: 50%
- background-color: rgba(242,242,242,0.7)
- width: 48px
- height: 48px
tap_action:
action: call-service
service: script.eteindre_salon
volet_canape:
card:
type: custom:button-card
name: 'Volet canapé :'
styles:
name:
- font-size: 1.0em
- font-weight: bold
- color: rgba(0,0,0,0.6)
- justify-self: start
card:
- background-color: rgba(255,255,255,0.0)
- border-radius: 0%
- border: none
tap_action:
action: none
hold_action:
action: none
vcup:
card:
type: custom:button-card
show_name: false
styles:
card:
- background-color: rgba(255,255,255,0.0)
- background-image: url(/local/images/icones/volet_ouvrir.png)
- background-size: cover
- height: 48px
- width: 48px
- border: none
tap_action:
action: call-service
service: script.ouvrir_volet_canape
vcstop:
card:
type: custom:button-card
show_name: false
styles:
card:
- background-color: rgba(255,255,255,0.0)
- background-image: url(/local/images/icones/volet_stopper.png)
- background-size: cover
- height: 48px
- width: 48px
- border: none
tap_action:
action: call-service
service: script.stopper_volet_canape
vcdown:
card:
type: custom:button-card
show_name: false
styles:
card:
- background-color: rgba(255,255,255,0.0)
- background-image: url(/local/images/icones/volet_fermer.png)
- background-size: cover
- height: 48px
- width: 48px
- border: none
tap_action:
action: call-service
service: script.fermer_volet_canape
volet_biblio:
card:
type: custom:button-card
name: 'Volet bibliothèque :'
styles:
name:
- font-size: 1.0em
- font-weight: bold
- color: rgba(0,0,0,0.6)
- justify-self: start
card:
- background-color: rgba(255,255,255,0.0)
- border-radius: 0%
- border: none
tap_action:
action: none
hold_action:
action: none
vbup:
card:
type: custom:button-card
show_name: false
styles:
card:
- background-color: rgba(255,255,255,0.0)
- background-image: url(/local/images/icones/volet_ouvrir.png)
- background-size: cover
- height: 48px
- width: 48px
- border: none
tap_action:
action: call-service
service: script.ouvrir_volet_bibliotheque
vbstop:
card:
type: custom:button-card
show_name: false
styles:
card:
- background-color: rgba(255,255,255,0.0)
- background-image: url(/local/images/icones/volet_stopper.png)
- background-size: cover
- height: 48px
- width: 48px
- border: none
tap_action:
action: call-service
service: script.stopper_volet_biblioteque
vbdown:
card:
type: custom:button-card
show_name: false
styles:
card:
- background-color: rgba(255,255,255,0.0)
- background-image: url(/local/images/icones/volet_fermer.png)
- background-size: cover
- height: 48px
- width: 48px
- border: none
tap_action:
action: call-service
service: script.fermer_volet_bibliotheque
styles:
custom_fields:
fond:
- background-image: url(/local/images/salon.png)
- position: absolute
- left: 0
- top: 0
- width: 100%
- height: 100%
- background-size: cover
- background-position: center
- opacity: 0.5
ncarte:
- position: absolute
- left: 10px
- top: '-3px'
eclairage:
- position: absolute
- left: 11%
- top: 20%
nplafonnier:
- position: absolute
- left: 32%
- top: 6%
plafonnier:
- position: absolute
- left: 33%
- top: 17%
nlampadaire:
- position: absolute
- left: 45%
- top: 11%
lampadaire:
- position: absolute
- left: 47%
- top: 17%
nlampe_poele:
- position: absolute
- left: 65%
- top: 6%
lampe_poele:
- position: absolute
- left: 64%
- top: 17%
nlampe_biblio:
- position: absolute
- left: 78%
- top: 6%
lampe_biblio:
- position: absolute
- left: 80%
- top: 17%
temp_value:
- width: 19%
- position: absolute
- left: 11%
- top: 35%
temp:
- width: 40px
- height: 40px
- position: absolute
- left: 5%
- top: 32%
ambiances:
- position: absolute
- left: 11%
- top: 48%
ndiner:
- position: absolute
- left: 43%
- top: 34%
diner:
- position: absolute
- left: 41%
- top: 45%
ntv:
- position: absolute
- left: 59%
- top: 34%
tv:
- position: absolute
- left: 61%
- top: 45%
neteindre:
- position: absolute
- left: 80%
- top: 34%
eteindre:
- position: absolute
- left: 79%
- top: 45%
volet_canape:
- position: absolute
- left: 11%
- top: 68%
vcup:
- position: absolute
- left: 42%
- top: 65%
vcstop:
- position: absolute
- left: 57%
- top: 65%
vcdown:
- position: absolute
- left: 72%
- top: 65%
volet_biblio:
- position: absolute
- left: 11%
- top: 85%
vbup:
- position: absolute
- left: 53%
- top: 82%
vbstop:
- position: absolute
- left: 68%
- top: 82%
vbdown:
- position: absolute
- left: 83%
- top: 82%
Un autre exemple avec un custom_field basé sur une carte autre qu’une button-card (bar-card) :
type: custom:stack-in-card
mode: vertical
background: true
card_mod:
style: |
ha-card {
border: none;
background-color: rgba(75,75,76,1.0);
}
cards:
- type: custom:button-card
aspect_ratio: 1/0.7
tap_action:
action: none
hold_action:
action: none
custom_fields:
ncarte:
card:
type: custom:button-card
name: Voiture
tap_action:
action: none
hold_action:
action: none
lock:
enabled: true
exemptions: []
styles:
card:
- border-radius: 0%
- border: none
- background-color: rgba(75,75,76,1.0)
- height: 40px
lock:
- opacity: 0
name:
- font-size: 1.4em
- font-weight: bold
- justify-self: start
- padding-left: 10px
- color: rgba(0,0,0,0.6)
nkilometrage:
card:
type: custom:button-card
name: 'Kilométrage total :'
styles:
card:
- background-color: rgba(75,75,76,0.0)
- border-radius: 0%
- border: none
- height: 40px
name:
- font-size: 0.8em
- font-weight: bold
- color: lightgray
- justify-self: end
- padding-right: 5px
kilometrage:
card:
type: custom:button-card
entity: sensor.sensor.lsjwhxxxxxxxxxx_mileage
show_name: false
show_icon: false
show_state: true
tap_action:
action: none
hold_action:
action: none
lock:
enabled: true
exemptions: []
styles:
card:
- border-radius: 0%
- border: none
- background-color: rgba(75,75,76,0.0)
- height: 40px
lock:
- opacity: 0
state:
- font-size: 1.1em
- font-weight: bold
- color: lightgray
- justify-self: end
mgicon:
card:
type: custom:button-card
icon: phu:mg
show_icon: true
styles:
card:
- border-radius: 0%
- border: none
- background-color: rgba(75,75,76,0.0)
- height: 40px
icon:
- color: lightgray
- padding-left: 10px
fond:
card:
type: custom:button-card
tap_action:
action: none
hold_action:
action: none
styles:
card:
- border-radius: 0%
- border: none
- background-color: rgba(75,75,76,0.0)
- aspect-ratio: 2/1
ncharge:
card:
type: custom:button-card
name: 'Niveau de charge :'
styles:
card:
- border-radius: 0%
- border: none
- background-color: rgba(75,75,76,1.0)
- height: 40px
name:
- font-size: 0.8em
- font-weight: bold
- color: lightgray
- justify-self: start
- align-self: end
- padding-left: 20px
- padding-top: 12px
charge_en_cours:
card:
type: custom:button-card
entity: binary_sensor.sensor.lsjwhxxxxxxxxxx_battery_charging
name: Charge en cours
show_state: false
show_icon: false
tap_action:
action: none
hold_action:
action: none
state:
- value: 'off'
styles:
name:
- color: rgba(0,0,0,0.0)
- value: 'on'
styles:
name:
- animation: colorswap 5s linear infinite
styles:
card:
- border: none
- background-color: rgba(75,75,76,1.0)
name:
- font-size: 1.0em
- font-weight: bold
- justify-self: start
- align-self: end
- padding-top: 7px
extra_styles: |
@keyframes colorswap {
0% {
color: rgba(0,0,0,0.0);
}
25% {
color: rgba(0,0,0,0.3);
}
50% {
color: rgba(0,0,0,0.0);
}
75% {
color: rgba(0,0,0,0.3);
}
100% {
color: rgba(0,0,0,0.0);
}
}
icone_charge_en_cours:
card:
type: custom:button-card
entity: binary_sensor.sensor.lsjwhxxxxxxxxxx_battery_charging
show_icon: false
show_name: false
show_state: false
aspect_ratio: 1/1
tap_action:
action: none
hold_action:
action: none
state:
- value: 'off'
styles:
card:
- background-color: rgba(75,75,76,0.0)
- border: none
- value: 'on'
styles:
card:
- animation: pictureswap 3s linear infinite
- background-size: cover
- background-color: rgba(75,75,76,0.0)
- border: none
extra_styles: |
@keyframes pictureswap {
0% {
background-image: url("/local/images/icones/charge_1.png");
}
25% {
background-image: url("/local/images/icones/charge_2.png");
}
50% {
background-image: url("/local/images/icones/charge_3.png");
}
75% {
background-image: url("/local/images/icones/charge_4.png");
}
100% {
background-image: url("/local/images/icones/charge_5.png");
}
}
bouton_config:
card:
type: custom:button-card
styles:
card:
- background-color: rgba(211,211,211,1.0)
- background-image: url(/local/images/icones/MG_config.png)
- background-size: cover
- border-radius: 50%
- height: 48px
- width: 48px
- box-shadow: 2px 2px 4px 0px rgba(32,32,32,0.5)
- border: 2px rgba(211,211,211,1.0) outset
bouton_info:
card:
type: custom:button-card
styles:
card:
- background-color: rgba(211,211,211,1.0)
- background-image: url(/local/images/icones/MG_info.png)
- background-size: cover
- border-radius: 50%
- width: 48px
- height: 48px
- box-shadow: 2px 2px 4px 0px rgba(32,32,32,0.5)
- border: 2px rgba(211,211,211,1.0) outset
bouton_charge:
card:
type: custom:button-card
entity: binary_sensor.sensor.lsjwhxxxxxxxxxx_charger_connected
show_name: false
show_icon: false
state:
- value: 'off'
styles:
card:
- height: 0px
- width: 0px
- border: none
- value: 'on'
styles:
card:
- height: 48px
- width: 48px
- border: 2px rgba(211,211,211,1.0) outset
styles:
card:
- background-color: rgba(211,211,211,1.0)
- background-image: url(/local/images/icones/MG_charge.png)
- background-size: cover
- border-radius: 50%
- box-shadow: 2px 2px 4px 0px rgba(32,32,32,0.5)
styles:
card:
- border: none
custom_fields:
ncarte:
- position: absolute
- left: 0px
- top: 0px
- width: 100%
nkilometrage:
- position: absolute
- left: 22%
- top: 0px
- width: 38%
kilometrage:
- position: absolute
- left: 60%
- top: 0px
- width: 25%
mgicon:
- position: absolute
- left: 85%
- top: 0px
- width: 15%
fond:
- background-image: url(/local/images/voiture.png)
- position: absolute
- left: 0
- top: 40px
- width: 100%
- background-size: cover
- background-position: center
- opacity: 1
ncharge:
- position: absolute
- width: 100%
- left: 0%
- top: 227px
charge_en_cours:
- position: absolute
- width: 35%
- left: 42%
- top: 225px
icone_charge_en_cours:
- position: absolute
- left: 80%
- top: 217px
- width: 60px
bouton_config:
- position: absolute
- left: 85%
- top: 50px
bouton_info:
- position: absolute
- left: 85%
- top: 110px
bouton_charge:
- position: absolute
- left: 85%
- top: 170px
- type: custom:bar-card
entities:
- entity: sensor.sensor.lsjwhxxxxxxxxxx_soc
height: 30px
positions:
icon: 'off'
indicator: 'off'
name: 'off'
severity:
- color: Red
from: 0
to: 25
- color: Orange
from: 25.1
to: 50
- color: DeepSkyBlue
from: 50.1
to: 100
decimal: 1
unit_of_measurement: '%'
card_mod:
style: |-
bar-card-currentbar, bar-card-backgroundbar {
border-radius: 10px;
box-shadow: 2px 2px 4px 0px rgba(32,32,32,0.5);
border: 2px rgba(211,211,211,1.0) outset;
}
bar-card-value {
margin: auto;
font-size: 16px;
font-weight: bold;
color: White;
}
bar-card-card {
margin-top: -10px;
margin-bottom: 0px;
}
ha-card {
box-shadow: none;
border: none;
margin: -5px;
background-color: rgb(250,250,250);
--ha-card-header-font-size: 18px;
}
- type: custom:button-card
custom_fields:
autonomie:
card:
type: custom:button-card
name: 'Autonomie restante :'
styles:
card:
- border: none
- border-radius: 0%
- background-color: rgba(0,0,0,0.0)
name:
- font-size: 0.8em
- font-weight: bold
- color: lightgray
valeur_autonomie:
card:
type: custom:button-card
entity: sensor.lsjwhxxxxxxxxxx_range
numeric_precision: 0
show_icon: false
show_name: false
show_state: true
styles:
card:
- border: none
- border-radius: 0%
- background-color: rgba(0,0,0,0.0)
state:
- font-size: 1.1em
- font-weight: bold
- color: lightgray
styles:
card:
- border: none
- height: 30px
- margin-top: '-10px'
custom_fields:
autonomie:
- position: absolute
- top: 4px
- left: 160px
valeur_autonomie:
- position: absolute
- top: 3px
- left: 300px