-
-
Save gwthompson/a23aa2bf035609a13df9c948828880d6 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: sun; | |
const STATION_VIBORG = "49" | |
const STATION_CPH = "48" | |
const GRASS_ID = "28" | |
const PREVIEW_WIDGET = false | |
// Pass your station ID here. See the constants above. | |
let pollen = await loadPollen(STATION_VIBORG) | |
if (config.runsInWidget) { | |
let widget = createWidget(GRASS_ID, pollen) | |
Script.setWidget(widget) | |
Script.complete() | |
} else if (config.runsWithSiri) { | |
let table = createTable(pollen) | |
table.present() | |
speakPollen(GRASS_ID, pollen) | |
Script.complete() | |
} else if (PREVIEW_WIDGET) { | |
let widget = createWidget(GRASS_ID, pollen) | |
await widget.presentSmall() | |
} else { | |
let table = createTable(pollen) | |
await table.present() | |
} | |
function createWidget(id, pollen) { | |
let name = pollenNameFromId(id) | |
let value = pollen.find(v => { | |
return v.id == GRASS_ID | |
}) | |
let gradient = new LinearGradient() | |
gradient.colors = [ | |
new Color("#26765c"), | |
new Color("#288c65") | |
] | |
gradient.locations = [0, 1] | |
let widget = new ListWidget() | |
widget.spacing = 5 | |
widget.backgroundGradient = gradient | |
let title = widget.addText("Pollen") | |
title.textColor = Color.white() | |
title.font = Font.headline() | |
if (value.inSeason && value.level > -1) { | |
let levelStr = value.level.toString() | |
let level = widget.addText(levelStr) | |
level.textColor = Color.white() | |
level.textSize = 40 | |
} | |
let emoji = widget.addText(value.levelEmoji) | |
emoji.font = Font.systemFont(32) | |
let desc = widget.addText(value.description) | |
desc.textColor = Color.white() | |
desc.textOpacity = 0.5 | |
return widget | |
} | |
function speakPollen(id, pollen) { | |
let name = pollenNameFromId(id) | |
let value = pollen.find(v => { | |
return v.id == GRASS_ID | |
}) | |
let str = null | |
if (value.inSeason) { | |
str = "The pollen count for " | |
+ name.toLocaleLowerCase() | |
+ " is " | |
+ value["level"] | |
+ "." | |
} else { | |
str = 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.level.toString()) | |
} 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(station) { | |
let values = await loadValues(station) | |
return valuesToPollen(values) | |
} | |
async function loadValues(station) { | |
let cookies = await loadCookies() | |
let jsessionId = findCookie("JSESSIONID", cookies) | |
let url = "https://www.pollental.dk/home" | |
+ "?p_p_id=pollenbox_WAR_pollenportlet" | |
+ "&p_p_lifecycle=2" | |
+ "&p_p_state=normal" | |
+ "&p_p_mode=view" | |
+ "&p_p_resource_id=getFeed" | |
+ "&p_p_cacheability=cacheLevelPage" | |
+ "&p_p_col_id=column-1&p_p_col_pos=1" | |
+ "&p_p_col_count=2" | |
+ "&s=" + jsessionId | |
+ "&station=" + station | |
let req = new Request(url) | |
req.headers = { | |
"Cookie": "JSESSIONID=" + jsessionId | |
} | |
return await req.loadJSON() | |
} | |
async function loadCookies() { | |
let url = "https://www.pollental.dk" | |
let req = new Request(url) | |
await req.load() | |
return req.response.cookies | |
} | |
function findCookie(name, cookies) { | |
let jsession = cookies.find(c => { | |
return c.name == name | |
}) | |
return jsession.value | |
} | |
function valuesToPollen(values) { | |
let feed = values.feed | |
let keys = Object.keys(feed) | |
let result = [] | |
for (id of keys) { | |
let value = feed[id] | |
let mapped = mapValue(value) | |
mapped.id = id | |
mapped.name = pollenNameFromId(id) | |
result.push(mapped) | |
} | |
return result | |
} | |
function mapValue(value) { | |
return { | |
level: value.level, | |
levelEmoji: getLevelEmoji(value), | |
inSeason: value.inSeason, | |
description: getValueDescription(value) | |
} | |
} | |
function getValueDescription(value) { | |
let desc = value.levelDescription | |
if (!value.inSeason) { | |
return "Not in season" | |
} else if (desc == "3") { | |
return "High" | |
} else if (desc == "2") { | |
return "Medium" | |
} else if (desc == "1") { | |
return "Low" | |
} else { | |
return null | |
} | |
} | |
function getLevelEmoji(value) { | |
if (value.inSeason) { | |
let desc = value.levelDescription | |
if (desc == "1") { | |
return "🟡" | |
} else if (desc == "2") { | |
return "🟠" | |
} else if (desc == "3") { | |
return "🚨" | |
} else { | |
return "💚" | |
} | |
} else { | |
return "💚" | |
} | |
} | |
function pollenNameFromId(id) { | |
if (id == "7") { | |
return "Birch" | |
} else if (id == "31") { | |
return "Mugwort" | |
} else if (id == "1") { | |
return "Alder" | |
} else if (id == "4") { | |
return "Elm" | |
} else if (id == "28") { | |
return "Grass" | |
} else if (id == "2") { | |
return "Hazel" | |
} else if (id == "44") { | |
return "Alternaria" | |
} else if (id == "45") { | |
return "Cladosporium" | |
} else { | |
return id | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment