HowTo: Node Red / Magic Mirror – Displaying Node Red Data on the Mirror

For a long time, I was looking for a way to easily display the data that I collect with NodeRed from my SmartHome on the MagicMirror.
Thanks to the many plugins for the MagicMirror and NodeRed this was implemented faster than expected. How it works is described in the following article.

Hints for our lovely english readers: Basically, many of the articles on Nerdiy.de are translations from the original german articles. Therefore, it may happen here and there that some illustrations are not available in english and that some translations are weird/strange/full of mistakes or generally totaly wrong. So if you find some obvious (or also not obvious) mistakes don't hesitate to leave us a hint about that in the comment section. 
Also please don't get confused, that instead of a "dot" often a "comma" is used as decimal separator. 🙂


Safety instructions

I know the following hints are always a bit annoying and seem unnecessary. But unfortunately, many people who knew it "better" from carelessness lost their eyes, fingers or other things or hurt themselves. In comparison, a loss of data is almost not worth mentioning, but even these can be really annoying. Therefore, please take five minutes to read the safety instructions. Even the coolest project is worth no injury or other annoyance. https://www.nerdiy.de/en/sicherheitshinweise/

Affiliate links / advertising links

The links to online shops listed here are so-called affiliate links. If you click on such an affiliate link and shop via this link, Nerdiy.de receives a commission from the online shop or provider concerned. The price doesn't change for you. If you do your purchases via these links, you will support Nerdiy.de in being able to offer further useful projects in the future. 🙂


Requirements

Helpful Articles:
Before you start with the installation, you should have prepared the RaspberryPi so far that it can be reached via the network and controlled by SSH.

The following three articles describe what to do to prepare the RaspberryPi:
RaspberryPi – Setting up for Nerdiys!
RaspberryPi – The First Configuration!
RaspberryPi – Control the RaspberryPi via SSH
MagicMirror – Installation of the required software
MagicMirror – install 3rd party modules

Required material:

In the following list you will find all the parts you need to implement this article.


Log in to the NodeRed configuration interface

Before you can edit your NodeRed configuration you must - if activated - first log in to the NodeRed configuration interface.

View of the login screen. Here you have to enter the login details that you entered during the configuration of the login. Information about this can be found in the article NodeRed - User Login Setup.

Create the data source in NodeRed as JSON

In this example, data of the RaspberryPI(which runs NodeRed) is displayed on the MagicMirror.
NodeRed provides this data as JSON, which the MagicMirror collects at regular intervals and displays on its display. You do not need to install new nodes because the data source is built from the standard nodes.

You have to build the following flow for this.

It is easier to insert the following node code:

[{"id":"cc7a1b10.a7c038","type":"http in","z":"8c9f8f17.13eb78","name":"","url":"/daten.json","method":"get","upload":false,"swaggerDoc":"","x":320,"y":460,"wires":[["61e489ce.08eb68"]]},{"id":"89f4552e.8cc4f8","type":"http response","z":"8c9f8f17.13eb78","name":"","x":1040,"y":460,"wires":[]},{"id":"ced95c01.75153","type":"change","z":"8c9f8f17.13eb78","name":"Set Headers","rules":[{"t":"set","p":"headers","pt":"msg","to":"{}","tot":"json"},{"t":"set","p":"headers.content-type","pt":"msg","to":"application/json","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":880,"y":460,"wires":[["89f4552e.8cc4f8"]]},{"id":"a5b108a6.e68c88","type":"template","z":"8c9f8f17.13eb78","name":"page","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{ \n    \"Daten\": [\n        {\n        \"name\": \"RPi Temp\",\n        \"value\": \"{{temp}}°C\",\n        \"lastUpdate\": \"{{temp-timestamp}}\"\n        },\n        {\n        \"name\": \"CPU Load\",\n        \"value\": \"{{load}}%\",\n        \"lastUpdate\": \"{{load-timestamp}}\"\n        },\n        {\n        \"name\": \"Free Memory\",\n        \"value\": \"{{free}}MB\",\n        \"lastUpdate\": \"{{free-timestamp}}\"\n        }\n    ]\n}","output":"str","x":720,"y":460,"wires":[["ced95c01.75153"]]},{"id":"c088c2a8.b53bc","type":"comment","z":"8c9f8f17.13eb78","name":"Json Feed zum Füttern des MagicMirrors","info":"","x":240,"y":80,"wires":[]},{"id":"61e489ce.08eb68","type":"change","z":"8c9f8f17.13eb78","name":"Copy time","rules":[{"t":"set","p":"temp","pt":"msg","to":"temp","tot":"flow"},{"t":"set","p":"temp-timestamp","pt":"msg","to":"temp-timestamp","tot":"flow"},{"t":"set","p":"load","pt":"msg","to":"load","tot":"flow"},{"t":"set","p":"load-timestamp","pt":"msg","to":"load-timestamp","tot":"flow"},{"t":"set","p":"free","pt":"msg","to":"free","tot":"flow"},{"t":"set","p":"free-timestamp","pt":"msg","to":"free-timestamp","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":460,"wires":[["a5b108a6.e68c88"]]},{"id":"b64f17d1.b71778","type":"comment","z":"8c9f8f17.13eb78","name":"Hier werden ankommende Daten für das spätere versenden zwischngespeichert","info":"","x":480,"y":140,"wires":[]},{"id":"9eede084.b713a","type":"comment","z":"8c9f8f17.13eb78","name":"Hier werden die gespeicherten Daten als Json ausgeliefert","info":"","x":410,"y":420,"wires":[]},{"id":"877b026b.7bbd9","type":"exec","z":"8c9f8f17.13eb78","command":"vcgencmd measure_temp","addpay":false,"append":"","useSpawn":"","timer":"","name":"RPi Temp.","x":510,"y":220,"wires":[["c71030c9.e8723"],[],[]]},{"id":"e2c23c0f.e6896","type":"inject","z":"8c9f8f17.13eb78","name":"","topic":"","payload":"","payloadType":"date","repeat":"10","crontab":"","once":false,"onceDelay":"","x":310,"y":220,"wires":[["877b026b.7bbd9","bd2a3aa8.b05be8","f6021bf6.b47108"]]},{"id":"c71030c9.e8723","type":"function","z":"8c9f8f17.13eb78","name":"cutString","func":"str = msg.payload\nmsg.payload = str.substring(5,9);\nreturn msg;","outputs":1,"noerr":0,"x":700,"y":220,"wires":[["38abd283.af271e"]]},{"id":"bd2a3aa8.b05be8","type":"exec","z":"8c9f8f17.13eb78","command":"top -d 1 -b -n2 | grep \"Cpu(s)\"|tail -n 1 | awk '{print $2 + $4}'","addpay":false,"append":"","useSpawn":"","timer":"","oldrc":false,"name":"CPU Load","x":510,"y":280,"wires":[["966babc4.47d538"],[],[]]},{"id":"f6021bf6.b47108","type":"exec","z":"8c9f8f17.13eb78","command":"free | grep Mem | awk '{print 100*($4+$6+$7)/$2}'","addpay":false,"append":"","useSpawn":"","timer":"","name":"Free Memory","x":510,"y":340,"wires":[["350be0e6.dc723"],[],[]]},{"id":"ff73e7b0.560078","type":"change","z":"8c9f8f17.13eb78","name":"Store time","rules":[{"t":"set","p":"temp","pt":"flow","to":"payload","tot":"msg"},{"t":"set","p":"temp-timestamp","pt":"flow","to":"timestamp","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1170,"y":220,"wires":[[]]},{"id":"ec6a82fb.238ff","type":"change","z":"8c9f8f17.13eb78","name":"Store time","rules":[{"t":"set","p":"load","pt":"flow","to":"payload","tot":"msg"},{"t":"set","p":"load-timestamp","pt":"flow","to":"timestamp","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1170,"y":280,"wires":[[]]},{"id":"bd9b96f7.e4c268","type":"change","z":"8c9f8f17.13eb78","name":"Store time","rules":[{"t":"set","p":"free","pt":"flow","to":"payload","tot":"msg"},{"t":"set","p":"free-timestamp","pt":"flow","to":"timestamp","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1170,"y":340,"wires":[[]]},{"id":"38abd283.af271e","type":"function","z":"8c9f8f17.13eb78","name":"addTimestamp","func":"msg.payload = msg.payload;\nvar now = new Date();\n\nvar Hours=now.getHours();\nvar Minutes=now.getMinutes();\nvar Seconds=now.getSeconds();\n\n if (Seconds<10)\n Seconds=\"0\"+Seconds;\n \n if (Minutes<10)\n Minutes=\"0\"+Minutes;\n \n if (Hours<10)\n Hours=\"0\"+Hours;\n \nmsg.timestamp=Hours+\":\"+Minutes+\":\"+Seconds;\nreturn msg;","outputs":1,"noerr":0,"x":960,"y":220,"wires":[["ff73e7b0.560078"]]},{"id":"9a625c6e.b43da","type":"function","z":"8c9f8f17.13eb78","name":"addTimestamp","func":"msg.payload = msg.payload;\nvar now = new Date();\n\nvar Hours=now.getHours();\nvar Minutes=now.getMinutes();\nvar Seconds=now.getSeconds();\n\n if (Seconds<10)\n Seconds=\"0\"+Seconds;\n \n if (Minutes<10)\n Minutes=\"0\"+Minutes;\n \n if (Hours<10)\n Hours=\"0\"+Hours;\n \nmsg.timestamp=Hours+\":\"+Minutes+\":\"+Seconds;\nreturn msg;","outputs":1,"noerr":0,"x":960,"y":280,"wires":[["ec6a82fb.238ff"]]},{"id":"a85eaa63.cad4a8","type":"function","z":"8c9f8f17.13eb78","name":"addTimestamp","func":"msg.payload = msg.payload;\nvar now = new Date();\n\nvar Hours=now.getHours();\nvar Minutes=now.getMinutes();\nvar Seconds=now.getSeconds();\n\n if (Seconds<10)\n Seconds=\"0\"+Seconds;\n \n if (Minutes<10)\n Minutes=\"0\"+Minutes;\n \n if (Hours<10)\n Hours=\"0\"+Hours;\n \nmsg.timestamp=Hours+\":\"+Minutes+\":\"+Seconds;\nreturn msg;","outputs":1,"noerr":0,"x":960,"y":340,"wires":[["bd9b96f7.e4c268"]]},{"id":"350be0e6.dc723","type":"function","z":"8c9f8f17.13eb78","name":"deleteWhitespace","func":"str = msg.payload\nmsg.payload = str.trim();\nreturn msg;","outputs":1,"noerr":0,"x":730,"y":340,"wires":[["a85eaa63.cad4a8"]]},{"id":"966babc4.47d538","type":"function","z":"8c9f8f17.13eb78","name":"deleteWhitespace","func":"str = msg.payload\nmsg.payload = str.trim();\nreturn msg;","outputs":1,"noerr":0,"x":730,"y":280,"wires":[["9a625c6e.b43da"]]}]

Now you will see a JSON with the data entered by you at the following address.

https://IP_EURER_NODE_RED_INSTALLATION:1880/daten.json

This can now be displayed by a MagicMirror plugin.  Of course you have to replace the “IP_EURER_NODE_RED_INSTALLATION”-part by the IP adress of your NodeRed Server. It is also important that you check if you need an “https://” or “http://” in front of your IP adress. This depents weather you have your NodeRed-connection encrypted or not.

JSON data as displayed to you in the Firefox browser. This one is good for debugging because it also displays errors in the JSON structure.

Installation of the module

In order for you to be able to view the data provided to you by NodeRed as JSON on the MagicMirror, you must then install the “MMM-JsonTable” module. You can find it at https://github.com/timdows/MMM-JsonTable.

Install this on your RaspberryPi. How to install your module is described in the following article:
MagicMirror – install 3rd party modules


Configuration of the module

The configuration of the module is kept simple, as the structure of the displayed data is given by the JSON.

sudo nano ~/MagicMirror/config/config.js
Open the configuration file of your MagicMirror and insert the module configuration.
{
   module: 'MMM-JsonTable',
   position: 'top_right',
   header: 'Raspi-Status',
   config: {
      url: 'https://IP_EURER_NODE_RED_INSTALLATION:1880/daten.json', // Required
      arrayName: 'Daten', // Optional
      tryFormatDate: false
   }
}
Of course you will replace “IP_EURER_NODE_RED_INSTALLATION” with the IP address of the RaspberryPi on which your MagicMirror is running.

Modification of the module for self-signed SSL certificates

Unfortunately, there is a problem with the MagicMirror plugin (currently: November 2018). This does not allow HTTPS connections if the SSL certificate is self-signed.
In other words, if you have your NodeRed installation secured by a self-signed SSL certificate as described in the article NodeRed – Encrypting Connection, the MagicMirror plugin will not be able to load or display the data from the JSON.

To solve this problem, there is a small workaround that shuts off this security feature. This means that the MagicMirror plugin can also accept self-signed SSL certificates and display the data of your JSON.

Go to the module folder of the MagicMirror module you just installed.

cd MagicMirror/modules/MMM-JsonTable/

There you open the file “node_helper.js” with the following command:

sudo nano node_helper.js

In the opened file you must now find the line with the following content:

request({ url: url, method: 'GET'}, function (error, response, body) {
In the uncorrected file you have to find the line with “request ({url: url, method: ‘GET’}, function (error, response, body) {“.

Now in this line you have to insert the command “, rejectUnauthorized: false” after the “… method: ‘GET'”.
The line should look like this:

 request({ url: url, method: 'GET', rejectUnauthorized: false}, function (error, response, body){
The corrected line looks like this.
Then you save the file again by pressing “CTRL + X”, then confirm with “J”(Or “y”) …
… and leave the file with “Enter”.

Last but not least, you have to restart your MagicMirror installation by entering the following command:

pm2 restart mm

After restarting and reloading the MagicMirror view, the data from the JSON will be displayed. 🙂


Additional Information

https://github.com/MichMich/MagicMirror
https://github.com/timdows/MMM-JsonTable


I hope everything worked as described. If not or you have any other questions or suggestions, please let me know in the comments. Also, ideas for new projects are always welcome. 🙂

Fab

P.S. Many of these projects - especially the hardware projects - cost a lot of time and money. Of course I do this because I enjoy it, but if you appreciate it that I share these information with you, I would be happy about a small donation to the coffee box. 🙂

Buy Me a Coffee at ko-fi.com

9 comments

  1. Hi, tolle Seite! Ich fange gerade erst an mit RedNote und bin zufällig auf deine Seite gestoßen. Top!
    Magicmirror betreibe ich schon etwas länger und meine Frage ist, kann ich auch andere JSon Daten anzeigen lassen ?

    Gruß Stefan

    1. Hi Stefan, danke freut mich. 🙂
      Klar die Daten die angezeigt werden kannst du natürlich auch ändern. Im Prinzip musst du nur die Daten ändern die an die “cutString oder “deleteWhitespace” nodes weitergeleitet werden ändern.
      Beste Grüße
      Fabian

  2. Super, vielen Dank. Dann versuche ich h das mal..
    Habe aber gerade noch mit dem Weatherground zu kämpfen. Bekomme das nicht richtig angezeigt.

    Gruß Stefan

      1. Hi, sorry ich meinte dein openweathermap.org… 😉
        Ich bekomme es irgendwie nicht unter einander und auch nicht alles angezeigt.
        Aber das wird schon, muss mich da ein bisschen reinfuchsen.

        Hast du hier eigentlich ein Forum oder so, wo man sich austauschen kann ?

        1. Hey,
          kein Problem. 🙂 Was bekommst du denn nicht untereinander? Die Ansicht im Dashboard?
          Ja, ich habe mal ein Forum eingerichtet. Muss das aber noch etwas ausbauen. Werde ich mir morgen drum kümmern. 🙂
          Beste Grüße
          Fab

  3. Danke für das Tutorial!
    Ich hatte den Bug, dass das Modul am Anfang nur “Awaiting json data…” angezeigt hat.
    Ein reboot hat das behoben.

Leave a Reply

Your email address will not be published. Required fields are marked *