[api] Add conditional compilation for Home Assistant service subscriptions (#9900)

This commit is contained in:
J. Nick Koston 2025-07-27 18:35:35 -10:00 committed by GitHub
parent 5029e248eb
commit 05f6d01cbe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 40 additions and 0 deletions

View File

@ -53,6 +53,7 @@ SERVICE_ARG_NATIVE_TYPES = {
CONF_ENCRYPTION = "encryption" CONF_ENCRYPTION = "encryption"
CONF_BATCH_DELAY = "batch_delay" CONF_BATCH_DELAY = "batch_delay"
CONF_CUSTOM_SERVICES = "custom_services" CONF_CUSTOM_SERVICES = "custom_services"
CONF_HOMEASSISTANT_SERVICES = "homeassistant_services"
CONF_HOMEASSISTANT_STATES = "homeassistant_states" CONF_HOMEASSISTANT_STATES = "homeassistant_states"
@ -119,6 +120,7 @@ CONFIG_SCHEMA = cv.All(
cv.Range(max=cv.TimePeriod(milliseconds=65535)), cv.Range(max=cv.TimePeriod(milliseconds=65535)),
), ),
cv.Optional(CONF_CUSTOM_SERVICES, default=False): cv.boolean, cv.Optional(CONF_CUSTOM_SERVICES, default=False): cv.boolean,
cv.Optional(CONF_HOMEASSISTANT_SERVICES, default=False): cv.boolean,
cv.Optional(CONF_HOMEASSISTANT_STATES, default=False): cv.boolean, cv.Optional(CONF_HOMEASSISTANT_STATES, default=False): cv.boolean,
cv.Optional(CONF_ON_CLIENT_CONNECTED): automation.validate_automation( cv.Optional(CONF_ON_CLIENT_CONNECTED): automation.validate_automation(
single=True single=True
@ -148,6 +150,9 @@ async def to_code(config):
if config.get(CONF_ACTIONS) or config[CONF_CUSTOM_SERVICES]: if config.get(CONF_ACTIONS) or config[CONF_CUSTOM_SERVICES]:
cg.add_define("USE_API_SERVICES") cg.add_define("USE_API_SERVICES")
if config[CONF_HOMEASSISTANT_SERVICES]:
cg.add_define("USE_API_HOMEASSISTANT_SERVICES")
if config[CONF_HOMEASSISTANT_STATES]: if config[CONF_HOMEASSISTANT_STATES]:
cg.add_define("USE_API_HOMEASSISTANT_STATES") cg.add_define("USE_API_HOMEASSISTANT_STATES")
@ -240,6 +245,7 @@ HOMEASSISTANT_ACTION_ACTION_SCHEMA = cv.All(
HOMEASSISTANT_ACTION_ACTION_SCHEMA, HOMEASSISTANT_ACTION_ACTION_SCHEMA,
) )
async def homeassistant_service_to_code(config, action_id, template_arg, args): async def homeassistant_service_to_code(config, action_id, template_arg, args):
cg.add_define("USE_API_HOMEASSISTANT_SERVICES")
serv = await cg.get_variable(config[CONF_ID]) serv = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, serv, False) var = cg.new_Pvariable(action_id, template_arg, serv, False)
templ = await cg.templatable(config[CONF_ACTION], args, None) templ = await cg.templatable(config[CONF_ACTION], args, None)
@ -283,6 +289,7 @@ HOMEASSISTANT_EVENT_ACTION_SCHEMA = cv.Schema(
HOMEASSISTANT_EVENT_ACTION_SCHEMA, HOMEASSISTANT_EVENT_ACTION_SCHEMA,
) )
async def homeassistant_event_to_code(config, action_id, template_arg, args): async def homeassistant_event_to_code(config, action_id, template_arg, args):
cg.add_define("USE_API_HOMEASSISTANT_SERVICES")
serv = await cg.get_variable(config[CONF_ID]) serv = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, serv, True) var = cg.new_Pvariable(action_id, template_arg, serv, True)
templ = await cg.templatable(config[CONF_EVENT], args, None) templ = await cg.templatable(config[CONF_EVENT], args, None)

View File

@ -755,6 +755,7 @@ message NoiseEncryptionSetKeyResponse {
message SubscribeHomeassistantServicesRequest { message SubscribeHomeassistantServicesRequest {
option (id) = 34; option (id) = 34;
option (source) = SOURCE_CLIENT; option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_API_HOMEASSISTANT_SERVICES";
} }
message HomeassistantServiceMap { message HomeassistantServiceMap {
@ -766,6 +767,7 @@ message HomeassistantServiceResponse {
option (id) = 35; option (id) = 35;
option (source) = SOURCE_SERVER; option (source) = SOURCE_SERVER;
option (no_delay) = true; option (no_delay) = true;
option (ifdef) = "USE_API_HOMEASSISTANT_SERVICES";
string service = 1; string service = 1;
repeated HomeassistantServiceMap data = 2; repeated HomeassistantServiceMap data = 2;

View File

@ -131,11 +131,13 @@ class APIConnection : public APIServerConnection {
void media_player_command(const MediaPlayerCommandRequest &msg) override; void media_player_command(const MediaPlayerCommandRequest &msg) override;
#endif #endif
bool try_send_log_message(int level, const char *tag, const char *line, size_t message_len); bool try_send_log_message(int level, const char *tag, const char *line, size_t message_len);
#ifdef USE_API_HOMEASSISTANT_SERVICES
void send_homeassistant_service_call(const HomeassistantServiceResponse &call) { void send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
if (!this->flags_.service_call_subscription) if (!this->flags_.service_call_subscription)
return; return;
this->send_message(call, HomeassistantServiceResponse::MESSAGE_TYPE); this->send_message(call, HomeassistantServiceResponse::MESSAGE_TYPE);
} }
#endif
#ifdef USE_BLUETOOTH_PROXY #ifdef USE_BLUETOOTH_PROXY
void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) override; void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) override;
void unsubscribe_bluetooth_le_advertisements(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override; void unsubscribe_bluetooth_le_advertisements(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override;
@ -209,9 +211,11 @@ class APIConnection : public APIServerConnection {
if (msg.dump_config) if (msg.dump_config)
App.schedule_dump_config(); App.schedule_dump_config();
} }
#ifdef USE_API_HOMEASSISTANT_SERVICES
void subscribe_homeassistant_services(const SubscribeHomeassistantServicesRequest &msg) override { void subscribe_homeassistant_services(const SubscribeHomeassistantServicesRequest &msg) override {
this->flags_.service_call_subscription = true; this->flags_.service_call_subscription = true;
} }
#endif
#ifdef USE_API_HOMEASSISTANT_STATES #ifdef USE_API_HOMEASSISTANT_STATES
void subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) override; void subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) override;
#endif #endif

View File

@ -843,6 +843,7 @@ void NoiseEncryptionSetKeyResponse::calculate_size(uint32_t &total_size) const {
ProtoSize::add_bool_field(total_size, 1, this->success); ProtoSize::add_bool_field(total_size, 1, this->success);
} }
#endif #endif
#ifdef USE_API_HOMEASSISTANT_SERVICES
void HomeassistantServiceMap::encode(ProtoWriteBuffer buffer) const { void HomeassistantServiceMap::encode(ProtoWriteBuffer buffer) const {
buffer.encode_string(1, this->key_ref_); buffer.encode_string(1, this->key_ref_);
buffer.encode_string(2, this->value_ref_); buffer.encode_string(2, this->value_ref_);
@ -871,6 +872,7 @@ void HomeassistantServiceResponse::calculate_size(uint32_t &total_size) const {
ProtoSize::add_repeated_message(total_size, 1, this->variables); ProtoSize::add_repeated_message(total_size, 1, this->variables);
ProtoSize::add_bool_field(total_size, 1, this->is_event); ProtoSize::add_bool_field(total_size, 1, this->is_event);
} }
#endif
#ifdef USE_API_HOMEASSISTANT_STATES #ifdef USE_API_HOMEASSISTANT_STATES
void SubscribeHomeAssistantStateResponse::encode(ProtoWriteBuffer buffer) const { void SubscribeHomeAssistantStateResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_string(1, this->entity_id_ref_); buffer.encode_string(1, this->entity_id_ref_);

View File

@ -1044,6 +1044,7 @@ class NoiseEncryptionSetKeyResponse : public ProtoMessage {
protected: protected:
}; };
#endif #endif
#ifdef USE_API_HOMEASSISTANT_SERVICES
class SubscribeHomeassistantServicesRequest : public ProtoDecodableMessage { class SubscribeHomeassistantServicesRequest : public ProtoDecodableMessage {
public: public:
static constexpr uint8_t MESSAGE_TYPE = 34; static constexpr uint8_t MESSAGE_TYPE = 34;
@ -1092,6 +1093,7 @@ class HomeassistantServiceResponse : public ProtoMessage {
protected: protected:
}; };
#endif
#ifdef USE_API_HOMEASSISTANT_STATES #ifdef USE_API_HOMEASSISTANT_STATES
class SubscribeHomeAssistantStatesRequest : public ProtoDecodableMessage { class SubscribeHomeAssistantStatesRequest : public ProtoDecodableMessage {
public: public:

View File

@ -1038,6 +1038,7 @@ void NoiseEncryptionSetKeyRequest::dump_to(std::string &out) const {
} }
void NoiseEncryptionSetKeyResponse::dump_to(std::string &out) const { dump_field(out, "success", this->success); } void NoiseEncryptionSetKeyResponse::dump_to(std::string &out) const { dump_field(out, "success", this->success); }
#endif #endif
#ifdef USE_API_HOMEASSISTANT_SERVICES
void SubscribeHomeassistantServicesRequest::dump_to(std::string &out) const { void SubscribeHomeassistantServicesRequest::dump_to(std::string &out) const {
out.append("SubscribeHomeassistantServicesRequest {}"); out.append("SubscribeHomeassistantServicesRequest {}");
} }
@ -1066,6 +1067,7 @@ void HomeassistantServiceResponse::dump_to(std::string &out) const {
} }
dump_field(out, "is_event", this->is_event); dump_field(out, "is_event", this->is_event);
} }
#endif
#ifdef USE_API_HOMEASSISTANT_STATES #ifdef USE_API_HOMEASSISTANT_STATES
void SubscribeHomeAssistantStatesRequest::dump_to(std::string &out) const { void SubscribeHomeAssistantStatesRequest::dump_to(std::string &out) const {
out.append("SubscribeHomeAssistantStatesRequest {}"); out.append("SubscribeHomeAssistantStatesRequest {}");

View File

@ -149,6 +149,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
break; break;
} }
#endif #endif
#ifdef USE_API_HOMEASSISTANT_SERVICES
case SubscribeHomeassistantServicesRequest::MESSAGE_TYPE: { case SubscribeHomeassistantServicesRequest::MESSAGE_TYPE: {
SubscribeHomeassistantServicesRequest msg; SubscribeHomeassistantServicesRequest msg;
msg.decode(msg_data, msg_size); msg.decode(msg_data, msg_size);
@ -158,6 +159,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
this->on_subscribe_homeassistant_services_request(msg); this->on_subscribe_homeassistant_services_request(msg);
break; break;
} }
#endif
case GetTimeRequest::MESSAGE_TYPE: { case GetTimeRequest::MESSAGE_TYPE: {
GetTimeRequest msg; GetTimeRequest msg;
msg.decode(msg_data, msg_size); msg.decode(msg_data, msg_size);
@ -639,12 +641,14 @@ void APIServerConnection::on_subscribe_logs_request(const SubscribeLogsRequest &
this->subscribe_logs(msg); this->subscribe_logs(msg);
} }
} }
#ifdef USE_API_HOMEASSISTANT_SERVICES
void APIServerConnection::on_subscribe_homeassistant_services_request( void APIServerConnection::on_subscribe_homeassistant_services_request(
const SubscribeHomeassistantServicesRequest &msg) { const SubscribeHomeassistantServicesRequest &msg) {
if (this->check_authenticated_()) { if (this->check_authenticated_()) {
this->subscribe_homeassistant_services(msg); this->subscribe_homeassistant_services(msg);
} }
} }
#endif
#ifdef USE_API_HOMEASSISTANT_STATES #ifdef USE_API_HOMEASSISTANT_STATES
void APIServerConnection::on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &msg) { void APIServerConnection::on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &msg) {
if (this->check_authenticated_()) { if (this->check_authenticated_()) {

View File

@ -60,7 +60,9 @@ class APIServerConnectionBase : public ProtoService {
virtual void on_noise_encryption_set_key_request(const NoiseEncryptionSetKeyRequest &value){}; virtual void on_noise_encryption_set_key_request(const NoiseEncryptionSetKeyRequest &value){};
#endif #endif
#ifdef USE_API_HOMEASSISTANT_SERVICES
virtual void on_subscribe_homeassistant_services_request(const SubscribeHomeassistantServicesRequest &value){}; virtual void on_subscribe_homeassistant_services_request(const SubscribeHomeassistantServicesRequest &value){};
#endif
#ifdef USE_API_HOMEASSISTANT_STATES #ifdef USE_API_HOMEASSISTANT_STATES
virtual void on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &value){}; virtual void on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &value){};
@ -218,7 +220,9 @@ class APIServerConnection : public APIServerConnectionBase {
virtual void list_entities(const ListEntitiesRequest &msg) = 0; virtual void list_entities(const ListEntitiesRequest &msg) = 0;
virtual void subscribe_states(const SubscribeStatesRequest &msg) = 0; virtual void subscribe_states(const SubscribeStatesRequest &msg) = 0;
virtual void subscribe_logs(const SubscribeLogsRequest &msg) = 0; virtual void subscribe_logs(const SubscribeLogsRequest &msg) = 0;
#ifdef USE_API_HOMEASSISTANT_SERVICES
virtual void subscribe_homeassistant_services(const SubscribeHomeassistantServicesRequest &msg) = 0; virtual void subscribe_homeassistant_services(const SubscribeHomeassistantServicesRequest &msg) = 0;
#endif
#ifdef USE_API_HOMEASSISTANT_STATES #ifdef USE_API_HOMEASSISTANT_STATES
virtual void subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) = 0; virtual void subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) = 0;
#endif #endif
@ -338,7 +342,9 @@ class APIServerConnection : public APIServerConnectionBase {
void on_list_entities_request(const ListEntitiesRequest &msg) override; void on_list_entities_request(const ListEntitiesRequest &msg) override;
void on_subscribe_states_request(const SubscribeStatesRequest &msg) override; void on_subscribe_states_request(const SubscribeStatesRequest &msg) override;
void on_subscribe_logs_request(const SubscribeLogsRequest &msg) override; void on_subscribe_logs_request(const SubscribeLogsRequest &msg) override;
#ifdef USE_API_HOMEASSISTANT_SERVICES
void on_subscribe_homeassistant_services_request(const SubscribeHomeassistantServicesRequest &msg) override; void on_subscribe_homeassistant_services_request(const SubscribeHomeassistantServicesRequest &msg) override;
#endif
#ifdef USE_API_HOMEASSISTANT_STATES #ifdef USE_API_HOMEASSISTANT_STATES
void on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &msg) override; void on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &msg) override;
#endif #endif

View File

@ -369,11 +369,13 @@ void APIServer::set_password(const std::string &password) { this->password_ = pa
void APIServer::set_batch_delay(uint16_t batch_delay) { this->batch_delay_ = batch_delay; } void APIServer::set_batch_delay(uint16_t batch_delay) { this->batch_delay_ = batch_delay; }
#ifdef USE_API_HOMEASSISTANT_SERVICES
void APIServer::send_homeassistant_service_call(const HomeassistantServiceResponse &call) { void APIServer::send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
for (auto &client : this->clients_) { for (auto &client : this->clients_) {
client->send_homeassistant_service_call(call); client->send_homeassistant_service_call(call);
} }
} }
#endif
#ifdef USE_API_HOMEASSISTANT_STATES #ifdef USE_API_HOMEASSISTANT_STATES
void APIServer::subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute, void APIServer::subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,

View File

@ -106,7 +106,9 @@ class APIServer : public Component, public Controller {
#ifdef USE_MEDIA_PLAYER #ifdef USE_MEDIA_PLAYER
void on_media_player_update(media_player::MediaPlayer *obj) override; void on_media_player_update(media_player::MediaPlayer *obj) override;
#endif #endif
#ifdef USE_API_HOMEASSISTANT_SERVICES
void send_homeassistant_service_call(const HomeassistantServiceResponse &call); void send_homeassistant_service_call(const HomeassistantServiceResponse &call);
#endif
#ifdef USE_API_SERVICES #ifdef USE_API_SERVICES
void register_user_service(UserServiceDescriptor *descriptor) { this->user_services_.push_back(descriptor); } void register_user_service(UserServiceDescriptor *descriptor) { this->user_services_.push_back(descriptor); }
#endif #endif

View File

@ -137,6 +137,7 @@ class CustomAPIDevice {
} }
#endif #endif
#ifdef USE_API_HOMEASSISTANT_SERVICES
/** Call a Home Assistant service from ESPHome. /** Call a Home Assistant service from ESPHome.
* *
* Usage: * Usage:
@ -221,6 +222,7 @@ class CustomAPIDevice {
} }
global_api_server->send_homeassistant_service_call(resp); global_api_server->send_homeassistant_service_call(resp);
} }
#endif
}; };
} // namespace esphome::api } // namespace esphome::api

View File

@ -2,6 +2,7 @@
#include "api_server.h" #include "api_server.h"
#ifdef USE_API #ifdef USE_API
#ifdef USE_API_HOMEASSISTANT_SERVICES
#include "api_pb2.h" #include "api_pb2.h"
#include "esphome/core/automation.h" #include "esphome/core/automation.h"
#include "esphome/core/helpers.h" #include "esphome/core/helpers.h"
@ -100,3 +101,4 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
} // namespace esphome::api } // namespace esphome::api
#endif #endif
#endif

View File

@ -23,6 +23,7 @@ CONFIG_SCHEMA = (
async def to_code(config): async def to_code(config):
cg.add_define("USE_API_HOMEASSISTANT_SERVICES")
var = await number.new_number( var = await number.new_number(
config, config,
min_value=0, min_value=0,

View File

@ -37,6 +37,7 @@ CONFIG_SCHEMA = cv.All(
async def to_code(config): async def to_code(config):
cg.add_define("USE_API_HOMEASSISTANT_SERVICES")
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config) await cg.register_component(var, config)
await switch.register_switch(var, config) await switch.register_switch(var, config)

View File

@ -109,6 +109,7 @@
#define USE_API #define USE_API
#define USE_API_CLIENT_CONNECTED_TRIGGER #define USE_API_CLIENT_CONNECTED_TRIGGER
#define USE_API_CLIENT_DISCONNECTED_TRIGGER #define USE_API_CLIENT_DISCONNECTED_TRIGGER
#define USE_API_HOMEASSISTANT_SERVICES
#define USE_API_HOMEASSISTANT_STATES #define USE_API_HOMEASSISTANT_STATES
#define USE_API_NOISE #define USE_API_NOISE
#define USE_API_PLAINTEXT #define USE_API_PLAINTEXT