2023-01-19 23:16:03 +01:00

149 lines
4.9 KiB
C++

#include <queue>
#include <AsyncMqttClient.h>
#include <ArduinoJson.h>
#include "ha.h"
#define MQTT_HOST IPAddress(192, 168, 5, 11)
#define MQTT_PORT 1883
namespace Mqtt {
void publishConfig();
void publishCommand();
void publishBmp280();
void connect();
void disconnect();
Task tReConnect(5 * TASK_MINUTE, TASK_FOREVER, connect, &ts);
Task tPublishConfig(TASK_IMMEDIATE, TASK_ONCE, publishConfig, &ts);
Task tPublishBmp(5 * TASK_MINUTE, TASK_FOREVER, publishBmp280, &ts);
Task tPublishCommand(TASK_SECOND, TASK_FOREVER, publishCommand, &ts);
AsyncMqttClient client;
struct {
const char* topic = "esp_clock/sensor/ir/value";
std::queue<uint8_t> queue;
uint8_t getCurrent() {
return queue.empty() ? 0 : queue.front();
}
void push(uint8_t el) {
if (client.connected()) queue.push(el);
}
void pop() {
queue.pop();
}
} commands;
const char* bmpTopic = "homeassistant/sensor/esp_clock/state";
const char* restartTopic = "homeassistant/button/esp_clock/restart";
const char* ledTopic = "homeassistant/switch/esp_clock/led/set";
const char* espClockTopic = "homeassistant/+/esp_clock/#";
void connect() {
client.connect();
}
void disconnect() {
client.unsubscribe(espClockTopic);
client.disconnect();
}
void publishTempConfig() {
char message[JSON_SIZE];
Ha::buildSensorConfig(message, Ha::TemperatureConfig{ "Living room Temperature", "living_room_temperature", bmpTopic });
client.publish("homeassistant/sensor/esp_clock/temperature/config", 0, true, message);
}
void publishPressureConfig() {
char message[JSON_SIZE];
Ha::buildSensorConfig(message, Ha::PressureConfig{ "Living room Pressure", "living_room_pressure", bmpTopic });
client.publish("homeassistant/sensor/esp_clock/pressure/config", 0, true, message);
}
void publishAltitudeConfig() {
char message[JSON_SIZE];
Ha::buildSensorConfig(message, Ha::AltitudeConfig{ "Living room Altitude", "living_room_altitude", bmpTopic });
client.publish("homeassistant/sensor/esp_clock/altitude/config", 0, true, message);
}
void publishRestartConfig() {
char message[JSON_SIZE];
Ha::buildRestartConfig(message, restartTopic);
client.publish("homeassistant/button/esp_clock/restart/config", 0, true, message);
}
void publishLedConfig() {
char message[JSON_SIZE];
Ha::buildLedConfig(message, ledTopic);
client.publish("homeassistant/switch/esp_clock/led/config", 0, true, message);
}
void publishConfig() {
publishTempConfig();
publishPressureConfig();
publishAltitudeConfig();
publishRestartConfig();
publishLedConfig();
ts.deleteTask(tPublishConfig);
}
void publishBmp280() {
Bmp::data.readAll();
StaticJsonDocument<255> jsonDoc;
jsonDoc["temperature"] = Bmp::data.temp;
jsonDoc["pressure"] = Bmp::data.pressure;
jsonDoc["altitude"] = Bmp::data.altitude;
char message[255];
serializeJson(jsonDoc, message);
client.publish(bmpTopic, 0, true, message);
}
void publishCommand() {
if (uint8_t cmd = commands.getCurrent()) {
char message[32];
sprintf(message, "%X", cmd);
if (client.publish(commands.topic, 0, true, message) != 0) {
Serial.print(cmd, HEX);
Serial.println();
commands.queue.pop();
}
}
}
void onMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
char msg[len + 1];
memcpy(msg, payload, len);
msg[len] = 0;
if (String{ restartTopic }.equals(topic) && String { "PRESS" }.equals(msg)) {
ESP.restart();
}
if (String{ ledTopic }.equals(topic)) {
if (String{ "ON" }.equals(msg)) {
digitalWrite(LED_BUILTIN, LOW);
} else {
digitalWrite(LED_BUILTIN, HIGH);
}
}
}
void setup() {
client.onConnect([](bool sessionPresent) {
tPublishConfig.enable();
tPublishBmp.enableIfNot();
tPublishCommand.enableDelayed();
client.subscribe(espClockTopic, 0);
tReConnect.disable();
Serial.println("Connected to MQTT");
});
client.onDisconnect([](AsyncMqttClientDisconnectReason reason) {
tReConnect.enableDelayed();
tPublishCommand.disable();
tPublishBmp.disable();
Serial.println("Disconnected from MQTT");
});
client.onMessage(onMessage);
client.setServer(MQTT_HOST, MQTT_PORT);
Serial.println("Connecting to MQTT...");
}
}