ESPHome 2026.1.0-dev
Loading...
Searching...
No Matches
custom_api_device.h
Go to the documentation of this file.
1#pragma once
2
3#include <map>
4#include "api_server.h"
5#ifdef USE_API
6#ifdef USE_API_USER_DEFINED_ACTIONS
7#include "user_services.h"
8#endif
9namespace esphome::api {
10
11#ifdef USE_API_USER_DEFINED_ACTIONS
12template<typename T, typename... Ts> class CustomAPIDeviceService : public UserServiceDynamic<Ts...> {
13 public:
14 CustomAPIDeviceService(const std::string &name, const std::array<std::string, sizeof...(Ts)> &arg_names, T *obj,
15 void (T::*callback)(Ts...))
16 : UserServiceDynamic<Ts...>(name, arg_names), obj_(obj), callback_(callback) {}
17
18 protected:
19 // CustomAPIDevice services don't support action responses - ignore call_id and return_response
20 void execute(uint32_t /*call_id*/, bool /*return_response*/, Ts... x) override {
21 (this->obj_->*this->callback_)(x...); // NOLINT
22 }
23
24 T *obj_;
25 void (T::*callback_)(Ts...);
26};
27#endif // USE_API_USER_DEFINED_ACTIONS
28
30 public:
32 bool is_connected() const { return global_api_server->is_connected(); }
33
55#ifdef USE_API_USER_DEFINED_ACTIONS
56 template<typename T, typename... Ts>
57 void register_service(void (T::*callback)(Ts...), const std::string &name,
58 const std::array<std::string, sizeof...(Ts)> &arg_names) {
59#ifdef USE_API_CUSTOM_SERVICES
60 auto *service = new CustomAPIDeviceService<T, Ts...>(name, arg_names, (T *) this, callback); // NOLINT
62#else
63 static_assert(
64 sizeof(T) == 0,
65 "register_service() requires 'custom_services: true' in the 'api:' section of your YAML configuration");
66#endif
67 }
68#else
69 template<typename T, typename... Ts>
70 void register_service(void (T::*callback)(Ts...), const std::string &name,
71 const std::array<std::string, sizeof...(Ts)> &arg_names) {
72 static_assert(
73 sizeof(T) == 0,
74 "register_service() requires 'custom_services: true' in the 'api:' section of your YAML configuration");
75 }
76#endif
77
96#ifdef USE_API_USER_DEFINED_ACTIONS
97 template<typename T> void register_service(void (T::*callback)(), const std::string &name) {
98#ifdef USE_API_CUSTOM_SERVICES
99 auto *service = new CustomAPIDeviceService<T>(name, {}, (T *) this, callback); // NOLINT
101#else
102 static_assert(
103 sizeof(T) == 0,
104 "register_service() requires 'custom_services: true' in the 'api:' section of your YAML configuration");
105#endif
106 }
107#else
108 template<typename T> void register_service(void (T::*callback)(), const std::string &name) {
109 static_assert(
110 sizeof(T) == 0,
111 "register_service() requires 'custom_services: true' in the 'api:' section of your YAML configuration");
112 }
113#endif
114
115#ifdef USE_API_HOMEASSISTANT_STATES
135 template<typename T>
136 void subscribe_homeassistant_state(void (T::*callback)(std::string), const std::string &entity_id,
137 const std::string &attribute = "") {
138 auto f = std::bind(callback, (T *) this, std::placeholders::_1);
140 }
141
161 template<typename T>
162 void subscribe_homeassistant_state(void (T::*callback)(std::string, std::string), const std::string &entity_id,
163 const std::string &attribute = "") {
164 auto f = std::bind(callback, (T *) this, entity_id, std::placeholders::_1);
166 }
167#else
168 template<typename T>
169 void subscribe_homeassistant_state(void (T::*callback)(std::string), const std::string &entity_id,
170 const std::string &attribute = "") {
171 static_assert(sizeof(T) == 0,
172 "subscribe_homeassistant_state() requires 'homeassistant_states: true' in the 'api:' section "
173 "of your YAML configuration");
174 }
175
176 template<typename T>
177 void subscribe_homeassistant_state(void (T::*callback)(std::string, std::string), const std::string &entity_id,
178 const std::string &attribute = "") {
179 static_assert(sizeof(T) == 0,
180 "subscribe_homeassistant_state() requires 'homeassistant_states: true' in the 'api:' section "
181 "of your YAML configuration");
182 }
183#endif
184
185#ifdef USE_API_HOMEASSISTANT_SERVICES
196 void call_homeassistant_service(const std::string &service_name) {
198 resp.set_service(StringRef(service_name));
200 }
201
216 void call_homeassistant_service(const std::string &service_name, const std::map<std::string, std::string> &data) {
218 resp.set_service(StringRef(service_name));
219 resp.data.init(data.size());
220 for (auto &it : data) {
221 auto &kv = resp.data.emplace_back();
222 kv.set_key(StringRef(it.first));
223 kv.value = it.second;
224 }
226 }
227
238 void fire_homeassistant_event(const std::string &event_name) {
240 resp.set_service(StringRef(event_name));
241 resp.is_event = true;
243 }
244
258 void fire_homeassistant_event(const std::string &service_name, const std::map<std::string, std::string> &data) {
260 resp.set_service(StringRef(service_name));
261 resp.is_event = true;
262 resp.data.init(data.size());
263 for (auto &it : data) {
264 auto &kv = resp.data.emplace_back();
265 kv.set_key(StringRef(it.first));
266 kv.value = it.second;
267 }
269 }
270#else
271 template<typename T = void> void call_homeassistant_service(const std::string &service_name) {
272 static_assert(sizeof(T) == 0, "call_homeassistant_service() requires 'homeassistant_services: true' in the 'api:' "
273 "section of your YAML configuration");
274 }
275
276 template<typename T = void>
277 void call_homeassistant_service(const std::string &service_name, const std::map<std::string, std::string> &data) {
278 static_assert(sizeof(T) == 0, "call_homeassistant_service() requires 'homeassistant_services: true' in the 'api:' "
279 "section of your YAML configuration");
280 }
281
282 template<typename T = void> void fire_homeassistant_event(const std::string &event_name) {
283 static_assert(sizeof(T) == 0, "fire_homeassistant_event() requires 'homeassistant_services: true' in the 'api:' "
284 "section of your YAML configuration");
285 }
286
287 template<typename T = void>
288 void fire_homeassistant_event(const std::string &service_name, const std::map<std::string, std::string> &data) {
289 static_assert(sizeof(T) == 0, "fire_homeassistant_event() requires 'homeassistant_services: true' in the 'api:' "
290 "section of your YAML configuration");
291 }
292#endif
293};
294
295} // namespace esphome::api
296#endif
StringRef is a reference to a string owned by something else.
Definition string_ref.h:22
void register_user_service(UserServiceDescriptor *descriptor)
Definition api_server.h:159
void send_homeassistant_action(const HomeassistantActionRequest &call)
bool is_connected(bool state_subscription_only=false) const
void subscribe_home_assistant_state(const char *entity_id, const char *attribute, std::function< void(std::string)> f)
void subscribe_homeassistant_state(void(T::*callback)(std::string), const std::string &entity_id, const std::string &attribute="")
Subscribe to the state (or attribute state) of an entity from Home Assistant.
void fire_homeassistant_event(const std::string &service_name, const std::map< std::string, std::string > &data)
void register_service(void(T::*callback)(Ts...), const std::string &name, const std::array< std::string, sizeof...(Ts)> &arg_names)
Register a custom native API service that will show up in Home Assistant.
void fire_homeassistant_event(const std::string &event_name)
void call_homeassistant_service(const std::string &service_name)
Call a Home Assistant service from ESPHome.
void register_service(void(T::*callback)(), const std::string &name)
Register a custom native API service that will show up in Home Assistant.
void fire_homeassistant_event(const std::string &event_name)
Fire an ESPHome event in Home Assistant.
bool is_connected() const
Return if a client (such as Home Assistant) is connected to the native API.
void fire_homeassistant_event(const std::string &service_name, const std::map< std::string, std::string > &data)
Fire an ESPHome event in Home Assistant.
void call_homeassistant_service(const std::string &service_name)
void subscribe_homeassistant_state(void(T::*callback)(std::string, std::string), const std::string &entity_id, const std::string &attribute="")
Subscribe to the state (or attribute state) of an entity from Home Assistant.
void call_homeassistant_service(const std::string &service_name, const std::map< std::string, std::string > &data)
Call a Home Assistant service from ESPHome.
void call_homeassistant_service(const std::string &service_name, const std::map< std::string, std::string > &data)
void execute(uint32_t, bool, Ts... x) override
CustomAPIDeviceService(const std::string &name, const std::array< std::string, sizeof...(Ts)> &arg_names, T *obj, void(T::*callback)(Ts...))
FixedVector< HomeassistantServiceMap > data
Definition api_pb2.h:1142
void set_service(const StringRef &ref)
Definition api_pb2.h:1141
APIServer * global_api_server
uint16_t x
Definition tt21100.cpp:5