123 lines
3.8 KiB
C++

#include <queue>
#include <AsyncMqttClient.h>
#include <ArduinoJson.h>
#define MQTT_HOST IPAddress(192, 168, 5, 138)
#define MQTT_PORT 1883
namespace Mqtt {
void publishCommand();
void publishBmp280();
Task tPublish(TASK_SECOND, TASK_FOREVER, publishCommand, &ts);
Task tPublishBmp(5 * TASK_MINUTE, TASK_FOREVER, publishBmp280, &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";
void buildDeviceConfig(JsonDocument& jsonDoc) {
JsonObject device = jsonDoc.createNestedObject("device");
device["name"] = "ESP Clock";
JsonArray connections = device.createNestedArray("connections");
JsonArray mac = connections.createNestedArray();
mac.add("mac");
mac.add("24:62:AB:09:4B:D6");
}
void buildTempConfig(JsonDocument& jsonDoc) {
buildDeviceConfig(jsonDoc);
jsonDoc["device_class"] = "temperature";
jsonDoc["name"] = "Livingroom Temperature";
jsonDoc["unique_id"] = "livingroom_temperature";
jsonDoc["unit_of_measurement"] = "°C";
jsonDoc["state_topic"] = bmpTopic;
jsonDoc["value_template"] = "{{ value_json.temperature}}";
}
void buildPressureConfig(JsonDocument& jsonDoc) {
buildDeviceConfig(jsonDoc);
jsonDoc["device_class"] = "pressure";
jsonDoc["name"] = "Livingroom Pressure";
jsonDoc["unique_id"] = "livingroom_pressure";
jsonDoc["unit_of_measurement"] = "hPa";
jsonDoc["state_topic"] = bmpTopic;
jsonDoc["value_template"] = "{{ value_json.pressure}}";
}
void publishTempConfig() {
StaticJsonDocument<512> jsonDoc;
buildTempConfig(jsonDoc);
char message[512];
serializeJson(jsonDoc, message);
client.publish("homeassistant/sensor/esp_clock/temperature/config", 0, true, message);
}
void publishPressureConfig() {
StaticJsonDocument<512> jsonDoc;
buildPressureConfig(jsonDoc);
char message[512];
serializeJson(jsonDoc, message);
client.publish("homeassistant/sensor/esp_clock/pressure/config", 0, true, message);
}
void publishConfig() {
publishTempConfig();
publishPressureConfig();
}
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 publishBmp280() {
Bmp::data.readAll();
StaticJsonDocument<255> jsonDoc;
jsonDoc["temperature"] = Bmp::data.temp;
jsonDoc["pressure"] = Bmp::data.pressure;
char message[255];
serializeJson(jsonDoc, message);
client.publish(bmpTopic, 0, true, message);
}
void setup() {
client.onConnect([](bool sessionPresent) {
publishConfig();
tPublish.enableDelayed();
tPublishBmp.enable();
Serial.println("Connected to MQTT");
});
client.onDisconnect([](AsyncMqttClientDisconnectReason reason) {
tPublish.disable();
tPublishBmp.disable();
Serial.println("Disconnected from MQTT");
});
client.setServer(MQTT_HOST, MQTT_PORT);
Serial.println("Connecting to MQTT...");
}
}