ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
prometheus_handler.cpp
Go to the documentation of this file.
2#if defined(USE_NETWORK) && !defined(USE_HOST)
4
6
7void PrometheusHandler::handleRequest(AsyncWebServerRequest *req) {
8 AsyncResponseStream *stream = req->beginResponseStream("text/plain; version=0.0.4; charset=utf-8");
9 std::string area = App.get_area();
10 std::string node = App.get_name();
11 std::string friendly_name = App.get_friendly_name();
12
13#ifdef USE_SENSOR
14 this->sensor_type_(stream);
15 for (auto *obj : App.get_sensors())
16 this->sensor_row_(stream, obj, area, node, friendly_name);
17#endif
18
19#ifdef USE_BINARY_SENSOR
20 this->binary_sensor_type_(stream);
21 for (auto *obj : App.get_binary_sensors())
22 this->binary_sensor_row_(stream, obj, area, node, friendly_name);
23#endif
24
25#ifdef USE_FAN
26 this->fan_type_(stream);
27 for (auto *obj : App.get_fans())
28 this->fan_row_(stream, obj, area, node, friendly_name);
29#endif
30
31#ifdef USE_LIGHT
32 this->light_type_(stream);
33 for (auto *obj : App.get_lights())
34 this->light_row_(stream, obj, area, node, friendly_name);
35#endif
36
37#ifdef USE_COVER
38 this->cover_type_(stream);
39 for (auto *obj : App.get_covers())
40 this->cover_row_(stream, obj, area, node, friendly_name);
41#endif
42
43#ifdef USE_SWITCH
44 this->switch_type_(stream);
45 for (auto *obj : App.get_switches())
46 this->switch_row_(stream, obj, area, node, friendly_name);
47#endif
48
49#ifdef USE_LOCK
50 this->lock_type_(stream);
51 for (auto *obj : App.get_locks())
52 this->lock_row_(stream, obj, area, node, friendly_name);
53#endif
54
55#ifdef USE_EVENT
56 this->event_type_(stream);
57 for (auto *obj : App.get_events())
58 this->event_row_(stream, obj, area, node, friendly_name);
59#endif
60
61#ifdef USE_TEXT
62 this->text_type_(stream);
63 for (auto *obj : App.get_texts())
64 this->text_row_(stream, obj, area, node, friendly_name);
65#endif
66
67#ifdef USE_TEXT_SENSOR
68 this->text_sensor_type_(stream);
69 for (auto *obj : App.get_text_sensors())
70 this->text_sensor_row_(stream, obj, area, node, friendly_name);
71#endif
72
73#ifdef USE_NUMBER
74 this->number_type_(stream);
75 for (auto *obj : App.get_numbers())
76 this->number_row_(stream, obj, area, node, friendly_name);
77#endif
78
79#ifdef USE_SELECT
80 this->select_type_(stream);
81 for (auto *obj : App.get_selects())
82 this->select_row_(stream, obj, area, node, friendly_name);
83#endif
84
85#ifdef USE_MEDIA_PLAYER
86 this->media_player_type_(stream);
87 for (auto *obj : App.get_media_players())
88 this->media_player_row_(stream, obj, area, node, friendly_name);
89#endif
90
91#ifdef USE_UPDATE
92 this->update_entity_type_(stream);
93 for (auto *obj : App.get_updates())
94 this->update_entity_row_(stream, obj, area, node, friendly_name);
95#endif
96
97#ifdef USE_VALVE
98 this->valve_type_(stream);
99 for (auto *obj : App.get_valves())
100 this->valve_row_(stream, obj, area, node, friendly_name);
101#endif
102
103#ifdef USE_CLIMATE
104 this->climate_type_(stream);
105 for (auto *obj : App.get_climates())
106 this->climate_row_(stream, obj, area, node, friendly_name);
107#endif
108
109 req->send(stream);
110}
111
112void PrometheusHandler::print_relabel_id_(AsyncResponseStream *stream, EntityBase *obj) {
113 auto item = relabel_map_id_.find(obj);
114 if (item != relabel_map_id_.end()) {
115 stream->print(item->second.c_str());
116 return;
117 }
118 char object_id_buf[OBJECT_ID_MAX_LEN];
119 stream->print(obj->get_object_id_to(object_id_buf).c_str());
120}
121
122void PrometheusHandler::print_relabel_name_(AsyncResponseStream *stream, EntityBase *obj) {
123 auto item = relabel_map_name_.find(obj);
124 if (item != relabel_map_name_.end()) {
125 stream->print(item->second.c_str());
126 return;
127 }
128 stream->print(reinterpret_cast<ProgmemStr>(obj->get_name_progmem().progmem_ptr()));
129}
130
131void PrometheusHandler::add_area_label_(AsyncResponseStream *stream, std::string &area) {
132 if (!area.empty()) {
133 stream->print(ESPHOME_F("\",area=\""));
134 stream->print(area.c_str());
135 }
136}
137
138void PrometheusHandler::add_node_label_(AsyncResponseStream *stream, std::string &node) {
139 if (!node.empty()) {
140 stream->print(ESPHOME_F("\",node=\""));
141 stream->print(node.c_str());
142 }
143}
144
145void PrometheusHandler::add_friendly_name_label_(AsyncResponseStream *stream, std::string &friendly_name) {
146 if (!friendly_name.empty()) {
147 stream->print(ESPHOME_F("\",friendly_name=\""));
148 stream->print(friendly_name.c_str());
149 }
150}
151
152void PrometheusHandler::print_metric_labels_(AsyncResponseStream *stream, ProgmemStr metric_name, EntityBase *obj,
153 std::string &area, std::string &node, std::string &friendly_name) {
154 stream->print(metric_name);
155 stream->print(ESPHOME_F("{id=\""));
156 this->print_relabel_id_(stream, obj);
157 add_area_label_(stream, area);
158 add_node_label_(stream, node);
159 add_friendly_name_label_(stream, friendly_name);
160 stream->print(ESPHOME_F("\",name=\""));
161 this->print_relabel_name_(stream, obj);
162}
163
164// Type-specific implementation
165#ifdef USE_SENSOR
166void PrometheusHandler::sensor_type_(AsyncResponseStream *stream) {
167 stream->print(ESPHOME_F("#TYPE esphome_sensor_value gauge\n"));
168 stream->print(ESPHOME_F("#TYPE esphome_sensor_failed gauge\n"));
169}
170void PrometheusHandler::sensor_row_(AsyncResponseStream *stream, sensor::Sensor *obj, std::string &area,
171 std::string &node, std::string &friendly_name) {
172 if (obj->is_internal() && !this->include_internal_)
173 return;
174 if (!std::isnan(obj->state)) {
175 // We have a valid value, output this value
176 stream->print(ESPHOME_F("esphome_sensor_failed{id=\""));
177 this->print_relabel_id_(stream, obj);
178 add_area_label_(stream, area);
179 add_node_label_(stream, node);
180 add_friendly_name_label_(stream, friendly_name);
181 stream->print(ESPHOME_F("\",name=\""));
182 this->print_relabel_name_(stream, obj);
183 stream->print(ESPHOME_F("\"} 0\n"));
184 // Data itself
185 stream->print(ESPHOME_F("esphome_sensor_value{id=\""));
186 this->print_relabel_id_(stream, obj);
187 add_area_label_(stream, area);
188 add_node_label_(stream, node);
189 add_friendly_name_label_(stream, friendly_name);
190 stream->print(ESPHOME_F("\",name=\""));
191 this->print_relabel_name_(stream, obj);
192 stream->print(ESPHOME_F("\",unit=\""));
193 stream->print(obj->get_unit_of_measurement_ref().c_str());
194 stream->print(ESPHOME_F("\"} "));
195 char value_buf[VALUE_ACCURACY_MAX_LEN];
196 value_accuracy_to_buf(value_buf, obj->state, obj->get_accuracy_decimals());
197 stream->print(value_buf);
198 stream->print(ESPHOME_F("\n"));
199 } else {
200 // Invalid state
201 stream->print(ESPHOME_F("esphome_sensor_failed{id=\""));
202 this->print_relabel_id_(stream, obj);
203 add_area_label_(stream, area);
204 add_node_label_(stream, node);
205 add_friendly_name_label_(stream, friendly_name);
206 stream->print(ESPHOME_F("\",name=\""));
207 this->print_relabel_name_(stream, obj);
208 stream->print(ESPHOME_F("\"} 1\n"));
209 }
210}
211#endif
212
213// Type-specific implementation
214#ifdef USE_BINARY_SENSOR
215void PrometheusHandler::binary_sensor_type_(AsyncResponseStream *stream) {
216 stream->print(ESPHOME_F("#TYPE esphome_binary_sensor_value gauge\n"));
217 stream->print(ESPHOME_F("#TYPE esphome_binary_sensor_failed gauge\n"));
218}
220 std::string &area, std::string &node, std::string &friendly_name) {
221 if (obj->is_internal() && !this->include_internal_)
222 return;
223 if (obj->has_state()) {
224 // We have a valid value, output this value
225 stream->print(ESPHOME_F("esphome_binary_sensor_failed{id=\""));
226 this->print_relabel_id_(stream, obj);
227 add_area_label_(stream, area);
228 add_node_label_(stream, node);
229 add_friendly_name_label_(stream, friendly_name);
230 stream->print(ESPHOME_F("\",name=\""));
231 this->print_relabel_name_(stream, obj);
232 stream->print(ESPHOME_F("\"} 0\n"));
233 // Data itself
234 stream->print(ESPHOME_F("esphome_binary_sensor_value{id=\""));
235 this->print_relabel_id_(stream, obj);
236 add_area_label_(stream, area);
237 add_node_label_(stream, node);
238 add_friendly_name_label_(stream, friendly_name);
239 stream->print(ESPHOME_F("\",name=\""));
240 this->print_relabel_name_(stream, obj);
241 stream->print(ESPHOME_F("\"} "));
242 stream->print(obj->state);
243 stream->print(ESPHOME_F("\n"));
244 } else {
245 // Invalid state
246 stream->print(ESPHOME_F("esphome_binary_sensor_failed{id=\""));
247 this->print_relabel_id_(stream, obj);
248 add_area_label_(stream, area);
249 add_node_label_(stream, node);
250 add_friendly_name_label_(stream, friendly_name);
251 stream->print(ESPHOME_F("\",name=\""));
252 this->print_relabel_name_(stream, obj);
253 stream->print(ESPHOME_F("\"} 1\n"));
254 }
255}
256#endif
257
258#ifdef USE_FAN
259void PrometheusHandler::fan_type_(AsyncResponseStream *stream) {
260 stream->print(ESPHOME_F("#TYPE esphome_fan_value gauge\n"));
261 stream->print(ESPHOME_F("#TYPE esphome_fan_failed gauge\n"));
262 stream->print(ESPHOME_F("#TYPE esphome_fan_speed gauge\n"));
263 stream->print(ESPHOME_F("#TYPE esphome_fan_oscillation gauge\n"));
264}
265void PrometheusHandler::fan_row_(AsyncResponseStream *stream, fan::Fan *obj, std::string &area, std::string &node,
266 std::string &friendly_name) {
267 if (obj->is_internal() && !this->include_internal_)
268 return;
269 stream->print(ESPHOME_F("esphome_fan_failed{id=\""));
270 this->print_relabel_id_(stream, obj);
271 add_area_label_(stream, area);
272 add_node_label_(stream, node);
273 add_friendly_name_label_(stream, friendly_name);
274 stream->print(ESPHOME_F("\",name=\""));
275 this->print_relabel_name_(stream, obj);
276 stream->print(ESPHOME_F("\"} 0\n"));
277 // Data itself
278 stream->print(ESPHOME_F("esphome_fan_value{id=\""));
279 this->print_relabel_id_(stream, obj);
280 add_area_label_(stream, area);
281 add_node_label_(stream, node);
282 add_friendly_name_label_(stream, friendly_name);
283 stream->print(ESPHOME_F("\",name=\""));
284 this->print_relabel_name_(stream, obj);
285 stream->print(ESPHOME_F("\"} "));
286 stream->print(obj->state);
287 stream->print(ESPHOME_F("\n"));
288 // Speed if available
289 if (obj->get_traits().supports_speed()) {
290 stream->print(ESPHOME_F("esphome_fan_speed{id=\""));
291 this->print_relabel_id_(stream, obj);
292 add_area_label_(stream, area);
293 add_node_label_(stream, node);
294 add_friendly_name_label_(stream, friendly_name);
295 stream->print(ESPHOME_F("\",name=\""));
296 this->print_relabel_name_(stream, obj);
297 stream->print(ESPHOME_F("\"} "));
298 stream->print(obj->speed);
299 stream->print(ESPHOME_F("\n"));
300 }
301 // Oscillation if available
302 if (obj->get_traits().supports_oscillation()) {
303 stream->print(ESPHOME_F("esphome_fan_oscillation{id=\""));
304 this->print_relabel_id_(stream, obj);
305 add_area_label_(stream, area);
306 add_node_label_(stream, node);
307 add_friendly_name_label_(stream, friendly_name);
308 stream->print(ESPHOME_F("\",name=\""));
309 this->print_relabel_name_(stream, obj);
310 stream->print(ESPHOME_F("\"} "));
311 stream->print(obj->oscillating);
312 stream->print(ESPHOME_F("\n"));
313 }
314}
315#endif
316
317#ifdef USE_LIGHT
318void PrometheusHandler::light_type_(AsyncResponseStream *stream) {
319 stream->print(ESPHOME_F("#TYPE esphome_light_state gauge\n"));
320 stream->print(ESPHOME_F("#TYPE esphome_light_color gauge\n"));
321 stream->print(ESPHOME_F("#TYPE esphome_light_effect_active gauge\n"));
322}
323void PrometheusHandler::light_row_(AsyncResponseStream *stream, light::LightState *obj, std::string &area,
324 std::string &node, std::string &friendly_name) {
325 if (obj->is_internal() && !this->include_internal_)
326 return;
327 // State
328 print_metric_labels_(stream, ESPHOME_F("esphome_light_state"), obj, area, node, friendly_name);
329 stream->print(ESPHOME_F("\"} "));
330 stream->print(obj->get_reported_values().is_on());
331 stream->print(ESPHOME_F("\n"));
332 // Brightness and RGBW
334 float brightness, r, g, b, w;
335 color.as_brightness(&brightness);
336 color.as_rgbw(&r, &g, &b, &w);
338 print_metric_labels_(stream, ESPHOME_F("esphome_light_color"), obj, area, node, friendly_name);
339 stream->print(ESPHOME_F("\",channel=\"brightness\"} "));
340 stream->print(brightness);
341 stream->print(ESPHOME_F("\n"));
342 }
344 print_metric_labels_(stream, ESPHOME_F("esphome_light_color"), obj, area, node, friendly_name);
345 stream->print(ESPHOME_F("\",channel=\"r\"} "));
346 stream->print(r);
347 stream->print(ESPHOME_F("\n"));
348 print_metric_labels_(stream, ESPHOME_F("esphome_light_color"), obj, area, node, friendly_name);
349 stream->print(ESPHOME_F("\",channel=\"g\"} "));
350 stream->print(g);
351 stream->print(ESPHOME_F("\n"));
352 print_metric_labels_(stream, ESPHOME_F("esphome_light_color"), obj, area, node, friendly_name);
353 stream->print(ESPHOME_F("\",channel=\"b\"} "));
354 stream->print(b);
355 stream->print(ESPHOME_F("\n"));
356 }
358 print_metric_labels_(stream, ESPHOME_F("esphome_light_color"), obj, area, node, friendly_name);
359 stream->print(ESPHOME_F("\",channel=\"w\"} "));
360 stream->print(w);
361 stream->print(ESPHOME_F("\n"));
362 }
363 // Skip effect metrics if light has no effects
364 if (!obj->get_effects().empty()) {
365 // Effect
366 StringRef effect = obj->get_effect_name();
367 print_metric_labels_(stream, ESPHOME_F("esphome_light_effect_active"), obj, area, node, friendly_name);
368 stream->print(ESPHOME_F("\",effect=\""));
369 // Only vary based on effect
370 if (effect == "None") {
371 stream->print(ESPHOME_F("None\"} 0\n"));
372 } else {
373 // c_str() is safe as effect names are null-terminated strings from codegen
374 stream->print(effect.c_str());
375 stream->print(ESPHOME_F("\"} 1\n"));
376 }
377 }
378}
379#endif
380
381#ifdef USE_COVER
382void PrometheusHandler::cover_type_(AsyncResponseStream *stream) {
383 stream->print(ESPHOME_F("#TYPE esphome_cover_value gauge\n"));
384 stream->print(ESPHOME_F("#TYPE esphome_cover_failed gauge\n"));
385}
386void PrometheusHandler::cover_row_(AsyncResponseStream *stream, cover::Cover *obj, std::string &area, std::string &node,
387 std::string &friendly_name) {
388 if (obj->is_internal() && !this->include_internal_)
389 return;
390 if (!std::isnan(obj->position)) {
391 // We have a valid value, output this value
392 stream->print(ESPHOME_F("esphome_cover_failed{id=\""));
393 this->print_relabel_id_(stream, obj);
394 add_area_label_(stream, area);
395 add_node_label_(stream, node);
396 add_friendly_name_label_(stream, friendly_name);
397 stream->print(ESPHOME_F("\",name=\""));
398 this->print_relabel_name_(stream, obj);
399 stream->print(ESPHOME_F("\"} 0\n"));
400 // Data itself
401 stream->print(ESPHOME_F("esphome_cover_value{id=\""));
402 this->print_relabel_id_(stream, obj);
403 add_area_label_(stream, area);
404 add_node_label_(stream, node);
405 add_friendly_name_label_(stream, friendly_name);
406 stream->print(ESPHOME_F("\",name=\""));
407 this->print_relabel_name_(stream, obj);
408 stream->print(ESPHOME_F("\"} "));
409 stream->print(obj->position);
410 stream->print(ESPHOME_F("\n"));
411 if (obj->get_traits().get_supports_tilt()) {
412 stream->print(ESPHOME_F("esphome_cover_tilt{id=\""));
413 this->print_relabel_id_(stream, obj);
414 add_area_label_(stream, area);
415 add_node_label_(stream, node);
416 add_friendly_name_label_(stream, friendly_name);
417 stream->print(ESPHOME_F("\",name=\""));
418 this->print_relabel_name_(stream, obj);
419 stream->print(ESPHOME_F("\"} "));
420 stream->print(obj->tilt);
421 stream->print(ESPHOME_F("\n"));
422 }
423 } else {
424 // Invalid state
425 stream->print(ESPHOME_F("esphome_cover_failed{id=\""));
426 this->print_relabel_id_(stream, obj);
427 add_area_label_(stream, area);
428 add_node_label_(stream, node);
429 add_friendly_name_label_(stream, friendly_name);
430 stream->print(ESPHOME_F("\",name=\""));
431 this->print_relabel_name_(stream, obj);
432 stream->print(ESPHOME_F("\"} 1\n"));
433 }
434}
435#endif
436
437#ifdef USE_SWITCH
438void PrometheusHandler::switch_type_(AsyncResponseStream *stream) {
439 stream->print(ESPHOME_F("#TYPE esphome_switch_value gauge\n"));
440 stream->print(ESPHOME_F("#TYPE esphome_switch_failed gauge\n"));
441}
442void PrometheusHandler::switch_row_(AsyncResponseStream *stream, switch_::Switch *obj, std::string &area,
443 std::string &node, std::string &friendly_name) {
444 if (obj->is_internal() && !this->include_internal_)
445 return;
446 stream->print(ESPHOME_F("esphome_switch_failed{id=\""));
447 this->print_relabel_id_(stream, obj);
448 add_area_label_(stream, area);
449 add_node_label_(stream, node);
450 add_friendly_name_label_(stream, friendly_name);
451 stream->print(ESPHOME_F("\",name=\""));
452 this->print_relabel_name_(stream, obj);
453 stream->print(ESPHOME_F("\"} 0\n"));
454 // Data itself
455 stream->print(ESPHOME_F("esphome_switch_value{id=\""));
456 this->print_relabel_id_(stream, obj);
457 add_area_label_(stream, area);
458 add_node_label_(stream, node);
459 add_friendly_name_label_(stream, friendly_name);
460 stream->print(ESPHOME_F("\",name=\""));
461 this->print_relabel_name_(stream, obj);
462 stream->print(ESPHOME_F("\"} "));
463 stream->print(obj->state);
464 stream->print(ESPHOME_F("\n"));
465}
466#endif
467
468#ifdef USE_LOCK
469void PrometheusHandler::lock_type_(AsyncResponseStream *stream) {
470 stream->print(ESPHOME_F("#TYPE esphome_lock_value gauge\n"));
471 stream->print(ESPHOME_F("#TYPE esphome_lock_failed gauge\n"));
472}
473void PrometheusHandler::lock_row_(AsyncResponseStream *stream, lock::Lock *obj, std::string &area, std::string &node,
474 std::string &friendly_name) {
475 if (obj->is_internal() && !this->include_internal_)
476 return;
477 stream->print(ESPHOME_F("esphome_lock_failed{id=\""));
478 this->print_relabel_id_(stream, obj);
479 add_area_label_(stream, area);
480 add_node_label_(stream, node);
481 add_friendly_name_label_(stream, friendly_name);
482 stream->print(ESPHOME_F("\",name=\""));
483 this->print_relabel_name_(stream, obj);
484 stream->print(ESPHOME_F("\"} 0\n"));
485 // Data itself
486 stream->print(ESPHOME_F("esphome_lock_value{id=\""));
487 this->print_relabel_id_(stream, obj);
488 add_area_label_(stream, area);
489 add_node_label_(stream, node);
490 add_friendly_name_label_(stream, friendly_name);
491 stream->print(ESPHOME_F("\",name=\""));
492 this->print_relabel_name_(stream, obj);
493 stream->print(ESPHOME_F("\"} "));
494 stream->print(obj->state);
495 stream->print(ESPHOME_F("\n"));
496}
497#endif
498
499// Type-specific implementation
500#ifdef USE_TEXT_SENSOR
501void PrometheusHandler::text_sensor_type_(AsyncResponseStream *stream) {
502 stream->print(ESPHOME_F("#TYPE esphome_text_sensor_value gauge\n"));
503 stream->print(ESPHOME_F("#TYPE esphome_text_sensor_failed gauge\n"));
504}
505void PrometheusHandler::text_sensor_row_(AsyncResponseStream *stream, text_sensor::TextSensor *obj, std::string &area,
506 std::string &node, std::string &friendly_name) {
507 if (obj->is_internal() && !this->include_internal_)
508 return;
509 if (obj->has_state()) {
510 // We have a valid value, output this value
511 stream->print(ESPHOME_F("esphome_text_sensor_failed{id=\""));
512 this->print_relabel_id_(stream, obj);
513 add_area_label_(stream, area);
514 add_node_label_(stream, node);
515 add_friendly_name_label_(stream, friendly_name);
516 stream->print(ESPHOME_F("\",name=\""));
517 this->print_relabel_name_(stream, obj);
518 stream->print(ESPHOME_F("\"} 0\n"));
519 // Data itself
520 stream->print(ESPHOME_F("esphome_text_sensor_value{id=\""));
521 this->print_relabel_id_(stream, obj);
522 add_area_label_(stream, area);
523 add_node_label_(stream, node);
524 add_friendly_name_label_(stream, friendly_name);
525 stream->print(ESPHOME_F("\",name=\""));
526 this->print_relabel_name_(stream, obj);
527 stream->print(ESPHOME_F("\",value=\""));
528 stream->print(obj->state.c_str());
529 stream->print(ESPHOME_F("\"} "));
530 stream->print(ESPHOME_F("1.0"));
531 stream->print(ESPHOME_F("\n"));
532 } else {
533 // Invalid state
534 stream->print(ESPHOME_F("esphome_text_sensor_failed{id=\""));
535 this->print_relabel_id_(stream, obj);
536 add_area_label_(stream, area);
537 add_node_label_(stream, node);
538 add_friendly_name_label_(stream, friendly_name);
539 stream->print(ESPHOME_F("\",name=\""));
540 this->print_relabel_name_(stream, obj);
541 stream->print(ESPHOME_F("\"} 1\n"));
542 }
543}
544#endif
545
546// Type-specific implementation
547#ifdef USE_TEXT
548void PrometheusHandler::text_type_(AsyncResponseStream *stream) {
549 stream->print(ESPHOME_F("#TYPE esphome_text_value gauge\n"));
550 stream->print(ESPHOME_F("#TYPE esphome_text_failed gauge\n"));
551}
552void PrometheusHandler::text_row_(AsyncResponseStream *stream, text::Text *obj, std::string &area, std::string &node,
553 std::string &friendly_name) {
554 if (obj->is_internal() && !this->include_internal_)
555 return;
556 if (obj->has_state()) {
557 // We have a valid value, output this value
558 stream->print(ESPHOME_F("esphome_text_failed{id=\""));
559 this->print_relabel_id_(stream, obj);
560 add_area_label_(stream, area);
561 add_node_label_(stream, node);
562 add_friendly_name_label_(stream, friendly_name);
563 stream->print(ESPHOME_F("\",name=\""));
564 this->print_relabel_name_(stream, obj);
565 stream->print(ESPHOME_F("\"} 0\n"));
566 // Data itself
567 stream->print(ESPHOME_F("esphome_text_value{id=\""));
568 this->print_relabel_id_(stream, obj);
569 add_area_label_(stream, area);
570 add_node_label_(stream, node);
571 add_friendly_name_label_(stream, friendly_name);
572 stream->print(ESPHOME_F("\",name=\""));
573 this->print_relabel_name_(stream, obj);
574 stream->print(ESPHOME_F("\",value=\""));
575 stream->print(obj->state.c_str());
576 stream->print(ESPHOME_F("\"} "));
577 stream->print(ESPHOME_F("1.0"));
578 stream->print(ESPHOME_F("\n"));
579 } else {
580 // Invalid state
581 stream->print(ESPHOME_F("esphome_text_failed{id=\""));
582 this->print_relabel_id_(stream, obj);
583 add_area_label_(stream, area);
584 add_node_label_(stream, node);
585 add_friendly_name_label_(stream, friendly_name);
586 stream->print(ESPHOME_F("\",name=\""));
587 this->print_relabel_name_(stream, obj);
588 stream->print(ESPHOME_F("\"} 1\n"));
589 }
590}
591#endif
592
593// Type-specific implementation
594#ifdef USE_EVENT
595void PrometheusHandler::event_type_(AsyncResponseStream *stream) {
596 stream->print(ESPHOME_F("#TYPE esphome_event_value gauge\n"));
597 stream->print(ESPHOME_F("#TYPE esphome_event_failed gauge\n"));
598}
599void PrometheusHandler::event_row_(AsyncResponseStream *stream, event::Event *obj, std::string &area, std::string &node,
600 std::string &friendly_name) {
601 if (obj->is_internal() && !this->include_internal_)
602 return;
603 if (obj->has_event()) {
604 // We have a valid event type, output this value
605 stream->print(ESPHOME_F("esphome_event_failed{id=\""));
606 this->print_relabel_id_(stream, obj);
607 add_area_label_(stream, area);
608 add_node_label_(stream, node);
609 add_friendly_name_label_(stream, friendly_name);
610 stream->print(ESPHOME_F("\",name=\""));
611 this->print_relabel_name_(stream, obj);
612 stream->print(ESPHOME_F("\"} 0\n"));
613 // Data itself
614 stream->print(ESPHOME_F("esphome_event_value{id=\""));
615 this->print_relabel_id_(stream, obj);
616 add_area_label_(stream, area);
617 add_node_label_(stream, node);
618 add_friendly_name_label_(stream, friendly_name);
619 stream->print(ESPHOME_F("\",name=\""));
620 this->print_relabel_name_(stream, obj);
621 stream->print(ESPHOME_F("\",last_event_type=\""));
622 // get_last_event_type() returns StringRef (null-terminated)
623 stream->print(obj->get_last_event_type().c_str());
624 stream->print(ESPHOME_F("\"} "));
625 stream->print(ESPHOME_F("1.0"));
626 stream->print(ESPHOME_F("\n"));
627 } else {
628 // No event triggered yet
629 stream->print(ESPHOME_F("esphome_event_failed{id=\""));
630 this->print_relabel_id_(stream, obj);
631 add_area_label_(stream, area);
632 add_node_label_(stream, node);
633 add_friendly_name_label_(stream, friendly_name);
634 stream->print(ESPHOME_F("\",name=\""));
635 this->print_relabel_name_(stream, obj);
636 stream->print(ESPHOME_F("\"} 1\n"));
637 }
638}
639#endif
640
641// Type-specific implementation
642#ifdef USE_NUMBER
643void PrometheusHandler::number_type_(AsyncResponseStream *stream) {
644 stream->print(ESPHOME_F("#TYPE esphome_number_value gauge\n"));
645 stream->print(ESPHOME_F("#TYPE esphome_number_failed gauge\n"));
646}
647void PrometheusHandler::number_row_(AsyncResponseStream *stream, number::Number *obj, std::string &area,
648 std::string &node, std::string &friendly_name) {
649 if (obj->is_internal() && !this->include_internal_)
650 return;
651 if (!std::isnan(obj->state)) {
652 // We have a valid value, output this value
653 stream->print(ESPHOME_F("esphome_number_failed{id=\""));
654 this->print_relabel_id_(stream, obj);
655 add_area_label_(stream, area);
656 add_node_label_(stream, node);
657 add_friendly_name_label_(stream, friendly_name);
658 stream->print(ESPHOME_F("\",name=\""));
659 this->print_relabel_name_(stream, obj);
660 stream->print(ESPHOME_F("\"} 0\n"));
661 // Data itself
662 stream->print(ESPHOME_F("esphome_number_value{id=\""));
663 this->print_relabel_id_(stream, obj);
664 add_area_label_(stream, area);
665 add_node_label_(stream, node);
666 add_friendly_name_label_(stream, friendly_name);
667 stream->print(ESPHOME_F("\",name=\""));
668 this->print_relabel_name_(stream, obj);
669 stream->print(ESPHOME_F("\"} "));
670 stream->print(obj->state);
671 stream->print(ESPHOME_F("\n"));
672 } else {
673 // Invalid state
674 stream->print(ESPHOME_F("esphome_number_failed{id=\""));
675 this->print_relabel_id_(stream, obj);
676 add_area_label_(stream, area);
677 add_node_label_(stream, node);
678 add_friendly_name_label_(stream, friendly_name);
679 stream->print(ESPHOME_F("\",name=\""));
680 this->print_relabel_name_(stream, obj);
681 stream->print(ESPHOME_F("\"} 1\n"));
682 }
683}
684#endif
685
686#ifdef USE_SELECT
687void PrometheusHandler::select_type_(AsyncResponseStream *stream) {
688 stream->print(ESPHOME_F("#TYPE esphome_select_value gauge\n"));
689 stream->print(ESPHOME_F("#TYPE esphome_select_failed gauge\n"));
690}
691void PrometheusHandler::select_row_(AsyncResponseStream *stream, select::Select *obj, std::string &area,
692 std::string &node, std::string &friendly_name) {
693 if (obj->is_internal() && !this->include_internal_)
694 return;
695 if (obj->has_state()) {
696 // We have a valid value, output this value
697 stream->print(ESPHOME_F("esphome_select_failed{id=\""));
698 this->print_relabel_id_(stream, obj);
699 add_area_label_(stream, area);
700 add_node_label_(stream, node);
701 add_friendly_name_label_(stream, friendly_name);
702 stream->print(ESPHOME_F("\",name=\""));
703 this->print_relabel_name_(stream, obj);
704 stream->print(ESPHOME_F("\"} 0\n"));
705 // Data itself
706 stream->print(ESPHOME_F("esphome_select_value{id=\""));
707 this->print_relabel_id_(stream, obj);
708 add_area_label_(stream, area);
709 add_node_label_(stream, node);
710 add_friendly_name_label_(stream, friendly_name);
711 stream->print(ESPHOME_F("\",name=\""));
712 this->print_relabel_name_(stream, obj);
713 stream->print(ESPHOME_F("\",value=\""));
714 // c_str() is safe as option values are null-terminated strings from codegen
715 stream->print(obj->current_option().c_str());
716 stream->print(ESPHOME_F("\"} "));
717 stream->print(ESPHOME_F("1.0"));
718 stream->print(ESPHOME_F("\n"));
719 } else {
720 // Invalid state
721 stream->print(ESPHOME_F("esphome_select_failed{id=\""));
722 this->print_relabel_id_(stream, obj);
723 add_area_label_(stream, area);
724 add_node_label_(stream, node);
725 add_friendly_name_label_(stream, friendly_name);
726 stream->print(ESPHOME_F("\",name=\""));
727 this->print_relabel_name_(stream, obj);
728 stream->print(ESPHOME_F("\"} 1\n"));
729 }
730}
731#endif
732
733#ifdef USE_MEDIA_PLAYER
734void PrometheusHandler::media_player_type_(AsyncResponseStream *stream) {
735 stream->print(ESPHOME_F("#TYPE esphome_media_player_state_value gauge\n"));
736 stream->print(ESPHOME_F("#TYPE esphome_media_player_volume gauge\n"));
737 stream->print(ESPHOME_F("#TYPE esphome_media_player_is_muted gauge\n"));
738 stream->print(ESPHOME_F("#TYPE esphome_media_player_failed gauge\n"));
739}
741 std::string &area, std::string &node, std::string &friendly_name) {
742 if (obj->is_internal() && !this->include_internal_)
743 return;
744 stream->print(ESPHOME_F("esphome_media_player_failed{id=\""));
745 this->print_relabel_id_(stream, obj);
746 add_area_label_(stream, area);
747 add_node_label_(stream, node);
748 add_friendly_name_label_(stream, friendly_name);
749 stream->print(ESPHOME_F("\",name=\""));
750 this->print_relabel_name_(stream, obj);
751 stream->print(ESPHOME_F("\"} 0\n"));
752 // Data itself
753 stream->print(ESPHOME_F("esphome_media_player_state_value{id=\""));
754 this->print_relabel_id_(stream, obj);
755 add_area_label_(stream, area);
756 add_node_label_(stream, node);
757 add_friendly_name_label_(stream, friendly_name);
758 stream->print(ESPHOME_F("\",name=\""));
759 this->print_relabel_name_(stream, obj);
760 stream->print(ESPHOME_F("\",value=\""));
762 stream->print(ESPHOME_F("\"} "));
763 stream->print(ESPHOME_F("1.0"));
764 stream->print(ESPHOME_F("\n"));
765 stream->print(ESPHOME_F("esphome_media_player_volume{id=\""));
766 this->print_relabel_id_(stream, obj);
767 add_area_label_(stream, area);
768 add_node_label_(stream, node);
769 add_friendly_name_label_(stream, friendly_name);
770 stream->print(ESPHOME_F("\",name=\""));
771 this->print_relabel_name_(stream, obj);
772 stream->print(ESPHOME_F("\"} "));
773 stream->print(obj->volume);
774 stream->print(ESPHOME_F("\n"));
775 stream->print(ESPHOME_F("esphome_media_player_is_muted{id=\""));
776 this->print_relabel_id_(stream, obj);
777 add_area_label_(stream, area);
778 add_node_label_(stream, node);
779 add_friendly_name_label_(stream, friendly_name);
780 stream->print(ESPHOME_F("\",name=\""));
781 this->print_relabel_name_(stream, obj);
782 stream->print(ESPHOME_F("\"} "));
783 if (obj->is_muted()) {
784 stream->print(ESPHOME_F("1.0"));
785 } else {
786 stream->print(ESPHOME_F("0.0"));
787 }
788 stream->print(ESPHOME_F("\n"));
789}
790#endif
791
792#ifdef USE_UPDATE
793void PrometheusHandler::update_entity_type_(AsyncResponseStream *stream) {
794 stream->print(ESPHOME_F("#TYPE esphome_update_entity_state gauge\n"));
795 stream->print(ESPHOME_F("#TYPE esphome_update_entity_info gauge\n"));
796 stream->print(ESPHOME_F("#TYPE esphome_update_entity_failed gauge\n"));
797}
798
800 switch (state) {
802 stream->print("unknown");
803 break;
805 stream->print("none");
806 break;
808 stream->print("available");
809 break;
811 stream->print("installing");
812 break;
813 default:
814 stream->print("invalid");
815 break;
816 }
817}
818
819void PrometheusHandler::update_entity_row_(AsyncResponseStream *stream, update::UpdateEntity *obj, std::string &area,
820 std::string &node, std::string &friendly_name) {
821 if (obj->is_internal() && !this->include_internal_)
822 return;
823 if (obj->has_state()) {
824 // We have a valid value, output this value
825 stream->print(ESPHOME_F("esphome_update_entity_failed{id=\""));
826 this->print_relabel_id_(stream, obj);
827 add_area_label_(stream, area);
828 add_node_label_(stream, node);
829 add_friendly_name_label_(stream, friendly_name);
830 stream->print(ESPHOME_F("\",name=\""));
831 this->print_relabel_name_(stream, obj);
832 stream->print(ESPHOME_F("\"} 0\n"));
833 // First update state
834 stream->print(ESPHOME_F("esphome_update_entity_state{id=\""));
835 this->print_relabel_id_(stream, obj);
836 add_area_label_(stream, area);
837 add_node_label_(stream, node);
838 add_friendly_name_label_(stream, friendly_name);
839 stream->print(ESPHOME_F("\",name=\""));
840 this->print_relabel_name_(stream, obj);
841 stream->print(ESPHOME_F("\",value=\""));
842 handle_update_state_(stream, obj->state);
843 stream->print(ESPHOME_F("\"} "));
844 stream->print(ESPHOME_F("1.0"));
845 stream->print(ESPHOME_F("\n"));
846 // Next update info
847 stream->print(ESPHOME_F("esphome_update_entity_info{id=\""));
848 this->print_relabel_id_(stream, obj);
849 add_area_label_(stream, area);
850 add_node_label_(stream, node);
851 add_friendly_name_label_(stream, friendly_name);
852 stream->print(ESPHOME_F("\",name=\""));
853 this->print_relabel_name_(stream, obj);
854 stream->print(ESPHOME_F("\",current_version=\""));
855 stream->print(obj->update_info.current_version.c_str());
856 stream->print(ESPHOME_F("\",latest_version=\""));
857 stream->print(obj->update_info.latest_version.c_str());
858 stream->print(ESPHOME_F("\",title=\""));
859 stream->print(obj->update_info.title.c_str());
860 stream->print(ESPHOME_F("\"} "));
861 stream->print(ESPHOME_F("1.0"));
862 stream->print(ESPHOME_F("\n"));
863 } else {
864 // Invalid state
865 stream->print(ESPHOME_F("esphome_update_entity_failed{id=\""));
866 this->print_relabel_id_(stream, obj);
867 add_area_label_(stream, area);
868 add_node_label_(stream, node);
869 add_friendly_name_label_(stream, friendly_name);
870 stream->print(ESPHOME_F("\",name=\""));
871 this->print_relabel_name_(stream, obj);
872 stream->print(ESPHOME_F("\"} 1\n"));
873 }
874}
875#endif
876
877#ifdef USE_VALVE
878void PrometheusHandler::valve_type_(AsyncResponseStream *stream) {
879 stream->print(ESPHOME_F("#TYPE esphome_valve_operation gauge\n"));
880 stream->print(ESPHOME_F("#TYPE esphome_valve_failed gauge\n"));
881 stream->print(ESPHOME_F("#TYPE esphome_valve_position gauge\n"));
882}
883
884void PrometheusHandler::valve_row_(AsyncResponseStream *stream, valve::Valve *obj, std::string &area, std::string &node,
885 std::string &friendly_name) {
886 if (obj->is_internal() && !this->include_internal_)
887 return;
888 stream->print(ESPHOME_F("esphome_valve_failed{id=\""));
889 this->print_relabel_id_(stream, obj);
890 add_area_label_(stream, area);
891 add_node_label_(stream, node);
892 add_friendly_name_label_(stream, friendly_name);
893 stream->print(ESPHOME_F("\",name=\""));
894 this->print_relabel_name_(stream, obj);
895 stream->print(ESPHOME_F("\"} 0\n"));
896 // Data itself
897 stream->print(ESPHOME_F("esphome_valve_operation{id=\""));
898 this->print_relabel_id_(stream, obj);
899 add_area_label_(stream, area);
900 add_node_label_(stream, node);
901 add_friendly_name_label_(stream, friendly_name);
902 stream->print(ESPHOME_F("\",name=\""));
903 this->print_relabel_name_(stream, obj);
904 stream->print(ESPHOME_F("\",operation=\""));
905 stream->print(reinterpret_cast<ProgmemStr>(valve::valve_operation_to_str(obj->current_operation)));
906 stream->print(ESPHOME_F("\"} "));
907 stream->print(ESPHOME_F("1.0"));
908 stream->print(ESPHOME_F("\n"));
909 // Now see if position is supported
910 if (obj->get_traits().get_supports_position()) {
911 stream->print(ESPHOME_F("esphome_valve_position{id=\""));
912 this->print_relabel_id_(stream, obj);
913 add_area_label_(stream, area);
914 add_node_label_(stream, node);
915 add_friendly_name_label_(stream, friendly_name);
916 stream->print(ESPHOME_F("\",name=\""));
917 this->print_relabel_name_(stream, obj);
918 stream->print(ESPHOME_F("\"} "));
919 stream->print(obj->position);
920 stream->print(ESPHOME_F("\n"));
921 }
922}
923#endif
924
925#ifdef USE_CLIMATE
926void PrometheusHandler::climate_type_(AsyncResponseStream *stream) {
927 stream->print(ESPHOME_F("#TYPE esphome_climate_setting gauge\n"));
928 stream->print(ESPHOME_F("#TYPE esphome_climate_value gauge\n"));
929 stream->print(ESPHOME_F("#TYPE esphome_climate_failed gauge\n"));
930}
931
932void PrometheusHandler::climate_setting_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area,
933 std::string &node, std::string &friendly_name, std::string &setting,
934 const LogString *setting_value) {
935 stream->print(ESPHOME_F("esphome_climate_setting{id=\""));
936 this->print_relabel_id_(stream, obj);
937 add_area_label_(stream, area);
938 add_node_label_(stream, node);
939 add_friendly_name_label_(stream, friendly_name);
940 stream->print(ESPHOME_F("\",name=\""));
941 this->print_relabel_name_(stream, obj);
942 stream->print(ESPHOME_F("\",category=\""));
943 stream->print(setting.c_str());
944 stream->print(ESPHOME_F("\",setting_value=\""));
945#ifdef USE_ESP8266
946 stream->print((const __FlashStringHelper *) setting_value);
947#else
948 stream->print(LOG_STR_ARG(setting_value));
949#endif
950 stream->print(ESPHOME_F("\"} "));
951 stream->print(ESPHOME_F("1.0"));
952 stream->print(ESPHOME_F("\n"));
953}
954
955void PrometheusHandler::climate_value_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area,
956 std::string &node, std::string &friendly_name, std::string &category,
957 const char *climate_value) {
958 stream->print(ESPHOME_F("esphome_climate_value{id=\""));
959 this->print_relabel_id_(stream, obj);
960 add_area_label_(stream, area);
961 add_node_label_(stream, node);
962 add_friendly_name_label_(stream, friendly_name);
963 stream->print(ESPHOME_F("\",name=\""));
964 this->print_relabel_name_(stream, obj);
965 stream->print(ESPHOME_F("\",category=\""));
966 stream->print(category.c_str());
967 stream->print(ESPHOME_F("\"} "));
968 stream->print(climate_value);
969 stream->print(ESPHOME_F("\n"));
970}
971
972void PrometheusHandler::climate_failed_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area,
973 std::string &node, std::string &friendly_name, std::string &category,
974 bool is_failed_value) {
975 stream->print(ESPHOME_F("esphome_climate_failed{id=\""));
976 this->print_relabel_id_(stream, obj);
977 add_area_label_(stream, area);
978 add_node_label_(stream, node);
979 add_friendly_name_label_(stream, friendly_name);
980 stream->print(ESPHOME_F("\",name=\""));
981 this->print_relabel_name_(stream, obj);
982 stream->print(ESPHOME_F("\",category=\""));
983 stream->print(category.c_str());
984 stream->print(ESPHOME_F("\"} "));
985 if (is_failed_value) {
986 stream->print(ESPHOME_F("1.0"));
987 } else {
988 stream->print(ESPHOME_F("0.0"));
989 }
990 stream->print(ESPHOME_F("\n"));
991}
992
993void PrometheusHandler::climate_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area,
994 std::string &node, std::string &friendly_name) {
995 if (obj->is_internal() && !this->include_internal_)
996 return;
997 // Data itself
998 bool any_failures = false;
999 std::string climate_mode_category = "mode";
1000 const auto *climate_mode_value = climate::climate_mode_to_string(obj->mode);
1001 climate_setting_row_(stream, obj, area, node, friendly_name, climate_mode_category, climate_mode_value);
1002 const auto traits = obj->get_traits();
1003 // Now see if traits is supported
1004 int8_t target_accuracy = traits.get_target_temperature_accuracy_decimals();
1005 int8_t current_accuracy = traits.get_current_temperature_accuracy_decimals();
1006 char value_buf[VALUE_ACCURACY_MAX_LEN];
1007 // max temp
1008 std::string max_temp = "maximum_temperature";
1009 value_accuracy_to_buf(value_buf, traits.get_visual_max_temperature(), target_accuracy);
1010 climate_value_row_(stream, obj, area, node, friendly_name, max_temp, value_buf);
1011 // min temp
1012 std::string min_temp = "minimum_temperature";
1013 value_accuracy_to_buf(value_buf, traits.get_visual_min_temperature(), target_accuracy);
1014 climate_value_row_(stream, obj, area, node, friendly_name, min_temp, value_buf);
1015 // now check optional traits
1016 if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_CURRENT_TEMPERATURE)) {
1017 std::string current_temp = "current_temperature";
1018 if (std::isnan(obj->current_temperature)) {
1019 climate_failed_row_(stream, obj, area, node, friendly_name, current_temp, true);
1020 any_failures = true;
1021 } else {
1022 value_accuracy_to_buf(value_buf, obj->current_temperature, current_accuracy);
1023 climate_value_row_(stream, obj, area, node, friendly_name, current_temp, value_buf);
1024 climate_failed_row_(stream, obj, area, node, friendly_name, current_temp, false);
1025 }
1026 }
1027 if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_CURRENT_HUMIDITY)) {
1028 std::string current_humidity = "current_humidity";
1029 if (std::isnan(obj->current_humidity)) {
1030 climate_failed_row_(stream, obj, area, node, friendly_name, current_humidity, true);
1031 any_failures = true;
1032 } else {
1033 value_accuracy_to_buf(value_buf, obj->current_humidity, 0);
1034 climate_value_row_(stream, obj, area, node, friendly_name, current_humidity, value_buf);
1035 climate_failed_row_(stream, obj, area, node, friendly_name, current_humidity, false);
1036 }
1037 }
1038 if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_TARGET_HUMIDITY)) {
1039 std::string target_humidity = "target_humidity";
1040 if (std::isnan(obj->target_humidity)) {
1041 climate_failed_row_(stream, obj, area, node, friendly_name, target_humidity, true);
1042 any_failures = true;
1043 } else {
1044 value_accuracy_to_buf(value_buf, obj->target_humidity, 0);
1045 climate_value_row_(stream, obj, area, node, friendly_name, target_humidity, value_buf);
1046 climate_failed_row_(stream, obj, area, node, friendly_name, target_humidity, false);
1047 }
1048 }
1049 if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_TWO_POINT_TARGET_TEMPERATURE |
1051 std::string target_temp_low = "target_temperature_low";
1052 value_accuracy_to_buf(value_buf, obj->target_temperature_low, target_accuracy);
1053 climate_value_row_(stream, obj, area, node, friendly_name, target_temp_low, value_buf);
1054 std::string target_temp_high = "target_temperature_high";
1055 value_accuracy_to_buf(value_buf, obj->target_temperature_high, target_accuracy);
1056 climate_value_row_(stream, obj, area, node, friendly_name, target_temp_high, value_buf);
1057 } else {
1058 std::string target_temp = "target_temperature";
1059 value_accuracy_to_buf(value_buf, obj->target_temperature, target_accuracy);
1060 climate_value_row_(stream, obj, area, node, friendly_name, target_temp, value_buf);
1061 }
1062 if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_ACTION)) {
1063 std::string climate_trait_category = "action";
1064 const auto *climate_trait_value = climate::climate_action_to_string(obj->action);
1065 climate_setting_row_(stream, obj, area, node, friendly_name, climate_trait_category, climate_trait_value);
1066 }
1067 if (traits.get_supports_fan_modes()) {
1068 std::string climate_trait_category = "fan_mode";
1069 if (obj->fan_mode.has_value()) {
1070 const auto *climate_trait_value = climate::climate_fan_mode_to_string(obj->fan_mode.value());
1071 climate_setting_row_(stream, obj, area, node, friendly_name, climate_trait_category, climate_trait_value);
1072 climate_failed_row_(stream, obj, area, node, friendly_name, climate_trait_category, false);
1073 } else {
1074 climate_failed_row_(stream, obj, area, node, friendly_name, climate_trait_category, true);
1075 any_failures = true;
1076 }
1077 }
1078 if (traits.get_supports_presets()) {
1079 std::string climate_trait_category = "preset";
1080 if (obj->preset.has_value()) {
1081 const auto *climate_trait_value = climate::climate_preset_to_string(obj->preset.value());
1082 climate_setting_row_(stream, obj, area, node, friendly_name, climate_trait_category, climate_trait_value);
1083 climate_failed_row_(stream, obj, area, node, friendly_name, climate_trait_category, false);
1084 } else {
1085 climate_failed_row_(stream, obj, area, node, friendly_name, climate_trait_category, true);
1086 any_failures = true;
1087 }
1088 }
1089 if (traits.get_supports_swing_modes()) {
1090 std::string climate_trait_category = "swing_mode";
1091 const auto *climate_trait_value = climate::climate_swing_mode_to_string(obj->swing_mode);
1092 climate_setting_row_(stream, obj, area, node, friendly_name, climate_trait_category, climate_trait_value);
1093 }
1094 std::string all_climate_category = "all";
1095 climate_failed_row_(stream, obj, area, node, friendly_name, all_climate_category, any_failures);
1096}
1097#endif
1098
1099} // namespace esphome::prometheus
1100
1101#endif
const StringRef & get_name() const
Get the name of this Application set by pre_setup().
const StringRef & get_friendly_name() const
Get the friendly name of this Application set by pre_setup().
const char * get_area() const
Get the area of this Application set by pre_setup().
const ProgmemStringRef & get_name_progmem() const
The name as stored, for consumers that read flash themselves (e.g. API progmem fields).
Definition entity_base.h:94
bool is_internal() const
StringRef get_unit_of_measurement_ref() const
bool has_state() const
StringRef get_object_id_to(std::span< char, OBJECT_ID_MAX_LEN > buf) const
Get object_id with zero heap allocation For static case: returns StringRef to internal storage (buffe...
constexpr const char * progmem_ptr() const
Definition string_ref.h:238
StringRef is a reference to a string owned by something else.
Definition string_ref.h:31
constexpr const char * c_str() const
Definition string_ref.h:78
Base class for all binary_sensor-type classes.
bool state
The current state of this binary sensor. Also used as the backing storage for StatefulEntityBase.
ClimateDevice - This is the base class for all climate integrations.
Definition climate.h:192
ClimateMode mode
The active mode of the climate device.
Definition climate.h:317
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
Definition climate.h:311
ClimateTraits get_traits()
Get the traits of this climate device with all overrides applied.
Definition climate.cpp:482
float target_temperature
The target temperature of the climate device.
Definition climate.h:298
float current_humidity
The current humidity of the climate device, as reported from the integration.
Definition climate.h:294
ClimateSwingMode swing_mode
The active swing mode of the climate device.
Definition climate.h:323
float target_temperature_low
The minimum target temperature of the climate device, for climate devices with split target temperatu...
Definition climate.h:301
float current_temperature
The current temperature of the climate device, as reported from the integration.
Definition climate.h:291
ClimateAction action
The active state of the climate device.
Definition climate.h:320
optional< ClimatePreset > preset
The active preset of the climate device.
Definition climate.h:314
float target_humidity
The target humidity of the climate device.
Definition climate.h:308
float target_temperature_high
The maximum target temperature of the climate device, for climate devices with split target temperatu...
Definition climate.h:303
int8_t get_target_temperature_accuracy_decimals() const
Base class for all cover devices.
Definition cover.h:115
float tilt
The current tilt value of the cover from 0.0 to 1.0.
Definition cover.h:128
float position
The position of the cover from 0.0 (fully closed) to 1.0 (fully open).
Definition cover.h:126
virtual CoverTraits get_traits()=0
bool has_event() const
Check if an event has been triggered.
Definition event.h:75
StringRef get_last_event_type() const
Return the last triggered event type, or empty StringRef if no event triggered yet.
Definition event.h:54
virtual FanTraits get_traits()=0
bool oscillating
The current oscillation state of the fan.
Definition fan.h:113
bool state
The current on/off state of the fan.
Definition fan.h:111
int speed
The current fan speed level.
Definition fan.h:115
bool supports_speed() const
Return if this fan supports speed modes.
Definition fan_traits.h:27
bool supports_oscillation() const
Return if this fan supports oscillation.
Definition fan_traits.h:23
This class represents the color state for a light object.
void as_rgbw(float *red, float *green, float *blue, float *white) const
Convert these light color values to an RGBW representation and write them to red, green,...
bool is_on() const
Get the binary true/false state of these light color values.
void as_brightness(float *brightness) const
Convert these light color values to a brightness-only representation and write them to brightness.
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
Definition light_state.h:68
StringRef get_effect_name()
Return the name of the current effect, or if no effect is active "None".
const LightColorValues & get_reported_values() const
The values reported to the frontend: current_values while a light publishes intermediate states on an...
Definition light_state.h:82
const ConstVector< LightEffect * > & get_effects() const
Get all effects for this light state.
LightColorValues current_values
The current values of the light as outputted to the light.
bool supports_color_capability(ColorCapability color_capability) const
Base class for all locks.
Definition lock.h:112
LockState state
The current reported state of the lock.
Definition lock.h:131
Base-class for all numbers.
Definition number.h:29
void number_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void add_friendly_name_label_(AsyncResponseStream *stream, std::string &friendly_name)
void handle_update_state_(AsyncResponseStream *stream, update::UpdateState state)
void climate_setting_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area, std::string &node, std::string &friendly_name, std::string &setting, const LogString *setting_value)
void event_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void media_player_row_(AsyncResponseStream *stream, media_player::MediaPlayer *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the media player state as prometheus data point.
void light_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void print_relabel_name_(AsyncResponseStream *stream, EntityBase *obj)
void text_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void update_entity_row_(AsyncResponseStream *stream, update::UpdateEntity *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the update state and info as prometheus data point.
std::map< EntityBase *, std::string > relabel_map_id_
void fan_row_(AsyncResponseStream *stream, fan::Fan *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the fan state as prometheus data point.
void climate_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void binary_sensor_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void switch_row_(AsyncResponseStream *stream, switch_::Switch *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the switch values state as prometheus data point.
std::map< EntityBase *, std::string > relabel_map_name_
void sensor_row_(AsyncResponseStream *stream, sensor::Sensor *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the sensor state as prometheus data point.
void light_row_(AsyncResponseStream *stream, light::LightState *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the light values state as prometheus data point.
void climate_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the climate state as prometheus data point.
void update_entity_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void climate_failed_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area, std::string &node, std::string &friendly_name, std::string &category, bool is_failed_value)
void print_relabel_id_(AsyncResponseStream *stream, EntityBase *obj)
void binary_sensor_row_(AsyncResponseStream *stream, binary_sensor::BinarySensor *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the binary sensor state as prometheus data point.
void number_row_(AsyncResponseStream *stream, number::Number *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the number state as prometheus data point.
void valve_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void switch_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void media_player_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void event_row_(AsyncResponseStream *stream, event::Event *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the event values state as prometheus data point.
void text_sensor_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void text_sensor_row_(AsyncResponseStream *stream, text_sensor::TextSensor *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the text sensor values state as prometheus data point.
void add_area_label_(AsyncResponseStream *stream, std::string &area)
void print_metric_labels_(AsyncResponseStream *stream, ProgmemStr metric_name, EntityBase *obj, std::string &area, std::string &node, std::string &friendly_name)
Print metric name and common labels (id, area, node, friendly_name, name)
void select_row_(AsyncResponseStream *stream, select::Select *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the select state as prometheus data point.
void cover_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void select_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void add_node_label_(AsyncResponseStream *stream, std::string &node)
void handleRequest(AsyncWebServerRequest *req) override
void text_row_(AsyncResponseStream *stream, text::Text *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the text values state as prometheus data point.
void cover_row_(AsyncResponseStream *stream, cover::Cover *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the cover values state as prometheus data point.
void lock_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void valve_row_(AsyncResponseStream *stream, valve::Valve *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the valve state as prometheus data point.
void climate_value_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area, std::string &node, std::string &friendly_name, std::string &category, const char *climate_value)
void fan_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void sensor_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void lock_row_(AsyncResponseStream *stream, lock::Lock *obj, std::string &area, std::string &node, std::string &friendly_name)
Return the lock values state as prometheus data point.
Base-class for all selects.
Definition select.h:28
StringRef current_option() const
Return the currently selected option, or empty StringRef if no state.
Definition select.h:42
Base-class for all sensors.
Definition sensor.h:47
float state
This member variable stores the last state that has passed through all filters.
Definition sensor.h:140
int8_t get_accuracy_decimals()
Get the accuracy in decimals, using the manual override if set.
Definition sensor.cpp:45
Base class for all switches.
Definition switch.h:43
bool state
The current reported state of the binary sensor.
Definition switch.h:60
Base-class for all text inputs.
Definition text.h:20
std::string state
Definition text.h:22
const UpdateState & state
const UpdateInfo & update_info
Base class for all valve devices.
Definition valve.h:102
float position
The position of the valve from 0.0 (fully closed) to 1.0 (fully open).
Definition valve.h:113
ValveOperation current_operation
The current operation of the valve (idle, opening, closing).
Definition valve.h:107
virtual ValveTraits get_traits()=0
bool get_supports_position() const
float target_humidity
Definition climate.h:19
bool state
Definition fan.h:2
const LogString * climate_action_to_string(ClimateAction action)
Convert the given ClimateAction to a human-readable string.
@ CLIMATE_SUPPORTS_CURRENT_HUMIDITY
@ CLIMATE_SUPPORTS_TWO_POINT_TARGET_TEMPERATURE
@ CLIMATE_SUPPORTS_CURRENT_TEMPERATURE
@ CLIMATE_REQUIRES_TWO_POINT_TARGET_TEMPERATURE
const LogString * climate_swing_mode_to_string(ClimateSwingMode swing_mode)
Convert the given ClimateSwingMode to a human-readable string.
const LogString * climate_preset_to_string(ClimatePreset preset)
Convert the given PresetMode to a human-readable string.
const LogString * climate_fan_mode_to_string(ClimateFanMode fan_mode)
Convert the given ClimateFanMode to a human-readable string.
const LogString * climate_mode_to_string(ClimateMode mode)
Convert the given ClimateMode to a human-readable string.
@ BRIGHTNESS
Master brightness of the light can be controlled.
@ RGB
Color can be controlled using RGB format (includes a brightness control for the color).
@ WHITE
Brightness of white channel can be controlled separately from other channels.
const char * media_player_state_to_string(MediaPlayerState state)
const LogString * valve_operation_to_str(ValveOperation op)
Definition valve.cpp:28
size_t value_accuracy_to_buf(std::span< char, VALUE_ACCURACY_MAX_LEN > buf, float value, int8_t accuracy_decimals)
Format value with accuracy to buffer, returns chars written (excluding null)
Definition helpers.cpp:625
Application App
Global storage of Application pointer - only one Application can exist.
const __FlashStringHelper * ProgmemStr
Definition progmem.h:31