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

Magicmirror touchscreen tablet dashboard

Scheduled Pinned Locked Moved Show your Mirror
18 Posts 8 Posters 7.1k Views 13 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.
  • C Offline
    CobraRL_
    last edited by Jan 31, 2023, 8:03 PM

    Hello everyone! As an absent-minded university student, I’ve always liked the idea of having a touchscreen dashboard that I could use to keep track of my schedule, to-do list, homework, etc.

    I have finished just that and I’d figure I’d share it with the forum.

    IMG_0068.jpg

    Here’s a link to the album of screenshots for each page since the image files were too big for the forum: https://imgur.com/a/LjmpA16

    This magicmirror has been achieved by using a number of 3rd party modules, custom CSS, and a custom music widget which connects to HomeAssistant and MMM-FF-Genius-Lyrics.

    Feel free to ask any questions or share any suggestions.

    K 1 Reply Last reply Feb 1, 2023, 7:59 AM Reply Quote 3
    • K Offline
      KamiSchami @CobraRL_
      last edited by Feb 1, 2023, 7:59 AM

      @CobraRL_ how did you implement that? which software is running?

      Real programmers never work 9 to 5. If they are around at 9 AM, it's because they were up all night.

      C 1 Reply Last reply Feb 1, 2023, 6:04 PM Reply Quote 0
      • C Offline
        CobraRL_ @KamiSchami
        last edited by Feb 1, 2023, 6:04 PM

        @KamiSchami I’m using a Raspberry Pi 4 running Home Assistant and MagicMirror on server mode, then opening MagicMirror from my tablet.

        I can go into detail how I tweaked and used every module if needed but for now I’ll provide a bit of the overview.

        In order of pages:

        • MMM-Pages
          • for separating all modules into individual pages (as shown on the top of the screen)
        • MMM-Page-Indicator
          • Usually the page indicators use dots, but I decided to use CSS to replace the dots with actual titles for each page.
        • MMM-Unsplash
          • Provides wallpaper

        Page 1 (Home)

        • Default Clock
          • I can talk about how I edited this, because usually the date is at the top not the bottom. I used CSS to reorient the module’s HTML elements
        • Default Weather with custom weather icons

        Page 2 (Schedule)

        • MMM-CalendarExt3
          • provides the weekly calendar. This has been heavily tweaked with CSS.
        • MMM-CalendarExt3Timeline
          • This provides the timetable on top of the calendar. It has also been heavily tweaked with CSS.

        Page 3 (Tasks)

        • MMM-CalendarExt3Agenda
          • I use my canvas calendar to provide me with all the assignments that are due. This modules on the bottom_right
        • MMM-ToDoist
          • I have the ToDoist app to help me keep up with the things I need to do. this module is on bottom_left.

        Page 4 (Room)

        • MMM-HomeAssistant-Touch
          • Also heavily tweaked with CSS, but allows me to control my homeassistant entities from the dashboard for ease-of-access

        Page 5 (Music)

        • MMM-HA-MediaPlayer
          • Originally this was MMM-HomeAssistant but I changed around the JS, Node helper, and CSS to make it a suitable music module that can also work with MMM-FF-Genius-Lyrics.
        • MMM-FF-Genius-Lyrics
          • Connects to the Genius API to get the lyrics of songs you’re listening to

        Page 6 (Timer)

        • Heavily tweaked MMM-KitchenTimer

        Page 7 (HomeAssistant)

        • iFrame
          • I use an iframe to show my HomeAssistant home page just in case I want to change the colors of my lights.

        Let me know if you want to know about any specific modules and how I tweaked them!

        E A 2 Replies Last reply Feb 15, 2023, 7:08 PM Reply Quote 1
        • E Offline
          easily @CobraRL_
          last edited by Feb 15, 2023, 7:08 PM

          @CobraRL_ Nice work! I really like your work with the page indicator. Can you provide an example how you changed the CSS of it? Would like to try it by myself.

          C 1 Reply Last reply Feb 24, 2023, 4:53 AM Reply Quote 0
          • A Offline
            Axel51 @CobraRL_
            last edited by Feb 17, 2023, 1:17 AM

            @CobraRL_ hi, i love your timer. Can you show/send me what you’ve changed on the MMM-KitchenTimer module?
            tx

            C 1 Reply Last reply Feb 24, 2023, 5:06 AM Reply Quote 0
            • C Offline
              CobraRL_ @easily
              last edited by Feb 24, 2023, 4:53 AM

              @easily It was kind of simple. I hid the page indicator’s “::before” and created an “::after” with the content of the page title. Here’s all the code I used for the page indicator:

              .MMM-page-indicator div div {
                display: flex;
                margin: 0px var(--header-horizontal-margin);
                justify-content: space-between;
              }
              
              .MMM-page-indicator div i::before {
                display: none;
              }
              
              .MMM-page-indicator .fa-circle::after {
                font-weight: 400 !important;
              }
              
              .MMM-page-indicator div i::after {
                font-family: var(--font-primary);
                font-size: var(--header-font-size);
                font-weight: 300;
              }
              
              .MMM-page-indicator div i:nth-child(1)::after {
                content: "Home";
              }
              
              .MMM-page-indicator div i:nth-child(2)::after {
                content: "Schedule";
              }
              
              .MMM-page-indicator div i:nth-child(3)::after {
                content: "Tasks";
              }
              
              .MMM-page-indicator div i:nth-child(4)::after {
                content: "Room";
              }
              
              .MMM-page-indicator div i:nth-child(5)::after {
                content: "Music";
              }
              
              .MMM-page-indicator div i:nth-child(6)::after {
                content: "Timer";
              }
              
              .MMM-page-indicator div i:nth-child(7)::after {
                content: "HomeAssistant";
              }
              
              1 Reply Last reply Reply Quote 0
              • C Offline
                CobraRL_ @Axel51
                last edited by Feb 24, 2023, 5:06 AM

                @Axel51 I did a bunch of small changes to the JS like adding extra class names, adding extra wrappers, and removing the sounds because I found them annoying. The extra class names and wrappers helped me with the css. Hopefully the css variables are self-explanatory that it still makes sense.

                Let me know if you need me to clarify anything!

                Here’s the .css code

                .MMM-KitchenTimer div {
                  display: grid;
                }
                
                .MMM-KitchenTimer .text {
                  font-family: var(--font-primary);
                  font-weight: 300;
                  font-size: 12rem;
                  color: var(--secondary-background-color);
                  text-align: center;
                  line-height: 1;
                }
                
                .MMM-KitchenTimer .paused {
                  color: rgba(255, 255, 255, 0.6);
                }
                
                .MMM-KitchenTimer .button {
                  font-size: 20px;
                  font-weight: 300;
                
                  display: flex;
                  align-items: center;
                  justify-content: center;
                  min-width: 6rem;
                  aspect-ratio: 1;
                  border-radius: 100px;
                
                  background-color: var(--primary-background-color);
                  color: var(--primary-foreground-color);
                  backdrop-filter: blur(var(--blur));
                  -webkit-backdrop-filter: blur(var(--blur));
                }
                
                .MMM-KitchenTimer .list-container {
                  display: flex !important;
                  justify-content: center;
                  gap: 1rem;
                }
                

                Here’s the .js code

                
                /* global Log, Module, moment, config */
                /* Magic Mirror
                 * Module: Kitchen timers
                 *
                 * By Tom Short
                 * MIT Licensed.
                 */
                Module.register("MMM-KitchenTimer",{
                    // Module config defaults.
                    defaults: {
                        timertext: ["1m", "5m", "20m"],
                        timersecs: [60, 300, 1200],
                    },
                    // Define required scripts.
                    getScripts: function() {
                        return [];
                    },
                    // Define styles.
                    getStyles: function() {
                        return ["MMM-KitchenTimer.css"];
                    },
                    // Define start sequence.
                    start: function() {
                        Log.info("Starting module: " + this.name);
                
                        // Schedule update.
                        setTimeout(function() {
                            self.getDom();
                        }, 1000);
                    },
                    // Override dom generator.
                    getDom: function() {
                        var time = 0, startTime, interval, alarm;
                        function start() {
                            if (!interval) {
                                startTime = Date.now();
                                interval = setInterval(update, 1000);
                            }
                            display();
                        }
                        function pause() {
                            if (interval) {
                		        timerText.className = "text paused";
                                sound.pause();
                                clearInterval(interval);
                                interval = null;
                            }
                        }
                        function update() {
                            time -= delta();
                            display();
                        }
                        function addSeconds(value) {
                            time += value;
                        }
                        function delta() {
                            var now = Date.now(),
                                d = now - startTime;
                            startTime = now;
                            return d / 1000;
                        }
                        function stop() {
                            pause();
                            time = 0;
                            display();
                        }       
                        function pad(val) {
                            var str = "00";
                            return str.substring(0, str.length - String(val).length) + val;
                        } 
                        function display() {
                            var secs = Math.round(Math.abs(time % 60));
                            var mins = Math.abs(Math.trunc(time / 60) % 60);
                            var hours = Math.abs(Math.trunc(time / 3600));
                            var sign = Math.sign(time); 
                            if (time > 0) {
                                timerText.className = "text positive";
                            } else if (time < 0) {
                		        timerText.className = "text negative";
                            } else {
                		        timerText.className = "text";
                            }
                            timerText.innerHTML = 
                                (time < 0 ? "-" : "") + 
                                (hours > 0 ? hours+":" : "") +
                                pad(mins,2) + ":" + pad(secs,2);
                        }
                        var timerText = document.createElement("span");
                        var wrapper = document.createElement("div");
                
                        wrapper.appendChild(timerText);
                
                        var wrapper2 = document.createElement("section");
                        wrapper2.className = "list-container";
                        // Create buttons
                        for (var i=0; i<this.config.timertext.length; i++) {
                            var el =  document.createElement("div");
                            el.className = "button";
                            el.innerHTML = this.config.timertext[i];
                            el.counter = i;
                            var self = this;
                            el.addEventListener("click", function(event) {
                                addSeconds(self.config.timersecs[this.counter]);
                                start();
                            }); 
                            wrapper2.appendChild(el);
                        }; 
                        const sound = document.createElement('audio');
                        sound.src = this.file("alarm.wav");
                        sound.setAttribute('autoplay', true);
                        sound.setAttribute('loop', true);
                        sound.pause();
                        const beep = document.createElement('audio');
                        beep.src = this.file("beep.wav");
                        beep.volume = 0.2;
                        beep.pause();
                        display();
                        timerText.addEventListener("click", function(event) {
                            if (interval) {
                                pause();
                            } else if (time != 0) {
                                start();
                            }
                        });
                        var stopButton = document.createElement("div");
                        stopButton.className = "button stop";
                        stopButton.innerHTML = "X";
                        stopButton.addEventListener("click", stop);
                        wrapper2.appendChild(stopButton);
                        wrapper.appendChild(wrapper2);
                        return wrapper;
                    }
                });
                
                
                1 Reply Last reply Reply Quote 0
                • W Offline
                  wfsaxton
                  last edited by Mar 11, 2023, 3:21 PM

                  Nice job on this. I was also thinking of going the tablet route with MM. I never thought of the server approach, which seems to make it a lot easier. Although I’m guessing streaming video wouldn’t work out so well (if I wanted to implement that).

                  Question: How did you set up the client on the tablet? Is it just a full-screen web browser?

                  C 1 Reply Last reply Mar 28, 2023, 2:53 AM Reply Quote 0
                  • C Offline
                    CobraRL_ @wfsaxton
                    last edited by Mar 28, 2023, 2:53 AM

                    @wfsaxton Yeah its just a fullscreen browser. I’ve tried doing google cast and a smart assistant on it but neither of them worked for me.

                    1 Reply Last reply Reply Quote 0
                    • F Offline
                      frentemorao
                      last edited by Apr 28, 2023, 10:28 AM

                      Your project is quite interesting.
                      I also have a pizero running MM on server mode and a tablet as a dashboard.

                      I would like to know how you manage to move between the different screens as it is a fullscreen browser.

                      Thanks in advance

                      S 1 Reply Last reply Apr 28, 2023, 11:45 AM Reply Quote 0
                      • 1
                      • 2
                      • 1 / 2
                      • First post
                        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