diff options
Diffstat (limited to 'misc')
| -rwxr-xr-x | misc/relayctl | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/misc/relayctl b/misc/relayctl new file mode 100755 index 0000000..b356031 --- /dev/null +++ b/misc/relayctl @@ -0,0 +1,67 @@ +#!/bin/sh + +# setup +set -e +die() { echo "usage: $0 [-r relay] [-s state] [-ght] [device]" && exit $1 ; } + +getstate() { + tty=$1 + relay=${2:-1} + + # write 0xFF for status + printf '\377' > $tty + + # read status response for selected relay + while read r; do case "$r" in "CH${relay}: "*) echo "$r" && return ;; esac; done < $tty +} + +genbytes() { + # the relay is controled by a fixed 4 byte command as follows: + start=160 # always 0xA0 + relay=$1 # relay id (counts from 1) + state=$2 # whether to energize 1 or 0 + checksum=$(( start + relay + state )) # checksum is just a sum + + # generate the octal sequence with printf, then convert to bytes with printf again + printf "$(printf '\\%03o\\%03o\\%03o\\%03o' $start $relay $state $checksum)" +} + +# args +relay=1 +state=1 + +while getopts 'r:s:ght' opt; do + case "$opt" in + r) relay="$OPTARG" ;; + s) state="$OPTARG" ;; + g) get=1 ;; + t) get=1 && toggle=1 ;; + h) die 0 ;; + \?) die 1 ;; + esac +done + +shift $((OPTIND - 1)) # shift to final arg +tty="${1:-/dev/stdout}" # output to stdout as fallback + +# validate +case $relay in [1-9]|[1-9][0-9]*) ;; *) die 1 ;; esac +case $state in [01]) ;; *) die 1 ;; esac +[ -n "$get" ] && [ "$tty" = "/dev/stdout" ] && die 1 + +# handle get commands +if [ -n "$get" ]; then + s=$(getstate "$tty" $relay) || die 1 + + if [ -z "$toggle" ]; then + echo "$s" && exit 0 # exit when no toggle + else + case "$s" in + *ON) state=0 ;; + *OFF) state=1 ;; + esac + fi +fi + +# go +genbytes $relay $state > "$tty" |
