Profil-Modell¶
Ein Profil ist eine Implementierung der IProfile Schnittstelle, die das Verhalten eines spezifischen Geräts beschreibt. Die Bibliothek interagiert mit dem Produkt nur über diese Schnittstelle.
IProfile-Schnittstelle¶
class IProfile {
public:
virtual ~IProfile() = default;
virtual void onOnline() = 0;
virtual void loop() = 0;
virtual void getConfig(JsonDocument& out) = 0;
virtual bool applyConfig(int id, int val) = 0;
virtual void buildInfoJson(char* buf, size_t len) const = 0;
};
Wann die Bibliothek jede Methode aufruft¶
| Methode | Wann aufgerufen | Was es tun muss |
|---|---|---|
onOnline() |
Beim ersten CloudStateMachine Übergang zu Online |
Konfiguration aus NVS laden, auf Hardware anwenden |
loop() |
Bei jeder Iteration von IdryerRuntime::loop() |
Timer, Animationen, Sensor-Polling |
buildInfoJson(buf, len) |
Beim Übergang zu Online; auf ping |
Geräteinformationen-Payload serialisieren |
getConfig(out) |
Auf invoke device.getConfig |
Dokument mit aktueller Konfiguration füllen |
applyConfig(id, val) |
Auf commands/set |
Parameter anwenden, in NVS speichern |
Beispiel: LedStripProfile¶
LedStripProfile ist die Profil-Implementierung für Storage Link. Befindet sich in src/storage/led_strip/.
class LedStripProfile : public IProfile {
public:
explicit LedStripProfile(LedStripExecutor* executor);
void onOnline() override;
void loop() override;
void getConfig(JsonDocument& out) override;
bool applyConfig(int id, int val) override;
void buildInfoJson(char* buf, size_t len) const override;
static void normalizeGroups(); // fix NVS state of toggle groups
static uint8_t selectedStripType(); // 0=WS2812B, 1=APA102
static uint8_t selectedColorOrder(); // 0=GRB, 1=RGB, 2=BRG, 3=BGR
static constexpr const char* DEVICE_TYPE = "storage_link";
static constexpr const char* HW_VERSION = "1.0";
static constexpr const char* FW_VERSION = "1.0.0";
private:
LedStripExecutor* executor_;
};
onOnline() wendet die aktuelle LED-Streifen-Konfiguration (LED-Anzahl, Helligkeit) auf LedStripExecutor an.
applyConfig(id, val) akzeptiert eine Parameter-ID aus menu_ids.h und einen neuen Wert. Speichert über das menu Objekt in NVS. Parameter wie strip_type und color_order benötigen einen Neustart — FastLED wird einmal beim Start initialisiert.
buildInfoJson erstellt die Payload für idryer/{serial}/info. Die Feldkomposition wird vom Produkt definiert. Storage Link veröffentlicht:
{
"deviceType": "storage_link",
"firmwareVersion": "1.0.0",
"hardwareVersion": "1.0",
"timestamp": "2026-04-28T10:00:00Z"
}
Für Geräte mit mehreren Kammer-Einheiten (iDryer LINK) ist es typisch, workTimeCounter, unitsCount und ein units Array, das Fähigkeiten beschreibt, hinzuzufügen.
ActionDispatcher¶
ActionDispatcher leitet zwei Befehlstypen ohne std::function (schlichte Funktionszeiger zur Heapeinsparung):
// Invoke: action with name and arguments
using InvokeHandler = bool (*)(const char* action, JsonObjectConst args, void* ctx);
// Set: setting a single parameter
using SetCallback = void (*)(JsonObjectConst data, void* ctx);
Registrierung in setup():
// Invoke — delegates to LedStripExecutor
dispatcher.setInvokeHandler(
[](const char* action, JsonObjectConst args, void* /*ctx*/) -> bool {
return s_executor.execute(action, args);
}, nullptr);
// Set — passes id/val to LedStripProfile
dispatcher.setSetCallback(
[](JsonObjectConst data, void* /*ctx*/) {
int id = data["id"] | -1;
int val = data["val"] | -1;
s_profile.applyConfig(id, val);
}, nullptr);
IdryerRuntime ruft dispatcher.handleInvoke(data) und dispatcher.handleSet(data) auf, wenn die entsprechenden MQTT-Befehle eintreffen.
Ein neues Profil erstellen¶
- Erstellen Sie eine Klasse, die von
IProfileerbt. - Implementieren Sie alle fünf Methoden.
- Übergeben Sie einen Zeiger auf das Profil an den
IdryerRuntimeKonstruktor. - Registrieren Sie Handler in
ActionDispatcherfürinvokeundsetBefehle.
Es gibt keine Einschränkungen, was das Profil in seinen Methoden tut — es hat vollständige Sichtbarkeit in den Produkt-Kontext.