Created
March 25, 2020 15:54
-
-
Save 5p4k/4c31900d92d3b03089ac2aab008af416 to your computer and use it in GitHub Desktop.
Blink Raspberry Pi LEDs depending on network status
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Unit] | |
Description=Network status as LED | |
StartLimitIntervalSec=0 | |
[Service] | |
Type=simple | |
Restart=always | |
RestartSec=1 | |
User=pi | |
ExecStart=/usr/local/bin/rpi-netstatus.sh | |
[Install] | |
WantedBy=multi-user.target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
GPIO_WORKING=26 | |
GPIO_ERROR=19 | |
GPIO_WARNING=13 | |
GPIO_SUCCESS=6 | |
GPIO_CONNECTION=16 | |
TEST_IP_HOST=8.8.8.8 | |
TEST_DNS_HOST=google.com | |
TEST_HTTP_URL="https://www.google.com" | |
TEST_WLAN_IF=wlan0 | |
TEST_INTERVAL=10s | |
function usage() { | |
echo "$0 [options]" | |
echo "" | |
echo " --ip TEST_IP_HOST [default $TEST_IP_HOST]" | |
echo " IP to ping to test connectivity." | |
echo "" | |
echo " --dns TEST_DNS_HOST [default $TEST_DNS_HOST]" | |
echo " Domain name to ping to test connectivity and DNS lookup." | |
echo "" | |
echo " --url TEST_HTTP_URL [default $TEST_HTTP_URL]" | |
echo " URL to test for HTTP(S) connectivity." | |
echo "" | |
echo " --interface TEST_WLAN_IF [default $TEST_WLAN_IF]" | |
echo " Interface to check whether is up and has a valid IPv4." | |
echo "" | |
echo "" | |
echo " --interval TEST_INTERVAL [default $TEST_INTERVAL]" | |
echo " Interval in seconds between consecutive tests." | |
echo "" | |
echo " --success GPIO_SUCCESS [default $GPIO_SUCCESS]" | |
echo " GPIO pin number for the LED identifying success for ping and http." | |
echo "" | |
echo " --warning GPIO_WARNING [default $GPIO_WARNING]" | |
echo " GPIO pin number for the LED identifying partial success for ping and http." | |
echo "" | |
echo " --error GPIO_ERROR [default $GPIO_ERROR]" | |
echo " GPIO pin number for the LED identifying failure for ping and http." | |
echo "" | |
echo " --connection GPIO_CONNECTION [default $GPIO_CONNECTION]" | |
echo " GPIO pin number for the LED marking whether the network interface is up and running." | |
echo "" | |
echo " --working GPIO_WORKING [default $GPIO_WORKING]" | |
echo " GPIO pin number for the LED marking that tests are being performed." | |
echo "" | |
echo " -h, --help" | |
echo " Shows this help." | |
} | |
while [[ $# -gt 0 ]]; do | |
case "$1" in | |
--ip) shift; TEST_IP_HOST="$1";; | |
--dns) shift; TEST_DNS_HOST="$1";; | |
--url) shift; TEST_HTTP_URL="$1";; | |
--interface) shift; TEST_WLAN_IF="$1";; | |
--interval) shift; TEST_INTERVAL="$1";; | |
--success) shift; GPIO_SUCCESS="$1";; | |
--warning) shift; GPIO_WARNING="$1";; | |
--error) shift; GPIO_ERROR="$1";; | |
--connection) shift; GPIO_CONNECTION="$1";; | |
--working) shift; GPIO_WORKING="$1";; | |
-h|--help) | |
usage | |
exit 0 | |
;; | |
*) | |
echo "Unrecognized option: $1" | |
usage | |
exit 1 | |
;; | |
esac | |
shift | |
done | |
ALL_PINS=("$GPIO_WORKING" "$GPIO_ERROR" "$GPIO_WARNING" "$GPIO_SUCCESS" "$GPIO_CONNECTION") | |
function _boolecho() { | |
case $1 in | |
1) echo -n "OK";; | |
0) echo -n "FAIL";; | |
*) echo -n "N/A";; | |
esac | |
} | |
function _set_pins() { | |
VALUE="$1" | |
shift | |
for PIN in "${@}"; do | |
DEST="/sys/class/gpio/gpio${PIN}/value" | |
if [[ -f "$DEST" ]]; then | |
echo "$VALUE" > "$DEST" | |
fi | |
done | |
} | |
function seth() { | |
_set_pins 1 "$@" | |
} | |
function setl() { | |
_set_pins 0 "$@" | |
} | |
function blink() { | |
PIN="$1" | |
TIMES="$2" | |
PERIOD="$3" | |
if [[ -z "$PERIOD" ]]; then | |
PERIOD="0.3s" | |
fi | |
while [[ $TIMES -ne 0 ]]; do | |
seth "$PIN" | |
sleep "$PERIOD" | |
setl "$PIN" | |
if [[ $TIMES -gt 0 ]]; then | |
TIMES=$(( TIMES - 1 )) | |
fi | |
done | |
} | |
function setup_pins() { | |
for PIN in "${ALL_PINS[@]}"; do | |
echo "Exporting pin $PIN..." | |
echo "$PIN" > /sys/class/gpio/export | |
sleep 1s | |
DEST="/sys/class/gpio/gpio${PIN}/direction" | |
if [[ -f "$DEST" ]]; then | |
echo out > "/sys/class/gpio/gpio${PIN}/direction" | |
fi | |
setl "$PIN" | |
done | |
} | |
function teardown_pins() { | |
for PIN in "${ALL_PINS[@]}"; do | |
echo "Unexporting pin $PIN..." | |
setl "$PIN" | |
echo "$PIN" > /sys/class/gpio/unexport | |
done | |
} | |
function greet() { | |
for PIN in "${ALL_PINS[@]}"; do | |
blink "$PIN" 1 | |
done | |
} | |
function goodbye() { | |
for PIN in "${ALL_PINS[@]}"; do | |
seth "$PIN" | |
done | |
sleep 0.5s | |
for PIN in "${ALL_PINS[@]}"; do | |
setl "$PIN" | |
done | |
} | |
function do_ping() { | |
IP_OK=2 | |
DNS_OK=2 | |
HTTP_OK=2 | |
if [[ $# -eq 0 ]] || [[ $1 -eq 0 ]]; then | |
seth "$GPIO_WORKING" | |
if ping -c 1 -W 1 "$TEST_IP_HOST" > /dev/null 2>&1; then | |
IP_OK=1 | |
if ping -c 1 -W 1 "$TEST_DNS_HOST" > /dev/null 2>&1; then | |
DNS_OK=1 | |
case "$(curl -s --max-time 2 -I "$TEST_HTTP_URL" | sed 's/^[^ ]* *\([0-9]\).*/\1/; 1q')" in | |
[23]) HTTP_OK=1;; | |
* ) HTTP_OK=0;; | |
esac | |
else | |
DNS_OK=0 | |
fi | |
else | |
IP_OK=0 | |
fi | |
setl "$GPIO_WORKING" | |
fi | |
echo "Ping on IP: $(_boolecho $IP_OK); Ping on DNS: $(_boolecho $DNS_OK); Curl on DNS: $(_boolecho $HTTP_OK)" | |
if [[ $IP_OK -eq 1 ]] && [[ $DNS_OK -eq 1 ]] && [[ $HTTP_OK -eq 1 ]]; then | |
seth "$GPIO_SUCCESS" | |
setl "$GPIO_WARNING" | |
setl "$GPIO_ERROR" | |
elif [[ $IP_OK -eq 1 ]] || [[ $DNS_OK -eq 1 ]] || [[ $HTTP_OK -eq 1 ]]; then | |
setl "$GPIO_SUCCESS" | |
seth "$GPIO_WARNING" | |
setl "$GPIO_ERROR" | |
else | |
setl "$GPIO_SUCCESS" | |
setl "$GPIO_WARNING" | |
seth "$GPIO_ERROR" | |
fi | |
} | |
BLINK_JOB="" | |
function _blinkjob_kill() { | |
if [[ -n "$BLINK_JOB" ]]; then | |
kill "$BLINK_JOB" | |
BLINK_JOB="" | |
fi | |
} | |
function _blinkjob_start() { | |
if [[ -z "$BLINK_JOB" ]]; then | |
blink "$1" -1 & | |
BLINK_JOB=$! | |
fi | |
} | |
function do_wifi() { | |
IF_STATUS="$(ip addr show "$TEST_WLAN_IF" 2> /dev/null)" | |
UP=2 | |
HAS_IP=2 | |
if echo "$IF_STATUS" | grep -F "state UP" > /dev/null 2>&1; then | |
UP=1 | |
if echo "$IF_STATUS" | grep '\binet \([0-9]\+\.\)\{3\}[0-9]\+/[0-9]\+\b' > /dev/null 2>&1; then | |
HAS_IP=1 | |
else | |
HAS_IP=0 | |
fi | |
else | |
UP=0 | |
fi | |
echo "IF is up: $(_boolecho $UP); IF has IP: $(_boolecho $HAS_IP)" | |
if [[ $UP -eq 1 ]] && [[ $HAS_IP -eq 1 ]]; then | |
_blinkjob_kill | |
seth "$GPIO_CONNECTION" | |
return 0 | |
elif [[ $UP -eq 1 ]] || [[ $HAS_IP -eq 1 ]]; then | |
_blinkjob_start "$GPIO_CONNECTION" | |
return 2 | |
else | |
_blinkjob_kill | |
setl "$GPIO_CONNECTION" | |
return 1 | |
fi | |
} | |
function main() { | |
while true; do | |
do_wifi | |
do_ping $? | |
sleep "$TEST_INTERVAL" | |
done | |
} | |
function graceful_exit() { | |
echo "" | |
echo "WARN Got SIGINT" | |
kill "$MAIN_JOB" | |
_blinkjob_kill | |
goodbye | |
teardown_pins | |
exit | |
} | |
trap graceful_exit INT # When running at command line | |
trap graceful_exit TERM # When running as a service | |
setup_pins | |
greet | |
main & | |
MAIN_JOB=$! | |
sleep infinity |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment