ESPHome 2026.1.3
Loading...
Searching...
No Matches
api_server.h
Go to the documentation of this file.
1#pragma once
2
4#ifdef USE_API
5#include "api_noise_context.h"
6#include "api_pb2.h"
7#include "api_pb2_service.h"
12#include "esphome/core/log.h"
14#include "list_entities.h"
15#include "subscribe_state.h"
16#ifdef USE_LOGGER
18#endif
19#ifdef USE_CAMERA
21#endif
22
23#include <vector>
24
25namespace esphome::api {
26
27#ifdef USE_API_USER_DEFINED_ACTIONS
28// Forward declaration - full definition in user_services.h
29class UserServiceDescriptor;
30#endif
31
32#ifdef USE_API_NOISE
35} PACKED; // NOLINT
36#endif
37
38class APIServer : public Component,
39 public Controller
40#ifdef USE_LOGGER
41 ,
43#endif
44#ifdef USE_CAMERA
45 ,
47#endif
48{
49 public:
50 APIServer();
51 void setup() override;
52 uint16_t get_port() const;
53 float get_setup_priority() const override;
54 void loop() override;
55 void dump_config() override;
56 void on_shutdown() override;
57 bool teardown() override;
58#ifdef USE_LOGGER
59 void on_log(uint8_t level, const char *tag, const char *message, size_t message_len) override;
60#endif
61#ifdef USE_CAMERA
62 void on_camera_image(const std::shared_ptr<camera::CameraImage> &image) override;
63#endif
64 void set_port(uint16_t port);
65 void set_reboot_timeout(uint32_t reboot_timeout);
66 void set_batch_delay(uint16_t batch_delay);
67 uint16_t get_batch_delay() const { return batch_delay_; }
68 void set_listen_backlog(uint8_t listen_backlog) { this->listen_backlog_ = listen_backlog; }
69 void set_max_connections(uint8_t max_connections) { this->max_connections_ = max_connections; }
70
71 // Get reference to shared buffer for API connections
72 std::vector<uint8_t> &get_shared_buffer_ref() { return shared_write_buffer_; }
73
74#ifdef USE_API_NOISE
75 bool save_noise_psk(psk_t psk, bool make_active = true);
76 bool clear_noise_psk(bool make_active = true);
77 void set_noise_psk(psk_t psk) { this->noise_ctx_.set_psk(psk); }
79#endif // USE_API_NOISE
80
82#ifdef USE_BINARY_SENSOR
84#endif
85#ifdef USE_COVER
86 void on_cover_update(cover::Cover *obj) override;
87#endif
88#ifdef USE_FAN
89 void on_fan_update(fan::Fan *obj) override;
90#endif
91#ifdef USE_LIGHT
93#endif
94#ifdef USE_SENSOR
95 void on_sensor_update(sensor::Sensor *obj) override;
96#endif
97#ifdef USE_SWITCH
98 void on_switch_update(switch_::Switch *obj) override;
99#endif
100#ifdef USE_TEXT_SENSOR
102#endif
103#ifdef USE_CLIMATE
105#endif
106#ifdef USE_NUMBER
107 void on_number_update(number::Number *obj) override;
108#endif
109#ifdef USE_DATETIME_DATE
111#endif
112#ifdef USE_DATETIME_TIME
114#endif
115#ifdef USE_DATETIME_DATETIME
117#endif
118#ifdef USE_TEXT
119 void on_text_update(text::Text *obj) override;
120#endif
121#ifdef USE_SELECT
122 void on_select_update(select::Select *obj) override;
123#endif
124#ifdef USE_LOCK
125 void on_lock_update(lock::Lock *obj) override;
126#endif
127#ifdef USE_VALVE
128 void on_valve_update(valve::Valve *obj) override;
129#endif
130#ifdef USE_MEDIA_PLAYER
132#endif
133#ifdef USE_WATER_HEATER
135#endif
136#ifdef USE_API_HOMEASSISTANT_SERVICES
138
139#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
140 // Action response handling
141 using ActionResponseCallback = std::function<void(const class ActionResponse &)>;
142 void register_action_response_callback(uint32_t call_id, ActionResponseCallback callback);
143 void handle_action_response(uint32_t call_id, bool success, StringRef error_message);
144#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
145 void handle_action_response(uint32_t call_id, bool success, StringRef error_message, const uint8_t *response_data,
146 size_t response_data_len);
147#endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
148#endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES
149#endif // USE_API_HOMEASSISTANT_SERVICES
150#ifdef USE_API_USER_DEFINED_ACTIONS
151 void initialize_user_services(std::initializer_list<UserServiceDescriptor *> services) {
152 this->user_services_.assign(services);
153 }
154#ifdef USE_API_CUSTOM_SERVICES
155 // Only compile push_back method when custom_services: true (external components)
156 void register_user_service(UserServiceDescriptor *descriptor) { this->user_services_.push_back(descriptor); }
157#endif
158#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
159 // Action call context management - supports concurrent calls from multiple clients
160 // Returns server-generated action_call_id to avoid collisions when clients use same call_id
161 uint32_t register_active_action_call(uint32_t client_call_id, APIConnection *conn);
162 void unregister_active_action_call(uint32_t action_call_id);
164 // Send response for a specific action call (uses action_call_id, sends client_call_id in response)
165 void send_action_response(uint32_t action_call_id, bool success, StringRef error_message);
166#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
167 void send_action_response(uint32_t action_call_id, bool success, StringRef error_message,
168 const uint8_t *response_data, size_t response_data_len);
169#endif // USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
170#endif // USE_API_USER_DEFINED_ACTION_RESPONSES
171#endif
172#ifdef USE_HOMEASSISTANT_TIME
173 void request_time();
174#endif
175
176#ifdef USE_ALARM_CONTROL_PANEL
178#endif
179#ifdef USE_EVENT
180 void on_event(event::Event *obj) override;
181#endif
182#ifdef USE_UPDATE
183 void on_update(update::UpdateEntity *obj) override;
184#endif
185#ifdef USE_ZWAVE_PROXY
187#endif
188#ifdef USE_IR_RF
189 void send_infrared_rf_receive_event(uint32_t device_id, uint32_t key, const std::vector<int32_t> *timings);
190#endif
191
192 bool is_connected(bool state_subscription_only = false) const;
193
194#ifdef USE_API_HOMEASSISTANT_STATES
196 const char *entity_id; // Pointer to flash (internal) or heap (external)
197 const char *attribute; // Pointer to flash or nullptr (nullptr means no attribute)
198 std::function<void(StringRef)> callback;
199 bool once;
200
201 // Dynamic storage for external components using std::string API (custom_api_device.h)
202 // These are only allocated when using the std::string overload (nullptr for const char* overload)
203 std::unique_ptr<std::string> entity_id_dynamic_storage;
204 std::unique_ptr<std::string> attribute_dynamic_storage;
205 };
206
207 // New const char* overload (for internal components - zero allocation)
208 void subscribe_home_assistant_state(const char *entity_id, const char *attribute, std::function<void(StringRef)> f);
209 void get_home_assistant_state(const char *entity_id, const char *attribute, std::function<void(StringRef)> f);
210
211 // std::string overload with StringRef callback (for custom_api_device.h with zero-allocation callback)
212 void subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
213 std::function<void(StringRef)> f);
214 void get_home_assistant_state(std::string entity_id, optional<std::string> attribute,
215 std::function<void(StringRef)> f);
216
217 // Legacy std::string overload (for custom_api_device.h - converts StringRef to std::string for callback)
218 void subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
219 std::function<void(const std::string &)> f);
220 void get_home_assistant_state(std::string entity_id, optional<std::string> attribute,
221 std::function<void(const std::string &)> f);
222
223 const std::vector<HomeAssistantStateSubscription> &get_state_subs() const;
224#endif
225#ifdef USE_API_USER_DEFINED_ACTIONS
226 const std::vector<UserServiceDescriptor *> &get_user_services() const { return this->user_services_; }
227#endif
228
229#ifdef USE_API_CLIENT_CONNECTED_TRIGGER
231#endif
232#ifdef USE_API_CLIENT_DISCONNECTED_TRIGGER
236#endif
237
238 protected:
239#ifdef USE_API_NOISE
240 bool update_noise_psk_(const SavedNoisePsk &new_psk, const LogString *save_log_msg, const LogString *fail_log_msg,
241 const psk_t &active_psk, bool make_active);
242#endif // USE_API_NOISE
243#ifdef USE_API_HOMEASSISTANT_STATES
244 // Helper methods to reduce code duplication
245 void add_state_subscription_(const char *entity_id, const char *attribute, std::function<void(StringRef)> f,
246 bool once);
247 void add_state_subscription_(std::string entity_id, optional<std::string> attribute, std::function<void(StringRef)> f,
248 bool once);
249 // Legacy helper: wraps std::string callback and delegates to StringRef version
250 void add_state_subscription_(std::string entity_id, optional<std::string> attribute,
251 std::function<void(const std::string &)> f, bool once);
252#endif // USE_API_HOMEASSISTANT_STATES
253 // Pointers and pointer-like types first (4 bytes each)
254 std::unique_ptr<socket::Socket> socket_ = nullptr;
255#ifdef USE_API_CLIENT_CONNECTED_TRIGGER
257#endif
258#ifdef USE_API_CLIENT_DISCONNECTED_TRIGGER
260#endif
261
262 // 4-byte aligned types
263 uint32_t reboot_timeout_{300000};
264 uint32_t last_connected_{0};
265
266 // Vectors and strings (12 bytes each on 32-bit)
267 std::vector<std::unique_ptr<APIConnection>> clients_;
268 std::vector<uint8_t> shared_write_buffer_; // Shared proto write buffer for all connections
269#ifdef USE_API_HOMEASSISTANT_STATES
270 std::vector<HomeAssistantStateSubscription> state_subs_;
271#endif
272#ifdef USE_API_USER_DEFINED_ACTIONS
273 std::vector<UserServiceDescriptor *> user_services_;
274#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
275 // Active action calls - supports concurrent calls from multiple clients
276 // Uses server-generated action_call_id to avoid collisions when multiple clients use same call_id
278 uint32_t action_call_id; // Server-generated unique ID (passed to actions)
279 uint32_t client_call_id; // Client's original call_id (used in response)
281 };
282 std::vector<ActiveActionCall> active_action_calls_;
283 uint32_t next_action_call_id_{1}; // Counter for generating unique action_call_ids
284#endif // USE_API_USER_DEFINED_ACTION_RESPONSES
285#endif
286#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
291 std::vector<PendingActionResponse> action_response_callbacks_;
292#endif
293
294 // Group smaller types together
295 uint16_t port_{6053};
296 uint16_t batch_delay_{100};
297 // Connection limits - these defaults will be overridden by config values
298 // from cv.SplitDefault in __init__.py which sets platform-specific defaults
299 uint8_t listen_backlog_{4};
301 bool shutting_down_ = false;
302 // 7 bytes used, 1 byte padding
303
304#ifdef USE_API_NOISE
307#endif // USE_API_NOISE
308};
309
310extern APIServer *global_api_server; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
311
312template<typename... Ts> class APIConnectedCondition : public Condition<Ts...> {
313 TEMPLATABLE_VALUE(bool, state_subscription_only)
314 public:
315 bool check(const Ts &...x) override {
316 return global_api_server->is_connected(this->state_subscription_only_.value(x...));
317 }
318};
319
320} // namespace esphome::api
321#endif
Base class for all automation conditions.
Definition automation.h:217
virtual bool check(const Ts &...x)=0
StringRef is a reference to a string owned by something else.
Definition string_ref.h:26
void on_valve_update(valve::Valve *obj) override
uint16_t get_batch_delay() const
Definition api_server.h:67
void on_switch_update(switch_::Switch *obj) override
void register_action_response_callback(uint32_t call_id, ActionResponseCallback callback)
std::vector< std::unique_ptr< APIConnection > > clients_
Definition api_server.h:267
void send_infrared_rf_receive_event(uint32_t device_id, uint32_t key, const std::vector< int32_t > *timings)
void on_time_update(datetime::TimeEntity *obj) override
void on_cover_update(cover::Cover *obj) override
void on_camera_image(const std::shared_ptr< camera::CameraImage > &image) override
std::vector< UserServiceDescriptor * > user_services_
Definition api_server.h:273
void on_light_update(light::LightState *obj) override
void on_media_player_update(media_player::MediaPlayer *obj) override
const std::vector< UserServiceDescriptor * > & get_user_services() const
Definition api_server.h:226
void initialize_user_services(std::initializer_list< UserServiceDescriptor * > services)
Definition api_server.h:151
void on_water_heater_update(water_heater::WaterHeater *obj) override
void set_port(uint16_t port)
void dump_config() override
void unregister_active_action_calls_for_connection(APIConnection *conn)
void handle_disconnect(APIConnection *conn)
void set_batch_delay(uint16_t batch_delay)
void set_reboot_timeout(uint32_t reboot_timeout)
void add_state_subscription_(const char *entity_id, const char *attribute, std::function< void(StringRef)> f, bool once)
void set_listen_backlog(uint8_t listen_backlog)
Definition api_server.h:68
void send_action_response(uint32_t action_call_id, bool success, StringRef error_message)
Trigger< std::string, std::string > * client_connected_trigger_
Definition api_server.h:256
APINoiseContext & get_noise_ctx()
Definition api_server.h:78
void register_user_service(UserServiceDescriptor *descriptor)
Definition api_server.h:156
bool save_noise_psk(psk_t psk, bool make_active=true)
void on_lock_update(lock::Lock *obj) override
void setup() override
void on_date_update(datetime::DateEntity *obj) override
bool teardown() override
APINoiseContext noise_ctx_
Definition api_server.h:305
void unregister_active_action_call(uint32_t action_call_id)
void on_number_update(number::Number *obj) override
void send_homeassistant_action(const HomeassistantActionRequest &call)
void on_event(event::Event *obj) override
void on_update(update::UpdateEntity *obj) override
std::vector< PendingActionResponse > action_response_callbacks_
Definition api_server.h:291
const std::vector< HomeAssistantStateSubscription > & get_state_subs() const
void subscribe_home_assistant_state(const char *entity_id, const char *attribute, std::function< void(StringRef)> f)
Trigger< std::string, std::string > * client_disconnected_trigger_
Definition api_server.h:259
std::vector< uint8_t > shared_write_buffer_
Definition api_server.h:268
void on_climate_update(climate::Climate *obj) override
void handle_action_response(uint32_t call_id, bool success, StringRef error_message)
std::function< void(const class ActionResponse &)> ActionResponseCallback
Definition api_server.h:141
bool update_noise_psk_(const SavedNoisePsk &new_psk, const LogString *save_log_msg, const LogString *fail_log_msg, const psk_t &active_psk, bool make_active)
void set_max_connections(uint8_t max_connections)
Definition api_server.h:69
void on_binary_sensor_update(binary_sensor::BinarySensor *obj) override
bool is_connected(bool state_subscription_only=false) const
ESPPreferenceObject noise_pref_
Definition api_server.h:306
void on_fan_update(fan::Fan *obj) override
std::vector< HomeAssistantStateSubscription > state_subs_
Definition api_server.h:270
void on_zwave_proxy_request(const esphome::api::ProtoMessage &msg)
bool clear_noise_psk(bool make_active=true)
void on_select_update(select::Select *obj) override
uint16_t get_port() const
std::vector< uint8_t > & get_shared_buffer_ref()
Definition api_server.h:72
void on_text_update(text::Text *obj) override
void on_text_sensor_update(text_sensor::TextSensor *obj) override
std::vector< ActiveActionCall > active_action_calls_
Definition api_server.h:282
void set_noise_psk(psk_t psk)
Definition api_server.h:77
void on_datetime_update(datetime::DateTimeEntity *obj) override
Trigger< std::string, std::string > * get_client_disconnected_trigger() const
Definition api_server.h:233
void on_sensor_update(sensor::Sensor *obj) override
void get_home_assistant_state(const char *entity_id, const char *attribute, std::function< void(StringRef)> f)
float get_setup_priority() const override
std::unique_ptr< socket::Socket > socket_
Definition api_server.h:254
uint32_t register_active_action_call(uint32_t client_call_id, APIConnection *conn)
void on_shutdown() override
void on_log(uint8_t level, const char *tag, const char *message, size_t message_len) override
Trigger< std::string, std::string > * get_client_connected_trigger() const
Definition api_server.h:230
void on_alarm_control_panel_update(alarm_control_panel::AlarmControlPanel *obj) override
Base class for all binary_sensor-type classes.
Listener interface for camera events.
Definition camera.h:46
ClimateDevice - This is the base class for all climate integrations.
Definition climate.h:182
Base class for all cover devices.
Definition cover.h:112
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
Definition light_state.h:91
Base class for all locks.
Definition lock.h:111
Interface for receiving log messages without std::function overhead.
Definition logger.h:62
Base-class for all numbers.
Definition number.h:29
Base-class for all selects.
Definition select.h:31
Base-class for all sensors.
Definition sensor.h:42
Base class for all switches.
Definition switch.h:39
Base-class for all text inputs.
Definition text.h:24
Base class for all valve devices.
Definition valve.h:106
const char * message
Definition component.cpp:38
APIServer * global_api_server
struct esphome::api::SavedNoisePsk PACKED
std::array< uint8_t, 32 > psk_t
std::unique_ptr< std::string > entity_id_dynamic_storage
Definition api_server.h:203
std::unique_ptr< std::string > attribute_dynamic_storage
Definition api_server.h:204
uint16_t x
Definition tt21100.cpp:5