// Small internal sensor-driver interface. // // The whole point of this file: adding a new sensor type later should mean // "write a new .c/.h pair implementing this interface, add one line to the // registry array in sensor_registry.c" — never editing app_main.c's control // flow or the telemetry POST loop. See sensor_registry.c for the array and // README.md's "Adding a new sensor" section for a walkthrough. // // UNVERIFIED AGAINST REAL HARDWARE — see README.md. #pragma once #include #include "esp_err.h" #include "cJSON.h" #ifdef __cplusplus extern "C" { #endif // Max length (including NUL) for a reading's sensor_type / unit strings. // Generous for the sensor_type strings this firmware emits ("temperature", // "humidity", "pressure", "presence", ...) with room for future ones. #define SENSOR_READING_TYPE_MAXLEN 24 #define SENSOR_READING_UNIT_MAXLEN 16 // One entry of the backend contract's `readings` array: // {"sensor_type": str, "value": number, "unit": str, "metadata": {}} // // `metadata` is optional. If non-NULL, ownership transfers to the caller // that serializes the reading (telemetry_client.c frees it after building // the request body) — a driver's read() must hand back a freshly-created // cJSON object it does not touch again, never a shared/static one. typedef struct { char sensor_type[SENSOR_READING_TYPE_MAXLEN]; double value; char unit[SENSOR_READING_UNIT_MAXLEN]; cJSON *metadata; // nullable; NULL serializes as {} } sensor_reading_t; // One registered sensor driver. // // name - short human-readable identifier, used only in log lines. // init - one-time hardware bring-up (bus/peripheral init, sensor reset, // presence/ID check). May be NULL if a driver needs no init step. // Called once at boot, in registry array order, before Wi-Fi // connects so a slow/hanging sensor bus can't block network // bring-up indefinitely (each init should still apply its own // reasonable internal timeout). // read - sample the sensor and append up to `max_out` readings to `out`, // writing the number actually written to `*out_count`. Called // once per reporting cycle from the telemetry task. Must return // ESP_OK even if it decides there is nothing new to report (set // *out_count = 0) — returning an error is reserved for actual // I/O failure (bus NACK, UART timeout with no valid frame, etc.), // which the registry logs and treats as "this driver contributed // nothing this cycle" without aborting the whole POST. typedef struct sensor_driver { const char *name; esp_err_t (*init)(void); esp_err_t (*read)(sensor_reading_t *out, size_t max_out, size_t *out_count); } sensor_driver_t; #ifdef __cplusplus } #endif