diff --git a/esphome/components/prometheus/prometheus_handler.cpp b/esphome/components/prometheus/prometheus_handler.cpp index 2d39d8ef3f..c31d34f000 100644 --- a/esphome/components/prometheus/prometheus_handler.cpp +++ b/esphome/components/prometheus/prometheus_handler.cpp @@ -77,6 +77,12 @@ void PrometheusHandler::handleRequest(AsyncWebServerRequest *req) { this->media_player_row_(stream, obj, area, node, friendly_name); #endif +#ifdef USE_UPDATE + this->update_entity_type_(stream); + for (auto *obj : App.get_updates()) + this->update_entity_row_(stream, obj, area, node, friendly_name); +#endif + req->send(stream); } @@ -679,6 +685,91 @@ void PrometheusHandler::media_player_row_(AsyncResponseStream *stream, media_pla } #endif +#ifdef USE_UPDATE +void PrometheusHandler::update_entity_type_(AsyncResponseStream *stream) { + stream->print(F("#TYPE esphome_update_entity_state gauge\n")); + stream->print(F("#TYPE esphome_update_entity_info gauge\n")); + stream->print(F("#TYPE esphome_update_entity_failed gauge\n")); +} + +void PrometheusHandler::handle_update_state_(AsyncResponseStream *stream, update::UpdateState state) { + switch (state) { + case update::UpdateState::UPDATE_STATE_UNKNOWN: + stream->print("unknown"); + break; + case update::UpdateState::UPDATE_STATE_NO_UPDATE: + stream->print("none"); + break; + case update::UpdateState::UPDATE_STATE_AVAILABLE: + stream->print("available"); + break; + case update::UpdateState::UPDATE_STATE_INSTALLING: + stream->print("installing"); + break; + default: + stream->print("invalid"); + break; + } +} + +void PrometheusHandler::update_entity_row_(AsyncResponseStream *stream, update::UpdateEntity *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_update_entity_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")); + // First update state + stream->print(F("esphome_update_entity_state{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=\"")); + handle_update_state_(stream, obj->state); + stream->print(F("\"} ")); + stream->print(F("1.0")); + stream->print(F("\n")); + // Next update info + stream->print(F("esphome_update_entity_info{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("\",current_version=\"")); + stream->print(obj->update_info.current_version.c_str()); + stream->print(F("\",latest_version=\"")); + stream->print(obj->update_info.latest_version.c_str()); + stream->print(F("\",title=\"")); + stream->print(obj->update_info.title.c_str()); + stream->print(F("\"} ")); + stream->print(F("1.0")); + stream->print(F("\n")); + } else { + // Invalid state + stream->print(F("esphome_update_entity_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 + } // namespace prometheus } // namespace esphome #endif diff --git a/esphome/components/prometheus/prometheus_handler.h b/esphome/components/prometheus/prometheus_handler.h index 41a06537ed..08a6e8dc8a 100644 --- a/esphome/components/prometheus/prometheus_handler.h +++ b/esphome/components/prometheus/prometheus_handler.h @@ -75,7 +75,7 @@ class PrometheusHandler : public AsyncWebHandler, public Component { #ifdef USE_BINARY_SENSOR /// Return the type for prometheus void binary_sensor_type_(AsyncResponseStream *stream); - /// Return the sensor state as prometheus data point + /// Return the binary sensor state as prometheus data point void binary_sensor_row_(AsyncResponseStream *stream, binary_sensor::BinarySensor *obj, std::string &area, std::string &node, std::string &friendly_name); #endif @@ -83,7 +83,7 @@ class PrometheusHandler : public AsyncWebHandler, public Component { #ifdef USE_FAN /// Return the type for prometheus void fan_type_(AsyncResponseStream *stream); - /// Return the sensor state as prometheus data point + /// Return the fan state as prometheus data point void fan_row_(AsyncResponseStream *stream, fan::Fan *obj, std::string &area, std::string &node, std::string &friendly_name); #endif @@ -91,7 +91,7 @@ class PrometheusHandler : public AsyncWebHandler, public Component { #ifdef USE_LIGHT /// Return the type for prometheus void light_type_(AsyncResponseStream *stream); - /// Return the Light Values state as prometheus data point + /// Return the light values state as prometheus data point void light_row_(AsyncResponseStream *stream, light::LightState *obj, std::string &area, std::string &node, std::string &friendly_name); #endif @@ -99,7 +99,7 @@ class PrometheusHandler : public AsyncWebHandler, public Component { #ifdef USE_COVER /// Return the type for prometheus void cover_type_(AsyncResponseStream *stream); - /// Return the switch Values state as prometheus data point + /// Return the cover values state as prometheus data point void cover_row_(AsyncResponseStream *stream, cover::Cover *obj, std::string &area, std::string &node, std::string &friendly_name); #endif @@ -107,7 +107,7 @@ class PrometheusHandler : public AsyncWebHandler, public Component { #ifdef USE_SWITCH /// Return the type for prometheus void switch_type_(AsyncResponseStream *stream); - /// Return the switch Values state as prometheus data point + /// Return the switch values state as prometheus data point void switch_row_(AsyncResponseStream *stream, switch_::Switch *obj, std::string &area, std::string &node, std::string &friendly_name); #endif @@ -115,7 +115,7 @@ class PrometheusHandler : public AsyncWebHandler, public Component { #ifdef USE_LOCK /// Return the type for prometheus void lock_type_(AsyncResponseStream *stream); - /// Return the lock Values state as prometheus data point + /// Return the lock values state as prometheus data point void lock_row_(AsyncResponseStream *stream, lock::Lock *obj, std::string &area, std::string &node, std::string &friendly_name); #endif @@ -123,7 +123,7 @@ class PrometheusHandler : public AsyncWebHandler, public Component { #ifdef USE_TEXT_SENSOR /// Return the type for prometheus void text_sensor_type_(AsyncResponseStream *stream); - /// Return the lock Values state as prometheus data point + /// Return the text sensor values state as prometheus data point void text_sensor_row_(AsyncResponseStream *stream, text_sensor::TextSensor *obj, std::string &area, std::string &node, std::string &friendly_name); #endif @@ -131,7 +131,7 @@ class PrometheusHandler : public AsyncWebHandler, public Component { #ifdef USE_NUMBER /// Return the type for prometheus void number_type_(AsyncResponseStream *stream); - /// Return the sensor state as prometheus data point + /// Return the number state as prometheus data point void number_row_(AsyncResponseStream *stream, number::Number *obj, std::string &area, std::string &node, std::string &friendly_name); #endif @@ -147,11 +147,20 @@ class PrometheusHandler : public AsyncWebHandler, public Component { #ifdef USE_MEDIA_PLAYER /// Return the type for prometheus void media_player_type_(AsyncResponseStream *stream); - /// Return the select state as prometheus data point + /// Return the media player 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 +#ifdef USE_UPDATE + /// Return the type for prometheus + void update_entity_type_(AsyncResponseStream *stream); + /// Return the update state and info as prometheus data point + void update_entity_row_(AsyncResponseStream *stream, update::UpdateEntity *obj, std::string &area, std::string &node, + std::string &friendly_name); + void handle_update_state_(AsyncResponseStream *stream, update::UpdateState state); +#endif + web_server_base::WebServerBase *base_; bool include_internal_{false}; std::map relabel_map_id_; diff --git a/tests/components/prometheus/common.yaml b/tests/components/prometheus/common.yaml index 1b87c1d6c1..9205c27f2a 100644 --- a/tests/components/prometheus/common.yaml +++ b/tests/components/prometheus/common.yaml @@ -1,12 +1,35 @@ +substitutions: + verify_ssl: "false" + esphome: name: livingroomdevice friendly_name: Living Room Device area: Living Room + on_boot: + then: + - if: + condition: + update.is_available: + then: + - logger.log: "Update available" + - update.perform: + force_update: true wifi: ssid: MySSID password: password1 +http_request: + verify_ssl: ${verify_ssl} + +ota: + - platform: http_request + +update: + - platform: http_request + name: Firmware Update + source: http://example.com/manifest.json + sensor: - platform: template id: template_sensor1