mirror of
https://github.com/esphome/esphome.git
synced 2026-02-25 04:45:29 -07:00
reset
This commit is contained in:
@@ -425,7 +425,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 [(container_pointer) = "FixedVector"];
|
||||
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
|
||||
|
||||
@@ -423,8 +423,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();
|
||||
if (traits.supports_preset_modes())
|
||||
msg.supported_preset_modes = &traits.supported_preset_modes();
|
||||
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) {
|
||||
|
||||
@@ -725,7 +725,7 @@ class ListEntitiesFanResponse final : public InfoResponseProtoMessage {
|
||||
bool supports_speed{false};
|
||||
bool supports_direction{false};
|
||||
int32_t supported_speed_count{0};
|
||||
const FixedVector<std::string> *supported_preset_modes{};
|
||||
const std::set<std::string> *supported_preset_modes{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
|
||||
@@ -35,17 +35,7 @@ fan::FanTraits CopyFan::get_traits() {
|
||||
traits.set_speed(base.supports_speed());
|
||||
traits.set_supported_speed_count(base.supported_speed_count());
|
||||
traits.set_direction(base.supports_direction());
|
||||
|
||||
// Copy preset modes from source to avoid dangling pointer to temporary
|
||||
if (base.supports_preset_modes()) {
|
||||
const auto &source_modes = base.supported_preset_modes();
|
||||
this->preset_modes_.init(source_modes.size());
|
||||
for (const auto &mode : source_modes) {
|
||||
this->preset_modes_.push_back(mode);
|
||||
}
|
||||
traits.set_supported_preset_modes(&this->preset_modes_);
|
||||
}
|
||||
|
||||
traits.set_supported_preset_modes(base.supported_preset_modes());
|
||||
return traits;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/components/fan/fan.h"
|
||||
|
||||
namespace esphome {
|
||||
@@ -20,7 +19,6 @@ class CopyFan : public fan::Fan, public Component {
|
||||
;
|
||||
|
||||
fan::Fan *source_;
|
||||
FixedVector<std::string> preset_modes_{};
|
||||
};
|
||||
|
||||
} // namespace copy
|
||||
|
||||
@@ -58,11 +58,10 @@ template<typename... Ts> class CycleSpeedAction : public Action<Ts...> {
|
||||
|
||||
void play(Ts... x) override {
|
||||
// check to see if fan supports speeds and is on
|
||||
auto traits = this->state_->get_traits();
|
||||
if (traits.supported_speed_count()) {
|
||||
if (this->state_->get_traits().supported_speed_count()) {
|
||||
if (this->state_->state) {
|
||||
int speed = this->state_->speed + 1;
|
||||
int supported_speed_count = traits.supported_speed_count();
|
||||
int supported_speed_count = this->state_->get_traits().supported_speed_count();
|
||||
bool off_speed_cycle = no_off_cycle_.value(x...);
|
||||
if (speed > supported_speed_count && off_speed_cycle) {
|
||||
// was running at max speed, off speed cycle enabled, so turn off
|
||||
|
||||
@@ -50,18 +50,8 @@ void FanCall::validate_() {
|
||||
}
|
||||
|
||||
if (!this->preset_mode_.empty()) {
|
||||
bool found = false;
|
||||
if (traits.supports_preset_modes()) {
|
||||
const auto &preset_modes = traits.supported_preset_modes();
|
||||
// Linear search is efficient for small preset mode lists (typically 2-5 items)
|
||||
for (const auto &mode : preset_modes) {
|
||||
if (mode == this->preset_mode_) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const auto &preset_modes = traits.supported_preset_modes();
|
||||
if (preset_modes.find(this->preset_mode_) == preset_modes.end()) {
|
||||
ESP_LOGW(TAG, "%s: Preset mode '%s' not supported", this->parent_.get_name().c_str(), this->preset_mode_.c_str());
|
||||
this->preset_mode_.clear();
|
||||
}
|
||||
@@ -102,12 +92,11 @@ FanCall FanRestoreState::to_call(Fan &fan) {
|
||||
call.set_speed(this->speed);
|
||||
call.set_direction(this->direction);
|
||||
|
||||
auto traits = fan.get_traits();
|
||||
if (traits.supports_preset_modes()) {
|
||||
if (fan.get_traits().supports_preset_modes()) {
|
||||
// Use stored preset index to get preset name
|
||||
const auto &preset_modes = traits.supported_preset_modes();
|
||||
const auto &preset_modes = fan.get_traits().supported_preset_modes();
|
||||
if (this->preset_mode < preset_modes.size()) {
|
||||
call.set_preset_mode(preset_modes[this->preset_mode]);
|
||||
call.set_preset_mode(*std::next(preset_modes.begin(), this->preset_mode));
|
||||
}
|
||||
}
|
||||
return call;
|
||||
@@ -118,12 +107,11 @@ void FanRestoreState::apply(Fan &fan) {
|
||||
fan.speed = this->speed;
|
||||
fan.direction = this->direction;
|
||||
|
||||
auto traits = fan.get_traits();
|
||||
if (traits.supports_preset_modes()) {
|
||||
if (fan.get_traits().supports_preset_modes()) {
|
||||
// Use stored preset index to get preset name
|
||||
const auto &preset_modes = traits.supported_preset_modes();
|
||||
const auto &preset_modes = fan.get_traits().supported_preset_modes();
|
||||
if (this->preset_mode < preset_modes.size()) {
|
||||
fan.preset_mode = preset_modes[this->preset_mode];
|
||||
fan.preset_mode = *std::next(preset_modes.begin(), this->preset_mode);
|
||||
}
|
||||
}
|
||||
fan.publish_state();
|
||||
@@ -200,16 +188,12 @@ void Fan::save_state_() {
|
||||
state.speed = this->speed;
|
||||
state.direction = this->direction;
|
||||
|
||||
auto traits = this->get_traits();
|
||||
if (traits.supports_preset_modes() && !this->preset_mode.empty()) {
|
||||
const auto &preset_modes = traits.supported_preset_modes();
|
||||
// Store index of current preset mode - linear search is efficient for small lists
|
||||
for (size_t i = 0; i < preset_modes.size(); i++) {
|
||||
if (preset_modes[i] == this->preset_mode) {
|
||||
state.preset_mode = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (this->get_traits().supports_preset_modes() && !this->preset_mode.empty()) {
|
||||
const auto &preset_modes = this->get_traits().supported_preset_modes();
|
||||
// Store index of current preset mode
|
||||
auto preset_iterator = preset_modes.find(this->preset_mode);
|
||||
if (preset_iterator != preset_modes.end())
|
||||
state.preset_mode = std::distance(preset_modes.begin(), preset_iterator);
|
||||
}
|
||||
|
||||
this->rtc_.save(&state);
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
namespace esphome {
|
||||
|
||||
#ifdef USE_API
|
||||
namespace api {
|
||||
class APIConnection;
|
||||
} // namespace api
|
||||
#endif
|
||||
|
||||
namespace fan {
|
||||
|
||||
class FanTraits {
|
||||
@@ -10,12 +18,6 @@ class FanTraits {
|
||||
FanTraits() = default;
|
||||
FanTraits(bool oscillation, bool speed, bool direction, int speed_count)
|
||||
: oscillation_(oscillation), speed_(speed), direction_(direction), speed_count_(speed_count) {}
|
||||
FanTraits(bool oscillation, bool speed, bool direction, int speed_count, const FixedVector<std::string> *preset_modes)
|
||||
: oscillation_(oscillation),
|
||||
speed_(speed),
|
||||
direction_(direction),
|
||||
speed_count_(speed_count),
|
||||
preset_modes_(preset_modes) {}
|
||||
|
||||
/// Return if this fan supports oscillation.
|
||||
bool supports_oscillation() const { return this->oscillation_; }
|
||||
@@ -34,18 +36,27 @@ class FanTraits {
|
||||
/// Set whether this fan supports changing direction
|
||||
void set_direction(bool direction) { this->direction_ = direction; }
|
||||
/// Return the preset modes supported by the fan.
|
||||
const FixedVector<std::string> &supported_preset_modes() const { return *this->preset_modes_; }
|
||||
std::set<std::string> supported_preset_modes() const { return this->preset_modes_; }
|
||||
/// Set the preset modes supported by the fan.
|
||||
void set_supported_preset_modes(const FixedVector<std::string> *preset_modes) { this->preset_modes_ = preset_modes; }
|
||||
void set_supported_preset_modes(const std::set<std::string> &preset_modes) { this->preset_modes_ = preset_modes; }
|
||||
/// Return if preset modes are supported
|
||||
bool supports_preset_modes() const { return this->preset_modes_ != nullptr && !this->preset_modes_->empty(); }
|
||||
bool supports_preset_modes() const { return !this->preset_modes_.empty(); }
|
||||
|
||||
protected:
|
||||
#ifdef USE_API
|
||||
// The API connection is a friend class to access internal methods
|
||||
friend class api::APIConnection;
|
||||
// This method returns a reference to the internal preset modes set.
|
||||
// It is used by the API to avoid copying data when encoding messages.
|
||||
// Warning: Do not use this method outside of the API connection code.
|
||||
// It returns a reference to internal data that can be invalidated.
|
||||
const std::set<std::string> &supported_preset_modes_for_api_() const { return this->preset_modes_; }
|
||||
#endif
|
||||
bool oscillation_{false};
|
||||
bool speed_{false};
|
||||
bool direction_{false};
|
||||
int speed_count_{};
|
||||
const FixedVector<std::string> *preset_modes_{nullptr};
|
||||
std::set<std::string> preset_modes_{};
|
||||
};
|
||||
|
||||
} // namespace fan
|
||||
|
||||
@@ -33,10 +33,10 @@ void HBridgeFan::setup() {
|
||||
restore->apply(*this);
|
||||
this->write_state_();
|
||||
}
|
||||
}
|
||||
|
||||
fan::FanTraits HBridgeFan::get_traits() {
|
||||
return fan::FanTraits(this->oscillating_ != nullptr, true, true, this->speed_count_, &this->preset_modes_);
|
||||
// Construct traits
|
||||
this->traits_ = fan::FanTraits(this->oscillating_ != nullptr, true, true, this->speed_count_);
|
||||
this->traits_.set_supported_preset_modes(this->preset_modes_);
|
||||
}
|
||||
|
||||
void HBridgeFan::dump_config() {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/components/output/binary_output.h"
|
||||
#include "esphome/components/output/float_output.h"
|
||||
#include "esphome/components/fan/fan.h"
|
||||
@@ -21,11 +22,11 @@ class HBridgeFan : public Component, public fan::Fan {
|
||||
void set_pin_a(output::FloatOutput *pin_a) { pin_a_ = pin_a; }
|
||||
void set_pin_b(output::FloatOutput *pin_b) { pin_b_ = pin_b; }
|
||||
void set_enable_pin(output::FloatOutput *enable) { enable_ = enable; }
|
||||
void set_preset_modes(const std::initializer_list<std::string> &presets) { this->preset_modes_ = presets; }
|
||||
void set_preset_modes(const std::set<std::string> &presets) { preset_modes_ = presets; }
|
||||
|
||||
void setup() override;
|
||||
void dump_config() override;
|
||||
fan::FanTraits get_traits() override;
|
||||
fan::FanTraits get_traits() override { return this->traits_; }
|
||||
|
||||
fan::FanCall brake();
|
||||
|
||||
@@ -36,7 +37,8 @@ class HBridgeFan : public Component, public fan::Fan {
|
||||
output::BinaryOutput *oscillating_{nullptr};
|
||||
int speed_count_{};
|
||||
DecayMode decay_mode_{DECAY_MODE_SLOW};
|
||||
FixedVector<std::string> preset_modes_{};
|
||||
fan::FanTraits traits_;
|
||||
std::set<std::string> preset_modes_{};
|
||||
|
||||
void control(const fan::FanCall &call) override;
|
||||
void write_state_();
|
||||
|
||||
@@ -12,11 +12,10 @@ void SpeedFan::setup() {
|
||||
restore->apply(*this);
|
||||
this->write_state_();
|
||||
}
|
||||
}
|
||||
|
||||
fan::FanTraits SpeedFan::get_traits() {
|
||||
return fan::FanTraits(this->oscillating_ != nullptr, true, this->direction_ != nullptr, this->speed_count_,
|
||||
&this->preset_modes_);
|
||||
// Construct traits
|
||||
this->traits_ = fan::FanTraits(this->oscillating_ != nullptr, true, this->direction_ != nullptr, this->speed_count_);
|
||||
this->traits_.set_supported_preset_modes(this->preset_modes_);
|
||||
}
|
||||
|
||||
void SpeedFan::dump_config() { LOG_FAN("", "Speed Fan", this); }
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/components/output/binary_output.h"
|
||||
#include "esphome/components/output/float_output.h"
|
||||
#include "esphome/components/fan/fan.h"
|
||||
@@ -17,8 +18,8 @@ class SpeedFan : public Component, public fan::Fan {
|
||||
void set_output(output::FloatOutput *output) { this->output_ = output; }
|
||||
void set_oscillating(output::BinaryOutput *oscillating) { this->oscillating_ = oscillating; }
|
||||
void set_direction(output::BinaryOutput *direction) { this->direction_ = direction; }
|
||||
void set_preset_modes(const std::initializer_list<std::string> &presets) { this->preset_modes_ = presets; }
|
||||
fan::FanTraits get_traits() override;
|
||||
void set_preset_modes(const std::set<std::string> &presets) { this->preset_modes_ = presets; }
|
||||
fan::FanTraits get_traits() override { return this->traits_; }
|
||||
|
||||
protected:
|
||||
void control(const fan::FanCall &call) override;
|
||||
@@ -28,7 +29,8 @@ class SpeedFan : public Component, public fan::Fan {
|
||||
output::BinaryOutput *oscillating_{nullptr};
|
||||
output::BinaryOutput *direction_{nullptr};
|
||||
int speed_count_{};
|
||||
FixedVector<std::string> preset_modes_{};
|
||||
fan::FanTraits traits_;
|
||||
std::set<std::string> preset_modes_{};
|
||||
};
|
||||
|
||||
} // namespace speed
|
||||
|
||||
@@ -11,11 +11,11 @@ void TemplateFan::setup() {
|
||||
if (restore.has_value()) {
|
||||
restore->apply(*this);
|
||||
}
|
||||
}
|
||||
|
||||
fan::FanTraits TemplateFan::get_traits() {
|
||||
return fan::FanTraits(this->has_oscillating_, this->speed_count_ > 0, this->has_direction_, this->speed_count_,
|
||||
&this->preset_modes_);
|
||||
// Construct traits
|
||||
this->traits_ =
|
||||
fan::FanTraits(this->has_oscillating_, this->speed_count_ > 0, this->has_direction_, this->speed_count_);
|
||||
this->traits_.set_supported_preset_modes(this->preset_modes_);
|
||||
}
|
||||
|
||||
void TemplateFan::dump_config() { LOG_FAN("", "Template Fan", this); }
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/components/fan/fan.h"
|
||||
|
||||
namespace esphome {
|
||||
@@ -15,8 +16,8 @@ class TemplateFan : public Component, public fan::Fan {
|
||||
void set_has_direction(bool has_direction) { this->has_direction_ = has_direction; }
|
||||
void set_has_oscillating(bool has_oscillating) { this->has_oscillating_ = has_oscillating; }
|
||||
void set_speed_count(int count) { this->speed_count_ = count; }
|
||||
void set_preset_modes(const std::initializer_list<std::string> &presets) { this->preset_modes_ = presets; }
|
||||
fan::FanTraits get_traits() override;
|
||||
void set_preset_modes(const std::set<std::string> &presets) { this->preset_modes_ = presets; }
|
||||
fan::FanTraits get_traits() override { return this->traits_; }
|
||||
|
||||
protected:
|
||||
void control(const fan::FanCall &call) override;
|
||||
@@ -24,7 +25,8 @@ class TemplateFan : public Component, public fan::Fan {
|
||||
bool has_oscillating_{false};
|
||||
bool has_direction_{false};
|
||||
int speed_count_{0};
|
||||
FixedVector<std::string> preset_modes_{};
|
||||
fan::FanTraits traits_;
|
||||
std::set<std::string> preset_modes_{};
|
||||
};
|
||||
|
||||
} // namespace template_
|
||||
|
||||
@@ -723,7 +723,7 @@ std::string WebServer::fan_json(fan::Fan *obj, JsonDetail start_config) {
|
||||
root["speed_level"] = obj->speed;
|
||||
root["speed_count"] = traits.supported_speed_count();
|
||||
}
|
||||
if (traits.supports_oscillation())
|
||||
if (obj->get_traits().supports_oscillation())
|
||||
root["oscillation"] = obj->oscillating;
|
||||
if (start_config == DETAIL_ALL) {
|
||||
this->add_sorting_info_(root, obj);
|
||||
|
||||
Reference in New Issue
Block a user