Nouvelle intégration : AtmoFrance - Qualité de l'air

@Pyroaction paramètres / appareils et services / intégrations puis ajouter une intégration et chercher Atmo France

Merci pour ce dev… sitôt lu, sitôt en place :wink:

1 « J'aime »

Merci @SebCaps pour l’intégration et pour l’aide @Krull56

1 « J'aime »

Hello,

Effectivement l’intégration fonctionne bien.
Par contre (c’est pas lié à l’intégration) mais Ozone / CO2 restent constant … Je ne sais pas si ça bouge beaucoup dans des villes comme Paris/Borbeaux/Lyon mais ici à Orléans, c’est pas super pertinent au quotidien

Voici ma carte « Qualité de l’air »:
image

type: horizontal-stack
title: Qualité de l'air
cards:
  - type: custom:button-card
    color_type: card
    entity: sensor.dioxyde_de_souffre_toussieu
    name: SO2
    state:
      - value: 1
        color: lightgreen
      - value: 2
        color: green
      - value: 3
        color: yellow
      - value: 4
        color: red
      - value: 5
        color: darkred
      - value: 6
        color: darkviolet
    styles:
      card:
        - height: 90px
        - font-size: 15px
  - type: custom:button-card
    color_type: card
    entity: sensor.ozone_toussieu
    name: Ozone
    state:
      - value: 1
        color: lightgreen
      - value: 2
        color: green
      - value: 3
        color: yellow
      - value: 4
        color: red
      - value: 5
        color: darkred
      - value: 6
        color: darkviolet
    styles:
      card:
        - height: 90px
        - font-size: 15px
  - type: custom:button-card
    color_type: card
    entity: sensor.pm10_toussieu
    name: PM < 10µm
    state:
      - value: 1
        color: lightgreen
      - value: 2
        color: green
      - value: 3
        color: yellow
      - value: 4
        color: red
      - value: 5
        color: darkred
      - value: 6
        color: darkviolet
    styles:
      card:
        - height: 90px
        - font-size: 15px
  - type: custom:button-card
    color_type: card
    entity: sensor.pm25_toussieu
    name: PM < 2.5µm
    state:
      - value: 1
        color: lightgreen
      - value: 2
        color: green
      - value: 3
        color: yellow
      - value: 4
        color: red
      - value: 5
        color: darkred
      - value: 6
        color: darkviolet
    styles:
      card:
        - height: 90px
        - font-size: 15px
5 « J'aime »

@Pyroaction merci pour la belle intégration. Chacun ses compétences et je suis perso plu a l’aise en back qu’en front …
Deux questions :

  • est ce que récupérer les alertes sur les polluants peut intéresser des personnes ?
  • est ce que si j’étais l’information couleur de l’API on pourrait l’utiliser dans une belle visualisation ?

Thx

Malette

Oui, ça peut être intéressent mais pourrais tu fournir un exemple si tu as

Salut,
Les données fournies sont pour les polluants SO2, PM10, O3 et NO2 un seuil d’alerte pour la veille, le jour courant et le lendemain sous forme d’un texte ( PAS DE DEPASSEMENT, INFORMATION ET RECOMMANDATION, ALERTE et ALERTE SUR PERSISTANCE). Les données sont fournies au niveau du département.
Mon idée est de fournir le niveau pour le jour courant et le lendemain pour les 4 polluants (AlerteNO2J ; AlerteNO2J+1…) =>8 sensors donc.
L’activation de ces sensors serait optionnelle.
Mon seul hic, c’est le chgt de date à minuit, les données sont mises à jour vers 13h => à minuit l’alerte à J+1 se « transforme » en alerte J mais le J+1 n’est plus dispo…
Dans le détails le JSON renvoyé pour info.

{
    "type": "FeatureCollection",
    "name": "national_data.national_alrt3j",
    "crs": {
        "type": "name",
        "properties": {
            "name": "urn:ogc:def:crs:EPSG::3857"
        }
    },
    "features": [
        {
            "type": "Feature",
            "properties": {
                "gml_id": 4169287,
                "aasqa": "44",
                "date_maj": "2023/05/26 17:00:42.488+02",
                "partition_field": "442023w21",
                "etat": "PAS DE DEPASSEMENT",
                "lib_zone": "Meurthe-et-Moselle",
                "lib_pol": "Dioxyde de soufre",
                "date_ech": "2023-05-25",
                "date_dif": "2023/05/26",
                "code_zone": "54",
                "code_pol": "1"
            },
            "geometry": null
        },
        {
            "type": "Feature",
            "properties": {
                "gml_id": 4169297,
                "aasqa": "44",
                "date_maj": "2023/05/26 17:00:42.488+02",
                "partition_field": "442023w21",
                "etat": "PAS DE DEPASSEMENT",
                "lib_zone": "Meurthe-et-Moselle",
                "lib_pol": "Particules fines, diamètre < 10 µm",
                "date_ech": "2023-05-25",
                "date_dif": "2023/05/26",
                "code_zone": "54",
                "code_pol": "5"
            },
            "geometry": null
        },
        {
            "type": "Feature",
            "properties": {
                "gml_id": 4169307,
                "aasqa": "44",
                "date_maj": "2023/05/26 17:00:42.488+02",
                "partition_field": "442023w21",
                "etat": "PAS DE DEPASSEMENT",
                "lib_zone": "Meurthe-et-Moselle",
                "lib_pol": "Ozone",
                "date_ech": "2023-05-25",
                "date_dif": "2023/05/26",
                "code_zone": "54",
                "code_pol": "7"
            },
            "geometry": null
        },
        {
            "type": "Feature",
            "properties": {
                "gml_id": 4169317,
                "aasqa": "44",
                "date_maj": "2023/05/26 17:00:42.488+02",
                "partition_field": "442023w21",
                "etat": "PAS DE DEPASSEMENT",
                "lib_zone": "Meurthe-et-Moselle",
                "lib_pol": "Dioxyde d'azote",
                "date_ech": "2023-05-25",
                "date_dif": "2023/05/26",
                "code_zone": "54",
                "code_pol": "8"
            },
            "geometry": null
        },
        {
            "type": "Feature",
            "properties": {
                "gml_id": 4169327,
                "aasqa": "44",
                "date_maj": "2023/05/26 17:00:42.488+02",
                "partition_field": "442023w21",
                "etat": "PAS DE DEPASSEMENT",
                "lib_zone": "Meurthe-et-Moselle",
                "lib_pol": "Dioxyde de soufre",
                "date_ech": "2023-05-26",
                "date_dif": "2023/05/26",
                "code_zone": "54",
                "code_pol": "1"
            },
            "geometry": null
        },
        {
            "type": "Feature",
            "properties": {
                "gml_id": 4169337,
                "aasqa": "44",
                "date_maj": "2023/05/26 17:00:42.488+02",
                "partition_field": "442023w21",
                "etat": "PAS DE DEPASSEMENT",
                "lib_zone": "Meurthe-et-Moselle",
                "lib_pol": "Particules fines, diamètre < 10 µm",
                "date_ech": "2023-05-26",
                "date_dif": "2023/05/26",
                "code_zone": "54",
                "code_pol": "5"
            },
            "geometry": null
        },
        {
            "type": "Feature",
            "properties": {
                "gml_id": 4169347,
                "aasqa": "44",
                "date_maj": "2023/05/26 17:00:42.488+02",
                "partition_field": "442023w21",
                "etat": "PAS DE DEPASSEMENT",
                "lib_zone": "Meurthe-et-Moselle",
                "lib_pol": "Ozone",
                "date_ech": "2023-05-26",
                "date_dif": "2023/05/26",
                "code_zone": "54",
                "code_pol": "7"
            },
            "geometry": null
        },
        {
            "type": "Feature",
            "properties": {
                "gml_id": 4169357,
                "aasqa": "44",
                "date_maj": "2023/05/26 17:00:42.488+02",
                "partition_field": "442023w21",
                "etat": "PAS DE DEPASSEMENT",
                "lib_zone": "Meurthe-et-Moselle",
                "lib_pol": "Dioxyde d'azote",
                "date_ech": "2023-05-26",
                "date_dif": "2023/05/26",
                "code_zone": "54",
                "code_pol": "8"
            },
            "geometry": null
        },
        {
            "type": "Feature",
            "properties": {
                "gml_id": 4169367,
                "aasqa": "44",
                "date_maj": "2023/05/26 17:00:42.488+02",
                "partition_field": "442023w21",
                "etat": "PAS DE DEPASSEMENT",
                "lib_zone": "Meurthe-et-Moselle",
                "lib_pol": "Dioxyde de soufre",
                "date_ech": "2023-05-27",
                "date_dif": "2023/05/26",
                "code_zone": "54",
                "code_pol": "1"
            },
            "geometry": null
        },
        {
            "type": "Feature",
            "properties": {
                "gml_id": 4169377,
                "aasqa": "44",
                "date_maj": "2023/05/26 17:00:42.488+02",
                "partition_field": "442023w21",
                "etat": "PAS DE DEPASSEMENT",
                "lib_zone": "Meurthe-et-Moselle",
                "lib_pol": "Particules fines, diamètre < 10 µm",
                "date_ech": "2023-05-27",
                "date_dif": "2023/05/26",
                "code_zone": "54",
                "code_pol": "5"
            },
            "geometry": null
        },
        {
            "type": "Feature",
            "properties": {
                "gml_id": 4169387,
                "aasqa": "44",
                "date_maj": "2023/05/26 17:00:42.488+02",
                "partition_field": "442023w21",
                "etat": "PAS DE DEPASSEMENT",
                "lib_zone": "Meurthe-et-Moselle",
                "lib_pol": "Ozone",
                "date_ech": "2023-05-27",
                "date_dif": "2023/05/26",
                "code_zone": "54",
                "code_pol": "7"
            },
            "geometry": null
        },
        {
            "type": "Feature",
            "properties": {
                "gml_id": 4169397,
                "aasqa": "44",
                "date_maj": "2023/05/26 17:00:42.488+02",
                "partition_field": "442023w21",
                "etat": "PAS DE DEPASSEMENT",
                "lib_zone": "Meurthe-et-Moselle",
                "lib_pol": "Dioxyde d'azote",
                "date_ech": "2023-05-27",
                "date_dif": "2023/05/26",
                "code_zone": "54",
                "code_pol": "8"
            },
            "geometry": null
        }
    ]
}

Hello,
Cela dépend « fortement » des localisations (et des périodes également je pense).
Je ne suis pas à Paris, mais pour le ‹ fun ›, voici l’index O3 pour Paris

1 « J'aime »

Si on reprend le modèle de home assistant ne peux t’on pas faire un input number si servirai de sauvegarde de la valeur pour le jour J et que l’intégration mettrai a jour si heure est de 23h59 sauf si nouvelle variation de la valeur durant la journée.
Puis un deuxième pour j+1

Bonjour est ce que ca fonctionne pour vous ?
De mon coté j’ai un erreur de connexion :
2023-07-05 14:53:04.693 ERROR (MainThread) [custom_components.atmofrance] Error requesting Atmo France data: No Data from Atmo France for INSEE code 08298 and date 2023-07-05
Et dans la page de login j’ai une erreure aussi :

La page login ne me fait plus d’erreur mais on est d’accord qu’elle ne débouche nul part quand on est logué ?

Salut,
Concernant l’erreur initiale du composant elle est due à une réponse erronée par rapport à l’attendu : il arrive que les données ne soit pas dispo.( pour la date et code INSEE considérée).
L’erreur sur le portail est probablement la cause initiale.

Je ne me rappelle plus quel est l’accès donnée après identification, mais de mon côté idem : après saisie des identifiants je reste sur la page de login, l’intégration fonctionne normalement ( pas d’erreur récente).
Si toujours ko avec l’intégration, passe le niveau de log en debug et poste le résultat.
Seb

1 « J'aime »

Salut j’ai bien tenté de mon cotés mais ça veut pas non plus.

Inscription sur le site ok et il précise bien que cette connexion ne sert que pour L’API
j’ai testé de code postaux reconnu par leur site mais tout est indisponible. voici les logs que je trouve.

Logger: homeassistant.components.sensor
Source: components/sensor/__init__.py:595
Integration: Capteur (documentation, issues)
First occurred: 17:19:52 (6 occurrences)
Last logged: 17:19:52

Error adding entities for domain sensor with platform atmofrance
Error while setting up atmofrance platform for sensor
atmofrance: Error on device update!
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 591, in state
    numerical_value = int(value)
                      ^^^^^^^^^^
ValueError: invalid literal for int() with base 10: ''

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 510, in async_add_entities
    await asyncio.gather(*tasks)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 750, in _async_add_entity
    await entity.add_to_platform_finish()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1004, in add_to_platform_finish
    self.async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 746, in async_write_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 808, in _async_write_ha_state
    state = self._stringify_state(available)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 752, in _stringify_state
    if (state := self.state) is None:
                 ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 595, in state
    raise ValueError(
ValueError: Sensor sensor.ozone_montbeton has device class 'aqi', state class 'measurement' unit 'None' and suggested precision 'None' thus indicating it has a numeric value; however, it has the non-numeric value: '' (<class 'str'>)

la seconde

Cette erreur provient d'une intégration personnalisée

Logger: custom_components.atmofrance
Source: helpers/update_coordinator.py:262
Integration: Atmo France (documentation, issues)
First occurred: 17:19:52 (2 occurrences)
Last logged: 17:19:52

Error requesting Atmo France data: No Data from Atmo France for INSEE code 82124 and date 2023-08-04
Error requesting Atmo France data: No Data from Atmo France for INSEE code 82121 and date 2023-08-04

et c’elle la il me la sort tous les jours alors que l’on vois bien les resultats sur leur sites

Cette erreur provient d'une intégration personnalisée

Logger: custom_components.atmofrance.api
Source: custom_components/atmofrance/api.py:80
Integration: Atmo France (documentation, issues)
First occurred: 17:19:47 (4 occurrences)
Last logged: 17:19:52

No data for INSEE 82124 and date 2023-08-04
No data for INSEE 82121 and date 2023-08-04

puis la derniere

Cette erreur provient d'une intégration personnalisée

Logger: custom_components.atmofrance
Source: helpers/update_coordinator.py:251
Integration: Atmo France (documentation, issues)
First occurred: 17:19:47 (2 occurrences)
Last logged: 17:19:47

Error requesting Atmo France data: No Data from Atmo France for INSEE code 82124 and date 2023-08-04
Error requesting Atmo France data: No Data from Atmo France for INSEE code 82121 and date 2023-08-04

@EgainMoney concernant la première erreur il s’agit d’un bug…
Peux tu STP l’enregistrer dans Github que je travaille dessus.
Concernant les autres messages qui sont en fait les même, ils sont présent lorsqu’il n’y a pas de données renvoyés par l’API.(cela arrive que les donnée ne soient pas présentes, mais en général cela ne dure pas…)
En appelant l’API avec les paramètre codeINSEE = 82124 et date > 04/08/2023 il n’y a pas de résultats. Cf ci dessous résultat via postman.=> l’intégration n’est pas en cause dans ce cas.


Per contre je suis intéréssé de savoir par quel moyen (site, url…) tu as les info, en tous cas l’API utilisé ne les fournis pas (en tous cas aujourd’hui et les jours précédents :frowning: )

Voici un début de contribution :

image
Il y a juste sous MA VILLE que je voudrais afficher Mauvais l’attibut libellé du sensor mais je ne trouve pas comment faire là :frowning:

Merci de votre aide

type: custom:stack-in-card
mode: vertical
keep:
  box_shadow: true
  margin: false
  border_radius: true
  background: false
  outer_padding: false
cards:
  - type: custom:mod-card
    card_mod:
      style:
        .: |
          :host {
            --text-divider-color: rgb(68, 115, 158);
            --text-divider-line-size: 1px;
          }
    card:
      type: custom:text-divider-row
      text: Qualité d'air
      align: left
  - type: custom:mod-card
    card_mod:
      style: |
        ha-card {
          margin: -15px -5px 0px -5px;
        }  
    card:
      type: horizontal-stack
      cards:
        - type: custom:button-card
          entity: sensor.qualite_globale_saint_genis_laval
          name: 'MA VILLE'
          icon: mdi:molecule
          layout: icon_name_state2nd
          color_type: icon
          show_name: true
          show_state: true
          state:
            - value: 1
              operator: '=='
              color: '#7FFF00'
              styles:
                state:
                  - color: '#7FFF00'
            - value: 2
              operator: '=='
              color: '#FE9A2E'
              styles:
                state:
                  - color: '#FE9A2E'
            - value: 3
              operator: '=='
              color: '#E74C3C'
              styles:
                state:
                  - color: '#E74C3C'
            - value: 4
              operator: '=='
              color: '#E74C3C'
              styles:
                state:
                  - color: '#E74C3C'
          size: 55%
          styles:
            card:
              - '--mdc-ripple-color': rgb(68, 115, 158)
              - '--mdc-ripple-press-opacity': 0.5
            name:
              - font-size: 16px
            state:
              - font-weight: bold
              - font-size: 16px
        - type: custom:bar-card
          entities:
            - entity: sensor.qualite_globale_saint_genis_laval
              name: Niveau
              icon: mdi:alert-circle
              height: 30px
              color: red
              min: 0
              max: 3
              positions:
                indicator: 'off'
                icon: 'off'
              severity:
                - color: '#E74C3C'
                  from: 3
                  to: 4
                - color: '#E74C3C'
                  from: 2
                  to: 3
                - color: '#FE9A2E'
                  from: 1
                  to: 2
                - color: '#7FFF00'
                  from: 0
                  to: 1
          card_mod:
            style: >
              bar-card-currentbar, bar-card-backgroundbar {
                border-radius: 15px;
              }

              #states > bar-card-row > bar-card-card > bar-card-background >
              bar-card-contentbar > bar-card-name {
                font-size: 16px;
                font-weight: bold;
                color: black;
                margin-left: 15px;
              }  bar-card-contentbar > bar-card-value {
                font-size: 16px;
                margin-right: 25px;
                {% if is_state('sensor.qualite_globale_saint_genis_laval', '1') %}
                  color: #7FFF00;
                  font-weight: bold;
                {% elif is_state('sensor.qualite_globale_saint_genis_laval', '2') %}
                  color: #FE9A2E;
                  font-weight: bold;
                {% elif is_state('sensor.qualite_globale_saint_genis_laval', '3') %}
                  color: black;
                  font-weight: bold;
                {% elif is_state('sensor.qualite_globale_saint_genis_laval', '4') %}
                  color: black;
                  font-weight: bold;
                {% endif %}
              } ha-card {
                margin-top: -2px;
                background: none;
                border: none;
              }
  - type: vertical-stack
    cards:
      - type: grid
        columns: 5
        square: false
        cards:
          - type: custom:button-card
            entity: sensor.dioxyde_d_azote_saint_genis_laval
            name: NO2
            aspect_ratio: 4/3
            show_state: false
            show_icon: true
            icon: mdi:molecule
            size: 100%
            styles:
              card:
                - '--mdc-ripple-color': rgb(68, 115, 158)
                - '--mdc-ripple-press-opacity': 0.5
              name:
                - font-size: 0.84em
              state:
                - font-size: 0.7em
            state:
              - value: 1
                color: lightgreen
              - value: 2
                color: green
              - value: 3
                color: yellow
              - value: 4
                color: red
              - value: 5
                color: darkred
              - value: 6
                color: darkviolet
            card_mod:
              style: |
                ha-card {
                  top: 1px !important;
                  border: none;
                }
          - type: custom:button-card
            entity: sensor.dioxyde_de_soufre_saint_genis_laval
            name: SO2
            aspect_ratio: 4/3
            show_state: false
            show_icon: true
            icon: mdi:molecule
            size: 100%
            styles:
              card:
                - '--mdc-ripple-color': rgb(68, 115, 158)
                - '--mdc-ripple-press-opacity': 0.5
              name:
                - font-size: 0.84em
              state:
                - font-size: 0.7em
            state:
              - value: 1
                color: lightgreen
              - value: 2
                color: green
              - value: 3
                color: yellow
              - value: 4
                color: red
              - value: 5
                color: darkred
              - value: 6
                color: darkviolet
          - type: custom:button-card
            entity: sensor.ozone_saint_genis_laval
            name: Ozone
            aspect_ratio: 4/3
            show_state: false
            show_icon: true
            icon: mdi:molecule
            size: 100%
            styles:
              card:
                - '--mdc-ripple-color': rgb(68, 115, 158)
                - '--mdc-ripple-press-opacity': 0.5
              name:
                - font-size: 0.84em
              state:
                - font-size: 0.7em
            state:
              - value: 1
                color: lightgreen
              - value: 2
                color: green
              - value: 3
                color: yellow
              - value: 4
                color: red
              - value: 5
                color: darkred
              - value: 6
                color: darkviolet
          - type: custom:button-card
            entity: sensor.pm10_saint_genis_laval
            name: PM10
            aspect_ratio: 4/3
            show_state: false
            show_icon: true
            icon: mdi:blur
            size: 100%
            styles:
              card:
                - '--mdc-ripple-color': rgb(68, 115, 158)
                - '--mdc-ripple-press-opacity': 0.5
              name:
                - font-size: 0.84em
              state:
                - font-size: 0.7em
            state:
              - value: 1
                color: lightgreen
              - value: 2
                color: green
              - value: 3
                color: yellow
              - value: 4
                color: red
              - value: 5
                color: darkred
              - value: 6
                color: darkviolet
          - type: custom:button-card
            entity: sensor.pm25_saint_genis_laval
            name: PM2.5
            aspect_ratio: 4/3
            show_state: false
            show_icon: true
            icon: mdi:blur
            size: 100%
            styles:
              card:
                - '--mdc-ripple-color': rgb(68, 115, 158)
                - '--mdc-ripple-press-opacity': 0.5
              name:
                - font-size: 0.84em
              state:
                - font-size: 0.7em
            state:
              - value: 1
                color: lightgreen
              - value: 2
                color: green
              - value: 3
                color: yellow
              - value: 4
                color: red
              - value: 5
                color: darkred
              - value: 6
                color: darkviolet
card_mod:
  style: |
    ha-card {
      box-shadow: 0 0 0 1px gray;
    }      

Salut,
Je ne connais pas particulièrement le composant custom_button_card , mais pour récupérer la valeur d’un attribut : c’est state_attr('device_tracker.paulus', 'battery')
Dans le cas présent :state_attr('sensor.qualite_globale_saint_genis_laval', 'Libellé') pour obtenir le libellé.

Merci pour le retour @SebCaps je vais tenté une incorporation dans ma carte du coup

salut je rentre juste
je vais aller regarder les log pour voir si j’ai toujours les infos a te donner.

J’ai testé sur tout le département 82 31 et il semble avoir un souci pour récupérer les infos de https://www.atmo-france.org/indiceatmo?geoloc vers l’API j’ai testé la ville de jérome et ça fonctionne

après plusieurs tests je vois que c’est ma région Occitanie qui ne renvoie pas d’infos sur L’API soucis sur atmo ?