ESPHome  2025.2.0
prometheus_handler.cpp
Go to the documentation of this file.
1 #include "prometheus_handler.h"
2 #ifdef USE_NETWORK
4 
5 namespace esphome {
6 namespace prometheus {
7 
8 void 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_TEXT_SENSOR
57  this->text_sensor_type_(stream);
58  for (auto *obj : App.get_text_sensors())
59  this->text_sensor_row_(stream, obj, area, node, friendly_name);
60 #endif
61 
62 #ifdef USE_NUMBER
63  this->number_type_(stream);
64  for (auto *obj : App.get_numbers())
65  this->number_row_(stream, obj, area, node, friendly_name);
66 #endif
67 
68 #ifdef USE_SELECT
69  this->select_type_(stream);
70  for (auto *obj : App.get_selects())
71  this->select_row_(stream, obj, area, node, friendly_name);
72 #endif
73 
74 #ifdef USE_MEDIA_PLAYER
75  this->media_player_type_(stream);
76  for (auto *obj : App.get_media_players())
77  this->media_player_row_(stream, obj, area, node, friendly_name);
78 #endif
79 
80 #ifdef USE_UPDATE
81  this->update_entity_type_(stream);
82  for (auto *obj : App.get_updates())
83  this->update_entity_row_(stream, obj, area, node, friendly_name);
84 #endif
85 
86 #ifdef USE_VALVE
87  this->valve_type_(stream);
88  for (auto *obj : App.get_valves())
89  this->valve_row_(stream, obj, area, node, friendly_name);
90 #endif
91 
92  req->send(stream);
93 }
94 
96  auto item = relabel_map_id_.find(obj);
97  return item == relabel_map_id_.end() ? obj->get_object_id() : item->second;
98 }
99 
101  auto item = relabel_map_name_.find(obj);
102  return item == relabel_map_name_.end() ? obj->get_name() : item->second;
103 }
104 
105 void PrometheusHandler::add_area_label_(AsyncResponseStream *stream, std::string &area) {
106  if (!area.empty()) {
107  stream->print(F("\",area=\""));
108  stream->print(area.c_str());
109  }
110 }
111 
112 void PrometheusHandler::add_node_label_(AsyncResponseStream *stream, std::string &node) {
113  if (!node.empty()) {
114  stream->print(F("\",node=\""));
115  stream->print(node.c_str());
116  }
117 }
118 
119 void PrometheusHandler::add_friendly_name_label_(AsyncResponseStream *stream, std::string &friendly_name) {
120  if (!friendly_name.empty()) {
121  stream->print(F("\",friendly_name=\""));
122  stream->print(friendly_name.c_str());
123  }
124 }
125 
126 // Type-specific implementation
127 #ifdef USE_SENSOR
128 void PrometheusHandler::sensor_type_(AsyncResponseStream *stream) {
129  stream->print(F("#TYPE esphome_sensor_value gauge\n"));
130  stream->print(F("#TYPE esphome_sensor_failed gauge\n"));
131 }
132 void PrometheusHandler::sensor_row_(AsyncResponseStream *stream, sensor::Sensor *obj, std::string &area,
133  std::string &node, std::string &friendly_name) {
134  if (obj->is_internal() && !this->include_internal_)
135  return;
136  if (!std::isnan(obj->state)) {
137  // We have a valid value, output this value
138  stream->print(F("esphome_sensor_failed{id=\""));
139  stream->print(relabel_id_(obj).c_str());
140  add_area_label_(stream, area);
141  add_node_label_(stream, node);
142  add_friendly_name_label_(stream, friendly_name);
143  stream->print(F("\",name=\""));
144  stream->print(relabel_name_(obj).c_str());
145  stream->print(F("\"} 0\n"));
146  // Data itself
147  stream->print(F("esphome_sensor_value{id=\""));
148  stream->print(relabel_id_(obj).c_str());
149  add_area_label_(stream, area);
150  add_node_label_(stream, node);
151  add_friendly_name_label_(stream, friendly_name);
152  stream->print(F("\",name=\""));
153  stream->print(relabel_name_(obj).c_str());
154  stream->print(F("\",unit=\""));
155  stream->print(obj->get_unit_of_measurement().c_str());
156  stream->print(F("\"} "));
157  stream->print(value_accuracy_to_string(obj->state, obj->get_accuracy_decimals()).c_str());
158  stream->print(F("\n"));
159  } else {
160  // Invalid state
161  stream->print(F("esphome_sensor_failed{id=\""));
162  stream->print(relabel_id_(obj).c_str());
163  add_area_label_(stream, area);
164  add_node_label_(stream, node);
165  add_friendly_name_label_(stream, friendly_name);
166  stream->print(F("\",name=\""));
167  stream->print(relabel_name_(obj).c_str());
168  stream->print(F("\"} 1\n"));
169  }
170 }
171 #endif
172 
173 // Type-specific implementation
174 #ifdef USE_BINARY_SENSOR
175 void PrometheusHandler::binary_sensor_type_(AsyncResponseStream *stream) {
176  stream->print(F("#TYPE esphome_binary_sensor_value gauge\n"));
177  stream->print(F("#TYPE esphome_binary_sensor_failed gauge\n"));
178 }
180  std::string &area, std::string &node, std::string &friendly_name) {
181  if (obj->is_internal() && !this->include_internal_)
182  return;
183  if (obj->has_state()) {
184  // We have a valid value, output this value
185  stream->print(F("esphome_binary_sensor_failed{id=\""));
186  stream->print(relabel_id_(obj).c_str());
187  add_area_label_(stream, area);
188  add_node_label_(stream, node);
189  add_friendly_name_label_(stream, friendly_name);
190  stream->print(F("\",name=\""));
191  stream->print(relabel_name_(obj).c_str());
192  stream->print(F("\"} 0\n"));
193  // Data itself
194  stream->print(F("esphome_binary_sensor_value{id=\""));
195  stream->print(relabel_id_(obj).c_str());
196  add_area_label_(stream, area);
197  add_node_label_(stream, node);
198  add_friendly_name_label_(stream, friendly_name);
199  stream->print(F("\",name=\""));
200  stream->print(relabel_name_(obj).c_str());
201  stream->print(F("\"} "));
202  stream->print(obj->state);
203  stream->print(F("\n"));
204  } else {
205  // Invalid state
206  stream->print(F("esphome_binary_sensor_failed{id=\""));
207  stream->print(relabel_id_(obj).c_str());
208  add_area_label_(stream, area);
209  add_node_label_(stream, node);
210  add_friendly_name_label_(stream, friendly_name);
211  stream->print(F("\",name=\""));
212  stream->print(relabel_name_(obj).c_str());
213  stream->print(F("\"} 1\n"));
214  }
215 }
216 #endif
217 
218 #ifdef USE_FAN
219 void PrometheusHandler::fan_type_(AsyncResponseStream *stream) {
220  stream->print(F("#TYPE esphome_fan_value gauge\n"));
221  stream->print(F("#TYPE esphome_fan_failed gauge\n"));
222  stream->print(F("#TYPE esphome_fan_speed gauge\n"));
223  stream->print(F("#TYPE esphome_fan_oscillation gauge\n"));
224 }
225 void PrometheusHandler::fan_row_(AsyncResponseStream *stream, fan::Fan *obj, std::string &area, std::string &node,
226  std::string &friendly_name) {
227  if (obj->is_internal() && !this->include_internal_)
228  return;
229  stream->print(F("esphome_fan_failed{id=\""));
230  stream->print(relabel_id_(obj).c_str());
231  add_area_label_(stream, area);
232  add_node_label_(stream, node);
233  add_friendly_name_label_(stream, friendly_name);
234  stream->print(F("\",name=\""));
235  stream->print(relabel_name_(obj).c_str());
236  stream->print(F("\"} 0\n"));
237  // Data itself
238  stream->print(F("esphome_fan_value{id=\""));
239  stream->print(relabel_id_(obj).c_str());
240  add_area_label_(stream, area);
241  add_node_label_(stream, node);
242  add_friendly_name_label_(stream, friendly_name);
243  stream->print(F("\",name=\""));
244  stream->print(relabel_name_(obj).c_str());
245  stream->print(F("\"} "));
246  stream->print(obj->state);
247  stream->print(F("\n"));
248  // Speed if available
249  if (obj->get_traits().supports_speed()) {
250  stream->print(F("esphome_fan_speed{id=\""));
251  stream->print(relabel_id_(obj).c_str());
252  add_area_label_(stream, area);
253  add_node_label_(stream, node);
254  add_friendly_name_label_(stream, friendly_name);
255  stream->print(F("\",name=\""));
256  stream->print(relabel_name_(obj).c_str());
257  stream->print(F("\"} "));
258  stream->print(obj->speed);
259  stream->print(F("\n"));
260  }
261  // Oscillation if available
262  if (obj->get_traits().supports_oscillation()) {
263  stream->print(F("esphome_fan_oscillation{id=\""));
264  stream->print(relabel_id_(obj).c_str());
265  add_area_label_(stream, area);
266  add_node_label_(stream, node);
267  add_friendly_name_label_(stream, friendly_name);
268  stream->print(F("\",name=\""));
269  stream->print(relabel_name_(obj).c_str());
270  stream->print(F("\"} "));
271  stream->print(obj->oscillating);
272  stream->print(F("\n"));
273  }
274 }
275 #endif
276 
277 #ifdef USE_LIGHT
278 void PrometheusHandler::light_type_(AsyncResponseStream *stream) {
279  stream->print(F("#TYPE esphome_light_state gauge\n"));
280  stream->print(F("#TYPE esphome_light_color gauge\n"));
281  stream->print(F("#TYPE esphome_light_effect_active gauge\n"));
282 }
283 void PrometheusHandler::light_row_(AsyncResponseStream *stream, light::LightState *obj, std::string &area,
284  std::string &node, std::string &friendly_name) {
285  if (obj->is_internal() && !this->include_internal_)
286  return;
287  // State
288  stream->print(F("esphome_light_state{id=\""));
289  stream->print(relabel_id_(obj).c_str());
290  add_area_label_(stream, area);
291  add_node_label_(stream, node);
292  add_friendly_name_label_(stream, friendly_name);
293  stream->print(F("\",name=\""));
294  stream->print(relabel_name_(obj).c_str());
295  stream->print(F("\"} "));
296  stream->print(obj->remote_values.is_on());
297  stream->print(F("\n"));
298  // Brightness and RGBW
300  float brightness, r, g, b, w;
301  color.as_brightness(&brightness);
302  color.as_rgbw(&r, &g, &b, &w);
303  stream->print(F("esphome_light_color{id=\""));
304  stream->print(relabel_id_(obj).c_str());
305  add_area_label_(stream, area);
306  add_node_label_(stream, node);
307  add_friendly_name_label_(stream, friendly_name);
308  stream->print(F("\",name=\""));
309  stream->print(relabel_name_(obj).c_str());
310  stream->print(F("\",channel=\"brightness\"} "));
311  stream->print(brightness);
312  stream->print(F("\n"));
313  stream->print(F("esphome_light_color{id=\""));
314  stream->print(relabel_id_(obj).c_str());
315  add_area_label_(stream, area);
316  add_node_label_(stream, node);
317  add_friendly_name_label_(stream, friendly_name);
318  stream->print(F("\",name=\""));
319  stream->print(relabel_name_(obj).c_str());
320  stream->print(F("\",channel=\"r\"} "));
321  stream->print(r);
322  stream->print(F("\n"));
323  stream->print(F("esphome_light_color{id=\""));
324  stream->print(relabel_id_(obj).c_str());
325  add_area_label_(stream, area);
326  add_node_label_(stream, node);
327  add_friendly_name_label_(stream, friendly_name);
328  stream->print(F("\",name=\""));
329  stream->print(relabel_name_(obj).c_str());
330  stream->print(F("\",channel=\"g\"} "));
331  stream->print(g);
332  stream->print(F("\n"));
333  stream->print(F("esphome_light_color{id=\""));
334  stream->print(relabel_id_(obj).c_str());
335  add_area_label_(stream, area);
336  add_node_label_(stream, node);
337  add_friendly_name_label_(stream, friendly_name);
338  stream->print(F("\",name=\""));
339  stream->print(relabel_name_(obj).c_str());
340  stream->print(F("\",channel=\"b\"} "));
341  stream->print(b);
342  stream->print(F("\n"));
343  stream->print(F("esphome_light_color{id=\""));
344  stream->print(relabel_id_(obj).c_str());
345  add_area_label_(stream, area);
346  add_node_label_(stream, node);
347  add_friendly_name_label_(stream, friendly_name);
348  stream->print(F("\",name=\""));
349  stream->print(relabel_name_(obj).c_str());
350  stream->print(F("\",channel=\"w\"} "));
351  stream->print(w);
352  stream->print(F("\n"));
353  // Effect
354  std::string effect = obj->get_effect_name();
355  if (effect == "None") {
356  stream->print(F("esphome_light_effect_active{id=\""));
357  stream->print(relabel_id_(obj).c_str());
358  add_area_label_(stream, area);
359  add_node_label_(stream, node);
360  add_friendly_name_label_(stream, friendly_name);
361  stream->print(F("\",name=\""));
362  stream->print(relabel_name_(obj).c_str());
363  stream->print(F("\",effect=\"None\"} 0\n"));
364  } else {
365  stream->print(F("esphome_light_effect_active{id=\""));
366  stream->print(relabel_id_(obj).c_str());
367  add_area_label_(stream, area);
368  add_node_label_(stream, node);
369  add_friendly_name_label_(stream, friendly_name);
370  stream->print(F("\",name=\""));
371  stream->print(relabel_name_(obj).c_str());
372  stream->print(F("\",effect=\""));
373  stream->print(effect.c_str());
374  stream->print(F("\"} 1\n"));
375  }
376 }
377 #endif
378 
379 #ifdef USE_COVER
380 void PrometheusHandler::cover_type_(AsyncResponseStream *stream) {
381  stream->print(F("#TYPE esphome_cover_value gauge\n"));
382  stream->print(F("#TYPE esphome_cover_failed gauge\n"));
383 }
384 void PrometheusHandler::cover_row_(AsyncResponseStream *stream, cover::Cover *obj, std::string &area, std::string &node,
385  std::string &friendly_name) {
386  if (obj->is_internal() && !this->include_internal_)
387  return;
388  if (!std::isnan(obj->position)) {
389  // We have a valid value, output this value
390  stream->print(F("esphome_cover_failed{id=\""));
391  stream->print(relabel_id_(obj).c_str());
392  add_area_label_(stream, area);
393  add_node_label_(stream, node);
394  add_friendly_name_label_(stream, friendly_name);
395  stream->print(F("\",name=\""));
396  stream->print(relabel_name_(obj).c_str());
397  stream->print(F("\"} 0\n"));
398  // Data itself
399  stream->print(F("esphome_cover_value{id=\""));
400  stream->print(relabel_id_(obj).c_str());
401  add_area_label_(stream, area);
402  add_node_label_(stream, node);
403  add_friendly_name_label_(stream, friendly_name);
404  stream->print(F("\",name=\""));
405  stream->print(relabel_name_(obj).c_str());
406  stream->print(F("\"} "));
407  stream->print(obj->position);
408  stream->print(F("\n"));
409  if (obj->get_traits().get_supports_tilt()) {
410  stream->print(F("esphome_cover_tilt{id=\""));
411  stream->print(relabel_id_(obj).c_str());
412  add_area_label_(stream, area);
413  add_node_label_(stream, node);
414  add_friendly_name_label_(stream, friendly_name);
415  stream->print(F("\",name=\""));
416  stream->print(relabel_name_(obj).c_str());
417  stream->print(F("\"} "));
418  stream->print(obj->tilt);
419  stream->print(F("\n"));
420  }
421  } else {
422  // Invalid state
423  stream->print(F("esphome_cover_failed{id=\""));
424  stream->print(relabel_id_(obj).c_str());
425  add_area_label_(stream, area);
426  add_node_label_(stream, node);
427  add_friendly_name_label_(stream, friendly_name);
428  stream->print(F("\",name=\""));
429  stream->print(relabel_name_(obj).c_str());
430  stream->print(F("\"} 1\n"));
431  }
432 }
433 #endif
434 
435 #ifdef USE_SWITCH
436 void PrometheusHandler::switch_type_(AsyncResponseStream *stream) {
437  stream->print(F("#TYPE esphome_switch_value gauge\n"));
438  stream->print(F("#TYPE esphome_switch_failed gauge\n"));
439 }
440 void PrometheusHandler::switch_row_(AsyncResponseStream *stream, switch_::Switch *obj, std::string &area,
441  std::string &node, std::string &friendly_name) {
442  if (obj->is_internal() && !this->include_internal_)
443  return;
444  stream->print(F("esphome_switch_failed{id=\""));
445  stream->print(relabel_id_(obj).c_str());
446  add_area_label_(stream, area);
447  add_node_label_(stream, node);
448  add_friendly_name_label_(stream, friendly_name);
449  stream->print(F("\",name=\""));
450  stream->print(relabel_name_(obj).c_str());
451  stream->print(F("\"} 0\n"));
452  // Data itself
453  stream->print(F("esphome_switch_value{id=\""));
454  stream->print(relabel_id_(obj).c_str());
455  add_area_label_(stream, area);
456  add_node_label_(stream, node);
457  add_friendly_name_label_(stream, friendly_name);
458  stream->print(F("\",name=\""));
459  stream->print(relabel_name_(obj).c_str());
460  stream->print(F("\"} "));
461  stream->print(obj->state);
462  stream->print(F("\n"));
463 }
464 #endif
465 
466 #ifdef USE_LOCK
467 void PrometheusHandler::lock_type_(AsyncResponseStream *stream) {
468  stream->print(F("#TYPE esphome_lock_value gauge\n"));
469  stream->print(F("#TYPE esphome_lock_failed gauge\n"));
470 }
471 void PrometheusHandler::lock_row_(AsyncResponseStream *stream, lock::Lock *obj, std::string &area, std::string &node,
472  std::string &friendly_name) {
473  if (obj->is_internal() && !this->include_internal_)
474  return;
475  stream->print(F("esphome_lock_failed{id=\""));
476  stream->print(relabel_id_(obj).c_str());
477  add_area_label_(stream, area);
478  add_node_label_(stream, node);
479  add_friendly_name_label_(stream, friendly_name);
480  stream->print(F("\",name=\""));
481  stream->print(relabel_name_(obj).c_str());
482  stream->print(F("\"} 0\n"));
483  // Data itself
484  stream->print(F("esphome_lock_value{id=\""));
485  stream->print(relabel_id_(obj).c_str());
486  add_area_label_(stream, area);
487  add_node_label_(stream, node);
488  add_friendly_name_label_(stream, friendly_name);
489  stream->print(F("\",name=\""));
490  stream->print(relabel_name_(obj).c_str());
491  stream->print(F("\"} "));
492  stream->print(obj->state);
493  stream->print(F("\n"));
494 }
495 #endif
496 
497 // Type-specific implementation
498 #ifdef USE_TEXT_SENSOR
499 void PrometheusHandler::text_sensor_type_(AsyncResponseStream *stream) {
500  stream->print(F("#TYPE esphome_text_sensor_value gauge\n"));
501  stream->print(F("#TYPE esphome_text_sensor_failed gauge\n"));
502 }
503 void PrometheusHandler::text_sensor_row_(AsyncResponseStream *stream, text_sensor::TextSensor *obj, std::string &area,
504  std::string &node, std::string &friendly_name) {
505  if (obj->is_internal() && !this->include_internal_)
506  return;
507  if (obj->has_state()) {
508  // We have a valid value, output this value
509  stream->print(F("esphome_text_sensor_failed{id=\""));
510  stream->print(relabel_id_(obj).c_str());
511  add_area_label_(stream, area);
512  add_node_label_(stream, node);
513  add_friendly_name_label_(stream, friendly_name);
514  stream->print(F("\",name=\""));
515  stream->print(relabel_name_(obj).c_str());
516  stream->print(F("\"} 0\n"));
517  // Data itself
518  stream->print(F("esphome_text_sensor_value{id=\""));
519  stream->print(relabel_id_(obj).c_str());
520  add_area_label_(stream, area);
521  add_node_label_(stream, node);
522  add_friendly_name_label_(stream, friendly_name);
523  stream->print(F("\",name=\""));
524  stream->print(relabel_name_(obj).c_str());
525  stream->print(F("\",value=\""));
526  stream->print(obj->state.c_str());
527  stream->print(F("\"} "));
528  stream->print(F("1.0"));
529  stream->print(F("\n"));
530  } else {
531  // Invalid state
532  stream->print(F("esphome_text_sensor_failed{id=\""));
533  stream->print(relabel_id_(obj).c_str());
534  add_area_label_(stream, area);
535  add_node_label_(stream, node);
536  add_friendly_name_label_(stream, friendly_name);
537  stream->print(F("\",name=\""));
538  stream->print(relabel_name_(obj).c_str());
539  stream->print(F("\"} 1\n"));
540  }
541 }
542 #endif
543 
544 // Type-specific implementation
545 #ifdef USE_NUMBER
546 void PrometheusHandler::number_type_(AsyncResponseStream *stream) {
547  stream->print(F("#TYPE esphome_number_value gauge\n"));
548  stream->print(F("#TYPE esphome_number_failed gauge\n"));
549 }
550 void PrometheusHandler::number_row_(AsyncResponseStream *stream, number::Number *obj, std::string &area,
551  std::string &node, std::string &friendly_name) {
552  if (obj->is_internal() && !this->include_internal_)
553  return;
554  if (!std::isnan(obj->state)) {
555  // We have a valid value, output this value
556  stream->print(F("esphome_number_failed{id=\""));
557  stream->print(relabel_id_(obj).c_str());
558  add_area_label_(stream, area);
559  add_node_label_(stream, node);
560  add_friendly_name_label_(stream, friendly_name);
561  stream->print(F("\",name=\""));
562  stream->print(relabel_name_(obj).c_str());
563  stream->print(F("\"} 0\n"));
564  // Data itself
565  stream->print(F("esphome_number_value{id=\""));
566  stream->print(relabel_id_(obj).c_str());
567  add_area_label_(stream, area);
568  add_node_label_(stream, node);
569  add_friendly_name_label_(stream, friendly_name);
570  stream->print(F("\",name=\""));
571  stream->print(relabel_name_(obj).c_str());
572  stream->print(F("\"} "));
573  stream->print(obj->state);
574  stream->print(F("\n"));
575  } else {
576  // Invalid state
577  stream->print(F("esphome_number_failed{id=\""));
578  stream->print(relabel_id_(obj).c_str());
579  add_area_label_(stream, area);
580  add_node_label_(stream, node);
581  add_friendly_name_label_(stream, friendly_name);
582  stream->print(F("\",name=\""));
583  stream->print(relabel_name_(obj).c_str());
584  stream->print(F("\"} 1\n"));
585  }
586 }
587 #endif
588 
589 #ifdef USE_SELECT
590 void PrometheusHandler::select_type_(AsyncResponseStream *stream) {
591  stream->print(F("#TYPE esphome_select_value gauge\n"));
592  stream->print(F("#TYPE esphome_select_failed gauge\n"));
593 }
594 void PrometheusHandler::select_row_(AsyncResponseStream *stream, select::Select *obj, std::string &area,
595  std::string &node, std::string &friendly_name) {
596  if (obj->is_internal() && !this->include_internal_)
597  return;
598  if (obj->has_state()) {
599  // We have a valid value, output this value
600  stream->print(F("esphome_select_failed{id=\""));
601  stream->print(relabel_id_(obj).c_str());
602  add_area_label_(stream, area);
603  add_node_label_(stream, node);
604  add_friendly_name_label_(stream, friendly_name);
605  stream->print(F("\",name=\""));
606  stream->print(relabel_name_(obj).c_str());
607  stream->print(F("\"} 0\n"));
608  // Data itself
609  stream->print(F("esphome_select_value{id=\""));
610  stream->print(relabel_id_(obj).c_str());
611  add_area_label_(stream, area);
612  add_node_label_(stream, node);
613  add_friendly_name_label_(stream, friendly_name);
614  stream->print(F("\",name=\""));
615  stream->print(relabel_name_(obj).c_str());
616  stream->print(F("\",value=\""));
617  stream->print(obj->state.c_str());
618  stream->print(F("\"} "));
619  stream->print(F("1.0"));
620  stream->print(F("\n"));
621  } else {
622  // Invalid state
623  stream->print(F("esphome_select_failed{id=\""));
624  stream->print(relabel_id_(obj).c_str());
625  add_area_label_(stream, area);
626  add_node_label_(stream, node);
627  add_friendly_name_label_(stream, friendly_name);
628  stream->print(F("\",name=\""));
629  stream->print(relabel_name_(obj).c_str());
630  stream->print(F("\"} 1\n"));
631  }
632 }
633 #endif
634 
635 #ifdef USE_MEDIA_PLAYER
636 void PrometheusHandler::media_player_type_(AsyncResponseStream *stream) {
637  stream->print(F("#TYPE esphome_media_player_state_value gauge\n"));
638  stream->print(F("#TYPE esphome_media_player_volume gauge\n"));
639  stream->print(F("#TYPE esphome_media_player_is_muted gauge\n"));
640  stream->print(F("#TYPE esphome_media_player_failed gauge\n"));
641 }
643  std::string &area, std::string &node, std::string &friendly_name) {
644  if (obj->is_internal() && !this->include_internal_)
645  return;
646  stream->print(F("esphome_media_player_failed{id=\""));
647  stream->print(relabel_id_(obj).c_str());
648  add_area_label_(stream, area);
649  add_node_label_(stream, node);
650  add_friendly_name_label_(stream, friendly_name);
651  stream->print(F("\",name=\""));
652  stream->print(relabel_name_(obj).c_str());
653  stream->print(F("\"} 0\n"));
654  // Data itself
655  stream->print(F("esphome_media_player_state_value{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(F("\",name=\""));
661  stream->print(relabel_name_(obj).c_str());
662  stream->print(F("\",value=\""));
664  stream->print(F("\"} "));
665  stream->print(F("1.0"));
666  stream->print(F("\n"));
667  stream->print(F("esphome_media_player_volume{id=\""));
668  stream->print(relabel_id_(obj).c_str());
669  add_area_label_(stream, area);
670  add_node_label_(stream, node);
671  add_friendly_name_label_(stream, friendly_name);
672  stream->print(F("\",name=\""));
673  stream->print(relabel_name_(obj).c_str());
674  stream->print(F("\"} "));
675  stream->print(obj->volume);
676  stream->print(F("\n"));
677  stream->print(F("esphome_media_player_is_muted{id=\""));
678  stream->print(relabel_id_(obj).c_str());
679  add_area_label_(stream, area);
680  add_node_label_(stream, node);
681  add_friendly_name_label_(stream, friendly_name);
682  stream->print(F("\",name=\""));
683  stream->print(relabel_name_(obj).c_str());
684  stream->print(F("\"} "));
685  if (obj->is_muted()) {
686  stream->print(F("1.0"));
687  } else {
688  stream->print(F("0.0"));
689  }
690  stream->print(F("\n"));
691 }
692 #endif
693 
694 #ifdef USE_UPDATE
695 void PrometheusHandler::update_entity_type_(AsyncResponseStream *stream) {
696  stream->print(F("#TYPE esphome_update_entity_state gauge\n"));
697  stream->print(F("#TYPE esphome_update_entity_info gauge\n"));
698  stream->print(F("#TYPE esphome_update_entity_failed gauge\n"));
699 }
700 
702  switch (state) {
704  stream->print("unknown");
705  break;
707  stream->print("none");
708  break;
710  stream->print("available");
711  break;
713  stream->print("installing");
714  break;
715  default:
716  stream->print("invalid");
717  break;
718  }
719 }
720 
721 void PrometheusHandler::update_entity_row_(AsyncResponseStream *stream, update::UpdateEntity *obj, std::string &area,
722  std::string &node, std::string &friendly_name) {
723  if (obj->is_internal() && !this->include_internal_)
724  return;
725  if (obj->has_state()) {
726  // We have a valid value, output this value
727  stream->print(F("esphome_update_entity_failed{id=\""));
728  stream->print(relabel_id_(obj).c_str());
729  add_area_label_(stream, area);
730  add_node_label_(stream, node);
731  add_friendly_name_label_(stream, friendly_name);
732  stream->print(F("\",name=\""));
733  stream->print(relabel_name_(obj).c_str());
734  stream->print(F("\"} 0\n"));
735  // First update state
736  stream->print(F("esphome_update_entity_state{id=\""));
737  stream->print(relabel_id_(obj).c_str());
738  add_area_label_(stream, area);
739  add_node_label_(stream, node);
740  add_friendly_name_label_(stream, friendly_name);
741  stream->print(F("\",name=\""));
742  stream->print(relabel_name_(obj).c_str());
743  stream->print(F("\",value=\""));
744  handle_update_state_(stream, obj->state);
745  stream->print(F("\"} "));
746  stream->print(F("1.0"));
747  stream->print(F("\n"));
748  // Next update info
749  stream->print(F("esphome_update_entity_info{id=\""));
750  stream->print(relabel_id_(obj).c_str());
751  add_area_label_(stream, area);
752  add_node_label_(stream, node);
753  add_friendly_name_label_(stream, friendly_name);
754  stream->print(F("\",name=\""));
755  stream->print(relabel_name_(obj).c_str());
756  stream->print(F("\",current_version=\""));
757  stream->print(obj->update_info.current_version.c_str());
758  stream->print(F("\",latest_version=\""));
759  stream->print(obj->update_info.latest_version.c_str());
760  stream->print(F("\",title=\""));
761  stream->print(obj->update_info.title.c_str());
762  stream->print(F("\"} "));
763  stream->print(F("1.0"));
764  stream->print(F("\n"));
765  } else {
766  // Invalid state
767  stream->print(F("esphome_update_entity_failed{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(F("\",name=\""));
773  stream->print(relabel_name_(obj).c_str());
774  stream->print(F("\"} 1\n"));
775  }
776 }
777 #endif
778 
779 #ifdef USE_VALVE
780 void PrometheusHandler::valve_type_(AsyncResponseStream *stream) {
781  stream->print(F("#TYPE esphome_valve_operation gauge\n"));
782  stream->print(F("#TYPE esphome_valve_failed gauge\n"));
783  stream->print(F("#TYPE esphome_valve_position gauge\n"));
784 }
785 
786 void PrometheusHandler::valve_row_(AsyncResponseStream *stream, valve::Valve *obj, std::string &area, std::string &node,
787  std::string &friendly_name) {
788  if (obj->is_internal() && !this->include_internal_)
789  return;
790  stream->print(F("esphome_valve_failed{id=\""));
791  stream->print(relabel_id_(obj).c_str());
792  add_area_label_(stream, area);
793  add_node_label_(stream, node);
794  add_friendly_name_label_(stream, friendly_name);
795  stream->print(F("\",name=\""));
796  stream->print(relabel_name_(obj).c_str());
797  stream->print(F("\"} 0\n"));
798  // Data itself
799  stream->print(F("esphome_valve_operation{id=\""));
800  stream->print(relabel_id_(obj).c_str());
801  add_area_label_(stream, area);
802  add_node_label_(stream, node);
803  add_friendly_name_label_(stream, friendly_name);
804  stream->print(F("\",name=\""));
805  stream->print(relabel_name_(obj).c_str());
806  stream->print(F("\",operation=\""));
808  stream->print(F("\"} "));
809  stream->print(F("1.0"));
810  stream->print(F("\n"));
811  // Now see if position is supported
812  if (obj->get_traits().get_supports_position()) {
813  stream->print(F("esphome_valve_position{id=\""));
814  stream->print(relabel_id_(obj).c_str());
815  add_area_label_(stream, area);
816  add_node_label_(stream, node);
817  add_friendly_name_label_(stream, friendly_name);
818  stream->print(F("\",name=\""));
819  stream->print(relabel_name_(obj).c_str());
820  stream->print(F("\"} "));
821  stream->print(obj->position);
822  stream->print(F("\n"));
823  }
824 }
825 #endif
826 
827 } // namespace prometheus
828 } // namespace esphome
829 #endif
Base class for all switches.
Definition: switch.h:39
bool state
The current on/off state of the fan.
Definition: fan.h:110
void handleRequest(AsyncWebServerRequest *req) override
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
Definition: light_state.h:63
bool oscillating
The current oscillation state of the fan.
Definition: fan.h:112
bool is_on() const
Get the binary true/false state of these light color values.
Base class for all cover devices.
Definition: cover.h:111
std::string value_accuracy_to_string(float value, int8_t accuracy_decimals)
Create a string from a value and an accuracy in decimals.
Definition: helpers.cpp:436
LightColorValues current_values
The current values of the light as outputted to the light.
Definition: light_state.h:94
void add_node_label_(AsyncResponseStream *stream, std::string &node)
std::string get_effect_name()
Return the name of the current effect, or if no effect is active "None".
LockState state
The current reported state of the lock.
Definition: lock.h:122
const std::vector< update::UpdateEntity * > & get_updates()
Definition: application.h:452
void select_type_(AsyncResponseStream *stream)
Return the type for prometheus.
const std::vector< valve::Valve * > & get_valves()
Definition: application.h:407
float position
The position of the valve from 0.0 (fully closed) to 1.0 (fully open).
Definition: valve.h:116
virtual FanTraits get_traits()=0
const UpdateState & state
Definition: update_entity.h:40
std::string relabel_id_(EntityBase *obj)
const std::string & get_area() const
Get the area of this Application set by pre_setup().
Definition: application.h:208
const std::string & get_friendly_name() const
Get the friendly name of this Application set by pre_setup().
Definition: application.h:205
const std::vector< fan::Fan * > & get_fans()
Definition: application.h:297
void text_sensor_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void update_entity_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void switch_type_(AsyncResponseStream *stream)
Return the type for prometheus.
bool supports_oscillation() const
Return if this fan supports oscillation.
Definition: fan_traits.h:16
void add_area_label_(AsyncResponseStream *stream, std::string &area)
virtual ValveTraits get_traits()=0
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.
float tilt
The current tilt value of the cover from 0.0 to 1.0.
Definition: cover.h:124
std::string get_object_id() const
Definition: entity_base.cpp:43
void valve_type_(AsyncResponseStream *stream)
Return the type for prometheus.
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.
virtual CoverTraits get_traits()=0
const std::vector< lock::Lock * > & get_locks()
Definition: application.h:397
const char * media_player_state_to_string(MediaPlayerState state)
void media_player_type_(AsyncResponseStream *stream)
Return the type for prometheus.
float state
This member variable stores the last state that has passed through all filters.
Definition: sensor.h:131
This class represents the color state for a light object.
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.
const UpdateInfo & update_info
Definition: update_entity.h:39
virtual bool has_state() const
Return whether this binary sensor has outputted a state.
void binary_sensor_type_(AsyncResponseStream *stream)
Return the type for prometheus.
const std::vector< switch_::Switch * > & get_switches()
Definition: application.h:257
Base-class for all numbers.
Definition: number.h:39
void add_friendly_name_label_(AsyncResponseStream *stream, std::string &friendly_name)
int speed
The current fan speed level.
Definition: fan.h:114
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 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.
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 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.
bool is_internal() const
Definition: entity_base.cpp:22
std::string get_unit_of_measurement()
Get the unit of measurement, using the manual override if set.
Definition: entity_base.cpp:87
const std::vector< text_sensor::TextSensor * > & get_text_sensors()
Definition: application.h:287
std::map< EntityBase *, std::string > relabel_map_name_
bool state
The current reported state of the binary sensor.
Definition: binary_sensor.h:61
const std::vector< sensor::Sensor * > & get_sensors()
Definition: application.h:277
Application App
Global storage of Application pointer - only one Application can exist.
void light_type_(AsyncResponseStream *stream)
Return the type for prometheus.
const std::vector< binary_sensor::BinarySensor * > & get_binary_sensors()
Definition: application.h:247
void handle_update_state_(AsyncResponseStream *stream, update::UpdateState state)
bool get_supports_position() const
Definition: valve_traits.h:12
const std::string & get_name() const
Get the name of this Application set by pre_setup().
Definition: application.h:202
void number_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.
const std::vector< cover::Cover * > & get_covers()
Definition: application.h:307
void lock_type_(AsyncResponseStream *stream)
Return the type for prometheus.
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.
float position
The position of the cover from 0.0 (fully closed) to 1.0 (fully open).
Definition: cover.h:122
void fan_type_(AsyncResponseStream *stream)
Return the type for prometheus.
void sensor_type_(AsyncResponseStream *stream)
Return the type for prometheus.
const std::vector< light::LightState * > & get_lights()
Definition: application.h:317
void cover_type_(AsyncResponseStream *stream)
Return the type for prometheus.
const char * valve_operation_to_str(ValveOperation op)
Definition: valve.cpp:21
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.
std::string state
Definition: select.h:33
std::string relabel_name_(EntityBase *obj)
bool get_supports_tilt() const
Definition: cover_traits.h:14
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.
const std::vector< media_player::MediaPlayer * > & get_media_players()
Definition: application.h:417
Base-class for all selects.
Definition: select.h:31
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
bool has_state() const
Return whether this select component has gotten a full state yet.
Definition: select.h:39
Base class for all valve devices.
Definition: valve.h:105
ValveOperation current_operation
The current operation of the valve (idle, opening, closing).
Definition: valve.h:110
Base class for all binary_sensor-type classes.
Definition: binary_sensor.h:37
LightColorValues remote_values
The remote color values reported to the frontend.
Definition: light_state.h:106
void as_rgbw(float *red, float *green, float *blue, float *white, float gamma=0, bool color_interlock=false) const
Convert these light color values to an RGBW representation and write them to red, green...
int8_t get_accuracy_decimals()
Get the accuracy in decimals, using the manual override if set.
Definition: sensor.cpp:25
const std::vector< select::Select * > & get_selects()
Definition: application.h:387
Base-class for all sensors.
Definition: sensor.h:57
const std::vector< number::Number * > & get_numbers()
Definition: application.h:337
void as_brightness(float *brightness, float gamma=0) const
Convert these light color values to a brightness-only representation and write them to brightness...
std::map< EntityBase *, std::string > relabel_map_id_
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.
bool state
The current reported state of the binary sensor.
Definition: switch.h:53
const StringRef & get_name() const
Definition: entity_base.cpp:10
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.
Base class for all locks.
Definition: lock.h:103
bool state
Definition: fan.h:34
bool supports_speed() const
Return if this fan supports speed modes.
Definition: fan_traits.h:20