IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

une" boucle" à heure fixe (h, h+15, h+30, h+45 etc ? [Python 2.X]


Sujet :

Python

  1. #1
    Membre du Club
    Homme Profil pro
    commercant
    Inscrit en
    Octobre 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : commercant
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2015
    Messages : 8
    Par défaut une" boucle" à heure fixe (h, h+15, h+30, h+45 etc ?
    Bonjour a tous

    Voici mon problème, j’ai fait un programme de balise météo radioamateur, donc je récupère les infos des sondes (température, pression, vitesse et direction du vent) puis je les transmet sur une fréquence radio par synthèse vocal toutes les 15 minutes (en fait, un time.sleep 900 secondes) le problème est que la durée de transmission varie de quelque secondes suivant les données a émettre . et donc après quelques heures le rythme du quart d’heure est perdu.
    Comment faire pour que mes émissions débutent régulièrement à H, H+15, H+30, H+45, …etc. ?
    d' avance merci
    Philippe

  2. #2
    Membre éclairé

    Inscrit en
    Novembre 2008
    Messages
    423
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 423
    Par défaut
    Bonjour,
    En utilisant le module time
    https://docs.python.org/2/library/time.html
    En gros :
    tant que 1
    lancer l'action
    stocker time_initial = time.time()
    tant que time.time() - time_initial > 900s, on attend

  3. #3
    Membre du Club
    Homme Profil pro
    commercant
    Inscrit en
    Octobre 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : commercant
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2015
    Messages : 8
    Par défaut
    Bonjour Fatbob

    Merci pour la réponse rapide. Ca me semble bien pour respecter les 15 minutes, mais en fait, serait il possible de lire l’heure et que le lancement de l’action intervienne à (exemple) 08h00,
    Puis 08h15, puis 08h30 etc ? et si je démarre mon programme à 08h07, la première action à 08h15 ?
    Bonne journée
    Phil

  4. #4
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 304
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 304
    Par défaut
    Le problème de ces solutions c'est qu'elles occupent inutilement la machine.

    Le time.sleep() est bloquant et le "tant que time.time() - time_initial > 900s, on attend" fait tourner le bouzin à pleine charge.

    Python possède un module Timer fait pour cela.

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    from threading import Timer
     
    def get_infos():
        """Retourne les donnees des capteurs"""
     
    def update():
        """Releve les donnees et les transmet"""
        set_timer()
        data = get_infos()
        send_data(data)
     
    def set_timer():
        t = Timer(900, update).start()
     
    def main():
        set_timer()
    Tu remarqueras que le timer est relancé avant le traitement pour que le temps nécessaire à celui-ci n'aie pas d'incidence sur le temps total.


    Edit: Nous nous sommes croisés. Pour démarrer à heure fixe, tu peux lire l'heure avec le module time et calculer les minutes manquantes pour le prochain quart d'heure et utiliser un autre Timer pour le premier démarrage.

    minutes_manquantes = 15 - minutes_actuelles % 15

  5. #5
    Membre du Club
    Homme Profil pro
    commercant
    Inscrit en
    Octobre 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : commercant
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2015
    Messages : 8
    Par défaut
    merci Vincent
    pour la réponse, la ça devient un peut ardu pour mon faible niveau en python
    j' étudie ça et je reviens quand j'ai compris...(ça peut être long )

    phil

  6. #6
    Membre du Club
    Homme Profil pro
    commercant
    Inscrit en
    Octobre 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : commercant
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2015
    Messages : 8
    Par défaut
    bonjour à tous

    j'ai résolu mon problème! en tâtonnant, je suis arrivé à cela.
    ce n'est peut être pas très "orthodoxe" mais ça fonctionne.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # script à_heure.py
     
    import datetime   # le but est de relancer une procedure tous les quarts d'heure
    import time
     
    i = 0
    while 1:
     
        h = datetime.datetime.now().strftime('%M,%S') # control des minutes et secondes
     
        if h == "15,00" or h == "30,00" or h == "45,00" or h == "00,00": # à h+15minutes et 00 secondes...etc
     
            print("Ca fait un quart d' heure!!")
     
            time.sleep(1) # une petite seconde d'attente pour eviter les repetitions et on boucle.

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 679
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 679
    Par défaut
    Salut,

    Citation Envoyé par LHT50 Voir le message
    ce n'est peut être pas très "orthodoxe" mais ça fonctionne.
    Votre code suppose que datetime.datetime.now() sera exécuté tous les quarts d'heure "pile poil" pour que le test "h == "15,00" or h == "30,00" or h == "45,00" or h == "00,00"" retourne vrai quand vous le voulez.
    Dans la pratique, ce sera rarement "pile poil" et donc, vous allez sauter des quarts d'heure.

    Ceci dit çà marche parce que vous "bouclez" à exécuter datetime.datetime.now(), autrement dit, vous consommez un CPU juste pour regarder le temps qui passe.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 304
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 304
    Par défaut
    ... et en plus tu bloques toujours ton appli avec time.sleep()

    Calcule le vrai temps restant, ce n'est pas si compliqué:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    >>> import time
    >>> min = time.localtime()[4]
    >>> min
    13
    >>> dif = 15 - min % 15
    >>> dif
    2

  9. #9
    Membre du Club
    Homme Profil pro
    commercant
    Inscrit en
    Octobre 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : commercant
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2015
    Messages : 8
    Par défaut
    Merci pour vos réponses et vos commentaires. Pour wiztricks,j’ai lancé une petite boucle pour contrôler la vérification de l’heure, elle ce fait plusieurs fois par seconde, donc je ne voie pas comment louper un quart d’heure ? Par contre le cpu luis est en pleine charge .
    En fait, mon montage est une balise météo qui émet sur une fréquences vhf radioamateur, donc tous les quart d’heure, il récupère les valeur des sondes (température, pression, vitesse et direction du vent) puis il enregistre les infos dans un fichier .txt et en fin des phrase sont constituées puis émises en synthèse vocale avec espeak. Cette émission dur entre 28 et 38 secondes (et ça toutes les 15 minutes). J’ai rajouté en fin du programme un time.sleep de 840 secondes soit 14 minutes ce qui fait que le cpu est en pleine charge que une minutes toutes les 15. Pensez vous que c’est dommageable pour le raspberry vu qu’il tournera 24h/24h ?

    bonne journée

    Phil

  10. #10
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2013
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 25
    Par défaut
    Pourquoi ne pas faire une tâche planifiée tout simplement qui lancera le code python.
    - > au lieu de vouloir le programmer en python vous laisserez le système gérer ça comme un grand.
    https://www.raspberrypi.org/document.../usage/cron.md

  11. #11
    Membre du Club
    Homme Profil pro
    commercant
    Inscrit en
    Octobre 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : commercant
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2015
    Messages : 8
    Par défaut
    oui Laurent l'idée est bonne, en plus je pourrais suspendre l'action par exemple de 22h00 à 05h00. Mon problème est que une des améliorations pour mon programme est que en plus de la diffusion tous les quarts d'heure, on puisse sur "demande" avoir le bulletin météo (demande par code radio, ctss,1750hz, typiquement radioamateur). et pour ça le programme doit tourner!
    phil

  12. #12
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 679
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 679
    Par défaut
    Salut,

    Citation Envoyé par LHT50 Voir le message
    J’ai rajouté en fin du programme un time.sleep de 840 secondes soit 14 minutes ce qui fait que le cpu est en pleine charge que une minutes toutes les 15. Pensez vous que c’est dommageable pour le raspberry vu qu’il tournera 24h/24h ?
    Le matériel y survivra. Par contre, toutes les activités qui auront besoin de CPU lorsque votre truc tourne comme un petit fou juste pour vérifier que ce n'est pas encore l'heure en souffriront.... Et un de ces quatre vous aurez des soucis pour comprendre ce qu'il se passe sur votre machine.
    C'est pas si compliqué d'essayer de faire mieux:
    une fonction qui retourne le quart d'heure suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import datetime as dt
    import time
     
    def get_next_quarter(dtime=None):
        dtime = dtime or dt.datetime.now()
        dtime = dtime.replace(second=0, microsecond=0)
     
        mns = dtime.minute
        next_ = ((mns+15) // 15) * 15
        return dtime + dt.timedelta(minutes=next_ - mns)
    Une simulation de traitement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def traitement():
        print('**traitement**')
        time.sleep(3)
    Et une mise en musique "tous les quarts d'heure":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    while True
        next_quarter = get_next_quarter(dt.datetime.now())
     
        while time.time() < next_quarter.timestamp():
            time.sleep(1)
     
        assert abs((next_quarter - dt.datetime.now()).total_seconds()) < 10
        print (next_quarter)
        traitement()
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  13. #13
    Membre chevronné
    Profil pro
    Ingénieur sécurité
    Inscrit en
    Février 2007
    Messages
    574
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 574
    Par défaut
    Salut,

    threading.Timer() peut etre utile ici. Similaire a wiztricks:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    import datetime as dt                                                                                                      
    import threading                                                                                                           
     
    def get_secs_to_quarter(dtime=None):                                                                                       
        dtime = dtime or dt.datetime.now()                                                                                     
        secs = dtime.minute * 60 + dtime.second                                                                                
        next_ = ((secs + 900) // 900) * 900                                                                                         
        return next_ - secs                                                                          
     
    def action(str_):                                                                                                               
        print(str_)                                                                                                            
     
    while True:                                                                                                         
        s = get_secs_to_quarter()                                                                                              
        t = threading.Timer(s, action, ("working...",))                                                                     
        t.start()                                                                                                              
        t.join()

  14. #14
    Membre du Club
    Homme Profil pro
    commercant
    Inscrit en
    Octobre 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : commercant
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2015
    Messages : 8
    Par défaut
    bonjour et merci pour vos codes, je les copies pour les tester, car avant de les employer je veux les comprendre (je suis toujours un novice en python)
    pour W, "si c'est compliqué de faire plus simple quand on ne maîtrise pas le langage" mais je bosse!!!

    cordialement
    Philippe

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 22/04/2015, 21h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo