v1 #1
22
API.md
22
API.md
@@ -8,7 +8,7 @@ All API endpoints return JSON unless otherwise noted.
|
|||||||
## Static Files
|
## Static Files
|
||||||
|
|
||||||
| Route | Method | Description | Response Type |
|
| Route | Method | Description | Response Type |
|
||||||
|------------------|--------|------------------------------|--------------|
|
| --------------- | ------ | ---------------------- | ------------- |
|
||||||
| `/` | GET | Main page | HTML |
|
| `/` | GET | Main page | HTML |
|
||||||
| `/settings` | GET | Settings page | HTML |
|
| `/settings` | GET | Settings page | HTML |
|
||||||
| `/rfid` | GET | RFID page | HTML |
|
| `/rfid` | GET | RFID page | HTML |
|
||||||
@@ -19,7 +19,7 @@ All API endpoints return JSON unless otherwise noted.
|
|||||||
## Timer & Data
|
## Timer & Data
|
||||||
|
|
||||||
| Route | Method | Description | Request Body/Params | Response Example |
|
| Route | Method | Description | Request Body/Params | Response Example |
|
||||||
|-------------------|--------|-------------------------------------|--------------------|------------------|
|
| ----------------- | ------ | --------------------------------- | ------------------- | --------------------- |
|
||||||
| `/api/data` | GET | Get current timer and status data | – | `{...}` |
|
| `/api/data` | GET | Get current timer and status data | – | `{...}` |
|
||||||
| `/api/reset-best` | POST | Reset best times | – | `{ "success": true }` |
|
| `/api/reset-best` | POST | Reset best times | – | `{ "success": true }` |
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ All API endpoints return JSON unless otherwise noted.
|
|||||||
## Button Learning
|
## Button Learning
|
||||||
|
|
||||||
| Route | Method | Description | Request Body/Params | Response Example |
|
| Route | Method | Description | Request Body/Params | Response Example |
|
||||||
|------------------------|--------|-------------------------------------|--------------------|------------------|
|
| --------------------- | ------ | --------------------------------- | ------------------- | ------------------------------------------------------- |
|
||||||
| `/api/unlearn-button` | POST | Remove all button assignments | – | `{ "success": true }` |
|
| `/api/unlearn-button` | POST | Remove all button assignments | – | `{ "success": true }` |
|
||||||
| `/api/start-learning` | POST | Start button learning mode | – | `{ "success": true }` |
|
| `/api/start-learning` | POST | Start button learning mode | – | `{ "success": true }` |
|
||||||
| `/api/stop-learning` | POST | Stop button learning mode | – | `{ "success": true }` |
|
| `/api/stop-learning` | POST | Stop button learning mode | – | `{ "success": true }` |
|
||||||
@@ -40,16 +40,16 @@ All API endpoints return JSON unless otherwise noted.
|
|||||||
## Settings
|
## Settings
|
||||||
|
|
||||||
| Route | Method | Description | Request Body/Params | Response Example |
|
| 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/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 }` |
|
| `/api/get-settings` | GET | Get current timer settings | – | `{ "maxTime": 300, "maxTimeDisplay": 20, "minTimeForLeaderboard": 5 }` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## WiFi Configuration
|
## WiFi Configuration
|
||||||
|
|
||||||
| Route | Method | Description | Request Body/Params | Response Example |
|
| Route | Method | Description | Request Body/Params | Response Example |
|
||||||
|-------------------|--------|-------------------------------------|--------------------|------------------|
|
| --------------- | ------ | ---------------------------------- | -------------------------------- | -------------------------------------- |
|
||||||
| `/api/set-wifi` | POST | Set WiFi SSID and password | `ssid`, `password` (form params) | `{ "success": true }` |
|
| `/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": "..." }` |
|
| `/api/get-wifi` | GET | Get current WiFi SSID and password | – | `{ "ssid": "...", "password": "..." }` |
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ All API endpoints return JSON unless otherwise noted.
|
|||||||
## Location Configuration
|
## Location Configuration
|
||||||
|
|
||||||
| Route | Method | Description | Request Body/Params | Response Example |
|
| Route | Method | Description | Request Body/Params | Response Example |
|
||||||
|----------------------|--------|-------------------------------------|--------------------|------------------|
|
| ------------------- | ------ | ------------------------ | -------------------------- | ------------------------- |
|
||||||
| `/api/set-location` | POST | Set location name and ID | `id`, `name` (form params) | `{ "success": true }` |
|
| `/api/set-location` | POST | Set location name and ID | `id`, `name` (form params) | `{ "success": true }` |
|
||||||
| `/api/get-location` | GET | Get current location | – | `{ "locationid": "..." }` |
|
| `/api/get-location` | GET | Get current location | – | `{ "locationid": "..." }` |
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ All API endpoints return JSON unless otherwise noted.
|
|||||||
## Button Update & Mode
|
## Button Update & Mode
|
||||||
|
|
||||||
| Route | Method | Description | Request Body/Params | Response Example |
|
| Route | Method | Description | Request Body/Params | Response Example |
|
||||||
|----------------------|--------|-------------------------------------|--------------------|------------------|
|
| -------------------- | ------ | ------------------------------- | ------------------------------------------------ | -------------------------- |
|
||||||
| `/api/updateButtons` | GET | Trigger MQTT update for buttons | – | `{ "success": true }` |
|
| `/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/set-mode` | POST | Set operational mode | `mode` (form param: "individual" or "wettkampf") | `{ "success": true }` |
|
||||||
| `/api/get-mode` | GET | Get current operational mode | – | `{ "mode": "individual" }` |
|
| `/api/get-mode` | GET | Get current operational mode | – | `{ "mode": "individual" }` |
|
||||||
@@ -77,7 +77,7 @@ All API endpoints return JSON unless otherwise noted.
|
|||||||
## System Info
|
## System Info
|
||||||
|
|
||||||
| Route | Method | Description | Request Body/Params | Response Example |
|
| 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 }` |
|
| `/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 }` |
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -85,7 +85,7 @@ All API endpoints return JSON unless otherwise noted.
|
|||||||
## WebSocket
|
## WebSocket
|
||||||
|
|
||||||
| Route | Description |
|
| Route | Description |
|
||||||
|---------|------------------------------------|
|
| ----- | ----------------------------------- |
|
||||||
| `/ws` | WebSocket endpoint for live updates |
|
| `/ws` | WebSocket endpoint for live updates |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ POST /api/unlearn-button
|
|||||||
→ Verlernt alle Button-Zuordnungen
|
→ Verlernt alle Button-Zuordnungen
|
||||||
|
|
||||||
POST /api/set-max-time
|
POST /api/set-max-time
|
||||||
→ Setzt die maximale Zeit und maxTimeDisplay
|
→ Setzt die maximale Zeit, maxTimeDisplay und minTimeForLeaderboard
|
||||||
|
|
||||||
GET /api/get-settings
|
GET /api/get-settings
|
||||||
→ Gibt die aktuellen Einstellungen zurück
|
→ Gibt die aktuellen Einstellungen zurück
|
||||||
|
|||||||
Binary file not shown.
@@ -182,6 +182,18 @@
|
|||||||
title="Zeit nach der die angezeigte Zeit zurückgesetzt wird"
|
title="Zeit nach der die angezeigte Zeit zurückgesetzt wird"
|
||||||
/>
|
/>
|
||||||
</div>
|
</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">
|
<div class="button-group">
|
||||||
<button type="submit" class="btn btn-primary">
|
<button type="submit" class="btn btn-primary">
|
||||||
💾 Einstellungen speichern
|
💾 Einstellungen speichern
|
||||||
@@ -718,6 +730,8 @@
|
|||||||
document.getElementById("maxTime").value = data.maxTime || 300;
|
document.getElementById("maxTime").value = data.maxTime || 300;
|
||||||
document.getElementById("maxTimeDisplay").value =
|
document.getElementById("maxTimeDisplay").value =
|
||||||
data.maxTimeDisplay || 20;
|
data.maxTimeDisplay || 20;
|
||||||
|
document.getElementById("minTimeForLeaderboard").value =
|
||||||
|
data.minTimeForLeaderboard || 5;
|
||||||
})
|
})
|
||||||
.catch((error) =>
|
.catch((error) =>
|
||||||
showMessage("Fehler beim Laden der Einstellungen", "error")
|
showMessage("Fehler beim Laden der Einstellungen", "error")
|
||||||
@@ -971,6 +985,9 @@
|
|||||||
const maxTimeDisplay = parseInt(
|
const maxTimeDisplay = parseInt(
|
||||||
document.getElementById("maxTimeDisplay").value
|
document.getElementById("maxTimeDisplay").value
|
||||||
);
|
);
|
||||||
|
const minTimeForLeaderboard = parseInt(
|
||||||
|
document.getElementById("minTimeForLeaderboard").value
|
||||||
|
);
|
||||||
|
|
||||||
fetch("/api/set-max-time", {
|
fetch("/api/set-max-time", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -981,7 +998,9 @@
|
|||||||
"maxTime=" +
|
"maxTime=" +
|
||||||
encodeURIComponent(maxTime) +
|
encodeURIComponent(maxTime) +
|
||||||
"&maxTimeDisplay=" +
|
"&maxTimeDisplay=" +
|
||||||
encodeURIComponent(maxTimeDisplay),
|
encodeURIComponent(maxTimeDisplay) +
|
||||||
|
"&minTimeForLeaderboard=" +
|
||||||
|
encodeURIComponent(minTimeForLeaderboard),
|
||||||
})
|
})
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ lib_deps =
|
|||||||
adafruit/Adafruit PN532@^1.3.4
|
adafruit/Adafruit PN532@^1.3.4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[env:esp32thing]
|
[env:esp32thing]
|
||||||
board = esp32thing_plus
|
board = esp32thing_plus
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
@@ -87,14 +88,41 @@ lib_deps =
|
|||||||
mlesniew/PicoMQTT@^1.3.0
|
mlesniew/PicoMQTT@^1.3.0
|
||||||
adafruit/Adafruit PN532@^1.3.4
|
adafruit/Adafruit PN532@^1.3.4
|
||||||
|
|
||||||
[env:esp32-s3-devkitc-1]
|
[env:um_feathers3]
|
||||||
board = esp32-s3-devkitc-1
|
board = um_feathers3
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
board_upload.flash_size = 16MB
|
board_upload.flash_size = 16MB
|
||||||
board_build.partitions = default_16MB.csv
|
board_build.partitions = default_16MB.csv
|
||||||
|
board_upload.wait_for_upload_port = false
|
||||||
build_flags =
|
build_flags =
|
||||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
-D ARDUINO_USB_CDC_ON_BOOT=1
|
||||||
-D BATTERY_PIN=35
|
-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 =
|
lib_deps =
|
||||||
bblanchon/ArduinoJson@^7.4.1
|
bblanchon/ArduinoJson@^7.4.1
|
||||||
esp32async/ESPAsyncWebServer@^3.7.7
|
esp32async/ESPAsyncWebServer@^3.7.7
|
||||||
|
|||||||
@@ -526,6 +526,15 @@ void sendTimeToOnlineAPI(int lane, String uid, float timeInSeconds) {
|
|||||||
|
|
||||||
// Funktionen für lokales Leaderboard
|
// Funktionen für lokales Leaderboard
|
||||||
void addLocalTime(String uid, String name, unsigned long timeMs) {
|
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;
|
LocalTime newTime;
|
||||||
newTime.uid = uid;
|
newTime.uid = uid;
|
||||||
newTime.name = name;
|
newTime.name = name;
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ bool learningMode = false;
|
|||||||
int learningStep = 0; // 0=Start1, 1=Stop1, 2=Start2, 3=Stop2
|
int learningStep = 0; // 0=Start1, 1=Stop1, 2=Start2, 3=Stop2
|
||||||
unsigned long maxTimeBeforeReset = 300000; // 5 Minuten default
|
unsigned long maxTimeBeforeReset = 300000; // 5 Minuten default
|
||||||
unsigned long maxTimeDisplay = 20000; // 20 Sekunden Standard (in ms)
|
unsigned long maxTimeDisplay = 20000; // 20 Sekunden Standard (in ms)
|
||||||
|
unsigned long minTimeForLeaderboard =
|
||||||
|
5000; // 5 Sekunden minimum für Leaderboard (in ms)
|
||||||
bool wifimodeAP = false; // AP-Modus deaktiviert
|
bool wifimodeAP = false; // AP-Modus deaktiviert
|
||||||
String masterlocation;
|
String masterlocation;
|
||||||
int gamemode; // 0=Individual, 1=Wettkampf
|
int gamemode; // 0=Individual, 1=Wettkampf
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ void saveSettings() {
|
|||||||
preferences.begin("settings", false);
|
preferences.begin("settings", false);
|
||||||
preferences.putULong("maxTime", maxTimeBeforeReset);
|
preferences.putULong("maxTime", maxTimeBeforeReset);
|
||||||
preferences.putULong("maxTimeDisplay", maxTimeDisplay);
|
preferences.putULong("maxTimeDisplay", maxTimeDisplay);
|
||||||
|
preferences.putULong("minTime", minTimeForLeaderboard);
|
||||||
preferences.putUInt("gamemode", gamemode);
|
preferences.putUInt("gamemode", gamemode);
|
||||||
preferences.putUInt("laneConfigType", laneConfigType);
|
preferences.putUInt("laneConfigType", laneConfigType);
|
||||||
preferences.putUInt("lane1Diff", lane1DifficultyType);
|
preferences.putUInt("lane1Diff", lane1DifficultyType);
|
||||||
@@ -93,6 +94,7 @@ void loadSettings() {
|
|||||||
preferences.begin("settings", true);
|
preferences.begin("settings", true);
|
||||||
maxTimeBeforeReset = preferences.getULong("maxTime", 300000);
|
maxTimeBeforeReset = preferences.getULong("maxTime", 300000);
|
||||||
maxTimeDisplay = preferences.getULong("maxTimeDisplay", 20000);
|
maxTimeDisplay = preferences.getULong("maxTimeDisplay", 20000);
|
||||||
|
minTimeForLeaderboard = preferences.getULong("minTime", 5000);
|
||||||
gamemode = preferences.getUInt("gamemode", 0);
|
gamemode = preferences.getUInt("gamemode", 0);
|
||||||
laneConfigType = preferences.getUInt("laneConfigType", 0);
|
laneConfigType = preferences.getUInt("laneConfigType", 0);
|
||||||
lane1DifficultyType = preferences.getUInt("lane1Diff", 0);
|
lane1DifficultyType = preferences.getUInt("lane1Diff", 0);
|
||||||
|
|||||||
@@ -84,6 +84,12 @@ void setupRoutes() {
|
|||||||
request->getParam("maxTimeDisplay", true)->value().toInt() * 1000;
|
request->getParam("maxTimeDisplay", true)->value().toInt() * 1000;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
if (request->hasParam("minTimeForLeaderboard", true)) {
|
||||||
|
minTimeForLeaderboard =
|
||||||
|
request->getParam("minTimeForLeaderboard", true)->value().toInt() *
|
||||||
|
1000;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
saveSettings();
|
saveSettings();
|
||||||
DynamicJsonDocument doc(32);
|
DynamicJsonDocument doc(32);
|
||||||
@@ -101,6 +107,7 @@ void setupRoutes() {
|
|||||||
DynamicJsonDocument doc(256);
|
DynamicJsonDocument doc(256);
|
||||||
doc["maxTime"] = maxTimeBeforeReset / 1000;
|
doc["maxTime"] = maxTimeBeforeReset / 1000;
|
||||||
doc["maxTimeDisplay"] = maxTimeDisplay / 1000;
|
doc["maxTimeDisplay"] = maxTimeDisplay / 1000;
|
||||||
|
doc["minTimeForLeaderboard"] = minTimeForLeaderboard / 1000;
|
||||||
String result;
|
String result;
|
||||||
serializeJson(doc, result);
|
serializeJson(doc, result);
|
||||||
request->send(200, "application/json", result);
|
request->send(200, "application/json", result);
|
||||||
|
|||||||
Reference in New Issue
Block a user