Difference between revisions of "Script for theft alarm using HDAPS"

From ThinkWiki
Jump to: navigation, search
(license)
(Support for negative readouts, increased threshold)
Line 24: Line 24:
 
# This script uses the HDAPS accelerometer found on recent ThinkPad models
 
# This script uses the HDAPS accelerometer found on recent ThinkPad models
 
# to emit an audio alarm when the laptop is tilted. In sufficiently
 
# to emit an audio alarm when the laptop is tilted. In sufficiently
# populated environments, it can be used as a laptop theft deterrent.
+
# populated environments, it can be used as a laptop theft deterrant.
 
#
 
#
 
# This file is placed in the public domain and may be freely distributed.
 
# This file is placed in the public domain and may be freely distributed.
Line 46: Line 46:
 
# Other tweakables
 
# Other tweakables
  
my $thresh = 0.15;  # tilt threshold (increase value to decrease sensitivity)
+
my $thresh = 0.20;  # tilt threshold (increase value to decrease sensitivity)
 
my $interval = 0.1;  # sampling interval in seconds
 
my $interval = 0.1;  # sampling interval in seconds
 
my $depth = 10;      # number of recent samples to analyze
 
my $depth = 10;      # number of recent samples to analyze
Line 58: Line 58:
 
     open(POS,"<",$pos_file) or die "Can't open HDAPS file $pos_file: $!\n";
 
     open(POS,"<",$pos_file) or die "Can't open HDAPS file $pos_file: $!\n";
 
     $_=<POS>;
 
     $_=<POS>;
     m/^\((\d+),(\d+)\)$/ or die "Can't parse $pos_file content\n";
+
     m/^\((-?\d+),(-?\d+)\)$/ or die "Can't parse $pos_file content\n";
 
     return ($1,$2);
 
     return ($1,$2);
 
}
 
}

Revision as of 21:41, 12 November 2005

General

Recent ThinkPad models include a built-in two-axis accelerometer, as part of the HDAPS feature. This accelerometer can be put to another use: as a laptop theft deterrent. The following script detects when the laptop is moved and emits a loud audio alarm. Against a casual laptop-snatcher in a populated environment (e.g., typical office space) this can be an effective deterrent.

Note that the alarm cannot work when the laptop is suspended or powered off. You will buy an external motion detector alarm for those cases.

Prerequisites

  • hdaps module loaded (comes with kernel 2.6.14 and later)
  • sox (SOund eXchange) sound utility
  • aumix command line mixer

The latter two should be included with your distribution, but check if they are installed.

The script

This Perl script periodically samples the tilt data reported by the accelerometer, computes the variance over recent samples, and triggers the alarm when the variance exceeds a given threshold.

On an HDAPS-equipped laptop running a modern Linux installation, the script should work as is. Just run it and see (or rather, hear) what happens when you tilt your laptop. The volume and alarm sound can be adjusted at the top of the script. On a ThinkPad T43, the synthetic siren at a volume of 100 is quite ear-splitting.

#!/usr/bin/perl
#
# This script uses the HDAPS accelerometer found on recent ThinkPad models
# to emit an audio alarm when the laptop is tilted. In sufficiently
# populated environments, it can be used as a laptop theft deterrant.
#
# This file is placed in the public domain and may be freely distributed.

use strict;
use warnings;

##############################
# Siren volume and content

# Audio volume (0..100)
my $volume = 70;

# Synthesize a syren for 1.0 seconds:
my $play_cmd = "sox -t nul /dev/null -t ossdsp /dev/dsp synth 1.0 sine 2000-4000 sine 4000-2000";

# Play a file:
# my $play_cmd = "play keep_your_hands_off_me.wav";

##############################
# Other tweakables

my $thresh = 0.20;   # tilt threshold (increase value to decrease sensitivity)
my $interval = 0.1;  # sampling interval in seconds
my $depth = 10;      # number of recent samples to analyze
my $pos_file='/sys/devices/platform/hdaps/position';
my $verbose = 1;

##############################
# Code

sub get_pos {
    open(POS,"<",$pos_file) or die "Can't open HDAPS file $pos_file: $!\n";
    $_=<POS>;
    m/^\((-?\d+),(-?\d+)\)$/ or die "Can't parse $pos_file content\n";
    return ($1,$2);
}

sub stddev {
    my $sum=0;
    my $sumsq=0;
    my $n=$#_+1;
    for my $v (@_) {
	$sum += $v;
	$sumsq += $v*$v;
    }
    return sqrt($n*$sumsq - $sum*$sum)/($n*($n-1));
}

my (@XHIST, @YHIST);
my ($x,$y) = get_pos;
for (1..$depth) {
    push(@XHIST,$x);
    push(@YHIST,$y);
}
my $alarm_file; # flags ongoing alarm (and stores saved mixer settings)

while (1) {
    my ($x,$y) = get_pos;
    shift(@XHIST); push(@XHIST,$x);
    shift(@YHIST); push(@YHIST,$y);
    my $xdev = stddev(@XHIST);
    my $ydev = stddev(@YHIST);

    # Print variance and history
    print "X: v=$xdev (".join(',',@XHIST).")  Y: v=$ydev (".join(",",@YHIST).")\n" if $verbose>1;

    my $tilted = $xdev>$thresh || $ydev>$thresh;

    if ($tilted && !(defined($alarm_file) && -f $alarm_file)) {
	print "ALARM\n" if $verbose>0;
	$alarm_file = `mktemp /tmp/hdaps-tilt.XXXXXXXX` or die "mktemp: $?";
	chomp($alarm_file);
	system('/bin/bash', '-c', <<"EOF")==0 or die "Failed: $?";
( trap \"aumix -L -f $alarm_file > /dev/null; rm -f $alarm_file" EXIT HUP QUIT TERM
  aumix -S -f $alarm_file &&
  aumix -v $volume -w 100 &&
  $play_cmd) &
EOF
    }

    select(undef, undef, undef, $interval); # sleep
}

The author of the script disclaims all warranty for this script, and releases it to the public domain.

To do

Features awaiting contribution:

  • Start out quietly, and increase siren duration and volume if movement persists. Reset after a period of no movement.
  • Automatically start and stop with screensaver (especially nifty when integrated with the fingerprint reader). Can probably be done similarly to lightwatch.pl.
  • Report theft via network (if you get a chance to).