mirror of
https://github.com/esphome/esphome.git
synced 2025-08-11 04:39:30 +00:00
Compare commits
106 Commits
memory
...
error-outp
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b3b55c6b6b | ||
![]() |
52204b2439 | ||
![]() |
296442d8f1 | ||
![]() |
fd442cc485 | ||
![]() |
4f58e1c8b9 | ||
![]() |
00d9baed11 | ||
![]() |
f1877ca084 | ||
![]() |
1f7c59f88d | ||
![]() |
b5f42bc493 | ||
![]() |
d8a46c7482 | ||
![]() |
20ad1ab4eb | ||
![]() |
940a8b43fa | ||
![]() |
f761404bf6 | ||
![]() |
e4dc62ea74 | ||
![]() |
c42c5dd946 | ||
![]() |
291215909a | ||
![]() |
0954a6185c | ||
![]() |
f13e742bd5 | ||
![]() |
7a4738ec4e | ||
![]() |
549b0d12b6 | ||
![]() |
412f4ac341 | ||
![]() |
d4ff1bcf5c | ||
![]() |
161f51e1f4 | ||
![]() |
da0c47629a | ||
![]() |
28b277c1c4 | ||
![]() |
936a090aaa | ||
![]() |
1be6d27012 | ||
![]() |
71557c9f58 | ||
![]() |
88cfcc1967 | ||
![]() |
fb379bbb88 | ||
![]() |
88d8cfe6a2 | ||
![]() |
f25abc3248 | ||
![]() |
5b6e152d6c | ||
![]() |
1d0a38446f | ||
![]() |
853dca6c5c | ||
![]() |
97560fd9ef | ||
![]() |
4b7f3355ea | ||
![]() |
110eac4f09 | ||
![]() |
79533cb0d7 | ||
![]() |
f4f69e827b | ||
![]() |
48a4dde824 | ||
![]() |
9b4fe54f45 | ||
![]() |
913c58cd2c | ||
![]() |
374858efeb | ||
![]() |
14dd48f9c3 | ||
![]() |
76d33308d9 | ||
![]() |
daccaf36a7 | ||
![]() |
56c88807ee | ||
![]() |
9c6dbbd8ea | ||
![]() |
a7dd849a8e | ||
![]() |
1f0c606be4 | ||
![]() |
ace375944c | ||
![]() |
5f7c2f771f | ||
![]() |
3d5b602288 | ||
![]() |
6d30269565 | ||
![]() |
4ff3137c0d | ||
![]() |
9d43ddd6f1 | ||
![]() |
f733c43dec | ||
![]() |
f5f0a01a85 | ||
![]() |
908891a096 | ||
![]() |
7657316a92 | ||
![]() |
4f425c700a | ||
![]() |
2c9987869e | ||
![]() |
68f388f78e | ||
![]() |
189d20a822 | ||
![]() |
08defd7360 | ||
![]() |
59d466a6c8 | ||
![]() |
85435e6b5f | ||
![]() |
f9453f9642 | ||
![]() |
f6cdbe37f9 | ||
![]() |
d6b222c370 | ||
![]() |
eecdaa5163 | ||
![]() |
4933ef780b | ||
![]() |
1702356fc8 | ||
![]() |
05f6d01cbe | ||
![]() |
573dad1736 | ||
![]() |
3a6cc0ea3d | ||
![]() |
2f9475a927 | ||
![]() |
8dce7b0905 | ||
![]() |
8b0ad3072f | ||
![]() |
93028a4d90 | ||
![]() |
c9793f3741 | ||
![]() |
5029e248eb | ||
![]() |
087970bca8 | ||
![]() |
7f0c66f835 | ||
![]() |
84ed1bcf34 | ||
![]() |
6ed9214465 | ||
![]() |
a3690422bf | ||
![]() |
20b61d4bdb | ||
![]() |
a2ed209542 | ||
![]() |
14862904ac | ||
![]() |
bcc56648c0 | ||
![]() |
e00839a608 | ||
![]() |
cf73f72119 | ||
![]() |
981b906579 | ||
![]() |
0e2520e4c0 | ||
![]() |
84ffa4274c | ||
![]() |
d64e4d3c49 | ||
![]() |
d54db471bd | ||
![]() |
a9d6ece752 | ||
![]() |
da491f7090 | ||
![]() |
11f970edec | ||
![]() |
6d37b916dc | ||
![]() |
b6e0188c42 | ||
![]() |
b7ce8c116b | ||
![]() |
2b87589562 |
@@ -1 +1 @@
|
||||
32b0db73b3ae01ba18c9cbb1dabbd8156bc14dded500471919bd0a3dc33916e0
|
||||
6af8b429b94191fe8e239fcb3b73f7982d0266cb5b05ffbc81edaeac1bc8c273
|
||||
|
42
.github/workflows/auto-label-pr.yml
vendored
42
.github/workflows/auto-label-pr.yml
vendored
@@ -63,7 +63,11 @@ jobs:
|
||||
'needs-docs',
|
||||
'needs-codeowners',
|
||||
'too-big',
|
||||
'labeller-recheck'
|
||||
'labeller-recheck',
|
||||
'bugfix',
|
||||
'new-feature',
|
||||
'breaking-change',
|
||||
'code-quality'
|
||||
];
|
||||
|
||||
const DOCS_PR_PATTERNS = [
|
||||
@@ -341,6 +345,31 @@ jobs:
|
||||
return labels;
|
||||
}
|
||||
|
||||
// Strategy: PR Template Checkbox detection
|
||||
async function detectPRTemplateCheckboxes() {
|
||||
const labels = new Set();
|
||||
const prBody = context.payload.pull_request.body || '';
|
||||
|
||||
console.log('Checking PR template checkboxes...');
|
||||
|
||||
// Check for checked checkboxes in the "Types of changes" section
|
||||
const checkboxPatterns = [
|
||||
{ pattern: /- \[x\] Bugfix \(non-breaking change which fixes an issue\)/i, label: 'bugfix' },
|
||||
{ pattern: /- \[x\] New feature \(non-breaking change which adds functionality\)/i, label: 'new-feature' },
|
||||
{ pattern: /- \[x\] Breaking change \(fix or feature that would cause existing functionality to not work as expected\)/i, label: 'breaking-change' },
|
||||
{ pattern: /- \[x\] Code quality improvements to existing code or addition of tests/i, label: 'code-quality' }
|
||||
];
|
||||
|
||||
for (const { pattern, label } of checkboxPatterns) {
|
||||
if (pattern.test(prBody)) {
|
||||
console.log(`Found checked checkbox for: ${label}`);
|
||||
labels.add(label);
|
||||
}
|
||||
}
|
||||
|
||||
return labels;
|
||||
}
|
||||
|
||||
// Strategy: Requirements detection
|
||||
async function detectRequirements(allLabels) {
|
||||
const labels = new Set();
|
||||
@@ -351,7 +380,7 @@ jobs:
|
||||
}
|
||||
|
||||
// Check for missing docs
|
||||
if (allLabels.has('new-component') || allLabels.has('new-platform')) {
|
||||
if (allLabels.has('new-component') || allLabels.has('new-platform') || allLabels.has('new-feature')) {
|
||||
const prBody = context.payload.pull_request.body || '';
|
||||
const hasDocsLink = DOCS_PR_PATTERNS.some(pattern => pattern.test(prBody));
|
||||
|
||||
@@ -535,7 +564,8 @@ jobs:
|
||||
dashboardLabels,
|
||||
actionsLabels,
|
||||
codeOwnerLabels,
|
||||
testLabels
|
||||
testLabels,
|
||||
checkboxLabels
|
||||
] = await Promise.all([
|
||||
detectMergeBranch(),
|
||||
detectComponentPlatforms(apiData),
|
||||
@@ -546,7 +576,8 @@ jobs:
|
||||
detectDashboardChanges(),
|
||||
detectGitHubActionsChanges(),
|
||||
detectCodeOwner(),
|
||||
detectTests()
|
||||
detectTests(),
|
||||
detectPRTemplateCheckboxes()
|
||||
]);
|
||||
|
||||
// Combine all labels
|
||||
@@ -560,7 +591,8 @@ jobs:
|
||||
...dashboardLabels,
|
||||
...actionsLabels,
|
||||
...codeOwnerLabels,
|
||||
...testLabels
|
||||
...testLabels,
|
||||
...checkboxLabels
|
||||
]);
|
||||
|
||||
// Detect requirements based on all other labels
|
||||
|
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -281,7 +281,7 @@ jobs:
|
||||
pio_cache_key: tidyesp32-idf
|
||||
- id: clang-tidy
|
||||
name: Run script/clang-tidy for ZEPHYR
|
||||
options: --environment nrf52-tidy --grep USE_ZEPHYR
|
||||
options: --environment nrf52-tidy --grep USE_ZEPHYR --grep USE_NRF52
|
||||
pio_cache_key: tidy-zephyr
|
||||
ignore_errors: false
|
||||
|
||||
|
@@ -11,7 +11,7 @@ ci:
|
||||
repos:
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.12.5
|
||||
rev: v0.12.7
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff
|
||||
|
@@ -155,6 +155,7 @@ esphome/components/esp32_rmt/* @jesserockz
|
||||
esphome/components/esp32_rmt_led_strip/* @jesserockz
|
||||
esphome/components/esp8266/* @esphome/core
|
||||
esphome/components/esp_ldo/* @clydebarrow
|
||||
esphome/components/espnow/* @jesserockz
|
||||
esphome/components/ethernet_info/* @gtjadsonsantos
|
||||
esphome/components/event/* @nohat
|
||||
esphome/components/event_emitter/* @Rapsssito
|
||||
@@ -294,6 +295,7 @@ esphome/components/microphone/* @jesserockz @kahrendt
|
||||
esphome/components/mics_4514/* @jesserockz
|
||||
esphome/components/midea/* @dudanov
|
||||
esphome/components/midea_ir/* @dudanov
|
||||
esphome/components/mipi_dsi/* @clydebarrow
|
||||
esphome/components/mipi_spi/* @clydebarrow
|
||||
esphome/components/mitsubishi/* @RubyBailey
|
||||
esphome/components/mixer/speaker/* @kahrendt
|
||||
@@ -471,7 +473,7 @@ esphome/components/tlc5971/* @IJIJI
|
||||
esphome/components/tm1621/* @Philippe12
|
||||
esphome/components/tm1637/* @glmnet
|
||||
esphome/components/tm1638/* @skykingjwc
|
||||
esphome/components/tm1651/* @freekode
|
||||
esphome/components/tm1651/* @mrtoy-me
|
||||
esphome/components/tmp102/* @timsavage
|
||||
esphome/components/tmp1075/* @sybrenstuvel
|
||||
esphome/components/tmp117/* @Azimath
|
||||
|
@@ -2,6 +2,7 @@
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
import functools
|
||||
import getpass
|
||||
import importlib
|
||||
import logging
|
||||
import os
|
||||
@@ -335,7 +336,7 @@ def check_permissions(port):
|
||||
raise EsphomeError(
|
||||
"You do not have read or write permission on the selected serial port. "
|
||||
"To resolve this issue, you can add your user to the dialout group "
|
||||
f"by running the following command: sudo usermod -a -G dialout {os.getlogin()}. "
|
||||
f"by running the following command: sudo usermod -a -G dialout {getpass.getuser()}. "
|
||||
"You will need to log out & back in or reboot to activate the new group access."
|
||||
)
|
||||
|
||||
@@ -463,13 +464,6 @@ def command_vscode(args):
|
||||
|
||||
|
||||
def command_compile(args, config):
|
||||
# Set memory analysis options in config
|
||||
if args.analyze_memory:
|
||||
config.setdefault(CONF_ESPHOME, {})["analyze_memory"] = True
|
||||
|
||||
if args.memory_report:
|
||||
config.setdefault(CONF_ESPHOME, {})["memory_report_file"] = args.memory_report
|
||||
|
||||
exit_code = write_cpp(config)
|
||||
if exit_code != 0:
|
||||
return exit_code
|
||||
@@ -849,17 +843,6 @@ def parse_args(argv):
|
||||
help="Only generate source code, do not compile.",
|
||||
action="store_true",
|
||||
)
|
||||
parser_compile.add_argument(
|
||||
"--analyze-memory",
|
||||
help="Analyze and display memory usage by component after compilation.",
|
||||
action="store_true",
|
||||
)
|
||||
parser_compile.add_argument(
|
||||
"--memory-report",
|
||||
help="Save memory analysis report to a file (supports .json or .txt).",
|
||||
type=str,
|
||||
metavar="FILE",
|
||||
)
|
||||
|
||||
parser_upload = subparsers.add_parser(
|
||||
"upload",
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -391,8 +391,7 @@ async def build_action(full_config, template_arg, args):
|
||||
)
|
||||
action_id = full_config[CONF_TYPE_ID]
|
||||
builder = registry_entry.coroutine_fun
|
||||
ret = await builder(config, action_id, template_arg, args)
|
||||
return ret
|
||||
return await builder(config, action_id, template_arg, args)
|
||||
|
||||
|
||||
async def build_action_list(config, templ, arg_type):
|
||||
@@ -409,8 +408,7 @@ async def build_condition(full_config, template_arg, args):
|
||||
)
|
||||
action_id = full_config[CONF_TYPE_ID]
|
||||
builder = registry_entry.coroutine_fun
|
||||
ret = await builder(config, action_id, template_arg, args)
|
||||
return ret
|
||||
return await builder(config, action_id, template_arg, args)
|
||||
|
||||
|
||||
async def build_condition_list(config, templ, args):
|
||||
|
@@ -7,7 +7,6 @@ namespace a4988 {
|
||||
static const char *const TAG = "a4988.stepper";
|
||||
|
||||
void A4988::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
if (this->sleep_pin_ != nullptr) {
|
||||
this->sleep_pin_->setup();
|
||||
this->sleep_pin_->digital_write(false);
|
||||
|
@@ -7,8 +7,6 @@ namespace absolute_humidity {
|
||||
static const char *const TAG = "absolute_humidity.sensor";
|
||||
|
||||
void AbsoluteHumidityComponent::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup for '%s'", this->get_name().c_str());
|
||||
|
||||
ESP_LOGD(TAG, " Added callback for temperature '%s'", this->temperature_sensor_->get_name().c_str());
|
||||
this->temperature_sensor_->add_on_state_callback([this](float state) { this->temperature_callback_(state); });
|
||||
if (this->temperature_sensor_->has_state()) {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
from esphome.components.esp32 import get_esp32_variant
|
||||
from esphome.components.esp32 import VARIANT_ESP32P4, get_esp32_variant
|
||||
from esphome.components.esp32.const import (
|
||||
VARIANT_ESP32,
|
||||
VARIANT_ESP32C2,
|
||||
@@ -140,6 +140,16 @@ ESP32_VARIANT_ADC1_PIN_TO_CHANNEL = {
|
||||
9: adc_channel_t.ADC_CHANNEL_8,
|
||||
10: adc_channel_t.ADC_CHANNEL_9,
|
||||
},
|
||||
VARIANT_ESP32P4: {
|
||||
16: adc_channel_t.ADC_CHANNEL_0,
|
||||
17: adc_channel_t.ADC_CHANNEL_1,
|
||||
18: adc_channel_t.ADC_CHANNEL_2,
|
||||
19: adc_channel_t.ADC_CHANNEL_3,
|
||||
20: adc_channel_t.ADC_CHANNEL_4,
|
||||
21: adc_channel_t.ADC_CHANNEL_5,
|
||||
22: adc_channel_t.ADC_CHANNEL_6,
|
||||
23: adc_channel_t.ADC_CHANNEL_7,
|
||||
},
|
||||
}
|
||||
|
||||
# pin to adc2 channel mapping
|
||||
@@ -198,6 +208,14 @@ ESP32_VARIANT_ADC2_PIN_TO_CHANNEL = {
|
||||
19: adc_channel_t.ADC_CHANNEL_8,
|
||||
20: adc_channel_t.ADC_CHANNEL_9,
|
||||
},
|
||||
VARIANT_ESP32P4: {
|
||||
49: adc_channel_t.ADC_CHANNEL_0,
|
||||
50: adc_channel_t.ADC_CHANNEL_1,
|
||||
51: adc_channel_t.ADC_CHANNEL_2,
|
||||
52: adc_channel_t.ADC_CHANNEL_3,
|
||||
53: adc_channel_t.ADC_CHANNEL_4,
|
||||
54: adc_channel_t.ADC_CHANNEL_5,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -249,6 +267,11 @@ def validate_adc_pin(value):
|
||||
{CONF_ANALOG: True, CONF_INPUT: True}, internal=True
|
||||
)(value)
|
||||
|
||||
if CORE.is_nrf52:
|
||||
return pins.gpio_pin_schema(
|
||||
{CONF_ANALOG: True, CONF_INPUT: True}, internal=True
|
||||
)(value)
|
||||
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
@@ -265,5 +288,6 @@ FILTER_SOURCE_FILES = filter_source_files_from_platform(
|
||||
PlatformFramework.RTL87XX_ARDUINO,
|
||||
PlatformFramework.LN882X_ARDUINO,
|
||||
},
|
||||
"adc_sensor_zephyr.cpp": {PlatformFramework.NRF52_ZEPHYR},
|
||||
}
|
||||
)
|
||||
|
@@ -13,6 +13,10 @@
|
||||
#include "hal/adc_types.h" // This defines ADC_CHANNEL_MAX
|
||||
#endif // USE_ESP32
|
||||
|
||||
#ifdef USE_ZEPHYR
|
||||
#include <zephyr/drivers/adc.h>
|
||||
#endif
|
||||
|
||||
namespace esphome {
|
||||
namespace adc {
|
||||
|
||||
@@ -38,15 +42,15 @@ enum class SamplingMode : uint8_t {
|
||||
|
||||
const LogString *sampling_mode_to_str(SamplingMode mode);
|
||||
|
||||
class Aggregator {
|
||||
template<typename T> class Aggregator {
|
||||
public:
|
||||
Aggregator(SamplingMode mode);
|
||||
void add_sample(uint32_t value);
|
||||
uint32_t aggregate();
|
||||
void add_sample(T value);
|
||||
T aggregate();
|
||||
|
||||
protected:
|
||||
uint32_t aggr_{0};
|
||||
uint32_t samples_{0};
|
||||
T aggr_{0};
|
||||
uint8_t samples_{0};
|
||||
SamplingMode mode_{SamplingMode::AVG};
|
||||
};
|
||||
|
||||
@@ -69,6 +73,11 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
||||
/// @return A float representing the setup priority.
|
||||
float get_setup_priority() const override;
|
||||
|
||||
#ifdef USE_ZEPHYR
|
||||
/// Set the ADC channel to be used by the ADC sensor.
|
||||
/// @param channel Pointer to an adc_dt_spec structure representing the ADC channel.
|
||||
void set_adc_channel(const adc_dt_spec *channel) { this->channel_ = channel; }
|
||||
#endif
|
||||
/// Set the GPIO pin to be used by the ADC sensor.
|
||||
/// @param pin Pointer to an InternalGPIOPin representing the ADC input pin.
|
||||
void set_pin(InternalGPIOPin *pin) { this->pin_ = pin; }
|
||||
@@ -136,8 +145,8 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
||||
adc_oneshot_unit_handle_t adc_handle_{nullptr};
|
||||
adc_cali_handle_t calibration_handle_{nullptr};
|
||||
adc_atten_t attenuation_{ADC_ATTEN_DB_0};
|
||||
adc_channel_t channel_;
|
||||
adc_unit_t adc_unit_;
|
||||
adc_channel_t channel_{};
|
||||
adc_unit_t adc_unit_{};
|
||||
struct SetupFlags {
|
||||
uint8_t init_complete : 1;
|
||||
uint8_t config_complete : 1;
|
||||
@@ -151,6 +160,10 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
||||
#ifdef USE_RP2040
|
||||
bool is_temperature_{false};
|
||||
#endif // USE_RP2040
|
||||
|
||||
#ifdef USE_ZEPHYR
|
||||
const struct adc_dt_spec *channel_ = nullptr;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace adc
|
||||
|
@@ -18,15 +18,15 @@ const LogString *sampling_mode_to_str(SamplingMode mode) {
|
||||
return LOG_STR("unknown");
|
||||
}
|
||||
|
||||
Aggregator::Aggregator(SamplingMode mode) {
|
||||
template<typename T> Aggregator<T>::Aggregator(SamplingMode mode) {
|
||||
this->mode_ = mode;
|
||||
// set to max uint if mode is "min"
|
||||
if (mode == SamplingMode::MIN) {
|
||||
this->aggr_ = UINT32_MAX;
|
||||
this->aggr_ = std::numeric_limits<T>::max();
|
||||
}
|
||||
}
|
||||
|
||||
void Aggregator::add_sample(uint32_t value) {
|
||||
template<typename T> void Aggregator<T>::add_sample(T value) {
|
||||
this->samples_ += 1;
|
||||
|
||||
switch (this->mode_) {
|
||||
@@ -47,7 +47,7 @@ void Aggregator::add_sample(uint32_t value) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t Aggregator::aggregate() {
|
||||
template<typename T> T Aggregator<T>::aggregate() {
|
||||
if (this->mode_ == SamplingMode::AVG) {
|
||||
if (this->samples_ == 0) {
|
||||
return this->aggr_;
|
||||
@@ -59,6 +59,12 @@ uint32_t Aggregator::aggregate() {
|
||||
return this->aggr_;
|
||||
}
|
||||
|
||||
#ifdef USE_ZEPHYR
|
||||
template class Aggregator<int32_t>;
|
||||
#else
|
||||
template class Aggregator<uint32_t>;
|
||||
#endif
|
||||
|
||||
void ADCSensor::update() {
|
||||
float value_v = this->sample();
|
||||
ESP_LOGV(TAG, "'%s': Voltage=%.4fV", this->get_name().c_str(), value_v);
|
||||
|
@@ -37,7 +37,6 @@ const LogString *adc_unit_to_str(adc_unit_t unit) {
|
||||
}
|
||||
|
||||
void ADCSensor::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup for '%s'", this->get_name().c_str());
|
||||
// Check if another sensor already initialized this ADC unit
|
||||
if (ADCSensor::shared_adc_handles[this->adc_unit_] == nullptr) {
|
||||
adc_oneshot_unit_init_cfg_t init_config = {}; // Zero initialize
|
||||
@@ -73,10 +72,9 @@ void ADCSensor::setup() {
|
||||
// Initialize ADC calibration
|
||||
if (this->calibration_handle_ == nullptr) {
|
||||
adc_cali_handle_t handle = nullptr;
|
||||
esp_err_t err;
|
||||
|
||||
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
|
||||
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2
|
||||
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
|
||||
// RISC-V variants and S3 use curve fitting calibration
|
||||
adc_cali_curve_fitting_config_t cali_config = {}; // Zero initialize first
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
|
||||
@@ -154,7 +152,7 @@ float ADCSensor::sample() {
|
||||
}
|
||||
|
||||
float ADCSensor::sample_fixed_attenuation_() {
|
||||
auto aggr = Aggregator(this->sampling_mode_);
|
||||
auto aggr = Aggregator<uint32_t>(this->sampling_mode_);
|
||||
|
||||
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
|
||||
int raw;
|
||||
@@ -188,7 +186,7 @@ float ADCSensor::sample_fixed_attenuation_() {
|
||||
ESP_LOGW(TAG, "ADC calibration conversion failed with error %d, disabling calibration", err);
|
||||
if (this->calibration_handle_ != nullptr) {
|
||||
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
|
||||
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2
|
||||
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
|
||||
adc_cali_delete_scheme_curve_fitting(this->calibration_handle_);
|
||||
#else // Other ESP32 variants use line fitting calibration
|
||||
adc_cali_delete_scheme_line_fitting(this->calibration_handle_);
|
||||
@@ -221,7 +219,7 @@ float ADCSensor::sample_autorange_() {
|
||||
if (this->calibration_handle_ != nullptr) {
|
||||
// Delete old calibration handle
|
||||
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
|
||||
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2
|
||||
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
|
||||
adc_cali_delete_scheme_curve_fitting(this->calibration_handle_);
|
||||
#else
|
||||
adc_cali_delete_scheme_line_fitting(this->calibration_handle_);
|
||||
@@ -233,7 +231,7 @@ float ADCSensor::sample_autorange_() {
|
||||
adc_cali_handle_t handle = nullptr;
|
||||
|
||||
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
|
||||
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2
|
||||
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
|
||||
adc_cali_curve_fitting_config_t cali_config = {};
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
|
||||
cali_config.chan = this->channel_;
|
||||
@@ -262,7 +260,7 @@ float ADCSensor::sample_autorange_() {
|
||||
ESP_LOGW(TAG, "ADC read failed in autorange with error %d", err);
|
||||
if (handle != nullptr) {
|
||||
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
|
||||
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2
|
||||
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
|
||||
adc_cali_delete_scheme_curve_fitting(handle);
|
||||
#else
|
||||
adc_cali_delete_scheme_line_fitting(handle);
|
||||
@@ -282,7 +280,7 @@ float ADCSensor::sample_autorange_() {
|
||||
}
|
||||
// Clean up calibration handle
|
||||
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
|
||||
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2
|
||||
USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4
|
||||
adc_cali_delete_scheme_curve_fitting(handle);
|
||||
#else
|
||||
adc_cali_delete_scheme_line_fitting(handle);
|
||||
|
@@ -17,7 +17,6 @@ namespace adc {
|
||||
static const char *const TAG = "adc.esp8266";
|
||||
|
||||
void ADCSensor::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup for '%s'", this->get_name().c_str());
|
||||
#ifndef USE_ADC_SENSOR_VCC
|
||||
this->pin_->setup();
|
||||
#endif
|
||||
@@ -38,7 +37,7 @@ void ADCSensor::dump_config() {
|
||||
}
|
||||
|
||||
float ADCSensor::sample() {
|
||||
auto aggr = Aggregator(this->sampling_mode_);
|
||||
auto aggr = Aggregator<uint32_t>(this->sampling_mode_);
|
||||
|
||||
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
|
||||
uint32_t raw = 0;
|
||||
|
@@ -9,7 +9,6 @@ namespace adc {
|
||||
static const char *const TAG = "adc.libretiny";
|
||||
|
||||
void ADCSensor::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup for '%s'", this->get_name().c_str());
|
||||
#ifndef USE_ADC_SENSOR_VCC
|
||||
this->pin_->setup();
|
||||
#endif // !USE_ADC_SENSOR_VCC
|
||||
@@ -31,7 +30,7 @@ void ADCSensor::dump_config() {
|
||||
|
||||
float ADCSensor::sample() {
|
||||
uint32_t raw = 0;
|
||||
auto aggr = Aggregator(this->sampling_mode_);
|
||||
auto aggr = Aggregator<uint32_t>(this->sampling_mode_);
|
||||
|
||||
if (this->output_raw_) {
|
||||
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
|
||||
|
@@ -14,7 +14,6 @@ namespace adc {
|
||||
static const char *const TAG = "adc.rp2040";
|
||||
|
||||
void ADCSensor::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup for '%s'", this->get_name().c_str());
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
adc_init();
|
||||
@@ -42,7 +41,7 @@ void ADCSensor::dump_config() {
|
||||
|
||||
float ADCSensor::sample() {
|
||||
uint32_t raw = 0;
|
||||
auto aggr = Aggregator(this->sampling_mode_);
|
||||
auto aggr = Aggregator<uint32_t>(this->sampling_mode_);
|
||||
|
||||
if (this->is_temperature_) {
|
||||
adc_set_temp_sensor_enabled(true);
|
||||
|
207
esphome/components/adc/adc_sensor_zephyr.cpp
Normal file
207
esphome/components/adc/adc_sensor_zephyr.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
|
||||
#include "adc_sensor.h"
|
||||
#ifdef USE_ZEPHYR
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
#include "hal/nrf_saadc.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace adc {
|
||||
|
||||
static const char *const TAG = "adc.zephyr";
|
||||
|
||||
void ADCSensor::setup() {
|
||||
if (!adc_is_ready_dt(this->channel_)) {
|
||||
ESP_LOGE(TAG, "ADC controller device %s not ready", this->channel_->dev->name);
|
||||
return;
|
||||
}
|
||||
|
||||
auto err = adc_channel_setup_dt(this->channel_);
|
||||
if (err < 0) {
|
||||
ESP_LOGE(TAG, "Could not setup channel %s (%d)", this->channel_->dev->name, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
|
||||
static const LogString *gain_to_str(enum adc_gain gain) {
|
||||
switch (gain) {
|
||||
case ADC_GAIN_1_6:
|
||||
return LOG_STR("1/6");
|
||||
case ADC_GAIN_1_5:
|
||||
return LOG_STR("1/5");
|
||||
case ADC_GAIN_1_4:
|
||||
return LOG_STR("1/4");
|
||||
case ADC_GAIN_1_3:
|
||||
return LOG_STR("1/3");
|
||||
case ADC_GAIN_2_5:
|
||||
return LOG_STR("2/5");
|
||||
case ADC_GAIN_1_2:
|
||||
return LOG_STR("1/2");
|
||||
case ADC_GAIN_2_3:
|
||||
return LOG_STR("2/3");
|
||||
case ADC_GAIN_4_5:
|
||||
return LOG_STR("4/5");
|
||||
case ADC_GAIN_1:
|
||||
return LOG_STR("1");
|
||||
case ADC_GAIN_2:
|
||||
return LOG_STR("2");
|
||||
case ADC_GAIN_3:
|
||||
return LOG_STR("3");
|
||||
case ADC_GAIN_4:
|
||||
return LOG_STR("4");
|
||||
case ADC_GAIN_6:
|
||||
return LOG_STR("6");
|
||||
case ADC_GAIN_8:
|
||||
return LOG_STR("8");
|
||||
case ADC_GAIN_12:
|
||||
return LOG_STR("12");
|
||||
case ADC_GAIN_16:
|
||||
return LOG_STR("16");
|
||||
case ADC_GAIN_24:
|
||||
return LOG_STR("24");
|
||||
case ADC_GAIN_32:
|
||||
return LOG_STR("32");
|
||||
case ADC_GAIN_64:
|
||||
return LOG_STR("64");
|
||||
case ADC_GAIN_128:
|
||||
return LOG_STR("128");
|
||||
}
|
||||
return LOG_STR("undefined gain");
|
||||
}
|
||||
|
||||
static const LogString *reference_to_str(enum adc_reference reference) {
|
||||
switch (reference) {
|
||||
case ADC_REF_VDD_1:
|
||||
return LOG_STR("VDD");
|
||||
case ADC_REF_VDD_1_2:
|
||||
return LOG_STR("VDD/2");
|
||||
case ADC_REF_VDD_1_3:
|
||||
return LOG_STR("VDD/3");
|
||||
case ADC_REF_VDD_1_4:
|
||||
return LOG_STR("VDD/4");
|
||||
case ADC_REF_INTERNAL:
|
||||
return LOG_STR("INTERNAL");
|
||||
case ADC_REF_EXTERNAL0:
|
||||
return LOG_STR("External, input 0");
|
||||
case ADC_REF_EXTERNAL1:
|
||||
return LOG_STR("External, input 1");
|
||||
}
|
||||
return LOG_STR("undefined reference");
|
||||
}
|
||||
|
||||
static const LogString *input_to_str(uint8_t input) {
|
||||
switch (input) {
|
||||
case NRF_SAADC_INPUT_AIN0:
|
||||
return LOG_STR("AIN0");
|
||||
case NRF_SAADC_INPUT_AIN1:
|
||||
return LOG_STR("AIN1");
|
||||
case NRF_SAADC_INPUT_AIN2:
|
||||
return LOG_STR("AIN2");
|
||||
case NRF_SAADC_INPUT_AIN3:
|
||||
return LOG_STR("AIN3");
|
||||
case NRF_SAADC_INPUT_AIN4:
|
||||
return LOG_STR("AIN4");
|
||||
case NRF_SAADC_INPUT_AIN5:
|
||||
return LOG_STR("AIN5");
|
||||
case NRF_SAADC_INPUT_AIN6:
|
||||
return LOG_STR("AIN6");
|
||||
case NRF_SAADC_INPUT_AIN7:
|
||||
return LOG_STR("AIN7");
|
||||
case NRF_SAADC_INPUT_VDD:
|
||||
return LOG_STR("VDD");
|
||||
case NRF_SAADC_INPUT_VDDHDIV5:
|
||||
return LOG_STR("VDDHDIV5");
|
||||
}
|
||||
return LOG_STR("undefined input");
|
||||
}
|
||||
#endif // ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
|
||||
|
||||
void ADCSensor::dump_config() {
|
||||
LOG_SENSOR("", "ADC Sensor", this);
|
||||
LOG_PIN(" Pin: ", this->pin_);
|
||||
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
|
||||
ESP_LOGV(TAG,
|
||||
" Name: %s\n"
|
||||
" Channel: %d\n"
|
||||
" vref_mv: %d\n"
|
||||
" Resolution %d\n"
|
||||
" Oversampling %d",
|
||||
this->channel_->dev->name, this->channel_->channel_id, this->channel_->vref_mv, this->channel_->resolution,
|
||||
this->channel_->oversampling);
|
||||
|
||||
ESP_LOGV(TAG,
|
||||
" Gain: %s\n"
|
||||
" reference: %s\n"
|
||||
" acquisition_time: %d\n"
|
||||
" differential %s",
|
||||
LOG_STR_ARG(gain_to_str(this->channel_->channel_cfg.gain)),
|
||||
LOG_STR_ARG(reference_to_str(this->channel_->channel_cfg.reference)),
|
||||
this->channel_->channel_cfg.acquisition_time, YESNO(this->channel_->channel_cfg.differential));
|
||||
if (this->channel_->channel_cfg.differential) {
|
||||
ESP_LOGV(TAG,
|
||||
" Positive: %s\n"
|
||||
" Negative: %s",
|
||||
LOG_STR_ARG(input_to_str(this->channel_->channel_cfg.input_positive)),
|
||||
LOG_STR_ARG(input_to_str(this->channel_->channel_cfg.input_negative)));
|
||||
} else {
|
||||
ESP_LOGV(TAG, " Positive: %s", LOG_STR_ARG(input_to_str(this->channel_->channel_cfg.input_positive)));
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
}
|
||||
|
||||
float ADCSensor::sample() {
|
||||
auto aggr = Aggregator<int32_t>(this->sampling_mode_);
|
||||
int err;
|
||||
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
|
||||
int16_t buf = 0;
|
||||
struct adc_sequence sequence = {
|
||||
.buffer = &buf,
|
||||
/* buffer size in bytes, not number of samples */
|
||||
.buffer_size = sizeof(buf),
|
||||
};
|
||||
int32_t val_raw;
|
||||
|
||||
err = adc_sequence_init_dt(this->channel_, &sequence);
|
||||
if (err < 0) {
|
||||
ESP_LOGE(TAG, "Could sequence init %s (%d)", this->channel_->dev->name, err);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
err = adc_read(this->channel_->dev, &sequence);
|
||||
if (err < 0) {
|
||||
ESP_LOGE(TAG, "Could not read %s (%d)", this->channel_->dev->name, err);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
val_raw = (int32_t) buf;
|
||||
if (!this->channel_->channel_cfg.differential) {
|
||||
// https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/0ed4d9ffc674ae407be7cacf5696a02f5e789861/cores/nRF5/wiring_analog_nRF52.c#L222
|
||||
if (val_raw < 0) {
|
||||
val_raw = 0;
|
||||
}
|
||||
}
|
||||
aggr.add_sample(val_raw);
|
||||
}
|
||||
|
||||
int32_t val_mv = aggr.aggregate();
|
||||
|
||||
if (this->output_raw_) {
|
||||
return val_mv;
|
||||
}
|
||||
|
||||
err = adc_raw_to_millivolts_dt(this->channel_, &val_mv);
|
||||
/* conversion to mV may not be supported, skip if not */
|
||||
if (err < 0) {
|
||||
ESP_LOGE(TAG, "Value in mV not available %s (%d)", this->channel_->dev->name, err);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return val_mv / 1000.0f;
|
||||
}
|
||||
|
||||
} // namespace adc
|
||||
} // namespace esphome
|
||||
#endif
|
@@ -3,6 +3,12 @@ import logging
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import sensor, voltage_sampler
|
||||
from esphome.components.esp32 import get_esp32_variant
|
||||
from esphome.components.nrf52.const import AIN_TO_GPIO, EXTRA_ADC
|
||||
from esphome.components.zephyr import (
|
||||
zephyr_add_overlay,
|
||||
zephyr_add_prj_conf,
|
||||
zephyr_add_user,
|
||||
)
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ATTENUATION,
|
||||
@@ -11,6 +17,7 @@ from esphome.const import (
|
||||
CONF_PIN,
|
||||
CONF_RAW,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
PLATFORM_NRF52,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
UNIT_VOLT,
|
||||
)
|
||||
@@ -60,6 +67,10 @@ ADCSensor = adc_ns.class_(
|
||||
"ADCSensor", sensor.Sensor, cg.PollingComponent, voltage_sampler.VoltageSampler
|
||||
)
|
||||
|
||||
CONF_NRF_SAADC = "nrf_saadc"
|
||||
|
||||
adc_dt_spec = cg.global_ns.class_("adc_dt_spec")
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
sensor.sensor_schema(
|
||||
ADCSensor,
|
||||
@@ -75,6 +86,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.SplitDefault(CONF_ATTENUATION, esp32="0db"): cv.All(
|
||||
cv.only_on_esp32, _attenuation
|
||||
),
|
||||
cv.OnlyWith(CONF_NRF_SAADC, PLATFORM_NRF52): cv.declare_id(adc_dt_spec),
|
||||
cv.Optional(CONF_SAMPLES, default=1): cv.int_range(min=1, max=255),
|
||||
cv.Optional(CONF_SAMPLING_MODE, default="avg"): _sampling_mode,
|
||||
}
|
||||
@@ -83,6 +95,8 @@ CONFIG_SCHEMA = cv.All(
|
||||
validate_config,
|
||||
)
|
||||
|
||||
CONF_ADC_CHANNEL_ID = "adc_channel_id"
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
@@ -93,7 +107,7 @@ async def to_code(config):
|
||||
cg.add_define("USE_ADC_SENSOR_VCC")
|
||||
elif config[CONF_PIN] == "TEMPERATURE":
|
||||
cg.add(var.set_is_temperature())
|
||||
else:
|
||||
elif not CORE.is_nrf52 or config[CONF_PIN][CONF_NUMBER] not in EXTRA_ADC:
|
||||
pin = await cg.gpio_pin_expression(config[CONF_PIN])
|
||||
cg.add(var.set_pin(pin))
|
||||
|
||||
@@ -122,3 +136,41 @@ async def to_code(config):
|
||||
):
|
||||
chan = ESP32_VARIANT_ADC2_PIN_TO_CHANNEL[variant][pin_num]
|
||||
cg.add(var.set_channel(adc_unit_t.ADC_UNIT_2, chan))
|
||||
|
||||
elif CORE.is_nrf52:
|
||||
CORE.data.setdefault(CONF_ADC_CHANNEL_ID, 0)
|
||||
channel_id = CORE.data[CONF_ADC_CHANNEL_ID]
|
||||
CORE.data[CONF_ADC_CHANNEL_ID] = channel_id + 1
|
||||
zephyr_add_prj_conf("ADC", True)
|
||||
nrf_saadc = config[CONF_NRF_SAADC]
|
||||
rhs = cg.RawExpression(
|
||||
f"ADC_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), {channel_id})"
|
||||
)
|
||||
adc = cg.new_Pvariable(nrf_saadc, rhs)
|
||||
cg.add(var.set_adc_channel(adc))
|
||||
gain = "ADC_GAIN_1_6"
|
||||
pin_number = config[CONF_PIN][CONF_NUMBER]
|
||||
if pin_number == "VDDHDIV5":
|
||||
gain = "ADC_GAIN_1_2"
|
||||
if isinstance(pin_number, int):
|
||||
GPIO_TO_AIN = {v: k for k, v in AIN_TO_GPIO.items()}
|
||||
pin_number = GPIO_TO_AIN[pin_number]
|
||||
zephyr_add_user("io-channels", f"<&adc {channel_id}>")
|
||||
zephyr_add_overlay(
|
||||
f"""
|
||||
&adc {{
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
channel@{channel_id} {{
|
||||
reg = <{channel_id}>;
|
||||
zephyr,gain = "{gain}";
|
||||
zephyr,reference = "ADC_REF_INTERNAL";
|
||||
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
|
||||
zephyr,input-positive = <NRF_SAADC_{pin_number}>;
|
||||
zephyr,resolution = <14>;
|
||||
zephyr,oversampling = <8>;
|
||||
}};
|
||||
}};
|
||||
"""
|
||||
)
|
||||
|
@@ -8,10 +8,7 @@ static const char *const TAG = "adc128s102";
|
||||
|
||||
float ADC128S102::get_setup_priority() const { return setup_priority::HARDWARE; }
|
||||
|
||||
void ADC128S102::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
this->spi_setup();
|
||||
}
|
||||
void ADC128S102::setup() { this->spi_setup(); }
|
||||
|
||||
void ADC128S102::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "ADC128S102:");
|
||||
|
@@ -10,7 +10,6 @@ static const uint8_t ADS1115_REGISTER_CONVERSION = 0x00;
|
||||
static const uint8_t ADS1115_REGISTER_CONFIG = 0x01;
|
||||
|
||||
void ADS1115Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
uint16_t value;
|
||||
if (!this->read_byte_16(ADS1115_REGISTER_CONVERSION, &value)) {
|
||||
this->mark_failed();
|
||||
|
@@ -9,7 +9,6 @@ static const char *const TAG = "ads1118";
|
||||
static const uint8_t ADS1118_DATA_RATE_860_SPS = 0b111;
|
||||
|
||||
void ADS1118::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
this->spi_setup();
|
||||
|
||||
this->config_ = 0;
|
||||
|
@@ -24,8 +24,6 @@ static const uint16_t ZP_CURRENT = 0x0000;
|
||||
static const uint16_t ZP_DEFAULT = 0xFFFF;
|
||||
|
||||
void AGS10Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
|
||||
auto version = this->read_version_();
|
||||
if (version) {
|
||||
ESP_LOGD(TAG, "AGS10 Sensor Version: 0x%02X", *version);
|
||||
@@ -45,8 +43,6 @@ void AGS10Component::setup() {
|
||||
} else {
|
||||
ESP_LOGE(TAG, "AGS10 Sensor Resistance: unknown");
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Sensor initialized");
|
||||
}
|
||||
|
||||
void AGS10Component::update() {
|
||||
|
@@ -38,8 +38,6 @@ static const uint8_t AHT10_STATUS_BUSY = 0x80;
|
||||
static const float AHT10_DIVISOR = 1048576.0f; // 2^20, used for temperature and humidity calculations
|
||||
|
||||
void AHT10Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
|
||||
if (this->write(AHT10_SOFTRESET_CMD, sizeof(AHT10_SOFTRESET_CMD)) != i2c::ERROR_OK) {
|
||||
ESP_LOGE(TAG, "Reset failed");
|
||||
}
|
||||
@@ -80,8 +78,6 @@ void AHT10Component::setup() {
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "Initialization complete");
|
||||
}
|
||||
|
||||
void AHT10Component::restart_read_() {
|
||||
|
@@ -17,8 +17,6 @@ static const char *const TAG = "aic3204";
|
||||
}
|
||||
|
||||
void AIC3204::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
|
||||
// Set register page to 0
|
||||
ERROR_CHECK(this->write_byte(AIC3204_PAGE_CTRL, 0x00), "Set page 0 failed");
|
||||
// Initiate SW reset (PLL is powered off as part of reset)
|
||||
|
@@ -301,8 +301,7 @@ async def alarm_action_disarm_to_code(config, action_id, template_arg, args):
|
||||
)
|
||||
async def alarm_action_pending_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
return var
|
||||
return cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
@@ -310,8 +309,7 @@ async def alarm_action_pending_to_code(config, action_id, template_arg, args):
|
||||
)
|
||||
async def alarm_action_trigger_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
return var
|
||||
return cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
@@ -319,8 +317,7 @@ async def alarm_action_trigger_to_code(config, action_id, template_arg, args):
|
||||
)
|
||||
async def alarm_action_chime_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
return var
|
||||
return cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
@@ -333,8 +330,7 @@ async def alarm_action_chime_to_code(config, action_id, template_arg, args):
|
||||
)
|
||||
async def alarm_action_ready_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
return var
|
||||
return cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
@automation.register_condition(
|
||||
@@ -352,4 +348,3 @@ async def alarm_control_panel_is_armed_to_code(
|
||||
@coroutine_with_priority(100.0)
|
||||
async def to_code(config):
|
||||
cg.add_global(alarm_control_panel_ns.using)
|
||||
cg.add_define("USE_ALARM_CONTROL_PANEL")
|
||||
|
@@ -90,8 +90,6 @@ bool AM2315C::convert_(uint8_t *data, float &humidity, float &temperature) {
|
||||
}
|
||||
|
||||
void AM2315C::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
|
||||
// get status
|
||||
uint8_t status = 0;
|
||||
if (this->read(&status, 1) != i2c::ERROR_OK) {
|
||||
|
@@ -34,7 +34,6 @@ void AM2320Component::update() {
|
||||
this->status_clear_warning();
|
||||
}
|
||||
void AM2320Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
uint8_t data[8];
|
||||
data[0] = 0;
|
||||
data[1] = 4;
|
||||
|
@@ -34,17 +34,20 @@ SetFrameAction = animation_ns.class_(
|
||||
"AnimationSetFrameAction", automation.Action, cg.Parented.template(Animation_)
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = espImage.IMAGE_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(Animation_),
|
||||
cv.Optional(CONF_LOOP): cv.All(
|
||||
{
|
||||
cv.Optional(CONF_START_FRAME, default=0): cv.positive_int,
|
||||
cv.Optional(CONF_END_FRAME): cv.positive_int,
|
||||
cv.Optional(CONF_REPEAT): cv.positive_int,
|
||||
}
|
||||
),
|
||||
},
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
espImage.IMAGE_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(Animation_),
|
||||
cv.Optional(CONF_LOOP): cv.All(
|
||||
{
|
||||
cv.Optional(CONF_START_FRAME, default=0): cv.positive_int,
|
||||
cv.Optional(CONF_END_FRAME): cv.positive_int,
|
||||
cv.Optional(CONF_REPEAT): cv.positive_int,
|
||||
}
|
||||
),
|
||||
},
|
||||
),
|
||||
espImage.validate_settings,
|
||||
)
|
||||
|
||||
|
||||
|
@@ -54,8 +54,6 @@ enum { // APDS9306 registers
|
||||
}
|
||||
|
||||
void APDS9306::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
|
||||
uint8_t id;
|
||||
if (!this->read_byte(APDS9306_PART_ID, &id)) { // Part ID register
|
||||
this->error_code_ = COMMUNICATION_FAILED;
|
||||
@@ -86,8 +84,6 @@ void APDS9306::setup() {
|
||||
|
||||
// Set to active mode
|
||||
APDS9306_WRITE_BYTE(APDS9306_MAIN_CTRL, 0x02);
|
||||
|
||||
ESP_LOGCONFIG(TAG, "APDS9306 setup complete");
|
||||
}
|
||||
|
||||
void APDS9306::dump_config() {
|
||||
|
@@ -15,7 +15,6 @@ static const char *const TAG = "apds9960";
|
||||
#define APDS9960_WRITE_BYTE(reg, value) APDS9960_ERROR_CHECK(this->write_byte(reg, value));
|
||||
|
||||
void APDS9960::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
uint8_t id;
|
||||
if (!this->read_byte(0x92, &id)) { // ID register
|
||||
this->error_code_ = COMMUNICATION_FAILED;
|
||||
|
@@ -53,6 +53,8 @@ SERVICE_ARG_NATIVE_TYPES = {
|
||||
CONF_ENCRYPTION = "encryption"
|
||||
CONF_BATCH_DELAY = "batch_delay"
|
||||
CONF_CUSTOM_SERVICES = "custom_services"
|
||||
CONF_HOMEASSISTANT_SERVICES = "homeassistant_services"
|
||||
CONF_HOMEASSISTANT_STATES = "homeassistant_states"
|
||||
|
||||
|
||||
def validate_encryption_key(value):
|
||||
@@ -118,6 +120,8 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.Range(max=cv.TimePeriod(milliseconds=65535)),
|
||||
),
|
||||
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_ON_CLIENT_CONNECTED): automation.validate_automation(
|
||||
single=True
|
||||
),
|
||||
@@ -146,6 +150,12 @@ async def to_code(config):
|
||||
if config.get(CONF_ACTIONS) or config[CONF_CUSTOM_SERVICES]:
|
||||
cg.add_define("USE_API_SERVICES")
|
||||
|
||||
if config[CONF_HOMEASSISTANT_SERVICES]:
|
||||
cg.add_define("USE_API_HOMEASSISTANT_SERVICES")
|
||||
|
||||
if config[CONF_HOMEASSISTANT_STATES]:
|
||||
cg.add_define("USE_API_HOMEASSISTANT_STATES")
|
||||
|
||||
if actions := config.get(CONF_ACTIONS, []):
|
||||
for conf in actions:
|
||||
template_args = []
|
||||
@@ -235,6 +245,7 @@ HOMEASSISTANT_ACTION_ACTION_SCHEMA = cv.All(
|
||||
HOMEASSISTANT_ACTION_ACTION_SCHEMA,
|
||||
)
|
||||
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])
|
||||
var = cg.new_Pvariable(action_id, template_arg, serv, False)
|
||||
templ = await cg.templatable(config[CONF_ACTION], args, None)
|
||||
@@ -278,6 +289,7 @@ HOMEASSISTANT_EVENT_ACTION_SCHEMA = cv.Schema(
|
||||
HOMEASSISTANT_EVENT_ACTION_SCHEMA,
|
||||
)
|
||||
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])
|
||||
var = cg.new_Pvariable(action_id, template_arg, serv, True)
|
||||
templ = await cg.templatable(config[CONF_EVENT], args, None)
|
||||
|
@@ -419,7 +419,7 @@ message ListEntitiesFanResponse {
|
||||
bool disabled_by_default = 9;
|
||||
string icon = 10 [(field_ifdef) = "USE_ENTITY_ICON"];
|
||||
EntityCategory entity_category = 11;
|
||||
repeated string supported_preset_modes = 12;
|
||||
repeated string supported_preset_modes = 12 [(container_pointer) = "std::set"];
|
||||
uint32 device_id = 13 [(field_ifdef) = "USE_DEVICES"];
|
||||
}
|
||||
// Deprecated in API version 1.6 - only used in deprecated fields
|
||||
@@ -500,7 +500,7 @@ message ListEntitiesLightResponse {
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
repeated ColorMode supported_color_modes = 12;
|
||||
repeated ColorMode supported_color_modes = 12 [(container_pointer) = "std::set<light::ColorMode>"];
|
||||
// next four supports_* are for legacy clients, newer clients should use color modes
|
||||
// Deprecated in API version 1.6
|
||||
bool legacy_supports_brightness = 5 [deprecated=true];
|
||||
@@ -755,17 +755,19 @@ message NoiseEncryptionSetKeyResponse {
|
||||
message SubscribeHomeassistantServicesRequest {
|
||||
option (id) = 34;
|
||||
option (source) = SOURCE_CLIENT;
|
||||
option (ifdef) = "USE_API_HOMEASSISTANT_SERVICES";
|
||||
}
|
||||
|
||||
message HomeassistantServiceMap {
|
||||
string key = 1;
|
||||
string value = 2;
|
||||
string value = 2 [(no_zero_copy) = true];
|
||||
}
|
||||
|
||||
message HomeassistantServiceResponse {
|
||||
option (id) = 35;
|
||||
option (source) = SOURCE_SERVER;
|
||||
option (no_delay) = true;
|
||||
option (ifdef) = "USE_API_HOMEASSISTANT_SERVICES";
|
||||
|
||||
string service = 1;
|
||||
repeated HomeassistantServiceMap data = 2;
|
||||
@@ -781,11 +783,13 @@ message HomeassistantServiceResponse {
|
||||
message SubscribeHomeAssistantStatesRequest {
|
||||
option (id) = 38;
|
||||
option (source) = SOURCE_CLIENT;
|
||||
option (ifdef) = "USE_API_HOMEASSISTANT_STATES";
|
||||
}
|
||||
|
||||
message SubscribeHomeAssistantStateResponse {
|
||||
option (id) = 39;
|
||||
option (source) = SOURCE_SERVER;
|
||||
option (ifdef) = "USE_API_HOMEASSISTANT_STATES";
|
||||
string entity_id = 1;
|
||||
string attribute = 2;
|
||||
bool once = 3;
|
||||
@@ -795,6 +799,7 @@ message HomeAssistantStateResponse {
|
||||
option (id) = 40;
|
||||
option (source) = SOURCE_CLIENT;
|
||||
option (no_delay) = true;
|
||||
option (ifdef) = "USE_API_HOMEASSISTANT_STATES";
|
||||
|
||||
string entity_id = 1;
|
||||
string state = 2;
|
||||
@@ -961,7 +966,7 @@ message ListEntitiesClimateResponse {
|
||||
|
||||
bool supports_current_temperature = 5;
|
||||
bool supports_two_point_target_temperature = 6;
|
||||
repeated ClimateMode supported_modes = 7;
|
||||
repeated ClimateMode supported_modes = 7 [(container_pointer) = "std::set<climate::ClimateMode>"];
|
||||
float visual_min_temperature = 8;
|
||||
float visual_max_temperature = 9;
|
||||
float visual_target_temperature_step = 10;
|
||||
@@ -970,11 +975,11 @@ message ListEntitiesClimateResponse {
|
||||
// Deprecated in API version 1.5
|
||||
bool legacy_supports_away = 11 [deprecated=true];
|
||||
bool supports_action = 12;
|
||||
repeated ClimateFanMode supported_fan_modes = 13;
|
||||
repeated ClimateSwingMode supported_swing_modes = 14;
|
||||
repeated string supported_custom_fan_modes = 15;
|
||||
repeated ClimatePreset supported_presets = 16;
|
||||
repeated string supported_custom_presets = 17;
|
||||
repeated ClimateFanMode supported_fan_modes = 13 [(container_pointer) = "std::set<climate::ClimateFanMode>"];
|
||||
repeated ClimateSwingMode supported_swing_modes = 14 [(container_pointer) = "std::set<climate::ClimateSwingMode>"];
|
||||
repeated string supported_custom_fan_modes = 15 [(container_pointer) = "std::set"];
|
||||
repeated ClimatePreset supported_presets = 16 [(container_pointer) = "std::set<climate::ClimatePreset>"];
|
||||
repeated string supported_custom_presets = 17 [(container_pointer) = "std::set"];
|
||||
bool disabled_by_default = 18;
|
||||
string icon = 19 [(field_ifdef) = "USE_ENTITY_ICON"];
|
||||
EntityCategory entity_category = 20;
|
||||
@@ -1114,7 +1119,7 @@ message ListEntitiesSelectResponse {
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
|
||||
repeated string options = 6;
|
||||
repeated string options = 6 [(container_pointer) = "std::vector"];
|
||||
bool disabled_by_default = 7;
|
||||
EntityCategory entity_category = 8;
|
||||
uint32 device_id = 9 [(field_ifdef) = "USE_DEVICES"];
|
||||
@@ -1292,6 +1297,9 @@ enum MediaPlayerState {
|
||||
MEDIA_PLAYER_STATE_IDLE = 1;
|
||||
MEDIA_PLAYER_STATE_PLAYING = 2;
|
||||
MEDIA_PLAYER_STATE_PAUSED = 3;
|
||||
MEDIA_PLAYER_STATE_ANNOUNCING = 4;
|
||||
MEDIA_PLAYER_STATE_OFF = 5;
|
||||
MEDIA_PLAYER_STATE_ON = 6;
|
||||
}
|
||||
enum MediaPlayerCommand {
|
||||
MEDIA_PLAYER_COMMAND_PLAY = 0;
|
||||
@@ -1299,6 +1307,15 @@ enum MediaPlayerCommand {
|
||||
MEDIA_PLAYER_COMMAND_STOP = 2;
|
||||
MEDIA_PLAYER_COMMAND_MUTE = 3;
|
||||
MEDIA_PLAYER_COMMAND_UNMUTE = 4;
|
||||
MEDIA_PLAYER_COMMAND_TOGGLE = 5;
|
||||
MEDIA_PLAYER_COMMAND_VOLUME_UP = 6;
|
||||
MEDIA_PLAYER_COMMAND_VOLUME_DOWN = 7;
|
||||
MEDIA_PLAYER_COMMAND_ENQUEUE = 8;
|
||||
MEDIA_PLAYER_COMMAND_REPEAT_ONE = 9;
|
||||
MEDIA_PLAYER_COMMAND_REPEAT_OFF = 10;
|
||||
MEDIA_PLAYER_COMMAND_CLEAR_PLAYLIST = 11;
|
||||
MEDIA_PLAYER_COMMAND_TURN_ON = 12;
|
||||
MEDIA_PLAYER_COMMAND_TURN_OFF = 13;
|
||||
}
|
||||
enum MediaPlayerFormatPurpose {
|
||||
MEDIA_PLAYER_FORMAT_PURPOSE_DEFAULT = 0;
|
||||
@@ -1333,6 +1350,8 @@ message ListEntitiesMediaPlayerResponse {
|
||||
repeated MediaPlayerSupportedFormat supported_formats = 9;
|
||||
|
||||
uint32 device_id = 10 [(field_ifdef) = "USE_DEVICES"];
|
||||
|
||||
uint32 feature_flags = 11;
|
||||
}
|
||||
message MediaPlayerStateResponse {
|
||||
option (id) = 64;
|
||||
@@ -1463,21 +1482,39 @@ message BluetoothGATTGetServicesRequest {
|
||||
}
|
||||
|
||||
message BluetoothGATTDescriptor {
|
||||
repeated uint64 uuid = 1 [(fixed_array_size) = 2];
|
||||
repeated uint64 uuid = 1 [(fixed_array_size) = 2, (fixed_array_skip_zero) = true];
|
||||
uint32 handle = 2;
|
||||
|
||||
// New field for efficient UUID (v1.12+)
|
||||
// Only one of uuid or short_uuid will be set.
|
||||
// short_uuid is used for both 16-bit and 32-bit UUIDs with v1.12+ clients.
|
||||
// 128-bit UUIDs always use the uuid field for backwards compatibility.
|
||||
uint32 short_uuid = 3; // 16-bit or 32-bit UUID
|
||||
}
|
||||
|
||||
message BluetoothGATTCharacteristic {
|
||||
repeated uint64 uuid = 1 [(fixed_array_size) = 2];
|
||||
repeated uint64 uuid = 1 [(fixed_array_size) = 2, (fixed_array_skip_zero) = true];
|
||||
uint32 handle = 2;
|
||||
uint32 properties = 3;
|
||||
repeated BluetoothGATTDescriptor descriptors = 4;
|
||||
|
||||
// New field for efficient UUID (v1.12+)
|
||||
// Only one of uuid or short_uuid will be set.
|
||||
// short_uuid is used for both 16-bit and 32-bit UUIDs with v1.12+ clients.
|
||||
// 128-bit UUIDs always use the uuid field for backwards compatibility.
|
||||
uint32 short_uuid = 5; // 16-bit or 32-bit UUID
|
||||
}
|
||||
|
||||
message BluetoothGATTService {
|
||||
repeated uint64 uuid = 1 [(fixed_array_size) = 2];
|
||||
repeated uint64 uuid = 1 [(fixed_array_size) = 2, (fixed_array_skip_zero) = true];
|
||||
uint32 handle = 2;
|
||||
repeated BluetoothGATTCharacteristic characteristics = 3;
|
||||
|
||||
// New field for efficient UUID (v1.12+)
|
||||
// Only one of uuid or short_uuid will be set.
|
||||
// short_uuid is used for both 16-bit and 32-bit UUIDs with v1.12+ clients.
|
||||
// 128-bit UUIDs always use the uuid field for backwards compatibility.
|
||||
uint32 short_uuid = 4; // 16-bit or 32-bit UUID
|
||||
}
|
||||
|
||||
message BluetoothGATTGetServicesResponse {
|
||||
@@ -1486,7 +1523,7 @@ message BluetoothGATTGetServicesResponse {
|
||||
option (ifdef) = "USE_BLUETOOTH_PROXY";
|
||||
|
||||
uint64 address = 1;
|
||||
repeated BluetoothGATTService services = 2 [(fixed_array_size) = 1];
|
||||
repeated BluetoothGATTService services = 2;
|
||||
}
|
||||
|
||||
message BluetoothGATTGetServicesDoneResponse {
|
||||
@@ -1584,7 +1621,10 @@ message BluetoothConnectionsFreeResponse {
|
||||
|
||||
uint32 free = 1;
|
||||
uint32 limit = 2;
|
||||
repeated uint64 allocated = 3;
|
||||
repeated uint64 allocated = 3 [
|
||||
(fixed_array_size_define) = "BLUETOOTH_PROXY_MAX_CONNECTIONS",
|
||||
(fixed_array_skip_zero) = true
|
||||
];
|
||||
}
|
||||
|
||||
message BluetoothGATTErrorResponse {
|
||||
@@ -1829,7 +1869,7 @@ message VoiceAssistantConfigurationResponse {
|
||||
option (ifdef) = "USE_VOICE_ASSISTANT";
|
||||
|
||||
repeated VoiceAssistantWakeWord available_wake_words = 1;
|
||||
repeated string active_wake_words = 2;
|
||||
repeated string active_wake_words = 2 [(container_pointer) = "std::vector"];
|
||||
uint32 max_active_wake_words = 3;
|
||||
}
|
||||
|
||||
|
@@ -112,8 +112,7 @@ void APIConnection::start() {
|
||||
APIError err = this->helper_->init();
|
||||
if (err != APIError::OK) {
|
||||
on_fatal_error();
|
||||
ESP_LOGW(TAG, "%s: Helper init failed %s errno=%d", this->get_client_combined_info().c_str(), api_error_to_str(err),
|
||||
errno);
|
||||
this->log_warning_("Helper init failed", err);
|
||||
return;
|
||||
}
|
||||
this->client_info_.peername = helper_->getpeername();
|
||||
@@ -144,8 +143,7 @@ void APIConnection::loop() {
|
||||
APIError err = this->helper_->loop();
|
||||
if (err != APIError::OK) {
|
||||
on_fatal_error();
|
||||
ESP_LOGW(TAG, "%s: Socket operation failed %s errno=%d", this->get_client_combined_info().c_str(),
|
||||
api_error_to_str(err), errno);
|
||||
this->log_socket_operation_failed_(err);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -161,8 +159,7 @@ void APIConnection::loop() {
|
||||
break;
|
||||
} else if (err != APIError::OK) {
|
||||
on_fatal_error();
|
||||
ESP_LOGW(TAG, "%s: Reading failed %s errno=%d", this->get_client_combined_info().c_str(), api_error_to_str(err),
|
||||
errno);
|
||||
this->log_warning_("Reading failed", err);
|
||||
return;
|
||||
} else {
|
||||
this->last_traffic_ = now;
|
||||
@@ -242,23 +239,11 @@ void APIConnection::loop() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
if (state_subs_at_ >= 0) {
|
||||
const auto &subs = this->parent_->get_state_subs();
|
||||
if (state_subs_at_ < static_cast<int>(subs.size())) {
|
||||
auto &it = subs[state_subs_at_];
|
||||
SubscribeHomeAssistantStateResponse resp;
|
||||
resp.set_entity_id(StringRef(it.entity_id));
|
||||
// attribute.value() returns temporary - must store it
|
||||
std::string attribute_value = it.attribute.value();
|
||||
resp.set_attribute(StringRef(attribute_value));
|
||||
resp.once = it.once;
|
||||
if (this->send_message(resp, SubscribeHomeAssistantStateResponse::MESSAGE_TYPE)) {
|
||||
state_subs_at_++;
|
||||
}
|
||||
} else {
|
||||
state_subs_at_ = -1;
|
||||
}
|
||||
this->process_state_subscriptions_();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool APIConnection::send_disconnect_response(const DisconnectRequest &msg) {
|
||||
@@ -288,8 +273,9 @@ uint16_t APIConnection::encode_message_to_buffer(ProtoMessage &msg, uint8_t mess
|
||||
#endif
|
||||
|
||||
// Calculate size
|
||||
uint32_t calculated_size = 0;
|
||||
msg.calculate_size(calculated_size);
|
||||
ProtoSize size_calc;
|
||||
msg.calculate_size(size_calc);
|
||||
uint32_t calculated_size = size_calc.get_size();
|
||||
|
||||
// Cache frame sizes to avoid repeated virtual calls
|
||||
const uint8_t header_padding = conn->helper_->frame_header_padding();
|
||||
@@ -424,8 +410,7 @@ uint16_t APIConnection::try_send_fan_info(EntityBase *entity, APIConnection *con
|
||||
msg.supports_speed = traits.supports_speed();
|
||||
msg.supports_direction = traits.supports_direction();
|
||||
msg.supported_speed_count = traits.supported_speed_count();
|
||||
for (auto const &preset : traits.supported_preset_modes())
|
||||
msg.supported_preset_modes.push_back(preset);
|
||||
msg.supported_preset_modes = &traits.supported_preset_modes_for_api_();
|
||||
return fill_and_encode_entity_info(fan, msg, ListEntitiesFanResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||
}
|
||||
void APIConnection::fan_command(const FanCommandRequest &msg) {
|
||||
@@ -481,8 +466,7 @@ uint16_t APIConnection::try_send_light_info(EntityBase *entity, APIConnection *c
|
||||
auto *light = static_cast<light::LightState *>(entity);
|
||||
ListEntitiesLightResponse msg;
|
||||
auto traits = light->get_traits();
|
||||
for (auto mode : traits.get_supported_color_modes())
|
||||
msg.supported_color_modes.push_back(static_cast<enums::ColorMode>(mode));
|
||||
msg.supported_color_modes = &traits.get_supported_color_modes_for_api_();
|
||||
if (traits.supports_color_capability(light::ColorCapability::COLOR_TEMPERATURE) ||
|
||||
traits.supports_color_capability(light::ColorCapability::COLD_WARM_WHITE)) {
|
||||
msg.min_mireds = traits.get_min_mireds();
|
||||
@@ -642,17 +626,13 @@ uint16_t APIConnection::try_send_climate_state(EntityBase *entity, APIConnection
|
||||
if (traits.get_supports_fan_modes() && climate->fan_mode.has_value())
|
||||
resp.fan_mode = static_cast<enums::ClimateFanMode>(climate->fan_mode.value());
|
||||
if (!traits.get_supported_custom_fan_modes().empty() && climate->custom_fan_mode.has_value()) {
|
||||
// custom_fan_mode.value() returns temporary - must store it
|
||||
std::string custom_fan_mode = climate->custom_fan_mode.value();
|
||||
resp.set_custom_fan_mode(StringRef(custom_fan_mode));
|
||||
resp.set_custom_fan_mode(StringRef(climate->custom_fan_mode.value()));
|
||||
}
|
||||
if (traits.get_supports_presets() && climate->preset.has_value()) {
|
||||
resp.preset = static_cast<enums::ClimatePreset>(climate->preset.value());
|
||||
}
|
||||
if (!traits.get_supported_custom_presets().empty() && climate->custom_preset.has_value()) {
|
||||
// custom_preset.value() returns temporary - must store it
|
||||
std::string custom_preset = climate->custom_preset.value();
|
||||
resp.set_custom_preset(StringRef(custom_preset));
|
||||
resp.set_custom_preset(StringRef(climate->custom_preset.value()));
|
||||
}
|
||||
if (traits.get_supports_swing_modes())
|
||||
resp.swing_mode = static_cast<enums::ClimateSwingMode>(climate->swing_mode);
|
||||
@@ -672,8 +652,7 @@ uint16_t APIConnection::try_send_climate_info(EntityBase *entity, APIConnection
|
||||
msg.supports_current_humidity = traits.get_supports_current_humidity();
|
||||
msg.supports_two_point_target_temperature = traits.get_supports_two_point_target_temperature();
|
||||
msg.supports_target_humidity = traits.get_supports_target_humidity();
|
||||
for (auto mode : traits.get_supported_modes())
|
||||
msg.supported_modes.push_back(static_cast<enums::ClimateMode>(mode));
|
||||
msg.supported_modes = &traits.get_supported_modes_for_api_();
|
||||
msg.visual_min_temperature = traits.get_visual_min_temperature();
|
||||
msg.visual_max_temperature = traits.get_visual_max_temperature();
|
||||
msg.visual_target_temperature_step = traits.get_visual_target_temperature_step();
|
||||
@@ -681,16 +660,11 @@ uint16_t APIConnection::try_send_climate_info(EntityBase *entity, APIConnection
|
||||
msg.visual_min_humidity = traits.get_visual_min_humidity();
|
||||
msg.visual_max_humidity = traits.get_visual_max_humidity();
|
||||
msg.supports_action = traits.get_supports_action();
|
||||
for (auto fan_mode : traits.get_supported_fan_modes())
|
||||
msg.supported_fan_modes.push_back(static_cast<enums::ClimateFanMode>(fan_mode));
|
||||
for (auto const &custom_fan_mode : traits.get_supported_custom_fan_modes())
|
||||
msg.supported_custom_fan_modes.push_back(custom_fan_mode);
|
||||
for (auto preset : traits.get_supported_presets())
|
||||
msg.supported_presets.push_back(static_cast<enums::ClimatePreset>(preset));
|
||||
for (auto const &custom_preset : traits.get_supported_custom_presets())
|
||||
msg.supported_custom_presets.push_back(custom_preset);
|
||||
for (auto swing_mode : traits.get_supported_swing_modes())
|
||||
msg.supported_swing_modes.push_back(static_cast<enums::ClimateSwingMode>(swing_mode));
|
||||
msg.supported_fan_modes = &traits.get_supported_fan_modes_for_api_();
|
||||
msg.supported_custom_fan_modes = &traits.get_supported_custom_fan_modes_for_api_();
|
||||
msg.supported_presets = &traits.get_supported_presets_for_api_();
|
||||
msg.supported_custom_presets = &traits.get_supported_custom_presets_for_api_();
|
||||
msg.supported_swing_modes = &traits.get_supported_swing_modes_for_api_();
|
||||
return fill_and_encode_entity_info(climate, msg, ListEntitiesClimateResponse::MESSAGE_TYPE, conn, remaining_size,
|
||||
is_single);
|
||||
}
|
||||
@@ -896,8 +870,7 @@ uint16_t APIConnection::try_send_select_info(EntityBase *entity, APIConnection *
|
||||
bool is_single) {
|
||||
auto *select = static_cast<select::Select *>(entity);
|
||||
ListEntitiesSelectResponse msg;
|
||||
for (const auto &option : select->traits.get_options())
|
||||
msg.options.push_back(option);
|
||||
msg.options = &select->traits.get_options();
|
||||
return fill_and_encode_entity_info(select, msg, ListEntitiesSelectResponse::MESSAGE_TYPE, conn, remaining_size,
|
||||
is_single);
|
||||
}
|
||||
@@ -1023,6 +996,7 @@ uint16_t APIConnection::try_send_media_player_info(EntityBase *entity, APIConnec
|
||||
ListEntitiesMediaPlayerResponse msg;
|
||||
auto traits = media_player->get_traits();
|
||||
msg.supports_pause = traits.get_supports_pause();
|
||||
msg.feature_flags = traits.get_feature_flags();
|
||||
for (auto &supported_format : traits.get_supported_formats()) {
|
||||
msg.supported_formats.emplace_back();
|
||||
auto &media_format = msg.supported_formats.back();
|
||||
@@ -1131,10 +1105,8 @@ void APIConnection::bluetooth_gatt_notify(const BluetoothGATTNotifyRequest &msg)
|
||||
|
||||
bool APIConnection::send_subscribe_bluetooth_connections_free_response(
|
||||
const SubscribeBluetoothConnectionsFreeRequest &msg) {
|
||||
BluetoothConnectionsFreeResponse resp;
|
||||
resp.free = bluetooth_proxy::global_bluetooth_proxy->get_bluetooth_connections_free();
|
||||
resp.limit = bluetooth_proxy::global_bluetooth_proxy->get_bluetooth_connections_limit();
|
||||
return this->send_message(resp, BluetoothConnectionsFreeResponse::MESSAGE_TYPE);
|
||||
bluetooth_proxy::global_bluetooth_proxy->send_connections_free(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void APIConnection::bluetooth_scanner_set_mode(const BluetoothScannerSetModeRequest &msg) {
|
||||
@@ -1211,9 +1183,7 @@ bool APIConnection::send_voice_assistant_get_configuration_response(const VoiceA
|
||||
resp_wake_word.trained_languages.push_back(lang);
|
||||
}
|
||||
}
|
||||
for (auto &wake_word_id : config.active_wake_words) {
|
||||
resp.active_wake_words.push_back(wake_word_id);
|
||||
}
|
||||
resp.active_wake_words = &config.active_wake_words;
|
||||
resp.max_active_wake_words = config.max_active_wake_words;
|
||||
return this->send_message(resp, VoiceAssistantConfigurationResponse::MESSAGE_TYPE);
|
||||
}
|
||||
@@ -1391,7 +1361,7 @@ bool APIConnection::send_hello_response(const HelloRequest &msg) {
|
||||
|
||||
HelloResponse resp;
|
||||
resp.api_version_major = 1;
|
||||
resp.api_version_minor = 10;
|
||||
resp.api_version_minor = 12;
|
||||
// Temporary string for concatenation - will be valid during send_message call
|
||||
std::string server_info = App.get_name() + " (esphome v" ESPHOME_VERSION ")";
|
||||
resp.set_server_info(StringRef(server_info));
|
||||
@@ -1512,6 +1482,7 @@ bool APIConnection::send_device_info_response(const DeviceInfoRequest &msg) {
|
||||
return this->send_message(resp, DeviceInfoResponse::MESSAGE_TYPE);
|
||||
}
|
||||
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
void APIConnection::on_home_assistant_state_response(const HomeAssistantStateResponse &msg) {
|
||||
for (auto &it : this->parent_->get_state_subs()) {
|
||||
if (it.entity_id == msg.entity_id && it.attribute.value() == msg.attribute) {
|
||||
@@ -1519,6 +1490,7 @@ void APIConnection::on_home_assistant_state_response(const HomeAssistantStateRes
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_API_SERVICES
|
||||
void APIConnection::execute_service(const ExecuteServiceRequest &msg) {
|
||||
bool found = false;
|
||||
@@ -1534,25 +1506,26 @@ void APIConnection::execute_service(const ExecuteServiceRequest &msg) {
|
||||
#endif
|
||||
#ifdef USE_API_NOISE
|
||||
bool APIConnection::send_noise_encryption_set_key_response(const NoiseEncryptionSetKeyRequest &msg) {
|
||||
psk_t psk{};
|
||||
NoiseEncryptionSetKeyResponse resp;
|
||||
resp.success = false;
|
||||
|
||||
psk_t psk{};
|
||||
if (base64_decode(msg.key, psk.data(), msg.key.size()) != psk.size()) {
|
||||
ESP_LOGW(TAG, "Invalid encryption key length");
|
||||
resp.success = false;
|
||||
return this->send_message(resp, NoiseEncryptionSetKeyResponse::MESSAGE_TYPE);
|
||||
}
|
||||
if (!this->parent_->save_noise_psk(psk, true)) {
|
||||
} else if (!this->parent_->save_noise_psk(psk, true)) {
|
||||
ESP_LOGW(TAG, "Failed to save encryption key");
|
||||
resp.success = false;
|
||||
return this->send_message(resp, NoiseEncryptionSetKeyResponse::MESSAGE_TYPE);
|
||||
} else {
|
||||
resp.success = true;
|
||||
}
|
||||
resp.success = true;
|
||||
|
||||
return this->send_message(resp, NoiseEncryptionSetKeyResponse::MESSAGE_TYPE);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
void APIConnection::subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) {
|
||||
state_subs_at_ = 0;
|
||||
}
|
||||
#endif
|
||||
bool APIConnection::try_to_clear_buffer(bool log_out_of_space) {
|
||||
if (this->flags_.remove)
|
||||
return false;
|
||||
@@ -1562,8 +1535,7 @@ bool APIConnection::try_to_clear_buffer(bool log_out_of_space) {
|
||||
APIError err = this->helper_->loop();
|
||||
if (err != APIError::OK) {
|
||||
on_fatal_error();
|
||||
ESP_LOGW(TAG, "%s: Socket operation failed %s errno=%d", this->get_client_combined_info().c_str(),
|
||||
api_error_to_str(err), errno);
|
||||
this->log_socket_operation_failed_(err);
|
||||
return false;
|
||||
}
|
||||
if (this->helper_->can_write_without_blocking())
|
||||
@@ -1583,17 +1555,18 @@ bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) {
|
||||
return false;
|
||||
if (err != APIError::OK) {
|
||||
on_fatal_error();
|
||||
ESP_LOGW(TAG, "%s: Packet write failed %s errno=%d", this->get_client_combined_info().c_str(),
|
||||
api_error_to_str(err), errno);
|
||||
this->log_warning_("Packet write failed", err);
|
||||
return false;
|
||||
}
|
||||
// Do not set last_traffic_ on send
|
||||
return true;
|
||||
}
|
||||
#ifdef USE_API_PASSWORD
|
||||
void APIConnection::on_unauthenticated_access() {
|
||||
this->on_fatal_error();
|
||||
ESP_LOGD(TAG, "%s access without authentication", this->get_client_combined_info().c_str());
|
||||
}
|
||||
#endif
|
||||
void APIConnection::on_no_setup_connection() {
|
||||
this->on_fatal_error();
|
||||
ESP_LOGD(TAG, "%s access without full connection", this->get_client_combined_info().c_str());
|
||||
@@ -1667,6 +1640,8 @@ void APIConnection::process_batch_() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get shared buffer reference once to avoid multiple calls
|
||||
auto &shared_buf = this->parent_->get_shared_buffer_ref();
|
||||
size_t num_items = this->deferred_batch_.size();
|
||||
|
||||
// Fast path for single message - allocate exact size needed
|
||||
@@ -1677,8 +1652,7 @@ void APIConnection::process_batch_() {
|
||||
uint16_t payload_size =
|
||||
item.creator(item.entity, this, std::numeric_limits<uint16_t>::max(), true, item.message_type);
|
||||
|
||||
if (payload_size > 0 &&
|
||||
this->send_buffer(ProtoWriteBuffer{&this->parent_->get_shared_buffer_ref()}, item.message_type)) {
|
||||
if (payload_size > 0 && this->send_buffer(ProtoWriteBuffer{&shared_buf}, item.message_type)) {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
// Log messages after send attempt for VV debugging
|
||||
// It's safe to use the buffer for logging at this point regardless of send result
|
||||
@@ -1705,20 +1679,18 @@ void APIConnection::process_batch_() {
|
||||
const uint8_t footer_size = this->helper_->frame_footer_size();
|
||||
|
||||
// Initialize buffer and tracking variables
|
||||
this->parent_->get_shared_buffer_ref().clear();
|
||||
shared_buf.clear();
|
||||
|
||||
// Pre-calculate exact buffer size needed based on message types
|
||||
uint32_t total_estimated_size = 0;
|
||||
uint32_t total_estimated_size = num_items * (header_padding + footer_size);
|
||||
for (size_t i = 0; i < this->deferred_batch_.size(); i++) {
|
||||
const auto &item = this->deferred_batch_[i];
|
||||
total_estimated_size += item.estimated_size;
|
||||
}
|
||||
|
||||
// Calculate total overhead for all messages
|
||||
uint32_t total_overhead = (header_padding + footer_size) * num_items;
|
||||
|
||||
// Reserve based on estimated size (much more accurate than 24-byte worst-case)
|
||||
this->parent_->get_shared_buffer_ref().reserve(total_estimated_size + total_overhead);
|
||||
shared_buf.reserve(total_estimated_size);
|
||||
this->flags_.batch_first_message = true;
|
||||
|
||||
size_t items_processed = 0;
|
||||
@@ -1760,7 +1732,7 @@ void APIConnection::process_batch_() {
|
||||
remaining_size -= payload_size;
|
||||
// Calculate where the next message's header padding will start
|
||||
// Current buffer size + footer space (that prepare_message_buffer will add for this message)
|
||||
current_offset = this->parent_->get_shared_buffer_ref().size() + footer_size;
|
||||
current_offset = shared_buf.size() + footer_size;
|
||||
}
|
||||
|
||||
if (items_processed == 0) {
|
||||
@@ -1770,17 +1742,15 @@ void APIConnection::process_batch_() {
|
||||
|
||||
// Add footer space for the last message (for Noise protocol MAC)
|
||||
if (footer_size > 0) {
|
||||
auto &shared_buf = this->parent_->get_shared_buffer_ref();
|
||||
shared_buf.resize(shared_buf.size() + footer_size);
|
||||
}
|
||||
|
||||
// Send all collected packets
|
||||
APIError err = this->helper_->write_protobuf_packets(ProtoWriteBuffer{&this->parent_->get_shared_buffer_ref()},
|
||||
APIError err = this->helper_->write_protobuf_packets(ProtoWriteBuffer{&shared_buf},
|
||||
std::span<const PacketInfo>(packet_info, packet_count));
|
||||
if (err != APIError::OK && err != APIError::WOULD_BLOCK) {
|
||||
on_fatal_error();
|
||||
ESP_LOGW(TAG, "%s: Batch write failed %s errno=%d", this->get_client_combined_info().c_str(), api_error_to_str(err),
|
||||
errno);
|
||||
this->log_warning_("Batch write failed", err);
|
||||
}
|
||||
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
@@ -1836,5 +1806,33 @@ uint16_t APIConnection::try_send_ping_request(EntityBase *entity, APIConnection
|
||||
return encode_message_to_buffer(req, PingRequest::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||
}
|
||||
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
void APIConnection::process_state_subscriptions_() {
|
||||
const auto &subs = this->parent_->get_state_subs();
|
||||
if (this->state_subs_at_ >= static_cast<int>(subs.size())) {
|
||||
this->state_subs_at_ = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &it = subs[this->state_subs_at_];
|
||||
SubscribeHomeAssistantStateResponse resp;
|
||||
resp.set_entity_id(StringRef(it.entity_id));
|
||||
|
||||
// Avoid string copy by directly using the optional's value if it exists
|
||||
resp.set_attribute(it.attribute.has_value() ? StringRef(it.attribute.value()) : StringRef(""));
|
||||
|
||||
resp.once = it.once;
|
||||
if (this->send_message(resp, SubscribeHomeAssistantStateResponse::MESSAGE_TYPE)) {
|
||||
this->state_subs_at_++;
|
||||
}
|
||||
}
|
||||
#endif // USE_API_HOMEASSISTANT_STATES
|
||||
|
||||
void APIConnection::log_warning_(const char *message, APIError err) {
|
||||
ESP_LOGW(TAG, "%s: %s %s errno=%d", this->get_client_combined_info().c_str(), message, api_error_to_str(err), errno);
|
||||
}
|
||||
|
||||
void APIConnection::log_socket_operation_failed_(APIError err) { this->log_warning_("Socket operation failed", err); }
|
||||
|
||||
} // namespace esphome::api
|
||||
#endif
|
||||
|
@@ -131,11 +131,13 @@ class APIConnection : public APIServerConnection {
|
||||
void media_player_command(const MediaPlayerCommandRequest &msg) override;
|
||||
#endif
|
||||
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) {
|
||||
if (!this->flags_.service_call_subscription)
|
||||
return;
|
||||
this->send_message(call, HomeassistantServiceResponse::MESSAGE_TYPE);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_BLUETOOTH_PROXY
|
||||
void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) override;
|
||||
void unsubscribe_bluetooth_le_advertisements(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override;
|
||||
@@ -188,7 +190,9 @@ class APIConnection : public APIServerConnection {
|
||||
// we initiated ping
|
||||
this->flags_.sent_ping = false;
|
||||
}
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
void on_home_assistant_state_response(const HomeAssistantStateResponse &msg) override;
|
||||
#endif
|
||||
#ifdef USE_HOMEASSISTANT_TIME
|
||||
void on_get_time_response(const GetTimeResponse &value) override;
|
||||
#endif
|
||||
@@ -207,10 +211,14 @@ class APIConnection : public APIServerConnection {
|
||||
if (msg.dump_config)
|
||||
App.schedule_dump_config();
|
||||
}
|
||||
#ifdef USE_API_HOMEASSISTANT_SERVICES
|
||||
void subscribe_homeassistant_services(const SubscribeHomeassistantServicesRequest &msg) override {
|
||||
this->flags_.service_call_subscription = true;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
void subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) override;
|
||||
#endif
|
||||
bool send_get_time_response(const GetTimeRequest &msg) override;
|
||||
#ifdef USE_API_SERVICES
|
||||
void execute_service(const ExecuteServiceRequest &msg) override;
|
||||
@@ -227,8 +235,17 @@ class APIConnection : public APIServerConnection {
|
||||
this->is_authenticated();
|
||||
}
|
||||
uint8_t get_log_subscription_level() const { return this->flags_.log_subscription; }
|
||||
|
||||
// Get client API version for feature detection
|
||||
bool client_supports_api_version(uint16_t major, uint16_t minor) const {
|
||||
return this->client_api_version_major_ > major ||
|
||||
(this->client_api_version_major_ == major && this->client_api_version_minor_ >= minor);
|
||||
}
|
||||
|
||||
void on_fatal_error() override;
|
||||
#ifdef USE_API_PASSWORD
|
||||
void on_unauthenticated_access() override;
|
||||
#endif
|
||||
void on_no_setup_connection() override;
|
||||
ProtoWriteBuffer create_buffer(uint32_t reserve_size) override {
|
||||
// FIXME: ensure no recursive writes can happen
|
||||
@@ -288,6 +305,10 @@ class APIConnection : public APIServerConnection {
|
||||
// Helper function to handle authentication completion
|
||||
void complete_authentication_();
|
||||
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
void process_state_subscriptions_();
|
||||
#endif
|
||||
|
||||
// Non-template helper to encode any ProtoMessage
|
||||
static uint16_t encode_message_to_buffer(ProtoMessage &msg, uint8_t message_type, APIConnection *conn,
|
||||
uint32_t remaining_size, bool is_single);
|
||||
@@ -492,7 +513,9 @@ class APIConnection : public APIServerConnection {
|
||||
|
||||
// Group 4: 4-byte types
|
||||
uint32_t last_traffic_;
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
int state_subs_at_ = -1;
|
||||
#endif
|
||||
|
||||
// Function pointer type for message encoding
|
||||
using MessageCreatorPtr = uint16_t (*)(EntityBase *, APIConnection *, uint32_t remaining_size, bool is_single);
|
||||
@@ -720,6 +743,11 @@ class APIConnection : public APIServerConnection {
|
||||
this->deferred_batch_.add_item_front(entity, MessageCreator(function_ptr), message_type, estimated_size);
|
||||
return this->schedule_batch_();
|
||||
}
|
||||
|
||||
// Helper function to log API errors with errno
|
||||
void log_warning_(const char *message, APIError err);
|
||||
// Specific helper for duplicated error message
|
||||
void log_socket_operation_failed_(APIError err);
|
||||
};
|
||||
|
||||
} // namespace esphome::api
|
||||
|
@@ -27,4 +27,33 @@ extend google.protobuf.MessageOptions {
|
||||
extend google.protobuf.FieldOptions {
|
||||
optional string field_ifdef = 1042;
|
||||
optional uint32 fixed_array_size = 50007;
|
||||
optional bool no_zero_copy = 50008 [default=false];
|
||||
optional bool fixed_array_skip_zero = 50009 [default=false];
|
||||
optional string fixed_array_size_define = 50010;
|
||||
|
||||
// container_pointer: Zero-copy optimization for repeated fields.
|
||||
//
|
||||
// When container_pointer is set on a repeated field, the generated message will
|
||||
// store a pointer to an existing container instead of copying the data into the
|
||||
// message's own repeated field. This eliminates heap allocations and improves performance.
|
||||
//
|
||||
// Requirements for safe usage:
|
||||
// 1. The source container must remain valid until the message is encoded
|
||||
// 2. Messages must be encoded immediately (which ESPHome does by default)
|
||||
// 3. The container type must match the field type exactly
|
||||
//
|
||||
// Supported container types:
|
||||
// - "std::vector<T>" for most repeated fields
|
||||
// - "std::set<T>" for unique/sorted data
|
||||
// - Full type specification required for enums (e.g., "std::set<climate::ClimateMode>")
|
||||
//
|
||||
// Example usage in .proto file:
|
||||
// repeated string supported_modes = 12 [(container_pointer) = "std::set"];
|
||||
// repeated ColorMode color_modes = 13 [(container_pointer) = "std::set<light::ColorMode>"];
|
||||
//
|
||||
// The corresponding C++ code must provide const reference access to a container
|
||||
// that matches the specified type and remains valid during message encoding.
|
||||
// This is typically done through methods returning const T& or special accessor
|
||||
// methods like get_options() or supported_modes_for_api_().
|
||||
optional string container_pointer = 50001;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,7 @@
|
||||
#include "esphome/core/string_ref.h"
|
||||
|
||||
#include "proto.h"
|
||||
#include "api_pb2_includes.h"
|
||||
|
||||
namespace esphome::api {
|
||||
|
||||
@@ -149,6 +150,9 @@ enum MediaPlayerState : uint32_t {
|
||||
MEDIA_PLAYER_STATE_IDLE = 1,
|
||||
MEDIA_PLAYER_STATE_PLAYING = 2,
|
||||
MEDIA_PLAYER_STATE_PAUSED = 3,
|
||||
MEDIA_PLAYER_STATE_ANNOUNCING = 4,
|
||||
MEDIA_PLAYER_STATE_OFF = 5,
|
||||
MEDIA_PLAYER_STATE_ON = 6,
|
||||
};
|
||||
enum MediaPlayerCommand : uint32_t {
|
||||
MEDIA_PLAYER_COMMAND_PLAY = 0,
|
||||
@@ -156,6 +160,15 @@ enum MediaPlayerCommand : uint32_t {
|
||||
MEDIA_PLAYER_COMMAND_STOP = 2,
|
||||
MEDIA_PLAYER_COMMAND_MUTE = 3,
|
||||
MEDIA_PLAYER_COMMAND_UNMUTE = 4,
|
||||
MEDIA_PLAYER_COMMAND_TOGGLE = 5,
|
||||
MEDIA_PLAYER_COMMAND_VOLUME_UP = 6,
|
||||
MEDIA_PLAYER_COMMAND_VOLUME_DOWN = 7,
|
||||
MEDIA_PLAYER_COMMAND_ENQUEUE = 8,
|
||||
MEDIA_PLAYER_COMMAND_REPEAT_ONE = 9,
|
||||
MEDIA_PLAYER_COMMAND_REPEAT_OFF = 10,
|
||||
MEDIA_PLAYER_COMMAND_CLEAR_PLAYLIST = 11,
|
||||
MEDIA_PLAYER_COMMAND_TURN_ON = 12,
|
||||
MEDIA_PLAYER_COMMAND_TURN_OFF = 13,
|
||||
};
|
||||
enum MediaPlayerFormatPurpose : uint32_t {
|
||||
MEDIA_PLAYER_FORMAT_PURPOSE_DEFAULT = 0,
|
||||
@@ -340,7 +353,7 @@ class HelloResponse : public ProtoMessage {
|
||||
StringRef name_ref_{};
|
||||
void set_name(const StringRef &ref) { this->name_ref_ = ref; }
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -371,14 +384,14 @@ class ConnectResponse : public ProtoMessage {
|
||||
#endif
|
||||
bool invalid_password{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
};
|
||||
class DisconnectRequest : public ProtoDecodableMessage {
|
||||
class DisconnectRequest : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 5;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
@@ -391,7 +404,7 @@ class DisconnectRequest : public ProtoDecodableMessage {
|
||||
|
||||
protected:
|
||||
};
|
||||
class DisconnectResponse : public ProtoDecodableMessage {
|
||||
class DisconnectResponse : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 6;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
@@ -404,7 +417,7 @@ class DisconnectResponse : public ProtoDecodableMessage {
|
||||
|
||||
protected:
|
||||
};
|
||||
class PingRequest : public ProtoDecodableMessage {
|
||||
class PingRequest : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 7;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
@@ -417,7 +430,7 @@ class PingRequest : public ProtoDecodableMessage {
|
||||
|
||||
protected:
|
||||
};
|
||||
class PingResponse : public ProtoDecodableMessage {
|
||||
class PingResponse : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 8;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
@@ -430,7 +443,7 @@ class PingResponse : public ProtoDecodableMessage {
|
||||
|
||||
protected:
|
||||
};
|
||||
class DeviceInfoRequest : public ProtoDecodableMessage {
|
||||
class DeviceInfoRequest : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 9;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
@@ -450,7 +463,7 @@ class AreaInfo : public ProtoMessage {
|
||||
StringRef name_ref_{};
|
||||
void set_name(const StringRef &ref) { this->name_ref_ = ref; }
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -466,7 +479,7 @@ class DeviceInfo : public ProtoMessage {
|
||||
void set_name(const StringRef &ref) { this->name_ref_ = ref; }
|
||||
uint32_t area_id{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -539,14 +552,14 @@ class DeviceInfoResponse : public ProtoMessage {
|
||||
AreaInfo area{};
|
||||
#endif
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
};
|
||||
class ListEntitiesRequest : public ProtoDecodableMessage {
|
||||
class ListEntitiesRequest : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 11;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
@@ -572,7 +585,7 @@ class ListEntitiesDoneResponse : public ProtoMessage {
|
||||
|
||||
protected:
|
||||
};
|
||||
class SubscribeStatesRequest : public ProtoDecodableMessage {
|
||||
class SubscribeStatesRequest : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 20;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
@@ -597,7 +610,7 @@ class ListEntitiesBinarySensorResponse : public InfoResponseProtoMessage {
|
||||
void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; }
|
||||
bool is_status_binary_sensor{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -614,7 +627,7 @@ class BinarySensorStateResponse : public StateResponseProtoMessage {
|
||||
bool state{false};
|
||||
bool missing_state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -637,7 +650,7 @@ class ListEntitiesCoverResponse : public InfoResponseProtoMessage {
|
||||
void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; }
|
||||
bool supports_stop{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -655,7 +668,7 @@ class CoverStateResponse : public StateResponseProtoMessage {
|
||||
float tilt{0.0f};
|
||||
enums::CoverOperation current_operation{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -695,9 +708,9 @@ class ListEntitiesFanResponse : public InfoResponseProtoMessage {
|
||||
bool supports_speed{false};
|
||||
bool supports_direction{false};
|
||||
int32_t supported_speed_count{0};
|
||||
std::vector<std::string> supported_preset_modes{};
|
||||
const std::set<std::string> *supported_preset_modes{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -718,7 +731,7 @@ class FanStateResponse : public StateResponseProtoMessage {
|
||||
StringRef preset_mode_ref_{};
|
||||
void set_preset_mode(const StringRef &ref) { this->preset_mode_ref_ = ref; }
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -760,12 +773,12 @@ class ListEntitiesLightResponse : public InfoResponseProtoMessage {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "list_entities_light_response"; }
|
||||
#endif
|
||||
std::vector<enums::ColorMode> supported_color_modes{};
|
||||
const std::set<light::ColorMode> *supported_color_modes{};
|
||||
float min_mireds{0.0f};
|
||||
float max_mireds{0.0f};
|
||||
std::vector<std::string> effects{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -793,7 +806,7 @@ class LightStateResponse : public StateResponseProtoMessage {
|
||||
StringRef effect_ref_{};
|
||||
void set_effect(const StringRef &ref) { this->effect_ref_ = ref; }
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -859,7 +872,7 @@ class ListEntitiesSensorResponse : public InfoResponseProtoMessage {
|
||||
void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; }
|
||||
enums::SensorStateClass state_class{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -876,7 +889,7 @@ class SensorStateResponse : public StateResponseProtoMessage {
|
||||
float state{0.0f};
|
||||
bool missing_state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -896,7 +909,7 @@ class ListEntitiesSwitchResponse : public InfoResponseProtoMessage {
|
||||
StringRef device_class_ref_{};
|
||||
void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; }
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -912,7 +925,7 @@ class SwitchStateResponse : public StateResponseProtoMessage {
|
||||
#endif
|
||||
bool state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -947,7 +960,7 @@ class ListEntitiesTextSensorResponse : public InfoResponseProtoMessage {
|
||||
StringRef device_class_ref_{};
|
||||
void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; }
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -965,7 +978,7 @@ class TextSensorStateResponse : public StateResponseProtoMessage {
|
||||
void set_state(const StringRef &ref) { this->state_ref_ = ref; }
|
||||
bool missing_state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1004,7 +1017,7 @@ class SubscribeLogsResponse : public ProtoMessage {
|
||||
this->message_len_ = len;
|
||||
}
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1036,7 +1049,7 @@ class NoiseEncryptionSetKeyResponse : public ProtoMessage {
|
||||
#endif
|
||||
bool success{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1044,7 +1057,8 @@ class NoiseEncryptionSetKeyResponse : public ProtoMessage {
|
||||
protected:
|
||||
};
|
||||
#endif
|
||||
class SubscribeHomeassistantServicesRequest : public ProtoDecodableMessage {
|
||||
#ifdef USE_API_HOMEASSISTANT_SERVICES
|
||||
class SubscribeHomeassistantServicesRequest : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 34;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
@@ -1061,10 +1075,9 @@ class HomeassistantServiceMap : public ProtoMessage {
|
||||
public:
|
||||
StringRef key_ref_{};
|
||||
void set_key(const StringRef &ref) { this->key_ref_ = ref; }
|
||||
StringRef value_ref_{};
|
||||
void set_value(const StringRef &ref) { this->value_ref_ = ref; }
|
||||
std::string value{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1085,14 +1098,16 @@ class HomeassistantServiceResponse : public ProtoMessage {
|
||||
std::vector<HomeassistantServiceMap> variables{};
|
||||
bool is_event{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
};
|
||||
class SubscribeHomeAssistantStatesRequest : public ProtoDecodableMessage {
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
class SubscribeHomeAssistantStatesRequest : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 38;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
@@ -1118,7 +1133,7 @@ class SubscribeHomeAssistantStateResponse : public ProtoMessage {
|
||||
void set_attribute(const StringRef &ref) { this->attribute_ref_ = ref; }
|
||||
bool once{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1142,7 +1157,8 @@ class HomeAssistantStateResponse : public ProtoDecodableMessage {
|
||||
protected:
|
||||
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
|
||||
};
|
||||
class GetTimeRequest : public ProtoDecodableMessage {
|
||||
#endif
|
||||
class GetTimeRequest : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 36;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
@@ -1164,7 +1180,7 @@ class GetTimeResponse : public ProtoDecodableMessage {
|
||||
#endif
|
||||
uint32_t epoch_seconds{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1179,7 +1195,7 @@ class ListEntitiesServicesArgument : public ProtoMessage {
|
||||
void set_name(const StringRef &ref) { this->name_ref_ = ref; }
|
||||
enums::ServiceArgType type{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1198,7 +1214,7 @@ class ListEntitiesServicesResponse : public ProtoMessage {
|
||||
uint32_t key{0};
|
||||
std::vector<ListEntitiesServicesArgument> args{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1252,7 +1268,7 @@ class ListEntitiesCameraResponse : public InfoResponseProtoMessage {
|
||||
const char *message_name() const override { return "list_entities_camera_response"; }
|
||||
#endif
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1274,7 +1290,7 @@ class CameraImageResponse : public StateResponseProtoMessage {
|
||||
}
|
||||
bool done{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1308,23 +1324,23 @@ class ListEntitiesClimateResponse : public InfoResponseProtoMessage {
|
||||
#endif
|
||||
bool supports_current_temperature{false};
|
||||
bool supports_two_point_target_temperature{false};
|
||||
std::vector<enums::ClimateMode> supported_modes{};
|
||||
const std::set<climate::ClimateMode> *supported_modes{};
|
||||
float visual_min_temperature{0.0f};
|
||||
float visual_max_temperature{0.0f};
|
||||
float visual_target_temperature_step{0.0f};
|
||||
bool supports_action{false};
|
||||
std::vector<enums::ClimateFanMode> supported_fan_modes{};
|
||||
std::vector<enums::ClimateSwingMode> supported_swing_modes{};
|
||||
std::vector<std::string> supported_custom_fan_modes{};
|
||||
std::vector<enums::ClimatePreset> supported_presets{};
|
||||
std::vector<std::string> supported_custom_presets{};
|
||||
const std::set<climate::ClimateFanMode> *supported_fan_modes{};
|
||||
const std::set<climate::ClimateSwingMode> *supported_swing_modes{};
|
||||
const std::set<std::string> *supported_custom_fan_modes{};
|
||||
const std::set<climate::ClimatePreset> *supported_presets{};
|
||||
const std::set<std::string> *supported_custom_presets{};
|
||||
float visual_current_temperature_step{0.0f};
|
||||
bool supports_current_humidity{false};
|
||||
bool supports_target_humidity{false};
|
||||
float visual_min_humidity{0.0f};
|
||||
float visual_max_humidity{0.0f};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1354,7 +1370,7 @@ class ClimateStateResponse : public StateResponseProtoMessage {
|
||||
float current_humidity{0.0f};
|
||||
float target_humidity{0.0f};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1415,7 +1431,7 @@ class ListEntitiesNumberResponse : public InfoResponseProtoMessage {
|
||||
StringRef device_class_ref_{};
|
||||
void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; }
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1432,7 +1448,7 @@ class NumberStateResponse : public StateResponseProtoMessage {
|
||||
float state{0.0f};
|
||||
bool missing_state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1464,9 +1480,9 @@ class ListEntitiesSelectResponse : public InfoResponseProtoMessage {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "list_entities_select_response"; }
|
||||
#endif
|
||||
std::vector<std::string> options{};
|
||||
const std::vector<std::string> *options{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1484,7 +1500,7 @@ class SelectStateResponse : public StateResponseProtoMessage {
|
||||
void set_state(const StringRef &ref) { this->state_ref_ = ref; }
|
||||
bool missing_state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1521,7 +1537,7 @@ class ListEntitiesSirenResponse : public InfoResponseProtoMessage {
|
||||
bool supports_duration{false};
|
||||
bool supports_volume{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1537,7 +1553,7 @@ class SirenStateResponse : public StateResponseProtoMessage {
|
||||
#endif
|
||||
bool state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1583,7 +1599,7 @@ class ListEntitiesLockResponse : public InfoResponseProtoMessage {
|
||||
StringRef code_format_ref_{};
|
||||
void set_code_format(const StringRef &ref) { this->code_format_ref_ = ref; }
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1599,7 +1615,7 @@ class LockStateResponse : public StateResponseProtoMessage {
|
||||
#endif
|
||||
enums::LockState state{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1637,7 +1653,7 @@ class ListEntitiesButtonResponse : public InfoResponseProtoMessage {
|
||||
StringRef device_class_ref_{};
|
||||
void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; }
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1670,7 +1686,7 @@ class MediaPlayerSupportedFormat : public ProtoMessage {
|
||||
enums::MediaPlayerFormatPurpose purpose{};
|
||||
uint32_t sample_bytes{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1680,14 +1696,15 @@ class MediaPlayerSupportedFormat : public ProtoMessage {
|
||||
class ListEntitiesMediaPlayerResponse : public InfoResponseProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 63;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 76;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 80;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "list_entities_media_player_response"; }
|
||||
#endif
|
||||
bool supports_pause{false};
|
||||
std::vector<MediaPlayerSupportedFormat> supported_formats{};
|
||||
uint32_t feature_flags{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1705,7 +1722,7 @@ class MediaPlayerStateResponse : public StateResponseProtoMessage {
|
||||
float volume{0.0f};
|
||||
bool muted{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1761,7 +1778,7 @@ class BluetoothLERawAdvertisement : public ProtoMessage {
|
||||
uint8_t data[62]{};
|
||||
uint8_t data_len{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1777,7 +1794,7 @@ class BluetoothLERawAdvertisementsResponse : public ProtoMessage {
|
||||
#endif
|
||||
std::vector<BluetoothLERawAdvertisement> advertisements{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1814,7 +1831,7 @@ class BluetoothDeviceConnectionResponse : public ProtoMessage {
|
||||
uint32_t mtu{0};
|
||||
int32_t error{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1840,8 +1857,9 @@ class BluetoothGATTDescriptor : public ProtoMessage {
|
||||
public:
|
||||
std::array<uint64_t, 2> uuid{};
|
||||
uint32_t handle{0};
|
||||
uint32_t short_uuid{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1854,8 +1872,9 @@ class BluetoothGATTCharacteristic : public ProtoMessage {
|
||||
uint32_t handle{0};
|
||||
uint32_t properties{0};
|
||||
std::vector<BluetoothGATTDescriptor> descriptors{};
|
||||
uint32_t short_uuid{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1867,8 +1886,9 @@ class BluetoothGATTService : public ProtoMessage {
|
||||
std::array<uint64_t, 2> uuid{};
|
||||
uint32_t handle{0};
|
||||
std::vector<BluetoothGATTCharacteristic> characteristics{};
|
||||
uint32_t short_uuid{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1878,14 +1898,14 @@ class BluetoothGATTService : public ProtoMessage {
|
||||
class BluetoothGATTGetServicesResponse : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 71;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 21;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 38;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "bluetooth_gatt_get_services_response"; }
|
||||
#endif
|
||||
uint64_t address{0};
|
||||
std::array<BluetoothGATTService, 1> services{};
|
||||
std::vector<BluetoothGATTService> services{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1901,7 +1921,7 @@ class BluetoothGATTGetServicesDoneResponse : public ProtoMessage {
|
||||
#endif
|
||||
uint64_t address{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -1940,7 +1960,7 @@ class BluetoothGATTReadResponse : public ProtoMessage {
|
||||
this->data_len_ = len;
|
||||
}
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2033,14 +2053,14 @@ class BluetoothGATTNotifyDataResponse : public ProtoMessage {
|
||||
this->data_len_ = len;
|
||||
}
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
};
|
||||
class SubscribeBluetoothConnectionsFreeRequest : public ProtoDecodableMessage {
|
||||
class SubscribeBluetoothConnectionsFreeRequest : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 80;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
@@ -2056,15 +2076,15 @@ class SubscribeBluetoothConnectionsFreeRequest : public ProtoDecodableMessage {
|
||||
class BluetoothConnectionsFreeResponse : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 81;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 16;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 20;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "bluetooth_connections_free_response"; }
|
||||
#endif
|
||||
uint32_t free{0};
|
||||
uint32_t limit{0};
|
||||
std::vector<uint64_t> allocated{};
|
||||
std::array<uint64_t, BLUETOOTH_PROXY_MAX_CONNECTIONS> allocated{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2082,7 +2102,7 @@ class BluetoothGATTErrorResponse : public ProtoMessage {
|
||||
uint32_t handle{0};
|
||||
int32_t error{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2099,7 +2119,7 @@ class BluetoothGATTWriteResponse : public ProtoMessage {
|
||||
uint64_t address{0};
|
||||
uint32_t handle{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2116,7 +2136,7 @@ class BluetoothGATTNotifyResponse : public ProtoMessage {
|
||||
uint64_t address{0};
|
||||
uint32_t handle{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2134,7 +2154,7 @@ class BluetoothDevicePairingResponse : public ProtoMessage {
|
||||
bool paired{false};
|
||||
int32_t error{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2152,14 +2172,14 @@ class BluetoothDeviceUnpairingResponse : public ProtoMessage {
|
||||
bool success{false};
|
||||
int32_t error{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
};
|
||||
class UnsubscribeBluetoothLEAdvertisementsRequest : public ProtoDecodableMessage {
|
||||
class UnsubscribeBluetoothLEAdvertisementsRequest : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 87;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
@@ -2183,7 +2203,7 @@ class BluetoothDeviceClearCacheResponse : public ProtoMessage {
|
||||
bool success{false};
|
||||
int32_t error{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2200,7 +2220,7 @@ class BluetoothScannerStateResponse : public ProtoMessage {
|
||||
enums::BluetoothScannerState state{};
|
||||
enums::BluetoothScannerMode mode{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2246,7 +2266,7 @@ class VoiceAssistantAudioSettings : public ProtoMessage {
|
||||
uint32_t auto_gain{0};
|
||||
float volume_multiplier{0.0f};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2268,7 +2288,7 @@ class VoiceAssistantRequest : public ProtoMessage {
|
||||
StringRef wake_word_phrase_ref_{};
|
||||
void set_wake_word_phrase(const StringRef &ref) { this->wake_word_phrase_ref_ = ref; }
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2335,7 +2355,7 @@ class VoiceAssistantAudio : public ProtoDecodableMessage {
|
||||
}
|
||||
bool end{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2393,7 +2413,7 @@ class VoiceAssistantAnnounceFinished : public ProtoMessage {
|
||||
#endif
|
||||
bool success{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2408,14 +2428,14 @@ class VoiceAssistantWakeWord : public ProtoMessage {
|
||||
void set_wake_word(const StringRef &ref) { this->wake_word_ref_ = ref; }
|
||||
std::vector<std::string> trained_languages{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
};
|
||||
class VoiceAssistantConfigurationRequest : public ProtoDecodableMessage {
|
||||
class VoiceAssistantConfigurationRequest : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 121;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
@@ -2436,10 +2456,10 @@ class VoiceAssistantConfigurationResponse : public ProtoMessage {
|
||||
const char *message_name() const override { return "voice_assistant_configuration_response"; }
|
||||
#endif
|
||||
std::vector<VoiceAssistantWakeWord> available_wake_words{};
|
||||
std::vector<std::string> active_wake_words{};
|
||||
const std::vector<std::string> *active_wake_words{};
|
||||
uint32_t max_active_wake_words{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2474,7 +2494,7 @@ class ListEntitiesAlarmControlPanelResponse : public InfoResponseProtoMessage {
|
||||
bool requires_code{false};
|
||||
bool requires_code_to_arm{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2490,7 +2510,7 @@ class AlarmControlPanelStateResponse : public StateResponseProtoMessage {
|
||||
#endif
|
||||
enums::AlarmControlPanelState state{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2530,7 +2550,7 @@ class ListEntitiesTextResponse : public InfoResponseProtoMessage {
|
||||
void set_pattern(const StringRef &ref) { this->pattern_ref_ = ref; }
|
||||
enums::TextMode mode{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2548,7 +2568,7 @@ class TextStateResponse : public StateResponseProtoMessage {
|
||||
void set_state(const StringRef &ref) { this->state_ref_ = ref; }
|
||||
bool missing_state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2582,7 +2602,7 @@ class ListEntitiesDateResponse : public InfoResponseProtoMessage {
|
||||
const char *message_name() const override { return "list_entities_date_response"; }
|
||||
#endif
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2601,7 +2621,7 @@ class DateStateResponse : public StateResponseProtoMessage {
|
||||
uint32_t month{0};
|
||||
uint32_t day{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2636,7 +2656,7 @@ class ListEntitiesTimeResponse : public InfoResponseProtoMessage {
|
||||
const char *message_name() const override { return "list_entities_time_response"; }
|
||||
#endif
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2655,7 +2675,7 @@ class TimeStateResponse : public StateResponseProtoMessage {
|
||||
uint32_t minute{0};
|
||||
uint32_t second{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2693,7 +2713,7 @@ class ListEntitiesEventResponse : public InfoResponseProtoMessage {
|
||||
void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; }
|
||||
std::vector<std::string> event_types{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2710,7 +2730,7 @@ class EventResponse : public StateResponseProtoMessage {
|
||||
StringRef event_type_ref_{};
|
||||
void set_event_type(const StringRef &ref) { this->event_type_ref_ = ref; }
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2732,7 +2752,7 @@ class ListEntitiesValveResponse : public InfoResponseProtoMessage {
|
||||
bool supports_position{false};
|
||||
bool supports_stop{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2749,7 +2769,7 @@ class ValveStateResponse : public StateResponseProtoMessage {
|
||||
float position{0.0f};
|
||||
enums::ValveOperation current_operation{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2784,7 +2804,7 @@ class ListEntitiesDateTimeResponse : public InfoResponseProtoMessage {
|
||||
const char *message_name() const override { return "list_entities_date_time_response"; }
|
||||
#endif
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2801,7 +2821,7 @@ class DateTimeStateResponse : public StateResponseProtoMessage {
|
||||
bool missing_state{false};
|
||||
uint32_t epoch_seconds{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2836,7 +2856,7 @@ class ListEntitiesUpdateResponse : public InfoResponseProtoMessage {
|
||||
StringRef device_class_ref_{};
|
||||
void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; }
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
@@ -2865,7 +2885,7 @@ class UpdateStateResponse : public StateResponseProtoMessage {
|
||||
StringRef release_url_ref_{};
|
||||
void set_release_url(const StringRef &ref) { this->release_url_ref_ = ref; }
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
|
@@ -383,6 +383,12 @@ template<> const char *proto_enum_to_string<enums::MediaPlayerState>(enums::Medi
|
||||
return "MEDIA_PLAYER_STATE_PLAYING";
|
||||
case enums::MEDIA_PLAYER_STATE_PAUSED:
|
||||
return "MEDIA_PLAYER_STATE_PAUSED";
|
||||
case enums::MEDIA_PLAYER_STATE_ANNOUNCING:
|
||||
return "MEDIA_PLAYER_STATE_ANNOUNCING";
|
||||
case enums::MEDIA_PLAYER_STATE_OFF:
|
||||
return "MEDIA_PLAYER_STATE_OFF";
|
||||
case enums::MEDIA_PLAYER_STATE_ON:
|
||||
return "MEDIA_PLAYER_STATE_ON";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
@@ -399,6 +405,24 @@ template<> const char *proto_enum_to_string<enums::MediaPlayerCommand>(enums::Me
|
||||
return "MEDIA_PLAYER_COMMAND_MUTE";
|
||||
case enums::MEDIA_PLAYER_COMMAND_UNMUTE:
|
||||
return "MEDIA_PLAYER_COMMAND_UNMUTE";
|
||||
case enums::MEDIA_PLAYER_COMMAND_TOGGLE:
|
||||
return "MEDIA_PLAYER_COMMAND_TOGGLE";
|
||||
case enums::MEDIA_PLAYER_COMMAND_VOLUME_UP:
|
||||
return "MEDIA_PLAYER_COMMAND_VOLUME_UP";
|
||||
case enums::MEDIA_PLAYER_COMMAND_VOLUME_DOWN:
|
||||
return "MEDIA_PLAYER_COMMAND_VOLUME_DOWN";
|
||||
case enums::MEDIA_PLAYER_COMMAND_ENQUEUE:
|
||||
return "MEDIA_PLAYER_COMMAND_ENQUEUE";
|
||||
case enums::MEDIA_PLAYER_COMMAND_REPEAT_ONE:
|
||||
return "MEDIA_PLAYER_COMMAND_REPEAT_ONE";
|
||||
case enums::MEDIA_PLAYER_COMMAND_REPEAT_OFF:
|
||||
return "MEDIA_PLAYER_COMMAND_REPEAT_OFF";
|
||||
case enums::MEDIA_PLAYER_COMMAND_CLEAR_PLAYLIST:
|
||||
return "MEDIA_PLAYER_COMMAND_CLEAR_PLAYLIST";
|
||||
case enums::MEDIA_PLAYER_COMMAND_TURN_ON:
|
||||
return "MEDIA_PLAYER_COMMAND_TURN_ON";
|
||||
case enums::MEDIA_PLAYER_COMMAND_TURN_OFF:
|
||||
return "MEDIA_PLAYER_COMMAND_TURN_OFF";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
@@ -814,7 +838,7 @@ void ListEntitiesFanResponse::dump_to(std::string &out) const {
|
||||
dump_field(out, "icon", this->icon_ref_);
|
||||
#endif
|
||||
dump_field(out, "entity_category", static_cast<enums::EntityCategory>(this->entity_category));
|
||||
for (const auto &it : this->supported_preset_modes) {
|
||||
for (const auto &it : *this->supported_preset_modes) {
|
||||
dump_field(out, "supported_preset_modes", it, 4);
|
||||
}
|
||||
#ifdef USE_DEVICES
|
||||
@@ -857,7 +881,7 @@ void ListEntitiesLightResponse::dump_to(std::string &out) const {
|
||||
dump_field(out, "object_id", this->object_id_ref_);
|
||||
dump_field(out, "key", this->key);
|
||||
dump_field(out, "name", this->name_ref_);
|
||||
for (const auto &it : this->supported_color_modes) {
|
||||
for (const auto &it : *this->supported_color_modes) {
|
||||
dump_field(out, "supported_color_modes", static_cast<enums::ColorMode>(it), 4);
|
||||
}
|
||||
dump_field(out, "min_mireds", this->min_mireds);
|
||||
@@ -1038,13 +1062,14 @@ void NoiseEncryptionSetKeyRequest::dump_to(std::string &out) const {
|
||||
}
|
||||
void NoiseEncryptionSetKeyResponse::dump_to(std::string &out) const { dump_field(out, "success", this->success); }
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_SERVICES
|
||||
void SubscribeHomeassistantServicesRequest::dump_to(std::string &out) const {
|
||||
out.append("SubscribeHomeassistantServicesRequest {}");
|
||||
}
|
||||
void HomeassistantServiceMap::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "HomeassistantServiceMap");
|
||||
dump_field(out, "key", this->key_ref_);
|
||||
dump_field(out, "value", this->value_ref_);
|
||||
dump_field(out, "value", this->value);
|
||||
}
|
||||
void HomeassistantServiceResponse::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "HomeassistantServiceResponse");
|
||||
@@ -1066,6 +1091,8 @@ void HomeassistantServiceResponse::dump_to(std::string &out) const {
|
||||
}
|
||||
dump_field(out, "is_event", this->is_event);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
void SubscribeHomeAssistantStatesRequest::dump_to(std::string &out) const {
|
||||
out.append("SubscribeHomeAssistantStatesRequest {}");
|
||||
}
|
||||
@@ -1081,6 +1108,7 @@ void HomeAssistantStateResponse::dump_to(std::string &out) const {
|
||||
dump_field(out, "state", this->state);
|
||||
dump_field(out, "attribute", this->attribute);
|
||||
}
|
||||
#endif
|
||||
void GetTimeRequest::dump_to(std::string &out) const { out.append("GetTimeRequest {}"); }
|
||||
void GetTimeResponse::dump_to(std::string &out) const { dump_field(out, "epoch_seconds", this->epoch_seconds); }
|
||||
#ifdef USE_API_SERVICES
|
||||
@@ -1169,26 +1197,26 @@ void ListEntitiesClimateResponse::dump_to(std::string &out) const {
|
||||
dump_field(out, "name", this->name_ref_);
|
||||
dump_field(out, "supports_current_temperature", this->supports_current_temperature);
|
||||
dump_field(out, "supports_two_point_target_temperature", this->supports_two_point_target_temperature);
|
||||
for (const auto &it : this->supported_modes) {
|
||||
for (const auto &it : *this->supported_modes) {
|
||||
dump_field(out, "supported_modes", static_cast<enums::ClimateMode>(it), 4);
|
||||
}
|
||||
dump_field(out, "visual_min_temperature", this->visual_min_temperature);
|
||||
dump_field(out, "visual_max_temperature", this->visual_max_temperature);
|
||||
dump_field(out, "visual_target_temperature_step", this->visual_target_temperature_step);
|
||||
dump_field(out, "supports_action", this->supports_action);
|
||||
for (const auto &it : this->supported_fan_modes) {
|
||||
for (const auto &it : *this->supported_fan_modes) {
|
||||
dump_field(out, "supported_fan_modes", static_cast<enums::ClimateFanMode>(it), 4);
|
||||
}
|
||||
for (const auto &it : this->supported_swing_modes) {
|
||||
for (const auto &it : *this->supported_swing_modes) {
|
||||
dump_field(out, "supported_swing_modes", static_cast<enums::ClimateSwingMode>(it), 4);
|
||||
}
|
||||
for (const auto &it : this->supported_custom_fan_modes) {
|
||||
for (const auto &it : *this->supported_custom_fan_modes) {
|
||||
dump_field(out, "supported_custom_fan_modes", it, 4);
|
||||
}
|
||||
for (const auto &it : this->supported_presets) {
|
||||
for (const auto &it : *this->supported_presets) {
|
||||
dump_field(out, "supported_presets", static_cast<enums::ClimatePreset>(it), 4);
|
||||
}
|
||||
for (const auto &it : this->supported_custom_presets) {
|
||||
for (const auto &it : *this->supported_custom_presets) {
|
||||
dump_field(out, "supported_custom_presets", it, 4);
|
||||
}
|
||||
dump_field(out, "disabled_by_default", this->disabled_by_default);
|
||||
@@ -1301,7 +1329,7 @@ void ListEntitiesSelectResponse::dump_to(std::string &out) const {
|
||||
#ifdef USE_ENTITY_ICON
|
||||
dump_field(out, "icon", this->icon_ref_);
|
||||
#endif
|
||||
for (const auto &it : this->options) {
|
||||
for (const auto &it : *this->options) {
|
||||
dump_field(out, "options", it, 4);
|
||||
}
|
||||
dump_field(out, "disabled_by_default", this->disabled_by_default);
|
||||
@@ -1462,6 +1490,7 @@ void ListEntitiesMediaPlayerResponse::dump_to(std::string &out) const {
|
||||
#ifdef USE_DEVICES
|
||||
dump_field(out, "device_id", this->device_id);
|
||||
#endif
|
||||
dump_field(out, "feature_flags", this->feature_flags);
|
||||
}
|
||||
void MediaPlayerStateResponse::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "MediaPlayerStateResponse");
|
||||
@@ -1532,6 +1561,7 @@ void BluetoothGATTDescriptor::dump_to(std::string &out) const {
|
||||
dump_field(out, "uuid", it, 4);
|
||||
}
|
||||
dump_field(out, "handle", this->handle);
|
||||
dump_field(out, "short_uuid", this->short_uuid);
|
||||
}
|
||||
void BluetoothGATTCharacteristic::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "BluetoothGATTCharacteristic");
|
||||
@@ -1545,6 +1575,7 @@ void BluetoothGATTCharacteristic::dump_to(std::string &out) const {
|
||||
it.dump_to(out);
|
||||
out.append("\n");
|
||||
}
|
||||
dump_field(out, "short_uuid", this->short_uuid);
|
||||
}
|
||||
void BluetoothGATTService::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "BluetoothGATTService");
|
||||
@@ -1557,6 +1588,7 @@ void BluetoothGATTService::dump_to(std::string &out) const {
|
||||
it.dump_to(out);
|
||||
out.append("\n");
|
||||
}
|
||||
dump_field(out, "short_uuid", this->short_uuid);
|
||||
}
|
||||
void BluetoothGATTGetServicesResponse::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "BluetoothGATTGetServicesResponse");
|
||||
@@ -1765,7 +1797,7 @@ void VoiceAssistantConfigurationResponse::dump_to(std::string &out) const {
|
||||
it.dump_to(out);
|
||||
out.append("\n");
|
||||
}
|
||||
for (const auto &it : this->active_wake_words) {
|
||||
for (const auto &it : *this->active_wake_words) {
|
||||
dump_field(out, "active_wake_words", it, 4);
|
||||
}
|
||||
dump_field(out, "max_active_wake_words", this->max_active_wake_words);
|
||||
|
34
esphome/components/api/api_pb2_includes.h
Normal file
34
esphome/components/api/api_pb2_includes.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/defines.h"
|
||||
|
||||
// This file provides includes needed by the generated protobuf code
|
||||
// when using pointer optimizations for component-specific types
|
||||
|
||||
#ifdef USE_CLIMATE
|
||||
#include "esphome/components/climate/climate_mode.h"
|
||||
#include "esphome/components/climate/climate_traits.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIGHT
|
||||
#include "esphome/components/light/light_traits.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_FAN
|
||||
#include "esphome/components/fan/fan_traits.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_SELECT
|
||||
#include "esphome/components/select/select_traits.h"
|
||||
#endif
|
||||
|
||||
// Standard library includes that might be needed
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace esphome::api {
|
||||
|
||||
// This file only provides includes, no actual code
|
||||
|
||||
} // namespace esphome::api
|
@@ -35,7 +35,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
}
|
||||
case DisconnectRequest::MESSAGE_TYPE: {
|
||||
DisconnectRequest msg;
|
||||
msg.decode(msg_data, msg_size);
|
||||
// Empty message: no decode needed
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "on_disconnect_request: %s", msg.dump().c_str());
|
||||
#endif
|
||||
@@ -44,7 +44,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
}
|
||||
case DisconnectResponse::MESSAGE_TYPE: {
|
||||
DisconnectResponse msg;
|
||||
msg.decode(msg_data, msg_size);
|
||||
// Empty message: no decode needed
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "on_disconnect_response: %s", msg.dump().c_str());
|
||||
#endif
|
||||
@@ -53,7 +53,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
}
|
||||
case PingRequest::MESSAGE_TYPE: {
|
||||
PingRequest msg;
|
||||
msg.decode(msg_data, msg_size);
|
||||
// Empty message: no decode needed
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "on_ping_request: %s", msg.dump().c_str());
|
||||
#endif
|
||||
@@ -62,7 +62,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
}
|
||||
case PingResponse::MESSAGE_TYPE: {
|
||||
PingResponse msg;
|
||||
msg.decode(msg_data, msg_size);
|
||||
// Empty message: no decode needed
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "on_ping_response: %s", msg.dump().c_str());
|
||||
#endif
|
||||
@@ -71,7 +71,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
}
|
||||
case DeviceInfoRequest::MESSAGE_TYPE: {
|
||||
DeviceInfoRequest msg;
|
||||
msg.decode(msg_data, msg_size);
|
||||
// Empty message: no decode needed
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "on_device_info_request: %s", msg.dump().c_str());
|
||||
#endif
|
||||
@@ -80,7 +80,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
}
|
||||
case ListEntitiesRequest::MESSAGE_TYPE: {
|
||||
ListEntitiesRequest msg;
|
||||
msg.decode(msg_data, msg_size);
|
||||
// Empty message: no decode needed
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "on_list_entities_request: %s", msg.dump().c_str());
|
||||
#endif
|
||||
@@ -89,7 +89,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
}
|
||||
case SubscribeStatesRequest::MESSAGE_TYPE: {
|
||||
SubscribeStatesRequest msg;
|
||||
msg.decode(msg_data, msg_size);
|
||||
// Empty message: no decode needed
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "on_subscribe_states_request: %s", msg.dump().c_str());
|
||||
#endif
|
||||
@@ -149,18 +149,20 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_SERVICES
|
||||
case SubscribeHomeassistantServicesRequest::MESSAGE_TYPE: {
|
||||
SubscribeHomeassistantServicesRequest msg;
|
||||
msg.decode(msg_data, msg_size);
|
||||
// Empty message: no decode needed
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "on_subscribe_homeassistant_services_request: %s", msg.dump().c_str());
|
||||
#endif
|
||||
this->on_subscribe_homeassistant_services_request(msg);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case GetTimeRequest::MESSAGE_TYPE: {
|
||||
GetTimeRequest msg;
|
||||
msg.decode(msg_data, msg_size);
|
||||
// Empty message: no decode needed
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "on_get_time_request: %s", msg.dump().c_str());
|
||||
#endif
|
||||
@@ -176,15 +178,18 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
this->on_get_time_response(msg);
|
||||
break;
|
||||
}
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
case SubscribeHomeAssistantStatesRequest::MESSAGE_TYPE: {
|
||||
SubscribeHomeAssistantStatesRequest msg;
|
||||
msg.decode(msg_data, msg_size);
|
||||
// Empty message: no decode needed
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "on_subscribe_home_assistant_states_request: %s", msg.dump().c_str());
|
||||
#endif
|
||||
this->on_subscribe_home_assistant_states_request(msg);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
case HomeAssistantStateResponse::MESSAGE_TYPE: {
|
||||
HomeAssistantStateResponse msg;
|
||||
msg.decode(msg_data, msg_size);
|
||||
@@ -194,6 +199,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
this->on_home_assistant_state_response(msg);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_API_SERVICES
|
||||
case ExecuteServiceRequest::MESSAGE_TYPE: {
|
||||
ExecuteServiceRequest msg;
|
||||
@@ -384,7 +390,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
#ifdef USE_BLUETOOTH_PROXY
|
||||
case SubscribeBluetoothConnectionsFreeRequest::MESSAGE_TYPE: {
|
||||
SubscribeBluetoothConnectionsFreeRequest msg;
|
||||
msg.decode(msg_data, msg_size);
|
||||
// Empty message: no decode needed
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "on_subscribe_bluetooth_connections_free_request: %s", msg.dump().c_str());
|
||||
#endif
|
||||
@@ -395,7 +401,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
#ifdef USE_BLUETOOTH_PROXY
|
||||
case UnsubscribeBluetoothLEAdvertisementsRequest::MESSAGE_TYPE: {
|
||||
UnsubscribeBluetoothLEAdvertisementsRequest msg;
|
||||
msg.decode(msg_data, msg_size);
|
||||
// Empty message: no decode needed
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "on_unsubscribe_bluetooth_le_advertisements_request: %s", msg.dump().c_str());
|
||||
#endif
|
||||
@@ -549,7 +555,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
#ifdef USE_VOICE_ASSISTANT
|
||||
case VoiceAssistantConfigurationRequest::MESSAGE_TYPE: {
|
||||
VoiceAssistantConfigurationRequest msg;
|
||||
msg.decode(msg_data, msg_size);
|
||||
// Empty message: no decode needed
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "on_voice_assistant_configuration_request: %s", msg.dump().c_str());
|
||||
#endif
|
||||
@@ -635,17 +641,21 @@ void APIServerConnection::on_subscribe_logs_request(const SubscribeLogsRequest &
|
||||
this->subscribe_logs(msg);
|
||||
}
|
||||
}
|
||||
#ifdef USE_API_HOMEASSISTANT_SERVICES
|
||||
void APIServerConnection::on_subscribe_homeassistant_services_request(
|
||||
const SubscribeHomeassistantServicesRequest &msg) {
|
||||
if (this->check_authenticated_()) {
|
||||
this->subscribe_homeassistant_services(msg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
void APIServerConnection::on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &msg) {
|
||||
if (this->check_authenticated_()) {
|
||||
this->subscribe_home_assistant_states(msg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void APIServerConnection::on_get_time_request(const GetTimeRequest &msg) {
|
||||
if (this->check_connection_setup_() && !this->send_get_time_response(msg)) {
|
||||
this->on_fatal_error();
|
||||
|
@@ -60,11 +60,17 @@ class APIServerConnectionBase : public ProtoService {
|
||||
virtual void on_noise_encryption_set_key_request(const NoiseEncryptionSetKeyRequest &value){};
|
||||
#endif
|
||||
|
||||
#ifdef USE_API_HOMEASSISTANT_SERVICES
|
||||
virtual void on_subscribe_homeassistant_services_request(const SubscribeHomeassistantServicesRequest &value){};
|
||||
#endif
|
||||
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
virtual void on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &value){};
|
||||
#endif
|
||||
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
virtual void on_home_assistant_state_response(const HomeAssistantStateResponse &value){};
|
||||
#endif
|
||||
virtual void on_get_time_request(const GetTimeRequest &value){};
|
||||
virtual void on_get_time_response(const GetTimeResponse &value){};
|
||||
|
||||
@@ -214,8 +220,12 @@ class APIServerConnection : public APIServerConnectionBase {
|
||||
virtual void list_entities(const ListEntitiesRequest &msg) = 0;
|
||||
virtual void subscribe_states(const SubscribeStatesRequest &msg) = 0;
|
||||
virtual void subscribe_logs(const SubscribeLogsRequest &msg) = 0;
|
||||
#ifdef USE_API_HOMEASSISTANT_SERVICES
|
||||
virtual void subscribe_homeassistant_services(const SubscribeHomeassistantServicesRequest &msg) = 0;
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
virtual void subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) = 0;
|
||||
#endif
|
||||
virtual bool send_get_time_response(const GetTimeRequest &msg) = 0;
|
||||
#ifdef USE_API_SERVICES
|
||||
virtual void execute_service(const ExecuteServiceRequest &msg) = 0;
|
||||
@@ -332,8 +342,12 @@ class APIServerConnection : public APIServerConnectionBase {
|
||||
void on_list_entities_request(const ListEntitiesRequest &msg) override;
|
||||
void on_subscribe_states_request(const SubscribeStatesRequest &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;
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
void on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &msg) override;
|
||||
#endif
|
||||
void on_get_time_request(const GetTimeRequest &msg) override;
|
||||
#ifdef USE_API_SERVICES
|
||||
void on_execute_service_request(const ExecuteServiceRequest &msg) override;
|
||||
|
@@ -369,12 +369,15 @@ 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; }
|
||||
|
||||
#ifdef USE_API_HOMEASSISTANT_SERVICES
|
||||
void APIServer::send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
|
||||
for (auto &client : this->clients_) {
|
||||
client->send_homeassistant_service_call(call);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
void APIServer::subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
|
||||
std::function<void(std::string)> f) {
|
||||
this->state_subs_.push_back(HomeAssistantStateSubscription{
|
||||
@@ -398,6 +401,7 @@ void APIServer::get_home_assistant_state(std::string entity_id, optional<std::st
|
||||
const std::vector<APIServer::HomeAssistantStateSubscription> &APIServer::get_state_subs() const {
|
||||
return this->state_subs_;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t APIServer::get_port() const { return this->port_; }
|
||||
|
||||
|
@@ -106,7 +106,9 @@ class APIServer : public Component, public Controller {
|
||||
#ifdef USE_MEDIA_PLAYER
|
||||
void on_media_player_update(media_player::MediaPlayer *obj) override;
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_SERVICES
|
||||
void send_homeassistant_service_call(const HomeassistantServiceResponse &call);
|
||||
#endif
|
||||
#ifdef USE_API_SERVICES
|
||||
void register_user_service(UserServiceDescriptor *descriptor) { this->user_services_.push_back(descriptor); }
|
||||
#endif
|
||||
@@ -126,6 +128,7 @@ class APIServer : public Component, public Controller {
|
||||
|
||||
bool is_connected() const;
|
||||
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
struct HomeAssistantStateSubscription {
|
||||
std::string entity_id;
|
||||
optional<std::string> attribute;
|
||||
@@ -138,6 +141,7 @@ class APIServer : public Component, public Controller {
|
||||
void get_home_assistant_state(std::string entity_id, optional<std::string> attribute,
|
||||
std::function<void(std::string)> f);
|
||||
const std::vector<HomeAssistantStateSubscription> &get_state_subs() const;
|
||||
#endif
|
||||
#ifdef USE_API_SERVICES
|
||||
const std::vector<UserServiceDescriptor *> &get_user_services() const { return this->user_services_; }
|
||||
#endif
|
||||
@@ -171,7 +175,9 @@ class APIServer : public Component, public Controller {
|
||||
std::string password_;
|
||||
#endif
|
||||
std::vector<uint8_t> shared_write_buffer_; // Shared proto write buffer for all connections
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
std::vector<HomeAssistantStateSubscription> state_subs_;
|
||||
#endif
|
||||
#ifdef USE_API_SERVICES
|
||||
std::vector<UserServiceDescriptor *> user_services_;
|
||||
#endif
|
||||
|
@@ -83,6 +83,7 @@ class CustomAPIDevice {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
/** Subscribe to the state (or attribute state) of an entity from Home Assistant.
|
||||
*
|
||||
* Usage:
|
||||
@@ -134,7 +135,9 @@ class CustomAPIDevice {
|
||||
auto f = std::bind(callback, (T *) this, entity_id, std::placeholders::_1);
|
||||
global_api_server->subscribe_home_assistant_state(entity_id, optional<std::string>(attribute), f);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_API_HOMEASSISTANT_SERVICES
|
||||
/** Call a Home Assistant service from ESPHome.
|
||||
*
|
||||
* Usage:
|
||||
@@ -172,7 +175,7 @@ class CustomAPIDevice {
|
||||
resp.data.emplace_back();
|
||||
auto &kv = resp.data.back();
|
||||
kv.set_key(StringRef(it.first));
|
||||
kv.set_value(StringRef(it.second));
|
||||
kv.value = it.second;
|
||||
}
|
||||
global_api_server->send_homeassistant_service_call(resp);
|
||||
}
|
||||
@@ -215,10 +218,11 @@ class CustomAPIDevice {
|
||||
resp.data.emplace_back();
|
||||
auto &kv = resp.data.back();
|
||||
kv.set_key(StringRef(it.first));
|
||||
kv.set_value(StringRef(it.second));
|
||||
kv.value = it.second;
|
||||
}
|
||||
global_api_server->send_homeassistant_service_call(resp);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace esphome::api
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "api_server.h"
|
||||
#ifdef USE_API
|
||||
#ifdef USE_API_HOMEASSISTANT_SERVICES
|
||||
#include "api_pb2.h"
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
@@ -69,22 +70,19 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
|
||||
resp.data.emplace_back();
|
||||
auto &kv = resp.data.back();
|
||||
kv.set_key(StringRef(it.key));
|
||||
std::string value = it.value.value(x...);
|
||||
kv.set_value(StringRef(value));
|
||||
kv.value = it.value.value(x...);
|
||||
}
|
||||
for (auto &it : this->data_template_) {
|
||||
resp.data_template.emplace_back();
|
||||
auto &kv = resp.data_template.back();
|
||||
kv.set_key(StringRef(it.key));
|
||||
std::string value = it.value.value(x...);
|
||||
kv.set_value(StringRef(value));
|
||||
kv.value = it.value.value(x...);
|
||||
}
|
||||
for (auto &it : this->variables_) {
|
||||
resp.variables.emplace_back();
|
||||
auto &kv = resp.variables.back();
|
||||
kv.set_key(StringRef(it.key));
|
||||
std::string value = it.value.value(x...);
|
||||
kv.set_value(StringRef(value));
|
||||
kv.value = it.value.value(x...);
|
||||
}
|
||||
this->parent_->send_homeassistant_service_call(resp);
|
||||
}
|
||||
@@ -100,3 +98,4 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
|
||||
|
||||
} // namespace esphome::api
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -35,11 +35,10 @@ namespace esphome::api {
|
||||
*
|
||||
* Unsafe Patterns (WILL cause crashes/corruption):
|
||||
* 1. Temporaries: msg.set_field(StringRef(obj.get_string())) // get_string() returns by value
|
||||
* 2. Optional values: msg.set_field(StringRef(optional.value())) // value() returns a copy
|
||||
* 3. Concatenation: msg.set_field(StringRef(str1 + str2)) // Result is temporary
|
||||
* 2. Concatenation: msg.set_field(StringRef(str1 + str2)) // Result is temporary
|
||||
*
|
||||
* For unsafe patterns, store in a local variable first:
|
||||
* std::string temp = optional.value(); // or get_string() or str1 + str2
|
||||
* std::string temp = get_string(); // or str1 + str2
|
||||
* msg.set_field(StringRef(temp));
|
||||
*
|
||||
* The send_*_response pattern ensures proper lifetime management by encoding
|
||||
@@ -334,13 +333,16 @@ class ProtoWriteBuffer {
|
||||
std::vector<uint8_t> *buffer_;
|
||||
};
|
||||
|
||||
// Forward declaration
|
||||
class ProtoSize;
|
||||
|
||||
class ProtoMessage {
|
||||
public:
|
||||
virtual ~ProtoMessage() = default;
|
||||
// Default implementation for messages with no fields
|
||||
virtual void encode(ProtoWriteBuffer buffer) const {}
|
||||
// Default implementation for messages with no fields
|
||||
virtual void calculate_size(uint32_t &total_size) const {}
|
||||
virtual void calculate_size(ProtoSize &size) const {}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
std::string dump() const;
|
||||
virtual void dump_to(std::string &out) const = 0;
|
||||
@@ -361,24 +363,32 @@ class ProtoDecodableMessage : public ProtoMessage {
|
||||
};
|
||||
|
||||
class ProtoSize {
|
||||
private:
|
||||
uint32_t total_size_ = 0;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief ProtoSize class for Protocol Buffer serialization size calculation
|
||||
*
|
||||
* This class provides static methods to calculate the exact byte counts needed
|
||||
* for encoding various Protocol Buffer field types. All methods are designed to be
|
||||
* efficient for the common case where many fields have default values.
|
||||
* This class provides methods to calculate the exact byte counts needed
|
||||
* for encoding various Protocol Buffer field types. The class now uses an
|
||||
* object-based approach to reduce parameter passing overhead while keeping
|
||||
* varint calculation methods static for external use.
|
||||
*
|
||||
* Implements Protocol Buffer encoding size calculation according to:
|
||||
* https://protobuf.dev/programming-guides/encoding/
|
||||
*
|
||||
* Key features:
|
||||
* - Object-based approach reduces flash usage by eliminating parameter passing
|
||||
* - Early-return optimization for zero/default values
|
||||
* - Direct total_size updates to avoid unnecessary additions
|
||||
* - Static varint methods for external callers
|
||||
* - Specialized handling for different field types according to protobuf spec
|
||||
* - Templated helpers for repeated fields and messages
|
||||
*/
|
||||
|
||||
ProtoSize() = default;
|
||||
|
||||
uint32_t get_size() const { return total_size_; }
|
||||
|
||||
/**
|
||||
* @brief Calculates the size in bytes needed to encode a uint32_t value as a varint
|
||||
*
|
||||
@@ -479,9 +489,7 @@ class ProtoSize {
|
||||
* @brief Common parameters for all add_*_field methods
|
||||
*
|
||||
* All add_*_field methods follow these common patterns:
|
||||
*
|
||||
* @param total_size Reference to the total message size to update
|
||||
* @param field_id_size Pre-calculated size of the field ID in bytes
|
||||
* * @param field_id_size Pre-calculated size of the field ID in bytes
|
||||
* @param value The value to calculate size for (type varies)
|
||||
* @param force Whether to calculate size even if the value is default/zero/empty
|
||||
*
|
||||
@@ -494,85 +502,63 @@ class ProtoSize {
|
||||
/**
|
||||
* @brief Calculates and adds the size of an int32 field to the total message size
|
||||
*/
|
||||
static inline void add_int32_field(uint32_t &total_size, uint32_t field_id_size, int32_t value) {
|
||||
// Skip calculation if value is zero
|
||||
if (value == 0) {
|
||||
return; // No need to update total_size
|
||||
}
|
||||
|
||||
// Calculate and directly add to total_size
|
||||
if (value < 0) {
|
||||
// Negative values are encoded as 10-byte varints in protobuf
|
||||
total_size += field_id_size + 10;
|
||||
} else {
|
||||
// For non-negative values, use the standard varint size
|
||||
total_size += field_id_size + varint(static_cast<uint32_t>(value));
|
||||
inline void add_int32(uint32_t field_id_size, int32_t value) {
|
||||
if (value != 0) {
|
||||
add_int32_force(field_id_size, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of an int32 field to the total message size (repeated field version)
|
||||
* @brief Calculates and adds the size of an int32 field to the total message size (force version)
|
||||
*/
|
||||
static inline void add_int32_field_repeated(uint32_t &total_size, uint32_t field_id_size, int32_t value) {
|
||||
// Always calculate size for repeated fields
|
||||
if (value < 0) {
|
||||
// Negative values are encoded as 10-byte varints in protobuf
|
||||
total_size += field_id_size + 10;
|
||||
} else {
|
||||
// For non-negative values, use the standard varint size
|
||||
total_size += field_id_size + varint(static_cast<uint32_t>(value));
|
||||
}
|
||||
inline void add_int32_force(uint32_t field_id_size, int32_t value) {
|
||||
// Always calculate size when forced
|
||||
// Negative values are encoded as 10-byte varints in protobuf
|
||||
total_size_ += field_id_size + (value < 0 ? 10 : varint(static_cast<uint32_t>(value)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of a uint32 field to the total message size
|
||||
*/
|
||||
static inline void add_uint32_field(uint32_t &total_size, uint32_t field_id_size, uint32_t value) {
|
||||
// Skip calculation if value is zero
|
||||
if (value == 0) {
|
||||
return; // No need to update total_size
|
||||
inline void add_uint32(uint32_t field_id_size, uint32_t value) {
|
||||
if (value != 0) {
|
||||
add_uint32_force(field_id_size, value);
|
||||
}
|
||||
|
||||
// Calculate and directly add to total_size
|
||||
total_size += field_id_size + varint(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of a uint32 field to the total message size (repeated field version)
|
||||
* @brief Calculates and adds the size of a uint32 field to the total message size (force version)
|
||||
*/
|
||||
static inline void add_uint32_field_repeated(uint32_t &total_size, uint32_t field_id_size, uint32_t value) {
|
||||
// Always calculate size for repeated fields
|
||||
total_size += field_id_size + varint(value);
|
||||
inline void add_uint32_force(uint32_t field_id_size, uint32_t value) {
|
||||
// Always calculate size when force is true
|
||||
total_size_ += field_id_size + varint(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of a boolean field to the total message size
|
||||
*/
|
||||
static inline void add_bool_field(uint32_t &total_size, uint32_t field_id_size, bool value) {
|
||||
// Skip calculation if value is false
|
||||
if (!value) {
|
||||
return; // No need to update total_size
|
||||
inline void add_bool(uint32_t field_id_size, bool value) {
|
||||
if (value) {
|
||||
// Boolean fields always use 1 byte when true
|
||||
total_size_ += field_id_size + 1;
|
||||
}
|
||||
|
||||
// Boolean fields always use 1 byte when true
|
||||
total_size += field_id_size + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of a boolean field to the total message size (repeated field version)
|
||||
* @brief Calculates and adds the size of a boolean field to the total message size (force version)
|
||||
*/
|
||||
static inline void add_bool_field_repeated(uint32_t &total_size, uint32_t field_id_size, bool value) {
|
||||
// Always calculate size for repeated fields
|
||||
inline void add_bool_force(uint32_t field_id_size, bool value) {
|
||||
// Always calculate size when force is true
|
||||
// Boolean fields always use 1 byte
|
||||
total_size += field_id_size + 1;
|
||||
total_size_ += field_id_size + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of a float field to the total message size
|
||||
*/
|
||||
static inline void add_float_field(uint32_t &total_size, uint32_t field_id_size, float value) {
|
||||
inline void add_float(uint32_t field_id_size, float value) {
|
||||
if (value != 0.0f) {
|
||||
total_size += field_id_size + 4;
|
||||
total_size_ += field_id_size + 4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -582,9 +568,9 @@ class ProtoSize {
|
||||
/**
|
||||
* @brief Calculates and adds the size of a fixed32 field to the total message size
|
||||
*/
|
||||
static inline void add_fixed32_field(uint32_t &total_size, uint32_t field_id_size, uint32_t value) {
|
||||
inline void add_fixed32(uint32_t field_id_size, uint32_t value) {
|
||||
if (value != 0) {
|
||||
total_size += field_id_size + 4;
|
||||
total_size_ += field_id_size + 4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -594,149 +580,104 @@ class ProtoSize {
|
||||
/**
|
||||
* @brief Calculates and adds the size of a sfixed32 field to the total message size
|
||||
*/
|
||||
static inline void add_sfixed32_field(uint32_t &total_size, uint32_t field_id_size, int32_t value) {
|
||||
inline void add_sfixed32(uint32_t field_id_size, int32_t value) {
|
||||
if (value != 0) {
|
||||
total_size += field_id_size + 4;
|
||||
total_size_ += field_id_size + 4;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: add_sfixed64_field removed - wire type 1 (64-bit: sfixed64) not supported
|
||||
// to reduce overhead on embedded systems
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of an enum field to the total message size
|
||||
*
|
||||
* Enum fields are encoded as uint32 varints.
|
||||
*/
|
||||
static inline void add_enum_field(uint32_t &total_size, uint32_t field_id_size, uint32_t value) {
|
||||
// Skip calculation if value is zero
|
||||
if (value == 0) {
|
||||
return; // No need to update total_size
|
||||
}
|
||||
|
||||
// Enums are encoded as uint32
|
||||
total_size += field_id_size + varint(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of an enum field to the total message size (repeated field version)
|
||||
*
|
||||
* Enum fields are encoded as uint32 varints.
|
||||
*/
|
||||
static inline void add_enum_field_repeated(uint32_t &total_size, uint32_t field_id_size, uint32_t value) {
|
||||
// Always calculate size for repeated fields
|
||||
// Enums are encoded as uint32
|
||||
total_size += field_id_size + varint(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of a sint32 field to the total message size
|
||||
*
|
||||
* Sint32 fields use ZigZag encoding, which is more efficient for negative values.
|
||||
*/
|
||||
static inline void add_sint32_field(uint32_t &total_size, uint32_t field_id_size, int32_t value) {
|
||||
// Skip calculation if value is zero
|
||||
if (value == 0) {
|
||||
return; // No need to update total_size
|
||||
inline void add_sint32(uint32_t field_id_size, int32_t value) {
|
||||
if (value != 0) {
|
||||
add_sint32_force(field_id_size, value);
|
||||
}
|
||||
|
||||
// ZigZag encoding for sint32: (n << 1) ^ (n >> 31)
|
||||
uint32_t zigzag = (static_cast<uint32_t>(value) << 1) ^ (static_cast<uint32_t>(value >> 31));
|
||||
total_size += field_id_size + varint(zigzag);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of a sint32 field to the total message size (repeated field version)
|
||||
* @brief Calculates and adds the size of a sint32 field to the total message size (force version)
|
||||
*
|
||||
* Sint32 fields use ZigZag encoding, which is more efficient for negative values.
|
||||
*/
|
||||
static inline void add_sint32_field_repeated(uint32_t &total_size, uint32_t field_id_size, int32_t value) {
|
||||
// Always calculate size for repeated fields
|
||||
inline void add_sint32_force(uint32_t field_id_size, int32_t value) {
|
||||
// Always calculate size when force is true
|
||||
// ZigZag encoding for sint32: (n << 1) ^ (n >> 31)
|
||||
uint32_t zigzag = (static_cast<uint32_t>(value) << 1) ^ (static_cast<uint32_t>(value >> 31));
|
||||
total_size += field_id_size + varint(zigzag);
|
||||
total_size_ += field_id_size + varint(zigzag);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of an int64 field to the total message size
|
||||
*/
|
||||
static inline void add_int64_field(uint32_t &total_size, uint32_t field_id_size, int64_t value) {
|
||||
// Skip calculation if value is zero
|
||||
if (value == 0) {
|
||||
return; // No need to update total_size
|
||||
inline void add_int64(uint32_t field_id_size, int64_t value) {
|
||||
if (value != 0) {
|
||||
add_int64_force(field_id_size, value);
|
||||
}
|
||||
|
||||
// Calculate and directly add to total_size
|
||||
total_size += field_id_size + varint(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of an int64 field to the total message size (repeated field version)
|
||||
* @brief Calculates and adds the size of an int64 field to the total message size (force version)
|
||||
*/
|
||||
static inline void add_int64_field_repeated(uint32_t &total_size, uint32_t field_id_size, int64_t value) {
|
||||
// Always calculate size for repeated fields
|
||||
total_size += field_id_size + varint(value);
|
||||
inline void add_int64_force(uint32_t field_id_size, int64_t value) {
|
||||
// Always calculate size when force is true
|
||||
total_size_ += field_id_size + varint(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of a uint64 field to the total message size
|
||||
*/
|
||||
static inline void add_uint64_field(uint32_t &total_size, uint32_t field_id_size, uint64_t value) {
|
||||
// Skip calculation if value is zero
|
||||
if (value == 0) {
|
||||
return; // No need to update total_size
|
||||
inline void add_uint64(uint32_t field_id_size, uint64_t value) {
|
||||
if (value != 0) {
|
||||
add_uint64_force(field_id_size, value);
|
||||
}
|
||||
|
||||
// Calculate and directly add to total_size
|
||||
total_size += field_id_size + varint(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of a uint64 field to the total message size (repeated field version)
|
||||
* @brief Calculates and adds the size of a uint64 field to the total message size (force version)
|
||||
*/
|
||||
static inline void add_uint64_field_repeated(uint32_t &total_size, uint32_t field_id_size, uint64_t value) {
|
||||
// Always calculate size for repeated fields
|
||||
total_size += field_id_size + varint(value);
|
||||
inline void add_uint64_force(uint32_t field_id_size, uint64_t value) {
|
||||
// Always calculate size when force is true
|
||||
total_size_ += field_id_size + varint(value);
|
||||
}
|
||||
|
||||
// NOTE: sint64 support functions (add_sint64_field, add_sint64_field_repeated) removed
|
||||
// NOTE: sint64 support functions (add_sint64_field, add_sint64_field_force) removed
|
||||
// sint64 type is not supported by ESPHome API to reduce overhead on embedded systems
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of a string field using length
|
||||
* @brief Calculates and adds the size of a length-delimited field (string/bytes) to the total message size
|
||||
*/
|
||||
static inline void add_string_field(uint32_t &total_size, uint32_t field_id_size, size_t len) {
|
||||
// Skip calculation if string is empty
|
||||
if (len == 0) {
|
||||
return; // No need to update total_size
|
||||
inline void add_length(uint32_t field_id_size, size_t len) {
|
||||
if (len != 0) {
|
||||
add_length_force(field_id_size, len);
|
||||
}
|
||||
|
||||
// Field ID + length varint + string bytes
|
||||
total_size += field_id_size + varint(static_cast<uint32_t>(len)) + static_cast<uint32_t>(len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of a string/bytes field to the total message size (repeated field version)
|
||||
* @brief Calculates and adds the size of a length-delimited field (string/bytes) to the total message size (repeated
|
||||
* field version)
|
||||
*/
|
||||
static inline void add_string_field_repeated(uint32_t &total_size, uint32_t field_id_size, const std::string &str) {
|
||||
// Always calculate size for repeated fields
|
||||
const uint32_t str_size = static_cast<uint32_t>(str.size());
|
||||
total_size += field_id_size + varint(str_size) + str_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of a bytes field to the total message size
|
||||
*/
|
||||
static inline void add_bytes_field(uint32_t &total_size, uint32_t field_id_size, size_t len) {
|
||||
// Skip calculation if bytes is empty
|
||||
if (len == 0) {
|
||||
return; // No need to update total_size
|
||||
}
|
||||
|
||||
inline void add_length_force(uint32_t field_id_size, size_t len) {
|
||||
// Always calculate size when force is true
|
||||
// Field ID + length varint + data bytes
|
||||
total_size += field_id_size + varint(static_cast<uint32_t>(len)) + static_cast<uint32_t>(len);
|
||||
total_size_ += field_id_size + varint(static_cast<uint32_t>(len)) + static_cast<uint32_t>(len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a pre-calculated size directly to the total
|
||||
*
|
||||
* This is used when we can calculate the total size by multiplying the number
|
||||
* of elements by the bytes per element (for repeated fixed-size types like float, fixed32, etc.)
|
||||
*
|
||||
* @param size The pre-calculated total size to add
|
||||
*/
|
||||
inline void add_precalculated_size(uint32_t size) { total_size_ += size; }
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of a nested message field to the total message size
|
||||
*
|
||||
@@ -745,26 +686,21 @@ class ProtoSize {
|
||||
*
|
||||
* @param nested_size The pre-calculated size of the nested message
|
||||
*/
|
||||
static inline void add_message_field(uint32_t &total_size, uint32_t field_id_size, uint32_t nested_size) {
|
||||
// Skip calculation if nested message is empty
|
||||
if (nested_size == 0) {
|
||||
return; // No need to update total_size
|
||||
inline void add_message_field(uint32_t field_id_size, uint32_t nested_size) {
|
||||
if (nested_size != 0) {
|
||||
add_message_field_force(field_id_size, nested_size);
|
||||
}
|
||||
|
||||
// Calculate and directly add to total_size
|
||||
// Field ID + length varint + nested message content
|
||||
total_size += field_id_size + varint(nested_size) + nested_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of a nested message field to the total message size (repeated field version)
|
||||
* @brief Calculates and adds the size of a nested message field to the total message size (force version)
|
||||
*
|
||||
* @param nested_size The pre-calculated size of the nested message
|
||||
*/
|
||||
static inline void add_message_field_repeated(uint32_t &total_size, uint32_t field_id_size, uint32_t nested_size) {
|
||||
// Always calculate size for repeated fields
|
||||
inline void add_message_field_force(uint32_t field_id_size, uint32_t nested_size) {
|
||||
// Always calculate size when force is true
|
||||
// Field ID + length varint + nested message content
|
||||
total_size += field_id_size + varint(nested_size) + nested_size;
|
||||
total_size_ += field_id_size + varint(nested_size) + nested_size;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -776,26 +712,29 @@ class ProtoSize {
|
||||
*
|
||||
* @param message The nested message object
|
||||
*/
|
||||
static inline void add_message_object(uint32_t &total_size, uint32_t field_id_size, const ProtoMessage &message) {
|
||||
uint32_t nested_size = 0;
|
||||
message.calculate_size(nested_size);
|
||||
inline void add_message_object(uint32_t field_id_size, const ProtoMessage &message) {
|
||||
// Calculate nested message size by creating a temporary ProtoSize
|
||||
ProtoSize nested_calc;
|
||||
message.calculate_size(nested_calc);
|
||||
uint32_t nested_size = nested_calc.get_size();
|
||||
|
||||
// Use the base implementation with the calculated nested_size
|
||||
add_message_field(total_size, field_id_size, nested_size);
|
||||
add_message_field(field_id_size, nested_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates and adds the size of a nested message field to the total message size (repeated field version)
|
||||
* @brief Calculates and adds the size of a nested message field to the total message size (force version)
|
||||
*
|
||||
* @param message The nested message object
|
||||
*/
|
||||
static inline void add_message_object_repeated(uint32_t &total_size, uint32_t field_id_size,
|
||||
const ProtoMessage &message) {
|
||||
uint32_t nested_size = 0;
|
||||
message.calculate_size(nested_size);
|
||||
inline void add_message_object_force(uint32_t field_id_size, const ProtoMessage &message) {
|
||||
// Calculate nested message size by creating a temporary ProtoSize
|
||||
ProtoSize nested_calc;
|
||||
message.calculate_size(nested_calc);
|
||||
uint32_t nested_size = nested_calc.get_size();
|
||||
|
||||
// Use the base implementation with the calculated nested_size
|
||||
add_message_field_repeated(total_size, field_id_size, nested_size);
|
||||
add_message_field_force(field_id_size, nested_size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -808,16 +747,15 @@ class ProtoSize {
|
||||
* @param messages Vector of message objects
|
||||
*/
|
||||
template<typename MessageType>
|
||||
static inline void add_repeated_message(uint32_t &total_size, uint32_t field_id_size,
|
||||
const std::vector<MessageType> &messages) {
|
||||
inline void add_repeated_message(uint32_t field_id_size, const std::vector<MessageType> &messages) {
|
||||
// Skip if the vector is empty
|
||||
if (messages.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the repeated field version for all messages
|
||||
// Use the force version for all messages in the repeated field
|
||||
for (const auto &message : messages) {
|
||||
add_message_object_repeated(total_size, field_id_size, message);
|
||||
add_message_object_force(field_id_size, message);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -827,8 +765,9 @@ inline void ProtoWriteBuffer::encode_message(uint32_t field_id, const ProtoMessa
|
||||
this->encode_field_raw(field_id, 2); // type 2: Length-delimited message
|
||||
|
||||
// Calculate the message size first
|
||||
uint32_t msg_length_bytes = 0;
|
||||
value.calculate_size(msg_length_bytes);
|
||||
ProtoSize msg_size;
|
||||
value.calculate_size(msg_size);
|
||||
uint32_t msg_length_bytes = msg_size.get_size();
|
||||
|
||||
// Calculate how many bytes the length varint needs
|
||||
uint32_t varint_length_bytes = ProtoSize::varint(msg_length_bytes);
|
||||
@@ -860,7 +799,9 @@ class ProtoService {
|
||||
virtual bool is_authenticated() = 0;
|
||||
virtual bool is_connection_setup() = 0;
|
||||
virtual void on_fatal_error() = 0;
|
||||
#ifdef USE_API_PASSWORD
|
||||
virtual void on_unauthenticated_access() = 0;
|
||||
#endif
|
||||
virtual void on_no_setup_connection() = 0;
|
||||
/**
|
||||
* Create a buffer with a reserved size.
|
||||
@@ -875,8 +816,9 @@ class ProtoService {
|
||||
|
||||
// Optimized method that pre-allocates buffer based on message size
|
||||
bool send_message_(const ProtoMessage &msg, uint8_t message_type) {
|
||||
uint32_t msg_size = 0;
|
||||
msg.calculate_size(msg_size);
|
||||
ProtoSize size;
|
||||
msg.calculate_size(size);
|
||||
uint32_t msg_size = size.get_size();
|
||||
|
||||
// Create a pre-sized buffer
|
||||
auto buffer = this->create_buffer(msg_size);
|
||||
@@ -898,6 +840,7 @@ class ProtoService {
|
||||
}
|
||||
|
||||
bool check_authenticated_() {
|
||||
#ifdef USE_API_PASSWORD
|
||||
if (!this->check_connection_setup_()) {
|
||||
return false;
|
||||
}
|
||||
@@ -906,6 +849,9 @@ class ProtoService {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return this->check_connection_setup_();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -7,8 +7,6 @@ namespace as3935 {
|
||||
static const char *const TAG = "as3935";
|
||||
|
||||
void AS3935Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
|
||||
this->irq_pin_->setup();
|
||||
LOG_PIN(" IRQ Pin: ", this->irq_pin_);
|
||||
|
||||
|
@@ -7,9 +7,7 @@ namespace as3935_spi {
|
||||
static const char *const TAG = "as3935_spi";
|
||||
|
||||
void SPIAS3935Component::setup() {
|
||||
ESP_LOGI(TAG, "SPIAS3935Component setup started!");
|
||||
this->spi_setup();
|
||||
ESP_LOGI(TAG, "SPI setup finished!");
|
||||
AS3935Component::setup();
|
||||
}
|
||||
|
||||
|
@@ -23,8 +23,6 @@ static const uint8_t REGISTER_AGC = 0x1A; // 8 bytes / R
|
||||
static const uint8_t REGISTER_MAGNITUDE = 0x1B; // 16 bytes / R
|
||||
|
||||
void AS5600Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
|
||||
if (!this->read_byte(REGISTER_STATUS).has_value()) {
|
||||
this->mark_failed();
|
||||
return;
|
||||
|
@@ -8,7 +8,6 @@ namespace as7341 {
|
||||
static const char *const TAG = "as7341";
|
||||
|
||||
void AS7341Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
LOG_I2C_DEVICE(this);
|
||||
|
||||
// Verify device ID
|
||||
|
@@ -71,7 +71,7 @@ bool AT581XComponent::i2c_read_reg(uint8_t addr, uint8_t &data) {
|
||||
return this->read_register(addr, &data, 1) == esphome::i2c::NO_ERROR;
|
||||
}
|
||||
|
||||
void AT581XComponent::setup() { ESP_LOGCONFIG(TAG, "Running setup"); }
|
||||
void AT581XComponent::setup() {}
|
||||
void AT581XComponent::dump_config() { LOG_I2C_DEVICE(this); }
|
||||
#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0]))
|
||||
bool AT581XComponent::i2c_write_config() {
|
||||
|
@@ -41,7 +41,6 @@ void ATM90E26Component::update() {
|
||||
}
|
||||
|
||||
void ATM90E26Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
this->spi_setup();
|
||||
|
||||
uint16_t mmode = 0x422; // default values for everything but L/N line current gains
|
||||
|
@@ -109,7 +109,6 @@ void ATM90E32Component::update() {
|
||||
}
|
||||
|
||||
void ATM90E32Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
this->spi_setup();
|
||||
|
||||
uint16_t mmode0 = 0x87; // 3P4W 50Hz
|
||||
|
@@ -17,7 +17,6 @@ constexpr static const uint8_t AXS_READ_TOUCHPAD[11] = {0xb5, 0xab, 0xa5, 0x5a,
|
||||
}
|
||||
|
||||
void AXS15231Touchscreen::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
if (this->reset_pin_ != nullptr) {
|
||||
this->reset_pin_->setup();
|
||||
this->reset_pin_->digital_write(false);
|
||||
@@ -36,7 +35,6 @@ void AXS15231Touchscreen::setup() {
|
||||
if (this->y_raw_max_ == 0) {
|
||||
this->y_raw_max_ = this->display_->get_native_height();
|
||||
}
|
||||
ESP_LOGCONFIG(TAG, "AXS15231 Touchscreen setup complete");
|
||||
}
|
||||
|
||||
void AXS15231Touchscreen::update_touches() {
|
||||
|
@@ -121,8 +121,6 @@ void spi_dma_tx_finish_callback(unsigned int param) {
|
||||
}
|
||||
|
||||
void BekenSPILEDStripLightOutput::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
|
||||
size_t buffer_size = this->get_buffer_size_();
|
||||
size_t dma_buffer_size = (buffer_size * 8) + (2 * 64);
|
||||
|
||||
|
@@ -38,7 +38,6 @@ MTreg:
|
||||
*/
|
||||
|
||||
void BH1750Sensor::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup for '%s'", this->name_.c_str());
|
||||
uint8_t turn_on = BH1750_COMMAND_POWER_ON;
|
||||
if (this->write(&turn_on, 1) != i2c::ERROR_OK) {
|
||||
this->mark_failed();
|
||||
|
@@ -516,6 +516,7 @@ def binary_sensor_schema(
|
||||
icon: str = cv.UNDEFINED,
|
||||
entity_category: str = cv.UNDEFINED,
|
||||
device_class: str = cv.UNDEFINED,
|
||||
filters: list = cv.UNDEFINED,
|
||||
) -> cv.Schema:
|
||||
schema = {}
|
||||
|
||||
@@ -527,6 +528,7 @@ def binary_sensor_schema(
|
||||
(CONF_ICON, icon, cv.icon),
|
||||
(CONF_ENTITY_CATEGORY, entity_category, cv.entity_category),
|
||||
(CONF_DEVICE_CLASS, device_class, validate_device_class),
|
||||
(CONF_FILTERS, filters, validate_filters),
|
||||
]:
|
||||
if default is not cv.UNDEFINED:
|
||||
schema[cv.Optional(key, default=default)] = validator
|
||||
@@ -652,7 +654,6 @@ async def binary_sensor_is_off_to_code(config, condition_id, template_arg, args)
|
||||
|
||||
@coroutine_with_priority(100.0)
|
||||
async def to_code(config):
|
||||
cg.add_define("USE_BINARY_SENSOR")
|
||||
cg.add_global(binary_sensor_ns.using)
|
||||
|
||||
|
||||
|
@@ -175,8 +175,7 @@ BLE_REMOVE_BOND_ACTION_SCHEMA = cv.Schema(
|
||||
)
|
||||
async def ble_disconnect_to_code(config, action_id, template_arg, args):
|
||||
parent = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, parent)
|
||||
return var
|
||||
return cg.new_Pvariable(action_id, template_arg, parent)
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
@@ -184,8 +183,7 @@ async def ble_disconnect_to_code(config, action_id, template_arg, args):
|
||||
)
|
||||
async def ble_connect_to_code(config, action_id, template_arg, args):
|
||||
parent = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, parent)
|
||||
return var
|
||||
return cg.new_Pvariable(action_id, template_arg, parent)
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
@@ -282,9 +280,7 @@ async def passkey_reply_to_code(config, action_id, template_arg, args):
|
||||
)
|
||||
async def remove_bond_to_code(config, action_id, template_arg, args):
|
||||
parent = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, parent)
|
||||
|
||||
return var
|
||||
return cg.new_Pvariable(action_id, template_arg, parent)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
|
@@ -87,6 +87,10 @@ async def to_code(config):
|
||||
cg.add(var.set_active(config[CONF_ACTIVE]))
|
||||
await esp32_ble_tracker.register_raw_ble_device(var, config)
|
||||
|
||||
# Define max connections for protobuf fixed array
|
||||
connection_count = len(config.get(CONF_CONNECTIONS, []))
|
||||
cg.add_define("BLUETOOTH_PROXY_MAX_CONNECTIONS", connection_count)
|
||||
|
||||
for connection_conf in config.get(CONF_CONNECTIONS, []):
|
||||
connection_var = cg.new_Pvariable(connection_conf[CONF_ID])
|
||||
await cg.register_component(connection_var, connection_conf)
|
||||
|
@@ -24,11 +24,84 @@ static void fill_128bit_uuid_array(std::array<uint64_t, 2> &out, esp_bt_uuid_t u
|
||||
((uint64_t) uuid.uuid.uuid128[1] << 8) | ((uint64_t) uuid.uuid.uuid128[0]);
|
||||
}
|
||||
|
||||
// Helper to fill UUID in the appropriate format based on client support and UUID type
|
||||
static void fill_gatt_uuid(std::array<uint64_t, 2> &uuid_128, uint32_t &short_uuid, const esp_bt_uuid_t &uuid,
|
||||
bool use_efficient_uuids) {
|
||||
if (!use_efficient_uuids || uuid.len == ESP_UUID_LEN_128) {
|
||||
// Use 128-bit format for old clients or when UUID is already 128-bit
|
||||
fill_128bit_uuid_array(uuid_128, uuid);
|
||||
} else if (uuid.len == ESP_UUID_LEN_16) {
|
||||
short_uuid = uuid.uuid.uuid16;
|
||||
} else if (uuid.len == ESP_UUID_LEN_32) {
|
||||
short_uuid = uuid.uuid.uuid32;
|
||||
}
|
||||
}
|
||||
|
||||
// Constants for size estimation
|
||||
static constexpr uint8_t SERVICE_OVERHEAD_LEGACY = 25; // UUID(20) + handle(4) + overhead(1)
|
||||
static constexpr uint8_t SERVICE_OVERHEAD_EFFICIENT = 10; // UUID(6) + handle(4)
|
||||
static constexpr uint8_t CHAR_SIZE_128BIT = 35; // UUID(20) + handle(4) + props(4) + overhead(7)
|
||||
static constexpr uint8_t DESC_SIZE_128BIT = 25; // UUID(20) + handle(4) + overhead(1)
|
||||
static constexpr uint8_t DESC_SIZE_16BIT = 10; // UUID(6) + handle(4)
|
||||
static constexpr uint8_t DESC_PER_CHAR = 1; // Assume 1 descriptor per characteristic
|
||||
|
||||
// Helper to estimate service size before fetching all data
|
||||
/**
|
||||
* Estimate the size of a Bluetooth service based on the number of characteristics and UUID format.
|
||||
*
|
||||
* @param char_count The number of characteristics in the service.
|
||||
* @param use_efficient_uuids Whether to use efficient UUIDs (16-bit or 32-bit) for newer APIVersions.
|
||||
* @return The estimated size of the service in bytes.
|
||||
*
|
||||
* This function calculates the size of a Bluetooth service by considering:
|
||||
* - A service overhead, which depends on whether efficient UUIDs are used.
|
||||
* - The size of each characteristic, assuming 128-bit UUIDs for safety.
|
||||
* - The size of descriptors, assuming one 128-bit descriptor per characteristic.
|
||||
*/
|
||||
static size_t estimate_service_size(uint16_t char_count, bool use_efficient_uuids) {
|
||||
size_t service_overhead = use_efficient_uuids ? SERVICE_OVERHEAD_EFFICIENT : SERVICE_OVERHEAD_LEGACY;
|
||||
// Always assume 128-bit UUIDs for characteristics to be safe
|
||||
size_t char_size = CHAR_SIZE_128BIT;
|
||||
// Assume one 128-bit descriptor per characteristic
|
||||
size_t desc_size = DESC_SIZE_128BIT * DESC_PER_CHAR;
|
||||
|
||||
return service_overhead + (char_size + desc_size) * char_count;
|
||||
}
|
||||
|
||||
bool BluetoothConnection::supports_efficient_uuids_() const {
|
||||
auto *api_conn = this->proxy_->get_api_connection();
|
||||
return api_conn && api_conn->client_supports_api_version(1, 12);
|
||||
}
|
||||
|
||||
void BluetoothConnection::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "BLE Connection:");
|
||||
BLEClientBase::dump_config();
|
||||
}
|
||||
|
||||
void BluetoothConnection::update_allocated_slot_(uint64_t find_value, uint64_t set_value) {
|
||||
auto &allocated = this->proxy_->connections_free_response_.allocated;
|
||||
auto *it = std::find(allocated.begin(), allocated.end(), find_value);
|
||||
if (it != allocated.end()) {
|
||||
*it = set_value;
|
||||
}
|
||||
}
|
||||
|
||||
void BluetoothConnection::set_address(uint64_t address) {
|
||||
// If we're clearing an address (disconnecting), update the pre-allocated message
|
||||
if (address == 0 && this->address_ != 0) {
|
||||
this->proxy_->connections_free_response_.free++;
|
||||
this->update_allocated_slot_(this->address_, 0);
|
||||
}
|
||||
// If we're setting a new address (connecting), update the pre-allocated message
|
||||
else if (address != 0 && this->address_ == 0) {
|
||||
this->proxy_->connections_free_response_.free--;
|
||||
this->update_allocated_slot_(0, address);
|
||||
}
|
||||
|
||||
// Call parent implementation to actually set the address
|
||||
BLEClientBase::set_address(address);
|
||||
}
|
||||
|
||||
void BluetoothConnection::loop() {
|
||||
BLEClientBase::loop();
|
||||
|
||||
@@ -57,7 +130,7 @@ void BluetoothConnection::reset_connection_(esp_err_t reason) {
|
||||
}
|
||||
|
||||
void BluetoothConnection::send_service_for_discovery_() {
|
||||
if (this->send_service_ == this->service_count_) {
|
||||
if (this->send_service_ >= this->service_count_) {
|
||||
this->send_service_ = DONE_SENDING_SERVICES;
|
||||
this->proxy_->send_gatt_services_done(this->address_);
|
||||
if (this->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE ||
|
||||
@@ -70,117 +143,181 @@ void BluetoothConnection::send_service_for_discovery_() {
|
||||
// Early return if no API connection
|
||||
auto *api_conn = this->proxy_->get_api_connection();
|
||||
if (api_conn == nullptr) {
|
||||
this->send_service_ = DONE_SENDING_SERVICES;
|
||||
return;
|
||||
}
|
||||
|
||||
// Send next service
|
||||
esp_gattc_service_elem_t service_result;
|
||||
uint16_t service_count = 1;
|
||||
esp_gatt_status_t service_status = esp_ble_gattc_get_service(this->gattc_if_, this->conn_id_, nullptr,
|
||||
&service_result, &service_count, this->send_service_);
|
||||
this->send_service_++;
|
||||
|
||||
if (service_status != ESP_GATT_OK) {
|
||||
ESP_LOGE(TAG, "[%d] [%s] esp_ble_gattc_get_service error at offset=%d, status=%d", this->connection_index_,
|
||||
this->address_str().c_str(), this->send_service_ - 1, service_status);
|
||||
return;
|
||||
}
|
||||
|
||||
if (service_count == 0) {
|
||||
ESP_LOGE(TAG, "[%d] [%s] esp_ble_gattc_get_service missing, service_count=%d", this->connection_index_,
|
||||
this->address_str().c_str(), service_count);
|
||||
return;
|
||||
}
|
||||
// Check if client supports efficient UUIDs
|
||||
bool use_efficient_uuids = this->supports_efficient_uuids_();
|
||||
|
||||
// Prepare response
|
||||
api::BluetoothGATTGetServicesResponse resp;
|
||||
resp.address = this->address_;
|
||||
auto &service_resp = resp.services[0];
|
||||
fill_128bit_uuid_array(service_resp.uuid, service_result.uuid);
|
||||
service_resp.handle = service_result.start_handle;
|
||||
|
||||
// Get the number of characteristics directly with one call
|
||||
uint16_t total_char_count = 0;
|
||||
esp_gatt_status_t char_count_status =
|
||||
esp_ble_gattc_get_attr_count(this->gattc_if_, this->conn_id_, ESP_GATT_DB_CHARACTERISTIC,
|
||||
service_result.start_handle, service_result.end_handle, 0, &total_char_count);
|
||||
// Dynamic batching based on actual size
|
||||
// Conservative MTU limit for API messages (accounts for WPA3 overhead)
|
||||
static constexpr size_t MAX_PACKET_SIZE = 1360;
|
||||
|
||||
if (char_count_status == ESP_GATT_OK && total_char_count > 0) {
|
||||
// Only reserve if we successfully got a count
|
||||
service_resp.characteristics.reserve(total_char_count);
|
||||
} else if (char_count_status != ESP_GATT_OK) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Error getting characteristic count, status=%d", this->connection_index_,
|
||||
this->address_str().c_str(), char_count_status);
|
||||
// Keep running total of actual message size
|
||||
size_t current_size = 0;
|
||||
api::ProtoSize size;
|
||||
resp.calculate_size(size);
|
||||
current_size = size.get_size();
|
||||
|
||||
while (this->send_service_ < this->service_count_) {
|
||||
esp_gattc_service_elem_t service_result;
|
||||
uint16_t service_count = 1;
|
||||
esp_gatt_status_t service_status = esp_ble_gattc_get_service(this->gattc_if_, this->conn_id_, nullptr,
|
||||
&service_result, &service_count, this->send_service_);
|
||||
|
||||
if (service_status != ESP_GATT_OK || service_count == 0) {
|
||||
ESP_LOGE(TAG, "[%d] [%s] esp_ble_gattc_get_service %s, status=%d, service_count=%d, offset=%d",
|
||||
this->connection_index_, this->address_str().c_str(),
|
||||
service_status != ESP_GATT_OK ? "error" : "missing", service_status, service_count, this->send_service_);
|
||||
this->send_service_ = DONE_SENDING_SERVICES;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the number of characteristics BEFORE adding to response
|
||||
uint16_t total_char_count = 0;
|
||||
esp_gatt_status_t char_count_status =
|
||||
esp_ble_gattc_get_attr_count(this->gattc_if_, this->conn_id_, ESP_GATT_DB_CHARACTERISTIC,
|
||||
service_result.start_handle, service_result.end_handle, 0, &total_char_count);
|
||||
|
||||
if (char_count_status != ESP_GATT_OK) {
|
||||
ESP_LOGE(TAG, "[%d] [%s] Error getting characteristic count, status=%d", this->connection_index_,
|
||||
this->address_str().c_str(), char_count_status);
|
||||
this->send_service_ = DONE_SENDING_SERVICES;
|
||||
return;
|
||||
}
|
||||
|
||||
// If this service likely won't fit, send current batch (unless it's the first)
|
||||
size_t estimated_size = estimate_service_size(total_char_count, use_efficient_uuids);
|
||||
if (!resp.services.empty() && (current_size + estimated_size > MAX_PACKET_SIZE)) {
|
||||
// This service likely won't fit, send current batch
|
||||
break;
|
||||
}
|
||||
|
||||
// Now add the service since we know it will likely fit
|
||||
resp.services.emplace_back();
|
||||
auto &service_resp = resp.services.back();
|
||||
|
||||
fill_gatt_uuid(service_resp.uuid, service_resp.short_uuid, service_result.uuid, use_efficient_uuids);
|
||||
|
||||
service_resp.handle = service_result.start_handle;
|
||||
|
||||
if (total_char_count > 0) {
|
||||
// Reserve space and process characteristics
|
||||
service_resp.characteristics.reserve(total_char_count);
|
||||
uint16_t char_offset = 0;
|
||||
esp_gattc_char_elem_t char_result;
|
||||
while (true) { // characteristics
|
||||
uint16_t char_count = 1;
|
||||
esp_gatt_status_t char_status =
|
||||
esp_ble_gattc_get_all_char(this->gattc_if_, this->conn_id_, service_result.start_handle,
|
||||
service_result.end_handle, &char_result, &char_count, char_offset);
|
||||
if (char_status == ESP_GATT_INVALID_OFFSET || char_status == ESP_GATT_NOT_FOUND) {
|
||||
break;
|
||||
}
|
||||
if (char_status != ESP_GATT_OK) {
|
||||
ESP_LOGE(TAG, "[%d] [%s] esp_ble_gattc_get_all_char error, status=%d", this->connection_index_,
|
||||
this->address_str().c_str(), char_status);
|
||||
this->send_service_ = DONE_SENDING_SERVICES;
|
||||
return;
|
||||
}
|
||||
if (char_count == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
service_resp.characteristics.emplace_back();
|
||||
auto &characteristic_resp = service_resp.characteristics.back();
|
||||
|
||||
fill_gatt_uuid(characteristic_resp.uuid, characteristic_resp.short_uuid, char_result.uuid, use_efficient_uuids);
|
||||
|
||||
characteristic_resp.handle = char_result.char_handle;
|
||||
characteristic_resp.properties = char_result.properties;
|
||||
char_offset++;
|
||||
|
||||
// Get the number of descriptors directly with one call
|
||||
uint16_t total_desc_count = 0;
|
||||
esp_gatt_status_t desc_count_status = esp_ble_gattc_get_attr_count(
|
||||
this->gattc_if_, this->conn_id_, ESP_GATT_DB_DESCRIPTOR, 0, 0, char_result.char_handle, &total_desc_count);
|
||||
|
||||
if (desc_count_status != ESP_GATT_OK) {
|
||||
ESP_LOGE(TAG, "[%d] [%s] Error getting descriptor count for char handle %d, status=%d",
|
||||
this->connection_index_, this->address_str().c_str(), char_result.char_handle, desc_count_status);
|
||||
this->send_service_ = DONE_SENDING_SERVICES;
|
||||
return;
|
||||
}
|
||||
if (total_desc_count == 0) {
|
||||
// No descriptors, continue to next characteristic
|
||||
continue;
|
||||
}
|
||||
|
||||
// Reserve space and process descriptors
|
||||
characteristic_resp.descriptors.reserve(total_desc_count);
|
||||
uint16_t desc_offset = 0;
|
||||
esp_gattc_descr_elem_t desc_result;
|
||||
while (true) { // descriptors
|
||||
uint16_t desc_count = 1;
|
||||
esp_gatt_status_t desc_status = esp_ble_gattc_get_all_descr(
|
||||
this->gattc_if_, this->conn_id_, char_result.char_handle, &desc_result, &desc_count, desc_offset);
|
||||
if (desc_status == ESP_GATT_INVALID_OFFSET || desc_status == ESP_GATT_NOT_FOUND) {
|
||||
break;
|
||||
}
|
||||
if (desc_status != ESP_GATT_OK) {
|
||||
ESP_LOGE(TAG, "[%d] [%s] esp_ble_gattc_get_all_descr error, status=%d", this->connection_index_,
|
||||
this->address_str().c_str(), desc_status);
|
||||
this->send_service_ = DONE_SENDING_SERVICES;
|
||||
return;
|
||||
}
|
||||
if (desc_count == 0) {
|
||||
break; // No more descriptors
|
||||
}
|
||||
|
||||
characteristic_resp.descriptors.emplace_back();
|
||||
auto &descriptor_resp = characteristic_resp.descriptors.back();
|
||||
|
||||
fill_gatt_uuid(descriptor_resp.uuid, descriptor_resp.short_uuid, desc_result.uuid, use_efficient_uuids);
|
||||
|
||||
descriptor_resp.handle = desc_result.handle;
|
||||
desc_offset++;
|
||||
}
|
||||
}
|
||||
} // end if (total_char_count > 0)
|
||||
|
||||
// Calculate the actual size of just this service
|
||||
api::ProtoSize service_sizer;
|
||||
service_resp.calculate_size(service_sizer);
|
||||
size_t service_size = service_sizer.get_size() + 1; // +1 for field tag
|
||||
|
||||
// Check if adding this service would exceed the limit
|
||||
if (current_size + service_size > MAX_PACKET_SIZE) {
|
||||
// We would go over - pop the last service if we have more than one
|
||||
if (resp.services.size() > 1) {
|
||||
resp.services.pop_back();
|
||||
ESP_LOGD(TAG, "[%d] [%s] Service %d would exceed limit (current: %d + service: %d > %d), sending current batch",
|
||||
this->connection_index_, this->address_str().c_str(), this->send_service_, current_size, service_size,
|
||||
MAX_PACKET_SIZE);
|
||||
// Don't increment send_service_ - we'll retry this service in next batch
|
||||
} else {
|
||||
// This single service is too large, but we have to send it anyway
|
||||
ESP_LOGV(TAG, "[%d] [%s] Service %d is too large (%d bytes) but sending anyway", this->connection_index_,
|
||||
this->address_str().c_str(), this->send_service_, service_size);
|
||||
// Increment so we don't get stuck
|
||||
this->send_service_++;
|
||||
}
|
||||
// Send what we have
|
||||
break;
|
||||
}
|
||||
|
||||
// Now we know we're keeping this service, add its size
|
||||
current_size += service_size;
|
||||
// Successfully added this service, increment counter
|
||||
this->send_service_++;
|
||||
}
|
||||
|
||||
// Now process characteristics
|
||||
uint16_t char_offset = 0;
|
||||
esp_gattc_char_elem_t char_result;
|
||||
while (true) { // characteristics
|
||||
uint16_t char_count = 1;
|
||||
esp_gatt_status_t char_status =
|
||||
esp_ble_gattc_get_all_char(this->gattc_if_, this->conn_id_, service_result.start_handle,
|
||||
service_result.end_handle, &char_result, &char_count, char_offset);
|
||||
if (char_status == ESP_GATT_INVALID_OFFSET || char_status == ESP_GATT_NOT_FOUND) {
|
||||
break;
|
||||
}
|
||||
if (char_status != ESP_GATT_OK) {
|
||||
ESP_LOGE(TAG, "[%d] [%s] esp_ble_gattc_get_all_char error, status=%d", this->connection_index_,
|
||||
this->address_str().c_str(), char_status);
|
||||
break;
|
||||
}
|
||||
if (char_count == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
service_resp.characteristics.emplace_back();
|
||||
auto &characteristic_resp = service_resp.characteristics.back();
|
||||
fill_128bit_uuid_array(characteristic_resp.uuid, char_result.uuid);
|
||||
characteristic_resp.handle = char_result.char_handle;
|
||||
characteristic_resp.properties = char_result.properties;
|
||||
char_offset++;
|
||||
|
||||
// Get the number of descriptors directly with one call
|
||||
uint16_t total_desc_count = 0;
|
||||
esp_gatt_status_t desc_count_status =
|
||||
esp_ble_gattc_get_attr_count(this->gattc_if_, this->conn_id_, ESP_GATT_DB_DESCRIPTOR, char_result.char_handle,
|
||||
service_result.end_handle, 0, &total_desc_count);
|
||||
|
||||
if (desc_count_status == ESP_GATT_OK && total_desc_count > 0) {
|
||||
// Only reserve if we successfully got a count
|
||||
characteristic_resp.descriptors.reserve(total_desc_count);
|
||||
} else if (desc_count_status != ESP_GATT_OK) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Error getting descriptor count for char handle %d, status=%d", this->connection_index_,
|
||||
this->address_str().c_str(), char_result.char_handle, desc_count_status);
|
||||
}
|
||||
|
||||
// Now process descriptors
|
||||
uint16_t desc_offset = 0;
|
||||
esp_gattc_descr_elem_t desc_result;
|
||||
while (true) { // descriptors
|
||||
uint16_t desc_count = 1;
|
||||
esp_gatt_status_t desc_status = esp_ble_gattc_get_all_descr(
|
||||
this->gattc_if_, this->conn_id_, char_result.char_handle, &desc_result, &desc_count, desc_offset);
|
||||
if (desc_status == ESP_GATT_INVALID_OFFSET || desc_status == ESP_GATT_NOT_FOUND) {
|
||||
break;
|
||||
}
|
||||
if (desc_status != ESP_GATT_OK) {
|
||||
ESP_LOGE(TAG, "[%d] [%s] esp_ble_gattc_get_all_descr error, status=%d", this->connection_index_,
|
||||
this->address_str().c_str(), desc_status);
|
||||
break;
|
||||
}
|
||||
if (desc_count == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
characteristic_resp.descriptors.emplace_back();
|
||||
auto &descriptor_resp = characteristic_resp.descriptors.back();
|
||||
fill_128bit_uuid_array(descriptor_resp.uuid, desc_result.uuid);
|
||||
descriptor_resp.handle = desc_result.handle;
|
||||
desc_offset++;
|
||||
}
|
||||
}
|
||||
|
||||
// Send the message (we already checked api_conn is not null at the beginning)
|
||||
// Send the message with dynamically batched services
|
||||
api_conn->send_message(resp, api::BluetoothGATTGetServicesResponse::MESSAGE_TYPE);
|
||||
}
|
||||
|
||||
|
@@ -24,11 +24,15 @@ class BluetoothConnection : public esp32_ble_client::BLEClientBase {
|
||||
|
||||
esp_err_t notify_characteristic(uint16_t handle, bool enable);
|
||||
|
||||
void set_address(uint64_t address) override;
|
||||
|
||||
protected:
|
||||
friend class BluetoothProxy;
|
||||
|
||||
bool supports_efficient_uuids_() const;
|
||||
void send_service_for_discovery_();
|
||||
void reset_connection_(esp_err_t reason);
|
||||
void update_allocated_slot_(uint64_t find_value, uint64_t set_value);
|
||||
|
||||
// Memory optimized layout for 32-bit systems
|
||||
// Group 1: Pointers (4 bytes each, naturally aligned)
|
||||
|
@@ -35,6 +35,9 @@ void BluetoothProxy::setup() {
|
||||
// Don't pre-allocate pool - let it grow only if needed in busy environments
|
||||
// Many devices in quiet areas will never need the overflow pool
|
||||
|
||||
this->connections_free_response_.limit = this->connections_.size();
|
||||
this->connections_free_response_.free = this->connections_.size();
|
||||
|
||||
this->parent_->add_scanner_state_callback([this](esp32_ble_tracker::ScannerState state) {
|
||||
if (this->api_connection_ != nullptr) {
|
||||
this->send_bluetooth_scanner_state_(state);
|
||||
@@ -134,20 +137,6 @@ void BluetoothProxy::dump_config() {
|
||||
YESNO(this->active_), this->connections_.size());
|
||||
}
|
||||
|
||||
int BluetoothProxy::get_bluetooth_connections_free() {
|
||||
int free = 0;
|
||||
for (auto *connection : this->connections_) {
|
||||
if (connection->address_ == 0) {
|
||||
free++;
|
||||
ESP_LOGV(TAG, "[%d] Free connection", connection->get_connection_index());
|
||||
} else {
|
||||
ESP_LOGV(TAG, "[%d] Used connection by [%s]", connection->get_connection_index(),
|
||||
connection->address_str().c_str());
|
||||
}
|
||||
}
|
||||
return free;
|
||||
}
|
||||
|
||||
void BluetoothProxy::loop() {
|
||||
if (!api::global_api_server->is_connected() || this->api_connection_ == nullptr) {
|
||||
for (auto *connection : this->connections_) {
|
||||
@@ -439,17 +428,13 @@ void BluetoothProxy::send_device_connection(uint64_t address, bool connected, ui
|
||||
this->api_connection_->send_message(call, api::BluetoothDeviceConnectionResponse::MESSAGE_TYPE);
|
||||
}
|
||||
void BluetoothProxy::send_connections_free() {
|
||||
if (this->api_connection_ == nullptr)
|
||||
return;
|
||||
api::BluetoothConnectionsFreeResponse call;
|
||||
call.free = this->get_bluetooth_connections_free();
|
||||
call.limit = this->get_bluetooth_connections_limit();
|
||||
for (auto *connection : this->connections_) {
|
||||
if (connection->address_ != 0) {
|
||||
call.allocated.push_back(connection->address_);
|
||||
}
|
||||
if (this->api_connection_ != nullptr) {
|
||||
this->send_connections_free(this->api_connection_);
|
||||
}
|
||||
this->api_connection_->send_message(call, api::BluetoothConnectionsFreeResponse::MESSAGE_TYPE);
|
||||
}
|
||||
|
||||
void BluetoothProxy::send_connections_free(api::APIConnection *api_connection) {
|
||||
api_connection->send_message(this->connections_free_response_, api::BluetoothConnectionsFreeResponse::MESSAGE_TYPE);
|
||||
}
|
||||
|
||||
void BluetoothProxy::send_gatt_services_done(uint64_t address) {
|
||||
|
@@ -49,6 +49,7 @@ enum BluetoothProxySubscriptionFlag : uint32_t {
|
||||
};
|
||||
|
||||
class BluetoothProxy : public esp32_ble_tracker::ESPBTDeviceListener, public Component {
|
||||
friend class BluetoothConnection; // Allow connection to update connections_free_response_
|
||||
public:
|
||||
BluetoothProxy();
|
||||
#ifdef USE_ESP32_BLE_DEVICE
|
||||
@@ -74,15 +75,13 @@ class BluetoothProxy : public esp32_ble_tracker::ESPBTDeviceListener, public Com
|
||||
void bluetooth_gatt_send_services(const api::BluetoothGATTGetServicesRequest &msg);
|
||||
void bluetooth_gatt_notify(const api::BluetoothGATTNotifyRequest &msg);
|
||||
|
||||
int get_bluetooth_connections_free();
|
||||
int get_bluetooth_connections_limit() { return this->connections_.size(); }
|
||||
|
||||
void subscribe_api_connection(api::APIConnection *api_connection, uint32_t flags);
|
||||
void unsubscribe_api_connection(api::APIConnection *api_connection);
|
||||
api::APIConnection *get_api_connection() { return this->api_connection_; }
|
||||
|
||||
void send_device_connection(uint64_t address, bool connected, uint16_t mtu = 0, esp_err_t error = ESP_OK);
|
||||
void send_connections_free();
|
||||
void send_connections_free(api::APIConnection *api_connection);
|
||||
void send_gatt_services_done(uint64_t address);
|
||||
void send_gatt_error(uint64_t address, uint16_t handle, esp_err_t error);
|
||||
void send_device_pairing(uint64_t address, bool paired, esp_err_t error = ESP_OK);
|
||||
@@ -149,6 +148,9 @@ class BluetoothProxy : public esp32_ble_tracker::ESPBTDeviceListener, public Com
|
||||
// Group 3: 4-byte types
|
||||
uint32_t last_advertisement_flush_time_{0};
|
||||
|
||||
// Pre-allocated response message - always ready to send
|
||||
api::BluetoothConnectionsFreeResponse connections_free_response_;
|
||||
|
||||
// Group 4: 1-byte types grouped together
|
||||
bool active_;
|
||||
uint8_t advertisement_count_{0};
|
||||
|
@@ -88,7 +88,6 @@ const char *oversampling_to_str(BME280Oversampling oversampling) { // NOLINT
|
||||
}
|
||||
|
||||
void BME280Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
uint8_t chip_id = 0;
|
||||
|
||||
// Mark as not failed before initializing. Some devices will turn off sensors to save on batteries
|
||||
|
@@ -71,7 +71,6 @@ static const char *iir_filter_to_str(BME680IIRFilter filter) {
|
||||
}
|
||||
|
||||
void BME680Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
uint8_t chip_id;
|
||||
if (!this->read_byte(BME680_REGISTER_CHIPID, &chip_id) || chip_id != 0x61) {
|
||||
this->mark_failed();
|
||||
|
@@ -15,8 +15,6 @@ std::vector<BME680BSECComponent *>
|
||||
uint8_t BME680BSECComponent::work_buffer_[BSEC_MAX_WORKBUFFER_SIZE] = {0};
|
||||
|
||||
void BME680BSECComponent::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup for '%s'", this->device_id_.c_str());
|
||||
|
||||
uint8_t new_idx = BME680BSECComponent::instances.size();
|
||||
BME680BSECComponent::instances.push_back(this);
|
||||
|
||||
|
@@ -21,8 +21,6 @@ static const char *const TAG = "bme68x_bsec2.sensor";
|
||||
static const std::string IAQ_ACCURACY_STATES[4] = {"Stabilizing", "Uncertain", "Calibrating", "Calibrated"};
|
||||
|
||||
void BME68xBSEC2Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
|
||||
this->bsec_status_ = bsec_init_m(&this->bsec_instance_);
|
||||
if (this->bsec_status_ != BSEC_OK) {
|
||||
this->mark_failed();
|
||||
|
@@ -119,7 +119,6 @@ const float GRAVITY_EARTH = 9.80665f;
|
||||
void BMI160Component::internal_setup_(int stage) {
|
||||
switch (stage) {
|
||||
case 0:
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
uint8_t chipid;
|
||||
if (!this->read_byte(BMI160_REGISTER_CHIPID, &chipid) || (chipid != 0b11010001)) {
|
||||
this->mark_failed();
|
||||
|
@@ -20,7 +20,6 @@ void BMP085Component::update() {
|
||||
this->set_timeout("temperature", 5, [this]() { this->read_temperature_(); });
|
||||
}
|
||||
void BMP085Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
uint8_t data[22];
|
||||
if (!this->read_bytes(BMP085_REGISTER_AC1_H, data, 22)) {
|
||||
this->mark_failed();
|
||||
|
@@ -57,7 +57,6 @@ static const char *iir_filter_to_str(BMP280IIRFilter filter) {
|
||||
}
|
||||
|
||||
void BMP280Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
uint8_t chip_id = 0;
|
||||
|
||||
// Read the chip id twice, to work around a bug where the first read is 0.
|
||||
|
@@ -70,7 +70,6 @@ static const LogString *iir_filter_to_str(IIRFilter filter) {
|
||||
|
||||
void BMP3XXComponent::setup() {
|
||||
this->error_code_ = NONE;
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
// Call the Device base class "initialise" function
|
||||
if (!reset()) {
|
||||
ESP_LOGE(TAG, "Failed to reset");
|
||||
|
@@ -128,8 +128,6 @@ void BMP581Component::setup() {
|
||||
*/
|
||||
|
||||
this->error_code_ = NONE;
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
|
||||
////////////////////
|
||||
// 1) Soft reboot //
|
||||
////////////////////
|
||||
|
@@ -15,7 +15,6 @@ static const uint8_t BP1658CJ_ADDR_START_5CH = 0x30;
|
||||
static const uint8_t BP1658CJ_DELAY = 2;
|
||||
|
||||
void BP1658CJ::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
this->data_pin_->setup();
|
||||
this->data_pin_->digital_write(false);
|
||||
this->clock_pin_->setup();
|
||||
|
@@ -20,7 +20,6 @@ static const uint8_t BP5758D_ALL_DATA_CHANNEL_ENABLEMENT = 0b00011111;
|
||||
static const uint8_t BP5758D_DELAY = 2;
|
||||
|
||||
void BP5758D::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
this->data_pin_->setup();
|
||||
this->data_pin_->digital_write(false);
|
||||
delayMicroseconds(BP5758D_DELAY);
|
||||
|
@@ -137,4 +137,3 @@ async def button_press_to_code(config, action_id, template_arg, args):
|
||||
@coroutine_with_priority(100.0)
|
||||
async def to_code(config):
|
||||
cg.add_global(button_ns.using)
|
||||
cg.add_define("USE_BUTTON")
|
||||
|
@@ -7,7 +7,6 @@ namespace canbus {
|
||||
static const char *const TAG = "canbus";
|
||||
|
||||
void Canbus::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
if (!this->setup_internal()) {
|
||||
ESP_LOGE(TAG, "setup error!");
|
||||
this->mark_failed();
|
||||
|
@@ -8,8 +8,6 @@ namespace cap1188 {
|
||||
static const char *const TAG = "cap1188";
|
||||
|
||||
void CAP1188Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
|
||||
// Reset device using the reset pin
|
||||
if (this->reset_pin_ != nullptr) {
|
||||
this->reset_pin_->setup();
|
||||
|
@@ -10,8 +10,6 @@ static const char *const TAG = "cd74hc4067";
|
||||
float CD74HC4067Component::get_setup_priority() const { return setup_priority::DATA; }
|
||||
|
||||
void CD74HC4067Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
|
||||
this->pin_s0_->setup();
|
||||
this->pin_s1_->setup();
|
||||
this->pin_s2_->setup();
|
||||
|
@@ -14,7 +14,6 @@ static const uint8_t CH422G_REG_OUT_UPPER = 0x23; // write reg for output bit
|
||||
static const char *const TAG = "ch422g";
|
||||
|
||||
void CH422GComponent::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
// set outputs before mode
|
||||
this->write_outputs_();
|
||||
// Set mode and check for errors
|
||||
|
@@ -4,7 +4,6 @@ namespace esphome {
|
||||
namespace chsc6x {
|
||||
|
||||
void CHSC6XTouchscreen::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
if (this->interrupt_pin_ != nullptr) {
|
||||
this->interrupt_pin_->setup();
|
||||
this->attach_interrupt_(this->interrupt_pin_, gpio::INTERRUPT_FALLING_EDGE);
|
||||
@@ -15,8 +14,6 @@ void CHSC6XTouchscreen::setup() {
|
||||
if (this->y_raw_max_ == this->y_raw_min_) {
|
||||
this->y_raw_max_ = this->display_->get_native_height();
|
||||
}
|
||||
|
||||
ESP_LOGCONFIG(TAG, "CHSC6X Touchscreen setup complete");
|
||||
}
|
||||
|
||||
void CHSC6XTouchscreen::update_touches() {
|
||||
|
@@ -519,5 +519,4 @@ async def climate_control_to_code(config, action_id, template_arg, args):
|
||||
|
||||
@coroutine_with_priority(100.0)
|
||||
async def to_code(config):
|
||||
cg.add_define("USE_CLIMATE")
|
||||
cg.add_global(climate_ns.using)
|
||||
|
@@ -5,6 +5,13 @@
|
||||
#include <set>
|
||||
|
||||
namespace esphome {
|
||||
|
||||
#ifdef USE_API
|
||||
namespace api {
|
||||
class APIConnection;
|
||||
} // namespace api
|
||||
#endif
|
||||
|
||||
namespace climate {
|
||||
|
||||
/** This class contains all static data for climate devices.
|
||||
@@ -173,6 +180,23 @@ class ClimateTraits {
|
||||
void set_visual_max_humidity(float visual_max_humidity) { this->visual_max_humidity_ = visual_max_humidity; }
|
||||
|
||||
protected:
|
||||
#ifdef USE_API
|
||||
// The API connection is a friend class to access internal methods
|
||||
friend class api::APIConnection;
|
||||
// These methods return references to internal data structures.
|
||||
// They are used by the API to avoid copying data when encoding messages.
|
||||
// Warning: Do not use these methods outside of the API connection code.
|
||||
// They return references to internal data that can be invalidated.
|
||||
const std::set<ClimateMode> &get_supported_modes_for_api_() const { return this->supported_modes_; }
|
||||
const std::set<ClimateFanMode> &get_supported_fan_modes_for_api_() const { return this->supported_fan_modes_; }
|
||||
const std::set<std::string> &get_supported_custom_fan_modes_for_api_() const {
|
||||
return this->supported_custom_fan_modes_;
|
||||
}
|
||||
const std::set<climate::ClimatePreset> &get_supported_presets_for_api_() const { return this->supported_presets_; }
|
||||
const std::set<std::string> &get_supported_custom_presets_for_api_() const { return this->supported_custom_presets_; }
|
||||
const std::set<ClimateSwingMode> &get_supported_swing_modes_for_api_() const { return this->supported_swing_modes_; }
|
||||
#endif
|
||||
|
||||
void set_mode_support_(climate::ClimateMode mode, bool supported) {
|
||||
if (supported) {
|
||||
this->supported_modes_.insert(mode);
|
||||
|
@@ -20,7 +20,6 @@ uint8_t cm1106_checksum(const uint8_t *response, size_t len) {
|
||||
}
|
||||
|
||||
void CM1106Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
uint8_t response[8] = {0};
|
||||
if (!this->cm1106_write_command_(C_M1106_CMD_GET_CO2, sizeof(C_M1106_CMD_GET_CO2), response, sizeof(response))) {
|
||||
ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
|
||||
|
@@ -265,5 +265,4 @@ async def cover_control_to_code(config, action_id, template_arg, args):
|
||||
|
||||
@coroutine_with_priority(100.0)
|
||||
async def to_code(config):
|
||||
cg.add_define("USE_COVER")
|
||||
cg.add_global(cover_ns.using)
|
||||
|
@@ -52,8 +52,6 @@ bool CS5460AComponent::softreset_() {
|
||||
}
|
||||
|
||||
void CS5460AComponent::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
|
||||
float current_full_scale = (pga_gain_ == CS5460A_PGA_GAIN_10X) ? 0.25 : 0.10;
|
||||
float voltage_full_scale = 0.25;
|
||||
current_multiplier_ = current_full_scale / (fabsf(current_gain_) * 0x1000000);
|
||||
|
@@ -42,7 +42,6 @@ static const uint8_t CSE7761_CMD_ENABLE_WRITE = 0xE5; // Enable write operation
|
||||
enum CSE7761 { RMS_IAC, RMS_IBC, RMS_UC, POWER_PAC, POWER_PBC, POWER_SC, ENERGY_AC, ENERGY_BC };
|
||||
|
||||
void CSE7761Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
this->write_(CSE7761_SPECIAL_COMMAND, CSE7761_CMD_RESET);
|
||||
uint16_t syscon = this->read_(0x00, 2); // Default 0x0A04
|
||||
if ((0x0A04 == syscon) && this->chip_init_()) {
|
||||
|
@@ -6,7 +6,6 @@ namespace cst226 {
|
||||
static const char *const TAG = "cst226.touchscreen";
|
||||
|
||||
void CST226Touchscreen::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
if (this->reset_pin_ != nullptr) {
|
||||
this->reset_pin_->setup();
|
||||
this->reset_pin_->digital_write(true);
|
||||
@@ -95,7 +94,6 @@ void CST226Touchscreen::continue_setup_() {
|
||||
}
|
||||
}
|
||||
this->setup_complete_ = true;
|
||||
ESP_LOGCONFIG(TAG, "CST226 Touchscreen setup complete");
|
||||
}
|
||||
void CST226Touchscreen::update_button_state_(bool state) {
|
||||
if (this->button_touched_ == state)
|
||||
|
@@ -35,11 +35,9 @@ void CST816Touchscreen::continue_setup_() {
|
||||
if (this->y_raw_max_ == this->y_raw_min_) {
|
||||
this->y_raw_max_ = this->display_->get_native_height();
|
||||
}
|
||||
ESP_LOGCONFIG(TAG, "CST816 Touchscreen setup complete");
|
||||
}
|
||||
|
||||
void CST816Touchscreen::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
if (this->reset_pin_ != nullptr) {
|
||||
this->reset_pin_->setup();
|
||||
this->reset_pin_->digital_write(true);
|
||||
|
@@ -20,8 +20,6 @@ static const uint8_t DAC7678_REG_INTERNAL_REF_0 = 0x80;
|
||||
static const uint8_t DAC7678_REG_INTERNAL_REF_1 = 0x90;
|
||||
|
||||
void DAC7678Output::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
|
||||
ESP_LOGV(TAG, "Resetting device");
|
||||
|
||||
// Reset device
|
||||
|
@@ -70,7 +70,6 @@ bool DallasTemperatureSensor::read_scratch_pad_() {
|
||||
}
|
||||
|
||||
void DallasTemperatureSensor::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
if (!this->check_address_())
|
||||
return;
|
||||
if (!this->read_scratch_pad_())
|
||||
|
@@ -164,7 +164,6 @@ async def register_datetime(var, config):
|
||||
cg.add(getattr(cg.App, f"register_{entity_type}")(var))
|
||||
CORE.register_platform_component(entity_type, var)
|
||||
await setup_datetime_core_(var, config)
|
||||
cg.add_define(f"USE_DATETIME_{config[CONF_TYPE]}")
|
||||
|
||||
|
||||
async def new_datetime(config, *args):
|
||||
@@ -175,7 +174,6 @@ async def new_datetime(config, *args):
|
||||
|
||||
@coroutine_with_priority(100.0)
|
||||
async def to_code(config):
|
||||
cg.add_define("USE_DATETIME")
|
||||
cg.add_global(datetime_ns.using)
|
||||
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components.zephyr import zephyr_add_prj_conf
|
||||
from esphome.config_helpers import filter_source_files_from_platform
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
@@ -10,6 +11,7 @@ from esphome.const import (
|
||||
CONF_LOOP_TIME,
|
||||
PlatformFramework,
|
||||
)
|
||||
from esphome.core import CORE
|
||||
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
DEPENDENCIES = ["logger"]
|
||||
@@ -44,6 +46,8 @@ CONFIG_SCHEMA = cv.All(
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
if CORE.using_zephyr:
|
||||
zephyr_add_prj_conf("HWINFO", True)
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
|
||||
@@ -62,5 +66,6 @@ FILTER_SOURCE_FILES = filter_source_files_from_platform(
|
||||
PlatformFramework.RTL87XX_ARDUINO,
|
||||
PlatformFramework.LN882X_ARDUINO,
|
||||
},
|
||||
"debug_zephyr.cpp": {PlatformFramework.NRF52_ZEPHYR},
|
||||
}
|
||||
)
|
||||
|
281
esphome/components/debug/debug_zephyr.cpp
Normal file
281
esphome/components/debug/debug_zephyr.cpp
Normal file
@@ -0,0 +1,281 @@
|
||||
#include "debug_component.h"
|
||||
#ifdef USE_ZEPHYR
|
||||
#include <climits>
|
||||
#include "esphome/core/log.h"
|
||||
#include <zephyr/drivers/hwinfo.h>
|
||||
#include <hal/nrf_power.h>
|
||||
#include <cstdint>
|
||||
|
||||
#define BOOTLOADER_VERSION_REGISTER NRF_TIMER2->CC[0]
|
||||
|
||||
namespace esphome {
|
||||
namespace debug {
|
||||
|
||||
static const char *const TAG = "debug";
|
||||
constexpr std::uintptr_t MBR_PARAM_PAGE_ADDR = 0xFFC;
|
||||
constexpr std::uintptr_t MBR_BOOTLOADER_ADDR = 0xFF8;
|
||||
|
||||
static void show_reset_reason(std::string &reset_reason, bool set, const char *reason) {
|
||||
if (!set) {
|
||||
return;
|
||||
}
|
||||
if (!reset_reason.empty()) {
|
||||
reset_reason += ", ";
|
||||
}
|
||||
reset_reason += reason;
|
||||
}
|
||||
|
||||
inline uint32_t read_mem_u32(uintptr_t addr) {
|
||||
return *reinterpret_cast<volatile uint32_t *>(addr); // NOLINT(performance-no-int-to-ptr)
|
||||
}
|
||||
|
||||
std::string DebugComponent::get_reset_reason_() {
|
||||
uint32_t cause;
|
||||
auto ret = hwinfo_get_reset_cause(&cause);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "Unable to get reset cause: %d", ret);
|
||||
return "";
|
||||
}
|
||||
std::string reset_reason;
|
||||
|
||||
show_reset_reason(reset_reason, cause & RESET_PIN, "External pin");
|
||||
show_reset_reason(reset_reason, cause & RESET_SOFTWARE, "Software reset");
|
||||
show_reset_reason(reset_reason, cause & RESET_BROWNOUT, "Brownout (drop in voltage)");
|
||||
show_reset_reason(reset_reason, cause & RESET_POR, "Power-on reset (POR)");
|
||||
show_reset_reason(reset_reason, cause & RESET_WATCHDOG, "Watchdog timer expiration");
|
||||
show_reset_reason(reset_reason, cause & RESET_DEBUG, "Debug event");
|
||||
show_reset_reason(reset_reason, cause & RESET_SECURITY, "Security violation");
|
||||
show_reset_reason(reset_reason, cause & RESET_LOW_POWER_WAKE, "Waking up from low power mode");
|
||||
show_reset_reason(reset_reason, cause & RESET_CPU_LOCKUP, "CPU lock-up detected");
|
||||
show_reset_reason(reset_reason, cause & RESET_PARITY, "Parity error");
|
||||
show_reset_reason(reset_reason, cause & RESET_PLL, "PLL error");
|
||||
show_reset_reason(reset_reason, cause & RESET_CLOCK, "Clock error");
|
||||
show_reset_reason(reset_reason, cause & RESET_HARDWARE, "Hardware reset");
|
||||
show_reset_reason(reset_reason, cause & RESET_USER, "User reset");
|
||||
show_reset_reason(reset_reason, cause & RESET_TEMPERATURE, "Temperature reset");
|
||||
|
||||
ESP_LOGD(TAG, "Reset Reason: %s", reset_reason.c_str());
|
||||
return reset_reason;
|
||||
}
|
||||
|
||||
uint32_t DebugComponent::get_free_heap_() { return INT_MAX; }
|
||||
|
||||
void DebugComponent::get_device_info_(std::string &device_info) {
|
||||
std::string supply = "Main supply status: ";
|
||||
if (nrf_power_mainregstatus_get(NRF_POWER) == NRF_POWER_MAINREGSTATUS_NORMAL) {
|
||||
supply += "Normal voltage.";
|
||||
} else {
|
||||
supply += "High voltage.";
|
||||
}
|
||||
ESP_LOGD(TAG, "%s", supply.c_str());
|
||||
device_info += "|" + supply;
|
||||
|
||||
std::string reg0 = "Regulator stage 0: ";
|
||||
if (nrf_power_mainregstatus_get(NRF_POWER) == NRF_POWER_MAINREGSTATUS_HIGH) {
|
||||
reg0 += nrf_power_dcdcen_vddh_get(NRF_POWER) ? "DC/DC" : "LDO";
|
||||
reg0 += ", ";
|
||||
switch (NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) {
|
||||
case (UICR_REGOUT0_VOUT_DEFAULT << UICR_REGOUT0_VOUT_Pos):
|
||||
reg0 += "1.8V (default)";
|
||||
break;
|
||||
case (UICR_REGOUT0_VOUT_1V8 << UICR_REGOUT0_VOUT_Pos):
|
||||
reg0 += "1.8V";
|
||||
break;
|
||||
case (UICR_REGOUT0_VOUT_2V1 << UICR_REGOUT0_VOUT_Pos):
|
||||
reg0 += "2.1V";
|
||||
break;
|
||||
case (UICR_REGOUT0_VOUT_2V4 << UICR_REGOUT0_VOUT_Pos):
|
||||
reg0 += "2.4V";
|
||||
break;
|
||||
case (UICR_REGOUT0_VOUT_2V7 << UICR_REGOUT0_VOUT_Pos):
|
||||
reg0 += "2.7V";
|
||||
break;
|
||||
case (UICR_REGOUT0_VOUT_3V0 << UICR_REGOUT0_VOUT_Pos):
|
||||
reg0 += "3.0V";
|
||||
break;
|
||||
case (UICR_REGOUT0_VOUT_3V3 << UICR_REGOUT0_VOUT_Pos):
|
||||
reg0 += "3.3V";
|
||||
break;
|
||||
default:
|
||||
reg0 += "???V";
|
||||
}
|
||||
} else {
|
||||
reg0 += "disabled";
|
||||
}
|
||||
ESP_LOGD(TAG, "%s", reg0.c_str());
|
||||
device_info += "|" + reg0;
|
||||
|
||||
std::string reg1 = "Regulator stage 1: ";
|
||||
reg1 += nrf_power_dcdcen_get(NRF_POWER) ? "DC/DC" : "LDO";
|
||||
ESP_LOGD(TAG, "%s", reg1.c_str());
|
||||
device_info += "|" + reg1;
|
||||
|
||||
std::string usb_power = "USB power state: ";
|
||||
if (nrf_power_usbregstatus_vbusdet_get(NRF_POWER)) {
|
||||
if (nrf_power_usbregstatus_outrdy_get(NRF_POWER)) {
|
||||
/**< From the power viewpoint, USB is ready for working. */
|
||||
usb_power += "ready";
|
||||
} else {
|
||||
/**< The USB power is detected, but USB power regulator is not ready. */
|
||||
usb_power += "connected (regulator is not ready)";
|
||||
}
|
||||
} else {
|
||||
/**< No power on USB lines detected. */
|
||||
usb_power += "disconected";
|
||||
}
|
||||
ESP_LOGD(TAG, "%s", usb_power.c_str());
|
||||
device_info += "|" + usb_power;
|
||||
|
||||
bool enabled;
|
||||
nrf_power_pof_thr_t pof_thr;
|
||||
|
||||
pof_thr = nrf_power_pofcon_get(NRF_POWER, &enabled);
|
||||
std::string pof = "Power-fail comparator: ";
|
||||
if (enabled) {
|
||||
switch (pof_thr) {
|
||||
case POWER_POFCON_THRESHOLD_V17:
|
||||
pof += "1.7V";
|
||||
break;
|
||||
case POWER_POFCON_THRESHOLD_V18:
|
||||
pof += "1.8V";
|
||||
break;
|
||||
case POWER_POFCON_THRESHOLD_V19:
|
||||
pof += "1.9V";
|
||||
break;
|
||||
case POWER_POFCON_THRESHOLD_V20:
|
||||
pof += "2.0V";
|
||||
break;
|
||||
case POWER_POFCON_THRESHOLD_V21:
|
||||
pof += "2.1V";
|
||||
break;
|
||||
case POWER_POFCON_THRESHOLD_V22:
|
||||
pof += "2.2V";
|
||||
break;
|
||||
case POWER_POFCON_THRESHOLD_V23:
|
||||
pof += "2.3V";
|
||||
break;
|
||||
case POWER_POFCON_THRESHOLD_V24:
|
||||
pof += "2.4V";
|
||||
break;
|
||||
case POWER_POFCON_THRESHOLD_V25:
|
||||
pof += "2.5V";
|
||||
break;
|
||||
case POWER_POFCON_THRESHOLD_V26:
|
||||
pof += "2.6V";
|
||||
break;
|
||||
case POWER_POFCON_THRESHOLD_V27:
|
||||
pof += "2.7V";
|
||||
break;
|
||||
case POWER_POFCON_THRESHOLD_V28:
|
||||
pof += "2.8V";
|
||||
break;
|
||||
}
|
||||
|
||||
if (nrf_power_mainregstatus_get(NRF_POWER) == NRF_POWER_MAINREGSTATUS_HIGH) {
|
||||
pof += ", VDDH: ";
|
||||
switch (nrf_power_pofcon_vddh_get(NRF_POWER)) {
|
||||
case NRF_POWER_POFTHRVDDH_V27:
|
||||
pof += "2.7V";
|
||||
break;
|
||||
case NRF_POWER_POFTHRVDDH_V28:
|
||||
pof += "2.8V";
|
||||
break;
|
||||
case NRF_POWER_POFTHRVDDH_V29:
|
||||
pof += "2.9V";
|
||||
break;
|
||||
case NRF_POWER_POFTHRVDDH_V30:
|
||||
pof += "3.0V";
|
||||
break;
|
||||
case NRF_POWER_POFTHRVDDH_V31:
|
||||
pof += "3.1V";
|
||||
break;
|
||||
case NRF_POWER_POFTHRVDDH_V32:
|
||||
pof += "3.2V";
|
||||
break;
|
||||
case NRF_POWER_POFTHRVDDH_V33:
|
||||
pof += "3.3V";
|
||||
break;
|
||||
case NRF_POWER_POFTHRVDDH_V34:
|
||||
pof += "3.4V";
|
||||
break;
|
||||
case NRF_POWER_POFTHRVDDH_V35:
|
||||
pof += "3.5V";
|
||||
break;
|
||||
case NRF_POWER_POFTHRVDDH_V36:
|
||||
pof += "3.6V";
|
||||
break;
|
||||
case NRF_POWER_POFTHRVDDH_V37:
|
||||
pof += "3.7V";
|
||||
break;
|
||||
case NRF_POWER_POFTHRVDDH_V38:
|
||||
pof += "3.8V";
|
||||
break;
|
||||
case NRF_POWER_POFTHRVDDH_V39:
|
||||
pof += "3.9V";
|
||||
break;
|
||||
case NRF_POWER_POFTHRVDDH_V40:
|
||||
pof += "4.0V";
|
||||
break;
|
||||
case NRF_POWER_POFTHRVDDH_V41:
|
||||
pof += "4.1V";
|
||||
break;
|
||||
case NRF_POWER_POFTHRVDDH_V42:
|
||||
pof += "4.2V";
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pof += "disabled";
|
||||
}
|
||||
ESP_LOGD(TAG, "%s", pof.c_str());
|
||||
device_info += "|" + pof;
|
||||
|
||||
auto package = [](uint32_t value) {
|
||||
switch (value) {
|
||||
case 0x2004:
|
||||
return "QIxx - 7x7 73-pin aQFN";
|
||||
case 0x2000:
|
||||
return "QFxx - 6x6 48-pin QFN";
|
||||
case 0x2005:
|
||||
return "CKxx - 3.544 x 3.607 WLCSP";
|
||||
}
|
||||
return "Unspecified";
|
||||
};
|
||||
|
||||
ESP_LOGD(TAG, "Code page size: %u, code size: %u, device id: 0x%08x%08x", NRF_FICR->CODEPAGESIZE, NRF_FICR->CODESIZE,
|
||||
NRF_FICR->DEVICEID[1], NRF_FICR->DEVICEID[0]);
|
||||
ESP_LOGD(TAG, "Encryption root: 0x%08x%08x%08x%08x, Identity Root: 0x%08x%08x%08x%08x", NRF_FICR->ER[0],
|
||||
NRF_FICR->ER[1], NRF_FICR->ER[2], NRF_FICR->ER[3], NRF_FICR->IR[0], NRF_FICR->IR[1], NRF_FICR->IR[2],
|
||||
NRF_FICR->IR[3]);
|
||||
ESP_LOGD(TAG, "Device address type: %s, address: %s", (NRF_FICR->DEVICEADDRTYPE & 0x1 ? "Random" : "Public"),
|
||||
get_mac_address_pretty().c_str());
|
||||
ESP_LOGD(TAG, "Part code: nRF%x, version: %c%c%c%c, package: %s", NRF_FICR->INFO.PART,
|
||||
NRF_FICR->INFO.VARIANT >> 24 & 0xFF, NRF_FICR->INFO.VARIANT >> 16 & 0xFF, NRF_FICR->INFO.VARIANT >> 8 & 0xFF,
|
||||
NRF_FICR->INFO.VARIANT & 0xFF, package(NRF_FICR->INFO.PACKAGE));
|
||||
ESP_LOGD(TAG, "RAM: %ukB, Flash: %ukB, production test: %sdone", NRF_FICR->INFO.RAM, NRF_FICR->INFO.FLASH,
|
||||
(NRF_FICR->PRODTEST[0] == 0xBB42319F ? "" : "not "));
|
||||
ESP_LOGD(
|
||||
TAG, "GPIO as NFC pins: %s, GPIO as nRESET pin: %s",
|
||||
YESNO((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)),
|
||||
YESNO(((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) !=
|
||||
(UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) ||
|
||||
((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) !=
|
||||
(UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))));
|
||||
|
||||
#ifdef USE_BOOTLOADER_MCUBOOT
|
||||
ESP_LOGD(TAG, "bootloader: mcuboot");
|
||||
#else
|
||||
ESP_LOGD(TAG, "bootloader: Adafruit, version %u.%u.%u", (BOOTLOADER_VERSION_REGISTER >> 16) & 0xFF,
|
||||
(BOOTLOADER_VERSION_REGISTER >> 8) & 0xFF, BOOTLOADER_VERSION_REGISTER & 0xFF);
|
||||
ESP_LOGD(TAG, "MBR bootloader addr 0x%08x, UICR bootloader addr 0x%08x", read_mem_u32(MBR_BOOTLOADER_ADDR),
|
||||
NRF_UICR->NRFFW[0]);
|
||||
ESP_LOGD(TAG, "MBR param page addr 0x%08x, UICR param page addr 0x%08x", read_mem_u32(MBR_PARAM_PAGE_ADDR),
|
||||
NRF_UICR->NRFFW[1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DebugComponent::update_platform_() {}
|
||||
|
||||
} // namespace debug
|
||||
} // namespace esphome
|
||||
#endif
|
@@ -1,6 +1,7 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import sensor
|
||||
from esphome.components.esp32 import CONF_CPU_FREQUENCY
|
||||
from esphome.components.psram import DOMAIN as PSRAM_DOMAIN
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_BLOCK,
|
||||
@@ -54,7 +55,7 @@ CONFIG_SCHEMA = {
|
||||
),
|
||||
cv.Optional(CONF_PSRAM): cv.All(
|
||||
cv.only_on_esp32,
|
||||
cv.requires_component("psram"),
|
||||
cv.requires_component(PSRAM_DOMAIN),
|
||||
sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_BYTES,
|
||||
icon=ICON_COUNTER,
|
||||
|
@@ -12,7 +12,6 @@ static const uint32_t TEARDOWN_TIMEOUT_DEEP_SLEEP_MS = 5000;
|
||||
bool global_has_deep_sleep = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
void DeepSleepComponent::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
global_has_deep_sleep = true;
|
||||
|
||||
const optional<uint32_t> run_duration = get_run_duration_();
|
||||
|
@@ -8,7 +8,6 @@ namespace dht {
|
||||
static const char *const TAG = "dht";
|
||||
|
||||
void DHT::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
this->pin_->digital_write(true);
|
||||
this->pin_->setup();
|
||||
this->pin_->digital_write(true);
|
||||
|
@@ -34,7 +34,6 @@ void DHT12Component::update() {
|
||||
this->status_clear_warning();
|
||||
}
|
||||
void DHT12Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
uint8_t data[5];
|
||||
if (!this->read_data_(data)) {
|
||||
this->mark_failed();
|
||||
|
@@ -51,8 +51,7 @@ DISPLAY_ROTATIONS = {
|
||||
|
||||
def validate_rotation(value):
|
||||
value = cv.string(value)
|
||||
if value.endswith("°"):
|
||||
value = value[:-1]
|
||||
value = value.removesuffix("°")
|
||||
return cv.enum(DISPLAY_ROTATIONS, int=True)(value)
|
||||
|
||||
|
||||
|
@@ -11,8 +11,6 @@ void DPS310Component::setup() {
|
||||
uint8_t coef_data_raw[DPS310_NUM_COEF_REGS];
|
||||
auto timer = DPS310_INIT_TIMEOUT;
|
||||
uint8_t reg = 0;
|
||||
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
// first, reset the sensor
|
||||
if (!this->write_byte(DPS310_REG_RESET, DPS310_CMD_RESET)) {
|
||||
this->mark_failed();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user