Skip to content

Instantly share code, notes, and snippets.

@krosenberg
Last active October 12, 2020 21:39
Show Gist options
  • Save krosenberg/ec8c7d012a7bde173431b04d490579ed to your computer and use it in GitHub Desktop.
Save krosenberg/ec8c7d012a7bde173431b04d490579ed to your computer and use it in GitHub Desktop.
Scriptable AQI widget
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: deep-green; icon-glyph: tree;
// change to the station id closest to you. station id can be found in the purple air url when you click on a sensor circle
// e.g. https://www.purpleair.com/map?opt=1/i/mAQI/a10/cC0&select=21057
const purpleAirStationID = 21057
let items = await loadItems()
let widget = await createWidget(items)
// Check if the script is running in
// a widget. If not, show a preview of
// the widget to easier debug it.
if (!config.runsInWidget) {
await widget.presentMedium()
}
// Tell the system to show the widget.
Script.setWidget(widget)
Script.complete()
async function createWidget(result) {
let w = new ListWidget()
let header = w.addText('Berkeley AQI (10 min avg)')
header.font = Font.boldSystemFont(16)
header.textColor = Color.black()
const val = JSON.parse(result.Stats).v1
const aqi = aqiFromPM(val)
w.backgroundColor = Color[getBGColor(aqi)]()
let titleTxt = w.addText(aqi.toString())
titleTxt.font = Font.boldSystemFont(40)
titleTxt.textColor = Color.black()
let date = w.addText(new Date().toLocaleTimeString())
date.font = Font.boldSystemFont(16)
date.textColor = Color.gray()
return w
}
async function loadItems() {
let url = "https://www.purpleair.com/json?show=" + purpleAirStationID
let req = new Request(url)
let json = await req.loadJSON()
return json.results[0]
}
function getBGColor(aqi) {
if (aqi > 200) {
return 'purple'
} else if (aqi > 150) {
return 'red'
} else if (aqi > 100) {
return 'orange'
} else if (aqi > 50) {
return 'yellow'
} else {
return 'green'
}
}
// from https://docs.google.com/document/d/15ijz94dXJ-YAZLi9iZ_RaBwrZ4KtYeCy08goGBwnbCU/edit
function aqiFromPM(pm) {
if (isNaN(pm)) return "-";
if (pm == undefined) return "-";
if (pm < 0) return pm;
if (pm > 1000) return "-";
/*
Good 0 - 50
Moderate 51 - 100
Unhealthy for Sensitive Groups 101 – 150
Unhealthy 151 – 200
Very Unhealthy 201 – 300
Hazardous 301 – 400
Hazardous 401 – 500
*/
if (pm > 350.5) {
return calcAQI(pm, 500, 401, 500, 350.5);
} else if (pm > 250.5) {
return calcAQI(pm, 400, 301, 350.4, 250.5);
} else if (pm > 150.5) {
return calcAQI(pm, 300, 201, 250.4, 150.5);
} else if (pm > 55.5) {
return calcAQI(pm, 200, 151, 150.4, 55.5);
} else if (pm > 35.5) {
return calcAQI(pm, 150, 101, 55.4, 35.5);
} else if (pm > 12.1) {
return calcAQI(pm, 100, 51, 35.4, 12.1);
} else if (pm >= 0) {
return calcAQI(pm, 50, 0, 12, 0);
} else {
return undefined;
}
}
function calcAQI(Cp, Ih, Il, BPh, BPl) {
var a = (Ih - Il);
var b = (BPh - BPl);
var c = (Cp - BPl);
return Math.round((a/b) * c + Il);
}
@owen123t
Copy link

how to find the sensor ID for your location

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment