MagicMirror Forum
    • Recent
    • Tags
    • Unsolved
    • Solved
    • MagicMirror² Repository
    • Documentation
    • 3rd-Party-Modules
    • Donate
    • Discord
    • Register
    • Login
    • Profile
    • Following 0
    • Followers 1
    • Topics 29
    • Posts 447
    • Groups 1
    R Offline
    1. Home
    2. rkorell
    3. Best
    A New Chapter for MagicMirror: The Community Takes the Lead
    Read the statement by Michael Teeuw here.

    Posts

    Recent Best Controversial
    • RE: Can´t rotate my display

      @robertybob said in Can´t rotate my display:

      Mine looks a little different :(

      OK, that’s bad…
      (It’s a Pi5, right?).

      The complete content of my dispsetup.sh is as follows:

      #!/bin/sh
      if ! raspi-config nonint is_pi || raspi-config nonint is_kms ; then
      if xrandr --output HDMI-1 --primary --mode 2560x1440 --rate 59.951 --pos 0x0 --rotate left --dryrun>
      xrandr --output HDMI-1 --primary --mode 2560x1440 --rate 59.951 --pos 0x0 --rotate left
      fi
      fi
      if [ -e /usr/share/tssetup.sh ] ; then
      . /usr/share/tssetup.sh
      fi
      if [ -e /usr/share/ovscsetup.sh ] ; then
      . /usr/share/ovscsetup.sh
      fi
      exit 0
      

      If I interpret your line correctly, you are using the Wayland-Window-Manager?
      (wlandr => wayland … ???).
      My box is a Pi4B, no wayland.
      I’ve seen elsewhere that the Pi5 can be forced to use X11 again - than the above should work directly.
      Otherwise you may give it a try to put your code into the dispsetup.sh?

      Here I found the description of your commandlines above. Unfortunately there is no description how to get this pesistent…

      In Addition I just found a hint in Raspberry-Forum
      There a guy stated:

      sudo nano .config/wayfire.ini
      
      -> scrolled down and changed the output section as below:
      
      [output:HDMI-A-1]
      mode = 1920X1080@60000
      position = 0,0
      transform = 90
      

      May this is the right way with wayland…

      Regards,
      Ralf

      posted in Troubleshooting
      R
      rkorell
    • RE: help needed

      @andrenajolly - most interesting is: what length is “full length” ?
      From this it depends for sure how to build the frame and how to choose right glass (kind of glass, thickness) …

      Kind regards,
      Ralf

      posted in Show your Mirror
      R
      rkorell
    • RE: MMM-Remote-Control

      @KristjanESPERANTO Dear Kristijan,

      after a long time I finally managed to see your “new” modul.
      First of all: Thanks a lot for your effort, again - nice piece!

      In the past few days I’ve completely rebuilt my mirror and migrated it to trixie as well as to the actual mirror and node versions.

      I ran into a reproducible issue with the restart functionality when MagicMirror is managed by pm2 (which is the recommended setup per the official MagicMirror documentation).

      The Problem

      When triggering a restart via the Remote-Control UI (or the /api/restart endpoint), MagicMirror enters an endless crash-loop with EADDRINUSE: address already in use :::8080.

      Root Cause
      The handleRestart function in node_helper.js (lines 717-741) uses the Electron-native restart mechanism:

      const {app} = require("electron");
      app.relaunch();
      app.quit();
      

      This works fine in standalone mode, but creates a race condition with pm2:

      1. app.relaunch() spawns a new Electron instance (child of the current process)
      2. app.quit() terminates the current Electron instance
      3. pm2 detects the termination as a crash and spawns another Electron instance
      4. Now two Electron instances compete for port 8080 → EADDRINUSE → both crash → pm2 keeps restarting → infinite loop

      The only way to recover is to manually identify and kill the orphaned Electron process, then trigger a clean restart via touch config.js (which pm2’s file-watch picks up).

      Interestingly, the catch-block fallback for server mode (lines 726-739) already does it correctly — it calls process.exit(0) and lets the process manager handle the restart. The Electron code path just doesn’t account for the pm2 scenario.

      Possible Fix

      When running under pm2, the Electron-native app.relaunch() should be skipped entirely.

      pm2 can be detected via environment variables like PM2_HOME, pm_id, or PM2_USAGE:

      handleRestart (query, res) {
        try {
          const {app} = require("electron");
          if (!app) { throw "Could not get Electron app instance."; }
      
          // When running under pm2, don't use app.relaunch() — pm2 handles restart
          if (process.env.PM2_HOME || process.env.pm_id !== undefined) {
            Log.log("Running under pm2, exiting cleanly for process manager restart...");
            this.sendResponse(res, undefined, {action: "RESTART", info: "Exiting for pm2 restart..."});
            setTimeout(() => app.quit(), 1000);
            return;
          }
      
          this.sendResponse(res, undefined, {action: "RESTART", info: "Restarting Electron..."});
          app.relaunch();
          app.quit();
        } catch (error) {
          // ... existing server mode fallback ...
        }
      }
      

      Environment

      • MagicMirror 2.34.0
      • MMM-Remote-Control 4.2.2 (commit b854832)
      • Node.js v22, Electron 39.5.2
      • Raspberry Pi 5, Debian 13 (Trixie)
      • Process manager: pm2 with file-watch on config.js

      Workaround

      For now, I’ve documented this for my setup: never use the restart button in Remote-Control. Monitor ON/OFF works fine, only the restart is
      affected.

      Thanks for considering this — happy to test any fix if needed!

      Warmest regards,
      Ralf

      posted in Utilities
      R
      rkorell
    • RE: Problems with WLAN connectivity - solved

      Dear @schlomm ,
      I initially had no clue at all regarding root cause :-)
      And the finding “undervoltage” was never expected but came out off my logfiles.

      After a LOT of tinkering and playing with syptomatic “solutions” system kept to be unstable so I decided to dig in and do some logging to identify root cause.

      For this I wrote a shellscript and installed a system service which collects this data every five minutes.

      shellscript:

      sudo nano /usr/local/bin/wlan-diagnose.sh
      

      content:

      #!/bin/bash
      LOGFILE="/var/log/wlan-diagnose.log"
      DATE=$(date '+%a %d %b %H:%M:%S %Z %Y')
      WLAN_IF="wlan0"
      
      echo "===== $DATE =====" >> $LOGFILE
      
      # IP-Adresse
      echo "--- IP-Adresse ---" >> $LOGFILE
      ip addr show $WLAN_IF >> $LOGFILE 2>&1
      
      # Link-Status
      echo "--- Link Status ---" >> $LOGFILE
      iw dev $WLAN_IF link >> $LOGFILE 2>&1
      
      # Default Route
      echo "--- Routing ---" >> $LOGFILE
      ip route >> $LOGFILE 2>&1
      
      # Wpa_supplicant Status
      echo "--- wpa_supplicant ---" >> $LOGFILE
      systemctl status wpa_supplicant --no-pager >> $LOGFILE 2>&1
      
      # Letzte wpa_supplicant Logs
      echo "--- wpa_supplicant journal (letzte 20 Zeilen) ---" >> $LOGFILE
      journalctl -u wpa_supplicant -n 20 --no-pager >> $LOGFILE 2>&1
      
      # Kernel/Treiber Logs
      echo "--- dmesg wlan0 ---" >> $LOGFILE
      dmesg | tail -n 20 >> $LOGFILE 2>&1
      
      # Ping-Test
      PING_TARGET="8.8.8.8"
      ping -I $WLAN_IF -c3 -W3 $PING_TARGET >> $LOGFILE 2>&1
      
      echo "" >> $LOGFILE
      
      

      set as executable:

      sudo chmod +x /usr/local/bin/wlan-diagnose.sh
      
      

      systemd-timer for this diagnosis script:

      sudo nano /etc/systemd/system/wlan-diagnose.timer
      

      content:

      [Unit]
      Description=WLAN Diagnose alle 5 Minuten
      
      [Timer]
      OnBootSec=1min
      OnUnitActiveSec=5min
      Persistent=true
      
      [Install]
      WantedBy=timers.target
      
      

      service file:

      sudo nano /etc/systemd/system/wlan-diagnose.service
      

      content:

      [Unit]
      Description=WLAN Diagnose Service
      
      [Service]
      Type=oneshot
      ExecStart=/usr/local/bin/wlan-diagnose.sh
      
      

      activate the service:

      sudo systemctl daemon-reload
      sudo systemctl enable --now wlan-diagnose.timer
      
      

      Created logfile: /var/log/wlan-diagnose.log

      possible command for filtering for errors:

      grep -i "fail\|error\|disconnect" /var/log/wlan-diagnose.log
      
      

      in my personal case directly after starting the service the undervoltage warnings appeared in the logfile:

      Sep 24 19:23:02 MagicMirrorPi5 wpa_supplicant[702]: wlan0: CTRL-EVENT-CONNECTED - Connection to f8:bc:0e:51:50:48 completed [id=0 id_str=] Sep 24 19:23:02 MagicMirrorPi5 wpa_supplicant[702]: bgscan simple: Failed to enable signal strength monitoring --- dmesg wlan0 --- [ 385.672898] hwmon hwmon4: Voltage normalised [ 399.780700] hwmon hwmon4: Undervoltage detected! [ 401.796721] hwmon hwmon4: Voltage normalised [ 403.812728] hwmon hwmon4: Undervoltage detected! [ 405.831888] hwmon hwmon4: Voltage normalised [ 425.988994] hwmon hwmon4: Undervoltage detected! [ 428.008109] hwmon hwmon4: Voltage normalised [ 434.052979] hwmon hwmon4: Undervoltage detected! [ 438.087587] hwmon hwmon4: Voltage normalised [ 442.117090] hwmon hwmon4: Undervoltage detected! [ 444.133104] hwmon hwmon4: Voltage normalised [ 452.198182] hwmon hwmon4: Undervoltage detected! [ 454.213171] hwmon hwmon4: Voltage normalised [ 470.341318] hwmon hwmon4: Undervoltage detected! [ 478.405369] hwmon hwmon4: Voltage normalised [ 488.485467] hwmon hwmon4: Undervoltage detected! [ 490.505469] hwmon hwmon4: Voltage normalised [ 514.693689] hwmon hwmon4: Undervoltage detected! [ 516.709733] hwmon hwmon4: Voltage normalised [ 520.744884] hwmon hwmon4: Undervoltage detected! PING 8.8.8.8 (8.8.8.8) from 172.23.56.157 wlan0: 56(84) bytes of data. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=116 time=13.2 ms 64 bytes from 8.8.8.8: icmp_seq=2 ttl=116 time=33.6 ms 64 bytes from 8.8.8.8: icmp_seq=3 ttl=116 time=27.5 ms --- 8.8.8.8 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 13.220/24.756/33.576/8.529 ms
      

      So I had identified my root cause with first strike.

      In the meantime (today) I had severe additional problems (also “identified” by this mentioned log) - but this was a kernel/device driver problem which I cannot solve today.
      But this leads to a modified recovery script because the version from yesterday only tried to restart the WPA_Supplicant which was not sufficient for my problem today.

      [EDIT - Sep, 8th, 2025: deleted old recovery script because usage of ping without qualified path produced an error by the script itself. For this reason the script is not as useful as I thought. Sorry for confusion! ]

      Hope this helps you.
      Do not hesitate to ask for further information …

      Warmest regards,
      Ralf

      posted in General Discussion
      R
      rkorell
    • RE: Can´t rotate my display

      @robertybob said in Can´t rotate my display:

      Raspberry Pi 3 :)

      May this in combination with bookworm?
      Sam acknowledged my assumption a posting above…

      • back to X11 …

      Regards,
      Ralf

      posted in Troubleshooting
      R
      rkorell
    • RE: help needed

      @schlomm Yes I had samples from them.

      In the end I‘ve decided to use the monitor in a nice ancient picture frame without any glass.
      So the „mirror“ effect is missing but this fits my usecase better.
      The frame is mounted in our living room and I can see all of the information from every place in the room…

      Warmest regards,
      Ralf

      posted in Show your Mirror
      R
      rkorell
    • RE: MMM-Remote-Control

      @KristjanESPERANTO Dear Kristijan,
      just tested v4.2.4 — works perfectly! Restart via the Remote-Control UI now completes cleanly
      under pm2, no orphaned Electron process, no port conflict. Exactly the behavior you’d expect.

      I also noticed you added a dedicated handleRestart.test.js with 210 lines of unit tests covering
      both the pm2 and standalone code paths — that’s really impressive and goes well beyond just a
      quick fix. Having proper test coverage for this kind of dual-mode behavior is exactly the right
      thing to do. Much appreciated!

      Thanks for the incredibly fast turnaround and the quality of the fix. Consider this confirmed
      working on:

      • MagicMirror 2.34.0
      • MMM-Remote-Control 4.2.4
      • Node.js v22, Electron 39.5.2
      • Raspberry Pi 5, Debian 13 (Trixie)
      • pm2 with file-watch

      Warmest regards,
      Ralf

      posted in Utilities
      R
      rkorell
    • RE: Problems with WLAN connectivity - solved

      Dear @schlomm , team,

      as I learned today sometimes system limitations are hard and leads to unwanted results.
      I even got more serioous trouble with my pi and his WIFI so I had to dig in deeper.
      The aproach until now - because of “growing” up - is a “recovery” and a “diagnose” part.
      This leads to - surprise, surprise :-) - inconsistent data and so dignosis is merely impossible.
      For this reason I converged both approches into one script and implemented a 4-stages error-handling and consecutive escalation (until reboot).

      At this stage i had to recognize: almost EVERY test results immediatly in an error at stage 1 (ping) and was resolved at stage 2 (L2/L3 - ICMP problem – checking status of wlan interface).
      To identify root cause for this I - again - dig down deeply (ChatGPT was NOT that helpful!) and found: At systemd level (on my system!?) ping is not in PATH !!!
      So a fully qualified call solved this problem - and most of my “problems” are solved !

      If you are using “ping”, too and stuck in problems in scripts - keep this in mind: “usr/bin/ping” might be really helpful for you.

      If you are interested in, here my current recovery-script - including some useful logging information:

      /usr/local/bin/wlan-recovery.sh
      #!/bin/bash
      # ============================================================================
      # WLAN Recovery Script (Monolithische Version)
      # Autor: Dr.  Ralf Korell, MD 
      # Datum: 2025-10-07
      #
      # Dieses Script wird per systemd-Timer regelmäßig aufgerufen.
      # Es prüft die WLAN-Verbindung in mehreren Stufen und führt nur dann
      # Recovery-Aktionen aus, wenn wirklich eine Unterbrechung vorliegt.
      #
      # Features:
      #   - Mehrstufige Diagnose (Ping, iw, IP, Route)
      #   - Schutz vor Fehlalarmen und Selbstabschüssen
      #   - SSH/VNC-Safe-Mode (keine Unterbrechung aktiver Sessions)
      #   - Logrotation + Statistikdatei
      # ============================================================================
      
      # === Konfiguration ==========================================================
      LOGFILE="/var/log/wlan-recovery.log"
      STATSFILE="/var/log/wlan-recovery.stats"
      MAX_LOG_SIZE=50000              # ~50 KB, dann Logrotation
      PING_TARGET="172.23.56.1"
      MAX_CONSECUTIVE_FAILS=2         # bevor Recovery startet
      COOLDOWN_FILE="/tmp/wlan-recovery.cooldown"
      COOLDOWN_MINUTES=5
      
      # interne Speicherorte (nicht verändern)
      STATEFILE="/tmp/wlan-recovery.state"
      DATE_NOW=$(date "+%Y-%m-%d %H:%M:%S")
      
      # === Hilfsfunktionen ========================================================
      
      log() {
          echo "$DATE_NOW: $1" | tee -a "$LOGFILE"
      }
      
      rotate_log() {
          if [ -f "$LOGFILE" ] && [ $(wc -c <"$LOGFILE") -gt $MAX_LOG_SIZE ]; then
              mv "$LOGFILE" "$LOGFILE.old"
              echo "$DATE_NOW: Log rotated." > "$LOGFILE"
          fi
      }
      
      increment_stat() {
          local key="$1"
          local value
          value=$(grep "^$key=" "$STATSFILE" 2>/dev/null | cut -d= -f2)
          value=$((value + 1))
          grep -v "^$key=" "$STATSFILE" 2>/dev/null > "${STATSFILE}.tmp"
          echo "$key=$value" >> "${STATSFILE}.tmp"
          mv "${STATSFILE}.tmp" "$STATSFILE"
      }
      
      cooldown_active() {
          if [ -f "$COOLDOWN_FILE" ]; then
              local last=$(date -r "$COOLDOWN_FILE" +%s)
              local now=$(date +%s)
              local diff=$(( (now - last) / 60 ))
              [ $diff -lt $COOLDOWN_MINUTES ]
          else
              return 1
          fi
      }
      
      start_cooldown() {
          touch "$COOLDOWN_FILE"
      }
      
      ssh_or_vnc_active() {
          ss -tn state established | grep -Eq '(:22|:5900)'
      }
      
      # === Diagnosefunktionen =====================================================
      
      is_connected_l2() {
          iw dev wlan0 link 2>/dev/null | grep -q "Connected to"
      }
      
      has_ip_l3() {
          ip -4 addr show wlan0 2>/dev/null | grep -q "inet "
      }
      
      has_route() {
          ip route get "$PING_TARGET" 2>/dev/null | grep -q "dev wlan0"
      }
      
      ping_ok() {
          /usr/bin/ping -I wlan0 -c 3 -W 2 "$PING_TARGET" >/dev/null 2>&1
      }
      
      # === Hauptlogik =============================================================
      
      rotate_log
      
      # Init Statsfile falls nicht vorhanden
      [ -f "$STATSFILE" ] || echo -e "success=0\nrecoveries=0\nfailures=0" > "$STATSFILE"
      
      # Lese bisherigen Fehlerzähler
      fails=0
      [ -f "$STATEFILE" ] && fails=$(cat "$STATEFILE")
      
      # Diagnose
      if ping_ok; then
          log "Ping erfolgreich. WLAN funktioniert."
          echo 0 > "$STATEFILE"
          increment_stat "success"
          exit 0
      fi
      
      # Wenn Ping fehlschlägt → weitere Prüfungen
      log "Ping fehlgeschlagen → erweiterte Diagnose..."
      
      if is_connected_l2 && has_ip_l3 && has_route; then
          log "L2/L3 ok → ICMP-Problem (kein Recovery)."
          increment_stat "failures"
          echo 0 > "$STATEFILE"
          exit 0
      fi
      
      # Hier gilt: echte Verbindung gestört
      fails=$((fails + 1))
      echo "$fails" > "$STATEFILE"
      
      if [ $fails -lt $MAX_CONSECUTIVE_FAILS ]; then
          log "Erster Fehler ($fails/$MAX_CONSECUTIVE_FAILS) → Beobachten..."
          increment_stat "failures"
          exit 0
      fi
      
      # Wenn Cooldown läuft → überspringen
      if cooldown_active; then
          log "Cooldown aktiv → Recovery übersprungen."
          exit 0
      fi
      
      # === Recovery-Stufen ========================================================
      
      if ssh_or_vnc_active; then
          log "SSH/VNC aktiv → keine Recovery ausgeführt, nur geloggt."
          increment_stat "failures"
          exit 0
      fi
      
      log "Verbindung tatsächlich gestört → Recovery-Prozess gestartet."
      increment_stat "recoveries"
      
      # Stufe 1: sanfte Reassoziation
      log "→ Stufe 1: wpa_supplicant Reassoziation..."
      wpa_cli -i wlan0 reassociate >/dev/null 2>&1
      sleep 5
      if ping_ok; then
          log "Reassoziation erfolgreich."
          echo 0 > "$STATEFILE"
          start_cooldown
          exit 0
      fi
      
      # Stufe 2: Interface Toggle
      log "→ Stufe 2: Interface Toggle..."
      ip link set wlan0 down
      sleep 2
      ip link set wlan0 up
      sleep 8
      if ping_ok; then
          log "Interface Toggle erfolgreich."
          echo 0 > "$STATEFILE"
          start_cooldown
          exit 0
      fi
      
      # Stufe 3: Treiber-Reload
      log "→ Stufe 3: Treiber-Reload..."
      modprobe -r brcmfmac && modprobe brcmfmac
      sleep 10
      if ping_ok; then
          log "Treiber-Reload erfolgreich."
          echo 0 > "$STATEFILE"
          start_cooldown
          exit 0
      fi
      
      # Wenn alles fehlschlägt
      log "Alle Recovery-Stufen fehlgeschlagen → Fehler bleibt bestehen."
      increment_stat "failures"
      start_cooldown
      exit 1
      

      [EDIT: in script above: changed ping count from -c 1 to -c 3 in:
      /usr/bin/ping -I wlan0 -c 1 -W 2 “$PING_TARGET” >/dev/null 2>&1
      ]
      Warmest regards,
      Ralf

      posted in General Discussion
      R
      rkorell
    • RE: Fresh install on bookworm only works with X11 - which disables VNC...

      @sdetweil :-)
      OK good move…
      But the startup-command is generated by your install-script, so this is the result of the “auto-start”…
      In the meantime I’ve figured out that may X11 is - in priciple - may the better choice for me because I might remember that MMM-Pir ( :-) ) had issues with wayland in context of screen-off …

      posted in Troubleshooting
      R
      rkorell
    • RE: [MMM-NounishReminder] Nounish Event Reminder for your MM

      @xppaicyber said

      Now you can customize the header text through the config.js file using the new header option:

      Dear XppaiCyberr,
      this is awesome!
      Thanks a LOT.

      Warmest regards,
      Ralf

      posted in Showcase
      R
      rkorell
    • RE: MMM-RainRadarDWD

      @OliWer

      Absolutely fine for me. Just a hint - as improvement path for further upcoming modules from your side :-)

      Warm regards,
      Ralf

      posted in Utilities
      R
      rkorell
    • RE: Wayland problems in the April 2026 release

      Dear @howest,

      Glad you got it working again! The Wayland transition is indeed a bit of a bumpy ride if it hits you unexpectedly.

      Just to share a different experience: I’m running MagicMirror on a Raspberry Pi 5 with Raspberry Pi OS Trixie, and Wayland works fine for me – including keyboard input.

      The wireless combo keyboard/mouse issue you described is a known pain point; Wayland handles HID devices differently than X11, and some receivers just don’t play nice out of the box.

      If you ever feel adventurous and want to try Wayland again: check if your keyboard receiver shows up cleanly under

      libinput list-devices.
      

      Sometimes a powered USB hub or simply a different receiver firmware makes all the difference.
      But honestly – if X11 runs stable and you’re happy, there’s zero pressure to switch. Wayland on the Pi is still maturing. Your setup, your rules! 😊

      Warm regards,
      Ralf

      posted in General Discussion
      R
      rkorell
    • RE: MMM-Universal-Pir - Desparately seeking right command

      @rkorell said in MMM-Universal-Pir - Desparately seeking right command:

      “DISPLAY=:0.0 xrandr --output HDMI-1 --off” / “DISPLAY=:0.0 xrandr --output HDMI-1 --primary --mode 2560x1440 --rate 59.951 --pos 0x0 --rotate left”

      these are the right commands and are working now!

      (If one was not too blonde to switch the commands …)
      My fault - I’ve entered the on comand to the off parameter …
      Sorry!

      Regards,
      Ralf

      posted in Troubleshooting
      R
      rkorell
    • RE: MMM-Globe: Meteosat imagery broken — fork with fix available

      @plainbroke :-) It will work in US but you will see the wrong half of the globe …

      To be serious: No, you requirement is for sure to see USA side of the globe - so it will not work for you - wrong satellite.

      Warmest regards,
      Ralf

      posted in Showcase
      R
      rkorell
    • RE: Again -- MMM-Navigate can't get installed.

      @crowimu
      I‘m not using this module and I do not know which of GPIO‘s you are using for your rotary encoder -
      In the module‘s description the author mentioned an eventually necessary modification for some of the PI‘s:

      On some Raspberry Pis it is neccesary to put the following line to /boot/config.txt for the GPIO where "rotary press (SW)" is connected:
      
      gpio=19=ip,pu
      
      Background: Sets your GPIO 19 as input (ip) and pull up (pu) Change the entry according to the GPIO pin you use.
      
      

      Have you double checked this?
      Your error-listing shows „invalid argument , write“ in some context to GPIO…
      May there is a topic for further investigation….

      Good luck!
      Regards,
      Ralf

      posted in Troubleshooting
      R
      rkorell
    • RE: How to add custom weather icons

      @kool said

      Bumping this back up. Pleeeease help

      Dear @kool ,

      if you are using url as suggested by Sam ( @sdetweil ), you are nearly done.
      As far as I can see from my rookie perspective you do have some redundancies in your config.js (e.g. the unit section: units, tempUnits, windUnits) ) but this shouldn’t disturb.
      As far as I understood you can delete these icontables because you do not use the icon-font but try to use some images from sigle file-URLs instead - so you can delete the whole section iconTable {} with all entries.

      In addition you have to adapt (see above, Sam’s tip) the URL of all you images in your custom.css file.
      (pls. double check, if the files are really in these locations)
      You wrote in your current css

      .weatherforecast .wi-day-sunny {
      content: url("/home/kool/MagicMirror/css/icons/6fas/day.svg") !important;
      
      }
      

      IF your weather-icon files are really in this directory (/home/kool/MagicMirror/css/icons/6fas/) than your css should be as follows:

      .weatherforecast .wi-day-sunny {
       content: url("/css/icons/6fas/day.svg");
      
      

      You do not need the !important flag (in my case)

      second wrong thing besides the URL is your qualifier.

      you are using

      .weatherforecast .wi-something  ....
      

      This cannot be recognized because .weatherforecast is not defined.

      At first you have to decide if you want to have different icons for the current weather and for the weather forecast.
      (In my case this is true).
      IF you would like to have this you have to differentiate the two instances of the weather-module by a “classes” definition.

      For example your first instance of the weather module (current weather) than should be

         module: "weather",
          position: "top_right", // Adjust position as needed
          classes: "weather_current",
          config: {
              weatherProvider: "openmeteo", // Specify the Open-Meteo provider
              apiBase: "https://api.open-meteo.com/v1", // REQUIRED: Base URL for Open-Meteo
      
             lat: xxxx, // REQUIRED: Latitude of the location
              lon: xxxx, // REQUIRED: Longitude of the location
              maxNumberOfDays: 8, // OPTIONAL: Number of forecast days (default is 5)
              pastDays: 0, // OPTIONAL: Number of past days of data to include (default is 0)
         units: "imperial", // Set this to 'imperial' for Fahrenheit and miles per hour
              tempUnits: "imperial", // Make sure to match with 'imperial'
              windUnits: "imperial",
              type: "current", // OPTIONAL: Change to "current" if only current weather data is desired
      
       
          }
      },
      

      (pay attention for the third line: classes: “weather_current”, )
      THIS is your qualifier if you are about to diffrentiate between current weather and weather forecast image-wise.
      (“weather_current” is just an example! you can name it like you want every name is suitable and OK, only pay attention that all of these namings are strictly case sensitive, so Weather is NOT the same as weather"

      Your correct line for custom.css than is:

      .weather_current .wi-day-sunny {
       content: url("/css/icons/6fas/day.svg");
      
      

      and the same dance than for your second instance with DIFFERENT classes-clause in config.js
      (e.g. a " classes: “weather_forecast”, " in the definition of the second weather instance ) results in a custom.css entry like this:

      .weather_forecast .wi-day-sunny {
       content: url("/css/icons/some_other_directory_with_smaller_icons/day.svg");
      
      

      Because the “forecast instance” of the weather module is (in my case) organized as table I found it really useful to differentite these logos - big ones for current, smaller ones for the forecast:

      ScreenFloat Bildschirmfoto von Sublime Text am 14_04_2025, 13_38_51 14_04_2025, 13-38-51.jpg

      If You do NOT like to differentiate the current and forecast instance you do NOT need the classes-phrase in config.js and your correct qualifier is the name of the module (so “weather” ) and your custom.css entry is like this:

      .weather .wi-day-sunny {
       content: url("/css/icons/6fas/day.svg");
      
      

      And this than is valid for both instances.

      Keep in mind that there are a LOT more weather conditions than the two times 5 conditions you have defined in your current custom.css!

      my own definition for the current weather for your reference:

      
      .weather_current .wi-fog  {
      content: url("/css/icons/current/wsymbol_0007_fog.png");
      }
      .weather_current .wi-cloudy  {
      content: url("/css/icons/current/wsymbol_0002_sunny_intervals.png");
      }
      .weather_current .wi-cloudy-windy {
      content: url("/css/icons/current/wsymbol_0004_black_low_cloud.png");
      }
      .weather_current .wi-rain  {
      content: url("/css/icons/current/wsymbol_0018_cloudy_with_heavy_rain.png");
      }
      .weather_current .wi-showers  {
      content: url("/css/icons/current/wsymbol_0017_cloudy_with_light_rain.png");
      }
      .weather_current .wi-thunderstorm  {
      content: url("/css/icons/current/wsymbol_0024_thunderstorms.png");
      }
      .weather_current .wi-snow  {
      content: url("/css/icons/current/wsymbol_0019_cloudy_with_light_snow.png");
      }
      .weather_current .wi-snowflake-cold {
      content: url("/css/icons/current/wsymbol_0020_cloudy_with_heavy_snow.png");
      }
      .weather_current .wi-na {
      content: url("/css/icons/current/wsymbol_0999_unknown.png");
      } 
      
      .weather_current .wi-day-sunny  {
        content: url("/css/icons/current/wsymbol_0001_sunny.png");
      }
      .weather_current .wi-day-cloudy  {
        content: url("/css/icons/current/wsymbol_0043_mostly_cloudy.png");
      }
      .weather_current .wi-day-cloudy-gusts  {
        content: url("/css/icons/current/wsymbol_0004_black_low_cloud.png");
      }
      .weather_current .wi-day-cloudy-windy  {
        content: url("/css/icons/current/wsymbol_0004_black_low_cloud.png");
      }
      .weather_current .wi-cloudy-windy  {
        content: url("/css/icons/current/wsymbol_0004_black_low_cloud.png");
      }
      .weather_current .wi-day-fog  {
        content: url("/css/icons/current/wsymbol_0007_fog.png");
      }
      .weather_current .wi-day-hail  {
        content: url("/css/icons/current/wsymbol_0015_heavy_hail_showers.png");
      }
      .weather_current .wi-day-haze  {
        content: url("/css/icons/current/wsymbol_0005_hazy_sun.png");
      }
      .weather_current .wi-day-lightning  {
        content: url("/css/icons/current/wsymbol_0016_thundery_showers.png");
      }
      .weather_current .wi-day-rain  {
        content: url("/css/icons/current/wsymbol_0085_extreme_rain_showers.png");
      }
      .weather_current .wi-day-rain-mix  {
        content: url("/css/icons/current/wsymbol_0009_light_rain_showers.png");
      }
      .weather_current .wi-day-rain-wind  {
        content: url("/css/icons/current/wsymbol_0010_heavy_rain_showers.png");
      }
      .weather_current .wi-day-showers  {
        content: url("/css/icons/current/wsymbol_0018_cloudy_with_heavy_rain.png");
      }
      .weather_current .wi-day-sleet  {
        content: url("/css/icons/current/wsymbol_0087_heavy_sleet_showers.png");
      }
      .weather_current .wi-day-sleet-storm  {
        content: url("/css/icons/current/wsymbol_0089_heavy_sleet.png");
      }
      .weather_current .wi-day-snow  {
        content: url("/css/icons/current/wsymbol_0011_light_snow_showers.png");
      }
      .weather_current .wi-day-snow-thunderstorm  {
        content: url("/css/icons/current/wsymbol_0057_thundery_snow_showers.png");
      }
      .weather_current .wi-day-snow-wind  {
        content: url("/css/icons/current/wsymbol_0053_blowing_snow.png");
      }
      .weather_current .wi-day-sprinkle  {
        content: url("/css/icons/current/wsymbol_0009_light_rain_showers.png");
      }
      .weather_current .wi-day-storm-showers  {
        content: url("/css/icons/current/wsymbol_0018_cloudy_with_heavy_rain.png");
      }
      .weather_current .wi-day-sunny-overcast  {
        content: url("/css/icons/current/wsymbol_0002_sunny_intervals.png");
      }
      .weather_current .wi-day-thunderstorm  {
        content: url("/css/icons/current/wsymbol_0024_thunderstorms.png");
      }
      .weather_current .wi-day-windy  {
        content: url("/css/icons/current/wsymbol_0060_windy.png");
      }
      .weather_current .wi-solar-eclipse  {
        content: url("/css/icons/current/wsymbol_0005_hazy_sun.png");
      }
      .weather_current .wi-hot  {
        content: url("/css/icons/current/wsymbol_0045_hot.png");
      }
      .weather_current .wi-day-cloudy-high  {
        content: url("/css/icons/current/wsymbol_0006_mist.png");
      }
      .weather_current .wi-day-light-wind  {
        content: url("/css/icons/current/wsymbol_0060_windy.png");
      }
      .weather_current .wi-night-clear  {
        content: url("/css/icons/current/wsymbol_0008_clear_sky_night.png");
      }
      .weather_current .wi-night-alt-cloudy  {
        content: url("/css/icons/current/wsymbol_0041_partly_cloudy_night.png");
      }
      .weather_current .wi-night-alt-partly-cloudy  {
        content: url("/css/icons/current/wsymbol_0041_partly_cloudy_night.png");
      }
      .weather_current .wi-night-alt-cloudy-gusts  {
        content: url("/css/icons/current/wsymbol_0041_partly_cloudy_night.png");
      }
      .weather_current .wi-night-alt-cloudy-windy  {
        content: url("/css/icons/current/wsymbol_0041_partly_cloudy_night.png");
      }
      .weather_current .wi-night-alt-hail  {
        content: url("/css/icons/current/wsymbol_0031_heavy_hail_showers_night.png");
      }
      .weather_current .wi-night-alt-lightning  {
        content: url("/css/icons/current/wsymbol_0032_thundery_showers_night.png");
      }
      .weather_current .wi-night-alt-rain  {
        content: url("/css/icons/current/wsymbol_0025_light_rain_showers_night.png");
      }
      .weather_current .wi-night-alt-rain-mix  {
        content: url("/css/icons/current/wsymbol_0026_heavy_rain_showers_night.png");
      }
      .weather_current .wi-night-alt-rain-wind  {
        content: url("/css/icons/current/wsymbol_0026_heavy_rain_showers_night.png");
      }
      .weather_current .wi-night-alt-showers  {
        content: url("/css/icons/current/wsymbol_0025_light_rain_showers_night.png");
      }
      .weather_current .wi-night-alt-sleet  {
        content: url("/css/icons/current/wsymbol_0029_sleet_showers_night.png");
      }
      .weather_current .wi-night-alt-sleet-storm  {
        content: url("/css/icons/current/wsymbol_0029_sleet_showers_night.png");
      }
      .weather_current .wi-night-alt-snow  {
        content: url("/css/icons/current/wsymbol_0028_heavy_snow_showers_night.png");
      }
      .weather_current .wi-night-alt-snow-thunderstorm  {
        content: url("/css/icons/current/wsymbol_0075_thundery_snow_showers_night.png");
      }
      .weather_current .wi-night-alt-snow-wind  {
        content: url("/css/icons/current/wsymbol_0071_blowing_snow_night.png");
      }
      .weather_current .wi-night-alt-sprinkle  {
        content: url("/css/icons/current/wsymbol_0025_light_rain_showers_night.png");
      }
      .weather_current .wi-night-alt-storm-showers  {
        content: url("/css/icons/current/wsymbol_0026_heavy_rain_showers_night.png");
      }
      .weather_current .wi-night-alt-thunderstorm  {
        content: url("/css/icons/current/wsymbol_0032_thundery_showers_night.png");
      }
      .weather_current .wi-night-cloudy  {
        content: url("/css/icons/current/wsymbol_0041_partly_cloudy_night.png");
      }
      .weather_current .wi-night-cloudy-gusts  {
        content: url("/css/icons/current/wsymbol_0044_mostly_cloudy_night.png");
      }
      .weather_current .wi-night-cloudy-windy  {
        content: url("/css/icons/current/wsymbol_0044_mostly_cloudy_night.png");
      }
      .weather_current .wi-night-fog  {
        content: url("/css/icons/current/wsymbol_0064_fog_night.png");
      }
      .weather_current .wi-night-hail  {
        content: url("/css/icons/current/wsymbol_0039_cloudy_with_heavy_hail_night.png");
      }
      .weather_current .wi-night-lightning  {
        content: url("/css/icons/current/wsymbol_0032_thundery_showers_night.png");
      }
      .weather_current .wi-night-partly-cloudy  {
        content: url("/css/icons/current/wsymbol_0041_partly_cloudy_night.png");
      }
      .weather_current .wi-night-rain  {
        content: url("/css/icons/current/wsymbol_0025_light_rain_showers_night.png");
      }
      .weather_current .wi-night-rain-mix  {
        content: url("/css/icons/current/wsymbol_0026_heavy_rain_showers_night.png");
      }
      .weather_current .wi-night-rain-wind  {
        content: url("/css/icons/current/wsymbol_0025_light_rain_showers_night.png");
      }
      .weather_current .wi-night-showers  {
        content: url("/css/icons/current/wsymbol_0026_heavy_rain_showers_night.png");
      }
      .weather_current .wi-night-sleet  {
        content: url("/css/icons/current/wsymbol_0029_sleet_showers_night.png");
      }
      .weather_current .wi-night-sleet-storm  {
        content: url("/css/icons/current/wsymbol_0029_sleet_showers_night.png");
      }
      .weather_current .wi-night-snow  {
        content: url("/css/icons/current/wsymbol_0027_light_snow_showers_night.png");
      }
      .weather_current .wi-night-snow-thunderstorm  {
        content: url("/css/icons/current/wsymbol_0075_thundery_snow_showers_night.png");
      }
      .weather_current .wi-night-snow-wind  {
        content: url("/css/icons/current/wsymbol_0028_heavy_snow_showers_night.png");
      }
      .weather_current .wi-night-sprinkle  {
        content: url("/css/icons/current/wsymbol_0025_light_rain_showers_night.png");
      }
      .weather_current .wi-night-storm-showers  {
        content: url("/css/icons/current/wsymbol_0026_heavy_rain_showers_night.png");
      }
      .weather_current .wi-night-thunderstorm  {
        content: url("/css/icons/current/wsymbol_0032_thundery_showers_night.png");
      }
      
      
      

      HTH & good luck!
      Ralf

      posted in Development
      R
      rkorell
    • RE: My new MagicMirror will not start with Wayland?

      @sdetweil As I wrote initially “npm run start:wayland” doesn’t work …
      (despite wayland configured).
      And the “stored” auto-start option npm run start:x11 DOES work - for whatever reason.

      VNC was really sluggish on this, performance a nightmare so - see above marked as “solution” I switched back to x11 and all is working fine.

      In the meantime I’ve also managed to get MMM-Pir to work by idenitfying and correcting two errors in Bugsounet’s code …

      Warm regards,
      Ralf

      posted in Troubleshooting
      R
      rkorell
    • RE: MMM-Globe: Meteosat imagery broken — fork with fix available

      @plainbroke you’re really welcome.
      Thanks for your patience :-)

      Ralf

      posted in Showcase
      R
      rkorell
    • RE: Netatmo module will not shown

      @kusselin said

      One question: Do you have Netatmo installed and running at home as hardware and searching in MM…?

      Nope, Netatmo not used by me …

      Regards,
      Ralf

      posted in Troubleshooting
      R
      rkorell
    • RE: Lost Swipe functionality

      @mischag
      This definitely sounds like a system not a MagicMirror problem.
      You didn’t provide system information, so it’s hard to say anything.
      What Pi? What OS? What screen?

      I recently upgraded a (really old) Pi 2B and the (until upgrade) smoothly running touch didn’t work anymore - clearly caused by OS-upgrade.
      The newer version introduced a completely different (touch) screen handling (without any warning, hint or message regarding this fact).
      The axes and x-y positionings were mirrored. Your description sounds like that…

      Regards,
      Ralf

      posted in Troubleshooting
      R
      rkorell
    • 1 / 1