Реализованы 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).
73 lines
2.0 KiB
C++
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;
|
|
}
|