100 lines
3.9 KiB
C++
100 lines
3.9 KiB
C++
#pragma once
|
|
|
|
#include <WiFiClient.h>
|
|
#include <ArduinoJson.h>
|
|
#include "esphome.h"
|
|
|
|
// Forward declare the global variables/pointers defined in main.cpp
|
|
extern template_::TemplateSensor *local_cellar_temp;
|
|
extern template_::TemplateSensor *local_cellar_humi;
|
|
extern template_::TemplateSensor *local_cellar_dp;
|
|
extern template_::TemplateSensor *local_cellar_out_temp;
|
|
extern template_::TemplateSensor *local_cellar_out_humi;
|
|
extern template_::TemplateSensor *local_cellar_out_dp;
|
|
extern template_::TemplateSensor *local_fan_status;
|
|
extern template_::TemplateSensor *local_mold_critical;
|
|
extern template_::TemplateSensor *local_fan_would_activate;
|
|
extern template_::TemplateSensor *local_mold_threshold;
|
|
extern template_::TemplateSensor *local_shelly_online;
|
|
extern globals::GlobalsComponent<bool> *prometheus_connected;
|
|
|
|
inline void fetch_prometheus() {
|
|
WiFiClient client;
|
|
if (!client.connect("prometheus.haumdaucher.de", 80)) {
|
|
prometheus_connected->value() = false;
|
|
ESP_LOGW("taupi", "Failed to connect to Prometheus over HTTP");
|
|
return;
|
|
}
|
|
|
|
// Send HTTP/1.0 request to avoid chunked transfer encoding!
|
|
client.println("GET /api/v1/query?query=%7B__name__%3D~%22taupi_.*%7Cup%22%2Cjob%3D%22taupi-fan%22%7D HTTP/1.0");
|
|
client.println("Host: prometheus.haumdaucher.de");
|
|
client.println("Authorization: Basic bW9yaXR6OlZhZWo2UXVpZXF1NHZvMGphZVJh");
|
|
client.println("Connection: close");
|
|
client.println();
|
|
|
|
// Read headers
|
|
bool headers_ended = false;
|
|
std::string body = "";
|
|
while (client.connected() || client.available()) {
|
|
if (client.available()) {
|
|
if (!headers_ended) {
|
|
String line = client.readStringUntil('\n');
|
|
if (line == "\r" || line == "") {
|
|
headers_ended = true;
|
|
}
|
|
} else {
|
|
String data = client.readString();
|
|
body += data.c_str();
|
|
}
|
|
}
|
|
}
|
|
client.stop();
|
|
|
|
if (body.length() == 0) {
|
|
prometheus_connected->value() = false;
|
|
ESP_LOGW("taupi", "Empty response body from Prometheus");
|
|
return;
|
|
}
|
|
|
|
prometheus_connected->value() = true;
|
|
|
|
// Parse body using ArduinoJson 7
|
|
JsonDocument doc;
|
|
DeserializationError error = deserializeJson(doc, body);
|
|
if (!error) {
|
|
JsonObject root = doc.as<JsonObject>();
|
|
JsonObject data = root["data"];
|
|
JsonArray result = data["result"];
|
|
for (JsonObject item : result) {
|
|
JsonObject metric = item["metric"];
|
|
std::string name = metric["__name__"].as<std::string>();
|
|
JsonArray value = item["value"];
|
|
if (value.size() >= 2) {
|
|
std::string val_str = value[1].as<std::string>();
|
|
float val = atof(val_str.c_str());
|
|
|
|
if (name == "taupi_temperature_celsius_innen") local_cellar_temp->publish_state(val);
|
|
else if (name == "taupi_humidity_percent_innen") local_cellar_humi->publish_state(val);
|
|
else if (name == "taupi_dewpoint_celsius_innen") local_cellar_dp->publish_state(val);
|
|
else if (name == "taupi_temperature_celsius_aussen") local_cellar_out_temp->publish_state(val);
|
|
else if (name == "taupi_humidity_percent_aussen") local_cellar_out_humi->publish_state(val);
|
|
else if (name == "taupi_dewpoint_celsius_aussen") local_cellar_out_dp->publish_state(val);
|
|
else if (name == "taupi_relay_status") local_fan_status->publish_state(val);
|
|
else if (name == "taupi_is_critical") local_mold_critical->publish_state(val);
|
|
else if (name == "taupi_would_fan_activate") local_fan_would_activate->publish_state(val);
|
|
else if (name == "taupi_critical_humidity_threshold_percent") local_mold_threshold->publish_state(val);
|
|
else if (name == "up") {
|
|
std::string job = metric["job"].as<std::string>();
|
|
if (job == "taupi-fan") {
|
|
local_shelly_online->publish_state(val);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ESP_LOGD("taupi", "Successfully parsed Taupi metrics from Prometheus");
|
|
} else {
|
|
ESP_LOGW("taupi", "JSON parsing failed: %s", error.c_str());
|
|
}
|
|
}
|