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