From 5b6963ade4d9c67215a332ec80cf4c487de97684 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 1 Oct 2014 16:31:55 +0200 Subject: [PATCH] Initial commit --- 433send/433send.c | 146 ++++++++++++++++++++++++++ doc/FHEMinstall.txt | 16 +++ scripts/.closetrigger.sh.swp | Bin 0 -> 12288 bytes scripts/close.sh | 4 + scripts/closetrigger.sh | 5 + scripts/dhcp2presency.sh | 18 ++++ scripts/lockbutton.sh | 38 +++++++ scripts/lockbutton.sh.d/01updatestate | 6 ++ scripts/lockbutton.sh.d/intrusion | 8 ++ scripts/lockbutton.sh.d/lights | 33 ++++++ scripts/open.sh | 4 + scripts/rsyslog-mikrotik.sh | 24 +++++ scripts/semaphore.sh | 25 +++++ scripts/upd_arps.sh | 46 ++++++++ scripts/upd_status.sh | 72 +++++++++++++ scripts/upd_status.sh.d/lights | 33 ++++++ systemfiles/crontab-l | 27 +++++ systemfiles/inittab | 75 +++++++++++++ systemfiles/rsyslog.conf | 126 ++++++++++++++++++++++ systemfiles/sudoers.d.closetrigger | 1 + webserver/cgi-bin/parse_query | 54 ++++++++++ webserver/cgi-bin/pidor.sh | 39 +++++++ webserver/htdocs/favicon.ico | Bin 0 -> 1406 bytes webserver/htdocs/index.html | 31 ++++++ 24 files changed, 831 insertions(+) create mode 100644 433send/433send.c create mode 100644 doc/FHEMinstall.txt create mode 100644 scripts/.closetrigger.sh.swp create mode 100755 scripts/close.sh create mode 100755 scripts/closetrigger.sh create mode 100755 scripts/dhcp2presency.sh create mode 100755 scripts/lockbutton.sh create mode 100755 scripts/lockbutton.sh.d/01updatestate create mode 100755 scripts/lockbutton.sh.d/intrusion create mode 100755 scripts/lockbutton.sh.d/lights create mode 100755 scripts/open.sh create mode 100755 scripts/rsyslog-mikrotik.sh create mode 100644 scripts/semaphore.sh create mode 100755 scripts/upd_arps.sh create mode 100755 scripts/upd_status.sh create mode 100755 scripts/upd_status.sh.d/lights create mode 100644 systemfiles/crontab-l create mode 100644 systemfiles/inittab create mode 100644 systemfiles/rsyslog.conf create mode 100644 systemfiles/sudoers.d.closetrigger create mode 100644 webserver/cgi-bin/parse_query create mode 100755 webserver/cgi-bin/pidor.sh create mode 100644 webserver/htdocs/favicon.ico create mode 100644 webserver/htdocs/index.html diff --git a/433send/433send.c b/433send/433send.c new file mode 100644 index 0000000..1e7eb4b --- /dev/null +++ b/433send/433send.c @@ -0,0 +1,146 @@ +/* + Usage: ./send + SystemCodeType is 1 for default and 2 for switches with 10 Bits 123456ABCD + Command is 0 for OFF and 1 for ON + */ + +#include "RCSwitch.h" +#include +#include +#include + +int main(int argc, char *argv[]) { + + /* + output PIN is hardcoded for testing purposes + see https://projects.drogon.net/raspberry-pi/wiringpi/pins/ + for pin mapping of the raspberry pi GPIO connector + */ + int PIN = 0; // GPIO-PIN 17 + int systemCodeType = atoi(argv[1]); + int systemCode = atoi(argv[2]); + int unitCode = atoi(argv[3]); + int command = atoi(argv[4]); + char pSystemCode[14]; + + if (wiringPiSetup () == -1) return 1; + printf("sending systemCodeType[%i] systemCode[%i] unitCode[%i] command[%i] ...\n", systemCodeType, systemCode, unitCode, command); + RCSwitch mySwitch = RCSwitch(); + printf("defining transmit PIN[%i] ... ",PIN); + mySwitch.enableTransmit(PIN); + printf("success\n"); + printf("computing system Code Type ...\n"); + switch(systemCodeType) + { + case 1: + { + printf("Switching \"default\" system[%i] unit[%i] ... ", systemCode, unitCode); + switch(command) + { + case 0: + { + printf("off\n"); + mySwitch.switchOff(systemCode, unitCode); + break; + } + case 1: + { + printf("on\n"); + mySwitch.switchOn(systemCode, unitCode); + break; + } + default: + { + printf("command[%i] is unsupported\n", command); + return -1; + } + } + break; + } + case 2: + { + printf("computing systemcode for Intertechno Type B house[%i] unit[%i] ... ",systemCode, unitCode); + switch(systemCode) + { + // house/family code A=1 - P=16 + case 1: { printf("1/A ... "); strcpy(pSystemCode,"0000"); break; } + case 2: { printf("2/B ... "); strcpy(pSystemCode,"F000"); break; } + case 3: { printf("3/C ... "); strcpy(pSystemCode,"0F00"); break; } + case 4: { printf("4/D ... "); strcpy(pSystemCode,"FF00"); break; } + case 5: { printf("5/E ... "); strcpy(pSystemCode,"00F0"); break; } + case 6: { printf("6/F ... "); strcpy(pSystemCode,"F0F0"); break; } + case 7: { printf("7/G ... "); strcpy(pSystemCode,"0FF0"); break; } + case 8: { printf("8/H ... "); strcpy(pSystemCode,"FFF0"); break; } + case 9: { printf("9/I ... "); strcpy(pSystemCode,"000F"); break; } + case 10: { printf("10/J ... "); strcpy(pSystemCode,"F00F"); break; } + case 11: { printf("11/K ... "); strcpy(pSystemCode,"0F0F"); break; } + case 12: { printf("12/L ... "); strcpy(pSystemCode,"FF0F"); break; } + case 13: { printf("13/M ... "); strcpy(pSystemCode,"00FF"); break; } + case 14: { printf("14/N ... "); strcpy(pSystemCode,"F0FF"); break; } + case 15: { printf("15/O ... "); strcpy(pSystemCode,"0FFF"); break; } + case 16: { printf("16/P ... "); strcpy(pSystemCode,"FFFF"); break; } + default: + { + printf("systemCode[%s] is unsupported\n", systemCode); + return -1; + } + } + printf("got systemCode\n"); + switch(unitCode) + { + // unit/group code 01-16 + case 1: { printf("1 ... "); strcat(pSystemCode,"0000"); break; } + case 2: { printf("2 ... "); strcat(pSystemCode,"F000"); break; } + case 3: { printf("3 ... "); strcat(pSystemCode,"0F00"); break; } + case 4: { printf("4 ... "); strcat(pSystemCode,"FF00"); break; } + case 5: { printf("5 ... "); strcat(pSystemCode,"00F0"); break; } + case 6: { printf("6 ... "); strcat(pSystemCode,"F0F0"); break; } + case 7: { printf("7 ... "); strcat(pSystemCode,"0FF0"); break; } + case 8: { printf("8 ... "); strcat(pSystemCode,"FFF0"); break; } + case 9: { printf("9 ... "); strcat(pSystemCode,"000F"); break; } + case 10: { printf("10 ... "); strcat(pSystemCode,"F00F"); break; } + case 11: { printf("11 ... "); strcat(pSystemCode,"0F0F"); break; } + case 12: { printf("12 ... "); strcat(pSystemCode,"FF0F"); break; } + case 13: { printf("13 ... "); strcat(pSystemCode,"00FF"); break; } + case 14: { printf("14 ... "); strcat(pSystemCode,"F0FF"); break; } + case 15: { printf("15 ... "); strcat(pSystemCode,"0FFF"); break; } + case 16: { printf("16 ... "); strcat(pSystemCode,"FFFF"); break; } + default: + { + printf("unitCode[%i] is unsupported\n", unitCode); + return -1; + } + } + strcat(pSystemCode,"0F"); // mandatory bits + switch(command) + { + case 0: + { + strcat(pSystemCode,"F0"); + mySwitch.sendTriState(pSystemCode); + printf("sent TriState signal: pSystemCode[%s]\n",pSystemCode); + break; + } + case 1: + { + strcat(pSystemCode,"FF"); + mySwitch.sendTriState(pSystemCode); + printf("sent TriState signal: pSystemCode[%s]\n",pSystemCode); + break; + } + default: + { + printf("command[%i] is unsupported\n", command); + return -1; + } + } + break; + } + default: + { + printf("command sequence unknown, aborting!\n"); + return -1; + } + } + return 0; + } diff --git a/doc/FHEMinstall.txt b/doc/FHEMinstall.txt new file mode 100644 index 0000000..93a95a7 --- /dev/null +++ b/doc/FHEMinstall.txt @@ -0,0 +1,16 @@ +http://www.fhemwiki.de/wiki/Raspberry_Pi + +sudo apt-get install perl libdevice-serialport-perl +sudo apt-get install libio-socket-ssl-perl libwww-perl +wget http://fhem.de/fhem-5.5.deb +dpkg -i fhem-5.5.deb +apt-get install -f + +go to interface: +http://pidor:8083/fhem + +how to make a button: +https://groups.google.com/forum/#!topic/fhem-users/1eQJ_Q4Evo4 +define MyBtn FS20 9999 99 +attr MyBtn dummy +define MyNotify notify MyBtn "/local/bin/mypgm %" diff --git a/scripts/.closetrigger.sh.swp b/scripts/.closetrigger.sh.swp new file mode 100644 index 0000000000000000000000000000000000000000..b694aef11c085987dd0352221a5f61c42c33a90a GIT binary patch literal 12288 zcmeI&J5Iwu5C-505+x781tv}$5uwCMD4>AQLXnDxM1|JgB{l?aw7Z4|aRp8R9WBS8 zc3x zkuLuu=a%F8N-V6(#kt~or^!M}CHLSXE(TMx+m%Va_!YFw2!o;8G;^LmFQgB tfLFt#@H~{^PB;knn)GR(z8mARe8?YKi$!uaG`h$o)v8gP<&g(U=@qncg9rcs literal 0 HcmV?d00001 diff --git a/scripts/close.sh b/scripts/close.sh new file mode 100755 index 0000000..ca7495d --- /dev/null +++ b/scripts/close.sh @@ -0,0 +1,4 @@ +#!/bin/bash +/usr/local/bin/gpio mode 7 out +/usr/local/bin/gpio write 7 1 + diff --git a/scripts/closetrigger.sh b/scripts/closetrigger.sh new file mode 100755 index 0000000..05fa4f0 --- /dev/null +++ b/scripts/closetrigger.sh @@ -0,0 +1,5 @@ +#!/bin/bash +logger -t $(basename $0) adding upd_status.sh to at +#echo "$(dirname "$0")/upd_status.sh" | at -t $(date --date "2 seconds" +%Y%m%d%H%M%S) +"$(dirname "$0")/upd_status.sh" /dev/null 2>&1 & +logger -t $(basename $0) added $(dirname "$0")/upd_status.sh as at job with ret=$? diff --git a/scripts/dhcp2presency.sh b/scripts/dhcp2presency.sh new file mode 100755 index 0000000..4db80c8 --- /dev/null +++ b/scripts/dhcp2presency.sh @@ -0,0 +1,18 @@ +#!/bin/bash +n=0 +for i in $(ls /run/dhcp-leases/) +do + if ping -qc 1 -W 1 "$i" >/dev/null + then + touch "/run/dhcp-leases/$ip" + n=$((n+1)) + else + logger -t $(basename $0) "dhcp $i is not pingable anymore" + if [ $(stat -c %Y /run/dhcp-leases/$i) -lt $(date --date "1 hour ago" +%s) ] + then + logger -t $(basename $0) "removing dhcp $i after one hour" + rm /run/dhcp-leases/$i + fi + fi +done +echo "$n" > /run/presency diff --git a/scripts/lockbutton.sh b/scripts/lockbutton.sh new file mode 100755 index 0000000..b87aa19 --- /dev/null +++ b/scripts/lockbutton.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# add this to /etc/inittab +# P1:2345:respawn:/root/lockbutton.sh +PATH=/bin:/usr/bin:/usr/local/bin +logger -t $(basename $0) "starting..." +gpio -g mode 11 in # this is usually SCLK as ALT0 + # transform into GPIO11 as IN +gpio -g mode 11 up # set internal pullup +while true +do + logger -t $(basename $0) "change detected (was $state)" + if [ $(gpio -g read 11) -eq 1 ] && [ "$state" != "pushed" ] + then + for plugin in "$0".d/* + do + "$plugin" pushed + logger -t $(basename $0) "called '$plugin pushed' with ret=$?" + done + state="pushed" + else + if [ "$state" != "released" ] + then + for plugin in "$0".d/* + do + "$plugin" released + logger -t $(basename $0) "called '$plugin released' with ret=$?" + done + state="released" + fi + fi + if ( [ $(gpio -g read 11) -eq 1 ] && [ "$state" = "released" ] ) || + ( [ $(gpio -g read 11) -eq 0 ] && [ "$state" = "pushed" ] ) + then + logger -t $(basename $0) "inconsistent state $state, aborting" + break + fi + gpio -g wfi 11 both # wait for change (uses no cpu, but interrupt) +done diff --git a/scripts/lockbutton.sh.d/01updatestate b/scripts/lockbutton.sh.d/01updatestate new file mode 100755 index 0000000..96b3e5a --- /dev/null +++ b/scripts/lockbutton.sh.d/01updatestate @@ -0,0 +1,6 @@ +#!/bin/bash +if [ "$1" = "pushed" ] || [ "$1" = "released" ] +then + logger -t $(basename $0) "writing $1 to doorlockbutton" + echo "$1" > /run/doorlockbutton +fi diff --git a/scripts/lockbutton.sh.d/intrusion b/scripts/lockbutton.sh.d/intrusion new file mode 100755 index 0000000..f0d2e93 --- /dev/null +++ b/scripts/lockbutton.sh.d/intrusion @@ -0,0 +1,8 @@ +#!/bin/bash +if [ "$1" = "released" ] && # if switch was released (the door opened, or someone is playing with the switch) + [ "$(cat /run/spacestatus)" = "closed" ] && # the status was closed + [ $(stat -c "%Y" /run/spacestatus) -lt $(date --date "1 hour ago" +%s) ] # since at least one hour +then + echo "intrusion detected: space was closed since some time and locked, but now is still closed but unlocked" | wall + logger -t $(basename $0) "INTRUSION ALARM. door was opened while status is closed" +fi diff --git a/scripts/lockbutton.sh.d/lights b/scripts/lockbutton.sh.d/lights new file mode 100755 index 0000000..eb264ba --- /dev/null +++ b/scripts/lockbutton.sh.d/lights @@ -0,0 +1,33 @@ +#!/bin/bash +# called by upd_status and lockbutton, so that whatever +# sequence is used, the lights go off +if ( [ "$1" = "pushed" ] || [ "$1" = "closed" ] ) && + [ "$(cat /run/spacestatus)" = "closed" ] && + [ "$(cat /run/doorlockbutton)" = "pushed" ] && + ( [ "$(stat -c %Y /run/spacestatus)" -gt "$(date --date "5 minutes ago" +%s)" ] || + [ "$(stat -c %Y /run/doorlockbutton)" -gt "$(date --date "5 minutes ago" +%s)" ] ) +then + logger -t $(basename $0) "switching all lights off" + for i in {1..16} + do + /usr/local/bin/433send 2 1A $i 0 #off + done + logger -t $(basename $0) "all lights should be off now" +fi +if [ "$1" = "released" ] && # the door has been opened + [ "$(cat /run/spacestatus)" = "open" ] && # status is open + [ "$(stat -c %Y /run/spacestatus)" -gt "$(date --date "50 minutes ago" +%s)" ] && # since less than 5 minutes + ( [ "$(date +%H)" -gt 18 ] || [ "$(date +%H)" -lt 8 ] ) +then + logger -t $(basename $0) "switching some lights on" + /usr/local/bin/433send 2 1A 1 1 #on +fi + +# type (2=10bit) +# | house 1-16 (always 1 in our case) +# | |group A-P (the dial thingie) +# | || unit (1-16) (the button, usually 1-4) +# | || | on/off +# | || | | +#/usr/local/bin/433send 2 1A 1 1 #on +#/usr/local/bin/433send 2 1A 1 0 #off diff --git a/scripts/open.sh b/scripts/open.sh new file mode 100755 index 0000000..336061c --- /dev/null +++ b/scripts/open.sh @@ -0,0 +1,4 @@ +#!/bin/bash +/usr/local/bin/gpio mode 7 out +/usr/local/bin/gpio write 7 0 + diff --git a/scripts/rsyslog-mikrotik.sh b/scripts/rsyslog-mikrotik.sh new file mode 100755 index 0000000..d8371cf --- /dev/null +++ b/scripts/rsyslog-mikrotik.sh @@ -0,0 +1,24 @@ +#!/bin/bash +exec 2>/tmp/out.log +set -x +PATH=/bin:/usr/bin +mkdir /run/dhcp-leases 2>/dev/null +while read l +do + ip="$(echo "$l" | + fgrep Address-Request| + fgrep "10.2.113" | + sed 's/^.* //')" + if [ "$ip" != "" ] + then + t=$(date +%s) + if [ -f "/run/dhcp-leases/$ip" ] + then + touch "/run/dhcp-leases/$ip" + else + logget -t $(basename $0) "new dhcp for $ip" + echo "$t" > "/run/dhcp-leases/$ip" + fi + echo "========== $t $ip" >> /tmp/out.log + fi +done diff --git a/scripts/semaphore.sh b/scripts/semaphore.sh new file mode 100644 index 0000000..7dbf89e --- /dev/null +++ b/scripts/semaphore.sh @@ -0,0 +1,25 @@ +#!/bin/bash +LockDir="/run/$(basename "$0").run" +P() { + while ! mkdir "$LockDir" 2>/dev/null + do + echo "cannot lock $LockDir, waiting" + LockDirStamp=$(stat -c %Y "$LockDir") + if [ "$LockDirStamp" != "" ] && [ "$LockDirStamp" -lt $(date --date "15 seconds ago" +%s) ] + then + echo lock is old, deleting + rmdir "$LockDir" + fi + sleep 1 + done + echo got lock +} +V() { + echo "releasing $LockDir" + rmdir "$LockDir" +} +P +echo "running protected code" +sleep 10 +V +echo "end protected code" diff --git a/scripts/upd_arps.sh b/scripts/upd_arps.sh new file mode 100755 index 0000000..4f6da0c --- /dev/null +++ b/scripts/upd_arps.sh @@ -0,0 +1,46 @@ +#!/bin/bash +if [ "$(awk -W version 2>/dev/null|awk '{print $1;exit}')" != "GNU" ] +then + echo "do 'apt-get install gawk' for this to work" + exit 1 +fi +export PATH=/bin:/usr/bin:/usr/sbin +arps="$( (cat /root/arps.txt # get old list + arp -an| # get current values + awk -F'[().: ]' '/10.2.113/ && $6 > 100 && !/incomplete/'| # only our subnet and only addresses above 100 + awk -v now=$(date +%s) '{print $4 " " now}') | # write them with current timestamp + awk '{arps[$1]=arps[$1]" "$2} + END { + for(i in arps) { + split(arps[i],a) + asort(a) + print i " " a[1] " " a[length(a)] # write out mac, oldest seen and newest seen + } + }'| + sort -k2 | # sort by timestamp, newest first + sort -u -k1,1 )" # remove duplicate arp (keeps the most recent entry by timestamp) +# echo "$arps" | sort -n -k2| awk -v onehour=$(date --date="1 hour ago" +%s) '{print $0 " " $3-onehour};c==1 && (($3 - $2)<3600*24) && ($3 > onehour) {n+=1;print "->"$0} +Current="$( +(date --date="1 hour ago" +"CURRENT: %s" + echo "$arps" )| +sort -n -k2| +awk 'c==1 && (($3 - $2)<3600*10) && ($3 > c) {n+=1} + /CURRENT:/{c=1} + END{print n}' +)" +Current="$( + echo "$arps" | + sort -n -k2| + awk -v onehour=$(date --date="1 hour ago" +%s) ' + $3 > onehour {print $0 " " $3-$2} + ' | + awk '$3-$2 < 24*3600' | + wc -l +)" +echo "$arps" > /root/arps.txt +oldCurrent="$(cat /run/presency)" +echo "$Current" > /run/presency +if [ "$Current" != "$oldCurrent" ] +then + logger -t $(basename $0) "there are now $Current people in Level2" +fi diff --git a/scripts/upd_status.sh b/scripts/upd_status.sh new file mode 100755 index 0000000..dc43bc5 --- /dev/null +++ b/scripts/upd_status.sh @@ -0,0 +1,72 @@ +#!/bin/bash +IGNORE_DOORLOCKBUTTON="no" +LockDir="/run/$(basename "$0").run" +P() { + while ! mkdir "$LockDir" 2>/dev/null + do + LockDirStamp=$(stat -c %Y "$LockDir" 2>/dev/null) + if [ "$LockDirStamp" != "" ] && [ "$LockDirStamp" -lt $(date --date "90 seconds ago" +%s) ] + then + rmdir "$LockDir" + logger -t $(basename $0) "deleting stale semaphore dir $LockDir" + fi + sleep 1 + done +} +V() { + rmdir "$LockDir" 2>/dev/null + if [ $? -ne 0 ] + then + logger -t $(basename $0) "semaphore dir $LockDir disappeared while running" + fi +} +P +if [ ! -f /run/spacestatus ] # self initilizing on new install or boot +then + if [ -f /root/var/spacestatus ] + then # we could also get it from spaceapi, so that could should go here: + logger -t $(basename $0) "boot detected, restoring spacestatus to $(cat /root/var/spacestatus)" + cp -p /root/var/spacestatus /run/spacestatus # restore from backup + else + logger -t $(basename $0) "never run before (new install?) setting spacestatus to closed" + echo "closed" > /run/spacestatus + fi + chown www-data /run/spacestatus +fi + +status=$(cat /run/spacestatus) +doorlockbutton=$(cat /run/doorlockbutton) +nai=$(stat -c "%Y" /run/spacestatus) # get mtime as status change time +if [ "$status" = "open" ] +then + /usr/bin/curl --max-time 1 --silent --data key=96f7896f97asdf89u0a9s7d7fdasgsda88af --data-urlencode sensors='{"state":{"open":true,"lastchange":'"$nai"'}}' http://spaceapi.syn2cat.lu/sensor/set + #logger -t $(basename $0) "sending status $status to spacapi ret=$?" +fi +for plugin in $(ls "$0".d) +do + "$0".d/"$plugin" "$status" +# logger -t $(basename $0) "called $plugin '$status'. ret=$?" +done + +if [ "$status" = "closed" ] && ( + [ "$IGNORE_DOORLOCKBUTTON" = "yes" ] || [ "$doorlockbutton" = "pushed" ] ) +then + # problem: if closing state but not actually shuting door for a longer time, the status in spaceapi + # will be the time of closing but not that of actually shutting the door + # but the status will only be updated once the door is shut + /usr/bin/curl --max-time 1 --silent --data key=96f7896f97asdf89u0a9s7d7fdasgsda88af --data-urlencode sensors='{"state":{"open":false,"lastchange":'"$nai"'}}' http://spaceapi.syn2cat.lu/sensor/set + #logger -t $(basename $0) "sending status $status to spacapi ret=$?" +fi + +if [ $nai -ne $(stat -c "%Y" /root/var/spacestatus) ] # backup file in case it changed +then + cp -p /run/spacestatus /root/var/spacestatus + logger -t $(basename $0) "spacestatus changed, saving to SD. ret=$?" +fi +presency=$(cat /run/presency) +if [ "$status" = "closed" ] +then + presency=0 +fi +/usr/bin/curl --max-time 1 --silent --data key=96f7896f97asdf89u0a9s7d7fdasgsda88af --data-urlencode sensors='{"sensors":{"people_now_present":[{"value":'"$presency"'}]}}' http://spaceapi.syn2cat.lu/sensor/set +V diff --git a/scripts/upd_status.sh.d/lights b/scripts/upd_status.sh.d/lights new file mode 100755 index 0000000..eb264ba --- /dev/null +++ b/scripts/upd_status.sh.d/lights @@ -0,0 +1,33 @@ +#!/bin/bash +# called by upd_status and lockbutton, so that whatever +# sequence is used, the lights go off +if ( [ "$1" = "pushed" ] || [ "$1" = "closed" ] ) && + [ "$(cat /run/spacestatus)" = "closed" ] && + [ "$(cat /run/doorlockbutton)" = "pushed" ] && + ( [ "$(stat -c %Y /run/spacestatus)" -gt "$(date --date "5 minutes ago" +%s)" ] || + [ "$(stat -c %Y /run/doorlockbutton)" -gt "$(date --date "5 minutes ago" +%s)" ] ) +then + logger -t $(basename $0) "switching all lights off" + for i in {1..16} + do + /usr/local/bin/433send 2 1A $i 0 #off + done + logger -t $(basename $0) "all lights should be off now" +fi +if [ "$1" = "released" ] && # the door has been opened + [ "$(cat /run/spacestatus)" = "open" ] && # status is open + [ "$(stat -c %Y /run/spacestatus)" -gt "$(date --date "50 minutes ago" +%s)" ] && # since less than 5 minutes + ( [ "$(date +%H)" -gt 18 ] || [ "$(date +%H)" -lt 8 ] ) +then + logger -t $(basename $0) "switching some lights on" + /usr/local/bin/433send 2 1A 1 1 #on +fi + +# type (2=10bit) +# | house 1-16 (always 1 in our case) +# | |group A-P (the dial thingie) +# | || unit (1-16) (the button, usually 1-4) +# | || | on/off +# | || | | +#/usr/local/bin/433send 2 1A 1 1 #on +#/usr/local/bin/433send 2 1A 1 0 #off diff --git a/systemfiles/crontab-l b/systemfiles/crontab-l new file mode 100644 index 0000000..12f86a7 --- /dev/null +++ b/systemfiles/crontab-l @@ -0,0 +1,27 @@ +# Edit this file to introduce tasks to be run by cron. +# +# Each task to run has to be defined through a single line +# indicating with different fields when the task will be run +# and what command to run for the task +# +# To define the time you can provide concrete values for +# minute (m), hour (h), day of month (dom), month (mon), +# and day of week (dow) or use '*' in these fields (for 'any').# +# Notice that tasks will be started based on the cron's system +# daemon's notion of time and timezones. +# +# Output of the crontab jobs (including errors) is sent through +# email to the user the crontab file belongs to (unless redirected). +# +# For example, you can run a backup of all your user accounts +# at 5 a.m every week with: +# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/ +# +# For more information see the manual pages of crontab(5) and cron(8) +# +# m h dom mon dow command +#* * * * * curl -XPOST "http://localhost:80/GPIO/0/value/1" + +#* * * * * /root/upd_arps.sh +* * * * * /root/dhcp2presency.sh +* * * * * /root/upd_status.sh > /run/spacestatus.out 2>&1 diff --git a/systemfiles/inittab b/systemfiles/inittab new file mode 100644 index 0000000..0854555 --- /dev/null +++ b/systemfiles/inittab @@ -0,0 +1,75 @@ +# /etc/inittab: init(8) configuration. +# $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $ + +# The default runlevel. +id:2:initdefault: + +# Boot-time system configuration/initialization script. +# This is run first except when booting in emergency (-b) mode. +si::sysinit:/etc/init.d/rcS + +# What to do in single-user mode. +~~:S:wait:/sbin/sulogin + +# /etc/init.d executes the S and K scripts upon change +# of runlevel. +# +# Runlevel 0 is halt. +# Runlevel 1 is single-user. +# Runlevels 2-5 are multi-user. +# Runlevel 6 is reboot. + +l0:0:wait:/etc/init.d/rc 0 +l1:1:wait:/etc/init.d/rc 1 +l2:2:wait:/etc/init.d/rc 2 +l3:3:wait:/etc/init.d/rc 3 +l4:4:wait:/etc/init.d/rc 4 +l5:5:wait:/etc/init.d/rc 5 +l6:6:wait:/etc/init.d/rc 6 +# Normally not reached, but fallthrough in case of emergency. +z6:6:respawn:/sbin/sulogin + +# What to do when CTRL-ALT-DEL is pressed. +ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now + +# Action on special keypress (ALT-UpArrow). +#kb::kbrequest:/bin/echo "Keyboard Request--edit /etc/inittab to let this work." + +# What to do when the power fails/returns. +pf::powerwait:/etc/init.d/powerfail start +pn::powerfailnow:/etc/init.d/powerfail now +po::powerokwait:/etc/init.d/powerfail stop + +# /sbin/getty invocations for the runlevels. +# +# The "id" field MUST be the same as the last +# characters of the device (after "tty"). +# +# Format: +# ::: +# +# Note that on most Debian systems tty7 is used by the X Window System, +# so if you want to add more getty's go ahead but skip tty7 if you run X. +# +1:2345:respawn:/sbin/getty --noclear 38400 tty1 +2:23:respawn:/sbin/getty 38400 tty2 +3:23:respawn:/sbin/getty 38400 tty3 +4:23:respawn:/sbin/getty 38400 tty4 +5:23:respawn:/sbin/getty 38400 tty5 +6:23:respawn:/sbin/getty 38400 tty6 + +# Example how to put a getty on a serial line (for a terminal) +# +#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100 +#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100 + +# Example how to put a getty on a modem line. +# +#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3 + + +#Spawn a getty on Raspberry Pi serial line +T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100 + +# pidor +P0:2345:respawn:/root/lockbutton.sh diff --git a/systemfiles/rsyslog.conf b/systemfiles/rsyslog.conf new file mode 100644 index 0000000..adbabd3 --- /dev/null +++ b/systemfiles/rsyslog.conf @@ -0,0 +1,126 @@ +# /etc/rsyslog.conf Configuration file for rsyslog. +# +# For more information see +# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html + + +################# +#### MODULES #### +################# + +$ModLoad imuxsock # provides support for local system logging +$ModLoad imklog # provides kernel logging support +#$ModLoad immark # provides --MARK-- message capability + +# provides UDP syslog reception +$ModLoad imudp +$UDPServerRun 514 + +# provides TCP syslog reception +#$ModLoad imtcp +#$InputTCPServerRun 514 + +$ModLoad omprog +$ActionOMProgBinary /root/rsyslog-mikrotik.sh + +########################### +#### GLOBAL DIRECTIVES #### +########################### + +# +# Use traditional timestamp format. +# To enable high precision timestamps, comment out the following line. +# +$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat + +# +# Set the default permissions for all log files. +# +$FileOwner root +$FileGroup adm +$FileCreateMode 0640 +$DirCreateMode 0755 +$Umask 0022 + +# +# Where to place spool and state files +# +$WorkDirectory /var/spool/rsyslog + +# +# Include all config files in /etc/rsyslog.d/ +# +$IncludeConfig /etc/rsyslog.d/*.conf + +$RepeatedMsgReduction on # suppress repeating messages (gunstick: does not work. wtf) +############### +#### RULES #### +############### + +# +# First some standard log files. Log by facility. +# +auth,authpriv.* /var/log/auth.log +*.*;auth,authpriv.none -/var/log/syslog +#cron.* /var/log/cron.log +daemon.* -/var/log/daemon.log +kern.* -/var/log/kern.log +lpr.* -/var/log/lpr.log +mail.* -/var/log/mail.log +user.* -/var/log/user.log + +# +# Logging for the mail system. Split it up so that +# it is easy to write scripts to parse these files. +# +mail.info -/var/log/mail.info +mail.warn -/var/log/mail.warn +mail.err /var/log/mail.err + +# +# Logging for INN news system. +# +news.crit /var/log/news/news.crit +news.err /var/log/news/news.err +news.notice -/var/log/news/news.notice + +# +# Some "catch-all" log files. +# +*.=debug;\ + auth,authpriv.none;\ + news.none;mail.none -/var/log/debug +*.=info;*.=notice;*.=warn;\ + auth,authpriv.none;\ + cron,daemon.none;\ + mail,news.none -/var/log/messages + +# +# Emergencies are sent to everybody logged in. +# +*.emerg :omusrmsg:* + +# +# I like to have messages displayed on the console, but only on a virtual +# console I usually leave idle. +# +#daemon,mail.*;\ +# news.=crit;news.=err;news.=notice;\ +# *.=debug;*.=info;\ +# *.=notice;*.=warn /dev/tty8 + +# The named pipe /dev/xconsole is for the `xconsole' utility. To use it, +# you must invoke `xconsole' with the `-file' option: +# +# $ xconsole -file /dev/xconsole [...] +# +# NOTE: adjust the list below, or you'll go crazy if you have a reasonably +# busy site.. +# +daemon.*;mail.*;\ + news.err;\ + *.=debug;*.=info;\ + *.=notice;*.=warn |/dev/xconsole + + +:hostname, isequal, "MikroTik" :omprog:;RSYSLOG_TraditionalFileFormat diff --git a/systemfiles/sudoers.d.closetrigger b/systemfiles/sudoers.d.closetrigger new file mode 100644 index 0000000..523b4a3 --- /dev/null +++ b/systemfiles/sudoers.d.closetrigger @@ -0,0 +1 @@ +www-data ALL=(root) NOPASSWD: /root/pidor/scripts/closetrigger.sh diff --git a/webserver/cgi-bin/parse_query b/webserver/cgi-bin/parse_query new file mode 100644 index 0000000..d36592c --- /dev/null +++ b/webserver/cgi-bin/parse_query @@ -0,0 +1,54 @@ +#!/bin/bash + +#parse-query +# Copyright 2007 Chris F.A. Johnson +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# rebuilt by gunstick 2012 (http://cfajohnson.com/shell/articles/parse-query/ is non working version) + +parse_query() #@ USAGE: parse_query var ... +{ + local var val + local IFS='&' + vars="&$*&" + [ "$REQUEST_METHOD" = "POST" ] && read QUERY_STRING + set -f + for item in $QUERY_STRING + do + var=${item%%=*} + val=${item#*=} + val=${val//+/ } +# case $vars in +# *"&$var&"* ) + case $val in + *%[0-9a-fA-F][0-9a-fA-F]*) + val=$( printf "%b" "${val//\%/\\x}." ) + val=${val%.} + #printf -v val "%b" "${val//\%/\\x}" + ;; + esac + val="$(echo "$val"|tr -d '\r')" + eval "FORM_$var=\$val" + # create var for use in form fields + val="$(echo "$val"|sed 's/&/\&/g;s/"/\"/g;s/
"
+exec 2>&1
+. "$(dirname "$0")"/parse_query
+parse_query
+logger -t $(basename $0) got $FORM_action from $REMOTE_USER
+logger -t $(basename $0) spacestatus was $(cat /run/spacestatus)
+if [ "$FORM_action" = "open" ]
+then
+  /usr/local/bin/gpio mode 7 out
+  /usr/local/bin/gpio write 7 0
+  if [ "$(cat /run/spacestatus)" != "open" ]   # do not modify timestamp on multiple clicks
+  then
+    echo "open" > /run/spacestatus
+  fi
+# is now handled in cron Gunstick20140904 #  /usr/bin/curl --max-time 1 --silent --data key=96f7896f97asdf89u0a9s7d7fdasgsda88af --data-urlencode sensors='{"state":{"open":true,"lastchange":'"$nai"'}}' http://spaceapi.syn2cat.lu/sensor/set
+fi
+
+if [ "$FORM_action" = "close" ]
+then
+  /usr/local/bin/gpio mode 7 out
+  /usr/local/bin/gpio write 7 1
+  if [ "$(cat /run/spacestatus)" != "closed" ]   # do not modify timestamp on multiple clicks
+  then
+    echo "closed" > /run/spacestatus
+  fi
+# is now handled in cron Gunstick20140904 #  /usr/bin/curl --max-time 1 --silent --data key=96f7896f97asdf89u0a9s7d7fdasgsda88af --data-urlencode sensors='{"state":{"open":false,"lastchange":'"$nai"'}}' http://spaceapi.syn2cat.lu/sensor/set
+  sudo /root/pidor/scripts/closetrigger.sh 
+  logger -t $(basename $0) closetrigger ret=$?
+fi
+
+
+logger -t $(basename $0) spacestatus is now $(cat /run/spacestatus)
+echo "
" +echo "" diff --git a/webserver/htdocs/favicon.ico b/webserver/htdocs/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..11100297b14df041f7a27a5db6266edd006b49f3 GIT binary patch literal 1406 zcmeH{+cVT*9L67|Qab1)9ajfMCnc$r zSVRn)kVDhxU`9$sc9^83ro&Aa{RR3`GiJJT?|tX_eV@-W&+ol>e=|S8hPHzPCYEd# z;7HDuG#)vVY+y&v3G;XU=LG@*)OA+K^}Q%7D}%4D4*cv6u-R+~_1$1+G$Wj5Nl6KW z`E9sZ`wsj&UC3&Ak3`b|l9Q8B`1~{Yd_H0edf*~8g2iGXEUyJdqY;@6Lx?WvLA=3= zq@*OokdM9FhvMR5I;$UEsv5+!jv_d#5y93mXti3f(i>oY^%Z$fM^IE$1m+bBZU}F5g2UmUqM`zc#(t!vq(IX+2$@U<9nGMiAY7$sHk;vpxgPn? zK0&QkgO}5c?8n2%A*Httq3X>yl$MqvqWC40N+ou_*YLS?9|nT~I-L&O>?UwB+94K;5z+YzT8kAt9uK*XK0vS6 z!_@T!A=le+?ZGfK8V$5fg9yxN1((Z3P2UgHlA=sKNKH*eKw3RSA`vPpE8(7435Cgu z^tK^nkXX7VBvki7Wf_39{4Lm-4Ja=!hli?q@;gtv=^L2B4Y-|HDva5^e~#mF^^v&| z^fQ5tx3|i}<^@+jzj(BRLm*XazBsFP3`xES5V&hU_>_ aJh@h{oIeTw+}Icy8{o+lHTD}AfA +Level2 + + +
+ + +
+ +
+ + +