MagicMirrorOrg / MagicMirror

MagicMirror² is an open source modular smart mirror platform. With a growing list of installable modules, the MagicMirror² allows you to convert your hallway or bathroom mirror into your personal assistant.
http://magicmirror.builders
MIT License
19.85k stars 4.22k forks source link

High CPU Usage in Latest Version: Electron Process Consumes 100% CPU Intermittently #3163

Closed theskyisthelimit closed 1 year ago

theskyisthelimit commented 1 year ago

Hello Everyone,

I have been running the MagicMirror for years on my Raspberry Pi 2 in client-only mode. Recently, I made the "mistake" of executing a git pull, and after that, nothing worked. I couldn't get it to run on the Raspberry Pi 2 again. Considering the performance was never optimal on the Raspberry Pi 2, I decided to do a fresh Raspbian install on a Raspberry Pi 3B+. For the installation, I used the amazing script by @sdetweil . However, after applying the hotfix from this link, the software starts, but the Electron process intermittently consumes +100% of the CPU. Every so often, the MagicMirror runs smoothly for about 10-20 seconds, but then, seemingly out of nowhere, the Electron process maxes out the CPU again, leading to poor performance. I even tried the same SD card from the Raspberry Pi 3 on a Raspberry Pi 4 with 8GB of RAM, but the issue persists. I'm not sure what changed between the version I had been using and the latest release, but something seems off.

RPI 3 RPI4

Any advice or suggestions would be greatly appreciated.

Thank you in advance for your help!

khassel commented 1 year ago

I cannot reproduce this.

My setup: Server on a rpi4 in server only mode (this pi has no screen) and the client on another rpi4, both current mm version with default config.

If you think it is the electron version you can downgrade it in the package.json and run npm run install-mm in the mm folder (you can test which electron version you are running by executing npx electron -v in the mm folder).

theskyisthelimit commented 1 year ago

Thanks for the quick reply!

  1. The server-side runs inside docker on a Synology NAS.

docker-compose:

version: '2'
services:
  magicmirror:
    container_name: magicmirror
    image: karsten13/magicmirror:latest
    ports:
      - "8585:8080"
    dns:
      - 1.1.1.1
    environment:
      - TZ=${mm_TZ}
    volumes:
      - ${mm_configpath_mm}/config:/opt/magic_mirror/config
      - ${mm_configpath_mm}/css:/opt/magic_mirror/css
      - ${mm_configpath_mm}/modules:/opt/magic_mirror/modules
    restart: unless-stopped
    command:
      - npm
      - run
      - server
networks:
  default:
    name: ProxyNetwork
    external: true
  1. Im using the follwing modules, although I'm not sure if it's any of these because I had no issues before.

this is my config (I removed the api keys and some other privacy related values)

const Outdoortempcolors = [
  {
    upTo: -5,
    value: "#277DA1",
  },
  {
    upTo: 0,
    value: "#577590",
  },
  {
    upTo: 5,
    value: "#4D908E",
  },
  {
    upTo: 15,
    value: "#43AA8B",
  },
  {
    upTo: 24,
    value: "#90BE6D",
  },
  {
    upTo: 25,
    value: "#bdd12e",
  },
  {
    upTo: 26,
    value: "#F9C74F",
  },
  {
    upTo: 27,
    value: "#F9844A",
  },
  {
    upTo: 28,
    value: "#F8961E",
  },
  {
    upTo: 29,
    value: "#F3722C",
  },
  {
    upTo: 30,
    value: "#F94144",
  },
];

const Humidity = [
  {
    upTo: 20,
    value: "#F9844A",
  },
  {
    upTo: 35,
    value: "#F9C74F",
  },
  {
    upTo: 40,
    value: "#90BE6D",
  },
  {
    upTo: 50,
    value: "#43AA8B",
  },
  {
    upTo: 55,
    value: "#F9C74F",
  },
  {
    upTo: 60,
    value: "#F3722C",
  },
  {
    upTo: 100,
    value: "#F94144",
  },
];

const Chargestate = [
  {
    upTo: 5,
    value: "#F94144",
  },
  {
    upTo: 10,
    value: "#F3722C",
  },
  {
    upTo: 15,
    value: "#F8961E",
  },
  {
    upTo: 20,
    value: "#F9844A",
  },
  {
    upTo: 30,
    value: "#F9C74F",
  },
  {
    upTo: 40,
    value: "#bdd12e",
  },
  {
    upTo: 80,
    value: "#90BE6D",
  },
  {
    upTo: 100,
    value: "#43AA8B",
  },
];

const Chargestatekm = [
  {
    upTo: 25,
    value: "#F94144",
  },
  {
    upTo: 50,
    value: "#F3722C",
  },
  {
    upTo: 100,
    value: "#F9844A",
  },
  {
    upTo: 150,
    value: "#F9C74F",
  },
  {
    upTo: 200,
    value: "#bdd12e",
  },
  {
    upTo: 400,
    value: "#90BE6D",
  },
  {
    upTo: 550,
    value: "#43AA8B",
  },
];

var config = {
  address: "0.0.0.0",
  port: 8080,
  ipWhitelist: [],
  language: "de",
  timeFormat: 24,
  units: "metric",

  modules: [
    { module: "mmpm" },
    {
      module: "MMM-OpenWeatherMapForecast",
      header: "",
      position: "top_right",
      classes: "default everyone",
      disabled: false,
      config: {
        apikey: "XXX",
        latitude: "46.00",
        longitude: "7.00",
        iconset: "1c",
        showHourlyForecast: false,
        maxDailiesToShow: 0,
        showPrecipitation: true,
        showDailyForecast: false,
        useAnimatedIcons: false,
        showSummary: false,
        concise: true,
        forecastLayout: "table",
      },
    },
    {
      module: "MMM-SwissCommute",
      position: "top_left",
      header: "XXX nach XXX",
      config: {
        from: "XXX", // Start train station
        to: "XXX", // Destination station
        maximumEntries: 5, // Max departures displayed
        updateInterval: 3 * 60 * 1000,
        minWalkingTime: 4, // Minimum time to get to the station
      },
    },
    {
      module: "MMM-SwissCommute",
      position: "top_left",
      header: "XXX nach XXX",
      config: {
        from: "XXX Bahnhof", // Start train station
        to: "XX", // Destination station
        maximumEntries: 5, // Max departures displayed
        updateInterval: 3 * 60 * 1000,
        minWalkingTime: 5, // Minimum time to get to the station
      },
    },
    {
      module: "clock",
      position: "top_center",
      config: {
        showMoonTimes: false,
        showSunTimes: false,
        showWeek: true,
        lat: 46.0,
        lon: 7.0,
        timezone: "Europe/Zurich",
      },
    },
    {
      module: "calendar",
      header: "Schweiz Feiertage",
      position: "top_left",
      config: {
        maximumEntries: 6, // Total Maximum Entries
        excludedEvents: [
          "Allerheiligen",
          "Allerseelen",
          "Reformationssonntag Schweiz",
          "Ewigkeitssonntag",
          "Erster Advent",
          "Zweiter Advent",
          "Dritter Advent",
          "Vierter Advent",
          "Palmsonntag",
          "Fronleichnam",
          "Reformationstag",
          "Eidg. Dank-, Buss- und Bettag",
        ],
        timeFormat: "aboslute",
        dateFormat: "DD. MMM ",
        dateEndFormat: "LT",
        fullDayEventDateFormat: "DD. MMM",
        calendars: [
          {
            name: "Holidays",
            symbol: "calendar-check",
            url: "https://fcal.ch/privat/fcal_holidays.ics.php?XXX",
          },
          {
            name: "Birthdays",
            symbol: "birthday-cake",
            url: "https://calendar.google.com/calendar/ical/XXX/basic.ics",
          },
          {
            name: "XXX Events",
            symbol: "calendar-plus",
            url: "https://calendar.google.com/calendar/ical/XXX/basic.ics",
          },
        ],
      },
    },
    {
      module: "MMM-WeatherChart",
      position: "center",
      config: {
        apiKey: "XXX",
        dataNum: 7,
        title: "",
        dataType: "daily",
        height: "400px",
        width: "1200px",
        lat: 46.00,
        lon: 7.00,
        showIcon: "true",
        showRain: "true",
        dailyLabel: "days_of_week",
        nightBorderDash: [5, 5],
        fillColor: "rgba(255, 255, 255, 0.1)",
        units: "metric",
        largeOpenWeatherIcon: true,
      },
    },
    {
      module: "MMM-RAIN-MAP",
      position: "bottom_center",
      config: {
        animationSpeedMs: 500,
        colorScheme: 5,
        colorizeTime: false,
        defaultZoomLevel: 8,
        displayTime: true,
        displayTimeline: true,
        displayClockSymbol: true,
        displayOnlyOnRain: false,
        extraDelayLastFrameMs: 1000,
        extraDelayCurrentFrameMs: 0,
        markers: [
          {
            lat: 46.00,
            lng: 7.00,
            color: "red",
          },
        ],
        mapPositions: [
          {
            lat: 46.00,
            lng: 7.00,
            zoom: 7,
            loops: 2,
          },
        ],

        mapUrl:
          "https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png",
        mapHeight: "400px", // must be a pixel value (no percent)
        mapWidth: "500px", // must be a pixel value (no percent)
        maxHistoryFrames: -1,
        maxForecastFrames: -1,
        substitudeModules: [],
        updateIntervalInSeconds: 300,
      },
    },
    {
      module: "MMM-Bring",
      position: "bottom_center",
      config: {
        email: "XXX@gmail.com",
        password: "XXX",
        updateInterval: 5, // in Minutes
        listName: "Zuhause", // optional
        showListName: false,
        activeItemColor: "#000",
        latestItemColor: "#4FABA2",
        showLatestItems: false,
        maxItems: 5,
        locale: "de-CH",
      },
    },
    {
      module: "MMM-PlexNowPlaying",
      position: "top_left",
      header: "Plex Streams",
      config: {
        serverProtocol: "https",
        serverAddress:
          "XXX.plex.direct",
        serverPort: 32400,
        xPlexToken: "XXX",
        updateInterval: 30,
        showUser: false,
        libraryBlackList: ["XXX"],
        hideWhenNothingPlaying: true,
      },
    },
    {
      module: "MMM-MQTT",
      header: "Sensors",
      position: "top_right",
      config: {
        logging: true,
        useWildcards: false,
        mqttServers: [
          {
            address: "192.168.8.4", // Server address or IP address
            port: "1883",
            user: "",
            password: "",
            subscriptions: [
              {
                topic: "Magicmirror/AVG",
                label: "<class='align-left mqtt-label'>Ø Average</>",
              },
              {
                topic: "Magicmirror/Living",
                label:
                  "<i class='mdi mdi-sofa'></i></><class='align-left mqtt-label'> Living Room</>",
              },
              {
                topic: "Magicmirror/Office",
                label:
                  "<i class='mdi mdi-chair-rolling'></i></><class='align-left mqtt-label'> Office</>",
              },
              {
                topic: "Magicmirror/Bedroom",
                label:
                  "<i class='mdi mdi-bed-king'></i></><class='align-left mqtt-label'> Bedroom</>",
              },
              {
                topic: "Magicmirror/Outdoor",
                label:
                  "<i class='mdi mdi-balcony'></i></><class='align-left mqtt-label'> Balcony</>",
              },
            ],
          },
        ],
      },
    },
    {
      module: "MMM-cryptocurrency",
      position: "bottom_right",
      config: {
        apikey: "XXX",
        currency: ["ethereum", "bitcoin", "loopring"],
        conversion: "USD",
        displayType: "logo",
        coloredLogos: false,
        maximumFractionDigits: "2",
        logoHeaderText: "",
        fontSize: "large",
        showGraphs: true,
      },
    },
    {
      module: "MMM-BurnIn",
      position: "bottom_bar", // whatever, doesn't render anything
      config: {
        updateInterval: 15, // in Minutes
      },
    },
    {
      module: "MMM-Sonos",
      header: "SONOS: Now Playing",
      position: "bottom_left",
      config: {
        showRoomName: false,
        apiBase: "http://192.168.8.8",
      },
    },
  ],
};

/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
  module.exports = config;
}
  1. yes, I will look what happens with the standard config and also try downgrading the electron version.

Thank you for the suggestions!

khassel commented 1 year ago

yes, I will look what happens with the standard config

before investing more time I will wait for your answer ...

I like MMM-RAIN-MAP but this module needs a lot of memory ...

theskyisthelimit commented 1 year ago

OK, here are my findings:

  1. Yes, MMM-RAIN-MAP uses a lot, but it’s essential. :-)
  2. Using the default config, "everything" is OK.
  3. I disabled modules one by one and found that the issue likely stems from the MMM-MQTT module. I use numerous HTML tags for different colors.
  4. After disabling the MMM-MQTT module, the software runs reasonably well on both RPI2 and RPI3. However, Electron still consumes up to 90% of the CPU on both devices.
  5. Interestingly, when I stop the MagicMirror client-only software with pm2 stop MagicMirror, the Electron process continues to run indefinitely, consuming maximum CPU capacity. This occurs every time I start and stop the software, even when I do so without using pm2. Unfortunately, I can't determine what it's doing.

If you can guide me on where to investigate further, I'm open to more debugging. However, I don't want to take up too much of your valuable time with this issue, especially if it's unique to my setup or the combination of modules I'm using. One option for me is to revert the client to an older version that worked seamlessly for years and could also handle the MMM-MQTT HTML colors. Would I only need to modify the package.json? I'm considering reverting to version 2.20.0 and working backward from there.

khassel commented 1 year ago

so we are a step closer ...

the Electron process continues to run indefinitely, consuming maximum CPU capacity

thats strange ... I did my tests with docker containers on both sides. And this happens with your config and the default config?

Would I only need to modify the package.json? I'm considering reverting to version 2.20.0 and working backward from there.

no, this was only a quick hack, if you want to use 2.20.0 you should checkout this version with git checkout v2.20.0 (from mm folder) and run npm install afterwards.

You could test the newest electron version 26.0.0 (by updating in package.json) which was released a few days ago and will be next electron version of mm (I don't believe that this solves the problem but who knows ...).

khassel commented 1 year ago

@theskyisthelimit any news? Or can we close this?

theskyisthelimit commented 1 year ago

Thank you and sorry for the delay. I reverted to V2.20.0 and the CPU load was also at 100%. My Magicmirror is working again. Its possible that it was also consuming 100% of the CPU before i upgraded to the latest. I think we can close this issue for now.