Files
cacto a645737927 Начальный каркас: прошивка ESP32 для зоны "Гроубокс"
Реализованы sensor-1 (DHT22, телеметрия temperature/humidity) и
реле-актуаторы light-1/pump-1/fan-1 (turn_on/turn_off/set_level) по
протоколу MQTT платформы home_automatization (devices/{id}/telemetry|commands|ack).
2026-08-11 18:46:37 +05:00

73 lines
2.0 KiB
C++

#include "devices.h"
#include "config.h"
struct Actuator {
const char* deviceId;
uint8_t pin;
bool on;
};
static Actuator actuators[] = {
{DEVICE_ID_LIGHT, PIN_RELAY_LIGHT, false},
{DEVICE_ID_PUMP, PIN_RELAY_PUMP, false},
{DEVICE_ID_FAN, PIN_RELAY_FAN, false},
};
static const size_t actuatorCount = sizeof(actuators) / sizeof(actuators[0]);
static void relayWrite(uint8_t pin, bool on) {
bool level = RELAY_ACTIVE_LOW ? !on : on;
digitalWrite(pin, level ? HIGH : LOW);
}
void devicesBegin() {
for (size_t i = 0; i < actuatorCount; i++) {
pinMode(actuators[i].pin, OUTPUT);
relayWrite(actuators[i].pin, false);
}
}
static Actuator* findActuator(const String& deviceId) {
for (size_t i = 0; i < actuatorCount; i++) {
if (deviceId == actuators[i].deviceId) {
return &actuators[i];
}
}
return nullptr;
}
// Реального диммирования у нас нет (обычные реле on/off), поэтому
// set_level трактуется как порог: level > 0 включает реле, level <= 0
// выключает. Ack всегда содержит и power, и level, чтобы отражать
// реальное состояние железа.
bool devicesApplyCommand(const String& deviceId, const String& action, double level, JsonDocument& outState) {
Actuator* actuator = findActuator(deviceId);
if (actuator == nullptr) {
return false;
}
if (action == "turn_on") {
actuator->on = true;
} else if (action == "turn_off") {
actuator->on = false;
} else if (action == "set_level") {
actuator->on = level > 0;
outState["level"] = level;
} else {
Serial.print("[devices] unknown action for ");
Serial.print(deviceId);
Serial.print(": ");
Serial.println(action);
return false;
}
relayWrite(actuator->pin, actuator->on);
outState["power"] = actuator->on ? "on" : "off";
Serial.print("[devices] ");
Serial.print(deviceId);
Serial.print(" -> ");
Serial.println(actuator->on ? "on" : "off");
return true;
}