#include "chip_temperature_sensor.h" #include "commissioning.h" #include "esp_log.h" #include "esp_timer.h" #include "mqtt.h" #include "rgb_led.h" namespace { constexpr const char *TAG = "kvida_os"; kvida::ChipTemperatureSensor g_chip_temp_sensor; esp_timer_handle_t g_chip_temp_timer = nullptr; void publish_chip_temperature_tick(void * /*arg*/) { if (!g_chip_temp_sensor.fetch()) { return; } kvida::SensorValue value{}; if (g_chip_temp_sensor.get(kvida::SensorChannel::ChipTemperature, value)) { float celsius = static_cast(value.val1) + static_cast(value.val2) * 1e-6f; kvida::publish_chip_temperature(celsius); } } void on_led_color(uint8_t red, uint8_t green, uint8_t blue) { kvida::drivers::rgb_led_set_color(red, green, blue); } } // namespace extern "C" void app_main(void) { ESP_LOGI(TAG, "kvida-os starting"); // Quick end-to-end data-flow proof (real Sensor impl -> MQTT/HA, and // HA -> MQTT -> actuator) using only what's on the ESP32-C6-DevKitC-1 // itself: no sensor profiles or hardware wiring exist yet. g_chip_temp_sensor.begin(); kvida::drivers::rgb_led_init(); kvida::set_led_color_handler(&on_led_color); const esp_timer_create_args_t timer_args = { .callback = &publish_chip_temperature_tick, .arg = nullptr, .dispatch_method = ESP_TIMER_TASK, .name = "chip_temp_publish", .skip_unhandled_events = true, }; ESP_ERROR_CHECK(esp_timer_create(&timer_args, &g_chip_temp_timer)); ESP_ERROR_CHECK(esp_timer_start_periodic(g_chip_temp_timer, 30LL * 1000000)); // First boot / no stored Wi-Fi credentials -> fall straight into // commissioning (nothing to protect yet, so no physical-interaction // gate needed here). Re-entering commissioning on an already-configured // device should require a physical trigger (e.g. the user button) per // AGENTS.md's security principle -- not wired up yet since `drivers` // doesn't have a real button implementation. if (!kvida::try_stored_credentials()) { kvida::start_commissioning(); } }