A New Chapter for MagicMirror: The Community Takes the Lead
Read the statement by Michael Teeuw here.
  • error loop

    11
    0 Votes
    11 Posts
    3k Views
    ?

    @jchenaud
    MODULE_DOM_CREATED is not so good time. Because, It would be emitted when Your DOM was created, but All of other DOMs are not rendered yet. DOM_OBJECTS_CREATED is better.
    If you want to using position, use .getDom(). A usual way to use position is, in .getDom() to initialize your rendering and to prepare the framework to draw.
    And you can choose one of drawing tricks.

    getDom() shall take care of all the drawing. in .getDom() put all of your rendering framework and contents. and you can refresh your render by calling .updateDom()

    getDom() shall draw only framework, Contents should be drawn by your another function with HTML DOM manipulation.

    or getDom() just return empty wrapper, Then, all of your rendering and refreshing will be performed by yourself.

    Which is better? case-by-case.

    For the last question; I cannot figure out. :)

  • Convert existing javascript code to magic mirror module

    Moved
    2
    0 Votes
    2 Posts
    995 Views
    S

    what does it do? I just ported over my pure node/angular/javascript code to mm…

    took some thinking about how to separate the existing code to fit the MM execution model…

    in general on MM you supply fragments of a page to be shown in some location on the MM page… you can also do a whole page in an iframe…

  • This topic is deleted!

    1
    0 Votes
    1 Posts
    14 Views
  • Help with converting this HTML file to MM2 module format...

    4
    0 Votes
    4 Posts
    1k Views
    D

    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

  • Real Time ECG

    3
    0 Votes
    3 Posts
    1k Views
    D

    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

  • help developing an outofmilk.com module

    8
    0 Votes
    8 Posts
    2k Views
    D

    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

  • Gurus, what is the problem with this code ?

    10
    0 Votes
    10 Posts
    2k Views
    ?

    @rsellmer
    one more thing;
    config.js is validated when MM is booted up, not rendered. maybe you can put some codes in config.js but that would not be working as your expectation.

  • MagicMirror to msSQL

    8
    0 Votes
    8 Posts
    3k Views
    rsellmerR

    Hi, I’ve sent an e-mail to you because I am new in MM and I need to do something like yours.
    Please, help me.
    Tks,
    Renato

  • Calling a general function

    3
    0 Votes
    3 Posts
    981 Views
    ?

    @rsellmer I’m not sure, but you seem to use jQuery. but jQuery is not included by default. You should include jQuery into your module.

  • Solved - Several module instances with one node_helper

    Solved
    3
    0 Votes
    3 Posts
    1k Views
    yawnsY

    Thanks for taking your time providing the solution you found. Very much appreciated

  • Assistant with screen

    8
    3 Votes
    8 Posts
    3k Views
    ?

    other stuffs

    RPI & Kiosk mode is tested. and I added some tiny features for touchscreen.

    If you want to run this module on the Kiosk mode, you should rebuild some module for matching electron version. See Installation.

  • 0 Votes
    2 Posts
    786 Views
    V

    After trying out the method of importing the config, it works well and seems to be stable. If anyone has any reason why not to require the config.js in a node_helper file, I would appreciate an explanation.

  • Feedback on first module

    1
    0 Votes
    1 Posts
    569 Views
    L

    I’m kinda new to node JS and I just created my first module.
    I would love some feedback on how to do things better or smarter so I could improve the module and do it better in the future.

    [card:Luukvdm/MMM-ClashRoyaleProfile]

  • This topic is deleted!

    1
    0 Votes
    1 Posts
    53 Views
  • 0 Votes
    8 Posts
    3k Views
    T

    For a first quick demo:
    https://streamable.com/5s6bn

  • Module suspend not being called

    3
    0 Votes
    3 Posts
    966 Views
    S

    this fix is now added to the develop branch, and will be merged to master at some time.
    Thanks Mitch

  • This topic is deleted!

    1
    0 Votes
    1 Posts
    27 Views
  • what can i do in a module, porting from another mirror project

    13
    0 Votes
    13 Posts
    3k Views
    idoodlerI

    @sdetweil Glad I could help you!

  • Module Position

    34
    0 Votes
    34 Posts
    10k Views
    M

    @strawberry-3-141 yes but I will probably use the voice control in a different way than I hought I would. Thats why I am not sure how I will change the code. Makes not much sence to waste your time on correcting the faults when I change pretty much every part of the program again right afterwards (and have to get used to git since I did not use it yet)

  • ReferenceError: Module is not defined...

    7
    0 Votes
    7 Posts
    3k Views
    justjim1220J

    @strawberry-3-141

    Thanks for answering…

    My calendar link is there, but my password is not. It does say private, but it actually is public, so anyone can see it, nothing too personal ever gets put on there anyway. :smirking_face:

    I can get a YT player to work on the MM, I’m just trying to figure out how to shuffle the list so it doesn’t start from the first song every time i gets loaded. And, if it’s just the video it has problems with, it gives a different error and will go to the next video. So, I know its not that either.