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

Trying to write my own Module...

Scheduled Pinned Locked Moved Development
31 Posts 5 Posters 19.3k 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.
  • M Offline
    mochman Module Developer
    last edited by mochman Dec 24, 2016, 9:18 PM Dec 24, 2016, 9:12 PM

    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
    • N Offline
      nbrenn
      last edited by Dec 24, 2016, 10:51 PM

      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!

      S 1 Reply Last reply Dec 24, 2016, 11:30 PM Reply Quote 0
      • S Offline
        strawberry 3.141 Project Sponsor Module Developer @nbrenn
        last edited by Dec 24, 2016, 11:30 PM

        @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
        • N Offline
          nbrenn
          last edited by Dec 26, 2016, 2:54 PM

          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
          • M Offline
            mochman Module Developer
            last edited by Dec 26, 2016, 3:12 PM

            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
            • N Offline
              nbrenn
              last edited by Dec 28, 2016, 1:43 PM

              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!

              S 1 Reply Last reply Dec 28, 2016, 1:44 PM Reply Quote 0
              • S Offline
                strawberry 3.141 Project Sponsor Module Developer @nbrenn
                last edited by strawberry 3.141 Dec 28, 2016, 1:44 PM Dec 28, 2016, 1:44 PM

                @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
                • N Offline
                  nbrenn
                  last edited by nbrenn Dec 28, 2016, 4:54 PM Dec 28, 2016, 4:51 PM

                  For posterity, I modified the if statement as follows, to remove the row items that have a 0 for wattage:

                  if (channels[i].children[n].textContent != 0) {
                       element.innterHTML = channels[i].children[n].textContent;
                       row.appendChild(element);
                       table.appendChild(row);
                  }
                  else {
                       table.removeChild(row);
                  }
                  
                  1 Reply Last reply Reply Quote 1
                  • M Offline
                    mochman Module Developer
                    last edited by Dec 28, 2016, 5:01 PM

                    Glad it all worked out for you!

                    1 Reply Last reply Reply Quote 0
                    • N Offline
                      nbrenn
                      last edited by Dec 28, 2016, 10:50 PM

                      I’m working on getting historical data (my API has a function getHistoricalData). The XML looks like the following:

                      <Time Time="2016-11-03 00:00:00">
                      <channel channel="194882" name="Main Power Main Panel">
                      <kWh>0.319</kWh>
                      </channel>
                      <channel channel="194885" name="Outlet 1">
                      <kWh>0.000</kWh>
                      </channel>
                      <channel channel="194886" name="Solar Panel 1">
                      <kWh>-5.737</kWh>
                      </channel>
                      <channel channel="194887" name="Solar Panel 2">
                      <kWh>-4.877</kWh>
                      </channel>
                      

                      The difference between this XML output, and the XML output from my getCurrentData call, is that name is not it’s own element. With the old function, <name> was in brackets. Now, it is name = ....

                      Would be getDom be the same as it was for getCurrentData, or is it different since it’s name= and not it’s own <name> ... </name>

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