Read the statement by Michael Teeuw here.
Module Intermittently Updating
-
Hi,
I am a total novice with JS, but have re-arranged the weather module to display my home weather station data instead of OpenWeathers data. The module works, but I’m having issues with it intermittently updating the data. In other words, the module will work and update fine for several days (or hours) and then will stop updating, and will show the same data until I restart MM or the pi. The other modules work fine on the MM, and per the weather station API page, I’m not exceeding the call limits. Only error I’m seeing on my Chrome console is:
“Uncaught SyntaxError: Unexpected end of JSON input
at JSON.parse ()
at weatherRequest1.onreadystatechange (MMM-AW.js:187:30)”,which to be honest I’m not sure what it means…
Appreciate any help! My config is attached. ```
Module.register(“MMM-AW”,{// Default module config. defaults: { applicationKey: "", apiKey: "", openWeatherMapLocationID: "", openWeatherMapAPI: "", units: config.units, updateInterval: 5 * 60 * 1000, // every 10 minutes animationSpeed: 1000, timeFormat: config.timeFormat, lang: config.language, tableClass: "large", showSun: true, showIcons: true, initialLoadDelay: 0, // 0 seconds delay retryDelay: 2500, apiBase: "https://rt.ambientweather.net/v1/devices", apiBaseOWM: "https://api.openweathermap.org/data/2.5/weather?", iconTable: { "01d": "wi-day-sunny", "02d": "wi-day-cloudy", "03d": "wi-cloudy", "04d": "wi-cloudy-windy", "09d": "wi-showers", "10d": "wi-rain", "11d": "wi-thunderstorm", "13d": "wi-snow", "50d": "wi-fog", "01n": "wi-night-clear", "02n": "wi-night-cloudy", "03n": "wi-night-cloudy", "04n": "wi-night-cloudy", "09n": "wi-night-showers", "10n": "wi-night-rain", "11n": "wi-night-thunderstorm", "13n": "wi-night-snow", "50n": "wi-night-alt-cloudy-windy" }, iconImageTable: { "01d": "sunny.png", "02d": "partlysunny.png", "03d": "partlycloudy.png", "04d": "cloudy.png", "09d": "sleet.png", "10d": "rain.png", "11d": "tstorms.png", "13d": "snow.png", "50d": "fog.png", "01n": "nt_clear.png", "02n": "nt_cloudy.png", "03n": "nt_mostlycloudy.png", "04n": "cloudy.png", "09n": "nt_sleet.png", "10n": "nt_rain.png", "11n": "nt_tstorms.png", "13n": "nt_snow.png", "50n": "nt-alt-cloudy-windy.png" }, }, getScripts: function(){ return ["moment.js"]; }, getStyles: function(){ return ["weather-icons.css", "MMM-AW.css"]; }, start: function () { Log.info("Starting module: " + this.name); moment.locale(config.language); this.windSpeed = null; this.windDirection = null; this.sunriseSunsetTime = null; this.sunriseSunsetIcon = null; this.temperature = null; this.weatherType = null; this.feelsLike = null; this.dailyRain = null; this.loaded = false; this.scheduleUpdate(this.config.initialLoadDelay); this.updateTimer = null; }, getDom: function() { var wrapper = document.createElement("div"); wrapper.className = this.config.tableClass; var medium = document.createElement("div"); medium.className = "normal medium"; var windIcon = document.createElement("span"); windIcon.className = "wi wi-strong-wind dimmed"; medium.appendChild(windIcon); var windSpeed = document.createElement("span"); windSpeed.innerHTML = " " + this.windSpeed + "<span class=\"xsmall\">" + "mph" + "</span>"; medium.appendChild(windSpeed); var windDirection = document.createElement("span"); windDirection.innerHTML = " " + this.windDirection; medium.appendChild(windDirection); var spacer = document.createElement("span"); spacer.innerHTML = " "; medium.appendChild(spacer); if (this.config.showSun){ var sunriseSunsetIcon = document.createElement("span"); sunriseSunsetIcon.className = "wi dimmed " + this.sunriseSunsetIcon; medium.appendChild(sunriseSunsetIcon); var sunriseSunsetTime = document.createElement("span"); sunriseSunsetTime.innerHTML = "" + this.sunriseSunsetTime; medium.appendChild(sunriseSunsetTime); } wrapper.appendChild(medium); var large = document.createElement("div"); large.className = "large light"; if (this.config.showIcons){ var weatherIcon = document.createElement("span"); weatherIcon.innerHTML = this.weatherTypeTxt; weatherIcon.classList.add("currentWeatherIconWrapper"); large.appendChild(weatherIcon); } var temperature = document.createElement("span"); temperature.className = "bright"; temperature.innerHTML = " " + this.temperature + "°"; large.appendChild(temperature); wrapper.appendChild(large); if(this.feelsLike !== null || this.dailyRain !== null){ var small1 = document.createElement("div"); small1.className = "normal small"; var feelsLike = document.createElement("span"); feelsLike.className = "dimmed"; feelsLike.innerHTML = "Feels like: "+ this.feelsLike + "°"; small1.appendChild(feelsLike); var spacer = document.createElement("span"); spacer.innerHTML = " "; small1.appendChild(spacer); var dailyRain = document.createElement("span"); dailyRain.className = "dimmed"; dailyRain.innerHTML = "Daily Rain: "+ this.dailyRain + "<span class=\"xsmall\">" + "in" + "</span>"; small1.appendChild(dailyRain); wrapper.appendChild(small1); } return wrapper; }, updateWeather: function() { var url = this.config.apiBase + this.getParams(); var self = this; var retry = true; var weatherRequest = new XMLHttpRequest(); weatherRequest.open("GET", url, true); weatherRequest.onreadystatechange = function() { if (this.readyState === 4) { if (this.status === 200) { self.processWeather(JSON.parse(this.response)); if (self.config.showSun || self.config.showIcons){ var owmurl = self.config.apiBaseOWM + "id=" + self.config.openWeatherMapLocationID + "&appid=" + self.config.openWeatherMapAPI var weatherRequest1 = new XMLHttpRequest(); weatherRequest1.open("GET", owmurl, true); weatherRequest1.onreadystatechange = function(){ if (this.readyState ===4 || this.status === 200){ self.processSun(JSON.parse(this.response)); } } weatherRequest1.send(); } } else if (this.status === 401) { self.config.appid = ""; self.updateDom(self.config.animationSpeed); Log.error(self.name + ": Incorrect APPID."); retry = false; } else if (this.status === 429){ self.updateDom(self.config.animationSpeed); Log.error(self.name + ": Too many requests."); retry = false; } else { Log.error(self.name + ": Could not load weather."); } if (retry) { self.scheduleUpdate((self.loaded) ? -1 : self.config.retryDelay); } } }; weatherRequest.send(); }, getParams: function() { var params = "?"; params += "applicationKey=" + this.config.applicationKey; params += "&apiKey=" + this.config.apiKey; return params; }, processWeather: function(data) { this.temperature = this.roundValue(data[0].lastData.tempf); this.windSpeed = this.roundValue(data[0].lastData.windspeedmph); this.windDirection = this.deg2Cardinal(data[0].lastData.winddir); this.feelsLike = this.roundValue(data[0].lastData.feelsLike); this.dailyRain = data[0].lastData.dailyrainin; if(this.temperature!=='undefined'){Log.info(this.name + "Temperature is loaded:" + this.temperature)} if(this.windSpeed!=='undefined'){Log.info(this.name + "Windspeed is loaded:" + this.windSpeed)} if(this.windDirection!=='undefined'){Log.info(this.name + 'Wind Direction is loaded:' + this.windDirection)} if(this.feelsLike!=='undefined'){Log.info(this.name + "Feels Like is Loaded:" + this.feelsLike)} if (this.dailyRain!=='undefined'){Log.info(this.name + "Daily Rain is Loaded:" + this.dailyRain)}; this.loaded = true; this.updateDom(this.config.animationSpeed); }, processSun: function(sunData) { var now = new Date(); var sunrise = new Date(sunData.sys.sunrise * 1000); var sunset = new Date(sunData.sys.sunset * 1000); var sunriseSunsetDateObject = (sunrise < now && sunset > now) ? sunset : sunrise; var timeString = moment(sunriseSunsetDateObject).format("h:mm a"); this.sunriseSunsetTime = timeString; this.sunriseSunsetIcon = (sunrise < now && sunset > now) ? "wi-sunset" : "wi-sunrise"; this.weatherType = this.config.iconTable[sunData.weather[0].icon]; this.weatherTypeTxt = "<img src ='./modules/MMM-AW/img/" + this.config.iconImageTable[sunData.weather[0].icon] + "' style ='vertical-align:middle' class='currentWeatherIcon'>"; this.loaded = true; this.updateDom(this.config.animationSpeed); }, scheduleUpdate: function(delay) { var nextLoad = this.config.updateInterval; if (typeof delay !== "undefined" && delay >= 0) { nextLoad = delay; } var self = this; setTimeout(function() { self.updateWeather(); }, nextLoad); }, deg2Cardinal: function(deg) { if (deg>11.25 && deg<33.75){ return "NNE"; }else if (deg>33.75 && deg<56.25){ return "ENE"; }else if (deg>56.25 && deg<78.75){ return "E"; }else if (deg>78.75 && deg<101.25){ return "ESE"; }else if (deg>101.25 && deg<123.75){ return "ESE"; }else if (deg>123.75 && deg<146.25){ return "SE"; }else if (deg>146.25 && deg<168.75){ return "SSE"; }else if (deg>168.75 && deg<191.25){ return "S"; }else if (deg>191.25 && deg<213.75){ return "SSW"; }else if (deg>213.75 && deg<236.25){ return "SW"; }else if (deg>236.25 && deg<258.75){ return "WSW"; }else if (deg>258.75 && deg<281.25){ return "W"; }else if (deg>281.25 && deg<303.75){ return "WNW"; }else if (deg>303.75 && deg<326.25){ return "NW"; }else if (deg>326.25 && deg<348.75){ return "NNW"; }else{ return "N"; }
},
roundValue: function(temperature) { return parseFloat(temperature).toFixed(1);
}
})
-
@drstang said in Module Intermittently Updating:
“Uncaught SyntaxError: Unexpected end of JSON input
at JSON.parse ()
at weatherRequest1.onreadystatechange (MMM-AW.js:187:30)”,that means the code was expecting data from the source, in JSON format, and did not get it…
Unexpected end of JSON input
means the code didn’t check for errors and recover from them.
-
@sdetweil Ahh ok. Well that makes sense. And I guess that could also theoretically cause it to hang/not update…
Appreciate it!
-
@drstang correct… once it fails like that, it will never recover… code died