diff --git a/apps/owmweather/ChangeLog b/apps/owmweather/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/owmweather/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/owmweather/README.md b/apps/owmweather/README.md new file mode 100644 index 000000000..694724c4a --- /dev/null +++ b/apps/owmweather/README.md @@ -0,0 +1,13 @@ +# Open Weather Map weather provider + +This updates [Weather](https://banglejs.com/apps/#weather) with data from the Open Weather Map API + +## Usage + +Just install and configure the app. This needs an internet-enabled Gadgetbridge version. +Install [My Location](https://banglejs.com/apps/#mylocation) to change the location for the weather requests. +Install one of the text input libraries to modify the API key in the settings + +## Creator + +[halemmerich](https://github.com/halemmerich) diff --git a/apps/owmweather/app.png b/apps/owmweather/app.png new file mode 100644 index 000000000..bbfc0ace0 Binary files /dev/null and b/apps/owmweather/app.png differ diff --git a/apps/owmweather/boot.js b/apps/owmweather/boot.js new file mode 100644 index 000000000..64d2df3e9 --- /dev/null +++ b/apps/owmweather/boot.js @@ -0,0 +1,28 @@ +(function() { + let waiting = false; + let settings = require("Storage").readJSON("owmweather.json", 1) || { + enabled: false + }; + + function completion(){ + waiting = false; + } + + if (settings.enabled) { + let weather = require("Storage").readJSON('weather.json') || {}; + let lastUpdate; + if (weather && weather.weather && weather.weather.time) lastUpdate = weather.weather.time; + if (!lastUpdate || lastUpdate + settings.refresh * 1000 * 60 < Date.now()){ + if (!waiting){ + waiting = true; + require("owmweather").pull(completion); + } + } + setInterval(() => { + if (!waiting && NRF.getSecurityStatus().connected){ + waiting = true; + require("owmweather").pull(completion); + } + }, settings.refresh * 1000 * 60); + } +})(); diff --git a/apps/owmweather/default.json b/apps/owmweather/default.json new file mode 100644 index 000000000..9d8998867 --- /dev/null +++ b/apps/owmweather/default.json @@ -0,0 +1 @@ +{"enabled":false,"refresh":180} diff --git a/apps/owmweather/interface.html b/apps/owmweather/interface.html new file mode 100644 index 000000000..f629a5be9 --- /dev/null +++ b/apps/owmweather/interface.html @@ -0,0 +1,48 @@ + + + + + +

Set OWM API key

+

+

+ + + + + + diff --git a/apps/owmweather/lib.js b/apps/owmweather/lib.js new file mode 100644 index 000000000..6ba52b498 --- /dev/null +++ b/apps/owmweather/lib.js @@ -0,0 +1,53 @@ +function parseWeather(response) { + let owmData = JSON.parse(response); + + let isOwmData = owmData.coord && owmData.weather && owmData.main; + + if (isOwmData) { + let json = require("Storage").readJSON('weather.json') || {}; + let weather = {}; + weather.time = Date.now(); + weather.hum = owmData.main.humidity; + weather.temp = owmData.main.temp; + weather.code = owmData.weather[0].id; + weather.wdir = owmData.wind.deg; + weather.wind = owmData.wind.speed; + weather.loc = owmData.name; + weather.txt = owmData.weather[0].main; + + if (weather.wdir != null) { + let deg = weather.wdir; + while (deg < 0 || deg > 360) { + deg = (deg + 360) % 360; + } + weather.wrose = ['n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'n'][Math.floor((deg + 22.5) / 45)]; + } + + json.weather = weather; + require("Storage").writeJSON('weather.json', json); + require("weather").emit("update", json.weather); + return undefined; + } else { + return /*LANG*/"Not OWM data"; + } +} + +exports.pull = function(completionCallback) { + let location = require("Storage").readJSON("mylocation.json", 1) || { + "lat": 51.50, + "lon": 0.12, + "location": "London" + }; + let settings = require("Storage").readJSON("owmweather.json", 1); + let uri = "https://api.openweathermap.org/data/2.5/weather?lat=" + location.lat.toFixed(2) + "&lon=" + location.lon.toFixed(2) + "&exclude=hourly,daily&appid=" + settings.apikey; + if (Bangle.http){ + Bangle.http(uri, {timeout:10000}).then(event => { + let result = parseWeather(event.resp); + if (completionCallback) completionCallback(result); + }).catch((e)=>{ + if (completionCallback) completionCallback(e); + }); + } else { + if (completionCallback) completionCallback(/*LANG*/"No http method found"); + } +}; diff --git a/apps/owmweather/metadata.json b/apps/owmweather/metadata.json new file mode 100644 index 000000000..d0229656d --- /dev/null +++ b/apps/owmweather/metadata.json @@ -0,0 +1,22 @@ +{ "id": "owmweather", + "name": "Open Weather Map weather provider", + "shortName":"OWM Weather", + "version":"0.01", + "description": "Pulls weather from OWM API", + "icon": "app.png", + "type": "bootloader", + "tags": "boot,tool,weather", + "supports" : ["BANGLEJS2"], + "interface": "interface.html", + "readme": "README.md", + "data": [ + {"name":"owmweather.json"}, + {"name":"weather.json"} + ], + "storage": [ + {"name":"owmweather.default.json","url":"default.json"}, + {"name":"owmweather.boot.js","url":"boot.js"}, + {"name":"owmweather","url":"lib.js"}, + {"name":"owmweather.settings.js","url":"settings.js"} + ] +} diff --git a/apps/owmweather/settings.js b/apps/owmweather/settings.js new file mode 100644 index 000000000..a4d21dd7c --- /dev/null +++ b/apps/owmweather/settings.js @@ -0,0 +1,84 @@ +(function(back) { + function writeSettings(key, value) { + var s = require('Storage').readJSON(FILE, true) || {}; + s[key] = value; + require('Storage').writeJSON(FILE, s); + readSettings(); + } + + function readSettings(){ + settings = Object.assign( + require('Storage').readJSON("owmweather.default.json", true) || {}, + require('Storage').readJSON(FILE, true) || {} + ); + } + + var FILE="owmweather.json"; + var settings; + readSettings(); + + function buildMainMenu(){ + var mainmenu = { + '': { 'title': 'OWM weather' }, + '< Back': back, + "Enabled": { + value: !!settings.enabled, + onchange: v => { + writeSettings("enabled", v); + } + }, + "Refresh every": { + value: settings.refresh / 60, + min: 1, + max: 48, + step: 1, + format: v=>v+"h", + onchange: v => { + writeSettings("refresh",Math.round(v * 60)); + } + }, + "Force refresh": ()=>{ + if (!settings.apikey){ + E.showAlert("API key is needed","Hint").then(()=>{ + E.showMenu(buildMainMenu()); + }); + } else { + E.showMessage("Reloading weather"); + require("owmweather").pull((e)=>{ + if (e) { + E.showAlert(e,"Error").then(()=>{ + E.showMenu(buildMainMenu()); + }); + } else { + E.showAlert("Success").then(()=>{ + E.showMenu(buildMainMenu()); + }); + } + }); + } + } + }; + + mainmenu["API key"] = function (){ + if (require("textinput")){ + require("textinput").input({text:settings.apikey}).then(result => { + if (result != "") { + print("Result is", result); + settings.apikey = result; + writeSettings("apikey",result); + } + E.showMenu(buildMainMenu()); + }); + } else { + E.showPrompt("Install a text input lib"),then(()=>{ + E.showMenu(buildMainMenu()); + }); + } + }; + + + return mainmenu; + } + + E.showMenu(buildMainMenu()); +});