107 lines
3.3 KiB
Bash
Executable File
107 lines
3.3 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# ==========================================================================
|
|
# UNIVERSAL KASA HS103 NAGIOS PLUGIN
|
|
# Usage: ./check_kasa.sh <IP_ADDRESS> <relay_state|rssi|on_time|sw_ver|mac>
|
|
# ==========================================================================
|
|
|
|
plugIP=""
|
|
plugPort="9999"
|
|
metric=""
|
|
|
|
while getopts "H:m:P:" opt; do
|
|
case "$opt" in
|
|
H) plugIP="$OPTARG";;
|
|
P) plugPort="$OPTARG";;
|
|
m) metric="$OPTARG";;
|
|
esac
|
|
done
|
|
shift $((OPTIND - 1))
|
|
restOfLine="$@"
|
|
|
|
if [ -z "$plugIP" ] || [ -z "$metric" ]; then
|
|
echo "UNKNOWN - Missing arguments. Usage: $0 <IP> <metric>"
|
|
echo " metric: relay_state rssi on_time sw_ver hw_ver mac model"
|
|
exit 3
|
|
fi
|
|
|
|
# Pre-encrypted XOR payload for get_sysinfo
|
|
# NOTE: Why this value is what it is is beyond the scope of this script
|
|
PAYLOAD="AAAAI9Dw0qHYq9+61/XPtJS20bTAn+yV5o/hh+jK8J7rh+vLtpbr"
|
|
|
|
# Fetch raw binary stream as clean decimal strings
|
|
RAW_STREAM=$(echo "$PAYLOAD" | base64 -d | nc -w 3 "$plugIP" "$plugPort" | od -An -v -t u1)
|
|
|
|
if [ -z "$RAW_STREAM" ]; then
|
|
echo "CRITICAL - No network response from HS103 at $plugIP"
|
|
exit 2
|
|
fi
|
|
|
|
# XOR Decryption Loop
|
|
DECRYPTED_JSON=""
|
|
KEY=171
|
|
|
|
for BYTE in $RAW_STREAM; do
|
|
if [ "$BYTE" -eq 0 ] && [ -z "$DECRYPTED_JSON" ]; then
|
|
continue
|
|
fi
|
|
OUTPUT=$(( BYTE ^ KEY ))
|
|
KEY=$BYTE
|
|
DECRYPTED_JSON+="$(printf "\\$(printf '%03o' "$OUTPUT")")"
|
|
done
|
|
|
|
# Clean out trailing encryption anomalies
|
|
CLEAN_JSON=$(echo "$DECRYPTED_JSON" | grep -o '{.*}' | sed 's/.$//')
|
|
|
|
# Extract the alias name universally for clean alert messaging
|
|
ALIAS=$(echo "$CLEAN_JSON" | jq -r '.get_sysinfo.alias')
|
|
|
|
# Dynamic Evaluation Engine based on your CLI parameter Choice
|
|
case "$metric" in
|
|
relay_state)
|
|
VALUE=$(echo "$CLEAN_JSON" | jq '.get_sysinfo.relay_state')
|
|
if [ "$VALUE" -eq 1 ]; then
|
|
echo "OK - ${ALIAS} Relay is ON | relay_state=1;;;;"
|
|
exit 0
|
|
else
|
|
echo "CRITICAL - ${ALIAS} Relay is OFF | relay_state=0;;;;"
|
|
exit 2
|
|
fi
|
|
;;
|
|
|
|
rssi)
|
|
VALUE=$(echo "$CLEAN_JSON" | jq '.get_sysinfo.rssi')
|
|
# Standard Wi-Fi signal threshold parameters
|
|
if [ "$VALUE" -ge -70 ]; then
|
|
echo "OK - ${ALIAS} Wi-Fi Signal Strength: ${VALUE} dBm | rssi=${VALUE};-75;-85;;"
|
|
exit 0
|
|
elif [ "$VALUE" -lt -70 ] && [ "$VALUE" -ge -82 ]; then
|
|
echo "WARNING - ${ALIAS} Wi-Fi Signal Weak: ${VALUE} dBm | rssi=${VALUE};-75;-85;;"
|
|
exit 1
|
|
else
|
|
echo "CRITICAL - ${ALIAS} Wi-Fi Signal Dropping Out: ${VALUE} dBm | rssi=${VALUE};-75;-85;;"
|
|
exit 2
|
|
fi
|
|
;;
|
|
|
|
on_time)
|
|
VALUE=$(echo "$CLEAN_JSON" | jq '.get_sysinfo.on_time')
|
|
# Converts raw seconds to readable hours for clear telemetry status
|
|
HOURS=$(echo "scale=2; $VALUE / 3600" | bc)
|
|
echo "OK - ${ALIAS} Continuous Active Runtime: ${HOURS} Hours | on_time=${VALUE};;;;"
|
|
exit 0
|
|
;;
|
|
|
|
sw_ver|hw_ver|mac|model)
|
|
# Dynamic handling for inventory/metadata parameters
|
|
VALUE=$(echo "$CLEAN_JSON" | jq -r ".get_sysinfo.${metric}")
|
|
echo "OK - ${ALIAS} ${metric}: ${VALUE}"
|
|
exit 0
|
|
;;
|
|
|
|
*)
|
|
echo "UNKNOWN - Unsupported metric: ${metric}. Choose: relay_state, rssi, on_time, sw_ver, hw_ver, mac, model"
|
|
exit 3
|
|
;;
|
|
esac
|