I decided to make my own home brew security system and thought it would be nice to share my code.
I bought one of these
http://www.desktopaviator.com/Produc...2040/index.htm
It is designed to add buttons to flight simulators but it worked perfect for my alarm system. It was $33
I wrote a small program to use it as follows
alarm.c
compile it withCode:#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h> int main(int argc,char** argv) { int fd,buttons; static char buttons_int[13]; if(argc!=2) { fprintf(stderr,"Usage: alarm <script or program to run that reads the environment variable BUTTONS_INT>\n"); exit(1); } if(fork()) {/*Make a deamon*/ exit(0); } while(1) { fd=open("/dev/alarm",O_RDONLY); read(fd,&buttons,sizeof(int)); close(fd); snprintf(buttons_int,13,"%i",buttons); setenv("BUTTONS_INT",buttons_int,1); system(argv[1]); usleep(10000); } return 0; }
gcc -o alarm alarm.c
second_watch.c
to compileCode:#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main(int argc,char** argv) { if(argc!=2) { fprintf(stderr,"Usage: second_watch <script to run every second>\n"); exit(1); } if(fork()) {/*Make a deamon*/ exit(0); } while(1) { system(argv[1]); sleep(1); } return 0; }
gcc -o second_watch second_watch.c
sudo cp alarm /usr/sbin/alarm
sudp cp second_watch /usr/bin/
install mysql to make using it easy
sudo apt-get install mysql-server mysql-client
create a script to use with it
/root/alarm_script.sh
create a script to start it via crontabCode:#!/bin/bash . /etc/alarm/mysql_root_info.sh . /etc/alarm/mysql_info.sh . /etc/alarm/alarm_definitions.sh . /etc/alarm/functions.sh PADDING="000000000" if [ "${BUTTONS_INT}" = "" ];then BUTTONS_INT=`get_default` fi SINCEEPOCH=`date "+%s"` NANOSECOND=`date "+%N"` post(){ echo -e "insert into alarm (timestamp,nanosecond,state) values (${SINCEEPOCH},${NANOSECOND},${BUTTONS_INT});" | mysql "${database}" -u "${rootusername}" --password="${rootpassword}" sleep 2; activity=`echo "select timestamp,nanosecond,state from alarm order by timestamp desc,nanosecond desc limit 1;"|mysql ${database} -u "${username}" --password="${password}"|grep -v timestamp|awk '{print $1 "." $2 "-" $3}'` TS=`echo ${activity}|cut -d. -f1` NS=`echo ${activity}|cut -d. -f2|cut -d- -f1` ST=`echo ${activity}|cut -d- -f2` NS_SIZE=`echo -e ${NS}|wc -c` let PADDING_NEEDED=10-${NS_SIZE} if [ ${PADDING_NEEDED} -gt 0 ];then NS=`echo ${PADDING} | cut -c ${PADDING_NEEDED}``echo -e "${NS}"` activity=${TS}.${NS}-${ST} fi old_state=`echo "select timestamp,nanosecond,state from state order by timestamp desc,nanosecond desc limit 1;"|mysql ${database} -u "${username}" --password="${password}"|grep -v timestamp|awk '{print $3}'` if [ "${SINCEEPOCH}.${NANOSECOND}-${BUTTONS_INT}" = "${activity}" ] && [ "${BUTTONS_INT}" != "${old_state}" ];then echo -e "insert into state (timestamp,nanosecond,state) values (${SINCEEPOCH},${NANOSECOND},${BUTTONS_INT});" | mysql "${database}" -u "${rootusername}" --password="${rootpassword}" else if [ "${BUTTONS_INT}" != "${old_state}" ];then echo "${SINCEEPOCH}.${NANOSECOND}-${BUTTONS_INT}" != "${activity}" > /tmp/chatter.txt else echo state has not changed > /tmp/chatter.txt fi fi } post &
/root/checkalarm.sh
sudo crontab -eCode:alarmpid=`ps h -C alarm` if [ "$alarmpid" = "" ];then /root/alarm /root/alarm_script.sh fi
create scripts to use it from a regular userCode:* * * * * /root/checkalarm.sh
second_watch_alarm.sh
watcher.shCode:#!/bin/bash . /etc/alarm/alarm_definitions.sh . /etc/alarm/functions.sh . /etc/alarm/mysql_info.sh lastseenfile=${HOME}/.alarm/lastseen.txt cd ${HOME}/.trusted recipients=`ls -1 *@* 2>/dev/null` email_recipients=`echo -e "${recipients}"|grep -v "[0-9]\{9\}@.*"` phone_recipients=`echo -e "${recipients}"|grep "[0-9]\{9\}@.*"` lump_10() { if [ ! -f ${lastseenfile} ];then mkdir -p ${HOME}/.alarm echo 0.0 > ${lastseenfile} fi lastseen=`cat ${lastseenfile}` TS="`echo -e "${lastseen}"|cut -d. -f1`" NS="`echo -e "${lastseen}"|cut -d. -f2`" activity=`echo "select timestamp,nanosecond,state from state where (timestamp > ${TS}) or (timestamp = ${TS} and nanosecond > $NS) order by timestamp desc,nanosecond desc;"|mysql ${database} -u "${username}" --password="${password}"|grep -v timestam p|awk '{print $1 "." $2 "-" $3}'` if [ "`echo -e "${activity}"|wc -c`" = "1" ];then return fi sleep 10; if [ ! -f ${lastseenfile} ];then mkdir -p ${HOME}/.alarm echo 0.0 > ${lastseenfile} fi lastseen=`cat ${lastseenfile}` TS="`echo -e "${lastseen}"|cut -d. -f1`" NS="`echo -e "${lastseen}"|cut -d. -f2`" activity=`echo "select timestamp,nanosecond,state from state where (timestamp > ${TS}) or (timestamp = ${TS} and nanosecond > $NS) order by timestamp desc,nanosecond desc;"|mysql ${database} -u "${username}" --password="${password}"|grep -v timestamp|awk '{print $1 "." $2 "-" $3}'` lastseennow=`echo -e "$activity" | head -n 1|cut -d- -f1` if [ "${lastseennow}" != "" ];then echo ${lastseennow} > ${lastseenfile} fi for item in `echo -e "${activity}"`; do TS="`echo ${item}|cut -d. -f1`" ST="`echo ${item}|cut -d- -f2`" TSH=`date -d @${TS} "+%H:%M:%S"` echo "${TSH} `alarm_status ${ST}`" done } watcher() { sleep 1; data="`lump_10`" if [ "$data" != "" ]; then for recipiant in ${email_recipients}; do if [ -f ${HOME}/.armed/${recipiant} ];then /bin/echo -e "$data" | sudo /usr/sbin/scripts/sendEmail \ -t "${recipiant}" \ -u "alarm status `date "+%F"`" \ 1> /dev/null 2>/dev/null fi done for recipiant in ${phone_recipients}; do if [ -f ${HOME}/.armed/${recipiant} ];then /bin/echo -e "$data" | sudo /usr/sbin/scripts/sendEmail \ -t "${recipiant}" \ 1> /dev/null 2>/dev/null fi done fi } watcher
Code:#!/bin/bash watch(){ running=`ps h -f -C second_watch|grep ^\`whoami\`\ ` if [ "${running}" = "" ]; then second_watch ${HOME}/second_watch_alarm.sh fi } watch 2>/dev/null >/dev/null
make sure it gets started using crontab
crontab -e
create the common filesCode:* * * * * ${HOME}/watcher.sh
/etc/alarm/alarm_definitions.sh
chmod 0755 /etc/alarm/alarm_definitions.shCode:# the item names are the name you want it to send you # the stat names are the default state of each # for normally open switches(most alarm reed switches) # the default state is 0 # for normally closed switches ( I found a couple of these for my windows that I wired in parallel) # the default state is 1 # also disconnected items default states are 0 STATION_ITEM[1]="Front Door"; STATION_STAT[1]="0"; STATION_ITEM[2]="Bedroom Window"; STATION_STAT[2]="0"; STATION_ITEM[3]="Living Room Window"; STATION_STAT[3]="1"; STATION_ITEM[4]="Station 4"; STATION_STAT[4]="1"; STATION_ITEM[5]="Station 5"; STATION_STAT[5]="1"; STATION_ITEM[6]="Station 6"; STATION_STAT[6]="1"; STATION_ITEM[7]="Station 7"; STATION_STAT[7]="1"; STATION_ITEM[8]="Station 8"; STATION_STAT[8]="1"; STATION_ITEM[9]="Station 9"; STATION_STAT[9]="1"; STATION_ITEM[10]="Station 10"; STATION_STAT[10]="1"; STATION_ITEM[11]="Station 11"; STATION_STAT[11]="1"; STATION_ITEM[12]="Station 12"; STATION_STAT[12]="1"; STATION_ITEM[13]="Station 13"; STATION_STAT[13]="1"; STATION_ITEM[14]="Station 14"; STATION_STAT[14]="1"; STATION_ITEM[15]="Station 15"; STATION_STAT[15]="1"; STATION_ITEM[16]="Station 16"; STATION_STAT[16]="1"; STATION_ITEM[17]="Station 17"; STATION_STAT[17]="1"; STATION_ITEM[18]="Station 18"; STATION_STAT[18]="1"; STATION_ITEM[19]="Station 19"; STATION_STAT[19]="1"; STATION_ITEM[20]="Station 20"; STATION_STAT[20]="1";
/etc/alarm/mysql_info.sh
chmod 0755 /etc/alarm/mysql_info.shCode:username=alarmviewer password=alarmviewerpassword database=alarm
/etc/alarm/mysql_root_info.sh
chmod 0700 /etc/alarm/mysql_root_info.shCode:rootusername=root rootpassword=password4mysql_root_user
/etc/alarm/functions.sh
chmod 0755 /etc/alarm/functions.shCode:get_default(){ full=00000000000000000000000000000000 bin="" for counter in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do if [ ${STATION_STAT[${counter}]} = 0 ];then bin="1${bin}" else bin="0${bin}" fi done let len=33-`echo $bin | wc -c` echo 10o2i${pad}${bin}p | dc } int2bin() { full=00000000000000000000000000000000 bin=`echo 2o10i${1}p | dc 2>/dev/null` let len=33-`echo $bin | wc -c` pad=`echo ${full}|cut -c 1-${len}` echo ${pad}${bin} } alarm_status() { OPENED="" BUTTONS=`int2bin $1` for counter in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do let otherend=33-counter; BUTTON=`echo $BUTTONS|cut -c $otherend`; if [ "$BUTTON" = "${STATION_STAT[$counter]}" ];then OPENED="${OPENED}${STATION_ITEM[$counter]},"; fi done if [ "${OPENED}" = "" ];then echo "all closed" else echo -e "${OPENED}" | sed s/",$"// fi }
create the udev using this script
create the database using this scriptCode:serial=`sudo lsusb -d 6017:3522 -v|grep iSerial|awk '{print $3}'` echo KERNEL==\"hidraw\*\", ATTRS{manufacturer}==\"Desktop Aviator\", ATTRS{product}==\"Digital Switch 2040\" , ATTRS{serial}==\"$serial\" , SYMLINK+=\"alarm\" > 50-alarm.rules sudo cp 50-alarm.rules /etc/udev/rules.d/ rm 50-alarm.rules sudo service udev restart
create sendEmail scriptCode:. /etc/alarm/mysql_info.sh . /etc/alarm/mysql_root_info.sh echo "create database ${database};" | mysql -u ${rootusername} --password="${rootpassword}" echo "create table alarm (timestamp bigint,nanosecond int,state int);" |mysql ${database} -u ${rootusername} --password="${rootpassword}" echo "create table state (timestamp bigint,nanosecond int,state int);" |mysql ${database} -u ${rootusername} --password="${rootpassword}" echo "create user '${username}'@'localhost' IDENTIFIED BY '${password}';"|mysql -u ${rootusername} --password="${rootpassword}" echo "grant select on ${database}.* to '${username}'@'localhost' identified by '${password}';"|mysql -u ${rootusername} --password="${rootpassword}"
/usr/sbin/scripts/sendEmail
chmod 0700 /usr/sbin/scriptsCode:#!/bin/bash username="gmail_account_for_computer" password="gmail_password" sendEmail -f "${username}@gmail.com" \ -s smtp.gmail.com:587 \ -o tls=yes \ -xu "${username}" \ -xp "${password}" \ $*
add users that can send email to sudoers
echo ALL ALL=NOPASSWD:/usr/sbin/scripts/sendEmail >> /etc/sudoers
================================================== ==============
I saw an arduino for $25 here http://shop.amcnano.com/Arduino-Duemilanove-SKU2001.htm
there are not as many inputs but plenty for most home security systems. When I get a hold of one I will try replacing my alarm system. There shouldn't be many modifications needed to implement the arduino



Adv Reply





Bookmarks