Bonjour,
je cherche à activer le deep_ sleep tous les x heures et 3 minutes. Je ne trouve pas de solution sur le net, je fais appelle à la communauté.
Pour le moment, j’ai le sleep duration sur 60min. Mais si je redémarre l’esp32 à 10h30 par exemple, il se réveillera à 11h30. Je voudrais qu’il se réveille a 11h03, puis 12h03 … .
Ce que tu cherches à faire c’est un réveil toutes les X heures suivi d’un offset de 3 minutes.
Le sleep_duration te permet de fixer ton nombre d’heures mais je ne pense pas qu’il existe un moyen simple d’instaurer un offset.
Je vais regarder dans la doc d’ESPHome mais j’imagine que tu as déjà jeté un oeil.
Salut,
en utilisant globals et l’ automation on_boot
globals:
- id: sleep_interval_hours
type: int
restore_value: no
initial_value: '1' # Toutes les 1 heure
- id: target_minute
type: int
restore_value: no
initial_value: '3' # À la minute 03
on_boot:
priority: -100
then:
- delay: 15s # Attente de la synchro HA
- lambda: |-
auto time = id(ha_time).now();
if (!time.is_valid()) {
ESP_LOGI("custom", "Heure invalide (pas de synchro HA). Deep sleep 60 min par défaut.");
id(deep_sleep_1).set_sleep_duration(60 * 60 * 1000ULL);
id(deep_sleep_1)->begin_sleep();
return;
}
int now_seconds = time.hour * 3600 + time.minute * 60 + time.second;
int h = time.hour;
int m = time.minute;
int interval = id(sleep_interval_hours);
int target_min = id(target_minute);
int next_target_hour = (h / interval) * interval;
if (m >= target_min) {
next_target_hour += interval;
}
if (next_target_hour >= 24) next_target_hour -= 24;
int target_seconds = next_target_hour * 3600 + target_min * 60;
int sleep_seconds = target_seconds - now_seconds;
if (sleep_seconds <= 60) sleep_seconds += interval * 3600;
ESP_LOGI("custom", "Il est %02d:%02d:%02d", h, m, time.second);
ESP_LOGI("custom", "Prochain réveil prévu à %02d:%02d (dans %d sec)", next_target_hour, target_min, sleep_seconds);
id(deep_sleep_1).set_sleep_duration(sleep_seconds * 1000ULL);
id(deep_sleep_1)->begin_sleep();
xxxx.yaml: In lambda function:
xxxx.yaml:18:23: error: 'class esphome::deep_sleep::DeepSleepComponent' has no member named 'start'
xxxx.yaml:43:21: error: 'class esphome::deep_sleep::DeepSleepComponent' has no member named 'start'
*** [.pioenvs\xxxx\src\main.cpp.o] Error 1
le code :
esphome:
name: ${name}
name_add_mac_suffix: false
friendly_name: ${friendly_name}
on_boot:
- priority: -100
then:
- delay: 15s # Attente de la synchro HA
- lambda: |-
auto time = id(ha_time).now();
if (!time.is_valid()) {
ESP_LOGI("custom", "Heure invalide (pas de synchro HA). Deep sleep 60 min par défaut.");
id(deep_sleep_1).set_sleep_duration(60 * 60 * 1000ULL);
id(deep_sleep_1).start();
return;
}
int now_seconds = time.hour * 3600 + time.minute * 60 + time.second;
int h = time.hour;
int m = time.minute;
int interval = id(sleep_interval_hours);
int target_min = id(target_minute);
int next_target_hour = (h / interval) * interval;
if (m >= target_min) {
next_target_hour += interval;
}
if (next_target_hour >= 24) next_target_hour -= 24;
int target_seconds = next_target_hour * 3600 + target_min * 60;
int sleep_seconds = target_seconds - now_seconds;
if (sleep_seconds <= 60) sleep_seconds += interval * 3600;
ESP_LOGI("custom", "Il est %02d:%02d:%02d", h, m, time.second);
ESP_LOGI("custom", "Prochain réveil prévu à %02d:%02d (dans %d sec)", next_target_hour, target_min, sleep_seconds);
id(deep_sleep_1).set_sleep_duration(sleep_seconds * 1000ULL);
id(deep_sleep_1).start();
esp32:
board: esp32-s3-devkitc-1
framework:
type: esp-idf
flash_size: 32MB
deep_sleep:
id: deep_sleep_1
run_duration: 2min
#sleep_duration: 58min
wakeup_pin: GPIO3 # Bouton vert
wakeup_pin_mode: INVERT_WAKEUP
la compilation est passée. Je vois que maintenant l’esp se met en sommeil directement au boot.
Je vais attendre voir à 18h03 si mon écran ce rafraichi.
Il me faudrais qu’au boot , l’esp reste allumé 2 min puis passe en sommeil avec l’heure programmé toutes les X heure 03 minutes.
oui regarde les logs série tu devrais voir les logs du type :
Il est 17:50:05
Prochain réveil prévu à 18:03 (dans xxxx sec)
Logiquement ton ESP se réveille à HH:03 toutes les heures , même si tu le démarres à une heure aléatoire. Exécute son run_duration pendant 2 minutes, puis se met en deep sleep jusqu’à la prochaine heure HH:03 .
Ok, ça aurait été mieux qu’il puisse actualiser les informations au boot avant de passer en sommeil. Parce que là, je suis obligé d’attendre HH:03 pour voir les changements que j’y apporte.
Au pire, j’enlève le code. Je finalise mes configurations et le remets.
soit tu y ajouter un délai fixe avant , risque de surcoso de la batterie , ou alors commente begin_sleep() pour travailler tranquille , vérifie dans les logs si HA envoie bien l’heure ha_time une fois OK → remets le deep sleep.
Bon du coup ca fonctionne, je les mis en priority 600 a la fin de met execution. Comme j’ai le temps d’avoir les sensor actualisé, puis actualisé l’écran et passer en sommeil.
Chez pas si c’est la meilleure solution, mais ça fonctionne.
[19:25:34][I][custom:046]: Il est 19:25:34
[19:25:34][I][custom:047]: Prochain réveil prévu à 20:03 (dans 2246 sec)
[19:25:34][I][deep_sleep:061]: Beginning sleep
[19:25:34][I][deep_sleep:063]: Sleeping for 2246000000us
esphome:
name: ${name}
name_add_mac_suffix: false
friendly_name: ${friendly_name}
on_boot:
- priority: 600
then:
- output.turn_on: bsp_sd_enable
- output.turn_on: bsp_battery_enable
- delay: 200ms
- component.update: battery_voltage
- component.update: battery_level
- delay: 40s
- component.update: epaper_display
- delay: 10s
- lambda: |-
auto time = id(ha_time).now();
if (!time.is_valid()) {
ESP_LOGI("custom", "Heure invalide (pas de synchro HA). Deep sleep 60 min par défaut.");
id(deep_sleep_1).set_sleep_duration(60 * 60 * 1000ULL);
id(deep_sleep_1)->begin_sleep();
return;
}
int now_seconds = time.hour * 3600 + time.minute * 60 + time.second;
int h = time.hour;
int m = time.minute;
int interval = id(sleep_interval_hours);
int target_min = id(target_minute);
int next_target_hour = (h / interval) * interval;
if (m >= target_min) {
next_target_hour += interval;
}
if (next_target_hour >= 24) next_target_hour -= 24;
int target_seconds = next_target_hour * 3600 + target_min * 60;
int sleep_seconds = target_seconds - now_seconds;
if (sleep_seconds <= 60) sleep_seconds += interval * 3600;
ESP_LOGI("custom", "Il est %02d:%02d:%02d", h, m, time.second);
ESP_LOGI("custom", "Prochain réveil prévu à %02d:%02d (dans %d sec)", next_target_hour, target_min, sleep_seconds);
id(deep_sleep_1).set_sleep_duration(sleep_seconds * 1000ULL);
id(deep_sleep_1)->begin_sleep();
external_components:
- source:
type: git
url: https://github.com/lublak/esphome
ref: dev
components: [ waveshare_epaper ]
esp32:
board: esp32-s3-devkitc-1
framework:
type: esp-idf
flash_size: 32MB
psram:
mode: octal
deep_sleep:
id: deep_sleep_1
run_duration: 2min
#sleep_duration: 58min
wakeup_pin: GPIO3 # Bouton vert
wakeup_pin_mode: INVERT_WAKEUP
Top, super boulot ! et tu as trouvé une solution propre et efficace en utilisant priority: 600 , ce qui fait que ton bloc on_boot s’exécute tout à la fin de l’initialisation , après que les capteurs et les entités HA soient synchronisées .
Salut @hackdiy,
j’ai trouvé un bug, à partir de 23h03, il ne se réveille plus. Il y a un problème pour 00h03. Après ça fonctionne très bien toute la journée, mais le passage à minuit non.
- lambda: |-
auto time = id(ha_time).now();
if (!time.is_valid()) {
ESP_LOGI("custom", "Heure invalide (pas de synchro HA). Deep sleep 60 min par défaut.");
id(deep_sleep_1).set_sleep_duration(60 * 60 * 1000ULL);
//id(deep_sleep_1)->begin_sleep();
id(deep_sleep_1).begin_sleep(true);
return;
}
int now_seconds = time.hour * 3600 + time.minute * 60 + time.second;
int h = time.hour;
int m = time.minute;
int interval = id(sleep_interval_hours);
int target_min = id(target_minute);
int next_target_hour = (h / interval) * interval;
if (m >= target_min) {
next_target_hour += interval;
}
if (next_target_hour >= 24) next_target_hour -= 24;
int target_seconds = next_target_hour * 3600 + target_min * 60;
int sleep_seconds = target_seconds - now_seconds;
if (sleep_seconds <= 60) sleep_seconds += interval * 3600;
ESP_LOGI("custom", "Il est %02d:%02d:%02d", h, m, time.second);
ESP_LOGI("custom", "Prochain réveil prévu à %02d:%02d (dans %d sec)", next_target_hour, target_min, sleep_seconds);
id(deep_sleep_1).set_sleep_duration(sleep_seconds * 1000ULL);
//id(deep_sleep_1)->begin_sleep();
id(deep_sleep_1).begin_sleep(true);
je pense que ça vient du problème next_target_hour devient 0, donc target_seconds = 180, mais now_seconds est ~83 000 (23h10).
Résultat : sleep_seconds est négatif tu ajoutes un intervalle, mais le calcul tombe à côté , et ne fait pas le saut au lendemain correctement.
Essaye en modifiant cette partie
- lambda: |-
auto time = id(ha_time).now();
if (!time.is_valid()) {
ESP_LOGI("custom", "Heure invalide (pas de synchro NTP). Deep sleep 60 min par défaut.");
id(deep_sleep_1).set_sleep_duration(60 * 60 * 1000ULL);
id(deep_sleep_1).begin_sleep(true);
return;
}
int now_seconds = time.hour * 3600 + time.minute * 60 + time.second;
int h = time.hour;
int m = time.minute;
int interval = id(sleep_interval_hours);
int target_min = id(target_minute);
// Calcul de la prochaine heure cible
int next_target_hour = (h / interval) * interval;
if (m >= target_min) {
next_target_hour += interval;
}
if (next_target_hour >= 24) next_target_hour -= 24;
int target_seconds = next_target_hour * 3600 + target_min * 60;
if (target_seconds <= now_seconds) {
target_seconds += 24 * 3600; // bascule au jour suivant
}
int sleep_seconds = target_seconds - now_seconds;
ESP_LOGI("custom", "Il est %02d:%02d:%02d", h, m, time.second);
ESP_LOGI("custom", "Prochain réveil prévu à %02d:%02d (dans %d sec)",
next_target_hour, target_min, sleep_seconds);
id(deep_sleep_1).set_sleep_duration((uint64_t)sleep_seconds * 1000ULL);
id(deep_sleep_1).begin_sleep(true);