Sorry for the delay @filikun, @Airyphyla, @alexreddy78 and @Lunkobelix .
I’m at the begining to create my own card with custom:button-card and I’m sure there are much cleaner ways of doing things than me. But here is the yaml of my card :
card_pool:
styles:
card:
- padding: "0px"
grid:
- grid-template-areas: "'cam overlay' 'measures measures'"
- grid-template-columns: "1fr 0"
- grid-template-rows: "180px min-content"
custom_fields:
overlay:
- height: 180px
- background: linear-gradient(180deg, rgba(var(--rgb-card-background-color),0) 45%, rgba(var(--rgb-card-background-color),1) 100%)
- opacity: 1
- padding: 0
custom_fields:
cam:
card:
type: picture-glance
camera_image: camera.poolcamera
entities: []
card_mod:
style:
hui-image:
$: |
div img {
height: 180px;
object-fit: cover;
object-position: center -25px;
}
.: |
hui-image {
height: calc(100% - 0px);
}
.: |
ha-card {
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
box-shadow: none;
}
ha-card .box {
display: none;
}
overlay: <div></div>
measures:
card:
type: custom:button-card
name: Analyses de l'eau
label: "[[[ return states['sensor.pool_analysed_at'].state; ]]]"
show_name: true
show_label: true
styles:
card:
- padding: 4%
- border-radius: 0px
- box-shadow: "none"
grid:
- grid-template-areas: "'n tmp . ph . redox . sel' 'l tmp . ph . redox . sel' 'graph graph graph graph graph graph graph graph' 'actions actions actions actions actions actions actions actions' 'infos infos infos infos infos infos infos infos'"
- grid-template-columns: "1fr 45px 5px 45px 5px 45px 5px 45px"
- grid-template-rows: "min-content min-content min-content"
name:
- font-weight: "bold"
- font-size: "14px"
- place-self: end left
label:
- font-size: "10px"
- place-self: start
- filter: "opacity(40%)"
custom_fields:
tmp:
card:
type: custom:button-card
template: button_pool_measure
name: Temp
label: "[[[ return states['sensor.pool_temperature'].state + '°C'; ]]]"
variables:
color: "blue"
select_value: "Temperature"
ph:
card:
type: custom:button-card
template: button_pool_measure
name: pH
label: "[[[ return states['sensor.pool_ph'].state; ]]]"
variables:
color: "green"
select_value: "PH"
alert: >
[[[
let ph = states['sensor.pool_ph'].state;
if (ph < 7.1 || ph > 7.5) return true;
return false;
]]]
redox:
card:
type: custom:button-card
template: button_pool_measure
name: RedOx
label: "[[[ return states['sensor.pool_orp'].state + 'mV'; ]]]"
variables:
color: "yellow"
select_value: "ORP"
alert: >
[[[
let orp = states['sensor.pool_orp'].state;
if (orp < 600 || orp > 800) return true;
return false;
]]]
sel:
card:
type: custom:button-card
template: button_pool_measure
name: Sel
label: "[[[ return states['sensor.pool_salinity'].state + 'g/l'; ]]]"
variables:
color: "red"
select_value: "Sel"
alert: >
[[[
let salinity = states['sensor.pool_salinity'].state;
if (salinity < 3 || salinity > 3.4) return true;
return false;
]]]
graph:
card:
type: custom:button-card
entity: input_select.ui_pool_select_measure
show_icon: false
state:
- name: Température de l'eau
value: Temperature
- name: pH de l'eau
value: PH
- name: Rédox de l'eau
value: ORP
- name: Salinité de l'eau
value: Sel
styles:
card:
- border-radius: 0px
- box-shadow: "none"
- padding-bottom: 0
name:
- font-weight: "normal"
- font-size: "12px"
- place-self: center left
grid:
- grid-template-areas: "'n i1 . i2 . i3' 'graph graph graph graph graph graph'"
- grid-template-columns: "1fr 61px 6px 61px 6px 61px"
- grid-template-rows: "min-content min-content"
custom_fields:
i1:
card:
type: custom:button-card
template: button_pool_period
name: Jour
variables:
period: Jour
i2:
card:
type: custom:button-card
template: button_pool_period
name: Semaine
variables:
period: Semaine
i3:
card:
type: custom:button-card
template: button_pool_period
name: Mois
variables:
period: Mois
graph:
card:
type: grid
square: false
columns: 1
cards:
- type: conditional
conditions:
- entity: input_select.ui_pool_select_measure
state: 'Temperature'
card:
type: custom:button-card
template: graph_pool_measure
variables:
entity: sensor.pool_temperature
color: "blue"
decimal: 0
- type: conditional
conditions:
- entity: input_select.ui_pool_select_measure
state: 'PH'
card:
type: custom:button-card
template: graph_pool_measure
variables:
entity: sensor.pool_ph
color: "green"
decimal: 1
yaxis:
min: 6.9
max: 7.7
annotations:
min:
value: 7.1
text: "7.1"
max:
value: 7.5
text: "7.5"
- type: conditional
conditions:
- entity: input_select.ui_pool_select_measure
state: 'ORP'
card:
type: custom:button-card
template: graph_pool_measure
variables:
entity: sensor.pool_orp
color: "yellow"
decimal: 0
yaxis:
min: 500
max: 800
annotations:
min:
value: 650
text: "650mv"
max:
value: 750
text: "750mv"
- type: conditional
conditions:
- entity: input_select.ui_pool_select_measure
state: 'Sel'
card:
type: custom:button-card
template: graph_pool_measure
variables:
entity: sensor.pool_salinity
color: "red"
decimal: 1
curve: "stepline"
yaxis:
min: 2.9
max: 3.4
actions:
card:
type: custom:button-card
styles:
card:
- border-radius: 0px
- box-shadow: "none"
- padding-top: 0
grid:
- grid-template-areas: " 'a1 . a2 . a3'"
- grid-template-columns: "1fr 10px 1fr 10px 1fr"
- grid-template-rows: "min-content"
custom_fields:
a1:
card:
type: custom:button-card
template: button_pool_action
entity: switch.piscine_filtration
name: Filtration
icon: mdi:engine
label: "[[[ return states['sensor.pool_pump_duration'].state; ]]]"
variables:
schedules: "[[[ return states['sensor.pool_pump_hours'].state; ]]]"
a2:
card:
type: custom:button-card
template: button_pool_action
entity: switch.piscine_surpresseur
name: Robot
icon: mdi:robot-mower
label: "[[[ return states['sensor.robot_duration'].state; ]]]"
variables:
schedules: "[[[ return states['input_text.robot_hours'].state; ]]]"
a3:
card:
type: custom:button-card
template: button_pool_action
entity: switch.piscine_electrolyseur_sel
name: Electrolyseur
icon: mdi:electron-framework
label: "[[[ return states['sensor.electrolyseur_sel_duration'].state; ]]]"
variables:
schedules: "-"
infos:
card:
type: custom:button-card
styles:
card:
- border-radius: 0px
- box-shadow: "none"
- padding-top: 0
grid:
- grid-template-areas: " 'i1 . i2 . i3 . i4'"
- grid-template-columns: "1fr 10px 1fr 10px 1fr 10px 1fr"
- grid-template-rows: "min-content"
custom_fields:
i1:
card:
type: custom:button-card
template: button_pool_info
name: Lumières
icon: mdi:lightbulb
i2:
card:
type: custom:button-card
template: button_pool_info
name: Mode<br/>filtration
label: "[[[ return states['input_select.pool_pump'].state; ]]]"
tap_action:
action: 'fire-dom-event'
browser_mod:
command: "popup"
large: true
hide_header: true
card:
type: "custom:button-card"
template: "popup_pool_pump"
style:
$: |
.mdc-dialog .mdc-dialog__container .mdc-dialog__surface {
box-shadow: none;
border-radius: 0px;
background-color: var(--main-background-color);
}
i3:
card:
type: custom:button-card
template: button_pool_info
name: Lavage<br/>filtre
label: Il y a 10 jours
variables:
alert: false
i4:
card:
type: custom:button-card
template: button_pool_info
name: Lavage<br/>skimmers
label: Il y a 25 jours
variables:
alert: true
graph_pool_measure:
variables:
entity : ""
color: ""
decimal: 0
curve: "smooth"
annotations:
min:
value: -100
text: ""
max:
value: -100
text: ""
yaxis:
min: auto
max: auto
styles:
card:
- padding: 0px
- border-radius: 0px
- box-shadow: "none"
grid:
- grid-template-areas: "'graph'"
- grid-template-columns: "1fr"
- grid-template-rows: "min-content"
custom_fields:
graph:
card:
type: custom:apexcharts-card
header:
show: false
graph_span: >
[[[
switch (states['input_select.ui_pool_select_measure_period'].state) {
case "Mois":
return "4w";
break
case "Semaine":
return "1w";
break;
case "Jour":
return "1d";
break;
}
]]]
series:
- entity: "[[[ return variables.entity; ]]]"
stroke_width: 3
color: "[[[ return `var(--google-${variables.color})`; ]]]"
fill_raw: last
type: area
yaxis:
- decimals: "[[[ return variables.decimal; ]]]"
min: "[[[ return variables.yaxis.min; ]]]"
max: "[[[ return variables.yaxis.max; ]]]"
apex_config:
tickAmount: 5
forceNiceScale: true
labels:
offsetX: -15
apex_config:
chart:
height: 200px
grid:
padding:
left: 0
right: 0
fill:
type: 'gradient'
gradient:
shade: "light"
type: "vertical"
opacityFrom: 0.7
opacityTo: 0.1
stops: [0, 100]
stroke:
curve: "[[[ return variables.curve; ]]]"
annotations:
position: 'front'
yaxis:
- y: "[[[ return variables.annotations.min.value; ]]]"
y2: "[[[ return variables.annotations.max.value; ]]]"
opacity: 0.2
- y: "[[[ return variables.annotations.max.value; ]]]"
strokeDashArray: 0
label:
text: "[[[ return variables.annotations.max.text; ]]]"
offsetX: -5
offsetY: -1
style:
fontSize: 8px
- y: "[[[ return variables.annotations.min.value; ]]]"
strokeDashArray: 0
label:
text: "[[[ return variables.annotations.min.text; ]]]"
offsetX: -5
offsetY: -1
style:
fontSize: 8px
card_mod:
style: |
ha-card {
border-radius: 0px;
box-shadow: none;
padding: 0;
margin: 0;
}
#state__name, .apexcharts-xaxis-label, .apexcharts-yaxis-label {
font-size: 10px !important;
}
button_pool_measure:
variables:
color: "blue"
select_value: "Temperature"
alert: false
show_name: true
show_label: true
aspect_ratio: 1/1
styles:
card:
- padding: "0px"
- box-shadow: none
- background-color: var(--primary-background-color)
- background-image: >
[[[
let theme = hass.themes.themes[hass.themes.theme].modes[(hass.themes.darkMode ? "dark" : "light")];
let color_bckg = theme[`google-${variables.color}`].replace('#', '%23');
let opacity = theme['opacity-bg'];
return "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 1440 1440'><path fill='"+color_bckg+"' fill-opacity='"+opacity+"' d='m 0,566 48,26.7 C 96,619 192,673 288,699.3 384,726 480,726 576,710 c 96,-16 192,-48 288,-42.7 96,5.7 192,47.7 288,58.7 96,11 192,-11 240,-21.3 l 48,-10.7 v 754 H 1392 1152 864 576 288 48 0 Z'></path></svg>\")";
]]]
- background-size: 100%
grid:
- grid-template-areas: "'n' 'l'"
- grid-template-columns: "1fr"
- grid-template-rows: "auto auto"
name:
- font-size: "10px"
- place-self: center
label:
- font-size: "10px"
- place-self: center
- font-weight: "bold"
- color: >
[[[
if (hass.themes.darkMode){
return "#FFFFFF";
} else {
return `rgba(var(--color-${variables.color}), 1)`;
}
]]]
custom_fields:
notification:
- border-radius: "50%"
- position: "absolute"
- right: "2px"
- top: "14px"
- height: "12px"
- width: "12px"
- border: "1px solid var(--card-background-color)"
- font-size: "6px"
- line-height: "12px"
- background-color: >
[[[
return "rgba(var(--color-red),1)";
]]]
custom_fields:
notification: >
[[[
if (variables.alert) {
return `<ha-icon icon="mdi:exclamation" style="width: 9px; height: 9px; color: var(--primary-background-color);"></ha-icon>`
}
]]]
tap_action:
action: call-service
service: input_select.select_option
service_data:
entity_id: input_select.ui_pool_select_measure
option: "[[[ return `${variables.select_value}`; ]]]"
button_pool_period:
variables:
period: "Semaine"
show_name: true
styles:
card:
- padding: "5px 0px"
- box-shadow: none
- background-color: >
[[[
if (states['input_select.ui_pool_select_measure_period'].state == variables.period) {
switch (states['input_select.ui_pool_select_measure'].state) {
case "Temperature":
return "var(--google-blue)";
case "PH":
return "var(--google-green)";
case "ORP":
return "var(--google-yellow)";
case "Sel":
return "var(--google-red)";
default:
return "var(--primary-background-color)";
}
} else {
return "var(--primary-background-color)";
}
]]]
name:
- font-size: "10px"
- place-self: center
- color: >
[[[
if (states['input_select.ui_pool_select_measure_period'].state == variables.period) {
return "white";
} else {
return "var(--primary-text-color)";
}
]]]
tap_action:
action: call-service
service: input_select.select_option
service_data:
entity_id: input_select.ui_pool_select_measure_period
option: "[[[ return `${variables.period}`; ]]]"
button_pool_action:
variables:
schedules: "-"
show_name: true
show_label: true
show_icon: true
styles:
card:
- padding: "5px 0px"
- box-shadow: none
- background-color: var(--primary-background-color)
grid:
- grid-template-areas: "'n' 'l' 'i' 'schedules'"
- grid-template-columns: "1fr"
- grid-template-rows: "min-content min-content min-content min-content"
name:
- font-size: "12px"
- place-self: center
- font-weight: "bold"
label:
- font-size: "10px"
- place-self: center
- filter: "opacity(40%)"
custom_fields:
schedules:
- font-size: "10px"
- place-self: center
- filter: "opacity(40%)"
custom_fields:
schedules: "[[[ return `${variables.schedules}`; ]]]"
button_pool_info:
variables:
alert: false
show_name: true
show_label: true
show_icon: true
styles:
card:
- padding: "5px 10px"
- box-shadow: none
- background-color: var(--primary-background-color)
- height: 55px
grid:
- grid-template-areas: "'n' 'l' 'i'"
- grid-template-columns: "1fr"
- grid-template-rows: "min-content min-content"
name:
- font-size: "10px"
- place-self: center
- font-weight: "bold"
label:
- font-size: "10px"
- place-self: center
- filter: "opacity(40%)"
- padding-top: 5px
icon:
- padding-top: 3px
custom_fields:
notification:
- border-radius: "50%"
- position: "absolute"
- right: "2px"
- top: "2px"
- height: "16px"
- width: "16px"
- border: "2px solid var(--card-background-color)"
- font-size: "12px"
- line-height: "14px"
- background-color: >
[[[
return "rgba(var(--color-red),1)";
]]]
custom_fields:
notification: >
[[[
if (variables.alert) {
return `<ha-icon icon="mdi:exclamation" style="width: 12px; height: 12px; color: var(--primary-background-color);"></ha-icon>`
}
]]]
For the question :
It’s both at the same time
For the choice of temperature, redox,… it’s an input_select with a conditional card and a unique chart template.
For the choice of the period it is also an input_select that I process in my chart template on the attribute graph_span