Compare commits

..

25 Commits

Author SHA1 Message Date
dc6dfc38ad usr/local/bin/custom/poe.sh aktualisiert 2025-10-12 19:33:11 +02:00
7561791a0b usr/local/bin/custom/poe.sh aktualisiert 2025-10-12 19:29:39 +02:00
c7266f73f3 srv/poe_manager/static/css/style.css aktualisiert 2025-10-12 19:21:06 +02:00
1a742c56c9 srv/poe_manager/static/css/style.css aktualisiert 2025-10-12 19:20:40 +02:00
9cdcc59038 srv/poe_manager/static/css/style.css aktualisiert 2025-10-12 19:20:11 +02:00
6523fdf675 srv/poe_manager/static/css/style.css aktualisiert 2025-10-12 19:19:42 +02:00
d846856cb4 srv/poe_manager/static/css/style.css aktualisiert 2025-10-12 19:19:02 +02:00
94142f9ead srv/poe_manager/static/css/style.css aktualisiert 2025-10-12 19:17:25 +02:00
8c93eab3a5 srv/poe_manager/static/css/style.css aktualisiert 2025-10-12 19:17:09 +02:00
ab6ecd773d srv/poe_manager/static/css/style.css aktualisiert 2025-10-12 19:16:51 +02:00
970f7dbeb5 srv/poe_manager/static/css/style.css aktualisiert 2025-10-12 19:16:34 +02:00
19f6390e22 srv/poe_manager/static/css/style.css aktualisiert 2025-10-12 19:16:08 +02:00
268800d31a srv/poe_manager/static/css/style.css aktualisiert 2025-10-12 19:14:41 +02:00
7b0c847e67 srv/poe_manager/app.py aktualisiert 2025-10-12 18:25:08 +02:00
007d9f919f revert 7c045a65b2
revert srv/poe_manager/templates/index.html aktualisiert
2025-10-12 18:24:13 +02:00
7c045a65b2 srv/poe_manager/templates/index.html aktualisiert 2025-10-12 18:23:57 +02:00
98023092a2 srv/poe_manager/templates/index.html aktualisiert 2025-10-12 18:23:16 +02:00
28fa9087a4 srv/poe_manager/app.py aktualisiert 2025-10-12 18:22:37 +02:00
804753dde8 srv/poe_manager/templates/index.html aktualisiert 2025-10-12 18:20:53 +02:00
eaf2e2f78e srv/poe_manager/templates/index.html aktualisiert 2025-10-12 18:18:45 +02:00
50d5f58af4 srv/poe_manager/app.py aktualisiert 2025-10-12 18:18:08 +02:00
12d2511695 srv/poe_manager/templates/index.html aktualisiert 2025-10-12 18:13:29 +02:00
3bd2aca4f5 srv/poe_manager/templates/index.html aktualisiert 2025-10-12 18:11:26 +02:00
b6e9ff3f98 srv/poe_manager/templates/index.html aktualisiert 2025-10-12 18:09:58 +02:00
398629eaaa srv/poe_manager/templates/index.html aktualisiert 2025-10-12 18:09:04 +02:00
4 changed files with 82 additions and 40 deletions

View File

@@ -4,6 +4,7 @@ from flask_login import LoginManager, login_user, login_required, logout_user, U
from flask_bcrypt import Bcrypt from flask_bcrypt import Bcrypt
from cryptography.fernet import Fernet from cryptography.fernet import Fernet
from datetime import datetime from datetime import datetime
from collections import defaultdict
import sqlite3, glob, os, re import sqlite3, glob, os, re
app = Flask(__name__) app = Flask(__name__)
@@ -118,6 +119,13 @@ def index():
c.execute("SELECT mac, name, is_active FROM devices ORDER BY name ASC") c.execute("SELECT mac, name, is_active FROM devices ORDER BY name ASC")
devices = c.fetchall() devices = c.fetchall()
devices = sorted(devices, key=lambda d: d[1][0].upper())
grouped_devices = defaultdict(list)
for d in devices:
first_letter = d[1][:2].upper()
grouped_devices[first_letter].append(d)
# Intervall aus DB laden # Intervall aus DB laden
c.execute("SELECT value FROM settings WHERE key='interval'") c.execute("SELECT value FROM settings WHERE key='interval'")
row = c.fetchone() row = c.fetchone()
@@ -151,7 +159,7 @@ def index():
else: else:
status_dict[dev[0]] = "unbekannt" status_dict[dev[0]] = "unbekannt"
return render_template("index.html", devices=devices, status=status_dict, last_seen=last_seen_dict, interval=interval) return render_template("index.html", grouped_devices=grouped_devices, devices=devices, status=status_dict, last_seen=last_seen_dict, interval=interval)
@app.route("/settings", methods=["GET", "POST"]) @app.route("/settings", methods=["GET", "POST"])
@login_required @login_required

View File

@@ -87,25 +87,33 @@ pre {
#log-container { #log-container {
position: relative; position: relative;
height: calc(100vh - 150px); /* Füllt die Seite minus Header */ height: calc(100vh - 252px); /* Füllt die Seite minus Header */
padding: 1rem; /* optional, Abstand innen */
box-sizing: border-box; /* damit Padding nicht die Höhe sprengt */
display: flex;
flex-direction: column;
} }
#log-box { #log-box {
height: 97%; flex: 1 1 auto; /* füllt den Container, berücksichtigt Header/Padding */
overflow: auto; overflow: auto;
white-space: pre-wrap; white-space: pre-wrap;
font-family: monospace; font-family: monospace;
border: 1px solid #dee2e6; /* Bootstrap-like border */ border: 1px solid #dee2e6;
padding: 1rem;
background-color: #f8f9fa; background-color: #f8f9fa;
padding: 0.5rem;
} }
#refresh-timer { #refresh-timer {
position: absolute; position: absolute;
bottom: 10px; bottom: 18px;
right: 10px; right: 30px;
font-size: 0.9em; font-size: 0.9em;
color: gray; color: gray;
background-color: rgba(255,255,255,0.7); /* optional, besser lesbar */
padding: 2px 4px;
border-radius: 3px;
pointer-events: none; /* damit Scrollbar nicht blockiert wird */
} }
/* Tabelle anpassen */ /* Tabelle anpassen */

View File

@@ -8,29 +8,33 @@
</span> </span>
</h2> </h2>
<div class="row g-3"> <div class="row g-3">
{% for d in devices %} {% for letter, group in grouped_devices.items() %}
<div class="col-6 col-md-4 col-lg-3 col-xl-2"> <div class="row g-3">
<div class="card text-center p-2" {% for d in group %}
{% if last_seen.get(d[0]) %} <div class="col-6 col-md-4 col-lg-3 col-xl-2">
title="{{ last_seen[d[0]] }}" <div class="card text-center p-2"
{% elif status[d[0]] == 'offline' %} {% if last_seen.get(d[0]) %}
title="Noch nie online" title="{{ last_seen[d[0]] }}"
{% endif %}> {% elif status[d[0]] == 'offline' %}
<div class="card-header">{{ d[1] }}</div> title="Noch nie online"
<div class="card-body"> {% endif %}>
<span class="fw-bold" style="color: <div class="card-header">{{ d[1] }}</div>
{% if d[2] == 0 %}gray <div class="card-body">
{% elif status[d[0]] == 'online' %}green <span class="fw-bold" style="color:
{% else %}red {% if d[2] == 0 %}gray
{% endif %};"> {% elif status[d[0]] == 'online' %}green
{% if d[2] == 0 %} {% else %}red
Deaktiviert {% endif %};">
{% else %} {% if d[2] == 0 %}
{% if status[d[0]] %}{{ status[d[0]]|capitalize }}{% else %}Unbekannt{% endif %} Deaktiviert
{% endif %} {% else %}
</span> {% if status[d[0]] %}{{ status[d[0]]|capitalize }}{% else %}Unbekannt{% endif %}
{% endif %}
</span>
</div>
</div> </div>
</div> </div>
{% endfor %}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>

View File

@@ -87,23 +87,45 @@ EOF
echo "" > "$LOGFILE" echo "" > "$LOGFILE"
MAX_PARALLEL=10 # maximal gleichzeitig laufende Geräte
while true; do while true; do
echo "--------------------------------------------------------------------" >> "$LOGFILE" echo "--------------------------------------------------------------------" >> "$LOGFILE"
python3 /srv/poe_manager/generate_ips.py | while IFS=: read -r rpi_ip dev_name switch_ip switch_hostname switch_port switch_user switch_pass; do python3 /srv/poe_manager/generate_ips.py | while IFS=: read -r rpi_ip dev_name switch_ip switch_hostname switch_port switch_user switch_pass; do
if ping -c 1 -W 2 "$rpi_ip" &> /dev/null; then # Funktion für ein Gerät
echo "$(date '+%Y-%m-%d %H:%M:%S') $dev_name ist erreichbar!" >> "$LOGFILE" check_device() {
else local rpi_ip="$1"
echo "$(date '+%Y-%m-%d %H:%M:%S') $dev_name ist nicht erreichbar!" >> "$LOGFILE" local dev_name="$2"
local switch_ip="$3"
local switch_hostname="$4"
local switch_port="$5"
local switch_user="$6"
local switch_pass="$7"
# Nur PoE neu starten, wenn Port vorhanden ist if ping -c 4 -W 1 "$rpi_ip" &> /dev/null; then
if [ -n "$switch_port" ] && [ "$switch_port" != "None" ]; then echo "$(date '+%Y-%m-%d %H:%M:%S') $dev_name ist erreichbar!" >> "$LOGFILE"
disable_poe "$switch_ip" "$switch_port" "$switch_user" "$switch_pass" else
echo "$(date '+%Y-%m-%d %H:%M:%S') $dev_name PoE auf Port $switch_port am Switch $switch_hostname deaktiviert." >> "$LOGFILE" echo "$(date '+%Y-%m-%d %H:%M:%S') $dev_name ist nicht erreichbar!" >> "$LOGFILE"
sleep 2
enable_poe "$switch_ip" "$switch_port" "$switch_user" "$switch_pass" if [ -n "$switch_port" ] && [ "$switch_port" != "None" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') $dev_name PoE auf Port $switch_port am Switch $switch_hostname aktiviert." >> "$LOGFILE" disable_poe "$switch_ip" "$switch_port" "$switch_user" "$switch_pass"
echo "$(date '+%Y-%m-%d %H:%M:%S') $dev_name PoE auf Port $switch_port am Switch $switch_hostname deaktiviert." >> "$LOGFILE"
sleep 2
enable_poe "$switch_ip" "$switch_port" "$switch_user" "$switch_pass"
echo "$(date '+%Y-%m-%d %H:%M:%S') $dev_name PoE auf Port $switch_port am Switch $switch_hostname aktiviert." >> "$LOGFILE"
fi
fi fi
fi }
# Job in Hintergrund starten
check_device "$rpi_ip" "$dev_name" "$switch_ip" "$switch_hostname" "$switch_port" "$switch_user" "$switch_pass" &
# Limit auf MAX_PARALLEL Jobs
while [ "$(jobs -rp | wc -l)" -ge "$MAX_PARALLEL" ]; do
sleep 0.2
done
done done
wait # alle Hintergrundjobs beenden, bevor sleep
sleep "$SLEEP" sleep "$SLEEP"
done done