1
0
mirror of https://github.com/esphome/esphome.git synced 2025-01-18 12:05:41 +00:00

[prometheus] Select, media_player, and number prometheus metrics (#7895)

This commit is contained in:
Jordan Zucker 2025-01-14 19:56:22 -08:00 committed by GitHub
parent e779a8bcb2
commit df26ace0f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 245 additions and 0 deletions

View File

@ -59,6 +59,24 @@ void PrometheusHandler::handleRequest(AsyncWebServerRequest *req) {
this->text_sensor_row_(stream, obj, area, node, friendly_name); this->text_sensor_row_(stream, obj, area, node, friendly_name);
#endif #endif
#ifdef USE_NUMBER
this->number_type_(stream);
for (auto *obj : App.get_numbers())
this->number_row_(stream, obj, area, node, friendly_name);
#endif
#ifdef USE_SELECT
this->select_type_(stream);
for (auto *obj : App.get_selects())
this->select_row_(stream, obj, area, node, friendly_name);
#endif
#ifdef USE_MEDIA_PLAYER
this->media_player_type_(stream);
for (auto *obj : App.get_media_players())
this->media_player_row_(stream, obj, area, node, friendly_name);
#endif
req->send(stream); req->send(stream);
} }
@ -511,6 +529,156 @@ void PrometheusHandler::text_sensor_row_(AsyncResponseStream *stream, text_senso
} }
#endif #endif
// Type-specific implementation
#ifdef USE_NUMBER
void PrometheusHandler::number_type_(AsyncResponseStream *stream) {
stream->print(F("#TYPE esphome_number_value gauge\n"));
stream->print(F("#TYPE esphome_number_failed gauge\n"));
}
void PrometheusHandler::number_row_(AsyncResponseStream *stream, number::Number *obj, std::string &area,
std::string &node, std::string &friendly_name) {
if (obj->is_internal() && !this->include_internal_)
return;
if (!std::isnan(obj->state)) {
// We have a valid value, output this value
stream->print(F("esphome_number_failed{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(F("\"} 0\n"));
// Data itself
stream->print(F("esphome_number_value{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(F("\"} "));
stream->print(obj->state);
stream->print(F("\n"));
} else {
// Invalid state
stream->print(F("esphome_number_failed{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(F("\"} 1\n"));
}
}
#endif
#ifdef USE_SELECT
void PrometheusHandler::select_type_(AsyncResponseStream *stream) {
stream->print(F("#TYPE esphome_select_value gauge\n"));
stream->print(F("#TYPE esphome_select_failed gauge\n"));
}
void PrometheusHandler::select_row_(AsyncResponseStream *stream, select::Select *obj, std::string &area,
std::string &node, std::string &friendly_name) {
if (obj->is_internal() && !this->include_internal_)
return;
if (obj->has_state()) {
// We have a valid value, output this value
stream->print(F("esphome_select_failed{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(F("\"} 0\n"));
// Data itself
stream->print(F("esphome_select_value{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(F("\",value=\""));
stream->print(obj->state.c_str());
stream->print(F("\"} "));
stream->print(F("1.0"));
stream->print(F("\n"));
} else {
// Invalid state
stream->print(F("esphome_select_failed{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(F("\"} 1\n"));
}
}
#endif
#ifdef USE_MEDIA_PLAYER
void PrometheusHandler::media_player_type_(AsyncResponseStream *stream) {
stream->print(F("#TYPE esphome_media_player_state_value gauge\n"));
stream->print(F("#TYPE esphome_media_player_volume gauge\n"));
stream->print(F("#TYPE esphome_media_player_is_muted gauge\n"));
stream->print(F("#TYPE esphome_media_player_failed gauge\n"));
}
void PrometheusHandler::media_player_row_(AsyncResponseStream *stream, media_player::MediaPlayer *obj,
std::string &area, std::string &node, std::string &friendly_name) {
if (obj->is_internal() && !this->include_internal_)
return;
stream->print(F("esphome_media_player_failed{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(F("\"} 0\n"));
// Data itself
stream->print(F("esphome_media_player_state_value{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(F("\",value=\""));
stream->print(media_player::media_player_state_to_string(obj->state));
stream->print(F("\"} "));
stream->print(F("1.0"));
stream->print(F("\n"));
stream->print(F("esphome_media_player_volume{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(F("\"} "));
stream->print(obj->volume);
stream->print(F("\n"));
stream->print(F("esphome_media_player_is_muted{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(F("\"} "));
if (obj->is_muted()) {
stream->print(F("1.0"));
} else {
stream->print(F("0.0"));
}
stream->print(F("\n"));
}
#endif
} // namespace prometheus } // namespace prometheus
} // namespace esphome } // namespace esphome
#endif #endif

View File

@ -128,6 +128,30 @@ class PrometheusHandler : public AsyncWebHandler, public Component {
std::string &friendly_name); std::string &friendly_name);
#endif #endif
#ifdef USE_NUMBER
/// Return the type for prometheus
void number_type_(AsyncResponseStream *stream);
/// Return the sensor state as prometheus data point
void number_row_(AsyncResponseStream *stream, number::Number *obj, std::string &area, std::string &node,
std::string &friendly_name);
#endif
#ifdef USE_SELECT
/// Return the type for prometheus
void select_type_(AsyncResponseStream *stream);
/// Return the select state as prometheus data point
void select_row_(AsyncResponseStream *stream, select::Select *obj, std::string &area, std::string &node,
std::string &friendly_name);
#endif
#ifdef USE_MEDIA_PLAYER
/// Return the type for prometheus
void media_player_type_(AsyncResponseStream *stream);
/// Return the select state as prometheus data point
void media_player_row_(AsyncResponseStream *stream, media_player::MediaPlayer *obj, std::string &area,
std::string &node, std::string &friendly_name);
#endif
web_server_base::WebServerBase *base_; web_server_base::WebServerBase *base_;
bool include_internal_{false}; bool include_internal_{false};
std::map<EntityBase *, std::string> relabel_map_id_; std::map<EntityBase *, std::string> relabel_map_id_;

View File

@ -78,6 +78,26 @@ lock:
} }
optimistic: true optimistic: true
select:
- platform: template
id: template_select1
name: "Template select"
optimistic: true
options:
- one
- two
- three
initial_option: two
number:
- platform: template
id: template_number1
name: "Template number"
optimistic: true
min_value: 0
max_value: 100
step: 1
prometheus: prometheus:
include_internal: true include_internal: true
relabel: relabel:

View File

@ -1 +1,34 @@
<<: !include common.yaml <<: !include common.yaml
i2s_audio:
i2s_lrclk_pin: 1
i2s_bclk_pin: 2
i2s_mclk_pin: 3
media_player:
- platform: i2s_audio
name: "Media Player"
dac_type: external
i2s_dout_pin: 18
mute_pin: 19
on_state:
- media_player.play:
- media_player.play_media: http://localhost/media.mp3
- media_player.play_media: !lambda 'return "http://localhost/media.mp3";'
on_idle:
- media_player.pause:
on_play:
- media_player.stop:
on_pause:
- media_player.toggle:
- wait_until:
media_player.is_idle:
- wait_until:
media_player.is_playing:
- wait_until:
media_player.is_announcing:
- wait_until:
media_player.is_paused:
- media_player.volume_up:
- media_player.volume_down:
- media_player.volume_set: 50%