Cron double

Bonjour,

debian 12.9, core 4.5
Thermostat Stable du 2024-09-30 10:49:26

@Loic , je reviens vers toi sur ce sujet de cron double que l’on pensait résolu.

Suite a quelques soucis de gestion de mes thermostats, j’ai ajouté quelques log dans le plugin et un scénario qui contrôle les crons.

tout d’abord le log (épuré), j’ai ajouté un id unique (rand) dans le code pour bien différencier les thread (Format = [id_unique] [Objet][Equipement] [fonction] message ) :

Thermostat :

[2025-11-19 20:21:02][DEBUG] [9750] [Chambre Parentale][Thermostat Chambre Parentale] [cron] repeat commande --> stop
[2025-11-19 20:21:02][DEBUG] [9750] [Chambre Parentale][Thermostat Chambre Parentale] [stopThermostat] Action stop

[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [execute] -> modeAction
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [executeMode] Confort

[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [pull]
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [pull] -> lancement temporal : {"thermostat_id":146}
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [temporal] Début calcul temporel
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [Reschedule] -> next : 2025-11-19 20:36:00, stop : , smartThermostat : 
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [Reschedule] -> Remove cron : 251372

[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [executeMode] -> lancement temporal
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [temporal] Début calcul temporel
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [Reschedule] -> next : 2025-11-19 20:36:00, stop : , smartThermostat : 
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [Reschedule] -> pas de cron a supprimer.

[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [temporal] Reprogrammation automatique : 2025-11-19 20:36:00
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [temporal] Programmation Smartstart

[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [temporal] Reprogrammation automatique : 2025-11-19 20:36:00
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [temporal] Programmation Smartstart
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [getNextState] Plugin agenda détecté

[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [getNextState] Plugin agenda détecté

[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [calculTemporalData] Température intérieure : 18.3 - Température extérieure : 11.2 - Consigne : 20
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [calculTemporalData] Direction : 1
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [calculTemporalData] Power calcul : (1.7 * 72.71) + (8.8 * 3.85) + 0 = 157.487
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [getNextState] Durée Smartstart : 24 à 2025-11-19 21:00:00 programmation : 2025-11-19 20:36:00
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [getNextState] Prochain Smartstart : 2025-11-19 20:36:00
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [Reschedule] -> next : 2025-11-19 20:36:00, stop : , smartThermostat : Array
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [Reschedule] -> pas de cron a supprimer.
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [temporal] Arrêt Smartstart
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [calculTemporalData] Température intérieure : 18.3 - Température extérieure : 11.2 - Consigne : 20
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [calculTemporalData] Direction : 1
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [calculTemporalData] Power calcul : (1.7 * 72.71) + (8.8 * 3.85) + 0 = 157.487
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [temporal] Durée du cycle  : 15
[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [Reschedule] -> next : , stop : 1, smartThermostat : 

[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [calculTemporalData] Température intérieure : 18.3 - Température extérieure : 11.2 - Consigne : 20
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [calculTemporalData] Direction : 1
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [calculTemporalData] Power calcul : (1.7 * 72.71) + (8.8 * 3.85) + 0 = 157.487
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [getNextState] Durée Smartstart : 24 à 2025-11-19 21:00:00 programmation : 2025-11-19 20:36:00
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [getNextState] Prochain Smartstart : 2025-11-19 20:36:00
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [Reschedule] -> next : 2025-11-19 20:36:00, stop : , smartThermostat : Array
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [Reschedule] -> pas de cron a supprimer.
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [temporal] Arrêt Smartstart
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [calculTemporalData] Température intérieure : 18.3 - Température extérieure : 11.2 - Consigne : 20
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [calculTemporalData] Direction : 1
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [calculTemporalData] Power calcul : (1.7 * 72.71) + (8.8 * 3.85) + 0 = 157.487
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [temporal] Durée du cycle  : 15
[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [Reschedule] -> next : , stop : 1, smartThermostat : 

[2025-11-19 20:21:02][DEBUG] [6660] [Chambre Parentale][Thermostat Chambre Parentale] [heat] Action chauffage

[2025-11-19 20:21:02][DEBUG] [8225] [Chambre Parentale][Thermostat Chambre Parentale] [heat] Action chauffage

Agenda :

[2025-11-19 20:21:02] INFO  Evènement sur la commande [Chambre Parentale][Programmation chauffage Parentale][En cours] valeur : test

Voici mon analyse :

Thermostat::pull (cycle) ce lance (8225) :

[2025-11-19 20:21:02] DEBUG  [8225] [Chambre Parentale][Thermostat Chambre Parentale] [pull] -> lancement temporal : {"thermostat_id":146}

Cela a pour effet de supprimer le cron (si il existe) :

[2025-11-19 20:21:02] DEBUG  [8225] [Chambre Parentale][Thermostat Chambre Parentale] [Reschedule] -> Remove cron : 251372

dans le même temps, ce nouveau thread (6660) est provoqué par le plugin agenda (changement de mode), et comme on peut le voir, il n’a aucun cron a supp car il a déja été supp par le thread précédent :

[2025-11-19 20:21:02] DEBUG  [6660] [Chambre Parentale][Thermostat Chambre Parentale] [Reschedule] -> pas de cron a supprimer.

Ce qui a pour effet de lancer, dans la suite du code, 2 reschedule :

[2025-11-19 20:21:02] DEBUG  [8225] [Chambre Parentale][Thermostat Chambre Parentale] [temporal] Reprogrammation automatique : 2025-11-19 20:36:00

[2025-11-19 20:21:02] DEBUG  [6660] [Chambre Parentale][Thermostat Chambre Parentale] [temporal] Reprogrammation automatique : 2025-11-19 20:36:00

Une fois ce cas arrivé, il y a en permanance 2 cron pull identique, car le code du plugin ne permet pas de rechercher/supprimer plusieurs cron a chaque reschedule.

Il y aurait bien des solutions :

  • temporiser (sleep) les actions ( executeMode() )
  • modifier le reschedule pour qu’il recherche tous les crons (hors smartstart et stop), mais cela ressemble plutot a une rustine car le cron double sera a un moment tout de même créé pour ensuite être supprimé.

Je préfère avoir ton avis d’expert :wink: sur ce sujet.

Il y a aussi un cas identique mais moins gênant entre un cron de répétition des commandes et le cron pull, ou dans les log on peut apercevoir un cron pull qui chauffe, et un cron de répétition qui stop. J’ai pas encore les log pour ce cas, car je m’était pour le moment concentré sur le double cron. Je posterai les log dès que je capterai le cas.


2 « J'aime »

Bonjour,

Je me doutais que le double cron venait d’un double lancement en même temps mais la je sais pas trop comment faire hormis un sleep random peut décaler la suppression/création mais ca garantie pas que ca marchera dans tous les cas malheureusement…

Merci pour ta réponse.

Pour la partie cron de répétition, j’ai réussi a intercepter le problème, et c’est lorsque celui-ci intervient en même temps que qu’un cron stop/start.

Exemple :
J’étais précédemment en chauffe (status = Chauffage)
le cron stop intervient → stopThermostat → execute bien l’arrêt
dans un même temps le cron de répétition intervient, il check le status du thermostat, donc status = Chauffage car le cron stop n’a pas encore eu le temps de faire l’event (Arrêté) sur la commande status, donc execution de la chauffe jusuq’au prochain cron de répétition ou cron cycle.


J’ai ajouter un sleep(2) dans le temporal, seulement si c’est un cron de cycle, et j’ai mis un sleep(4) sur la répétitions des cmd, Je n’est plus de « problème » pour le moment, je vais laisser tourner comme ca pour le moment.

1 « J'aime »

Laisse bien tourner pour voir c’est la solution la plus simple mais pas la plus sur, la plus sur serait d’avoir des mutex mais en php c’est pas ca et c’est super lourd a mettre en place.

1 « J'aime »