Request: Binding for PurpleAir air-quality sensors

I would like to acquire and use a PurpleAir PA-II indoor/outdoor PM2.5 sensor for local, off-line (no internet connection) integration with OpenHAB. (My OpenHAB setup is air-gapped from the internet and will remain so probably forever, for security, privacy, and reliability.)

I’m surprised that a search for “purpleair” turns up zero results on the OpenHab comunity forums so far. The PurpleAir devices are now very popular & widely deployed, verified to be reasonably-accurate by various government air-quality agencies, etc.

PurpleAir’s website is very “cloud oriented” (sensors are designed to feed data to the cloud 24/7) but it appears they also allow direct API access to the local server in the device, giving it the potential to be used as a reliable local sensor for an OpenHAB setup. (Querying the PA device on the LAN, not sending out requests to the PurpleAir internet cloud.)

I can’t seem to find a forum board dedicated to technical users of the PurpleAir products, but I did find this useful post about accessing its API:

https://www.wxforum.net/index.php?topic=33482.msg339512#msg339512

Has anyone gotten a PurpleAir to feed data into OpenHAB? If so, how? Would anyone who owns/uses a PurpleAir be willing to write an OpenHAB binding for it, or describe how to easily access the PA data using an existing OpenHAB binding?

Thanks in advance.

I have successfully gotten PurpleAir sensors to write data locally into openHAB through an intermediary nodejs server.

In my example below, I am only getting the “pm2.5_aqi” but there are many values coming from the sensor that you could use.

First, set up your PurpleAir sensor to send to a local server with a port of your choosing. Here’s a sample using a server at 192.168.1.216 and a port of 8079:

image
Next, set up a nodejs server with the following code. You will want to turn this into a service so it starts up at boot time, but you can run it manually to test it out. I am a newbie for nodejs programming, so I’m sure this can be improved. It currently has very little error handling. This takes an incoming POST request and converts it to write out to the REST interface of openHAB. I have an Item called PurpleAir, but of course you can change this to any Item you’d like. And my openHAB server is at 192.168.1.216 with port 8080; change this to match your OH installation.

const express = require('express')
const http = require('http')
const app = express()
const bodyParser = require('body-parser')

// Tell express to use the body-parser middleware and to not parse extended bodies
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json()); // for parsing application/json

var options = {
  // set the openHAB IP/hostname and port here
  host: '192.168.1.216',
  port: 8080,
  // set the openHAB item here
  path: '/rest/items/PurpleAir',
  method: 'POST',
  headers: {
    'Content-Type': 'text/plain',
    'Accept': 'application/json'
  }
};

app.post('/purpleair', (req, res) => {
  const body = req.body.Body
  // console.log(req.body);
  console.log('AQI is: ' + req.body["pm2.5_aqi"]);
  postReq = http.request(options, function(res) {
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
      console.log('BODY: ' + chunk);
    });
  });
  postReq.on('error', (error) => {
    console.error(error) });
  postReq.write(req.body["pm2.5_aqi"].toString());
  postReq.end();
  res.set('Content-Type', 'text/plain')
  res.send('Okay')
})

// choose an unused port for this use:
app.listen(8079)

You can use the console.log of the req.body to see in your syslog the entire POST body coming in which should match the link that you get with the data when your register.

1 Like

After I posted the above using a push from the PurpleAir sensor, I found out that there appears to be an undocumented way to pull the data locally. See this post. If you set a fixed IP for the sensor, you can use “http://sensorIP/json” and you’ll get the data from the sensor formatted in JSON. This means that it should be very easy to use the http binding to pull out the data periodically.

I think I will continue to use the push method as that is documented/supported by PurpleAir and I prefer the model where it pushes data whenever it is ready as opposed to polling, but the above should work and won’t require anything external to openHAB.

1 Like

Thanks for your detailed replies. I’ve marked both of them as “Solution” because they each solve the basic problem of how to get OpenHAB to talk to a PurpleAir (PA) unit on a completely firewalled and/or air-gapped network.

For those who are comfortable using a firewall between their OpenHAB instance and other networks (such as the public internet,) it would be pretty straightforward to set up a custom firewall to allow push and/or pull requests between the PurpleAir unit and OpenHAB. This would give best-of-both-worlds functionality, allowing the PurpleAir to contribute usefully to the public PA database while ensuring complete reliability on the OpenHAB side. (Regardless of internet downtime, PA cloud server API downtime, or even possible long-term failure of the PA cloud services, e.g. due to bankruptcy.)

I won’t have time to implement this in the near future (<3 months) because I have other prerequisites I need to take care of – like migrating from OH1 to OH2 (! I’m still on OH1…) but I’ve bookmarked this topic and will follow/ update here in the coming months & years if I get around to setting up a PurpleAir unit.

Hi there,

I know I’m bumping a topic from a long time ago but I’ve been working on a purpleair binding. You can find it here: https://github.com/ottoxgam/org.openhab.binding.purpleair with the Jar file: https://github.com/ottoxgam/org.openhab.binding.purpleair/blob/master/target/org.openhab.binding.purpleair-2.5.0-SNAPSHOT.jar

This works using the thingspeak api. You’ll need you the ID of your station from https://www.purpleair.com/json. First, head to https://www.purpleair.com/map?opt=1 and find your station. When you click on it, it;ll show your station name. Use that to search on the /json page to find your station ID.

The binding Supports:
pm1 value
pm2.5 value
pm10 value
rssi
uptime
temperature
humidity
pressure
label (Station Name)
latitude
longitude
aqi
aqi description
aqimessage

2 Likes

Any progress on making this live & available to download as an official binding?

I find it a little hard to believe that with PurpleAir being arguably the world’s largest public-sourced particular-matter AQ monitoring service, that there isn’t already an OpenHAB binding for it, including both the PurpleAir public cloud API, and for processing live JSON data obtained directly over the local LAN from local, personally-owned PurpleAir PA-II sensor devices.

I wish I had the programming skills to implement the above but I do not, hopefully someone will do it soon. Thanks for yours / others ongoing efforts.