ESPHome  2023.11.6
api_connection.cpp
Go to the documentation of this file.
1 #include "api_connection.h"
2 #include <cerrno>
3 #include <cinttypes>
4 #include <utility>
7 #include "esphome/core/hal.h"
8 #include "esphome/core/log.h"
9 #include "esphome/core/version.h"
10 
11 #ifdef USE_DEEP_SLEEP
13 #endif
14 #ifdef USE_HOMEASSISTANT_TIME
16 #endif
17 #ifdef USE_BLUETOOTH_PROXY
19 #endif
20 #ifdef USE_VOICE_ASSISTANT
22 #endif
23 
24 namespace esphome {
25 namespace api {
26 
27 static const char *const TAG = "api.connection";
28 static const int ESP32_CAMERA_STOP_STREAM = 5000;
29 
30 APIConnection::APIConnection(std::unique_ptr<socket::Socket> sock, APIServer *parent)
31  : parent_(parent), initial_state_iterator_(this), list_entities_iterator_(this) {
32  this->proto_write_buffer_.reserve(64);
33 
34 #if defined(USE_API_PLAINTEXT)
35  this->helper_ = std::unique_ptr<APIFrameHelper>{new APIPlaintextFrameHelper(std::move(sock))};
36 #elif defined(USE_API_NOISE)
37  this->helper_ = std::unique_ptr<APIFrameHelper>{new APINoiseFrameHelper(std::move(sock), parent->get_noise_ctx())};
38 #else
39 #error "No frame helper defined"
40 #endif
41 }
43  this->last_traffic_ = millis();
44 
45  APIError err = this->helper_->init();
46  if (err != APIError::OK) {
48  ESP_LOGW(TAG, "%s: Helper init failed: %s errno=%d", this->client_combined_info_.c_str(), api_error_to_str(err),
49  errno);
50  return;
51  }
52  this->client_info_ = helper_->getpeername();
53  this->client_peername_ = this->client_info_;
54  this->helper_->set_log_info(this->client_info_);
55 }
56 
58 #ifdef USE_BLUETOOTH_PROXY
59  if (bluetooth_proxy::global_bluetooth_proxy->get_api_connection() == this) {
61  }
62 #endif
63 #ifdef USE_VOICE_ASSISTANT
64  if (voice_assistant::global_voice_assistant->get_api_connection() == this) {
66  }
67 #endif
68 }
69 
71  if (this->remove_)
72  return;
73 
74  if (!network::is_connected()) {
75  // when network is disconnected force disconnect immediately
76  // don't wait for timeout
77  this->on_fatal_error();
78  ESP_LOGW(TAG, "%s: Network unavailable, disconnecting", this->client_combined_info_.c_str());
79  return;
80  }
81  if (this->next_close_) {
82  // requested a disconnect
83  this->helper_->close();
84  this->remove_ = true;
85  return;
86  }
87 
88  APIError err = this->helper_->loop();
89  if (err != APIError::OK) {
91  ESP_LOGW(TAG, "%s: Socket operation failed: %s errno=%d", this->client_combined_info_.c_str(),
92  api_error_to_str(err), errno);
93  return;
94  }
95  ReadPacketBuffer buffer;
96  err = this->helper_->read_packet(&buffer);
97  if (err == APIError::WOULD_BLOCK) {
98  // pass
99  } else if (err != APIError::OK) {
100  on_fatal_error();
101  if (err == APIError::SOCKET_READ_FAILED && errno == ECONNRESET) {
102  ESP_LOGW(TAG, "%s: Connection reset", this->client_combined_info_.c_str());
103  } else if (err == APIError::CONNECTION_CLOSED) {
104  ESP_LOGW(TAG, "%s: Connection closed", this->client_combined_info_.c_str());
105  } else {
106  ESP_LOGW(TAG, "%s: Reading failed: %s errno=%d", this->client_combined_info_.c_str(), api_error_to_str(err),
107  errno);
108  }
109  return;
110  } else {
111  this->last_traffic_ = millis();
112  // read a packet
113  this->read_message(buffer.data_len, buffer.type, &buffer.container[buffer.data_offset]);
114  if (this->remove_)
115  return;
116  }
117 
120 
121  const uint32_t keepalive = 60000;
122  const uint32_t now = millis();
123  if (this->sent_ping_) {
124  // Disconnect if not responded within 2.5*keepalive
125  if (now - this->last_traffic_ > (keepalive * 5) / 2) {
126  on_fatal_error();
127  ESP_LOGW(TAG, "%s didn't respond to ping request in time. Disconnecting...", this->client_combined_info_.c_str());
128  }
129  } else if (now - this->last_traffic_ > keepalive) {
130  ESP_LOGVV(TAG, "Sending keepalive PING...");
131  this->sent_ping_ = true;
133  }
134 
135 #ifdef USE_ESP32_CAMERA
136  if (this->image_reader_.available() && this->helper_->can_write_without_blocking()) {
137  uint32_t to_send = std::min((size_t) 1024, this->image_reader_.available());
138  auto buffer = this->create_buffer();
139  // fixed32 key = 1;
140  buffer.encode_fixed32(1, esp32_camera::global_esp32_camera->get_object_id_hash());
141  // bytes data = 2;
142  buffer.encode_bytes(2, this->image_reader_.peek_data_buffer(), to_send);
143  // bool done = 3;
144  bool done = this->image_reader_.available() == to_send;
145  buffer.encode_bool(3, done);
146  bool success = this->send_buffer(buffer, 44);
147 
148  if (success) {
149  this->image_reader_.consume_data(to_send);
150  }
151  if (success && done) {
152  this->image_reader_.return_image();
153  }
154  }
155 #endif
156 
157  if (state_subs_at_ != -1) {
158  const auto &subs = this->parent_->get_state_subs();
159  if (state_subs_at_ >= (int) subs.size()) {
160  state_subs_at_ = -1;
161  } else {
162  auto &it = subs[state_subs_at_];
164  resp.entity_id = it.entity_id;
165  resp.attribute = it.attribute.value();
167  state_subs_at_++;
168  }
169  }
170  }
171 }
172 
173 std::string get_default_unique_id(const std::string &component_type, EntityBase *entity) {
174  return App.get_name() + component_type + entity->get_object_id();
175 }
176 
178  // remote initiated disconnect_client
179  // don't close yet, we still need to send the disconnect response
180  // close will happen on next loop
181  ESP_LOGD(TAG, "%s requested disconnected", this->client_combined_info_.c_str());
182  this->next_close_ = true;
183  DisconnectResponse resp;
184  return resp;
185 }
187  // pass
188 }
189 
190 #ifdef USE_BINARY_SENSOR
192  if (!this->state_subscription_)
193  return false;
194 
196  resp.key = binary_sensor->get_object_id_hash();
197  resp.state = state;
198  resp.missing_state = !binary_sensor->has_state();
199  return this->send_binary_sensor_state_response(resp);
200 }
203  msg.object_id = binary_sensor->get_object_id();
204  msg.key = binary_sensor->get_object_id_hash();
205  if (binary_sensor->has_own_name())
206  msg.name = binary_sensor->get_name();
207  msg.unique_id = get_default_unique_id("binary_sensor", binary_sensor);
208  msg.device_class = binary_sensor->get_device_class();
209  msg.is_status_binary_sensor = binary_sensor->is_status_binary_sensor();
210  msg.disabled_by_default = binary_sensor->is_disabled_by_default();
211  msg.icon = binary_sensor->get_icon();
212  msg.entity_category = static_cast<enums::EntityCategory>(binary_sensor->get_entity_category());
214 }
215 #endif
216 
217 #ifdef USE_COVER
219  if (!this->state_subscription_)
220  return false;
221 
222  auto traits = cover->get_traits();
223  CoverStateResponse resp{};
224  resp.key = cover->get_object_id_hash();
225  resp.legacy_state =
227  resp.position = cover->position;
228  if (traits.get_supports_tilt())
229  resp.tilt = cover->tilt;
230  resp.current_operation = static_cast<enums::CoverOperation>(cover->current_operation);
231  return this->send_cover_state_response(resp);
232 }
234  auto traits = cover->get_traits();
236  msg.key = cover->get_object_id_hash();
237  msg.object_id = cover->get_object_id();
238  if (cover->has_own_name())
239  msg.name = cover->get_name();
240  msg.unique_id = get_default_unique_id("cover", cover);
241  msg.assumed_state = traits.get_is_assumed_state();
242  msg.supports_position = traits.get_supports_position();
243  msg.supports_tilt = traits.get_supports_tilt();
244  msg.supports_stop = traits.get_supports_stop();
245  msg.device_class = cover->get_device_class();
247  msg.icon = cover->get_icon();
248  msg.entity_category = static_cast<enums::EntityCategory>(cover->get_entity_category());
249  return this->send_list_entities_cover_response(msg);
250 }
252  cover::Cover *cover = App.get_cover_by_key(msg.key);
253  if (cover == nullptr)
254  return;
255 
256  auto call = cover->make_call();
257  if (msg.has_legacy_command) {
258  switch (msg.legacy_command) {
260  call.set_command_open();
261  break;
263  call.set_command_close();
264  break;
266  call.set_command_stop();
267  break;
268  }
269  }
270  if (msg.has_position)
271  call.set_position(msg.position);
272  if (msg.has_tilt)
273  call.set_tilt(msg.tilt);
274  if (msg.stop)
275  call.set_command_stop();
276  call.perform();
277 }
278 #endif
279 
280 #ifdef USE_FAN
282  if (!this->state_subscription_)
283  return false;
284 
285  auto traits = fan->get_traits();
286  FanStateResponse resp{};
287  resp.key = fan->get_object_id_hash();
288  resp.state = fan->state;
289  if (traits.supports_oscillation())
290  resp.oscillating = fan->oscillating;
291  if (traits.supports_speed()) {
292  resp.speed_level = fan->speed;
293  }
294  if (traits.supports_direction())
295  resp.direction = static_cast<enums::FanDirection>(fan->direction);
296  return this->send_fan_state_response(resp);
297 }
299  auto traits = fan->get_traits();
301  msg.key = fan->get_object_id_hash();
302  msg.object_id = fan->get_object_id();
303  if (fan->has_own_name())
304  msg.name = fan->get_name();
305  msg.unique_id = get_default_unique_id("fan", fan);
306  msg.supports_oscillation = traits.supports_oscillation();
307  msg.supports_speed = traits.supports_speed();
308  msg.supports_direction = traits.supports_direction();
309  msg.supported_speed_count = traits.supported_speed_count();
311  msg.icon = fan->get_icon();
312  msg.entity_category = static_cast<enums::EntityCategory>(fan->get_entity_category());
313  return this->send_list_entities_fan_response(msg);
314 }
316  fan::Fan *fan = App.get_fan_by_key(msg.key);
317  if (fan == nullptr)
318  return;
319 
320  auto call = fan->make_call();
321  if (msg.has_state)
322  call.set_state(msg.state);
323  if (msg.has_oscillating)
324  call.set_oscillating(msg.oscillating);
325  if (msg.has_speed_level) {
326  // Prefer level
327  call.set_speed(msg.speed_level);
328  }
329  if (msg.has_direction)
330  call.set_direction(static_cast<fan::FanDirection>(msg.direction));
331  call.perform();
332 }
333 #endif
334 
335 #ifdef USE_LIGHT
337  if (!this->state_subscription_)
338  return false;
339 
340  auto traits = light->get_traits();
341  auto values = light->remote_values;
342  auto color_mode = values.get_color_mode();
343  LightStateResponse resp{};
344 
345  resp.key = light->get_object_id_hash();
346  resp.state = values.is_on();
347  resp.color_mode = static_cast<enums::ColorMode>(color_mode);
348  resp.brightness = values.get_brightness();
349  resp.color_brightness = values.get_color_brightness();
350  resp.red = values.get_red();
351  resp.green = values.get_green();
352  resp.blue = values.get_blue();
353  resp.white = values.get_white();
354  resp.color_temperature = values.get_color_temperature();
355  resp.cold_white = values.get_cold_white();
356  resp.warm_white = values.get_warm_white();
357  if (light->supports_effects())
358  resp.effect = light->get_effect_name();
359  return this->send_light_state_response(resp);
360 }
362  auto traits = light->get_traits();
364  msg.key = light->get_object_id_hash();
365  msg.object_id = light->get_object_id();
366  if (light->has_own_name())
367  msg.name = light->get_name();
368  msg.unique_id = get_default_unique_id("light", light);
369 
371  msg.icon = light->get_icon();
372  msg.entity_category = static_cast<enums::EntityCategory>(light->get_entity_category());
373 
374  for (auto mode : traits.get_supported_color_modes())
375  msg.supported_color_modes.push_back(static_cast<enums::ColorMode>(mode));
376 
377  msg.legacy_supports_brightness = traits.supports_color_capability(light::ColorCapability::BRIGHTNESS);
378  msg.legacy_supports_rgb = traits.supports_color_capability(light::ColorCapability::RGB);
380  msg.legacy_supports_rgb && (traits.supports_color_capability(light::ColorCapability::WHITE) ||
381  traits.supports_color_capability(light::ColorCapability::COLD_WARM_WHITE));
382  msg.legacy_supports_color_temperature = traits.supports_color_capability(light::ColorCapability::COLOR_TEMPERATURE) ||
383  traits.supports_color_capability(light::ColorCapability::COLD_WARM_WHITE);
384 
386  msg.min_mireds = traits.get_min_mireds();
387  msg.max_mireds = traits.get_max_mireds();
388  }
389  if (light->supports_effects()) {
390  msg.effects.emplace_back("None");
391  for (auto *effect : light->get_effects())
392  msg.effects.push_back(effect->get_name());
393  }
394  return this->send_list_entities_light_response(msg);
395 }
398  if (light == nullptr)
399  return;
400 
401  auto call = light->make_call();
402  if (msg.has_state)
403  call.set_state(msg.state);
404  if (msg.has_brightness)
405  call.set_brightness(msg.brightness);
406  if (msg.has_color_mode)
407  call.set_color_mode(static_cast<light::ColorMode>(msg.color_mode));
408  if (msg.has_color_brightness)
410  if (msg.has_rgb) {
411  call.set_red(msg.red);
412  call.set_green(msg.green);
413  call.set_blue(msg.blue);
414  }
415  if (msg.has_white)
416  call.set_white(msg.white);
417  if (msg.has_color_temperature)
419  if (msg.has_cold_white)
420  call.set_cold_white(msg.cold_white);
421  if (msg.has_warm_white)
422  call.set_warm_white(msg.warm_white);
423  if (msg.has_transition_length)
425  if (msg.has_flash_length)
426  call.set_flash_length(msg.flash_length);
427  if (msg.has_effect)
428  call.set_effect(msg.effect);
429  call.perform();
430 }
431 #endif
432 
433 #ifdef USE_SENSOR
435  if (!this->state_subscription_)
436  return false;
437 
438  SensorStateResponse resp{};
439  resp.key = sensor->get_object_id_hash();
440  resp.state = state;
441  resp.missing_state = !sensor->has_state();
442  return this->send_sensor_state_response(resp);
443 }
446  msg.key = sensor->get_object_id_hash();
447  msg.object_id = sensor->get_object_id();
448  if (sensor->has_own_name())
449  msg.name = sensor->get_name();
450  msg.unique_id = sensor->unique_id();
451  if (msg.unique_id.empty())
452  msg.unique_id = get_default_unique_id("sensor", sensor);
453  msg.icon = sensor->get_icon();
456  msg.force_update = sensor->get_force_update();
457  msg.device_class = sensor->get_device_class();
458  msg.state_class = static_cast<enums::SensorStateClass>(sensor->get_state_class());
460  msg.entity_category = static_cast<enums::EntityCategory>(sensor->get_entity_category());
461  return this->send_list_entities_sensor_response(msg);
462 }
463 #endif
464 
465 #ifdef USE_SWITCH
467  if (!this->state_subscription_)
468  return false;
469 
470  SwitchStateResponse resp{};
471  resp.key = a_switch->get_object_id_hash();
472  resp.state = state;
473  return this->send_switch_state_response(resp);
474 }
477  msg.key = a_switch->get_object_id_hash();
478  msg.object_id = a_switch->get_object_id();
479  if (a_switch->has_own_name())
480  msg.name = a_switch->get_name();
481  msg.unique_id = get_default_unique_id("switch", a_switch);
482  msg.icon = a_switch->get_icon();
483  msg.assumed_state = a_switch->assumed_state();
485  msg.entity_category = static_cast<enums::EntityCategory>(a_switch->get_entity_category());
486  msg.device_class = a_switch->get_device_class();
487  return this->send_list_entities_switch_response(msg);
488 }
490  switch_::Switch *a_switch = App.get_switch_by_key(msg.key);
491  if (a_switch == nullptr)
492  return;
493 
494  if (msg.state) {
495  a_switch->turn_on();
496  } else {
497  a_switch->turn_off();
498  }
499 }
500 #endif
501 
502 #ifdef USE_TEXT_SENSOR
504  if (!this->state_subscription_)
505  return false;
506 
508  resp.key = text_sensor->get_object_id_hash();
509  resp.state = std::move(state);
510  resp.missing_state = !text_sensor->has_state();
511  return this->send_text_sensor_state_response(resp);
512 }
515  msg.key = text_sensor->get_object_id_hash();
516  msg.object_id = text_sensor->get_object_id();
517  msg.name = text_sensor->get_name();
518  msg.unique_id = text_sensor->unique_id();
519  if (msg.unique_id.empty())
520  msg.unique_id = get_default_unique_id("text_sensor", text_sensor);
521  msg.icon = text_sensor->get_icon();
522  msg.disabled_by_default = text_sensor->is_disabled_by_default();
523  msg.entity_category = static_cast<enums::EntityCategory>(text_sensor->get_entity_category());
524  return this->send_list_entities_text_sensor_response(msg);
525 }
526 #endif
527 
528 #ifdef USE_CLIMATE
530  if (!this->state_subscription_)
531  return false;
532 
533  auto traits = climate->get_traits();
534  ClimateStateResponse resp{};
535  resp.key = climate->get_object_id_hash();
536  resp.mode = static_cast<enums::ClimateMode>(climate->mode);
537  resp.action = static_cast<enums::ClimateAction>(climate->action);
538  if (traits.get_supports_current_temperature())
539  resp.current_temperature = climate->current_temperature;
540  if (traits.get_supports_two_point_target_temperature()) {
541  resp.target_temperature_low = climate->target_temperature_low;
542  resp.target_temperature_high = climate->target_temperature_high;
543  } else {
544  resp.target_temperature = climate->target_temperature;
545  }
546  if (traits.get_supports_fan_modes() && climate->fan_mode.has_value())
547  resp.fan_mode = static_cast<enums::ClimateFanMode>(climate->fan_mode.value());
548  if (!traits.get_supported_custom_fan_modes().empty() && climate->custom_fan_mode.has_value())
549  resp.custom_fan_mode = climate->custom_fan_mode.value();
550  if (traits.get_supports_presets() && climate->preset.has_value()) {
551  resp.preset = static_cast<enums::ClimatePreset>(climate->preset.value());
552  }
553  if (!traits.get_supported_custom_presets().empty() && climate->custom_preset.has_value())
554  resp.custom_preset = climate->custom_preset.value();
555  if (traits.get_supports_swing_modes())
556  resp.swing_mode = static_cast<enums::ClimateSwingMode>(climate->swing_mode);
557  return this->send_climate_state_response(resp);
558 }
560  auto traits = climate->get_traits();
562  msg.key = climate->get_object_id_hash();
563  msg.object_id = climate->get_object_id();
564  if (climate->has_own_name())
565  msg.name = climate->get_name();
566  msg.unique_id = get_default_unique_id("climate", climate);
567 
569  msg.icon = climate->get_icon();
570  msg.entity_category = static_cast<enums::EntityCategory>(climate->get_entity_category());
571 
572  msg.supports_current_temperature = traits.get_supports_current_temperature();
573  msg.supports_two_point_target_temperature = traits.get_supports_two_point_target_temperature();
574 
575  for (auto mode : traits.get_supported_modes())
576  msg.supported_modes.push_back(static_cast<enums::ClimateMode>(mode));
577 
578  msg.visual_min_temperature = traits.get_visual_min_temperature();
579  msg.visual_max_temperature = traits.get_visual_max_temperature();
580  msg.visual_target_temperature_step = traits.get_visual_target_temperature_step();
581  msg.visual_current_temperature_step = traits.get_visual_current_temperature_step();
582 
583  msg.legacy_supports_away = traits.supports_preset(climate::CLIMATE_PRESET_AWAY);
584  msg.supports_action = traits.get_supports_action();
585 
586  for (auto fan_mode : traits.get_supported_fan_modes())
587  msg.supported_fan_modes.push_back(static_cast<enums::ClimateFanMode>(fan_mode));
588  for (auto const &custom_fan_mode : traits.get_supported_custom_fan_modes())
590  for (auto preset : traits.get_supported_presets())
591  msg.supported_presets.push_back(static_cast<enums::ClimatePreset>(preset));
592  for (auto const &custom_preset : traits.get_supported_custom_presets())
594  for (auto swing_mode : traits.get_supported_swing_modes())
595  msg.supported_swing_modes.push_back(static_cast<enums::ClimateSwingMode>(swing_mode));
596  return this->send_list_entities_climate_response(msg);
597 }
599  climate::Climate *climate = App.get_climate_by_key(msg.key);
600  if (climate == nullptr)
601  return;
602 
603  auto call = climate->make_call();
604  if (msg.has_mode)
605  call.set_mode(static_cast<climate::ClimateMode>(msg.mode));
606  if (msg.has_target_temperature)
612  if (msg.has_fan_mode)
613  call.set_fan_mode(static_cast<climate::ClimateFanMode>(msg.fan_mode));
614  if (msg.has_custom_fan_mode)
615  call.set_fan_mode(msg.custom_fan_mode);
616  if (msg.has_preset)
617  call.set_preset(static_cast<climate::ClimatePreset>(msg.preset));
618  if (msg.has_custom_preset)
619  call.set_preset(msg.custom_preset);
620  if (msg.has_swing_mode)
621  call.set_swing_mode(static_cast<climate::ClimateSwingMode>(msg.swing_mode));
622  call.perform();
623 }
624 #endif
625 
626 #ifdef USE_NUMBER
628  if (!this->state_subscription_)
629  return false;
630 
631  NumberStateResponse resp{};
632  resp.key = number->get_object_id_hash();
633  resp.state = state;
634  resp.missing_state = !number->has_state();
635  return this->send_number_state_response(resp);
636 }
639  msg.key = number->get_object_id_hash();
640  msg.object_id = number->get_object_id();
641  if (number->has_own_name())
642  msg.name = number->get_name();
643  msg.unique_id = get_default_unique_id("number", number);
644  msg.icon = number->get_icon();
646  msg.entity_category = static_cast<enums::EntityCategory>(number->get_entity_category());
648  msg.mode = static_cast<enums::NumberMode>(number->traits.get_mode());
649  msg.device_class = number->traits.get_device_class();
650 
651  msg.min_value = number->traits.get_min_value();
652  msg.max_value = number->traits.get_max_value();
653  msg.step = number->traits.get_step();
654 
655  return this->send_list_entities_number_response(msg);
656 }
658  number::Number *number = App.get_number_by_key(msg.key);
659  if (number == nullptr)
660  return;
661 
662  auto call = number->make_call();
663  call.set_value(msg.state);
664  call.perform();
665 }
666 #endif
667 
668 #ifdef USE_TEXT
670  if (!this->state_subscription_)
671  return false;
672 
673  TextStateResponse resp{};
674  resp.key = text->get_object_id_hash();
675  resp.state = std::move(state);
676  resp.missing_state = !text->has_state();
677  return this->send_text_state_response(resp);
678 }
681  msg.key = text->get_object_id_hash();
682  msg.object_id = text->get_object_id();
683  msg.name = text->get_name();
684  msg.icon = text->get_icon();
686  msg.entity_category = static_cast<enums::EntityCategory>(text->get_entity_category());
687  msg.mode = static_cast<enums::TextMode>(text->traits.get_mode());
688 
689  msg.min_length = text->traits.get_min_length();
690  msg.max_length = text->traits.get_max_length();
691  msg.pattern = text->traits.get_pattern();
692 
693  return this->send_list_entities_text_response(msg);
694 }
696  text::Text *text = App.get_text_by_key(msg.key);
697  if (text == nullptr)
698  return;
699 
700  auto call = text->make_call();
701  call.set_value(msg.state);
702  call.perform();
703 }
704 #endif
705 
706 #ifdef USE_SELECT
708  if (!this->state_subscription_)
709  return false;
710 
711  SelectStateResponse resp{};
712  resp.key = select->get_object_id_hash();
713  resp.state = std::move(state);
714  resp.missing_state = !select->has_state();
715  return this->send_select_state_response(resp);
716 }
719  msg.key = select->get_object_id_hash();
720  msg.object_id = select->get_object_id();
721  if (select->has_own_name())
722  msg.name = select->get_name();
723  msg.unique_id = get_default_unique_id("select", select);
724  msg.icon = select->get_icon();
726  msg.entity_category = static_cast<enums::EntityCategory>(select->get_entity_category());
727 
728  for (const auto &option : select->traits.get_options())
729  msg.options.push_back(option);
730 
731  return this->send_list_entities_select_response(msg);
732 }
734  select::Select *select = App.get_select_by_key(msg.key);
735  if (select == nullptr)
736  return;
737 
738  auto call = select->make_call();
739  call.set_option(msg.state);
740  call.perform();
741 }
742 #endif
743 
744 #ifdef USE_BUTTON
747  msg.key = button->get_object_id_hash();
748  msg.object_id = button->get_object_id();
749  if (button->has_own_name())
750  msg.name = button->get_name();
751  msg.unique_id = get_default_unique_id("button", button);
752  msg.icon = button->get_icon();
754  msg.entity_category = static_cast<enums::EntityCategory>(button->get_entity_category());
755  msg.device_class = button->get_device_class();
756  return this->send_list_entities_button_response(msg);
757 }
759  button::Button *button = App.get_button_by_key(msg.key);
760  if (button == nullptr)
761  return;
762 
763  button->press();
764 }
765 #endif
766 
767 #ifdef USE_LOCK
769  if (!this->state_subscription_)
770  return false;
771 
772  LockStateResponse resp{};
773  resp.key = a_lock->get_object_id_hash();
774  resp.state = static_cast<enums::LockState>(state);
775  return this->send_lock_state_response(resp);
776 }
779  msg.key = a_lock->get_object_id_hash();
780  msg.object_id = a_lock->get_object_id();
781  if (a_lock->has_own_name())
782  msg.name = a_lock->get_name();
783  msg.unique_id = get_default_unique_id("lock", a_lock);
784  msg.icon = a_lock->get_icon();
785  msg.assumed_state = a_lock->traits.get_assumed_state();
787  msg.entity_category = static_cast<enums::EntityCategory>(a_lock->get_entity_category());
788  msg.supports_open = a_lock->traits.get_supports_open();
789  msg.requires_code = a_lock->traits.get_requires_code();
790  return this->send_list_entities_lock_response(msg);
791 }
793  lock::Lock *a_lock = App.get_lock_by_key(msg.key);
794  if (a_lock == nullptr)
795  return;
796 
797  switch (msg.command) {
798  case enums::LOCK_UNLOCK:
799  a_lock->unlock();
800  break;
801  case enums::LOCK_LOCK:
802  a_lock->lock();
803  break;
804  case enums::LOCK_OPEN:
805  a_lock->open();
806  break;
807  }
808 }
809 #endif
810 
811 #ifdef USE_MEDIA_PLAYER
813  if (!this->state_subscription_)
814  return false;
815 
817  resp.key = media_player->get_object_id_hash();
818  resp.state = static_cast<enums::MediaPlayerState>(media_player->state);
819  resp.volume = media_player->volume;
820  resp.muted = media_player->is_muted();
821  return this->send_media_player_state_response(resp);
822 }
825  msg.key = media_player->get_object_id_hash();
826  msg.object_id = media_player->get_object_id();
827  if (media_player->has_own_name())
828  msg.name = media_player->get_name();
829  msg.unique_id = get_default_unique_id("media_player", media_player);
830  msg.icon = media_player->get_icon();
831  msg.disabled_by_default = media_player->is_disabled_by_default();
832  msg.entity_category = static_cast<enums::EntityCategory>(media_player->get_entity_category());
833 
834  auto traits = media_player->get_traits();
835  msg.supports_pause = traits.get_supports_pause();
836 
838 }
841  if (media_player == nullptr)
842  return;
843 
844  auto call = media_player->make_call();
845  if (msg.has_command) {
846  call.set_command(static_cast<media_player::MediaPlayerCommand>(msg.command));
847  }
848  if (msg.has_volume) {
849  call.set_volume(msg.volume);
850  }
851  if (msg.has_media_url) {
852  call.set_media_url(msg.media_url);
853  }
854  call.perform();
855 }
856 #endif
857 
858 #ifdef USE_ESP32_CAMERA
859 void APIConnection::send_camera_state(std::shared_ptr<esp32_camera::CameraImage> image) {
860  if (!this->state_subscription_)
861  return;
862  if (this->image_reader_.available())
863  return;
864  if (image->was_requested_by(esphome::esp32_camera::API_REQUESTER) ||
865  image->was_requested_by(esphome::esp32_camera::IDLE))
866  this->image_reader_.set_image(std::move(image));
867 }
870  msg.key = camera->get_object_id_hash();
871  msg.object_id = camera->get_object_id();
872  if (camera->has_own_name())
873  msg.name = camera->get_name();
874  msg.unique_id = get_default_unique_id("camera", camera);
876  msg.icon = camera->get_icon();
877  msg.entity_category = static_cast<enums::EntityCategory>(camera->get_entity_category());
878  return this->send_list_entities_camera_response(msg);
879 }
881  if (esp32_camera::global_esp32_camera == nullptr)
882  return;
883 
884  if (msg.single)
886  if (msg.stream) {
888 
889  App.scheduler.set_timeout(this->parent_, "api_esp32_camera_stop_stream", ESP32_CAMERA_STOP_STREAM, []() {
891  });
892  }
893 }
894 #endif
895 
896 #ifdef USE_HOMEASSISTANT_TIME
900 }
901 #endif
902 
903 #ifdef USE_BLUETOOTH_PROXY
906 }
909 }
911  if (this->client_api_version_major_ < 1 || this->client_api_version_minor_ < 7) {
913  for (auto &service : resp.service_data) {
914  service.legacy_data.assign(service.data.begin(), service.data.end());
915  service.data.clear();
916  }
917  for (auto &manufacturer_data : resp.manufacturer_data) {
918  manufacturer_data.legacy_data.assign(manufacturer_data.data.begin(), manufacturer_data.data.end());
919  manufacturer_data.data.clear();
920  }
921  return this->send_bluetooth_le_advertisement_response(resp);
922  }
924 }
927 }
930 }
933 }
936 }
939 }
942 }
943 
946 }
947 
953  return resp;
954 }
955 #endif
956 
957 #ifdef USE_VOICE_ASSISTANT
961  }
962 }
965  if (voice_assistant::global_voice_assistant->get_api_connection() != this) {
966  return;
967  }
968 
969  if (msg.error) {
971  return;
972  }
973  struct sockaddr_storage storage;
974  socklen_t len = sizeof(storage);
975  this->helper_->getpeername((struct sockaddr *) &storage, &len);
977  }
978 };
981  if (voice_assistant::global_voice_assistant->get_api_connection() != this) {
982  return;
983  }
984 
986  }
987 }
988 
989 #endif
990 
991 #ifdef USE_ALARM_CONTROL_PANEL
993  if (!this->state_subscription_)
994  return false;
995 
997  resp.key = a_alarm_control_panel->get_object_id_hash();
998  resp.state = static_cast<enums::AlarmControlPanelState>(a_alarm_control_panel->get_state());
999  return this->send_alarm_control_panel_state_response(resp);
1000 }
1003  msg.key = a_alarm_control_panel->get_object_id_hash();
1004  msg.object_id = a_alarm_control_panel->get_object_id();
1005  msg.name = a_alarm_control_panel->get_name();
1006  msg.unique_id = get_default_unique_id("alarm_control_panel", a_alarm_control_panel);
1007  msg.icon = a_alarm_control_panel->get_icon();
1008  msg.disabled_by_default = a_alarm_control_panel->is_disabled_by_default();
1009  msg.entity_category = static_cast<enums::EntityCategory>(a_alarm_control_panel->get_entity_category());
1010  msg.supported_features = a_alarm_control_panel->get_supported_features();
1011  msg.requires_code = a_alarm_control_panel->get_requires_code();
1012  msg.requires_code_to_arm = a_alarm_control_panel->get_requires_code_to_arm();
1014 }
1017  if (a_alarm_control_panel == nullptr)
1018  return;
1019 
1020  auto call = a_alarm_control_panel->make_call();
1021  switch (msg.command) {
1023  call.disarm();
1024  break;
1026  call.arm_away();
1027  break;
1029  call.arm_home();
1030  break;
1032  call.arm_night();
1033  break;
1035  call.arm_vacation();
1036  break;
1038  call.arm_custom_bypass();
1039  break;
1041  call.pending();
1042  break;
1043  }
1044  call.set_code(msg.code);
1045  call.perform();
1046 }
1047 #endif
1048 
1049 bool APIConnection::send_log_message(int level, const char *tag, const char *line) {
1050  if (this->log_subscription_ < level)
1051  return false;
1052 
1053  // Send raw so that we don't copy too much
1054  auto buffer = this->create_buffer();
1055  // LogLevel level = 1;
1056  buffer.encode_uint32(1, static_cast<uint32_t>(level));
1057  // string message = 3;
1058  buffer.encode_string(3, line, strlen(line));
1059  // SubscribeLogsResponse - 29
1060  return this->send_buffer(buffer, 29);
1061 }
1062 
1064  this->client_info_ = msg.client_info;
1065  this->client_peername_ = this->helper_->getpeername();
1066  this->client_combined_info_ = this->client_info_ + " (" + this->client_peername_ + ")";
1067  this->helper_->set_log_info(this->client_combined_info_);
1070  ESP_LOGV(TAG, "Hello from client: '%s' | %s | API Version %" PRIu32 ".%" PRIu32, this->client_info_.c_str(),
1071  this->client_peername_.c_str(), this->client_api_version_major_, this->client_api_version_minor_);
1072 
1073  HelloResponse resp;
1074  resp.api_version_major = 1;
1075  resp.api_version_minor = 9;
1076  resp.server_info = App.get_name() + " (esphome v" ESPHOME_VERSION ")";
1077  resp.name = App.get_name();
1078 
1079  this->connection_state_ = ConnectionState::CONNECTED;
1080  return resp;
1081 }
1083  bool correct = this->parent_->check_password(msg.password);
1084 
1085  ConnectResponse resp;
1086  // bool invalid_password = 1;
1087  resp.invalid_password = !correct;
1088  if (correct) {
1089  ESP_LOGD(TAG, "%s: Connected successfully", this->client_combined_info_.c_str());
1090  this->connection_state_ = ConnectionState::AUTHENTICATED;
1092 #ifdef USE_HOMEASSISTANT_TIME
1094  this->send_time_request();
1095  }
1096 #endif
1097  }
1098  return resp;
1099 }
1101  DeviceInfoResponse resp{};
1102  resp.uses_password = this->parent_->uses_password();
1103  resp.name = App.get_name();
1104  resp.friendly_name = App.get_friendly_name();
1105  resp.suggested_area = App.get_area();
1106  resp.mac_address = get_mac_address_pretty();
1107  resp.esphome_version = ESPHOME_VERSION;
1108  resp.compilation_time = App.get_compilation_time();
1109 #if defined(USE_ESP8266) || defined(USE_ESP32)
1110  resp.manufacturer = "Espressif";
1111 #elif defined(USE_RP2040)
1112  resp.manufacturer = "Raspberry Pi";
1113 #elif defined(USE_BK72XX)
1114  resp.manufacturer = "Beken";
1115 #elif defined(USE_RTL87XX)
1116  resp.manufacturer = "Realtek";
1117 #elif defined(USE_HOST)
1118  resp.manufacturer = "Host";
1119 #endif
1120  resp.model = ESPHOME_BOARD;
1121 #ifdef USE_DEEP_SLEEP
1122  resp.has_deep_sleep = deep_sleep::global_has_deep_sleep;
1123 #endif
1124 #ifdef ESPHOME_PROJECT_NAME
1125  resp.project_name = ESPHOME_PROJECT_NAME;
1126  resp.project_version = ESPHOME_PROJECT_VERSION;
1127 #endif
1128 #ifdef USE_WEBSERVER
1129  resp.webserver_port = USE_WEBSERVER_PORT;
1130 #endif
1131 #ifdef USE_BLUETOOTH_PROXY
1132  resp.legacy_bluetooth_proxy_version = bluetooth_proxy::global_bluetooth_proxy->get_legacy_version();
1133  resp.bluetooth_proxy_feature_flags = bluetooth_proxy::global_bluetooth_proxy->get_feature_flags();
1134 #endif
1135 #ifdef USE_VOICE_ASSISTANT
1136  resp.voice_assistant_version = voice_assistant::global_voice_assistant->get_version();
1137 #endif
1138  return resp;
1139 }
1141  for (auto &it : this->parent_->get_state_subs()) {
1142  if (it.entity_id == msg.entity_id && it.attribute.value() == msg.attribute) {
1143  it.callback(msg.state);
1144  }
1145  }
1146 }
1148  bool found = false;
1149  for (auto *service : this->parent_->get_user_services()) {
1150  if (service->execute_service(msg)) {
1151  found = true;
1152  }
1153  }
1154  if (!found) {
1155  ESP_LOGV(TAG, "Could not find matching service!");
1156  }
1157 }
1159  state_subs_at_ = 0;
1160 }
1161 bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint32_t message_type) {
1162  if (this->remove_)
1163  return false;
1164  if (!this->helper_->can_write_without_blocking()) {
1165  delay(0);
1166  APIError err = this->helper_->loop();
1167  if (err != APIError::OK) {
1168  on_fatal_error();
1169  ESP_LOGW(TAG, "%s: Socket operation failed: %s errno=%d", this->client_combined_info_.c_str(),
1170  api_error_to_str(err), errno);
1171  return false;
1172  }
1173  if (!this->helper_->can_write_without_blocking()) {
1174  // SubscribeLogsResponse
1175  if (message_type != 29) {
1176  ESP_LOGV(TAG, "Cannot send message because of TCP buffer space");
1177  }
1178  delay(0);
1179  return false;
1180  }
1181  }
1182 
1183  APIError err = this->helper_->write_packet(message_type, buffer.get_buffer()->data(), buffer.get_buffer()->size());
1184  if (err == APIError::WOULD_BLOCK)
1185  return false;
1186  if (err != APIError::OK) {
1187  on_fatal_error();
1188  if (err == APIError::SOCKET_WRITE_FAILED && errno == ECONNRESET) {
1189  ESP_LOGW(TAG, "%s: Connection reset", this->client_combined_info_.c_str());
1190  } else {
1191  ESP_LOGW(TAG, "%s: Packet write failed %s errno=%d", this->client_combined_info_.c_str(), api_error_to_str(err),
1192  errno);
1193  }
1194  return false;
1195  }
1196  // Do not set last_traffic_ on send
1197  return true;
1198 }
1200  this->on_fatal_error();
1201  ESP_LOGD(TAG, "%s: tried to access without authentication.", this->client_combined_info_.c_str());
1202 }
1204  this->on_fatal_error();
1205  ESP_LOGD(TAG, "%s: tried to access without full connection.", this->client_combined_info_.c_str());
1206 }
1208  this->helper_->close();
1209  this->remove_ = true;
1210 }
1211 
1212 } // namespace api
1213 } // namespace esphome
bool get_force_update() const
Get whether force update mode is enabled.
Definition: sensor.h:78
Base class for all switches.
Definition: switch.h:39
value_type const & value() const
Definition: optional.h:89
bool send_list_entities_binary_sensor_response(const ListEntitiesBinarySensorResponse &msg)
bool state
The current on/off state of the fan.
Definition: fan.h:103
bool send_text_sensor_state(text_sensor::TextSensor *text_sensor, std::string state)
ClimateSwingMode swing_mode
The active swing mode of the climate device.
Definition: climate.h:185
bool send_alarm_control_panel_state(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel)
bool has_own_name() const
Definition: entity_base.h:23
AlarmControlPanelState get_state() const
Get the state.
enums::EntityCategory entity_category
Definition: api_pb2.h:629
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
Definition: light_state.h:34
LightCall & set_color_brightness(optional< float > brightness)
Set the color brightness of the light from 0.0 (no color) to 1.0 (fully on)
Definition: light_call.cpp:593
bool oscillating
The current oscillation state of the fan.
Definition: fan.h:105
bool has_state() const
Return whether this number has gotten a full state yet.
Definition: number.h:52
bool send_fan_state_response(const FanStateResponse &msg)
std::vector< uint8_t > * get_buffer() const
Definition: proto.h:269
void request_image(CameraRequester requester)
media_player::MediaPlayer * get_media_player_by_key(uint32_t key, bool include_internal=false)
Definition: application.h:321
bool send_text_info(text::Text *text)
bool send_climate_info(climate::Climate *climate)
MediaPlayerCall & set_command(MediaPlayerCommand command)
FanDirection direction
The current direction of the fan.
Definition: fan.h:109
Base class for all cover devices.
Definition: cover.h:111
const std::vector< UserServiceDescriptor * > & get_user_services() const
Definition: api_server.h:102
LightCall & set_red(optional< float > red)
Set the red RGB value of the light from 0.0 to 1.0.
Definition: light_call.cpp:601
void start_stream(CameraRequester requester)
enums::EntityCategory entity_category
Definition: api_pb2.h:1157
LightCall & set_color_temperature(optional< float > color_temperature)
Set the color temperature of the light in mireds for CWWW or RGBWW lights.
Definition: light_call.cpp:633
void bluetooth_gatt_notify(const BluetoothGATTNotifyRequest &msg) override
TextMode get_mode() const
Definition: text_traits.h:29
bool send_cover_info(cover::Cover *cover)
bool send_text_state_response(const TextStateResponse &msg)
enums::EntityCategory entity_category
Definition: api_pb2.h:1209
bool send_ping_request(const PingRequest &msg)
LightCall & set_cold_white(optional< float > cold_white)
Set the cold white value of the light from 0.0 to 1.0.
Definition: light_call.cpp:641
bool send_switch_state(switch_::Switch *a_switch, bool state)
float target_temperature
The target temperature of the climate device.
Definition: climate.h:172
VoiceAssistant * global_voice_assistant
std::string get_effect_name()
Return the name of the current effect, or if no effect is active "None".
climate::Climate * get_climate_by_key(uint32_t key, bool include_internal=false)
Definition: application.h:276
std::string get_device_class()
Get the device class, using the manual override if set.
Definition: entity_base.cpp:78
select::Select * get_select_by_key(uint32_t key, bool include_internal=false)
Definition: application.h:303
CoverCall make_call()
Construct a new cover call used to control the cover.
Definition: cover.cpp:149
void alarm_control_panel_command(const AlarmControlPanelCommandRequest &msg) override
void on_voice_assistant_response(const VoiceAssistantResponse &msg) override
TextTraits traits
Definition: text.h:27
BluetoothConnectionsFreeResponse subscribe_bluetooth_connections_free(const SubscribeBluetoothConnectionsFreeRequest &msg) override
std::string get_default_unique_id(const std::string &component_type, EntityBase *entity)
InitialStateIterator initial_state_iterator_
const char * api_error_to_str(APIError err)
virtual std::string unique_id()
Override this method to set the unique ID of this sensor.
Definition: text_sensor.cpp:68
TextCall & set_value(const std::string &value)
Definition: text_call.cpp:10
CoverOperation current_operation
The current operation of the cover (idle, opening, closing).
Definition: cover.h:116
std::vector< enums::ClimatePreset > supported_presets
Definition: api_pb2.h:976
Base class for all buttons.
Definition: button.h:29
enums::EntityCategory entity_category
Definition: api_pb2.h:1110
bool send_camera_info(esp32_camera::ESP32Camera *camera)
std::vector< std::string > options
Definition: api_pb2.h:1108
bool send_fan_state(fan::Fan *fan)
virtual FanTraits get_traits()=0
bool send_climate_state_response(const ClimateStateResponse &msg)
enums::EntityCategory entity_category
Definition: api_pb2.h:663
enums::EntityCategory entity_category
Definition: api_pb2.h:1794
lock::Lock * get_lock_by_key(uint32_t key, bool include_internal=false)
Definition: application.h:312
bool send_binary_sensor_state_response(const BinarySensorStateResponse &msg)
bool check_password(const std::string &password) const
Definition: api_server.cpp:148
bool supports_effects()
Return whether the light has any effects that meet the trait requirements.
bool send_climate_state(climate::Climate *climate)
ClimateMode mode
The active mode of the climate device.
Definition: climate.h:164
virtual bool get_requires_code() const =0
Returns if the alarm_control_panel has a code.
bool send_button_info(button::Button *button)
button::Button * get_button_by_key(uint32_t key, bool include_internal=false)
Definition: application.h:222
virtual bool assumed_state()
Return whether this switch uses an assumed state - i.e.
Definition: switch.cpp:58
uint32_t socklen_t
Definition: headers.h:97
bool send_list_entities_fan_response(const ListEntitiesFanResponse &msg)
DisconnectResponse disconnect(const DisconnectRequest &msg) override
virtual bool is_status_binary_sensor() const
bool send_number_state_response(const NumberStateResponse &msg)
bool send_lock_state(lock::Lock *a_lock, lock::LockState state)
bool send_text_state(text::Text *text, std::string state)
const std::string & get_area() const
Get the area of this Application set by pre_setup().
Definition: application.h:166
const std::string & get_friendly_name() const
Get the friendly name of this Application set by pre_setup().
Definition: application.h:163
std::unique_ptr< APIFrameHelper > helper_
SelectTraits traits
Definition: select.h:34
enums::ClimateSwingMode swing_mode
Definition: api_pb2.h:1033
float target_temperature_high
The maximum target temperature of the climate device, for climate devices with split target temperatu...
Definition: climate.h:177
void media_player_command(const MediaPlayerCommandRequest &msg) override
float current_temperature
The current temperature of the climate device, as reported from the integration.
Definition: climate.h:168
bool send_list_entities_select_response(const ListEntitiesSelectResponse &msg)
Color temperature can be controlled.
void client_subscription(api::APIConnection *client, bool subscribe)
HomeassistantTime * global_homeassistant_time
LightCall & set_color_mode(optional< ColorMode > color_mode)
Set the color mode of the light.
Definition: light_call.cpp:585
enums::ColorMode color_mode
Definition: api_pb2.h:584
void send_camera_state(std::shared_ptr< esp32_camera::CameraImage > image)
std::vector< BluetoothServiceData > service_data
Definition: api_pb2.h:1317
NumberCall & set_value(float value)
Definition: number_call.cpp:10
bool has_value() const
Definition: optional.h:87
void execute_service(const ExecuteServiceRequest &msg) override
std::vector< std::string > supported_custom_presets
Definition: api_pb2.h:977
int get_max_length() const
Definition: text_traits.h:21
Base-class for all text inputs.
Definition: text.h:24
TextCall make_call()
Instantiate a TextCall object to modify this text component&#39;s state.
Definition: text.h:35
void subscribe_voice_assistant(const SubscribeVoiceAssistantRequest &msg) override
LightCall & set_transition_length(optional< uint32_t > transition_length)
Set the transition length of this call in milliseconds.
Definition: light_call.cpp:561
virtual bool is_muted() const
Definition: media_player.h:80
ClimateCall & set_swing_mode(ClimateSwingMode swing_mode)
Set the swing mode of the climate device.
Definition: climate.cpp:234
AlarmControlPanelCall make_call()
Make a AlarmControlPanelCall.
bool send_number_info(number::Number *number)
void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) override
float tilt
The current tilt value of the cover from 0.0 to 1.0.
Definition: cover.h:124
bool is_connected()
Return whether the node is connected to the network (through wifi, eth, ...)
Definition: util.cpp:15
void stop_stream(CameraRequester requester)
std::string get_object_id() const
Definition: entity_base.cpp:43
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
virtual MediaPlayerTraits get_traits()=0
ClimateSwingMode swing_mode
Definition: climate.h:541
void on_no_setup_connection() override
void trigger(Ts... x)
Inform the parent automation that the event has triggered.
Definition: automation.h:95
alarm_control_panel::AlarmControlPanel * get_alarm_control_panel_by_key(uint32_t key, bool include_internal=false)
Definition: application.h:333
bool send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor)
enums::ClimateFanMode fan_mode
Definition: api_pb2.h:1031
LockTraits traits
Definition: lock.h:124
optional< std::string > custom_fan_mode
The active custom fan mode of the climate device.
Definition: climate.h:188
cover::Cover * get_cover_by_key(uint32_t key, bool include_internal=false)
Definition: application.h:258
virtual CoverTraits get_traits()=0
void bluetooth_device_request(const api::BluetoothDeviceRequest &msg)
BluetoothProxy * global_bluetooth_proxy
Device is in away preset.
Definition: climate_mode.h:88
ClimateCall & set_target_temperature_low(float target_temperature_low)
Set the low point target temperature of the climate device.
Definition: climate.cpp:257
bool send_select_info(select::Select *select)
virtual std::string unique_id()
Override this method to set the unique ID of this sensor.
Definition: sensor.cpp:88
bool send_bluetooth_le_advertisement_response(const BluetoothLEAdvertisementResponse &msg)
ClimateCall make_call()
Make a climate device control call, this is used to control the climate device, see the ClimateCall d...
Definition: climate.cpp:445
fan::Fan * get_fan_by_key(uint32_t key, bool include_internal=false)
Definition: application.h:249
void lock()
Turn this lock on.
Definition: lock.cpp:30
enums::EntityCategory entity_category
Definition: api_pb2.h:921
std::string get_icon() const
Definition: entity_base.cpp:30
std::shared_ptr< APINoiseContext > get_noise_ctx()
Definition: api_server.h:38
ClimateCall & set_target_temperature(float target_temperature)
Set the target temperature of the climate device.
Definition: climate.cpp:253
enums::ClimatePreset preset
Definition: api_pb2.h:1037
Trigger< std::string, std::string > * get_client_connected_trigger() const
Definition: api_server.h:104
bool send_list_entities_text_sensor_response(const ListEntitiesTextSensorResponse &msg)
FanCall & set_speed(int speed)
Definition: fan.h:59
bool send_sensor_state(sensor::Sensor *sensor, float state)
Brightness of cold and warm white output can be controlled.
void bluetooth_gatt_read(const api::BluetoothGATTReadRequest &msg)
void press()
Press this button.
Definition: button.cpp:9
bool send_select_state(select::Select *select, std::string state)
std::vector< std::string > get_options() const
bool send_list_entities_light_response(const ListEntitiesLightResponse &msg)
enums::EntityCategory entity_category
Definition: api_pb2.h:415
ESP32Camera * global_esp32_camera
optional< ClimatePreset > preset
The active preset of the climate device.
Definition: climate.h:191
enums::FanDirection direction
Definition: api_pb2.h:512
std::vector< std::string > effects
Definition: api_pb2.h:537
bool send_text_sensor_state_response(const TextSensorStateResponse &msg)
virtual bool has_state() const
Return whether this binary sensor has outputted a state.
uint8_t custom_preset
Definition: climate.h:539
std::vector< uint8_t > proto_write_buffer_
bool send_list_entities_cover_response(const ListEntitiesCoverResponse &msg)
bool send_log_message(int level, const char *tag, const char *line)
Base-class for all numbers.
Definition: number.h:39
Brightness of white channel can be controlled separately from other channels.
int speed
The current fan speed level.
Definition: fan.h:107
bool send_list_entities_camera_response(const ListEntitiesCameraResponse &msg)
ClimateCall & set_preset(ClimatePreset preset)
Set the preset of the climate device.
Definition: climate.cpp:196
bool has_state() const
Return whether this text input has gotten a full state yet.
Definition: text.h:32
std::vector< std::string > supported_custom_fan_modes
Definition: api_pb2.h:975
BedjetMode mode
BedJet operating mode.
Definition: bedjet_codec.h:151
enums::LockCommand command
Definition: api_pb2.h:1188
bool send_list_entities_button_response(const ListEntitiesButtonResponse &msg)
ClimateCall & set_fan_mode(ClimateFanMode fan_mode)
Set the fan mode of the climate device.
Definition: climate.cpp:154
const float COVER_OPEN
Definition: cover.cpp:9
bool send_media_player_info(media_player::MediaPlayer *media_player)
bool send_list_entities_media_player_response(const ListEntitiesMediaPlayerResponse &msg)
void bluetooth_gatt_write(const BluetoothGATTWriteRequest &msg) override
ClimateTraits get_traits()
Get the traits of this climate device with all overrides applied.
Definition: climate.cpp:418
void turn_on()
Turn this switch on.
Definition: switch.cpp:11
bool send_alarm_control_panel_info(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel)
SelectCall make_call()
Instantiate a SelectCall object to modify this select component&#39;s state.
Definition: select.h:42
std::string get_unit_of_measurement()
Get the unit of measurement, using the manual override if set.
Definition: entity_base.cpp:87
bool send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor, bool state)
void bluetooth_device_request(const BluetoothDeviceRequest &msg) override
bool send_fan_info(fan::Fan *fan)
enums::AlarmControlPanelStateCommand command
Definition: api_pb2.h:1774
FanCall & set_oscillating(bool oscillating)
Definition: fan.h:50
Application App
Global storage of Application pointer - only one Application can exist.
void bluetooth_gatt_write(const api::BluetoothGATTWriteRequest &msg)
StateClass get_state_class()
Get the state class, using the manual override if set.
Definition: sensor.cpp:33
enums::EntityCategory entity_category
Definition: api_pb2.h:1061
const std::vector< LightEffect * > & get_effects() const
Get all effects for this light state.
ColorMode get_color_mode() const
Get the color mode of these light color values.
LightCall & set_state(optional< bool > state)
Set the binary ON/OFF state of the light.
Definition: light_call.cpp:553
void on_disconnect_response(const DisconnectResponse &value) override
light::LightState * get_light_by_key(uint32_t key, bool include_internal=false)
Definition: application.h:267
void on_get_time_response(const GetTimeResponse &value) override
bool get_assumed_state() const
Definition: lock.h:44
void button_command(const ButtonCommandRequest &msg) override
void bluetooth_gatt_write_descriptor(const api::BluetoothGATTWriteDescriptorRequest &msg)
Master brightness of the light can be controlled.
void bluetooth_gatt_read_descriptor(const BluetoothGATTReadDescriptorRequest &msg) override
const std::string & get_name() const
Get the name of this Application set by pre_setup().
Definition: application.h:160
bool send_list_entities_number_response(const ListEntitiesNumberResponse &msg)
bool send_switch_state_response(const SwitchStateResponse &msg)
bool send_cover_state(cover::Cover *cover)
bool read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) override
LightCall & set_warm_white(optional< float > warm_white)
Set the warm white value of the light from 0.0 to 1.0.
Definition: light_call.cpp:649
void subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) override
switch_::Switch * get_switch_by_key(uint32_t key, bool include_internal=false)
Definition: application.h:213
bool send_list_entities_lock_response(const ListEntitiesLockResponse &msg)
void unsubscribe_api_connection(api::APIConnection *api_connection)
ClimateFanMode fan_mode
Definition: climate.h:533
bool send_buffer(ProtoWriteBuffer buffer, uint32_t message_type) override
NumberTraits traits
Definition: number.h:49
void bluetooth_gatt_write_descriptor(const BluetoothGATTWriteDescriptorRequest &msg) override
std::string client_info
Definition: api_pb2.h:220
void unsubscribe_bluetooth_le_advertisements(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override
void bluetooth_gatt_get_services(const BluetoothGATTGetServicesRequest &msg) override
bool send_list_entities_sensor_response(const ListEntitiesSensorResponse &msg)
std::vector< enums::ClimateFanMode > supported_fan_modes
Definition: api_pb2.h:973
optional< std::string > custom_preset
The active custom preset mode of the climate device.
Definition: climate.h:194
LightCall & set_effect(optional< std::string > effect)
Set the effect of the light by its name.
Definition: light_call.cpp:657
bool send_list_entities_alarm_control_panel_response(const ListEntitiesAlarmControlPanelResponse &msg)
ClimateCall & set_target_temperature_high(float target_temperature_high)
Set the high point target temperature of the climate device.
Definition: climate.cpp:261
esp32_camera::CameraImageReader image_reader_
void bluetooth_gatt_notify(const api::BluetoothGATTNotifyRequest &msg)
void set_image(std::shared_ptr< CameraImage > image)
bool send_select_state_response(const SelectStateResponse &msg)
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
Definition: climate.h:182
float position
The position of the cover from 0.0 (fully closed) to 1.0 (fully open).
Definition: cover.h:122
void switch_command(const SwitchCommandRequest &msg) override
ConnectResponse connect(const ConnectRequest &msg) override
bool send_light_info(light::LightState *light)
void start_streaming(struct sockaddr_storage *addr, uint16_t port)
EntityCategory get_entity_category() const
Definition: entity_base.cpp:39
NumberCall make_call()
Definition: number.h:45
FanCall & set_state(bool binary_state)
Definition: fan.h:41
void select_command(const SelectCommandRequest &msg) override
bool send_light_state_response(const LightStateResponse &msg)
bool send_sensor_info(sensor::Sensor *sensor)
std::string size_t len
Definition: helpers.h:292
void open()
Open (unlatch) this lock.
Definition: lock.cpp:40
DeviceInfoResponse device_info(const DeviceInfoRequest &msg) override
bool send_media_player_state_response(const MediaPlayerStateResponse &msg)
text::Text * get_text_by_key(uint32_t key, bool include_internal=false)
Definition: application.h:294
bool send_subscribe_home_assistant_state_response(const SubscribeHomeAssistantStateResponse &msg)
ClimateCall & set_mode(ClimateMode mode)
Set the mode of the climate device.
Definition: climate.cpp:130
const std::vector< HomeAssistantStateSubscription > & get_state_subs() const
Definition: api_server.cpp:314
number::Number * get_number_by_key(uint32_t key, bool include_internal=false)
Definition: application.h:285
enums::EntityCategory entity_category
Definition: api_pb2.h:474
bool send_list_entities_switch_response(const ListEntitiesSwitchResponse &msg)
FanCall make_call()
Definition: fan.cpp:86
LightCall & set_flash_length(optional< uint32_t > flash_length)
Start and set the flash length of this call in milliseconds.
Definition: light_call.cpp:569
bool get_requires_code() const
Definition: lock.h:42
LightCall & set_green(optional< float > green)
Set the green RGB value of the light from 0.0 to 1.0.
Definition: light_call.cpp:609
bool uses_password() const
Definition: api_server.cpp:147
Base-class for all selects.
Definition: select.h:31
bool send_light_state(light::LightState *light)
std::vector< enums::ColorMode > supported_color_modes
Definition: api_pb2.h:530
void set_timeout(Component *component, const std::string &name, uint32_t timeout, std::function< void()> func)
Definition: scheduler.cpp:22
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
void on_unauthenticated_access() override
bool has_state() const
Return whether this sensor has gotten a full state (that passed through all filters) yet...
Definition: sensor.cpp:97
void bluetooth_gatt_read_descriptor(const api::BluetoothGATTReadDescriptorRequest &msg)
void text_command(const TextCommandRequest &msg) override
bool has_state() const
Return whether this select component has gotten a full state yet.
Definition: select.h:39
void lock_command(const LockCommandRequest &msg) override
std::vector< BluetoothServiceData > manufacturer_data
Definition: api_pb2.h:1318
void unlock()
Turn this lock off.
Definition: lock.cpp:35
bool send_media_player_state(media_player::MediaPlayer *media_player)
bool send_sensor_state_response(const SensorStateResponse &msg)
bool send_cover_state_response(const CoverStateResponse &msg)
bool send_list_entities_text_response(const ListEntitiesTextResponse &msg)
Base class for all binary_sensor-type classes.
Definition: binary_sensor.h:37
Color can be controlled using RGB format (includes a brightness control for the color).
LightColorValues remote_values
The remote color values reported to the frontend.
Definition: light_state.h:77
LockState
Enum for all states a lock can be in.
Definition: lock.h:26
void light_command(const LightCommandRequest &msg) override
bool send_lock_info(lock::Lock *a_lock)
NumberMode get_mode() const
Definition: number_traits.h:29
bool send_alarm_control_panel_state_response(const AlarmControlPanelStateResponse &msg)
bool send_list_entities_climate_response(const ListEntitiesClimateResponse &msg)
int8_t get_accuracy_decimals()
Get the accuracy in decimals, using the manual override if set.
Definition: sensor.cpp:25
LightCall & set_white(optional< float > white)
Set the white value value of the light from 0.0 to 1.0 for RGBW[W] lights.
Definition: light_call.cpp:625
LightCall & set_brightness(optional< float > brightness)
Set the target brightness of the light from 0.0 (fully off) to 1.0 (fully on)
Definition: light_call.cpp:577
void number_command(const NumberCommandRequest &msg) override
ListEntitiesIterator list_entities_iterator_
void subscribe_api_connection(api::APIConnection *api_connection, uint32_t flags)
int get_min_length() const
Definition: text_traits.h:19
bool send_switch_info(switch_::Switch *a_switch)
bool send_text_sensor_info(text_sensor::TextSensor *text_sensor)
enums::LegacyCoverCommand legacy_command
Definition: api_pb2.h:447
Base-class for all sensors.
Definition: sensor.h:57
std::string get_mac_address_pretty()
Get the device MAC address as a string, in colon-separated uppercase hex notation.
Definition: helpers.cpp:576
bool send_lock_state_response(const LockStateResponse &msg)
void on_home_assistant_state_response(const HomeAssistantStateResponse &msg) override
virtual uint32_t get_supported_features() const =0
A numeric representation of the supported features as per HomeAssistant.
LightCall & set_blue(optional< float > blue)
Set the blue RGB value of the light from 0.0 to 1.0.
Definition: light_call.cpp:617
std::vector< enums::ClimateSwingMode > supported_swing_modes
Definition: api_pb2.h:974
void on_voice_assistant_event_response(const VoiceAssistantEventResponse &msg) override
enums::SensorStateClass state_class
Definition: api_pb2.h:626
HelloResponse hello(const HelloRequest &msg) override
std::string get_compilation_time() const
Definition: application.h:173
bool send_bluetooth_le_advertisement(const BluetoothLEAdvertisementResponse &msg)
enums::EntityCategory entity_category
Definition: api_pb2.h:540
enums::EntityCategory entity_category
Definition: api_pb2.h:980
std::vector< uint8_t > container
enums::MediaPlayerCommand command
Definition: api_pb2.h:1271
MediaPlayerCall & set_media_url(const std::string &url)
bool is_disabled_by_default() const
Definition: entity_base.cpp:26
void climate_command(const ClimateCommandRequest &msg) override
bool send_number_state(number::Number *number, float state)
APIConnection(std::unique_ptr< socket::Socket > socket, APIServer *parent)
ProtoWriteBuffer create_buffer() override
uint8_t custom_fan_mode
Definition: climate.h:534
bool get_supports_open() const
Definition: lock.h:40
uint32_t get_object_id_hash()
Definition: entity_base.cpp:76
std::string get_pattern() const
Definition: text_traits.h:25
float target_temperature_low
The minimum target temperature of the climate device, for climate devices with split target temperatu...
Definition: climate.h:175
SelectCall & set_option(const std::string &option)
Definition: select_call.cpp:10
void cover_command(const CoverCommandRequest &msg) override
void bluetooth_gatt_send_services(const api::BluetoothGATTGetServicesRequest &msg)
std::vector< enums::ClimateMode > supported_modes
Definition: api_pb2.h:967
const StringRef & get_name() const
Definition: entity_base.cpp:10
void bluetooth_gatt_read(const BluetoothGATTReadRequest &msg) override
void camera_image(const CameraImageRequest &msg) override
FanCall & set_direction(FanDirection direction)
Definition: fan.h:66
ClimatePreset preset
Definition: climate.h:538
MediaPlayerCall & set_volume(float volume)
Base class for all locks.
Definition: lock.h:103
ClimateAction action
The active state of the climate device.
Definition: climate.h:166
ClimateDevice - This is the base class for all climate integrations.
Definition: climate.h:161
void on_event(const api::VoiceAssistantEventResponse &msg)
bool state
Definition: fan.h:34
void turn_off()
Turn this switch off.
Definition: switch.cpp:15
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:26
virtual bool get_requires_code_to_arm() const =0
Returns if the alarm_control_panel requires a code to arm.
void fan_command(const FanCommandRequest &msg) override