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 stores listed here are so-called affiliate links. If you click on such an affiliate link and store via this link, Nerdiy.de receives a commission from the online store 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.

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":"{"data": \"RPi Temp\",\n \"value\": \"{{temp}}°C\",\n \"lastUpdate\": \"{{temp-timestamp}}\"\n },\n \"name\": \"CPU Load\",\n \"value\": \"{{load}}%\",\n \"lastUpdate\": \"{{load-timestamp}}\"\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 to feed the MagicMirror", "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": "Incoming data is cached here for later sending", "info":"", "x":480, "y":140, "wires":[]},{"id": "9eede084.b713a", "type": "comment", "z": "8c9f8f17.13eb78", "name": "Here the stored data are delivered as Json", "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();\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();\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();\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 address of your NodeRed Server. It is also important that you check if you need an "https://" or "http://" in front of your IP address. This depents weather you have your NodeRed-connection encrypted or not.

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

{ module: 'MMM-JsonTable', position: 'top_right', header: 'raspi-status', config: { url: 'https://IP_EURER_NODE_RED_INSTALLATION:1880/daten.json', // Required arrayName: 'data', // Optional tryFormatDate: false } }

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 Connectionthe 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) {

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){



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
Have fun with the project
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. 🙂
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 that I share this information with you, I would be happy about a small donation to the coffee box. 🙂
Hi, great site! I'm just starting with RedNote and came across your site by accident. Top!
Magicmirror I run a little longer and my question is, can I display other JSon data ?
Greeting Stefan
Hi Stefan, thanks I'm glad 🙂
Of course you can change the data that is displayed. In principle you only have to change the data that is forwarded to the "cutString or "deleteWhitespace" nodes.
Best regards
Fabian
Great, thank you very much. Then I try h that times...
But I am still struggling with the Weatherground. I can't get it to display correctly.
Greeting Stefan
Okay, feel free to let me know how it went 🙂 .
I haven't worked with weatherground at all yet. But here you can find my code for openweathermap.org 🙂
https://nerdiy.de/nodered-aktuelle-wetterdaten-von-openweathermap-beziehen/
Hi, sorry I meant your openweathermap.org... 😉
I somehow do not get it displayed under each other and also not everything.
But it'll be fine, I'll have to fiddle with it a bit.
Do you actually have a forum or something here where you can exchange ideas ?
Hey,
no problem. 🙂 What do you not get each other? The view in the dashboard?
Yes, I have once set up a forum. But must still expand something. I'll take care of it tomorrow. 🙂
Best regards
Fab
Hey Stefan,
have now made the forum a little "pretty". You can find the link to it in the top navigation bar 🙂 .
Thanks for the tutorial!
I had the bug that the module only showed "Awaiting json data..." at the beginning.
A reboot fixed that.
Hey Achim,
Thank you very much for the tip. Then I still have to write that to it. Thank you 🙂