Node-RED. Ajouter un widget météo au Dashboard connecté à OpenWeatherMap avec du code HTML / Angular

Partager sur facebook
Partager sur twitter
Partager sur linkedin
Partager sur pinterest
Partager sur email
Partager sur telegram

Le node template-html du plugin Node-RED-Dashboard permet de créer des Widgets personnalisés avec du code HTML. Le node template permet d’ajouter du code HTML standard ou d’utiliser le framework Angularjs pour créer des widgets personnalisés.

 

Pour ce projet, nous allons créer un Widget qui affiche la météo du jour ainsi que les prévisions à 14 jours à partir des données récupérées via l’API du service OpenWeatherMap.org.

Si vous débutez avec Node-RED, je vous conseille de commencer par lire ces quelques articles d’initiation

A LIRE AUSSI :
Débuter avec Node-Red sur Raspberry Pi. Installation, autostart, prise en main
A LIRE AUSSI :
Installer Node-RED sur macOS ou Windows 10, démarrage automatique avec PM2
A LIRE AUSSI :
Node-RED : installer, désinstaller facilement des modules avec le gestionnaire de palette

Installer le Node OpenWeatherMap pour Node-RED

Ouvrez le gestionnaire de palette et cliquer sur l’onglet install.

Gestionnaire de plugin Node-RED

Faire une recherche sur le mot clé weathermap puis installer le plugin node-red-node-openweathermap.

Installer le plugin nodered pour openweathermap

Le plugin OpenWeatherMap est livré avec 2 Nodes. Ils sont identiques à l’exception du premier Node qui accepte un déclencheur externe. C’est celui-ci que je vous conseille d’utiliser de manière à pouvoir actualiser régulièrement les prévisions météo. On pourra actualiser manuellement à l’aide d’un bouton ou à intervalle régulier à l’aide d’un node inject.

Plugin openweathermap pour Node-RED

Installer le Node Dashboard pour Node-RED

Depuis le gestionnaire de plugin, allez sur l’onglet install puis faire une recherche sur le mot clé dashboard. Il en existe plusieurs, installer le plugin node-red-dahsboard.

Installer le plugin node-red-dashboard

Nous n’allons pas re-détailler les Nodes proposés par le plugin dans cet article. Pour en savoir plus, voici deux articles qui traitent en détail du sujet

A LIRE AUSSI :
Node-RED. Créer un dashboard pour objet connecté. Bouton, liste, interrupteur, slider, formulaire (Partie 1)
A LIRE AUSSI :
Node-RED. Dashboard pour objet connecté. Jauges, graphiques, notifications, template HTML (Partie 2)

Récupérer une clé API sur OpenWeatherMap

OpenWeatherMap est un service météo qui propose un service gratuit jusqu’à 60 appels / minutes ou 1 millions d’appels / mois. C’est largement suffisant pour un usage personnel ! OWM est d’ailleurs intégré à la plupart des logiciels domotiques Open Source (Domoticz, Jeedom, Home Assistant…). Il existe plusieurs offres payantes pour un usage professionnel.

Créer un compte (gratuit) et ouvrez votre page utilisateur. Depuis l’onglet API Keys, donner un nom à la clé d’API personnelle puis cliquer sur Generate

Créer un clé API personnelle pour OpenWeatherMap

Copier la clé, elle est immédiatement activée et disponible. On peut créer autant de clé API que l’on souhaite sans dépasser la limite du plan gratuit (60 requêtes / minute).

récupérer la clé API personnelle pour OpenWeatherMap

Connecter Node-RED à OpenWeatherMap

Ajouter un Node OWM sur le flow et faites un double clic pour ouvrir le panneau de configuration. Configurer comme ceci

  • API Key coller votre clé personnelle créée précédemment
  • Language sélectionner la langue dans laquelle vous souhaitez la météo. Il reste malheureusement un peu d’anglais, mais le plus gros est déjà traduit correctement.
  • Réponse, choisir une option
    • Current weather la météo du jour
    • 5 day forecast prévision à 5 jours. En fait renvoi la prévision toutes les 3 heures sur 14 jours !
    • Combined ne fonctionne pas

Choisir le type de réponse d'OpenWeatherMap souhaitée

  • Location indiquer le nom / pays ou les coordonnées GPS du lieu
  • Name donnez un nom au Node

Done pour enregistrer. Branchez un Debug et Déployer

Récupérer la météo du jour depuis OpenWeatherMap.org

Ouvrez le debug pour afficher la réponse au format JSON de l’API d’OWM. Ici la météo du jour.

Météo du jour renvoyée par OpenWeatherMap au format JSON (par défaut)

Créer un Widget Météo avec un Node template HTML/Angular

Le node Template permet d’afficher sur le Dashboard du code HTML standard ou Angular de Google. Angular est un framework qui permet développer plus facilement des sites internets ou des applications mobiles (à l’aide d’Ionic par exemple).


Remarque. Angular est un framework qui évolue encore énormément et rapidement. A priori, le node Template est compatible avec Angular v4. Les nouvelles Directives (*ngIf au lieu de ng-if), nouveaux Pipes… ne sont pas (encore) disponibles.

Si vous débutez avec le plugin Dashboard, commencez par lire cet article qui explique comment créer un dashboard (onglets et groupes).

A LIRE AUSSI :
Node-RED. Créer un dashboard pour objet connecté. Bouton, liste, interrupteur, slider, formulaire (Partie 1)

Ajouter un node Template et coller le code ci-dessous dans le champ code.

<h3>Météo du jour</h3>
<p>Météo à Lyon le {{msg.payload.sunrise*1000 | date:'d/M'}}</p>
<div layout="row">
    <div layout="column" style="padding:25px">
        <div layout="column" layout-align="center center">
            <span style="color:#3a3a3a!important">Température</span>
            <div layout="row" layout-align="start center">
                <i class="fa fa-thermometer fa-fw"></i>
                <p style="color: black">{{msg.payload.tempc}}°C</p>
            </div>
        </div>    
        <div layout="row" layout-align="center" style="padding:5px">
            <i style="color:blue" class="fa fa-thermometer-empty fa-fw" aria-hidden="true"></i>
            <span flex style="color: blue;font-size:10px!important">{{msg.payload.temp_minc}}°C</span>
    
            <i style="color:red" class="fa fa-thermometer-full fa-fw" aria-hidden="true"></i>
            <span flex style="color: red;font-size:10px!important">{{msg.payload.temp_maxc}}°C</span>
        </div>
    </div>
    <div layout="column" style="padding:25px" layout-align="center center">
        <span flex>Humidité</span>
        <span flex style="color: black">{{msg.payload.humidity}} %</span>
    </div>
    <div layout="column" style="padding:25px" layout-align="center center">
        <span flex>Pression Atm.</span>
        <span flex style="color: black">{{msg.payload.pressure}} mbar</span>
    </div>
    <div layout="column" style="padding:25px" layout-align="center center">
        <p flex>Tendance</p>
        <p flex style="color: black">{{msg.payload.detail| uppercase}}</p>
        <i ng-if="msg.payload.icon=='01d'" class="fa fa-sun-o fa-2x" style="color:yellow"></i>
        <i ng-if="msg.payload.icon=='02d'" class="fa fa-cloud fa-2x" style="color:grey"></i>
        <i ng-if="msg.payload.icon=='03d'" class="fa fa-cloud fa-2x" style="color:grey"></i>
        <i ng-if="msg.payload.icon=='04d'" class="fa fa-cloud fa-2x" style="color:grey"></i>
        <i ng-if="msg.payload.icon=='09d'" class="fa fa-tint fa-2x" style="color:grey"></i>
        <i ng-if="msg.payload.icon=='10d'" class="fa fa-tint fa-2x" style="color:grey"></i>
        <i ng-if="msg.payload.icon=='11d'" class="fa fa-bolt fa-2x" style="color:grey"></i>
        <i ng-if="msg.payload.icon=='13d'" class="fa fa-snowflake-o fa-2x" style="color:grey"></i>
        <i ng-if="msg.payload.icon=='50d'" class="fa fa-cloud fa-2x" style="color:grey"></i>
    </div>
</div>
<div>
    <div layout="row" layout-align="start center">
        <i class="fa fa-arrow-circle-up"></i>
        <p style="margin-left:4px"> Lever du soleil à {{msg.payload.sunrise*1000 | date:"HH:MM"}} </p>
        <i style="margin-left:10px" class="fa fa-arrow-circle-down"></i>
        <p style="margin-left:4px"> Coucher du soleil à {{msg.payload.sunset*1000 | date:"HH:MM"}}</p>
    </div>  
</div>

Pour gagner du temps, voici le code complet du flow que vous pouvez directement importer sur le flow

[{"id":"6504a840.b5f2b8","type":"ui_template","z":"12b9999b.7256a6","group":"d9fc5c5f.19c72","name":"Météo","order":1,"width":"0","height":"0","format":"<h3>Météo du jour</h3>\n<p>Météo à Lyon le {{msg.payload.sunrise*1000 | date:'d/M'}}</p>\n<div layout=\"row\">\n    <div layout=\"column\" style=\"padding:25px\">\n        <div layout=\"column\" layout-align=\"center center\">\n            <span style=\"color:#3a3a3a!important\">Température</span>\n            <div layout=\"row\" layout-align=\"start center\">\n                <i class=\"fa fa-thermometer fa-fw\"></i>\n                <p style=\"color: black\">{{msg.payload.tempc}}°C</p>\n            </div>\n        </div>    \n        <div layout=\"row\" layout-align=\"center\" style=\"padding:5px\">\n            <i style=\"color:blue\" class=\"fa fa-thermometer-empty fa-fw\" aria-hidden=\"true\"></i>\n            <span flex style=\"color: blue;font-size:10px!important\">{{msg.payload.temp_minc}}°C</span>\n    \n            <i style=\"color:red\" class=\"fa fa-thermometer-full fa-fw\" aria-hidden=\"true\"></i>\n            <span flex style=\"color: red;font-size:10px!important\">{{msg.payload.temp_maxc}}°C</span>\n        </div>\n    </div>\n    <div layout=\"column\" style=\"padding:25px\" layout-align=\"center center\">\n        <span flex>Humidité</span>\n        <span flex style=\"color: black\">{{msg.payload.humidity}} %</span>\n    </div>\n    <div layout=\"column\" style=\"padding:25px\" layout-align=\"center center\">\n        <span flex>Pression Atm.</span>\n        <span flex style=\"color: black\">{{msg.payload.pressure}} mbar</span>\n    </div>\n    <div layout=\"column\" style=\"padding:25px\" layout-align=\"center center\">\n        <p flex>Tendance</p>\n        <p flex style=\"color: black\">{{msg.payload.detail| uppercase}}</p>\n        <i ng-if=\"msg.payload.icon=='01d'\" class=\"fa fa-sun-o fa-2x\" style=\"color:yellow\"></i>\n        <i ng-if=\"msg.payload.icon=='02d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"msg.payload.icon=='03d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"msg.payload.icon=='04d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"msg.payload.icon=='09d'\" class=\"fa fa-tint fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"msg.payload.icon=='10d'\" class=\"fa fa-tint fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"msg.payload.icon=='11d'\" class=\"fa fa-bolt fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"msg.payload.icon=='13d'\" class=\"fa fa-snowflake-o fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"msg.payload.icon=='50d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n    </div>\n</div>\n<div>\n    <div layout=\"row\" layout-align=\"start center\">\n        <i class=\"fa fa-arrow-circle-up\"></i>\n        <p style=\"margin-left:4px\"> Lever du soleil à {{msg.payload.sunrise*1000 | date:\"HH:MM\"}} </p>\n        <i style=\"margin-left:10px\" class=\"fa fa-arrow-circle-down\"></i>\n        <p style=\"margin-left:4px\"> Coucher du soleil à {{msg.payload.sunset*1000 | date:\"HH:MM\"}}</p>\n    </div>  \n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":490,"y":100,"wires":[[]]},{"id":"f528240.040cbe","type":"debug","z":"12b9999b.7256a6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":510,"y":220,"wires":[]},{"id":"38d477e5.da5688","type":"ui_template","z":"12b9999b.7256a6","group":"1e31c676.3642ea","name":"reponse","order":3,"width":0,"height":0,"format":"<h3>Météo du jour</h3>\n<p>Réponse décodée avec le <a href=\"https://angular.io/api/common/JsonPipe\" target=\"_blank\">pipe Angular json</a></p>\n<pre>{{msg.payload | json}}</pre>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":500,"y":160,"wires":[[]]},{"id":"10528df7.922f02","type":"openweathermap","z":"12b9999b.7256a6","name":"Météo à Lyon","wtype":"current","lon":"","lat":"","city":"lyon","country":"france","language":"fr","x":280,"y":120,"wires":[["6504a840.b5f2b8","38d477e5.da5688","f528240.040cbe"]]},{"id":"d9fc5c5f.19c72","type":"ui_group","z":"","name":"Prévisions","tab":"e10674c.ce00988","order":1,"disp":true,"width":"12","collapse":false},{"id":"1e31c676.3642ea","type":"ui_group","z":"","name":"Réponse OpenWeatherMap","tab":"e10674c.ce00988","order":2,"disp":true,"width":"6","collapse":false},{"id":"e10674c.ce00988","type":"ui_tab","z":"","name":"Home","icon":"fa-fire","disabled":false,"hidden":false}]

Une fois déployé, voici ce que vous devez obtenir

Widget météo du jour développé avec node-red et Openweathermap

Comment fonctionne ce code HTML ?

Le code HTML a été développé à l’aide du Framework Angular de Google. Difficile d’expliquer en détail tout le fonctionnement d’Angular. Il existe de très nombreux tutoriels ansi qu’une excellente documentation en ligne.

Comment afficher un titre et du texte

On utilise tout simplement des balises HTML pour afficher des titres (h1,h2,….)

De même pour afficher du texte, on utilise les balises HTML telles que <p> ou <span>.

Comment extraire des données du payload Node-RED ?

Pour extraire une données du flux de messages Node-RED, il suffit d’utiliser le système de double accolades propre à Angular {{valeur}}

Cerise sur le gateau, Angular propose un système de mise en forme à la volée bien pratique appelé Pipe. Par exemple pour mettre en majuscule le texte, on ajoutera le pipe uppercase comme ceci

{{valeur | uppercase}}

Il existe déjà de nombreux Pipes

  • Mise en forme du texte : uppercase, lowercase, titlecase (ne fonctionne pas avec le Template Angular pour Node-RED)
  • date : conversion de date
  • number : mise en forme des nombres décimaux
  • json : affichage sous la forme d’un objet json lisible par l’homme

Le système de double accolade est utilisable n’importe où dans le code HTML. Cette ligne permet par exemple de concaténer un libellé avec l’heure de lever du soleil.

Remarquez au passage l’utilisation du Pipe date pour extraire l’heure du lever du soleil du timestamp (horodatage au format unix). Vous pouvez également voir qu’il est possible d’attribuer un style CSS comme pour du code HTML standard.
Lever du soleil à {{msg.payload.sunrise*1000 | date:"HH:MM"}}

Comment organiser les blocs en ligne et colonnes ?

Angular dispose d’un système de mise en page appelé Layout qui permet d’organiser les éléments en ligne (row) et colonne (column). Pour cela Angular fonctionne à l’aide de <div> qui ne sont rien de plus que des blocs. On utilise le système de directives Angular, un système équivalent aux classes HTML pour passer des paramètres à la <div> comme ceci

<div layout="row">

... Contenu de la div (du bloc)

</div>

Il est possible de combiner les lignes et les colonnes pour concevoir des affichages complexes.

Comment utiliser des icônes de la police FontAwesome ?

Vous avez certainement remarqué les icônes un peu partout sur le Widget. Elle proviennent de la police Open Source FontAwesome, version 4.7. Il n’y a aucune installation à faire pour pouvoir les utiliser sur le Dashboard Node-RED. Il suffit d’utiliser une balise <i> comme ceci

<i class="fa fa-thermometer"></i>

Pour trouver les classes des icônes de la version 4.7, rendez-vous sur cette page

D’autres classes sont disponibles :

  • fa-lg light, icône de petite dimension
  • fa-2x taille double
  • fa-3x taille triple
  • fa-4x
  • fa-5x
  • fa-fw pour fixed width, permet d’ajouter une marge après l’icône ce qui évite de devoir gérer une marge
  • Orientations
    • fa-rotatate-* rotation de l’icone à 90, 180 ou 270°
    • fa-flip-horizontal ou fa-flip-vertical

Toutes les classes disponibles sont détaillées ici

Comment réaliser un affichage conditionnel ?

La directive ng-if (attention *ngIf n’est pas supporté) permet d’afficher (ou masquer) un élément lorsqu’une condition est remplie. Ici par exemple, on affiche l’icône ensoleillé si l’API renvoi le code météo 01d. La codification des conditions météos utilisée par OpenWeatherMap est disponible sur cette page.

<i ng-if="msg.payload.icon=='01d'" class="fa fa-sun-o fa-2x" style="color:yellow"></i>
Remarque, on peut accéder au payload du message directement dans la directive ng-if sans avoir besoin d’utiliser le système de double accolades.

Afficher les prévisions météo sur les 14 prochains jours

Voyons maintenant comment créer une liste répétée avec la directive ng-repeat. Créer un nouveau Node OWM et choisissez l’option 5 days forecast. L’API retourne bien les prévisions sur 14 jours toutes les 3 heures).

Créer un node Template et coller le code ci-dessous

<h3>Prévisions sur les 14 prochains jours</h3>
<div layout="row" layout-align="center center">
  <span flex>Prévision du</span>
  <span flex>Température</span>
  <span flex>Pression Atm.</span>
  <span flex>Météo</span>
</div>
<div layout="row" layout-align="center center" ng-repeat="prevision in msg.payload">
  <span flex style="color: blue">{{prevision.dt*1000 | date:"EEEE d MMMM à H:00":"":"fr-fr" }}</span>
  <div layout="column" style="padding:25px">
        <div layout="column" layout-align="center center">
            <div layout="row" layout-align="start center">
                <p style="color: black;margin-left:8px">{{prevision.main.temp | number:1.0-0}}°C</p>
            </div>
        </div>    
        <div layout="row" layout-align="center" style="padding:5px">
            <span flex style="color: blue;font-size:10px!important;margin-right:5px">{{prevision.main.temp_min | number:1.0-0}}°C</span>
            <span flex style="color: red;font-size:10px!important">{{prevision.main.temp_max | number:1.0-0}}°C</span>
        </div>
    </div>
  <span flex style="color: black">{{prevision.main.pressure}} mbar</span>
    <div layout="column" style="padding:25px" layout-align="center center">
        <span flex style="color: black">{{prevision.weather[0].description}}</span>
        <i ng-if="prevision.weather[0].icon=='01d'" class="fa fa-sun-o fa-2x" style="color:yellow"></i>
        <i ng-if="prevision.weather[0].icon=='02d'" class="fa fa-cloud fa-2x" style="color:grey"></i>
        <i ng-if="prevision.weather[0].icon=='03d'" class="fa fa-cloud fa-2x" style="color:grey"></i>
        <i ng-if="prevision.weather[0].icon=='04d'" class="fa fa-cloud fa-2x" style="color:grey"></i>
        <i ng-if="prevision.weather[0].icon=='09d'" class="fa fa-tint fa-2x" style="color:grey"></i>
        <i ng-if="prevision.weather[0].icon=='10d'" class="fa fa-tint fa-2x" style="color:grey"></i>
        <i ng-if="prevision.weather[0].icon=='11d'" class="fa fa-bolt fa-2x" style="color:grey"></i>
        <i ng-if="prevision.weather[0].icon=='13d'" class="fa fa-snowflake-o fa-2x" style="color:grey"></i>
        <i ng-if="prevision.weather[0].icon=='50d'" class="fa fa-cloud fa-2x" style="color:grey"></i>
    </div>
</div>

Ou le code du flow

[{"id":"25bafe0e.b49272","type":"ui_template","z":"12b9999b.7256a6","group":"d9fc5c5f.19c72","name":"Prévisions","order":3,"width":"0","height":"0","format":"<h3>Prévisions sur les 14 prochains jours</h3>\n<div layout=\"row\" layout-align=\"center center\">\n  <span flex>Prévision du</span>\n  <span flex>Température</span>\n  <span flex>Pression Atm.</span>\n  <span flex>Météo</span>\n</div>\n<div layout=\"row\" layout-align=\"center center\" ng-repeat=\"prevision in msg.payload\">\n  <span flex style=\"color: blue\">{{prevision.dt*1000 | date:\"EEEE d MMMM à H:00\":\"\":\"fr-fr\" }}</span>\n  <div layout=\"column\" style=\"padding:25px\">\n        <div layout=\"column\" layout-align=\"center center\">\n            <div layout=\"row\" layout-align=\"start center\">\n                <p style=\"color: black;margin-left:8px\">{{prevision.main.temp | number:1.0-0}}°C</p>\n            </div>\n        </div>    \n        <div layout=\"row\" layout-align=\"center\" style=\"padding:5px\">\n            <span flex style=\"color: blue;font-size:10px!important;margin-right:5px\">{{prevision.main.temp_min | number:1.0-0}}°C</span>\n            <span flex style=\"color: red;font-size:10px!important\">{{prevision.main.temp_max | number:1.0-0}}°C</span>\n        </div>\n    </div>\n  <span flex style=\"color: black\">{{prevision.main.pressure}} mbar</span>\n    <div layout=\"column\" style=\"padding:25px\" layout-align=\"center center\">\n        <span flex style=\"color: black\">{{prevision.weather[0].description}}</span>\n        <i ng-if=\"prevision.weather[0].icon=='01d'\" class=\"fa fa-sun-o fa-2x\" style=\"color:yellow\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='02d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='03d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='04d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='09d'\" class=\"fa fa-tint fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='10d'\" class=\"fa fa-tint fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='11d'\" class=\"fa fa-bolt fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='13d'\" class=\"fa fa-snowflake-o fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='50d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n    </div>\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":510,"y":280,"wires":[[]]},{"id":"c6442529.2d4f58","type":"openweathermap","z":"12b9999b.7256a6","name":"Prévisions à lyon","wtype":"forecast","lon":"","lat":"","city":"lyon","country":"france","language":"fr","x":290,"y":280,"wires":[["25bafe0e.b49272"]]},{"id":"d9fc5c5f.19c72","type":"ui_group","z":"","name":"Prévisions","tab":"e10674c.ce00988","order":1,"disp":true,"width":"12","collapse":false},{"id":"e10674c.ce00988","type":"ui_tab","z":"","name":"Home","icon":"fa-fire","disabled":false,"hidden":false}]

On retrouve la plupart des concepts expliqué précédemment.

Ici, l’API retourne un tableau au format JSON contenant 40 lignes.

Pour récupérer la pression atmosphérique on suivra le chemin

tableau[indice_ligne][main][pressure]

Pour la prévision

tableau[indice_ligne][weather][0][description]

Prévisions météo sur 14 jours renvoyée par l'API OpenWeatherMap

Mettons ceci en pratique avec Angular à l’aide de la Directive ng-repeat qui permet de parcourir un tableau au format JSON

<div layout="row" layout-align="center center" ng-repeat="prevision in msg.payload">

L’objet prevision contient chaque ligne du tableau. Pour afficher la pression atmosphérique, il suffit d’utiliser le système de double accolades d’Angular que l’on connait bien maintenant, et le tour est joué !

<span>{{prevision.main.pressure}} mbar</span>

Voici ce que ça donne

prévisions météo sur 14 jours node-red widget dashboard

Flow complet du projet Node-RED

Pour gagner du temps, voici le code complet du flow qu’il vous suffit d’importer. N’oubliez pas de coller votre clé d’API et de changer la ville avant de déployer.

[{"id":"12b9999b.7256a6","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"6504a840.b5f2b8","type":"ui_template","z":"12b9999b.7256a6","group":"d9fc5c5f.19c72","name":"Météo","order":1,"width":"0","height":"0","format":"<h3>Météo du jour</h3>\n<p>Météo à Lyon le {{msg.payload.sunrise*1000 | date:'d/M'}}</p>\n<div layout=\"row\">\n    <div layout=\"column\" style=\"padding:25px\">\n        <div layout=\"column\" layout-align=\"center center\">\n            <span style=\"color:#3a3a3a!important\">Température</span>\n            <div layout=\"row\" layout-align=\"start center\">\n                <i class=\"fa fa-thermometer fa-fw\"></i>\n                <p style=\"color: black\">{{msg.payload.tempc}}°C</p>\n            </div>\n        </div>    \n        <div layout=\"row\" layout-align=\"center\" style=\"padding:5px\">\n            <i style=\"color:blue\" class=\"fa fa-thermometer-empty fa-fw\" aria-hidden=\"true\"></i>\n            <span flex style=\"color: blue;font-size:10px!important\">{{msg.payload.temp_minc}}°C</span>\n    \n            <i style=\"color:red\" class=\"fa fa-thermometer-full fa-fw\" aria-hidden=\"true\"></i>\n            <span flex style=\"color: red;font-size:10px!important\">{{msg.payload.temp_maxc}}°C</span>\n        </div>\n    </div>\n    <div layout=\"column\" style=\"padding:25px\" layout-align=\"center center\">\n        <span flex>Humidité</span>\n        <span flex style=\"color: black\">{{msg.payload.humidity}} %</span>\n    </div>\n    <div layout=\"column\" style=\"padding:25px\" layout-align=\"center center\">\n        <span flex>Pression Atm.</span>\n        <span flex style=\"color: black\">{{msg.payload.pressure}} mbar</span>\n    </div>\n    <div layout=\"column\" style=\"padding:25px\" layout-align=\"center center\">\n        <p flex>Tendance</p>\n        <p flex style=\"color: black\">{{msg.payload.detail| uppercase}}</p>\n        <i ng-if=\"msg.payload.icon=='01d'\" class=\"fa fa-sun-o fa-2x\" style=\"color:yellow\"></i>\n        <i ng-if=\"msg.payload.icon=='02d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"msg.payload.icon=='03d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"msg.payload.icon=='04d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"msg.payload.icon=='09d'\" class=\"fa fa-tint fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"msg.payload.icon=='10d'\" class=\"fa fa-tint fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"msg.payload.icon=='11d'\" class=\"fa fa-bolt fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"msg.payload.icon=='13d'\" class=\"fa fa-snowflake-o fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"msg.payload.icon=='50d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n    </div>\n</div>\n<div>\n    <div layout=\"row\" layout-align=\"start center\">\n        <i class=\"fa fa-arrow-circle-up\"></i>\n        <p style=\"margin-left:4px\"> Lever du soleil à {{msg.payload.sunrise*1000 | date:\"HH:MM\"}} </p>\n        <i style=\"margin-left:10px\" class=\"fa fa-arrow-circle-down\"></i>\n        <p style=\"margin-left:4px\"> Coucher du soleil à {{msg.payload.sunset*1000 | date:\"HH:MM\"}}</p>\n    </div>  \n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":490,"y":100,"wires":[[]]},{"id":"f528240.040cbe","type":"debug","z":"12b9999b.7256a6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":510,"y":220,"wires":[]},{"id":"25bafe0e.b49272","type":"ui_template","z":"12b9999b.7256a6","group":"d9fc5c5f.19c72","name":"Prévisions","order":3,"width":"0","height":"0","format":"<h3>Prévisions sur les 14 prochains jours</h3>\n<div layout=\"row\" layout-align=\"center center\">\n  <span flex>Prévision du</span>\n  <span flex>Température</span>\n  <span flex>Pression Atm.</span>\n  <span flex>Météo</span>\n</div>\n<div layout=\"row\" layout-align=\"center center\" ng-repeat=\"prevision in msg.payload\">\n  <span flex style=\"color: blue\">{{prevision.dt*1000 | date:\"EEEE d MMMM à H:00\":\"\":\"fr-fr\" }}</span>\n  <div layout=\"column\" style=\"padding:25px\">\n        <div layout=\"column\" layout-align=\"center center\">\n            <div layout=\"row\" layout-align=\"start center\">\n                <p style=\"color: black;margin-left:8px\">{{prevision.main.temp | number:1.0-0}}°C</p>\n            </div>\n        </div>    \n        <div layout=\"row\" layout-align=\"center\" style=\"padding:5px\">\n            <span flex style=\"color: blue;font-size:10px!important;margin-right:5px\">{{prevision.main.temp_min | number:1.0-0}}°C</span>\n            <span flex style=\"color: red;font-size:10px!important\">{{prevision.main.temp_max | number:1.0-0}}°C</span>\n        </div>\n    </div>\n  <span flex style=\"color: black\">{{prevision.main.pressure}} mbar</span>\n    <div layout=\"column\" style=\"padding:25px\" layout-align=\"center center\">\n        <span flex style=\"color: black\">{{prevision.weather[0].description}}</span>\n        <i ng-if=\"prevision.weather[0].icon=='01d'\" class=\"fa fa-sun-o fa-2x\" style=\"color:yellow\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='02d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='03d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='04d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='09d'\" class=\"fa fa-tint fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='10d'\" class=\"fa fa-tint fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='11d'\" class=\"fa fa-bolt fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='13d'\" class=\"fa fa-snowflake-o fa-2x\" style=\"color:grey\"></i>\n        <i ng-if=\"prevision.weather[0].icon=='50d'\" class=\"fa fa-cloud fa-2x\" style=\"color:grey\"></i>\n    </div>\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":510,"y":280,"wires":[[]]},{"id":"38d477e5.da5688","type":"ui_template","z":"12b9999b.7256a6","group":"1e31c676.3642ea","name":"reponse","order":3,"width":0,"height":0,"format":"<h3>Météo du jour</h3>\n<p>Réponse décodée avec le <a href=\"https://angular.io/api/common/JsonPipe\" target=\"_blank\">pipe Angular json</a></p>\n<pre>{{msg.payload | json}}</pre>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":500,"y":160,"wires":[[]]},{"id":"dade1f8b.be12e","type":"ui_button","z":"12b9999b.7256a6","name":"","group":"1e31c676.3642ea","order":1,"width":0,"height":0,"passthru":false,"label":"Actualiser","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"date","topic":"","x":80,"y":120,"wires":[["c6442529.2d4f58","10528df7.922f02"]]},{"id":"10528df7.922f02","type":"openweathermap","z":"12b9999b.7256a6","name":"Météo à Lyon","wtype":"current","lon":"","lat":"","city":"lyon","country":"france","language":"fr","x":280,"y":120,"wires":[["6504a840.b5f2b8","38d477e5.da5688","f528240.040cbe"]]},{"id":"c6442529.2d4f58","type":"openweathermap","z":"12b9999b.7256a6","name":"Prévisions à lyon","wtype":"forecast","lon":"","lat":"","city":"lyon","country":"france","language":"fr","x":290,"y":280,"wires":[["25bafe0e.b49272","f528240.040cbe"]]},{"id":"d9fc5c5f.19c72","type":"ui_group","z":"","name":"Prévisions","tab":"e10674c.ce00988","order":1,"disp":true,"width":"12","collapse":false},{"id":"1e31c676.3642ea","type":"ui_group","z":"","name":"Réponse OpenWeatherMap","tab":"e10674c.ce00988","order":2,"disp":true,"width":"6","collapse":false},{"id":"e10674c.ce00988","type":"ui_tab","z":"","name":"Home","icon":"fa-fire","disabled":false,"hidden":false}]

widget meteo dashboard node-red template html angular

Mises à jour

27/07/2020 Première publication du tutoriel

Avez-vous aimé cet article ?
[Total: 1 Moyenne: 4]

Vous rencontrez un problème avec ce sujet ?

Peut-être que quelqu’un a déjà trouvé la solution, visitez le forum avant de poser votre question

Accéder directement aux forums

Vous avez aimé ce projet ? Ne manquez plus aucun projet en vous abonnant à notre lettre d’information hebdomadaire!

Nous serions ravis de connaître votre avis

      Laisser un commentaire

      Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

      Domotique et objets connectés à faire soi-même