/* * Host implementation of relay.h -- a fake furnace. * * Lets the real control loop run on the desktop: hysteresis, minimum on and * off times and the cycles-per-hour ceiling all behave exactly as they will on * the device, with the relay changes printed instead of switching 24VAC. * * Timestamps are wall-clock relative to start-up so a log can be read against * the protection timings in thermostat.h without arithmetic. */ #include #include #include #include "relay.h" static bool relay_state[RELAY_COUNT]; static struct timespec t0; static double seconds_since_start(void) { struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); return (double)(now.tv_sec - t0.tv_sec) + (double)(now.tv_nsec - t0.tv_nsec) / 1e9; } esp_err_t relay_init(void) { clock_gettime(CLOCK_MONOTONIC, &t0); for (int i = 0; i < RELAY_COUNT; i++) { relay_state[i] = false; } fprintf(stderr, "[relay-sim] both relays idle\n"); return ESP_OK; } void relay_set(relay_id_t id, bool energized) { if (id < 0 || id >= RELAY_COUNT || relay_state[id] == energized) { return; } relay_state[id] = energized; fprintf(stderr, "[relay-sim] %7.1fs %-8s -> %s\n", seconds_since_start(), relay_name(id), energized ? "ON" : "OFF"); } bool relay_get(relay_id_t id) { if (id < 0 || id >= RELAY_COUNT) { return false; } return relay_state[id]; } const char *relay_name(relay_id_t id) { switch (id) { case RELAY_HEAT: return "heat(W)"; case RELAY_FAN: return "fan(G)"; default: return "?"; } }