v1 #1
82
API.md
82
API.md
@@ -7,87 +7,87 @@ All API endpoints return JSON unless otherwise noted.
|
||||
|
||||
## Static Files
|
||||
|
||||
| Route | Method | Description | Response Type |
|
||||
|------------------|--------|------------------------------|--------------|
|
||||
| `/` | GET | Main page | HTML |
|
||||
| `/settings` | GET | Settings page | HTML |
|
||||
| `/rfid` | GET | RFID page | HTML |
|
||||
| `/firmware.bin` | GET | Firmware file (SPIFFS) | Binary |
|
||||
| Route | Method | Description | Response Type |
|
||||
| --------------- | ------ | ---------------------- | ------------- |
|
||||
| `/` | GET | Main page | HTML |
|
||||
| `/settings` | GET | Settings page | HTML |
|
||||
| `/rfid` | GET | RFID page | HTML |
|
||||
| `/firmware.bin` | GET | Firmware file (SPIFFS) | Binary |
|
||||
|
||||
---
|
||||
|
||||
## Timer & Data
|
||||
|
||||
| Route | Method | Description | Request Body/Params | Response Example |
|
||||
|-------------------|--------|-------------------------------------|--------------------|------------------|
|
||||
| `/api/data` | GET | Get current timer and status data | – | `{...}` |
|
||||
| `/api/reset-best` | POST | Reset best times | – | `{ "success": true }` |
|
||||
| Route | Method | Description | Request Body/Params | Response Example |
|
||||
| ----------------- | ------ | --------------------------------- | ------------------- | --------------------- |
|
||||
| `/api/data` | GET | Get current timer and status data | – | `{...}` |
|
||||
| `/api/reset-best` | POST | Reset best times | – | `{ "success": true }` |
|
||||
|
||||
---
|
||||
|
||||
## Button Learning
|
||||
|
||||
| Route | Method | Description | Request Body/Params | Response Example |
|
||||
|------------------------|--------|-------------------------------------|--------------------|------------------|
|
||||
| `/api/unlearn-button` | POST | Remove all button assignments | – | `{ "success": true }` |
|
||||
| `/api/start-learning` | POST | Start button learning mode | – | `{ "success": true }` |
|
||||
| `/api/stop-learning` | POST | Stop button learning mode | – | `{ "success": true }` |
|
||||
| `/api/learn/status` | GET | Get learning mode status | – | `{ "active": true, "step": 1 }` |
|
||||
| `/api/buttons/status` | GET | Get button assignment and voltage | – | `{ "lane1Start": true, "lane1StartVoltage": 3.3, ... }` |
|
||||
| Route | Method | Description | Request Body/Params | Response Example |
|
||||
| --------------------- | ------ | --------------------------------- | ------------------- | ------------------------------------------------------- |
|
||||
| `/api/unlearn-button` | POST | Remove all button assignments | – | `{ "success": true }` |
|
||||
| `/api/start-learning` | POST | Start button learning mode | – | `{ "success": true }` |
|
||||
| `/api/stop-learning` | POST | Stop button learning mode | – | `{ "success": true }` |
|
||||
| `/api/learn/status` | GET | Get learning mode status | – | `{ "active": true, "step": 1 }` |
|
||||
| `/api/buttons/status` | GET | Get button assignment and voltage | – | `{ "lane1Start": true, "lane1StartVoltage": 3.3, ... }` |
|
||||
|
||||
---
|
||||
|
||||
## Settings
|
||||
|
||||
| Route | Method | Description | Request Body/Params | Response Example |
|
||||
|----------------------|--------|-------------------------------------|--------------------|------------------|
|
||||
| `/api/set-max-time` | POST | Set max timer and display time | `maxTime`, `maxTimeDisplay` (form params, seconds) | `{ "success": true }` |
|
||||
| `/api/get-settings` | GET | Get current timer settings | – | `{ "maxTime": 300, "maxTimeDisplay": 20 }` |
|
||||
| Route | Method | Description | Request Body/Params | Response Example |
|
||||
| ------------------- | ------ | ------------------------------ | --------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
||||
| `/api/set-max-time` | POST | Set max timer and display time | `maxTime`, `maxTimeDisplay`, `minTimeForLeaderboard` (form params, seconds) | `{ "success": true }` |
|
||||
| `/api/get-settings` | GET | Get current timer settings | – | `{ "maxTime": 300, "maxTimeDisplay": 20, "minTimeForLeaderboard": 5 }` |
|
||||
|
||||
---
|
||||
|
||||
## WiFi Configuration
|
||||
|
||||
| Route | Method | Description | Request Body/Params | Response Example |
|
||||
|-------------------|--------|-------------------------------------|--------------------|------------------|
|
||||
| `/api/set-wifi` | POST | Set WiFi SSID and password | `ssid`, `password` (form params) | `{ "success": true }` |
|
||||
| `/api/get-wifi` | GET | Get current WiFi SSID and password | – | `{ "ssid": "...", "password": "..." }` |
|
||||
| Route | Method | Description | Request Body/Params | Response Example |
|
||||
| --------------- | ------ | ---------------------------------- | -------------------------------- | -------------------------------------- |
|
||||
| `/api/set-wifi` | POST | Set WiFi SSID and password | `ssid`, `password` (form params) | `{ "success": true }` |
|
||||
| `/api/get-wifi` | GET | Get current WiFi SSID and password | – | `{ "ssid": "...", "password": "..." }` |
|
||||
|
||||
---
|
||||
|
||||
## Location Configuration
|
||||
|
||||
| Route | Method | Description | Request Body/Params | Response Example |
|
||||
|----------------------|--------|-------------------------------------|--------------------|------------------|
|
||||
| `/api/set-location` | POST | Set location name and ID | `id`, `name` (form params) | `{ "success": true }` |
|
||||
| `/api/get-location` | GET | Get current location | – | `{ "locationid": "..." }` |
|
||||
| Route | Method | Description | Request Body/Params | Response Example |
|
||||
| ------------------- | ------ | ------------------------ | -------------------------- | ------------------------- |
|
||||
| `/api/set-location` | POST | Set location name and ID | `id`, `name` (form params) | `{ "success": true }` |
|
||||
| `/api/get-location` | GET | Get current location | – | `{ "locationid": "..." }` |
|
||||
|
||||
---
|
||||
|
||||
## Button Update & Mode
|
||||
|
||||
| Route | Method | Description | Request Body/Params | Response Example |
|
||||
|----------------------|--------|-------------------------------------|--------------------|------------------|
|
||||
| `/api/updateButtons` | GET | Trigger MQTT update for buttons | – | `{ "success": true }` |
|
||||
| `/api/set-mode` | POST | Set operational mode | `mode` (form param: "individual" or "wettkampf") | `{ "success": true }` |
|
||||
| `/api/get-mode` | GET | Get current operational mode | – | `{ "mode": "individual" }` |
|
||||
| Route | Method | Description | Request Body/Params | Response Example |
|
||||
| -------------------- | ------ | ------------------------------- | ------------------------------------------------ | -------------------------- |
|
||||
| `/api/updateButtons` | GET | Trigger MQTT update for buttons | – | `{ "success": true }` |
|
||||
| `/api/set-mode` | POST | Set operational mode | `mode` (form param: "individual" or "wettkampf") | `{ "success": true }` |
|
||||
| `/api/get-mode` | GET | Get current operational mode | – | `{ "mode": "individual" }` |
|
||||
|
||||
---
|
||||
|
||||
## System Info
|
||||
|
||||
| Route | Method | Description | Request Body/Params | Response Example |
|
||||
|---------------|--------|-------------------------------------|--------------------|------------------|
|
||||
| `/api/info` | GET | Get system info (IP, MAC, memory, license, etc.) | – | `{ "ip": "...", "ipSTA": "...", "channel": 1, "mac": "...", "freeMemory": 123456, "connectedButtons": 3, "isOnline": true, "valid": "Ja", "tier": 1 }` |
|
||||
| Route | Method | Description | Request Body/Params | Response Example |
|
||||
| ----------- | ------ | ------------------------------------------------ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `/api/info` | GET | Get system info (IP, MAC, memory, license, etc.) | – | `{ "ip": "...", "ipSTA": "...", "channel": 1, "mac": "...", "freeMemory": 123456, "connectedButtons": 3, "isOnline": true, "valid": "Ja", "tier": 1 }` |
|
||||
|
||||
---
|
||||
|
||||
## WebSocket
|
||||
|
||||
| Route | Description |
|
||||
|---------|------------------------------------|
|
||||
| `/ws` | WebSocket endpoint for live updates|
|
||||
| Route | Description |
|
||||
| ----- | ----------------------------------- |
|
||||
| `/ws` | WebSocket endpoint for live updates |
|
||||
|
||||
---
|
||||
|
||||
**All API endpoints return JSON unless otherwise noted. POST requests expect form parameters (not JSON body).**
|
||||
**All API endpoints return JSON unless otherwise noted. POST requests expect form parameters (not JSON body).**
|
||||
|
||||
@@ -9,7 +9,7 @@ POST /api/unlearn-button
|
||||
→ Verlernt alle Button-Zuordnungen
|
||||
|
||||
POST /api/set-max-time
|
||||
→ Setzt die maximale Zeit und maxTimeDisplay
|
||||
→ Setzt die maximale Zeit, maxTimeDisplay und minTimeForLeaderboard
|
||||
|
||||
GET /api/get-settings
|
||||
→ Gibt die aktuellen Einstellungen zurück
|
||||
|
||||
Binary file not shown.
@@ -182,6 +182,18 @@
|
||||
title="Zeit nach der die angezeigte Zeit zurückgesetzt wird"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="minTimeForLeaderboard">Minimale Zeit für Leaderboard (Sekunden):</label>
|
||||
<input
|
||||
type="number"
|
||||
id="minTimeForLeaderboard"
|
||||
name="minTimeForLeaderboard"
|
||||
min="1"
|
||||
max="300"
|
||||
value="5"
|
||||
title="Zeiten unter diesem Wert werden nicht ins lokale Leaderboard eingetragen (Missbrauchsschutz)"
|
||||
/>
|
||||
</div>
|
||||
<div class="button-group">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
💾 Einstellungen speichern
|
||||
@@ -718,6 +730,8 @@
|
||||
document.getElementById("maxTime").value = data.maxTime || 300;
|
||||
document.getElementById("maxTimeDisplay").value =
|
||||
data.maxTimeDisplay || 20;
|
||||
document.getElementById("minTimeForLeaderboard").value =
|
||||
data.minTimeForLeaderboard || 5;
|
||||
})
|
||||
.catch((error) =>
|
||||
showMessage("Fehler beim Laden der Einstellungen", "error")
|
||||
@@ -971,6 +985,9 @@
|
||||
const maxTimeDisplay = parseInt(
|
||||
document.getElementById("maxTimeDisplay").value
|
||||
);
|
||||
const minTimeForLeaderboard = parseInt(
|
||||
document.getElementById("minTimeForLeaderboard").value
|
||||
);
|
||||
|
||||
fetch("/api/set-max-time", {
|
||||
method: "POST",
|
||||
@@ -981,7 +998,9 @@
|
||||
"maxTime=" +
|
||||
encodeURIComponent(maxTime) +
|
||||
"&maxTimeDisplay=" +
|
||||
encodeURIComponent(maxTimeDisplay),
|
||||
encodeURIComponent(maxTimeDisplay) +
|
||||
"&minTimeForLeaderboard=" +
|
||||
encodeURIComponent(minTimeForLeaderboard),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
|
||||
@@ -52,6 +52,7 @@ lib_deps =
|
||||
adafruit/Adafruit PN532@^1.3.4
|
||||
|
||||
|
||||
|
||||
[env:esp32thing]
|
||||
board = esp32thing_plus
|
||||
monitor_speed = 115200
|
||||
@@ -87,14 +88,41 @@ lib_deps =
|
||||
mlesniew/PicoMQTT@^1.3.0
|
||||
adafruit/Adafruit PN532@^1.3.4
|
||||
|
||||
[env:esp32-s3-devkitc-1]
|
||||
board = esp32-s3-devkitc-1
|
||||
[env:um_feathers3]
|
||||
board = um_feathers3
|
||||
monitor_speed = 115200
|
||||
board_upload.flash_size = 16MB
|
||||
board_build.partitions = default_16MB.csv
|
||||
board_upload.wait_for_upload_port = false
|
||||
build_flags =
|
||||
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||
-DBATTERY_PIN=35
|
||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
||||
-D BATTERY_PIN=35
|
||||
-D ARDUINO_USB_MODE=1
|
||||
|
||||
lib_deps =
|
||||
bblanchon/ArduinoJson@^7.4.1
|
||||
esp32async/ESPAsyncWebServer@^3.7.7
|
||||
esp32async/AsyncTCP@^3.4.2
|
||||
mlesniew/PicoMQTT@^1.3.0
|
||||
adafruit/Adafruit PN532@^1.3.4
|
||||
|
||||
[env:um_feathers3_debug]
|
||||
board = um_feathers3
|
||||
board_upload.flash_size = 16MB
|
||||
board_build.partitions = default_16MB.csv
|
||||
board_upload.wait_for_upload_port = false
|
||||
build_flags =
|
||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
||||
-D BATTERY_PIN=35
|
||||
-D ARDUINO_USB_MODE=0
|
||||
|
||||
build_type = debug
|
||||
debug_speed = 12000
|
||||
debug_tool = esp-builtin
|
||||
upload_port = COM5
|
||||
monitor_speed = 115200
|
||||
monitor_port = COM7
|
||||
|
||||
lib_deps =
|
||||
bblanchon/ArduinoJson@^7.4.1
|
||||
esp32async/ESPAsyncWebServer@^3.7.7
|
||||
|
||||
@@ -526,6 +526,15 @@ void sendTimeToOnlineAPI(int lane, String uid, float timeInSeconds) {
|
||||
|
||||
// Funktionen für lokales Leaderboard
|
||||
void addLocalTime(String uid, String name, unsigned long timeMs) {
|
||||
// Prüfe minimale Zeit für Leaderboard-Eintrag
|
||||
if (timeMs < minTimeForLeaderboard) {
|
||||
Serial.printf(
|
||||
"Zeit zu kurz für Leaderboard: %s (%s) - %.2fs (Minimum: %.2fs)\n",
|
||||
name.c_str(), uid.c_str(), timeMs / 1000.0,
|
||||
minTimeForLeaderboard / 1000.0);
|
||||
return; // Zeit wird nicht ins Leaderboard eingetragen
|
||||
}
|
||||
|
||||
LocalTime newTime;
|
||||
newTime.uid = uid;
|
||||
newTime.name = name;
|
||||
|
||||
@@ -72,7 +72,9 @@ bool learningMode = false;
|
||||
int learningStep = 0; // 0=Start1, 1=Stop1, 2=Start2, 3=Stop2
|
||||
unsigned long maxTimeBeforeReset = 300000; // 5 Minuten default
|
||||
unsigned long maxTimeDisplay = 20000; // 20 Sekunden Standard (in ms)
|
||||
bool wifimodeAP = false; // AP-Modus deaktiviert
|
||||
unsigned long minTimeForLeaderboard =
|
||||
5000; // 5 Sekunden minimum für Leaderboard (in ms)
|
||||
bool wifimodeAP = false; // AP-Modus deaktiviert
|
||||
String masterlocation;
|
||||
int gamemode; // 0=Individual, 1=Wettkampf
|
||||
bool startCompetition = false; // Flag, ob der Timer gestartet wurde
|
||||
|
||||
@@ -82,6 +82,7 @@ void saveSettings() {
|
||||
preferences.begin("settings", false);
|
||||
preferences.putULong("maxTime", maxTimeBeforeReset);
|
||||
preferences.putULong("maxTimeDisplay", maxTimeDisplay);
|
||||
preferences.putULong("minTime", minTimeForLeaderboard);
|
||||
preferences.putUInt("gamemode", gamemode);
|
||||
preferences.putUInt("laneConfigType", laneConfigType);
|
||||
preferences.putUInt("lane1Diff", lane1DifficultyType);
|
||||
@@ -93,6 +94,7 @@ void loadSettings() {
|
||||
preferences.begin("settings", true);
|
||||
maxTimeBeforeReset = preferences.getULong("maxTime", 300000);
|
||||
maxTimeDisplay = preferences.getULong("maxTimeDisplay", 20000);
|
||||
minTimeForLeaderboard = preferences.getULong("minTime", 5000);
|
||||
gamemode = preferences.getUInt("gamemode", 0);
|
||||
laneConfigType = preferences.getUInt("laneConfigType", 0);
|
||||
lane1DifficultyType = preferences.getUInt("lane1Diff", 0);
|
||||
|
||||
@@ -84,6 +84,12 @@ void setupRoutes() {
|
||||
request->getParam("maxTimeDisplay", true)->value().toInt() * 1000;
|
||||
changed = true;
|
||||
}
|
||||
if (request->hasParam("minTimeForLeaderboard", true)) {
|
||||
minTimeForLeaderboard =
|
||||
request->getParam("minTimeForLeaderboard", true)->value().toInt() *
|
||||
1000;
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
saveSettings();
|
||||
DynamicJsonDocument doc(32);
|
||||
@@ -101,6 +107,7 @@ void setupRoutes() {
|
||||
DynamicJsonDocument doc(256);
|
||||
doc["maxTime"] = maxTimeBeforeReset / 1000;
|
||||
doc["maxTimeDisplay"] = maxTimeDisplay / 1000;
|
||||
doc["minTimeForLeaderboard"] = minTimeForLeaderboard / 1000;
|
||||
String result;
|
||||
serializeJson(doc, result);
|
||||
request->send(200, "application/json", result);
|
||||
|
||||
Reference in New Issue
Block a user