diff --git a/README.txt b/README.txt index f4eb4b3..fac891c 100644 --- a/README.txt +++ b/README.txt @@ -18,6 +18,7 @@ cat > /home/pi/.config/lxsession/LXDE/autostart <<"EOF" @xset -dpms @xset s noblank @unclutter -display :0 -noevents -grab +@sudo python ./doorbuzz/setneocolor.py @./doorbuzz/buzzctrl.sh @./doorbuzz/videoplayer.sh @sudo python ./doorbuzz/shutdownbutton.py @@ -38,6 +39,11 @@ IP adress in decimal phone_notification_client.sh communicates with pidor's doorbuzz_wrapper.sh to command the flash light +# new: using redis to manage the 60 led circle +sudo apt-get install python-pip redis-server +sudo pip install redis +#the redi.sh comes from here: https://github.com/crypt1d/redi.sh + todo ==== create a config file diff --git a/buzzctrl.sh b/buzzctrl.sh index 208f38a..e14e32c 100755 --- a/buzzctrl.sh +++ b/buzzctrl.sh @@ -1,12 +1,23 @@ #!/bin/bash # led is not neopixel, so use the python lib for that BUTTONPIN=25 -SHOWLEDPRG="sudo python /home/pi/doorbuzz/setneocolor.py" BUZZERURL="$(cat "$(dirname "$0")"/secret.txt)/state.xml?relay1State=2&pulseTime1=5" BUZZERSTATUSURL="$(cat "$(dirname "$0")"/secret.txt)/state.xml" ATTENUATION=4 # file secret.txt should contain username:password +cd $(dirname "$0") +showleds() { + ./redi.sh </dev/null +# sudo python /home/pi/doorbuzz/setneocolor.py $1 $2 $3 $4 +} # install by putting into /etc/rc.local # su pi -c '/home/pi/doorbuzz/buzzctrl.sh' & @@ -19,7 +30,7 @@ pulseon() { red=$1 green=$2 blue=$3 - $SHOWLEDPRG pulse $((red/ATTENUATION)) $((green/ATTENUATION)) $((blue/ATTENUATION)) /dev/null 2>&1 & + showleds pulse $((red/ATTENUATION)) $((green/ATTENUATION)) $((blue/ATTENUATION)) /dev/null 2>&1 & echo $! } pulseoff() { @@ -32,7 +43,7 @@ ledcolor() { red=$1 green=$2 blue=$3 - $SHOWLEDPRG set $((red/ATTENUATION)) $((green/ATTENUATION)) $((blue/ATTENUATION)) + showleds set $((red/ATTENUATION)) $((green/ATTENUATION)) $((blue/ATTENUATION)) } declare -a morse morse[0]="-----" @@ -60,31 +71,25 @@ echo $morsecode red=$2 green=$3 blue=$4 - $SHOWLEDPRG morse $((red/ATTENUATION)) $((green/ATTENUATION)) $((blue/ATTENUATION)) "$morsecode" + showleds morse $((red/ATTENUATION)) $((green/ATTENUATION)) $((blue/ATTENUATION)) "$morsecode" echo } echo "morsing IP" -ledcolor 255 255 255 -sleep 3 -ledcolor 0 0 0 -sleep 1 morseled "$(hostname -I|awk -F. '{sub(" ","",$NF);printf $NF}')" 255 0 0 -ledcolor 255 255 255 -sleep 1 +sleep 10 echo "Main loop" while true do ledcolor 0 255 255 pulsepid=$(pulseon 0 0 255 ) - trap "pulseoff $pulsepid;ledcolor 0 0 0;exit" 1 2 3 + trap "ledcolor 0 0 0;exit" 1 2 3 gpio -g wfi $BUTTONPIN falling while [ $(gpio -g read $BUTTONPIN) != 0 ] do gpio -g wfi $BUTTONPIN falling done - pulseoff $pulsepid ledcolor 0 255 255 echo "Pushiii" wget -O - -S --timeout=1 --tries=1 "$BUZZERURL" 2>&1 @@ -92,6 +97,7 @@ do if [ $ret -ne 0 ] then morseled "$ret" 255 0 0 + sleep 5 else while wget -O - --timeout=1 --tries=1 $BUZZERSTATUSURL|grep '1' do diff --git a/phone_notification_client.sh b/phone_notification_client.sh index 4265739..c69dd5f 100755 --- a/phone_notification_client.sh +++ b/phone_notification_client.sh @@ -5,6 +5,9 @@ run_file="/var/run/phone_ringing_status" pidor=root@10.2.113.2 old_status=0 new_status=0 +cd $(dirname "$0") + + while true # empty pipe do sleep 1 @@ -45,8 +48,10 @@ do fi echo "phone status change detected" if [ "$new_status" -eq 0 ]; then + echo "neoaction=flash" | ./redi.sh echo "flashon" >&"${COPROC[1]}" else + echo "neoaction=pulse" | ./redi.sh echo "flashoff" >&"${COPROC[1]}" fi # echo $new_status > ${run_file} diff --git a/redi.sh b/redi.sh new file mode 100755 index 0000000..3299306 --- /dev/null +++ b/redi.sh @@ -0,0 +1,198 @@ +#!/bin/bash + +REDIS_HOST=127.0.0.1 +REDIS_PORT=6379 +CLIENT_VERSION=0.2 + + +function redis_read_str() { + typeset REDIS_STR="$@" + printf %b "$REDIS_STR" | cut -f2- -d"+" | tr -d '\r' +} + +function redis_read_err() { + typeset REDIS_ERR="$@" + printf %s "$REDIS_ERR" | cut -f2- -d"-" + exit 1 +} + +function redis_read_int() { + typeset -i OUT_INT=$(printf %s $1 | tr -d '\:' | tr -d '\r') + printf %b "$OUT_INT" +} + +function redis_read_bulk() { + typeset -i BYTE_COUNT=$1 + typeset -i FILE_DESC=$2 + if [[ $BYTE_COUNT -lt 0 ]]; then + echo "ERROR: Null or incorrect string size returned." >&2 + exec {FILE_DESC}>&- + exit 1 + fi + + echo $(dd bs=1 count=$BYTE_COUNT status=noxfer <&$FILE_DESC 2>/dev/null) + dd bs=1 count=2 status=noxfer <&$FILE_DESC 1>/dev/null 2>&1 # we are removing the extra character \r +} + +function redis_read() { + +typeset -i FILE_DESC=$1 + +if [[ $# -eq 2 ]]; then + typeset -i PARAM_COUNT=$2 + typeset -i PARAM_CUR=1 +fi + +while read socket_data +do + typeset first_char=$(printf %b "$socket_data" | head -c1) + + case $first_char in + "+") + #echo "This is a simple string." + redis_read_str "$socket_data" + ;; + "-") + #echo "This is an error." + redis_read_err "$socket_data" + ;; + ":") + #echo "This is an integer." + redis_read_int $socket_data + ;; + "\$") + #echo "This is a bulk string." + bytecount=$(printf %b "$socket_data" | cut -f2 -d"\$" | tr -d '\r') + redis_read_bulk $bytecount $FILE_DESC + ;; + "*") + #echo "This is an array." + paramcount=$(printf %b "$socket_data" | cut -f2 -d"*" | tr -d '\r') + redis_read $FILE_DESC $paramcount + ;; + esac + +if [[ ! -z $PARAM_COUNT ]]; then + if [[ $PARAM_CUR -lt $PARAM_COUNT ]]; then + ((PARAM_CUR+=1)) + continue + else + break + fi +else + break +fi + +done<&$FILE_DESC + +} + +function redis_get_var() { + typeset REDIS_VAR="$@" + printf %b "*2\r\n\$3\r\nGET\r\n\$${#REDIS_VAR}\r\n$REDIS_VAR\r\n" +} + +function redis_set_var() { + typeset REDIS_VAR="$1" + shift + typeset REDIS_VAR_VAL="$@" + printf %b "*3\r\n\$3\r\nSET\r\n\$${#REDIS_VAR}\r\n$REDIS_VAR\r\n\$${#REDIS_VAR_VAL}\r\n$REDIS_VAR_VAL\r\n" +} + +function redis_get_array() { + typeset REDIS_ARRAY="$1" + printf %b "*4\r\n\$6\r\nLRANGE\r\n\$${#REDIS_ARRAY}\r\n$REDIS_ARRAY\r\n\$1\r\n0\r\n\$2\r\n-1\r\n" +} + +function redis_set_array() { + typeset REDIS_ARRAY="$1" + typeset -a REDIS_ARRAY_VAL=("${!2}") + + printf %b "*2\r\n\$3\r\nDEL\r\n\$${#REDIS_ARRAY}\r\n$REDIS_ARRAY\r\n" + for i in "${REDIS_ARRAY_VAL[@]}" + do + printf %b "*3\r\n\$5\r\nRPUSH\r\n\$${#REDIS_ARRAY}\r\n$REDIS_ARRAY\r\n\$${#i}\r\n$i\r\n" + done +} + +while getopts g:P:H:p:ha opt; do + case $opt in + p) + REDIS_PW=${OPTARG} + ;; + H) + REDIS_HOST=${OPTARG} + ;; + P) + REDIS_PORT=${OPTARG} + ;; + g) + REDIS_GET=${OPTARG} + ;; + a) + REDIS_ARRAY=1 + ;; + h) + echo "" + echo "USAGE:" + echo " $0 [-a] [-g ] [-p ] [-H ] [-P ]" + echo "" + exit 1 + ;; + esac +done + + +# +# Main thread +# + +exec {FD}<> /dev/tcp/$REDIS_HOST/$REDIS_PORT + +if [[ ! -z $REDIS_PW ]]; then + redis_compose_cmd "AUTH $REDIS_PW" >&$FD +fi + +if [[ ! -z $REDIS_GET ]]; then + if [[ $REDIS_ARRAY -eq 1 ]]; then + redis_get_array $REDIS_GET >&$FD + IFS=$'\n' + typeset -a OUTPUT_ARRAY + + for i in `redis_read $FD` + do + OUTPUT_ARRAY+=($i) + done + + typeset | grep ^OUTPUT_ARRAY | sed "s/OUTPUT_ARRAY/$REDIS_GET/" + + else + redis_get_var $REDIS_GET >&$FD + redis_read $FD + fi + + exec {FD}>&- + exit 0 +fi + +# Pipe read +while read line +do + REDIS_TODO=$line + +if [[ $REDIS_ARRAY -eq 1 ]]; then + ARRAY_NAME=$(printf %b "$REDIS_TODO" | cut -f1 -d"=") + typeset -a temparray=$(printf %b "$REDIS_TODO" | cut -f2- -d"=") + redis_set_array $ARRAY_NAME temparray[@] >&$FD + redis_read $FD 1>/dev/null 2>&1 + exit 0 +fi + +KEYNAME=$(printf %b "$REDIS_TODO" | cut -f1 -d"=") +KEYVALUE=$(printf %b "$REDIS_TODO" | cut -f2- -d"=") + +redis_set_var $KEYNAME $KEYVALUE >&$FD +redis_read $FD 1>/dev/null 2>&1 + +done < /dev/stdin +exec {FD}>&- diff --git a/setneocolor.py b/setneocolor.py index 7958060..b5e5de2 100755 --- a/setneocolor.py +++ b/setneocolor.py @@ -4,6 +4,7 @@ from __future__ import division import time import sys from math import * +import redis from neopixel import * @@ -15,50 +16,90 @@ LED_DMA = 5 # DMA channel to use for generating signal (try 5) LED_BRIGHTNESS = 100 # Set to 0 for darkest and 255 for brightest LED_INVERT = False # True to invert the signal (when using NPN transistor level shift) +def wheel(pos): + """Generate rainbow colors across 0-255 positions.""" + if pos < 85: + return Color(pos * 3, 255 - pos * 3, 0) + elif pos < 170: + pos -= 85 + return Color(255 - pos * 3, 0, pos * 3) + else: + pos -= 170 + return Color(0, pos * 3, 255 - pos * 3) + def clockcalc(value): return 1+((30+int(value))%60) # Main program logic follows: if __name__ == '__main__': - # Create NeoPixel object with appropriate configuration. - strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS) - # Intialize the library (must be called once before other functions). - strip.begin() - r=int(sys.argv[2]) - g=int(sys.argv[3]) - b=int(sys.argv[4]) - if(sys.argv[1] == "set"): + # Create NeoPixel object with appropriate configuration. + strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS) + # Intialize the library (must be called once before other functions). + strip.begin() + myredis=redis.StrictRedis(host='localhost', port=6379, db=0) + while True: + time.sleep(50/1000.0) + try: + r=int(myredis.get('neored')) + except: + r=0 + try: + g=int(myredis.get('neogreen')) + except: + g=0 + try: + b=int(myredis.get('neoblue')) + except: + b=0 + try: + action=myredis.get('neoaction') + except: + action="set" + if(action == "set"): print "Color set to: ",r,g,b - strip.setPixelColor(0, Color(r,g,b)) + for i in range(0,LED_COUNT): + strip.setPixelColor(i, Color(r,g,b)) strip.show() - if(sys.argv[1] == "morse"): + if(action == "morse"): print "Morsing with: ",r,g,b speed=10 - morsecode=sys.argv[5] + for i in range(0,LED_COUNT): + strip.setPixelColor(i, Color(0,0,0)) + morsecode=myredis.get('neomorse') + morsep=1 for c in morsecode: if c==".": - strip.setPixelColor(0, Color(r,g,b)) - strip.show() - time.sleep(0.2) - strip.setPixelColor(0, Color(0,0,0)) - strip.show() - time.sleep(0.2) + strip.setPixelColor(morsep, Color(r,g,b)) + morsep+=1 + strip.setPixelColor(morsep, Color(0,0,0)) + morsep+=1 if c=="-": - strip.setPixelColor(0, Color(r,g,b)) - strip.show() - time.sleep(0.7) - strip.setPixelColor(0, Color(0,0,0)) - strip.show() - time.sleep(0.2) + strip.setPixelColor(morsep, Color(r,g,b)) + morsep+=1 + strip.setPixelColor(morsep, Color(r,g,b)) + morsep+=1 + strip.setPixelColor(morsep, Color(0,0,0)) + morsep+=1 + strip.setPixelColor(morsep, Color(0,0,0)) + morsep+=1 if c==" ": - strip.setPixelColor(0, Color(0,0,0)) - strip.show() - time.sleep(1) - if(sys.argv[1] == "pulse"): + strip.setPixelColor(morsep, Color(0,0,0)) + morsep+=1 + strip.setPixelColor(morsep, Color(0,0,0)) + morsep+=1 + strip.setPixelColor(morsep, Color(0,0,0)) + morsep+=1 + strip.setPixelColor(morsep, Color(0,0,0)) + morsep+=1 + strip.show() + time.sleep(1) + if(action == "pulse"): print "Pulsing with: ",r,g,b pulsewidth=50 - while True: + while (action==myredis.get('neoaction')): for i in range(pulsewidth): + if(action!=myredis.get('neoaction')): + break color=Color(0,0,0) for j in range(0,60): strip.setPixelColor(clockcalc(j), color) @@ -73,3 +114,23 @@ if __name__ == '__main__': strip.setPixelColor(clockcalc(time.strftime('%S',time.localtime())),Color(0,30,0)) strip.show() time.sleep(50/1000.0) + + if(action == "flash"): + print "Flashing with: ",r,g,b + print myredis.get('neoaction') + wait_ms=50 + """Rainbow movie theater light style chaser animation.""" + while (action==myredis.get('neoaction')): + print " Flashing with: ",r,g,b + for j in range(256): + print " Flashing with: ",r,g,b + if(action!=myredis.get('neoaction')): + break + for q in range(3): + for i in range(0, strip.numPixels(), 3): + strip.setPixelColor(i+q, wheel((i+j) % 255)) + strip.show() + time.sleep(wait_ms/1000.0) + for i in range(0, strip.numPixels(), 3): + strip.setPixelColor(i+q, 0) +