Начальный каркас: прошивка 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).
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user