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.

    DIY Module Displays Nothing

    Scheduled Pinned Locked Moved Solved Troubleshooting
    14 Posts 3 Posters 1.2k Views 2 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.
    • S Do not disturb
      sdetweil @sdetweil
      last edited by sdetweil

      @hokie-bird

      this test
      this.isPlaying = (this.nowPlaying.artist && this.nowPlaying.song) ? true : false;

      will always evaluate to true
      if artist and song are “”, as strings those will evaluate to true

      null is a non-true value, but also not a string

      Sam

      How to add modules

      learning how to use browser developers window for css changes

      1 Reply Last reply Reply Quote 0
      • H Offline
        hokie-bird
        last edited by

        Thanks to all for the suggestions. Ive attempted to incorporate them all, which has yeilded a small bit of progress: now 'No song is playing" appears bottom_center at MM startup for a second or 2, then vanishes nothing displaying again regardless of whether music starts, stops, etc. Browser console still reports data being received, and I cant figure how else to use the Developer Tools to troubleshoot. Here’s the latest code:

        MMM-LyrionNowPlaying.js

        /* MagicMirror² Module: MMM-LyrionNowPlaying */
        
        Module.register("MMM-LyrionNowPlaying", {
        
            // Default module config.
            defaults: {
                updateInterval: 1000,
                retryDelay: 2500,
                lyrionServer: 'http://localhost:9000',
                playerName: 'livingroom-mm',
                showCoverArt: true,
                coverArtSize: 150,
                fadeSpeed: 4000,
            },
        
            getStyles: function () {
                return ["MMM-LyrionNowPlaying.css"];
            },
        
            start: function () {
                Log.info("Starting module: " + this.name);
                this.nowPlaying = {
                    artist: "",
                    song: "",
                    timeRemaining: "",
                    coverArt: ""
                };
                this.isPlaying = false;
                this.updateTimer = null; // Initialize updateTimer
        
                this.updateDom(0);
                this.scheduleUpdate();
            },
        
            notificationReceived: function (notification, payload, sender) {
                if (notification === "ALL_MODULES_STARTED" || notification === "DOM_OBJECTS_CREATED") {
                    this.sendSocketNotification('GET_LYRION_NOW_PLAYING', {
                        lyrionServer: this.config.lyrionServer,
                        playerName: this.config.playerName
                    });
                }
            },
        
            getDom: function () {
                const wrapper = document.createElement("div");
                wrapper.classList.add("wrapper");
        
                if (this.isPlaying) {
                    if (this.nowPlaying.coverArt && this.config.showCoverArt) {
                        const coverArtImg = document.createElement("img");
                        coverArtImg.src = this.nowPlaying.coverArt;
                        coverArtImg.width = this.config.coverArtSize;
                        coverArtImg.height = this.config.coverArtSize;
                        coverArtImg.classList.add("coverArt");
                        wrapper.appendChild(coverArtImg);
                    }
        
                    const infoContainer = document.createElement("div");
                    infoContainer.classList.add("infoContainer");
        
                    if (this.nowPlaying.artist && this.nowPlaying.song) {
                        const songInfo = document.createElement("div");
                        songInfo.classList.add("songInfo");
                        songInfo.innerHTML =
                            this.nowPlaying.artist + " - " +
                            this.nowPlaying.song;
                        infoContainer.appendChild(songInfo);
                    }
        
                    if (this.nowPlaying.timeRemaining) {
                        const timeRemaining = document.createElement("div");
                        timeRemaining.classList.add("timeRemaining");
                        timeRemaining.innerHTML = "Time Remaining: " + this.nowPlaying.timeRemaining;
                        infoContainer.appendChild(timeRemaining);
                    }
        
                    wrapper.appendChild(infoContainer);
                } else {
                    wrapper.innerHTML = "No song is currently playing.";
                }
        
                console.log("Generated HTML:", wrapper.innerHTML);
                return wrapper;
            },
        
            scheduleUpdate: function () {
                if (this.updateTimer) {
                    clearInterval(this.updateTimer);
                }
        
                this.updateTimer = setInterval(() => {
                    this.getLyrionNowPlaying();
                }, this.config.updateInterval);
            },
        
            getLyrionNowPlaying: function () {
                this.sendSocketNotification('GET_LYRION_NOW_PLAYING', {
                    lyrionServer: this.config.lyrionServer,
                    playerName: this.config.playerName
                });
            },
        
            socketNotificationReceived: function (notification, payload) {
                if (notification === 'LYRION_NOW_PLAYING_RESULT') {
                    if (payload.error) {
                        Log.error(`MMM-LyrionNowPlaying: ${payload.error}`);
                    } else {
                        this.nowPlaying = payload;
                        console.log("Received data:", this.nowPlaying);
                        console.log("this.nowPlaying after update:", this.nowPlaying);
        
                        // Corrected isPlaying check:
                        this.isPlaying = (this.nowPlaying.artist && this.nowPlaying.artist !== "" && this.nowPlaying.song && this.nowPlaying.song !== "") ? true : false;
        
                        const duration = Number(this.nowPlaying.duration);
                        const position = Number(this.nowPlaying.position);
        
                        if (!isNaN(duration) && !isNaN(position) && duration > 0 && position >= 0) {
                            this.nowPlaying.timeRemaining = this.formatTime(duration - position);
                        } else {
                            this.nowPlaying.timeRemaining = "";
                        }
        
                        this.updateDom(this.config.fadeSpeed);
                    }
                }
            },
        
            formatTime: function (seconds) {
                const minutes = Math.floor(seconds / 60);
                const remainingSeconds = seconds % 60;
                return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
            }
        });
        
        

        Suggestions welcome and again a huge thank you to the community.

        S 1 Reply Last reply Reply Quote 0
        • S Do not disturb
          sdetweil @hokie-bird
          last edited by

          @hokie-bird

          I built it and fixed minor things…
          created a dummy node_helper and a dummy album art png.

          so save yours out of the way,(rename the folder)
          cd ~/MagicMirror/modules
          git clone https://github.com/sdetweil/MMM-LyrionNowPlaying

          test
          copy your node helper over mine

          be careful on your update frequency asking the node_helper all the time…

          once per second is probably too fast…
          i made mine ignore socketNotifications() til a response was sent (after 5 second delay) from the 1st time.
          the duration is just number that changes…, duration just a fixed number

          Sam

          How to add modules

          learning how to use browser developers window for css changes

          1 Reply Last reply Reply Quote 0
          • H Offline
            hokie-bird
            last edited by

            @sdetweil cant thank you enough for taking the time to do that, WOW!

            Here’s what I’ve learned. I subbed your LyrionNowPlaying.js in for mine, and results were exactly the same: “No song currently playing” at startup for a second or two, vanishes and never returns despite music starting/stopping. Then I subbed your node_helper.js for mine (with your module.js file and .png) and BOOM! your data and image appeared! Granted, it would appear for 4 seconds or so, disappear for 1-2, then re-appear but progress! So, safe to assume its somehow something in my node_helper? Here’s the latest, and again wildly grateful for your help.

            node_helper.js

            const NodeHelper = require('node_helper');
            const request = require('request');
            
            module.exports = NodeHelper.create({
            
                start: function() {
                    console.log("Starting node_helper for: " + this.name);
                    this.nowPlaying = { 
                        artist: "", 
                        song: "",
                        timeRemaining: "",
                        duration: 0, 
                        position: 0,
                        coverArt: "" 
                    }; 
                    this.sendSocketNotification('LYRION_NOW_PLAYING_RESULT', this.nowPlaying); // Send initial empty state
                },
            
                socketNotificationReceived: function(notification, payload) {
                    if (notification === 'GET_LYRION_NOW_PLAYING') {
                        this.getLyrionNowPlaying(payload);
                    }
                },
            
                getLyrionNowPlaying: function(payload) {
                    const { lyrionServer, playerName } = payload;
                    const options = {
                        url: `${lyrionServer}/jsonrpc.js`,
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify({
                            "id": 1,
                            "method": "slim.request",
                            "params": [playerName, ["status", "-", 1, "tags:artist"]] 
                        })
                    };
            
                    request(options, (error, response, body) => {
                        if (error) {
                            console.error(`MMM-LyrionNowPlaying: Error connecting to Lyrion server: ${error}`);
                            this.sendSocketNotification('LYRION_NOW_PLAYING_RESULT', { error: `Error connecting to Lyrion server: ${error}` });
                            return;
                        }
            
                        if (response.statusCode !== 200) {
                            console.error(`MMM-LyrionNowPlaying: Received unexpected status code from Lyrion server: ${response.statusCode}`);
                            this.sendSocketNotification('LYRION_NOW_PLAYING_RESULT', { error: `Received unexpected status code from Lyrion server: ${response.statusCode}` });
                            return;
                        }
            
                        try {
                            const data = JSON.parse(body);
                            console.log("Raw Data:", data); 
            
                            if (!data.result) {
                                console.error(`MMM-LyrionNowPlaying: Invalid response from Lyrion server: Missing 'result' in response`);
                                this.sendSocketNotification('LYRION_NOW_PLAYING_RESULT', { error: `Invalid response from Lyrion server: Missing 'result' in response` });
                                return;
                            }
            
                            if (!data.result.mode || data.result.mode !== 'play') { 
                                this.nowPlaying = { 
                                    artist: "", 
                                    song: "",
                                    timeRemaining: "",
                                    duration: 0, 
                                    position: 0,
                                    coverArt: "" 
                                }; 
                                this.sendSocketNotification('LYRION_NOW_PLAYING_RESULT', this.nowPlaying); // Send "no song" notification immediately
                                return; 
                            }
            
                            // Handle cases where playlist_loop might be missing or empty
                            let artist = "Unknown Artist";
                            let song = "Unknown Song";
            
                            if (data.result.playlist_loop && data.result.playlist_loop[0]) {
                                artist = data.result.playlist_loop[0].artist || "Unknown Artist";
                                song = data.result.playlist_loop[0].title || "Unknown Song"; 
                            }
            
                            this.nowPlaying = {
                                artist: artist,
                                song: song,
                                duration: data.result.duration || 0, 
                                position: data.result.time || 0,
                                coverArt: `${lyrionServer}/music/current/cover.jpg?player=${playerName}` 
                            }; 
            
                            this.nowPlaying.timeRemaining = this.formatTime(this.nowPlaying.duration - this.nowPlaying.position);
            
                            this.sendSocketNotification('LYRION_NOW_PLAYING_RESULT', this.nowPlaying); 
            
                        } catch (err) {
                            console.error(`MMM-LyrionNowPlaying: Error parsing Lyrion API response: ${err}`);
                            this.sendSocketNotification('LYRION_NOW_PLAYING_RESULT', { error: `Error parsing Lyrion API response: ${err}` });
                        }
                    });
                },
            
                formatTime: function(seconds) {
                    const minutes = Math.floor(seconds / 60);
                    const remainingSeconds = seconds % 60;
                    return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
                }
            });
            
            
            S 1 Reply Last reply Reply Quote 0
            • S Do not disturb
              sdetweil @hokie-bird
              last edited by sdetweil

              @hokie-bird not sure, but two things

              1. the sendSocketNotification() in start should be removed , the browser side is not up yet.

              2. you are sending requests for playing info 1/second,
                can the server handle multiple concurrently?
                how long is the response time ?

              i would change that to 5 seconds to test,
              you can change it in config.js

              Sam

              How to add modules

              learning how to use browser developers window for css changes

              1 Reply Last reply Reply Quote 0
              • H Offline
                hokie-bird
                last edited by

                Thank you again @sdetweil

                I implemented both of your changes (removing sendSocketNotification() in start and 5 second refresh interval) and it seems the refresh interval is what is impacting the display. At 1 second, basically nothing, but at 5 seconds I get a 5 second display, then maybe a 2 second disappearance and then a 5 second display repeating pattern. (Which is somewhat interesting as the browser console is reporting accurate data every 1 second, despite nothing being displayed.) Not sure how to get a constant/non-disappearing display (when music is playing) while still getting an accurate reflection/countdown of the time remain, but I’ll experiment with that.

                Of course, suggestions welcome. And thanks again.

                S 1 Reply Last reply Reply Quote 0
                • S Do not disturb
                  sdetweil @hokie-bird
                  last edited by sdetweil

                  @hokie-bird you are also asking for a 4 second transition on the changes w updateDom(…)

                  so 2 seconds fade out and 2 seconds fade in

                  this.updateDom(this.config.fadeSpeed);
                  and you are interrupting the fade with another updateDom

                  Sam

                  How to add modules

                  learning how to use browser developers window for css changes

                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    hokie-bird
                    last edited by

                    It was the fade! when I switch the fade to 0, even the refresh of 1 seconds works and displays perfectly. @sdetweil you are brilliant!

                    Thank you!

                    1 Reply Last reply Reply Quote 0
                    • S sdetweil has marked this topic as solved on
                    • 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