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.

    Trying to write my own Module...

    Scheduled Pinned Locked Moved Development
    31 Posts 5 Posters 19.6k Views 5 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.
    • nbrennN Offline
      nbrenn
      last edited by

      Thanks for the great support.

      I currently have no errors with what you’ve helped provide me with. However, it displays the else condition, and NO DATA.

      Right now, my MMM-EMonitor.js looks like the following:

      Module.register ("MMM-EMonitor", {
          
          //default module config.
          defaults: {
              // Insert defaults here
              interval: 900000 // Every 15 mins
          },
          
          getStyles: function() {
              return ["MMM-EMonitor.css"];
          },
          
          // Define the start sequence
          start: function() {
              Log.log("Starting module: " + this.name);
              
              //this.securitykey = REDACTED;
              this.url = 'https://api.emonitor.us/location/getCurrentData?security_key=REDACTED';
              this.getCurrentData(this);
          },
          
         getCurrentData: function(that) {
             that.sendSocketNotification('GET-CURRENT-DATA', that.url);
             setTimeout(that.getCurrentData, that.config.interval, that);
          },
          
      
         getDom: function(){
       	 var wrapper = document.createElement("div");
      
        	if(this.xml){
         	 var channels = this.xml.getElementsByTagName("channel");
         	 for(var i = 0; i < channels.length; i++){
          	   for(var n = 0; n < channels[i].children.length; n++){
             		if(channels[i].children[n].tagName === "name" || channels[i].children[n].tagName === "watts"){
                	var element = document.createElement("div");
                	element.classList.add(channels[i].children[n].tagName);
                	element.innerHTML = channels[i].children[n].textContent;
                	wrapper.appendChild(element);
              	}
            	}
          	}
        	} else {
          		wrapper.innerHTML = "NO DATA";
        	}
        	return wrapper;
      }
      });
      

      and my css looks like the following:

      .MMM-EMonitor .centered {
          text-align: center;
      }
      

      Like I mentioned, the NO DATA is showing up. The security key is working, and returns the XML which I have in my original post.

      1 Reply Last reply Reply Quote 0
      • mochmanM Offline
        mochman Module Developer
        last edited by

        You don’t have this.xml defined anywhere in your script. If you look at @strawberry-3-141’s post, it says:

        I’m assuming that you saved your server response into this.xml

        You need to create a function that uses the URL and saves that data in a variable called xml. Since your program never does that, this.xml isn’t defined so your if/else always goes to “NO DATA”.

        Why do you have

        getCurrentData: function(that) {
               that.sendSocketNotification('GET-CURRENT-DATA', that.url);
               setTimeout(that.getCurrentData, that.config.interval, that);
            },
        

        in your program? Did you just see it in another persons code? This code snippet sends your URL to node_helper.js. Are you using that node_helper to pull the XML data from the website? If so, you’re going to need a socketNotificationReceived function to get the data and put it into the xml variable.

        The modules documentation shows you some examples of that.

        1 Reply Last reply Reply Quote 1
        • nbrennN Offline
          nbrenn
          last edited by

          Ahh, that makes sense. I do not have a node_helper.js, and I had the getCurrentData function because I tried to replicate a different module. I will remove these lines of code since they serve no purpose for me at the moment.

          I’ll try to take a look at examples to see how to save the data into the xml variable, so that this.xml can be used.

          1 Reply Last reply Reply Quote 0
          • mochmanM Offline
            mochman Module Developer
            last edited by mochman

            MMM-EMonitor.js

            Module.register ("MMM-EMonitor", {
            
                //default module config.
                defaults: {
                    // Insert defaults here
                    interval: 900000, // Every 15 mins
                    security_key: null,
                    animationSpeed: 1000
                },
            
                getStyles: function() {
                    return ["MMM-EMonitor.css"];
                },
            
                // Define the start sequence
                start: function() {
                    Log.log("Starting module: " + this.name);
                    this.loaded = false;
                    this.xml = null;
                    this.url = 'https://api.emonitor.us/location/getCurrentData?security_key=';
                    setInterval(this.getCurrentData(), this.config_interval);
                },
            
               getCurrentData: function() {
                    var self = this;
                    var xhttp = new XMLHttpRequest();
                    xhttp.onreadystatechange = function() {
                            if (this.readyState == 4 && this.status == 200) {
                                    self.xml = self.parseXML(this.responseText);
                                    self.loaded = true;
                                    self.updateDom(self.config.animationSpeed);
                            }
                    };
                    xhttp.open("GET", this.url+this.config.security_key, true);
                    xhttp.send();
                },
            
            
               getDom: function(){
                    var wrapper = document.createElement("div");
                    if(!this.loaded) {
                            wrapper.innerHTML = "Loading...";
                            return wrapper;
                    }
                    if(this.xml !== null){
                     var table = document.createElement("table");
                     table.classList.add("xsmall", "table");
                     var channels = this.xml.getElementsByTagName("channel");
                     for(var i = 0; i < channels.length; i++){
                       var row = document.createElement("tr");
                       for(var n = 0; n < channels[i].children.length; n++){
                            if(channels[i].children[n].tagName === "name" || channels[i].children[n].tagName === "watts"){
                            var element = document.createElement("td");
                            element.classList.add(channels[i].children[n].tagName);
                            element.innerHTML = channels[i].children[n].textContent;
                            row.appendChild(element);
                            }
                       table.appendChild(row);
                       }
                     }
                     wrapper.appendChild(table);
                    } else {
                            console.log("Returned no Data");
                            wrapper.innerHTML = "NO DATA";
                    }
                    return wrapper;
               },
            
               parseXML: function(xmlStr){
                    return ( new window.DOMParser() ).parseFromString(xmlStr, "text/xml");
               }
            
            });
            

            Your config.js should have:

            {
                                    module: 'MMM-EMonitor',
                                    position: 'top_left',
                                    config: {
                                            security_key: 'XXXXXXXXXXXXXXX'  //your security key
                                    }
                            }
            

            This just displays everything in a large table. You may want to modify the for loop to not display data when the wattage is 0, that should get rid of a bunch of rows.

            1 Reply Last reply Reply Quote 1
            • nbrennN Offline
              nbrenn
              last edited by

              This is awesome.

              A few clarifying questions:

              • Is the purpose of the xhttp.open("GET"... line to make the API call to the website? Is this when the connection is made to the XML page?

              • So, you’re going through each "channel" and creating a row in the table for each channel? And then for each channel’s name and wattage, a data object is created?

              • If I didn’t have any .css file, would the data still show up?

              Thanks for the clarifications, and again, thanks for the great support. This community is top-notch!

              strawberry 3.141S 1 Reply Last reply Reply Quote 0
              • strawberry 3.141S Offline
                strawberry 3.141 Project Sponsor Module Developer @nbrenn
                last edited by

                @nbrenn

                1. yes the xmlhttprequest is also better known as ajax request
                2. for each channel a row will be created and for name and watts a column will be created with their specific values
                3. the data will still be displayed, but without any custom styling

                Please create a github issue if you need help, so I can keep track

                1 Reply Last reply Reply Quote 0
                • nbrennN Offline
                  nbrenn
                  last edited by

                  I’m trying to display just the names where the watts that are != 0. I want both the values greater than 0 and the values less than 0 (in order to include the negative values from the solar generation).

                  I attempted to modify the getDom. It is displaying every names in the .XML and shows the watts value only if it is != 0. But how do I also remove the names that are 0? The output currently looks like the following:

                  Power Panel        66
                  Outlets            20
                  Heat Pump
                  Oven   
                  East Solar Panel  -70
                  West Solar Panel  -50
                  
                  getDom: function(){
                          var wrapper = document.createElement("div");
                          if(!this.loaded) {
                                  wrapper.innerHTML = "Loading...";
                                  return wrapper;
                          }
                          if(this.xml !== null){
                           var table = document.createElement("table");
                           table.classList.add("xsmall", "table");
                           var channels = this.xml.getElementsByTagName("channel");
                           for(var i = 0; i < channels.length; i++){
                             var row = document.createElement("tr");
                             for(var n = 0; n < channels[i].children.length; n++){
                                  if(channels[i].children[n].tagName === "name" || channels[i].children[n].tagName === "watts"){
                                  var element = document.createElement("td");
                                  element.classList.add(channels[i].children[n].tagName);
                                  if (channels[i].children[n].textContent != 0){
                  			element.innerHTML = channels[i].children[n].textContent;
                  			row.appendChild(element);
                  			}
                                  
                                  }
                             table.appendChild(row);
                             }
                           }
                           wrapper.appendChild(table);
                          } else {
                                  console.log("Returned no Data");
                                  wrapper.innerHTML = "NO DATA";
                          }
                          return wrapper;
                     },
                  
                  1 Reply Last reply Reply Quote 0
                  • mochmanM Offline
                    mochman Module Developer
                    last edited by

                    Looks like you need to modify your other if/then statement. The one you’ve modified checks both the name and watts to see if they are !=0. Since the name always !=0, it’s displayed.

                    1 Reply Last reply Reply Quote 0
                    • nbrennN Offline
                      nbrenn
                      last edited by

                      It looks like the values are not updating. (The wattage values didn’t change at all overnight).

                      Should the line:

                      setInterval(this.getCurrentData(), this.config_interval);
                      

                      be changed to:

                      setInterval(this.getCurrentData(), this.interval);
                      

                      Are we calling the interval variable in the config incorrectly?

                      Thanks!

                      strawberry 3.141S 1 Reply Last reply Reply Quote 0
                      • strawberry 3.141S Offline
                        strawberry 3.141 Project Sponsor Module Developer @nbrenn
                        last edited by strawberry 3.141

                        @nbrenn this.config.interval

                        Please create a github issue if you need help, so I can keep track

                        1 Reply Last reply Reply Quote 2
                        • 1
                        • 2
                        • 3
                        • 4
                        • 2 / 4
                        • First post
                          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