Download PA generated jpg file

I have just completed cleaning and resetting my 3-year old PA unit. I need to be able to download the PA-generated file [us-epa-pm25-aqi.jpeg] to include it in an HTML display page that I use in my home for an information screen. I am hoping not to have to navigate the entire API setup, just for this one image. Any suggestions? I would need the direct http:// page address, which would presumably contain my key to access that single image. Any help much appreciated. This unit has been fantastic, especially during periods when there is heavy burning in the area.

I could be wrong, but I don’t think there will be a direct http link for that image. It seems to be generated dynamically using highcharts. If I were doing this I would write a small script to log data directly from my sensor and plot it to an image for use on my web page.

Thanks, James. That’s Plan B.
Your reply is much appreciated.


I wrote a Python script today that can do this. Code up on GitHub


Wow! I am blown away.
You’ve done an amazing job on this.

Thank you so much.
I hope it will be useful to others as well.
Now to sharpen my PY skills.

Thank you. I have a few improvements to make today and will update. I recommend using git clone to get the repo that way updates are as easy as a git pull. Happy to help, answer any questions or make changes to suit specific needs.

Well, let me preface this by saying that I’m 87 and only had a vague idea about Python.
I have managed to install your wonderful code and it fits and displays exactly as I wanted.
I should tell you that I have it installed on a Raspi 5.

I’m attaching a screenshot.
The display code I’m using is a Ham Radio Display that I have a modified bit for our local (FL) weather.
Purely an HTML page with live graphics embedded.

At the moment the date on the air quality graph remains the same (today), and the graph values appear not to be plotting correctly, but I am
overjoyed not only that you came thru with this wonderful addition, but that I managed to brute force it to mostly work.
And I am now fully intrigued with Python,

Other than adding the local IP, I did not find any other local value that needed to be changed.

Thanks again.
Made a nice Sunday for me.


(You can see where your graph fits in the scheme. I’m gradually replacing redundant weather info with new data as I find it. - NOTE the Heat Risk graph - 104 hF at the moment)

And here is a sampling of the CSV data found in that file:

Wonderful! The x-axis label range is from the minimum and maximum datetime values in the data. They will look silly until more days are logged. The initial settings in the code will be for logging every two minutes, plotting the graph every four minutes and keeping / plotting up to two weeks of data. All of which can be changed by editing the variables.

I plan to change how often the truncate function is called to reduce data writes. I am also going to add an optional text box on the graph with the current reading.

Did you clone the repo using git? If so you can use git pull to get these changes although any changes you have made will be undone. Come to think of it I can put the user variables into a config file so changes would be preserved. I’ll go ahead and do that.

Did you have to make any other changes that I should make on my end?

No. Other than my IP, I’m staying away from the code until I understand it better.
Yes, I did the git clone.
I like the “current reading” idea.
The range scale is fine, probably.
The actual converted readings do not mirror mine - here’s the jpg from Purple Air this afternoon:

I’m probably away from this for a couple of days, with a business meeting.
Thanks again for everything.


I’ve corrected the readings error you discovered. The issue was that Humidity values from the sensor are raw and need to be corrected in code and the CF1 PM 2.5 value must be used for the EPA calculation.

This version moves user variables to a separate file.

I’ve added some user variables to control plot title and labels

I’ve added the current reading text to the chart. This can be turned on or off in

The code that truncates the logged (and plotted) data to the user specified duration (currently 2 weeks) runs on a user specified interval (currently 24 hours).

James -

You’ve sure been busy.
All loaded fine, and appears to be working as designed.
I may try to tweak it a bit (title, current # display) once I get back into circulation in a couple off weeks.
A great job with this.
Thank you so much.
As I said before, I hope it will be useful to other PA users, as well.



Thank you Dan, I’m continuing to make a few edits. Added an average line and choice of color mode, tweaked the orange and yellow color bands. If you ever have any suggested changes I’m all ears.

Good Morning, James.

After letting this run for a while, I thought I should send you the associated graphs from here.

This is the graph generated by your amazing programming:

And this is the graph which PurpleAir generates over the same timeframe

The generated numbers are generally much lower than the PA figures.

Here is a screen capture of a comparison between generated numbers and PA calculations:

I am not at all versed on the various conversions, so have nothing to offer here.
I so appreciate your work on this.
And hope that if you have a “real life” beyond coding PA charts, that you take the time to enjoy it.
The amount of work you’ve done is amazing.

Thanks for everything.


Hi Dan,

Previously I was applying the US EPA Conversion which is more accurate for wood smoke but not as accurate for some other particulates such as mineral dust. I’ve added a setting for this conversion in and set it to False.

Generally PM 2.5 with the EPA Conversion will be lower than without it. I’ll spend some time testing to see if there are any issues in the code.

And hope that if you have a “real life” beyond coding PA charts, that you take the time to enjoy it.”

haha - I do. I spent most of the day blasting around SoCal in my sports car.


The data I’m logging vs the map data is pretty close.

Yes, the data in your log (and jpg) pretty much mirrors what I’m seeing from PA. Kudos again. I’ll let this run for a week or so (as soon as I can set it up to run virtually so it doesn’t shut down automatically.) Thanks again. Nice bit of coding.

Great to hear. I often run small programs like this on a Raspberry Pi. I run it in a “Screen” session so I can close the terminal window without ending the program.

Dan, I’ve added a user selectable y-axis limit in Initial config value is ‘auto’.

I can’t wait to see it.
A wonderful update.