dclaar / purple_air

Code for displaying Air Quality from a Purple Air device
MIT License
6 stars 4 forks source link

AQI doesn't fail over when a sensor downs a laser counter #10

Closed danswett closed 3 years ago

danswett commented 3 years ago

The Purple Air devices have two sensors for redundancy, and automatically "down" a sensor when they detect a problem.

https://www.purpleair.com/json?show=38607 is a device that's currently in this state - sensor A is "degraded" so the map reports the data from sensor B. Unfortunately it looks like aqi.py only pulls the values from sensor A, so if those stop working correctly then it will report the wrong information.

It doesn't look like there's a value in the json response that flags a sensor as degraded - the web UI seems to make this determination by comparing the values of sensors A and B (and it must also be doing some kind of lookback to decide which one to trust?)

It does look like a bunch of the sensor values seem to get "zeroed out", so spot checking those might also help weight the response.

For the sake of the bug report, here's a dump of the current json response for 38607:

// 20201008133542 // https://www.purpleair.com/json?show=38607

{ "mapVersion": "0.22", "baseVersion": "7", "mapVersionString": "", "results": [ { "ID": 38607, "Label": "Hopi (Street)", "DEVICE_LOCATIONTYPE": "outside", "THINGSPEAK_PRIMARY_ID": "855224", "THINGSPEAK_PRIMARY_ID_READ_KEY": "1UVUAPZARKPZ9UUM", "THINGSPEAK_SECONDARY_ID": "855226", "THINGSPEAK_SECONDARY_ID_READ_KEY": "P63TM3YUI180KBIP", "Lat": 37.390649, "Lon": -122.079714, "PM2_5Value": "3333.12", "LastSeen": 1602189246, "Type": "PMS5003+PMS5003+BME280", "Hidden": "false", "Flag": 1, "DEVICE_BRIGHTNESS": "15", "DEVICE_HARDWAREDISCOVERED": "2.0+BME280+PMSX003-B+PMSX003-A", "Version": "6.01", "LastUpdateCheck": 1602189244, "Created": 1567096527, "Uptime": "2510773", "RSSI": "-46", "Adc": "0.02", "p_0_3_um": "0.0", "p_0_5_um": "0.0", "p_1_0_um": "0.0", "p_2_5_um": "0.0", "p_5_0_um": "0.0", "p_10_0_um": "0.0", "pm1_0_cf_1": "5000.24", "pm2_5_cf_1": "5000.24", "pm10_0_cf_1": "5000.24", "pm1_0_atm": "3333.12", "pm2_5_atm": "3333.12", "pm10_0_atm": "3333.12", "isOwner": 0, "humidity": "41", "temp_f": "78", "pressure": "1012.61", "AGE": 1, "Stats": "{\"v\":1365.48,\"v1\":321.89,\"v2\":143.72,\"v3\":94.66,\"v4\":48.01,\"v5\":35.84,\"v6\":31.53,\"pm\":1365.48,\"lastModified\":1602126725789,\"timeSinceModified\":120012}" }, { "ID": 38608, "ParentID": 38607, "Label": "Hopi (Street) B", "THINGSPEAK_PRIMARY_ID": "855228", "THINGSPEAK_PRIMARY_ID_READ_KEY": "P5R421CYT6X3JN8L", "THINGSPEAK_SECONDARY_ID": "855230", "THINGSPEAK_SECONDARY_ID_READ_KEY": "9K0NZFANA8SU3CW6", "Lat": 37.390649, "Lon": -122.079714, "PM2_5Value": "32.67", "LastSeen": 1602189246, "Hidden": "false", "Created": 1567096527, "p_0_3_um": "3252.21", "p_0_5_um": "961.4", "p_1_0_um": "258.47", "p_2_5_um": "29.02", "p_5_0_um": "2.4", "p_10_0_um": "0.5", "pm1_0_cf_1": "17.64", "pm2_5_cf_1": "34.79", "pm10_0_cf_1": "36.31", "pm1_0_atm": "17.64", "pm2_5_atm": "32.67", "pm10_0_atm": "36.31", "isOwner": 0, "AGE": 1, "Stats": "{\"v\":32.67,\"v1\":31.63,\"v2\":33.05,\"v3\":34.83,\"v4\":39.41,\"v5\":36.36,\"v6\":32.8,\"pm\":32.67,\"lastModified\":1602189246334,\"timeSinceModified\":120368}" } ] }

PurpleAirDegradedSensors

dclaar commented 3 years ago

It's not actually true that it only uses A. As you can see in your result above, this is a 2 element array. The app calculates as:

    self.pm2_5_atm = (float(data_a['pm2_5_atm']) + float(data_b['pm2_5_atm']))/2

So it has:

"Compare and contrast"

Looking at mine, the only difference is that yours has "Flag": 1, in the first array entry. I'm guessing that means "I'm bad, I'm bad, you know it" (Sorry, Michael Jackson!)

I've asked in the FB group if my suspicion is correct, and I've got some code ready if it is true.

For a workaround, you could just change the lines in WebAQI.py to only look at B for now.

danswett commented 3 years ago

I stand corrected! Thanks!

On Thu, Oct 8, 2020 at 9:09 PM Doug Claar notifications@github.com wrote:

It's not actually true that it only uses A. As you can see in your result above, this is a 2 element array. The app calculates as:

self.pm2_5_atm = (float(data_a['pm2_5_atm']) + float(data_b['pm2_5_atm']))/2

So it has:

  • "pm2_5_atm": "3333.12",
  • "pm2_5_atm": "32.67", Obviously, the first is going to swamp the second.

"Compare and contrast"

Looking at mine, the only difference is that yours has "Flag": 1, in the first array entry. I'm guessing that means "I'm bad, I'm bad, you know it" (Sorry, Michael Jackson!)

I've asked in the FB group if my suspicion is correct, and I've got some code ready if it is true.

For a workaround, you could just change the lines in WebAQI.py to only look at B for now.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/dclaar/purple_air/issues/10#issuecomment-705956457, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA4JWNNVMU6HKT6FMFUDADDSJ2EIPANCNFSM4SJH4J6A .

dclaar commented 3 years ago

If someone can tell me what the local interface does when a sensor is bad, I can implement that, but right now I only know about the web interface, so I've fixed that one.

danswett commented 3 years ago

Thanks!

On Sat, Oct 10, 2020 at 10:59 AM Doug Claar notifications@github.com wrote:

If someone can tell me what the local interface does when a sensor is bad, I can implement that, but right now I only know about the web interface, so I've fixed that one.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/dclaar/purple_air/issues/10#issuecomment-706588160, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA4JWNJ2WDUJJVEDBOVPD2LSKCOIZANCNFSM4SJH4J6A .

dclaar commented 3 years ago

Fixed for web. Closed due to lack of information for local interface.