Skip to content

Instantly share code, notes, and snippets.

@grahamb
Forked from jasonsnell/purpleaqijsnell.js
Last active September 18, 2020 20:34
Show Gist options
  • Save grahamb/84a0e4d2c1978faa3658dbc9d865eb68 to your computer and use it in GitHub Desktop.
Save grahamb/84a0e4d2c1978faa3658dbc9d865eb68 to your computer and use it in GitHub Desktop.
AQI Widget Code
// Displays Air Quality Index based on station data from
// aqicn.org
//
// Requires an API token: https://aqicn.org/data-platform/token/#/
//
// Configuration: configure the widget "Parameter" with a query string
// containing the station name and API token, e.g:
// station=Burnaby North Eton, British Comlumbia, Canada&token=12345
//
// based on widget code by Jason Snell <jsnell@sixcolors.com>
// https://gist.github.com/jasonsnell/4b458e2775e11ff7dd8b21dd26aa504e
// based on code by Matt Silverlock
// gradient routine contributed by Rob Silverii
const API_URL = "https://api.waqi.info/feed";
const qs = (s) =>
JSON.parse(
'{"' +
decodeURI(s)
.replace(/"/g, '\\"')
.replace(/&/g, '","')
.replace(/=/g, '":"') +
'"}'
);
async function getSensorData() {
const params =
(args && args.widgetParameter) || "station=shanghai&token=demo";
const { token, station } = qs(params);
console.log({ token, station });
const url = `${API_URL}/${escape(station)}/?token=${token}`;
let req = new Request(url);
let json = await req.loadJSON();
return json.data;
}
// Widget attributes: AQI level threshold, text label, gradient start and end colors, text color
const levelAttributes = [
{
threshold: 300,
label: "Hazardous",
startColor: "9e2043",
endColor: "7e0023",
textColor: "ffffff",
},
{
threshold: 200,
label: "Very Unhealthy",
startColor: "8f3f97",
endColor: "6f1f77",
textColor: "ffffff",
},
{
threshold: 150,
label: "Unhealthy",
startColor: "FF3D3D",
endColor: "D60000",
textColor: "ffffff",
},
{
threshold: 100,
label: "Unhealthy (S.G.)",
startColor: "FFA63D",
endColor: "D67200",
textColor: "000000",
},
{
threshold: 50,
label: "Moderate",
startColor: "ffff00",
endColor: "cccc00",
textColor: "000000",
},
{
threshold: 0,
label: "Good",
startColor: "00e400",
endColor: "00bb00",
textColor: "000000",
},
];
// Get level attributes for AQI
const getLevelAttributes = (level, attributes) =>
attributes
.filter((c) => level > c.threshold)
.sort((a, b) => b.threshold - a.threshold)[0];
function calculateLevel(aqi) {
let res = {
level: "OK",
label: "fine",
startColor: "white",
endColor: "white",
};
let level = parseInt(aqi, 10) || 0;
// Set attributes
res = getLevelAttributes(level, levelAttributes);
// Set level
res.level = level;
return res;
}
async function run() {
let wg = new ListWidget();
wg.setPadding(20, 15, 10, 10);
try {
let data = await getSensorData();
const { aqi } = data;
let level = calculateLevel(aqi);
let aqitext = aqi.toString();
let startColor = new Color(level.startColor);
let endColor = new Color(level.endColor);
let gradient = new LinearGradient();
gradient.colors = [startColor, endColor];
gradient.locations = [0.0, 1];
wg.backgroundGradient = gradient;
let header = wg.addText("Air Quality");
header.textColor = new Color(level.textColor);
header.font = Font.regularSystemFont(15);
let content = wg.addText(aqitext);
content.textSize = 45;
content.textColor = new Color(level.textColor);
content.font = Font.semiboldRoundedSystemFont(45);
let wordLevel = wg.addText(level.label);
wordLevel.textColor = new Color(level.textColor);
wordLevel.font = Font.boldSystemFont(15);
let spacerOne = wg.addSpacer(10);
let id = wg.addText(data.city.name);
id.textColor = new Color(level.textColor);
id.font = Font.mediumSystemFont(12);
let updatedAt = data.time.s;
let ts = wg.addText(`Updated ${updatedAt}`);
ts.textColor = new Color(level.textColor);
ts.font = Font.lightSystemFont(10);
let spacerTop = wg.addSpacer();
wg.url = data.city.url;
} catch (e) {
console.log(e);
let err = wg.addText(`error: ${e}`);
err.textSize = 10;
err.textColor = Color.red();
err.textOpacity = 30;
}
wg.presentSmall();
Script.setWidget(wg);
Script.complete();
}
await run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment