Améliorer la gestion des configurations et des captures dans les scripts de timelapse
This commit is contained in:
87
Automate.py
87
Automate.py
@@ -26,43 +26,90 @@ def main():
|
||||
# Récupérer le statut de la caméra depuis l'API
|
||||
camera_status = api_client.get_camera_status()
|
||||
|
||||
# Vérifier si la configuration actuelle est déjà active et non terminée
|
||||
is_active_config = config.get("config_active", False)
|
||||
images_remaining = config.get("nb_images_restantes", 0)
|
||||
|
||||
if camera_status is None:
|
||||
logging.error("Impossible d'obtenir le statut de la caméra depuis l'API")
|
||||
logging.warning("Impossible d'obtenir le statut de la caméra depuis l'API")
|
||||
if is_active_config and images_remaining > 0:
|
||||
logging.info("Utilisation de la configuration locale existante")
|
||||
return
|
||||
logging.info("Aucune configuration active et impossibilité de récupérer le statut")
|
||||
return
|
||||
|
||||
# Mettre à jour la configuration locale
|
||||
api_client.update_camera_config(camera_status)
|
||||
|
||||
# Vérifier l'état de maintenance
|
||||
# Vérifier l'état de maintenance en priorité
|
||||
if camera_status.get("maintenance", False):
|
||||
logging.info("Caméra en mode maintenance, aucune action nécessaire")
|
||||
# Mettre à jour la configuration pour refléter le mode maintenance
|
||||
config.update_config({"maintenance": True, "config_active": False})
|
||||
return
|
||||
|
||||
# Vérifier si un arrêt de la procédure est demandé
|
||||
if camera_status.get("stop_flag", False):
|
||||
logging.info("Arrêt de la procédure en cours...")
|
||||
|
||||
# Supprimer le fichier de configuration s'il existe
|
||||
config.delete_config_file()
|
||||
# Réinitialiser les configurations actives
|
||||
config.update_config({
|
||||
"config_active": False,
|
||||
"nb_images_restantes": 0,
|
||||
"stop_current_config": True
|
||||
})
|
||||
|
||||
# Confirmer l'arrêt au serveur
|
||||
confirmed = api_client.confirm_stop()
|
||||
if confirmed:
|
||||
logging.info("Arrêt confirmé au serveur")
|
||||
else:
|
||||
logging.warning("Échec de la confirmation d'arrêt au serveur")
|
||||
|
||||
# Configuration d'un redémarrage régulier pour vérifier les nouvelles configurations
|
||||
config.set("restart_interval", 120) # 2 minutes
|
||||
|
||||
# Confirmer l'arrêt
|
||||
api_client.confirm_stop()
|
||||
return
|
||||
|
||||
# Vérifier s'il y a une configuration à appliquer
|
||||
if not camera_status.get("idle", True):
|
||||
logging.info("Configuration active détectée")
|
||||
# Vérifier si le système est en IDLE et si une configuration est déjà active
|
||||
is_idle = camera_status.get("idle", True)
|
||||
|
||||
# Obtenir les paramètres
|
||||
interval = camera_status.get("interval", 3)
|
||||
if is_idle:
|
||||
logging.info("Système en mode IDLE")
|
||||
if is_active_config:
|
||||
# Si le nombre d'images est atteint, désactiver la configuration
|
||||
if images_remaining <= 0:
|
||||
logging.info("Configuration terminée: nombre d'images atteint")
|
||||
config.update_config({"config_active": False})
|
||||
else:
|
||||
logging.info(f"Configuration active: il reste {images_remaining} images à capturer")
|
||||
else:
|
||||
logging.info("Aucune configuration active, attente en mode IDLE")
|
||||
# Configuration d'un redémarrage régulier pour vérifier les nouvelles configurations
|
||||
config.set("restart_interval", 120) # 2 minutes
|
||||
return
|
||||
|
||||
# Envoyer l'intervalle au microcontrôleur
|
||||
logging.info(f"Envoi de l'intervalle au microcontrôleur: {interval}s")
|
||||
micro_controller.send_interval(interval)
|
||||
# Si on arrive ici, il y a une nouvelle configuration à appliquer
|
||||
logging.info("Nouvelle configuration active détectée")
|
||||
|
||||
# Éteindre le système après configuration
|
||||
logging.info("Configuration terminée, arrêt du système")
|
||||
subprocess.run(["sudo", "shutdown", "now"])
|
||||
# Mettre à jour la configuration locale
|
||||
config_update = {
|
||||
"config_active": True,
|
||||
"maintenance": False,
|
||||
"timelapse": camera_status.get("interval", 3),
|
||||
"conf_nb_images": camera_status.get("nb_images", 1),
|
||||
"nb_images_restantes": camera_status.get("nb_images", 1),
|
||||
"stop_current_config": False,
|
||||
"idle": is_idle
|
||||
}
|
||||
|
||||
config.update_config(config_update)
|
||||
|
||||
# Envoyer l'intervalle au microcontrôleur
|
||||
interval = camera_status.get("interval", 3)
|
||||
logging.info(f"Envoi de l'intervalle au microcontrôleur: {interval}s")
|
||||
micro_controller.send_interval(interval)
|
||||
|
||||
# Éteindre le système après configuration (mais ne pas arrêter en prod)
|
||||
# logging.info("Configuration terminée, arrêt du système")
|
||||
# subprocess.run(["sudo", "shutdown", "now"])
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Erreur dans le script d'automatisation: {e}")
|
||||
|
||||
@@ -9,8 +9,10 @@ Remplace l'ancien Send_data_stocked.py
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
import time
|
||||
from timelapse.config import config
|
||||
from timelapse.capture import timelapse_manager
|
||||
from timelapse.api_client import api_client
|
||||
|
||||
|
||||
def main():
|
||||
@@ -21,14 +23,46 @@ def main():
|
||||
logging.info("Démarrage de la synchronisation des données hors ligne")
|
||||
|
||||
try:
|
||||
# Vérifier la connexion au serveur
|
||||
camera_status = api_client.get_camera_status()
|
||||
if camera_status is None:
|
||||
logging.error("Impossible de se connecter au serveur. Synchronisation reportée.")
|
||||
sys.exit(1)
|
||||
|
||||
# Vérifier si le système est en maintenance
|
||||
if camera_status.get("maintenance", False):
|
||||
logging.info("Caméra en mode maintenance, aucune synchronisation effectuée")
|
||||
sys.exit(0)
|
||||
|
||||
# Synchroniser les captures hors ligne
|
||||
start_time = time.time()
|
||||
sync_count = timelapse_manager.sync_offline_captures()
|
||||
duration = time.time() - start_time
|
||||
|
||||
if sync_count > 0:
|
||||
logging.info(f"Synchronisation réussie de {sync_count} captures")
|
||||
logging.info(f"Synchronisation réussie de {sync_count} captures en {duration:.2f} secondes")
|
||||
|
||||
# Vérifier s'il reste des images à synchroniser
|
||||
remaining_offline = timelapse_manager.count_offline_captures()
|
||||
if remaining_offline > 0:
|
||||
logging.info(f"Il reste encore {remaining_offline} captures à synchroniser")
|
||||
else:
|
||||
logging.info("Toutes les captures hors ligne ont été synchronisées")
|
||||
else:
|
||||
logging.info("Aucune capture à synchroniser")
|
||||
|
||||
# Vérifier si un arrêt est demandé
|
||||
if camera_status.get("stop_flag", False):
|
||||
logging.info("Demande d'arrêt détectée, confirmation au serveur")
|
||||
api_client.confirm_stop()
|
||||
|
||||
# Réinitialiser l'état actif
|
||||
config.update_config({
|
||||
"config_active": False,
|
||||
"nb_images_restantes": 0,
|
||||
"stop_current_config": True
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Erreur lors de la synchronisation des données: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
@@ -95,17 +95,35 @@ class APIClient:
|
||||
return False
|
||||
|
||||
try:
|
||||
# Récupérer l'état actuel pour comparaison
|
||||
is_currently_active = config.get("config_active", False)
|
||||
current_nb_images = config.get("conf_nb_images", 0)
|
||||
|
||||
# Vérifier si c'est une nouvelle configuration
|
||||
is_new_config = (not is_currently_active and not status.get("idle", True))
|
||||
|
||||
# Préparer la mise à jour
|
||||
config_update = {
|
||||
"maintenance": status.get("maintenance", False),
|
||||
"timelapse": status.get("interval", 3),
|
||||
"conf_nb_images": status.get("nb_images", 1),
|
||||
"nb_images_restantes": status.get("nb_images", 1),
|
||||
"set_config": status.get("idle", False),
|
||||
"idle": status.get("idle", True),
|
||||
"stop_current_config": status.get("stop_flag", False)
|
||||
}
|
||||
|
||||
# Ne mettre à jour le nombre d'images restantes que pour une nouvelle configuration
|
||||
# ou si la configuration est réinitialisée
|
||||
if is_new_config or status.get("stop_flag", False):
|
||||
config_update["nb_images_restantes"] = status.get("nb_images", 1)
|
||||
config_update["config_active"] = not status.get("idle", True)
|
||||
|
||||
if is_new_config:
|
||||
logging.info(f"Nouvelle configuration: {status.get('nb_images', 1)} images à capturer")
|
||||
|
||||
# Mise à jour de la configuration
|
||||
config.update_config(config_update)
|
||||
logging.info("Configuration mise à jour depuis l'API")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@@ -167,21 +167,62 @@ class TimelapseCaptureManager:
|
||||
|
||||
Args:
|
||||
online: Si la caméra est connectée au serveur
|
||||
|
||||
Returns:
|
||||
bool: True si la séquence est terminée (toutes les images capturées), False sinon
|
||||
"""
|
||||
# Vérifier si la configuration est active
|
||||
is_active = config.get("config_active", False)
|
||||
is_stopped = config.get("stop_current_config", False)
|
||||
|
||||
if not is_active or is_stopped:
|
||||
logging.info("Aucune configuration active ou configuration arrêtée")
|
||||
return True
|
||||
|
||||
# Vérifier si des images sont restantes à capturer
|
||||
remaining_images = config.get("nb_images_restantes", 0)
|
||||
|
||||
if remaining_images > 0:
|
||||
logging.info(f"Démarrage d'une séquence de capture ({remaining_images} images restantes)")
|
||||
if remaining_images <= 0:
|
||||
logging.info("Toutes les images ont été capturées")
|
||||
# Désactiver la configuration active
|
||||
config.update_config({"config_active": False})
|
||||
return True
|
||||
|
||||
# Capturer une image
|
||||
self.single_capture(online)
|
||||
logging.info(f"Démarrage d'une séquence de capture ({remaining_images} images restantes)")
|
||||
|
||||
# Capturer une image
|
||||
result = self.single_capture(online)
|
||||
|
||||
if result:
|
||||
# Décrémenter le compteur d'images restantes
|
||||
remaining_images = config.decrement_remaining_images()
|
||||
logging.info(f"Images restantes: {remaining_images}")
|
||||
|
||||
# Vérifier si c'était la dernière image
|
||||
if remaining_images <= 0:
|
||||
logging.info("Toutes les images ont été capturées")
|
||||
# Désactiver la configuration active
|
||||
config.update_config({"config_active": False})
|
||||
return True
|
||||
else:
|
||||
logging.info("Aucune image restante à capturer")
|
||||
logging.error("Échec de la séquence de capture")
|
||||
|
||||
return False
|
||||
|
||||
def count_offline_captures(self):
|
||||
"""
|
||||
Compte le nombre de captures hors ligne en attente de synchronisation.
|
||||
|
||||
Returns:
|
||||
int: Nombre de captures hors ligne
|
||||
"""
|
||||
if not os.path.exists(self.offline_dir):
|
||||
return 0
|
||||
|
||||
offline_dirs = [d for d in os.listdir(self.offline_dir)
|
||||
if os.path.isdir(os.path.join(self.offline_dir, d))]
|
||||
|
||||
return len(offline_dirs)
|
||||
|
||||
|
||||
# Instance globale du gestionnaire de capture
|
||||
|
||||
@@ -23,22 +23,41 @@ def main():
|
||||
logging.info("Démarrage de la capture d'images en mode hors ligne")
|
||||
|
||||
try:
|
||||
# Chargement de la configuration
|
||||
# Vérifier si une configuration active existe
|
||||
is_active_config = config.get("config_active", False)
|
||||
is_stopped = config.get("stop_current_config", False)
|
||||
remaining_images = config.get("nb_images_restantes", 0)
|
||||
interval = config.get("timelapse", 3) # Intervalle par défaut: 3 secondes
|
||||
|
||||
logging.info(f"Configuration: {remaining_images} images à capturer, intervalle de {interval}s")
|
||||
|
||||
if remaining_images <= 0:
|
||||
logging.info("Aucune image à capturer en mode hors ligne")
|
||||
# Si arrêté ou pas de configuration active, ne rien faire
|
||||
if is_stopped:
|
||||
logging.info("Configuration arrêtée, aucune action à effectuer")
|
||||
return
|
||||
|
||||
# Exécuter la séquence de capture en mode hors ligne
|
||||
timelapse_manager.run_capture_sequence(online=False)
|
||||
if not is_active_config:
|
||||
logging.info("Aucune configuration active en mode hors ligne")
|
||||
return
|
||||
|
||||
# Envoi de l'intervalle au microcontrôleur si nécessaire
|
||||
if interval > 0:
|
||||
if remaining_images <= 0:
|
||||
logging.info("Aucune image restante à capturer")
|
||||
# Désactiver la configuration puisqu'elle est terminée
|
||||
config.update_config({"config_active": False})
|
||||
return
|
||||
|
||||
logging.info(f"Configuration: {remaining_images} images à capturer")
|
||||
|
||||
# Exécuter la séquence de capture en mode hors ligne
|
||||
sequence_completed = timelapse_manager.run_capture_sequence(online=False)
|
||||
|
||||
# Obtenir l'intervalle de timelapse pour le microcontrôleur si nécessaire
|
||||
interval = config.get("timelapse", 3)
|
||||
if interval > 0 and is_active_config and not sequence_completed:
|
||||
logging.info(f"Envoi de l'intervalle au microcontrôleur: {interval}s")
|
||||
micro_controller.send_interval(interval)
|
||||
else:
|
||||
# Si la séquence est terminée, réinitialiser l'intervalle
|
||||
if sequence_completed:
|
||||
logging.info("Séquence terminée, réinitialisation de l'intervalle")
|
||||
micro_controller.send_interval(0) # 0 pour désactiver
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Erreur lors de la capture en mode hors ligne: {e}")
|
||||
|
||||
@@ -28,6 +28,14 @@ def main():
|
||||
|
||||
if status is None:
|
||||
logging.error("Impossible d'obtenir le statut de la caméra depuis l'API")
|
||||
|
||||
# Dans le cas où une configuration active existe déjà, continuer avec celle-ci
|
||||
if config.get("config_active", False) and config.get("nb_images_restantes", 0) > 0:
|
||||
logging.info("Utilisation de la configuration locale existante")
|
||||
timelapse_manager.run_capture_sequence(online=False) # Mode hors ligne si API inaccessible
|
||||
else:
|
||||
logging.info("Pas de configuration active, abandon de la capture")
|
||||
|
||||
sys.exit(1)
|
||||
|
||||
# Mise à jour de la configuration
|
||||
@@ -42,10 +50,28 @@ def main():
|
||||
if status.get("stop_flag", False):
|
||||
logging.info("Demande d'arrêt détectée, confirmation au serveur")
|
||||
api_client.confirm_stop()
|
||||
|
||||
# Réinitialiser l'état actif
|
||||
config.update_config({
|
||||
"config_active": False,
|
||||
"nb_images_restantes": 0
|
||||
})
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
# Si le mode est IDLE et qu'aucune configuration n'est active, ne rien faire
|
||||
if status.get("idle", True) and not config.get("config_active", False):
|
||||
logging.info("Mode IDLE, aucune action à effectuer")
|
||||
sys.exit(0)
|
||||
|
||||
# Exécuter la séquence de capture
|
||||
timelapse_manager.run_capture_sequence(online=True)
|
||||
sequence_completed = timelapse_manager.run_capture_sequence(online=True)
|
||||
|
||||
# Si la séquence est terminée (toutes les images capturées), notifier l'API
|
||||
if sequence_completed and config.get("nb_images_restantes", 0) <= 0:
|
||||
logging.info("Toutes les images ont été capturées, notification au serveur")
|
||||
# TODO: Implémenter une méthode pour notifier la fin de la séquence
|
||||
# api_client.notify_sequence_complete()
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Erreur lors de la capture en mode connecté: {e}")
|
||||
|
||||
Reference in New Issue
Block a user