Neues Produkt auf Basis von idryer-core hinzufügen¶
Diese Anleitung ist für neue Produkte auf Basis von idryer-core: Filamenttrockner, Heizblock, Beleuchtung, Sensor oder anderes Modul. Sie zeigt, was in der Bibliothek bleibt und was in den konkreten Produktcode gehört.
Eine praktische Checkliste zum Erstellen eines neuen Geräts auf der Basis von idryer-core.
Zwei Szenarien:
- Minimal — MQTT + Cloud nur. Ausreichend für die meisten einfachen Geräte.
- Erweitert — MQTT + lokaler WS-Zugriff über LAN. Für Geräte, die lokalen Zugriff ohne die Cloud benötigen.
Szenario 1: Minimales MQTT-only-Gerät¶
Minimales Set: WiFi, MQTT, Cloud State Machine, ein Profil.
Referenz: examples/minimal_mqtt_only/
1. Implementieren Sie IProfile¶
// src/mydevice/my_profile.h
#include <profiles/IProfile.h>
class MyProfile : public idryer::IProfile {
public:
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;
};
2. Montieren Sie die Composition Root¶
#include <idryer_core.h>
static idryer::ArduinoWifiStore s_wifiStore;
static idryer::ArduinoWifiManager s_wifi;
static idryer::ArduinoCredentialStore s_credentials;
static idryer::ArduinoHttpClient s_http;
static idryer::cloud::HttpApi s_api(&s_http, IDRYER_API_BASE);
static idryer::MqttClient s_mqtt;
static idryer::cloud::CloudStateMachine s_cloud(&s_wifi, &s_credentials, &s_api, &s_mqtt);
static idryer::ActionDispatcher s_dispatcher;
static MyProfile s_profile;
static idryer::IdryerRuntime s_runtime(&s_cloud, &s_dispatcher, &s_profile, &s_mqtt);
3. Registrieren Sie den Command Handler und starten Sie¶
static void handleCommand(const char* cmd, JsonObjectConst data) {
const char* action = data["action"] | "";
if (strcmp(cmd, "get_config") == 0 ||
(strcmp(cmd, "invoke") == 0 && strcmp(action, "device.getConfig") == 0))
{
StaticJsonDocument<256> doc;
s_profile.getConfig(doc);
s_mqtt.publishConfig(doc);
return;
}
if (strcmp(cmd, "invoke") == 0) { s_dispatcher.handleInvoke(data); return; }
if (strcmp(cmd, "set") == 0) { s_dispatcher.handleSet(data); return; }
}
void setup() {
Serial.begin(115200);
idryer::hal::initArduinoHal(&Serial);
// ... load WiFi credentials, seedSerialFromMac ...
s_runtime.setCommandHandler(handleCommand);
s_runtime.begin();
}
void loop() {
s_runtime.loop();
}
Szenario 2: MQTT + Local WS Gerät¶
Erweitert Minimal. Fügt LocalAccess (LAN WebSocket + mDNS) und DevicePublisher hinzu — ein dünner Wrapper zum Veröffentlichen auf beiden Transporte in einem Aufruf.
Referenz: examples/mqtt_with_local_ws/
Zusätzliche Objekte¶
#include <local_access/local_access.h>
#include <local_access/device_publisher.h>
static idryer::LocalAccess s_local;
static idryer::DevicePublisher s_pub(&s_mqtt, &s_local);
Command Handler — einer für beide Transporte¶
static void handleCommand(const char* cmd, JsonObjectConst data) {
const char* action = data["action"] | "";
if (strcmp(cmd, "get_config") == 0 ||
(strcmp(cmd, "invoke") == 0 && strcmp(action, "device.getConfig") == 0))
{
StaticJsonDocument<256> doc;
s_profile.getConfig(doc);
s_pub.publishConfig(doc); // → MQTT + WS
return;
}
if (strcmp(cmd, "invoke") == 0) { s_dispatcher.handleInvoke(data); return; }
if (strcmp(cmd, "set") == 0) { s_dispatcher.handleSet(data); return; }
}
Initialisierung in setup()¶
s_credentials.seedSerialFromMac();
{
idryer::DeviceIdentity identity;
s_credentials.load(identity);
s_local.initMdns(identity.serialNumber); // mDNS before WS starts
s_local.begin(identity.serialNumber, identity.token);
s_local.setCommandSink(handleCommand); // same handler
s_local.setTokenRefreshCallback([]() {
idryer::DeviceIdentity id;
s_credentials.load(id);
s_local.updateToken(id.token);
});
}
s_runtime.setCommandHandler(handleCommand);
s_runtime.begin();