Skip to content

Instantly share code, notes, and snippets.

@29SimonB
Last active April 22, 2021 17:34
Show Gist options
  • Save 29SimonB/b50f628961c86022873bac51284e7fdb to your computer and use it in GitHub Desktop.
Save 29SimonB/b50f628961c86022873bac51284e7fdb to your computer and use it in GitHub Desktop.
iOS Widget, das ein tägliches Corona Update innerhalb Deutschlands anzeigt (für die scriptable.app)
// Licence: Robert Koch-Institut (RKI), dl-de/by-2-0
// Location sources
async function getLocation() {
try {
if (args.widgetParameter) {
const fixedCoordinates = args.widgetParameter.split(",").map(parseFloat);
return { latitude: fixedCoordinates[0], longitude: fixedCoordinates[1] };
} else {
Location.setAccuracyToThreeKilometers();
return await Location.current();
}
} catch (e) {
return null;
}
}
// Inzidenz sources
const incidenceUrl = (location) =>
`https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/RKI_Landkreisdaten/FeatureServer/0/query?where=1%3D1&outFields=GEN,cases7_per_100k&geometry=${location.longitude.toFixed(
3
)}%2C${location.latitude.toFixed(
3
)}&geometryType=esriGeometryPoint&inSR=4326&spatialRel=esriSpatialRelWithin&returnGeometry=false&outSR=4326&f=json`
const incidenceUrlStates =
`https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/Coronaf%E4lle_in_den_Bundesl%E4ndern/FeatureServer/0/query?where=1%3D1&outFields=cases7_bl_per_100k&returnGeometry=false&outSR=4326&f=json`
async function getIncidenceData() {
try {
const location = await getLocation();
if (location) {
let data = await new Request(incidenceUrl(location)).loadJSON();
const attr = data.features[0].attributes;
return {
value: attr.cases7_per_100k.toFixed(1),
areaName: attr.GEN,
shouldCache: true,
};
} else {
let data = await new Request(incidenceUrlStates).loadJSON();
const incidencePerState = data.features.map(
(f) => f.attributes.cases7_bl_per_100k
);
const averageIncidence =
incidencePerState.reduce((a, b) => a + b) / incidencePerState.length;
return {
value: averageIncidence.toFixed(1),
areaName: "Deutschland",
shouldCache: false,
};
}
} catch (e) {
return null;
}
}
const incidenceData = await getIncidenceData();
// Vaccination sources
const country = "Germany"
const vaccineStatus = `https://api.vaccination-tracker.app/v1/de-vaccinations-current?geo=${country}`
async function getVaccineData() {
let data = await new Request(vaccineStatus).loadJSON();
const attr = data.data[0];
var values = {}
data.data.forEach(row => {
if(row["key"] == "sum") {
values["quote"] = row["quote"];
}
if(row["key"] == "sum" || row["key"] == "delta_vortag") {
values[row["key"]] = row["value"];
}
});
return values;
}
const number = await getVaccineData();
// Cases and deaths sources
const url = `https://coronavirus-19-api.herokuapp.com/countries/${country}`
const req = new Request(url)
const res = await req.loadJSON();
// Recovered sources
const newRecoveredApiUrl =
`https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/RKI_COVID19/FeatureServer/0/query?f=json&where=NeuGenesen%20IN(1%2C%20-1)&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=*&outStatistics=%5B%7B%22statisticType%22%3A%22sum%22%2C%22onStatisticField%22%3A%22AnzahlFall%22%2C%22outStatisticFieldName%22%3A%22value%22%7D%5D&resultType=standard&cacheHint=true`
async function getNewRecoveredData() {
let data = await new Request(newRecoveredApiUrl).loadJSON();
const attr = data.features[0].attributes;
return {
value: attr.value,
areaName: "Deutschland",
shouldCache: false,
};
}
const newRecoveredData = await getNewRecoveredData();
// create and show the widget
let widget = createWidget();
if (!config.runsInWidget) {
await widget.presentMedium();
} else {
Script.setWidget(widget);
}
Script.complete();
function createWidget(items) {
const list = new ListWidget();
// build the widget step by step
let header, label;
let stack = list.addStack()
stack.layoutVertically()
let stack1 = stack.addStack()
stack1.layoutHorizontally()
stack.addSpacer()
let stack2 = stack.addStack()
stack2.layoutHorizontally()
let stack3 = stack1.addStack()
stack3.layoutVertically()
stack3.size = new Size(85, 51)
stack1.addSpacer(18)
let stack4 = stack1.addStack()
stack4.layoutVertically()
stack4.size = new Size(79, 51)
stack1.addSpacer(18)
let stack5 = stack1.addStack()
stack5.layoutVertically()
stack5.size = new Size(97, 51)
let stack6 = stack2.addStack()
stack6.layoutVertically()
stack6.size = new Size(85, 51)
stack2.addSpacer(18)
let stack7 = stack2.addStack()
stack7.layoutVertically()
stack7.size = new Size(79, 51)
stack2.addSpacer(18)
let stack8 = stack2.addStack()
stack8.layoutVertically()
stack8.size = new Size(97, 51)
// add text to the list
header = stack3.addText("🦠 INFIZIERTE")
header.font = Font.mediumSystemFont(12)
label = stack3.addText(res.cases.toLocaleString() + "")
label.font = Font.mediumSystemFont(16)
label = stack3.addText("[+" + res.todayCases.toLocaleString() + "]")
label.font = Font.mediumSystemFont(14)
label.textColor = Color.gray()
header = stack4.addText("🗓 INZIDENZ")
header.font = Font.mediumSystemFont(12)
if (incidenceData) {
label = stack4.addText(incidenceData.value.replace(".", ",") + "");
label.font = Font.mediumSystemFont(16);
if (incidenceData.value >= 50) {
label.textColor = Color.red();
} else if (incidenceData.value >= 25) {
label.textColor = Color.orange();
}
}
label = stack4.addText(incidenceData.areaName)
label.font = Font.mediumSystemFont(14)
label.textColor = Color.gray()
header = stack5.addText("☠️ TODESFÄLLE")
header.font = Font.mediumSystemFont(12)
label = stack5.addText(res.deaths.toLocaleString())
label.font = Font.mediumSystemFont(16)
label = stack5.addText("[+" + res.todayDeaths + "]")
label.font = Font.mediumSystemFont(14)
label.textColor = Color.gray()
header = stack6.addText("💉 GEIMPFT")
header.font = Font.mediumSystemFont(12)
label = stack6.addText(number.sum.toLocaleString() + "")
label.font = Font.mediumSystemFont(16)
label = stack6.addText("[+" + number.delta_vortag.toLocaleString() + "]")
label.font = Font.mediumSystemFont(14)
label.textColor = Color.gray()
header = stack7.addText("📊 QUOTE")
header.font = Font.mediumSystemFont(12)
label = stack7.addText(number.quote.toLocaleString() + "%")
label.font = Font.mediumSystemFont(16)
label = stack7.addText("")
label.font = Font.mediumSystemFont(16)
header = stack8.addText("💚 GENESEN")
header.font = Font.mediumSystemFont(12)
label = stack8.addText(res.recovered.toLocaleString() + "")
label.font = Font.mediumSystemFont(16)
label = stack8.addText("[+" + newRecoveredData.value.toLocaleString() + "]")
label.font = Font.mediumSystemFont(14)
label.textColor = Color.gray()
return list
}
@29SimonB
Copy link
Author

29SimonB commented Jan 8, 2021

Intro

Das Corona Update Germany Widget zeigt dir die aktuellsten und wichtigsten vom Robert-Koch-Institut übermittelten Zahlen zur Corona Krise in Deutschland.

Anforderungen

  • iOS 14/iPadOS 14
  • Scriptable version 1.5 (oder neuer)

Installation

  • Kopiere den Source code von oben (klick vorher auf "raw" oben rechts)
  • Öffne die Scriptable app
  • Klick auf das "+" Symbol oben rechts und füge das kopierte Skript ein
  • Klick auf den Titel des Skripts ganz oben und vergebe einen Namen (z.B. Corona Update Germany)
  • Speichere das Skript durch Klick auf "Done" oben links
  • Gehe auf deinen iOS/iPadOS Homescreen und drücke irgendwo lang, um in den "wiggle mode" zu kommen (mit dem man auch die App Symbole anordnen kann)
  • Drücke das "+" Symbol oben links, blättere dann nach unten zu "Scriptable" (Liste ist alphabetisch), wähle die zweite Widget Größe (middle) und drück unten auf "Widget hinzufügen"
  • Drücke auf das Widget, um seine Einstellungen zu bearbeiten (optional lang drücken, wenn der Wiggle Modus schon beendet wurde)
  • Wähle unter "Script" das oben erstellte aus (Corona Update Germany)

Quellen

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