Charges for PurpleAir API calls

Confirmed. And the same for PWS_Dashboard calls.

Maybe we don’t need every item in the json?

I will check if there is a new API.
The one we are now using in PWS_Dashboard has no selection of items.

https://api.purpleair.com/v1/sensors/7302?api_key=_API_SETTING_

Description:

https://api.purpleair.com/#api-sensors-get-sensor-data

We use only 13 fields from the API.
Current PM10 and PM25
PM25 history 10 minutes, 30 minutes, 60 minutes, 6 hour, 24 hour 1 week
Temperature, humidity, last_seen, time_stamp

Data returned with the currently used API

    [api_version] => V1.0.11-0.0.49
    [time_stamp] => 1693766314
    [data_time_stamp] => 1693766282
    [sensor] => Array
        (
            [sensor_index] => 7302
            [last_modified] => 1601193766
            [date_created] => 1517976119
            [last_seen] => 1693766222
            [private] => 0
            [is_owner] => 0
            [name] => Sluispark Leuven
            [icon] => 0
            [location_type] => 0
            [model] => PA-II-SD
            [hardware] => 2.0+OPENLOG+NO-DISK+DS3231+BME280+PMSX003-B+PMSX003-A
            [led_brightness] => 35
            [firmware_version] => 7.02
            [rssi] => -34
            [uptime] => 28204
            [pa_latency] => 246
            [memory] => 16184
            [position_rating] => 5
            [latitude] => 50.886353
            [longitude] => 4.700279
            [altitude] => 56
            [channel_state] => 3
            [channel_flags] => 0
            [channel_flags_manual] => 0
            [channel_flags_auto] => 0
            [confidence] => 100
            [confidence_auto] => 100
            [confidence_manual] => 100
            [humidity] => 47
            [humidity_a] => 47
            [temperature] => 81
            [temperature_a] => 81
            [pressure] => 1022.75
            [pressure_a] => 1022.75
            [analog_input] => 0.03
            [pm1.0] => 8.7
            [pm1.0_a] => 9.1
            [pm1.0_b] => 8.4
            [pm2.5] => 11.5
            [pm2.5_a] => 12
            [pm2.5_b] => 11.1
            [pm2.5_alt] => 6.7
            [pm2.5_alt_a] => 7
            [pm2.5_alt_b] => 6.5
            [pm10.0] => 12.3
            [pm10.0_a] => 12.7
            [pm10.0_b] => 12
            [scattering_coefficient] => 26.2
            [scattering_coefficient_a] => 27
            [scattering_coefficient_b] => 25.3
            [deciviews] => 14.2
            [deciviews_a] => 14.5
            [deciviews_b] => 13.9
            [visual_range] => 94.3
            [visual_range_a] => 91.9
            [visual_range_b] => 96.7
            [0.3_um_count] => 1744
            [0.3_um_count_a] => 1803
            [0.3_um_count_b] => 1686
            [0.5_um_count] => 482
            [0.5_um_count_a] => 495
            [0.5_um_count_b] => 469
            [1.0_um_count] => 55
            [1.0_um_count_a] => 58
            [1.0_um_count_b] => 52
            [2.5_um_count] => 3
            [2.5_um_count_a] => 4
            [2.5_um_count_b] => 3
            [5.0_um_count] => 0
            [5.0_um_count_a] => 0
            [5.0_um_count_b] => 1
            [10.0_um_count] => 0
            [10.0_um_count_a] => 0
            [10.0_um_count_b] => 0
            [pm1.0_cf_1] => 8.7
            [pm1.0_cf_1_a] => 9.07
            [pm1.0_cf_1_b] => 8.4
            [pm1.0_atm] => 8.7
            [pm1.0_atm_a] => 9.07
            [pm1.0_atm_b] => 8.4
            [pm2.5_atm] => 11.5
            [pm2.5_atm_a] => 11.98
            [pm2.5_atm_b] => 11.07
            [pm2.5_cf_1] => 11.5
            [pm2.5_cf_1_a] => 11.98
            [pm2.5_cf_1_b] => 11.07
            [pm10.0_atm] => 12.3
            [pm10.0_atm_a] => 12.69
            [pm10.0_atm_b] => 11.95
            [pm10.0_cf_1] => 12.3
            [pm10.0_cf_1_a] => 12.69
            [pm10.0_cf_1_b] => 11.95
            [primary_id_a] => 421366
            [primary_key_a] => MJSX2FP5VSVTYZ6D
            [primary_id_b] => 421368
            [primary_key_b] => N0GGM3BU4MAHOSD8
            [secondary_id_a] => 421367
            [secondary_key_a] => NA24TOW2IOOIOWCN
            [secondary_id_b] => 421369
            [secondary_key_b] => A3FP2L1W92BH5PDZ
            [stats] => Array
                (
                    [pm2.5] => 11.5
                    [pm2.5_10minute] => 11.2
                    [pm2.5_30minute] => 10.5
                    [pm2.5_60minute] => 11.1
                    [pm2.5_6hour] => 21.1
                    [pm2.5_24hour] => 13.6
                    [pm2.5_1week] => 4.4
                    [time_stamp] => 1693766222
                )

            [stats_a] => Array
                (
                    [pm2.5] => 12
                    [pm2.5_10minute] => 11.5
                    [pm2.5_30minute] => 10.8
                    [pm2.5_60minute] => 11.4
                    [pm2.5_6hour] => 21.4
                    [pm2.5_24hour] => 13.9
                    [pm2.5_1week] => 4.7
                    [time_stamp] => 1693766222
                )

            [stats_b] => Array
                (
                    [pm2.5] => 11.1
                    [pm2.5_10minute] => 10.9
                    [pm2.5_30minute] => 10.2
                    [pm2.5_60minute] => 10.8
                    [pm2.5_6hour] => 20.8
                    [pm2.5_24hour] => 13.4
                    [pm2.5_1week] => 4.2
                    [time_stamp] => 1693766222
                )

        )

)

Wim

I think you just have to specify each individual field that you need in the “Fields” parameter?

PurpleAir Develop

and

API Use Guidelines - Data / API - PurpleAir Community

Yes, I saw that when I trying to find all new information.

I also have to test if the old API-keys (which we acquired by sensing an email), will continue to work when using the list of fields. Would be a pity to have to start paying if we switch to this new API-“description”.

In the past there was no list of available fields. And certainly no selection of fields.
You got all fields available, and that was far less than what is available now.

The number of fields needed could be less than 20.
Question 1:
What would be the “bill” for on year loading those 20 fields every 120 seconds?
If that is to costly:
Question 2:
What is the acceptable age of the sensor data? 5 minutes or maybe 30 minutes maximum ?

Wim

I agree - but it is probably only a matter of time before they get you too :slightly_frowning_face:

I’ll have to do some sums. . .

Official sites at aqicn are updated every hour, but it does seems a pity if you can’t get your own data in less time than that. . .

I have mine set to 30 mins.

Because a lot of users have “free” APIs you may have to consider writing a new API call for those of us who are being charged. Does that make sense?

First test:

https://api.purpleair.com/v1/sensors/7302?api_key=_API_SETTING_,&fields=latitude,longitude,last_seen,pm2.5,pm2.5_10minute,pm2.5_30minute,pm2.5_60minute,pm2.5_6hour,pm2.5_24hour,pm2.5_1week,pm10.0_atm_a,pm10.0_atm_a,pm10.0_atm_b,sensor_index,name

The “OLD” API-key can not be used for the “new” API.
No usable data is returned

api_version	"V1.0.11-0.0.49"
time_stamp	1693769196
error	"ApiKeyInvalidError"
description	"The provided api_key was not valid."

Without the list of fields the complete data is retuned.

https://api.purpleair.com/v1/sensors/7302?api_key=_API_SETTING_

Can someone use the “First test” link and capture the json-data ?
I can adapt the script as soon as i have the json file to test with.

I think about making a MITM script to capture the new data and format as if was the old data.

Wim

{
    "api_version": "V1.0.11-0.0.49",
    "time_stamp": 1693773032,
    "data_time_stamp": 1693773011,
    "sensor": {
        "sensor_index": 190464,
        "last_seen": 1693772937,
        "name": "Fairmilehead",
        "latitude": 55.89852,
        "longitude": -3.208202,
        "pm2.5": 3.8,
        "pm10.0_atm_a": 3.8,
        "pm10.0_atm_b": 3.7,
        "stats": {
            "pm2.5": 3.8,
            "pm2.5_10minute": 3.3,
            "pm2.5_30minute": 2.9,
            "pm2.5_60minute": 2.5,
            "pm2.5_6hour": 4.6,
            "pm2.5_24hour": 4.7,
            "pm2.5_1week": 2.8,
            "time_stamp": 1693772937
        }
    }
}

We don’t need “name”, “latitude” or “longitude” - do we?

LATER EDIT: That call seems to have cost 21 points compared to 155 for the full API :slightly_smiling_face:

EVEN LATER EDIT: Hope Ken’s watching this topic :wink:

Yes we do. Also temperature and humidity are used in the blocks/pop-up

Attached a zip of: PWS_load_files.php|09|2023-09-04|
Only for users with a new PurpleAir sensor who nowadays can get a paid-for API only.

We use 12 points for every data load.

Currently the script loads the data every 100 → 120 seconds when a user / browser window is active
The cron-job is normally executed every 600 seconds.

Worst case (24 hours multiple open browser-windows) the 1.000.000 free points run out after 115 days. In real life the free poionts should last a few years.

One could change the line 347 from

    $allowed_age    = $purpleRefresh*$times;

to a lesser use, f.i. every 10 minutes

   $allowed_age    = 5 * $purpleRefresh*$times;

Then the free/bought points will last multiple years for sure.

Please test this version and post your remarks.

Succes,
Wim

PWS_load_files.php.zip (7.7 KB)

Could you have two types of API calls? An initial one that gets a full set of data including name, latitude and longitude which are then stored. Subsequent calls don’t fetch those values which presumably will rarely, if ever, change. That would be a 25% saving on points for most calls.

But I have to change 3 scripts which retrieve the data in that case.
And write a “HowTo” description

But AFAICS the general fields are not charged.
Only the sensor fields.
I think I get 12 points charged for 1 download of 22 items which has 12 sensor data and 10 general fields
I need more testing as i tried many different API-calls

Wim

{ "api_version" : "V1.0.11-0.0.49",
  "time_stamp" : 1693811013,
  "data_time_stamp" : 1693810991,
  "sensor" : {
    "sensor_index" : 7302,
    "last_seen" : 1693810991,
    "name" : "Sluispark Leuven",
    "latitude" : 50.886353,
    "longitude" : 4.700279,
    "humidity" : 62,
    "temperature" : 69,
    "pm2.5" : 35.7,
    "pm10.0_atm_a" : 42.85,
    "pm10.0_atm_b" : 41.82,
    "stats" : { "pm2.5" : 35.7, 
                "pm2.5_10minute" : 36.2, 
                "pm2.5_30minute" : 35.2, 
                "pm2.5_60minute" : 33.8, 
                "pm2.5_6hour" : 25.4, 
                "pm2.5_24hour" : 16.5, 
                "pm2.5_1week" : 5.2, 
                "time_stamp" : 1693810991}
  }
}

Ahhh I assumed all fields were charged for based on @bitsostring’s comment about not requesting those values.

I will do more testing tomorrow as todays figures are a mess. :unamused:

Latest tests show 25 points for the API-call, sadly all fields are counted.

users who were so unlucky to recently buy a PurpleAir sensor better set the $purpleRefresh in line 50 of PWS_settings to 300.
The data will be refreshed every 5 minutes by the cron-job.
That will lower the daily points used to 25 (points) * 24 (hours) * 12 (cron) = 7.200 points / day
The free and 10$ points will last 138 days.

If you consider buying a PurpleAir sensor you have to spent another 30$ yearly to have your AQ measurements on your website.

Consider other AQ sensors which still allow to retrieve ones own data for free from the sellers network .

Wim

They are - see PurpleAir Develop

At least name, lat and long are. . . not sensor_index

And temp and humidity are a joke, they are only measured to monitor the sensor temp. Baro looks OK, though :wink:

EDIT: See PurpleAir Sensors Functional Overview - Sensors - PurpleAir Community

They would have to double my humidity readings, and then some. . . I have removed them from my popup.

Thanks, Wim, seems to be working fine :slightly_smiling_face:

$purpleRefresh currently set at 600 (I don’t use the cron), and I’ve got down to 18 points per call by deleting name, lat, long, temp and hum (temp/hum worth 2 points each!). So that should give me (worst case) 18 * 24 * 6 = 2,592 points/day → 386 days/million points. In practice my dashboard is only running for about 15 hours/day :wink:

I’ve “hard-wired” name, lat and long into AQ_purpleair_c_block.php

Gaia A12 on order :smile:

Will that API be free?

Probably not for a long time.

PurpleAir API
In the past PurpleAir had a very simple free API without a key
They changed to one with a free key as larger players downloaded the data of all stations.
Now they charge new “customers” to get their own data.
And probably to old customers also in the near? future

PurpleAir CustomUpload
PurpleAir had/has code in its sensor to upload to your own website, similar to Ecowitt.
Although the “register page” still allows to enter credentials, it does not work in the past years. At least for my two PurpleAir sensors and for a dozen Leuven script users.

Luftdaten API
Still free. They use donations

Luftdaten CustomUpload
Not functional anymore but as long as we can download for free, nobody uses that custom-upload.

WL.com is free but limited functionality compared to the paid-for version

Ecowitt Allows custom upload and free API access to ecowitt.net

GAIA A12 ??? This time they promise a good API and maybe a local access.

Most sensors can be accessed for their data from the local network.
PurpleAir IP/json
Luftdaten IP/data.json
WL-AirLink IP/v1/current_conditions
But to get the data to the user-website can be a tedious task, so use a 24/7 weather-program for that.


I think that other AQ, lightning a.s.o. sensor-manufacturers will follow the same path as PurpleAir.
There is no money in offering a free website and allow others to download the data for free.

Similar to what we have seen with WeatherUnderground, but WU gives us a free API with a decent daily allowance plus a free weather-forecast.

PurpleAir is the first one I know of to ask money after you bought an expensive device
They not even allow our sensor we fully paid for, to upload the sensor-data to another website

I attach the setup for PurpleAir.
Maybe the newer PurpleAir-sensors can do the custom upload again.

Wim

Same as mine, except I allowed upload to WU ( OEDINB1).

I doubt if they will allow a custom upload. . . :slightly_frowning_face:

The PurpleAir business model and how they treat contributors is truly pathetic…

1 Like

Agreed, is there a way for us to stop sending them data and just keep it to ourselves?

I use meteobridge to add the aqi to my webcam, maybe thats a way around it?

(The AQ is updated every 2 mins on my webcam)

UPDATE: Happily working away using about 90 calls, 1620 points/day → 617 days/million points.

2 posts were split to a new topic: Warning to ALL PurpleAir users