ESPHome 2026.10.0-dev
Loading...
Searching...
No Matches
user_services.cpp
Go to the documentation of this file.
1#include "user_services.h"
2#include "esphome/core/hal.h"
3#include "esphome/core/log.h"
5
6namespace esphome::api {
7
8StringRef UserServiceStatic::str_(size_t idx, std::span<char> &scratch) const {
9 const char *s = progmem_read_ptr(&this->strings_[idx]);
10 if (s == nullptr)
11 return {};
12#ifdef USE_ESP8266
13 // Codegen sizes the scratch buffer for the largest service; the bound only guards other callers
14 if (scratch.empty())
15 return {};
16 size_t len = strnlen_P(s, scratch.size() - 1);
17 progmem_memcpy(scratch.data(), s, len);
18 scratch[len] = '\0';
19 StringRef ref(scratch.data(), len);
20 scratch = scratch.subspan(len + 1);
21 return ref;
22#else
23 return StringRef(s);
24#endif
25}
26
28 std::span<const enums::ServiceArgType> arg_types, std::span<char> scratch) const {
30 msg.name = this->str_(0, scratch);
31 msg.key = this->key_;
33#ifdef USE_API_USER_DEFINED_ACTION_METADATA
34 msg.description = this->str_(1, scratch);
35#endif
36 msg.args.init(arg_types.size());
37 for (size_t i = 0; i < arg_types.size(); i++) {
38 size_t base = USER_ACTION_HEADER_STRINGS + i * USER_ACTION_ARG_STRINGS;
39 auto &arg = msg.args.emplace_back();
40 arg.type = arg_types[i];
41 arg.name = this->str_(base, scratch);
42#ifdef USE_API_USER_DEFINED_ACTION_METADATA
43 arg.description = this->str_(base + 1, scratch);
44 arg.example = this->str_(base + 2, scratch);
45#endif
46 }
47 return msg;
48}
49
50template<> bool get_execute_arg_value<bool>(const ExecuteServiceArgument &arg) { return arg.bool_; }
52 if (arg.legacy_int != 0)
53 return arg.legacy_int;
54 return arg.int_;
55}
56template<> float get_execute_arg_value<float>(const ExecuteServiceArgument &arg) { return arg.float_; }
57template<> std::string get_execute_arg_value<std::string>(const ExecuteServiceArgument &arg) { return arg.string_; }
58// Zero-copy StringRef version for YAML-generated services (string_ is null-terminated after decode)
60
61// Legacy std::vector versions for external components using custom_api_device.h - optimized with reserve
62template<> std::vector<bool> get_execute_arg_value<std::vector<bool>>(const ExecuteServiceArgument &arg) {
63 std::vector<bool> result;
64 result.reserve(arg.bool_array.size());
65 result.insert(result.end(), arg.bool_array.begin(), arg.bool_array.end());
66 return result;
67}
68template<> std::vector<int32_t> get_execute_arg_value<std::vector<int32_t>>(const ExecuteServiceArgument &arg) {
69 std::vector<int32_t> result;
70 result.reserve(arg.int_array.size());
71 result.insert(result.end(), arg.int_array.begin(), arg.int_array.end());
72 return result;
73}
74template<> std::vector<float> get_execute_arg_value<std::vector<float>>(const ExecuteServiceArgument &arg) {
75 std::vector<float> result;
76 result.reserve(arg.float_array.size());
77 result.insert(result.end(), arg.float_array.begin(), arg.float_array.end());
78 return result;
79}
80template<> std::vector<std::string> get_execute_arg_value<std::vector<std::string>>(const ExecuteServiceArgument &arg) {
81 std::vector<std::string> result;
82 result.reserve(arg.string_array.size());
83 result.insert(result.end(), arg.string_array.begin(), arg.string_array.end());
84 return result;
85}
86
87// New FixedVector const reference versions for YAML-generated services - zero-copy
88template<>
92template<>
96template<>
100template<>
105
110// Zero-copy StringRef version for YAML-generated services
112
113// Legacy std::vector versions for external components using custom_api_device.h
124
125// New FixedVector const reference versions for YAML-generated services
138
139} // namespace esphome::api
Fixed-capacity vector - allocates once at runtime, never reallocates This avoids std::vector template...
Definition helpers.h:545
StringRef is a reference to a string owned by something else.
Definition string_ref.h:26
enums::SupportsResponseType supports_response
Definition api_pb2.h:1344
FixedVector< ListEntitiesServicesArgument > args
Definition api_pb2.h:1343
StringRef str_(size_t idx, std::span< char > &scratch) const
Reference table entry idx; nullptr gives an empty StringRef.
ListEntitiesServicesResponse encode_list_service_response_(std::span< const enums::ServiceArgType > arg_types, std::span< char > scratch) const
enums::SupportsResponseType supports_response_
@ SERVICE_ARG_TYPE_BOOL_ARRAY
Definition api_pb2.h:91
@ SERVICE_ARG_TYPE_STRING_ARRAY
Definition api_pb2.h:94
@ SERVICE_ARG_TYPE_FLOAT_ARRAY
Definition api_pb2.h:93
float get_execute_arg_value< float >(const ExecuteServiceArgument &arg)
bool get_execute_arg_value< bool >(const ExecuteServiceArgument &arg)
int32_t get_execute_arg_value< int32_t >(const ExecuteServiceArgument &arg)
enums::ServiceArgType to_service_arg_type()
enums::ServiceArgType to_service_arg_type< StringRef >()
StringRef get_execute_arg_value< StringRef >(const ExecuteServiceArgument &arg)
enums::ServiceArgType to_service_arg_type< int32_t >()
enums::ServiceArgType to_service_arg_type< bool >()
enums::ServiceArgType to_service_arg_type< std::string >()
std::string get_execute_arg_value< std::string >(const ExecuteServiceArgument &arg)
T get_execute_arg_value(const ExecuteServiceArgument &arg)
enums::ServiceArgType to_service_arg_type< float >()
const char * progmem_read_ptr(const char *const *addr)
Definition hal.h:44
void progmem_memcpy(void *dst, const void *src, size_t len)
Definition hal.h:48
const void size_t len
Definition hal.h:64
watchdog_hw scratch[0]