refactor: Display-Firmware neutral als P4_Display_Firmware führen

Der Ordner hieß JC_Display_Firmware, bedient seit 1.6.0 aber auch das
Waveshare 7inch DSI LCD (H) am ESP32-P4-Pico. Der Name führte in die Irre.

- JC_Display_Firmware/ -> P4_Display_Firmware/ (samt Sketch, den Arduino
  gleichnamig zum Ordner verlangt)
- Doku/JC-Display_UART-Protokoll.md -> Doku/P4-Display_UART-Protokoll.md,
  Verweise und Titel angepasst
- Verweise in CLAUDE.md, README und Quelltextköpfen nachgezogen

Nur Namen und Pfade, keine Logikänderung. Der Vendor-Ordner
JC_Display_Firmware_7zoll/ behält seinen Namen, ebenso die Bezeichner
JC_PANEL_TYPE/jc_board_bringup im Quelltext.

Enthält außerdem die bereits im Arbeitsverzeichnis liegende, noch nicht
committete Ergänzung des Git-Workflows in CLAUDE.md (PRs über die Gitea-API
statt der hängenden tea-CLI).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
This commit is contained in:
raw-designs
2026-09-01 03:30:42 +02:00
co-authored by Claude Opus 5
parent e0c6784ecf
commit 4f9f686d81
4805 changed files with 26 additions and 26 deletions
+91
View File
@@ -0,0 +1,91 @@
// =====================================================================================
// protocol_client.h - UART-Protokoll-Client (P4-Seite)
// =====================================================================================
// Implementiert die Display-Seite des in Doku/P4-Display_UART-Protokoll.md (v2)
// beschriebenen Protokolls:
// - empfaengt : state / ack / error / profiles / profileDetails / hello
// - sendet : hello / ping / getState / listProfiles / loadProfile / action /
// saveBrew / saveService / saveSensor / setPid /
// startAutotune / stopAutotune / getProfileDetails
// - Heartbeat, hello-Handshake, Link-Timeout-Ueberwachung
//
// Parsen: ArduinoJson (der ESP32-P4 hat reichlich RAM/PSRAM).
// =====================================================================================
#pragma once
#include <Arduino.h>
#include "config.h"
#include "machine_state.h"
class ProtocolClient {
public:
// Callback-Typen
typedef void (*StateCb)(const MachineState& st);
typedef void (*ProfilesCb)(const String profiles[], int count);
typedef void (*RawJsonCb)(const String& json); // profileDetails (Roh-JSON)
typedef void (*AckCb)(uint32_t id, bool ok, const String& message);
explicit ProtocolClient(MachineState& state) : _state(state) {}
void begin();
void loop();
bool linkUp() const { return _state.linkUp; }
// --- Diagnose-Zaehler (fuer On-Screen-Debug) ---
unsigned long rxByteCount = 0; // gesamt empfangene Bytes (auch unvollstaendige)
unsigned long rxLineCount = 0; // vollstaendige Zeilen
unsigned long txCmdCount = 0; // gesendete Kommandos
unsigned long helloCount = 0; // gesendete hello
unsigned long parseErrorCount = 0; // JSON-Parse-Fehler
String lastRxLine; // zuletzt empfangene Rohzeile
// --- Callbacks registrieren ---
void onState(StateCb cb) { _stateCb = cb; }
void onProfiles(ProfilesCb cb) { _profilesCb = cb; }
void onProfileDetails(RawJsonCb cb) { _profileDetailsCb = cb; }
void onUsageStats(RawJsonCb cb) { _usageStatsCb = cb; } // Antwort auf getUsageStats (Roh-JSON)
void onWifiNetworks(RawJsonCb cb) { _wifiNetworksCb = cb; } // Antwort auf scanWifi (Roh-JSON)
void onOta(RawJsonCb cb) { _otaCb = cb; } // OTA-Nachrichten von der S3 (Roh-JSON)
void onAck(AckCb cb) { _ackCb = cb; }
// --- Kommandos (Rueckgabe: vergebene id) ---
uint32_t sendHello();
uint32_t sendPing();
uint32_t sendGetState();
uint32_t sendListProfiles();
uint32_t sendGetUsageStats(); // Nutzungsstatistik anfordern
uint32_t sendLoadProfile(const String& profile);
uint32_t sendGetProfileDetails(const String& profile);
uint32_t sendAction(const String& action, const String& value = "");
uint32_t sendSetPid(const String& fieldsJson); // z.B. "\"kpW\":5.0,\"kiW\":0.2"
uint32_t sendStartAutotune(const String& target);// "water" | "steam"
uint32_t sendStopAutotune();
uint32_t sendScanWifi(); // WLAN-Scan anstossen
uint32_t sendSetWifi(const String& ssid, const String& password); // verbinden
// Frei-Form: zusaetzliche Felder als bereits serialisiertes JSON-Fragment ohne
// aeussere Klammern, z.B. sendCommand("saveBrew", "\"bbtEnabled\":true,\"bbtSecs\":25");
uint32_t sendCommand(const String& op, const String& extraFields = "");
private:
void handleLine(const String& line);
void applyState(const String& json);
void applyProfiles(const String& json);
void maintainLink();
MachineState& _state;
String _rxBuf;
bool _rxOverflow = false;
uint32_t _nextId = 1;
unsigned long _lastHeartbeatMs = 0;
unsigned long _lastHelloMs = 0;
StateCb _stateCb = nullptr;
ProfilesCb _profilesCb = nullptr;
RawJsonCb _profileDetailsCb = nullptr;
RawJsonCb _usageStatsCb = nullptr;
RawJsonCb _wifiNetworksCb = nullptr;
RawJsonCb _otaCb = nullptr;
AckCb _ackCb = nullptr;
};