mirror of
https://github.com/esphome/esphome.git
synced 2026-10-28 00:42:11 +00:00
[prometheus] Add prometheus datetime metrics (#9941)
This commit is contained in:
1 parent
d552396650
commit
205ef9407f
3 files changed
+153
No files matched your search
@@ -1,4 +1,5 @@
|
||||
#include "prometheus_handler.h"
|
||||
#include <cinttypes>
|
||||
#if defined(USE_NETWORK) && !defined(USE_HOST)
|
||||
#include "esphome/core/application.h"
|
||||
|
||||
@@ -100,6 +101,24 @@ void PrometheusHandler::handleRequest(AsyncWebServerRequest *req) {
|
||||
this->valve_row_(stream, obj, area, node, friendly_name);
|
||||
#endif
|
||||
|
||||
#ifdef USE_DATETIME_DATE
|
||||
this->date_type_(stream);
|
||||
for (auto *obj : App.get_dates())
|
||||
this->date_row_(stream, obj, area, node, friendly_name);
|
||||
#endif
|
||||
|
||||
#ifdef USE_DATETIME_TIME
|
||||
this->time_type_(stream);
|
||||
for (auto *obj : App.get_times())
|
||||
this->time_row_(stream, obj, area, node, friendly_name);
|
||||
#endif
|
||||
|
||||
#ifdef USE_DATETIME_DATETIME
|
||||
this->datetime_type_(stream);
|
||||
for (auto *obj : App.get_datetimes())
|
||||
this->datetime_row_(stream, obj, area, node, friendly_name);
|
||||
#endif
|
||||
|
||||
#ifdef USE_CLIMATE
|
||||
this->climate_type_(stream);
|
||||
for (auto *obj : App.get_climates())
|
||||
@@ -1096,6 +1115,78 @@ void PrometheusHandler::climate_row_(AsyncResponseStream *stream, climate::Clima
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_DATETIME_DATE) || defined(USE_DATETIME_DATETIME) || defined(USE_DATETIME_TIME)
|
||||
void PrometheusHandler::date_time_rows_(AsyncResponseStream *stream, ProgmemStr failed_metric, ProgmemStr value_metric,
|
||||
EntityBase *obj, int64_t value_ms, std::string &area, std::string &node,
|
||||
std::string &friendly_name) {
|
||||
if (obj->is_internal() && !this->include_internal_)
|
||||
return;
|
||||
this->print_metric_labels_(stream, failed_metric, obj, area, node, friendly_name);
|
||||
if (!obj->has_state()) {
|
||||
stream->print(ESPHOME_F("\"} 1\n"));
|
||||
return;
|
||||
}
|
||||
stream->print(ESPHOME_F("\"} 0\n"));
|
||||
this->print_metric_labels_(stream, value_metric, obj, area, node, friendly_name);
|
||||
// Date and datetime are ms since the epoch (what Grafana expects), time is ms since midnight
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "\"} %" PRId64 "\n", value_ms);
|
||||
stream->print(buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_DATETIME_DATE
|
||||
void PrometheusHandler::date_type_(AsyncResponseStream *stream) {
|
||||
stream->print(ESPHOME_F("#TYPE esphome_date_value gauge\n"));
|
||||
stream->print(ESPHOME_F("#TYPE esphome_date_failed gauge\n"));
|
||||
}
|
||||
void PrometheusHandler::date_row_(AsyncResponseStream *stream, datetime::DateEntity *obj, std::string &area,
|
||||
std::string &node, std::string &friendly_name) {
|
||||
int64_t value_ms = 0;
|
||||
if (obj->has_state()) {
|
||||
// DateEntity::state_as_esptime() leaves the time fields unset, so build midnight here
|
||||
ESPTime t{};
|
||||
t.year = obj->year;
|
||||
t.month = obj->month;
|
||||
t.day_of_month = obj->day;
|
||||
t.recalc_timestamp_local();
|
||||
value_ms = static_cast<int64_t>(t.timestamp) * 1000;
|
||||
}
|
||||
this->date_time_rows_(stream, ESPHOME_F("esphome_date_failed"), ESPHOME_F("esphome_date_value"), obj, value_ms, area,
|
||||
node, friendly_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_DATETIME_TIME
|
||||
void PrometheusHandler::time_type_(AsyncResponseStream *stream) {
|
||||
stream->print(ESPHOME_F("#TYPE esphome_time_value gauge\n"));
|
||||
stream->print(ESPHOME_F("#TYPE esphome_time_failed gauge\n"));
|
||||
}
|
||||
void PrometheusHandler::time_row_(AsyncResponseStream *stream, datetime::TimeEntity *obj, std::string &area,
|
||||
std::string &node, std::string &friendly_name) {
|
||||
int64_t value_ms = 0;
|
||||
if (obj->has_state())
|
||||
value_ms = (static_cast<int64_t>(obj->hour) * 3600 + obj->minute * 60 + obj->second) * 1000;
|
||||
this->date_time_rows_(stream, ESPHOME_F("esphome_time_failed"), ESPHOME_F("esphome_time_value"), obj, value_ms, area,
|
||||
node, friendly_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_DATETIME_DATETIME
|
||||
void PrometheusHandler::datetime_type_(AsyncResponseStream *stream) {
|
||||
stream->print(ESPHOME_F("#TYPE esphome_datetime_value gauge\n"));
|
||||
stream->print(ESPHOME_F("#TYPE esphome_datetime_failed gauge\n"));
|
||||
}
|
||||
void PrometheusHandler::datetime_row_(AsyncResponseStream *stream, datetime::DateTimeEntity *obj, std::string &area,
|
||||
std::string &node, std::string &friendly_name) {
|
||||
int64_t value_ms = 0;
|
||||
if (obj->has_state())
|
||||
value_ms = static_cast<int64_t>(obj->state_as_esptime().timestamp) * 1000;
|
||||
this->date_time_rows_(stream, ESPHOME_F("esphome_datetime_failed"), ESPHOME_F("esphome_datetime_value"), obj,
|
||||
value_ms, area, node, friendly_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace esphome::prometheus
|
||||
|
||||
#endif
|
||||
@@ -193,6 +193,36 @@ class PrometheusHandler final : public AsyncWebHandler, public Component {
|
||||
std::string &friendly_name);
|
||||
#endif
|
||||
|
||||
#if defined(USE_DATETIME_DATE) || defined(USE_DATETIME_DATETIME) || defined(USE_DATETIME_TIME)
|
||||
/// Print the failed row and, when the entity has a state, the value row in milliseconds
|
||||
void date_time_rows_(AsyncResponseStream *stream, ProgmemStr failed_metric, ProgmemStr value_metric, EntityBase *obj,
|
||||
int64_t value_ms, std::string &area, std::string &node, std::string &friendly_name);
|
||||
#endif
|
||||
|
||||
#ifdef USE_DATETIME_DATE
|
||||
/// Return the type for prometheus
|
||||
void date_type_(AsyncResponseStream *stream);
|
||||
/// Return the date state as prometheus data point
|
||||
void date_row_(AsyncResponseStream *stream, datetime::DateEntity *obj, std::string &area, std::string &node,
|
||||
std::string &friendly_name);
|
||||
#endif
|
||||
|
||||
#ifdef USE_DATETIME_TIME
|
||||
/// Return the type for prometheus
|
||||
void time_type_(AsyncResponseStream *stream);
|
||||
/// Return the time state as prometheus data point
|
||||
void time_row_(AsyncResponseStream *stream, datetime::TimeEntity *obj, std::string &area, std::string &node,
|
||||
std::string &friendly_name);
|
||||
#endif
|
||||
|
||||
#ifdef USE_DATETIME_DATETIME
|
||||
/// Return the type for prometheus
|
||||
void datetime_type_(AsyncResponseStream *stream);
|
||||
/// Return the datetime state as prometheus data point
|
||||
void datetime_row_(AsyncResponseStream *stream, datetime::DateTimeEntity *obj, std::string &area, std::string &node,
|
||||
std::string &friendly_name);
|
||||
#endif
|
||||
|
||||
#ifdef USE_CLIMATE
|
||||
/// Return the type for prometheus
|
||||
void climate_type_(AsyncResponseStream *stream);
|
||||
|
||||
@@ -182,6 +182,29 @@ climate:
|
||||
name: LG Climate
|
||||
transmitter_id: xmitr
|
||||
|
||||
datetime:
|
||||
- platform: template
|
||||
name: Date
|
||||
id: test_date
|
||||
type: date
|
||||
initial_value: "2000-1-2"
|
||||
set_action:
|
||||
- logger.log: "set_value"
|
||||
- platform: template
|
||||
name: Time
|
||||
id: test_time
|
||||
type: time
|
||||
initial_value: "12:34:56am"
|
||||
set_action:
|
||||
- logger.log: "set_value"
|
||||
- platform: template
|
||||
name: DateTime
|
||||
id: test_datetime
|
||||
type: datetime
|
||||
initial_value: "2000-1-2 12:34:56"
|
||||
set_action:
|
||||
- logger.log: "set_value"
|
||||
|
||||
prometheus:
|
||||
include_internal: true
|
||||
relabel:
|
||||
@@ -191,3 +214,12 @@ prometheus:
|
||||
template_text_sensor1:
|
||||
id: hello_text
|
||||
name: Text Substitution
|
||||
test_date:
|
||||
id: prometheus_date
|
||||
name: Prometheus Date
|
||||
test_time:
|
||||
id: prometheus_time
|
||||
name: Prometheus Time
|
||||
test_datetime:
|
||||
id: prometheus_datetime
|
||||
name: Prometheus DateTime
|
||||
Reference in new issue
Block a user