Added trial '-j' option to bypass myair python script and call api directly.

This commit is contained in:
Rob Pearce 2023-09-03 16:27:53 +10:00
parent 4bfc710a54
commit f945018efb
1 changed files with 143 additions and 34 deletions

155
aircon.sh
View File

@ -132,6 +132,7 @@ function getzoneaction() { # populates zproblem[] and zaction[]
problem="n/a" problem="n/a"
thisperfect=1 thisperfect=1
else else
[[ $robtest -eq 1 ]] && echo " owner of ${zname[$idx]} is [${zowner[$idx]}]" >&2
if [[ -z ${zowner[$idx]} ]]; then if [[ -z ${zowner[$idx]} ]]; then
pingok=1 pingok=1
#[[ $robtest -eq 1 ]] && echo " empty owner so no ping " #[[ $robtest -eq 1 ]] && echo " empty owner so no ping "
@ -190,6 +191,11 @@ function getzoneaction() { # populates zproblem[] and zaction[]
zpri[$idx]="$priority" zpri[$idx]="$priority"
zownerhome[$idx]="$pingok" zownerhome[$idx]="$pingok"
[[ $robtest -eq 1 ]] && echo " zproblem is: ${zproblem[$idx]}"
[[ $robtest -eq 1 ]] && echo " zpri is: ${zpri[$idx]}"
[[ $robtest -eq 1 ]] && echo " zownerhome is: ${zownerhome[$idx]}"
if [[ $problem == "owner_not_home" ]]; then if [[ $problem == "owner_not_home" ]]; then
# turn the zone off # turn the zone off
if [[ ${zstate[$idx]} != "close" ]]; then if [[ ${zstate[$idx]} != "close" ]]; then
@ -281,6 +287,8 @@ function getzoneaction() { # populates zproblem[] and zaction[]
fi fi
zaction[$idx]="$thisaction" zaction[$idx]="$thisaction"
zperfect[$idx]=$thisperfect zperfect[$idx]=$thisperfect
[[ $robtest -eq 1 ]] && echo " zaction is: ${zaction[$idx]}"
[[ $robtest -eq 1 ]] && echo " zperfect is: ${zperfect[$idx]}"
profile "getzoneaction for idx ${zname[$idx]}" profile "getzoneaction for idx ${zname[$idx]}"
} }
@ -609,7 +617,7 @@ function generate_actions() { # populates global: nairconcommands & airconcmd
# gen_aircon_command zone_idx "command1 command2 etc" # gen_aircon_command zone_idx "command1 command2 etc"
function gen_aircon_command() { function gen_aircon_command() {
local idx allactions this toadd num doneset othername otherid otheridx db donemode str local idx allactions this toadd num doneset othername otherid otherid2 otheridx db donemode str jtoadd="" id2
idx=$1 idx=$1
shift shift
allactions="$*" allactions="$*"
@ -622,49 +630,63 @@ function gen_aircon_command() {
IFS=' ' read -ra tok <<< "${allactions}" IFS=' ' read -ra tok <<< "${allactions}"
for this in ${tok[@]}; do for this in ${tok[@]}; do
if [[ $this == *power_on* ]]; then if [[ $this == *power_on* ]]; then
add_aircon_command $idx -1 "Power on system" "on" add_aircon_command $idx -1 "Power on system" "on" '"info":{"state":"on"}'
elif [[ $this == *power_off* ]]; then elif [[ $this == *power_off* ]]; then
add_aircon_command $idx -1 "Power off system" "off" add_aircon_command $idx -1 "Power off system" "off" '"info":{"state":"off"}'
elif [[ $this == *set_myzone* && $airconmyzoneid != ${zid[$idx]} ]]; then elif [[ $this == *set_myzone* && $airconmyzoneid != ${zid[$idx]} ]]; then
[[ $idx -eq -1 ]] && continue [[ $idx -eq -1 ]] && continue
add_aircon_command $idx -1 "Set MyZone to ${zname[$idx]}" "myzone --zone ${zid[$idx]}" add_aircon_command $idx -1 "Set MyZone to ${zname[$idx]}" "myzone --zone ${zid[$idx]}" "\"info\":{\"myZone\":${zid[$idx]}}"
elif [[ $this == *open:* ]]; then elif [[ $this == *open:* ]]; then
# open vent in another zone
[[ $idx -eq -1 ]] && continue [[ $idx -eq -1 ]] && continue
othername=$(echo "$this" | sed -e 's/^.*open://;s/ .*//') othername=$(echo "$this" | sed -e 's/^.*open://;s/ .*//')
otheridx=$(getidxfromname $othername) otheridx=$(getidxfromname $othername)
otherid=${zid[$otheridx]} otherid=${zid[$otheridx]}
add_aircon_command $idx $otheridx "Open vent in ${zname[$otheridx]}" "set --zone ${otherid} --state on --temp ${zsettemp[$otheridx]}" otherid2=$(printf "z%02d" "$otherid")
add_aircon_command $idx $otheridx "Open vent in ${zname[$otheridx]}" "set --zone ${otherid} --state on --temp ${zsettemp[$otheridx]}" "\"zones\":{\"${otherid2}\":{\"state\":\"open\",\"setTemp\",${zsettemp[$otheridx]}}"
elif [[ $this == *close:* ]]; then elif [[ $this == *close:* ]]; then
# close vent in another zone
[[ $idx -eq -1 ]] && continue [[ $idx -eq -1 ]] && continue
othername=$(echo "$this" | sed -e 's/^.*close://;s/ .*//') othername=$(echo "$this" | sed -e 's/^.*close://;s/ .*//')
otheridx=$(getidxfromname $othername) otheridx=$(getidxfromname $othername)
otherid=${zid[$otheridx]} otherid=${zid[$otheridx]}
add_aircon_command $idx $otheridx "Close vent in ${zname[$otheridx]}" "set --zone ${otherid} --state off --temp ${zsettemp[$otheridx]}" otherid2=$(printf "z%02d" "$otherid")
add_aircon_command $idx $otheridx "Close vent in ${zname[$otheridx]}" "set --zone ${otherid} --state off --temp ${zsettemp[$otheridx]}" "\"zones\":{\"${otherid2}\":{\"state\":\"close\",\"setTemp\",${zsettemp[$otheridx]}}"
elif [[ $this == *set_mode:* ]]; then elif [[ $this == *set_mode:* ]]; then
str=$(echo "$this" | sed -e 's/^.*set_mode://;s/ .*//') str=$(echo "$this" | sed -e 's/^.*set_mode://;s/ .*//')
add_aircon_command $idx -1 "Set system mode to '$str'" "$str" add_aircon_command $idx -1 "Set system mode to '$str'" "$str" "\"info\":{\"mode\":\"${str}\"}"
elif [[ $this == *set_temp* || $this == *open_vent* || $this == *close_vent* ]]; then elif [[ $this == *set_temp* || $this == *open_vent* || $this == *close_vent* ]]; then
[[ $idx -eq -1 ]] && continue [[ $idx -eq -1 ]] && continue
if [[ $doneset -eq 0 ]]; then if [[ $doneset -eq 0 ]]; then
id2=$(printf "z%02d" "${zid[$idx]}")
jtoadd="\"zones\":{\"${id2}\":{"
toadd="" toadd=""
comm="" comm=""
if [[ $allactions == *open_vent* ]]; then if [[ $allactions == *open_vent* ]]; then
toadd="$toadd --state on" toadd="$toadd --state on"
jtoadd="${jtoadd}\"state\":\"open\","
comm="open vent" comm="open vent"
elif [[ $allactions == *close_vent* ]]; then elif [[ $allactions == *close_vent* ]]; then
toadd="$toadd --state off" toadd="$toadd --state off"
jtoadd="${jtoadd}\"state\":\"close\","
comm="close vent" comm="close vent"
fi fi
if [[ $allactions == *set_temp* ]]; then if [[ $allactions == *set_temp* ]]; then
num=$(echo "$this" | sed -e 's/^.*set_temp://;s/ .*//') num=$(echo "$this" | sed -e 's/^.*set_temp://;s/ .*//')
toadd="$toadd --temp $num" toadd="$toadd --temp $num"
jtoadd="${jtoadd}\"setTemp\":\"$num\","
[[ -n $comm ]] && comm="${comm} and " [[ -n $comm ]] && comm="${comm} and "
comm="${comm}set temperature to $num degrees" comm="${comm}set temperature to $num degrees"
else else
toadd="$toadd --temp ${zsettemp[$idx]}" toadd="$toadd --temp ${zsettemp[$idx]}"
jtoadd="${jtoadd}\"setTemp\":\"${zsettemp[$idx]}\","
fi fi
if [[ -n $toadd ]]; then if [[ -n $toadd ]]; then
add_aircon_command $idx -1 "In zone ${zname[$idx]}, $comm" "set --zone ${zid[$idx]}$toadd"
jtoadd="${jtoadd/%,/}}}" # remove trailing comma, add closing braces
add_aircon_command $idx -1 "In zone ${zname[$idx]}, $comm" "set --zone ${zid[$idx]}$toadd" "$jtoadd"
doneset=1 doneset=1
fi fi
fi fi
@ -674,7 +696,7 @@ function gen_aircon_command() {
# add_aircon_command zone_idx "comment goes here" "actual pymyair command to run" # add_aircon_command zone_idx "comment goes here" "actual pymyair command to run"
function add_aircon_command() { function add_aircon_command() {
local x idx otheridx comment db local x idx otheridx comment db cmd jcmd
[[ $# -le 1 ]] && return 1 [[ $# -le 1 ]] && return 1
@ -684,6 +706,11 @@ function add_aircon_command() {
shift shift
comment=$1 comment=$1
shift shift
cmd="$1"
shift
jcmd="{ \"ac1\":{"
jcmd="${jcmd}$1"
jcmd="${jcmd} } }"
if [[ $otheridx -ne -1 ]]; then if [[ $otheridx -ne -1 ]]; then
if [[ -n $comment ]]; then if [[ -n $comment ]]; then
@ -702,7 +729,8 @@ function add_aircon_command() {
return 1 return 1
fi fi
done done
airconcmd[$nairconcommands]="$*" airconcmd[$nairconcommands]="$cmd"
airconjcmd[$nairconcommands]="$jcmd"
airconcomment[$nairconcommands]="$comment" airconcomment[$nairconcommands]="$comment"
if [[ $idx -eq -1 ]]; then if [[ $idx -eq -1 ]]; then
airconcmdzone[$nairconcommands]="Aircon" airconcmdzone[$nairconcommands]="Aircon"
@ -723,13 +751,13 @@ function add_aircon_command() {
return 0 return 0
} }
function addnoop() { function addnoop() {
local idx local idx
idx=$(getidxfromname "$1") idx=$(getidxfromname "$1")
zignore[$idx]=1 zignore[$idx]=1
} }
function addnomyzone() { function addnomyzone() {
local idx local idx
idx=$(getidxfromname "$1") idx=$(getidxfromname "$1")
@ -1490,17 +1518,30 @@ function gen_config() {
} }
function get_aircon_info() { function get_aircon_info() {
local jsoninfo url state
profile "query aircon" profile "query aircon"
[[ $cronmode -eq 0 && $logmode -eq 0 ]] && echo -en "${GREEN}${BOLD}>> ${PLAIN}${GREEN}Querying aircon... ${PLAIN}" [[ $cronmode -eq 0 && $logmode -eq 0 ]] && echo -en "${GREEN}${BOLD}>> ${PLAIN}${GREEN}Querying aircon... ${PLAIN}"
if [[ $JSONAPI -eq 1 ]]; then
url="${AIRCON_URL}/getSystemData"
jsoninfo=$(curl -s "$url" 2>/dev/null)
zones=$(echo "$jsoninfo" | jq -r '.aircons.ac1.zones[] | [ .name, .state, .setTemp, .measuredTemp, .number ] | @csv' | tr -d '" ')
state=$(echo "$jsoninfo" | jq -r '.aircons.ac1.info.state' | tr -d '" ')
if [[ $state == "off" ]]; then
airconmode="off"
else
airconmode=$(echo "$jsoninfo" | jq -r '.aircons.ac1.info.mode' | tr -d '" ')
fi
airconmyzoneid=$(echo "$jsoninfo" | jq -r '.aircons.ac1.info.myZone ' | tr -d '" ')
else
zones=$(myair $AIRCON_IP zones | jq -r '.[] | [ .name, .state, .setTemp, .measuredTemp, .number ] | @csv' | tr -d '" ') zones=$(myair $AIRCON_IP zones | jq -r '.[] | [ .name, .state, .setTemp, .measuredTemp, .number ] | @csv' | tr -d '" ')
airconmode=$(myair $AIRCON_IP mode) airconmode=$(myair $AIRCON_IP mode)
airconmyzoneid=$(myair $AIRCON_IP myzone)
fi
nzones=0 nzones=0
for line in $zones; do for line in $zones; do
IFS=',' read -ra tok <<< "$line" IFS=',' read -ra tok <<< "$line"
addzone "${tok[0]}" "${tok[1]}" "${tok[2]}" "${tok[3]}" "${tok[4]}" addzone "${tok[0]}" "${tok[1]}" "${tok[2]}" "${tok[3]}" "${tok[4]}"
done done
airconmyzoneid=$(myair $AIRCON_IP myzone)
airconmyzone=$(getnamefromid $airconmyzoneid) airconmyzone=$(getnamefromid $airconmyzoneid)
[[ $cronmode -eq 0 && $logmode -eq 0 ]] && echo -e "${GREEN}${BOLD}ok${PLAIN}" [[ $cronmode -eq 0 && $logmode -eq 0 ]] && echo -e "${GREEN}${BOLD}ok${PLAIN}"
profile "query aircon" profile "query aircon"
@ -1691,14 +1732,68 @@ function show_proposed_commands() {
[[ $count -eq 0 ]] && echo -e "${GREY}n/a${PLAIN}" [[ $count -eq 0 ]] && echo -e "${GREY}n/a${PLAIN}"
} }
function combine_commands() {
local x id2 basefile tfile combinejq jcmd jurl
combinejq=".[0]"
if [[ ${#airconjcmd} -eq 0 ]]; then
return 1
fi
basefile=$(mktemp /tmp/$$.json.base.XXXXXX)
[[ -z $basefile ]] && { error "couldnt create base json file" >&2; exit 1; }
echo -e "{\n\"aircons\": {\n\"ac1\": {\n\"info\": {\n},\n\"zones\": {\n" >${basefile}
for x in ${zid[@]}; do
id2=$(printf "%02d" $x)
echo " \"z${id2}\": { }," >>${basefile}
done
sed -i '$s/,$//' ${basefile}
echo -e "}\n}\n}\n}\n" >> ${basefile}
for x in ${!airconjcmd[@]}; do
tfile[$x]=$(mktemp /tmp/$$.json.$x.XXXXXX)
[[ -z ${tfile[$x]} ]] && { error "couldnt create temp file" >&2; exit 1; }
echo "${airconjcmd[$x]}" >${tfile[$x]}
combinejq="${combinejq} * .[$((x + 1))]"
done
jcmd=$(jq -s "$combinejq" $basefile ${tfile[@]} )
[[ $? -ne 0 ]] && { error "couldnt merge json command files " >&2; exit 1; }
[[ -z $jcmd ]] && { error "got empty merged json command" >&2; exit 1; }
jurl="${AIRCON_URL}/setAircon?json=$jcmd"
for x in ${tfile[@]};
do rm -f "${x}"
done
rm -f "$basefile"
echo "$jurl" | tr -d '\n '
return 0
}
function run_commands() { function run_commands() {
local x local x tfile combinejq jcmd jurl res jqres
for x in ${!airconcmd[@]}; do for x in ${!airconcmd[@]}; do
#echo RUNNING myair $AIRCON_IP ${airconcmd[$x]}
[[ -n ${airconcomment[$x]} ]] && action "${airconcomment[$x]}" [[ -n ${airconcomment[$x]} ]] && action "${airconcomment[$x]}"
echo RUNNING myair $AIRCON_IP ${airconcmd[$x]} if [[ $JSONAPI -eq 1 ]]; then
myair $AIRCON_IP ${airconcmd[$x]} >/dev/null 2>&1 myair $AIRCON_IP ${airconcmd[$x]} >/dev/null 2>&1
fi
influx_insert "INSERT aircon action=\"${airconcomment[$x]}\",comment=\"${airconproblem[$x]}\"" influx_insert "INSERT aircon action=\"${airconcomment[$x]}\",comment=\"${airconproblem[$x]}\""
done done
if [[ $JSONAPI -eq 1 ]]; then
jurl=$(combine_commands)
res=$(curl -s -g "$jurl" 3>/dev/null)
jqres=$(echo "$res" | jq -r '.ack' 2>/dev/null)
if [[ $jqres != "true" ]]; then
error "Myair API call failed:"
echo -e "$RED curl -s -g $jurl$PLAIN"
return 1
fi
fi
} }
function profile() { function profile() {
@ -1801,6 +1896,7 @@ limit=$DEFAULTLIMIT
profiler=0 profiler=0
csvfile="$DEFAULT_CSVFILE" csvfile="$DEFAULT_CSVFILE"
sanitycheck=0 sanitycheck=0
JSONAPI=0
RULEFORMAT=ansi RULEFORMAT=ansi
robtest=0 robtest=0
@ -1820,7 +1916,7 @@ fi
ALLARGS="$ALLARGS $*" ALLARGS="$ALLARGS $*"
optstring="aA:bcD:f:hHi:I:k:l:Lo:pmRsSt:T:wWx:y" optstring="aA:bcD:f:hHi:I:jk:l:Lo:pmRsSt:T:wWx:y"
while getopts "$optstring" i $ALLARGS; do while getopts "$optstring" i $ALLARGS; do
case "$i" in case "$i" in
a) a)
@ -1829,6 +1925,12 @@ while getopts "$optstring" i $ALLARGS; do
b) b)
RULEDB=1 RULEDB=1
;; ;;
D)
influxhost="${OPTARG}"
;;
f)
CONFIGFILE=${OPTARG}
;;
h) h)
usage; usage;
exit 1; exit 1;
@ -1836,19 +1938,16 @@ while getopts "$optstring" i $ALLARGS; do
H) H)
RULEFORMAT=html RULEFORMAT=html
;; ;;
f)
CONFIGFILE=${OPTARG}
;;
i) i)
AIRCON_IP=${OPTARG} AIRCON_IP=${OPTARG}
;; ;;
D)
influxhost="${OPTARG}"
;;
I) I)
logmode=2 logmode=2
influxdb="$OPTARG" influxdb="$OPTARG"
;; ;;
j)
JSONAPI=1
;;
A) A)
influxdb="$OPTARG" influxdb="$OPTARG"
;; ;;
@ -1909,6 +2008,8 @@ while getopts "$optstring" i $ALLARGS; do
done done
shift $((OPTIND - 1)) shift $((OPTIND - 1))
AIRCON_URL="http://${AIRCON_IP}:2025"
if [[ ! -e $ARPING ]]; then if [[ ! -e $ARPING ]]; then
info "Warning: arping binary '$ARPING' not found, will use ping instead" info "Warning: arping binary '$ARPING' not found, will use ping instead"
fi fi
@ -1933,8 +2034,15 @@ fi
if [[ $showwho -eq 0 ]]; then if [[ $showwho -eq 0 ]]; then
if [[ $JSONAPI -eq 1 ]]; then
JQ=$(which myair 2>/dev/null)
if [[ $? -ne 0 ]]; then
error "Can't find jq executable in path."
exit 1
fi
else
if [[ -z $MYAIR ]]; then if [[ -z $MYAIR ]]; then
MYAIR=$(which myair) MYAIR=$(which myair 2>/dev/null)
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
error "Can't find pymyair executable 'myair' in path. Install it from here: https://github.com/smallsam/pymyair" error "Can't find pymyair executable 'myair' in path. Install it from here: https://github.com/smallsam/pymyair"
exit 1 exit 1
@ -1945,6 +2053,7 @@ if [[ $showwho -eq 0 ]]; then
exit 1 exit 1
fi fi
fi fi
fi
fi fi