L'Agenzia regionale per la prevenzione, l'ambiente e l'energia dell´Emilia-Romagna (Arpae) espone tramite API malamente documentate tutta una serie di dati riguardanti le rilevazioni che vengono fatte in regione da varie centraline sparse sul territorio.
Qui scrivo tutti i modi che ho individuato per importare i dati dentro a Home Assistant sotto forma di sensori che possono poi essere utilizzati per visualizzare grafici e affini sulla dashboard.
L'end point a cui inviare le richieste è sempre https://apps.arpae.it/REST
ma espone diversi tipi di estrazioni che non sono tutte documentate, o almeno io non ho trovato un gran che. La cosa migliore è copiare da alcune pagine di Arpae le chiamate e poi andare a sentimento...
- Dal sito di Home Assistant la pagina sui RESTful Sensor
- Dal sito di ARPAE la pagina dove descrive l'API per ottenere la Qualità dell’aria: situazione riassuntiva regionale
- Dal sito di ARPAE il grafico pollini e spore e i dati sui pollini
Tutte le configurazioni sotto riportate vanno fatte in /homeassistant/configuration.yaml
.
Questo sensore raccoglie i dati di PM10, PM2.5, NO2 (diossido di azoto) e O3 (ozono) dalla centralina identificata dall'id "4000022" che si trova a Modena nel Parco Ferrari. La rilevazione viene aggiornata una volta al giorno e pubblicata il giorno successivo quindi uso la funzione now() - timedelta(days = 1)).strftime('%Y%m%d')
per ottenere la stringa relativa al giorno precedente all'esecuzione della chiamata. La centralina esporebbe anche altri dati relativi al superamento delle soglie consentite.
rest:
- resource: "https://apps.arpae.it/REST/qa_stazioni?projection=%7B%22foto%22%3A0%7D&where=%7B%22_id%22%3A%7B%22%24eq%22%3A%224000022%22%7D%7D"
sensor:
- name: "ARPAE pm10"
value_template: "{{ value_json['_items'][0]['dati'][(now() - timedelta(days = 1)).strftime('%Y%m%d')].pm10 }}"
unit_of_measurement: "µg/m³"
state_class: measurement
device_class: pm10
- name: "ARPAE pm2.5"
value_template: "{{ value_json['_items'][0]['dati'][(now() - timedelta(days = 1)).strftime('%Y%m%d')].pm25 }}"
unit_of_measurement: "µg/m³"
state_class: measurement
device_class: pm25
- name: "ARPAE no2"
value_template: "{{ value_json['_items'][0]['dati'][(now() - timedelta(days = 1)).strftime('%Y%m%d')].no2 }}"
unit_of_measurement: "µg/m³"
state_class: measurement
device_class: nitrous_oxide
Una cosa importante riguarda il fatto che la URL deve essere scritta tra doppie virgolette e che tutti i parametri vanno encodati. In pratica la query che eseguo è ?projection={"foto":0}&where={"_id":{"$eq":"4000022"}}
.
Con questi dati ho potuto creare ad esempio questo grafico
chart_type: bar
period: day
type: statistics-graph
entities:
- sensor.pm10
- sensor.no2
stat_types:
- mean
days_to_show: 7
hide_legend: true
title: Livello PM e NO2 ultimi 7 giorni
Un altro modo di importare questa API è quello di filtrare per comune ({"comune":{"$eq":"MODENA"}}
) e poi prendere dentro tutte le centraline. Dato che HA non supporta il foreach dentro alla configurazione delle sonde, non ho trovato di meglio che scrivere un blocco di configurazione per ogni centralina (per Modena sono 6).
Quindi il blocco qui sotto andrebbe ripetuto N volte spostandosi nell'array value_json['items']
:
- resource: "https://apps.arpae.it/REST/qa_stazioni?projection=%7B%22foto%22%3A0%7D&where=%7B%22comune%22%3A%7B%22%24eq%22%3A%22MODENA%22%7D%7D"
sensor:
- name: "ARPAE 0 nome"
value_template: "{{ value_json['_items'][0].nome }}"
unique_id: "qa_stazioni0.nome"
- name: "ARPAE 0 pm10"
value_template: "{{ value_json['_items'][0]['dati'][(now() - timedelta(days = 1)).strftime('%Y%m%d')].pm10 }}"
unique_id: "qa_stazioni0.pm10"
unit_of_measurement: "µg/m³"
state_class: measurement
device_class: pm10
- name: "ARPAE 0 pm2.5"
value_template: "{{ value_json['_items'][0]['dati'][(now() - timedelta(days = 1)).strftime('%Y%m%d')].pm25 }}"
unique_id: "qa_stazioni0.pm25"
unit_of_measurement: "µg/m³"
state_class: measurement
device_class: pm25
- name: "ARPAE 0 no2"
value_template: "{{ value_json['_items'][0]['dati'][(now() - timedelta(days = 1)).strftime('%Y%m%d')].no2 }}"
unique_id: "qa_stazioni0.no2"
unit_of_measurement: "µg/m³"
state_class: measurement
device_class: nitrous_oxide
- name: "ARPAE 1 nome"
value_template: "{{ value_json['_items'][1].nome }}"
unique_id: "qa_stazioni1.nome"
- name: "ARPAE 1 pm10"
value_template: "{{ value_json['_items'][1]['dati'][(now() - timedelta(days = 1)).strftime('%Y%m%d')].pm10 }}"
unique_id: "qa_stazioni1.pm10"
unit_of_measurement: "µg/m³"
state_class: measurement
device_class: pm10
- name: "ARPAE 1 pm2.5"
value_template: "{{ value_json['_items'][1]['dati'][(now() - timedelta(days = 1)).strftime('%Y%m%d')].pm25 }}"
unique_id: "qa_stazioni1.pm25"
unit_of_measurement: "µg/m³"
state_class: measurement
device_class: pm25
- name: "ARPAE 1 no2"
value_template: "{{ value_json['_items'][1]['dati'][(now() - timedelta(days = 1)).strftime('%Y%m%d')].no2 }}"
unique_id: "qa_stazioni1.no2"
unit_of_measurement: "µg/m³"
state_class: measurement
device_class: nitrous_oxide
In realtà nel json ci sarebbe scritto che le sonde misurano anche altri valori ma o sono vuoti o non ve n'è traccia nei risultati:
"parametri_misurati": "As (Arsenico); BaP (Benzo(a)pyrene); Black Carbon BC1 (370nm) ; Black Carbon BC10 (950nm); Black Carbon BC2 (430nm); Black Carbon BC3 (470nm); Black Carbon BC4 (525nm); Black Carbon BC5 (565nm); Black Carbon BC6 (590nm); Black Carbon BC7 (660nm); Black Carbon BC8 (700nm); Black Carbon BC9 (880nm); Cd (Cadmio); N Aliquote; Ni (Nickel); NO (Monossido di azoto); NOX (Ossidi di azoto); NO2 (Biossido di azoto); O3 (Ozono); Pb (Piombo); PM1 (aggiuntivo 1); PM1 OPC; PM10; PM10 (aggiuntivo 1); PM10 OPC; PM2.5; PM2.5 OPC; PM4 OPC; PNC OPC; PTS OPC"
Per quanto riguarda l'ozono i dati sono gli stessi che vengono pubblicati in questa pagina ma al momento ho deciso di non leggerli anche perchè non so bene cosa significhino dal punto di vista della salute.
Questo sensore raccoglie i bollettini giornalieri riguardanti la qualità dell'aria. I risultati sono gli stessi pubblicati in /qa_stazioni
però è diverso il modo in cui è organizzato l'array. Contiene al primo livello i giorni (a partire dal giorno precedente) ed al secondo livello le province. L'ho trovato abbastanza inutile al mio scopo anche perchè è più scomodo da scorrere in json.
Visualizza le previsioni sulla concentrazione di PM 10 (media 24 ore) sulla mappa in questa pagina.
Stessa mappa sopra ma con i valori riguardanti "l'indice di qualità dell'aria".
Stessa mappa sopra ma con i valori riguardanti la concentrazione di PM 24 (media 24 ore).
Stessa mappa sopra ma con i valori riguardanti la concentrazione di Biossido di Azoto (media oraria max).
Stessa mappa sopra ma con i valori riguardanti la concentrazione di Ozono (media 8 ore max).
Visualizza delle valutazioni sulla concentrazione di PM 10 (media 24 ore) sulla mappa in questa pagina
Restituisce l'elenco delle stazioni per la rilevazione dei pollini. I filtri da applicare sono:
sort=[("ordine",1)]
projection={"foto":0}
(per escludere le foto delle stazioni dal json)where={"stato":true}
La URL completa così composta è
https://apps.arpae.it/REST/pollini_stazioni?sort=%5B(%22ordine%22,1)%5D&projection=%7B%22foto%22%3A0%7D&where=%7B%22stato%22%3Atrue%7D
Le stazioni sono:
id | città |
---|---|
4176 | Piacenza |
4177 | Parma |
4178 | Reggio Emilia |
4179 | Modena |
4181 | Bologna |
4189 | San Giovanni Persiceto |
4190 | San Pietro Capofiume |
4182 | Ferrara |
4185 | Ravenna |
4184 | Faenza |
4186 | Forlì |
4187 | Cesena |
4188 | Rimini |
Quindi una query per vedere i risultati di una sola stazione, ad esempio Modena è:
where={"_id":{"$eq":"4179"}}
https://apps.arpae.it/REST/pollini_stazioni?sort=%5B(%22ordine%22,1)%5D&projection=%7B%22foto%22%3A0%7D&where=%7B%22_id%22%3A%7B%22%24eq%22%3A%224179%22%7D%7D
Questa richiesta restituisce un bollettino settimanale (descritto nel campo intervallo_validita
) composto dalla media regionale dei valori dei pollini rilevati nelle varie stazioni.
Si può richiedere l'elenco di tutti i bollettini di uno specifico anno:
sort=[("anno",-1)]
projection={"anno":1}
https://apps.arpae.it/REST/bollettini_pollini?sort=%5B(%22anno%22,-1)%5D&projection=%7B%22anno%22%3A1%7D
Per avere l'ultimo bollettino (più aggiornato) vanno usati i filtri:
sort=[("_id",-1)]
embedded={"stazioni":0}
(per escludere le immagini dal json)
https://apps.arpae.it/REST/bollettini_pollini?embedded=%7B%22stazioni%22%3A0%7D&sort=%5B(%22_id%22,-1)%5D
A questo punto i dati interessanti sono:
$[_items][0][commento]
che contiene una serie di campi testuali con la situazione e le previsioni$[_items][0][letture]
che contiene le letture fatte dalle varie stazioni sui seguenti pollini:
Polline | Pianta |
---|---|
GRAMINACEE | |
BETULACEE | Alnus, Betula, Ambrosia |
COMPOSITEE | Artemisia, indistinte |
CORILACEE | Nocciolo |
FAGACEE | Castagno, Faggio, Quercia |
OLEACEE | Ulivo, Frassini, Indistinte |
PLANTAGINACEE | |
URTICACEE | |
CUPRESSACEE/TAXACEE | |
AMARANTACEE | |
POLYGONACEE | |
EUFORBIACEEE | |
MIRTACEE | |
ULMACEE | Indistinte |
PLATANACEE | |
ACERACEE | |
PINACEE | |
SALICACEE | Salice, Pioppo |
CIPERACEE | |
IUGLANDACEE | |
IPPOCASTANACEE | |
SPORE | Alternaria, Stemphilium |
Altri pollini | |
Non identificati | |
CANNABACEE | |
UMBELLIFERE | |
CORILACEE | Carpino, Ostria |
MORACEE | Broussonetia, Morus |
Per ogni tipologia è presente una "tendenza", i dati divisi per ogni giorno e, solo per alcune tipoligie di pollini anche la classe di concentrazione (alta, media, bassa, assente), la media ed il massimo valore.
Ovviamente non ho la minima idea di cosa abbia senso analizzare, mi baso sul fatto che in questo grafico ci hanno messo solo: FAGACEE - Quercia, GRAMINACEE, OLEACEE - Frassini, OLEACEE - Ulivo, PINACEE, PLANTAGINACEE, URTICACEE, SPORE - Alternaria. E infatti solo le uniche che hanno anche il valore della classe di concentrazione e la media.
Come non detto, forse ho trovato qualcosa... questi dell'Arpae sono terribili con la documentazione ma guardando le chiamate che fa questa pagina direi che si possano estrarre dei dati utili e aggiornati