Mapping Real-time Air Quality Data: Using the PurpleAir API with Velocity

2952
8
05-24-2023 09:00 AM
BrianBaldwin
Esri Regular Contributor
2 8 2,952

Modern GIS is about dynamic, real-time data. Static data is important… but there should be more focus on skills and experience with ‘living’ datasets.

When I looked around for datasets to test; querying, visualizing, analyzing, and archiving real-time air quality data sounded like a good plan to me. If you are not familiar with PurpleAir – they build air quality sensors that private and public entities have deployed across the globe. They also provide an API that lets users send data requests to poll their sensors.

In this blog – I wanted to run through how I configured ArcGIS Velocity to read the PurpleAir API and then built a dashboard from the data feed (along with historical information!) that can then be combined with your own data, or anything in the Living Atlas.

In my short example – I wanted look at real-time air quality and pull in historical redlining data. Then, I added US Census American Community Survey (ACS) data related to poverty.

Overall, the ease of use of the ArcGIS Velocity feed configuration, as well as the amazing documentation in the PurpleAir API (as well as the wealth of data) made this a really fun project.

PurpleAir Maps and Data

First off, thanks to the folks at PurpleAir for their great API and sensors. I have no affiliation with PurpleAir other than an interest in getting their data mapped!

The PurpleAir website includes a map to explore sensor locations and data fields. 

The map shows all of the sensors that have been marked as ‘public’, thereby letting anyone see the data getting captured across the world for all of these sensors… it’s an amazing dataset. Based on the PurpleAir documentation, these sensors are recording data every 2 minutes for attributes like air quality, temperature, humidity, etc. (for the full list, just refer to the API documentation).

Here are a couple screen shots from the PurpleAir map:

BrianBaldwin_0-1684773921459.png

Vietnam...

 

BrianBaldwin_1-1684773929500.png

Bosnia...

 

BrianBaldwin_2-1684773947781.png

California...

PurpleAir API – Getting Started

To get started, you need to send an e-mail request to PurpleAir for an API Key – once you have a key, you can send READ and WRITE requests to the API. You’ll need an API key to do anything going forward from here.

The first thing that I needed to do (the best practice in the API), was to create a group, and then add sensors to that group. In that way, I could send one request to poll multiple sensors. In my use case, I wanted to get all of the data for New Haven, CT sensors.

BrianBaldwin_3-1684773994012.png

 

After creating the group (which will generate a unique ID for your group, write this down!), you then need to add sensors to that group.

To get the sensor_index for the sensors you are interested in (for a specific geography), you first need to send a request over to the ‘sensors’ API – I ended up using ‘nwlng, nwlat, selng, selat’ to define a bounding box for New Haven.

BrianBaldwin_4-1684774041693.png

 

BrianBaldwin_5-1684774064813.png

Here are the bounding box parameters, so you can return the sensor_index IDs for the sensors you actually care about.

 

After you have your sensor_index values, you can then add them to your group.

You can do this using the ‘Create Member’ POST request. You just need to send over your new group ID and the sensor_index values.

BrianBaldwin_6-1684774140169.png

 

Now, we are ready to build your request to poll the sensors!

Building the Sensor Data Request

We already created a group and added sensors to it, so now we can use the ‘groups’ API to send 1 request and retrieve data for all of the members of that group.

BrianBaldwin_7-1684774251427.png

I hope you remembered your group ID!

 

There are a lot of different attributes that you can return, so make sure you select only those fields that you need, to keep the request more compact.

You will end up creating a comma separated list of fields that you want to send over in the request. In my example, I wanted to poll for these fields:

 

 

 

name, model, hardware, location_type, private, latitude, longitude, altitude, position_rating, uptime, last_seen, last_modified, date_created, humidity, temperature, pressure, pm2.5_alt, pm2.5_alt_a, pm2.5_alt_b, pm2.5

 

 

 

 

Diving into ArcGIS Velocity

Esri offers 2 different software solutions for real-time data, ArcGIS GeoEvent Server and ArcGIS Velocity. You can read more about both solutions in the links above.

The biggest difference between the 2, is that ArcGIS Velocity is a SaaS solution, whereas GeoEvent Server part of an ArcGIS Enterprise deployment. In my opinion, Velocity is also a bit easier to configure and get up and running. If you want to learn more about Velocity, or getting started with it, there are some great resources here. The rest of this blog will walk through the PurpleAir configuration.

In ArcGIS Velocity, we are going to create a ‘feed’ with the PurpleAir API (with the request we have already built out).

ArcGIS Velocity includes a wide-range of different feed types, for the PurpleAir API, we need to use the ‘Web and Messaging’ type.

BrianBaldwin_0-1684777887248.png

 

This feed type provides a lot of different options and it’s where you can configure requests to a wide-array of APIs.

To poll the PurpleAir API, we will use the ‘HTTP Poller’.

BrianBaldwin_1-1684777979737.png

 

Since we have already know the parameters for our API request, we just need to put them in the right places in the Velocity UI. This includes the URL, the ‘fields’, and the API key.

BrianBaldwin_2-1684779511260.png

 

If the request worked, you’ll get a response back that looks something like this:

BrianBaldwin_3-1684779537616.png

 

The one issue with this response, is that all of the data for the sensors is found in the ‘data’ field that was returned. This is a place where Velocity makes this really easy. All you need to do is enter in the ‘Root node’ (‘data’ in this case), and then click ‘Derive schema’ to update the field definition.

To make it easier to use your data, you can also provide field names that will be applied in the feature service.

BrianBaldwin_4-1684779586151.png

 

If you set names for your fields, it will be easier for you as you assign the key fields, notably the XY, datetime, and your unique ID.

BrianBaldwin_5-1684779765164.png

 

Then we set the interval to send the requests. Make sure that you don’t crush the API with requests! Keep the requests at something reasonable.

BrianBaldwin_6-1684779787375.png

 

Lastly, give your feed a name and specify if you want to create a feature layer to host all of the observations.

BrianBaldwin_7-1684779826176.png

 

Let’s Map this Stuff!

The last step is simply building out an ArcGIS Dashboard to display all of your data. In my example, I combined the real-time data with some additional layers from the Living Atlas to provide more context.

The one spot that I have been tripped up before, is getting the serial chart to display historical values.

Here's a short video that shows some of the settings.

 

That's it! Thanks again to the PurpleAir team for their great documentation and API. Check out their API documentation here: PurpleAir API. As always - if you have any questions, or if you get something built out, I'd love to see it.

8 Comments
PeterKnoop
MVP Regular Contributor

Great post! Wish it included GeoEvent Server in the example though, since Velocity is not included in the education license 😞

BrianBaldwin
Esri Regular Contributor

Great point @PeterKnoop  - I can certainly provide an outline/how to with GeoEvent - it wouldn't be much different - but totally get it!

Teresa_Blader
Occasional Contributor III

Edit: if I just use "name" then I get the sensor_index and the name, in the output.

 

Do you add sensor_index (for building the sensor group) under fields? I get an error: sensor_index was not found. I wonder if it because it's an integer, but the parameters request a String.

Teresa_Blader_0-1685991312000.png

 

 

BrianBaldwin
Esri Regular Contributor

@Teresa_Blader - So the 'fields' value is a string, but you need to then insert a comma seperated list of fields that you want returned - so instead of 'sensor_index' try adding something like:

 

name, icon, model, hardware, location_type, private, latitude, longitude, altitude, position_rating, led_brightness, firmware_version, firmware_upgrade, rssi, uptime, pa_latency

 

 

The bounding box information you are sending in the request should limit what gets returned to just the georgraphy you want.

SAIDEEPAKPINAKANA
New Contributor

Hello Mr. Brian @BrianBaldwin ,

Can you please send the tutorial for Mapping Real-time Air Quality Data: Using the Purple air API with GeoEvent server. It would be of great help as we do not have access to velocity. 

Thank you,

Sai Deepak

BrianBaldwin
Esri Regular Contributor

@SAIDEEPAKPINAKANA - that's a great idea. I'll add it to my 'list' of things to look at getting built-out. The other thing I wanted to try was using the new Data Pipelines functionality to feed in data from the API as well...

Data Pipelines: https://doc.arcgis.com/en/data-pipelines/latest/get-started/about-data-pipelines.htm

 

GiovanniZinn
New Contributor

Hi Brian,

This is very exciting to see!  We are actually trying to build something like this for new haven permanently, and would love to connect directly with you on this.  Thanks!

BrianBaldwin
Esri Regular Contributor

@GiovanniZinn - Feel free to reach out at any time via e-mail: bbaldwin AT esri.com

I am sure 2 spaces and spelling out AT instead of @ will trick all the bots...

About the Author
Brian works as a Lead Engineer at Esri to support customers in Education. Brian has worked as a lecturer in GIS, supported non-profits through his community planning work, and honestly just loves working with users to help solve their geospatial quandaries!