MagicMirror Forum
    • Recent
    • Tags
    • Unsolved
    • Solved
    • MagicMirror² Repository
    • Documentation
    • 3rd-Party-Modules
    • Donate
    • Discord
    • Register
    • Login
    1. Home
    2. doubleT
    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 4
    • Topics 4
    • Posts 176
    • Groups 1

    Posts

    Recent Best Controversial
    • RE: grafana module for bar graphs display.

      Ok, I cloned the module, set up a grafana and tried it out.

      The console error shows: Refused to display 'https://myname.grafana.net/login' in a frame because it set 'X-Frame-Options' to 'deny'.

      Searching for that on Google brought me to the Grafana website:

      Embedding Grafana

      If you’re embedding Grafana in a frame, iframe, embed or object on a different website it will no longer work due to a new setting that per default instructs the browser to not allow Grafana to be embedded.

      There are two topics on that: https://github.com/grafana/grafana/issues/17458, https://github.com/grafana/grafana/issues/15714

      Without any further investigation it seems like there are some settings that need to be done when you’re hosting grafana? So maybe it’s not possible to get to these settings on the free hosted versions?

      There are two other issues:
      If using the free hosted version there’s something about an API key. That might be an issue as well?
      And the module config is not asking for the entire grafana URL but wants several parts of the URL, but the actual grafana URL seems to be different to what the module is making out of these parts.

      Sorry, at the moment I can’t look any further into this, maybe someone else is interested in grafana and comes up with a solution.

      @SvenSommer?

      posted in Requests
      D
      doubleT
    • RE: grafana module for bar graphs display.

      Hi,

      looking at the module, it is just an iFrame that displays a grafana graph. So there is not much anyone on here could do. I don’t know anything about graphana, but from what I’ve seen, it seems like graphana is capable of doing “horizontal graphs” (meaning bars vertically stacked and growing horizontally?).

      Seems like you’d have to look for help in the grafana community. As I said, it seems like the module here just shows whatever you have in grafana.

      Do you have a grafana ready? Or an example of an image what you have and what it should look like?

      Regards,
      Torben

      posted in Requests
      D
      doubleT
    • RE: custom JS file (JQUERY)

      If you have a git hub account you can fork the module’s repo to your own github account and then install/clone it to your modules folder from your own git. Make the change, push it to your remote repo. When there’s an update, you can merge the update with your changed code on github and update the module afterwards. Or not even bother with updates anymore at all, if you want that.

      posted in Troubleshooting
      D
      doubleT
    • RE: Text Align Vertical

      Vertical-align only works in inline elements and table cells.

      Two common css hacks are these: https://jsfiddle.net/02vxofa6/1/

      The parent (or a wrapper div container filling the parent) is set to display: table-cell; and vertical-align: middle;

      If there’s a reason this cannot be done, there’s also another hack:
      Set the parent to position: relative; and the text to position: absolute: top: 50%;
      But then it’s not exactly in the middle, as the distance to the top is 50%. Give the text a fixed height (maybe even considering a line break there) and set margin-top to - half the text height. height: 20px; margin-top: -10pxfor example.

      posted in Development
      D
      doubleT
    • RE: What are all the warnings when installing mm2

      See them more like warnings to the developers. ;) As long as it starts and runs, it runs.

      posted in Troubleshooting
      D
      doubleT
    • RE: What are all the warnings when installing mm2

      A lot of packages give you a warning, mostly about something being deprecated. The used packages and their versions are written in the package.json, sometimes developers have a reason to use a specific version and sometimes there are newer versions available. In that case, npm could warn about the package being deprecated.

      I’ve seen in some projects, that updating a package might need updating the context the package is used in, soe usually it’s best to leave this alone, unless you want to open a can of errors.

      Another developer once told me “As long as it’s only a warning, ignore it. If npm really wants something from you, it’ll stop and tell you.”

      (node.js is the runtime environment, packages are helpers (special functions that make developing easier because you use that shortcut instead of programming something yourself that someone else already provided), npm is the node package manager, package.json is where the dependencies of these packages are declared so npm knows which packages and versions to install)

      posted in Troubleshooting
      D
      doubleT
    • RE: unable to reply to topic here

      Weird, I have no problems with Firefox or Chrome but with IE and Edge and I think it’s just that the pop-up message that asks you if you want to continue posting in an old thread is blocked.

      posted in Custom CSS
      D
      doubleT
    • RE: unable to reply to topic here

      There should be a pop-up message: “The topic you are replying to is quite old. Would you like to create a new topic instead, and reference this one in your reply?”

      It’s possible that your browser is blocking the pop-up.

      I can replicate this error in Internet Explorer and Edge.
      Try Chrome or Firefox.

      This post shouldn’t be in the “custom css” subforum, it should be in “General Discussion” > “Forum”.

      posted in Custom CSS
      D
      doubleT
    • RE: error loop

      Well, the error information are pretty clear, you just need to look at your code to come to a conclusion. Without seeing the code, we can’t know anything about why these errors occur.

      1st says there’s no element by the class name you’re searching for. Either it’s not there or you’re looking in the wrong place.

      2nd says you’re trying to append something that is not an element. You can’t append a string, for example.

      For example, that’s a string and won’t work:

      let parent = document.getElementById("parent");
      let element = "<div>lorem ipsum</div>";
      parent.appendChild(element);
      

      This will work:

      let parent = document.getElementById("parent");
      let element = document.createElement("div");
      element.innerHTML = "lorem ipsum";
      parent.appendChild(element);
      
      posted in Development
      D
      doubleT
    • RE: Currated Art

      I’m sure there’s an API for Arts&Culture. Everything on Google has an API. And it’s in the Cloud. There’s API documentation for the previous version, Google’s “Project Art” / “OpenGallery”.

      Edit: https://developers.google.com/opengallery/ => 404 :(
      https://opengallery.culturalspot.org/home
      Everything seems reachable … :/

      posted in Requests
      D
      doubleT
    • RE: Currated Art

      First thing that came to my mind:
      “Every piece of art you’ve ever wanted to see – up close and searchable” by Amit Sood at TED, https://www.youtube.com/watch?v=CjB6DQGalU0
      (if you don’t watch the full 15 min, check 4:00 min)

      https://artsandculture.google.com/

      In a quick search, I couldn’t find any current information on whether there is an API, but I’d guess so.

      posted in Requests
      D
      doubleT
    • RE: MMM-CountEvents

      More is always good! Nice module, I like that you can count the time since past events.

      posted in Utilities
      D
      doubleT
    • RE: Help with converting this HTML file to MM2 module format...

      I’d put them in a different structure, perhaps, depending on what you want to achieve.

      If it’s just this list that you want: Remove all line breaks and tabs, lead all quotation marks with a backslash (\") and put that complete one line of code in:

      targetElement.innerHTML = "your Code here";
      

      More flexible:


      var newsSources = [
      {
      “id”:“washington_post”,
      “name”:“Washington Post”,
      “alt”:“Washington Post”,
      “link”:“https://www.washingtonpost.com/?reload=true”
      },
      {
      “id”:“usa_today”,
      “name”:“USA Today”,
      “alt”:“USA Today”,
      “link”:“http://rssfeeds.usatoday.com/UsatodaycomNation-TopStories”
      },
      {
      “id”:“irish_news”,
      “name”:“Irish News”,
      “alt”:“Irish News”,
      “link”:“http://www.irishnews.com/news/worldnews/”
      },
      {
      “id”:“wall_street_journal”,
      “name”:“Wall St. Journal”,
      “alt”:“Wall St. Journal”,
      “link”:“https://www.wsj.com/news/us”
      },
      {
      “id”:“kansas_city_star”,
      “name”:“The Kansas City Star”,
      “alt”:“Kansas City, MO News”,
      “link”:“https://www.kansascity.com/news/”
      },
      {
      “id”:“bbc_news”,
      “name”:“BBC World News”,
      “alt”:“BBC World News”,
      “link”:“https://www.bbc.com/news/world”
      }
      ];
      newMainElement = document.createElement(“div”);
      newMainHeadline = document.createElement(“h2”);
      newMainHeadline.innerHTML = “< img src="pix/break_news.png" alt="Breaking News" />”;
      newMainElement.apply(newMainHeadline);
      frstWrapper = document.createElement(“div”);
      scndWrapper = document.createElement(“div”); // really neccessary?
      thrdWrapper = document.createElement(“div”); // really neccessary?
      newsList = document.createElement(“ul”);
      for (i=0; i< =newsSources.length; i++) {
      newsItem = document.createElement(“li”);
      newsLogo = document.createElement(“div”);
      newsLogo.innerHTML = “< img src="pix"+newsSources[i].id+”.png" alt="“+newsSources[i].alt+”" />"
      newsLink = document.createElement(“h3”);
      newsLink.innerHTML = “< a href="”+newsSources[i].link+“" target="myIframe">”+newsSources[i].name+“”;
      newsItem.apply(newsLogo);
      newsItem.apply(newsLink);
      newsList.apply(newsItem);
      }
      thrdWrapper.apply(newsList); // really neccessary? see above
      scndWrapper.apply(thrdWrapper); // really neccessary? see above
      frstWrapper.apply(scndWrapper);
      newMainElement.apply(frstWrapper);


      I didn’t use the code block because it can’t handle \".
      In < img and < a you have to remove the space.
      id = image name, you’ll have to adapt a little, I wrote them in a more uniform style.
      alt = could be the same as the name, but I put it in as you varied a little with your alt titles.


      Oh, by the way:
      Seems like this could also be a good case for a template system.
      https://forum.magicmirror.builders/topic/2443/html-templating-system
      https://forum.magicmirror.builders/topic/5053/better-way-to-use-html-in-module-development

      posted in Development
      D
      doubleT
    • RE: Real Time ECG

      For anything involving a graph drawn from JS(ON) data, I can only recommend highcharts.

      It’s possible to display dynamic graphs from live data. Example: https://www.highcharts.com/stock/demo/dynamic-update/
      https://www.highcharts.com/docs/working-with-data/live-data

      Your python code could provide a JSON and the MM-module calls the JSON and prints the graph.

      I’ve used highcharts before but never dynamically like in the example above.
      Here’s an example where I used it in a module: https://github.com/TTigges/MMM-Oiltank/blob/master/MMM-Oiltank.js

      posted in Development
      D
      doubleT
    • RE: Multiples of same module?

      If you want a quick and dirty solution, copy the module folder, rename the copy and then change the module’s name to match the new module/folder name in all occurances (file names and within the code).

      posted in Troubleshooting
      D
      doubleT
    • RE: countdown module for repeating aniversary

      As you said, MMM-doomsDay isn’t really the module you’re looking for. I wrote a possible solution as an answer to your question in the other thread. But the downside is, it’d only be possible for one event as that module can’t even list several events (at least that’s what I saw from a short look at the code).

      So in your case I’d take MMM-doomsDay and built your own module from that with the code changes I posted in the other thread.

      posted in Productivity
      D
      doubleT
    • RE: MMM-doomsDay - The countdown module,

      @zdenek Even though I think it’s possible with a few changes to the code, I don’t think this would fit the scope of this module, which is to manually set a countdown to one specific event (noteven a few, right?) but not for a whole list of calendar dates.

      Even if the code ignores the year and just always shows the next event, does it make sense to have it display “364 days left” right the next day?

      Anyway, if you want to do that, I’d suggest adding:

          doomsDay: "2018-12-24 24:00:00",
          yearlyEvent: true,
          toWhat: "X-Mass"
      

      The most simple simple change to the code would be to add this at line 48:

      if (this.config.yearlyEvent && daysLeft < = 0) {
          var diff = now.getFullYear() - doomsday.getFullYear();
          // update doomsday:
          doomsDay.setFullYear(d.getFullYear() + diff);
          // calculate again:
          timeparser = Date.parse(doomsDay) - Date.parse(now);
          daysLeft = Math.floor(timeparser/(1000*60*60*24));
      }
      

      (remove the space between “< =” … )
      I didn’t test this, though, (and I don’t recommend it).

      posted in Utilities
      D
      doubleT
    • RE: help developing an outofmilk.com module

      Uh, interesting topic. I like API calls. :D Back when I started, my main issue was understanding the node_helper.js – and that it was neccessary.
      I’m still struggling to make sense of your token complexity. Apart from that, your files would be something like this:

      MMM-OutOfMilk.js:

      Module.register("MMM-OutOfMilk",{
          defaults: {
              // your defaults
          },
      
          start: function() {
              var payload = "start"; // example
              this.sendSocketNotification("GetMyShoppingList", payload);
          },
      
          socketNotificationReceived: function(notification, shoppingList) {
              if (notification === "ShoppingListRecieved") {
                  this.handeShoppingList(shoppingList);
              }
          },
      
          handleShoppingList: function(shoppingList) {
              // do something with your shopping list
          }
      }
      

      node_helper.js:

      var NodeHelper = require("node_helper");
      var request = require("request"); // needed? see below
      var fs = require("fs"); // needed? see below
      var timer = 0; // needed? see below "I added a timer"
      var token;
      
      module.exports = NodeHelper.create({
          start: function() {
          },
          socketNotificationReceived: function(notification, payload) {
              if (notification === "GetMyShoppingList") {
                  // start the logic to recieve the shopping list
                  // get token?
                  // make call
                  this.getShoppingList(payload);
              }
          },
          getToken: function(payload) {
              // however you get your token
              getShoppingList(payload);
          },
          getShoppingList: function(payload) {
              var self = this;
              var source = ; // your source URL
              if (token) {
              	request({
      	            url: source,
      	            json: true
      	        }, function (error, response, body) {
      	            if (!error && response.statusCode === 200) {
      	                self.sendSocketNotification("ShoppingListRecieved", body);
      	            }
      	            else {
      	            	// check error if it's a token issue
      	            	// if so, get new token
      	            	self.getToken(payload);
      	            }
      	        })
              }    
          }
      }
      

      From another project I know that sometimes a token can be used for a while. In that case I’d directly call the getShoppingList and only on an error that read “wrong token” or something like that, I’d call getToken which saves the token to a global variable and calls back getShoppingList to try again. That way you don’t have to get a new token for every call.

      Alternatively?

          getShoppingList: function(token) {
              var self = this;
              var source = ; // your source URL
              var rawdata = fs.readFileSync(source);
              var history =  JSON.parse(rawdata);
              self.sendSocketNotification("ShoppingListRecieved", history);
          }
      

      I’d also use a timer to request data on the first call and after that automatically only every full hour:
      So, in the node_helper.js, in the socketNotificationReceived I don’t forward the payload to this.updateTimer(payload) instead of getToken or getShoppingList to do this:

          updateTimer: function(payload) {
              var self = this;
              var d = new Date();
              var h = d.getHours();
              var min = d.getMinutes();
              var sec = d.getSeconds();
              if (timer === 0) {
                  timer ++; // prevent unnecessary timer by double calls
                  this.getShoppingList(payload);
      
                  if((min == '00') && (sec == '00')){
      //              console.log(h + ":" + min + ":" + sec + " - update and wait 1 hour");
      //              console.log("restart timer");
                      setTimeout(() => {
                          this.clearTimer(payload);
                      }, 60*1000*60); // 60 sec * 1000 ms = 1 min * 60 = 1 hour
                  } else {
      //              console.log(h + ":" + min + ":" + sec + " - update waits for " + (59-min) + " min and " + (60-sec) + "sec");
      //              console.log("restart timer");
                      setTimeout(() => {
                          this.clearTimer(payload);
                      }, ((60-sec)*1000)+(60*1000*(59-min)));
                  }
              }
              else {
      //          console.log("timer already running, data displayed outside of timer run");
                  this.getShoppingList(payload);
              }
          },
      
          clearTimer: function(payload) {
              timer --;
              this.updateTimer(payload);
          }
      

      For one of my modules I couldn’t use fs.readFile... or request because of CORS issues. In that case I had to use a php proxy.
      I’d strongly suggest trying to solve this with fs.readFile... or request but just for the sake of completeness and maybe to help you understand:

      In order to use PHP within nodeJS via Child Process Dependency you have to have PHP installed and in your PATH!
      You can read how I used it, here: https://forum.magicmirror.builders/topic/5830/call-api-no-cors-used-to-do-it-with-php-proxy/9

      posted in Development
      D
      doubleT
    • RE: How to develop modules

      I’d second that.

      For a quick overview:

      The DOM (all visible elements) is based on HTML, styled with CSS and usually filled with content and function by Java Script. That’s all you need for basic modules.

      If you go further, you’ll need Python in case you have something connected to the Pi andnodeJS for advanced modules with some backend code, like API calls, though some nodeJS knowledge will help you a lot to understand the whole structure in the first place.

      jQuery can be a helpful Java Script library.
      API calls usually deliver JSON or – rarely – XML, but both should be familiar if you know JS objects and arrays and HTML.

      As Sean said, playing around and manipulating existing modules should help you a lot. Go through the code, see if you understand the connections and find out what happens if you manipulate it.

      Your most important tool when working in js-files is the browser console where you can print to with the js code console.log("show me the content of var x: " + x); MM code Log.info("show me the content of var x: " + x);

      posted in General Discussion
      D
      doubleT
    • 1 / 1