From fbbcd16cc2edd3e30c246b84e3936ba6d02857a7 Mon Sep 17 00:00:00 2001 From: SylDor Date: Fri, 6 Mar 2026 19:23:05 +0000 Subject: [PATCH] Dateien nach "/" hochladen --- ha_bridge.sh | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 ha_bridge.sh diff --git a/ha_bridge.sh b/ha_bridge.sh new file mode 100644 index 0000000..abc513b --- /dev/null +++ b/ha_bridge.sh @@ -0,0 +1,96 @@ +#!/bin/bash + +# --- KONFIGURATION --- +LOGFILE="/home/DeinKonto/.minetest/debug.txt" +TOKEN="DeinToken" +HA_URL="http://192.168.178.40:8123/api/states" +DB_PATH="/home/DeinHomeVerzeichnis/.minetest/worlds/DeineWelt/players.sqlite" + + +# --- INITIALER STARTWERT (Aus der DB beim Start des Scripts) --- +# Holt alle Spieler, die in den letzten 2 Min aktiv waren als Basiswert +PLAYER_COUNT=$(sqlite3 "$DB_PATH" "SELECT COUNT(name) FROM player WHERE modification_date > datetime('now', '-2 minutes');") +[[ -z "$PLAYER_COUNT" ]] && PLAYER_COUNT=0 + +# --- TELEMETRIE SCHLEIFE (UPTIME, CPU, DIAMANTEN & SPIELZEIT) --- +( + while true; do + PID=$(pgrep luanti) + + if [ ! -z "$PID" ]; then + # 1. Uptime & CPU berechnen + UPTIME_SEC=$(ps -p $PID -o etimes= | tr -d ' ') + UPTIME_HOURS=$(echo "scale=1; $UPTIME_SEC / 3600" | bc -l | sed 's/^\./0./') + CPU_LOAD=$(ps -p $PID -o %cpu= | tr -d ' ' | tr ',' '.') + + curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d "{\"state\": \"$UPTIME_HOURS\", \"attributes\": {\"unit_of_measurement\": \"h\", \"friendly_name\": \"ServerUp\"}}" \ + "$HA_URL/sensor.luanti_uptime" + + curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d "{\"state\": \"$CPU_LOAD\", \"attributes\": {\"unit_of_measurement\": \"%\", \"friendly_name\": \"CPU Last\"}}" \ + "$HA_URL/sensor.luanti_cpu" + + # 2. Reichtums-Scan & Live-Spielzeit + if [ -f "$DB_PATH" ]; then + # --- DIAMANTEN (Rohdiamanten x1, Blöcke x9) --- + sqlite3 "$DB_PATH" "SELECT player, item FROM player_inventory_items WHERE item LIKE '%diamond%' AND item NOT LIKE '%pick%' AND item NOT LIKE '%axe%' AND item NOT LIKE '%shovel%';" | awk -F'|' '{ + item=$2; player=$1; count=1; + split(item, parts, " "); + if (parts[2] ~ /^[0-9]+$/) { count = parts[2]; } + if (item ~ /block/) { value = count * 9; } else { value = count; } + sum[player] += value + } END { + for (p in sum) print p "|" sum[p] + }' | while read ROW; do + P_NAME=$(echo "$ROW" | cut -d'|' -f1) + P_TOTAL=$(echo "$ROW" | cut -d'|' -f2) + P_LOWER=$(echo "$P_NAME" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/_/g') + curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d "{\"state\": \"$P_TOTAL\", \"attributes\": {\"unit_of_measurement\": \"💎\", \"friendly_name\": \"Diamant-Vermögen $P_NAME\"}}" \ + "$HA_URL/sensor.luanti_diamonds_$P_LOWER" + done + + # --- LIVE SPIELZEIT (Aktivität in den letzten 2 Min) --- + sqlite3 "$DB_PATH" "SELECT name FROM player WHERE modification_date > datetime('now', '-2 minutes');" | while read P_ONLINE; do + P_LOWER=$(echo "$P_ONLINE" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/_/g') + CURRENT_PT=$(curl -s -H "Authorization: Bearer $TOKEN" "$HA_URL/sensor.luanti_playtime_$P_LOWER" | jq -r '.state') + if [[ "$CURRENT_PT" == "null" || "$CURRENT_PT" == "unknown" ]]; then CURRENT_PT="0.0"; fi + NEW_PT=$(echo "scale=3; $CURRENT_PT + 0.016" | bc -l | sed 's/^\./0./') + curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d "{\"state\": \"$NEW_PT\", \"attributes\": {\"unit_of_measurement\": \"h\", \"friendly_name\": \"Spielzeit $P_ONLINE\"}}" \ + "$HA_URL/sensor.luanti_playtime_$P_LOWER" + done + fi + fi + sleep 60 + done +) & + +# --- LOG-PARSER (ECHTZEIT SPIELER STATUS & ZÄHLER) --- +tail -n 0 -F "$LOGFILE" | grep --line-buffered -E "joins game|leaves game" | while read LINE ; do + if [[ "$LINE" == *"joins game"* ]]; then + PLAYER=$(echo "$LINE" | sed -n 's/.*ACTION\[Server\]: \(.*\) \[.*/\1/p') + [[ -z "$PLAYER" ]] && PLAYER=$(echo "$LINE" | awk '{print $4}' | tr -d '[]') + STATE="on" + PLAYER_COUNT=$((PLAYER_COUNT + 1)) + else + PLAYER=$(echo "$LINE" | awk '{print $4}') + STATE="off" + PLAYER_COUNT=$((PLAYER_COUNT - 1)) + fi + + # Zähler-Check (darf nicht unter 0 fallen) + if [ "$PLAYER_COUNT" -lt 0 ]; then PLAYER_COUNT=0; fi + + # 1. Binary Sensor für den einzelnen Spieler + PLAYER_LOWER=$(echo "$PLAYER" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/_/g') + curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d "{\"state\": \"$STATE\", \"attributes\": {\"friendly_name\": \"$PLAYER\", \"device_class\": \"connectivity\"}}" \ + "$HA_URL/binary_sensor.luanti_${PLAYER_LOWER}" + + # 2. Gesamt-Zähler sofort an HA senden + curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d "{\"state\": \"$PLAYER_COUNT\", \"attributes\": {\"unit_of_measurement\": \"Spieler\", \"friendly_name\": \"Spieler Online\", \"icon\": \"mdi:account-group\"}}" \ + "$HA_URL/sensor.luanti_spieler_online" +done