Pular para conteúdo

Raiz de composição

O produto cria todos os objetos da biblioteca em main.cpp como variáveis estáticas e passa dependências através de construtores. Sem fábricas, sem registros globais — apenas montagem explícita.

Ordem de criação de objetos

As dependências são construídas de baixo para cima: primeira camada de plataforma, depois pilha de nuvem, depois tempo de execução.

// 1. Camada de plataforma
idryer::ArduinoWifiStore       s_wifiStore;      // NVS: SSID/password
idryer::ArduinoWifiManager     s_wifi;           // Gerenciamento WiFi
idryer::ArduinoCredentialStore s_credentials;    // NVS: serial/token/deviceId
idryer::ArduinoHttpClient      s_http;           // TLS HTTP para provisionamento

// 2. Pilha de nuvem
idryer::cloud::HttpApi           s_api(&s_http, IDRYER_API_BASE);
idryer::MqttClient               s_mqtt;
idryer::cloud::CloudStateMachine s_cloud(&s_wifi, &s_credentials, &s_api, &s_mqtt);
idryer::ActionDispatcher         s_dispatcher;

// 3. Perfil de produto (implementa IProfile) — código do produto, não da biblioteca
LedStripProfile s_profile(&s_executor);

// 4. Tempo de execução — vincula tudo
idryer::IdryerRuntime s_runtime(&s_cloud, &s_dispatcher, &s_profile, &s_mqtt);

O que setup() faz

void setup() {
    // HAL: logs vão para /dev/null enquanto Improv possui Serial
    idryer::hal::initArduinoHal(nullptr);

    // Restaurar credenciais WiFi salvas
    char ssid[64], pass[64];
    if (s_wifiStore.load(ssid, sizeof(ssid), pass, sizeof(pass))) {
        s_wifi.begin(ssid, pass);
    }

    // Gerar série a partir do MAC se ainda não estiver presente
    s_credentials.seedSerialFromMac();

    // Registrar manipuladores de comando
    s_dispatcher.setInvokeHandler(onInvoke, nullptr);
    s_dispatcher.setSetCallback(onSetCommand, nullptr);

    // Opcional: reagir a transições de máquina de estado
    s_cloud.setStateChangeCallback([](auto prev, auto, void*) {
        if (prev == idryer::cloud::CloudState::WifiConnecting)
            configTime(0, 0, "pool.ntp.org", "time.google.com");
    }, nullptr);

    // Reivindicação automática para dispositivos autónomos
    s_cloud.setUnclaimedCallback([](void*) {
        s_cloud.requestClaim();
    }, nullptr);

    // Iniciar o tempo de execução
    s_runtime.begin();
}

void loop() {
    s_runtime.loop();     // CloudStateMachine + IProfile::loop()
    // ... lógica do produto (sensores, telemetria)
}

Regras de montagem

  • Todos os objetos da biblioteca são estáticos (static). Sem new ou malloc para objetos de nível superior.
  • runtime.begin() é chamado por último em setup(), depois de todos os manipuladores serem registrados.
  • runtime.loop() é chamado primeiro em loop().
  • Objetos de produto (sensores, telemetria) são criados separadamente e conectados diretamente a s_mqtt — o tempo de execução não os conhece.

A raiz de composição completa de Storage Link está em src/main.cpp no repositório iDryer-Storage (publicado separadamente).

Camadas de dispositivo em ordem de montagem:

Camada Objetos Fonte
Plataforma s_wifiStore, s_wifi, s_credentials, s_http idryer-core
Nuvem s_api, s_mqtt, s_cloud, s_dispatcher idryer-core
Dispositivo s_executor, s_profile src/storage/led_strip/
Tempo de execução s_runtime idryer-core
Sensores s_sensor, s_telemetry src/storage/sensors/, src/storage/telemetry/