Using virtual pin to shutdown raspberry pi (Using WiringPi, C++)

Is there a way to shutdown the raspberry pi using a virtual push button…
I’ve got a shell script containing:
sudo sleep 1; shutdown -h now

Would it be something like this?

        // When V1 is pressed, pi will shutdown
    BLYNK_WRITE(V1)
    {
    	int i = param.asInt();
    	if(i == 1) {
    		system("home/pi/shutdown.sh");
    	
    	}
    }

I use this for reboot… just remove the -r for shutdown.

EDIT - this is for NodeJS, not WiringPi :blush:

var process = require('child_process'); // Allows this script to run CLI commands

// ----- RPi Reboot Command -----
var RPiReboot = new blynk.VirtualPin(20);  // Setup Reboot Button

RPiReboot.on('write', function(param) {  // Watches for V20 Button
  if (param == 1) {  // Runs the CLI command if the button on V20 is pressed
    process.exec('sudo /sbin/shutdown -r', function (msg) { console.log(msg) });
}
});

@Gunner thanks, just tried that (changed to V1) but got this error when trying to rebuild…

        main.cpp:80:1: error: ‘var’ does not name a type
     var process = require('child_process'); // Allows this script to run CLI commands
     ^~~
    main.cpp:83:1: error: ‘var’ does not name a type
     var RPiReboot = new blynk.VirtualPin(1);  // Setup Reboot Button
     ^~~
    main.cpp:85:1: error: ‘RPiReboot’ does not name a type
     RPiReboot.on('write', function(param) {  // Watches for V1 Button
     ^~~~~~~~~
    main.cpp:89:2: error: expected unqualified-id before ‘)’ token
     });
      ^
    Makefile:70: recipe for target 'main.o' failed
    make: *** [main.o] Error 1

Strange… as I understand it, var is like JS way of defining a variable… that would be like Arduino IDE throwing a compiling error over int MyVariable; :thinking:

You might have some other syntax issues in your code… can you post it in full here?

  //#define BLYNK_DEBUG
  #define BLYNK_PRINT stdout
  #ifdef RASPBERRY
    #include <BlynkApiWiringPi.h>
  #else
    #include <BlynkApiLinux.h>
  #endif

  #include <BlynkSocket.h>
  #include <BlynkOptionsParser.h>

  #include <sys/types.h>
  #include <sys/stat.h>
  #include <unistd.h>
  #include <fcntl.h>
  #include <cstring>

  #include <iostream>
  #include <fstream>
  #include <thread>
  #include <string>

  #include <cstdio>
  #include <memory>
  #include <stdexcept>
  #include <array>
  #include <cstdlib>
  #include <algorithm>




  static BlynkTransportSocket _blynkTransport;
  BlynkSocket Blynk(_blynkTransport);

  static const char *auth, *serv;
  static uint16_t port;

  #include <BlynkWidgets.h>

  // Execute the "cmd" string and return the result as a std::string
  std::string exec(const char* cmd) {
      std::array<char, 128> buffer;
      std::string result;
      std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
      if (!pipe) throw std::runtime_error("popen() failed!");
      while (!feof(pipe.get())) {
          if (fgets(buffer.data(), 128, pipe.get()) != nullptr)
              result += buffer.data();
      }
      result.erase(std::remove(result.begin(), result.end(), '\n'), result.end());
      return result;
  }

  // When the virtual button V0 is checked start music, when unchecked stop music
  // A random song from the /home/pi/Music/Lullaby will be picked
  BLYNK_WRITE(V0)
  {
  	int i = param.asInt();
  	if(i == 1) {
  		printf("Start music");
  		std::string line = "omxplayer --no-osd --no-keys -o local ~/Music/Lullaby/" + exec("ls ~/Music/Lullaby/ | shuf | head -n 1") + " &";
  		system(line.c_str());
  	} else {
  		printf("Stop music");
  		system("pkill omxplayer");
  	}
  }

  // When V1 is pressed, pi will shutdown
  var process = require('child_process'); // Allows this script to run CLI commands

  // ----- RPi Reboot Command -----
  var RPiReboot = new blynk.VirtualPin(1);  // Setup Reboot Button

  RPiReboot.on('write', function(param) {  // Watches for V1 Button
    if (param == 1) {  // Runs the CLI command if the button on V1 is pressed
      process.exec('sudo /sbin/shutdown', function (msg) { console.log(msg) });
  }
  });




  //BLYNK_CONNECTED() {
  //	Blynk.syncVirtual(V0);
  //	Blynk.syncVirtual(V1);
  //}


  void setup()
  {
      Blynk.begin(auth, serv, port);
  }

  void loop()
  {
      Blynk.run();
  }

  // Avoid parsing the command line arguments
  // replace this with your own auth token
  void set_stuff() {
      // Set the auth token
      auth = "XXXXXXXXXXXXXX";
      
      // Set default values
      serv = BLYNK_DEFAULT_DOMAIN;
      port = BLYNK_DEFAULT_PORT;	
      
      setup();    
  }

  // Send a push notification and return
  void send_notification(const char *notification) {
      while(true) {        
          // Only when connected (ready to send/recive data) send a push notification
  		if(Blynk.connected()) {			
  			printf("Prepare to notify\n");
  			Blynk.notify(notification);
  			break;
  		}
      }	    
  }


  const char *pipe_name="/tmp/BlynkAppCommunicator";

  // Check the named pipe for signal
  void checkPipe() {
  	for(;;) {
  		std::ifstream file{pipe_name};
  		std::string line;
  		std::getline(file, line);
  		std::cout << "From pipe: " << line << '\n';
  		file.close();
  		if(line == "PUSH_NOTIFICATION") {
  			send_notification("EMERGENCY!!! No Movement Detected!!!");
  		}
  		if(line == "EXIT") break;
  	}
  }

  int main(int argc, char* argv[])
  {
  	// Make sure there is a named pipe available
  	mkfifo(pipe_name, 0666);
  	
  	// Start a new thread that will read from the named pipe
  	std::thread th{checkPipe};
  	
  	set_stuff();
  	
  	// Infinite loop
      while(true) {
          loop();
  	}	
  	    
      th.join();

      return 0;
  }

It compiled and worked fine until putting it in… :slight_smile:

Ahhh… you are using WiringPi C++… the code I gave you is for NodeJS :stuck_out_tongue: Guess I should have asked what language you are using.

The CLI command would be the same, but how you run a child process from WiringPi is beyond me.

dont worry about that lol… atleast it will work on the one running nodejs as I have to run it on that one too… two pi’s with two different ways of doing it is a pain in the arse… know anyone who would know the process for wiringpi?

What is wrong with the nodejs one?

    //#define BLYNK_DEBUG
    #define BLYNK_PRINT stdout
    #ifdef RASPBERRY
      #include <BlynkApiWiringPi.h>
    #else
      #include <BlynkApiLinux.h>
    #endif
    #include <BlynkSocket.h>
    #include <BlynkOptionsParser.h>

    static BlynkTransportSocket _blynkTransport;
    BlynkSocket Blynk(_blynkTransport);

    static const char *auth, *serv;
    static uint16_t port;

    #include <BlynkWidgets.h>

    BLYNK_WRITE(V1)
    {
        printf("Got a value: %s\n", param[0].asStr());
    }

    var process = require('child_process'); // Allows this script to run CLI commands

    // ----- RPi Reboot Command -----
    var RPiReboot = new blynk.VirtualPin(2);  // Setup Reboot Button

    RPiReboot.on('write', function(param) {  // Watches for V2 Button
      if (param == 1) {  // Runs the CLI command if the button on V20 is pressed
        process.exec('sudo /sbin/shutdown -r', function (msg) { console.log(msg) });
    }
    });

    void setup()
    {
        Blynk.begin(auth, serv, port);
    }

    void loop()
    {
        Blynk.run();
    }

    var process = require('child_process'); // Allows this script to run CLI commands

    // ----- RPi Reboot Command -----
    var RPiReboot = new blynk.VirtualPin(20);  // Setup Reboot Button

    RPiReboot.on('write', function(param) {  // Watches for V20 Button
      if (param == 1) {  // Runs the CLI command if the button on V20 is pressed
        process.exec('sudo /sbin/shutdown -r', function (msg) { console.log(msg) });
    }
    });

    int main(int argc, char* argv[])
    {
        parse_options(argc, argv, auth, serv, port);

        setup();
        while(true) {
            loop();
        }

        return 0;

getting this error:

    pi@tombabypi:~ $ cd ~/blynk-library/linux/
    pi@tombabypi:~/blynk-library/linux $ make clean all target=raspberry
    rm main.o ../src/utility/BlynkDebug.o ../src/utility/BlynkHandlers.o ../src/utility/BlynkTimer.o blynk
    rm: remove write-protected regular file 'main.o'? 
    rm: remove write-protected regular file '../src/utility/BlynkDebug.o'? 
    rm: remove write-protected regular file '../src/utility/BlynkHandlers.o'? 
    rm: remove write-protected regular file '../src/utility/BlynkTimer.o'? 
    rm: remove write-protected regular file 'blynk'? 
    g++ -I ../src/ -I ./ -DLINUX -c -O3 -w -DRASPBERRY main.cpp -o main.o
    main.cpp:33:1: error: ‘var’ does not name a type
     var process = require('child_process'); // Allows this script to run CLI commands
     ^~~
    main.cpp:36:1: error: ‘var’ does not name a type
     var RPiReboot = new blynk.VirtualPin(2);  // Setup Reboot Button
     ^~~
    main.cpp:38:1: error: ‘RPiReboot’ does not name a type
     RPiReboot.on('write', function(param) {  // Watches for V2 Button
     ^~~~~~~~~
    main.cpp:42:2: error: expected unqualified-id before ‘)’ token
     });
      ^
    main.cpp:54:1: error: ‘var’ does not name a type
     var process = require('child_process'); // Allows this script to run CLI commands
     ^~~
    main.cpp:57:1: error: ‘var’ does not name a type
     var RPiReboot = new blynk.VirtualPin(20);  // Setup Reboot Button
     ^~~
    main.cpp:59:1: error: ‘RPiReboot’ does not name a type
     RPiReboot.on('write', function(param) {  // Watches for V20 Button
     ^~~~~~~~~
    main.cpp:63:2: error: expected unqualified-id before ‘)’ token
     });
      ^

Well, for one, you still have it mixed in with C++ style commands :stuck_out_tongue:
WiringPi is more like a GPIO support library for the RPi that uses C++ type commands.

NodeJS is a full language based on javascript (AFAIK)… and while I have seen WiringPi ports that work with (under) other languages, I don’t see the purpose myself.

But back to your question… that little snippet I gave you needs to run under Blynk’s JS library, nothing to do with WiringPi.

PS, when posting code here, you need to use the proper formatting otherwise it doesn’t always show correctly…

Blynk - FTFC

I have fixed your posts in this topic… look back and see how.

Ah i see my issue… i’ve got both types of Blynk installed on that Pi :joy:

And the RPi can actually handle that :slight_smile: … basically looks like two clients to the server… gets a bit tricky when sharing GPIO through :wink:

Yeah i’m not even going to attempt to do that haha…

just thought i’d let you know that i managed to get the virtual shutdown button to work for the raspberry pi using wiring pi… now to figure out the mess of the other raspberry pi using nodejs or both if i dare lol

Cool… how? just in case someone actually searches for such a thing :stuck_out_tongue_winking_eye:

BLYNK_WRITE(V2)
{
	int i = param.asInt();
	if(i == 1) {
		system("sudo poweroff");	
	}
}

:slight_smile:

on a side note… apparently i’m missing <DHT.h> …? * nevermind fixed it haha

1 Like