From 7e4494fa2a52b02f16e02918ae9b5b3d18b3c70c Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Tue, 28 Jun 2022 10:06:06 +1000 Subject: [PATCH] Fixed device detection Added -a arg to specify arping location Fall back to ping if arping unavailable Put usage text in alphabetical order Fix device name length detection in -W mode --- aircon.sh | 53 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/aircon.sh b/aircon.sh index 5a0b17d..63142f6 100755 --- a/aircon.sh +++ b/aircon.sh @@ -5,7 +5,6 @@ # TODO: ditch pymyair # TODO: manual controls - DEFAULT_KILLFILE="${HOME}/.aircon_noaction" DEFAULT_CONFIGFILE=${HOME}/.airconrc DEFAULT_CSVFILE=${HOME}/acstats.csv @@ -15,6 +14,9 @@ DEFAULT_TOLERANCE=0 VALID_MODES=" cool heat " VALID_ZONE_STATES=" open close " +ARPING_DEF=/usr/local/sbin/arping +ARPING=${ARPING_DEF} + BOLD="\033[1m" PLAIN="\033[0m" STRIKE="\033[9m" @@ -53,26 +55,27 @@ function usage() { echo echo " Modifies aircon based on configured parameters in $DEFAULT_CONFIGFILE." echo - echo " -h Show this text." - echo " -c Cron mode. Only show output if actions were taken." - echo " -i x.x.x.x Specify IP address for aircon (default is $DEFAULT_AIRCON_IP)" - echo " -D dbhost Specify influxdb hostname for -I and -A options (default: localhost)" - echo " -I db Log all zone temperatures to given influxdb database, then exit (see -o)." + echo " -a file Specify location of arping binary (default: $ARPING_DEF)." echo " -A db Log actions to given influxdb database." + echo " -c Cron mode. Only show output if actions were taken." + echo " -D dbhost Specify influxdb hostname for -I and -A options (default: localhost)" echo " -f file Specify an alternate config file." + echo " -h Show this text." + echo " -i x.x.x.x Specify IP address for aircon (default is $DEFAULT_AIRCON_IP)" + echo " -I db Log all zone temperatures to given influxdb database, then exit (see -o)." echo " -k file If file exists, never change aircon settings (default: $DEFAULT_KILLFILE)." echo " -l num Set number of too hot/cold zones at which to taking action." echo " -L Log all zone temperatures to CSV file, then exit (see -o)." - echo " -o file Specify CSV output file. Default: $DEFAULT_CSVFILE" echo " -m Generate a config file based on current aircon setup." + echo " -o file Specify CSV output file. Default: $DEFAULT_CSVFILE" echo " -p Profiler mode." echo " -s Validate config file then exit." echo " -S[H] Show configured rules in human-readable format" echo " (HTML if -H given, otherwise ANSI)." - echo " -w List which people are available then exit." - echo " -W List zone-owning devices are available then exit." echo " -t num Specify degrees below min temperature before taking action." echo " -T num Specify degrees above max temperature before taking action." + echo " -w List which people are available then exit." + echo " -W List zone-owning devices are available then exit." echo " -y Actually run commands/db inserts. By default, commands are just displayed." echo } @@ -1318,7 +1321,7 @@ function parse_config() { # if we can ping ANY of the args, return ok function canping() { local n hname ip db host success=0 mac - local os + local os arprv arpres os=$(uname -s) db=0 # get ip and clear arp @@ -1338,7 +1341,11 @@ function canping() { # send new arp req for n in ${!ip[@]}; do if [[ -n ${ip[$n]} ]]; then - arping -c10 -W0.1 -w4 -C1 -q ${ip[$n]} 2>/dev/null & + if [[ -e $ARPING ]]; then + ${ARPING} -c10 -W0.2 -w4 -C1 -q ${ip[$n]} 2>/dev/null & + else + ping -c 1 -w 1 -q ${ip[$n]} 2>/dev/null & + fi fi done @@ -1349,10 +1356,10 @@ function canping() { # now check entries for n in ${!ip[@]}; do if [[ -n ${ip[$n]} ]]; then - mac=$(arp -n ${ip[$n]}) - #mac=$(arp -n $ip | egrep -v "Host|xpired" | awk '{print $2}') - #[[ $mac == *:* ]] && thisrv=0 - [[ $? -eq 0 ]] && success=1 + arpres=$(arp -n ${ip[$n]} 2>/dev/null) + arprv=$? + mac=$(echo "$arpres" | egrep -v "Host|xpired" | awk '{print $2}') + [[ $mac == *:* ]] && success=1 fi [[ $db -eq 1 ]] && info "canping() ${hname[$n]} (${ip[$n]}) is $success - mac=$mac" if [[ $success -eq 1 ]]; then @@ -1794,6 +1801,9 @@ ALLARGS="$ALLARGS $*" optstring="A:cD:f:hHi:I:k:l:Lo:pmRsSt:T:wWx:y" while getopts "$optstring" i $ALLARGS; do case "$i" in + a) + ARPING=${OPTARG} + ;; h) usage; exit 1; @@ -1874,6 +1884,10 @@ while getopts "$optstring" i $ALLARGS; do done shift $((OPTIND - 1)) +if [[ ! -e $ARPING ]]; then + info "Warning: arping binary '$ARPING' not found, will use ping instead" +fi + if [[ -n $influxdb ]]; then influx_init "$influxdb" || exit 1 fi @@ -1946,6 +1960,7 @@ if [[ $showwho -eq 1 ]]; then for x in ${pname[@]}; do [[ ${#x} -gt $maxlen ]] && maxlen=$((${#x} + 3)) done + maxlen=$((maxlen + 1)) # get a list of all phones TFORMAT="${BOLD}${UNDERLINE}%-${maxlen}s%-16s${PLAIN}\n" HFORMAT="%-${maxlen}s${GREEN}%-16s${PLAIN}\n" @@ -1977,17 +1992,20 @@ elif [[ $showwho -eq 2 ]]; then AFORMAT="%-${maxlen}s${RED}%-16s${PLAIN}%s\n" alldevs=$(echo "${ownerhost[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ') + n=0 for x in $alldevs; do canping ${x} >/dev/null 2>&1 - pingres[$x]=$? + pingres[$n]=$? + n=$((n + 1)) done [[ $cronmode -eq 0 && $logmode -eq 0 ]] && echo -e "${GREEN}${BOLD}ok${PLAIN}" echo printf "$TFORMAT" "Devices" "Availability" "Zones owned" + n=0 for x in $alldevs; do - if [[ ${pingres[$x]} -eq 0 ]]; then + if [[ ${pingres[$n]} -eq 0 ]]; then thisform="$HFORMAT" str="Available" else @@ -2002,6 +2020,7 @@ elif [[ $showwho -eq 2 ]]; then done allmydevs=$(echo "${mydevs[@]}" | tr '\n' ' ') printf "$thisform" "${x}" "$str" "${allmydevs}" + n=$((n + 1)) done echo exit 0