From 19e01fd8e72c33c4e1cb90cceedd2e67481c9dbe Mon Sep 17 00:00:00 2001 From: CJ Date: Sun, 18 Jan 2026 11:52:57 +0000 Subject: [PATCH] Upload files to "/" --- LICENSE | 9 ++ README.md | 132 ++++++++++++++++++++++++++++ Simple Dash.PNG | Bin 0 -> 28863 bytes index.html | 227 ++++++++++++++++++++++++++++++++++++++++++++++++ server.py | 30 +++++++ 5 files changed, 398 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 Simple Dash.PNG create mode 100644 index.html create mode 100644 server.py diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8152839 --- /dev/null +++ b/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2024 CJ + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..a49b968 --- /dev/null +++ b/README.md @@ -0,0 +1,132 @@ +# Flask Powered Status Page Buy Me a Coffee at ko-fi.com + +A simple webpage to keep an eye on the online status of devices. The page also displays the full date which refreshes at midnight, the current time which updates every second, and how long until the status refreshes. + +![Simple Dashboard](https://gitea.cjgameslive.com/CJ/Flask-Powered-Status-Page/raw/branch/main/img/Simple%20Dash.PNG) + +## The server +For our webpage to update the statuses it will need to connect with a backend server which will query an IP address (rows 11, 12, and 13). Thoretically you can add as many devices as you want. This will return a json of `{"status":"online"}`, `{"status":"offline"}` or `{"status":"Device not found"}` if there is an error. + +The device names we can query are set in the first part of the device list, these could be any name you wish such as an easy to remember device name, or the name of the person who owns the device. In theory, if your family has reserved IP addresses for their phones you could change `online` and `offline` on row 24 to `home` and `away` to show if the persons phone is connected to the WiFi. + +You will need `python3` and `flask-cors` installed, the server is run in pthon whilst flask-cors ensures our server is reachable by the webpage. Python3 should already be available if you are running this on a Raspberry Pi, you will only need to install flask-cors using: +``` +pip install flask-cors +``` + +To run the server for texting you can use: +``` +python3 server.py +``` + +I would recommend making it executable using: +``` +chmod +x server.py +``` + +Then running it using: +``` +./server.py +``` +add `&` at the end to run in the background, you can also Google how to add it to crontab to make it run at boot. + +This will run in your terminal on port 5000, this is set on line 30 so you can adjust the port number if this is already in use. + +You can test the output using curl, make sure to change `{device}` to the device name you set on lines 11+ (such as `http://127.0.0.1:5000/check_status/pi4`) +``` + curl http://your_server_ip_or_domain:5000/check_status/{device} +``` + +## The webpage +The first things you will want to chage is lines 98, 102, and 106 to reflect whatever you are monitoring. You can leave the id if you want (`pi4Badge`, `pi5Badge`, `pi0Badge`), this will never be seen on the front end, but you will want to change `Pi 4`, `Pi 5`, and `Pi 0` to whatever you are monitoring. Make sure to keep the `: Offline` as this is used in the javascrypt to update the status. + +If you are only monitoring one device you can update this section: +``` +
+
+
Pi 4: Offline
+
+
+``` + +If you want to add more devices you can either copy and paste the section updating the id's and labels, or you can insert more colums by adding a divider and new section before the final `` on line 108: +``` +
+
+
Pi 0W: Offline
+
+``` + +### javascrypt +If you change any of the names in server.py you must update them in lines 155, 156, and 157 to be able to fetch their status, and if you update any of the id's in the webpage above you must update them. For example, if we added pi0W as a device in our server.py: +``` +# List of IP addresses to check +devices = { + 'pi4': '{IP}', + 'pi5': '{IP}', + 'pi0': '{IP}', + 'pi0W': '{IP}' +} +``` + +and added it as a new column to our devices in index.html: +``` +
+
+
Pi 4: Offline
+
+
+
+
Pi 5: Offline
+
+
+
+
Pi 0: Offline
+
+
+
+
Pi 0W: Offline
+
+
+``` + +we would need to update our function to retrieve and update the status: +``` + function updateStatus() { + fetchStatus('pi4', 'pi4Badge'); + fetchStatus('pi5', 'pi5Badge'); + fetchStatus('pi0', 'pi0Badge'); + fetchStatus('pi0W', 'pi0WBadge'); + } +``` + +If we had updated our statuses from `online` and `offline` to `home` and `away` we would also need to amend rows 166 to: +``` +const statusText = data.status === 'home' ? ': Home' : ': Away'; +``` + +168 to: +``` + if (data.status === 'home') { +``` + +as well as out html above: +``` +
+
Pi 4: Away
+
+``` + +All of our statuses will start as `Offline` or `Away` do that only a positive result will show `Online` or `Home`, although this will be updated as the page updates anyway. If there is an error in the connection with the server the badges will turn orange and display `: Server Error`, it will keep trying to reconnect and break the countdown timer to the next update (which should correct once reconnected). + +By defult the status is refreshed every minute, if you wish to update this you will need to update row 215 +``` + updateTimer(60); // This example sets the timer to 60 seconds +``` + +and 222 +``` + setInterval(updateStatus, 60000); // Update every minute +``` + +to your desired refresh interval. \ No newline at end of file diff --git a/Simple Dash.PNG b/Simple Dash.PNG new file mode 100644 index 0000000000000000000000000000000000000000..76f756580b366b4aeff3365b22013f06e5fc1862 GIT binary patch literal 28863 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 literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 0000000..99c9a3f --- /dev/null +++ b/index.html @@ -0,0 +1,227 @@ + + + + + +Status Board + + + + +
+

+ +

+
+
Pi 4: Offline
+
+
+
+
Pi 5: Offline
+
+
+
+
Pi 0: Offline
+
+
+ +
+ + + + + + + diff --git a/server.py b/server.py new file mode 100644 index 0000000..73dd0d9 --- /dev/null +++ b/server.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +from flask import Flask, jsonify +from flask_cors import CORS +from subprocess import run, PIPE + +app = Flask(__name__) +CORS(app) + +# List of IP addresses to check +devices = { + 'pi4': '{IP}', + 'pi5': '{IP}', + 'pi0': '{IP}' +} + +def is_device_connected(ip_address): + result = run(['ping', '-c', '1', ip_address], stdout=PIPE, stderr=PIPE, tex> + return result.returncode == 0 + +@app.route('/check_status/') +def check_status(device): + ip_address = devices.get(device) + if ip_address: + status = 'online' if is_device_connected(ip_address) else 'offline' + return jsonify({'status': status}) + else: + return jsonify({'error': 'Device not found'}), 404 + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000)