De rien
Liste de courses :
Intégration en natif via l’UI (Intitulé liste d’achats), mais tu sembles l’avoir déjà fait. Je précise pour d’éventuels futurs intéressés.
Il faut ensuite créer un fichier que tu nommeras « shopping_list.py » et que tu placeras au même endroit que tes fichiers de config (configuration.yaml, etc…)
Et place ce code dans le fichier :
#!/usr/local/bin/python
# coding: utf8
import json
with open('/config/.shopping_list.json') as data_file:
shoppingListData = json.load(data_file)
content = u"<b>Liste de Courses:</b><br>"
for entry in shoppingListData:
if not entry['complete']:
content += u"- %s<br>" % entry['name']
content += u"<br>"
print(content)
Puis dans ton sensors.yaml (ou équivalent), place ce code :
- platform: command_line
name: Liste de Courses
command: python3 /config/shopping_list.py
json_attributes:
- name
Ensuite, pour avoir ma mise en page sur la carte :
card:
cards:
- type: shopping-list
- entity: null
name: COCHER TOUS LES ARTICLES
show_icon: false
style: |
ha-card {
background: none;
font-size: 6px;
font-weight: bold;
color: rgba(3, 169, 244, 0.5);
}
tap_action:
action: call-service
service: shopping_list.complete_all
type: button
- cards:
- entity: script.liste_courses_envoyer_quintus
name: ENVOYER À QUINTUS
show_icon: false
style: |
ha-card {
width: 150px;
margin-left: -10px;
margin-right: auto;
background: none;
font-size: 6px;
font-weight: bold;
color: rgba(3, 169, 244, 0.5);
border-radius: 20px;
}
tap_action:
action: toggle
type: button
- entity: script.liste_courses_envoyer_stickysnoops
name: ENVOYER À STICKYSNOOPS
show_header_toggle: false
show_icon: false
style: |
ha-card {
width: 150px;
margin-left: auto;
margin-right: 0px;
background: none;
font-size: 6px;
font-weight: bold;
color: rgba(3, 169, 244, 0.5);
border-radius: 20px;
}
tap_action:
action: toggle
type: button
type: horizontal-stack
mode: vertical
style: |
ha-card {
border-radius: 20px;
}
type: custom:stack-in-card
conditions:
- entity: input_boolean.liste_courses
state: 'on'
type: conditional
Et le script qui va avec :
alias: '[Liste de Courses] Envoyer Liste à Quintus'
sequence:
- data: {}
entity_id: sensor.liste_de_courses
service: homeassistant.update_entity
- delay:
hours: 0
minutes: 0
seconds: 2
milliseconds: 0
- service: notify.mobile_app_quintus_s21
data_template:
data:
sticky: 'true'
subject: <b>Liste de Courses</b>
message: '{{ states(''sensor.liste_de_courses'') }}'
title: Home Assistant
mode: single
Il suffit ensuite de faire un bouton qui « toggle » un boolean (ici nommé « liste_courses ») pour dévoiler la carte (si vraiment tu veux faire comme moi. Pas obligé)
Media Player :
Voici le code pompeux de ma carte :
cards:
- artwork: full-cover
entity: media_player.multiroom
hide:
icon_state: false
power_state: false
progress: false
repeat: false
runtime: false
shuffle: false
source: true
volume: false
icon: mdi:cast-audio
idle_view:
when_idle: true
when_paused: true
when_standby: true
name: Serveur Multiroom
shortcuts:
buttons:
- data:
card:
aspect_ratio: 160%
style: |
ha-card {
border-radius: 20px;
margin-left: auto;
margin-right: auto;
}
type: iframe
url: http://192.168.1.90:3689/#/
deviceID:
- this
large: true
style:
$: |
.mdc-dialog .mdc-dialog__container .mdc-dialog__surface {
border-radius: 22px;
}
.: |
:host {
--mdc-theme-surface: rgba(0,0,0,0);
--secondary-background-color: rgba(0,0,0,0.5);
--ha-card-background: rgba(40,40,40,0.8);
}
:host .content {
width: 60%;
top: 10px;
}
title: Liste de Lecture
icon: mdi:playlist-music
id: browser_mod.popup
type: service
- data:
card:
cards:
- cards:
- aspect_ratio: 100%
entity: input_text.fete_homme
image: /local/Images/Best.jpg
name: Best de Quintus
show_state: false
style: |
ha-card {
border-radius: 10px;
text-align: center
}
tap_action:
action: call-service
service: rest_command.multiroom_playlist_quintus
type: picture-entity
- aspect_ratio: 100%
entity: input_text.fete_homme
image: /local/Images/Trop Mimi.jpg
name: Un peu de douceur...bordel
show_state: false
style: |
ha-card {
border-radius: 10px;
text-align: center
}
tap_action:
action: call-service
service: rest_command.multiroom_playlist_stickysnoops
type: picture-entity
- aspect_ratio: 100%
entity: input_text.fete_homme
image: /local/Images/OST.jpg
name: OST
show_state: false
style: |
ha-card {
border-radius: 10px;
text-align: center
}
tap_action:
action: call-service
service: rest_command.multiroom_playlist_ost
type: picture-entity
type: horizontal-stack
- cards:
- aspect_ratio: 100%
entity: input_text.fete_homme
image: /local/Images/OUI_FM.jpg
show_name: false
show_state: false
style: |
ha-card {
border-radius: 10px;
text-align: center
}
tap_action:
action: call-service
service: rest_command.multiroom_ouifm
type: picture-entity
- aspect_ratio: 100%
entity: input_text.fete_homme
image: /local/Images/OUI FM - Rock Indé.png
show_name: false
show_state: false
style: |
ha-card {
border-radius: 10px;
text-align: center
}
tap_action:
action: call-service
service: rest_command.multiroom_ouifm_rockinde
type: picture-entity
- aspect_ratio: 100%
entity: input_text.fete_homme
image: /local/Images/OUI FM - Alternatif.png
show_name: false
show_state: false
style: |
ha-card {
border-radius: 10px;
text-align: center
}
tap_action:
action: call-service
service: rest_command.multiroom_ouifm_alternatif
type: picture-entity
- aspect_ratio: 100%
entity: input_text.fete_homme
image: /local/Images/OUI FM - Classic Rock.png
show_name: false
show_state: false
style: |
ha-card {
border-radius: 10px;
text-align: center
}
tap_action:
action: call-service
service: rest_command.multiroom_ouifm_classicrock
type: picture-entity
type: horizontal-stack
- cards:
- color_type: blank-card
type: custom:button-card
- aspect_ratio: 100%
entity: input_text.fete_homme
image: /local/Images/RTL2.png
show_name: false
show_state: false
style: |
ha-card {
border-radius: 10px;
text-align: center
}
tap_action:
action: call-service
service: rest_command.multiroom_rtl2
type: picture-entity
- color_type: blank-card
type: custom:button-card
type: horizontal-stack
type: vertical-stack
large: true
style:
$: |
.mdc-dialog .mdc-dialog__container .mdc-dialog__surface {
border-radius: 12px;
}
.: |
:host {
--mdc-theme-surface: rgba(0,0,0,0);
--secondary-background-color: rgba(0,0,0,0.5);
--ha-card-background: rgba(40,40,40,0.8);
width: 80%;
}
:host .content {
top: 10px;
}
title: Source de Musique
deviceID:
- this
icon: hass:folder-music
id: browser_mod.popup
type: service
column_height: 40
columns: 4
style: |
:host {
--mini-media-player-name-font-weight: bold;
--mini-media-player-overlay-color-stop: 25%;
--mini-media-player-overlay-color: rgba(40,40,40, .8);
--mini-media-player-accent-color: rgba(37,129,172, .6);
--mini-media-player-button-color: rgba(240,240,240, .1);
--mini-media-player-progress-height: 12px;
--mini-media-player-icon-color: rgb(37,129,172);
--mini-media-player-media-cover-info-color: rgba(137,229,272, 1);
background:
{% if is_state_attr('media_player.multiroom', 'media_album_name', 'OUI FM La Radio du Rock') %} url(/local/Images/OUI_FM.jpg)
{% elif is_state_attr('media_player.multiroom', 'media_album_name', 'OUI FM Rock Indé') %} url(/local/Images/OUI_FM_Rock.jpg)
{% elif is_state_attr('media_player.multiroom', 'media_album_name', 'OUI FM Alternatif') %} url(/local/Images/OUI_FM_Alternatif.jpg)
{% elif is_state_attr('media_player.multiroom', 'media_album_name', 'OUI FM Classic Rock') %} url(/local/Images/OUI_FM_Classic.jpg)
{% elif is_state_attr('media_player.multiroom', 'media_album_name', 'RTL2 [MP3 192]') %} url(/local/Images/RTL2.png)
{% else %} none
{% endif %} center / cover ;
}
toggle_power: false
type: custom:mini-media-player
- entities:
- entities:
- entity: media_player.multiroom_yamaha_5_1
name: Salon - Ampli 5.1
- entity: media_player.multiroom_varys
name: Salon - Varys
- entity: media_player.multiroom_marc_pc
name: Bureau
- entity: media_player.multiroom_salle_de_bain
name: Salle de Bain
head: group.pieces
padding: 2
show_state: false
type: custom:fold-entity-row
type: entities
mode: vertical
style:
.: |
ha-card {
border-radius: 20px;
}
type: custom:stack-in-card
Et c’est vrai qu’il est pompeux. Et bourré d’aberrations que je n’ai jamais pris le temps de corriger.
En exemple, je ne savais pas à l’époque faire de bouton sans avoir à mettre une entité. Du coup, tu verras dans mon code des « entity: input_text.fete_homme » complètement inutiles. Ils sont juste là car ils me permettaient de feinter et réussir à créer un bouton clickable. Alors que c’est tout à fait possible de faire sans (on a bien tous commencé un jour, hein )
Tout comme faire des rest_command pour appeler les playlist. Obsolète. Depuis, HA permet de les appeler directement depuis l’entité media_player avec un media_player.select_source.
Tout ça pour dire que cette carte est vieille. La vérité c’est que je ne l’utilise que rarement maintenant. Voilà pourquoi je ne lui ai pas donné un coup de neuf.
Pour les pochettes, soit le media_player les fournit directement, soit je passe par un background qui se met en fonction du « media_album_name » de ma source, exemple : OUI FM.
Lumières :
Pour ma view Lumières, ce n’est qu’une seule carte en mode panel. Je vais bientot la changer car je ne suis pas satisfait. Je pense passer sur le très joli style Minimalist relayé par @Clemalex.
Mais si tu souhaites prendre ce que j’ai fait jusque là (et que j’ai en fait copié sur d’autres), voici le code d’un bouton :
Code :
enableColumns: true
masonry: false
home: false
rows:
- columns:
- column: 1
entities:
- entities:
- card: custom:button-card
cardOptions:
entity: light.ambiance_salon
show_last_changed: true
state_display: |
[[[
if (entity.state === 'on')
return 'Allumée';
else
return 'Eteinte';
]]]
custom_fields:
icon_hue: >
<svg viewBox="0 0 32 32"><path d="M8.4395,16.668
C8.9795,16.552
9.5115,16.895 9.6285,17.435 C9.7455,17.974 9.4025,18.506 8.8625,18.623
C8.3225,18.74 7.7905,18.397 7.6735,17.857 C7.5565,17.317 7.9005,16.785
8.4395,16.668 M13.3275,15.611 C13.8665,15.495 14.3985,15.838
14.5155,16.377 C14.6325,16.917 14.2895,17.449 13.7505,17.566
C13.2105,17.683 12.6775,17.34 12.5605,16.8 C12.4445,16.261
12.7875,15.729 13.3275,15.611 M18.2135,14.555 C18.7535,14.438
19.2865,14.781 19.4025,15.32 C19.5195,15.86 19.1765,16.393 18.6365,16.51
C18.0965,16.626 17.5645,16.283 17.4485,15.743 C17.3315,15.203
17.6735,14.671 18.2135,14.555 M23.1005,13.498 C23.6405,13.381
24.1725,13.724 24.2905,14.264 C24.4065,14.804 24.0635,15.336
23.5235,15.453 C22.9835,15.569 22.4515,15.227 22.3355,14.687
C22.2175,14.147 22.5615,13.614 23.1005,13.498 M10.6695,20.639
L25.4735,17.444 C26.5535,17.211 27.2405,16.147 27.0065,15.067
C26.4495,12.484 23.9035,10.842 21.3205,11.399 L6.5165,14.594
C5.4365,14.827 4.7505,15.891 4.9835,16.971 C5.5415,19.554 8.0865,21.196
10.6695,20.639 M25,26 C24.447,26 24,25.553 24,25 C24,24.447 24.447,24
25,24 C25.553,24 26,24.447 26,25 C26,25.553 25.553,26 25,26 M20,26
C19.447,26 19,25.553 19,25 C19,24.447 19.447,24 20,24 C20.553,24
21,24.447 21,25 C21,25.553 20.553,26 20,26 M15,26 C14.447,26 14,25.553
14,25 C14,24.447 14.447,24 15,24 C15.553,24 16,24.447 16,25 C16,25.553
15.553,26 15,26 M10,26 C9.447,26 9,25.553 9,25 C9,24.447 9.447,24 10,24
C10.553,24 11,24.447 11,25 C11,25.553 10.553,26 10,26 M27,22 L9,22 C5,22
4,19 4,18 L4,23 C4,25.762 6.238,28 9,28 L27,28 C27.553,28 28,27.553
28,27 L28,23 C28,22.447 27.553,22 27,22 M22,8 C21.447,8 21,7.553 21,7
C21,6.447 21.447,6 22,6 C22.553,6 23,6.447 23,7 C23,7.553 22.553,8 22,8
M17,8 C16.447,8 16,7.553 16,7 C16,6.447 16.447,6 17,6 C17.553,6 18,6.447
18,7 C18,7.553 17.553,8 17,8 M12,8 C11.447,8 11,7.553 11,7 C11,6.447
11.447,6 12,6 C12.553,6 13,6.447 13,7 C13,7.553 12.553,8 12,8 M7,8
C6.447,8 6,7.553 6,7 C6,6.447 6.447,6 7,6 C7.553,6 8,6.447 8,7 C8,7.553
7.553,8 7,8 M23,4 L5,4 C4.447,4 4,4.447 4,5 L4,9 C4,9.553 4.447,10 5,10
L23,10 C27,10 28,13 28,14 L28,9 C28,6.238 25.762,4 23,4"
style="fill:#C0C0C0;"></path> <g><circle cx="7" cy="7" r="0.878"
style="fill:var(--button-card-light-color)"/> <circle cx="17" cy="7"
r="0.878" style="fill:var(--button-card-light-color)"/> <circle cx="22"
cy="7" r="0.878" style="fill:var(--button-card-light-color)"/> <circle
cx="8.651" cy="17.646" r="0.878"
style="fill:var(--button-card-light-color)"/> <circle cx="13.538"
cy="16.589" r="0.878" style="fill:var(--button-card-light-color)"/>
<circle cx="18.425" cy="15.532" r="0.878"
style="fill:var(--button-card-light-color)"/> <circle cx="23.313"
cy="14.475" r="0.878" style="fill:var(--button-card-light-color)"/>
<circle cx="10" cy="25" r="0.878"
style="fill:var(--button-card-light-color)"/> <circle cx="15" cy="25"
r="0.878" style="fill:var(--button-card-light-color)"/> <circle cx="20"
cy="25" r="0.878" style="fill:var(--button-card-light-color)"/> <circle
cx="25" cy="25" r="0.878" style="fill:var(--button-card-light-color)"/>
<circle cx="12" cy="7" r="0.878"
style="fill:var(--button-card-light-color)"/></g> </svg>
styles:
card:
- font-family: Sf Display
- letter-spacing: 0.05vw
- font-weight: bold
- font-size: 100%
name:
- top: 30%
- left: 54%
- position: absolute
label:
- top: 42%
- left: 54%
- position: absolute
state:
- top: 36%
- left: 54%
- position: absolute
custom_fields:
icon_hue:
- top: 2%
- left: 2%
- width: 40%
- position: absolute
circle:
- top: 2%
- left: 74%
- width: 24%
- position: absolute
- letter-spacing: 0.03vw
template: light
higherSize: 1
wider: true
widerSize: 2
noPadding: true
title: Ambiance
tileOnRow: 2
title: Lumières
titleColor: '#FFF'
style: |
:host {
--tile-background: rgba(255, 255, 255, 0.1);
--tile-border-radius: 10px;
--tile-width: 100px;
--tile-height: 100px;
--tile-on-background: none;
--tile-name-text-color: rgba(255, 255, 255, 1);
--tile-on-name-text-color: rgba(0, 0, 0, 1);
--tile-state-text-color: rgba(0, 0, 0, 0.7);
--tile-on-state-text-color: rgba(255,255,255, 1);
--tile-state-changed-text-color: rgb(255, 255, 255);
--tile-unavailable-state-text-color: rgba(255, 0, 0, 1);
--tile-value-text-color: rgba(255, 0, 0, 1);
--tile-icon-color: rgba(0, 0, 0, 0.6);
--tile-on-icon-color: #F7D959;
--tile-width-mobile: 140px;
--tile-height-mobile: 140px;
background: none;
}
type: custom:homekit-card
Quand tu vois la gueule du code pour 1 seul bouton, tu comprendras que je ne te mets pas toute la page
Je pense qu’avec ça, tu devrais t’en sortir. Mais si tu coinces, tu sais quoi faire