MaPaLo76
4dd4ce0620
feat(FR-002): Web Console via HTTP-Polling (/log + /log-data) -- v1.1.0
...
- Ring-Buffer _logBuf in web_server.cpp: webLogForward() schreibt auf Core 1
- GET /log-data liefert Puffer als Plain-Text (kein WebSocket, kein Core-Konflikt)
- Browser pollt alle 2 s, Auto-Scroll, dunkles Terminal-Theme
- LOG_I/LOG_E/LOG_D: Timestamp (HH:MM:SS nach NTP, sonst +Xs), webLogForward()
- Alle Serial.* in laser_tracker.cpp, mqtt_client.cpp, web_server.cpp auf LOG_I/LOG_E
- main.cpp: esp_reset_reason() beim Booten loggen (POWER_ON / WATCHDOG / PANIC...)
- telnet_logger.h entfernt (war nur noch Deprecated-Stub)
- Feature-Requests.md: FR-002 abgeschlossen
2026-02-28 17:24:56 +01:00
MaPaLo76
a97fa0c111
fix(mqtt): session_sum Binaerzahl-Bug behoben
...
- String(int, 2) interpretiert 2. Argument als Basis (binaer), nicht Dezimalstellen
Beispiel: 18 Min -> '10010' (binaer)
- Fix: direkter int-Wert als JSON-Integer (kein serialized/String noetig)
- platformio.ini: Version 1.0.1 -> 1.0.2
- Feature-Requests.md: FR-004 dokumentiert und abgeschlossen
2026-02-27 21:18:02 +01:00
MaPaLo76
44929934bc
docs(fr): FR-003 Commit-Hash korrigiert
2026-02-26 22:46:10 +01:00
MaPaLo76
3a310828b6
fix(ntp): Zeitzone CET/CEST + Lokalzeit im MQTT-Payload
...
- wifi_connector.cpp: configTime(0,0) -> configTzTime(CET-1CEST,M3.5.0,M10.5.0/3)
Automatische Sommer-/Winterzeitumschaltung fuer Deutschland
- mqtt_client.cpp: gmtime() -> localtime(), Z-Suffix entfernt
session_start_time zeigt Lokalzeit (CET/CEST)
- platformio.ini: Version 1.0.0 -> 1.0.1 (Patch)
- README.md: session_start_time Dokumentation aktualisiert
- Feature-Requests.md: FR-003 abgeschlossen
2026-02-26 22:45:53 +01:00
MaPaLo76
6eceadf011
docs(fr): FR-002 Web Console (WebSerial) eingetragen
2026-02-26 22:26:00 +01:00
MaPaLo76
75f5b7a576
feat(web,mqtt): Firmware-Version auf Webseite und MQTT-Status
...
- platformio.ini: -DFIRMWARE_VERSION='1.0.0' als build_flag (Single Source of Truth)
- config.h: #ifndef FIRMWARE_VERSION Fallback fuer Arduino IDE
- web_server.cpp: config.h eingebunden; Firmware-Zeile in Statustabelle (/);
Footer 'v1.0.0 (Feb 26 2026)' auf /config
- mqtt_client.cpp: firmware_version im lasercutter/status Payload;
buf von 160 auf 220 Bytes vergroessert
- Feature-Requests.md: FR-001 dokumentiert
2026-02-26 21:53:05 +01:00
MaPaLo76
234a3a4b9b
docs(plan): Phase 10 abgeschlossen, Projekt vollstaendig dokumentiert
...
- Implementation-Plan.md: Phase 10 alle Tasks als erledigt markiert
- README.md: Implementierungsstand-Tabelle aktualisiert (Phase 8-10 abgeschlossen)
2026-02-26 21:41:08 +01:00
MaPaLo76
fcb992d5d1
docs(plan): Phase 9 abgeschlossen, Feature-Requests.md eingeführt
...
- Implementation-Plan.md: Phase 9 als abgeschlossen markiert
- copilot-instructions.md: Commit-Regel geändert
Bug Fix / kleines Feature -> Feature-Requests.md
Neue Phase / Architektur -> Implementation-Plan.md
- Feature-Requests.md: neu erstellt für laufende Bug Fixes und Feature Requests
2026-02-26 21:40:11 +01:00
MaPaLo76
6bef93210e
feat(ota): ArduinoOTA integration + platformio.ini refactor
...
- ArduinoOTA in web_server.cpp integriert (Hostname: lasercutter-display)
- WebServerManager::loop() hinzugefuegt -> ArduinoOTA.handle()
- webServer.loop() in main.cpp aufgerufen
- platformio.ini: gemeinsamer [env]-Basisblock (lib_deps einmalig)
- Neues env az-delivery-devkit-v4-ota (espota, upload_flags --auth Anleitung)
- Neues env az-delivery-devkit-v4-ota-http (ElegantOTA HTTP Fallback)
- upload_ota.py: HTTP-Multipart-Upload Script fuer ElegantOTA
- README.md: Abschnitt Via WiFi (OTA) mit Passwort-Anleitung
- Implementation-Plan.md: Task 9.9 dokumentiert
2026-02-26 21:35:55 +01:00
MaPaLo76
974616aee2
refactor(wifi): non-blocking WiFi-Architektur (Proposal B+D)
...
- WiFiManager als Pointer, lazy new in begin() verhindert Crash durch
globale Konstruktoren vor Arduino-Framework-Init
- WiFi.mode(WIFI_STA) vor Credentials-Pruefung; getWiFiSSID(true) statt
WiFi.SSID() (erfordert gestarteten Stack)
- Credentials vorhanden: WiFi.begin() non-blocking, Ergebnis in loop()
- Keine Credentials: setConfigPortalBlocking(false) + process() in loop()
- Nach 3 Fehlversuchen: startConfigPortal() automatisch
- onConnect(): stopWebPortal() vor AsyncWebServer-Start (Port-80-Konflikt)
- main.cpp: LaserTracker startet vor WiFi (Prioritaet 1)
- MQTT + WebServer: Lazy-Init beim ersten WiFi-Connect
- Display rate-limited: W 500ms-Blinker, Minuten 60s, Sekunden 1s, M bei Aenderung
- Manuell getestet: LaserTracker laeuft sofort, WiFi non-blocking verifiziert
2026-02-26 21:05:22 +01:00
MaPaLo76
7fb14307ea
Vor Architektur Änderung
2026-02-26 18:50:45 +01:00
MaPaLo76
e045dcb756
Update - Screeshots
2026-02-23 22:58:17 +01:00
MaPaLo76
3516e58dc6
feat(web): Konfigurationsseite Buttons gleich breit
...
- buildConfigPage(): width:100% fuer alle Buttons (via .btn-Klasse)
- Flex-Spalten-Layout identisch zur Statusseite (gap:.6rem, margin-top:1.5rem)
- Farben unveraendert: Blau=Speichern, Grau=Abbrechen
- Implementation-Plan.md Phase 7.8 ergaenzt
2026-02-23 22:56:09 +01:00
MaPaLo76
99b5c25e37
feat(tracker): resetSessionSum + MQTT reset_session + UI-Verbesserungen
...
- resetSession() umbenannt in resetSessionSum() (klarere Semantik)
- Bug fix: resetSessionSum() setzt laufende Session-Timer korrekt zurueck
(vorher: getAllSessionsSumMinutes() blieb > 0 nach Reset)
- consumeSessionReset() nach consumeSessionEnd()-Muster (consume-Semantik)
- Vor Reset: akkumulierte Netto-Sekunden sichern -> publishSession() wie Session-Ende
- MQTT: payload {reset_session:true} via lasercutter/reset loest resetSessionSum() aus
- MQTT: Session-Reset publiziert identisches JSON wie normales Session-Ende
- Web: Button-Layout ueberarbeitet (alle 3 Buttons blau, uebereinander, gleich breit)
- Docs: README.md + Implementation-Plan.md aktualisiert
2026-02-23 22:49:30 +01:00
MaPaLo76
fde1f12315
fix(auth): HTTP Basic Auth funktioniert korrekt
...
- requestAuthentication() auf Basic Auth umgestellt (false = kein Digest)
- webPassword/webUser Buffer von 32 auf 64 Byte vergroessert
- POST /config: leeres Passwortfeld laesst bestehendes Passwort unveraendert
- Checkbox 'clear_auth' zum expliziten Deaktivieren des Schutzes
- Temporaere Debug-Ausgaben entfernt
2026-02-23 22:09:28 +01:00
MaPaLo76
07c99dc7d8
feat(web): HTTP-Basic-Auth fuer alle Routen; webUser/webPassword in NVS; ElegantOTA.setAuth()
2026-02-23 21:32:47 +01:00
MaPaLo76
18a1f67f64
feat(mqtt): session_start_time ISO-8601 UTC; NTP waitForNtp nach WLAN-Connect; docs: README + Plan Phase 9 abgeschlossen
2026-02-23 21:23:45 +01:00
MaPaLo76
2073c3678c
feat(main): Phase 9 - LOG_D, getFreeHeap-Monitor; fix: PIMPL web_server loest ESPAsyncWebServer/WiFiManager HTTP-Enum-Konflikt
2026-02-23 21:06:59 +01:00
MaPaLo76
530d2f4670
feat(main): Phase 8 - WebServer, Watchdog, WLAN/MQTT-Fehlerstatus, Initialisierungsreihenfolge, Ceiling-Minuten pro Session
2026-02-23 20:50:04 +01:00
MaPaLo76
e273f1ea6c
feat(display): showSessionRing - Sekunden-Kreisanzeige auf Modulen 5-7, 12-Uhr-Start (Phase 5b / 5.7 abgeschlossen)
2026-02-23 20:19:33 +01:00
MaPaLo76
4111f451d4
docs(tests): Burst-Begriff durch Session ersetzt, MQTT-Payloads aktualisiert
2026-02-23 19:53:35 +01:00
MaPaLo76
e98002db7b
refactor(laser,web): getSessionMinutes->getAllSessionsSumMinutes, Platzhalter SESSION->ALLSESSIONS, BURST->LASTSESSION
2026-02-23 19:50:47 +01:00
MaPaLo76
d644ff4986
refactor(laser): Burst-Begriff durch Session ersetzt (BurstState->SessionState, getLastBurstSeconds->getLastSessionSeconds, consumeBurstEnd->consumeSessionEnd)
2026-02-23 19:33:40 +01:00
MaPaLo76
ff67b07144
fix(mqtt): publishSession nicht bei GRATIS-only Burst (lastBurstSec == 0)
2026-02-23 19:25:43 +01:00
MaPaLo76
d0d4666cf7
refactor(mqtt,web): Terminologie Session/Maschinenlaufzeit, JSON-Felder aktualisiert
2026-02-23 19:17:29 +01:00
MaPaLo76
dbe2e9791b
Update README.md Screenshots
2026-02-22 21:22:54 +01:00
MaPaLo76
e18b00f37e
Update README.md Screenshots
2026-02-22 21:21:24 +01:00
MaPaLo76
52b04ac9a6
Update README.md Screenshots
2026-02-22 21:20:06 +01:00
MaPaLo76
546b155af2
fix(web): POST /reset setzt nur Session zurueck (resetSession), nicht NVS-Gesamtzeit
2026-02-22 20:55:24 +01:00
MaPaLo76
440dd532b6
docs(tests): Test 7.7 WebServer Abschnitt und Checkliste ergaenzt
2026-02-22 20:48:15 +01:00
MaPaLo76
d6adc9f23e
docs: Phase 7 Checkliste, README Test 7.7 Abschnitt und Implementierungsstand
2026-02-22 20:44:51 +01:00
MaPaLo76
16838fa265
feat(web): Phase 7 WebServer (ESPAsyncWebServer, Config, Reset, ElegantOTA)
2026-02-22 20:43:08 +01:00
MaPaLo76
f5257e2191
docs(plan): Phase 6 6.6 und 6.7 offen (Reconnect + Modul-5-Error ungetestet)
2026-02-22 20:30:01 +01:00
MaPaLo76
3892c6b329
docs(plan): Phase 6 Checkboxen gesetzt, Details aktualisiert (TLS, LWT, JSON-Reset)
2026-02-22 20:29:05 +01:00
MaPaLo76
82ae93626a
docs(readme): Implementierungsstand Phase 6 ergaenzt, Test 6.5 in Uebersicht, Projektstruktur aktualisiert
2026-02-22 20:26:04 +01:00
MaPaLo76
46b62f720a
docs(tests): Test 6.5 Checkliste aktualisiert (Reset OK, LWT OK, Modul5/Reconnect ungetestet)
2026-02-22 20:22:02 +01:00
MaPaLo76
84e6062ab1
docs(readme): MQTT-Sektion auf Phase-6-Stand (TLS, JSON-Reset, korrekte Payloads, Broker-Default)
2026-02-22 20:17:45 +01:00
MaPaLo76
100e4b960d
feat(mqtt): Reset-Topic akzeptiert JSON-Payload {reset:true} zusaetzlich zu plain 1
2026-02-22 20:15:39 +01:00
MaPaLo76
c1bd36c84f
docs(tests): Test 6.5 als OK markiert (mqtt.majufilo.eu TLS:8883)
2026-02-22 20:13:53 +01:00
MaPaLo76
0dbfa07744
feat(mqtt): TLS-Unterstuetzung (WiFiClientSecure, Port 8883), Secrets-Datei gitignoriert
2026-02-22 20:06:53 +01:00
MaPaLo76
b9c20c4a98
chore: Copilot Workspace Instructions hinzugefuegt (Deutsch, Terminal-Wiederverwendung)
2026-02-22 19:45:24 +01:00
MaPaLo76
7e7d8797f8
docs(tests): Test 6.5 MqttClient in test_sketches/README ergaenzt
2026-02-22 19:39:52 +01:00
MaPaLo76
71ef2c7ad0
feat(mqtt): Phase 6 - MqttClient implementiert (PubSubClient, publishSession, Heartbeat, Reset-Subscribe)
2026-02-22 19:36:29 +01:00
MaPaLo76
f389a7deea
docs(tests): test_sketches/README.md vollstaendig auf Phase-5-Stand
2026-02-22 19:17:32 +01:00
MaPaLo76
d5d0085d93
docs(readme): README auf Phase-5-Stand aktualisiert, Tests-Sektion ergaenzt
2026-02-22 19:14:15 +01:00
MaPaLo76
bf1b32e24d
fix(laser): NVS zaehlt gesamte Laser-AN-Zeit inkl. Gratiszeit
2026-02-22 18:54:35 +01:00
MaPaLo76
d114a58de6
fix(phase5): LaserTracker neu - Session/Burst-Logik korrigiert
...
- BurstState-Maschine: INACTIVE -> GRATIS -> NET_COUNTING
- _sessionNetSec (RAM): Netto-Sekunden der Betriebssitzung, reset beim Start
- _totalMinutesBase (NVS via settings.saveTotalMinutes): persistierte Gesamtzeit
- Gratis-Countdown startet bei JEDEM Laser-AN-Ereignis neu
- Netto-Zeit wird erst nach Ablauf der Gratiszeit gezaehlt
- getSessionMinutes(): sessionNetSec / 60 (ganzzahlig, hart)
- getCountdownRemaining(): nur 0 wenn INACTIVE oder NET_COUNTING
- Display Module 1-3: Session-Minuten (nicht Gesamtzeit)
- Display Module 5-7: Countdown waehrend GRATIS, sonst Idle
- settings.saveTotalMinutes() statt direkter Preferences-Calls
- main.cpp + test_laser_tracker.cpp auf neue API umgestellt
2026-02-22 18:48:35 +01:00
MaPaLo76
3827342c0c
feat(laser): implement LaserTracker with debounce, gratis time and NVS save
...
- Add include/laser_tracker.h: LaserTracker class declaration
- Software debounce (LASER_DEBOUNCE_MS = 50ms from config.h)
- Polarity-aware GPIO read (LOW_ACTIVE / HIGH_ACTIVE from settings)
- Session lifecycle: onSessionStart / onSessionEnd
- Gratis time countdown, net seconds accumulation
- Getters: isActive, getTotalMinutes, getSessionSeconds,
getCountdownRemaining, getLastSessionSeconds, resetTotal
- Add src/laser_tracker.cpp: full implementation
- readRaw() applies signal polarity
- loop() handles debounce state machine and edge detection
- onSessionEnd() saves updated totalMinutes to NVS
- getTotalMinutes() returns live value (base + current net session)
- Add test_sketches/test_laser_tracker.cpp: interactive test sketch
- Button on GPIO 4 simulates laser signal
- BOOT button (GPIO 0, 3s hold) resets total
- Display: modules 1-3 = total minutes, modules 5-7 = countdown/net
- Add test-laser-tracker env to platformio.ini
- Update src/main.cpp: integrate laserTracker.begin/loop + live display
- Update Implementation-Plan.md: mark Phase 5 tasks 5.1-5.6 complete
2026-02-22 14:30:14 +01:00
MaPaLo76
26a4e9b95c
fix(display): redesign module layout - integer minutes, dedicated error slots
...
New module assignment:
Module 0 : WiFi error indicator (showWifiError) - 'W' / blank
Module 1-3 : laser time in full minutes, 3-digit right-aligned
Module 4 : MQTT error indicator (showMqttError) - 'M' / blank
Module 5-7 : countdown seconds / idle / status, 3-digit right-aligned
Changes in display_manager.h:
- Update zone layout comments
- showLaserTime: integer minutes only, writes modules 1-3 (module 0 untouched)
- showCountdown: writes modules 5-7 only (module 4 untouched)
- showIdle: ' --' on modules 5-7
- showStatus: 3-char string on modules 5-7
- Add showWifiError(bool): module 0
- Add showMqttError(bool): module 4
Changes in display_manager.cpp:
- Add BMP_M character bitmap
- Add 'M' case in charBitmap()
- Rewrite showLaserTime() - round to int, 3 chars, modules 1-3
- Rewrite showCountdown() - 3 chars, modules 5-7
- Rewrite showIdle() - ' --' on modules 5-7
- Rewrite showStatus() - 3 chars, modules 5-7
- Add showWifiError() / showMqttError() implementations
- Update printToSerial() log output
Changes in test_sketch:
- 9 test steps covering all new methods incl. combination test
- Tested on hardware: all steps passed
2026-02-22 14:15:18 +01:00
MaPaLo76
4349b37f05
feat(display): implement DisplayManager with raw MD_MAX72XX
...
- Add include/display_manager.h: DisplayManager class declaration
- Two-zone layout: Zone 0 (top, laser time), Zone 1 (bottom, countdown/status)
- showLaserTime(), showCountdown(), showIdle(), showStatus(), setBrightness()
- rotateCCW() bitmap transformation for 90 deg physical module rotation
- charBitmap() for 17-character set (0-9, space, dash, dot, special chars)
- Add src/display_manager.cpp: full implementation
- Double-init pattern for SPI power stability
- showLaserTime() format: <10 -> ' x.x', <100 -> 'xx.x', <1000 -> ' xxx', else 'xxxx'
- showCountdown() right-aligned 4-char format
- All methods use writeZone() -> writeChar() -> rotateCCW() -> MD_MAX72XX
- Add test_sketches/test_display_manager.cpp: 6-step verification test
- allLedsOn/Off, showLaserTime (12 boundary values), showCountdown 5->0
- showIdle, showStatus (Err/AP/WiFi/oF), live simulation loop
- Update platformio.ini: add test-display-mgr environment
- Update src/main.cpp: integrate display.begin/showIdle/update
- Update Implementation-Plan.md: mark Phase 4 tasks 4.1-4.3 complete
Tested on hardware: all 6 test steps passed
2026-02-22 14:00:54 +01:00