Ereignishorizont
Onboarding Technik

Onboarding Technik

Wenn ich weiter sehen konnte, dann deshalb, weil ich auf den Schultern von Riesen stand.

Isaac Newton, Brief an Robert Hooke, 5. Februar 1676.

Bild: Der Schuhkarton mit Steuereinheit

Die Technik hinter Onboarding

Bitcoin war zunächst nur ein Gedanke, den Satoshi Nakamoto in einem Bitcoin Whitepaper veröffentlicht und in Software umgesetzt hat. Der Software Code von Bitcoin ist freie und quelloffene Software. Jeder kann ihn einsehen, kopieren, ändern und verwenden, wie er möchte. Hunderte von Programmierern haben bereits an der Entwicklung mitgewirkt und tun es weiterhin – freiwillig und unentgeltlich. Indem Satoshi Nakamoto sein Wissen geteilt hat, ermöglichte er es anderen, ihr Wissen beizutragen, und gemeinsam haben sie etwas Unglaubliches geschaffen: die Rückkehr zu einem guten Geld für die Menschheit.

Seitdem ich Bitcoin Lightning kennengelernt und zu schätzen gelernt habe, schwirrte die Idee für diese Seite in meinem Kopf herum: Menschen Bitcoin Lightning näher zu bringen, ganz einfach und ohne Voraussetzungen. Es hat ein paar Jahre gedauert, bis ich alle Puzzlesteine zusammenhatte. Das Wissen über die Technologie und deren Anwendung muss man sich hart erarbeiten. Jetzt war es endlich soweit, und auch ich werde mein Wissen teilen, damit ihr es verwenden und vielleicht sogar darauf aufbauen könnt. Ich habe alles in Form eines Spickzettels in diesem Artikel zusammengestellt. Die komplexen Abschnitte mit Befehlen und Skripten sind hauptsächlich für mich selbst als Gedankenstütze gedacht. Das Ganze drumherum, wie es zusammenspielt und funktioniert, ist jedoch für euch. Es ist grob strukturiert, stellt keine Anleitung dar und erhebt keinen Anspruch auf Vollständigkeit, aber es erklärt die Technik und Funktionen hinter dem Onboarding. Nutzt es, um vielleicht noch etwas Besseres zu bauen, damit wir noch mehr Menschen Bitcoin näher bringen können.

Die Hardware und Software für Webcam und Mikrocontroller

Eine kurzer Auszug der verwendet Hardware und Beschreibung der Funktion. Alle Bilder zum Aufbau findet ihr hier.

Webcam: Seeed Studio XIAO ESP32S3 Sense Website

Streamer Software: ESP32CAM-RTSP Website

Der ESP32CAM-RTSP erzeugt den RTSP-Stream der Webcam und ermöglicht verschiedene Einstellungen. Zur Installation flasht man die Software mit PlatformIO, einer Erweiterung für Visual Studio Code. Nach einem Neustart stellt der ESP32 einen Wifi Access Point namens ESP32CAM-RTSP zur Verfügung. Damit kann man sich mit einem Wifi-fähigen Gerät (Handy/Notebook) verbinden, ohne ein Passwort eingeben zu müssen. Ist man mit ESP32CAM-RTSP verbunden, kann man die Webseite http://192.168.4.1/ aufrufen. Das ist der Access Point (AP) oder auch das Webinterface zur ersten Konfiguration. Dort muss man die Daten für sein eigenes Wifi und ein Passwort für den erneuten Zugang zum Webinterface hinterlegen. Der Benutzername ist immer "admin". Nach dem Speichern und Neustart sollte der ESP32 jetzt auch im Heimnetzwerk verfügbar sein. Das kann man am eigenen Router überprüfen und die neue IP direkt in den Browser eingeben. Alternativ kann man auch den Direktlink http://esp32cam-rtsp/ verwenden. In beiden Fällen sollte man wieder auf das Webinterface zugreifen können. Es kann zwar etwas dauern, aber falls es nicht funktioniert, empfiehlt es sich, mit PlatformIO ein Terminalfenster zu öffnen und online nachzusehen.

Ein Playmobil hält die Kamera

Zum Webinterface: Neben der SSID, dem Wifi-Passwort und dem Webinterface (AP)-Passwort (der Benutzername ist: admin) ist vor allem die "Frame size" relevant. Der XIAO ESP32S3 Sense ist für seine Größe ziemlich leistungsstark, allerdings fängt das Bild bei Auflösungen größer als VGA stark an zu ruckeln. Die maximale Auflösung ist nur für Einzelbilder geeignet. Ansonsten kann man hier gut mit der Webcam herumspielen und Einstellungen ausprobieren. Unten findet man auch die Links zu den Streams und Snapshots. Der rtsp://192.168.xxx.xxx:554/mjpeg/1 ist der Link, der weiterverarbeitet wird.

Zum ESP32: Der ESP32 wird auch abhängig von der eingestellten Auflösung sehr heiß. Nur Fotos sind kein Problem, aber schon bei VGA wird der ESP32 auf der Rückseite sehr heiß. Für längere Betriebsdauer wird empfohlen, den ESP32 aktiv zu belüften.

Zum Wifi: Die Wifi-Verbindung muss sehr gut sein, sonst funktioniert die Übertragung nicht. Zum Glück findet man auf der Webinterface-Seite vom ESP32 unter "Network" den Punkt "Signalstärke". Alles unter -67 dBm ist gut, wobei -55 dBm perfekt ist. Experimentiert mit der Antenne und dem Standort, um die Signalstärke zu optimieren.

Verwendete Software zum Flashen Software
PlatformIO: https://platformio.org/ als Erweiterung in VSCode: https://code.visualstudio.com/

Sonstiges: Das Objektiv kann man etwas tunen. Wenn man die Fixierverklebung am Objektiv mit einem scharfen Messer löst, dann kann man das Objektiv drehen und damit verstellen. Dadurch kann man die Schärfe für Nahaufnahmen etwas verbessern.

Der Mikrocontroller

Hier verwendete Mikrocontroller (in der Mitte/links im Bild) ist ein ESP32 mit zwei Relais on Board. Wenn ich das nochmal neu bauen müsste, würde ich es nicht mehr auf diese Weise machen, da das Board nur zwei Relais hat und ich einen externen Adapter (CP2102 über dem Microcontroller-Board) für die Kommunikation per USB benötige. Verwendet also lieber einen einfachen ESP32 mit einer Relaisleiste, die sich mit einem High-Level-Trigger schalten lässt.

Die Verdrahtung

Die Verdrahtung ist sicherlich recht abenteuerlich, aber sie funktioniert. 😉

Alles wird mit 12V DC über ein Netzteil oder einen Akku versorgt. Ein Spannungswandler wandelt die Spannung auf 5V für den ESP32, die Kamera, die Relais, den BTC-Ticker, die Antriebe und das Ambientelicht um. Nur die Hauptbeleuchtung und der Lichtspot sind mit 12V versorgt.

Die Verwendung von 12V war eine Entscheidung, die ich getroffen habe, weil ich das gesamte System auch mobil aufbauen wollte. Leider hat sich herausgestellt, dass ich trotzdem meinen Heimrouter für das Dynamic Domain Name System (DNS) benötige. Falls jemand eine Alternative kennt, wie ich meine Webcam mit dem MediaMTX-Server ohne DNS verbinden kann, wäre ich überglücklich davon zu erfahren.

Das Programm für den Mikrocontroller

Das Programm zur Steuerung für den Mikrocontroller findet ihr hier. Es handelt sich um eine etwas ältere und modifizierte Version des aktuellen bitcoinSwitch.

Schaltzentrale Schuhkarton

Schaltplan Steuerung

Der Lightning Knoten und LNbits

Neben dem Lightning Node ist LNbits wohl das wichtigste Element für die Onboarding-Funktion. LNbits ist ein Wallet- und Account-System, das den Node als Finanzierungsquelle verwendet.

LNbits bietet die Möglichkeit eines Accounts, bei dem man mehrere Wallets hinzufügen kann. Zusätzlich gibt es Erweiterungen wie z.B. LNURLDevice für den bitcoinSwitch, LNURLp für die Spenden- und Kommentarfunktion, LNURLw für die Auszahlung von Gutscheinen und natürlich auch die Paywall, über die ihr auf diese Seite gefunden habt.

Lightning-Node

LNbits mit den Wallets und Erweiterungen

Streaming Server – VPS mit MediaMTX – Die Grundlage

Um den Einzelstream der Heim-Webcam leistungsstark zu vervielfältigen und ihn dann im öffentlichen Internet auf mehreren Webseiten gleichzeitig zu streamen, benötigt es einen Streaming-Server. Dieser Server holt den Stream von der Webcam ab, bereitet das Signal auf und stellt es als RTSP-Stream im HTTPS-Format zur Verfügung.

Für den Virtuellen Privaten Server (VPS) verwende ich Digital Ocean, mit dem ich gute Erfahrungen gemacht habe. Wer möchte, kann meinen Referral-Link verwenden, würde ich freuen. Informationen zur Einrichtung eines VPS finden sich am besten auf meiner LNbits Server Seite. Es reicht der kleinste VPS mit 1 CPU, 512 MB Memory und 10 GB Disk.

Die Streaming-Server-Software, die ich verwende, ist MediaMTX. Diese Software ist ein unglaublicher Echtzeit-Medienserver und Medien-Proxy.

Ein weiterer wichtiger Bestandteil in diesem Aufbau ist ffmpeg.org. Dies ist eine vollständige, plattformübergreifende Lösung zum Aufnehmen, Konvertieren und Streamen von Audio und Video. Mit ffmpeg kann man Online-Konvertierungen von Bildern, Ton und Videoformaten durchführen. Es ist gewissermaßen ein Zauberstab für Medienkonvertierung. Mit ffmpeg habe ich den QR-Code ins Bild und den Ton im Hintergrund gezaubert.

Dann benötigt man noch Caddy Server als Reverse Proxy, damit die Anfragen der Webseite auch zum MediaMTX-Stream weitergeleitet werden. Caddy ist wirklich unglaublich einfach zu verwenden. Es ist eine Software, die einem das Leben wirklich erleichtert.

Im Folgenden findet ihr zu allem Beispiele zur Installation und den Einstellungen.

Internet Anbindung – Zwei wichtige Webadressen

  1. Die Webadresse zum Stream des Streaming-Servers. Ich habe dafür die Subdomain "rtsp" für meine Webseite eingerichtet. Dazu erstellt man bei seinem Domainanbieter unter z.B. "Manage DNS records" einen neuen Eintrag vom Typ "A" mit dem Namen "rtsp", der auf die IP-Adresse des Streaming-Servers, also dem VPS, verweist. Der gesamte Link sieht wie folgt aus: https://rtsp.mydomain.xyz/mystream/. Um das "https" kümmert sich Caddy bei richtiger Einstellung automatisch. "mystream" ist der Streamname, den man im MediaMTX vergibt.

  2. Dynamic Domain Name System (DNS) mit DuckDNS.org. Die Webcam ist im Heimnetzwerk verbaut. Da ich keine feste IP habe, führt mein Internetanbieter in regelmäßigen Abständen eine Zwangstrennung durch. Er trennt also etwa alle 24 Stunden meine Internetverbindung und gibt mir eine neue IP-Adresse. Der Streaming-Server, der den Videostream aufbereiten und vervielfältigen soll, muss den Stream der Webcam ja erst einmal irgendwo abholen. Aber wie soll er zu meiner Webcam gelangen, wenn regelmäßig die IP-Adresse geändert wird? Das erledigt DuckDNS. Es wandelt Domainnamenanfragen, wie z.B. https://meinbeispiel.duckdns.com, in eine dynamische IP-Adresse um. Dort bekommt man eine feste Webadresse, die dann auf die wechselnde IP-Adresse verweist. Mein FritzBox-Router meldet sich dafür regelmäßig bei DuckDNS und teilt ihm damit meine aktuelle IP-Adresse mit. Ändert sich meine IP-Adresse, registriert das DuckDNS und leitet neue Anfragen auf die neue IP-Adresse weiter. Damit kann mein Streaming-Server auch immer meine Heimrouter erreichen. Der Heimrouter leitet die Anfragen dann zu meiner Webcam weiter.

Der Router – Hier die FritzBox

Wie im Kapitel DNS beschrieben, kann mein Streaming Server mit Hilfe eines DNS-Servers meinen Heimrouter erreichen. Aber was muss ich tun, damit mein Router Anfragen an meine Webcam weiterleitet?

Als erstes muss man DuckDNS als DNS-Server einstellen. Dazu geht man in der Fritzbox unter Internet / Freigabe / DynDNS, aktiviert es und füllt die Felder mit:

# Update-URL
https://www.duckdns.org/update?domains=meinbeispiel&token=meintoken&ip=<ipaddr>&ipv6=<ip6addr>
# Domain
meinbeispiel.duckdns.com
# Benutzername
none
# Kennwort
meintoken

Jetzt einmal auf Übernehmen.

Die Subdomain "meinbeispiel" bekommt ihr nach der Registrierung bei DuckDNS.org. Dort bekommt ihr auch den Token "meintoken".

Als zweites müsst ihr unter Internet / Freigabe / Portfreigabe den Port 554 für rtsp:// Anfragen freigeben und auf die IP Adresse der Webcam weiterleiten. Dazu wählt unter Portfreigabe / Gerät für Freigabe hinzufügen und dann wählt ihr unter Gerät die IP Adresse eurer Webcam aus. Jetzt könnt ihr unten bei Freigabe eine neue Freigabe hinzufügen und befüllen mit

Als zweites müsst ihr unter Internet / Freigabe / Portfreigabe den Port 554 für rtsp:// Anfragen freigeben und auf die IP-Adresse der Webcam weiterleiten. Dazu wählt ihr unter Portfreigabe / Gerät für Freigabe hinzufügen und dann wählt ihr unter Gerät die IP-Adresse eurer Webcam aus. Jetzt könnt ihr unten bei Freigabe eine neue Freigabe hinzufügen und befüllen mit:

# MyFRITZ!-Freigabe
# Anwendung
Andere Anwendung
# Bezeichnung
rtsp
# Schema
Manuelle Eingabe
rtsp://
# Port an Gerät
554
# Freigabe aktivieren
OK

Jetzt noch einmal auf übernehmen damit es abgespeichert wird.

Damit kann mein MediaMTX-Server meinen Heimrouter mit wechselnder IP-Adresse über DuckDNS finden. Mein Heimrouter leitet Anfragen für den Stream an meine Kamera in meinem lokalen Netzwerk an Port 554 weiter. Dadurch kann die Kamera zum MediaMTX-Server streamen, welcher dann das Signal umwandelt und bei Anfragen von Webbrowsern streamt, also das Signal meiner Kamera skaliert. Die Lösung funktioniert gut, allerdings bin ich auf meinen Heimrouter angewiesen. Ich würde den Schuhkarton gerne mobil halten, um ihn auch mal bei einem Meetup zu präsentieren. Ich überlege schon, dies über eine VPN-Verbindung zu meinem Heimrouter zu realisieren, bin jedoch noch nicht tiefer eingestiegen. Falls jemand von euch also eine Idee hat, wäre ich für Vorschläge dankbar.

VPS-Server einrichten und Grundeinstellungen

Als erste braucht ihr einen VPS-Server auf dem dem ihr MediaMTX laufen lassen könnt. Wie man so einen Server aufsetzt habe ich schon im Tutorial zu LNbits ausgiebig erklärt. Ihr finde alles Informationen im Kapitel 7. Der Aufbau eines LNbits Server.

7.1 – Allgemein – Einrichten eines Virtual Private Server (VPS)
7.2 – VPS – Grundeinstellungen des Virtual Private Server

Installation und Einrichtung des MediaMTX-Servers

MediaMTX Installation

  1. Lade die aktuelle Binärdatei von der Release-Seite herunter.
  2. Lege im Stammverzeichnis einen neuen Ordner namens ‘server’ an.
  3. Lade die heruntergeladene Binärdatei herunter und entpacke sie in den erstellten Ordner.

    mkdir server cd server wget https://github.com/bluenviron/mediamtx/releases/download/v1.3.1/mediamtx_v1.3.1_linux_amd64.tar.gz tar -xf mediamtx_v1.3.1_linux_amd64.tar.gz

Manuelles Starten zum Testen ist möglich mit: ./mediamtx

MediaMTX Autostart

Hinweis: Der Linux User heißt hier satoshi.

sudo nano /etc/systemd/system/mediamtx.service

Befüllen mit

[Unit]
Wants=network.target
[Service]
ExecStart=/home/satoshi/server/mediamtx /home/satoshi/server/mediamtx.yml
[Install]
WantedBy=multi-user.target

Nützliche Befehle

sudo systemctl enable mediamtx.service
sudo systemctl start mediamtx.service
sudo systemctl stop mediamtx.service
sudo systemctl status mediamtx.service
sudo systemctl disable mediamtx.service
sudo systemctl daemon-reload
sudo journalctl -u mediamtx -f --since "1 hour ago"

Einrichten eines Caddy Proxy Servers

Damit ihr den Stream später auch von außen abrufen könnt, müsst ihr einen Proxy Server einrichten, der die Anfragen direkt auf den Stream weiterleitet. Dazu benötigt ihr eine (Sub-)Domain, die auf den Server zeigt.

Caddy installieren

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

Caddyfile anlegen

sudo caddy stop
sudo nano /etc/caddy/Caddyfile

Alles rauslöschen und befüllen mit:

rtsp.mydomain.xyz
reverse_proxy :8889

Einmal starten, kontrollieren und wieder stoppen

sudo caddy start
sudo caddy stop 

Ankommende Anfragen von einem Webseitenaufruf, wie z.B. https://rtsp.mydomain.xyz/mystream/, werden dann auf den Port 8889 weitergeleitet. In diesem Beispiel erfolgt die Weiterleitung sogar direkt zum Pfad "mystream", wo der Streaming Server MediaMTX den aktuellen Stream als WebRTC zur Verfügung stellt.

Caddy Autostart

sudo nano /etc/systemd/system/caddy.service

Befülle mit:

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateDevices=yes
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

Nützliche Befehle

sudo systemctl enable caddy.service
sudo systemctl start caddy.service
sudo systemctl stop caddy.service
sudo systemctl status caddy.service
sudo systemctl disable caddy.service
sudo systemctl daemon-reload
sudo journalctl -u caddy -f --since "1 hour ago"
sudo journalctl -xeu caddy.service

Die Installation von ffmpeg und der erste Start eines Streams

MediaMTX stellt den Streaming-Server bereit und sollte nun im Hintergrund laufen. Allerdings benötigen wir etwas, das den Webcam-Stream abholt, das Video aufbereitet, gegebenenfalls mit einem QR-Code und Musik versieht und an MediaMTX übergibt. Dies übernimmt ffmpeg für uns.

Installation

cd
sudo apt install ffmpeg
ffmpeg -version

Einfacher start des Streams

ffmpeg -rtsp_transport tcp -i "rtsp://meinbeispiel.duckdns.org/mjpeg/1" -pix_fmt yuv420p -r:v 30 -c:v libx264 -preset ultrafast -b:v 600k -f rtsp rtsp://localhost:8554/mystream

rtsp://meinbeispiel.duckdns.com/mjpeg/1 ist die Quelle des Streams, meine Webcam. rtsp://111.111.111.111:8554/mystream ist das Ziel für den Eingang im MediaMTX Auslesen kann man den Stream dann auf https://rtsp.mydomain.xyz/mystream/

QR-Code Bild und Sound Datei ablegen

Das PNG-Bild für den QR-Code hat eine Auflösung von 128×128 Pixel. Die Musikdatei music.mp3 beispielsweise hat eine Bitrate von 192 kBit/s.

scp qr128.png satoshi@111.111.111.111:/home/satoshi/server/
scp music.mp3 satoshi@111.111.111.111:/home/satoshi/server/

Überwachung des Streams mit automatischem Neustart

Das Starten des Streams ist eine Sache, jedoch kann sich der Stream aufhängen, wenn für eine gewisse Zeit keine Daten eintreffen, selbst wenn die Quelle wieder ordnungsgemäß funktioniert. Daher müssen wir den Autostart mit einer Überwachung versehen, die den Stream neu startet, wenn er ausgesetzt hat.

Startskript für den Stream erstellen

sudo nano /home/satoshi/server/ffmpeg.sh

Befülle mit

#!/bin/sh
ffmpeg -rtsp_transport tcp -stream_loop -1 -i "rtsp://meinbeispiel.duckdns.org/mjpeg/1" \
-i qr128.png -stream_loop -1 -i music.mp3 -filter_complex "[0:v][1:v]overlay=W-w-5:H-h-5[v];\
[2:a]aloop=loop=-1[outa]" -map "[v]" -map "[outa]" -pix_fmt yuv420p -r:v 30 -c:v libx264 \
-preset ultrafast -b:v 600k -c:a libopus -b:a 128k -f rtsp rtsp://localhost:8554/mystream 2>&1 | tee ffmpeg.log

Es ist zu beachten, dass im gleichen Verzeichnis, in dem dieses Skript liegt, auch eine kleine PNG-Bilddatei namens "qr128.png" sowie eine Audiodatei "music.mp3" mit einer Bitrate deiner Wahl vorhanden sein müssen. Das Bild wird dann rechts unten im Stream eingeblendet, und die Musik wiederholt sich kontinuierlich. Dieses Skript kann zum Testen einmal manuell gestartet werden.

sh /home/satoshi/server/ffmpeg.sh

Angehängt wurde auch 2>&1 | tee ffmpeg.log angehängt. Dadurch wird eine Logdatei erstellt, mit der der Stream anschließend überwacht werden kann.

Jetzt können wir das eigentliche Skript "Checker.sh" erstellen, das sowohl den Start des Streaming-Skripts als auch die Überprüfung des ordnungsgemäßen Betriebs des Streams ermöglicht.

sudo nano /home/satoshi/server/checker.sh

Befüllen mit

#!/bin/bash
bash /home/satoshi/server/ffmpeg.sh & echo "started ffmpeg.."
LOG_FILE="/home/satoshi/server/ffmpeg.log"
MAX_SAME_FRAME_COUNT=3  # Count of frames before "Stream has hung"
same_frame_count=0
last_frame=""
while true
do
    frame=$(tail -n 1 "$LOG_FILE" | sed -nr 's/.*frame=(.*)fps.*/\1/p')
    if [ "$frame" = "$last_frame" ]
    then
        ((same_frame_count++))
        if [ "$same_frame_count" -ge "$MAX_SAME_FRAME_COUNT" ]
        then
            echo "Stream has hung (by frame)"
            printf "%s - Stream has hung (by frame)\n" "$(date)" >> stream.log
            pkill ffmpeg
            echo "killed ffmpeg..."
            printf "%s - Killed ffmpeg...\n" "$(date)" >> stream.log
            echo "Waiting 5 secs"
            sleep 5
            bash /home/satoshi/server/ffmpeg.sh &
            echo "started ffmpeg.."
            printf "%s - Started ffmpeg..\n" "$(date)" >> stream.log
            echo "Waiting 30 secs"
            sleep 30
            same_frame_count=0
        fi
    else
        echo "Frame has changed."
        same_frame_count=0
    fi
    last_frame="$frame"
    sleep 10
done

Das Skript überprüft den Stream mithilfe der Datei "ffmpeg.log" auf Aktualisierungen und startet das Skript "ffmpeg.sh" gegebenenfalls neu. Tritt ein Fehler auf und wird der Stream gestoppt oder gestartet, wird dies in die Datei "stream.log" protokolliert.

Test des Checker

sh /home/satoshi/server/checker.sh

Autostart des Checker-Service – Start des Streams

Der Checker sollte auch bei einem Neustart des VPS automatisch starten. Dazu wird ein checker.service angelegen.

sudo nano /etc/systemd/system/checker.service

Befüllen mit

[Unit]
Description=Checker

[Service]
WorkingDirectory=/home/satoshi/server/
ExecStart=/bin/bash /home/satoshi/server/checker.sh

[Install]
WantedBy=multi-user.target

Achte auf den den Shebang /bin/bash

Nützliche Befehle

sudo systemctl enable checker.service
sudo systemctl start checker.service
sudo systemctl status checker.service
sudo systemctl stop checker.service
sudo systemctl disable checker.service
sudo systemctl daemon-reload
sudo journalctl -u checker -f --since "1 hour ago"

Die beiden Log Dateien stream.log und ffmpeg.log kann man auslesen und mit du -sh die aktuelle Größe anzeigen lassen.

cat stream.log
cat ffmpeg.log
du -sh ffmpeg.log
du -sh stream.log

Cronjob zum löschen der ffmpeg.log

Die ffmpeg.log-Datei wächst ganz schön, und das Durchsuchen der Datei nach gleichen Frames in einer immer weiter anwachsenden Datei scheint die CPU doch ziemlich zu belasten. Man kann sehen, wie die CPU-Last steigt.

CPU Last proportional zu Größe des Log Files. Löschung um 1 und 13 Uhr

Eine echte Lösung dafür habe ich noch nicht gefunden, aber eine Notlösung: Die Datei wird einfach in einem bestimmten Intervall gelöscht. Der Checker registriert das und startet dann alles einmal neu.

sudo crontab -e

Folgenden Eintrag ans Ende machen

0 */12 * * * sudo rm /home/satoshi/server/ffmpeg.log

-> Die Log Dateien werden alle 12 Stunden jeweils um 00:00 und 12:00 Uhr gelöscht.

0 0 * * * sudo rm /home/satoshi/server/ffmpeg.log

-> Die Log Dateien werden um 00:00 UTC (Coordinated Universal Time) gelöscht

Logs prüfen

sudo grep CRON /var/log/syslog

Funktioniert es nicht und man möchte mehr Informationen über die Ursache erhalten, kann man die Meldung in eine Log Datei schreiben die man auslesen kann. Hier z.B. alle 5 Minuten den Befehl ausführen und loggen:

*/5 * * * * sudo rm /home/test/ffmpeg.log 2>&1 | logger -t mycmd

Anzeigen mit

sudo grep 'mycmd' /var/log/syslog

Laravel PHP-Server

Auf der Webseite werden drei verschiedene Daten angezeigt:

  1. Wallet-Guthaben
  2. Voucher-Zähler
  3. (Spenden-)Transaktionswert und Notiz zur Transaktion

Während das Auslesen der Daten für 1. und 3. rein über die LNbits Wallet API erfolgt, erfordert der Gutschein-Zähler etwas mehr Aufwand. Es muss eine Methode zur Aufsummierung der Anzahl implementiert werden. Die Integration von 1. und 3. in die Webseite wäre relativ einfach. Hierfür benötigt man lediglich eine HTML-Seite.

<!DOCTYPE html>
<html>
<head>
    <title>LNbits Wallet Information</title>
</head>
<body>
    <h1>LNbits Wallet Information</h1>
    <p><h4>Wallet Balance:  <big><span id="wallet-balance"></span></big></h4> </p>
    <p><h4>Payment Comments:</h4></p>
    <ul id="payment-comments"></ul>

<div onclick="javascript:location.reload();">[Aktualisieren]</div>

<script src="script.js"></script>

</body>
</html>

Und ein Script.js

document.addEventListener('DOMContentLoaded', async function() {
    // LNbits API Configuration
    const LNBITS_URL = "https://lnbits.yourdomain.xyz";
    const LNBITS_APIKEY = "youlnbitsapikey";

    // API Call to get payment comments
    const payment_url = `${LNBITS_URL}/api/v1/payments/`;
    const headers = new Headers();
    headers.append("Content-Type", "application/json");
    headers.append("X-Api-Key", LNBITS_APIKEY);

    const response = await fetch(payment_url, { headers });
    const data = await response.json();

    const paymentList = document.getElementById('payment-comments');
    let count = 0; // Zähler für die Anzahl der Einträge

    for (let i = 0; i < data.length && count < 5; i++) {
        const payment = data[i];

        if (payment.extra && payment.extra.tag === "lnurlp") {
            const comment = payment.extra.comment && payment.extra.comment[0] ? payment.extra.comment[0] : "-";
            const amount = payment.amount / 1000; 
            const listItem = document.createElement('li');
            listItem.textContent = `Amount: ${amount} sats, Comment: ${comment}`; 
            paymentList.appendChild(listItem);
            count++; // Zähler erhöhen
        }
    }

    // API Call to get wallet balance
    const wallet_url = `${LNBITS_URL}/api/v1/wallet`;
    const walletResponse = await fetch(wallet_url, { headers });
    const walletData = await walletResponse.json();

    const walletBalanceElement = document.getElementById('wallet-balance');
    const walletBalance = walletData.balance / 1000; 
    walletBalanceElement.textContent = `${walletBalance} sats`; 
});

Die Veröffentlichung der LNbits-URL und des Invoice-/Read-Keys auf der Webseite könnte potenziell missbraucht werden. Obwohl es sich nicht um den Admin-Key handelt, ist es dennoch unerwünscht, solche Informationen auf der Webseite preiszugeben. Obwohl es JavaScript Obfuscator Tools gibt, die JavaScript-Code verschleiern können und somit das Auffinden von Schlüsselwörtern wie "LNBITS_APIKEY" erschweren, ist dies keine sichere Lösung. Da der Webserver den verschleierten Code lesen kann, besteht die Möglichkeit, den Code wiederherzustellen.

Eine bessere Lösung ist daher die Verwendung eines separaten Servers, der die Daten liefert, jedoch keinen direkten Zugriff auf die Schnittstelle zum LNbits-Server ermöglicht. Hierfür kann ein eigener VPS (Virtual Private Server) eingerichtet werden, auf dem ein Laravel-Server für das PHP-Framework läuft. Auf diesem Server wird auch die Addition für den Gutschein-Zähler durchgeführt. Die Wallet-Daten sind in einem geschützten Bereich und von außen nicht einsehbar.

Ich muss zugeben, dass dies meine Fähigkeiten übersteigt, weshalb ich Hilfe von Ben in Anspruch genommen habe. Er hat einen Server eingerichtet und den Code für die LNbits-Bridge geschrieben. Obwohl ich mich nicht im Detail damit auskenne, kann ich die Parameter auf dem Server anpassen.

Eine echt Hilfe – ChatGPT

Und zu guter Letzt, natürlich noch ChatGPT. Der persönliche Assistent und wandelndes Lexikon. Er kann einem helfen Lösungen für Probleme finden, komplizierte Zusammenhänge gut erklären oder einfach nur auf die Sprünge helfen, wenn man mal nicht mehr weiter weiß.


Bitcoin ist eine Revolution, die sich selbst schützt,
indem sie die Revolutionäre reich und unbestechlich macht.

unknown

Erstellt mit Liebe 🧡 Seit 829980 / 832856

– Lightning ⚡ (er)leben –