Après recherche, j’ai trouvé qu’il faut copier le code dans le dashboard comme éditeur de configuration.
Malheureusement j’ai une erreur : Votre configuration n’est pas valide : r: At path: views – Expected an array value, but received: undefined
le script présenté en début de discussion crée des entités mameteo.xxxxx
Tu peux les afficher avec une carte entities par exemple :
type: entities
entities:
- entity: mameteo.data
type: attribute
attribute: temperature
name: température
suffix: °C
icon: mdi:temperature-celsius
- entity: mameteo.data
type: attribute
attribute: humidite
suffix: '%'
name: humidité
icon: mdi:air-humidifier
- entity: mameteo.data
type: attribute
name: pression
attribute: pression
suffix: hPa
- entity: mameteo.data
type: attribute
attribute: temperature_10cm
name: température à -10cm
suffix: °C
icon: mdi:temperature-celsius
- type: section
label: pluie
- entity: mameteo.data
type: attribute
attribute: nebulosite
name: nébulosité
suffix: octa (/8)
icon: mdi:cloud-outline
- entity: mameteo.data
type: attribute
attribute: precipitation
name: précipitation 6'
suffix: mm
- type: section
label: vent
- entity: mameteo.data
type: attribute
attribute: vent_force
name: vent
suffix: km/h
icon: mdi:wind-power-outline
- entity: mameteo.data
type: attribute
name: sens du vent
icon: mdi:windsock
attribute: vent_direction
suffix: °
- entity: mameteo.data
type: attribute
attribute: rafale_force
name: force rafale
suffix: km/h
icon: mdi:wind-power-outline
Cela répond-il à ta question ?
Un très grand merci.
Cela fonctionne. Malheureusement pour moi aucune donnée de stations à proximité de chez moi.
Cela m’a permis de m’exercer.
Au plaisir.
Bonjour,
Je rencontre un pb avec l’intégration. L’entité mameteo.data ne se créé pas.
J’ai bien l’autorisation d’accès chez MF avec la clé valide, l’automatisation du package est bien créée. J’ai également le service python activé.
Je pensais initialement que ça pouvait venir de la station sélectionnée qui correspond à ma zone géographique. Mais même avec la station Annecy Meythet, il ne se passe rien. J’ai l’impression que ça bug au niveau de l’execution du script.
Est-ce quelqu’un aurait rencontré le même pb que moi?
Merci de votre aide.
que dises les traces que tu dois retrouver dans Paramètres / Systeme / Journaux et « afficher les journaux bruts » ?
J’ai identifié ce message d’erreur :
2024-11-26 18:02:12.748 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [140538298102208] Error handling message: expected str for dictionary value @ data['template']. Got [] (invalid_format) from 192.168.1.20 (Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0)
2024-11-26 18:02:33.980 ERROR (MainThread) [homeassistant.helpers.event] Error while processing template: Template<template=({{ (state_attr('mameteo.data','raw') | from_json)['ray_glo01'] }}) renders=2>
de toute évidence, la station demandée n’a pas la balise 'ray_glo01'
remplace
rg = resp['ray_glo01']
if rg is not None:
rg /= 360
par
rg = resp.get('ray_glo01', None)
if rg is not None:
rg /= 360
ainsi tu auras rg = None
sans provoquer d’erreur
Y a-t-il eu une modification du code par rapport à la version publiée en début de ce fil ?
J’ai réutilisé le code tel quel, en modifiant simplement la clé pour l’accès à mon compte MF. Donc je m’attendais à ce que cela fonctionne spontanément avec l’exemple de la station d’Annecy… avant de la changer par ma station locale une fois que ça aurait fonctionné.
N’étant ni un expert du python, ni de json, je ne vois pas où remplacer les lignes que tu proposes car ça ne correspond pas au code que j’ai :
source: |
from datetime import datetime
import requests
import urllib.parse
try:
serveur = 'https://public-api.meteofrance.fr/public/DPObs/v1'
key = data.get("key", "")
service = '/station/infrahoraire-6m'
station = '74182001' # code de la station sélectionnée : Annecy Meythet
datage = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") # en UTC
url = serveur + service + '?id_station=' + station + '&date=' + urllib.parse.quote(datage) + '&format=json&apikey=' + urllib.parse.quote(key)
print('url=', url)
r = requests.get(url)
rstr = str(r)
print(r)
if '<400>' in rstr:
hass.states.set('mameteo.data', '400: Contrôle de paramètres en erreur')
elif '<404>' in rstr:
hass.states.set('mameteo.data', '404: Jeu de données inexistant')
elif '<Response [200]>' in rstr:
print('analyse du json')
resp = r.json()[0]
print('resp=', resp)
# hass.states.set( 'mameteo.data', datetime.now().strftime("%d/%m/%Y %H:%M:%S"), { 'json': 'r' } )
datage = datetime.strftime( datetime.strptime(resp['reference_time'], '%Y-%m-%dT%H:%M:%SZ'), '%d/%m/%Y %H:%M:%S' )
hass.states.set( 'mameteo.data', datetime.now().strftime("%d/%m/%Y %H:%M:%S"),
{
'raw': str(resp).replace('\'', '\"'), # ainsi on peut faire : (state_attr('mameteo.data','raw') | from_json)['t']
'raw2': str(resp),
'reference_time': datage, # date and time of the production of the data in UTC
'temperature': resp['t']-273.15, # air temperature at 2 meters above the ground in Kelvin degrees -> °C
'humidite': resp['u'], # hourly relative humidity at 2 meters
'pression': resp['pres']/100, # station pressure in Pa -> hPa
'vent_direction': resp['dd'], # mean wind direction at 10 meters above the ground in degrees
'vent_force': resp['ff']*3.6, # mean wind speed at 10 meters above the ground in m/s -> km/h
'rafale_direction': resp['dxi10'], # 10 minutes mean wind gust direction at 10 meters above the ground in degrees
'rafale_force': resp['fxi10']*3.6, # 10 minutes mean wind gust speed at 10 meters above the ground in m/s
'precipitation': resp['rr_per'], # all precipitation over the previous 6 minutes in mm
'puissance_solaire': resp['ray_glo01']/360, # global radiation over the previous 6 minutes in J/m² = Wh/m² pendant 6mn -> puissance solaire W/m²
'ensoleillement': resp['insolh'], # sunshine duration over the previous 1H in min
'visibilite': resp['vv'], # horizontal visibility in meters
'origine': 'Météo France, Données Observation 6mn'
})
hass.states.set( 'mameteo.reference_time', datage, { 'unit_of_measurement': 'UTC' } )
hass.states.set( 'mameteo.temperature', resp['t']-273.15, { 'unit_of_measurement': '°C' } )
hass.states.set( 'mameteo.humidite', resp['u'], { 'unit_of_measurement': '%' } )
hass.states.set( 'mameteo.pression', resp['pres']/100, { 'unit_of_measurement': 'hPa' } )
hass.states.set( 'mameteo.vent_direction', resp['dd'], { 'unit_of_measurement': '°' } )
hass.states.set( 'mameteo.vent_force', resp['ff']*3.6, { 'unit_of_measurement': 'km/h' } )
hass.states.set( 'mameteo.rafale_direction', resp['dxi10'], { 'unit_of_measurement': '°' } )
hass.states.set( 'mameteo.rafale_force', resp['fxi10']*3.6, { 'unit_of_measurement': 'km/h' } )
hass.states.set( 'mameteo.precipitation', resp['rr_per'], { 'unit_of_measurement': 'mm/1h' } )
hass.states.set( 'mameteo.puissance_solaire',resp['ray_glo01']/360, { 'unit_of_measurement': 'W/m²' } )
hass.states.set( 'mameteo.ensoleillement', resp['insolh'], { 'unit_of_measurement': 'mn' } )
hass.states.set( 'mameteo.visibilite', resp['vv'], { 'unit_of_measurement': 'm' } )
else:
hass.states.set('mameteo.data', 'erreur non définie: ' + rstr)
except Exception as e:
print(f'exception: {e=}')
print('automation.mameteo_data_6mn: terminé')
voici la dernière version de la partie automation :
automation:
# Météo France - data 6mn
# interrogation de l'API de Météo France : données d'observation (6'), fréquence de modif : 6 minutes
- id: mameteo_data_6mn
alias: MaMétéo - data 6mn
description: 'interrogation de l''API de Météo France'
mode: restart
trigger:
- platform: time_pattern
# toutes les 6 minutes, à 59 s
minutes: "/6"
seconds: 59
condition: []
action:
- service: python_script.exec
data:
key: !secret mf_key_obs
key_limit: !secret mf_key_obs_limit
title: Python inline
source: |
from datetime import datetime, timezone
import requests
import urllib.parse
try:
serveur = 'https://public-api.meteofrance.fr/public/DPObs/v1'
key = data.get("key", "")
key_limit = data.get("key_limit", "")
service = '/station/infrahoraire-6m'
station = '74182001' # code de la station sélectionnée : Annecy Meythet
datage = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") # en UTC
url = serveur + service + '?id_station=' + station + '&date=' + urllib.parse.quote(datage) + '&format=json&apikey=' + urllib.parse.quote(key)
# print('url=', url)
r = requests.get(url)
rstr = str(r)
# print(r)
if '<400>' in rstr:
hass.states.set('mameteo.data', '400: Contrôle de paramètres en erreur')
elif '<404>' in rstr:
hass.states.set('mameteo.data', '404: Jeu de données inexistant')
elif '<Response [200]>' in rstr:
# print('analyse du json')
resp = r.json()[0]
# print('resp=', resp)
datage = datetime.strftime( datetime.strptime(resp['reference_time'], '%Y-%m-%dT%H:%M:%SZ'), '%d/%m/%Y %H:%M:%S' )
t = resp.get('t', None)
if t is not None:
t -= 273.15
t_10 = resp.get('t_10', None)
if t_10 is not None:
t_10 -= 273.15
t_20 = resp.get('t_20', None)
if t_20 is not None:
t_20 -= 273.15
t_100 = resp.get('t_100', None)
if t_100 is not None:
t_100 -= 273.15
ff = resp.get('ff', None)
if ff is not None:
ff *= 3.6
fxi10 = resp.get('fxi10', None)
if fxi10 is not None:
fxi10 *= 3.6
p = resp.get('pres', None)
if p is not None:
p /= 100
rg = resp.get('ray_glo01', None)
if rg is not None:
rg /= 360 # 1 J = 1 W * 1 s = 1 Wh / 3600, rg = J/m² * 6 mn = Wh/m² / 3600 * (6 * 60) s
# W/m² = Wh/m² / (6 * 60) s = J/m² * 3600 / 360
hass.states.set( 'mameteo.data', datetime.now().strftime("%d/%m/%Y %H:%M:%S"),
{
'raw': str(resp).replace('\'', '\"'), # ainsi on peut faire : (state_attr('mameteo.data','raw') | from_json)['t']
'reference_time': datage, # date and time of the production of the data in UTC
'temperature': t, # air temperature at 2 meters above the ground in Kelvin degrees -> °C
'temperature_10cm': t_10, # temperature at 10 centimeters below the ground in Kelvin degrees -> °C
'temperature_20cm': t_20, # temperature at 20 centimeters below the ground in Kelvin degrees -> °C
'temperature_100cm': t_100, # temperature at 100 centimeters below the ground in Kelvin degrees -> °C
'humidite': resp['u'], # hourly relative humidity at 2 meters
'pression': p, # station pressure in Pa -> hPa
'vent_direction': resp['dd'], # mean wind direction at 10 meters above the ground in degrees
'vent_force': ff, # mean wind speed at 10 meters above the ground in m/s -> km/h
'rafale_direction': resp['dxi10'], # 10 minutes mean wind gust direction at 10 meters above the ground in degrees
'rafale_force': fxi10, # 10 minutes mean wind gust speed at 10 meters above the ground in m/s
'precipitation': resp['rr_per'], # all precipitation over the previous 6 minutes in mm
'puissance_solaire': rg, # global radiation over the previous 6 minutes in J/m² = Wh/m² pendant 6mn -> puissance solaire W/m²
'ensoleillement': resp['insolh'], # sunshine duration over the previous 1H in min
'visibilite': resp['vv'], # horizontal visibility in meters
'origine': 'Météo France, Données Observation 6mn',
'key_limit': key_limit
})
hass.states.set( 'mameteo.reference_time', datage, { 'unit_of_measurement': 'UTC', 'alias': 'date and time of the production of the data in UTC' } )
hass.states.set( 'mameteo.temperature', t, { 'unit_of_measurement': '°C', 'alias': 'air temperature at 2 meters above the ground in Kelvin degrees -> °C' } )
hass.states.set( 'mameteo.temperature_10cm', t_10, { 'unit_of_measurement': '°C', 'alias': 'temperature at 10 centimeters below the ground in Kelvin degrees -> °C' } )
hass.states.set( 'mameteo.temperature_20cm', t_20, { 'unit_of_measurement': '°C', 'alias': 'temperature at 20 centimeters below the ground in Kelvin degrees -> °C' } )
hass.states.set( 'mameteo.temperature_100cm',t_100, { 'unit_of_measurement': '°C', 'alias': 'temperature at 100 centimeters below the ground in Kelvin degrees -> °C' } )
hass.states.set( 'mameteo.humidite', resp['u'], { 'unit_of_measurement': '%', 'alias': 'hourly relative humidity at 2 meters' } )
hass.states.set( 'mameteo.pression', p, { 'unit_of_measurement': 'hPa', 'alias': 'station pressure in Pa -> hPa' } )
hass.states.set( 'mameteo.vent_direction', resp['dd'], { 'unit_of_measurement': '°', 'alias': 'mean wind direction at 10 meters above the ground in degrees' } )
hass.states.set( 'mameteo.vent_force', ff, { 'unit_of_measurement': 'km/h','alias': 'mean wind speed at 10 meters above the ground in m/s -> km/h' } )
hass.states.set( 'mameteo.rafale_direction', resp['dxi10'], { 'unit_of_measurement': '°', 'alias': '10 minutes mean wind gust direction at 10 meters above the ground in degrees' } )
hass.states.set( 'mameteo.rafale_force', fxi10, { 'unit_of_measurement': 'km/h','alias': '10 minutes mean wind gust speed at 10 meters above the ground in m/s' } )
hass.states.set( 'mameteo.precipitation', resp['rr_per'], { 'unit_of_measurement': 'mm/1h','alias': 'all precipitation over the previous 6 minutes in mm' } )
hass.states.set( 'mameteo.puissance_solaire',rg, { 'unit_of_measurement': 'W/m²','alias': 'global radiation over the previous 6 minutes in J/m² = Wh/m² pendant 6mn -> puissance solaire W/m²' } )
hass.states.set( 'mameteo.ensoleillement', resp['insolh'], { 'unit_of_measurement': 'mn', 'alias': 'sunshine duration over the previous 1H in min' } )
hass.states.set( 'mameteo.visibilite', resp['vv'], { 'unit_of_measurement': 'm', 'alias': 'horizontal visibility in meters' } )
else:
hass.states.set( 'mameteo.data', 'erreur non définie: ' + rstr, { 'key_limit': key_limit } )
except Exception as e:
print(f'exception: {e=}')
hass.states.set( 'mameteo.data', 'exception', { 'text': f'{e=}' } )
print('automation.mameteo_data_6mn: terminé')
Ah oui en effet, la partie automatisation a un peu changé.
Avec cette version, l’entité mameteo.data est bien créée cette fois et la station météo près de chez moi renvoie bien les infos. J’en ai certaines (puissance solaire et ensoleillement) qui ne retournent rien pour l’instant sur le dashboard que tu as partagé, mais je vais creuser un peu de mon côté pour comprendre comment sont rapatriées les données.
Merci encore pour ton aide @Georges. Et bravo pour cette intégration fort utile !
j’ai peur de te décevoir, mais si la station sélectionnée n’est pas équipé de certains capteurs (puissance solaire et ensoleillement dans ton cas), tu n’auras jamais les données correspondantes qui n’existent pas
pour ma part, j’ai la chance d’être à coté d’un petit aérodrome bien équipé (chance pour les infos, malchance pour le bruit…)