コンテンツにスキップ

公開 API: iDryer::Link

iDryer::Link は組込み開発者のための単一の エントリ ポイントです。ファサードはスタック全体を隠しています: WiFi/Improv、クラウド ステート マシン、HTTP クレーム、MQTT、ローカル WebSocket、NVS。プロダクトは telemetry/status フィールドを埋め、コールバックを登録し、begin()/loop() を呼び出すだけで済みます。


ライフサイクル

典型的な main.cpp スケルトン:

#include <iDryer.h>
#include <runtime/idryer_runtime.h>  // only needed if setCommandHandler is used

static const iDryer::Config CFG = {
    .deviceType        = iDryer::DeviceType::StorageLink,
    .unitsCount        = 1,
    .hasAirTemp        = true,
    .hasAirHumidity    = true,
    .hasHeaterTemp     = false,
    .hasHeaterPower    = false,
    .hasFanStatus      = false,
    .hasScales         = false,
    .hasRfid           = false,
    .telemetryPeriodMs = 10000,
    .statusPeriodMs    = 0,
    .hardwareVersion   = "1.0",
    .firmwareVersion   = "1.0.0",
};

static iDryer::Link link(CFG);

void setup() {
    link.begin();
    // setCommandHandler — strictly AFTER begin(): begin() installs its own dispatcher
    link.runtime()->setCommandHandler(handleCommand);
}

void loop() {
    link.loop();
    link.telemetry.airTempC[0]       = sensor.readTemp();
    link.telemetry.airHumidityPct[0] = sensor.readHumidity();
}

設定: iDryer::Config

main.cpp で 1 回埋められ、Link コンストラクターに渡されます。すべてのフィールドは集約初期化 (C++ 指定イニシャライザー) を使用します。

フィールド タイプ 目的 注記
deviceType DeviceType デバイス タイプ 必須
unitsCount uint8_t ユニット (チャンバー) の数、1..MAX_UNITS (4) 必須
hasAirTemp bool 気温センサーが存在 false = JSON から省略
hasAirHumidity bool 湿度センサーが存在 false = JSON から省略
hasHeaterTemp bool ヒーター温度センサーが存在 —
hasHeaterPower bool ヒーター電力センサーが存在 —
hasFanStatus bool ファン ステータスが存在 —
hasScales bool スケールが存在 —
hasRfid bool RFID リーダーが存在 —
telemetryPeriodMs uint32_t Telemetry (ms) の自動発行期間 0 = 発行しない
statusPeriodMs uint32_t Status (ms) の自動発行期間 0 = 発行しない
hardwareVersion const char* ハードウェア バージョン文字列 必須
firmwareVersion const char* ファームウェア バージョン文字列 必須

どの連携をイメージに含めるかは、製品の platformio.ini の IDRYER_WITH_HA、IDRYER_WITH_BAMBU、 IDRYER_WITH_MOONRAKER で決まります。無効な連携はイメージにも integrations/status にも存在せず、 ポータルからのコマンドは拒否されます。


コンストラクター

explicit Link(const Config& cfg);

const リファレンスで設定を取得します。CFG はフル オブジェクト ライフタイム (通常 static const) に対して存在する必要があります。

メソッド

begin()

bool begin();

SDK スタック全体を起動します: WiFi/Improv、クラウド ステート マシン、HTTP クレーム、MQTT、ローカル WebSocket、NVS 永続性。

setup() で 1 回呼び出します。初期化が成功すると true を返します。

void setup() {
    link.begin();
}

loop()

void loop();

唯一の必須ティック。WiFi/MQTT/LocalAccess をサービスし、自動発行テレメトリーとステータスをそれらのタイマーで提供します。

loop() の毎回の反復で呼び出します。この呼び出しなしでは接続は維持されません。

void loop() {
    link.loop();  // first in loop(), before product logic
}

ソース: iDryer-Storage/src/main.cpp:253, iHeater-link/src/main.cpp:381.

publishTelemetryNow()

void publishTelemetryNow();

telemetryPeriodMs タイマーに関係なく、現在の link.telemetry 状態を直ちに発行します。

publishStatusNow()

void publishStatusNow();

現在の link.status 状態を直ちに発行します。コマンドを処理した後に使用し、新しい状態をポータルに直ちに反映させます。

// iHeater-link/src/main.cpp:238
device().publishStatusNow();

raiseEvent()

void raiseEvent(EventKind   severity,
                const char* event,
                const char* message,
                uint8_t     unitId = 0xFF);

トピック idryer/{serial}/events にイベントを発行します。直ちに送信されます。

パラメーター タイプ 目的
severity EventKind Info / Warning / Error
event const char* イベント コード、例えば "OVERHEAT"、"SESSION_COMPLETE"
message const char* 任意のデバッグ テキスト
unitId uint8_t ユニット インデックス (0..unitsCount-1) またはデバイス全体の 0xFF
link.raiseEvent(iDryer::EventKind::Error, "OVERHEAT", "U1 too hot", 0);

onCommand()

bool onCommand(const char* name, CommandCallback cb);

コマンド名ごとにハンドラーを登録します。MQTT または Local WS で commands/{name} が任意の JSON とともに届くと呼ばれます。

CommandCallback = void (*)(JsonObjectConst data)

s_link.onCommand("revoke", [](JsonObjectConst) { s_link.handleRevoke(); });

名前は任意です。drying、stop、storage、get_config、set、profile、 led.pulse など何でも構いません。あふれた場合(コマンドは最大 12 個)や引数が 不正な場合は false を返します。

組み込みコマンド link_integration、bambu_apply、ping はライブラリ自身が 処理し、横取りはできません。同じ名前でハンドラーを登録することは可能で、 ライブラリの処理のあとに実行されます。

重要: runtime()->setCommandHandler(...) を設定すると、完全なディスパッチャー がすべてを受け取り、ここで登録したハンドラーは呼ばれません。

onIntegrationStatus()

void onIntegrationStatus(IntegrationStatusCallback cb);

インテグレーション接続状態が変わるとき呼び出されます (HA、Bambu、Moonraker)。オプション コールバック。

IntegrationStatusCallback = std::function<void(const iDryer::IntegrationStatus&)>

onClaimComplete()

void onClaimComplete(ClaimCompleteCallback cb);

バックエンドが紐づけを確認した時点で一度だけ呼ばれます(MQTT が立ち上がる前)。

ClaimCompleteCallback = void (*)(const char* deviceId)

isBound()

bool isBound() const;

true — デバイスは恒久的なシークレットを持ち、アカウントに紐づいています。 false — 設定モード。アプリまたはフラッシャーからのペアリングトークンを待って います。製品側はこの状態を画面に出すために使います。

handleRevoke()

void handleRevoke();

ポータルからの REVOKE コマンドを処理します。シークレットを消去し、デバイスを トークン待ちに戻します。onCommand("revoke") から呼びます。

mqttKey()

const char* mqttKey() const;

デバイスが MQTT を公開する際のキー。紐づけ前はモジュールのシリアル、紐づけ後は コントローラーのシリアルです。

isOnline()

bool isOnline() const;

デバイスが登録されており、MQTT セッションがアクティブな場合、true を返します。

// iHeater-link/src/main.cpp:281
if (device().isOnline()) { ... }

serial()

const char* serial() const;

デバイス シリアル番号 (NVS からの文字列、クレーム中に割り当て)。クレームが完了する前は空の文字列。

seedWifiCredentialsIfEmpty()

void seedWifiCredentialsIfEmpty(const char* ssid, const char* password);

WiFi 認証情報がまだ設定されていない場合のみ、NVS に書き込みます。begin() の前に呼び出します。ハードコードされた認証情報を持つ dev 環境で使用されます。

setWifiCredentials()

void setWifiCredentials(const char* ssid, const char* password);

常に NVS の WiFi 認証情報を上書きします。Dev ヘルパーと強制的な再プロビジョニング。

// iHeater-link/src/main.cpp:313
device().setWifiCredentials(ssid.c_str(), pass.c_str());

eraseClaimAndRestart()

void eraseClaimAndRestart();

NVS からデバイス トークンを削除し、チップを再起動します。再起動後、デバイスはクレームされていません — 自動クレーム フローが再度開始されます。この関数は戻りません。

// iHeater-link/src/main.cpp:293
device().eraseClaimAndRestart();

integrationsManager()

idryer::cloud::LinkIntegrationsManager* integrationsManager();

インテグレーション マネージャーへのアウトレット — プロダクト側のワイヤリング用 (Moonraker チャンバー ターゲット コールバック、Bambu プリンター ステータスなど)。

#include <integrations/common/link_integrations_manager.h> が必要です。

// iHeater-link/src/main.cpp:337
device().integrationsManager()->setVirtualChamberCallback(onVirtualChamberUpdate);

mqttClient()

idryer::MqttClient* mqttClient();

SDK MQTT クライアントへのアウトレット — 独自のトピックを発行するかコマンド ルーティング (例えば MenuBridge) に統合するコンポーネント用。

#include <mqtt/mqtt_client.h> が必要です。

devicePublisher()

idryer::DevicePublisher* devicePublisher();

デュアル発行ヘルパーへのアウトレット — 1 つのペイロードを MQTT とローカル WS の両方に同時に送信します。自動発行テレメトリーと同じ方法でポータルに到達する必要があるプロダクト応答に使用します。

// iDryer-Storage/src/main.cpp:175
link.devicePublisher()->publishConfigRaw(buf, len);

runtime()

idryer::IdryerRuntime* runtime();

SDK ランタイムへのアウトレット — ファサード ディスパッチャーの代わりに完全なコマンド ハンドラーを設定するために使用。setCommandHandler(...) 後、onCommand() で登録したハンドラーは MQTT パス経由では呼び出されません。

重要: begin() の後に厳密に呼び出します — begin() は独自のディスパッチャーをインストールします。これは上書きされる必要があります。

// iDryer-Storage/src/main.cpp:249
link.runtime()->setCommandHandler(handleCommand);

// Handler signature:
// void handleCommand(const char* cmd, JsonObjectConst data);

#include <runtime/idryer_runtime.h> が必要です。


テレメトリー フィールド

loop() でプロダクトによって埋められます。SDK は telemetryPeriodMs タイマーで読み取り、MQTT とローカル WS に発行します。

フィールド タイプ 設定フラグ 目的
telemetry.airTempC[unitId] float hasAirTemp 気温、°C
telemetry.airHumidityPct[unitId] float hasAirHumidity 湿度、%
telemetry.heaterTempC[unitId] float hasHeaterTemp ヒーター温度、°C
telemetry.heaterPower01[unitId] float hasHeaterPower ヒーター電力、0.0..1.0
telemetry.fanOn[unitId] bool hasFanStatus ファン ステータス
telemetry.weightG[unitId] uint16_t hasScales 重量、グラム
// iDryer-Storage/src/main.cpp:267
link.telemetry.airTempC[0]       = r.temperature;
link.telemetry.airHumidityPct[0] = r.humidity;

unitId = 最初の (または唯一の) ユニットの場合 0。インデックスは < Config.unitsCount である必要があります。

Status フィールド — 同じ構造ですが、操作状態:

フィールド タイプ 目的
status.mode[unitId] UnitMode 現在のユニット モード
status.targetTempC[unitId] float 目標温度
status.durationS[unitId] uint32_t リクエストされた期間、s (0 = 無制限)
status.elapsedS[unitId] uint32_t セッション開始からの経過時間、s
// iHeater-link/src/main.cpp:229
device().status.mode[0]        = iDryer::UnitMode::Drying;
device().status.targetTempC[0] = cmd.targetTempC;
device().publishStatusNow();

ランタイム経由のコールバック登録

着信コマンドの完全な制御が必要な場合 (例えば、プロダクトが get_config、set、非標準 invoke を処理):

// Signature — from idryer_runtime.h
void handleCommand(const char* cmd, JsonObjectConst data);

// Registration — strictly after link.begin()
link.runtime()->setCommandHandler(handleCommand);

cmd — コマンド文字列 ("set"、"invoke"、"ping"、"get_config")。 data — ArduinoJson JsonObjectConst with ペイロード。

この方式では、onCommand() のハンドラーは MQTT パスから呼び出されません。プロダクトがコマンドを自分で解釈します。


列挙

iDryer::DeviceType

値 数値 目的
Unknown 0 なし / 未定義
Dryer 1 ドライヤー (iDryer LINK)
Heater 2 ヒーター
StorageLink 4 ストレージ リンク (ESP32-C3 + LED)
IHeaterLink 5 iHeater リンク

iDryer::UnitMode

Idle、Drying、Storage、Profile、Fault、Unknown

iDryer::EventKind

Info、Warning、Error

iDryer::RequestKind

Start、Stop、Storage、Find、ClearErrors

iDryer::IntegrationKind

Ha、Bambu、Moonraker

iDryer::IntegrationState

Disabled、Idle、Connecting、Online、ConfigMissing、Error


より深く掘る場合

ファサードはほとんどのタスクに十分です。idryer::IdryerRuntime、idryer::MqttClient、idryer::cloud::LinkIntegrationsManager でファサード レベルより下で作業する必要がある場合 — アーキテクチャ セクションを参照してください。