ESPHome  2022.6.3
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 
57 // Type-specific implementation
58 #ifdef USE_SENSOR
59 void PrometheusHandler::sensor_type_(AsyncResponseStream *stream) {
60  stream->print(F("#TYPE esphome_sensor_value GAUGE\n"));
61  stream->print(F("#TYPE esphome_sensor_failed GAUGE\n"));
62 }
63 void PrometheusHandler::sensor_row_(AsyncResponseStream *stream, sensor::Sensor *obj) {
64  if (obj->is_internal() && !this->include_internal_)
65  return;
66  if (!std::isnan(obj->state)) {
67  // We have a valid value, output this value
68  stream->print(F("esphome_sensor_failed{id=\""));
69  stream->print(obj->get_object_id().c_str());
70  stream->print(F("\",name=\""));
71  stream->print(obj->get_name().c_str());
72  stream->print(F("\"} 0\n"));
73  // Data itself
74  stream->print(F("esphome_sensor_value{id=\""));
75  stream->print(obj->get_object_id().c_str());
76  stream->print(F("\",name=\""));
77  stream->print(obj->get_name().c_str());
78  stream->print(F("\",unit=\""));
79  stream->print(obj->get_unit_of_measurement().c_str());
80  stream->print(F("\"} "));
81  stream->print(value_accuracy_to_string(obj->state, obj->get_accuracy_decimals()).c_str());
82  stream->print('\n');
83  } else {
84  // Invalid state
85  stream->print(F("esphome_sensor_failed{id=\""));
86  stream->print(obj->get_object_id().c_str());
87  stream->print(F("\",name=\""));
88  stream->print(obj->get_name().c_str());
89  stream->print(F("\"} 1\n"));
90  }
91 }
92 #endif
93 
94 // Type-specific implementation
95 #ifdef USE_BINARY_SENSOR
96 void PrometheusHandler::binary_sensor_type_(AsyncResponseStream *stream) {
97  stream->print(F("#TYPE esphome_binary_sensor_value GAUGE\n"));
98  stream->print(F("#TYPE esphome_binary_sensor_failed GAUGE\n"));
99 }
101  if (obj->is_internal() && !this->include_internal_)
102  return;
103  if (obj->has_state()) {
104  // We have a valid value, output this value
105  stream->print(F("esphome_binary_sensor_failed{id=\""));
106  stream->print(obj->get_object_id().c_str());
107  stream->print(F("\",name=\""));
108  stream->print(obj->get_name().c_str());
109  stream->print(F("\"} 0\n"));
110  // Data itself
111  stream->print(F("esphome_binary_sensor_value{id=\""));
112  stream->print(obj->get_object_id().c_str());
113  stream->print(F("\",name=\""));
114  stream->print(obj->get_name().c_str());
115  stream->print(F("\"} "));
116  stream->print(obj->state);
117  stream->print('\n');
118  } else {
119  // Invalid state
120  stream->print(F("esphome_binary_sensor_failed{id=\""));
121  stream->print(obj->get_object_id().c_str());
122  stream->print(F("\",name=\""));
123  stream->print(obj->get_name().c_str());
124  stream->print(F("\"} 1\n"));
125  }
126 }
127 #endif
128 
129 #ifdef USE_FAN
130 void PrometheusHandler::fan_type_(AsyncResponseStream *stream) {
131  stream->print(F("#TYPE esphome_fan_value GAUGE\n"));
132  stream->print(F("#TYPE esphome_fan_failed GAUGE\n"));
133  stream->print(F("#TYPE esphome_fan_speed GAUGE\n"));
134  stream->print(F("#TYPE esphome_fan_oscillation GAUGE\n"));
135 }
136 void PrometheusHandler::fan_row_(AsyncResponseStream *stream, fan::Fan *obj) {
137  if (obj->is_internal() && !this->include_internal_)
138  return;
139  stream->print(F("esphome_fan_failed{id=\""));
140  stream->print(obj->get_object_id().c_str());
141  stream->print(F("\",name=\""));
142  stream->print(obj->get_name().c_str());
143  stream->print(F("\"} 0\n"));
144  // Data itself
145  stream->print(F("esphome_fan_value{id=\""));
146  stream->print(obj->get_object_id().c_str());
147  stream->print(F("\",name=\""));
148  stream->print(obj->get_name().c_str());
149  stream->print(F("\"} "));
150  stream->print(obj->state);
151  stream->print('\n');
152  // Speed if available
153  if (obj->get_traits().supports_speed()) {
154  stream->print(F("esphome_fan_speed{id=\""));
155  stream->print(obj->get_object_id().c_str());
156  stream->print(F("\",name=\""));
157  stream->print(obj->get_name().c_str());
158  stream->print(F("\"} "));
159  stream->print(obj->speed);
160  stream->print('\n');
161  }
162  // Oscillation if available
163  if (obj->get_traits().supports_oscillation()) {
164  stream->print(F("esphome_fan_oscillation{id=\""));
165  stream->print(obj->get_object_id().c_str());
166  stream->print(F("\",name=\""));
167  stream->print(obj->get_name().c_str());
168  stream->print(F("\"} "));
169  stream->print(obj->oscillating);
170  stream->print('\n');
171  }
172 }
173 #endif
174 
175 #ifdef USE_LIGHT
176 void PrometheusHandler::light_type_(AsyncResponseStream *stream) {
177  stream->print(F("#TYPE esphome_light_state GAUGE\n"));
178  stream->print(F("#TYPE esphome_light_color GAUGE\n"));
179  stream->print(F("#TYPE esphome_light_effect_active GAUGE\n"));
180 }
181 void PrometheusHandler::light_row_(AsyncResponseStream *stream, light::LightState *obj) {
182  if (obj->is_internal() && !this->include_internal_)
183  return;
184  // State
185  stream->print(F("esphome_light_state{id=\""));
186  stream->print(obj->get_object_id().c_str());
187  stream->print(F("\",name=\""));
188  stream->print(obj->get_name().c_str());
189  stream->print(F("\"} "));
190  stream->print(obj->remote_values.is_on());
191  stream->print(F("\n"));
192  // Brightness and RGBW
194  float brightness, r, g, b, w;
195  color.as_brightness(&brightness);
196  color.as_rgbw(&r, &g, &b, &w);
197  stream->print(F("esphome_light_color{id=\""));
198  stream->print(obj->get_object_id().c_str());
199  stream->print(F("\",name=\""));
200  stream->print(obj->get_name().c_str());
201  stream->print(F("\",channel=\"brightness\"} "));
202  stream->print(brightness);
203  stream->print(F("\n"));
204  stream->print(F("esphome_light_color{id=\""));
205  stream->print(obj->get_object_id().c_str());
206  stream->print(F("\",name=\""));
207  stream->print(obj->get_name().c_str());
208  stream->print(F("\",channel=\"r\"} "));
209  stream->print(r);
210  stream->print(F("\n"));
211  stream->print(F("esphome_light_color{id=\""));
212  stream->print(obj->get_object_id().c_str());
213  stream->print(F("\",name=\""));
214  stream->print(obj->get_name().c_str());
215  stream->print(F("\",channel=\"g\"} "));
216  stream->print(g);
217  stream->print(F("\n"));
218  stream->print(F("esphome_light_color{id=\""));
219  stream->print(obj->get_object_id().c_str());
220  stream->print(F("\",name=\""));
221  stream->print(obj->get_name().c_str());
222  stream->print(F("\",channel=\"b\"} "));
223  stream->print(b);
224  stream->print(F("\n"));
225  stream->print(F("esphome_light_color{id=\""));
226  stream->print(obj->get_object_id().c_str());
227  stream->print(F("\",name=\""));
228  stream->print(obj->get_name().c_str());
229  stream->print(F("\",channel=\"w\"} "));
230  stream->print(w);
231  stream->print(F("\n"));
232  // Effect
233  std::string effect = obj->get_effect_name();
234  if (effect == "None") {
235  stream->print(F("esphome_light_effect_active{id=\""));
236  stream->print(obj->get_object_id().c_str());
237  stream->print(F("\",name=\""));
238  stream->print(obj->get_name().c_str());
239  stream->print(F("\",effect=\"None\"} 0\n"));
240  } else {
241  stream->print(F("esphome_light_effect_active{id=\""));
242  stream->print(obj->get_object_id().c_str());
243  stream->print(F("\",name=\""));
244  stream->print(obj->get_name().c_str());
245  stream->print(F("\",effect=\""));
246  stream->print(effect.c_str());
247  stream->print(F("\"} 1\n"));
248  }
249 }
250 #endif
251 
252 #ifdef USE_COVER
253 void PrometheusHandler::cover_type_(AsyncResponseStream *stream) {
254  stream->print(F("#TYPE esphome_cover_value GAUGE\n"));
255  stream->print(F("#TYPE esphome_cover_failed GAUGE\n"));
256 }
257 void PrometheusHandler::cover_row_(AsyncResponseStream *stream, cover::Cover *obj) {
258  if (obj->is_internal() && !this->include_internal_)
259  return;
260  if (!std::isnan(obj->position)) {
261  // We have a valid value, output this value
262  stream->print(F("esphome_cover_failed{id=\""));
263  stream->print(obj->get_object_id().c_str());
264  stream->print(F("\",name=\""));
265  stream->print(obj->get_name().c_str());
266  stream->print(F("\"} 0\n"));
267  // Data itself
268  stream->print(F("esphome_cover_value{id=\""));
269  stream->print(obj->get_object_id().c_str());
270  stream->print(F("\",name=\""));
271  stream->print(obj->get_name().c_str());
272  stream->print(F("\"} "));
273  stream->print(obj->position);
274  stream->print('\n');
275  if (obj->get_traits().get_supports_tilt()) {
276  stream->print(F("esphome_cover_tilt{id=\""));
277  stream->print(obj->get_object_id().c_str());
278  stream->print(F("\",name=\""));
279  stream->print(obj->get_name().c_str());
280  stream->print(F("\"} "));
281  stream->print(obj->tilt);
282  stream->print('\n');
283  }
284  } else {
285  // Invalid state
286  stream->print(F("esphome_cover_failed{id=\""));
287  stream->print(obj->get_object_id().c_str());
288  stream->print(F("\",name=\""));
289  stream->print(obj->get_name().c_str());
290  stream->print(F("\"} 1\n"));
291  }
292 }
293 #endif
294 
295 #ifdef USE_SWITCH
296 void PrometheusHandler::switch_type_(AsyncResponseStream *stream) {
297  stream->print(F("#TYPE esphome_switch_value GAUGE\n"));
298  stream->print(F("#TYPE esphome_switch_failed GAUGE\n"));
299 }
300 void PrometheusHandler::switch_row_(AsyncResponseStream *stream, switch_::Switch *obj) {
301  if (obj->is_internal() && !this->include_internal_)
302  return;
303  stream->print(F("esphome_switch_failed{id=\""));
304  stream->print(obj->get_object_id().c_str());
305  stream->print(F("\",name=\""));
306  stream->print(obj->get_name().c_str());
307  stream->print(F("\"} 0\n"));
308  // Data itself
309  stream->print(F("esphome_switch_value{id=\""));
310  stream->print(obj->get_object_id().c_str());
311  stream->print(F("\",name=\""));
312  stream->print(obj->get_name().c_str());
313  stream->print(F("\"} "));
314  stream->print(obj->state);
315  stream->print('\n');
316 }
317 #endif
318 
319 #ifdef USE_LOCK
320 void PrometheusHandler::lock_type_(AsyncResponseStream *stream) {
321  stream->print(F("#TYPE esphome_lock_value GAUGE\n"));
322  stream->print(F("#TYPE esphome_lock_failed GAUGE\n"));
323 }
324 void PrometheusHandler::lock_row_(AsyncResponseStream *stream, lock::Lock *obj) {
325  if (obj->is_internal() && !this->include_internal_)
326  return;
327  stream->print(F("esphome_lock_failed{id=\""));
328  stream->print(obj->get_object_id().c_str());
329  stream->print(F("\",name=\""));
330  stream->print(obj->get_name().c_str());
331  stream->print(F("\"} 0\n"));
332  // Data itself
333  stream->print(F("esphome_lock_value{id=\""));
334  stream->print(obj->get_object_id().c_str());
335  stream->print(F("\",name=\""));
336  stream->print(obj->get_name().c_str());
337  stream->print(F("\"} "));
338  stream->print(obj->state);
339  stream->print('\n');
340 }
341 #endif
342 
343 } // namespace prometheus
344 } // namespace esphome
345 
346 #endif // USE_ARDUINO
Base class for all switches.
Definition: switch.h:33
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:32
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:250
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:66
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
const std::vector< fan::Fan * > & get_fans()
Definition: application.h:221
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:24
const std::vector< lock::Lock * > & get_locks()
Definition: application.h:275
float state
This member variable stores the last state that has passed through all filters.
Definition: sensor.h:132
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:185
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.
bool state
The current reported state of the binary sensor.
Definition: binary_sensor.h:50
const std::vector< sensor::Sensor * > & get_sensors()
Definition: application.h:203
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:176
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:230
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:239
void cover_type_(AsyncResponseStream *stream)
Return the type for prometheus.
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:26
LightColorValues remote_values
The remote color values reported to the frontend.
Definition: light_state.h:78
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:37
Base-class for all sensors.
Definition: sensor.h:47
void as_brightness(float *brightness, float gamma=0) const
Convert these light color values to a brightness-only representation and write them to brightness...
bool state
The current reported state of the binary sensor.
Definition: switch.h:48
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