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

    Posts

    Recent Best Controversial
    • RE: AHT20 Humidity + Temperature Sensor

      @rkorell Yes, I can describe how I arrived at a resolution for my particular problem - which was to replace DHTxx sensors with the more accurate AHT20 temperature and humidity sensors.

      Caveat: I do not necessarily recommend this for the average person though, because I did not find Magic Mirror modules that natively support this sensor, and as a result had to make changes outside of the config.js and custom.css files. As usual, this puts me at risk of something breaking when the module is updated.

      The module being used (MMM-Temperature - found at https://github.com/Tom-Hirschberger/MMM-Temperature) utilizes python scripts to capture the data from the sensor. While the module is quite complete, with script support for many sensors, I did create a new script in order to use this particular sensor.

      The sensor is supported by Adafruit (https://learn.adafruit.com/adafruit-aht20/python-circuitpython), with instructions to install various adafruit libraries including adafruit-ahtx0 (sudo pip3 install adafruit-circuitpython-ahtx0).

      Using those libraries, your script needs to include the following instructions:

      import board
      import adafruit_ahtx0
      sensor = adafruit_ahtx0.AHTx0(board.I2C())
      

      One of the existing scripts supports I2C sensors using the Adafruit libraries, so it looked like a good candidate to use as a model. See htu21:

      #!/usr/bin/env python3
      #pip3 install adafruit-circuitpython-htu21d
      import board
      from adafruit_htu21d import HTU21D
      import json
      
      result = {}
      try:
          # Create sensor object, communicating over the board's default I2C bus
          i2c = board.I2C()  # uses board.SCL and board.SDA
          sensor = HTU21D(i2c)
          result["temperature_c"] = sensor.temperature
          result["humidity"] = sensor.relative_humidity
          result["temperature_f"] = (result["temperature_c"]*1.8) + 32
          result["error"] = False
      except:
          result["temperature_c"] = 0.0
          result["humidity"] = 0.0
          result["temperature_f"] = (result["temperature_c"]*1.8) + 32
          result["error"] = True
      
      print(json.dumps(result))
      

      My resulting script is aht20:

      #!/usr/bin/env python3
      # aht20: Modeled on htu21 
      # pip3 install adafruit-circuitpython-htu21d
      # pip3 install adafruit-circuitpython-ahtx0
      import board
      import adafruit_ahtx0
      import json
      
      result = {}
      try:
          # Create sensor object, communicating over the board's default I2C bus
          i2c = board.I2C()  # uses board.SCL and board.SDA
          # sensor = HTU21D(i2c)
          sensor = adafruit_ahtx0.AHTx0(board.I2C())
          result["temperature_c"] = sensor.temperature
          result["humidity"] = sensor.relative_humidity
          result["temperature_f"] = (result["temperature_c"]*1.8) + 32
          result["error"] = False
      except:
          result["temperature_c"] = 0.0
          result["humidity"] = 0.0
          result["temperature_f"] = (result["temperature_c"]*1.8) + 32
          result["error"] = True
      
      print(json.dumps(result))
      

      This module is now displaying the temperature and humidity from the sensor directly connected it it. Now all I have to do is figure out the complicated css and get it to look like the other modules on my Magic Mirror.

      Barring any objections, I will mark this as solved.

      posted in Requests
      J
      JohnGalt
    • RE: AHT20 Humidity + Temperature Sensor

      @rkorell + @sdetweil - Thanks for the support. I think I have fixed this for myself by adapting an existing module (“MMM-Temperature”, // https://github.com/Tom-Hirschberger/MMM-Temperature).

      That module calls scripts for various sensors to capture the data. I was able to adapt an existing script for use with this sensor, so I think I am good for now.

      posted in Requests
      J
      JohnGalt
    • RE: AHT20 Humidity + Temperature Sensor

      @rkorell – Hi Ralf:

      Yes, I2C is enabled and functioning. There is a test script that does return current temperature and humidity:
      Invoking “python AHT20_test.py” does launch this script (Note - I launch from the terminal using ‘python’, not ‘python3’, telling me the system is indeed defaulting to python3):

      # SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
      # SPDX-License-Identifier: MIT
      
      """
      Basic `AHTx0` example test
      """
      
      import time
      import board
      import adafruit_ahtx0
      
      # Create sensor object, communicating over the board's default I2C bus
      i2c = board.I2C()  # uses board.SCL and board.SDA
      # i2c = board.STEMMA_I2C()  # For using the built-in STEMMA QT connector on a microcontroller
      sensor = adafruit_ahtx0.AHTx0(i2c)
      
      while True:
          print("\nTemperature: %0.1f C" % sensor.temperature)
          print("Humidity: %0.1f %%" % sensor.relative_humidity)
          time.sleep(2)
      
      posted in Requests
      J
      JohnGalt
    • RE: AHT20 Humidity + Temperature Sensor

      @sdetweil – Thanks, Sam. It looks like I intended to send bme280.py but actually copied MMM-BME280.js. I see below where Ralf did post it, so I will look at that, too.

      posted in Requests
      J
      JohnGalt
    • RE: AHT20 Humidity + Temperature Sensor

      @sdetweil – Hi Sam, thanks for looking in on this.

      I guess I don’t understand… If the module is calling a python script, and the script is polling the sensor - then it would seem to me that the browser isn’t accessing the hardware or files directly. Obviously I’m missing something here.

      posted in Requests
      J
      JohnGalt
    • RE: AHT20 Humidity + Temperature Sensor

      @rkorell Ralf: OK, I have a chance to work on this today - Thanks for your help.

      To ease troubleshooting, I have temporarily disabled MMM-Temperature and am only running MMM-BME280. Below are the following:

      1. Config for this module
      2. Error as captured using pm2 logs
      3. Code listing of bme280.js, which is called by the module

      Config:

      {module: 'MMM-BME280', // https://github.com/awitwicki/MMM-BME280
        disabled: false,
        position: 'top_right',
        config: {
          titleText: "Office - MMM-BME280",
          updateInterval: 100, //seconds 
          deviceAddress: "0x38", //0x76 = default
          temperatureScaleType: 1, // 0=Celsius
          pressureScaleType: 1, // 0 = hPa
      	} },
      

      Errors [from pm2 logs]:
      0|MagicMirror | [2025-04-15 12:57:48.599] [ERROR] exec error: Error: Command failed: python3 ./modules/MMM-BME280/bme280.py 0x38
      0|MagicMirror | Traceback (most recent call last):
      0|MagicMirror | File “/home/pi/MagicMirror/./modules/MMM-BME280/bme280.py”, line 176, in
      0|MagicMirror | main()
      0|MagicMirror | File “/home/pi/MagicMirror/./modules/MMM-BME280/bme280.py”, line 171, in main
      0|MagicMirror | temperature,pressure,humidity = readBME280All()
      0|MagicMirror | File “/home/pi/MagicMirror/./modules/MMM-BME280/bme280.py”, line 82, in readBME280All
      0|MagicMirror | bus.write_byte_data(addr, REG_CONTROL_HUM, OVERSAMPLE_HUM)
      0|MagicMirror | OSError: [Errno 121] Remote I/O error
      0|MagicMirror |

      Code for bme280.py:

      Module.register("MMM-BME280", {
          // Default module config.
          defaults: {
              updateInterval: 100, // Seconds
              titleText: "Home weather",
              deviceAddress: "0x76",
              temperatureScaleType: 0, // Celsuis
              pressureScaleType: 0 // hPa
          },
      
          // Define start sequence.
          start: function () {
              Log.info("Starting module: " + this.name);
      
              this.temperature = 'Loading...';
              this.humidity = 'Loading...';
              this.pressure = 'Loading...';
      
              this.update();
              setInterval(
                  this.update.bind(this),
                  this.config.updateInterval * 1000);
          },
      
          update: function () {
              this.sendSocketNotification('REQUEST', this.config);
          },
      
          getStyles: function () {
              return ['MMM-BME280.css'];
          },
      
          // Override dom generator.
          getDom: function () {
              var wrapper = document.createElement("div");
      
              var header = document.createElement("div");
              var label = document.createTextNode(this.config.titleText);
              header.className = 'bme-header';
              header.appendChild(label)
              wrapper.appendChild(header);
      
              var table = document.createElement("table");
              var tbdy = document.createElement('tbody');
              for (var i = 0; i < 3; i++) {
                  var val = "";
                  var sufix = "";
                  var icon_img = "";
      
                  switch (i) {
                      case 0:
                          switch (this.config.temperatureScaleType) {
                              case 0: // Celsius
                                  val = this.temperature;
                                  sufix = "°C";
                                  break;
                              case 1: // Fahrenheit
                                  val = Math.round(this.temperature * 9.0 / 5.0 + 32.0);
                                  sufix = "°F";
                                  break;
                          }
                          icon_img = "temperature-high";
                          break;
                      case 1:
                          val = this.humidity;
                          icon_img = "tint";
                          sufix = "%";
                          break;
                      case 2:
                          switch (this.config.pressureScaleType) {
                              case 0: // hPa
                                  val = this.pressure;
                                  sufix = " hPa";
                                  break;
                              case 1: // inHg
                                  val = Math.round(this.pressure * 100 / 33.864) / 100;
                                  sufix = " inHg";
                                  break;
                          }
                          icon_img = "tachometer-alt";
                          break;
                  }
      
                  var tr = document.createElement('tr');
                  var icon = document.createElement("i");
      
                  icon.className = 'fa fa-' + icon_img + ' bme-icon';
      
                  var text_div = document.createElement("div");
                  var text = document.createTextNode(" " + val + sufix);
                  text_div.className = 'bme-text';
                  text_div.appendChild(text);
      
                  var td = document.createElement('td');
                  td.className = 'bme-td-icon';
                  td.appendChild(icon)
                  tr.appendChild(td)
      
                  var td = document.createElement('td');
                  td.appendChild(text_div)
                  tr.appendChild(td)
      
                  tbdy.appendChild(tr);
              }
              table.appendChild(tbdy);
              wrapper.appendChild(table);
      
              return wrapper;
          },
      
          socketNotificationReceived: function (notification, payload) {
              if (notification === 'DATA') {
                  this.temperature = payload.temp;
                  this.humidity = payload.humidity;
                  this.pressure = payload.press;
                  this.updateDom();
              }
          },
      });
      
      posted in Requests
      J
      JohnGalt
    • RE: AHT20 Humidity + Temperature Sensor

      @rkorell – Thanks for responding, answers follow:

      1. Yes, the first use case is a sensor connected directly to the Raspberry Pi 4 where the Magic Mirror is running. It will be great if I can expand this in the future to display on my office Magic Mirror the outputs from sensors on three (3) other Pis (they run Magic Mirror, NEMS network monitor and Pi-Aware flight tracking, respectively).

      2. I am just running the two Magic Mirror modules listed above. I don’t know what scripts they run. At this point I have just looked and don’t see any obvious way to adapt them. I did try changing the address of the device from their default to 0x38, which is what I think is the address for this sensor attached to my Pi - but I still don’t get output. I should have some time this afternoon to SSH into that machine, and I can locate the scripts and log the error messages.

      posted in Requests
      J
      JohnGalt
    • RE: Pollen module

      I use MMM-Pollen: https://github.com/vincep5/MMM-Pollen

      posted in Requests
      J
      JohnGalt
    • AHT20 Humidity + Temperature Sensor

      Does anyone know of a module that will display the output from AHT20 temperature + humidity sensors? I got these after having used the older DHTxx sensors in the past. These new sensors use I2C, and I have confirmed the sensor is wired up correctly and sending data by using an example script.

      Now I’d like to get the output on the Magic Mirror. While I do see some modules that read from I2C compatible sensors, I haven’t seen one that reads these.

      Currently I an working with these two modules, both to no avail:
      MMMiTemperature: https://github.com/Tom-Hirschberger/MMM-Temperature
      and
      MMM-BME280: https://github.com/awitwicki/MMM-BME280

      posted in Requests
      J
      JohnGalt
    • RE: How to Use NY Times Subscription with Default Newsfeed Module

      @karsten13 – Yes, that’s what I figured.

      The problem from the provider’s perspective would be how to both give access to legitimate subscribers while limiting access to others. The only solution that springs to mind would be to authenticate the user when they query the server, but for something like this where all the users’ computers might each be coming for content several times each day - it begins to be a lot of computing overhead.

      posted in Development
      J
      JohnGalt
    • 1 / 1