Bonjour Ă tous,
Je viens vous présenter une carte pour calibrer et régler facilement un LD2450. Et sans plus tarder, entrons dans le vif du sujet :
Le problĂšme
Mon LD2450 a perdu toutes ses zones de dĂ©tection suite Ă une mise Ă jour. Jâai dĂ» tout reconfigurer⊠et lĂ , câest le drame ![]()
Configurer un radar LD2450 via les entitĂ©s brutes dâESPHome, câest :
-
Des sliders en millimĂštres (essayez de visualiser mentalement « X=2380, Width=2340 »âŠ)
-
Aucun retour visuel : impossible de savoir si votre zone couvre le canapĂ© ou le mur dâĂ cĂŽtĂ©
-
Un aller-retour infernal entre lâinterface HA et la piĂšce physique pour vĂ©rifier « est-ce que ça dĂ©tecte lĂ ? »
Je nâai jamais vraiment trouvĂ© de carte qui me convienne sur les forums. @freetronic a partagĂ© rĂ©cemment une carte sympa pour le LD2410, mais rien que de penser Ă aller explorer son code
.
Le challenge de faire ma propre carte pendant mes vacances était lancé !
Mon besoin était simple : une carte qui me permette de VOIR mes zones en temps réel pendant que je les ajuste, comme un vrai outil de calibration visuelle intégré à mon dashboard.
La solution : une carte tout-en-un
Tous vos radars sur une seule carte
PlutĂŽt que dâavoir un tableau de bord Ă rallonge, la carte est entiĂšrement articulĂ©e autour dâun simple input_select (contenant la liste de vos radars LD2450). Ce menu dĂ©roulant permet de basculer instantanĂ©ment dâun capteur Ă un autre (Salon, Cuisine, CouloirâŠ). Toute lâinterface se recharge magiquement avec les paramĂštres et les entitĂ©s spĂ©cifiques de lâappareil sĂ©lectionnĂ© !
Construisez vos zones sur-mesure (et sans effort)
Finis les fastidieux allers-retours dans la piĂšce pour tester votre configuration !

-
Ajustement en direct : Les curseurs en bas de carte (Limite Droite, Distance, Largeur, Profondeur) redessinent vos zones géométriques en temps réel sur la carte.
-
Configuration en mÚtres : Tous les réglages se font en mÚtres (-4 m à +4 m) pour plus de sens (finis les millimÚtres incompréhensibles).
-
Support de lâinclinaison : Votre capteur nâest pas posĂ© bien droit ? Un curseur dâAngle compense dynamiquement tout le calcul trigonomĂ©trique de lâaffichage.
Visualisez vos cibles en temps réel
Testez dynamiquement lâoccupation de vos zones avec validation visuelle instantanĂ©e.

-
Suivi 2D précis : Les cibles (personnes)


se déplacent en direct sur le plan quadrillé. -
RĂ©activitĂ© lumineuse : DĂšs quâune cible pĂ©nĂštre dans les limites dâune zone, celle-ci sâillumine instantanĂ©ment. Câest lâoutil parfait pour vĂ©rifier vos bordures et Ă©viter les dĂ©clenchements parasites.
Configuration & Code
Prérequis (HACS)
Pour faire fonctionner cette carte, vous aurez besoin des modules suivants :
-
Mushroom Cards (pour lâinterface de contrĂŽle)
-
Plotly Graph Card (pour le rendu radar interactif)
-
Config Template Card (pour la sélection dynamique du capteur)
-
Stack In Card & Tabbed Card (pour la mise en page propre)
Code YAML de la carte
type: vertical-stack
cards:
- type: custom:config-template-card
entities:
- input_select.liste_esp_ld2450
- >-
${ states['input_select.liste_esp_ld2450'] ? 'binary_sensor.' +
states['input_select.liste_esp_ld2450'].state + '_radar_any_presence' :
'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'binary_sensor.' +
states['input_select.liste_esp_ld2450'].state + '_radar_zone1_presence' :
'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'binary_sensor.' +
states['input_select.liste_esp_ld2450'].state + '_radar_zone2_presence' :
'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'binary_sensor.' +
states['input_select.liste_esp_ld2450'].state + '_radar_zone3_presence' :
'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'binary_sensor.' +
states['input_select.liste_esp_ld2450'].state + '_radar_zout1_presence' :
'sun.sun' }
variables:
esp: >-
states['input_select.liste_esp_ld2450'] ?
states['input_select.liste_esp_ld2450'].state : 'esp_salon02'
card:
type: vertical-stack
cards:
- type: custom:mushroom-select-card
entity: input_select.liste_esp_ld2450
name: Capteur LD2450 Actif
icon: mdi:radar
layout: horizontal
- type: custom:mushroom-entity-card
entity: ${ 'binary_sensor.' + esp + '_radar_any_presence' }
name: Détection Globale (Toutes zones)
icon: mdi:home-account
icon_color: >-
${ states['binary_sensor.' + esp + '_radar_any_presence'].state ===
'on' ? '#2E8B57' : 'disabled' }
layout: horizontal
- type: grid
columns: 2
square: false
cards:
- type: custom:mushroom-entity-card
entity: ${ 'binary_sensor.' + esp + '_radar_zone1_presence' }
name: Zone 1
icon: mdi:square-outline
icon_color: >-
${ states['binary_sensor.' + esp +
'_radar_zone1_presence']?.state === 'on' ? '#2E8B57' :
'disabled' }
- type: custom:mushroom-entity-card
entity: ${ 'binary_sensor.' + esp + '_radar_zone2_presence' }
name: Zone 2
icon: mdi:square-outline
icon_color: >-
${ states['binary_sensor.' + esp +
'_radar_zone2_presence']?.state === 'on' ? '#2E8B57' :
'disabled' }
- type: custom:mushroom-entity-card
entity: ${ 'binary_sensor.' + esp + '_radar_zone3_presence' }
name: Zone 3
icon: mdi:square-outline
icon_color: >-
${ states['binary_sensor.' + esp +
'_radar_zone3_presence']?.state === 'on' ? '#2E8B57' :
'disabled' }
- type: custom:mushroom-entity-card
entity: ${ 'binary_sensor.' + esp + '_radar_zout1_presence' }
name: Exclusion
icon: mdi:shield-off-outline
icon_color: >-
${ states['binary_sensor.' + esp +
'_radar_zout1_presence']?.state === 'on' ? '#2E8B57' :
'disabled' }
- type: custom:plotly-graph
title: Visualisation Temps Réel
refresh_interval: 1
hours_to_show: current_day
ha_theme: true
layout:
height: 400
margin:
l: 30
r: 30
t: 30
b: 30
xaxis:
type: number
range:
- -4
- 4
dtick: 1
gridcolor: RGBA(200,200,200,0.1)
zerolinecolor: RGBA(200,200,200,0.2)
fixedrange: true
yaxis:
type: number
range:
- 8
- 0
dtick: 1
gridcolor: RGBA(200,200,200,0.1)
zerolinecolor: RGBA(200,200,200,0.2)
fixedrange: true
scaleanchor: x
scaleratio: 1
entities:
- entity: ""
name: Cible 1
mode: markers
marker:
size: 15
color: "#2E8B57"
symbol: circle
x: |
$fn ({hass}) => {
let esp = hass.states['input_select.liste_esp_ld2450']?.state || 'esp_salon02';
return [ Number(hass.states['sensor.'+esp+'_radar_target1_x']?.state?.replace(',', '.') || 0) ];
}
"y": |
$fn ({hass}) => {
let esp = hass.states['input_select.liste_esp_ld2450']?.state || 'esp_salon02';
return [ Number(hass.states['sensor.'+esp+'_radar_target1_y']?.state?.replace(',', '.') || 0) ];
}
- entity: ""
name: Cible 2
mode: markers
marker:
size: 12
color: orange
symbol: circle
x: |
$fn ({hass}) => {
let esp = hass.states['input_select.liste_esp_ld2450']?.state || 'esp_salon02';
return [ Number(hass.states['sensor.'+esp+'_radar_target2_x']?.state?.replace(',', '.') || 0) ];
}
"y": |
$fn ({hass}) => {
let esp = hass.states['input_select.liste_esp_ld2450']?.state || 'esp_salon02';
return [ Number(hass.states['sensor.'+esp+'_radar_target2_y']?.state?.replace(',', '.') || 0) ];
}
- entity: ""
name: Cible 3
mode: markers
marker:
size: 12
color: blue
symbol: circle
x: |
$fn ({hass}) => {
let esp = hass.states['input_select.liste_esp_ld2450']?.state || 'esp_salon02';
return [ Number(hass.states['sensor.'+esp+'_radar_target3_x']?.state?.replace(',', '.') || 0) ];
}
"y": |
$fn ({hass}) => {
let esp = hass.states['input_select.liste_esp_ld2450']?.state || 'esp_salon02';
return [ Number(hass.states['sensor.'+esp+'_radar_target3_y']?.state?.replace(',', '.') || 0) ];
}
- entity: ""
name: Zone 1
mode: lines
fill: toself
fillcolor: >-
$ex hass.states['binary_sensor.' +
(hass.states['input_select.liste_esp_ld2450'] ?
hass.states['input_select.liste_esp_ld2450'].state : 'esp_salon02') +
'_radar_zone1_presence'].state === 'on' ? 'RGBA(46,139,87,0.4)' :
'RGBA(46,139,87,0.1)'
line:
color: RGBA(46,139,87,0.8)
width: 2
x: |
$fn ({hass}) => {
let esp = hass.states['input_select.liste_esp_ld2450']?.state || 'esp_salon02';
let zx = Number(hass.states['number.'+esp+'_radar_zone1_x']?.state?.replace(',', '.') || 0);
let zw = Number(hass.states['number.'+esp+'_radar_zone1_width']?.state?.replace(',', '.') || 0);
let zh = Number(hass.states['number.'+esp+'_radar_zone1_height']?.state?.replace(',', '.') || 0);
let angle = Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) * Math.PI / 180;
let angle90 = (Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) - 90) * Math.PI / 180;
return [ zx, zx - zw * Math.cos(angle), zx - zw * Math.cos(angle) + zh * Math.cos(angle90), zx + zh * Math.cos(angle90), zx ];
}
"y": |
$fn ({hass}) => {
let esp = hass.states['input_select.liste_esp_ld2450']?.state || 'esp_salon02';
let zy = Number(hass.states['number.'+esp+'_radar_zone1_y']?.state?.replace(',', '.') || 0);
let zw = Number(hass.states['number.'+esp+'_radar_zone1_width']?.state?.replace(',', '.') || 0);
let zh = Number(hass.states['number.'+esp+'_radar_zone1_height']?.state?.replace(',', '.') || 0);
let angle = Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) * Math.PI / 180;
let angle90 = (Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) + 90) * Math.PI / 180;
return [ zy, zy + zw * Math.sin(angle), zy + zw * Math.sin(angle) + zh * Math.sin(angle90), zy + zh * Math.sin(angle90), zy ];
}
- entity: ""
name: Zone 2
mode: lines
fill: toself
fillcolor: >-
$ex hass.states['binary_sensor.' +
(hass.states['input_select.liste_esp_ld2450'] ?
hass.states['input_select.liste_esp_ld2450'].state : 'esp_salon02') +
'_radar_zone2_presence'].state === 'on' ? 'RGBA(255,165,0,0.4)' :
'RGBA(255,165,0,0.1)'
line:
color: RGBA(255,165,0,0.8)
width: 2
x: |
$fn ({hass}) => {
let esp = hass.states['input_select.liste_esp_ld2450']?.state || 'esp_salon02';
let zx = Number(hass.states['number.'+esp+'_radar_zone2_x']?.state?.replace(',', '.') || 0);
let zw = Number(hass.states['number.'+esp+'_radar_zone2_width']?.state?.replace(',', '.') || 0);
let zh = Number(hass.states['number.'+esp+'_radar_zone2_height']?.state?.replace(',', '.') || 0);
let angle = Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) * Math.PI / 180;
let angle90 = (Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) - 90) * Math.PI / 180;
return [ zx, zx - zw * Math.cos(angle), zx - zw * Math.cos(angle) + zh * Math.cos(angle90), zx + zh * Math.cos(angle90), zx ];
}
"y": |
$fn ({hass}) => {
let esp = hass.states['input_select.liste_esp_ld2450']?.state || 'esp_salon02';
let zy = Number(hass.states['number.'+esp+'_radar_zone2_y']?.state?.replace(',', '.') || 0);
let zw = Number(hass.states['number.'+esp+'_radar_zone2_width']?.state?.replace(',', '.') || 0);
let zh = Number(hass.states['number.'+esp+'_radar_zone2_height']?.state?.replace(',', '.') || 0);
let angle = Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) * Math.PI / 180;
let angle90 = (Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) + 90) * Math.PI / 180;
return [ zy, zy + zw * Math.sin(angle), zy + zw * Math.sin(angle) + zh * Math.sin(angle90), zy + zh * Math.sin(angle90), zy ];
}
- entity: ""
name: Zone 3
mode: lines
fill: toself
fillcolor: >-
$ex hass.states['binary_sensor.' +
(hass.states['input_select.liste_esp_ld2450'] ?
hass.states['input_select.liste_esp_ld2450'].state : 'esp_salon02') +
'_radar_zone3_presence'].state === 'on' ? 'RGBA(0,0,255,0.4)' :
'RGBA(0,0,255,0.1)'
line:
color: RGBA(0,0,255,0.8)
width: 2
x: |
$fn ({hass}) => {
let esp = hass.states['input_select.liste_esp_ld2450']?.state || 'esp_salon02';
let zx = Number(hass.states['number.'+esp+'_radar_zone3_x']?.state?.replace(',', '.') || 0);
let zw = Number(hass.states['number.'+esp+'_radar_zone3_width']?.state?.replace(',', '.') || 0);
let zh = Number(hass.states['number.'+esp+'_radar_zone3_height']?.state?.replace(',', '.') || 0);
let angle = Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) * Math.PI / 180;
let angle90 = (Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) - 90) * Math.PI / 180;
return [ zx, zx - zw * Math.cos(angle), zx - zw * Math.cos(angle) + zh * Math.cos(angle90), zx + zh * Math.cos(angle90), zx ];
}
"y": |
$fn ({hass}) => {
let esp = hass.states['input_select.liste_esp_ld2450']?.state || 'esp_salon02';
let zy = Number(hass.states['number.'+esp+'_radar_zone3_y']?.state?.replace(',', '.') || 0);
let zw = Number(hass.states['number.'+esp+'_radar_zone3_width']?.state?.replace(',', '.') || 0);
let zh = Number(hass.states['number.'+esp+'_radar_zone3_height']?.state?.replace(',', '.') || 0);
let angle = Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) * Math.PI / 180;
let angle90 = (Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) + 90) * Math.PI / 180;
return [ zy, zy + zw * Math.sin(angle), zy + zw * Math.sin(angle) + zh * Math.sin(angle90), zy + zh * Math.sin(angle90), zy ];
}
- entity: ""
name: Exclusion 1
mode: lines
fill: toself
fillcolor: >-
$ex hass.states['binary_sensor.' +
(hass.states['input_select.liste_esp_ld2450'] ?
hass.states['input_select.liste_esp_ld2450'].state : 'esp_salon02') +
'_radar_zout1_presence'].state === 'on' ? 'RGBA(255,0,0,0.4)' :
'RGBA(255,0,0,0.1)'
line:
color: RGBA(255,0,0,0.8)
width: 2
dash: dash
x: |
$fn ({hass}) => {
let esp = hass.states['input_select.liste_esp_ld2450']?.state || 'esp_salon02';
let zx = Number(hass.states['number.'+esp+'_radar_zout1_x']?.state?.replace(',', '.') || 0);
let zw = Number(hass.states['number.'+esp+'_radar_zout1_width']?.state?.replace(',', '.') || 0);
let zh = Number(hass.states['number.'+esp+'_radar_zout1_height']?.state?.replace(',', '.') || 0);
let angle = Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) * Math.PI / 180;
let angle90 = (Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) - 90) * Math.PI / 180;
return [ zx, zx - zw * Math.cos(angle), zx - zw * Math.cos(angle) + zh * Math.cos(angle90), zx + zh * Math.cos(angle90), zx ];
}
"y": |
$fn ({hass}) => {
let esp = hass.states['input_select.liste_esp_ld2450']?.state || 'esp_salon02';
let zy = Number(hass.states['number.'+esp+'_radar_zout1_y']?.state?.replace(',', '.') || 0);
let zw = Number(hass.states['number.'+esp+'_radar_zout1_width']?.state?.replace(',', '.') || 0);
let zh = Number(hass.states['number.'+esp+'_radar_zout1_height']?.state?.replace(',', '.') || 0);
let angle = Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) * Math.PI / 180;
let angle90 = (Number(hass.states['number.'+esp+'_radar_angle']?.state?.replace(',', '.') || 0) + 90) * Math.PI / 180;
return [ zy, zy + zw * Math.sin(angle), zy + zw * Math.sin(angle) + zh * Math.sin(angle90), zy + zh * Math.sin(angle90), zy ];
}
- type: vertical-stack
cards:
- type: custom:config-template-card
entities:
- input_select.liste_esp_ld2450
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_angle' : 'sun.sun' }
variables:
esp: >-
states['input_select.liste_esp_ld2450'] ? states['input_select.liste_esp_ld2450'].state : 'esp_salon02'
card:
type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_angle' }
name: Angle d'inclinaison du radar
icon: mdi:angle-acute
- type: custom:tabbed-card
tabs:
- attributes:
label: Zone 1
card:
type: custom:config-template-card
entities:
- input_select.liste_esp_ld2450
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zone1_x' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zone1_y' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zone1_width' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zone1_height' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zone1_timeout' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'switch.' + states['input_select.liste_esp_ld2450'].state + '_radar_target_must_leave_zone1' : 'sun.sun' }
variables:
esp: >-
states['input_select.liste_esp_ld2450'] ? states['input_select.liste_esp_ld2450'].state : 'esp_salon02'
card:
type: grid
columns: 2
square: false
cards:
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zone1_x' }
name: Limite Droite (X)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zone1_y' }
name: Distance Initiale (Y)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zone1_width' }
name: Expansion Gauche (Largeur)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zone1_height' }
name: Profondeur (Longueur)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zone1_timeout' }
name: Timeout
display_mode: buttons
- type: custom:mushroom-entity-card
entity: ${ 'switch.' + esp + '_radar_target_must_leave_zone1' }
name: Rester Actif (Sortie)
icon: mdi:account-cancel
icon_color: >-
${ states['switch.' + esp + '_radar_target_must_leave_zone1']?.state === 'on' ? '#2E8B57' : 'disabled' }
tap_action:
action: toggle
- attributes:
label: Zone 2
card:
type: custom:config-template-card
entities:
- input_select.liste_esp_ld2450
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zone2_x' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zone2_y' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zone2_width' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zone2_height' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zone2_timeout' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'switch.' + states['input_select.liste_esp_ld2450'].state + '_radar_target_must_leave_zone2' : 'sun.sun' }
variables:
esp: >-
states['input_select.liste_esp_ld2450'] ? states['input_select.liste_esp_ld2450'].state : 'esp_salon02'
card:
type: grid
columns: 2
square: false
cards:
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zone2_x' }
name: Limite Droite (X)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zone2_y' }
name: Distance Initiale (Y)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zone2_width' }
name: Expansion Gauche (Largeur)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zone2_height' }
name: Profondeur (Longueur)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zone2_timeout' }
name: Timeout
display_mode: buttons
- type: custom:mushroom-entity-card
entity: ${ 'switch.' + esp + '_radar_target_must_leave_zone2' }
name: Rester Actif (Sortie)
icon: mdi:account-cancel
icon_color: >-
${ states['switch.' + esp + '_radar_target_must_leave_zone2']?.state === 'on' ? '#2E8B57' : 'disabled' }
tap_action:
action: toggle
- attributes:
label: Zone 3
card:
type: custom:config-template-card
entities:
- input_select.liste_esp_ld2450
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zone3_x' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zone3_y' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zone3_width' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zone3_height' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zone3_timeout' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'switch.' + states['input_select.liste_esp_ld2450'].state + '_radar_target_must_leave_zone3' : 'sun.sun' }
variables:
esp: >-
states['input_select.liste_esp_ld2450'] ? states['input_select.liste_esp_ld2450'].state : 'esp_salon02'
card:
type: grid
columns: 2
square: false
cards:
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zone3_x' }
name: Limite Droite (X)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zone3_y' }
name: Distance Initiale (Y)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zone3_width' }
name: Expansion Gauche (Largeur)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zone3_height' }
name: Profondeur (Longueur)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zone3_timeout' }
name: Timeout
display_mode: buttons
- type: custom:mushroom-entity-card
entity: ${ 'switch.' + esp + '_radar_target_must_leave_zone3' }
name: Rester Actif (Sortie)
icon: mdi:account-cancel
icon_color: >-
${ states['switch.' + esp + '_radar_target_must_leave_zone3']?.state === 'on' ? '#2E8B57' : 'disabled' }
tap_action:
action: toggle
- attributes:
label: Exclusion 1
card:
type: custom:config-template-card
entities:
- input_select.liste_esp_ld2450
- >-
${ states['input_select.liste_esp_ld2450'] ? 'switch.' + states['input_select.liste_esp_ld2450'].state + '_radar_zout1_enable' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zout1_x' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zout1_y' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zout1_width' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zout1_height' : 'sun.sun' }
- >-
${ states['input_select.liste_esp_ld2450'] ? 'number.' + states['input_select.liste_esp_ld2450'].state + '_radar_zout1_timeout' : 'sun.sun' }
variables:
esp: >-
states['input_select.liste_esp_ld2450'] ? states['input_select.liste_esp_ld2450'].state : 'esp_salon02'
card:
type: vertical-stack
cards:
- type: custom:mushroom-entity-card
entity: ${ 'switch.' + esp + '_radar_zout1_enable' }
name: Activer Exclusion
icon_color: >-
${ states['switch.' + esp + '_radar_zout1_enable']?.state === 'on' ? '#2E8B57' : 'disabled' }
tap_action:
action: toggle
- type: grid
columns: 2
square: false
cards:
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zout1_x' }
name: Limite Droite (X)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zout1_y' }
name: Distance Initiale (Y)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zout1_width' }
name: Expansion Gauche (Largeur)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zout1_height' }
name: Profondeur (Longueur)
- type: custom:mushroom-number-card
entity: ${ 'number.' + esp + '_radar_zout1_timeout' }
name: Timeout
display_mode: buttons
Code Source & GitHub
Pour ne pas surcharger ce post avec dâinterminables dĂ©tails techniques (lâexplication du code Javascript de la carte Plotly, ou nos modifications apportĂ©es au code ESPHome)⊠jâai tout centralisĂ© et documentĂ© pas-Ă -pas sur GitHub.
Vous y trouverez les prérequis, le firmware .ld2450.yaml adapté, et la fameuse carte à copier-coller :
Découvrir le projet et la carte sur GitHub
NB (Concours Dashboard) : Comme il ne fallait choisir quâune seule carte pour la participation au concours, jâai sĂ©lectionnĂ© le LD2450. Mais pour info, sachez quâun travail en cours est actuellement menĂ© pour dĂ©cliner cette exacte mĂȘme philosophie dâinterface de calibration (visuelle et multi-ESP) sur le LD2410. Le chantier est visible sur le dĂ©pĂŽt global ha-ld24xx-radars si les curieux veulent dĂ©jĂ y jeter un Ćil !

