Skip to content

Instantly share code, notes, and snippets.

@simonbs
Last active July 17, 2022 17:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save simonbs/50d02fa42984c77075e4e1b00897b7de to your computer and use it in GitHub Desktop.
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.
// 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