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);
}
})