From 7abb4751e8a39d68b146c037f7de4c973cd75f9f Mon Sep 17 00:00:00 2001 From: Baron-Paelen <50848243+Baron-Paelen@users.noreply.github.com> Date: Sun, 7 Jan 2024 21:32:30 -0800 Subject: [PATCH] prototype done --- dev/heartbeat-prototype/README.md | 14 ++++++++ dev/heartbeat-prototype/raspi/failtest.sh | 2 ++ dev/heartbeat-prototype/raspi/raspi.sh | 39 +++++++++++++++++++++++ dev/heartbeat-prototype/user/user.py | 36 +++++++++++++++++++++ 4 files changed, 91 insertions(+) create mode 100644 dev/heartbeat-prototype/README.md create mode 100644 dev/heartbeat-prototype/raspi/failtest.sh create mode 100644 dev/heartbeat-prototype/raspi/raspi.sh create mode 100644 dev/heartbeat-prototype/user/user.py diff --git a/dev/heartbeat-prototype/README.md b/dev/heartbeat-prototype/README.md new file mode 100644 index 0000000..4825e73 --- /dev/null +++ b/dev/heartbeat-prototype/README.md @@ -0,0 +1,14 @@ +# How to Use! +0. Connect the user's device to the raspi's network. +1. Get the `raspi` folder on the raspi. +2. Get the `user` folder on a user's device. +3. On the user's device, run `user.py` *first*. +4. On the raspi, run `raspi.sh` with appropriate arguments. + - First argument is the user's connected IP address + - Second argument is the command to run when the heartbeat fails + - `./raspi.sh IP FAILCMD` +5. Enjoy! + +## Example +- `./raspi.sh 10.42.0.3 ./failtest.sh` +- `./raspi.sh "10.42.0.3" "touch grass"` \ No newline at end of file diff --git a/dev/heartbeat-prototype/raspi/failtest.sh b/dev/heartbeat-prototype/raspi/failtest.sh new file mode 100644 index 0000000..b7f3b32 --- /dev/null +++ b/dev/heartbeat-prototype/raspi/failtest.sh @@ -0,0 +1,2 @@ +#!/bin/bash +echo "hello world!" \ No newline at end of file diff --git a/dev/heartbeat-prototype/raspi/raspi.sh b/dev/heartbeat-prototype/raspi/raspi.sh new file mode 100644 index 0000000..64afde4 --- /dev/null +++ b/dev/heartbeat-prototype/raspi/raspi.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +### +# This should be run on the raspi to send heartbeat to the user's computer +### + + +# Set the remote server URL to first argument +REMOTE_SERVER_URL="$1" +# Command to run if heartbeat fails to send +CMD_ON_FAIL="$2" +# Seconds to wait before sending heartbeat +HEARTBEAT_INTERVAL=0.5 +# Flag to track if CMD_ON_FAIL has been run +CMD_RAN=0 + +# Function to send heartbeat +send_heartbeat() { + curl --max-time 1 -s -o /dev/null -w "%{http_code}" "$REMOTE_SERVER_URL" +} + +# Main loop for sending heartbeat every HEARTBEAT_INTERVAL seconds +# If heartbeat fails to send, run CMD_ON_FAIL once, then retry sending heartbeat +while true; do + if [ "$(send_heartbeat)" == "200" ]; then + echo "Heartbeat sent successfully" + CMD_RAN=0 + else + if [ "$CMD_RAN" -eq 0 ]; then + echo "Failed to send heartbeat. Running command..." + $CMD_ON_FAIL + CMD_RAN=1 + else + echo "Failed to send heartbeat. Command already ran." + fi + fi + + sleep $HEARTBEAT_INTERVAL +done diff --git a/dev/heartbeat-prototype/user/user.py b/dev/heartbeat-prototype/user/user.py new file mode 100644 index 0000000..6fe6dab --- /dev/null +++ b/dev/heartbeat-prototype/user/user.py @@ -0,0 +1,36 @@ +from flask import Flask +from datetime import datetime, timedelta + +### +# This should be run on the user's machine. +# You can check `localhost:80/status` to see if the raspi has reported recently. +### + +app = Flask(__name__) +last_heartbeat_time = datetime.now() + +# Set the maximum allowed time between heartbeats in seconds +MAX_HEARTBEAT_INTERVAL = 15 + +@app.route('/', methods=['GET']) +def log_heartbeat(): + global last_heartbeat_time + + # Update the last heartbeat time + last_heartbeat_time = datetime.now() + + print("Received heartbeat!") + return "OK", 200 + +@app.route('/status', methods=['GET']) +def check_status(): + global last_heartbeat_time + + # Check if the heartbeat is received within the allowed timeframe + if datetime.now() - last_heartbeat_time > timedelta(seconds=MAX_HEARTBEAT_INTERVAL): + return "Error: Heartbeat not received within the allowed timeframe", 500 + else: + return "OK", 200 + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=80)