Last active
July 17, 2022 17:35
-
-
Save simonbs/50d02fa42984c77075e4e1b00897b7de to your computer and use it in GitHub Desktop.
Shows the current pollen counts. Pulls data from a Danish provider and only works in Denmark.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Variables used by Scriptable. | |
// These must be at the very top of the file. Do not edit. | |
// icon-color: deep-green; icon-glyph: tree; | |
const STATION_VIBORG = "49" | |
const STATION_CPH = "48" | |
const IDS = { | |
BIRCH: "7", | |
MUGWORT: "31", | |
ALDER: "1", | |
ELM: "4", | |
GRASS: "28", | |
HAZEL: "2", | |
ALTERNARIA: "44", | |
CLADOSPORIUM: "45" | |
} | |
const PREVIEW_REGULAR_WIDGET = false | |
const PREVIEW_CIRCULAR_WIDGET = false | |
const PREVIEW_RECTANGULAR_WIDGET = false | |
// Pass your station ID here. See the constants above. | |
let pollen = await loadPollen(STATION_CPH) | |
let grassValue = pollen.find(e => e.id == IDS.GRASS) | |
let birchValue = pollen.find(e => e.id == IDS.BIRCH) | |
let elmValue = pollen.find(e => e.id == IDS.ELM) | |
if (config.runsInWidget) { | |
let widget = null | |
if (config.widgetFamily == "accessoryCircular") { | |
widget = createCircularWidget(grassValue) | |
} else if (config.widgetFamily == "accessoryRectangular") { | |
widget = createRectangularWidget([grassValue, birchValue]) | |
} else if (config.widgetFamily == "accessoryInline") { | |
widget = createInlineWidget(grassValue) | |
} else if (config.widgetFamily == "small") { | |
widget = createWidget([grassValue]) | |
} else { | |
widget = createWidget([grassValue, birchValue, elmValue]) | |
} | |
Script.setWidget(widget) | |
Script.complete() | |
} else if (config.runsWithSiri) { | |
let table = createTable(pollen) | |
table.present() | |
speakPollen(grassValue) | |
Script.complete() | |
} else if (PREVIEW_REGULAR_WIDGET) { | |
let widget = createWidget(grassValue) | |
await widget.presentSmall() | |
} else if (PREVIEW_CIRCULAR_WIDGET) { | |
let widget = createCircularWidget(grassValue) | |
await widget.presentSmall() | |
} else if (PREVIEW_RECTANGULAR_WIDGET) { | |
let widget = createRectangularWidget(grassValue) | |
await widget.presentSmall() | |
} else { | |
let table = createTable(pollen) | |
await table.present() | |
} | |
function createCircularWidget(value) { | |
let widget = new ListWidget() | |
widget.addAccessoryWidgetBackground = true | |
let wname = widget.addText(value.name) | |
let wlevel = widget.addText(value.stringLevel) | |
wname.font = Font.caption1() | |
wlevel.font = Font.title1() | |
wlevel.minimumScaleFactor = 0.2 | |
wname.centerAlignText() | |
wlevel.centerAlignText() | |
return widget | |
} | |
function createRectangularWidget(values) { | |
let widget = new ListWidget() | |
let innerStack = widget.addStack() | |
innerStack.layoutHorizontally() | |
innerStack.spacing = 20 | |
for (value of values) { | |
let valueStack = innerStack.addStack() | |
valueStack.layoutVertically() | |
let wname = valueStack.addText(value.name) | |
wname.font = Font.headline() | |
if (value.level > -1) { | |
let wlevel = valueStack.addText(value.stringLevel) | |
wlevel.font = Font.body() | |
} | |
if (value.description != null && value.description.length > 0) { | |
let wdesc = valueStack.addText(value.description) | |
wdesc.font = Font.body() | |
wdesc.textOpacity = 0.75 | |
} | |
} | |
return widget | |
} | |
function createInlineWidget(value) { | |
let text = value.name + ": " + value.stringLevel | |
if (value.description != null && value.description.length > 0) { | |
text += " (" + value.description + ")" | |
} | |
let widget = new ListWidget() | |
let wtext = widget.addText(text) | |
wtext.minimumScaleFactor = 0.2 | |
return widget | |
} | |
function createWidget(values) { | |
let gradient = new LinearGradient() | |
gradient.colors = [ | |
new Color("#26765c"), | |
new Color("#288c65") | |
] | |
gradient.locations = [0, 1] | |
let widget = new ListWidget() | |
widget.backgroundGradient = gradient | |
let innerStack = widget.addStack() | |
innerStack.spacing = 30 | |
for (value of values) { | |
let valueStack = innerStack.addStack() | |
valueStack.layoutVertically() | |
valueStack.spacing = 5 | |
let title = valueStack.addText(value.name) | |
title.textColor = Color.white() | |
title.font = Font.title2() | |
if (value.inSeason && value.level > -1) { | |
let levelStr = value.level.toString() | |
let level = valueStack.addText(levelStr) | |
level.font = Font.headline() | |
level.textColor = Color.white() | |
level.textSize = 40 | |
} | |
if (value.description != null && value.description.length > 0) { | |
let desc = valueStack.addText(value.description) | |
desc.font = Font.body() | |
desc.textColor = Color.white() | |
desc.textOpacity = 0.5 | |
} | |
} | |
innerStack.addSpacer() | |
return widget | |
} | |
function speakPollen(value) { | |
let str = null | |
if (value.inSeason) { | |
str = "The pollen count for " | |
+ value.name.toLocaleLowerCase() | |
+ " is " | |
+ value.stringLevel | |
+ "." | |
} else { | |
str = value.name + " is not in season." | |
} | |
Speech.speak(str) | |
Script.setShortcutOutput(str) | |
} | |
function createTable(pollen) { | |
let table = new UITable() | |
table.showSeparators = true | |
for (value of pollen) { | |
let row = createTableRow(value) | |
table.addRow(row) | |
} | |
return table | |
} | |
function createTableRow(value) { | |
let row = new UITableRow() | |
row.height = 60 | |
let nameCell | |
if (value.inSeason && value.level > -1) { | |
nameCell = row.addText(value.name, value.stringLevel) | |
} else { | |
nameCell = row.addText(value.name) | |
} | |
let descCell = row.addText(value.description) | |
let emojiCell = row.addText(value.levelEmoji) | |
nameCell.widthWeight = 40 | |
descCell.widthWeight = 45 | |
emojiCell.widthWeight = 15 | |
descCell.rightAligned() | |
emojiCell.rightAligned() | |
return row | |
} | |
async function loadPollen(stationId) { | |
let url = "https://www.astma-allergi.dk/umbraco/Api/PollenApi/GetPollenFeed" | |
let request = new Request(url) | |
let str = await request.loadString() | |
let parsedStr = JSON.parse(str) | |
let json = JSON.parse(parsedStr) | |
let stationData = json.fields[stationId] | |
let data = stationData.mapValue.fields.data.mapValue.fields | |
return getDisplayValues(data) | |
} | |
function getDisplayValues(data) { | |
let keys = Object.keys(data) | |
let result = [] | |
for (id of keys) { | |
let value = data[id].mapValue.fields | |
let displayValue = getDisplayValue(id, value) | |
result.push(displayValue) | |
} | |
return result | |
} | |
function getDisplayValue(id, value) { | |
let level = -1 | |
if (value.level != null) { | |
level = value.level.integerValue | |
} | |
return { | |
id: id, | |
name: pollenNameFromId(id), | |
level: level, | |
stringLevel: level.toString(), | |
levelEmoji: getLevelEmoji(value), | |
inSeason: value.inSeason.booleanValue, | |
description: getLevelDescription(value) | |
} | |
} | |
function getLevelDescription(value) { | |
let level = value.level.integerValue | |
if (!value.inSeason.booleanValue) { | |
return "Not in season" | |
} else if (level > 50) { | |
return "High" | |
} else if (level > 10) { | |
return "Medium" | |
} else if (level > 0) { | |
return "Low" | |
} else { | |
return null | |
} | |
} | |
function getLevelEmoji(value) { | |
if (value.inSeason) { | |
let level = value.level | |
if (level > 50) { | |
return "π¨" | |
} else if (level > 10) { | |
return "β οΈ" | |
} else if (level > 0) { | |
return "π" | |
} else { | |
return "π" | |
} | |
} else { | |
return "π" | |
} | |
} | |
function pollenNameFromId(id) { | |
if (id == IDS.BIRCH) { | |
return "Birch" | |
} else if (id == IDS.MUGWORT) { | |
return "Mugwort" | |
} else if (id == IDS.ALDER) { | |
return "Alder" | |
} else if (id == IDS.ELM) { | |
return "Elm" | |
} else if (id == IDS.GRASS) { | |
return "Grass" | |
} else if (id == IDS.HAZEL) { | |
return "Hazel" | |
} else if (id == IDS.ALTERNARIA) { | |
return "Alternaria" | |
} else if (id == IDS.CLADOSPORIUM) { | |
return "Cladosporium" | |
} else { | |
return id | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment