ESPHome  2025.3.3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
api_connection.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "esphome/core/defines.h"
4 #ifdef USE_API
5 #include "api_frame_helper.h"
6 #include "api_pb2.h"
7 #include "api_pb2_service.h"
8 #include "api_server.h"
10 #include "esphome/core/component.h"
11 
12 #include <vector>
13 
14 namespace esphome {
15 namespace api {
16 
17 using send_message_t = bool(APIConnection *, void *);
18 
19 /*
20  This class holds a pointer to the source component that wants to publish a message, and a pointer to a function that
21  will lazily publish that message. The two pointers allow dedup in the deferred queue if multiple publishes for the
22  same component are backed up, and take up only 8 bytes of memory. The entry in the deferred queue (a std::vector) is
23  the DeferredMessage instance itself (not a pointer to one elsewhere in heap) so still only 8 bytes per entry. Even
24  100 backed up messages (you'd have to have at least 100 sensors publishing because of dedup) would take up only 0.8
25  kB.
26 */
28  struct DeferredMessage {
29  friend class DeferredMessageQueue;
30 
31  protected:
32  void *source_;
34 
35  public:
36  DeferredMessage(void *source, send_message_t *send_message) : source_(source), send_message_(send_message) {}
37  bool operator==(const DeferredMessage &test) const {
38  return (source_ == test.source_ && send_message_ == test.send_message_);
39  }
40  } __attribute__((packed));
41 
42  protected:
43  // vector is used very specifically for its zero memory overhead even though items are popped from the front (memory
44  // footprint is more important than speed here)
45  std::vector<DeferredMessage> deferred_queue_;
47 
48  // helper for allowing only unique entries in the queue
49  void dmq_push_back_with_dedup_(void *source, send_message_t *send_message);
50 
51  public:
52  DeferredMessageQueue(APIConnection *api_connection) : api_connection_(api_connection) {}
53  void process_queue();
54  void defer(void *source, send_message_t *send_message);
55 };
56 
58  public:
59  APIConnection(std::unique_ptr<socket::Socket> socket, APIServer *parent);
60  virtual ~APIConnection();
61 
62  void start();
63  void loop();
64 
67  return this->send_list_entities_done_response(resp);
68  }
69 #ifdef USE_BINARY_SENSOR
70  bool send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor, bool state);
71  void send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor);
72  static bool try_send_binary_sensor_state(APIConnection *api, void *v_binary_sensor);
73  static bool try_send_binary_sensor_state(APIConnection *api, binary_sensor::BinarySensor *binary_sensor, bool state);
74  static bool try_send_binary_sensor_info(APIConnection *api, void *v_binary_sensor);
75 #endif
76 #ifdef USE_COVER
77  bool send_cover_state(cover::Cover *cover);
78  void send_cover_info(cover::Cover *cover);
79  static bool try_send_cover_state(APIConnection *api, void *v_cover);
80  static bool try_send_cover_info(APIConnection *api, void *v_cover);
81  void cover_command(const CoverCommandRequest &msg) override;
82 #endif
83 #ifdef USE_FAN
84  bool send_fan_state(fan::Fan *fan);
85  void send_fan_info(fan::Fan *fan);
86  static bool try_send_fan_state(APIConnection *api, void *v_fan);
87  static bool try_send_fan_info(APIConnection *api, void *v_fan);
88  void fan_command(const FanCommandRequest &msg) override;
89 #endif
90 #ifdef USE_LIGHT
91  bool send_light_state(light::LightState *light);
92  void send_light_info(light::LightState *light);
93  static bool try_send_light_state(APIConnection *api, void *v_light);
94  static bool try_send_light_info(APIConnection *api, void *v_light);
95  void light_command(const LightCommandRequest &msg) override;
96 #endif
97 #ifdef USE_SENSOR
98  bool send_sensor_state(sensor::Sensor *sensor, float state);
99  void send_sensor_info(sensor::Sensor *sensor);
100  static bool try_send_sensor_state(APIConnection *api, void *v_sensor);
101  static bool try_send_sensor_state(APIConnection *api, sensor::Sensor *sensor, float state);
102  static bool try_send_sensor_info(APIConnection *api, void *v_sensor);
103 #endif
104 #ifdef USE_SWITCH
105  bool send_switch_state(switch_::Switch *a_switch, bool state);
106  void send_switch_info(switch_::Switch *a_switch);
107  static bool try_send_switch_state(APIConnection *api, void *v_a_switch);
108  static bool try_send_switch_state(APIConnection *api, switch_::Switch *a_switch, bool state);
109  static bool try_send_switch_info(APIConnection *api, void *v_a_switch);
110  void switch_command(const SwitchCommandRequest &msg) override;
111 #endif
112 #ifdef USE_TEXT_SENSOR
113  bool send_text_sensor_state(text_sensor::TextSensor *text_sensor, std::string state);
114  void send_text_sensor_info(text_sensor::TextSensor *text_sensor);
115  static bool try_send_text_sensor_state(APIConnection *api, void *v_text_sensor);
116  static bool try_send_text_sensor_state(APIConnection *api, text_sensor::TextSensor *text_sensor, std::string state);
117  static bool try_send_text_sensor_info(APIConnection *api, void *v_text_sensor);
118 #endif
119 #ifdef USE_ESP32_CAMERA
120  void set_camera_state(std::shared_ptr<esp32_camera::CameraImage> image);
121  void send_camera_info(esp32_camera::ESP32Camera *camera);
122  static bool try_send_camera_info(APIConnection *api, void *v_camera);
123  void camera_image(const CameraImageRequest &msg) override;
124 #endif
125 #ifdef USE_CLIMATE
126  bool send_climate_state(climate::Climate *climate);
127  void send_climate_info(climate::Climate *climate);
128  static bool try_send_climate_state(APIConnection *api, void *v_climate);
129  static bool try_send_climate_info(APIConnection *api, void *v_climate);
130  void climate_command(const ClimateCommandRequest &msg) override;
131 #endif
132 #ifdef USE_NUMBER
133  bool send_number_state(number::Number *number, float state);
134  void send_number_info(number::Number *number);
135  static bool try_send_number_state(APIConnection *api, void *v_number);
136  static bool try_send_number_state(APIConnection *api, number::Number *number, float state);
137  static bool try_send_number_info(APIConnection *api, void *v_number);
138  void number_command(const NumberCommandRequest &msg) override;
139 #endif
140 #ifdef USE_DATETIME_DATE
141  bool send_date_state(datetime::DateEntity *date);
142  void send_date_info(datetime::DateEntity *date);
143  static bool try_send_date_state(APIConnection *api, void *v_date);
144  static bool try_send_date_info(APIConnection *api, void *v_date);
145  void date_command(const DateCommandRequest &msg) override;
146 #endif
147 #ifdef USE_DATETIME_TIME
148  bool send_time_state(datetime::TimeEntity *time);
149  void send_time_info(datetime::TimeEntity *time);
150  static bool try_send_time_state(APIConnection *api, void *v_time);
151  static bool try_send_time_info(APIConnection *api, void *v_time);
152  void time_command(const TimeCommandRequest &msg) override;
153 #endif
154 #ifdef USE_DATETIME_DATETIME
155  bool send_datetime_state(datetime::DateTimeEntity *datetime);
156  void send_datetime_info(datetime::DateTimeEntity *datetime);
157  static bool try_send_datetime_state(APIConnection *api, void *v_datetime);
158  static bool try_send_datetime_info(APIConnection *api, void *v_datetime);
159  void datetime_command(const DateTimeCommandRequest &msg) override;
160 #endif
161 #ifdef USE_TEXT
162  bool send_text_state(text::Text *text, std::string state);
163  void send_text_info(text::Text *text);
164  static bool try_send_text_state(APIConnection *api, void *v_text);
165  static bool try_send_text_state(APIConnection *api, text::Text *text, std::string state);
166  static bool try_send_text_info(APIConnection *api, void *v_text);
167  void text_command(const TextCommandRequest &msg) override;
168 #endif
169 #ifdef USE_SELECT
170  bool send_select_state(select::Select *select, std::string state);
171  void send_select_info(select::Select *select);
172  static bool try_send_select_state(APIConnection *api, void *v_select);
173  static bool try_send_select_state(APIConnection *api, select::Select *select, std::string state);
174  static bool try_send_select_info(APIConnection *api, void *v_select);
175  void select_command(const SelectCommandRequest &msg) override;
176 #endif
177 #ifdef USE_BUTTON
178  void send_button_info(button::Button *button);
179  static bool try_send_button_info(APIConnection *api, void *v_button);
180  void button_command(const ButtonCommandRequest &msg) override;
181 #endif
182 #ifdef USE_LOCK
183  bool send_lock_state(lock::Lock *a_lock, lock::LockState state);
184  void send_lock_info(lock::Lock *a_lock);
185  static bool try_send_lock_state(APIConnection *api, void *v_a_lock);
186  static bool try_send_lock_state(APIConnection *api, lock::Lock *a_lock, lock::LockState state);
187  static bool try_send_lock_info(APIConnection *api, void *v_a_lock);
188  void lock_command(const LockCommandRequest &msg) override;
189 #endif
190 #ifdef USE_VALVE
191  bool send_valve_state(valve::Valve *valve);
192  void send_valve_info(valve::Valve *valve);
193  static bool try_send_valve_state(APIConnection *api, void *v_valve);
194  static bool try_send_valve_info(APIConnection *api, void *v_valve);
195  void valve_command(const ValveCommandRequest &msg) override;
196 #endif
197 #ifdef USE_MEDIA_PLAYER
198  bool send_media_player_state(media_player::MediaPlayer *media_player);
199  void send_media_player_info(media_player::MediaPlayer *media_player);
200  static bool try_send_media_player_state(APIConnection *api, void *v_media_player);
201  static bool try_send_media_player_info(APIConnection *api, void *v_media_player);
202  void media_player_command(const MediaPlayerCommandRequest &msg) override;
203 #endif
204  bool try_send_log_message(int level, const char *tag, const char *line);
206  if (!this->service_call_subscription_)
207  return;
208  this->send_homeassistant_service_response(call);
209  }
210 #ifdef USE_BLUETOOTH_PROXY
211  void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) override;
212  void unsubscribe_bluetooth_le_advertisements(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override;
213  bool send_bluetooth_le_advertisement(const BluetoothLEAdvertisementResponse &msg);
214 
215  void bluetooth_device_request(const BluetoothDeviceRequest &msg) override;
216  void bluetooth_gatt_read(const BluetoothGATTReadRequest &msg) override;
217  void bluetooth_gatt_write(const BluetoothGATTWriteRequest &msg) override;
218  void bluetooth_gatt_read_descriptor(const BluetoothGATTReadDescriptorRequest &msg) override;
219  void bluetooth_gatt_write_descriptor(const BluetoothGATTWriteDescriptorRequest &msg) override;
220  void bluetooth_gatt_get_services(const BluetoothGATTGetServicesRequest &msg) override;
221  void bluetooth_gatt_notify(const BluetoothGATTNotifyRequest &msg) override;
222  BluetoothConnectionsFreeResponse subscribe_bluetooth_connections_free(
223  const SubscribeBluetoothConnectionsFreeRequest &msg) override;
224 
225 #endif
226 #ifdef USE_HOMEASSISTANT_TIME
228  GetTimeRequest req;
229  this->send_get_time_request(req);
230  }
231 #endif
232 
233 #ifdef USE_VOICE_ASSISTANT
234  void subscribe_voice_assistant(const SubscribeVoiceAssistantRequest &msg) override;
235  void on_voice_assistant_response(const VoiceAssistantResponse &msg) override;
236  void on_voice_assistant_event_response(const VoiceAssistantEventResponse &msg) override;
237  void on_voice_assistant_audio(const VoiceAssistantAudio &msg) override;
238  void on_voice_assistant_timer_event_response(const VoiceAssistantTimerEventResponse &msg) override;
239  void on_voice_assistant_announce_request(const VoiceAssistantAnnounceRequest &msg) override;
240  VoiceAssistantConfigurationResponse voice_assistant_get_configuration(
241  const VoiceAssistantConfigurationRequest &msg) override;
242  void voice_assistant_set_configuration(const VoiceAssistantSetConfiguration &msg) override;
243 #endif
244 
245 #ifdef USE_ALARM_CONTROL_PANEL
246  bool send_alarm_control_panel_state(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
247  void send_alarm_control_panel_info(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
248  static bool try_send_alarm_control_panel_state(APIConnection *api, void *v_a_alarm_control_panel);
249  static bool try_send_alarm_control_panel_info(APIConnection *api, void *v_a_alarm_control_panel);
250  void alarm_control_panel_command(const AlarmControlPanelCommandRequest &msg) override;
251 #endif
252 
253 #ifdef USE_EVENT
254  void send_event(event::Event *event, std::string event_type);
255  void send_event_info(event::Event *event);
256  static bool try_send_event(APIConnection *api, void *v_event);
257  static bool try_send_event(APIConnection *api, event::Event *event, std::string event_type);
258  static bool try_send_event_info(APIConnection *api, void *v_event);
259 #endif
260 
261 #ifdef USE_UPDATE
262  bool send_update_state(update::UpdateEntity *update);
263  void send_update_info(update::UpdateEntity *update);
264  static bool try_send_update_state(APIConnection *api, void *v_update);
265  static bool try_send_update_info(APIConnection *api, void *v_update);
266  void update_command(const UpdateCommandRequest &msg) override;
267 #endif
268 
269  void on_disconnect_response(const DisconnectResponse &value) override;
270  void on_ping_response(const PingResponse &value) override {
271  // we initiated ping
272  this->ping_retries_ = 0;
273  this->sent_ping_ = false;
274  }
275  void on_home_assistant_state_response(const HomeAssistantStateResponse &msg) override;
276 #ifdef USE_HOMEASSISTANT_TIME
277  void on_get_time_response(const GetTimeResponse &value) override;
278 #endif
279  HelloResponse hello(const HelloRequest &msg) override;
280  ConnectResponse connect(const ConnectRequest &msg) override;
281  DisconnectResponse disconnect(const DisconnectRequest &msg) override;
282  PingResponse ping(const PingRequest &msg) override { return {}; }
283  DeviceInfoResponse device_info(const DeviceInfoRequest &msg) override;
284  void list_entities(const ListEntitiesRequest &msg) override { this->list_entities_iterator_.begin(); }
285  void subscribe_states(const SubscribeStatesRequest &msg) override {
286  this->state_subscription_ = true;
287  this->initial_state_iterator_.begin();
288  }
289  void subscribe_logs(const SubscribeLogsRequest &msg) override {
290  this->log_subscription_ = msg.level;
291  if (msg.dump_config)
293  }
295  this->service_call_subscription_ = true;
296  }
297  void subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) override;
298  GetTimeResponse get_time(const GetTimeRequest &msg) override {
299  // TODO
300  return {};
301  }
302  void execute_service(const ExecuteServiceRequest &msg) override;
303 
304  bool is_authenticated() override { return this->connection_state_ == ConnectionState::AUTHENTICATED; }
305  bool is_connection_setup() override {
306  return this->connection_state_ == ConnectionState ::CONNECTED || this->is_authenticated();
307  }
308  void on_fatal_error() override;
309  void on_unauthenticated_access() override;
310  void on_no_setup_connection() override;
312  // FIXME: ensure no recursive writes can happen
313  this->proto_write_buffer_.clear();
314  return {&this->proto_write_buffer_};
315  }
316  bool send_buffer(ProtoWriteBuffer buffer, uint32_t message_type) override;
317 
318  std::string get_client_combined_info() const { return this->client_combined_info_; }
319 
320  protected:
321  friend APIServer;
322 
323  bool send_(const void *buf, size_t len, bool force);
324 
325  enum class ConnectionState {
326  WAITING_FOR_HELLO,
327  CONNECTED,
328  AUTHENTICATED,
329  } connection_state_{ConnectionState::WAITING_FOR_HELLO};
330 
331  bool remove_{false};
332 
333  // Buffer used to encode proto messages
334  // Re-use to prevent allocations
335  std::vector<uint8_t> proto_write_buffer_;
336  std::unique_ptr<APIFrameHelper> helper_;
337 
338  std::string client_info_;
339  std::string client_peername_;
341  uint32_t client_api_version_major_{0};
342  uint32_t client_api_version_minor_{0};
343 #ifdef USE_ESP32_CAMERA
345 #endif
346 
347  bool state_subscription_{false};
348  int log_subscription_{ESPHOME_LOG_LEVEL_NONE};
349  uint32_t last_traffic_;
350  uint32_t next_ping_retry_{0};
351  uint8_t ping_retries_{0};
352  bool sent_ping_{false};
353  bool service_call_subscription_{false};
354  bool next_close_ = false;
359  int state_subs_at_ = -1;
360 };
361 
362 } // namespace api
363 } // namespace esphome
364 #endif
Base class for all switches.
Definition: switch.h:39
bool state
Definition: fan.h:34
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
Definition: light_state.h:63
void loop()
void subscribe_homeassistant_services(const SubscribeHomeassistantServicesRequest &msg) override
void dmq_push_back_with_dedup_(void *source, send_message_t *send_message)
Base class for all cover devices.
Definition: cover.h:111
void send_homeassistant_service_call(const HomeassistantServiceResponse &call)
void * source_
InitialStateIterator initial_state_iterator_
Base class for all buttons.
Definition: button.h:29
bool(APIConnection *, void *) send_message_t
class esphome::bedjet::BedjetCodec __attribute__
std::unique_ptr< APIFrameHelper > helper_
void defer(void *source, send_message_t *send_message)
std::string get_client_combined_info() const
DeferredMessageQueue deferred_message_queue_
Base-class for all text inputs.
Definition: text.h:24
std::vector< uint8_t > proto_write_buffer_
Base-class for all numbers.
Definition: number.h:39
void subscribe_states(const SubscribeStatesRequest &msg) override
Application App
Global storage of Application pointer - only one Application can exist.
send_message_t * send_message_
void on_ping_response(const PingResponse &value) override
esphome::binary_sensor::BinarySensor * binary_sensor
Definition: statsd.h:41
esp32_camera::CameraImageReader image_reader_
DeferredMessageQueue(APIConnection *api_connection)
std::string size_t len
Definition: helpers.h:301
GetTimeResponse get_time(const GetTimeRequest &msg) override
bool operator==(optional< T > const &x, optional< U > const &y)
Definition: optional.h:113
void subscribe_logs(const SubscribeLogsRequest &msg) override
Base-class for all selects.
Definition: select.h:31
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
bool is_authenticated() override
Base class for all valve devices.
Definition: valve.h:105
Base class for all binary_sensor-type classes.
Definition: binary_sensor.h:37
DeferredMessage(void *source, send_message_t *send_message)
LockState
Enum for all states a lock can be in.
Definition: lock.h:26
ListEntitiesIterator list_entities_iterator_
bool is_connection_setup() override
Base-class for all sensors.
Definition: sensor.h:57
PingResponse ping(const PingRequest &msg) override
ProtoWriteBuffer create_buffer() override
esphome::sensor::Sensor * sensor
Definition: statsd.h:38
std::vector< DeferredMessage > deferred_queue_
Base class for all locks.
Definition: lock.h:103
ClimateDevice - This is the base class for all climate integrations.
Definition: climate.h:168
void list_entities(const ListEntitiesRequest &msg) override
std::unique_ptr< Socket > socket(int domain, int type, int protocol)
Create a socket of the given domain, type and protocol.