Cette année, j’ai décidé d’optimiser la gestion de la filtration de ma piscine. Mon objectif ? Appliquer la même philosophie de redondance et de haute disponibilité que pour mon infrastructure réseau (notamment avec mon cluster Proxmox).
En domotique, et particulièrement pour une piscine, la question de la sécurisation est cruciale. Personne n’est à l’abri d’une défaillance technique. Or, garantir un temps de filtration précis est vital, surtout lors des fortes chaleurs, sous peine de voir l’eau tourner en quelques jours. C’est pourquoi cette année j’ai encore amélioré un peu mon installation pour permettre une sécurisation de la planification de la filtration.
Le choix du matériel : le module Shelly Pro 3
Pour piloter ma filtration, j’ai renouvelé ma confiance au Shelly Pro 3. Ce module rail DIN s’intègre parfaitement dans un tableau électrique pour une installation propre dans le poolhouse.
Ses atouts sont nombreux :
- Polyvalence : 3 entrées à contact sec pour piloter simultanément la pompe, l’éclairage et la PAC (Pompe à Chaleur).
- Fiabilité filaire : Il dispose d’un port Ethernet (RJ45).
En tant que professionnel de l’IT, je privilégie toujours le filaire. Le local technique est souvent éloigné de la maison et le Wi-Fi peut s’y révéler instable. Pour du matériel critique (caméras, domotique de sécurité), le câble reste la solution ultime pour garantir la communication sur le réseau local.
L’évolution de la stratégie : de l’ordre direct à la planification locale
Jusqu’à présent, ma domotique (via Home Assistant) calculait le temps de filtration optimal et envoyait en temps réel les ordres d’allumage et d’extinction. Bien que fiable, ce système présentait un point de vulnérabilité : si le serveur domotique tombait, la pompe s’arrêtait.
Cette année, je passe à une stratégie de pilotage “hybride” beaucoup plus résiliente :
- La domotique reste le cerveau : Elle évalue chaque jour la durée de filtration idéale selon la température de l’eau et les tarifs d’énergie.
- Le module devient autonome : Au lieu d’un simple ordre “On/Off”, Home Assistant envoie désormais une planification complète au module Shelly.
- La sécurité avant tout : En cas de coupure réseau ou de panne du serveur domotique, le Shelly conserve sa programmation en mémoire. Il continue de piloter la pompe localement, assurant un fonctionnement nominal jusqu’à mon intervention.
L’idée : La domotique donne la direction, mais le module Shelly assure l’exécution en toute autonomie.
Pourquoi cette approche change tout ?
Optimisation énergétique : On continue de profiter de la puissance de calcul de la domotique pour réduire les factures.
- Sérénité totale : Même si votre box internet ou votre serveur plante pendant vos vacances, votre piscine reste propre et fonctionnelle.
- Maintenance facilitée : Le système est moins dépendant des aléas du réseau domestique.
Comment Home Assistant prends le contrôle de la planification du module Shelly ?
Pour y parvenir, nous allons utiliser l’API Shelly via RESTful. Avec un peu de code YAML dans un fichier packages, on va pouvoir appeler des fonctions pour effacer la programmation en mémoire dans le Shelly et lui en envoyer une nouvelle que la domotique prendra soin de définir chaque jour de manière dynamique.

Il faut donc créer un nouveau fichier yaml package. Si vous ne connaissez pas bien les packages, je vous invite à lire mon guide dédié ici, c’est une bonne pratique à adopter au plus vite sur votre installation.
Vous devrez disposer de l’adresse IP du module Shelly sur votre réseau et vous prendrez soin de figer son adresse IP dans le DHCP ou via une configuration manuelle. Une fois fait, il n’y a plus qu’a alimenter le fichier package avec les commandes. Ici j’ai créé les différentes commandes REST selon les temps de filtration que j’utilise. 4h, 6h, 8h ou 12h.
rest_command:
# PROG 1 - Filtration pour 4h
shelly_pro3_schedule_prog1_on:
url: "http://192.168.1.82/rpc/Schedule.Create"
method: POST
content_type: "application/json"
payload: >
{
"enable": true,
"timespec": "0 30 12 * * *",
"calls": [{"method": "Switch.Set", "params": {"id": 0, "on": true}}]
}
shelly_pro3_schedule_prog1_off:
url: "http://192.168.1.82/rpc/Schedule.Create"
method: POST
content_type: "application/json"
payload: >
{
"enable": true,
"timespec": "0 30 14 * * *",
"calls": [{"method": "Switch.Set", "params": {"id": 0, "on": false}}]
}
# PROG 2 - Filtration pour 6h
shelly_pro3_schedule_prog2_on:
url: "http://192.168.1.82/rpc/Schedule.Create"
method: POST
content_type: "application/json"
payload: >
{
"enable": true,
"timespec": "0 0 11 * * *",
"calls": [{"method": "Switch.Set", "params": {"id": 0, "on": true}}]
}
shelly_pro3_schedule_prog2_off:
url: "http://192.168.1.82/rpc/Schedule.Create"
method: POST
content_type: "application/json"
payload: >
{
"enable": true,
"timespec": "0 30 14 * * *",
"calls": [{"method": "Switch.Set", "params": {"id": 0, "on": false}}]
}
shelly_pro3_schedule_prog22_on:
url: "http://192.168.1.82/rpc/Schedule.Create"
method: POST
content_type: "application/json"
payload: >
{
"enable": true,
"timespec": "0 30 16 * * *",
"calls": [{"method": "Switch.Set", "params": {"id": 0, "on": true}}]
}
shelly_pro3_schedule_prog22_off:
url: "http://192.168.1.82/rpc/Schedule.Create"
method: POST
content_type: "application/json"
payload: >
{
"enable": true,
"timespec": "0 0 18 * * *",
"calls": [{"method": "Switch.Set", "params": {"id": 0, "on": false}}]
}
# PROG 3 - Filtration pour 8h
shelly_pro3_schedule_prog3_on:
url: "http://192.168.1.82/rpc/Schedule.Create"
method: POST
content_type: "application/json"
payload: >
{
"enable": true,
"timespec": "0 0 10 * * *",
"calls": [{"method": "Switch.Set", "params": {"id": 0, "on": true}}]
}
shelly_pro3_schedule_prog3_off:
url: "http://192.168.1.82/rpc/Schedule.Create"
method: POST
content_type: "application/json"
payload: >
{
"enable": true,
"timespec": "0 0 18 * * *",
"calls": [{"method": "Switch.Set", "params": {"id": 0, "on": false}}]
}
# PROG 4 - Filtration pour 12h
shelly_pro3_schedule_prog4_on:
url: "http://192.168.1.82/rpc/Schedule.Create"
method: POST
content_type: "application/json"
payload: >
{
"enable": true,
"timespec": "0 0 9 * * *",
"calls": [{"method": "Switch.Set", "params": {"id": 0, "on": true}}]
}
shelly_pro3_schedule_prog4_off:
url: "http://192.168.1.82/rpc/Schedule.Create"
method: POST
content_type: "application/json"
payload: >
{
"enable": true,
"timespec": "0 0 21 * * *",
"calls": [{"method": "Switch.Set", "params": {"id": 0, "on": false}}]
}
shelly_pro3_schedule_list:
url: "http://192.168.1.82/rpc/Schedule.List"
method: GET
shelly_pro3_schedule_delete_all:
url: "http://192.168.1.82/rpc/Schedule.DeleteAll"
method: POST
content_type: "application/json"
payload: "{}"
sensor:
- platform: rest
name: "Shelly Pro3 Schedules"
unique_id: shelly_pro3_schedules
resource: "http://192.168.1.82/rpc/Schedule.List"
method: GET
value_template: "{{ value_json.jobs | length }} schedules actifs"
json_attributes:
- jobs
scan_interval: 60 # actualisation toutes les 60 secondes
En fin de fichier, on retrouve des commandes qui permettent à la fois de supprimer une planification du module Shelly, puis de les lister pour en disposer dans un tableau de bord.
Pour la mise en forme sous le tableau de bord, Home Assistant, on va faire appel à une extension HACS qui permet de créer un tableau avec style. Il s’agit de l’extension Flex Table. Procédez donc à son installation via HACS avant d’entreprendre cette partie.
On va maintenant ajouter le bloc suivant en fin du fichier package. Ce template va nous permettre de mettre en forme les données de planification. Pensez bien à procédez au redémarrage de votre Home Assistant sous Parametres / Outils de développement / YAML une fois le fichier package configuré.
template:
- sensor:
- name: "Shelly Pro3 Schedule Liste"
unique_id: shelly_pro3_schedule_liste
state: "{{ state_attr('sensor.shelly_pro3_schedules', 'jobs') | length }} programmations"
attributes:
programmations: >
{% set jobs = state_attr('sensor.shelly_pro3_schedules', 'jobs') %}
{% if jobs %}
{% set ns = namespace(result=[]) %}
{% for job in jobs %}
{% set parts = job.timespec.split(' ') %}
{% set heure = parts[2] | int %}
{% set minute = parts[1] | int %}
{% set action = job.calls[0].params.on %}
{% set etat = '🟢 ON' if action else '🔴 OFF' %}
{% set actif = '✅ Actif' if job.enable else '⏸️ Désactivé' %}
{% set ligne = "ID " ~ job.id ~ " | " ~ "%02d"|format(heure) ~ "h" ~ "%02d"|format(minute) ~ " | " ~ etat ~ " | " ~ actif %}
{% set ns.result = ns.result + [ligne] %}
{% endfor %}
{{ ns.result | join('\n') }}
{% else %}
Aucune programmation
{% endif %}
Créez ensuite une nouvelle carte sous votre tableau de bord de gestion de la piscine ou vous aurez pris soin d’y ajouter l’entité liste que nous avons créé plus haut, ainsi que l’etat du relais.

Choisissez une nouvelle entité custom, et collez le code ci-dessous :
type: custom:flex-table-card
clickable: false
entities:
- sensor.shelly_pro3_schedules
columns:
- name: Heure
data: jobs
modify: |
(() => {
const parts = x.timespec.split(' ');
const h = String(parseInt(parts[2])).padStart(2, '0');
const m = String(parseInt(parts[1])).padStart(2, '0');
return `<span style="font-family:monospace;font-size:1.1em;font-weight:600;color:#000000">${h}h${m}</span>`;
})()
align: center
multi_delimiter: <br>
- name: Action
data: jobs
modify: |
(() => {
const on = x.calls[0].params.on;
const color = on ? '#22c55e' : '#ef4444';
const bg = on ? '#22c55e18' : '#ef444418';
const border= on ? '#22c55e44' : '#ef444444';
const dot = `<span style="display:inline-block;width:7px;height:7px;border-radius:50%;background:${color};box-shadow:0 0 5px ${color};margin-right:5px;vertical-align:middle"></span>`;
const label = on ? 'ON' : 'OFF';
return `<span style="display:inline-flex;align-items:center;padding:3px 10px;border-radius:20px;background:${bg};border:1px solid ${border};color:${color};font-size:.75em;font-weight:700;letter-spacing:.08em">${dot}${label}</span>`;
})()
align: center
multi_delimiter: <br>
- name: Statut
data: jobs
modify: |
x.enable
? '<span title="Actif" style="font-size:1.1em">✅</span>'
: '<span title="En pause" style="font-size:1.1em">⏸️</span>'
align: center
multi_delimiter: <br>
card_mod:
style: |
ha-card {
background: #16181f;
border: 1px solid rgba(255,255,255,0.06);
border-radius: 16px;
box-shadow: 0 8px 32px rgba(0,0,0,0.5);
}
.card-header {
font-family: 'Syne', sans-serif !important;
font-size: 13px !important;
font-weight: 700 !important;
letter-spacing: .06em !important;
text-transform: uppercase !important;
color: #e2e8f0 !important;
padding: 14px 16px 10px !important;
border-bottom: 1px solid rgba(255,255,255,0.06);
}
table {
width: 100%;
border-collapse: collapse;
}
thead tr th {
font-family: 'DM Mono', monospace !important;
font-size: 9px !important;
font-weight: 500 !important;
letter-spacing: .12em !important;
text-transform: uppercase !important;
color: #334155 !important;
padding: 8px 12px 6px !important;
border-bottom: 1px solid rgba(255,255,255,0.05) !important;
background: transparent !important;
}
tbody tr {
border-bottom: 1px solid rgba(255,255,255,0.04) !important;
transition: background .15s ease;
}
tbody tr:last-child {
border-bottom: none !important;
}
tbody tr:hover {
background: rgba(255,255,255,0.03) !important;
}
tbody tr td {
padding: 10px 12px !important;
color: #94a3b8 !important;
font-size: .9em !important;
}
Résultat, votre tableau de bord indique maintenant la configuration injectée dans le module Shelly après lecture. Ce tableau se met à jour automatiquement dès chaque changement opéré.

L’automatisation Home Assitant
Il ne reste alors plus qu’à construire l’automatisation pour orchestrer tout ce petit monde et faire de cette nouvelle gestion de la filtration, une gestion encore plus intelligente, dynamique et fiable. Pour cela, je fais appel aux triggers ID qui permettent de tout mettre dans une même automatisation.

Notez que l’intégration de l’IA Gemini dans Home Assistant, comme nous vous l’expliquons dans cet autre guide, permet d’avoir les services de l’IA pour définir en un clic le titre et assigner automatiquement les bons TAGs à l’automatisation. C’est vraiment super pratique !
Conclusion
Et voilà une mise à jour intéressante pour la filtration de piscine. Notez que le concept peut tout aussi bien s’appliquer à d’autres applications d’un module Shelly, comme le chauffe-eau par exemple. Avec cette nouvelle approche de pilotage, vous avez la garantie d’une programmation toujours assurée, même si un problème survient sur votre réseau local, votre domotique ou votre Wifi en votre absence. Ce genre de sécurité est primordiale dans une stratégie domotique de qualité, et encore plus quand il est question de garantir la filtration de la piscine en plein cœur de l’été.







