From 1f50bd064973da339ead15d9b35cea789f1426d7 Mon Sep 17 00:00:00 2001 From: Alfredo Date: Tue, 28 Mar 2023 00:08:26 +0200 Subject: [PATCH 01/14] Fix EzoCommandType enum (#4593) * Fix EzoCommandType enum Assign explicit value to EZO_CALIBRATION, and rescale all subsequent values. * Remove enum values --------- Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- esphome/components/ezo/ezo.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/esphome/components/ezo/ezo.h b/esphome/components/ezo/ezo.h index 72e82a574f..28b46643e9 100644 --- a/esphome/components/ezo/ezo.h +++ b/esphome/components/ezo/ezo.h @@ -12,14 +12,14 @@ static const char *const TAG = "ezo.sensor"; enum EzoCommandType : uint8_t { EZO_READ = 0, - EZO_LED = 1, - EZO_DEVICE_INFORMATION = 2, - EZO_SLOPE = 3, + EZO_LED, + EZO_DEVICE_INFORMATION, + EZO_SLOPE, EZO_CALIBRATION, - EZO_SLEEP = 4, - EZO_I2C = 5, - EZO_T = 6, - EZO_CUSTOM = 7 + EZO_SLEEP, + EZO_I2C, + EZO_T, + EZO_CUSTOM }; enum EzoCalibrationType : uint8_t { EZO_CAL_LOW = 0, EZO_CAL_MID = 1, EZO_CAL_HIGH = 2 }; From cb2fcaa9b1e076bce939700e8cc9e3d437c938a7 Mon Sep 17 00:00:00 2001 From: Fabian Date: Tue, 28 Mar 2023 08:38:56 +0200 Subject: [PATCH 02/14] `EntityBase` Name can stay in flash. (#4594) * `EntityBase`can stay in flash. * Trying to please the CI. --------- Co-authored-by: Your Name --- esphome/components/button/button.cpp | 3 - esphome/components/button/button.h | 3 - esphome/components/climate/climate.cpp | 5 - esphome/components/climate/climate.h | 5 - esphome/components/cover/cover.cpp | 3 +- esphome/components/cover/cover.h | 1 - .../components/esp32_camera/esp32_camera.cpp | 3 +- .../components/esp32_camera/esp32_camera.h | 1 - esphome/components/fan/fan.cpp | 3 - esphome/components/fan/fan.h | 4 - esphome/components/fan/fan_state.h | 1 - esphome/components/light/light_state.cpp | 1 - esphome/components/light/light_state.h | 3 - esphome/components/lock/lock.cpp | 3 +- esphome/components/lock/lock.h | 1 - esphome/components/partition/light.py | 2 +- esphome/components/sensor/sensor.cpp | 3 +- esphome/components/sensor/sensor.h | 1 - esphome/components/switch/switch.cpp | 3 +- esphome/components/switch/switch.h | 1 - .../components/text_sensor/text_sensor.cpp | 3 - esphome/components/text_sensor/text_sensor.h | 3 - esphome/core/entity_base.cpp | 12 +- esphome/core/entity_base.h | 10 +- esphome/core/string_ref.cpp | 12 ++ esphome/core/string_ref.h | 134 ++++++++++++++++++ 26 files changed, 161 insertions(+), 63 deletions(-) create mode 100644 esphome/core/string_ref.cpp create mode 100644 esphome/core/string_ref.h diff --git a/esphome/components/button/button.cpp b/esphome/components/button/button.cpp index 3d58780d6d..dfa417de7b 100644 --- a/esphome/components/button/button.cpp +++ b/esphome/components/button/button.cpp @@ -6,9 +6,6 @@ namespace button { static const char *const TAG = "button"; -Button::Button(const std::string &name) : EntityBase(name) {} -Button::Button() : Button("") {} - void Button::press() { ESP_LOGD(TAG, "'%s' Pressed.", this->get_name().c_str()); this->press_action(); diff --git a/esphome/components/button/button.h b/esphome/components/button/button.h index 3b5f338887..a4902810b2 100644 --- a/esphome/components/button/button.h +++ b/esphome/components/button/button.h @@ -28,9 +28,6 @@ namespace button { */ class Button : public EntityBase { public: - explicit Button(); - explicit Button(const std::string &name); - /** Press this button. This is called by the front-end. * * For implementing buttons, please override press_action. diff --git a/esphome/components/climate/climate.cpp b/esphome/components/climate/climate.cpp index 37572ae913..b4d5ee9685 100644 --- a/esphome/components/climate/climate.cpp +++ b/esphome/components/climate/climate.cpp @@ -453,12 +453,7 @@ void Climate::set_visual_temperature_step_override(float target, float current) this->visual_target_temperature_step_override_ = target; this->visual_current_temperature_step_override_ = current; } -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -Climate::Climate(const std::string &name) : EntityBase(name) {} -#pragma GCC diagnostic pop -Climate::Climate() : Climate("") {} ClimateCall Climate::make_call() { return ClimateCall(this); } ClimateCall ClimateDeviceRestoreState::to_call(Climate *climate) { diff --git a/esphome/components/climate/climate.h b/esphome/components/climate/climate.h index 520036f718..43bd71657d 100644 --- a/esphome/components/climate/climate.h +++ b/esphome/components/climate/climate.h @@ -166,11 +166,6 @@ struct ClimateDeviceRestoreState { */ class Climate : public EntityBase { public: - /// Construct a climate device with empty name (will be set later). - Climate(); - /// Construct a climate device with a name. - Climate(const std::string &name); - /// The active mode of the climate device. ClimateMode mode{CLIMATE_MODE_OFF}; /// The active state of the climate device. diff --git a/esphome/components/cover/cover.cpp b/esphome/components/cover/cover.cpp index 902e9bca94..24dd88b698 100644 --- a/esphome/components/cover/cover.cpp +++ b/esphome/components/cover/cover.cpp @@ -31,7 +31,7 @@ const char *cover_operation_to_str(CoverOperation op) { } } -Cover::Cover(const std::string &name) : EntityBase(name), position{COVER_OPEN} {} +Cover::Cover() : position{COVER_OPEN} {} CoverCall::CoverCall(Cover *parent) : parent_(parent) {} CoverCall &CoverCall::set_command(const char *command) { @@ -204,7 +204,6 @@ optional Cover::restore_state_() { return {}; return recovered; } -Cover::Cover() : Cover("") {} std::string Cover::get_device_class() { if (this->device_class_override_.has_value()) return *this->device_class_override_; diff --git a/esphome/components/cover/cover.h b/esphome/components/cover/cover.h index 8ae9cfc8dd..c6a420fa97 100644 --- a/esphome/components/cover/cover.h +++ b/esphome/components/cover/cover.h @@ -111,7 +111,6 @@ const char *cover_operation_to_str(CoverOperation op); class Cover : public EntityBase { public: explicit Cover(); - explicit Cover(const std::string &name); /// The current operation of the cover (idle, opening, closing). CoverOperation current_operation{COVER_OPERATION_IDLE}; diff --git a/esphome/components/esp32_camera/esp32_camera.cpp b/esphome/components/esp32_camera/esp32_camera.cpp index 4a53748213..e4020a902e 100644 --- a/esphome/components/esp32_camera/esp32_camera.cpp +++ b/esphome/components/esp32_camera/esp32_camera.cpp @@ -202,7 +202,7 @@ void ESP32Camera::loop() { float ESP32Camera::get_setup_priority() const { return setup_priority::DATA; } /* ---------------- constructors ---------------- */ -ESP32Camera::ESP32Camera(const std::string &name) : EntityBase(name) { +ESP32Camera::ESP32Camera() { this->config_.pin_pwdn = -1; this->config_.pin_reset = -1; this->config_.pin_xclk = -1; @@ -215,7 +215,6 @@ ESP32Camera::ESP32Camera(const std::string &name) : EntityBase(name) { global_esp32_camera = this; } -ESP32Camera::ESP32Camera() : ESP32Camera("") {} /* ---------------- setters ---------------- */ /* set pin assignment */ diff --git a/esphome/components/esp32_camera/esp32_camera.h b/esphome/components/esp32_camera/esp32_camera.h index 62fdbabd06..5f88c6fda8 100644 --- a/esphome/components/esp32_camera/esp32_camera.h +++ b/esphome/components/esp32_camera/esp32_camera.h @@ -103,7 +103,6 @@ class CameraImageReader { /* ---------------- ESP32Camera class ---------------- */ class ESP32Camera : public Component, public EntityBase { public: - ESP32Camera(const std::string &name); ESP32Camera(); /* setters */ diff --git a/esphome/components/fan/fan.cpp b/esphome/components/fan/fan.cpp index c8a3064f6c..87566bad4a 100644 --- a/esphome/components/fan/fan.cpp +++ b/esphome/components/fan/fan.cpp @@ -80,9 +80,6 @@ void FanRestoreState::apply(Fan &fan) { fan.publish_state(); } -Fan::Fan() : EntityBase("") {} -Fan::Fan(const std::string &name) : EntityBase(name) {} - FanCall Fan::turn_on() { return this->make_call().set_state(true); } FanCall Fan::turn_off() { return this->make_call().set_state(false); } FanCall Fan::toggle() { return this->make_call().set_state(!this->state); } diff --git a/esphome/components/fan/fan.h b/esphome/components/fan/fan.h index 337bb3935a..f9d317e675 100644 --- a/esphome/components/fan/fan.h +++ b/esphome/components/fan/fan.h @@ -99,10 +99,6 @@ struct FanRestoreState { class Fan : public EntityBase { public: - Fan(); - /// Construct the fan with name. - explicit Fan(const std::string &name); - /// The current on/off state of the fan. bool state{false}; /// The current oscillation state of the fan. diff --git a/esphome/components/fan/fan_state.h b/esphome/components/fan/fan_state.h index 044ee59736..5926e700b0 100644 --- a/esphome/components/fan/fan_state.h +++ b/esphome/components/fan/fan_state.h @@ -15,7 +15,6 @@ enum ESPDEPRECATED("LegacyFanDirection members are deprecated, use FanDirection class ESPDEPRECATED("FanState is deprecated, use Fan instead.", "2022.2") FanState : public Fan, public Component { public: FanState() = default; - explicit FanState(const std::string &name) : Fan(name) {} /// Get the traits of this fan. FanTraits get_traits() override { return this->traits_; } diff --git a/esphome/components/light/light_state.cpp b/esphome/components/light/light_state.cpp index 64c29a346b..50ebd8882b 100644 --- a/esphome/components/light/light_state.cpp +++ b/esphome/components/light/light_state.cpp @@ -8,7 +8,6 @@ namespace light { static const char *const TAG = "light"; -LightState::LightState(const std::string &name, LightOutput *output) : EntityBase(name), output_(output) {} LightState::LightState(LightOutput *output) : output_(output) {} LightTraits LightState::get_traits() { return this->output_->get_traits(); } diff --git a/esphome/components/light/light_state.h b/esphome/components/light/light_state.h index 81f8be7207..ac4718ade5 100644 --- a/esphome/components/light/light_state.h +++ b/esphome/components/light/light_state.h @@ -33,9 +33,6 @@ enum LightRestoreMode { */ class LightState : public EntityBase, public Component { public: - /// Construct this LightState using the provided traits and name. - LightState(const std::string &name, LightOutput *output); - LightState(LightOutput *output); LightTraits get_traits(); diff --git a/esphome/components/lock/lock.cpp b/esphome/components/lock/lock.cpp index dbb8a941ad..ddc5445349 100644 --- a/esphome/components/lock/lock.cpp +++ b/esphome/components/lock/lock.cpp @@ -24,8 +24,7 @@ const char *lock_state_to_string(LockState state) { } } -Lock::Lock(const std::string &name) : EntityBase(name), state(LOCK_STATE_NONE) {} -Lock::Lock() : Lock("") {} +Lock::Lock() : state(LOCK_STATE_NONE) {} LockCall Lock::make_call() { return LockCall(this); } void Lock::lock() { diff --git a/esphome/components/lock/lock.h b/esphome/components/lock/lock.h index 52256691f6..7a98187a4f 100644 --- a/esphome/components/lock/lock.h +++ b/esphome/components/lock/lock.h @@ -103,7 +103,6 @@ class LockCall { class Lock : public EntityBase { public: explicit Lock(); - explicit Lock(const std::string &name); /** Make a lock device control call, this is used to control the lock device, see the LockCall description * for more info. diff --git a/esphome/components/partition/light.py b/esphome/components/partition/light.py index 73cda2c926..8e45915cf3 100644 --- a/esphome/components/partition/light.py +++ b/esphome/components/partition/light.py @@ -102,7 +102,7 @@ async def to_code(config): conf[CONF_ADDRESSABLE_LIGHT_ID], await cg.get_variable(conf[CONF_SINGLE_LIGHT_ID]), ) - light_state = cg.new_Pvariable(conf[CONF_LIGHT_ID], "", wrapper) + light_state = cg.new_Pvariable(conf[CONF_LIGHT_ID], wrapper) await cg.register_component(light_state, conf) segments.append(AddressableSegment(light_state, 0, 1, False)) diff --git a/esphome/components/sensor/sensor.cpp b/esphome/components/sensor/sensor.cpp index 0de452b784..fc66e03d6b 100644 --- a/esphome/components/sensor/sensor.cpp +++ b/esphome/components/sensor/sensor.cpp @@ -20,8 +20,7 @@ std::string state_class_to_string(StateClass state_class) { } } -Sensor::Sensor(const std::string &name) : EntityBase(name), state(NAN), raw_state(NAN) {} -Sensor::Sensor() : Sensor("") {} +Sensor::Sensor() : state(NAN), raw_state(NAN) {} std::string Sensor::get_unit_of_measurement() { if (this->unit_of_measurement_.has_value()) diff --git a/esphome/components/sensor/sensor.h b/esphome/components/sensor/sensor.h index e3651752cf..4308eafb12 100644 --- a/esphome/components/sensor/sensor.h +++ b/esphome/components/sensor/sensor.h @@ -57,7 +57,6 @@ std::string state_class_to_string(StateClass state_class); class Sensor : public EntityBase { public: explicit Sensor(); - explicit Sensor(const std::string &name); /// Get the unit of measurement, using the manual override if set. std::string get_unit_of_measurement(); diff --git a/esphome/components/switch/switch.cpp b/esphome/components/switch/switch.cpp index caa072b1ea..72e7add158 100644 --- a/esphome/components/switch/switch.cpp +++ b/esphome/components/switch/switch.cpp @@ -6,8 +6,7 @@ namespace switch_ { static const char *const TAG = "switch"; -Switch::Switch(const std::string &name) : EntityBase(name), state(false) {} -Switch::Switch() : Switch("") {} +Switch::Switch() : state(false) {} void Switch::turn_on() { ESP_LOGD(TAG, "'%s' Turning ON.", this->get_name().c_str()); diff --git a/esphome/components/switch/switch.h b/esphome/components/switch/switch.h index b89d8db6a5..8bea3b36db 100644 --- a/esphome/components/switch/switch.h +++ b/esphome/components/switch/switch.h @@ -32,7 +32,6 @@ enum SwitchRestoreMode { class Switch : public EntityBase { public: explicit Switch(); - explicit Switch(const std::string &name); /** Publish a state to the front-end from the back-end. * diff --git a/esphome/components/text_sensor/text_sensor.cpp b/esphome/components/text_sensor/text_sensor.cpp index d76ab7e27d..f10cd50267 100644 --- a/esphome/components/text_sensor/text_sensor.cpp +++ b/esphome/components/text_sensor/text_sensor.cpp @@ -6,9 +6,6 @@ namespace text_sensor { static const char *const TAG = "text_sensor"; -TextSensor::TextSensor() : TextSensor("") {} -TextSensor::TextSensor(const std::string &name) : EntityBase(name) {} - void TextSensor::publish_state(const std::string &state) { this->raw_state = state; this->raw_callback_.call(state); diff --git a/esphome/components/text_sensor/text_sensor.h b/esphome/components/text_sensor/text_sensor.h index cf7b6b86ef..996af02f7e 100644 --- a/esphome/components/text_sensor/text_sensor.h +++ b/esphome/components/text_sensor/text_sensor.h @@ -30,9 +30,6 @@ namespace text_sensor { class TextSensor : public EntityBase { public: - explicit TextSensor(); - explicit TextSensor(const std::string &name); - /// Getter-syntax for .state. std::string get_state() const; /// Getter-syntax for .raw_state diff --git a/esphome/core/entity_base.cpp b/esphome/core/entity_base.cpp index 49a73854a1..19ab57349d 100644 --- a/esphome/core/entity_base.cpp +++ b/esphome/core/entity_base.cpp @@ -6,16 +6,14 @@ namespace esphome { static const char *const TAG = "entity_base"; -EntityBase::EntityBase(std::string name) : name_(std::move(name)) { this->calc_object_id_(); } - // Entity Name -const std::string &EntityBase::get_name() const { return this->name_; } -void EntityBase::set_name(const std::string &name) { - if (name.empty()) { - this->name_ = App.get_friendly_name(); +const StringRef &EntityBase::get_name() const { return this->name_; } +void EntityBase::set_name(const char *name) { + this->name_ = StringRef(name); + if (this->name_.empty()) { + this->name_ = StringRef(App.get_friendly_name()); this->has_own_name_ = false; } else { - this->name_ = name; this->has_own_name_ = true; } this->calc_object_id_(); diff --git a/esphome/core/entity_base.h b/esphome/core/entity_base.h index 5ab1f7b424..e25aab21a9 100644 --- a/esphome/core/entity_base.h +++ b/esphome/core/entity_base.h @@ -2,6 +2,7 @@ #include #include +#include "string_ref.h" namespace esphome { @@ -14,12 +15,9 @@ enum EntityCategory : uint8_t { // The generic Entity base class that provides an interface common to all Entities. class EntityBase { public: - EntityBase() : EntityBase("") {} - explicit EntityBase(std::string name); - // Get/set the name of this Entity - const std::string &get_name() const; - void set_name(const std::string &name); + const StringRef &get_name() const; + void set_name(const char *name); // Get whether this Entity has its own name or it should use the device friendly_name. bool has_own_name() const { return this->has_own_name_; } @@ -54,7 +52,7 @@ class EntityBase { virtual uint32_t hash_base() { return 0L; } void calc_object_id_(); - std::string name_; + StringRef name_; bool has_own_name_{false}; std::string object_id_; const char *icon_c_str_{nullptr}; diff --git a/esphome/core/string_ref.cpp b/esphome/core/string_ref.cpp new file mode 100644 index 0000000000..ce1e33cbb7 --- /dev/null +++ b/esphome/core/string_ref.cpp @@ -0,0 +1,12 @@ +#include "string_ref.h" + +namespace esphome { + +#ifdef USE_JSON + +// NOLINTNEXTLINE(readability-identifier-naming) +void convertToJson(const StringRef &src, JsonVariant dst) { dst.set(src.c_str()); } + +#endif // USE_JSON + +} // namespace esphome diff --git a/esphome/core/string_ref.h b/esphome/core/string_ref.h new file mode 100644 index 0000000000..5940a7ee65 --- /dev/null +++ b/esphome/core/string_ref.h @@ -0,0 +1,134 @@ +#pragma once + +#include +#include +#include +#include "esphome/core/defines.h" + +#ifdef USE_JSON +#include "esphome/components/json/json_util.h" +#endif // USE_JSON + +namespace esphome { + +/** + * StringRef is a reference to a string owned by something else. So it behaves like simple string, but it does not own + * pointer. When it is default constructed, it has empty string. You can freely copy or move around this struct, but + * never free its pointer. str() function can be used to export the content as std::string. StringRef is adopted from + * + */ +class StringRef { + public: + using traits_type = std::char_traits; + using value_type = traits_type::char_type; + using allocator_type = std::allocator; + using size_type = std::allocator_traits::size_type; + using difference_type = std::allocator_traits::difference_type; + using const_reference = const value_type &; + using const_pointer = const value_type *; + using const_iterator = const_pointer; + using const_reverse_iterator = std::reverse_iterator; + + constexpr StringRef() : base_(""), len_(0) {} + explicit StringRef(const std::string &s) : base_(s.c_str()), len_(s.size()) {} + explicit StringRef(const char *s) : base_(s), len_(strlen(s)) {} + constexpr StringRef(const char *s, size_t n) : base_(s), len_(n) {} + template + constexpr StringRef(const CharT *s, size_t n) : base_(reinterpret_cast(s)), len_(n) {} + template + StringRef(InputIt first, InputIt last) + : base_(reinterpret_cast(&*first)), len_(std::distance(first, last)) {} + template + StringRef(InputIt *first, InputIt *last) + : base_(reinterpret_cast(first)), len_(std::distance(first, last)) {} + template constexpr static StringRef from_lit(const CharT (&s)[N]) { + return StringRef{s, N - 1}; + } + static StringRef from_maybe_nullptr(const char *s) { + if (s == nullptr) { + return StringRef(); + } + + return StringRef(s); + } + + constexpr const_iterator begin() const { return base_; }; + constexpr const_iterator cbegin() const { return base_; }; + + constexpr const_iterator end() const { return base_ + len_; }; + constexpr const_iterator cend() const { return base_ + len_; }; + + const_reverse_iterator rbegin() const { return const_reverse_iterator{base_ + len_}; } + const_reverse_iterator crbegin() const { return const_reverse_iterator{base_ + len_}; } + + const_reverse_iterator rend() const { return const_reverse_iterator{base_}; } + const_reverse_iterator crend() const { return const_reverse_iterator{base_}; } + + constexpr const char *c_str() const { return base_; } + constexpr size_type size() const { return len_; } + constexpr bool empty() const { return len_ == 0; } + constexpr const_reference operator[](size_type pos) const { return *(base_ + pos); } + + std::string str() const { return std::string(base_, len_); } + const uint8_t *byte() const { return reinterpret_cast(base_); } + + operator std::string() const { return str(); } + + private: + const char *base_; + size_type len_; +}; + +inline bool operator==(const StringRef &lhs, const StringRef &rhs) { + return lhs.size() == rhs.size() && std::equal(std::begin(lhs), std::end(lhs), std::begin(rhs)); +} + +inline bool operator==(const StringRef &lhs, const std::string &rhs) { + return lhs.size() == rhs.size() && std::equal(std::begin(lhs), std::end(lhs), std::begin(rhs)); +} + +inline bool operator==(const std::string &lhs, const StringRef &rhs) { return rhs == lhs; } + +inline bool operator==(const StringRef &lhs, const char *rhs) { + return lhs.size() == strlen(rhs) && std::equal(std::begin(lhs), std::end(lhs), rhs); +} + +inline bool operator==(const char *lhs, const StringRef &rhs) { return rhs == lhs; } + +inline bool operator!=(const StringRef &lhs, const StringRef &rhs) { return !(lhs == rhs); } + +inline bool operator!=(const StringRef &lhs, const std::string &rhs) { return !(lhs == rhs); } + +inline bool operator!=(const std::string &lhs, const StringRef &rhs) { return !(rhs == lhs); } + +inline bool operator!=(const StringRef &lhs, const char *rhs) { return !(lhs == rhs); } + +inline bool operator!=(const char *lhs, const StringRef &rhs) { return !(rhs == lhs); } + +inline bool operator<(const StringRef &lhs, const StringRef &rhs) { + return std::lexicographical_compare(std::begin(lhs), std::end(lhs), std::begin(rhs), std::end(rhs)); +} + +inline std::string &operator+=(std::string &lhs, const StringRef &rhs) { + lhs.append(rhs.c_str(), rhs.size()); + return lhs; +} + +inline std::string operator+(const char *lhs, const StringRef &rhs) { + auto str = std::string(lhs); + str.append(rhs.c_str(), rhs.size()); + return str; +} + +inline std::string operator+(const StringRef &lhs, const char *rhs) { + auto str = lhs.str(); + str.append(rhs); + return str; +} + +#ifdef USE_JSON +// NOLINTNEXTLINE(readability-identifier-naming) +void convertToJson(const StringRef &src, JsonVariant dst); +#endif // USE_JSON + +} // namespace esphome From 922344811f66c18b08aff21c804b0ba8c4c1e4b4 Mon Sep 17 00:00:00 2001 From: richardhopton Date: Tue, 28 Mar 2023 01:54:58 -0700 Subject: [PATCH 03/14] feat: Add support to unsubscribe from BLE advertisements (#4620) * feat: Add support to unsubscribe from BLE advertisements * Fix tests & clang --------- Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- esphome/components/api/api.proto | 7 +++++++ esphome/components/api/api_connection.h | 3 +++ esphome/components/api/api_pb2.cpp | 6 ++++++ esphome/components/api/api_pb2.h | 9 +++++++++ esphome/components/api/api_pb2_service.cpp | 21 +++++++++++++++++++++ esphome/components/api/api_pb2_service.h | 6 ++++++ 6 files changed, 52 insertions(+) diff --git a/esphome/components/api/api.proto b/esphome/components/api/api.proto index a64aac52e2..fd00317282 100644 --- a/esphome/components/api/api.proto +++ b/esphome/components/api/api.proto @@ -53,6 +53,8 @@ service APIConnection { rpc bluetooth_gatt_write_descriptor(BluetoothGATTWriteDescriptorRequest) returns (void) {} rpc bluetooth_gatt_notify(BluetoothGATTNotifyRequest) returns (void) {} rpc subscribe_bluetooth_connections_free(SubscribeBluetoothConnectionsFreeRequest) returns (BluetoothConnectionsFreeResponse) {} + rpc unsubscribe_bluetooth_le_advertisements(UnsubscribeBluetoothLEAdvertisementsRequest) returns (void) {} + } @@ -1361,6 +1363,11 @@ message BluetoothDeviceUnpairingResponse { int32 error = 3; } +message UnsubscribeBluetoothLEAdvertisementsRequest { + option (id) = 87; + option (source) = SOURCE_CLIENT; +} + message BluetoothDeviceClearCacheResponse { option (id) = 88; option (source) = SOURCE_SERVER; diff --git a/esphome/components/api/api_connection.h b/esphome/components/api/api_connection.h index b2076635b0..bc6ae5d7c3 100644 --- a/esphome/components/api/api_connection.h +++ b/esphome/components/api/api_connection.h @@ -153,6 +153,9 @@ class APIConnection : public APIServerConnection { void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) override { this->bluetooth_le_advertisement_subscription_ = true; } + void unsubscribe_bluetooth_le_advertisements(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override { + this->bluetooth_le_advertisement_subscription_ = false; + } bool is_authenticated() override { return this->connection_state_ == ConnectionState::AUTHENTICATED; } bool is_connection_setup() override { return this->connection_state_ == ConnectionState ::CONNECTED || this->is_authenticated(); diff --git a/esphome/components/api/api_pb2.cpp b/esphome/components/api/api_pb2.cpp index 43587469af..6260020064 100644 --- a/esphome/components/api/api_pb2.cpp +++ b/esphome/components/api/api_pb2.cpp @@ -6062,6 +6062,12 @@ void BluetoothDeviceUnpairingResponse::dump_to(std::string &out) const { out.append("}"); } #endif +void UnsubscribeBluetoothLEAdvertisementsRequest::encode(ProtoWriteBuffer buffer) const {} +#ifdef HAS_PROTO_MESSAGE_DUMP +void UnsubscribeBluetoothLEAdvertisementsRequest::dump_to(std::string &out) const { + out.append("UnsubscribeBluetoothLEAdvertisementsRequest {}"); +} +#endif bool BluetoothDeviceClearCacheResponse::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { case 1: { diff --git a/esphome/components/api/api_pb2.h b/esphome/components/api/api_pb2.h index ff581cac6f..ade9b9cc8f 100644 --- a/esphome/components/api/api_pb2.h +++ b/esphome/components/api/api_pb2.h @@ -1555,6 +1555,15 @@ class BluetoothDeviceUnpairingResponse : public ProtoMessage { protected: bool decode_varint(uint32_t field_id, ProtoVarInt value) override; }; +class UnsubscribeBluetoothLEAdvertisementsRequest : public ProtoMessage { + public: + void encode(ProtoWriteBuffer buffer) const override; +#ifdef HAS_PROTO_MESSAGE_DUMP + void dump_to(std::string &out) const override; +#endif + + protected: +}; class BluetoothDeviceClearCacheResponse : public ProtoMessage { public: uint64_t address{0}; diff --git a/esphome/components/api/api_pb2_service.cpp b/esphome/components/api/api_pb2_service.cpp index 73015fa914..e613cbcad9 100644 --- a/esphome/components/api/api_pb2_service.cpp +++ b/esphome/components/api/api_pb2_service.cpp @@ -813,6 +813,15 @@ bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type, #endif break; } + case 87: { + UnsubscribeBluetoothLEAdvertisementsRequest msg; + msg.decode(msg_data, msg_size); +#ifdef HAS_PROTO_MESSAGE_DUMP + ESP_LOGVV(TAG, "on_unsubscribe_bluetooth_le_advertisements_request: %s", msg.dump().c_str()); +#endif + this->on_unsubscribe_bluetooth_le_advertisements_request(msg); + break; + } default: return false; } @@ -1193,6 +1202,18 @@ void APIServerConnection::on_subscribe_bluetooth_connections_free_request( } } #endif +void APIServerConnection::on_unsubscribe_bluetooth_le_advertisements_request( + const UnsubscribeBluetoothLEAdvertisementsRequest &msg) { + if (!this->is_connection_setup()) { + this->on_no_setup_connection(); + return; + } + if (!this->is_authenticated()) { + this->on_unauthenticated_access(); + return; + } + this->unsubscribe_bluetooth_le_advertisements(msg); +} } // namespace api } // namespace esphome diff --git a/esphome/components/api/api_pb2_service.h b/esphome/components/api/api_pb2_service.h index 7f19292ff3..ad6696176c 100644 --- a/esphome/components/api/api_pb2_service.h +++ b/esphome/components/api/api_pb2_service.h @@ -216,6 +216,8 @@ class APIServerConnectionBase : public ProtoService { #ifdef USE_BLUETOOTH_PROXY bool send_bluetooth_device_unpairing_response(const BluetoothDeviceUnpairingResponse &msg); #endif + virtual void on_unsubscribe_bluetooth_le_advertisements_request( + const UnsubscribeBluetoothLEAdvertisementsRequest &value){}; #ifdef USE_BLUETOOTH_PROXY bool send_bluetooth_device_clear_cache_response(const BluetoothDeviceClearCacheResponse &msg); #endif @@ -296,6 +298,8 @@ class APIServerConnection : public APIServerConnectionBase { virtual BluetoothConnectionsFreeResponse subscribe_bluetooth_connections_free( const SubscribeBluetoothConnectionsFreeRequest &msg) = 0; #endif + virtual void unsubscribe_bluetooth_le_advertisements(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) = 0; + protected: void on_hello_request(const HelloRequest &msg) override; void on_connect_request(const ConnectRequest &msg) override; @@ -367,6 +371,8 @@ class APIServerConnection : public APIServerConnectionBase { #ifdef USE_BLUETOOTH_PROXY void on_subscribe_bluetooth_connections_free_request(const SubscribeBluetoothConnectionsFreeRequest &msg) override; #endif + void on_unsubscribe_bluetooth_le_advertisements_request( + const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override; }; } // namespace api From 3ac7bf3761aa050a6eec24a65a06160c88f490d1 Mon Sep 17 00:00:00 2001 From: Fabian Date: Tue, 28 Mar 2023 11:00:34 +0200 Subject: [PATCH 04/14] EntityBase: Move ObjectId to Flash (#4569) * Move EntityBase Object Id from memory to flash. * Sprinkler use common `setup_entity` method. * Remove `EntityBase` from Sprinkler. * Support for entity names set to None * change so gh PR picks up commit. --------- Co-authored-by: Your Name Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- esphome/core/entity_base.cpp | 33 ++++++++++++++++++++++++++----- esphome/core/entity_base.h | 7 ++++--- esphome/cpp_helpers.py | 5 +++++ esphome/helpers.py | 11 +++++++++++ tests/unit_tests/test_helpers.py | 34 ++++++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 8 deletions(-) diff --git a/esphome/core/entity_base.cpp b/esphome/core/entity_base.cpp index 19ab57349d..3d61e36fd1 100644 --- a/esphome/core/entity_base.cpp +++ b/esphome/core/entity_base.cpp @@ -16,7 +16,6 @@ void EntityBase::set_name(const char *name) { } else { this->has_own_name_ = true; } - this->calc_object_id_(); } // Entity Internal @@ -41,13 +40,37 @@ EntityCategory EntityBase::get_entity_category() const { return this->entity_cat void EntityBase::set_entity_category(EntityCategory entity_category) { this->entity_category_ = entity_category; } // Entity Object ID -const std::string &EntityBase::get_object_id() { return this->object_id_; } +std::string EntityBase::get_object_id() const { + // Check if `App.get_friendly_name()` is constant or dynamic. + if (!this->has_own_name_ && App.is_name_add_mac_suffix_enabled()) { + // `App.get_friendly_name()` is dynamic. + return str_sanitize(str_snake_case(App.get_friendly_name())); + } else { + // `App.get_friendly_name()` is constant. + if (this->object_id_c_str_ == nullptr) { + return ""; + } + return this->object_id_c_str_; + } +} +void EntityBase::set_object_id(const char *object_id) { + this->object_id_c_str_ = object_id; + this->calc_object_id_(); +} // Calculate Object ID Hash from Entity Name void EntityBase::calc_object_id_() { - this->object_id_ = str_sanitize(str_snake_case(this->name_)); - // FNV-1 hash - this->object_id_hash_ = fnv1_hash(this->object_id_); + // Check if `App.get_friendly_name()` is constant or dynamic. + if (!this->has_own_name_ && App.is_name_add_mac_suffix_enabled()) { + // `App.get_friendly_name()` is dynamic. + const auto object_id = str_sanitize(str_snake_case(App.get_friendly_name())); + // FNV-1 hash + this->object_id_hash_ = fnv1_hash(object_id); + } else { + // `App.get_friendly_name()` is constant. + // FNV-1 hash + this->object_id_hash_ = fnv1_hash(this->object_id_c_str_); + } } uint32_t EntityBase::get_object_id_hash() { return this->object_id_hash_; } diff --git a/esphome/core/entity_base.h b/esphome/core/entity_base.h index e25aab21a9..0a53c3fccc 100644 --- a/esphome/core/entity_base.h +++ b/esphome/core/entity_base.h @@ -22,8 +22,9 @@ class EntityBase { // Get whether this Entity has its own name or it should use the device friendly_name. bool has_own_name() const { return this->has_own_name_; } - // Get the sanitized name of this Entity as an ID. Caching it internally. - const std::string &get_object_id(); + // Get the sanitized name of this Entity as an ID. + std::string get_object_id() const; + void set_object_id(const char *object_id); // Get the unique Object ID of this Entity uint32_t get_object_id_hash(); @@ -54,7 +55,7 @@ class EntityBase { StringRef name_; bool has_own_name_{false}; - std::string object_id_; + const char *object_id_c_str_{nullptr}; const char *icon_c_str_{nullptr}; uint32_t object_id_hash_; bool internal_{false}; diff --git a/esphome/cpp_helpers.py b/esphome/cpp_helpers.py index ab5231e055..cc53f491f5 100644 --- a/esphome/cpp_helpers.py +++ b/esphome/cpp_helpers.py @@ -20,6 +20,7 @@ from esphome.types import ConfigType, ConfigFragmentType from esphome.cpp_generator import add, get_variable from esphome.cpp_types import App from esphome.util import Registry, RegistryEntry +from esphome.helpers import snake_case, sanitize _LOGGER = logging.getLogger(__name__) @@ -101,6 +102,10 @@ async def register_parented(var, value): async def setup_entity(var, config): """Set up generic properties of an Entity""" add(var.set_name(config[CONF_NAME])) + if not config[CONF_NAME]: + add(var.set_object_id(sanitize(snake_case(CORE.friendly_name)))) + else: + add(var.set_object_id(sanitize(snake_case(config[CONF_NAME])))) add(var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT])) if CONF_INTERNAL in config: add(var.set_internal(config[CONF_INTERNAL])) diff --git a/esphome/helpers.py b/esphome/helpers.py index b5a6306342..884f640d7b 100644 --- a/esphome/helpers.py +++ b/esphome/helpers.py @@ -7,6 +7,7 @@ from pathlib import Path from typing import Union import tempfile from urllib.parse import urlparse +import re _LOGGER = logging.getLogger(__name__) @@ -334,3 +335,13 @@ def add_class_to_obj(value, cls): if type(value) is type_: # pylint: disable=unidiomatic-typecheck return add_class_to_obj(func(value), cls) raise + + +def snake_case(value): + """Same behaviour as `helpers.cpp` method `str_snake_case`.""" + return value.replace(" ", "_").lower() + + +def sanitize(value): + """Same behaviour as `helpers.cpp` method `str_sanitize`.""" + return re.sub("[^-_0-9a-zA-Z]", r"", value) diff --git a/tests/unit_tests/test_helpers.py b/tests/unit_tests/test_helpers.py index f883b8b44f..b98838024f 100644 --- a/tests/unit_tests/test_helpers.py +++ b/tests/unit_tests/test_helpers.py @@ -229,3 +229,37 @@ def test_file_compare(fixture_path, file1, file2, expected): actual = helpers.file_compare(path1, path2) assert actual == expected + + +@pytest.mark.parametrize( + "text, expected", + ( + ("foo", "foo"), + ("foo bar", "foo_bar"), + ("foo Bar", "foo_bar"), + ("foo BAR", "foo_bar"), + ("foo.bar", "foo.bar"), + ("fooBAR", "foobar"), + ("Foo-bar_EEK", "foo-bar_eek"), + (" foo", "__foo"), + ), +) +def test_snake_case(text, expected): + actual = helpers.snake_case(text) + + assert actual == expected + + +@pytest.mark.parametrize( + "text, expected", + ( + ("foo_bar", "foo_bar"), + ('!"§$%&/()=?foo_bar', "foo_bar"), + ('foo_!"§$%&/()=?bar', "foo_bar"), + ('foo_bar!"§$%&/()=?', "foo_bar"), + ), +) +def test_sanitize(text, expected): + actual = helpers.sanitize(text) + + assert actual == expected From a2931b6774a141462b92b78bbf1e1294dd422cf5 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Wed, 29 Mar 2023 12:31:07 +1300 Subject: [PATCH 05/14] Add workflow to sync device classes with HA dev (#4629) --- .github/workflows/sync-device-classes.yml | 60 +++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 .github/workflows/sync-device-classes.yml diff --git a/.github/workflows/sync-device-classes.yml b/.github/workflows/sync-device-classes.yml new file mode 100644 index 0000000000..82eead332e --- /dev/null +++ b/.github/workflows/sync-device-classes.yml @@ -0,0 +1,60 @@ +--- +name: Synchronise Device Classes from Home Assistant + +on: + workflow_dispatch: + schedule: + - cron: '45 6 * * *' + +permissions: + contents: write + pull-requests: write + +jobs: + sync: + name: Sync Device Classes + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Checkout Home Assistant + uses: actions/checkout@v3 + with: + repository: home-assistant/core + path: home-assistant + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: 3.11 + + - name: Install Home Assistant + run: | + python -m pip install --upgrade pip + pip install -e home-assistant + + - name: Sync + run: | + python ./script/sync-device_class.py + + - name: Get PR template + id: pr-template-body + run: | + body=$(cat .github/PULL_REQUEST_TEMPLATE.md) + delimiter="$(openssl rand -hex 8)" + echo "body<<$delimiter" >> $GITHUB_OUTPUT + echo "$body" >> $GITHUB_OUTPUT + echo "$delimiter" >> $GITHUB_OUTPUT + + - name: Commit changes + uses: peter-evans/create-pull-request@v4 + with: + commit-message: "Synchronise Device Classes from Home Assistant" + committer: esphomebot + author: esphomebot + branch: sync/device-classes/ + branch-suffix: timestamp + delete-branch: true + title: "Synchronise Device Classes from Home Assistant" + body: ${{ steps.pr-template-body.outputs.body }} From c4ddf7697d36fe25eefa9458e1e329a0d1f48f54 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Wed, 29 Mar 2023 14:02:34 +1300 Subject: [PATCH 06/14] Update sync-device-classes.yml --- .github/workflows/sync-device-classes.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sync-device-classes.yml b/.github/workflows/sync-device-classes.yml index 82eead332e..671fe1f21a 100644 --- a/.github/workflows/sync-device-classes.yml +++ b/.github/workflows/sync-device-classes.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@v3 with: repository: home-assistant/core - path: home-assistant + path: lib/home-assistant - name: Setup Python uses: actions/setup-python@v4 @@ -32,7 +32,7 @@ jobs: - name: Install Home Assistant run: | python -m pip install --upgrade pip - pip install -e home-assistant + pip install -e lib/home-assistant - name: Sync run: | From a014d853a41c01e095390ec0351714c94a66c105 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 29 Mar 2023 15:47:00 +1300 Subject: [PATCH 07/14] Synchronise Device Classes from Home Assistant (#4633) * Synchronise Device Classes from Home Assistant * Remove count do the `DEVICE_CLASSES` list is also updated * Format file --------- Co-authored-by: esphomebot Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- esphome/components/number/__init__.py | 4 ++++ esphome/components/sensor/__init__.py | 4 ++++ esphome/const.py | 2 ++ script/sync-device_class.py | 8 ++++---- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/esphome/components/number/__init__.py b/esphome/components/number/__init__.py index 7db973612b..7dce625389 100644 --- a/esphome/components/number/__init__.py +++ b/esphome/components/number/__init__.py @@ -31,6 +31,7 @@ from esphome.const import ( DEVICE_CLASS_DISTANCE, DEVICE_CLASS_EMPTY, DEVICE_CLASS_ENERGY, + DEVICE_CLASS_ENERGY_STORAGE, DEVICE_CLASS_FREQUENCY, DEVICE_CLASS_GAS, DEVICE_CLASS_HUMIDITY, @@ -59,6 +60,7 @@ from esphome.const import ( DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS, DEVICE_CLASS_VOLTAGE, DEVICE_CLASS_VOLUME, + DEVICE_CLASS_VOLUME_STORAGE, DEVICE_CLASS_WATER, DEVICE_CLASS_WEIGHT, DEVICE_CLASS_WIND_SPEED, @@ -81,6 +83,7 @@ DEVICE_CLASSES = [ DEVICE_CLASS_DISTANCE, DEVICE_CLASS_EMPTY, DEVICE_CLASS_ENERGY, + DEVICE_CLASS_ENERGY_STORAGE, DEVICE_CLASS_FREQUENCY, DEVICE_CLASS_GAS, DEVICE_CLASS_HUMIDITY, @@ -109,6 +112,7 @@ DEVICE_CLASSES = [ DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS, DEVICE_CLASS_VOLTAGE, DEVICE_CLASS_VOLUME, + DEVICE_CLASS_VOLUME_STORAGE, DEVICE_CLASS_WATER, DEVICE_CLASS_WEIGHT, DEVICE_CLASS_WIND_SPEED, diff --git a/esphome/components/sensor/__init__.py b/esphome/components/sensor/__init__.py index b63e157efb..ac25884697 100644 --- a/esphome/components/sensor/__init__.py +++ b/esphome/components/sensor/__init__.py @@ -43,6 +43,7 @@ from esphome.const import ( DEVICE_CLASS_DURATION, DEVICE_CLASS_EMPTY, DEVICE_CLASS_ENERGY, + DEVICE_CLASS_ENERGY_STORAGE, DEVICE_CLASS_FREQUENCY, DEVICE_CLASS_GAS, DEVICE_CLASS_HUMIDITY, @@ -72,6 +73,7 @@ from esphome.const import ( DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS, DEVICE_CLASS_VOLTAGE, DEVICE_CLASS_VOLUME, + DEVICE_CLASS_VOLUME_STORAGE, DEVICE_CLASS_WATER, DEVICE_CLASS_WEIGHT, DEVICE_CLASS_WIND_SPEED, @@ -97,6 +99,7 @@ DEVICE_CLASSES = [ DEVICE_CLASS_DURATION, DEVICE_CLASS_EMPTY, DEVICE_CLASS_ENERGY, + DEVICE_CLASS_ENERGY_STORAGE, DEVICE_CLASS_FREQUENCY, DEVICE_CLASS_GAS, DEVICE_CLASS_HUMIDITY, @@ -126,6 +129,7 @@ DEVICE_CLASSES = [ DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS, DEVICE_CLASS_VOLTAGE, DEVICE_CLASS_VOLUME, + DEVICE_CLASS_VOLUME_STORAGE, DEVICE_CLASS_WATER, DEVICE_CLASS_WEIGHT, DEVICE_CLASS_WIND_SPEED, diff --git a/esphome/const.py b/esphome/const.py index 7b2fdfc3a4..f627b5abd4 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -946,6 +946,7 @@ DEVICE_CLASS_DOOR = "door" DEVICE_CLASS_DURATION = "duration" DEVICE_CLASS_EMPTY = "" DEVICE_CLASS_ENERGY = "energy" +DEVICE_CLASS_ENERGY_STORAGE = "energy_storage" DEVICE_CLASS_FREQUENCY = "frequency" DEVICE_CLASS_GARAGE = "garage" DEVICE_CLASS_GARAGE_DOOR = "garage_door" @@ -1000,6 +1001,7 @@ DEVICE_CLASS_VIBRATION = "vibration" DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS = "volatile_organic_compounds" DEVICE_CLASS_VOLTAGE = "voltage" DEVICE_CLASS_VOLUME = "volume" +DEVICE_CLASS_VOLUME_STORAGE = "volume_storage" DEVICE_CLASS_WATER = "water" DEVICE_CLASS_WEIGHT = "weight" DEVICE_CLASS_WINDOW = "window" diff --git a/script/sync-device_class.py b/script/sync-device_class.py index 882655561b..ae6f4be0c8 100755 --- a/script/sync-device_class.py +++ b/script/sync-device_class.py @@ -25,9 +25,9 @@ DOMAINS = { def sub(path, pattern, repl): - with open(path, "r") as handle: + with open(path) as handle: content = handle.read() - content = re.sub(pattern, repl, content, flags=re.MULTILINE, count=1) + content = re.sub(pattern, repl, content, flags=re.MULTILINE) with open(path, "w") as handle: handle.write(content) @@ -48,7 +48,7 @@ def main(): out = "" for cls in sorted(classes): out += f'DEVICE_CLASS_{cls.upper()} = "{classes[cls]}"\n' - sub("esphome/const.py", '(DEVICE_CLASS_\w+ = "\w*"\r?\n)+', out) + sub("esphome/const.py", '(DEVICE_CLASS_\\w+ = "\\w*"\r?\n)+', out) for domain in sorted(allowed): # replace imports @@ -58,7 +58,7 @@ def main(): sub( f"esphome/components/{domain}/__init__.py", - "( DEVICE_CLASS_\w+,\r?\n)+", + "( DEVICE_CLASS_\\w+,\r?\n)+", out, ) From b5d0aede381d21ea6683575603805a56fddaf1a8 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Thu, 30 Mar 2023 14:08:31 +1300 Subject: [PATCH 08/14] Remove AUTO_LOAD from as3935 (#4630) --- esphome/components/as3935/__init__.py | 1 - esphome/components/as3935/as3935.cpp | 14 ++++++++++++-- esphome/components/as3935/as3935.h | 23 +++++++++++++++-------- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/esphome/components/as3935/__init__.py b/esphome/components/as3935/__init__.py index 0951d01e68..cf0580ca62 100644 --- a/esphome/components/as3935/__init__.py +++ b/esphome/components/as3935/__init__.py @@ -12,7 +12,6 @@ from esphome.const import ( CONF_CAPACITANCE, ) -AUTO_LOAD = ["sensor", "binary_sensor"] MULTI_CONF = True CONF_AS3935_ID = "as3935_id" diff --git a/esphome/components/as3935/as3935.cpp b/esphome/components/as3935/as3935.cpp index b36856218a..c5651caee3 100644 --- a/esphome/components/as3935/as3935.cpp +++ b/esphome/components/as3935/as3935.cpp @@ -26,9 +26,13 @@ void AS3935Component::setup() { void AS3935Component::dump_config() { ESP_LOGCONFIG(TAG, "AS3935:"); LOG_PIN(" Interrupt Pin: ", this->irq_pin_); +#ifdef USE_BINARY_SENSOR LOG_BINARY_SENSOR(" ", "Thunder alert", this->thunder_alert_binary_sensor_); +#endif +#ifdef USE_SENSOR LOG_SENSOR(" ", "Distance", this->distance_sensor_); LOG_SENSOR(" ", "Lightning energy", this->energy_sensor_); +#endif } float AS3935Component::get_setup_priority() const { return setup_priority::DATA; } @@ -44,16 +48,22 @@ void AS3935Component::loop() { ESP_LOGI(TAG, "Disturber was detected - try increasing the spike rejection value!"); } else if (int_value == LIGHTNING_INT) { ESP_LOGI(TAG, "Lightning has been detected!"); - if (this->thunder_alert_binary_sensor_ != nullptr) +#ifdef USE_BINARY_SENSOR + if (this->thunder_alert_binary_sensor_ != nullptr) { this->thunder_alert_binary_sensor_->publish_state(true); + this->set_timeout(10, [this]() { this->thunder_alert_binary_sensor_->publish_state(false); }); + } +#endif +#ifdef USE_SENSOR uint8_t distance = this->get_distance_to_storm_(); if (this->distance_sensor_ != nullptr) this->distance_sensor_->publish_state(distance); + uint32_t energy = this->get_lightning_energy_(); if (this->energy_sensor_ != nullptr) this->energy_sensor_->publish_state(energy); +#endif } - this->thunder_alert_binary_sensor_->publish_state(false); } void AS3935Component::write_indoor(bool indoor) { diff --git a/esphome/components/as3935/as3935.h b/esphome/components/as3935/as3935.h index 2cba9b11a0..a8af703a59 100644 --- a/esphome/components/as3935/as3935.h +++ b/esphome/components/as3935/as3935.h @@ -1,9 +1,14 @@ #pragma once #include "esphome/core/component.h" +#include "esphome/core/defines.h" #include "esphome/core/hal.h" +#ifdef USE_SENSOR #include "esphome/components/sensor/sensor.h" +#endif +#ifdef USE_BINARY_SENSOR #include "esphome/components/binary_sensor/binary_sensor.h" +#endif namespace esphome { namespace as3935 { @@ -52,6 +57,15 @@ enum AS3935Values { }; class AS3935Component : public Component { +#ifdef USE_SENSOR + SUB_SENSOR(distance) + SUB_SENSOR(energy) +#endif + +#ifdef USE_BINARY_SENSOR + SUB_BINARY_SENSOR(thunder_alert) +#endif + public: void setup() override; void dump_config() override; @@ -59,11 +73,7 @@ class AS3935Component : public Component { void loop() override; void set_irq_pin(GPIOPin *irq_pin) { irq_pin_ = irq_pin; } - void set_distance_sensor(sensor::Sensor *distance_sensor) { distance_sensor_ = distance_sensor; } - void set_energy_sensor(sensor::Sensor *energy_sensor) { energy_sensor_ = energy_sensor; } - void set_thunder_alert_binary_sensor(binary_sensor::BinarySensor *thunder_alert_binary_sensor) { - thunder_alert_binary_sensor_ = thunder_alert_binary_sensor; - } + void set_indoor(bool indoor) { indoor_ = indoor; } void write_indoor(bool indoor); void set_noise_level(uint8_t noise_level) { noise_level_ = noise_level; } @@ -92,9 +102,6 @@ class AS3935Component : public Component { virtual void write_register(uint8_t reg, uint8_t mask, uint8_t bits, uint8_t start_position) = 0; - sensor::Sensor *distance_sensor_{nullptr}; - sensor::Sensor *energy_sensor_{nullptr}; - binary_sensor::BinarySensor *thunder_alert_binary_sensor_{nullptr}; GPIOPin *irq_pin_; bool indoor_; From a546ffd490d067225b5982e809ff424a54bf3b1d Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Thu, 30 Mar 2023 14:08:51 +1300 Subject: [PATCH 09/14] Add ifdef to new bt proxy unsubscribe (#4634) * Add ifdef to new bt proxy unsubscribe * Also add to subscribe message and wrap api conneciton code * Format file --- esphome/components/api/api.proto | 2 ++ esphome/components/api/api_connection.h | 15 +++++++++------ esphome/components/api/api_pb2_service.cpp | 12 ++++++++++++ esphome/components/api/api_pb2_service.h | 13 ++++++++++++- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/esphome/components/api/api.proto b/esphome/components/api/api.proto index fd00317282..e36f0581ca 100644 --- a/esphome/components/api/api.proto +++ b/esphome/components/api/api.proto @@ -1127,6 +1127,7 @@ message MediaPlayerCommandRequest { message SubscribeBluetoothLEAdvertisementsRequest { option (id) = 66; option (source) = SOURCE_CLIENT; + option (ifdef) = "USE_BLUETOOTH_PROXY"; } message BluetoothServiceData { @@ -1366,6 +1367,7 @@ message BluetoothDeviceUnpairingResponse { message UnsubscribeBluetoothLEAdvertisementsRequest { option (id) = 87; option (source) = SOURCE_CLIENT; + option (ifdef) = "USE_BLUETOOTH_PROXY"; } message BluetoothDeviceClearCacheResponse { diff --git a/esphome/components/api/api_connection.h b/esphome/components/api/api_connection.h index bc6ae5d7c3..c85c69a2b9 100644 --- a/esphome/components/api/api_connection.h +++ b/esphome/components/api/api_connection.h @@ -97,6 +97,12 @@ class APIConnection : public APIServerConnection { this->send_homeassistant_service_response(call); } #ifdef USE_BLUETOOTH_PROXY + void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) override { + this->bluetooth_le_advertisement_subscription_ = true; + } + void unsubscribe_bluetooth_le_advertisements(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override { + this->bluetooth_le_advertisement_subscription_ = false; + } bool send_bluetooth_le_advertisement(const BluetoothLEAdvertisementResponse &msg); void bluetooth_device_request(const BluetoothDeviceRequest &msg) override; @@ -150,12 +156,7 @@ class APIConnection : public APIServerConnection { return {}; } void execute_service(const ExecuteServiceRequest &msg) override; - void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) override { - this->bluetooth_le_advertisement_subscription_ = true; - } - void unsubscribe_bluetooth_le_advertisements(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override { - this->bluetooth_le_advertisement_subscription_ = false; - } + bool is_authenticated() override { return this->connection_state_ == ConnectionState::AUTHENTICATED; } bool is_connection_setup() override { return this->connection_state_ == ConnectionState ::CONNECTED || this->is_authenticated(); @@ -200,7 +201,9 @@ class APIConnection : public APIServerConnection { uint32_t last_traffic_; bool sent_ping_{false}; bool service_call_subscription_{false}; +#ifdef USE_BLUETOOTH_PROXY bool bluetooth_le_advertisement_subscription_{false}; +#endif bool next_close_ = false; APIServer *parent_; InitialStateIterator initial_state_iterator_; diff --git a/esphome/components/api/api_pb2_service.cpp b/esphome/components/api/api_pb2_service.cpp index e613cbcad9..7d019e1d3d 100644 --- a/esphome/components/api/api_pb2_service.cpp +++ b/esphome/components/api/api_pb2_service.cpp @@ -329,6 +329,8 @@ bool APIServerConnectionBase::send_media_player_state_response(const MediaPlayer #ifdef USE_MEDIA_PLAYER #endif #ifdef USE_BLUETOOTH_PROXY +#endif +#ifdef USE_BLUETOOTH_PROXY bool APIServerConnectionBase::send_bluetooth_le_advertisement_response(const BluetoothLEAdvertisementResponse &msg) { #ifdef HAS_PROTO_MESSAGE_DUMP ESP_LOGVV(TAG, "send_bluetooth_le_advertisement_response: %s", msg.dump().c_str()); @@ -442,6 +444,8 @@ bool APIServerConnectionBase::send_bluetooth_device_unpairing_response(const Blu } #endif #ifdef USE_BLUETOOTH_PROXY +#endif +#ifdef USE_BLUETOOTH_PROXY bool APIServerConnectionBase::send_bluetooth_device_clear_cache_response(const BluetoothDeviceClearCacheResponse &msg) { #ifdef HAS_PROTO_MESSAGE_DUMP ESP_LOGVV(TAG, "send_bluetooth_device_clear_cache_response: %s", msg.dump().c_str()); @@ -717,12 +721,14 @@ bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type, break; } case 66: { +#ifdef USE_BLUETOOTH_PROXY SubscribeBluetoothLEAdvertisementsRequest msg; msg.decode(msg_data, msg_size); #ifdef HAS_PROTO_MESSAGE_DUMP ESP_LOGVV(TAG, "on_subscribe_bluetooth_le_advertisements_request: %s", msg.dump().c_str()); #endif this->on_subscribe_bluetooth_le_advertisements_request(msg); +#endif break; } case 68: { @@ -814,12 +820,14 @@ bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type, break; } case 87: { +#ifdef USE_BLUETOOTH_PROXY UnsubscribeBluetoothLEAdvertisementsRequest msg; msg.decode(msg_data, msg_size); #ifdef HAS_PROTO_MESSAGE_DUMP ESP_LOGVV(TAG, "on_unsubscribe_bluetooth_le_advertisements_request: %s", msg.dump().c_str()); #endif this->on_unsubscribe_bluetooth_le_advertisements_request(msg); +#endif break; } default: @@ -1082,6 +1090,7 @@ void APIServerConnection::on_media_player_command_request(const MediaPlayerComma this->media_player_command(msg); } #endif +#ifdef USE_BLUETOOTH_PROXY void APIServerConnection::on_subscribe_bluetooth_le_advertisements_request( const SubscribeBluetoothLEAdvertisementsRequest &msg) { if (!this->is_connection_setup()) { @@ -1094,6 +1103,7 @@ void APIServerConnection::on_subscribe_bluetooth_le_advertisements_request( } this->subscribe_bluetooth_le_advertisements(msg); } +#endif #ifdef USE_BLUETOOTH_PROXY void APIServerConnection::on_bluetooth_device_request(const BluetoothDeviceRequest &msg) { if (!this->is_connection_setup()) { @@ -1202,6 +1212,7 @@ void APIServerConnection::on_subscribe_bluetooth_connections_free_request( } } #endif +#ifdef USE_BLUETOOTH_PROXY void APIServerConnection::on_unsubscribe_bluetooth_le_advertisements_request( const UnsubscribeBluetoothLEAdvertisementsRequest &msg) { if (!this->is_connection_setup()) { @@ -1214,6 +1225,7 @@ void APIServerConnection::on_unsubscribe_bluetooth_le_advertisements_request( } this->unsubscribe_bluetooth_le_advertisements(msg); } +#endif } // namespace api } // namespace esphome diff --git a/esphome/components/api/api_pb2_service.h b/esphome/components/api/api_pb2_service.h index ad6696176c..457a3d28a9 100644 --- a/esphome/components/api/api_pb2_service.h +++ b/esphome/components/api/api_pb2_service.h @@ -154,8 +154,10 @@ class APIServerConnectionBase : public ProtoService { #ifdef USE_MEDIA_PLAYER virtual void on_media_player_command_request(const MediaPlayerCommandRequest &value){}; #endif +#ifdef USE_BLUETOOTH_PROXY virtual void on_subscribe_bluetooth_le_advertisements_request( const SubscribeBluetoothLEAdvertisementsRequest &value){}; +#endif #ifdef USE_BLUETOOTH_PROXY bool send_bluetooth_le_advertisement_response(const BluetoothLEAdvertisementResponse &msg); #endif @@ -216,8 +218,10 @@ class APIServerConnectionBase : public ProtoService { #ifdef USE_BLUETOOTH_PROXY bool send_bluetooth_device_unpairing_response(const BluetoothDeviceUnpairingResponse &msg); #endif +#ifdef USE_BLUETOOTH_PROXY virtual void on_unsubscribe_bluetooth_le_advertisements_request( const UnsubscribeBluetoothLEAdvertisementsRequest &value){}; +#endif #ifdef USE_BLUETOOTH_PROXY bool send_bluetooth_device_clear_cache_response(const BluetoothDeviceClearCacheResponse &msg); #endif @@ -272,7 +276,9 @@ class APIServerConnection : public APIServerConnectionBase { #ifdef USE_MEDIA_PLAYER virtual void media_player_command(const MediaPlayerCommandRequest &msg) = 0; #endif +#ifdef USE_BLUETOOTH_PROXY virtual void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) = 0; +#endif #ifdef USE_BLUETOOTH_PROXY virtual void bluetooth_device_request(const BluetoothDeviceRequest &msg) = 0; #endif @@ -298,8 +304,9 @@ class APIServerConnection : public APIServerConnectionBase { virtual BluetoothConnectionsFreeResponse subscribe_bluetooth_connections_free( const SubscribeBluetoothConnectionsFreeRequest &msg) = 0; #endif +#ifdef USE_BLUETOOTH_PROXY virtual void unsubscribe_bluetooth_le_advertisements(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) = 0; - +#endif protected: void on_hello_request(const HelloRequest &msg) override; void on_connect_request(const ConnectRequest &msg) override; @@ -346,7 +353,9 @@ class APIServerConnection : public APIServerConnectionBase { #ifdef USE_MEDIA_PLAYER void on_media_player_command_request(const MediaPlayerCommandRequest &msg) override; #endif +#ifdef USE_BLUETOOTH_PROXY void on_subscribe_bluetooth_le_advertisements_request(const SubscribeBluetoothLEAdvertisementsRequest &msg) override; +#endif #ifdef USE_BLUETOOTH_PROXY void on_bluetooth_device_request(const BluetoothDeviceRequest &msg) override; #endif @@ -371,8 +380,10 @@ class APIServerConnection : public APIServerConnectionBase { #ifdef USE_BLUETOOTH_PROXY void on_subscribe_bluetooth_connections_free_request(const SubscribeBluetoothConnectionsFreeRequest &msg) override; #endif +#ifdef USE_BLUETOOTH_PROXY void on_unsubscribe_bluetooth_le_advertisements_request( const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override; +#endif }; } // namespace api From 616e0a21d8929672dba62472db3e57089f34f762 Mon Sep 17 00:00:00 2001 From: felixlungu Date: Thu, 30 Mar 2023 04:12:06 +0300 Subject: [PATCH 10/14] add bluetooth mac address in dump_config() (#4628) * add bluetooth mac address in dump_config() * Update ble.cpp * Update ble.cpp * Update ble.cpp * Update ble.cpp * Update ble.cpp * Update ble.cpp * Update ble.cpp --- esphome/components/esp32_ble/ble.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/esphome/components/esp32_ble/ble.cpp b/esphome/components/esp32_ble/ble.cpp index 160084b913..502399f97a 100644 --- a/esphome/components/esp32_ble/ble.cpp +++ b/esphome/components/esp32_ble/ble.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -211,7 +212,16 @@ void ESP32BLE::real_gattc_event_handler_(esp_gattc_cb_event_t event, esp_gatt_if float ESP32BLE::get_setup_priority() const { return setup_priority::BLUETOOTH; } -void ESP32BLE::dump_config() { ESP_LOGCONFIG(TAG, "ESP32 BLE:"); } +void ESP32BLE::dump_config() { + const uint8_t *mac_address = esp_bt_dev_get_address(); + if (mac_address) { + ESP_LOGCONFIG(TAG, "ESP32 BLE:"); + ESP_LOGCONFIG(TAG, " MAC address: %02X:%02X:%02X:%02X:%02X:%02X", mac_address[0], mac_address[1], mac_address[2], + mac_address[3], mac_address[4], mac_address[5]); + } else { + ESP_LOGCONFIG(TAG, "ESP32 BLE: bluetooth stack is not enabled"); + } +} ESP32BLE *global_ble = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) From 28534ecc61852068727e8c081b0afabbf888b62f Mon Sep 17 00:00:00 2001 From: kahrendt Date: Fri, 31 Mar 2023 00:27:24 -0400 Subject: [PATCH 11/14] Binary map bugfixes (#4636) * limit configuration to 64 binary sensors to match code limitation * remove superfluous debug logging * improve state publishing logic eliminating NAN being sent on boot in certain cases * adjust type for bitmask shift to match mask variable type --- .../binary_sensor_map/binary_sensor_map.cpp | 29 +++++++------------ .../components/binary_sensor_map/sensor.py | 4 +-- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/esphome/components/binary_sensor_map/binary_sensor_map.cpp b/esphome/components/binary_sensor_map/binary_sensor_map.cpp index b2dffaf74d..3934e0a99c 100644 --- a/esphome/components/binary_sensor_map/binary_sensor_map.cpp +++ b/esphome/components/binary_sensor_map/binary_sensor_map.cpp @@ -30,7 +30,7 @@ void BinarySensorMap::process_group_() { if (bs.binary_sensor->state) { num_active_sensors++; total_current_value += bs.sensor_value; - mask |= 1 << i; + mask |= 1ULL << i; } } // check if the sensor map was touched @@ -38,12 +38,11 @@ void BinarySensorMap::process_group_() { // did the bit_mask change or is it a new sensor touch if (this->last_mask_ != mask) { float publish_value = total_current_value / num_active_sensors; - ESP_LOGD(TAG, "'%s' - Publishing %.2f", this->name_.c_str(), publish_value); this->publish_state(publish_value); } } else if (this->last_mask_ != 0ULL) { // is this a new sensor release - ESP_LOGD(TAG, "'%s' - No binary sensor active, publishing NAN", this->name_.c_str()); + ESP_LOGV(TAG, "'%s' - No binary sensor active, publishing NAN", this->name_.c_str()); this->publish_state(NAN); } this->last_mask_ = mask; @@ -52,28 +51,22 @@ void BinarySensorMap::process_group_() { void BinarySensorMap::process_sum_() { float total_current_value = 0.0; uint64_t mask = 0x00; - // check all binary_sensors for its state. when active add its value to total_current_value. - // create a bitmask for the binary_sensor status on all channels + // - check all binary_sensor states + // - if active, add its value to total_current_value + // - creates a bitmask for the binary_sensor status on all channels for (size_t i = 0; i < this->channels_.size(); i++) { auto bs = this->channels_[i]; if (bs.binary_sensor->state) { total_current_value += bs.sensor_value; - mask |= 1 << i; + mask |= 1ULL << i; } } - // check if the sensor map was touched - if (mask != 0ULL) { - // did the bit_mask change or is it a new sensor touch - if (this->last_mask_ != mask) { - float publish_value = total_current_value; - ESP_LOGD(TAG, "'%s' - Publishing %.2f", this->name_.c_str(), publish_value); - this->publish_state(publish_value); - } - } else if (this->last_mask_ != 0ULL) { - // is this a new sensor release - ESP_LOGD(TAG, "'%s' - No binary sensor active, publishing 0", this->name_.c_str()); - this->publish_state(0.0); + + // update state only if the binary sensor states have changed or if no state has ever been sent on boot + if ((this->last_mask_ != mask) || (!this->has_state())) { + this->publish_state(total_current_value); } + this->last_mask_ = mask; } diff --git a/esphome/components/binary_sensor_map/sensor.py b/esphome/components/binary_sensor_map/sensor.py index 025be490cd..573cce9223 100644 --- a/esphome/components/binary_sensor_map/sensor.py +++ b/esphome/components/binary_sensor_map/sensor.py @@ -39,7 +39,7 @@ CONFIG_SCHEMA = cv.typed_schema( ).extend( { cv.Required(CONF_CHANNELS): cv.All( - cv.ensure_list(entry), cv.Length(min=1) + cv.ensure_list(entry), cv.Length(min=1, max=64) ), } ), @@ -50,7 +50,7 @@ CONFIG_SCHEMA = cv.typed_schema( ).extend( { cv.Required(CONF_CHANNELS): cv.All( - cv.ensure_list(entry), cv.Length(min=1) + cv.ensure_list(entry), cv.Length(min=1, max=64) ), } ), From 4faa9d109eec8d13cac74f32926237b0087d839a Mon Sep 17 00:00:00 2001 From: Fabian Date: Fri, 31 Mar 2023 06:28:49 +0200 Subject: [PATCH 12/14] entity_base avoid padding bytes. (#4637) Co-authored-by: Your Name --- esphome/core/entity_base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/core/entity_base.h b/esphome/core/entity_base.h index 0a53c3fccc..e40a7013bf 100644 --- a/esphome/core/entity_base.h +++ b/esphome/core/entity_base.h @@ -54,10 +54,10 @@ class EntityBase { void calc_object_id_(); StringRef name_; - bool has_own_name_{false}; const char *object_id_c_str_{nullptr}; const char *icon_c_str_{nullptr}; uint32_t object_id_hash_; + bool has_own_name_{false}; bool internal_{false}; bool disabled_by_default_{false}; EntityCategory entity_category_{ENTITY_CATEGORY_NONE}; From 79f861f012c7b68e531124411e474081d3491fd8 Mon Sep 17 00:00:00 2001 From: Fabian Date: Fri, 31 Mar 2023 06:29:17 +0200 Subject: [PATCH 13/14] Avoid sensor padding. (#4638) Co-authored-by: Your Name --- esphome/components/sensor/sensor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/sensor/sensor.h b/esphome/components/sensor/sensor.h index 4308eafb12..efcada1411 100644 --- a/esphome/components/sensor/sensor.h +++ b/esphome/components/sensor/sensor.h @@ -161,7 +161,6 @@ class Sensor : public EntityBase { CallbackManager raw_callback_; ///< Storage for raw state callbacks. CallbackManager callback_; ///< Storage for filtered state callbacks. - bool has_state_{false}; Filter *filter_list_{nullptr}; ///< Store all active filters. optional unit_of_measurement_; ///< Unit of measurement override @@ -169,6 +168,7 @@ class Sensor : public EntityBase { optional device_class_; ///< Device class override optional state_class_{STATE_CLASS_NONE}; ///< State class override bool force_update_{false}; ///< Force update mode + bool has_state_{false}; }; } // namespace sensor From 9922eb83e2851f23992d021ae59adba5d56d73d7 Mon Sep 17 00:00:00 2001 From: Fabian Date: Fri, 31 Mar 2023 06:30:24 +0200 Subject: [PATCH 14/14] Support advanced UART customization (#4465) * Add methods to get hardware uart details. * Fix `setRxBufferSize` error. --------- Co-authored-by: Your Name --- esphome/components/uart/uart_component_esp32_arduino.cpp | 2 +- esphome/components/uart/uart_component_esp32_arduino.h | 3 +++ esphome/components/uart/uart_component_esp_idf.cpp | 7 ++++++- esphome/components/uart/uart_component_esp_idf.h | 4 ++++ esphome/components/uart/uart_component_rp2040.h | 3 +++ 5 files changed, 17 insertions(+), 2 deletions(-) diff --git a/esphome/components/uart/uart_component_esp32_arduino.cpp b/esphome/components/uart/uart_component_esp32_arduino.cpp index 402e41e0b5..8bbbc1a650 100644 --- a/esphome/components/uart/uart_component_esp32_arduino.cpp +++ b/esphome/components/uart/uart_component_esp32_arduino.cpp @@ -100,8 +100,8 @@ void ESP32ArduinoUARTComponent::setup() { invert = true; if (rx_pin_ != nullptr && rx_pin_->is_inverted()) invert = true; - this->hw_serial_->begin(this->baud_rate_, get_config(), rx, tx, invert); this->hw_serial_->setRxBufferSize(this->rx_buffer_size_); + this->hw_serial_->begin(this->baud_rate_, get_config(), rx, tx, invert); } void ESP32ArduinoUARTComponent::dump_config() { diff --git a/esphome/components/uart/uart_component_esp32_arduino.h b/esphome/components/uart/uart_component_esp32_arduino.h index 4a000b12d2..f85c709097 100644 --- a/esphome/components/uart/uart_component_esp32_arduino.h +++ b/esphome/components/uart/uart_component_esp32_arduino.h @@ -28,6 +28,9 @@ class ESP32ArduinoUARTComponent : public UARTComponent, public Component { uint32_t get_config(); + HardwareSerial *get_hw_serial() { return this->hw_serial_; } + uint8_t get_hw_serial_number() { return this->number_; } + protected: void check_logger_conflict() override; diff --git a/esphome/components/uart/uart_component_esp_idf.cpp b/esphome/components/uart/uart_component_esp_idf.cpp index 80255ccddf..1560409772 100644 --- a/esphome/components/uart/uart_component_esp_idf.cpp +++ b/esphome/components/uart/uart_component_esp_idf.cpp @@ -79,7 +79,12 @@ void IDFUARTComponent::setup() { return; } - err = uart_driver_install(this->uart_num_, this->rx_buffer_size_, 0, 0, nullptr, 0); + err = uart_driver_install(this->uart_num_, /* UART RX ring buffer size. */ this->rx_buffer_size_, + /* UART TX ring buffer size. If set to zero, driver will not use TX buffer, TX function will + block task until all data have been sent out.*/ + 0, + /* UART event queue size/depth. */ 20, &(this->uart_event_queue_), + /* Flags used to allocate the interrupt. */ 0); if (err != ESP_OK) { ESP_LOGW(TAG, "uart_driver_install failed: %s", esp_err_to_name(err)); this->mark_failed(); diff --git a/esphome/components/uart/uart_component_esp_idf.h b/esphome/components/uart/uart_component_esp_idf.h index 27fb80d2cc..fdaa4da9a7 100644 --- a/esphome/components/uart/uart_component_esp_idf.h +++ b/esphome/components/uart/uart_component_esp_idf.h @@ -23,9 +23,13 @@ class IDFUARTComponent : public UARTComponent, public Component { int available() override; void flush() override; + uint8_t get_hw_serial_number() { return this->uart_num_; } + QueueHandle_t *get_uart_event_queue() { return &this->uart_event_queue_; } + protected: void check_logger_conflict() override; uart_port_t uart_num_; + QueueHandle_t uart_event_queue_; uart_config_t get_config_(); SemaphoreHandle_t lock_; diff --git a/esphome/components/uart/uart_component_rp2040.h b/esphome/components/uart/uart_component_rp2040.h index 163315dee7..f26c913cff 100644 --- a/esphome/components/uart/uart_component_rp2040.h +++ b/esphome/components/uart/uart_component_rp2040.h @@ -30,6 +30,9 @@ class RP2040UartComponent : public UARTComponent, public Component { uint16_t get_config(); + bool is_hw_serial() { return this->hw_serial_; } + HardwareSerial *get_hw_serial() { return this->serial_; } + protected: void check_logger_conflict() override {} bool hw_serial_{false};