Je suis en train d’adapter pour mon capteur température, mais je crois que j’ai un problème au niveau du curseur, je ne dois pas avoir tout bien modifié pour correspondre à ce que je fais, je teste avec un input pour l’instant, je ne vois pas où j’ai raté, j’ai modifié pour être un peu plus proche de mon Netatmo et de chez moi, l’exemple d’affichage ici est celui sur mon ordinateur mais sur mon smartphone la mise en page correspond bien, par contre je n’arrive pas à intégrer le min et max, mais je crois que netatmo ne le remonte pas :
type: custom:button-card
entity: input_number.test
show_state: false
show_icon: false
show_name: false
tap_action: none
double_tap_action: none
hold_action: none
custom_fields:
icon:
card:
type: custom:button-card
icon: mdi:thermometer
styles:
card:
- aspect-ratio: 1/1
- width: 20px
- padding: 0
- border: 1px solid white
- border-radius: 50%
- background: none
icon:
- width: 90%
- color: white
name:
card:
type: custom:button-card
name: Netatmo Salon Température
styles:
card:
- width: 300px
- padding: 0
- border: none
- border-radius: 0
- background: none
name:
- font-size: 1rem
- align-self: start
- justify-self: start
- color: white
- font-weight: 500
separation:
card:
type: custom:button-card
styles:
card:
- width: 600px
- height: 0px
- padding: 0
- border: 0px solid rgba(54,56,68,1.0)
- border-radius: 0
- background: none
bar:
card:
type: custom:button-card
show_name: false
show_icon: false
show_state: false
styles:
card:
- height: 6px
- width: 250px
- border-radius: 999px
- border: 0
- padding: 0px
- background: >-
linear-gradient(to right, rgba(255,0,0,1.0) 0%,
rgba(255,165,0,1.0) 5%, rgba(255,255,0,1.0) 10%, rgba(0,255,0,1.0)
50%, rgba(255,255,0,1.0) 90%, rgba(255,165,0,1.0) 95%,
rgba(255,0,0,1.0) 100%)
cursor:
card:
type: custom:button-card
show_name: false
show_icon: false
show_state: false
styles:
card:
- width: 12px
- height: 25px
- border-radius: 999px
- border: 4px solid rgba(42,45,54,1.0)
- background-color: |
[[[
const minTemp = 0; // MIN CHANGÉ
const maxTemp = 35; // MAX CHANGÉ
const temp = Number(entity.state) || minTemp;
const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
const percent = clamp(((temp - minTemp) / (maxTemp - minTemp)) * 100, 0, 100);
const stops = [
{ p: 0, c: [0, 0, 255] },
{ p: 25, c: [0, 165, 255] },
{ p: 50, c: [0, 255, 0] },
{ p: 62.5, c: [255, 255, 0] },
{ p: 75, c: [255, 165, 0] },
{ p: 100, c: [255, 0, 0] }
];
let i = 1;
while (i < stops.length && percent > stops[i].p) i++;
const a = stops[i - 1];
const b = stops[i];
const t = (percent - a.p) / (b.p - a.p);
const lerp = (x, y, t) => Math.round(x + (y - x) * t);
const r = lerp(a.c[0], b.c[0], t);
const g = lerp(a.c[1], b.c[1], t);
const bcol = lerp(a.c[2], b.c[2], t);
return `rgba(${r},${g},${bcol},1.0)`;
]]]
value:
card:
type: custom:button-card
show_name: false
show_icon: false
show_state: true
state_display: |
[[[
return parseFloat(entity.state).toFixed(0);
]]]
styles:
card:
- width: auto
- padding: 0
- border: none
- border-radius: 0
- background: none
state:
- color: white
- font-size: 2rem
- font-weight: 700
unit:
card:
type: custom:button-card
name: °C
styles:
card:
- width: auto
- padding: 0
- border: none
- border-radius: 0
- background: none
name:
- font-size: 1.4rem
- align-self: start
- justify-self: start
- color: rgba(167,176,205,1.0)
- font-weight: 800
min_val:
card:
type: custom:button-card
name: 0°C
styles:
card:
- width: auto
- padding: 0
- border: none
- border-radius: 0
- background: none
name:
- font-size: 1.0rem
- align-self: start
- justify-self: start
- color: rgba(167,176,205,1.0)
- font-weight: 400
max_val:
card:
type: custom:button-card
name: 35°C
styles:
card:
- width: auto
- padding: 0
- border: none
- border-radius: 0
- background: none
name:
- font-size: 1.0rem
- align-self: start
- justify-self: start
- color: rgba(167,176,205,1.0)
- font-weight: 400
comment:
card:
type: custom:button-card
show_name: true
show_icon: false
show_state: false
name: |
[[[
const temp = Number(entity.state) || 0;
if (temp < 15) { // < 15°C
return "Trop froid";
}
if (temp >= 15 && temp < 18.5) {
return "Frais";
}
if (temp >= 18.5 && temp < 22) {
return "Confort idéal";
}
if (temp >= 22 && temp < 24) {
return "Légèrement chaud";
}
if (temp >= 24) {
return "Trop chaud";
}
return "Indisponible";
]]]
styles:
card:
- height: 8px
- width: auto
- height: 1px
- border-radius: 999px
- border: 0
- padding: 8px
- background: white
- background-color: |
[[[
const minTemp = 0;
const maxTemp = 35;
const temp = Number(entity.state) || minTemp;
const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
const percent = clamp(((temp - minTemp) / (maxTemp - minTemp)) * 100, 0, 100);
const stops = [
{ p: 0, c: [0, 0, 255] }, // 0°C
{ p: 25, c: [0, 165, 255] }, // 18.5°C
{ p: 50, c: [0, 255, 0] }, // 22°C
{ p: 62.5, c: [255, 255, 0] }, // 24°C
{ p: 75, c: [255, 165, 0] }, // 26°C
{ p: 100, c: [255, 0, 0] } // 35°C
];
let i = 1;
while (i < stops.length && percent > stops[i].p) i++;
const a = stops[i - 1];
const b = stops[i];
const t = (percent - a.p) / (b.p - a.p);
const lerp = (x, y, t) => Math.round(x + (y - x) * t);
const r = lerp(a.c[0], b.c[0], t);
const g = lerp(a.c[1], b.c[1], t);
const bcol = lerp(a.c[2], b.c[2], t);
return `rgba(${r},${g},${bcol},0.5)`;
]]]
name:
- font-size: 0.9rem
- font-weight: 600
- color: |
[[[
const minTemp = 0;
const maxTemp = 35;
const temp = Number(entity.state) || minTemp;
const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
const percent = clamp(((temp - minTemp) / (maxTemp - minTemp)) * 100, 0, 100);
const stops = [
{ p: 0, c: [0, 0, 255] },
{ p: 25, c: [0, 165, 255] },
{ p: 50, c: [0, 255, 0] },
{ p: 62.5, c: [255, 255, 0] },
{ p: 75, c: [255, 165, 0] },
{ p: 100, c: [255, 0, 0] }
];
let i = 1;
while (i < stops.length && percent > stops[i].p) i++;
const a = stops[i - 1];
const b = stops[i];
const t = (percent - a.p) / (b.p - a.p);
const lerp = (x, y, t) => Math.round(x + (y - x) * t);
const r = lerp(a.c[0], b.c[0], t);
const g = lerp(a.c[1], b.c[1], t);
const bcol = lerp(a.c[2], b.c[2], t);
return `rgba(${r},${g},${bcol},1.0)`;
]]]
styles:
card:
- background-color: rgba(42,45,54,1.0)
- aspect-ratio: 7/1
- cursor: default
custom_fields:
icon:
- position: absolute
- top: 30%
- left: 1%
name:
- position: absolute
- top: 3%
- left: 8%
separation:
- position: absolute
- top: 17%
- left: 0%
value:
- position: absolute
- top: 26%
- right: 15%
- margin-right: 1%
- transform: translateY(-50%)
unit:
- position: absolute
- left: 83.5%
- top: 20%
- margin-left: 1%
- transform: translateY(-50%)
min_val:
- position: absolute
- top: 65%
- left: 28%
max_val:
- position: absolute
- top: 65%
- right: 1%
comment:
- position: absolute
- left: 17%
- top: 65%
- transform: translate(-50%, -50%)
bar:
- position: absolute
- left: 63%
- top: 55%
- transform: translate(-50%, -50%)
cursor:
- position: absolute
- top: "[[[ return 'calc(55% - 12.5px)'; ]]]"
- left: |
[[[
const value = Number(entity.state) || 0;
const min = 0;
const max = 35;
const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
const percent = clamp(((value - min) / (max - min)) * 100, 0, 100);
const barWidth = 250;
const halfCursor = 8;
const offsetPx = (barWidth * percent) / 100;
return `calc(50% - ${barWidth/2}px + ${offsetPx}px - ${halfCursor}px)`;
]]]

Sur mon smartphone :







