Qualité d'air

Ah ouaip et le token est valable 1h a ce que je lis,…

Les données sont mise à jour 2 fois par jour … Donc le token d’une heure c’est large

image

Salut …
Quand plus simple chez Météo France en mode « scrape » !!
Pour moi « Atmo Fance » n’est pas possible ici ! :portugal:, et site Europe un peu caca !

Looks good !
Pourrais tu partager ton code pour faire du Multiscrape ?
(j’arrive à afficher une page web, mais pas uniquement le contenu qui m’intéresse, et ce malgré la lecture du tuto de Pulpy-Luke sur le prix de l’essence)

Merci beaucoup !

Montre moi la page que tu veux récupérer, avec entourer ce que tu veux .

Pour info maître @Pulpy-Luke :innocent:a fait c’est vrai de bon tuto, encore faut-il que tu saches te se servir des outils !

ça y est maintenant on va croire que je suis gourou d’une secte, celle des multicrapers fous ? :rofl:

Pas facile de reconnaître quand on Bon !

:rofl:

Bonsoir,
De ce que j’ai compris c’est qu’il faut effectivement se créer un compte en conservant le token
Après dans mon fichier sensors.yaml j’ai créé cela :

##Indices air
  - platform: rest
    scan_interval: '06:00:00'
    name: Indice global du jour
    resource: http://api.atmo-aura.fr/api/v1/communes/XXX/indices/atmo?api_token=XXX&date_calcul=yesterday&echeance=1
    value_template: "{{ value_json.data[0].indice }}"
    json_attributes_path: "$.data[0]"
    json_attributes:
      - qualificatif
  - platform: rest
    scan_interval: '06:00:00'
    name: Indice Particules fines PM2.5 du jour
    resource: http://api.atmo-aura.fr/api/v1/communes/XXX/indices/atmo?api_token=XXX&date_calcul=yesterday&echeance=1
    value_template: "{{ value_json.data[0].sous_indices[0].indice }}"
    json_attributes_path: "$.data[0].sous_indices[0]"
    json_attributes:
      - polluant_nom
      - concentration
  - platform: rest
    scan_interval: '06:00:00'
    name: Indice Particules fines PM10 du jour
    resource: http://api.atmo-aura.fr/api/v1/communes/XXX/indices/atmo?api_token=XXX&date_calcul=yesterday&echeance=1
    value_template: "{{ value_json.data[0].sous_indices[1].indice }}"
    json_attributes_path: "$.data[0].sous_indices[1]"
    json_attributes:
      - polluant_nom
      - concentration
  - platform: rest
    scan_interval: '06:00:00'
    name: Indice Dioxyde de soufre SO2 du jour
    resource: http://api.atmo-aura.fr/api/v1/communes/XXX/indices/atmo?api_token=XXX&date_calcul=yesterday&echeance=1
    value_template: "{{ value_json.data[0].sous_indices[2].indice }}"
    json_attributes_path: "$.data[0].sous_indices[2]"
    json_attributes:
      - polluant_nom
      - concentration
  - platform: rest
    scan_interval: '06:00:00'
    name: Indice Ozone O3 du jour
    resource: http://api.atmo-aura.fr/api/v1/communes/XXX/indices/atmo?api_token=XXX&date_calcul=yesterday&echeance=1
    value_template: "{{ value_json.data[0].sous_indices[3].indice }}"
    json_attributes_path: "$.data[0].sous_indices[3]"
    json_attributes:
      - polluant_nom
      - concentration
  - platform: rest
    scan_interval: '06:00:00'
    name: Indice Dioxyde d'azote No2 du jour
    resource: http://api.atmo-aura.fr/api/v1/communes/XXX/indices/atmo?api_token=XXX&date_calcul=yesterday&echeance=1
    value_template: "{{ value_json.data[0].sous_indices[4].indice }}"
    json_attributes_path: "$.data[0].sous_indices[4]"
    json_attributes:
      - polluant_nom
      - concentration

Ce qui me permet de récupérer ce qui m’intéresse et j’ai crée un dashboard comme ceci :

type: vertical-stack
cards:
  - type: custom:mod-card
    style:
      .: |
        :host {
          --text-divider-color: rgb(68, 115, 158);
          --text-divider-line-size: 1px;
          --border-width: 0px !important;
        }
    card:
      type: custom:text-divider-row
      text: Indice global du jour
      align: center
  - type: custom:flex-table-card
    entities:
      include:
        - sensor.indice_global_du_jour
    columns:
      - data: qualificatif
        name: ' '
        align: center
  - type: gauge
    min: 0.5
    max: 6.5
    needle: true
    segments:
      - from: 0.5
        color: blue
      - from: 1.5
        color: green
      - from: 2.5
        color: yellow
      - from: 3.5
        color: orange
      - from: 4.5
        color: '#db4437'
      - from: 5.5
        color: purple
    name: ''
    entity: sensor.indice_global_du_jour
  - type: custom:mod-card
    style:
      .: |
        :host {
          --text-divider-color: rgb(68, 115, 158);
          --text-divider-line-size: 1px;
          --border-width: 0px !important;
        }
    card:
      type: custom:text-divider-row
      text: Indices
      align: center
  - type: custom:auto-entities
    card:
      type: grid
      columns: 4
      square: true
    card_param: cards
    filter:
      include:
        - entity_id: sensor.indice_*
          attributes: ''
          options:
            type: custom:button-card
            color_type: icon
            show_name: true
            show_state: false
            style: |
              ha-card {
                background: none;
                box-shadow: #ccffcc;
                border-width: 0px;
              }
            styles:
              card:
                - height: 100px
                - width: 100px
              name:
                - font-size: 14px
            state:
              - value: '1'
                color: blue
                icon: mdi:rectangle
              - value: '2'
                operator: '=='
                color: green
                icon: mdi:rectangle
              - value: '3'
                operator: '=='
                color: yellow
                icon: mdi:rectangle
              - value: '4'
                operator: '=='
                color: orange
                icon: mdi:rectangle
              - value: '5'
                operator: '=='
                color: red
                icon: mdi:rectangle
              - value: '6'
                operator: '=='
                color: purple
                icon: mdi:rectangle
            size: 30%
            name: |
              [[[
               return entity.attributes.polluant_nom
              ]]]
      exclude:
        - entity_id: sensor.indice_dioxyde_d_azote_no2_de_demain
        - entity_id: sensor.indice_global_*
        - entity_id: sensor.indice_dioxyde_de_soufre_so2_de_demain
        - entity_id: sensor.indice_ozone_o3_de_demain
        - entity_id: sensor.indice_particules_fines_pm10_de_demain
        - entity_id: sensor.indice_particules_fines_pm2_5_de_demain
    sort:
      method: state
      reverse: true
      ignore_case: true
      numeric: false

Dans la formule il y a mentionné yesterday&echeance1 car avec now&echeance0 j’ai des problèmes de récupération

Si cela peut aider

Merci pour ton messages et les infos mais comment fait pour la partie api_token

Dans leur documentation, c’est écrit que ce token n’est valide que 6h , …

Bonjour,
Le mien est valable tout le temps après inscription il me semble

Merci !
J’ai compris, tu n’utilise pas le site français mais celui de rhone-alpes ( api.atmo-aura.fr )

Ça me dérange pas étant moi-même dans cette région :slight_smile:

Et oui, sur ce site, le token n’expire pas tous les heure et semble être valide longtemps.

Par contre, pour info, les données retourner par les api avec yesterday&echeance1 et now&echeance0 ne sont pas identique (sûrement car hier c’était une estimation et là, c’est des vrais mesure ?)

Ce site est encore mieux que le site français car il donne aussi les valeurs en µg/m³ (et pas seulement un indice), du coup, je vais pouvoir enregistrer ces infos dans un influxdb par la suite …

Si ça peut servir, j’ai convertir les 6 requêtes rest en une seul via le multiscrape et aussi rajouter les device_class qui vont bien (mais j’ai pas trouver le device classe pour le Dioxyde de soufre ) ( la liste est là : Sensor Entity | Home Assistant Developer Docs ) et rajouter un attribut label pour afficher en mode texte le niveau de pollution.

Mon dashbard crée est de type markdown et j’affiche 2 villes :

home assistant qualite air

Code Multiscrape :

Le code est relativement long a cause de l’implementation des indices de pollution « en mode texte »

# TODO : utiliser today&echeance=0
# Et si data[] est vide (le matin)  ( aka value_json.data[0] n'hexiste pas, il faut utiliser yesterday&echeance=1
- name: Qualité de l'air ville1
  resource: http://api.atmo-aura.fr/api/v1/communes/XXXXX/indices/atmo?api_token=YYYYYY&date_calcul=yesterday&echeance=1
  scan_interval: 86400
  button:
    - unique_id: air_qualite_ville1_refresh
      name: Qualite Air Refresh
  sensor:
    - unique_id: air_qualite_ville1_indice_global
      name: Qualite Air Indice global du jour
      value_template: "{{ value_json.data[0].indice }}"
      attributes:
        - name: Qualificatif
          value_template: "{{ value_json.data[0].qualificatif }}"
        - name: Date
          value_template: "{{ value_json.data[0].date_calcul }}"
      icon: mdi:air-filter
    - unique_id: air_qualite_ville1_pm2.5
      name: Particules fines PM2.5
      device_class: PM25
      unit_of_measurement: µg/m³
      value_template: "{{ value_json.data[0].sous_indices[0].concentration }}"
      icon: mdi:air-filter
      attributes:
        - name: indice
          value_template: "{{ value_json.data[0].sous_indices[0].indice }}"
        - name: label
          value_template: >
            {% set value = value_json.data[0].sous_indices[0].indice %}
            {% if (value == 0) %}
              Indisponible
            {% elif (value == 1) %}
              Bon
            {% elif (value == 2) %}
              Moyen
            {% elif (value == 3) %}
              Dégradé
            {% elif (value == 4) %}
              Mauvais
            {% elif (value == 5) %}
              Très mauvais
            {% elif (value == 6) %}
              Extrêmement mauvais
            {% elif (value == 7) %}
              Evénement
            {% else %}
              {{ value }}
            {% endif %}
    - unique_id: air_qualite_ville1_pm10
      name: Particules fines PM10
      device_class: PM10
      unit_of_measurement: µg/m³
      value_template: "{{ value_json.data[0].sous_indices[1].concentration }}"
      icon: mdi:air-filter
      attributes:
        - name: indice
          value_template: "{{ value_json.data[0].sous_indices[1].indice }}"
        - name: label
          value_template: >
            {% set value = value_json.data[0].sous_indices[1].indice %}
            {% if (value == 0) %}
              Indisponible
            {% elif (value == 1) %}
              Bon
            {% elif (value == 2) %}
              Moyen
            {% elif (value == 3) %}
              Dégradé
            {% elif (value == 4) %}
              Mauvais
            {% elif (value == 5) %}
              Très mauvais
            {% elif (value == 6) %}
              Extrêmement mauvais
            {% elif (value == 7) %}
              Evénement
            {% else %}
              {{ value }}
            {% endif %}
    - unique_id: air_qualite_ville1_s02
      name: Qualite Air Dioxyde de soufre
      # device_class: ???
      unit_of_measurement: µg/m³
      value_template: "{{ value_json.data[0].sous_indices[2].concentration }}"
      icon: mdi:air-filter
      attributes:
        - name: indice
          value_template: "{{ value_json.data[0].sous_indices[2].indice }}"
        - name: label
          value_template: >
            {% set value = value_json.data[0].sous_indices[2].indice %}
            {% if (value == 0) %}
              Indisponible
            {% elif (value == 1) %}
              Bon
            {% elif (value == 2) %}
              Moyen
            {% elif (value == 3) %}
              Dégradé
            {% elif (value == 4) %}
              Mauvais
            {% elif (value == 5) %}
              Très mauvais
            {% elif (value == 6) %}
              Extrêmement mauvais
            {% elif (value == 7) %}
              Evénement
            {% else %}
              {{ value }}
            {% endif %}
    - unique_id: air_qualite_ville1_o3
      name: Qualite Air Ozone
      device_class: OZONE
      unit_of_measurement: µg/m³
      value_template: "{{ value_json.data[0].sous_indices[3].concentration }}"
      icon: mdi:air-filter
      attributes:
        - name: indice
          value_template: "{{ value_json.data[0].sous_indices[3].indice }}"
        - name: label
          value_template: >
            {% set value = value_json.data[0].sous_indices[3].indice %}
            {% if (value == 0) %}
              Indisponible
            {% elif (value == 1) %}
              Bon
            {% elif (value == 2) %}
              Moyen
            {% elif (value == 3) %}
              Dégradé
            {% elif (value == 4) %}
              Mauvais
            {% elif (value == 5) %}
              Très mauvais
            {% elif (value == 6) %}
              Extrêmement mauvais
            {% elif (value == 7) %}
              Evénement
            {% else %}
              {{ value }}
            {% endif %}
    - unique_id: air_qualite_ville1_no2
      name: Qualite Air Dioxyde d'azote
      device_class: NITROGEN_DIOXIDE
      unit_of_measurement: µg/m³
      value_template: "{{ value_json.data[0].sous_indices[4].concentration }}"
      icon: mdi:air-filter
      attributes:
        - name: indice
          value_template: "{{ value_json.data[0].sous_indices[4].indice }}"
        - name: label
          value_template: >
            {% set value = value_json.data[0].sous_indices[4].indice %}
            {% if (value == 0) %}
              Indisponible
            {% elif (value == 1) %}
              Bon
            {% elif (value == 2) %}
              Moyen
            {% elif (value == 3) %}
              Dégradé
            {% elif (value == 4) %}
              Mauvais
            {% elif (value == 5) %}
              Très mauvais
            {% elif (value == 6) %}
              Extrêmement mauvais
            {% elif (value == 7) %}
              Evénement
            {% else %}
              {{ value }}
            {% endif %}

- name: Qualité de l'air ville2
  resource: http://api.atmo-aura.fr/api/v1/communes/XXXXX/indices/atmo?api_token=YYYYYY&date_calcul=yesterday&echeance=1
  scan_interval: 86400
  button:
    - unique_id: air_qualite_ville2_refresh
      name: Qualite Air Refresh
  sensor:
    - unique_id: air_qualite_ville2_indice_global
      name: Qualite Air Indice global du jour
      value_template: "{{ value_json.data[0].indice }}"
      attributes:
        - name: Qualificatif
          value_template: "{{ value_json.data[0].qualificatif }}"
        - name: Date
          value_template: "{{ value_json.data[0].date_calcul }}"
      icon: mdi:air-filter
    - unique_id: air_qualite_ville2_pm2.5
      name: Particules fines PM2.5
      device_class: PM25
      unit_of_measurement: µg/m³
      value_template: "{{ value_json.data[0].sous_indices[0].concentration }}"
      icon: mdi:air-filter
      attributes:
        - name: indice
          value_template: "{{ value_json.data[0].sous_indices[0].indice }}"
        - name: label
          value_template: >
            {% set value = value_json.data[0].sous_indices[0].indice %}
            {% if (value == 0) %}
              Indisponible
            {% elif (value == 1) %}
              Bon
            {% elif (value == 2) %}
              Moyen
            {% elif (value == 3) %}
              Dégradé
            {% elif (value == 4) %}
              Mauvais
            {% elif (value == 5) %}
              Très mauvais
            {% elif (value == 6) %}
              Extrêmement mauvais
            {% elif (value == 7) %}
              Evénement
            {% else %}
              {{ value }}
            {% endif %}
    - unique_id: air_qualite_ville2_pm10
      name: Particules fines PM10
      device_class: PM10
      unit_of_measurement: µg/m³
      value_template: "{{ value_json.data[0].sous_indices[1].concentration }}"
      icon: mdi:air-filter
      attributes:
        - name: indice
          value_template: "{{ value_json.data[0].sous_indices[1].indice }}"
        - name: label
          value_template: >
            {% set value = value_json.data[0].sous_indices[1].indice %}
            {% if (value == 0) %}
              Indisponible
            {% elif (value == 1) %}
              Bon
            {% elif (value == 2) %}
              Moyen
            {% elif (value == 3) %}
              Dégradé
            {% elif (value == 4) %}
              Mauvais
            {% elif (value == 5) %}
              Très mauvais
            {% elif (value == 6) %}
              Extrêmement mauvais
            {% elif (value == 7) %}
              Evénement
            {% else %}
              {{ value }}
            {% endif %}
    - unique_id: air_qualite_ville2_s02
      name: Qualite Air Dioxyde de soufre
      # device_class: ???
      unit_of_measurement: µg/m³
      value_template: "{{ value_json.data[0].sous_indices[2].concentration }}"
      icon: mdi:air-filter
      attributes:
        - name: indice
          value_template: "{{ value_json.data[0].sous_indices[2].indice }}"
        - name: label
          value_template: >
            {% set value = value_json.data[0].sous_indices[2].indice %}
            {% if (value == 0) %}
              Indisponible
            {% elif (value == 1) %}
              Bon
            {% elif (value == 2) %}
              Moyen
            {% elif (value == 3) %}
              Dégradé
            {% elif (value == 4) %}
              Mauvais
            {% elif (value == 5) %}
              Très mauvais
            {% elif (value == 6) %}
              Extrêmement mauvais
            {% elif (value == 7) %}
              Evénement
            {% else %}
              {{ value }}
            {% endif %}
    - unique_id: air_qualite_ville2_o3
      name: Qualite Air Ozone
      device_class: OZONE
      unit_of_measurement: µg/m³
      value_template: "{{ value_json.data[0].sous_indices[3].concentration }}"
      icon: mdi:air-filter
      attributes:
        - name: indice
          value_template: "{{ value_json.data[0].sous_indices[3].indice }}"
        - name: label
          value_template: >
            {% set value = value_json.data[0].sous_indices[3].indice %}
            {% if (value == 0) %}
              Indisponible
            {% elif (value == 1) %}
              Bon
            {% elif (value == 2) %}
              Moyen
            {% elif (value == 3) %}
              Dégradé
            {% elif (value == 4) %}
              Mauvais
            {% elif (value == 5) %}
              Très mauvais
            {% elif (value == 6) %}
              Extrêmement mauvais
            {% elif (value == 7) %}
              Evénement
            {% else %}
              {{ value }}
            {% endif %}
    - unique_id: air_qualite_ville2_no2
      name: Qualite Air Dioxyde d'azote
      device_class: NITROGEN_DIOXIDE
      unit_of_measurement: µg/m³
      value_template: "{{ value_json.data[0].sous_indices[4].concentration }}"
      icon: mdi:air-filter
      attributes:
        - name: indice
          value_template: "{{ value_json.data[0].sous_indices[4].indice }}"
        - name: label
          value_template: >
            {% set value = value_json.data[0].sous_indices[4].indice %}
            {% if (value == 0) %}
              Indisponible
            {% elif (value == 1) %}
              Bon
            {% elif (value == 2) %}
              Moyen
            {% elif (value == 3) %}
              Dégradé
            {% elif (value == 4) %}
              Mauvais
            {% elif (value == 5) %}
              Très mauvais
            {% elif (value == 6) %}
              Extrêmement mauvais
            {% elif (value == 7) %}
              Evénement
            {% else %}
              {{ value }}
            {% endif %}
Code Dashboard Type markdown
type: vertical-stack
cards:
  - type: markdown
    content: >-
      Résultat pour le {{
      state_attr("sensor.air_qualite_ville1_indice_global","date") }} : 

      | Ville | Global | PM 2.5 | PM 10 | Dioxyde de soufre | Ozone | Dioxyde
      d'azote |

      |:---:|:---:|:---:|:---:|:---:|:---:|:---:|

      | ville1 | {{ state_attr("sensor.air_qualite_ville1_indice_global",
      "qualificatif") }} | {{ state_attr("sensor.air_qualite_ville1_pm2_5",
      "label") }} | {{ state_attr("sensor.air_qualite_ville1_pm10", "label")
      }} | {{ state_attr("sensor.air_qualite_ville1_s02", "label") }} | {{
      state_attr("sensor.air_qualite_ville1_o3", "label") }} | {{
      state_attr("sensor.air_qualite_ville1_no2", "label") }} |

      |  | | {{ states('sensor.air_qualite_ville1_pm2_5') }} | {{
      states('sensor.air_qualite_ville1_pm10') }} | {{
      states('sensor.air_qualite_ville1_s02') }} | {{
      states('sensor.air_qualite_ville1_o3') }} | {{
      states('sensor.air_qualite_ville1_no2') }} |

      | ville2 | {{
      state_attr("sensor.air_qualite_ville2_indice_global", "qualificatif")
      }} | {{ state_attr("sensor.air_qualite_ville2_pm2_5", "label") }} | {{
      state_attr("sensor.air_qualite_ville2_pm10", "label") }} | {{
      state_attr("sensor.air_qualite_ville2_s02", "label") }} | {{
      state_attr("sensor.air_qualite_ville2_o3", "label") }} | {{
      state_attr("sensor.air_qualite_ville2_no2", "label") }} |

      | | | {{ states('sensor.air_qualite_ville2_pm2_5') }} | {{
      states('sensor.air_qualite_ville2_pm10') }} | {{
      states('sensor.air_qualite_ville2_s02') }} | {{
      states('sensor.air_qualite_ville2_o3') }} | {{
      states('sensor.air_qualite_ville2_no2') }} |
    title: Qualité de l'air
  - type: entities
    entities:
      - entity: button.air_qualite_ville1_refresh
        name: Refresh ville1
      - entity: button.air_qualite_ville2_refresh
        name: Refresh ville2

Salut,
Il n’y a que les imbéciles qui ne changent pas d’avis parait il… Je retire donc une partie de mes [propos] (Qualité d'air - #68 par SebCaps)], ayant trouvé ,le temps l’envie et grandement aidé par le fabuleux tuto sur le dev d’une intégration, je me suis lancé dans le dev d’une intégration pour récupérer les données d’air Atmo.
Pour le moment il reste des coups de tournevis à donner, mais sont OK :

  • la configuration via l’interface (saisie des identifiants, du code postal (gestion du multi code)
  • création de 5 capteurs

L’Api n’est pas hyper bien documentée, mais je pars sur l’appel du endpoint 112 avec code INSEE et récupére les données du jour.
Si vous avez d’autres idées / souhait je suis preneur, dans la limite de mes capacités :wink:

Reste à faire => pas mal de tests, optimisation et savoir comment publier sur HACS…
J’espére fin de semaine prochaine pour une publication…
Stay tuned.

Un pt’it screen pour me rajouter un peu de pression et donner envie ;-)…

3 « J'aime »

Salut
Pour l’ajout dans hacs il faut ajouter le fichier hacs.json à la racine du projet git. Tu peux reprendre celui d’un autre et adapter. De mémoire il faut corriger la description, l’URL…

Salut,
Mode auto promotion : l’intégration atmofrance est dispo😀
Plus d’infos par ici Nouvelle intégration : AtmoFrance - Qualité de l'air

4 « J'aime »

Hello,

Désolé pour le déterrage mais du coup, dans toutes ces refs un peu perdu…

Pour ce qui est de la qualité de l’air intérieur et en local de préférence, quelle référence semble bonne du coup ?
Sans avoir à jouer du fer à souder :slight_smile: parce que le post mis en solution est pour l’API, sauf si j’ai pas bien saisi :wink:

Pareil que @Nardol
Je souhaiterais savoir quel est le meilleur capteur de qualité d’air qui envoie des informations précises CO2 COV, T°C… en Zigbee et qui s’intègre au top dans HA.
Si quelqu’un pourrait nous conseiller. Merci d’avance

CO2 en Zigbee pour moi il y en a qu’un seul mais qui ne marche pas ,… Désolé

Atmo France fonctionne parfaitement chez moi

Sinon tu as les stations Netatmo qui ont une intégration sur HA.
Ce n’est pas du 100% local car ça passe par le cloud Netatmo, mais ça remonte le CO2, température, Humidité, niveau sonore.

Ca ne donne pas le taux de CO2 dans ta maison :stuck_out_tongue:

Moi j’ai choisi airthings en bluetooth qui fonctionne en local.

1 « J'aime »