From 55778cdcd006668ad1ecd0ca1564e38194d5b2e7 Mon Sep 17 00:00:00 2001 From: inversion-nl Date: Wed, 15 Jun 2016 09:39:40 +0200 Subject: [PATCH 1/3] Add extra debugging boolean Better tests of data to prevent crashes Default values in settings --- app.js | 392 ++++++++++++++++++++++++-------------------- app.json | 2 +- settings/index.html | 50 +++--- 3 files changed, 237 insertions(+), 207 deletions(-) diff --git a/app.js b/app.js index 9f4a2bf..ec52c93 100644 --- a/app.js +++ b/app.js @@ -3,7 +3,7 @@ var Wunderground = require('wundergroundnode'); var wunderground; -var defaultUpdateTime = 60; +var defaultUpdateTime = 10; var maxLocationGetTries = 3; var units_metric; var insightsLogs = @@ -31,15 +31,37 @@ var lon = null; var address; var weatherData = {}; +// Enable full logging for more info +var fullLogging = false; + // Variables for when value has changed var oldTemp; var oldHum; function value_exist(string) { - if (typeof string != 'undefined') return true; + if (typeof string != 'undefined' && string != null) return true; else return false; } +function test_weatherData(data) { + if (!value_exist(data)) { + if (fullLogging) Homey.log('test_weatherData'); + if (fullLogging) Homey.log('Value was undefined or null, returning empty string'); + return ""; + } + else return data; +} + +function parseWeatherFloat(data) { + var temp = parseFloat(data); + if (isNaN(temp)) { + if (fullLogging) Homey.log('parseWeatherFloat'); + if (fullLogging) Homey.log('Value was NaN, returning 0'); + return 0; + } + else return temp; +} + function epochToString(epoch) { var date = new Date(0); date.setUTCSeconds(epoch); @@ -58,7 +80,6 @@ var self = { Homey.log(""); self.checkInsightsLogs(); - self.checkSettings(); // Listen for triggers and conditions Homey.log("Registering trigger and condition listeners") @@ -99,27 +120,24 @@ var self = { Homey.on('memwarn', self.appWarning); Homey.on('unload', self.unload); } catch (err) { - Homey.log('!!Registration for app warning and performance listeners failed!!') + Homey.log('Registration for one of the app warning and performance listeners failed!') } - - // Get location - self.getLocation(function(err, location) { - // Update weather right now and schedule every user defined minutes - self.updateWeather(); - self.scheduleWeather(update_frequenty); - }); + + // Check settings and start updating weather + self.checkSettings(); }, scheduleWeather: function(update_frequenty) { Homey.log(""); Homey.log("Schedule weather"); + if (interval) { - Homey.log("Current interval", interval); - Homey.log("Clearing current interval"); + Homey.log("Clearing current interval", interval); clearInterval(interval); } - interval = setInterval(trigger_update.bind(this), update_frequenty * 60 * 1000); // To minutes - Homey.log('Interval:', update_frequenty); + + interval = setInterval(trigger_update.bind(this), update_frequenty * 60 * 1000); // From minutes to milliseconds + if (fullLogging) Homey.log('Interval:', interval); function trigger_update() { self.updateWeather(); }; @@ -127,8 +145,8 @@ var self = { }, setUnits: function() { - Homey.log(''); - Homey.log('setUnits'); + if (fullLogging) Homey.log(''); + if (fullLogging) Homey.log('setUnits'); units_metric = Homey.manager('settings').get('units_metric'); var units_imperial = Homey.manager('settings').get('units_imperial'); @@ -138,10 +156,10 @@ var self = { if (units_auto && value_exist(homey_units) && homey_units != "") { Homey.manager('settings').set('currentSettingUnits', 'auto'); if (homey_units == 'metric') { - Homey.log('Autodetected metric units'); + if (fullLogging) Homey.log('Autodetected metric units'); units_metric = true; } else { - Homey.log('Autodetected imperial units'); + if (fullLogging) Homey.log('Autodetected imperial units'); units_metric = false; } } else if (!value_exist(units_auto) && !value_exist(units_metric) && !value_exist(units_imperial)) { @@ -176,12 +194,12 @@ var self = { // Get user settings for update frequenty update_frequenty = Homey.manager('settings').get('updateFrequenty'); - Homey.log("Update every (user setting): " + update_frequenty); + if (fullLogging) Homey.log("Update every (user setting): " + update_frequenty); if (!usePersonalKey) { // Using Inversion key, max update frequenty is 60 minutes if (update_frequenty < defaultUpdateTime || update_frequenty > 1439 || !value_exist(update_frequenty)) { - Homey.log("Update value out of bounds, resetting to default"); + if (fullLogging) Homey.log("Update value out of bounds, resetting to default"); update_frequenty = defaultUpdateTime; // in minutes Homey.log("Update value: " + update_frequenty + " minutes"); } @@ -189,22 +207,21 @@ var self = { // Using user personal key if (update_frequenty < 1 || update_frequenty > 1439 || !value_exist(update_frequenty)) { // Defaulting back to 60 minutes - Homey.log("Update value out of bounds: " + update_frequenty + " minutes"); + if (fullLogging) Homey.log("Update value out of bounds: " + update_frequenty + " minutes"); update_frequenty = defaultUpdateTime; // in minutes Homey.log("Update value: " + update_frequenty + " minutes"); } } - - // Set default values - var autolocation = true; // Get user settings var country = Homey.manager('settings').get('country'); var city = Homey.manager('settings').get('city'); - autolocation = Homey.manager('settings').get('autolocation'); + var autolocation = Homey.manager('settings').get('autolocation'); + if (!value_exist(autolocation) && !value_exist(city) && !value_exist(country)) { - Homey.log('location information invalid, resetting to defaults') + if (fullLogging) Homey.log('One of the location information is invalid, falling back to auto location') autolocation = true; + Homey.manager('settings').set('autolocation', true); } // Check user settings @@ -212,44 +229,53 @@ var self = { Homey.log("Use Homey's location"); if (value_exist(lat) && value_exist(lon) && lat != 0 && lon != 0 && lat != null && lon != null) { Homey.log("Using lat lon for location"); - Homey.log("lat: " + lat + " lon: " + lon); address = lat + ',' + lon; + self.scheduleWeather(update_frequenty); } else { - Homey.log("Lat lon data invalid"); + Homey.log("Lat lon data invalid"); + if (locationGetCounter <= maxLocationGetTries) { Homey.log("Fetching location, try " + locationGetCounter + " of " + maxLocationGetTries) locationGetCounter++; self.getLocation(function(err, location) { - Homey.log("Location found, check settings"); - self.checkSettings(); - return; + if (!err && location != null) { + Homey.log("Location found"); + lat = location.latitude; + lon = location.longitude; + address = lat + ',' + lon; + self.scheduleWeather(update_frequenty); + // Found location, reset counter + locationGetCounter = 0; + return; + } }); - return; } else if (value_exist(country) && value_exist(city) && country != "" && city != "") { - Homey.log("Using country and city for location"); + Homey.log("Max location detection attempts reached, using country and city for location"); address = country + '/' + city; + self.scheduleWeather(update_frequenty); } else { - Homey.log("One of the country/city fields is empty, using defaults"); + Homey.log("Max location detection attempts reached and one of the country/city fields is empty, using defaults"); address = "Netherlands/Amsterdam"; + self.scheduleWeather(update_frequenty); } - Homey.log("Resetting locationGetCounter"); - locationGetCounter = 0; } } else if (value_exist(country) && value_exist(city) && country != "" && city != "") { address = "Netherlands/Amsterdam" Homey.log("Using country and city for location"); address = country + '/' + city; + self.scheduleWeather(update_frequenty); } else { - Homey.log("One of the country/city fields is empty, setting auto location which will trigger checkSettings() again"); + Homey.log("One of the country/city fields is empty, setting to autolocation which will trigger checkSettings() again"); Homey.manager('settings').set('autolocation', true); + self.scheduleWeather(update_frequenty); } }, initWunderground: function(key) { - Homey.log(""); - Homey.log("initWunderground"); + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("initWunderground"); if (wunderground != null) { - Homey.log("wunderground != null"); + if (fullLogging) Homey.log("wunderground != null"); //wunderground = null; } wunderground = new Wunderground(key); @@ -258,27 +284,29 @@ var self = { settingsChanged: function(settingname) { Homey.log(""); // Not interested in currentSettingUnits changes - if (settingname != 'currentSettingUnits' || settingname != 'currentsettingunits') Homey.log("Setting has changed: " + settingname); + if (settingname != "currentSettingUnits" || settingname != "currentsettingunits") { + Homey.log("Setting has changed", settingname); + } + // Homey v 0.8.35 has a bug where all variables are lower case - if (settingname == 'currentSettingUnits' || settingname != 'currentsettingunits') { + if (settingname == "currentSettingUnits" || settingname == "currentSettingUnits") { // Don't do anything when this setting has changed or it will cause a loop + return; } else if (settingname == 'updatefrequenty' || settingname == 'updateFrequenty') { // If the frequenty is changed we have to cancel the current interval and schedule a new self.checkSettings(); Homey.log("Scheduling weather update every:", update_frequenty); self.scheduleWeather(update_frequenty); - Homey.log("Fetching weather right now"); - self.updateWeather(); } else if (settingname == 'units_auto' || settingname == 'units_imperial' || settingname == 'units_metric') { // Let's check if the units have changed var units_metric = Homey.manager('settings').get('units_metric'); - Homey.log('units_metric:', units_metric); + if (fullLogging) Homey.log('units_metric:', units_metric); var units_imperial = Homey.manager('settings').get('units_imperial'); - Homey.log('units_imperial:', units_imperial); + if (fullLogging) Homey.log('units_imperial:', units_imperial); var units_auto = Homey.manager('settings').get('units_auto'); - Homey.log('units_auto:', units_auto); + if (fullLogging) Homey.log('units_auto:', units_auto); var currentSettingUnits = Homey.manager('settings').get('currentSettingUnits'); - Homey.log('currentSettingUnits:', currentSettingUnits); + if (fullLogging) Homey.log('currentSettingUnits:', currentSettingUnits); if (units_metric && value_exist(currentSettingUnits)) { if (currentSettingUnits != 'metric') { @@ -321,180 +349,174 @@ var self = { Homey.log(''); Homey.log('appWarning'); Homey.log('data', data); - if (data.count) Homey.log('count: ' + data.count + '/5'); // count: 1/5, 2/5 etc. after count 5, your app is killed + try { + if (data != null && value_exist(data) && data.count) Homey.log('count: ' + data.count + '/5'); // count: 1/5, 2/5 etc. after count 5, your app is killed + } catch(err) { + Homey.log('appWarning error', err); + } }, unload: function() { - Homey.log(''); - Homey.log('appWarning'); + if (fullLogging) Homey.log(''); + if (fullLogging) Homey.log('unload'); if (wunderground != null) { - Homey.log("wunderground != null"); + if (fullLogging) Homey.log("wunderground != null, closing wunderground"); wunderground = null; } }, tempAbove: function(callback, args) { - Homey.log(""); - Homey.log("function temp above"); - Homey.log("Current temp: " + weatherData.temp); - Homey.log("args.variable: " + args.variable); + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("function temp above"); + if (fullLogging) Homey.log("Current temp: " + weatherData.temp); + if (fullLogging) Homey.log("args.variable: " + args.variable); if (weatherData.temp > args.variable) { - Homey.log("temp " + weatherData.temp + " is above " + args.variable + ", triggering temp above trigger"); + if (fullLogging) Homey.log("temp " + weatherData.temp + " is above " + args.variable + ", triggering temp above trigger"); callback("temp " + weatherData.temp + " is above " + args.variable, true); } else { - Homey.log("temp " + weatherData.temp + " is not above " + args.variable); + if (fullLogging) Homey.log("temp " + weatherData.temp + " is not above " + args.variable); callback("temp is not above", false); } }, tempBelow: function(callback, args) { - Homey.log(""); - Homey.log("function temp below"); - Homey.log("Current temp: " + weatherData.temp); - Homey.log("args.variable: " + args.variable); + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("function temp below"); + if (fullLogging) Homey.log("Current temp: " + weatherData.temp); + if (fullLogging) Homey.log("args.variable: " + args.variable); if (weatherData.temp < args.variable) { - Homey.log("temp is below!"); + if (fullLogging) Homey.log("temp is below!"); callback(null, true); } else { - Homey.log("temp is not below"); + if (fullLogging) Homey.log("temp is not below"); callback(null, false); } }, humAbove: function(callback, args) { - Homey.log(""); - Homey.log("function hum above"); - Homey.log("Current hum: " + weatherData.relative_humidity); - Homey.log("args.variable: " + args.variable); + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("function hum above"); + if (fullLogging) Homey.log("Current hum: " + weatherData.relative_humidity); + if (fullLogging) Homey.log("args.variable: " + args.variable); if (weatherData.relative_humidity > args.variable) { - Homey.log("hum is above!"); + if (fullLogging) Homey.log("hum is above!"); callback(null, true); } else { - Homey.log("hum is not above"); + if (fullLogging) Homey.log("hum is not above"); callback(null, false); } }, humBelow: function(callback, args) { - Homey.log(""); - Homey.log("function hum below"); - Homey.log("Current hum: " + weatherData.relative_humidity); - Homey.log("args.variable: " + args.variable); + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("function hum below"); + if (fullLogging) Homey.log("Current hum: " + weatherData.relative_humidity); + if (fullLogging) Homey.log("args.variable: " + args.variable); if (weatherData.relative_humidity < args.variable) { - Homey.log("hum is below!"); + if (fullLogging) Homey.log("hum is below!"); callback(null, true); } else { - Homey.log("hum is not below"); + if (fullLogging) Homey.log("hum is not below"); callback(null, false); } }, uvAbove: function(callback, args) { - Homey.log(""); - Homey.log("function uv above"); - Homey.log("Current uv: " + weatherData.uv); - Homey.log("args.variable: " + args.variable); + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("function uv above"); + if (fullLogging) Homey.log("Current uv: " + weatherData.uv); + if (fullLogging) Homey.log("args.variable: " + args.variable); if (weatherData.uv > args.variable) { - Homey.log("uv is above!"); + if (fullLogging) Homey.log("uv is above!"); callback(null, true); } else { - Homey.log("uv is not above"); + if (fullLogging) Homey.log("uv is not above"); callback(null, false); } }, uvBelow: function(callback, args) { - Homey.log(""); - Homey.log("function uv below"); - Homey.log("Current uv: " + weatherData.uv); - Homey.log("args.variable: " + args.variable); + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("function uv below"); + if (fullLogging) Homey.log("Current uv: " + weatherData.uv); + if (fullLogging) Homey.log("args.variable: " + args.variable); if (weatherData.uv < args.variable) { - Homey.log("uv is below!"); + if (fullLogging) Homey.log("uv is below!"); callback(null, true); } else { - Homey.log("uv is not below"); + if (fullLogging) Homey.log("uv is not below"); callback(null, false); } }, windAbove: function(callback, args) { - Homey.log(""); - Homey.log("function wind above"); - Homey.log("Current wind speed: " + weatherData.wind); - Homey.log("args.variable: " + args.variable); + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("function wind above"); + if (fullLogging) Homey.log("Current wind speed: " + weatherData.wind); + if (fullLogging) Homey.log("args.variable: " + args.variable); if (weatherData.wind > args.variable) { - Homey.log("wind speed is above!"); + if (fullLogging) Homey.log("wind speed is above!"); callback(null, true); } else { - Homey.log("wind speed is not above"); + if (fullLogging) Homey.log("wind speed is not above"); callback(null, false); } }, windBelow: function(callback, args) { - Homey.log(""); - Homey.log("function wind below"); - Homey.log("Current wind: " + weatherData.wind); - Homey.log("args.variable: " + args.variable); + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("function wind below"); + if (fullLogging) Homey.log("Current wind: " + weatherData.wind); + if (fullLogging) Homey.log("args.variable: " + args.variable); if (weatherData.wind < args.variable) { - Homey.log("wind is below!"); + if (fullLogging) Homey.log("wind is below!"); callback(null, true); } else { - Homey.log("wind is not below"); + if (fullLogging) Homey.log("wind is not below"); callback(null, false); } }, windgustAbove: function(callback, args) { - Homey.log(""); - Homey.log("function windgust above"); - Homey.log("Current wind gust: " + weatherData.wind_gust); - Homey.log("args.variable: " + args.variable); + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("function windgust above"); + if (fullLogging) Homey.log("Current wind gust: " + weatherData.wind_gust); + if (fullLogging) Homey.log("args.variable: " + args.variable); if (weatherData.wind_gust > args.variable) { - Homey.log("wind speed is above!"); + if (fullLogging) Homey.log("wind speed is above!"); callback(null, true); } else { - Homey.log("wind speed is not above"); + if (fullLogging) Homey.log("wind speed is not above"); callback(null, false); } }, windgustBelow: function(callback, args) { - Homey.log(""); - Homey.log("function windgust below"); - Homey.log("Current wind gust: " + weatherData.wind_gust); - Homey.log("args.variable: " + args.variable); + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("function windgust below"); + if (fullLogging) Homey.log("Current wind gust: " + weatherData.wind_gust); + if (fullLogging) Homey.log("args.variable: " + args.variable); if (weatherData.wind_gust < args.variable) { - Homey.log("windgust is below!"); + if (fullLogging) Homey.log("windgust is below!"); callback(null, true); } else { - Homey.log("windgust is not below"); + if (fullLogging) Homey.log("windgust is not below"); callback(null, false); } }, //get location getLocation: function(callback) { - Homey.log(""); - Homey.log("getLocation"); - Homey.manager('geolocation').on('location', function (location) { - Homey.log("Homey location changed"); - Homey.log(location); - lat = location.latitude; - lon = location.longitude; - callback(null, location); - }); + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("getLocation"); Homey.manager('geolocation').getLocation(function(err, location) { - if (typeof location.latitude == 'undefined' || location.latitude == 0) { - Homey.log("Location is undefined"); - callback(new Error("location is undefined")); - return; + if (!value_exist(location.latitude) || location.latitude == 0) { + if (fullLogging) Homey.log("Location is undefined"); + callback(true, null); } else { - Homey.log("location found:", location); - lat = location.latitude; - lon = location.longitude; - callback(null, location); + if (fullLogging) Homey.log("location found:", location); + callback(false, location); } }); }, @@ -504,11 +526,15 @@ var self = { Homey.log(""); Homey.log("Update Weather"); Homey.log('Requesting for location', address); + if (!value_exist(address)) { + Homey.log('No valid address data, not updating weather') + return; + } // Get weather data wunderground.conditions().request(address, function(err, response) { - Homey.log('request error:', err); + if (fullLogging) Homey.log('request error:', err); var error = false; var err_msg; @@ -519,55 +545,58 @@ var self = { error = true; } catch(err) { // No error message found so this looks good - Homey.log('No error message found in weather request'); + if (fullLogging) Homey.log('No error message found in weather request'); error = false; } if (!err && response && !error) { - // Cut % sign - var hum = response.current_observation.relative_humidity; - var hum_float = parseFloat(hum.substr(0, (hum.length -1))); + var hum = test_weatherData(response.current_observation.relative_humidity); + try { + // Cut % sign and convert to float + var hum_float = parseWeatherFloat(hum.substr(0, (hum.length -1))); + } catch(err) { + var hum_float = 0; + Homey.log("Error while parsing relative_humidity to float, setting to 0"); + } // Use correct user units if (units_metric) { - Homey.log('Using metric units'); - var temp = parseFloat(response.current_observation.temp_c); - var feelslike = parseFloat(response.current_observation.feelslike_c); - var dewpoint = parseFloat(response.current_observation.dewpoint_c); - var pressure = parseFloat(response.current_observation.pressure_mb); - var wind = parseFloat(response.current_observation.wind_kph); - var wind_gust = parseFloat(response.current_observation.wind_gust_kph); - var visibility = parseFloat(response.current_observation.visibility_km); - var precip_1hr = parseFloat(response.current_observation.precip_1hr_metric); - var precip_today = parseFloat(response.current_observation.precip_today_metric); + if (fullLogging) Homey.log('Using metric units'); + var temp = parseWeatherFloat(test_weatherData(response.current_observation.temp_c)); + var feelslike = parseWeatherFloat(test_weatherData(response.current_observation.feelslike_c)); + var dewpoint = parseWeatherFloat(test_weatherData(response.current_observation.dewpoint_c)); + var pressure = parseWeatherFloat(test_weatherData(response.current_observation.pressure_mb)); + var wind = parseWeatherFloat(test_weatherData(response.current_observation.wind_kph)); + var wind_gust = parseWeatherFloat(test_weatherData(response.current_observation.wind_gust_kph)); + var visibility = parseWeatherFloat(test_weatherData(response.current_observation.visibility_km)); + var precip_1hr = parseWeatherFloat(test_weatherData(response.current_observation.precip_1hr_metric)); + var precip_today = parseWeatherFloat(test_weatherData(response.current_observation.precip_today_metric)); } else { - Homey.log('Using imperial units'); - var temp = parseFloat(response.current_observation.temp_f); - var feelslike = parseFloat(response.current_observation.feelslike_f); - var dewpoint = parseFloat(response.current_observation.dewpoint_f); - var pressure = parseFloat(response.current_observation.pressure_in); - var wind = parseFloat(response.current_observation.wind_mph); - var wind_gust = parseFloat(response.current_observation.wind_gust_mph); - var visibility = parseFloat(response.current_observation.visibility_mi); - var precip_1hr = parseFloat(response.current_observation.precip_1hr_in); - var precip_today = parseFloat(response.current_observation.precip_today_in); + if (fullLogging) Homey.log('Using imperial units'); + var temp = parseWeatherFloat(test_weatherData(response.current_observation.temp_f)); + var feelslike = parseWeatherFloat(test_weatherData(response.current_observation.feelslike_f)); + var dewpoint = parseWeatherFloat(test_weatherData(response.current_observation.dewpoint_f)); + var pressure = parseWeatherFloat(test_weatherData(response.current_observation.pressure_in)); + var wind = parseWeatherFloat(test_weatherData(response.current_observation.wind_mph)); + var wind_gust = parseWeatherFloat(test_weatherData(response.current_observation.wind_gust_mph)); + var visibility = parseWeatherFloat(test_weatherData(response.current_observation.visibility_mi)); + var precip_1hr = parseWeatherFloat(test_weatherData(response.current_observation.precip_1hr_in)); + var precip_today = parseWeatherFloat(test_weatherData(response.current_observation.precip_today_in)); } - // Reset values they where not a number or below zero - if (precip_1hr == "NaN") precip_1hr = 0; - if (precip_today == "NaN") precip_today = 0; - var uv = parseFloat(response.current_observation.UV); + // Reset values they are below zero + var uv = parseWeatherFloat(test_weatherData(response.current_observation.UV)); if (uv < 0) uv = 0; weatherData = { - city: response.current_observation.display_location.city, - country: response.current_observation.display_location.country, - weather_descr: response.current_observation.weather, + city: test_weatherData(response.current_observation.display_location.city), + country: test_weatherData(response.current_observation.display_location.country), + weather_descr: test_weatherData(response.current_observation.weather), relative_humidity: hum_float, - observation_epoch: response.current_observation.observation_epoch, - wind_degrees: parseFloat(response.current_observation.wind_degrees), - wind_dir: response.current_observation.wind_dir, + observation_epoch: test_weatherData(response.current_observation.observation_epoch), + wind_degrees: parseWeatherFloat((test_weatherData(response.current_observation.wind_degrees))), + wind_dir: test_weatherData(response.current_observation.wind_dir), uv: uv, temp: temp, feelslike: feelslike, @@ -582,20 +611,20 @@ var self = { Homey.log("Current time: " + new Date()); Homey.log("Observation time: " + epochToString(weatherData.observation_epoch)); - Homey.log("Weather data:"); - Homey.log(weatherData); + if (fullLogging) Homey.log("Weather data:"); + if (fullLogging) Homey.log(weatherData); // Temperature triggers and conditions if (value_exist(weatherData.temp)) { // Determine if the temp has changed if (!value_exist(oldTemp)){ - Homey.log("No oldTemp value exists, maybe it's the first start of app"); + if (fullLogging) Homey.log("No oldTemp value exists, maybe it's the first start of app"); // First time update after reboot/install oldTemp = weatherData.temp; } else if (diff(oldTemp, weatherData.temp) >= 1) { // Only trigger when difference is equal or more then 1 degree - Homey.log("oldTemp: " + oldTemp + " temp: " + weatherData.temp); + if (fullLogging) Homey.log("oldTemp: " + oldTemp + " temp: " + weatherData.temp); oldTemp = weatherData.temp; self.tempChanged(weatherData.temp, weatherData.relative_humidity, weatherData.weather_descr); } @@ -615,7 +644,7 @@ var self = { oldHum = weatherData.relative_humidity; } else if (diff(oldHum, weatherData.relative_humidity) >= 1) { // Only trigger when difference is equal or more then 1 percent - Homey.log("oldHum: " + oldHum + " hum: " + weatherData.relative_humidity); + if (fullLogging) Homey.log("oldHum: " + oldHum + " hum: " + weatherData.relative_humidity); oldHum = weatherData.relative_humidity; self.humChanged(weatherData.temp, weatherData.relative_humidity, weatherData.weather_descr); } @@ -682,7 +711,7 @@ var self = { var tokens = {'temp': temp, 'hum': hum, 'weather_descr': weather_descr}; - Homey.log("Sending trigger temp_changed with tokens: " + JSON.stringify(tokens)); + if (fullLogging) Homey.log("Sending trigger temp_changed with tokens: " + JSON.stringify(tokens)); Homey.manager('flow').trigger('temp_changed', tokens); }, @@ -691,7 +720,7 @@ var self = { var tokens = {'temp': temp, 'hum': hum, 'weather_descr': weather_descr}; - Homey.log("Sending trigger hum_changed with tokens: " + JSON.stringify(tokens)); + if (fullLogging) Homey.log("Sending trigger hum_changed with tokens: " + JSON.stringify(tokens)); Homey.manager('flow').trigger('hum_changed', tokens); }, @@ -787,7 +816,7 @@ var self = { // Let's check all required logs are there on Homey for (var l in insightsLogs) { if (currentInsightLogs.indexOf(insightsLogs[l]) < 0) { - Homey.log("Log " + insightsLogs[l] + " is not on Homey"); + if (fullLogging) Homey.log("Log " + insightsLogs[l] + " is not on Homey"); self.createInsightsLogs(insightsLogs[l]); } } @@ -796,10 +825,10 @@ var self = { }, createInsightsLogs: function(log) { - Homey.log(""); - Homey.log("createInsightsLogs"); - Homey.log("Create Insights log: " + log); - Homey.log("Metric units", units_metric); + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("createInsightsLogs"); + if (fullLogging) Homey.log("Create Insights log: " + log); + if (fullLogging) Homey.log("Metric units", units_metric); var temp_unit; var distance_unit; @@ -817,10 +846,10 @@ var self = { if (units_auto && value_exist(homey_units) && homey_units != "") { Homey.manager('settings').set('currentSettingUnits', 'auto'); if (homey_units == 'metric') { - Homey.log('Autodetected metric units'); + if (fullLogging) Homey.log('Autodetected metric units'); units_metric = true; } else { - Homey.log('Autodetected imperial units'); + if (fullLogging) Homey.log('Autodetected imperial units'); units_metric = false; } } @@ -1103,7 +1132,6 @@ var self = { } function testWU(callback, args) { - Homey.log(""); Homey.log("TestWU API call"); @@ -1114,7 +1142,7 @@ function testWU(callback, args) { Homey.log('Testing for location:', address); if (!value_exist(wundergroundKey) || wundergroundKey == "" || wundergroundKey == null) { - Homey.log("Weather underground key is empty, using Inversion key"); + if (fullLogging) Homey.log("Weather underground key is empty, using Inversion key"); wundergroundKey = Homey.env.WUNDERGROUND_KEY; } else Homey.log('Using user defined Weather Underground key'); @@ -1153,7 +1181,7 @@ function testWU(callback, args) { } if (!err && !error) { - Homey.log("Weather response received"); + if (fullLogging) Homey.log("Weather response received"); // Return specific data var temp = response.current_observation.temp_c; diff --git a/app.json b/app.json index f842316..4b93e76 100644 --- a/app.json +++ b/app.json @@ -9,7 +9,7 @@ "en": "Informs you about the weather", "nl": "Geeft je informatie over het weer" }, - "version": "0.1.0", + "version": "0.2.0", "compatibility": ">=0.8.29", "category": "internet", "author": { diff --git a/settings/index.html b/settings/index.html index 3a1049c..237504e 100644 --- a/settings/index.html +++ b/settings/index.html @@ -14,7 +14,7 @@

- +

@@ -94,44 +94,46 @@

Homey.get('country', function(err, country) { if (err) { - console.error(err) - } else { - document.getElementById('country').value = country; - currentValues.country = country; + console.error(err); + country = 'Netherlands'; } + document.getElementById('country').value = country; + currentValues.country = country; }) Homey.get('city', function(err, city) { if (err) { - console.error(err) - } else { - document.getElementById('city').value = city; - currentValues.city = city; + console.error(err); + city = 'Amsterdam' } + document.getElementById('city').value = city; + currentValues.city = city; }) Homey.get('updateFrequenty', function(err, updateFrequenty) { if (err) { - console.error(err) - } else { - document.getElementById('updateFrequenty').value = updateFrequenty; - currentValues.updateFrequenty = updateFrequenty; + console.error(err); + updateFrequenty = 60; } + if (typeof updateFrequenty == 'undefined' || updateFrequenty == null) updateFrequenty = 60; + document.getElementById('updateFrequenty').value = updateFrequenty; + currentValues.updateFrequenty = updateFrequenty; }) Homey.get('autolocation', function(err, autolocation) { if (err) { - console.error(err) - } else { - document.getElementById('autolocation').checked = autolocation; - document.getElementById('locationfields').disabled = autolocation; - currentValues.autolocation = autolocation; + console.error(err); + autolocation = true; } + if (typeof autolocation == 'undefined' || autolocation == null) autolocation = true; + document.getElementById('autolocation').checked = autolocation; + document.getElementById('locationfields').disabled = autolocation; + currentValues.autolocation = autolocation; }) Homey.get('wundergroundKey', function(err, wundergroundKey) { if (err) { - Homey.error(err) + Homey.error(err); } else { document.getElementById('wundergroundKey').value = wundergroundKey; currentValues.wundergroundKey = wundergroundKey; @@ -140,16 +142,16 @@

Homey.get('units_auto', function(err, units_auto) { if (err) { - Homey.error(err) - } else { - document.getElementById('units_auto').checked = units_auto; - currentValues.units_auto = units_auto; + Homey.error(err); + units_auto = true; } + document.getElementById('units_auto').checked = units_auto; + currentValues.units_auto = units_auto; }) Homey.get('units_metric', function(err, units_metric) { if (err) { - Homey.error(err) + Homey.error(err); } else { document.getElementById('units_metric').checked = units_metric; currentValues.units_metric = units_metric; From da61ef5433130d70598b85b1120a30e67dffbbbc Mon Sep 17 00:00:00 2001 From: Robin van Kekem Date: Wed, 15 Jun 2016 19:19:53 +0200 Subject: [PATCH 2/3] add forecast-1 --- app.js | 112 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 90 insertions(+), 22 deletions(-) diff --git a/app.js b/app.js index ec52c93..bdc518e 100644 --- a/app.js +++ b/app.js @@ -22,7 +22,8 @@ var insightsLogs = "visibility" ]; -var interval; +var weatherInterval; +var forecastInterval; var update_frequenty = defaultUpdateTime; var locationGetCounter = 1; var difMinute; @@ -125,23 +126,53 @@ var self = { // Check settings and start updating weather self.checkSettings(); + + // Print current date and time + Homey.log("Current time: " + new Date()); }, scheduleWeather: function(update_frequenty) { Homey.log(""); Homey.log("Schedule weather"); - if (interval) { - Homey.log("Clearing current interval", interval); - clearInterval(interval); + if (weatherInterval) { + Homey.log("Clearing current weatherInterval", weatherInterval); + clearInterval(weatherInterval); + } + + if (update_frequenty == null || update_frequenty == 0 || isNaN(update_frequenty)) { + Homey.log("Update_frequenty out of bounds, reset to default", update_frequenty); + update_frequenty = defaultUpdateTime; } - interval = setInterval(trigger_update.bind(this), update_frequenty * 60 * 1000); // From minutes to milliseconds - if (fullLogging) Homey.log('Interval:', interval); + var updateTime = update_frequenty * 60 * 1000; + weatherInterval = setInterval(trigger_update.bind(this), updateTime); // From minutes to milliseconds + if (fullLogging) Homey.log('weatherInterval:', weatherInterval); function trigger_update() { self.updateWeather(); }; - + }, + + scheduleForecast: function(update_frequenty) { + Homey.log(""); + Homey.log("Schedule forecast"); + + if (forecastInterval) { + Homey.log("Clearing current forecastInterval", forecastInterval); + clearInterval(forecastInterval); + } + + if (update_frequenty == null || update_frequenty == 0 || isNaN(update_frequenty)) { + Homey.log("Update_frequenty out of bounds, reset to default", update_frequenty); + update_frequenty = defaultUpdateTime; + } + + var updateTime = update_frequenty * 60 * 1000; + forecastInterval = setInterval(trigger_update.bind(this), updateTime); // From minutes to milliseconds + if (fullLogging) Homey.log('forecastInterval:', forecastInterval); + function trigger_update() { + self.updateForecast(); + }; }, setUnits: function() { @@ -231,6 +262,7 @@ var self = { Homey.log("Using lat lon for location"); address = lat + ',' + lon; self.scheduleWeather(update_frequenty); + self.scheduleForecast(update_frequenty); } else { Homey.log("Lat lon data invalid"); @@ -244,6 +276,7 @@ var self = { lon = location.longitude; address = lat + ',' + lon; self.scheduleWeather(update_frequenty); + self.scheduleForecast(update_frequenty); // Found location, reset counter locationGetCounter = 0; return; @@ -253,10 +286,12 @@ var self = { Homey.log("Max location detection attempts reached, using country and city for location"); address = country + '/' + city; self.scheduleWeather(update_frequenty); + self.scheduleForecast(update_frequenty); } else { Homey.log("Max location detection attempts reached and one of the country/city fields is empty, using defaults"); address = "Netherlands/Amsterdam"; self.scheduleWeather(update_frequenty); + self.scheduleForecast(update_frequenty); } } } else if (value_exist(country) && value_exist(city) && country != "" && city != "") { @@ -264,10 +299,12 @@ var self = { Homey.log("Using country and city for location"); address = country + '/' + city; self.scheduleWeather(update_frequenty); + self.scheduleForecast(update_frequenty); } else { Homey.log("One of the country/city fields is empty, setting to autolocation which will trigger checkSettings() again"); Homey.manager('settings').set('autolocation', true); self.scheduleWeather(update_frequenty); + self.scheduleForecast(update_frequenty); } }, @@ -521,6 +558,50 @@ var self = { }); }, + // test the Wunderground response for errors + testResponse: function(err, result) { + + if (err) return true; + + var err_msg; + try { + // If error is in the response, something must have gone wrong + err_msg = result.response.error.description; + Homey.log('Error:', err_msg); + return true; + } catch(err) { + // No error message found so this looks good + if (fullLogging) Homey.log('No error message found in weather request'); + return false; + } + }, + + // update the forecast + updateForecast: function() { + Homey.log(""); + Homey.log("Update forecast"); + Homey.log('Requesting for location', address); + + if (!value_exist(address)) { + Homey.log('No valid address data, not fetching forecast') + return; + } + + // Get forecast data + wunderground.forecast().request(address, function(err, response) { + Homey.log(""); + Homey.log("updateForecast response"); + + var error = self.testResponse(err, response); + + if (response && !error) { + Homey.log("Response:"); + var data = response.forecast.txt_forecast.forecastday + Homey.log(data); + } + }); + }, + // update the weather updateWeather: function() { Homey.log(""); @@ -534,22 +615,9 @@ var self = { // Get weather data wunderground.conditions().request(address, function(err, response) { - if (fullLogging) Homey.log('request error:', err); - - var error = false; - var err_msg; - try { - // If error is in the response, something must have gone wrong - err_msg = result.response.error.description; - Homey.log('Error:', err_msg); - error = true; - } catch(err) { - // No error message found so this looks good - if (fullLogging) Homey.log('No error message found in weather request'); - error = false; - } + var error = self.testResponse(err, response); - if (!err && response && !error) { + if (response && !error) { var hum = test_weatherData(response.current_observation.relative_humidity); try { From cb651a3e6bd5a2843d4f4b7aee6f7f8f949accf8 Mon Sep 17 00:00:00 2001 From: Robin van Kekem Date: Fri, 22 Jul 2016 12:05:14 +0200 Subject: [PATCH 3/3] * Better checks to prevent undefined crashes * Built in triggers to read the weather forecast * Flow action to read the weather (Read in Homey's set language!) --- README.md | 34 +- app.js | 304 ++++++++++++++---- app.json | 141 +++++++- locales/en.json | 10 + locales/nl.json | 10 + .../wundergroundnode/lib/wundergroundnode.js | 5 +- 6 files changed, 440 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index dc14c18..e8e4a47 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,14 @@ Want to close your windows screen when the wind picks up? Want to be notified when the levels of UV become high risk? Weather Underground app helps you accomplish these! +#Built in voice triggers +* Read Weather forecast + * Read forecast for today (*Okay homey weather for today*) + * Read forecast for tomorrow (*Okay homey weather for tomorrow*) + * Read forecast for day after tomorrow (*Okay homey weather for day after tomorrow*) + * Read how many rain has fallen today, until now (*Okay homey rainfall today*) + * Read how many rain has fallen the past hour (*Okay homey rainfall this hour*) + #Flow triggers * Temperature has changed @@ -34,6 +42,16 @@ Weather Underground app helps you accomplish these! * Wind gust is below an certain speed +#Flow actions +* Read forecast for today +* Read forecast for tonight +* Read forecast for tomorrow +* Read forecast for tomorrow night +* Read forecast for day after tomorrow +* Read forecast for rain this hour +* Read forecast for rain today + + #Insights * Temperature * Humidity @@ -57,7 +75,6 @@ If you don't have a key the app uses my key and will update every 60 minutes. #Future functions -* Read Weather forecast * Trigger/condition on current weather condition (Cloudy, Raining etc) * Trigger on weather alerts * Average/high/low temperature on this date @@ -65,5 +82,18 @@ If you don't have a key the app uses my key and will update every 60 minutes. * Much more! +#Changes +* Version 2.0 + * Better checks to prevent undefined crashes + * Built in triggers to read the weather forecast + * Flow action to read the weather (Read in Homey's set language!) + + +#Donate +This is an open source application and totaly free. +By donating you support me in my work of which I do in my own free time. +[![Paypal Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=AY82R46VQSSS2&lc=US&item_name=Weather%20Underground%20App%20for%20Homey&item_number=wunderground_homey¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted) + + #Source -https://github.com/Inversion-NL/nl.inversion.wunderground +https://github.com/Inversion-NL/nl.inversion.wunderground \ No newline at end of file diff --git a/app.js b/app.js index bdc518e..495e884 100644 --- a/app.js +++ b/app.js @@ -3,11 +3,11 @@ var Wunderground = require('wundergroundnode'); var wunderground; -var defaultUpdateTime = 10; +var defaultUpdateTime = 60; var maxLocationGetTries = 3; var units_metric; var insightsLogs = -[ + [ "temp", "hum", "feelslike", @@ -30,7 +30,9 @@ var difMinute; var lat = null; var lon = null; var address; +var unitData = {}; var weatherData = {}; +var forecastData = {}; // Enable full logging for more info var fullLogging = false; @@ -73,6 +75,12 @@ function diff(a,b) { return Math.abs(a-b); } +function isInt(value) { + return !isNaN(value) && + parseInt(Number(value)) == value && + !isNaN(parseInt(value, 10)); +} + var self = { // this `init` function will be run when Homey is done loading init: function() { @@ -83,6 +91,26 @@ var self = { self.checkInsightsLogs(); // Listen for triggers and conditions + self.registerTriggerAndConditionListeners; + + // Listen for speech input + Homey.manager('speech-input').on('speech', self.parseSpeach); + + // Listen for changes in settings + Homey.log("Registering settings listener"); + Homey.manager('settings').on('set', self.settingsChanged); + + // Listen for Homey app warnings and performance triggers + self.registerWarningAndPerformanceListeners; + + // Check settings and start updating weather + self.checkSettings(); + + // Print current date and time + Homey.log("Current time: " + new Date()); + }, + + registerTriggerAndConditionListeners: function() { Homey.log("Registering trigger and condition listeners") Homey.manager('flow').on('trigger.temp_above', self.tempAbove); Homey.manager('flow').on('condition.temp_above', self.tempAbove); @@ -108,12 +136,17 @@ var self = { Homey.manager('flow').on('condition.windgust_above', self.windgustAbove); Homey.manager('flow').on('trigger.windgust_below', self.windgustBelow); Homey.manager('flow').on('condition.windgust_below', self.windgustBelow); - - // Listen for changes in settings - Homey.log("Registering settings listener"); - Homey.manager('settings').on('set', self.settingsChanged); - - // Listen for Homey app warnings and performance triggers + + Homey.manager('flow').on('action.readForecast_today', self.readForecast_today); + Homey.manager('flow').on('action.readForecast_today', self.readForecast_tonight); + Homey.manager('flow').on('action.readForecast_tomorrow', self.readForecast_tomorrow); + Homey.manager('flow').on('action.readForecast_tomorrow', self.readForecast_tomorrowNight); + Homey.manager('flow').on('action.readForecast_dayAfterTomorrow', self.readForecast_dayAfterTomorrow); + Homey.manager('flow').on('action.readRain_hour', self.readRain_hour); + Homey.manager('flow').on('action.readRain_today', self.readRain_today); + }, + + registerWarningAndPerformanceListeners: function() { try { Homey.log("Registering several app warning and performance listeners"); Homey.on('cpuwarn', self.appWarning); @@ -123,12 +156,6 @@ var self = { } catch (err) { Homey.log('Registration for one of the app warning and performance listeners failed!') } - - // Check settings and start updating weather - self.checkSettings(); - - // Print current date and time - Homey.log("Current time: " + new Date()); }, scheduleWeather: function(update_frequenty) { @@ -141,7 +168,7 @@ var self = { } if (update_frequenty == null || update_frequenty == 0 || isNaN(update_frequenty)) { - Homey.log("Update_frequenty out of bounds, reset to default", update_frequenty); + Homey.log("Update_frequenty out of bounds, reset to default: ", update_frequenty); update_frequenty = defaultUpdateTime; } @@ -163,7 +190,7 @@ var self = { } if (update_frequenty == null || update_frequenty == 0 || isNaN(update_frequenty)) { - Homey.log("Update_frequenty out of bounds, reset to default", update_frequenty); + Homey.log("Update_frequenty out of bounds, reset to default: ", update_frequenty); update_frequenty = defaultUpdateTime; } @@ -197,6 +224,28 @@ var self = { // Something is wrong here, none of the radio buttons are checked! Homey.log('No unit value existed, resetting to auto'); Homey.manager('settings').set('units_auto', 'true'); + + // Let check the units again + self.setUnits(); + return; + } + + if (units_metric) { + unitData = { + temp_unit : "°C", + distance_unit : 'km', + speed_unit : 'kmh', + pressure_unit : 'mbar', + distance_small_unit : 'mm' + } + } else { + unitData = { + temp_unit : "°F", + distance_unit : 'mi', + speed_unit : 'mph', + pressure_unit : 'inch', + distance_small_unit : 'in' + } } }, @@ -315,7 +364,11 @@ var self = { if (fullLogging) Homey.log("wunderground != null"); //wunderground = null; } - wunderground = new Wunderground(key); + + var language = Homey.manager('i18n').getLanguage(); + if (!value_exist(language)) language = 'EN'; + Homey.log('Setting language to', language); + wunderground = new Wunderground(key, language); }, settingsChanged: function(settingname) { @@ -542,6 +595,67 @@ var self = { } }, + readForecast_today: function(args) { + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("function readForecast_today"); + if (value_exist(forecastData) && forecastData.length > 0) { + self.readForecast(0); + callback(null, true); + } else { + Homey.manager('speech-output').say(__("app.speech.weatherDataNotAvailable")); + callback(null, true); + } + }, + + readForecast_tonight: function(args) { + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("function readForecast_tonight"); + if (value_exist(forecastData) && forecastData.length > 0) { + self.readForecast(1); + callback(null, true); + } else { + Homey.manager('speech-output').say(__("app.speech.weatherDataNotAvailable")); + callback(null, true); + } + }, + + readForecast_tomorrow: function(args) { + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("function readForecast_tomorrow"); + if (value_exist(forecastData) && forecastData.length > 0) { + self.readForecast(2); + callback(null, true); + } else { + Homey.manager('speech-output').say(__("app.speech.weatherDataNotAvailable")); + callback(null, true); + } + }, + + readForecast_tomorrowNight: function(args) { + if (fullLogging) Homey.log(""); + if (fullLogging) Homey.log("function readForecast_tomorrowNight"); + if (value_exist(forecastData) && forecastData.length > 0) { + self.readForecast(3); + callback(null, true); + } else { + Homey.manager('speech-output').say(__("app.speech.weatherDataNotAvailable")); + callback(null, true); + } + }, + + readForecast: function(day) { + var forecastText; + if (isInt(day)) { + if (units_metric) + forecastText = forecastData[day].fcttext_metric; + else + forecastText = forecastData[day].fcttext; + + if (value_exist(forecastText)) Homey.manager('speech-output').say(forecastText); + else Homey.manager('speech-output').say(__("app.speech.somethingWrong")); + } + }, + //get location getLocation: function(callback) { if (fullLogging) Homey.log(""); @@ -595,9 +709,9 @@ var self = { var error = self.testResponse(err, response); if (response && !error) { - Homey.log("Response:"); - var data = response.forecast.txt_forecast.forecastday - Homey.log(data); + forecastData = response.forecast.txt_forecast.forecastday; + } else { + // Do something here } }); }, @@ -898,44 +1012,11 @@ var self = { if (fullLogging) Homey.log("Create Insights log: " + log); if (fullLogging) Homey.log("Metric units", units_metric); - var temp_unit; - var distance_unit; - var speed_unit; - var pressure_unit; - var distance_small_unit; - - // On very first start units aren't - if (!value_exist(units_metric)) { - units_metric = Homey.manager('settings').get('units_metric'); - var units_imperial = Homey.manager('settings').get('units_imperial'); - var units_auto = Homey.manager('settings').get('units_auto'); - var homey_units = Homey.manager('i18n').getUnits(); - - if (units_auto && value_exist(homey_units) && homey_units != "") { - Homey.manager('settings').set('currentSettingUnits', 'auto'); - if (homey_units == 'metric') { - if (fullLogging) Homey.log('Autodetected metric units'); - units_metric = true; - } else { - if (fullLogging) Homey.log('Autodetected imperial units'); - units_metric = false; - } - } - } - - if (units_metric) { - temp_unit = "°C"; - distance_unit = 'km'; - speed_unit = 'kmh'; - pressure_unit = 'mbar'; - distance_small_unit = 'mm'; - } else { - temp_unit = "°F"; - distance_unit = 'mi'; - speed_unit = 'mph'; - pressure_unit = 'inch'; - distance_small_unit = 'in'; - } + var temp_unit = unitData.temp_unit; + var distance_unit = unitData.distance_unit; + var speed_unit = unitData.speed_unit; + var pressure_unit = unitData.pressure_unit; + var distance_small_unit = unitData.distance_small_unit; switch(log) { case 'temp': @@ -1196,6 +1277,113 @@ var self = { Homey.manager('insights').createEntry(logName, value, new Date(), function(err, success){ if (err) return Homey.error(err); }) + }, + + parseSpeach: function(speech, callback) { + Homey.log(""); + Homey.log("parseSpeach"); + + // On very first start units aren't always there yet + if (!value_exist(units_metric)) { + units_metric = Homey.manager('settings').get('units_metric'); + var units_imperial = Homey.manager('settings').get('units_imperial'); + var units_auto = Homey.manager('settings').get('units_auto'); + var homey_units = Homey.manager('i18n').getUnits(); + + if (units_auto && value_exist(homey_units) && homey_units != "") { + Homey.manager('settings').set('currentSettingUnits', 'auto'); + if (homey_units == 'metric') { + if (fullLogging) Homey.log('Autodetected metric units'); + units_metric = true; + } else { + if (fullLogging) Homey.log('Autodetected imperial units'); + units_metric = false; + } + } + } + + self.updateForecast(); + self.updateWeather(); + + if (value_exist(forecastData) && forecastData.length > 0 && value_exist(weatherData) && Object.keys(weatherData).length > 0) { + Homey.log("Weather and forecast data available"); + + /* Units available: + var temp_unit = unitData.temp_unit; + var distance_unit = unitData.distance_unit; + var speed_unit = unitData.speed_unit; + var pressure_unit = unitData.pressure_unit; + var distance_small_unit = unitData.distance_small_unit; + */ + + speech.triggers.some(function (trigger) { + + switch (trigger.id) { + case 'weather_tomorrow' : + Homey.log("weather_tomorrow"); + var forecastText; + + if (units_metric) + forecastText = forecastData[2].fcttext_metric; + else + forecastText = forecastData[2].fcttext; + + speech.say(forecastText); + callback(null, true); + return true; + + case 'weather_dayAfterTomorrow' : + Homey.log("weather_dayAfterTomorrow"); + var forecastText; + + if (units_metric) + forecastText = forecastData[4].fcttext_metric; + else + forecastText = forecastData[4].fcttext; + + speech.say(forecastText); + callback(null, true); + return true; + + case 'weather_today' : + Homey.log("weather_today"); + var forecastText; + + if (units_metric) + forecastText = forecastData[0].fcttext_metric; + else + forecastText = forecastData[0].fcttext; + + speech.say(forecastText); + callback(null, true); + return true; + + case 'rain_today' : + Homey.log("rain_today"); + var text = __("app.speech.rainToday") + " " + weatherData.precip_today + unitData.distance_small_unit; + speech.say(text); + text = ""; + callback(null, true); + return true; + + case 'rain_hour' : + Homey.log("rain_hour"); + var text = __("app.speech.rainToday") + " " + weatherData.precip_1hr + unitData.distance_small_unit; + speech.say(text); + text = ""; + callback(null, true); + return true; + + default: + // Guess it wasn't meant for this app, return that in the callback + callback(true, null); + } + }); + } else { + if (fullLogging) Homey.log("!! Weather and forecast not available"); + speech.say(__("app.speech.weatherDataNotAvailableYet")); + callback(null, true); + } } } diff --git a/app.json b/app.json index 4b93e76..335fb48 100644 --- a/app.json +++ b/app.json @@ -5,10 +5,12 @@ "en": "Weather Underground", "nl": "Weather Underground" }, + "description": { "en": "Informs you about the weather", "nl": "Geeft je informatie over het weer" }, + "version": "0.2.0", "compatibility": ">=0.8.29", "category": "internet", @@ -16,16 +18,22 @@ "name": "Inversion NL", "email": "inversion-nl@gmail.com" }, + "permissions": [ - "homey:manager:geolocation" + "homey:manager:geolocation", + "homey:manager:speech-input", + "homey:manager:speech-output" ], + "images": { "large": "./assets/images/large.jpg", "small": "./assets/images/small.jpg" }, + "dependencies": { "wundernode": "*" }, + "flow": { "triggers": [ @@ -733,6 +741,135 @@ } ] } + ], + + "actions": [ + { + "id": "readForecast_today", + "title": { + "en": "Read forecast for today", + "nl": "Weersvoorspelling voor vandaag oplezen" + } + }, + { + "id": "readForecast_tonight", + "title": { + "en": "Read forecast for tonight", + "nl": "Weersvoorspelling voor vanavond oplezen" + } + }, + { + "id": "readForecast_tomorrow", + "title": { + "en": "Read forecast for tomorrow", + "nl": "Weersvoorspelling voor morgen oplezen" + } + }, + { + "id": "readForecast_tomorrowNight", + "title": { + "en": "Read forecast for tomorrow night", + "nl": "Weersvoorspelling voor morgenavond oplezen" + } + }, + { + "id": "readForecast_dayAfterTomorrow", + "title": { + "en": "Read forecast for day after tomorrow", + "nl": "Weersvoorspelling voor overmorgen oplezen" + } + }, + { + "id": "readRain_hour", + "title": { + "en": "Read amount of rain this hour", + "nl": "Regen hoeveelheid dit uur oplezen" + } + }, + { + "id": "readRain_today", + "title": { + "en": "Read amount of rain today", + "nl": "Regen hoeveelheid vandaag oplezen" + } + } + ] + }, + + + "speech": [ + { + "id": "weather_tomorrow", + "importance": 0.7, + "triggers": { + "en": [ + "weather tomorrow", + "weather for tomorrow" + ], + "nl": [ + "weer morgen", + "weer voor morgen" + ] + } + }, + + { + "id": "weather_dayAfterTomorrow", + "importance": 0.7, + "triggers": { + "en": [ + "weather day after tomorrow", + "weather for the day after tomorrow" + ], + "nl": [ + "weer overmorgen", + "weer voor overmorgen" + ] + } + }, + + { + "id": "weather_today", + "importance": 0.7, + "triggers": { + "en": [ + "weather today", + "weather for today" + ], + "nl": [ + "weer vandaag", + "weer voor vandaag" + ] + } + }, + { + "id": "rain_today", + "importance": 0.7, + "triggers": { + "en": [ + "rainfall today", + "rain is fallen today" + ], + "nl": [ + "regen is er vandaag gevallen", + "regen vandaag", + "regen valt er vandaag" + ] + } + }, + { + "id": "rain_hour", + "importance": 0.7, + "triggers": { + "en": [ + "rainfall this hour", + "rain has fallen this hour" + ], + "nl": [ + "regen is er dit uur gevallen", + "regen dit uur" ] + } } -} + ] +} \ No newline at end of file diff --git a/locales/en.json b/locales/en.json index 97b0ee8..9177765 100644 --- a/locales/en.json +++ b/locales/en.json @@ -46,5 +46,15 @@ "settings_unexpectedError" : "Unexpected error occured. Please try again" } } + }, + + "app" : { + "speech" : { + "weatherDataNotAvailableYet" : "I'm sorry, weather data isn't available yet. Please try again later", + "weatherDataNotAvailable" : "I'm sorry, weather data isn't available. Please try again later", + "somethingWrong" : "I'm sorry, something went wrong. Please try again later", + "rainToday" : "Today it has been raining", + "rainHour" : "The past hour it has rained" + } } } \ No newline at end of file diff --git a/locales/nl.json b/locales/nl.json index 213ed3e..b0fe2e5 100644 --- a/locales/nl.json +++ b/locales/nl.json @@ -46,5 +46,15 @@ "settings_unexpectedError" : "Onverwachte fout opgetreden. Probeer nogmaals a.u.b." } } + }, + + "app" : { + "speech" : { + "weatherDataNotAvailableYet" : "Sorry, weer gegevens nog niet opgehaald. Probeer het later nogmaals", + "weatherDataNotAvailable" : "Sorry, weer gegevens niet beschikbaar. Probeer het later nogmaals", + "somethingWrong" : "Sorry, er is iets mis gegaan. Probeer het later nogmaals", + "rainToday" : "Vandaag heeft het tot nu toe", + "rainHour" : "Het afgelopen uur heeft het" + } } } \ No newline at end of file diff --git a/node_modules/wundergroundnode/lib/wundergroundnode.js b/node_modules/wundergroundnode/lib/wundergroundnode.js index 4ac621a..407be1e 100644 --- a/node_modules/wundergroundnode/lib/wundergroundnode.js +++ b/node_modules/wundergroundnode/lib/wundergroundnode.js @@ -2,7 +2,7 @@ var request = require('request'); var _ = require('underscore'); var moment = require('moment'); -var Wunderground = function(apikey) { +var Wunderground = function(apikey, language) { "use strict"; var that = this; @@ -127,7 +127,8 @@ var Wunderground = function(apikey) { } // Construct the url - var url = 'http://api.wunderground.com/api/' + apikey + '/' + that.chainedRequests.join('') + 'q/'+query + format; + var url = 'http://api.wunderground.com/api/' + apikey + '/' + that.chainedRequests.join('') + 'lang:' + language.toUpperCase() + '/q/' + query + format; + Homey.log('constructed url', url); that.chainedRequests = []; // Request the url