marcusraitner / COVID-19-Dashboard

Dieses Scriptable-Skript erzeugt ein Widget, das den Verlauf der 7-Tage-Inzidenz und die Auslastung der Intensivbetten am aktuellen Standort anzeigt. Zusätzlich angezeigt wird der aktuelle Wert der 7-Tage-Inzidenz des zugehörigen Bundeslandes und der Impfstatus des Bundeslandes.
GNU General Public License v3.0
210 stars 16 forks source link

Time gap #52

Closed Copperlanding closed 3 years ago

Copperlanding commented 3 years ago

Hi Marcus, I am new here. My dashboard is not updated with the latest RKI value when I start my phone. Another application shows instantly the figure of the past day. What do I do wrong? (See picture: 49,1 is the current figure while 53 is the number 2 days ago. Both boards run under „scripts“. thank you 1CDEE31D-9690-4E9D-B98E-7F12A9BC011A

Win002 commented 3 years ago

Ich habe das gleiche Problem, selbst mit Parameter Frozen=y

marcusraitner commented 3 years ago

Hi, thanks for pointing this out. Let's have a look at it. The RKI delivers in their excel (newest version is from yesterday, May 28!) the following values (last one is the one for May 28):

79,5 | 72,2 | 71,9 | 66,9 | 50,2 | 48,9 | 52,8

This is exactly what my widget shows (I assume you use frozen=y). What is the other widget; can you share a link such that I could look into their code?

marcusraitner commented 3 years ago

Now the excel was updated and the last value for May 29 indeed is 49,1. It will hopefully shortly appear in the app (when the API behind replicates the excel) with frozen=y

marcusraitner commented 3 years ago

I would nevertheless be curios how the other widget knew already before. Would be interesting for #45

Copperlanding commented 3 years ago

Hi Marcus, thanks for the immediate reply. Your script was updated now however the other script is always faster😉

Here the code:

// Licence: Robert Koch-Institut (RKI), dl-de/by-2-0 const apiUrl = (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 apiUrlStates = ' 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 '

const widget = await createWidget() if (!config.runsInWidget) { await widget.presentSmall() } Script.setWidget(widget) Script.complete()

async function createWidget(items) { const data = await getData() const list = new ListWidget() const header = list.addText("🦠 Inzidenz".toUpperCase()) header.font = Font.mediumSystemFont(13) if(data) { if(!data.shouldCache) { list.addSpacer(6) const loadingIndicator = list.addText("Ort wird ermittelt...".toUpperCase()) loadingIndicator.font = Font.mediumSystemFont(13) loadingIndicator.textOpacity = 0.5 } list.addSpacer() const label = list.addText(data.incidence+"") label.font = Font.boldSystemFont(24) label.textColor = data.incidence >= 50 ? Color.red() : data.incidence

= 35 ? Color.orange() : Color.green() list.addText(data.areaName) if(data.shouldCache) { list.refreshAfterDate = new Date(Date.now() + 60601000) } } else { list.addSpacer() list.addText("Daten nicht verfügbar") } return list }

async function getData() { try { const location = await getLocation() if(location) { let data = await new Request(apiUrl(location)).loadJSON() const attr = data.features[0].attributes return { incidence: attr.cases7_per_100k.toFixed(1), areaName: attr.GEN, shouldCache: true }; } else { let data = await new Request(apiUrlStates).loadJSON() const incidencePerState = data.features.map((f) => f.attributes.cases7_bl_per_100k) const averageIncidence = incidencePerState.reduce((a, b) => a + b) / incidencePerState.length return { incidence: averageIncidence.toFixed(1), areaName: "Deutschland", shouldCache: false }; } } catch(e) { return null } }

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; } } Hope that helps and I would be very happy if Thus helps you making your fantastic even better. Best wishes Copperlanding

Marcus Raitner @.***> schrieb am Sa. 29. Mai 2021 um 09:04:

I would nevertheless be curios how the other widget knew already before. Would be interesting for #45 https://github.com/marcusraitner/COVID-19-Dashboard/issues/45

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/marcusraitner/COVID-19-Dashboard/issues/52#issuecomment-850784010, or unsubscribe https://github.com/notifications/unsubscribe-auth/AUISAMRWULD7OV2T6SKIOHDTQCGWPANCNFSM45X63PRA .

Win002 commented 3 years ago

Wir sind auch Frühaufsteher. Das RKI widget (angefügt) zeigt die richtigen Daten in der Regel weit vor 5:00 morgens an. Ich habe es rki genannt, ich weiß gar nicht mehr woher es kommt. Schönes Wochenende

Marcus Raitner @.***> schrieb am Sa. 29. Mai 2021 um 09:04:

I would nevertheless be curios how the other widget knew already before. Would be interesting for #45 https://github.com/marcusraitner/COVID-19-Dashboard/issues/45

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/marcusraitner/COVID-19-Dashboard/issues/52#issuecomment-850784010, or unsubscribe https://github.com/notifications/unsubscribe-auth/AUGGVPQRPOZ6C6OZEP4G263TQCGWPANCNFSM45X63PRA .

{ "always_run_in_app" : false, "icon" : { "color" : "deep-brown", "glyph" : "magic" }, "name" : "RKI", "script" : "\/\/ Licence: Robert Koch-Institut (RKI), dl-de\/by-2-0\nconst newCasesApiUrl = https:\/\/services7.arcgis.com\/mOBPykOjAyBO2ZKk\/arcgis\/rest\/services\/RKI_COVID19\/FeatureServer\/0\/query?f=json&where=NeuerFall%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;\n\nconst incidenceUrl = (location) => https:\/\/services7.arcgis.com\/mOBPykOjAyBO2ZKk\/arcgis\/rest\/services\/RKI_Landkreisdaten\/FeatureServer\/0\/query?where=1%3D1&outFields=GEN,last_update,cases,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\n\nconst saveIncidenceLatLon = (location) => {\n let fm = FileManager.iCloud()\n let path = fm.joinPath(fm.documentsDirectory(), \"covid19latlon.json\")\n fm.writeString(path, JSON.stringify(location))\n}\n\nconst getsavedIncidenceLatLon = () => {\n let fm = FileManager.iCloud()\n let path = fm.joinPath(fm.documentsDirectory(), \"covid19latlon.json\")\n let data = fm.readString(path)\n return JSON.parse(data)\n}\n\nlet widget = await createWidget()\nif (!config.runsInWidget) {\n await widget.presentSmall()\n}\n\nScript.setWidget(widget)\nScript.complete()\n\nasync function createWidget(items) {\n let data, attr, header, label\n\n const list = new ListWidget()\n\n\n \/\/ fetch new cases\n data = await new Request(newCasesApiUrl).loadJSON()\n\n if(!data || !data.features || !data.features.length) {\n const errorList = new ListWidget()\n errorList.addText(\"Keine Ergebnisse für die Anfrage nach den Neuinfektionen.\")\n return errorList\n }\n\n header = list.addText(\"🦠 Neuinfektionen \".toUpperCase())\n header.centerAlignText()\n header.font = Font.mediumSystemFont(10)\n\n label = list.addText(\"+\"+data.features[0].attributes.value)\n label.font = Font.mediumSystemFont(20)\n label.centerAlignText()\n const country = list.addText(\"Deutschland\")\n country.centerAlignText()\n country.font = Font.mediumSystemFont(12)\n country.textColor = Color.gray()\n\n\n list.addSpacer()\n\n \/\/ fetch new incidents\n let location\n\n if(args.widgetParameter) {\n\n const fixedCoordinates = args.widgetParameter.split(\",\").map(parseFloat)\n\n location = {\n latitude: fixedCoordinates[0],\n longitude: fixedCoordinates[1]\n }\n\n } else {\n\n Location.setAccuracyToThreeKilometers()\n try {\n location = await Location.current()\n console.log('get current lat\/lon')\n saveIncidenceLatLon(location)\n } catch(e) {\n console.log('using saved lat\/lon')\n location = getsavedIncidenceLatLon()\n }\n }\n\n\n data = await new Request(incidenceUrl(location)).loadJSON()\n\n if(!data || !data.features || !data.features.length) {\n const errorList = new ListWidget()\n errorList.addText(\"Keine Ergebnisse für den aktuellen Ort gefunden.\")\n return errorList\n }\n\n attr = data.features[0].attributes\n const incidence = attr.cases7_per_100k.toFixed(1)\n const cityName = attr.GEN\n const cases =attr.cases\n const lastUpdate = attr.last_update\n\n header = list.addText(\"🦠 Inzidenz\".toUpperCase())\n header.centerAlignText()\n header.font = Font.mediumSystemFont(10)\n\n label = list.addText(incidence)\n label.centerAlignText()\n label.font = Font.mediumSystemFont(24) \n\n label2 = list.addText(\"(\"+cases+\")\")\n label2.centerAlignText()\n label2.font = Font.mediumSystemFont(12) \n\n\n\n if(incidence >= 50) {\n label.textColor = Color.red()\n } else if(incidence >= 25) {\n label.textColor = Color.orange()\n }\n\n const city = list.addText(cityName)\n city.centerAlignText()\n city.font = Font.mediumSystemFont(12)\n city.textColor = Color.gray()\n\n list.addSpacer()\n\n label3 = list.addText (\"letztes Update: \"+lastUpdate.substr(0,10))\n label3.centerAlignText()\n label3.font = Font.mediumSystemFont(6) \n\n\n return list\n}\n \n", "share_sheet_inputs" : [

] }

marcusraitner commented 3 years ago

Thanks for the code. I actually have this value as well (I use the same call) but I don't use this latest value of the incidence at the moment, because I want to show the whole history and thus I either calculate it or I take the one of the excel (with the time gap). I'm curios: did you use the setting frozen=y as you experienced this gap? Because with frozen=n there normally is no such gap as this then uses only the RKI-APIs and all of them are updated at midnight.

Win002 commented 3 years ago

Yes frozen=y

Marcus Raitner @.***> schrieb am Sa. 29. Mai 2021 um 09:31:

Thanks for the code. I actually have this value as well (I use the same call) but I don't use this latest value of the incidence at the moment, because I want to show the whole history and thus I either calculate it or I take the one of the excel (with the time gap). I'm curios: did you use the setting frozen=y as you experienced this gap? Because with frozen=n there normally is no such gap as this then uses only the RKI-APIs and all of them are updated at midnight.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/marcusraitner/COVID-19-Dashboard/issues/52#issuecomment-850787635, or unsubscribe https://github.com/notifications/unsubscribe-auth/AUGGVPR3YTILR6ZLNZF6SZDTQCJ6DANCNFSM45X63PRA .

Win002 commented 3 years ago

Ist besser frozen=n zu benutzen?

Oliver Dietrich @.***> schrieb am Sa. 29. Mai 2021 um 09:33:

Yes frozen=y

Marcus Raitner @.***> schrieb am Sa. 29. Mai 2021 um 09:31:

Thanks for the code. I actually have this value as well (I use the same call) but I don't use this latest value of the incidence at the moment, because I want to show the whole history and thus I either calculate it or I take the one of the excel (with the time gap). I'm curios: did you use the setting frozen=y as you experienced this gap? Because with frozen=n there normally is no such gap as this then uses only the RKI-APIs and all of them are updated at midnight.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/marcusraitner/COVID-19-Dashboard/issues/52#issuecomment-850787635, or unsubscribe https://github.com/notifications/unsubscribe-auth/AUGGVPR3YTILR6ZLNZF6SZDTQCJ6DANCNFSM45X63PRA .

marcusraitner commented 3 years ago

Ok, for the issue with frozen I will address this in #45 with the same value as the other widget.

marcusraitner commented 3 years ago

Ist besser frozen=n zu benutzen?

Kommt drauf an. Wird dann immer aus den Fallzahlen berechnet: ist also aktueller und richtiger. Ist aber eben nicht der Wert der zählt; für die Maßnahmen gelten die Werte aus dem Excel (also frozen=y)

Copperlanding commented 3 years ago

Frozen=True If I use Frozen=False the gap would be eliminated? Sorry, did not understand what the disadvantages are using “false”? Regards

Marcus Raitner @.***> schrieb am Sa. 29. Mai 2021 um 09:31:

Thanks for the code. I actually have this value as well (I use the same call) but I don't use this latest value of the incidence at the moment, because I want to show the whole history and thus I either calculate it or I take the one of the excel (with the time gap). I'm curios: did you use the setting frozen=y as you experienced this gap? Because with frozen=n there normally is no such gap as this then uses only the RKI-APIs and all of them are updated at midnight.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/marcusraitner/COVID-19-Dashboard/issues/52#issuecomment-850787635, or unsubscribe https://github.com/notifications/unsubscribe-auth/AUISAMTLC7J2LT3AQKEBAP3TQCJ6BANCNFSM45X63PRA .

Win002 commented 3 years ago

Die Zahlen, die morgens im „RKI“ Widget angezeigt werden sind identisch mit der Seite https://experience.arcgis.com. Sind die Daten dann Frozen? Irgendwie blicke ich nicht durch.

Marcus Raitner @.***> schrieb am Sa. 29. Mai 2021 um 09:35:

Ist besser frozen=n zu benutzen?

Kommt drauf an. Wird dann immer aus den Fallzahlen berechnet: ist also aktueller und richtiger. Ist aber eben nicht der Wert der zählt; für die Maßnahmen gelten die Werte aus dem Excel (also frozen=y)

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/marcusraitner/COVID-19-Dashboard/issues/52#issuecomment-850788161, or unsubscribe https://github.com/notifications/unsubscribe-auth/AUGGVPVM7RUEEQUZ4BPAKHLTQCKNLANCNFSM45X63PRA .

marcusraitner commented 3 years ago

Frozen=True If I use Frozen=False the gap would be eliminated? Sorry, did not understand what the disadvantages are using “false”?

Ok, thanks. And no worries. As my README is only in German you had no chance to understand. With frozen=n I take the cases per day and calculate the incidence from them. However, due to some cases being reported later this leads to incidences of the past days slightly changing over time. But with this method you get an accurate picture of the true incidence. For making decisions about measures this is not so great and this is why the RKI freezes those incidences and does therefore neglect the cases reported later. These are then the values in the official excel of the RKI. It depends on what you want to see.

Copperlanding commented 3 years ago

👍🏻😊

Marcus Raitner @.***> schrieb am Sa. 29. Mai 2021 um 09:42:

Frozen=True If I use Frozen=False the gap would be eliminated? Sorry, did not understand what the disadvantages are using “false”?

Ok, thanks. And no worries. As my README is only in German you had no chance to understand. With frozen=n I take the cases per day and calculate the incidence from them. However, due to some cases being reported later this leads to incidences of the past days slightly changing over time. But with this method you get an accurate picture of the true incidence. For making decisions about measures this is not so great and this is why the RKI freezes those incidences and does therefore neglect the cases reported later. These are then the values in the official excel of the RKI. It depends on what you want to see.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/marcusraitner/COVID-19-Dashboard/issues/52#issuecomment-850789110, or unsubscribe https://github.com/notifications/unsubscribe-auth/AUISAMQIWHNWMCK52EY3FCTTQCLIDANCNFSM45X63PRA .

marcusraitner commented 3 years ago

Die Zahlen, die morgens im „RKI“ Widget angezeigt werden sind identisch mit der Seite https://experience.arcgis.com. Sind die Daten dann Frozen? Irgendwie blicke ich nicht durch.

Bei dem Wert für den aktuellen Tag macht das vermutlich keinen Unterschied. Der ist ja immer aus den zu dem Zeitpunkt verfügbaren Werten der letzten sieben Tage berechnet und wird dann eben eingefroren. Die Frage ist dann nur wenn es zu Nachmeldungen von Fällen für diese sieben Tage kommt (und das passiert oft). Der eingefrorene Wert wird dadurch nicht geändert, wenn ich ihn neu berechne ändert sich der Wert aber nachträglich (ist ja logisch auch richtig). Du würdest also den Unterschied nur merken, wenn du morgen oder übermorgen wieder auf den heutigen Wert schaust. Bei meinem Widget ist das der Fall, bei dem RKI Widget passiert das ja nicht.

marcusraitner commented 3 years ago

is solved with latest version here (pull request #53).

Win002 commented 3 years ago

Guten Morgen,

Kann ich bei beigefügtem Widget die Inzidenz für ganz Deutschland anzeigen lassen, und nicht nur für nrw?

Viele Grüße Oliver Dietrich

{ "always_run_in_app" : false, "icon" : { "color" : "deep-brown", "glyph" : "magic" }, "name" : "RKI", "script" : "\/\/ Licence: Robert Koch-Institut (RKI), dl-de\/by-2-0\nconst newCasesApiUrl = https:\/\/services7.arcgis.com\/mOBPykOjAyBO2ZKk\/arcgis\/rest\/services\/RKI_COVID19\/FeatureServer\/0\/query?f=json&where=NeuerFall%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;\n\nconst incidenceUrl = (location) => https:\/\/services7.arcgis.com\/mOBPykOjAyBO2ZKk\/arcgis\/rest\/services\/RKI_Landkreisdaten\/FeatureServer\/0\/query?where=1%3D1&outFields=GEN,last_update,cases,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\n\nconst saveIncidenceLatLon = (location) => {\n let fm = FileManager.iCloud()\n let path = fm.joinPath(fm.documentsDirectory(), \"covid19latlon.json\")\n fm.writeString(path, JSON.stringify(location))\n}\n\nconst getsavedIncidenceLatLon = () => {\n let fm = FileManager.iCloud()\n let path = fm.joinPath(fm.documentsDirectory(), \"covid19latlon.json\")\n let data = fm.readString(path)\n return JSON.parse(data)\n}\n\nlet widget = await createWidget()\nif (!config.runsInWidget) {\n await widget.presentSmall()\n}\n\nScript.setWidget(widget)\nScript.complete()\n\nasync function createWidget(items) {\n let data, attr, header, label\n\n const list = new ListWidget()\n\n\n \/\/ fetch new cases\n data = await new Request(newCasesApiUrl).loadJSON()\n\n if(!data || !data.features || !data.features.length) {\n const errorList = new ListWidget()\n errorList.addText(\"Keine Ergebnisse für die Anfrage nach den Neuinfektionen.\")\n return errorList\n }\n\n header = list.addText(\"🦠 Neuinfektionen \".toUpperCase())\n header.centerAlignText()\n header.font = Font.mediumSystemFont(10)\n\n label = list.addText(\"+\"+data.features[0].attributes.value)\n label.font = Font.mediumSystemFont(20)\n label.centerAlignText()\n const country = list.addText(\"Deutschland\")\n country.centerAlignText()\n country.font = Font.mediumSystemFont(12)\n country.textColor = Color.gray()\n\n\n list.addSpacer()\n\n \/\/ fetch new incidents\n let location\n\n if(args.widgetParameter) {\n\n const fixedCoordinates = args.widgetParameter.split(\",\").map(parseFloat)\n\n location = {\n latitude: fixedCoordinates[0],\n longitude: fixedCoordinates[1]\n }\n\n } else {\n\n Location.setAccuracyToThreeKilometers()\n try {\n location = await Location.current()\n console.log('get current lat\/lon')\n saveIncidenceLatLon(location)\n } catch(e) {\n console.log('using saved lat\/lon')\n location = getsavedIncidenceLatLon()\n }\n }\n\n\n data = await new Request(incidenceUrl(location)).loadJSON()\n\n if(!data || !data.features || !data.features.length) {\n const errorList = new ListWidget()\n errorList.addText(\"Keine Ergebnisse für den aktuellen Ort gefunden.\")\n return errorList\n }\n\n attr = data.features[0].attributes\n const incidence = attr.cases7_per_100k.toFixed(1)\n const cityName = attr.GEN\n const cases =attr.cases\n const lastUpdate = attr.last_update\n\n header = list.addText(\"🦠 Inzidenz\".toUpperCase())\n header.centerAlignText()\n header.font = Font.mediumSystemFont(10)\n\n label = list.addText(incidence)\n label.centerAlignText()\n label.font = Font.mediumSystemFont(24) \n\n label2 = list.addText(\"(\"+cases+\")\")\n label2.centerAlignText()\n label2.font = Font.mediumSystemFont(12) \n\n\n\n if(incidence >= 50) {\n label.textColor = Color.red()\n } else if(incidence >= 25) {\n label.textColor = Color.orange()\n }\n\n const city = list.addText(cityName)\n city.centerAlignText()\n city.font = Font.mediumSystemFont(12)\n city.textColor = Color.gray()\n\n list.addSpacer()\n\n label3 = list.addText (\"letztes Update: \"+lastUpdate.substr(0,10))\n label3.centerAlignText()\n label3.font = Font.mediumSystemFont(6) \n\n\n return list\n}\n \n", "share_sheet_inputs" : [

] }

marcusraitner commented 3 years ago

@Win002 Ich hole die Inzidenz für DE und den R-Wert über diese API: https://api.corona-zahlen.org/germany