C interfaces

These listings come directly from the firmware headers whenever the website is rebuilt. See the code guide for module ownership and the HTTP and USB references for interfaces used outside the firmware process.

Fusion core

fc_thermal_t carries native samples and validity/correction masks. Timestamps are local monotonic microseconds. fc_calibration_t holds the row-major RGB-to-thermal homography; fc_measure() computes native-sample region statistics independently of rendering.

 1#pragma once
 2#include <stdbool.h>
 3#include <stddef.h>
 4#include <stdint.h>
 5#define FC_TW 32
 6#define FC_TH 24
 7#define FC_PIXELS (FC_TW * FC_TH)
 8#define FC_MAX_REGIONS 8
 9
10typedef struct {
11    float celsius[FC_PIXELS];
12    uint8_t valid[FC_PIXELS], corrected[FC_PIXELS];
13    int64_t start_us, end_us;
14    uint32_t sequence;
15} fc_thermal_t;
16
17typedef struct {
18    bool enabled;
19    const char *version;
20    unsigned width, height;
21    /* RGB pixel centres -> native thermal pixel centres, row-major. */
22    float rgb_to_thermal[9];
23    float display_min_c, display_max_c, opacity;
24} fc_calibration_t;
25
26typedef struct {
27    const char *id;
28    float x0, y0, x1, y1; /* RGB pixel-centre coordinates. */
29    unsigned min_samples;
30} fc_region_t;
31
32typedef struct {
33    unsigned samples, boundary_samples;
34    bool supported, ambiguous;
35    float max_c, mean_c;
36} fc_measurement_t;
37
38bool fc_calibration_valid(const fc_calibration_t *cal);
39bool fc_pair_valid(
40    const fc_thermal_t *t,
41    int64_t rgb_start,
42    int64_t rgb_end,
43    int64_t now,
44    int64_t max_span,
45    int64_t max_age
46);
47/* Out-of-coverage or invalid neighbourhood returns false; no extrapolation. */
48bool fc_bicubic(const fc_thermal_t *t, float x, float y, float *celsius);
49bool fc_render(
50    const fc_calibration_t *cal,
51    const fc_thermal_t *thermal,
52    const uint8_t *rgb,
53    uint8_t *fused,
54    size_t buffer_size
55);
56bool fc_measure(
57    const fc_calibration_t *cal,
58    const fc_thermal_t *thermal,
59    const fc_region_t *regions,
60    size_t count,
61    fc_measurement_t *out
62);
63void fc_demo(fc_thermal_t *thermal, uint8_t *rgb, unsigned width, unsigned height, int64_t now);
64/* RGB888 to top-down 24-bit BMP; caller supplies full output buffer. */
65size_t fc_bmp_size(unsigned width, unsigned height);
66bool fc_bmp(const uint8_t *rgb, unsigned width, unsigned height, uint8_t *out, size_t size);

Protection core

pc_update() evaluates configuration, sensor freshness, thresholds and re-arm conditions. GPIO output and persistence belong to system_control.c, allowing the state machine and RMS implementation to run in host tests.

 1#pragma once
 2#include <stdbool.h>
 3#include <stdint.h>
 4
 5typedef enum { PC_DISARMED, PC_ARMED, PC_TRIPPED } pc_state_t;
 6
 7typedef enum {
 8    PC_NONE,
 9    PC_NOT_CONFIGURED,
10    PC_SENSOR_FAULT,
11    PC_OVERCURRENT,
12    PC_OVERHEAT,
13    PC_MANUAL,
14    PC_STORAGE_FAULT
15} pc_reason_t;
16
17typedef struct {
18    uint32_t version;
19    bool commissioned;
20    float current_limit_a, temperature_limit_c, current_scale_a_per_v;
21} pc_config_t;
22
23typedef struct {
24    bool current_valid, thermal_valid;
25    float current_a, temperature_c;
26    int64_t current_time_us, thermal_time_us;
27} pc_input_t;
28
29typedef struct {
30    pc_state_t state;
31    pc_reason_t reason;
32    int64_t healthy_since_us;
33} pc_controller_t;
34
35bool pc_config_valid(const pc_config_t *c);
36void pc_init(pc_controller_t *p, bool persisted_trip);
37/* All times use the same local monotonic clock. No network input can arm. */
38bool pc_update(
39    pc_controller_t *p,
40    const pc_config_t *c,
41    const pc_input_t *in,
42    int64_t now,
43    bool physical_rearm,
44    bool open_request
45);
46const char *pc_state_name(pc_state_t state);
47const char *pc_reason_name(pc_reason_t reason);
48
49typedef struct {
50    unsigned count;
51    double mean, m2;
52    bool invalid;
53} pc_rms_t;
54
55void pc_rms_add(pc_rms_t *window, int16_t adc_code);
56float pc_rms_current(const pc_rms_t *window, float scale_a_per_v);

System control

The HTTP handlers and USB dispatcher share system_config_apply(). system_request_open() de-energizes the relay; it does not clear a trip or authorize closing.

 1#pragma once
 2#include "esp_err.h"
 3#include "esp_http_server.h"
 4#include "fusion_core.h"
 5#include "cJSON.h"
 6esp_err_t system_start(void);
 7bool system_thermal_snapshot(fc_thermal_t *out);
 8void system_add_status(cJSON *root);
 9esp_err_t system_config_get(httpd_req_t *req);
10esp_err_t system_config_set(httpd_req_t *req);
11esp_err_t system_open(httpd_req_t *req);
12cJSON *system_config_json(void);
13esp_err_t system_config_apply(const cJSON *json);
14void system_request_open(void);

Connection settings

device_settings() returns immutable settings for the current boot. A successful save persists a complete replacement; callers must restart before it becomes active. device_settings_public() returns an owned cJSON object with secret values redacted.

 1#pragma once
 2#include "esp_err.h"
 3#include "cJSON.h"
 4
 5typedef struct {
 6    char wifi_ssid[33], wifi_password[64], api_token[97];
 7    char camera_url[192], camera_id[64], installation_id[64];
 8    char telemetry_url[256], telemetry_token[701];
 9} device_settings_t;
10
11/* Immutable active settings for this boot. Saved changes take effect after restart. */
12esp_err_t device_settings_init(void);
13const device_settings_t *device_settings(void);
14cJSON *device_settings_public(void);
15esp_err_t device_settings_save(const cJSON *json);

Telemetry publisher

The snapshot callback returns heap-allocated JSON. The publisher takes ownership and frees it after acceptance or queue eviction. See telemetry delivery.

 1#pragma once
 2#include <stddef.h>
 3#include <stdint.h>
 4#include <stdbool.h>
 5typedef char *(*telemetry_snapshot_fn)(void); /* Returns malloc-owned JSON. */
 6
 7typedef struct {
 8    uint8_t *bytes;
 9    size_t size;
10    uint32_t sequence, age_ms;
11    bool synthetic;
12} telemetry_frame_t;
13
14/* Returns a free()-owned copy only when the local fusion is fresh. */
15typedef telemetry_frame_t (*telemetry_frame_fn)(void);
16void telemetry_start(telemetry_snapshot_fn snapshot, telemetry_frame_fn frame);