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