ESPHome 2025.12.2
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"
13#include "list_entities.h"
14#include "subscribe_state.h"
15#ifdef USE_LOGGER
17#endif
18#ifdef USE_CAMERA
20#endif
21
22#include <vector>
23
24namespace esphome::api {
25
26#ifdef USE_API_USER_DEFINED_ACTIONS
27// Forward declaration - full definition in user_services.h
28class UserServiceDescriptor;
29#endif
30
31#ifdef USE_API_NOISE
34} PACKED; // NOLINT
35#endif
36
37class APIServer : public Component,
38 public Controller
39#ifdef USE_LOGGER
40 ,
42#endif
43#ifdef USE_CAMERA
44 ,
46#endif
47{
48 public:
49 APIServer();
50 void setup() override;
51 uint16_t get_port() const;
52 float get_setup_priority() const override;
53 void loop() override;
54 void dump_config() override;
55 void on_shutdown() override;
56 bool teardown() override;
57#ifdef USE_LOGGER
58 void on_log(uint8_t level, const char *tag, const char *message, size_t message_len) override;
59#endif
60#ifdef USE_CAMERA
61 void on_camera_image(const std::shared_ptr<camera::CameraImage> &image) override;
62#endif
63#ifdef USE_API_PASSWORD
64 bool check_password(const uint8_t *password_data, size_t password_len) const;
65 void set_password(const std::string &password);
66#endif
67 void set_port(uint16_t port);
68 void set_reboot_timeout(uint32_t reboot_timeout);
69 void set_batch_delay(uint16_t batch_delay);
70 uint16_t get_batch_delay() const { return batch_delay_; }
71 void set_listen_backlog(uint8_t listen_backlog) { this->listen_backlog_ = listen_backlog; }
72 void set_max_connections(uint8_t max_connections) { this->max_connections_ = max_connections; }
73
74 // Get reference to shared buffer for API connections
75 std::vector<uint8_t> &get_shared_buffer_ref() { return shared_write_buffer_; }
76
77#ifdef USE_API_NOISE
78 bool save_noise_psk(psk_t psk, bool make_active = true);
79 bool clear_noise_psk(bool make_active = true);
80 void set_noise_psk(psk_t psk) { this->noise_ctx_.set_psk(psk); }
82#endif // USE_API_NOISE
83
85#ifdef USE_BINARY_SENSOR
87#endif
88#ifdef USE_COVER
89 void on_cover_update(cover::Cover *obj) override;
90#endif
91#ifdef USE_FAN
92 void on_fan_update(fan::Fan *obj) override;
93#endif
94#ifdef USE_LIGHT
96#endif
97#ifdef USE_SENSOR
98 void on_sensor_update(sensor::Sensor *obj) override;
99#endif
100#ifdef USE_SWITCH
102#endif
103#ifdef USE_TEXT_SENSOR
105#endif
106#ifdef USE_CLIMATE
108#endif
109#ifdef USE_NUMBER
110 void on_number_update(number::Number *obj) override;
111#endif
112#ifdef USE_DATETIME_DATE
114#endif
115#ifdef USE_DATETIME_TIME
117#endif
118#ifdef USE_DATETIME_DATETIME
120#endif
121#ifdef USE_TEXT
122 void on_text_update(text::Text *obj) override;
123#endif
124#ifdef USE_SELECT
125 void on_select_update(select::Select *obj) override;
126#endif
127#ifdef USE_LOCK
128 void on_lock_update(lock::Lock *obj) override;
129#endif
130#ifdef USE_VALVE
131 void on_valve_update(valve::Valve *obj) override;
132#endif
133#ifdef USE_MEDIA_PLAYER
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, const std::string &error_message);
144#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
145 void handle_action_response(uint32_t call_id, bool success, const std::string &error_message,
146 const uint8_t *response_data, 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, const std::string &error_message);
166#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
167 void send_action_response(uint32_t action_call_id, bool success, const std::string &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
189 bool is_connected(bool state_subscription_only = false) const;
190
191#ifdef USE_API_HOMEASSISTANT_STATES
193 const char *entity_id; // Pointer to flash (internal) or heap (external)
194 const char *attribute; // Pointer to flash or nullptr (nullptr means no attribute)
195 std::function<void(std::string)> callback;
196 bool once;
197
198 // Dynamic storage for external components using std::string API (custom_api_device.h)
199 // These are only allocated when using the std::string overload (nullptr for const char* overload)
200 std::unique_ptr<std::string> entity_id_dynamic_storage;
201 std::unique_ptr<std::string> attribute_dynamic_storage;
202 };
203
204 // New const char* overload (for internal components - zero allocation)
205 void subscribe_home_assistant_state(const char *entity_id, const char *attribute, std::function<void(std::string)> f);
206 void get_home_assistant_state(const char *entity_id, const char *attribute, std::function<void(std::string)> f);
207
208 // Existing std::string overload (for custom_api_device.h - heap allocation)
209 void subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
210 std::function<void(std::string)> f);
211 void get_home_assistant_state(std::string entity_id, optional<std::string> attribute,
212 std::function<void(std::string)> f);
213
214 const std::vector<HomeAssistantStateSubscription> &get_state_subs() const;
215#endif
216#ifdef USE_API_USER_DEFINED_ACTIONS
217 const std::vector<UserServiceDescriptor *> &get_user_services() const { return this->user_services_; }
218#endif
219
220#ifdef USE_API_CLIENT_CONNECTED_TRIGGER
222#endif
223#ifdef USE_API_CLIENT_DISCONNECTED_TRIGGER
227#endif
228
229 protected:
230#ifdef USE_API_NOISE
231 bool update_noise_psk_(const SavedNoisePsk &new_psk, const LogString *save_log_msg, const LogString *fail_log_msg,
232 const psk_t &active_psk, bool make_active);
233#endif // USE_API_NOISE
234#ifdef USE_API_HOMEASSISTANT_STATES
235 // Helper methods to reduce code duplication
236 void add_state_subscription_(const char *entity_id, const char *attribute, std::function<void(std::string)> f,
237 bool once);
238 void add_state_subscription_(std::string entity_id, optional<std::string> attribute,
239 std::function<void(std::string)> f, bool once);
240#endif // USE_API_HOMEASSISTANT_STATES
241 // Pointers and pointer-like types first (4 bytes each)
242 std::unique_ptr<socket::Socket> socket_ = nullptr;
243#ifdef USE_API_CLIENT_CONNECTED_TRIGGER
245#endif
246#ifdef USE_API_CLIENT_DISCONNECTED_TRIGGER
248#endif
249
250 // 4-byte aligned types
251 uint32_t reboot_timeout_{300000};
252 uint32_t last_connected_{0};
253
254 // Vectors and strings (12 bytes each on 32-bit)
255 std::vector<std::unique_ptr<APIConnection>> clients_;
256#ifdef USE_API_PASSWORD
257 std::string password_;
258#endif
259 std::vector<uint8_t> shared_write_buffer_; // Shared proto write buffer for all connections
260#ifdef USE_API_HOMEASSISTANT_STATES
261 std::vector<HomeAssistantStateSubscription> state_subs_;
262#endif
263#ifdef USE_API_USER_DEFINED_ACTIONS
264 std::vector<UserServiceDescriptor *> user_services_;
265#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
266 // Active action calls - supports concurrent calls from multiple clients
267 // Uses server-generated action_call_id to avoid collisions when multiple clients use same call_id
269 uint32_t action_call_id; // Server-generated unique ID (passed to actions)
270 uint32_t client_call_id; // Client's original call_id (used in response)
272 };
273 std::vector<ActiveActionCall> active_action_calls_;
274 uint32_t next_action_call_id_{1}; // Counter for generating unique action_call_ids
275#endif // USE_API_USER_DEFINED_ACTION_RESPONSES
276#endif
277#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
282 std::vector<PendingActionResponse> action_response_callbacks_;
283#endif
284
285 // Group smaller types together
286 uint16_t port_{6053};
287 uint16_t batch_delay_{100};
288 // Connection limits - these defaults will be overridden by config values
289 // from cv.SplitDefault in __init__.py which sets platform-specific defaults
290 uint8_t listen_backlog_{4};
292 bool shutting_down_ = false;
293 // 7 bytes used, 1 byte padding
294
295#ifdef USE_API_NOISE
298#endif // USE_API_NOISE
299};
300
301extern APIServer *global_api_server; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
302
303template<typename... Ts> class APIConnectedCondition : public Condition<Ts...> {
304 TEMPLATABLE_VALUE(bool, state_subscription_only)
305 public:
306 bool check(const Ts &...x) override {
307 return global_api_server->is_connected(this->state_subscription_only_.value(x...));
308 }
309};
310
311} // namespace esphome::api
312#endif
Base class for all automation conditions.
Definition automation.h:183
virtual bool check(const Ts &...x)=0
void get_home_assistant_state(const char *entity_id, const char *attribute, std::function< void(std::string)> f)
void on_valve_update(valve::Valve *obj) override
uint16_t get_batch_delay() const
Definition api_server.h:70
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:255
void set_password(const std::string &password)
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:264
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:217
void initialize_user_services(std::initializer_list< UserServiceDescriptor * > services)
Definition api_server.h:151
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 set_listen_backlog(uint8_t listen_backlog)
Definition api_server.h:71
Trigger< std::string, std::string > * client_connected_trigger_
Definition api_server.h:244
APINoiseContext & get_noise_ctx()
Definition api_server.h:81
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
void handle_action_response(uint32_t call_id, bool success, const std::string &error_message)
bool teardown() override
APINoiseContext noise_ctx_
Definition api_server.h:296
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
bool check_password(const uint8_t *password_data, size_t password_len) const
std::vector< PendingActionResponse > action_response_callbacks_
Definition api_server.h:282
const std::vector< HomeAssistantStateSubscription > & get_state_subs() const
Trigger< std::string, std::string > * client_disconnected_trigger_
Definition api_server.h:247
std::vector< uint8_t > shared_write_buffer_
Definition api_server.h:259
void on_climate_update(climate::Climate *obj) override
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:72
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:297
void on_fan_update(fan::Fan *obj) override
std::vector< HomeAssistantStateSubscription > state_subs_
Definition api_server.h:261
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:75
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:273
void set_noise_psk(psk_t psk)
Definition api_server.h:80
void on_datetime_update(datetime::DateTimeEntity *obj) override
Trigger< std::string, std::string > * get_client_disconnected_trigger() const
Definition api_server.h:224
void on_sensor_update(sensor::Sensor *obj) override
void send_action_response(uint32_t action_call_id, bool success, const std::string &error_message)
void add_state_subscription_(const char *entity_id, const char *attribute, std::function< void(std::string)> f, bool once)
float get_setup_priority() const override
std::unique_ptr< socket::Socket > socket_
Definition api_server.h:242
uint32_t register_active_action_call(uint32_t client_call_id, APIConnection *conn)
void subscribe_home_assistant_state(const char *entity_id, const char *attribute, std::function< void(std::string)> f)
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:221
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:177
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:56
Base-class for all numbers.
Definition number.h:29
Base-class for all selects.
Definition select.h:30
Base-class for all sensors.
Definition sensor.h:43
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:200
std::unique_ptr< std::string > attribute_dynamic_storage
Definition api_server.h:201
uint16_t x
Definition tt21100.cpp:5