[prometheus] Avoid generating unused light color metrics to reduce memory usage on ESP8266 (#9530)

Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Pawelo
2025-11-26 19:06:51 +01:00
committed by GitHub
parent 12a51ff047
commit 083886c4b0
3 changed files with 92 additions and 78 deletions

View File

@@ -141,6 +141,24 @@ void PrometheusHandler::add_friendly_name_label_(AsyncResponseStream *stream, st
}
}
#ifdef USE_ESP8266
void PrometheusHandler::print_metric_labels_(AsyncResponseStream *stream, const __FlashStringHelper *metric_name,
EntityBase *obj, std::string &area, std::string &node,
std::string &friendly_name) {
#else
void PrometheusHandler::print_metric_labels_(AsyncResponseStream *stream, const char *metric_name, EntityBase *obj,
std::string &area, std::string &node, std::string &friendly_name) {
#endif
stream->print(metric_name);
stream->print(ESPHOME_F("{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(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
}
// Type-specific implementation
#ifdef USE_SENSOR
void PrometheusHandler::sensor_type_(AsyncResponseStream *stream) {
@@ -303,13 +321,7 @@ void PrometheusHandler::light_row_(AsyncResponseStream *stream, light::LightStat
if (obj->is_internal() && !this->include_internal_)
return;
// State
stream->print(ESPHOME_F("esphome_light_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(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
print_metric_labels_(stream, ESPHOME_F("esphome_light_state"), obj, area, node, friendly_name);
stream->print(ESPHOME_F("\"} "));
stream->print(obj->remote_values.is_on());
stream->print(ESPHOME_F("\n"));
@@ -318,78 +330,45 @@ void PrometheusHandler::light_row_(AsyncResponseStream *stream, light::LightStat
float brightness, r, g, b, w;
color.as_brightness(&brightness);
color.as_rgbw(&r, &g, &b, &w);
stream->print(ESPHOME_F("esphome_light_color{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(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(ESPHOME_F("\",channel=\"brightness\"} "));
stream->print(brightness);
stream->print(ESPHOME_F("\n"));
stream->print(ESPHOME_F("esphome_light_color{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(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(ESPHOME_F("\",channel=\"r\"} "));
stream->print(r);
stream->print(ESPHOME_F("\n"));
stream->print(ESPHOME_F("esphome_light_color{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(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(ESPHOME_F("\",channel=\"g\"} "));
stream->print(g);
stream->print(ESPHOME_F("\n"));
stream->print(ESPHOME_F("esphome_light_color{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(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(ESPHOME_F("\",channel=\"b\"} "));
stream->print(b);
stream->print(ESPHOME_F("\n"));
stream->print(ESPHOME_F("esphome_light_color{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(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(ESPHOME_F("\",channel=\"w\"} "));
stream->print(w);
stream->print(ESPHOME_F("\n"));
// Effect
std::string effect = obj->get_effect_name();
if (effect == "None") {
stream->print(ESPHOME_F("esphome_light_effect_active{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(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(ESPHOME_F("\",effect=\"None\"} 0\n"));
} else {
stream->print(ESPHOME_F("esphome_light_effect_active{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(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
if (obj->get_traits().supports_color_capability(light::ColorCapability::BRIGHTNESS)) {
print_metric_labels_(stream, ESPHOME_F("esphome_light_color"), obj, area, node, friendly_name);
stream->print(ESPHOME_F("\",channel=\"brightness\"} "));
stream->print(brightness);
stream->print(ESPHOME_F("\n"));
}
if (obj->get_traits().supports_color_capability(light::ColorCapability::RGB)) {
print_metric_labels_(stream, ESPHOME_F("esphome_light_color"), obj, area, node, friendly_name);
stream->print(ESPHOME_F("\",channel=\"r\"} "));
stream->print(r);
stream->print(ESPHOME_F("\n"));
print_metric_labels_(stream, ESPHOME_F("esphome_light_color"), obj, area, node, friendly_name);
stream->print(ESPHOME_F("\",channel=\"g\"} "));
stream->print(g);
stream->print(ESPHOME_F("\n"));
print_metric_labels_(stream, ESPHOME_F("esphome_light_color"), obj, area, node, friendly_name);
stream->print(ESPHOME_F("\",channel=\"b\"} "));
stream->print(b);
stream->print(ESPHOME_F("\n"));
}
if (obj->get_traits().supports_color_capability(light::ColorCapability::WHITE)) {
print_metric_labels_(stream, ESPHOME_F("esphome_light_color"), obj, area, node, friendly_name);
stream->print(ESPHOME_F("\",channel=\"w\"} "));
stream->print(w);
stream->print(ESPHOME_F("\n"));
}
// Skip effect metrics if light has no effects
if (!obj->get_effects().empty()) {
// Effect
std::string effect = obj->get_effect_name();
print_metric_labels_(stream, ESPHOME_F("esphome_light_effect_active"), obj, area, node, friendly_name);
stream->print(ESPHOME_F("\",effect=\""));
stream->print(effect.c_str());
stream->print(ESPHOME_F("\"} 1\n"));
// Only vary based on effect
if (effect == "None") {
stream->print(ESPHOME_F("None\"} 0\n"));
} else {
stream->print(effect.c_str());
stream->print(ESPHOME_F("\"} 1\n"));
}
}
}
#endif

View File

@@ -66,6 +66,14 @@ class PrometheusHandler : public AsyncWebHandler, public Component {
void add_area_label_(AsyncResponseStream *stream, std::string &area);
void add_node_label_(AsyncResponseStream *stream, std::string &node);
void add_friendly_name_label_(AsyncResponseStream *stream, std::string &friendly_name);
/// Print metric name and common labels (id, area, node, friendly_name, name)
#ifdef USE_ESP8266
void print_metric_labels_(AsyncResponseStream *stream, const __FlashStringHelper *metric_name, EntityBase *obj,
std::string &area, std::string &node, std::string &friendly_name);
#else
void print_metric_labels_(AsyncResponseStream *stream, const char *metric_name, EntityBase *obj, std::string &area,
std::string &node, std::string &friendly_name);
#endif
#ifdef USE_SENSOR
/// Return the type for prometheus

View File

@@ -112,6 +112,25 @@ cover:
}
return COVER_CLOSED;
light:
- platform: binary
name: "Binary Light"
output: test_output
- platform: monochromatic
name: "Brightness Light"
output: test_output
- platform: rgb
name: "RGB Light"
red: test_output
green: test_output
blue: test_output
- platform: rgbw
name: "RGBW Light"
red: test_output
green: test_output
blue: test_output
white: test_output
lock:
- platform: template
id: template_lock1
@@ -122,6 +141,14 @@ lock:
return LOCK_STATE_UNLOCKED;
optimistic: true
output:
- platform: template
id: test_output
type: float
write_action:
- lambda: |-
// no-op for CI/build tests
(void)state;
select:
- platform: template
id: template_select1