# FNA-Steuerung

Eine Ampelsteuerung für das FieldNet

# Vorraussetzungen und Funktionen

### Voraussetzungen

Für die Steuerung wird ein PC/Gerät benötigt, auf dem Docker läuft und installiert ist. Dies kann ein Notebook (Windows, Linux, Mac) aber auch ein PC/Raspberry Pi sein. Bei einem Gerät ohne Bildschirm, wie bei einem Raspberry wird noch ein Eingabegerät oder eine Fernbedienung benötigt. Dies kann ein Smartphone, Tablet oder ein zweites Notebook sein.

### Funktionen

- Hellichkeit der Ampel einstellbar
- Lautsträke der Hupe einstellbar
- Vorlaufzeit frei definierbar
- Schusszeit wird durch Anzahl der Pfeile sowie der Zeit pro Pfeil definiert
- AB/CD Gruppen Modus
- Alternierend Einzeln
- Alternierend Mannschaft
- Nachschießen mit Anzahl der Pfeile als Zwischensequenz einstellbar
- Stechen beim Alernierend als Zwischensequenz einstellbar
- Automatisches Schießleiterprotokoll + PDF Download
- Einzelne Voreinstellungen (Halle, Finale, Liga, etc.) kann angepasst und gespeichert werden

# Installation

In diesem Kampitel geht es um die Installation und Update der Software

# Windows

### Vorraussetungen

- Docker Dektop installiert (Anleitungen gibt es auf der Offiziellen Website oder im Internet)

### Projektdateien und Software

- [Docker-Compose Datei](https://codeberg.org/BSApp/FieldNetAmpel-DockerInfrastructur/src/branch/main/docker-compose.yaml)

### Benötigtes Material

<table border="1" id="bkmrk-anzahl-art-link-1-m4" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 33.3333%;"></col><col style="width: 33.3333%;"></col><col style="width: 33.3333%;"></col></colgroup><tbody><tr><td>**Anzahl**</td><td>**Art**</td><td>**Link**</td></tr><tr><td>1</td><td>Notebook</td><td>  
</td></tr></tbody></table>

### Anleitung - Start/Installation der Steuerung

#### 1. Docker Desktop starten

Die Ampelsteuerung ist in einzelne Module aufgeteilt. Diese kommunizieren miteinander über eine ValKey/Redis Datenbank. Um die Benutzung der Software möglichst einfach zu gestalten sind alle Module in Docker Container geschachtelt. Um diese starten zu können, müssen wir in Docker Desktop die einzelnen Container miteinander starten. Dies funktioniert am einfachsten über eine Docker Compose Datei. Hierfür muss starten wir als erstes Docker Desktop. Unsere Oberfläche für das starten und stopen von Docker Container.

#### 2. Docker Compose Stack starten

Um Docker Desktop unsere Container und wie sie miteinander arbeiten sollen beizubrigen benötigen wir die bereitgestellte Docker-Compose Datei. Bei dem Compose module von Docker handelt es sich um eine automatisch installierte erweiterung, welche uns anhand einer .yaml Datei mehrere Container als einen zusammenhängenden Dienst starten lassen. Weiterhin können wir darin abhängigkeiten und Konfigurationen mitgeben. Da diese Datei nicht in der Oberfläche hinzugefügt werden kann müssen wir diese in einen Ordner legen und über die CMD einen Befehl absetzen.

1. Lege die Datei in einem Ordner mit dem Namen "FNA-Steuerung" auf deinem PC ab.
2. Starte eine Kommandozeile in diesem ordner. Rechtsklick in dem Ordner und "In Terminal öffnen" auswählen [![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-03/scaled-1680-/YkUALvAJNClwQPx6-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-03/YkUALvAJNClwQPx6-image.png)
3. In der Komandozeile geben wir folgenden Befehl ein `docker compose up -d`, dieser startet anhand der "docker-compose.yaml" Datei die entsprechenden Container im Hintergrund. (ohne -d würden wir die Ausgabe der Container sehen und beim schließen der Kommandozeile würde die Steuerng beendet werden)
4. Es werden nun die benötigten Docker Images heruntergeladen und dannach gestartet [![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-03/scaled-1680-/VYGXFlNGNyJoXycd-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-03/VYGXFlNGNyJoXycd-image.png)
    
    [![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-03/scaled-1680-/B1YstDQ758vCsVqb-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-03/B1YstDQ758vCsVqb-image.png)
5. Nun ist wird dieser auch in Docker Desktop angezeigt und kann dort gestartet und gestoppt werden

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-03/scaled-1680-/TNN8iB9tQgjv838U-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-03/TNN8iB9tQgjv838U-image.png)

#### 3. WebUI öffnen

Nachdem die Container nun laufen kann auf die Weboberfläche (WebUI) der Steuerng zugegriffen werden. Diese läuft auf Port 80. Im Browser die URL [http://127.0.0.1](http://127.0.0.1) eingeben.

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-03/scaled-1680-/XXQPexrYUXMxfvgp-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-03/XXQPexrYUXMxfvgp-image.png)

Eine Detailierte Anleitung, wie die Steuerung bedient werden kann gibt es in anderen Kapitel.

### Anleitung - Stoppen der Steuerung

Die Steuerung kann über den Docker Desktop einfach gestoppt und gestartet werden. Hierzu unter Container bei der fna-steuerung unter Aktionen Starten bzw. stoppen. Solltest du die Software nicht manuell stoppen, wird sie beim nächsten Start von Docker Desktop, oder deinem PC automatisch gestartet.

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-03/scaled-1680-/CKJxbltPAkpbuYWZ-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-03/CKJxbltPAkpbuYWZ-image.png)

<span style="background-color: rgb(241, 196, 15);">**WICHTIG**: Im Netzwerk darf nur eine Steuerung gleichzeitig laufen, da sonst die Anzeigegeräte unterschiedliche Informationen erhalten.</span>

### Anleitung - Update der Steuerung

Um die Steuerung auf den aktuellen Stan zu bringen müssen die Container gestoppt werden. Im Anschluss wechselt man auf den Reiter Images, wählt bei Actions die 3 Punkte aus und klickt auf Pull. Dadurch wird die neuste Version der Software heruntergeladen. Du musst dies für alle 4 Images machen einzeln machen.

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-03/scaled-1680-/NTq5YGHunp5JneuW-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-03/NTq5YGHunp5JneuW-image.png)

# Linux

### Vorraussetungen

- Docker und Docker Compose installiert (Anleitungen für deine Distribution gibt es meist auf der offiziellen Docker Website)
- Diese Anleitung legt eine Debianbasierte Distribution zu grunde.

### Projektdateien und Software

- [Docker Compose YAML Datei](https://codeberg.org/BSApp/FieldNetAmpel-DockerInfrastructur/src/branch/main/docker-compose.yaml)

### Benötigtes Material

<table border="1" id="bkmrk-anzahl-art-link-1-m4" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 33.3333%;"></col><col style="width: 33.3333%;"></col><col style="width: 33.3333%;"></col></colgroup><tbody><tr><td>**Anzahl**</td><td>**Art**</td><td>**Link**</td></tr><tr><td>1</td><td>Linux PC / Raspberry Pi / o.ä.</td><td>  
</td></tr></tbody></table>

### Anleitung - Start/Installation der Steuerung

#### 1. Ordner anlegen und Docker Compose Datei ablegen

Als erstes erstellen wir im Home Verzeichnis einen Ordner namens fna-steuerung

```shell
## Optional, wenn wget nicht installiert ist
sudo apt install wget -y
## Erstellen des Ordners fna-steuerung
cd ~
mkdir fna-steuerung
cd fna-steuerung
## Downloaden der docker-compose.yaml
wget https://gitlab.gras-it.de/bsapp/fieldnet-ampel/fna-docker-infrastructur/-/blob/e561a872b02b854c72ce75088ba0750fe36b8028/docker-compose.yaml
```

#### 2. Starten des Docker Compose Service

Nachdem wir die docker-compose.yaml Datei heruntergeladen haben können wir den Service starten

```shell
## Springen in den Ordner fna-steuerung
cd ~/fna-steuerung
## Starten des Services
#Je nach dem ob der Benutzer in der docker Gruppe ist mit oder ohne SUDO
#Ist der Benutzer in der docker gruppe kann das sudo weggelassen werden
sudo docker compose up -d
```

#### 3. Öffnen der WebUI

Nachdem die Container nun laufen kann auf die Weboberfläche (WebUI) der Steuerng zugegriffen werden. Diese läuft auf Port 80. Im Browser die URL [http://127.0.0.1](http://127.0.0.1/) eingeben. Alternativ, wenn die Steuerung ohne Bildschirm betrieben wird, dann auf dem Gerät mit Bildschirm (Notebook / Smartphone / Tablet) die IP Adresse oder der DNS Name des "Servers" eingeben. z.B. [http://10.0.1.10](http://10.0.1.10) oder [http://sv-ampel](http://sv-ampel)

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-03/scaled-1680-/XXQPexrYUXMxfvgp-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-03/XXQPexrYUXMxfvgp-image.png)

### Anleitung - Stoppen der Steuerung

Die steuerung kann über ein docker compose down gestoppt werden. Solltest du die Software nicht manuell stoppen, wird sie beim nächsten Start von deinem PC automatisch gestartet.

```shell
## Springen in den Ordner fna-steuerung
cd ~/fna-steuerung
## Stoppen des Services
#Je nach dem ob der Benutzer in der docker Gruppe ist mit oder ohne SUDO
#Ist der Benutzer in der docker gruppe kann das sudo weggelassen werden
sudo docker compose down
```

<span style="background-color: rgb(241, 196, 15);">**WICHTIG**: Im Netzwerk darf nur eine Steuerung gleichzeitig laufen, da sonst die Anzeigegeräte unterschiedliche Informationen erhalten.</span>

### Anleitung - Update der Steuerung

Die steuerung kann mit einem einfachen docker compose pull und einem neuerstellen beim Start durchgeführt werden. Hierzu muss der Servie auf jeden fall gestoppt sein.

```shell
## Springen in den Ordner fna-steuerung
cd ~/fna-steuerung
## Stoppen des Services
sudo docker compose down
## Starten des Services
#Je nach dem ob der Benutzer in der docker Gruppe ist mit oder ohne SUDO
#Ist der Benutzer in der docker gruppe kann das sudo weggelassen werden
sudo docker compose pull
sudo docker compose up --force-recreate -d
sudo docker image prune -f
```

# Mac OS

## Voraussetzungen

Docker Desktop installiert (Anleitungen gibt es auf der offiziellen Website oder im Internet)

### Projektdateien und Software

[Docker-Compose Datei](https://codeberg.org/BSApp/FieldNetAmpel-DockerInfrastructur/src/branch/main/docker-compose.yaml)

### Benötigtes Material

<table id="bkmrk-anzahl-art-link-1-ma"><tbody><tr><th>Anzahl</th><th>Art</th><th>Link</th></tr><tr><td>1</td><td>Mac</td><td> </td></tr></tbody></table>

## Anleitung - Start/Installation der Steuerung

### 1. Docker Desktop starten

Die Ampelsteuerung ist in einzelne Module aufgeteilt. Diese kommunizieren miteinander über eine ValKey/Redis Datenbank. Um die Benutzung der Software möglichst einfach zu gestalten sind alle Module in Docker Container geschachtelt. Um diese starten zu können, müssen wir in Docker Desktop die einzelnen Container miteinander starten. Dies funktioniert am einfachsten über eine Docker Compose Datei. Hierfür starten wir als erstes Docker Desktop. Unsere Oberfläche für das Starten und Stoppen von Docker Container.

### 2. Docker Compose Stack starten

Um Docker Desktop unsere Container und wie sie miteinander arbeiten sollen beizubringen benötigen wir die bereitgestellte Docker-Compose Datei. Bei dem Compose Modul von Docker handelt es sich um eine automatisch installierte Erweiterung, welche uns anhand einer .yaml Datei mehrere Container als einen zusammenhängenden Dienst starten lassen. Weiterhin können wir darin Abhängigkeiten und Konfigurationen mitgeben. Da diese Datei nicht in der Oberfläche hinzugefügt werden kann müssen wir diese in einen Ordner legen und über das Terminal einen Befehl absetzen.

1. Lege die Datei in einem Ordner mit dem Namen "FNA-Steuerung" auf deinem Mac ab.
2. Starte ein Terminal in diesem Ordner. Rechtsklick in dem Ordner im Finder und "Neues Terminal beim Ordner" auswählen oder öffne das Terminal und navigiere mit **cd** zum entsprechenden Ordner
3. Im Terminal geben wir folgenden Befehl ein: **docker compose up -d**, dieser startet anhand der "docker-compose.yaml" Datei die entsprechenden Container im Hintergrund. (ohne -d würden wir die Ausgabe der Container sehen und beim Schließen des Terminals würde die Steuerung beendet werden)
4. Es werden nun die benötigten Docker Images heruntergeladen und danach gestartet
5. Nun wird dieser auch in Docker Desktop angezeigt und kann dort gestartet und gestoppt werden

### 3. WebUI öffnen

Nachdem die Container nun laufen kann auf die Weboberfläche (WebUI) der Steuerung zugegriffen werden. Diese läuft auf Port 80. Im Browser die URL http://127.0.0.1 eingeben.

Eine detaillierte Anleitung, wie die Steuerung bedient werden kann gibt es in anderen Kapiteln.

## Anleitung - Stoppen der Steuerung

Die Steuerung kann über Docker Desktop einfach gestoppt und gestartet werden. Hierzu unter Container bei der fna-steuerung unter Aktionen Starten bzw. Stoppen. Solltest du die Software nicht manuell stoppen, wird sie beim nächsten Start von Docker Desktop, oder deinem Mac automatisch gestartet.

**WICHTIG:** Im Netzwerk darf nur eine Steuerung gleichzeitig laufen, da sonst die Anzeigegeräte unterschiedliche Informationen erhalten.

## Anleitung - Update der Steuerung

Um die Steuerung auf den aktuellen Stand zu bringen müssen die Container gestoppt werden. Im Anschluss wechselt man auf den Reiter Images, wählt bei Actions die 3 Punkte aus und klickt auf Pull. Dadurch wird die neueste Version der Software heruntergeladen. Du musst dies für alle 4 Images einzeln machen.

# Die WebUI

Wie wir die Webbasierte Oberfläche verwendet. Wie stelle ich die Ampel korrekt ein und wie nutze ich diese in einem Wettkampf

# Benutzen der Steuerung

# Hauptoberfläche (Main Interface)

Die Weboberfläche der FNA-Steuerung ist über den Browser erreichbar (z. B. `http://sv-ampel` oder `http://127.0.0.1`).

Um nicht mit jedem Gerät im Netzwerk die Ampel steuern zu können, muss man sich Anmelden. Der 6 stellige initiale Pin lautet 123456.

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-04/scaled-1680-/NHXGuG6Vv6nwzYUz-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-04/NHXGuG6Vv6nwzYUz-image.png)

Je nach konfiguriertem Modus erscheint eine von zwei Ansichten: der **Standard-Modus** für Wettkämpfe und Liga

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-04/scaled-1680-/eVTSe22QUjE8BjbC-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-04/eVTSe22QUjE8BjbC-image.png)

sowie der **Alternierend-Modus**

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-04/scaled-1680-/9OQFJX5skQHWDx3Z-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-04/9OQFJX5skQHWDx3Z-image.png)

---

## Kurzübersicht

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-04/scaled-1680-/wqHxg6lkASsdMI3l-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-04/wqHxg6lkASsdMI3l-image.png)

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-04/scaled-1680-/3ltttVRDng9cwv4f-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-04/3ltttVRDng9cwv4f-image.png)

---

## Steuerleiste

Die vier Schaltflächen oben sind in beiden Ansichten identisch vorhanden.

<table id="bkmrk-schaltfl%C3%A4che-funktio" style="width: 100%;"><thead><tr><th style="width: 12.2721%;">Schaltfläche</th><th style="width: 87.7279%;">Funktion</th></tr></thead><tbody><tr><td style="width: 12.2721%;">**START**</td><td style="width: 87.7279%;">Startet die aktive Schusssequenz. Die Ampel beginnt mit der konfigurierten Vorlaufzeit.</td></tr><tr><td style="width: 12.2721%;">**STOPP**</td><td style="width: 87.7279%;">Bricht die laufende Sequenz sofort ab. Die Ampel wechselt auf Rot.</td></tr><tr><td style="width: 12.2721%;">**GEFAHR**</td><td style="width: 87.7279%;">Löst ein Gefahrensignal aus: Die Hupe ertönt 5-mal, die Ampel wechselt sofort auf Rot. Nach Beenden des Gefahrenmodus setzt die Ampel an der Stelle fort, an der sie unterbrochen wurde.</td></tr><tr><td style="width: 12.2721%;">**WECHSEL**</td><td style="width: 87.7279%;">Abhängig vom aktiven Modus – siehe die jeweiligen Abschnitte unten.</td></tr></tbody></table>

> **Hinweis:** STOPP und GEFAHR sind unterschiedliche Aktionen. STOPP beendet die Sequenz kontrolliert und endgültig. GEFAHR unterbricht die laufende Sequenz für eine Sicherheitssituation und setzt sie danach automatisch fort.

---

## Standard-Modus (Wettkampf / Liga)

Dieser Modus wird für normale Wettkämpfe und Ligabetrieb verwendet. Alle Ampelanlagen geben die gleichen Informationen aus.

### Anzeigebereich

Der mittlere Bereich zeigt zwei Informationen nebeneinander:

**Links – Ampelstatus und Zeit:** Die drei farbigen Felder (Rot, Gelb, Grün) spiegeln den aktuellen Zustand der physischen Ampel wider. Inaktive Farben erscheinen dunkel/gedimmt, die aktive Farbe leuchtet hell. Die große Zahl darunter zeigt die **verbleibenden Sekunden** im aktuellen Schussabschnitt.

**Rechts – Gruppe:** Das Kürzel **AB** oder **CD** zeigt an, welche Gruppe gerade an der Reihe ist.

### WECHSEL im Standard-Modus

Im Standard-Modus wechselt **WECHSEL** die aktive Gruppe von AB nach CD (oder umgekehrt). Dies wird eingesetzt, wenn die Gruppen abwechselnd auf die Scheibe schießen.

### Untere Schaltflächen

Die untere linke Schaltfläche ändert sich je nach Konfiguration:

<table id="bkmrk-schaltfl%C3%A4che-wann-si" style="width: 100%; height: 186.375px;"><thead><tr style="height: 46.5938px;"><th style="width: 17.2825%; height: 46.5938px;">Schaltfläche</th><th style="width: 20.1288%; height: 46.5938px;">Wann sichtbar</th><th style="width: 62.5887%; height: 46.5938px;">Funktion</th></tr></thead><tbody><tr style="height: 46.5938px;"><td style="width: 17.2825%; height: 46.5938px;">**NACHSCHIESSEN**

</td><td style="width: 20.1288%; height: 46.5938px;">Nachschießen nicht konfiguriert</td><td style="width: 62.5887%; height: 46.5938px;">Startet eine Nachschieß-Sequenz für einzelne Athleten, die einen oder mehrere Pfeile nachholen müssen. Die Anzahl der Nachschusspfeile ist in den Einstellungen konfigurierbar.</td></tr><tr style="height: 46.5938px;"><td style="width: 17.2825%; height: 46.5938px;">**BEENDEN / ANPASSEN**</td><td style="width: 20.1288%; height: 46.5938px;">Nachschießen konfiguriert</td><td style="width: 62.5887%; height: 46.5938px;">Beendet das Nachschießen und wechselt wieder in den vorherigen Modus</td></tr><tr style="height: 46.5938px;"><td style="width: 17.2825%; height: 46.5938px;">**EINSTELLUNGEN**</td><td style="width: 20.1288%; height: 46.5938px;">Immer</td><td style="width: 62.5887%; height: 46.5938px;">Öffnet die Konfigurationsseite für Zeiten, Modi und Voreinstellungen.</td></tr></tbody></table>

---

## Alternierend-Modus

Im Alternierend-Modus schießen zwei Mannschaften oder Athleten abwechselnd. Dabei sind **zwei separate Ampeln** (A1 links, A2 rechts) aktiv, die unabhängig voneinander gesteuert werden.

### Anzeigebereich

Der Anzeigebereich ist horizontal in zwei gleichwertige Hälften geteilt:

**Linke Hälfte (A1):** Zeigt den Ampelstatus von Ampel 1 (Rot, Gelb, Grün) sowie darunter die **verbleibenden Sekunden** für diese Ampel.

**Rechte Hälfte (A2):** Zeigt den Ampelstatus von Ampel 2 (Rot, Gelb, Grün) sowie darunter die **verbleibenden Sekunden** für diese Ampel.

Beide Ampeln laufen im Wechsel: Während eine Ampel auf Grün schaltet (Schussfreigabe), bleibt die andere auf Rot.

### WECHSEL im Alternierend-Modus

Im Alternierend-Modus bestimmt **WECHSEL**, welche Ampel (links oder rechts) den ersten Durchgang beginnt. Dies kann vor dem START genutzt werden, um die Startreihenfolge festzulegen.

### Untere Schaltflächen

<table id="bkmrk-schaltfl%C3%A4che-funktio-1" style="width: 100%;"><thead><tr><th style="width: 19.2996%;">Schaltfläche</th><th style="width: 80.7004%;">Funktion</th></tr></thead><tbody><tr><td style="width: 19.2996%;">**STECHEN**</td><td style="width: 80.7004%;">Startet eine Stechen-Sequenz für Entscheidungssituationen. Im Alternierend-Modus gibt es kein Nachschießen – stattdessen steht diese Schaltfläche zur Verfügung.</td></tr><tr><td style="width: 19.2996%;">**EINSTELLUNGEN**</td><td style="width: 80.7004%;">Öffnet die Konfigurationsseite.</td></tr></tbody></table>

---

## Schnellübersicht: Unterschiede der beiden Modi

<table id="bkmrk-merkmal-standard-mod"><thead><tr><th>Merkmal</th><th>Standard-Modus</th><th>Alternierend-Modus</th></tr></thead><tbody><tr><td>Anzahl Ampeln</td><td>1</td><td>2 (A1 links, A2 rechts)</td></tr><tr><td>Zeitanzeige</td><td>Verbleibende Sekunden + Gruppe AB/CD</td><td>Verbleibende Sekunden je Ampel</td></tr><tr><td>WECHSEL-Funktion</td><td>Gruppe AB ↔ CD wechseln</td><td>Startreihenfolge (links/rechts) festlegen</td></tr><tr><td>Nachschießen</td><td>✓ Möglich (wenn konfiguriert)</td><td>✗ Nicht verfügbar</td></tr><tr><td>Stechen</td><td>✗ Nicht verfügbar</td><td>✓ Möglich</td></tr><tr><td>GEFAHR-Verhalten</td><td>Hupe 5× + sofort Rot, danach Fortsetzung</td><td>Hupe 5× + sofort Rot, danach Fortsetzung</td></tr></tbody></table>

# Einstellen der Parameter (Zeiten und Modis)

Die Einstellungsseite der FNA-Steuerung ist in zwei Bereiche aufgeteilt: **Allgemein** (links) und **Wettkampf** (rechts). Über den Button **← Zurück** gelangst du jederzeit zur Hauptsteuerung zurück.

---

## Übersicht der Einstellungsseite

[![2026-04-27 16_39_36-2026-04-27 16_36_48-Greenshot.png - Greenshot - Editor.png](https://docs.bsapp.de/uploads/images/gallery/2026-04/KxZDPFXlbnHuJlQt-2026-04-27-16-39-36-2026-04-27-16-36-48-greenshot-png-greenshot-editor.png)](https://docs.bsapp.de/uploads/images/gallery/2026-04/uGk04txMImacKh3Y-image.png)

> Die Einstellungsseite ist unter `http://<IP-Adresse>/settings` erreichbar oder direkt über den Button **⚙ EINSTELLUNGEN** auf der Hauptseite.

---

## Bereich: Allgemein

### Ampel Helligkeit

Stellt die Helligkeit der Ampel-Anzeigegeräte ein.

<table id="bkmrk-eigenschaft-wert-min"><thead><tr><th>Eigenschaft</th><th>Wert</th></tr></thead><tbody><tr><td>Minimum</td><td>0 (aus)</td></tr><tr><td>Maximum</td><td>100 (volle Helligkeit)</td></tr></tbody></table>

Mit den **+** und **−** Buttons kannst du den Wert schrittweise anpassen.

---

### Lautstärke Hupe

Stellt die Lautstärke der akustischen Signale (Hupe) ein.

<table id="bkmrk-eigenschaft-wert-min-1"><thead><tr><th>Eigenschaft</th><th>Wert</th></tr></thead><tbody><tr><td>Minimum</td><td>0 (stumm)</td></tr><tr><td>Maximum</td><td>100 (volle Lautstärke)</td></tr><tr><td>Standard</td><td>80</td></tr></tbody></table>

Mit den **+** und **−** Buttons kannst du den Wert schrittweise anpassen.

---

## Bereich: Wettkampf

Hier werden die Parameter für den Schießbetrieb konfiguriert. Alle Änderungen werden erst mit **✓ Speichern und zurück** übernommen.

---

### Vorauswahl

Über das Dropdown-Menü kannst du ein gespeichertes Preset auswählen (z. B. *Finale Einzel*, *Liga*, *Halle*).

> **Hinweis:** Das Laden einer Vorauswahl überschreibt automatisch die Felder **Vorbereitungszeit**, **Zeit pro Pfeil**, **Anzahl Pfeile** und **Modus**. Der Name sowie Helligkeit und Lautstärke bleiben unverändert.

Mit dem **🗑** (Papierkorb)-Button rechts neben der Vorauswahl kann das aktuell gewählte Preset gelöscht werden. Mit dem **+** (Plus)-Button links neben der Vorauswahl kann ein neues Preset erstellt werden.

---

### Name

Der Name des aktuellen Einstellungsprofils. Dieser Name wird in der Vorauswahl-Liste angezeigt.

---

### Vorbereitungszeit

Die Vorbereitungszeit ist die Zeit (in Sekunden) zwischen dem **doppelten Hupsignal** (Schützen an die Scheibe) und dem **Startsignal** (grünes Licht + ein Hupsignal).

<table id="bkmrk-signal-bedeutung-2%C3%97-"><thead><tr><th>Signal</th><th>Bedeutung</th></tr></thead><tbody><tr><td>2× Hupe</td><td>Schützen begeben sich an die Schießlinie</td></tr><tr><td>Vorbereitungszeit läuft</td><td>Schützen bereiten sich vor</td></tr><tr><td>Grün + 1× Hupe</td><td>Freigabe zum Schießen</td></tr></tbody></table>

Mit den **+** und **−** Buttons anpassen.

---

### Zeit pro Pfeil

Gibt an, wie viel Zeit (in Sekunden) ein Schütze pro Pfeil zur Verfügung hat.

> **Beispiel:** Bei 20 Sekunden pro Pfeil und 3 Pfeilen ergibt sich eine Gesamtschießzeit von **60 Sekunden**.

---

### Anzahl Pfeile

Legt fest, wie viele Pfeile pro Durchgang geschossen werden.

Die **Gesamtschießzeit** errechnet sich aus:

```
Schießzeit = Anzahl Pfeile × Zeit pro Pfeil
```

> Diese Berechnung gilt für die Modi **KEIN** und **AB/CD**. Bei den alternierenden Modi (Alt. Einzel / Alt. Man.) läuft die Zeit anders ab – siehe unten.

---

### Modus

Der Modus bestimmt, wie die Schützen bzw. Mannschaften gegeneinander schießen.

<table id="bkmrk-modus-beschreibung-k" style="width: 100%;"><thead><tr><th style="width: 15.0075%;">Modus</th><th style="width: 84.9925%;">Beschreibung</th></tr></thead><tbody><tr><td style="width: 15.0075%;">**KEIN**</td><td style="width: 84.9925%;">Kein Gruppenformat – alle Schützen schießen gleichzeitig (z. B. Liga-Betrieb). Die Gesamtschießzeit ergibt sich aus Anzahl Pfeile × Zeit pro Pfeil.</td></tr><tr><td style="width: 15.0075%;">**AB/CD**</td><td style="width: 84.9925%;">Gruppenmodus: Gruppe A/B und C/D schießen abwechselnd. Die Schießzeit ergibt sich aus Anzahl Pfeile × Zeit pro Pfeil.</td></tr><tr><td style="width: 15.0075%;">**Alt. Einzel**</td><td style="width: 84.9925%;">Alternierend Einzel: Zwei Einzelschützen schießen abwechselnd. Die Ampel zeigt immer die Zeit für **einen Pfeil** an und wechselt nach jedem Pfeil zur anderen Seite.</td></tr><tr><td style="width: 15.0075%;">**Alt. Man.**</td><td style="width: 84.9925%;">Alternierend Mannschaft: Zwei Mannschaften schießen abwechselnd. Die Gesamtzeit wird vollständig angezeigt und **nicht** zurückgesetzt. Wenn eine Mannschaft ihren Pfeil geschossen hat, wird die Zeit angehalten, bis die andere Mannschaft an der Reihe war – dann läuft sie weiter.</td></tr></tbody></table>

#### Ablauf Alternierend Einzel (Alt. Einzel)

```
Schütze A schießt Pfeil 1  →  Wechsel  →  Schütze B schießt Pfeil 1
→  Wechsel  →  Schütze A schießt Pfeil 2  →  ...
```

Die Anzeige zeigt jeweils die Zeit für **einen einzelnen Pfeil**. Nach jedem Pfeil wechselt die Seite.

#### Ablauf Alternierend Mannschaft (Alt. Man.)

```
Mannschaft A jeder Schütze schießt ein Pfeil  →  Zeit stoppt  →  Mannschaft B jeder Schütze schießt ein Pfeil
→  Zeit stoppt  →  Mannschaft A jeder Schütze schießt ein Pfeil  →  ...

```

Die Gesamtzeit läuft durch und wird nur pausiert, wenn die andere Mannschaft schießt. Sie wird **nicht** zurückgesetzt.

---

## Speichern

Nach dem Anpassen aller gewünschten Parameter klicke auf:

> **✓ Speichern und zurück**

Die Einstellungen werden gespeichert und du kehrst zur Hauptsteuerung zurück. Das aktuelle Profil wird dabei unter dem eingetragenen **Namen** als Vorauswahl gespeichert bzw. aktualisiert.

---

> **Tipp:** Lege für häufig verwendete Wettkampfformate (z. B. Finale Einzel, Halle 18m, Liga) eigene Profile an, um schnell zwischen verschiedenen Einstellungen wechseln zu können.

# Schießleiterprotokoll

Das Schießleiterprotokoll ist eine automatisch erstellte Aufzeichnung aller relevanten Aktionen, die während einer Veranstaltung über die Ampelsteuerung durchgeführt wurden. Es dient als offizieller Nachweis für den Schießleiter und kann direkt aus der WebUI geöffnet und ausgedruckt werden.

---

## Übersicht der Protokoll-Schaltflächen

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-04/scaled-1680-/bQaIhq3DBbDAnHRc-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-04/bQaIhq3DBbDAnHRc-image.png)

Im Bereich **Protokoll** der Einstellungsseite stehen vier Schaltflächen zur Verfügung:

<table id="bkmrk-schaltfl%C3%A4che-funktio" style="width: 100%;"><thead><tr><th style="width: 35.305%;">Schaltfläche</th><th style="width: 64.695%;">Funktion</th></tr></thead><tbody><tr><td style="width: 35.305%;">📋 **Protokoll öffnen**</td><td style="width: 64.695%;">Öffnet das aktuelle Protokoll als PDF im Browser</td></tr><tr><td style="width: 35.305%;">🗑️ **Protokoll löschen**</td><td style="width: 64.695%;">Löscht alle gespeicherten Protokolleinträge unwiderruflich</td></tr><tr><td style="width: 35.305%;">🕐 **Uhrzeit einstellen**</td><td style="width: 64.695%;">Ermöglicht die manuelle Synchronisation der Systemzeit</td></tr><tr><td style="width: 35.305%;">⊘ **Einschießen**</td><td style="width: 64.695%;">Markiert die aktuelle Sitzung als Einschieß-Phase</td></tr></tbody></table>

> **Hinweis:** Die Schaltflächen befinden sich auf der Seite **Einstellungen**, erreichbar über den Button „EINSTELLUNGEN" auf der Hauptseite der WebUI.

---

## Protokoll öffnen

Ein Klick auf **„Protokoll öffnen"** generiert das Schießleiterprotokoll als PDF und öffnet es im Browser. Das Protokoll enthält:

- Kopfbereich mit Feldern für **Name**, **Veranstaltung**, **Datum** und **Unterschrift** (manuell auszufüllen nach dem Ausdruck)
- Eine tabellarische Auflistung aller Aktionen mit: 
    - **Zeitpunkt** – genaues Datum und Uhrzeit des Ereignisses
    - **Aktion** – z. B. START, STOPP, WECHSEL, NACHSCHIESSEN, STECHEN
    - **Infos** – zusätzliche Details wie aktiver Modus, Gruppe (AB/CD), Anzahl Pfeile oder Schützen

### Beispiel eines Protokolleintrags

<table id="bkmrk-zeitpunkt-aktion-inf"><thead><tr><th>Zeitpunkt</th><th>Aktion</th><th>Infos</th></tr></thead><tbody><tr><td>3.4.2026, 20:50:13</td><td>START gedrückt</td><td>AB/CD: –, Einschießen: False, Alternierend: True</td></tr><tr><td>3.4.2026, 20:49:37</td><td>STECHEN Einzeln</td><td>Anzahl Schützen: 2</td></tr><tr><td>3.4.2026, 20:48:41</td><td>NACHSCHIESSEN</td><td>Anzahl Pfeile: 3</td></tr></tbody></table>

Das PDF kann direkt aus dem Browser gedruckt oder gespeichert werden.

---

## Protokoll löschen

> ⚠️ **Achtung:** Das Löschen des Protokolls ist **nicht rückgängig** zu machen. Alle bisher gespeicherten Einträge werden dauerhaft entfernt.

Ein Klick auf **„Protokoll löschen"** (rot hinterlegt) entfernt sämtliche Protokolleinträge. Dies sollte erst nach dem Ausdruck bzw. der Speicherung des Protokolls für die zurückliegende Veranstaltung erfolgen – typischerweise zu Beginn einer neuen Veranstaltung, um ein sauberes Protokoll zu erhalten.

---

## Uhrzeit einstellen

Da die Ampelsteuerung auch **offline** betrieben werden kann, kann die interne Systemzeit von der tatsächlichen Uhrzeit abweichen – etwa nach einem Neustart ohne Internetzugang.

### Warum ist das wichtig?

Alle Protokolleinträge werden mit einem Zeitstempel versehen. Ist die Systemzeit falsch, stimmen die Zeitangaben im Protokoll nicht mit dem realen Ablauf überein. Durch das manuelle Einstellen der Uhrzeit werden neue Einträge mit der korrekten Zeit gespeichert.

### So stellen Sie die Uhrzeit ein

1. Öffnen Sie die **Einstellungen** über die Hauptseite der WebUI.
2. Klicken Sie im Bereich „Protokoll" auf **„Uhrzeit einstellen"**.
3. Tragen Sie die aktuelle Uhrzeit in das angezeigte Eingabefeld ein.
4. Bestätigen Sie die Eingabe.

> ⚠️ **Wichtig:** Die Uhrzeitkorrektur wirkt sich **nur auf zukünftige Einträge** aus. Bereits im Protokoll gespeicherte Einträge werden **nicht nachträglich angepasst**. Stellen Sie die Uhrzeit daher **vor Beginn der Veranstaltung** ein.

---

## Einschießen

Die Schaltfläche **„Einschießen"** kennzeichnet eine Schießphase explizit als Einschieß-Durchgang. Ist der Einschieß-Modus aktiv, wird dies in jedem Protokolleintrag unter **Infos** vermerkt (`Einschießen: True`).

### Verwendung

- Aktivieren Sie „Einschießen" **vor** dem Start einer Einschieß-Phase.
- Alle während dieser Phase protokollierten Aktionen (START, STOPP usw.) werden entsprechend als Einschießen markiert.
- Deaktivieren Sie den Modus wieder, bevor die reguläre Wettkampfphase beginnt, damit die Protokollierung korrekt unterscheidet.

---

## Empfohlene Vorgehensweise bei einer Veranstaltung

1. **Vor der Veranstaltung:**
    
    
    - Uhrzeit prüfen und ggf. über **„Uhrzeit einstellen"** synchronisieren.
    - Altes Protokoll der vorherigen Veranstaltung exportieren/drucken.
    - Protokoll über **„Protokoll löschen"** zurücksetzen.
2. **Während der Veranstaltung:**
    
    
    - Einschießen über den Button **„Einschießen"** markieren.
    - Die Steuerung protokolliert alle Aktionen automatisch im Hintergrund.
3. **Nach der Veranstaltung:**
    
    
    - Über **„Protokoll öffnen"** das PDF generieren.
    - Protokoll ausdrucken und mit Name, Veranstaltung, Datum und Unterschrift vervollständigen.
    - Das ausgefüllte Protokoll zu den Veranstaltungsunterlagen nehmen.

# Sicherheit

In den Einstellungen gibt es zwei bereiche zum Thema Sicherheit.

### Bereich: PIN

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-04/scaled-1680-/H8M6c9qGxRc5v1qR-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-04/H8M6c9qGxRc5v1qR-image.png)

Hier kann über die Schaltfläche PIN ändern der Loginpin für die Anmeldung angepasst werden. Der Standard PIN ist 123456.

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-04/scaled-1680-/Hl2gY0eVjZhuJPfq-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-04/Hl2gY0eVjZhuJPfq-image.png)

---

### Bereich: Geräte

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-04/scaled-1680-/sJSRGnmtVSkx47Kt-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-04/sJSRGnmtVSkx47Kt-image.png)

Verschiedene Arten von Geräte müssen mit der Steuerung interagieren haben aber oft eine Möglichkeit zur Eingabe eines PIN's. Für dieses Problem gibt es die Möglichkeit Geräte für den Endpunkt /api/cmd freizuschalten. Sobald sich ein Gerät, zum Beispiel eine Fernbedienung für den Kampfrichter, an der Steuerung meldet, erscheint dieses in dieser Auflistung und kann genehmigt werden.

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-04/scaled-1680-/dmSctZXhxQtBU3HD-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-04/dmSctZXhxQtBU3HD-image.png)

Sobald das Gerät Zugelassen wurde, kann es für 24 Stunden mit der Steuerung interagieren.

[![image.png](https://docs.bsapp.de/uploads/images/gallery/2026-04/scaled-1680-/ZbqJDRYEEdgJNUEJ-image.png)](https://docs.bsapp.de/uploads/images/gallery/2026-04/ZbqJDRYEEdgJNUEJ-image.png)

Über die Schaltfläche Widerrufen, kann ein aktives Gerät auch entfernt werden.

# API Dokumentation

Die FNA-Steuerung stellt eine REST-API bereit, über die alle Funktionen der Ampelsteuerung programmatisch abgerufen und gesteuert werden können. Die API ist unter `http://<ip-adresse>/api/` erreichbar.

---

## Übersicht der Endpunkte

<table id="bkmrk-methode-endpunkt-bes"><thead><tr><th>Methode</th><th>Endpunkt</th><th>Beschreibung</th><th class="align-center">PIN Auth</th><th class="align-center">Device Auth</th></tr></thead><tbody><tr><td>GET</td><td>`/api/status`</td><td>Aktuellen Status der Ampeln abrufen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>GET</td><td>`/api/cmd`</td><td>Verfügbare Befehle abrufen</td><td class="align-center">X</td><td class="align-center">X</td></tr><tr><td>POST</td><td>`/api/cmd/{cmd}`</td><td>Befehl ausführen</td><td class="align-center">X</td><td class="align-center">X</td></tr><tr><td>GET</td><td>`/api/config`</td><td>Alle Konfigurationen abrufen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>POST</td><td>`/api/config`</td><td>Neue Konfiguration erstellen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>GET</td><td>`/api/config/preset`</td><td>Aktive Voreinstellung abrufen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>GET</td><td>`/api/config/volume`</td><td>Lautstärke abrufen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>PUT</td><td>`/api/config/volume`</td><td>Lautstärke setzen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>GET</td><td>`/api/config/brightness`</td><td>Helligkeit abrufen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>PUT</td><td>`/api/config/brightness`</td><td>Helligkeit setzen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>PUT</td><td>`/api/config/nach`</td><td>Nachschießen-Anzahl setzen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>DELETE</td><td>`/api/config/nach`</td><td>Nachschießen deaktivieren</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>GET</td><td>`/api/config/{id}`</td><td>Einzelne Konfiguration abrufen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>PUT</td><td>`/api/config/{id}`</td><td>Konfiguration aktualisieren</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>DELETE</td><td>`/api/config/{id}`</td><td>Konfiguration löschen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>GET</td><td>`/api/logs`</td><td>Protokolleinträge abrufen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>DELETE</td><td>`/api/logs`</td><td>Protokoll löschen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>GET</td><td>`/api/logs/training`</td><td>Trainings-Modus abrufen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>PUT</td><td>`/api/logs/training`</td><td>Trainings-Modus setzen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>GET</td><td>`/api/time`</td><td>Systemzeit abrufen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>POST</td><td>`/api/sync-time`</td><td>Systemzeit synchronisieren</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>POST</td><td>`/api/auth/login`  
</td><td>Anmelden mit PIN</td><td class="align-center">  
</td><td class="align-center">  
</td></tr><tr><td>GET</td><td>`/api/auth/status`</td><td>Status des Session (Auth)</td><td class="align-center">  
</td><td class="align-center">  
</td></tr><tr><td>POST</td><td>`/api/auth/logout`</td><td>Abmelden</td><td class="align-center">  
</td><td class="align-center">  
</td></tr><tr><td>PUT</td><td>`/api/auth/pin`</td><td>Login PIN ändern</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>GET</td><td>`/api/devices/pending`</td><td>Liste der wartenden Geräte</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>POST</td><td>`/api/devices/pending/{device_id}/approve`</td><td>Gerät zulassen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>DELETE</td><td>`/api/devices/pending/{device_id}`</td><td>Wartendes gerät löschen</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>GET</td><td>`/api/devices/approved`</td><td>Liste der zugelassenen Geräte</td><td class="align-center">X</td><td class="align-center">  
</td></tr><tr><td>DELETE</td><td>`/api/devices/approved/{device_id}`</td><td>Zugelassenes Gerät löschen</td><td class="align-center">X</td><td class="align-center">  
</td></tr></tbody></table>

---

## Status

### `GET /api/status`

Gibt den aktuellen Betriebsstatus beider Ampeln zurück.

**Antwort** `200 OK`

```json
{
  "a1": {
    "red": true,
    "yellow": false,
    "green": false,
    "time": 120,
    "group": "A"
  },
  "a2": {
    "red": false,
    "yellow": false,
    "green": true,
    "time": 120,
    "group": "B"
  },
  "run": true,
  "group_mode": false,
  "count_arrows": 3,
  "alt_mode": false,
  "shoot_break": false,
  "shoot_off_mode": false
}

```

<table id="bkmrk-feld-typ-beschreibun"><thead><tr><th>Feld</th><th>Typ</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`a1` / `a2`</td><td>Objekt</td><td>Status von Ampel 1 und 2</td></tr><tr><td>`a1.red`</td><td>Boolean</td><td>Rotes Licht aktiv</td></tr><tr><td>`a1.yellow`</td><td>Boolean</td><td>Gelbes Licht aktiv</td></tr><tr><td>`a1.green`</td><td>Boolean</td><td>Grünes Licht aktiv</td></tr><tr><td>`a1.time`</td><td>Integer</td><td>Verbleibende Zeit in Sekunden</td></tr><tr><td>`a1.group`</td><td>String</td><td>Zugewiesene Gruppe (z. B. `"A"` oder `"B"`)</td></tr><tr><td>`run`</td><td>Boolean</td><td>Steuerung läuft aktuell</td></tr><tr><td>`group_mode`</td><td>Boolean</td><td>AB/CD-Gruppenmodus aktiv</td></tr><tr><td>`count_arrows`</td><td>Integer</td><td>Aktuell eingestellte Pfeilanzahl</td></tr><tr><td>`alt_mode`</td><td>Boolean</td><td>Alternierend-Modus aktiv</td></tr><tr><td>`shoot_break`</td><td>Boolean</td><td>Schießpause aktiv</td></tr><tr><td>`shoot_off_mode`</td><td>Boolean</td><td>Gibt an, ob Nachschießen oder Stechen eingestellt ist</td></tr></tbody></table>

---

## Befehle

### `GET /api/cmd`

Gibt zurück, welche Befehle aktuell verfügbar (ausführbar) sind.

**Antwort** `200 OK`

```json
{
  "CommandStatus": {
    "START": true,
    "STOP": false,
    "SWITCH": false,
    "BREAK": false
  }
}

```

<table id="bkmrk-befehl-beschreibung-"><thead><tr><th>Befehl</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`START`</td><td>Schießsequenz starten</td></tr><tr><td>`STOP`</td><td>Schießsequenz stoppen</td></tr><tr><td>`SWITCH`</td><td>Gruppe wechseln (bei Alternierend-Modus)</td></tr><tr><td>`BREAK`</td><td>Schießpause einleiten</td></tr></tbody></table>

---

### `POST /api/cmd/{cmd}`

Führt einen Steuerungsbefehl aus.

**Pfadparameter**

<table id="bkmrk-parameter-typ-beschr"><thead><tr><th>Parameter</th><th>Typ</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`cmd`</td><td>String</td><td>Befehl: `START`, `STOP`, `SWITCH` oder `BREAK`</td></tr></tbody></table>

**Beispiel**

```
POST /api/cmd/START
```

**Antworten**

<table id="bkmrk-code-beschreibung-20"><thead><tr><th>Code</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`200 OK`</td><td>Befehl erfolgreich ausgeführt</td></tr><tr><td>`400 Bad Request`</td><td>Ungültiger oder nicht erlaubter Befehl</td></tr><tr><td>`500 Internal Server Error`</td><td>Serverfehler</td></tr></tbody></table>

---

## Konfigurationen

Konfigurationen enthalten alle Einstellungen für einen Schießbetrieb (z. B. Zeit pro Pfeil, Pfeilanzahl, Modus). Es können mehrere Konfigurationen gespeichert werden.

### `GET /api/config`

Gibt alle gespeicherten Konfigurationen zurück.

**Antwort** `200 OK` – Array von Konfigurationsobjekten (siehe Felder unten)

---

### `POST /api/config`

Erstellt eine neue Konfiguration.

**Anfrage-Body**

```json
{
  "name": "Halle 18m",
  "time_per_arrow": 40,
  "prepare_time": 10,
  "count_arrows": 3,
  "group_mode": false,
  "alt_single": false,
  "alt_team": false
}

```

<table id="bkmrk-feld-typ-beschreibun-1"><thead><tr><th>Feld</th><th>Typ</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`name`</td><td>String</td><td>Bezeichnung der Konfiguration</td></tr><tr><td>`time_per_arrow`</td><td>Integer</td><td>Zeit pro Pfeil in Sekunden</td></tr><tr><td>`prepare_time`</td><td>Integer</td><td>Vorlaufzeit in Sekunden</td></tr><tr><td>`count_arrows`</td><td>Integer</td><td>Anzahl der Pfeile pro Durchgang</td></tr><tr><td>`group_mode`</td><td>Boolean</td><td>AB/CD-Gruppenmodus aktivieren</td></tr><tr><td>`alt_single`</td><td>Boolean</td><td>Alternierend Einzeln aktivieren</td></tr><tr><td>`alt_team`</td><td>Boolean</td><td>Alternierend Mannschaft aktivieren</td></tr></tbody></table>

**Antwort** `200 OK` – Die erstellte Konfiguration inkl. `id` und `preset`-Flag

---

### `GET /api/config/{id}`

Gibt eine einzelne Konfiguration anhand ihrer ID zurück.

---

### `PUT /api/config/{id}`

Aktualisiert eine vorhandene Konfiguration. Body entspricht `POST /api/config`.

---

### `DELETE /api/config/{id}`

Löscht eine Konfiguration anhand ihrer ID.

---

### `GET /api/config/preset`

Gibt die aktuell als Voreinstellung markierte Konfiguration zurück.

**Antworten**

<table id="bkmrk-code-beschreibung-20-1"><thead><tr><th>Code</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`200 OK`</td><td>Voreinstellung gefunden</td></tr><tr><td>`404 Not Found`</td><td>Keine Voreinstellung gesetzt</td></tr></tbody></table>

---

## Lautstärke &amp; Helligkeit

### `GET /api/config/volume`

Gibt die aktuelle Lautstärke der Hupe zurück.

**Antwort** `200 OK`

```json
{ "amp_horn_vol": 80 }

```

---

### `PUT /api/config/volume?vol={wert}`

Setzt die Lautstärke der Hupe.

**Abfrageparameter**

<table id="bkmrk-parameter-typ-pflich"><thead><tr><th>Parameter</th><th>Typ</th><th>Pflicht</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`vol`</td><td>Integer</td><td>Ja</td><td>Lautstärkewert</td></tr></tbody></table>

---

### `GET /api/config/brightness`

Gibt die aktuelle Helligkeit der Ampeln zurück.

**Antwort** `200 OK`

```json
{ "amp_bright": 100 }

```

---

### `PUT /api/config/brightness?bright={wert}`

Setzt die Helligkeit der Ampeln.

<table id="bkmrk-parameter-typ-pflich-1"><thead><tr><th>Parameter</th><th>Typ</th><th>Pflicht</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`bright`</td><td>Integer</td><td>Ja</td><td>Helligkeitswert</td></tr></tbody></table>

---

## Nachschießen

### `PUT /api/config/nach?count={anzahl}`

Aktiviert das Nachschießen mit der angegebenen Pfeilanzahl. Bei Alternierendem Modus wird hiermit das Stecken mit angegebener Schützenzahl aktiviert.

<table id="bkmrk-parameter-typ-pflich-2"><thead><tr><th>Parameter</th><th>Typ</th><th>Pflicht</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`count`</td><td>Integer</td><td>Ja</td><td>Anzahl der Pfeile für das Nachschießen / Schützen für Stechen</td></tr></tbody></table>

---

### `DELETE /api/config/nach`

Deaktiviert das Nachschießen.

---

## Protokoll (Logs)

### `GET /api/logs`

Gibt alle Protokolleinträge zurück.

**Antwort** `200 OK`

```json
[
  {
    "id": 1,
    "timestamp": "2026-04-03T10:00:00",
    "action": "START",
    "description": "Schießsequenz gestartet"
  }
]

```

<table id="bkmrk-feld-typ-beschreibun-2"><thead><tr><th>Feld</th><th>Typ</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`id`</td><td>Integer</td><td>Eindeutige ID des Eintrags</td></tr><tr><td>`timestamp`</td><td>DateTime</td><td>Zeitstempel des Ereignisses</td></tr><tr><td>`action`</td><td>String</td><td>Ausgeführte Aktion</td></tr><tr><td>`description`</td><td>String</td><td>Beschreibung des Ereignisses</td></tr></tbody></table>

---

### `DELETE /api/logs`

Löscht alle Protokolleinträge.

---

### `GET /api/logs/training`

Gibt zurück, ob der Trainings-Modus aktiv ist (Protokolleinträge werden im Trainings-Modus nicht für das Schießleiterprotokoll gewertet).

**Antwort** `200 OK`

```json
{ "training": false }

```

---

### `PUT /api/logs/training?training={wert}`

Aktiviert oder deaktiviert den Trainings-Modus.

<table id="bkmrk-parameter-typ-pflich-3"><thead><tr><th>Parameter</th><th>Typ</th><th>Pflicht</th><th>Standard</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`training`</td><td>Boolean</td><td>Nein</td><td>`false`</td><td>`true` = Trainings-Modus aktiv</td></tr></tbody></table>

---

## Zeit

### `GET /api/time`

Gibt die aktuelle Systemzeit der Steuerung zurück.

**Antwort** `200 OK`

```json
{ "time": "2026-04-03T10:00:00" }

```

---

### `POST /api/sync-time`

Synchronisiert die Systemzeit der Steuerung.

**Anfrage-Body**

```json
{ "time": "2026-04-03T10:00:00" }

```

**Antwort** `200 OK` – Bestätigung mit der gesetzten Zeit

---

## Auth

### `POST /api/auth/login`

Authentifiziert die UI

**Anfrage-Body**

```json
{ "pin": "123456" }

```

**Antwort** `200 OK`

```json
{  "token": "AA-BB-CC-DD" }

```

### `GET /api/auth/status`

Gibt den Auth Status zurück

**Antwort** `200 OK`

```json
{  "authenticated": true }

```

### `POST /api/auth/logout`

Meldet die Session ab

**Antwort** `200 OK`

### `POST /api/auth/pin`

Änder die Anmeldepin

**Anfrage-Body**

```json
{ "new_pin": "987654" }

```

**Antwort** `200 OK`

---

## Devices

### `GET /api/devices/pending`

Gibt eine Liste der wartenden Geräte zurück

**Antwort** `200 OK`

```json
[
  {
    "id": 1,
    "ip": "192.168.1.10",
    "first_seen": "2026-04-27T15:02:44.310Z",
    "last_seen": "2026-04-27T15:02:44.310Z",
    "request_count": 5,
    "app_name": "amp",
    "device_type": "remote",
    "discover_checked": true
  }
]

```

<table id="bkmrk-feld-typ-beschreibun-3"><thead><tr><th>Feld</th><th>Typ</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`id`</td><td>Integer</td><td>Eindeutige ID des Eintrags</td></tr><tr><td>`ip`</td><td>String</td><td>IP des Gerätes</td></tr><tr><td>`first_seen`</td><td>TimeStamp</td><td>Wann hat sich das Gerät zum ersten mal gemeldet</td></tr><tr><td>`last_seen`</td><td>TimeStamp</td><td>Wann hat sich das Gerät zum letzten mal gemeldet</td></tr><tr><td>`request_count`</td><td>Integer</td><td>Wie oft hat sich das Gerät gemeldet</td></tr><tr><td>`app_name`</td><td>String</td><td>Info aus dem /discover feld App (Wenn vorhanden)</td></tr><tr><td>`device_type`</td><td>String</td><td>Info aus dem /discover feld Type (Wenn vorhanden)</td></tr><tr><td>`discover_checked`</td><td>Boolean</td><td>Gibt an, ob /discover geprüft werden konnte</td></tr></tbody></table>


### `POST /api/devices/pending/{device_id}/approve`

Gibt ein Gerät anhand der device\_id frei, sodass dieses die Ampel steuern kann.

**Abfrageparameter**

<table id="bkmrk-parameter-typ-pflich-4"><thead><tr><th>Parameter</th><th>Typ</th><th>Pflicht</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`device_id`</td><td>Integer</td><td>Ja</td><td>Device ID</td></tr></tbody></table>

**Antwort** `200 OK`

### `DELETE /api/devices/pending/{device_id}`

Weist ein wartendes Gerät zurück anhand der device\_id.

**Abfrageparameter**

<table id="bkmrk-parameter-typ-pflich-5"><thead><tr><th>Parameter</th><th>Typ</th><th>Pflicht</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`device_id`</td><td>Integer</td><td>Ja</td><td>Device ID</td></tr></tbody></table>

**Antwort** `200 OK`

### `GET /api/devices/approved`

Gibt eine Liste der zugelassenen Geräte zurück

**Antwort** `200 OK`

```json
[
  {
    "id": 1,
    "ip": "192.168.1.10",
    "app_name": "amp",
    "device_type": "remote",
    "approved_at": "2026-04-27T15:13:04.210Z",
    "expires_at": "2026-04-27T15:13:04.210Z"
  }
]

```

<table id="bkmrk-feld-typ-beschreibun-4"><thead><tr><th>Feld</th><th>Typ</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`id`</td><td>Integer</td><td>Eindeutige ID des Eintrags</td></tr><tr><td>`ip`</td><td>String</td><td>IP des Gerätes</td></tr><tr><td>`app_name`</td><td>String</td><td>Info aus dem /discover feld App (Wenn vorhanden)</td></tr><tr><td>`device_type`</td><td>String</td><td>Info aus dem /discover feld Type (Wenn vorhanden)</td></tr><tr><td>`approved_at`</td><td>TimeStamp</td><td>Gibt an, wann das Gerät zugelassen wurde</td></tr><tr><td>`expires_at`</td><td>TimeStamp</td><td>Gibt an, ab wann das Gerät nicht mehr zugelassen ist</td></tr></tbody></table>

### `DELETE /api/devices/approved/{device_id}`

Weist ein zugelassenes Gerät zurück anhand der device\_id. Dannach ist das Gerät nicht mehr berechtigt Anfragen an `/api/cmd` zu senden

**Abfrageparameter**

<table id="bkmrk-parameter-typ-pflich-6"><thead><tr><th>Parameter</th><th>Typ</th><th>Pflicht</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`device_id`</td><td>Integer</td><td>Ja</td><td>Device ID</td></tr></tbody></table>

**Antwort** `200 OK`

---

## Antwortformate

### Erfolg / Fehler (`DefaultStatusOUT`)

Viele Endpunkte antworten bei Erfolg oder Fehler mit folgendem Format:

```json
{ "status": "ok" }

```

---

## Hinweise

> **Wichtig:** Im Netzwerk darf nur eine Steuerung gleichzeitig laufen, da sonst die Anzeigegeräte widersprüchliche Informationen erhalten könnten.

- Alle Zeitangaben im Format ISO 8601 (`YYYY-MM-DDTHH:MM:SS`)
- Die API ist nur durch eine PIN Authentifizierung gesichert – sie sollte nur in einem gesicherten, lokalen Netzwerk betrieben werden
- Basis-URL: `http://<ip-adresse>/api/`

# Fehlerbehebung

### PIN vergessen

Solltest du einen PIN vergessen haben, kannst du über docker mit folgendem Befehl den PIN zurücksetzen

```bash
# Setzt den PIN auf 123456 zurück.
# Verwendung im laufenden Container:

docker exec <container_name> sh /app/reset_pin.sh

# Wenn du z.B. die Docker Infrastruktur Datei aus der Installationsanleitung genommen hast 
docker exec fna-webui sh /app/reset_pin.sh
```