• Recent
  • Tags
  • Unsolved
  • Solved
  • MagicMirror² Repository
  • Documentation
  • 3rd-Party-Modules
  • Donate
  • Discord
  • Register
  • Login
MagicMirror Forum
  • Recent
  • Tags
  • Unsolved
  • Solved
  • MagicMirror² Repository
  • Documentation
  • 3rd-Party-Modules
  • Donate
  • Discord
  • Register
  • Login
A New Chapter for MagicMirror: The Community Takes the Lead
Read the statement by Michael Teeuw here.

Module Intermittently Updating

Scheduled Pinned Locked Moved Development
4 Posts 2 Posters 295 Views 2 Watching
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    drstang
    last edited by Aug 23, 2023, 1:21 PM

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

    }

    })

    S 1 Reply Last reply Aug 23, 2023, 1:24 PM Reply Quote 0
    • S Away
      sdetweil @drstang
      last edited by Aug 23, 2023, 1:24 PM

      @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.

      Sam

      How to add modules

      learning how to use browser developers window for css changes

      D 1 Reply Last reply Aug 23, 2023, 1:29 PM Reply Quote 0
      • D Offline
        drstang @sdetweil
        last edited by Aug 23, 2023, 1:29 PM

        @sdetweil Ahh ok. Well that makes sense. And I guess that could also theoretically cause it to hang/not update…

        Appreciate it!

        S 1 Reply Last reply Aug 23, 2023, 1:31 PM Reply Quote 0
        • S Away
          sdetweil @drstang
          last edited by Aug 23, 2023, 1:31 PM

          @drstang correct… once it fails like that, it will never recover… code died

          Sam

          How to add modules

          learning how to use browser developers window for css changes

          1 Reply Last reply Reply Quote 0
          • 1 / 1
          1 / 1
          • First post
            1/4
            Last post
          Enjoying MagicMirror? Please consider a donation!
          MagicMirror created by Michael Teeuw.
          Forum managed by Sam, technical setup by Karsten.
          This forum is using NodeBB as its core | Contributors
          Contact | Privacy Policy