METEO : utilisez l’API de Météo France

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…)