MagicMirror Forum
    • Recent
    • Tags
    • Unsolved
    • Solved
    • MagicMirror² Repository
    • Documentation
    • 3rd-Party-Modules
    • Donate
    • Discord
    • Register
    • Login
    1. Home
    2. drstang
    3. Posts
    A New Chapter for MagicMirror: The Community Takes the Lead
    Read the statement by Michael Teeuw here.
    D
    Offline
    • Profile
    • Following 0
    • Followers 0
    • Topics 3
    • Posts 14
    • Groups 0

    Posts

    Recent Best Controversial
    • 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 = "&nbsp;";
      	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 = "&nbsp;";
      		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);
      

      }

      })

      posted in Development
      D
      drstang
    • RE: Help with Module DOM

      @mumblebaj

      The data I get back is just numerals, with the exception of wind direction, which I convert to cardinal values :

      (temp) 48.6
      (wind speed) 2.2
      (wind direction) NNE
      (feels like) 48.6
      (daily rain) 0

      Although with @sdetweil help, and using conditionals, I’m able to see my data on the MM now!

      posted in Development
      D
      drstang
    • RE: Help with Module DOM

      @sdetweil

      Thanks! I’ll give that a try!

      posted in Development
      D
      drstang
    • Help with Module DOM

      Hi - trying my own spinoff of the weather modules to pull in my home weather station information. I’m still learning JS, but have been getting the hang of it…

      I’m able to parse my preliminary values (as I’ve been able to show by logging it) and have been able to send them to my updateDom section (again by logging), but I haven’t been able to get my “feelsLike” and “dailyRainIn” to update at all. No matter where I try putting it in the appendChild code for these values, it won’t update to the MM. My temperature, wind speed and wind direction do properly log.

      I’ve racked my brain trying to figure this out and changing the combinations, but can’t solve it. Any help would be greatly appreciated! Thanks!

      Module.register("MMM-AWtest",{
          
      	// Default module config.
      	defaults: {
              applicationKey: "",     
      		apiKey: "",
      		units: config.units,
      		updateInterval: 10 * 60 * 1000, // every 10 minutes
      		animationSpeed: 1000,
      		timeFormat: config.timeFormat,
      		lang: config.language,
      		tableClass: "large",
      
      
      		initialLoadDelay: 0, // 0 seconds delay
      		retryDelay: 2500,
                      
      		apiBase: "https://rt.ambientweather.net/v1/devices"
      	},    
      	start: function () {
      		this.windSpeed = null;
      		this.windDirection = null;
      		//this.sunriseSunsetTime = null;
      		//this.sunriseSunsetIcon = null;
      		this.temperature = null;
      		//this.weatherType = null;
      		this.feelsLike = null;
      		this.dailyRainIn = 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 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);
      		
      		wrapper.appendChild(medium);
      
      		var large = document.createElement("div");
      		large.className = "large light";
      		
      		var temperature = document.createElement("span");
      		temperature.className = "bright";
      		temperature.innerHTML = " " + this.temperature + "°";
      		large.appendChild(temperature);
      
      		wrapper.appendChild(large);
      
      		var small = document.createElement("div");
      		small.className = "dimmed small";
      		
      		Log.info('pre-dom:' + this.feelsLike)
      		var feelsLike = document.createElement('span');
      		//feelsLike.className = 'dimmed';
      		feelsLike.innnerHTML = "FEELS LIKE: " + this.feelsLike + "°";
              small.appendChild(feelsLike);
              
              Log.info('pre-dom:' + this.dailyRainIn)
      		var dailyRainIn = document.createElement('span');
      		//dailyRainIn.className = 'dimmed';
      		dailyRainIn.innnerHTML = " Daily Rain: " + this.dailyRainIn + "<span class=\"xsmall\">" + "in" + "</span>";
              small.appendChild(dailyRainIn);
      
      		wrapper.appendChild(small);
      		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));
      				} 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.dailyRainIn = 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.dailyRainIn!=='undefined'){Log.info(this.name + "Daily Rain is Loaded:" + this.dailyRainIn)};
      
      
      		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);
      }
      
      })
      
      posted in Development
      D
      drstang
    • 1
    • 2
    • 2 / 2