Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible to add long press wait to listen-for-shutdown.py? #2

Open
intrglctcrevfnk opened this issue Jul 8, 2017 · 12 comments
Open

Comments

@intrglctcrevfnk
Copy link

I've been using your script for a while now and I really like how clean it is. I've used it on every Pi setup I've done so far (7 total for various around the house projects and for friends) and it has worked flawlessly!

Anyway I recently set up a Octoprint for my Maker Select Plus and installed a button on the side of my case. I have accidentally tapped the button while loading and unloading filament several times. I was looking to add a wait/time delay so that a long press would trigger the script. There are other tutorials out there but i really like what I've got with your script. Also many of these tutorials offer a reboot on a short press/shutdown on a long press. I am not a professional coder, changed majors from computer science way back in 1999 so it is all quite rusty.

So really I'd like your opinion on wether the modified code below would actually work or what you would do to change it. It's hacked together from other sources and modified to the best of my abilities. I imported time and sleep in the header. Only big issue based on my limited knowledge is the 'if' call at the beginning since there isn't an 'else' that follows. I learned C way back in the day so I thought it might need a 'do'.

Note: Formatting on inserting code is strange on Github. I'm pretty new here so I added quote indentions because the code did not format correctly when copying it here.

#!/usr/bin/env python

import time
from time import sleep
import RPi.GPIO as GPIO
import subprocess

GPIO.setmode(GPIO.BCM)
GPIO.setup(3, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.wait_for_edge(3, GPIO.FALLING)

def Long_press_shutdown:
#count how long the button is pressed
#not sure - is if: the correct call???

if
            counter = 0

            while ( pressed == 1 ):

                    if ( GPIO.input(3) == False ):

                            # button is still pressed

                            counter = counter + 1

                            # break if we count beyond 5 (to stop accidental shutdowns)
                            if (counter >= 5):

                                    pressed = 0

                            else:

                                    sleep(0.2)


                    else:
                            # button has been released

                            pressed = 0

            # button has been released, count cycles and determine action


            # count how long the button was pressed

            if (counter < 2):

                    # short press, do nothing
                    pressed = 0
                    int_active = 0

            else:
                    # longer press
                    if (counter < 5):

                            # longer press, initiate shutdown

                            print("system is shutting down...")

                            # run the shutdown command
                            subprocess.call(['shutdown', '-h', 'now'], shell=False)

#Use the interrupt from pin 3 to call the routine Long_press_shutdown
GPIO.add_event_detect(3, GPIO.FALLING, callback = Int_shutdown, bouncetime = 1000)

Please take a look and let me know!

@josephtyler
Copy link
Contributor

josephtyler commented Jul 19, 2017

I think in this case you would not call wait_for_edge, but this is a good use of add_event_detect.

I think the logic of your script makes sense. Have you tested this?

If I have time soon, perhaps I'll add this feature to the script.

@karneaud
Copy link

+1

@Nizhile
Copy link

Nizhile commented Apr 17, 2019

I recently replaced RPi.GPIO by gpizero library on my Raspberry. Using this library should give simplier result (not yet tested).

def shutdown():
    subprocess.call(['shutdown', '-h', 'now'], shell=False)

def reboot():
    subprocess.call(['shutdown', '-r', 'now'], shell=False)

button = Button(3, hold_time=2)
button.when_held = shutdown
button.when_pressed  = reboot

pause()

See answer to using a button long press vs short press

@Nizhile
Copy link

Nizhile commented Apr 19, 2019

I had some time to test my previous suggestion for longpress. It does not work as when_pressed is called anytime button is pressed (obviously 😁 ). Thus the script should wait for button to be released. It is still more compact than using RPi.GPIO as the timing and wait are handled by gpiozero library.

#!/usr/bin/env python

from gpiozero import Button
import subprocess

perform_halt = 0

def longpress():
    global perform_halt
    perform_halt = 1

button = Button(3, hold_time=2)
button.when_held = longpress

button.wait_for_press()
button.wait_for_release()

if (perform_halt):
    subprocess.call(['shutdown', '-h', 'now'], shell=False)
else:
    subprocess.call(['shutdown', '-r', 'now'], shell=False)

@Malakai-Mods
Copy link

Malakai-Mods commented Aug 8, 2019

I had some time to test my previous suggestion for longpress. It does not work as when_pressed is called anytime button is pressed (obviously 😁 ). Thus the script should wait for button to be released. It is still more compact than using RPi.GPIO as the timing and wait are handled by gpiozero library.

Is this tested working? Any chance of a pull request?

Edit, didn't work for me. Pi instantly shuts down upon button press

@Nizhile
Copy link

Nizhile commented Aug 19, 2019

Is this tested working? Any chance of a pull request?

@Malakai-Mods yes and only @ZLevine can tell.

Short press will trigger a reboot and you'll see the following in an open shell:

Broadcast message from root@framboise (Mon Aug 19 09:18:02 2019):

The system is going down for reboot NOW!`

Long press will trigger a halt with the following message:

Broadcast message from root@framboise (Mon Aug 19 09:19:53 2019):

The system is going down for system halt NOW!

Anyway it will probably not make it to the main repository because this script support an article about the power off/on switch.

However, you can use https://github.com/Nizhile/pi-power-button and use branch gpiozero_long_press to get this feature.

@azizhk
Copy link

azizhk commented Aug 26, 2019

@Nizhile can this be modified such that only long press causes shutdown:
I've had some trouble with while loops using too much CPU in the past so wanted to know if this is ok.

from gpiozero import Button
import subprocess

perform_halt = 0

def longpress():
    global perform_halt
    perform_halt = 1

button = Button(3, hold_time=2)
button.when_held = longpress

while True:
  button.wait_for_press()
  button.wait_for_release()

  if (perform_halt):
      subprocess.call(['shutdown', '-h', 'now'], shell=False)
      break

@azizhk
Copy link

azizhk commented Aug 26, 2019

🙈 😅 I realized I could have done just this:

from gpiozero import Button
import subprocess

def longpress():
    subprocess.call(['shutdown', '-h', 'now'], shell=False)

button = Button(3, hold_time=2)
button.when_held = longpress
pause()

@Nizhile
Copy link

Nizhile commented Aug 27, 2019

🙈 😅 I realized I could have done just this:

button = Button(3, hold_time=2)
button.when_held = longpress
pause()

That is the reason why I find gpiozero interesting 😊

@peterpan192
Copy link

@Nizhile I can't figure out, how to adjust your script in order to achieve the following. I hope you or anyone else can help me out here.

longpress -> run bash-script A
shortpress -> run bash-script B

To test this, I adjusted
subprocess.call(['shutdown', '-h', 'now'], shell=False)
to
subprocess.call(['touch', '/home/pi/shutdown'], shell=False)
and
subprocess.call(['shutdown', '-r', 'now'], shell=False)
to
subprocess.call(['touch', '/home/pi/reboot'], shell=False)

The file "reboot" is generated but for the first part it shuts down the pi anyways. I also tried to change
perform_halt = 1
to
perform_halt = 0
which leads to the pi not shutting down anymore on longpress but it's not doing anything else as well.

Python is just not mine but I wanted to show that I at least tried.

@Nizhile
Copy link

Nizhile commented Mar 11, 2022

@Nizhile I can't figure out, how to adjust your script in order to achieve the following. I hope you or anyone else can help me out here.

longpress -> run bash-script A shortpress -> run bash-script B

The current snippets in the comment all rely on the fact that the script will launch a single command.
In halt/reboot example, the longpress() callback will differentiate both press actions. The script waits for the button to be pressed, then to be released.
Depending on the value set by longpress, launch either command a or command b. Then the py script will end itself. So it launch a single command.
Hope the explanation is clear enough 🙂

@peterpan192
Copy link

@Nizhile I can't figure out, how to adjust your script in order to achieve the following. I hope you or anyone else can help me out here.
longpress -> run bash-script A shortpress -> run bash-script B

The current snippets in the comment all rely on the fact that the script will launch a single command. In halt/reboot example, the longpress() callback will differentiate both press actions. The script waits for the button to be pressed, then to be released. Depending on the value set by longpress, launch either command a or command b. Then the py script will end itself. So it launch a single command. Hope the explanation is clear enough 🙂

Yeah, you're right! Once one of the presses is triggered, the script will end itself. 🙈
It worked all the way! My mistake - but thanks for helping me out! :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants