diff --git a/apps/airqualityci/ChangeLog b/apps/airqualityci/ChangeLog new file mode 100644 index 0000000000..cd5afdcc99 --- /dev/null +++ b/apps/airqualityci/ChangeLog @@ -0,0 +1 @@ +0.01: Initial clockinfo release diff --git a/apps/airqualityci/README.md b/apps/airqualityci/README.md new file mode 100644 index 0000000000..7a057fa558 --- /dev/null +++ b/apps/airqualityci/README.md @@ -0,0 +1,19 @@ +# Air Quality Clock Info + +Create a list of clockinfos, each displaying air quality and/or temperature, fetched from IQAir + +Requires Gadgetbridge internet access + +# Display modes + +Tapping the clockinfo changes its mode. + +Examples of possible modes: +- `45` +- `45 31°` +- `NYC 45` +- `NYC 45 31°` +- `NYC` + + +Not affiliated with IQAir. diff --git a/apps/airqualityci/app.png b/apps/airqualityci/app.png new file mode 100644 index 0000000000..3790b7b2d7 Binary files /dev/null and b/apps/airqualityci/app.png differ diff --git a/apps/airqualityci/clkinfo.js b/apps/airqualityci/clkinfo.js new file mode 100644 index 0000000000..c5730b5457 --- /dev/null +++ b/apps/airqualityci/clkinfo.js @@ -0,0 +1,91 @@ +(function() { + let data = require("Storage").readJSON("airqualityci.json", 1) || {}; + let config = require("Storage").readJSON("airqualityci.settings.json") || {}; + + function checkAQI(cb) { + let d = new Date(); + if (config.apiKey && config.rows) { + config.rows.forEach((row) => { + if (row.url) { + let el = row.url.replace(/\/$/, "").split("/").reverse(); + let url = `https://api.airvisual.com/v2/city?city=${el[0]}&state=${el[1]}&country=${el[2]}&key=${config.apiKey}`; + data[row.url] = data[row.url] || {}; + // If neither attempt nor time are set, then we have never tried + // If attempt was set more than 1 minute ago, try again + // If time was set more than 1 hour ago, refresh + if ((!data[row.url].time && !data[row.url].attempt) || + (data[row.url].attempt && data[row.url].attempt + 60000 < d.getTime()) || + (data[row.url].time && data[row.url].time + 3600000 < d.getTime())) { + data[row.url].attempt = d.getTime(); + Bangle.http(url).then((r) => { + let resp = JSON.parse(r.resp); + data[row.url] = { + aqius: resp.data.current.pollution.aqius, + temp: resp.data.current.weather.tp, + time: d.getTime() + } + cb(); + require("Storage").writeJSON("airqualityci.json", data); + }); + } + } + }); + } + } + + let locs = { + name: "AirQuality", + items: [] + }; + + if (config.rows) { + config.rows.forEach((row, id) => { + locs.items.push({ + name: "AQI " + row.name, + show: () => {}, + hide: () => {}, + run: function() { + if ( ! config.rows[id].mode ) { + config.rows[id].mode = 2; + } else if ( config.rows[id].mode === 5 ){ + config.rows[id].mode = 1; + } else { + config.rows[id].mode += 1; + } + this.emit("redraw"); + require("Storage").writeJSON("airqualityci.settings.json", config); + }, + get: function() { + checkAQI(() => this.emit("redraw")); + let aqi = data[config.rows[id].url] + let txt = ""; + let aqius = (aqi && typeof(aqi.aqius) == "number") ? aqi.aqius : "..."; + let temp = (aqi && typeof(aqi.temp) == "number") ? aqi.temp : "..."; + switch ( config.rows[id].mode) { + case 2: + txt = aqius + " " + temp + "°"; + break; + case 3: + txt = row.name + " " + aqius; + break; + case 4: + txt = row.name + " " + aqius + " " + temp + "°"; + break; + case 5: + txt = row.name; + break; + default: + txt = aqius; + } + return { + text: txt, + short: aqius, + img: atob("GBiBAAA4AAB8AAd+AA++QB/d8D/t8D/p+DvqcBUPsA7vgB9fwA7vgAXvgAH/AAHwgAD3wAbfwA9/wA+/gA/fAA/OAA/gAAfAAAAAAA==") + }; + } + }); + }); + } + + return locs; +}) diff --git a/apps/airqualityci/custom.html b/apps/airqualityci/custom.html new file mode 100644 index 0000000000..d615d45bcf --- /dev/null +++ b/apps/airqualityci/custom.html @@ -0,0 +1,116 @@ + + + + + + +

The AQI and temp are sourced from IQAir, which requires "Allow Internet Access" to be enabled in Gadgetbridge.

+

To use AQI, you need an IQAir API key. To get one for free, create an IQAir account, then create an API key in your user dashboard.

+

To specify the IQAir source, find your city on the IQAir website, then copy and paste the URL. It should look something like https://www.iqair.com/usa/new-york/new-york-city

+ + + + + +
NameIQAir URL
+ + + +
+ +
+ + + + + + + + diff --git a/apps/airqualityci/metadata.json b/apps/airqualityci/metadata.json new file mode 100644 index 0000000000..e43967dcfa --- /dev/null +++ b/apps/airqualityci/metadata.json @@ -0,0 +1,18 @@ +{ "id": "airqualityci", + "name": "Air Quality Clockinfo", + "version": "0.01", + "description": "Create clockinfos for air quality and temperature", + "icon": "app.png", + "type": "clkinfo", + "tags": "clkinfo", + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "custom": "custom.html", + "storage": [ + {"name":"airqualityci.clkinfo.js","url":"clkinfo.js"} + ], + "data": [ + {"name":"airqualityci.json"}, + {"name":"airqualityci.settings.json"} + ] +}