Aller au contenu

Ce tchat, hébergé sur une plateforme indépendante d'Infoclimat, est géré et modéré par une équipe autonome, sans lien avec l'Association.
Un compte séparé du site et du forum d'Infoclimat est nécessaire pour s'y connecter.

Weewx


BMGB-59

Messages recommandés

  • Réponses 1,1k
  • Créé
  • Dernière réponse

Les plus actifs

Les plus actifs

Messages populaires

Bonjour à toutes et tous. Voilà je pense qu’il est temps d’ouvrir un sujet autour de weewx. Comme nous devons rester confiné ; je vous invite à respecter les recommandations voici du travail

Et voici les 15 fichiers pour les traductions. Bon téléchargement traduction fichier about_inc.pdf traduction fichier celestial_html_tmpl.pdf traduction fichier celestial_inc.pdf traduction

Avec le Raspberry, il y a une solution alternative à l'achat d'un datalogger Davis : le "Météo-Pi"  - https://wifilogger.net/meteopi.html   Il est composé de 2 modules : un qui s'enfiche dan

Images postées

Je vais changer de stratégie. Je vais tenter d'utiliser le driver fileparse.py. Il suffirait d'écrire un script pour extraire la hauteur de marée du moment dans un fichier recueillant mes horaires de marée, et la coller dans un autre fichier au format de fileparse.py qui lui s'occuperait de l'envoyer dans la boucle de Weewx.

 

Mon facteur limitant est que je n'ai aucune compétence en matière de conception de script.

 

Quel site me recommanderiez-vous pour apprendre à faire ça, sachant que je débute totalement ?

 

ollpat, ton lien ne fonctionne pas

Lien à poster
Partager sur d’autres sites

@TopeX:  à ma connaissance, on ne peut utiliser qu'un seul driver à la fois dans Weewx, à moins d'avoir 2 instances séparées de weewx, ayant chacune un driver différent, ce qui complique les choses.

 

Je peux t'aider à écrire un service weewx qui ajoute la hauteur de marée dans les données du loop packet.  As-tu une formule qui calcule la hauteur de marée pour une date et heure donnée?

 

Sinon, on peut récupérer la bonne valeur dans la base de donnée (4 ans en arrière).

Modifié par jackT
  • J'aime 1
Lien à poster
Partager sur d’autres sites

Ah, bah volontiers ! 😃

 

Le plus simple serait de récupérer les données. Soit dans la bd quatre ans en arrière, ou encore plus simple (pour moi), dans un fichier csv. J'imagine un csv à 2 colonnes : horodatage et hauteur.

 

créer un service revient à créer un script python ou je me trompe ?

Lien à poster
Partager sur d’autres sites

Pardon ! Pardon ! Pardon ! A la réflexion, tu as raison, il serait préférable de récupérer les données dans la bd 4 ans en arrière. En espérant que tu n'aies pas déjà commencé à plancher dessus... ☹️

Lien à poster
Partager sur d’autres sites

Oui, c'est un script python qui s'intègre à la configuration de weewx.

 

Côté script, le plus simple est de récupérer dans la base de donnée. Un fichier csv contenant les données d'une année avec une donnée toutes les 5 minutes va contenir plus de 105000 lignes, et il faudrait pour chaque paquet de boucle chercher dans ces 105000 lignes laquelle a le bon horodatage.

 

Quelles sont les unités des données de ta base weewx ?  Metric ou US ?

Lien à poster
Partager sur d’autres sites

il y a 34 minutes, TopeX a dit :

 

Je suis en  metric mais la base de données est en us.

Et tes données "hauteur" que tu a importé dans la base? elle sont en mètre(metric)  ou en pieds (us) ?

Lien à poster
Partager sur d’autres sites

Voici donc un script à tester, en assumant que les données décalées dans le temps des hauteur de marées sont bien enregistrées dans la base de donnée en pieds et non en mètres. SI ce n'est pas le cas, on pourra modifier le groupe d'unité utilisé pour ce paramètre. Le script importe et utilise des objets et méthodes de weewx, ce qui simplifie les choses.  Il y a plus de commentaires que de code...  c'est pour mieux comprendre!.

import datetime
import time
import weewx
import weewx.units
import weewx.wxformulas
from weewx.engine import StdService
from dateutil.relativedelta import relativedelta

VERSION = "1.0"
# fonctions pour l'envoi de messages dans le log de weewx
try:
    # Test for new-style weewx logging by trying to import weeutil.logger
    import weeutil.logger
    import logging
    log = logging.getLogger(__name__)
    def logdbg(msg):
        log.debug(msg)
    def loginf(msg):
        log.info(msg)

except ImportError:
    # Old-style weewx logging
    import syslog
    def logmsg(level, msg):
        syslog.syslog(level, 'maree: %s' % msg)
    def logdbg(msg):
        logmsg(syslog.LOG_DEBUG, msg)
    def loginf(msg):
        logmsg(syslog.LOG_INFO, msg)
# fin fonctions messages log

# Définition du groupe d'unité utilisé pour le champ "hauteur" :
weewx.units.obs_group_dict["hauteur"] = "group_altitude"


# création d'une sous-classe "Maree" , héritée de la classe "StdService" :
class Maree(StdService):
    decalage = 4  # décalage, en année des données de marée

    def __init__(self, engine, config_dict):
        # Initialisation de la superclasse:
        super(Maree, self).__init__(engine, config_dict)
        # ligne dans le fichier log pour indiquer la version du service utilisée:
        loginf("service version is %s" % VERSION)
        # obtient un object  db manager pour l'accès à la base de donnée :
        manager_dict = weewx.manager.get_manager_dict_from_config(config_dict, 'wx_binding')
        self.db_manager = weewx.manager.open_manager(manager_dict)
        # Interception événement LOOP: lorsqu'un nouveau paquet loop est emis par weewx, celui ci est transmis
        # à la fonction  "new_loop-packet" , définie en fin de script et qui ajoute le nouveau champ :
        self.bind(weewx.NEW_LOOP_PACKET, self.new_loop_packet)

    # Récupère la valeur de marée de la même date et heure, mais avec le décalage indiqué par la variable "decalage" :
    def get_maree(self, ts):
        # ts = timestamp du loop packet
        # datetime 4 ans avant le timestamp du loop packet :
        ago_dt = datetime.datetime.fromtimestamp(ts) - relativedelta(years=Maree.decalage)
        # convertit le datetime calculé en timestamp :
        ago_ts = time.mktime(ago_dt.timetuple())
        # récupère la valeur d'archive avec une tolérance de 10 minutes (600 secondes),
        # car le timestamp du paquet ne correspond jamais exactement au timestamp de l'archive de la base de donnée :
        _record = self.db_manager.getRecord(ago_ts, 600)
        # récupère la valeur si il y a un champ "hauteur" dans l'enregistrement d'archive :
        if _record and 'hauteur' in _record:
            _result = _record['hauteur']
            # ligne log debug affichant le timestamp et la valeur lue :
            logdbg("timestamp = %f  , hauteur = %f" % (ago_ts, _result))
        else :
            _result = None
        return _result

    def new_loop_packet(self, event):
        # ajoute le champ "hauteur" et sa valeur dans le loop packet:
        event.packet['hauteur'] = self.get_maree(event.packet['dateTime'])

 

Pour l'installation :

  • Sauver ce script dans un fichier "maree.py"
  • Modifier éventuellement la ligne 38 "decalage = 4" qui indique  en années le décalage par rapport à l'horodatage actuel pour trouver la bonne valeur de marée.
  • Copier ce fichier dans /usr/share/weewx/user
  • Modifier weewx.conf pour enregistrer le nouveau service : dans la section [Engine] ajouter à la fin de la ligne "process_services" : ",user.maree.Maree"

  -  Arrêter et redémarrer weewx.

 

Une nouvelle observation "hauteur_meter" est maintenant publiée via MQTT à chaque boucle.

Côté skin Belchertown, il faut ajouter le paramètre "hauteur " à la liste des observation dans le fichier conf (station_observations =......)

Il faudra attendre le prochain archivage suivant le redémarrage de Weewx et le transfert des fichiers vers ton hébergement pour que l'affichage de la marée soit correcte.

 

Le champ "hauteur" utilise le même groupe d'unité que le champ  "base de nuages". Sur ta page d'accueil, il semble que cette unité est configurée sans décimales, tu auras donc la hauteur de marée affichée aussi sans décimale.

 

Il y a moyen de contourner cela en ajoutant une ligne dans les script "belchertown.py" du skin belchetown pour régler spécifiquement le nombre de décimales pour la hauteur de marée.

 

  • Solidaire 1
Lien à poster
Partager sur d’autres sites

Alors là chapeau ! J'ai tout installé sans rien regarder plus que ça. Là, tout de suite ça plante. J'ai cru voir passer dans le log qu'il obtient un nonetype plutôt qu'un nombre et que ça ne lui plait pas ou un truc dans le genre. Je vais regarder ça de plus près et essayer de comprendre comment tout ça se goupille avant d'alerter la cavalerie.

 

Edit : j'ai modifié vite fait la valeur de décalage de 4 pour 1461 et 'years' pour 'days' quelques lignes plus loin. Même résultat. Je verrai ça ce soir, il faut vraiment que je retourne au boulot ! 👨‍🌾 🐐

 

Un grand merci dans tous les cas !

Modifié par TopeX
  • Haha 1
Lien à poster
Partager sur d’autres sites

Il y a 5 heures, TopeX a dit :

Je vais regarder ça de plus près et essayer de comprendre comment tout ça se goupille

Vérifie bien que les indentations sont respectées dans ton script. C'est très important en python.

Ce même script fonctionne chez moi en test (voir http://meteo-sciez.fr/weewx/belchertown/ ). N'ayant pas de données décalées de hauteur de marée, j'ai juste récupéré à la place du champ "hauteur" le champ "OutTemp"  d'il y a 4 ans.

       if _record and 'outTemp' in _record:
            _result = _record['outTemp']
Lien à poster
Partager sur d’autres sites

J'ai refait l'installation depuis le départ. Même erreur. Mais je te mets le log complet du démarrage de weewx, parce que je m'aperçois qu'il va quand même chercher la bonne valeur à la bonne date. On le voit à 23:12:28. Donc ça fonctionne quand même !

 

Terminal SSH(3).PDF

 

Edit du petit matin : je me dois de contextualiser pour trouver ce qui cloche chez moi. Déjà pour info, mon install est en setup.py. J'imagine que ça ne change rien mais je ne tiens pas tout. D'autre part, ma procédure d'import ne fonctionne pas correctement. Je me suis retrouvé plusieurs fois avec une erreur "unable to add record XXXX : unique constraint failed" qui indique qu'une ligne est déjà peuplée. Pour contourner le problème, j'ai ajouter 2 secondes à tous mes horodatages.

Au final, suite à plusieurs essais, je me retrouve avec des lignes vierges ("null"). J'ai une série de trois lignes récurrentes : t+0s ("null"), t+1s ("null") et enfin t+2s ("bonne valeur")

 

Mais il ne s'agit pas de "nonetype"

Modifié par TopeX
Lien à poster
Partager sur d’autres sites

Concernant l'erreur qui bloque tout, c'est effectivement dû au fait que la valeur du champ "hauteur" qui est récupérée de la base de donnée est nulle (valeur "null"). Dans ce cas, la variable "_result" à la valeur None. (nonetype). 

 

Je rajoute donc un test  "if _result is not None" pour éviter le blocage , et aussi pour éviter d'envoyer dans le loop packet la valeur si elle est nulle:

    # Récupère la valeur de marée de la même date et heure, mais avec le décalage indiqué par la variable "decalage" :
    def get_maree(self, ts):
        # ts = timestamp du loop packet
        # datetime 4 ans avant le timestamp du loop packet :
        ago_dt = datetime.datetime.fromtimestamp(ts) - relativedelta(days=Maree.decalage)
        # convertit le datetime calculé en timestamp :
        ago_ts = time.mktime(ago_dt.timetuple())
        # récupère la valeur d'archive avec une tolérance de 10 minutes (600 secondes),
        # car le timestamp du paquet ne correspond jamais exactement au timestamp de l'archive de la base de donnée :
        _record = self.db_manager.getRecord(ago_ts, 600)
        # récupère la valeur si il y a un champ "hauteur" dans l'enregistrement d'archive :
        if _record and 'hauteur' in _record:
            _result = _record['hauteur']
            # ligne log debug affichant le timestamp et la valeur lue :
            if _result is not None :
                logdbg("timestamp = %f  , hauteur = %f" % (ago_ts, _result))
            else:
                logdbg("timestamp = %f  , hauteur = null" % (ago_ts))
        else :
            _result = None
        return _result

    def new_loop_packet(self, event):
        # ajoute le champ "hauteur" et sa valeur dans le loop packet si cette valeur n'est pas nulle:
        _hauteur = self.get_maree(event.packet['dateTime'])
        if _hauteur is not None: event.packet['hauteur'] = _hauteur

 

Avec cette modification, il ne devrait plus avoir d'erreur qui bloque, et seules les valeurs non nulles de marée seront envoyées.

 

Le mieux serait d'effacer dans la base de donnée les enregistrements qui ont une valeur "null"  de hauteur en envoyant une requête du style

DELETE FROM archive WHERE hauteur IS NULL and dateTime  < XXXXXXXXXX

 où XXXXXXXXX est un timestamp avant lequel les données "anciennes" ne contiennent que la hauteur et non tes autres données météo.

 

Une autre manière de faire, peut être plus facile à gérer à long-terme , pourrait être de mettre les données prédictives de hauteur de marée (sur 4 ans) dans une base de donnée séparée et de définir un "binding" dans la configuration de weewx pour pour que weewx puisse accéder à cette base.

Avec une base séparée, et en cas de problèmes, c'est plus facile de vider complètement la base de donnée et de réimporter les bonnes valeurs

Lien à poster
Partager sur d’autres sites

Il y a 1 heure, jackT a dit :

Le mieux serait d'effacer dans la base de donnée les enregistrements qui ont une valeur "null"  de hauteur en envoyant une requête du style

DELETE FROM archive WHERE hauteur IS NULL and dateTime  < XXXXXXXXXX

 où XXXXXXXXX est un timestamp avant lequel les données "anciennes" ne contiennent que la hauteur et non tes autres données météo.

 

 

Je ne comprends pas bien. Les lignes contenant une donnée 'hauteur' ne contiennent rien d'autres et inversement, les lignes contenant une hauteur de marée 'null' contiennent toutes les autres données météo. ça va effacer quoi exactement  ?

 

Sinon, la base de donnée alternative existe. Je ne sais plus pourquoi je l'ai délaissée. je vais tenter de faire ça à l'avenir. Y a-t-il un moyen d'utiliser wee_import avec une autre bd que weex.sdb à tout hasard ?

 

Et bonne nouvelle, le temps de rédiger ce billet, tout s'est mis en place et ça fonctionne nickel ! 😃💪👃

 

Modifié par TopeX
Lien à poster
Partager sur d’autres sites

il y a 49 minutes, TopeX a dit :

Y a-t-il un moyen d'utiliser wee_import avec une autre bd que weex.sdb à tout hasard ?

Oui.  

Il suffit de faire une copie de ton fichier weewx.conf en par exemple weewx_import.conf, puis modifier dans ce nouveau fichier le paramètre "data_binding" (section  [StdArchive]) pour qu'il pointe vers le data binding de ta base séparée. 

 

Pour l'appel de wee_import, il faudra rajouter le paramètre --config=/xxx/yyyy/weewx_import.conf   et cela devrait jouer !

 

 

Lien à poster
Partager sur d’autres sites

il y a 59 minutes, TopeX a dit :

Les lignes contenant une donnée 'hauteur' ne contiennent rien d'autres et inversement, les lignes contenant une hauteur de marée 'null' contiennent toutes les autres données météo. ça va effacer quoi exactement  ?

Dans ce cas, difficile de supprimer les valeurs nulles de tes enregistrements passés.  

Par contre, à partir d'aujourd'hui, tu pourras remarquer que tous tes nouveaux enregistrements de ta base de donnée auront une valeur non nulle de hauteur : weewx utilise les données LOOP pour les insérer dans la table archive.

Lien à poster
Partager sur d’autres sites

il y a 33 minutes, jackT a dit :

Oui.  

Il suffit de faire une copie de ton fichier weewx.conf en par exemple weewx_import.conf, puis modifier dans ce nouveau fichier le paramètre "data_binding" (section  [StdArchive]) pour qu'il pointe vers le data binding de ta base séparée. 

 

Pour l'appel de wee_import, il faudra rajouter le paramètre --config=/xxx/yyyy/weewx_import.conf   et cela devrait jouer !

 

 

Ah oui, astucieux...  j'aurais pu réfléchir un peu avant de poser la question...

 

Pour l'histoire du format à 2 décimales, j'y travaille : je n'ai pas encore trouvé la solution sur le github de Belchertown, mais j'y ai quand même trouvé cette astuce :

 

    [[MQTT]] 
        [[[inputs]]]
            [[[[hauteur]]]]
                format = %.2f

 

J'ai essayé aussi avec [[[[hauteur_meter]]]], mais sans plus de succès. J'aimerais bien comprendre pourquoi ?

Lien à poster
Partager sur d’autres sites

Bonjour, 

 

je suis en train de passer à Weewx mais je suis bloqué au stade du paramétrage du fichier conf , je veux utilisé le Raspberry en wifi pour la connexion a la box étant donné que je dispose d'un datalogger ip.

 

donc sur le type de port du fichier .conf, je dois laissé port Ethernet ? 

 

je suppose que oui car ceci ne concerne que la liaison datalogger ip => raspberry ?

 

 

merci !!

 

Capture d’écran 2023-02-22 134321.png

Lien à poster
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
  • En ligne récemment   1 membre est en ligne

×
×
  • Créer...