Files
2026-09-06 12:08:05 -04:00

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