ESPHome  2024.3.1
prometheus_handler.cpp
Go to the documentation of this file.
1 #include "prometheus_handler.h"
3 
4 namespace esphome {
5 namespace prometheus {
6 
7 void PrometheusHandler::handleRequest(AsyncWebServerRequest *req) {
8  AsyncResponseStream *stream = req->beginResponseStream("text/plain; version=0.0.4; charset=utf-8");
9 
10 #ifdef USE_SENSOR
11  this->sensor_type_(stream);
12  for (auto *obj : App.get_sensors())
13  this->sensor_row_(stream, obj);
14 #endif
15 
16 #ifdef USE_BINARY_SENSOR
17  this->binary_sensor_type_(stream);
18  for (auto *obj : App.get_binary_sensors())
19  this->binary_sensor_row_(stream, obj);
20 #endif
21 
22 #ifdef USE_FAN
23  this->fan_type_(stream);
24  for (auto *obj : App.get_fans())
25  this->fan_row_(stream, obj);
26 #endif
27 
28 #ifdef USE_LIGHT
29  this->light_type_(stream);
30  for (auto *obj : App.get_lights())
31  this->light_row_(stream, obj);
32 #endif
33 
34 #ifdef USE_COVER
35  this->cover_type_(stream);
36  for (auto *obj : App.get_covers())
37  this->cover_row_(stream, obj);
38 #endif
39 
40 #ifdef USE_SWITCH
41  this->switch_type_(stream);
42  for (auto *obj : App.get_switches())
43  this->switch_row_(stream, obj);
44 #endif
45 
46 #ifdef USE_LOCK
47  this->lock_type_(stream);
48  for (auto *obj : App.get_locks())
49  this->lock_row_(stream, obj);
50 #endif
51 
52  req->send(stream);
53 }
54 
56  auto item = relabel_map_id_.find(obj);
57  return item == relabel_map_id_.end() ? obj->get_object_id() : item->second;
58 }
59 
61  auto item = relabel_map_name_.find(obj);
62  return item == relabel_map_name_.end() ? obj->get_name() : item->second;
63 }
64 
65 // Type-specific implementation
66 #ifdef USE_SENSOR
67 void PrometheusHandler::sensor_type_(AsyncResponseStream *stream) {
68  stream->print(F("#TYPE esphome_sensor_value GAUGE\n"));
69  stream->print(F("#TYPE esphome_sensor_failed GAUGE\n"));
70 }
71 void PrometheusHandler::sensor_row_(AsyncResponseStream *stream, sensor::Sensor *obj) {
72  if (obj->is_internal() && !this->include_internal_)
73  return;
74  if (!std::isnan(obj->state)) {
75  // We have a valid value, output this value
76  stream->print(F("esphome_sensor_failed{id=\""));
77  stream->print(relabel_id_(obj).c_str());
78  stream->print(F("\",name=\""));
79  stream->print(relabel_name_(obj).c_str());
80  stream->print(F("\"} 0\n"));
81  // Data itself
82  stream->print(F("esphome_sensor_value{id=\""));
83  stream->print(relabel_id_(obj).c_str());
84  stream->print(F("\",name=\""));
85  stream->print(relabel_name_(obj).c_str());
86  stream->print(F("\",unit=\""));
87  stream->print(obj->get_unit_of_measurement().c_str());
88  stream->print(F("\"} "));
89  stream->print(value_accuracy_to_string(obj->state, obj->get_accuracy_decimals()).c_str());
90  stream->print(F("\n"));
91  } else {
92  // Invalid state
93  stream->print(F("esphome_sensor_failed{id=\""));
94  stream->print(relabel_id_(obj).c_str());
95  stream->print(F("\",name=\""));
96  stream->print(relabel_name_(obj).c_str());
97  stream->print(F("\"} 1\n"));
98  }
99 }
100 #endif
101 
102 // Type-specific implementation
103 #ifdef USE_BINARY_SENSOR
104 void PrometheusHandler::binary_sensor_type_(AsyncResponseStream *stream) {
105  stream->print(F("#TYPE esphome_binary_sensor_value GAUGE\n"));
106  stream->print(F("#TYPE esphome_binary_sensor_failed GAUGE\n"));
107 }
109  if (obj->is_internal() && !this->include_internal_)
110  return;
111  if (obj->has_state()) {
112  // We have a valid value, output this value
113  stream->print(F("esphome_binary_sensor_failed{id=\""));
114  stream->print(relabel_id_(obj).c_str());
115  stream->print(F("\",name=\""));
116  stream->print(relabel_name_(obj).c_str());
117  stream->print(F("\"} 0\n"));
118  // Data itself
119  stream->print(F("esphome_binary_sensor_value{id=\""));
120  stream->print(relabel_id_(obj).c_str());
121  stream->print(F("\",name=\""));
122  stream->print(relabel_name_(obj).c_str());
123  stream->print(F("\"} "));
124  stream->print(obj->state);
125  stream->print(F("\n"));
126  } else {
127  // Invalid state
128  stream->print(F("esphome_binary_sensor_failed{id=\""));
129  stream->print(relabel_id_(obj).c_str());
130  stream->print(F("\",name=\""));
131  stream->print(relabel_name_(obj).c_str());
132  stream->print(F("\"} 1\n"));
133  }
134 }
135 #endif
136 
137 #ifdef USE_FAN
138 void PrometheusHandler::fan_type_(AsyncResponseStream *stream) {
139  stream->print(F("#TYPE esphome_fan_value GAUGE\n"));
140  stream->print(F("#TYPE esphome_fan_failed GAUGE\n"));
141  stream->print(F("#TYPE esphome_fan_speed GAUGE\n"));
142  stream->print(F("#TYPE esphome_fan_oscillation GAUGE\n"));
143 }
144 void PrometheusHandler::fan_row_(AsyncResponseStream *stream, fan::Fan *obj) {
145  if (obj->is_internal() && !this->include_internal_)
146  return;
147  stream->print(F("esphome_fan_failed{id=\""));
148  stream->print(relabel_id_(obj).c_str());
149  stream->print(F("\",name=\""));
150  stream->print(relabel_name_(obj).c_str());
151  stream->print(F("\"} 0\n"));
152  // Data itself
153  stream->print(F("esphome_fan_value{id=\""));
154  stream->print(relabel_id_(obj).c_str());
155  stream->print(F("\",name=\""));
156  stream->print(relabel_name_(obj).c_str());
157  stream->print(F("\"} "));
158  stream->print(obj->state);
159  stream->print(F("\n"));
160  // Speed if available
161  if (obj->get_traits().supports_speed()) {
162  stream->print(F("esphome_fan_speed{id=\""));
163  stream->print(relabel_id_(obj).c_str());
164  stream->print(F("\",name=\""));
165  stream->print(relabel_name_(obj).c_str());
166  stream->print(F("\"} "));
167  stream->print(obj->speed);
168  stream->print(F("\n"));
169  }
170  // Oscillation if available
171  if (obj->get_traits().supports_oscillation()) {
172  stream->print(F("esphome_fan_oscillation{id=\""));
173  stream->print(relabel_id_(obj).c_str());
174  stream->print(F("\",name=\""));
175  stream->print(relabel_name_(obj).c_str());
176  stream->print(F("\"} "));
177  stream->print(obj->oscillating);
178  stream->print(F("\n"));
179  }
180 }
181 #endif
182 
183 #ifdef USE_LIGHT
184 void PrometheusHandler::light_type_(AsyncResponseStream *stream) {
185  stream->print(F("#TYPE esphome_light_state GAUGE\n"));
186  stream->print(F("#TYPE esphome_light_color GAUGE\n"));
187  stream->print(F("#TYPE esphome_light_effect_active GAUGE\n"));
188 }
189 void PrometheusHandler::light_row_(AsyncResponseStream *stream, light::LightState *obj) {
190  if (obj->is_internal() && !this->include_internal_)
191  return;
192  // State
193  stream->print(F("esphome_light_state{id=\""));
194  stream->print(relabel_id_(obj).c_str());
195  stream->print(F("\",name=\""));
196  stream->print(relabel_name_(obj).c_str());
197  stream->print(F("\"} "));
198  stream->print(obj->remote_values.is_on());
199  stream->print(F("\n"));
200  // Brightness and RGBW
202  float brightness, r, g, b, w;
203  color.as_brightness(&brightness);
204  color.as_rgbw(&r, &g, &b, &w);
205  stream->print(F("esphome_light_color{id=\""));
206  stream->print(relabel_id_(obj).c_str());
207  stream->print(F("\",name=\""));
208  stream->print(relabel_name_(obj).c_str());
209  stream->print(F("\",channel=\"brightness\"} "));
210  stream->print(brightness);
211  stream->print(F("\n"));
212  stream->print(F("esphome_light_color{id=\""));
213  stream->print(relabel_id_(obj).c_str());
214  stream->print(F("\",name=\""));
215  stream->print(relabel_name_(obj).c_str());
216  stream->print(F("\",channel=\"r\"} "));
217  stream->print(r);
218  stream->print(F("\n"));
219  stream->print(F("esphome_light_color{id=\""));
220  stream->print(relabel_id_(obj).c_str());
221  stream->print(F("\",name=\""));
222  stream->print(relabel_name_(obj).c_str());
223  stream->print(F("\",channel=\"g\"} "));
224  stream->print(g);
225  stream->print(F("\n"));
226  stream->print(F("esphome_light_color{id=\""));
227  stream->print(relabel_id_(obj).c_str());
228  stream->print(F("\",name=\""));
229  stream->print(relabel_name_(obj).c_str());
230  stream->print(F("\",channel=\"b\"} "));
231  stream->print(b);
232  stream->print(F("\n"));
233  stream->print(F("esphome_light_color{id=\""));
234  stream->print(relabel_id_(obj).c_str());
235  stream->print(F("\",name=\""));
236  stream->print(relabel_name_(obj).c_str());
237  stream->print(F("\",channel=\"w\"} "));
238  stream->print(w);
239  stream->print(F("\n"));
240  // Effect
241  std::string effect = obj->get_effect_name();
242  if (effect == "None") {
243  stream->print(F("esphome_light_effect_active{id=\""));
244  stream->print(relabel_id_(obj).c_str());
245  stream->print(F("\",name=\""));
246  stream->print(relabel_name_(obj).c_str());
247  stream->print(F("\",effect=\"None\"} 0\n"));
248  } else {
249  stream->print(F("esphome_light_effect_active{id=\""));
250  stream->print(relabel_id_(obj).c_str());
251  stream->print(F("\",name=\""));
252  stream->print(relabel_name_(obj).c_str());
253  stream->print(F("\",effect=\""));
254  stream->print(effect.c_str());
255  stream->print(F("\"} 1\n"));
256  }
257 }
258 #endif
259 
260 #ifdef USE_COVER
261 void PrometheusHandler::cover_type_(AsyncResponseStream *stream) {
262  stream->print(F("#TYPE esphome_cover_value GAUGE\n"));
263  stream->print(F("#TYPE esphome_cover_failed GAUGE\n"));
264 }
265 void PrometheusHandler::cover_row_(AsyncResponseStream *stream, cover::Cover *obj) {
266  if (obj->is_internal() && !this->include_internal_)
267  return;
268  if (!std::isnan(obj->position)) {
269  // We have a valid value, output this value
270  stream->print(F("esphome_cover_failed{id=\""));
271  stream->print(relabel_id_(obj).c_str());
272  stream->print(F("\",name=\""));
273  stream->print(relabel_name_(obj).c_str());
274  stream->print(F("\"} 0\n"));
275  // Data itself
276  stream->print(F("esphome_cover_value{id=\""));
277  stream->print(relabel_id_(obj).c_str());
278  stream->print(F("\",name=\""));
279  stream->print(relabel_name_(obj).c_str());
280  stream->print(F("\"} "));
281  stream->print(obj->position);
282  stream->print(F("\n"));
283  if (obj->get_traits().get_supports_tilt()) {
284  stream->print(F("esphome_cover_tilt{id=\""));
285  stream->print(relabel_id_(obj).c_str());
286  stream->print(F("\",name=\""));
287  stream->print(relabel_name_(obj).c_str());
288  stream->print(F("\"} "));
289  stream->print(obj->tilt);
290  stream->print(F("\n"));
291  }
292  } else {
293  // Invalid state
294  stream->print(F("esphome_cover_failed{id=\""));
295  stream->print(relabel_id_(obj).c_str());
296  stream->print(F("\",name=\""));
297  stream->print(relabel_name_(obj).c_str());
298  stream->print(F("\"} 1\n"));
299  }
300 }
301 #endif
302 
303 #ifdef USE_SWITCH
304 void PrometheusHandler::switch_type_(AsyncResponseStream *stream) {
305  stream->print(F("#TYPE esphome_switch_value GAUGE\n"));
306  stream->print(F("#TYPE esphome_switch_failed GAUGE\n"));
307 }
308 void PrometheusHandler::switch_row_(AsyncResponseStream *stream, switch_::Switch *obj) {
309  if (obj->is_internal() && !this->include_internal_)
310  return;
311  stream->print(F("esphome_switch_failed{id=\""));
312  stream->print(relabel_id_(obj).c_str());
313  stream->print(F("\",name=\""));
314  stream->print(relabel_name_(obj).c_str());
315  stream->print(F("\"} 0\n"));
316  // Data itself
317  stream->print(F("esphome_switch_value{id=\""));
318  stream->print(relabel_id_(obj).c_str());
319  stream->print(F("\",name=\""));
320  stream->print(relabel_name_(obj).c_str());
321  stream->print(F("\"} "));
322  stream->print(obj->state);
323  stream->print(F("\n"));
324 }
325 #endif
326 
327 #ifdef USE_LOCK
328 void PrometheusHandler::lock_type_(AsyncResponseStream *stream) {
329  stream->print(F("#TYPE esphome_lock_value GAUGE\n"));
330  stream->print(F("#TYPE esphome_lock_failed GAUGE\n"));
331 }
332 void PrometheusHandler::lock_row_(AsyncResponseStream *stream, lock::Lock *obj) {
333  if (obj->is_internal() && !this->include_internal_)
334  return;
335  stream->print(F("esphome_lock_failed{id=\""));
336  stream->print(relabel_id_(obj).c_str());
337  stream->print(F("\",name=\""));
338  stream->print(relabel_name_(obj).c_str());
339  stream->print(F("\"} 0\n"));
340  // Data itself
341  stream->print(F("esphome_lock_value{id=\""));
342  stream->print(relabel_id_(obj).c_str());
343  stream->print(F("\",name=\""));
344  stream->print(relabel_name_(obj).c_str());
345  stream->print(F("\"} "));
346  stream->print(obj->state);
347  stream->print(F("\n"));
348 }
349 #endif
350 
351 } // namespace prometheus
352 } // namespace esphome
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:34
bool oscillating
The current oscillation state of the fan.
Definition: fan.h:112
void switch_row_(AsyncResponseStream *stream, switch_::Switch *obj)
Return the switch Values state as prometheus data point.
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:412
LightColorValues current_values
The current values of the light as outputted to the light.
Definition: light_state.h:65
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
virtual FanTraits get_traits()=0
std::string relabel_id_(EntityBase *obj)
const std::vector< fan::Fan * > & get_fans()
Definition: application.h:255
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
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
virtual CoverTraits get_traits()=0
const std::vector< lock::Lock * > & get_locks()
Definition: application.h:327
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 light_row_(AsyncResponseStream *stream, light::LightState *obj)
Return the Light Values state as prometheus data point.
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:219
int speed
The current fan speed level.
Definition: fan.h:114
bool is_internal() const
Definition: entity_base.cpp:22
void sensor_row_(AsyncResponseStream *stream, sensor::Sensor *obj)
Return the sensor state as prometheus data point.
std::string get_unit_of_measurement()
Get the unit of measurement, using the manual override if set.
Definition: entity_base.cpp:87
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:237
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:210
void binary_sensor_row_(AsyncResponseStream *stream, binary_sensor::BinarySensor *obj)
Return the sensor state as prometheus data point.
const std::vector< cover::Cover * > & get_covers()
Definition: application.h:264
void lock_row_(AsyncResponseStream *stream, lock::Lock *obj)
Return the lock Values state as prometheus data point.
void lock_type_(AsyncResponseStream *stream)
Return the type for prometheus.
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:273
void cover_type_(AsyncResponseStream *stream)
Return the type for prometheus.
std::string relabel_name_(EntityBase *obj)
bool get_supports_tilt() const
Definition: cover_traits.h:14
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
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:77
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
Base-class for all sensors.
Definition: sensor.h:57
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_
bool state
The current reported state of the binary sensor.
Definition: switch.h:53
void cover_row_(AsyncResponseStream *stream, cover::Cover *obj)
Return the switch Values state as prometheus data point.
const StringRef & get_name() const
Definition: entity_base.cpp:10
Base class for all locks.
Definition: lock.h:103
void fan_row_(AsyncResponseStream *stream, fan::Fan *obj)
Return the sensor state as prometheus data point.
bool supports_speed() const
Return if this fan supports speed modes.
Definition: fan_traits.h:20