Waking your monitor with motion on Linux

Here is some nerd-sorcery that will probably only interest me. If you aren’t running a Linux desktop or there is something good on QVC right now, go ahead and stop reading.

A recent Hak5 episode talked about motion, a program that monitors the video signal from cameras and can detect movement, generally for security purposes. The context in the show was having a locked screen record people moving in front of your laptop when you head to the lavatory in Starbucks.

While I don’t have a need for that type of thing (my digitalia generally goes to the lavatory with me), I thought of something else I could do with motion. Like most desktop users, my screensaver (blank) is set to go off after a while, and to turn the monitors back on I waggle the mouse. Well…what if you can just move in front of the web cam to wake up the monitors? After all, waggling the mouse is physical labor, which I am opposed to for ethical/philosophical reasons.

I think I have it worked out. We’ll need to install motion and copy motion.conf to our home folder so we can screw with it. I’m on Ubuntu, but aside from apt the basic steps should be the same on any distro (YMMV).

sudo apt-get install motion
mkdir ~/.motion
cd ~/.motion  
sudo cp /etc/motion/motion.conf .
sudo chown <your user name> motion.conf

 

Now for customizing motion.conf:

# You'll find these lines in various places in motion.conf

# set motion to run in daemon mode
daemon on

# comment out the pid capture file, as we don't need it
; process_id_file xxxx

# disable the capturing of images, as we only care about motion detection
output_normal off

# turn off the web server, we don't need that either
webcam_port 0
control_port 0

# when motion is detected, turn off the screensaver
on_motion_detected 'qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.SetActive false'

 

I found the defaults for the rest of motion.conf to be fine. The dbus line to turn off the screensaver is the freedesktop standard which works for KDE, but for Gnome/Unity you might have to change it to:

on_motion_detected 'qdbus org.gnome.ScreenSaver /ScreenSaver org.gnome.ScreenSaver.SetActive false'

That dbus command basically says “turn off your screensaver” and fires when motion is detected.

Next we need to monitor the screensaver on/off dbus event so we can fire up motion when the screensaver is active and kill motion when the screensaver is off (so we can free up the webcam for regular use). Here’s a Python way to do it:

#!/usr/bin/env python
# coding: utf-8

import dbus
import dbus.glib
import os

def screensaver_changed(state):
    """This method is called when the screensaver starts/stops """
    try:
        if state == 1:
            os.system("motion -c /home/<your user name>/.motion/motion.conf")
        else:
            os.system("killall motion")
    except:
        print "Kaboom! You suck."

def main():
    import gobject
    gobject.MainLoop().run()

session_bus = dbus.SessionBus()
session_bus.add_signal_receiver(screensaver_changed, 'ActiveChanged', 'org.freedesktop.ScreenSaver')
main()

 

Basically we’re assigning a listener to the to the screensaver activation change dbus event. If the screensaver is activated, motion fires up, and when it is deactivated (motion picks up movement or you waggle your mouse), motion is killed. Again, you might need to sub out org.gnome.ScreenSaver for org.freedesktop.ScreenSaver if you’re on Gnome/Unity.

Next, have your python script start when you log in. In KDE you can do that in System Settings->Startup and Shutdown, and there will be a similar thing in Gnome someplace. Unity probably has a lens for it (snark!).

To test it, walk out of your web cam’s field of vision and dump this in a command line (subbing for Gnome/Unity again if necessary):

qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.SetActive true

 

Your screen saver should activate and the light on your web cam should come up. Walk in front of the web cam and give it the finger, and your monitors should light right up.