Bon je remets une pièce dans la machine avec un soucis bien particulier et pourtant bien commun et pas du tout cité ici :
De nombreux capteurs (aqara pour la température par ex) fonctionnent très bien à 0% de batterie (plus d’un an déjà et toujours aussi réactifs les 4 miens) tandis que d’autres meurent à 12% de batterie (signal plat)…
Bref j’ai adapté pour obtenir ce beau tableau qui a la particularité d’adapter l’opacité au niveau de batterie et de tracer la courbe de température en couleur, courbe qui devient grisée avec un petit signal
si le capteur ne répond plus (même si la batterie n’est pas 0%)
il faut juste installer depuis HACS GitHub - iantrich/config-template-card: 📝 Templatable Lovelace Configurations (qui est bien pratique pour éviter de créer des entités pour un affichage dynamique… certainement utile dans bien d’autres situations)
Voici le code, il devrait bien y avoir quelqu’un pour suggérer des amélioration ? En tout cas je suis parti de ce fil de discussion dans mes essais initialement ![]()
type: custom:config-template-card
entities:
- sensor.time
card:
type: vertical-stack
cards: |-
${Object.keys(this.hass.states).filter(e =>
e.startsWith('sensor.') &&
e.endsWith('_battery') &&
!e.includes('battery_plus') &&
!e.startsWith('sensor.sm') &&
this.hass.states[e.replace('_battery', '_temperature')]
).sort((a, b) =>
parseFloat(this.hass.states[a].state) - parseFloat(this.hass.states[b].state)
).map(batteryId => {
const tempId = batteryId.replace('_battery', '_temperature');
const batteryLevel = parseFloat(this.hass.states[batteryId].state) || 0;
const opacity = Math.max(0.15, batteryLevel / 100);
const tempState = this.hass.states[tempId];
const lastChanged = new Date(tempState.last_changed);
const now = new Date();
const hoursSinceChange = (now - lastChanged) / (1000 * 60 * 60);
const isStale = hoursSinceChange > 6;
const displayName = this.hass.states[batteryId].attributes.friendly_name || batteryId;
const nameWithWarning = isStale ? '⚠️ ' + displayName : displayName;
// Définir les couleurs : normales ou grisées si capteur mort
const colorThresholds = isStale ? [
{value: 0, color: '#666666'}
] : [
{value: 40, color: '#6e0000'},
{value: 30, color: '#470101'},
{value: 25, color: '#ff0000'},
{value: 20, color: '#ffba00'},
{value: 15, color: '#00aa99'},
{value: 10, color: '#0090ff'},
{value: 5, color: '#004e8b'},
{value: 0, color: '#002542'}
];
return {
type: 'custom:stack-in-card',
keep: {
border_radius: false,
margin: false,
outer_padding: false,
box_shadow: false,
background: false
},
card_mod: {
style: 'ha-card { border-radius: 0px !important; margin: 0px !important; padding: 0px !important; box-shadow: none !important; overflow: hidden !important; margin-bottom: -5px !important; height: 38px !important; }'
},
cards: [
{
type: 'custom:mini-graph-card',
entities: [tempId],
height: 25,
hours_to_show: 72,
points_per_hour: 0.5,
line_width: 1.5,
smoothing: true,
color_thresholds: colorThresholds,
show: {
name: false,
icon: false,
state: false,
legend: false,
fill: false,
labels: false,
points: false
},
card_mod: {
style: 'ha-card { position: absolute !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 25px !important; border: 0px !important; opacity: 60% !important; pointer-events: none !important; background: transparent !important; box-shadow: none !important; border-radius: 0px !important; overflow: hidden !important; mix-blend-mode: screen !important; } ha-card .graph { height: 25px !important; margin: 0 !important; padding: 0 !important; } ha-card .graph .graph__container { height: 25px !important; margin-top: -18px !important; margin-left: 0 !important; margin-right: 0 !important; padding: 0 !important; }'
}
},
{
type: 'custom:bar-card',
entity: batteryId,
name: nameWithWarning,
height: 1,
title_position: 'inside',
positions: {
icon: 'inside',
indicator: 'inside',
name: 'inside',
value: 'inside'
},
show_icon: true,
align: 'split',
max: 100,
unit_of_measurement: '%',
color: 'lightgreen',
card_mod: {
style: `ha-card { height: 45px; font-size: small; opacity: 100%; border: none !important; background: transparent !important; box-shadow: none !important; border-radius: 0px !important; margin: 0px !important;} ha-icon {opacity: ${opacity} !important; color: white !important; } bar-card-name { color: white !important; opacity: 80%;} bar-card-value { color: white !important; } bar-card-currentbar,bar-card-current {opacity: ${opacity*.2+.05} !important;} bar-card-currentbar, bar-card-current, bar-card-backgroundbar { height: 40px !important; margin-top: -25px !important; margin-left: -16px !important; margin-right: -20px !important; margin-bottom: 0px !important; border-radius: 0px !important; } bar-card-backgroundbar {opacity: 0% !important;}`
}
}
]
};
})}
