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

    Posts

    Recent Best Controversial
    • RE: MM & Google Maps Traffic

      /* global Module */

      /* Magic Mirror

      • Module: MMM-Traffic
      • By Sam Lewis https://github.com/SamLewis0602
      • MIT Licensed.
        */

      Module.register(‘MMM-Traffic’, {

      defaults: {
          api_key: '',
          mode: 'driving',
          interval: 300000, //all modules use milliseconds
          origin: '',
          destination: '',
          mon_destination: '',
          tues_destination: '',
          wed_destination: '',
          thurs_destination: '',
          fri_destination: '',
          traffic_model: 'best_guess',
          departure_time: 'now',
          arrival_time: '',
          loadingText: 'Loading commute...',
          prependText: 'Current commute is',
          changeColor: false,
          limitYellow: 10,
          limitRed: 30,
          showGreen: true,
          language: config.language,
          show_summary: true,
          showWeekend: true,
          allTime: true,
          startHr: 7,
          endHr: 22,
          avoid:'',
            summaryText:'via',
            leaveByText:'Leave by',
            arriveByText:'to arrive by',
          hideOffHours: false,
      },
      setLocalParams: function(){
      	// These parameters are populated mostly 
      	// by node_helper
          this.loaded = false;
          this.mapLoaded= false;
          this.leaveBy = '';
          this.symbols = {
              'driving': 'fa fa-car',
              'walking': 'fa fa-odnoklassniki',
              'bicycling': 'fa fa-bicycle',
              'transit': 'fa fa-train'
          };
          this.commute = '';
          this.summary = '';
      },
      start: function() {
          Log.info('Starting module: ' + this.name);
          if (this.data.classes === 'MMM-Traffic') {
            this.data.classes = 'bright medium';
          }
          this.loaded = false;
          this.mapLoaded= false;
          this.leaveBy = '';
          var myURL = 'https://maps.googleapis.com/maps/api/directions/json' + this.getParams();  
          console.log("Querying with loc = " + myURL);
          this.url = encodeURI('https://maps.googleapis.com/maps/api/directions/json' + this.getParams());
          this.symbols = {
              'driving': 'fa fa-car',
              'walking': 'fa fa-odnoklassniki',
              'bicycling': 'fa fa-bicycle',
              'transit': 'fa fa-train'
          };
          this.commute = '';
          this.summary = '';
          this.updateCommute(this);
      },
      // Handler for notifications from any other module asking for 
      // TRAFFFIC update.
      // This will invoke updateCommute with new source and destination
      // TODO: The new source and destination will continue to get displayed untill
      // it is reset. Will try to revert that
      notificationReceived: function(notification, payload, sender){
      	Log.log(notification+" received from "+sender);
      	var myURL = "";
      	if(notification === "TRAFFIC_ACTION_NEEDED"){
      		console.log("Received new traffic update request for start: "+payload.start_location+" end:"+payload.end_location);
      		myURL = 'https://maps.googleapis.com/maps/api/directions/json' + 
      			    this.getParam_specific(payload.start_location, payload.end_location);
      		console.log("Querying with "+myURL);
      	    this.url = encodeURI(myURL);
      		this.updateCommute(this);
      	}
      },
      
      updateCommute: function(self) {
      	console.log("updateCommute called");
          timeConfig = {
            showWeekend:    self.config.showWeekend,
            allTime:        self.config.allTime,
            startHr:        self.config.startHr,
            endHr:          self.config.endHr
          };
      
          if (self.config.arrival_time.length == 4) {
            self.sendSocketNotification('LEAVE_BY', {'url':self.url, 'arrival':self.config.arrival_time, 'timeConfig':timeConfig});
          } else {
            self.sendSocketNotification('TRAFFIC_URL', {'url':self.url, 'timeConfig':timeConfig});
          }
          setTimeout(self.updateCommute, self.config.interval, self);
      },
      getStyles: function() {
          return ['traffic.css', 'font-awesome.css'];
      },
      createMap_area: function(start_location, end_location){
      	console.log("createMap_area invoked");
      	if(document.getElementById('map'))
      	{
      		console.log("Map Div available "+start_location.lat);
      		var map_options = {
      			center: new google.maps.LatLng(start_location.lat, start_location.lng),
      			zoom: 20,
                  size: '300x300',
      			panControl: true,
      			mapTypeControl: false,
      			panControlOptions: {
      				position: google.maps.ControlPosition.RIGHT_CENTER
      			},
      			zoomControl: true,
      			zoomControlOptions: {
      				style: google.maps.ZoomControlStyle.LARGE,
      				position: google.maps.ControlPosition.RIGHT_CENTER
      			},
      			scaleControl: false,
      			streetViewControl: false,
      			streetViewControlOptions: {
      				position: google.maps.ControlPosition.RIGHT_CENTER
      			}
      		};
      	    // map div is added to document.body
          	var map = new google.maps.Map(document.getElementById("map"), map_options);
      
      		var start_bound = new google.maps.LatLng(start_location.lat, start_location.lng);
      
      		var end_bound = new google.maps.LatLng(end_location.lat, end_location.lng);
      		var marker = new google.maps.Marker({
      			position: start_bound,
      			map: map
      		});
      
      		var marker = new google.maps.Marker({
      			position: end_bound,
      			map: map
      		})
      
      		var bounds = new google.maps.LatLngBounds();
      		bounds.extend(start_bound);
      		bounds.extend(end_bound);
      		map.fitBounds(bounds);
      		// the preserveViewport is almost mandatory to prevent zoom/pan out of the screen
             var directionsDisplay = new google.maps.DirectionsRenderer({
                 map: map,
      		   zoom: 20,
      		   preserveViewport: true
             });
      	   directionsDisplay.setMap(map);
      
             // Set destination, origin and travel mode.
             var request = {
               destination: end_location,
               origin: start_location,
               travelMode: 'DRIVING'
             };
             // Pass the directions request to the directions service.
             var directionsService = new google.maps.DirectionsService();
             directionsService.route(request, function(response, status) {
                 if (status == 'OK') {
                     // Display the route on the map.
                     directionsDisplay.setDirections(response);
                 }
             }); 
             // Pass the directions request to the directions service.
      	   this.mapLoaded = true;
      	}
      	return document.getElementById('map');
      },
      createMap: function(){
          var wrapper = document.createElement('div');
          wrapper.style.height = this.config.height;
          wrapper.style.width = this.config.width;
      	wrapper.setAttribute("id", "map");
          
          // This script is appended to the main body
          var outer_script = document.createElement("script");
          outer_script.type = "text/javascript";
          outer_script.src = "https://maps.googleapis.com/maps/api/js?key=" + this.config.api_key;
      	outer_script.setAttribute("async","");
      	outer_script.setAttribute("defer","");
          document.body.appendChild(outer_script);
          outer_script.onload = function(){
      		console.log("Added the map script to document body");
          }
          return wrapper; 
      },
      
      
      getDom: function() {
          var wrapper = document.createElement("div");
          var commuteInfo = document.createElement('div');
          var routeName = document.createElement('div');
          // Map display 
      
          if (!this.loaded) {
              console.log("[MMM-Traffic]Pre-loading invoked");
              //wrapper.innerHTML = this.config.loadingText;
      		// Invoke adding the Google Maps base script to the dcoument.body
      		// It needs to be invoked only once.
              wrapper.appendChild(this.createMap());
               
              return wrapper;
          }
      
          if ((this.commute == '' || this.commute == '--') && this.config.hideOffHours && !this.config.allTime) {
              wrapper.innerHTML = '';
              return wrapper;
          }
          // Obtain start/end co-ordinates
          var start_loc = this.start_location;
          var end_loc = this.end_location;
          console.log("Start lat "+start_loc.lat+" long "+start_loc.lng); 
          wrapper.appendChild(this.createMap_area(this.start_location, this.end_location));
      
      
          //symbol
          var symbol = document.createElement('span');
          symbol.className = this.symbols[this.config.mode] + ' symbol';
          commuteInfo.appendChild(symbol);
          
      
          if (this.config.arrival_time == '') {
            //commute time
            var trafficInfo = document.createElement('span');
            trafficInfo.innerHTML = this.config.prependText + ' ' + this.commute;
            commuteInfo.appendChild(trafficInfo);
      
            //routeName
            if (this.config.route_name) {
              routeName.className = 'dimmed small';
              if (this.summary.length > 0 && this.config.show_summary){
                routeName.innerHTML = this.config.route_name + ' ' + this.config.summaryText + ' ' + this.summary;
              } else {
                routeName.innerHTML = this.config.route_name;
              }
            }
          } else {
            //leave-by time
            var trafficInfo = document.createElement('span');
            trafficInfo.innerHTML = this.config.leaveByText + ' ' + this.leaveBy;
            commuteInfo.appendChild(trafficInfo);
      
            //routeName
            if (this.config.route_name) {
              routeName.className = 'dimmed small';
              if (this.summary.length > 0 && this.config.show_summary){
                routeName.innerHTML = this.config.route_name + ' ' + this.config.summaryText + ' ' + this.summary + ' ' + this.config.arriveByText + ' ' + this.config.arrival_time.substring(0,2) + ":" + this.config.arrival_time.substring(2,4);
              } else {
            console.log(typeof this.config.arrival_time );
                routeName.innerHTML = this.config.route_name + ' ' + this.config.arriveByText + ' ' + this.config.arrival_time.substring(0,2) + ":" + this.config.arrival_time.substring(2,4);
              }
            }
          }
      
          //change color if desired
          if (this.config.changeColor) {
            if (this.trafficComparison >= 1 + (this.config.limitRed / 100)) {
              commuteInfo.className += ' red';
            } else if (this.trafficComparison >= 1 + (this.config.limitYellow / 100)) {
              commuteInfo.className += ' yellow';
            } else if (this.config.showGreen) {
              commuteInfo.className += ' green';
            }
          }
      
          wrapper.appendChild(commuteInfo);
          wrapper.appendChild(routeName);
          return wrapper;
      },
      getParam_specific: function(origin, destination){
          var params = '?';
          params += 'mode=' + this.config.mode;
          params += '&origin=' + origin;
          params += '&destination=' + destination;
          params += '&key=' + this.config.api_key;
          params += '&traffic_model=' + this.config.traffic_model;
          params += '&language=' + this.config.language;
          if (this.config.avoid.length > 0) {
            params += '&avoid=' + this.config.avoid;
          }
          return params;
      },
      
      getParams: function() {
          var params = '?';
          params += 'mode=' + this.config.mode;
          params += '&origin=' + this.config.origin;
          params += '&destination=' + this.getTodaysDestination();
          params += '&key=' + this.config.api_key;
          params += '&traffic_model=' + this.config.traffic_model;
          params += '&language=' + this.config.language;
          if (this.config.avoid.length > 0) {
            params += '&avoid=' + this.config.avoid;
          }
          return params;
      },
      
      getTodaysDestination: function() {
          var todays_destination = "";
          switch (new Date().getDay()) {
            case 1:
              todays_destination = this.config.mon_destination;
              break;
            case 2:
              todays_destination = this.config.tues_destination;
              break;
            case 3:
              todays_destination = this.config.wed_destination; 
              break;
            case 4:
              todays_destination = this.config.thurs_destination;
              break;
            case 5:
              todays_destination = this.config.fri_destination;
              break;
            default:
              //to handle Sat and Sun (GoogleAPI may raise error if no destination set)   
              todays_destination = this.config.destination; 
          }
      
          if(todays_destination === ""){ //if no weekday destinations defined in config.js, set to default
              todays_destination = this.config.destination;           
          }
      
          return todays_destination;
      },
      
      socketNotificationReceived: function(notification, payload) {
          this.leaveBy = '';
          this.start_location = payload.start_location;
          this.end_location = payload.end_location;
          if (notification === 'TRAFFIC_COMMUTE' && payload.url === this.url) {
              Log.info('received TRAFFIC_COMMUTE');
              this.commute = payload.commute;
              this.summary = payload.summary;
              this.trafficComparison = payload.trafficComparison;
              this.loaded = true;
              this.updateDom(1000);
          } else if (notification === 'TRAFFIC_TIMING' && payload.url === this.url) {
              Log.info('received TRAFFIC_TIMING');
              this.leaveBy = payload.commute;
              this.commute = payload.commute; //support for hideOffHours
              this.summary = payload.summary;
              this.loaded = true;
              this.updateDom(1000);
          }
      }
      

      });

      posted in Troubleshooting
      M
      Mirrorolentia
    • RE: MM & Google Maps Traffic

      Please install the MMM-Traffic module and replace the MMM-Traffic.js with the above code.
      Below is a sample entry in config.js

      {
                  module: 'MMM-Traffic',
                  position: 'top_left',
                  classes: 'dimmed medium', //optional, default is 'bright medium', only applies to commute info not route_name
                  config: {
                      api_key: '', // Your Google Maps API_KEY needs to go here
                      mode: 'driving',
                      origin: '',
                      destination: '',
                      mon_destination: '',
                      arrival_time: '', //optional, but needs to be in 24 hour time if used.
                      route_name: 'Home to Work',
                      changeColor: true,
                      showGreen: false,
                      limitYellow: 5, //Greater than 5% of journey time due to traffic
                      limitRed: 20, //Greater than 20% of journey time due to traffic
                      traffic_model: 'best_guess',
                      interval: 60000, //2 minutes
                      showWeekend: true,
                      allTime: true,
                      width: '300px',
                      height: '300px'
                  }
              },
      
      posted in Troubleshooting
      M
      Mirrorolentia
    • 1 / 1