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

Problem Adding Buttons & required Remote-Control Modules

Scheduled Pinned Locked Moved Solved Troubleshooting
26 Posts 4 Posters 1.6k Views 4 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
    ChrisLeduex @sdetweil
    last edited by Nov 5, 2024, 6:28 PM

    @sdetweil Thank you for catching those, too much copying and pasting.

    Removed one of the start functions from the module.js file and also updated this line in the node_helper.js file so now it is returning the pin state instead of the pin number.
    //const pinState = parseInt(stdout.trim(), 10);
    const pinState = stdout.includes(“hi”) ? 1 : 0;

    There still seems to be an issue somewhere in my node_helper.js file though because I’m still not seeing anything from that file in the console. Looking through the forum it seems node_helper file issues are common and I’ve tried implementing a few of the solutions I found there but still haven’t found the problem but I will keep trying. I suspect maybe I’m not nesting my socket notifications correctly.

    PinToggleTest.js

    Module.register("MMM-PinToggleTest", {
      defaults: {
        pin: 19,
        modulesToToggle: ["clock", "calendar"],
        interval: 1000
      },
    
      start: function() {
        console.log("MMM-PinToggleTest started");
        Log.info("MMM-PinToggleTest is starting, sending CONFIG...");
        this.previousPinState = null;
    
        // Request initial pin check from the helper
        this.sendSocketNotification("CONFIG", this.config);
      },
      
      socketNotificationReceived: function(notification, payload) {
    		if (notification === 'STARTED') {
        console.log("STARTED notification received from node_helper");
        this.config.text = 'Started';
        this.updateDom();
    		}
    	},
    
      socketNotificationReceived: function(notification, payload) {
        if (notification === "PIN_STATE") {
          const pinState = payload;
          console.log(`Received pin state: ${pinState}`);  // Log received state
    
          // Toggle modules based on pin state
          if (pinState !== this.previousPinState) {
            this.previousPinState = pinState;
            this.toggleModules(pinState === 1);
          }
        }
      },
    
      toggleModules: function(show) {
        console.log(`Toggling modules to ${show ? "show" : "hide"}`);
        this.config.modulesToToggle.forEach(moduleName => {
          const modules = MM.getModules().withClass(moduleName);
          modules.forEach(module => {
            if (show) {
              module.show(1000);  // Show module with fade-in effect
            } else {
              module.hide(1000);  // Hide module with fade-out effect
            }
          });
        });
      },
    
      getDom: function() {
        const wrapper = document.createElement("div");
        wrapper.innerHTML = "<small>MMM-PinToggleTest</small>";
        return wrapper;
      }
    });
    

    node_helper.js

    const NodeHelper = require("node_helper");
    const exec = require("child_process").exec;
    //const rpio = require("rpio");
    //const Gpio = require("onoff").Gpio;
    
    //module.exports = NodeHelper.create({
    //  start: function() {
    //    console.log("Starting node_helper for MMM-PinToggleTest");
    //    this.previousPinState = null;
    //    this.config = null;
    //  },
    
    module.exports = NodeHelper.create({
      start() {
        this.started = false;
      },
    
      socketNotificationReceived: function(notification, payload) {
        if (notification === "CONFIG" && !this.started) {
          const self = this;
          console.log("CONFIG notification received");
          this.config = payload;
          this.schedulePinCheck();
          this.sendSocketNotification('STARTED', {message: 'test'});
          console.log("STARTED notification sent back to front end");
        }
      },
    
      schedulePinCheck: function() {
        console.log(`Setting up pin check every ${this.config.interval} ms`);
        setInterval(() => {
          this.checkPinState();
        }, this.config.interval);
      },
    
      checkPinState: function() {
        const pinNumber = this.config.pin;
    
        // Execute pinctrl command
        exec(`pinctrl get ${pinNumber}`, (error, stdout, stderr) => {
          if (error) {
            console.error(`Error reading GPIO pin ${pinNumber}: ${stderr}`);
            return;
          }
    
          //const pinState = parseInt(stdout.trim(), 10);
          const pinState = stdout.includes("hi") ? 1 : 0;
          console.log(`Detected pin state for pin ${pinNumber}: ${pinState}`);  // Log the detected state
    
          // Only send if state has changed
            if (pinState !== this.previousPinState) {
            this.previousPinState = pinState;
            console.log(`Pin state changed to ${pinState}`);
            this.sendSocketNotification("PIN_STATE", pinState);
            
            // Small delay to avoid multiple triggers
            setTimeout(() => {}, 100);
          }
        });
      }
    });
    
    S 1 Reply Last reply Nov 5, 2024, 6:35 PM Reply Quote 0
    • S Away
      sdetweil @ChrisLeduex
      last edited by Nov 5, 2024, 6:35 PM

      @ChrisLeduex I see this from the output of npm start

      [2024-11-05 12:32:28.225] [LOG]   Current pin state for GPIO 19: 1 
      [2024-11-05 12:32:28.225] [LOG]   Pin state changed to 1 at 2024-11-05T18:32:28.224Z 
      [2024-11-05 12:32:28.244] [INFO]  [MMM-MealieMenu] Week starts: 2024-11-04, next week starts: 2024-11-11 
      [2024-11-05 12:32:28.375] [INFO]  Mealie error={} 
      [2024-11-05 12:32:28.400] [INFO]  Newsfeed-Fetcher: Broadcasting 15 items. 
      [2024-11-05 12:32:28.413] [INFO]  Newsfeed-Fetcher: Broadcasting 22 items. 
      [2024-11-05 12:32:28.819] [INFO]  Newsfeed-Fetcher: reloadInterval set to ttl=5400000 for url http://www.tagesschau.de/xml/rss2 
      [2024-11-05 12:32:28.847] [INFO]  Newsfeed-Fetcher: Broadcasting 40 items. 
      [2024-11-05 12:32:29.225] [LOG]   Current pin state for GPIO 19: 1 
      [2024-11-05 12:32:30.225] [LOG]   Current pin state for GPIO 19: 1 
      [2024-11-05 12:32:31.225] [LOG]   Current pin state for GPIO 19: 1 
      [2024-11-05 12:32:32.225] [LOG]   Current pin state for GPIO 19: 1 
      [2024-11-05 12:32:33.224] [LOG]   Current pin state for GPIO 19: 1 
      [2024-11-05 12:32:34.225] [LOG]   Current pin state for GPIO 19: 1 
      [2024-11-05 12:32:35.226] [LOG]   Current pin state for GPIO 19: 1 
      [2024-11-05 12:32:36.227] [LOG]   Current pin state for GPIO 19: 1 
      [2024-11-05 12:32:37.229] [LOG]   Current pin state for GPIO 19: 1 
      [2024-11-05 12:32:38.227] [LOG]   Current pin state for GPIO 19: 1 
      

      I wrote a little pinctrl script that just outputs 1

      #!/bin/bash
      echo 1
      

      as pinctrl is not on my linux desktop

      Sam

      How to add modules

      learning how to use browser developers window for css changes

      C 1 Reply Last reply Nov 5, 2024, 8:11 PM Reply Quote 0
      • C Offline
        ChrisLeduex @sdetweil
        last edited by Nov 5, 2024, 8:11 PM

        @sdetweil Ah yes, I forgot I have a python script I was kicking off manually that I forgot to run before testing those fixes. It is working now and both files are communicating with each other, thank you.

        My next step is to see if I can get this working with the MMM-Buttons/MMM-ModuleToggleButton modules.

        S 1 Reply Last reply Nov 5, 2024, 9:44 PM Reply Quote 0
        • S Away
          sdetweil @ChrisLeduex
          last edited by Nov 5, 2024, 9:44 PM

          @ChrisLeduex buttons is interrupt driven, but can be changed to polling like you are doing

          Sam

          How to add modules

          learning how to use browser developers window for css changes

          C 1 Reply Last reply Nov 6, 2024, 1:56 AM Reply Quote 0
          • C Offline
            ChrisLeduex @sdetweil
            last edited by Nov 6, 2024, 1:56 AM

            @sdetweil Yeah you’re right, that one might be more difficult. But I do have MMM-ModuleToggleButton working with pinctrl. Here’s the updated node_helper.js file just in case anyone’s interested.

            node_helper.js

            const NodeHelper = require('node_helper'); // eslint-disable-line import/no-extraneous-dependencies
            //const Gpio = require('onoff').Gpio;
            const { exec } = require("child_process");
            
            module.exports = NodeHelper.create({
              start() {
                this.started = false;
              },
            
              socketNotificationReceived(notification, payload) {
                if (notification === 'TOGGLE_BUTTON_CONFIG' && !this.started) {
                  const self = this;
                  this.config = payload;
            
                  //const button = new Gpio(this.config.buttonGpioPin, 'in', 'both', { persistentWatch: true, debounceTimeout: this.config.debounceTimeoutInMilliseconds });
                  //button.watch((err, state) => {
                  //  if (state === 1) {
                  //    self.sendSocketNotification(self.config.notificationName, true);
                  //  }
                  //});
            
                  //this.started = true;
                  
                  // Set up GPIO as input using pinctrl command
                  const pin = this.config.buttonGpioPin;
                  const debounceTimeout = this.config.debounceTimeoutInMilliseconds;
                  const notificationName = this.config.notificationName;
                  let lastState = null;
            
                  // Function to read the pin state using pinctrl
                  const checkPinState = () => {
                  exec(`pinctrl get ${pin}`, (err, stdout, stderr) => {
                    if (err) {
                      console.error(`Error reading GPIO state: ${err.message}`);
                      return;
                    }
                   
                    // Parse the pin state from stdout
                    const state = stdout.includes("hi") ? 1 : 0;
            
                    // Handle state change with debounce
                    if (state !== lastState && state === 1) {
                      this.sendSocketNotification(notificationName, true);
                    }
                   
                    // Update last state
                    lastState = state;
                  });
                  };
            
                // Set up an interval to check the pin state with debounce
                setInterval(checkPinState, debounceTimeout || 100); // Defaults to 100ms if debounce is not defined
                  
                }
              }
            });
            
            1 Reply Last reply Reply Quote 0
            • S sdetweil has marked this topic as solved on Nov 20, 2024, 3:13 AM
            • 1
            • 2
            • 3
            • 3 / 3
            3 / 3
            • First post
              26/26
              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