• 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 891 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.
  • S Away
    sdetweil @ChrisLeduex
    last edited by sdetweil Nov 4, 2024, 8:50 PM Nov 4, 2024, 7:56 PM

    @ChrisLeduex well, you don’t have any source errors. altho you have 2 start: functions in the modulename.js

    I see this as output of the pinctrl command on my pi 4

     pinctrl
     0: ip    pu | hi // ID_SDA/GPIO0 = input
     1: ip    pu | hi // ID_SCL/GPIO1 = input
     2: ip    pu | hi // GPIO2 = input
     3: ip    pu | hi // GPIO3 = input
     4: ip    pu | hi // GPIO4 = input
     5: ip    pu | hi // GPIO5 = input
     6: ip    pu | hi // GPIO6 = input
     7: ip    pu | hi // GPIO7 = input
     8: ip    pu | hi // GPIO8 = input
     9: ip    pd | lo // GPIO9 = input
    10: ip    pd | lo // GPIO10 = input
    11: ip    pd | lo // GPIO11 = input
    12: ip    pd | lo // GPIO12 = input
    13: ip    pd | lo // GPIO13 = input
    14: ip    pn | hi // GPIO14 = input
    15: ip    pu | hi // GPIO15 = input
    16: ip    pd | lo // GPIO16 = input
    17: ip    pd | lo // GPIO17 = input
    18: ip    pd | lo // GPIO18 = input
    19: ip    pd | lo // GPIO19 = input
    20: ip    pd | lo // GPIO20 = input
    21: ip    pd | lo // GPIO21 = input
    22: ip    pd | lo // GPIO22 = input
    23: ip    pd | lo // GPIO23 = input
    24: ip    pd | lo // GPIO24 = input
    25: ip    pd | lo // GPIO25 = input
    26: ip    pd | lo // GPIO26 = input
    27: ip    pd | lo // GPIO27 = input
    28: a5    pu | hi // RGMII_MDIO/GPIO28 = RGMII_MDIO
    29: a5    pd | lo // RGMIO_MDC/GPIO29 = RGMII_MDC
    30: a3    pu | lo // CTS0/GPIO30 = CTS0
    31: a3    pn | lo // RTS0/GPIO31 = RTS0
    32: a3    pn | hi // TXD0/GPIO32 = TXD0
    33: a3    pu | hi // RXD0/GPIO33 = RXD0
    34: a3    pn | hi // SD1_CLK/GPIO34 = SD1_CLK
    35: a3    pu | hi // SD1_CMD/GPIO35 = SD1_CMD
    36: a3    pu | hi // SD1_DATA0/GPIO36 = SD1_DAT0
    37: a3    pu | hi // SD1_DATA1/GPIO37 = SD1_DAT1
    38: a3    pu | hi // SD1_DATA2/GPIO38 = SD1_DAT2
    39: a3    pu | hi // SD1_DATA3/GPIO39 = SD1_DAT3
    40: a0    pn | lo // PWM0_MISO/GPIO40 = PWM1_0
    41: a0    pn | lo // PWM1_MOSI/GPIO41 = PWM1_1
    42: op -- pu | lo // STATUS_LED_G_CLK/GPIO42 = output
    43: ip    pu | hi // SPIFLASH_CE_N/GPIO43 = input
    44: ip    pu | hi // SDA0/GPIO44 = input
    45: ip    pu | hi // SCL0/GPIO45 = input
    46: ip    pu | lo // RGMII_RXCLK/GPIO46 = input
    47: ip    pu | lo // RGMII_RXCTL/GPIO47 = input
    48: ip    pd | lo // RGMII_RXD0/GPIO48 = input
    49: ip    pd | lo // RGMII_RXD1/GPIO49 = input
    50: ip    pd | lo // RGMII_RXD2/GPIO50 = input
    51: ip    pd | lo // RGMII_RXD3/GPIO51 = input
    52: ip    pd | lo // RGMII_TXCLK/GPIO52 = input
    53and : ip    pd | lo // RGMII_TXCTL/GPIO53 = input
    

    and this for output of pinctrl 19

    19: ip    pd | lo // GPIO19 = input
    

    so the “pinctrl 19” command and parseInt(“19: ip pd | lo // GPIO19 = input”, 10);
    will return 19

    I think you meant pinctrl get 19, after sometime prior doing pinctrl set

    pinctrl help
    shows all it can do

    Sam

    How to add modules

    learning how to use browser developers window for css changes

    C 1 Reply Last reply Nov 5, 2024, 6:28 PM Reply Quote 0
    • 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
                21/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