Utilizing Button on Series 4 Pogoplug

This forum is for Marvell Kirkwood devices such as the GoFlex Home/Net, PogoPlug v1/v2, SheevaPlug, and ZyXEL devices.

Utilizing Button on Series 4 Pogoplug

Postby neonpolaris » Mon Nov 11, 2013 3:37 pm

I recently picked up a Pogoplug v4 from Radioshack on clearance (less than $20!) and set about installing Arch Linux on it. The Arch install was very simple (thanks guys!). I then set up automounting USB drives with udevil and added a script to automatically update samba with the new shares upon insertion. I also made scripts to shutdown the device or just eject the plugged in drives (for removal while running), but I wanted to be able to run these without having to ssh in to run them. The pogoplug v4 has a single button on the back labelled 'eject', which is mapped to /dev/input/event0. However, I had quite a time figuring out how to put this to use. Thanks to a helpful point in the right direction from another user in the IRC channel, I eventually got it all figured out. I thought I'd share it here since I didn't see it spelled out anywhere else on the forum, and it took me a considerable time to get it going. It's probably obvious for anyone with prior experience with evdev and/or python, but I didn't really have either. I'm willing to bet that there are others like me that could use a hand here, so here goes...

Pogoplug Button in ArchLinuxARM for Dummies:

The only way I found to read the input event was with a python package called evdev. Unlike Debian/Ubuntu, there's no python-evdev package in the repositories. That's okay, because we can still get it done in just a few commands thanks to pip, a python package manager.

First step, update your repository databases with:
$this->bbcode_second_pass_code('', 'pacman -Syy')
I find that if I don't always do this before trying to get packages, I get 404 errors for things that have been updated recently. Arch seems up update packages way faster than other distributions, too.

Next, we install python and pip:
$this->bbcode_second_pass_code('', 'pacman -S python-pip')
This installs pip and it's dependencies (python and setuptools).

Since evdev must be built, we need to install the base-devel group next:
$this->bbcode_second_pass_code('', 'pacman -S base-devel')
I just hit [enter] for all, maybe it's not all needed just for this but I went with it anyway.

Alternatively, the three commands above can be issued all together by:
$this->bbcode_second_pass_code('', 'pacman -Sy python-pip base-devel')
Once that's done (may take a few minutes), we're ready to install evdev via pip:
$this->bbcode_second_pass_code('', 'pip install evdev')
It looks like it hangs for a while with no on-screen feedback after issuing the above command, but don't worry it goes through.

Finally, all we need to do is write the appropriate python script to listen to the button. This page was useful for figuring out most of it: http://pythonhosted.org/evdev/ All of the python scripts are saved as .py files and ran like this:
$this->bbcode_second_pass_code('', 'python scriptname.py')
Here's a sample script, 'test.py':
$this->bbcode_second_pass_code('', 'import subprocess
from evdev import InputDevice, categorize, ecodes
dev = InputDevice('/dev/input/event0')
print(dev)
for event in dev.read_loop():
if event.type == ecodes.EV_KEY:
print(categorize(event))')
As you can see, the script listens for events and reacts when one is detected, printing out some info. It reacts separately to 'down' and 'up' events. This means that one press will create two events. If you wish to react simply to a press, you can ignore one or the other. Here's a script 'down.py' that reacts to a down event and launches a script:
$this->bbcode_second_pass_code('', 'import subprocess
from evdev import InputDevice, categorize, ecodes
dev = InputDevice('/dev/input/event0')
print(dev)
for event in dev.read_loop():
# if a downpress
if event.type == ecodes.EV_KEY and event.code == 161 and event.value == 1:
print("Button Down Detected")
subprocess.call("/path/script.sh", shell=True)')
The button on my Pogoplug v4 gives event.code 161. By reacting only to that code, we can be sure to ignore any other buttons. There's only one button on this device, but other devices could have more. For other devices, you can get the specific event code by using the first python script and pressing the button. event.value of 1 means down event, ignoring the up event. If you replace the script path with your own, you can be done here.

After some more testing, I noticed that sometimes when I press the button, I'll get two presses (two sets of up and down). This is from the button wiggling a bit when I first press it. You can add some basic debounce like this 'debounce.py':
$this->bbcode_second_pass_code('', 'import subprocess
from evdev import InputDevice, categorize, ecodes
dev = InputDevice('/dev/input/event0')
print(dev)
for event in dev.read_loop():
# if a downpress
if event.type == ecodes.EV_KEY and event.code == 161 and event.value == 1:
downtime = event.timestamp()
print(downtime)
if event.type == ecodes.EV_KEY and event.code == 161 and event.value == 0:
uptime = event.timestamp()
print(uptime)
difference = uptime - downtime
print(difference)
if difference > 0.2:
print("Button Press Detected")
subprocess.call("/path/script.sh", shell=True)')
Since evdev is nice enough to give us a timestamp for each event, we can use those to detect how long a button press by comparing the up event time to the down event time. The above script measures the time difference and ignores the press if it was less than 0.2 seconds long. You can adjust that time to your liking.

Continuing on, I decided to use the time counter to implement the feature I wanted all along, eject on short press, shutdown on long press. Here's the final 'button.py':
$this->bbcode_second_pass_code('', 'import subprocess
from evdev import InputDevice, categorize, ecodes
dev = InputDevice('/dev/input/event0')
print(dev)
for event in dev.read_loop():
# if a downpress
if event.type == ecodes.EV_KEY and event.code == 161 and event.value == 1:
downtime = event.timestamp()
print(downtime)
if event.type == ecodes.EV_KEY and event.code == 161 and event.value == 0:
uptime = event.timestamp()
print(uptime)
difference = uptime - downtime
print(difference)
if difference > 0.2 and difference < 4:
print("ejecting")
subprocess.call("/path/eject.sh", shell=True)
print("done")
if difference >= 4:
print("shutting down")
subprocess.call("/path/shutdown.sh", shell=True)')
This script ignores presses shorter than 0.2 seconds, launches /path/eject.sh for presses between 0.2 and 4 seconds, and launches /path/shutdown.sh for presses longer than 4 seconds. So to shutdown the device, I can press the button, count to 5, and let go.

My scripts (eject and shutdown) blink the led in different ways to let me know right away that the press worked. Just launch the button.py via your preferred method on startup and you're all set.

So that's it. If you have any questions, feel free to ask. For any corrections, feel free to say so and I'll update the post above.
neonpolaris
 
Posts: 3
Joined: Thu Jul 18, 2013 2:30 am

Re: Utilizing Button on Series 4 Pogoplug

Postby permitivity » Tue Nov 12, 2013 1:41 am

Thanks for putting this out there, and for the detailed instructions. I'm going to give it a try on Thanksgiving break.
permitivity
 
Posts: 141
Joined: Mon Feb 18, 2013 3:08 am

Re: Utilizing Button on Series 4 Pogoplug

Postby neonpolaris » Tue Nov 12, 2013 2:45 am

Thanks!

I saw the input-event-daemon suggestion on your thread, but it didn't make any sense to me at the time. After having gone through all of the stuff in the first post here, I have a better understanding of the system and so input-event-daemon makes more sense to me now. I would say that the daemon is probably a faster way to get the button going. I might even make a separate post outlining its install/usage later. However, the python method gives more control (different reactions per length of time pressed, for example) so I'm going to stick with that for my personal usage.
neonpolaris
 
Posts: 3
Joined: Thu Jul 18, 2013 2:30 am


Return to Marvell Kirkwood

Who is online

Users browsing this forum: No registered users and 7 guests