mirror of
https://github.com/esphome/esphome.git
synced 2026-05-24 09:56:46 +08:00
[climate] Return std::string_view from get_custom_fan_mode() and get_custom_preset()
This commit is contained in:
@@ -675,13 +675,15 @@ 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->has_custom_fan_mode()) {
|
||||
resp.custom_fan_mode = StringRef(climate->get_custom_fan_mode());
|
||||
auto mode = climate->get_custom_fan_mode();
|
||||
resp.custom_fan_mode = StringRef(mode.data(), mode.size());
|
||||
}
|
||||
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->has_custom_preset()) {
|
||||
resp.custom_preset = StringRef(climate->get_custom_preset());
|
||||
auto preset = climate->get_custom_preset();
|
||||
resp.custom_preset = StringRef(preset.data(), preset.size());
|
||||
}
|
||||
if (traits.get_supports_swing_modes())
|
||||
resp.swing_mode = static_cast<enums::ClimateSwingMode>(climate->swing_mode);
|
||||
|
||||
@@ -164,21 +164,21 @@ void BedJetClimate::control(const ClimateCall &call) {
|
||||
return;
|
||||
}
|
||||
} else if (call.has_custom_preset()) {
|
||||
const char *preset = call.get_custom_preset();
|
||||
auto preset = call.get_custom_preset();
|
||||
bool result;
|
||||
|
||||
if (strcmp(preset, "M1") == 0) {
|
||||
if (preset == "M1") {
|
||||
result = this->parent_->button_memory1();
|
||||
} else if (strcmp(preset, "M2") == 0) {
|
||||
} else if (preset == "M2") {
|
||||
result = this->parent_->button_memory2();
|
||||
} else if (strcmp(preset, "M3") == 0) {
|
||||
} else if (preset == "M3") {
|
||||
result = this->parent_->button_memory3();
|
||||
} else if (strcmp(preset, "LTD HT") == 0) {
|
||||
} else if (preset == "LTD HT") {
|
||||
result = this->parent_->button_heat();
|
||||
} else if (strcmp(preset, "EXT HT") == 0) {
|
||||
} else if (preset == "EXT HT") {
|
||||
result = this->parent_->button_ext_heat();
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Unsupported preset: %s", preset);
|
||||
ESP_LOGW(TAG, "Unsupported preset: %.*s", (int) preset.size(), preset.data());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -208,10 +208,11 @@ void BedJetClimate::control(const ClimateCall &call) {
|
||||
this->set_fan_mode_(fan_mode);
|
||||
}
|
||||
} else if (call.has_custom_fan_mode()) {
|
||||
const char *fan_mode = call.get_custom_fan_mode();
|
||||
auto fan_index = bedjet_fan_speed_to_step(fan_mode);
|
||||
auto fan_mode = call.get_custom_fan_mode();
|
||||
auto fan_index = bedjet_fan_speed_to_step(fan_mode.data());
|
||||
if (fan_index <= 19) {
|
||||
ESP_LOGV(TAG, "[%s] Converted fan mode %s to bedjet fan step %d", this->get_name().c_str(), fan_mode, fan_index);
|
||||
ESP_LOGV(TAG, "[%s] Converted fan mode %.*s to bedjet fan step %d", this->get_name().c_str(),
|
||||
(int) fan_mode.size(), fan_mode.data(), fan_index);
|
||||
bool result = this->parent_->set_fan_index(fan_index);
|
||||
if (result) {
|
||||
this->set_custom_fan_mode_(fan_mode);
|
||||
|
||||
@@ -682,19 +682,19 @@ bool Climate::set_fan_mode_(ClimateFanMode mode) {
|
||||
return set_primary_mode(this->fan_mode, this->custom_fan_mode_, mode);
|
||||
}
|
||||
|
||||
bool Climate::set_custom_fan_mode_(const char *mode) {
|
||||
bool Climate::set_custom_fan_mode_(const char *mode, size_t len) {
|
||||
auto traits = this->get_traits();
|
||||
return set_custom_mode<ClimateFanMode>(this->custom_fan_mode_, this->fan_mode, traits.find_custom_fan_mode_(mode),
|
||||
this->has_custom_fan_mode());
|
||||
return set_custom_mode<ClimateFanMode>(this->custom_fan_mode_, this->fan_mode,
|
||||
traits.find_custom_fan_mode_(mode, len), this->has_custom_fan_mode());
|
||||
}
|
||||
|
||||
void Climate::clear_custom_fan_mode_() { this->custom_fan_mode_ = nullptr; }
|
||||
|
||||
bool Climate::set_preset_(ClimatePreset preset) { return set_primary_mode(this->preset, this->custom_preset_, preset); }
|
||||
|
||||
bool Climate::set_custom_preset_(const char *preset) {
|
||||
bool Climate::set_custom_preset_(const char *preset, size_t len) {
|
||||
auto traits = this->get_traits();
|
||||
return set_custom_mode<ClimatePreset>(this->custom_preset_, this->preset, traits.find_custom_preset_(preset),
|
||||
return set_custom_mode<ClimatePreset>(this->custom_preset_, this->preset, traits.find_custom_preset_(preset, len),
|
||||
this->has_custom_preset());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
@@ -110,8 +112,12 @@ class ClimateCall {
|
||||
const optional<ClimateFanMode> &get_fan_mode() const;
|
||||
const optional<ClimateSwingMode> &get_swing_mode() const;
|
||||
const optional<ClimatePreset> &get_preset() const;
|
||||
const char *get_custom_fan_mode() const { return this->custom_fan_mode_; }
|
||||
const char *get_custom_preset() const { return this->custom_preset_; }
|
||||
std::string_view get_custom_fan_mode() const {
|
||||
return this->custom_fan_mode_ != nullptr ? std::string_view(this->custom_fan_mode_) : std::string_view();
|
||||
}
|
||||
std::string_view get_custom_preset() const {
|
||||
return this->custom_preset_ != nullptr ? std::string_view(this->custom_preset_) : std::string_view();
|
||||
}
|
||||
bool has_custom_fan_mode() const { return this->custom_fan_mode_ != nullptr; }
|
||||
bool has_custom_preset() const { return this->custom_preset_ != nullptr; }
|
||||
|
||||
@@ -266,11 +272,15 @@ class Climate : public EntityBase {
|
||||
/// The active swing mode of the climate device.
|
||||
ClimateSwingMode swing_mode{CLIMATE_SWING_OFF};
|
||||
|
||||
/// Get the active custom fan mode (read-only access).
|
||||
const char *get_custom_fan_mode() const { return this->custom_fan_mode_; }
|
||||
/// Get the active custom fan mode (read-only access). Returns std::string_view.
|
||||
std::string_view get_custom_fan_mode() const {
|
||||
return this->custom_fan_mode_ != nullptr ? std::string_view(this->custom_fan_mode_) : std::string_view();
|
||||
}
|
||||
|
||||
/// Get the active custom preset (read-only access).
|
||||
const char *get_custom_preset() const { return this->custom_preset_; }
|
||||
/// Get the active custom preset (read-only access). Returns std::string_view.
|
||||
std::string_view get_custom_preset() const {
|
||||
return this->custom_preset_ != nullptr ? std::string_view(this->custom_preset_) : std::string_view();
|
||||
}
|
||||
|
||||
protected:
|
||||
friend ClimateCall;
|
||||
@@ -280,7 +290,9 @@ class Climate : public EntityBase {
|
||||
bool set_fan_mode_(ClimateFanMode mode);
|
||||
|
||||
/// Set custom fan mode. Reset primary fan mode. Return true if fan mode has been changed.
|
||||
bool set_custom_fan_mode_(const char *mode);
|
||||
bool set_custom_fan_mode_(const char *mode) { return this->set_custom_fan_mode_(mode, strlen(mode)); }
|
||||
bool set_custom_fan_mode_(const char *mode, size_t len);
|
||||
bool set_custom_fan_mode_(std::string_view mode) { return this->set_custom_fan_mode_(mode.data(), mode.size()); }
|
||||
/// Clear custom fan mode.
|
||||
void clear_custom_fan_mode_();
|
||||
|
||||
@@ -288,7 +300,9 @@ class Climate : public EntityBase {
|
||||
bool set_preset_(ClimatePreset preset);
|
||||
|
||||
/// Set custom preset. Reset primary preset. Return true if preset has been changed.
|
||||
bool set_custom_preset_(const char *preset);
|
||||
bool set_custom_preset_(const char *preset) { return this->set_custom_preset_(preset, strlen(preset)); }
|
||||
bool set_custom_preset_(const char *preset, size_t len);
|
||||
bool set_custom_preset_(std::string_view preset) { return this->set_custom_preset_(preset.data(), preset.size()); }
|
||||
/// Clear custom preset.
|
||||
void clear_custom_preset_();
|
||||
|
||||
|
||||
@@ -65,12 +65,14 @@ void AirConditioner::control(const ClimateCall &call) {
|
||||
if (call.get_preset().has_value()) {
|
||||
ctrl.preset = Converters::to_midea_preset(call.get_preset().value());
|
||||
} else if (call.has_custom_preset()) {
|
||||
ctrl.preset = Converters::to_midea_preset(call.get_custom_preset());
|
||||
// get_custom_preset() returns string_view; Converters expects null-terminated const char*
|
||||
ctrl.preset = Converters::to_midea_preset(call.get_custom_preset().data());
|
||||
}
|
||||
if (call.get_fan_mode().has_value()) {
|
||||
ctrl.fanMode = Converters::to_midea_fan_mode(call.get_fan_mode().value());
|
||||
} else if (call.has_custom_fan_mode()) {
|
||||
ctrl.fanMode = Converters::to_midea_fan_mode(call.get_custom_fan_mode());
|
||||
// get_custom_fan_mode() returns string_view; Converters expects null-terminated const char*
|
||||
ctrl.fanMode = Converters::to_midea_fan_mode(call.get_custom_fan_mode().data());
|
||||
}
|
||||
this->base_.control(ctrl);
|
||||
}
|
||||
|
||||
@@ -357,7 +357,7 @@ bool MQTTClimateComponent::publish_state_() {
|
||||
}
|
||||
}
|
||||
if (this->device_->has_custom_preset())
|
||||
payload = this->device_->get_custom_preset();
|
||||
payload = this->device_->get_custom_preset().data();
|
||||
if (!this->publish(this->get_preset_state_topic(), payload))
|
||||
success = false;
|
||||
}
|
||||
@@ -429,7 +429,7 @@ bool MQTTClimateComponent::publish_state_() {
|
||||
}
|
||||
}
|
||||
if (this->device_->has_custom_fan_mode())
|
||||
payload = this->device_->get_custom_fan_mode();
|
||||
payload = this->device_->get_custom_fan_mode().data();
|
||||
if (!this->publish(this->get_fan_mode_state_topic(), payload))
|
||||
success = false;
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ void ThermostatClimate::control(const climate::ClimateCall &call) {
|
||||
if (call.has_custom_preset()) {
|
||||
// setup_complete_ blocks modifying/resetting the temps immediately after boot
|
||||
if (this->setup_complete_) {
|
||||
this->change_custom_preset_(call.get_custom_preset());
|
||||
this->change_custom_preset_(call.get_custom_preset().data());
|
||||
} else {
|
||||
// Use the base class method which handles pointer lookup internally
|
||||
this->set_custom_preset_(call.get_custom_preset());
|
||||
@@ -1231,7 +1231,7 @@ void ThermostatClimate::change_custom_preset_(const char *custom_preset) {
|
||||
if (config != nullptr) {
|
||||
ESP_LOGV(TAG, "Custom preset %s requested", custom_preset);
|
||||
if (this->change_preset_internal_(*config) || !this->has_custom_preset() ||
|
||||
strcmp(this->get_custom_preset(), custom_preset) != 0) {
|
||||
this->get_custom_preset() != custom_preset) {
|
||||
// Fire any preset changed trigger if defined
|
||||
Trigger<> *trig = this->preset_change_trigger_;
|
||||
// Use the base class method which handles pointer lookup and preset reset internally
|
||||
|
||||
@@ -1543,13 +1543,15 @@ std::string WebServer::climate_json_(climate::Climate *obj, JsonDetail start_con
|
||||
root[ESPHOME_F("fan_mode")] = PSTR_LOCAL(climate_fan_mode_to_string(obj->fan_mode.value()));
|
||||
}
|
||||
if (!traits.get_supported_custom_fan_modes().empty() && obj->has_custom_fan_mode()) {
|
||||
root[ESPHOME_F("custom_fan_mode")] = obj->get_custom_fan_mode();
|
||||
// get_custom_fan_mode() returns string_view pointing to null-terminated string literals from codegen
|
||||
root[ESPHOME_F("custom_fan_mode")] = obj->get_custom_fan_mode().data();
|
||||
}
|
||||
if (traits.get_supports_presets() && obj->preset.has_value()) {
|
||||
root[ESPHOME_F("preset")] = PSTR_LOCAL(climate_preset_to_string(obj->preset.value()));
|
||||
}
|
||||
if (!traits.get_supported_custom_presets().empty() && obj->has_custom_preset()) {
|
||||
root[ESPHOME_F("custom_preset")] = obj->get_custom_preset();
|
||||
// get_custom_preset() returns string_view pointing to null-terminated string literals from codegen
|
||||
root[ESPHOME_F("custom_preset")] = obj->get_custom_preset().data();
|
||||
}
|
||||
if (traits.get_supports_swing_modes()) {
|
||||
root[ESPHOME_F("swing_mode")] = PSTR_LOCAL(climate_swing_mode_to_string(obj->swing_mode));
|
||||
|
||||
@@ -12,6 +12,25 @@ climate:
|
||||
x.set_mode(CLIMATE_MODE_FAN_ONLY);
|
||||
on_state:
|
||||
- logger.log: State changed!
|
||||
- lambda: |-
|
||||
// Test get_custom_fan_mode() returns std::string_view
|
||||
if (id(midea_unit).has_custom_fan_mode()) {
|
||||
auto fan_mode = id(midea_unit).get_custom_fan_mode();
|
||||
// Compare with string literal using ==
|
||||
if (fan_mode == "SILENT") {
|
||||
ESP_LOGD("test", "Fan mode is SILENT");
|
||||
}
|
||||
// Log using %.*s format for string_view
|
||||
ESP_LOGD("test", "Custom fan mode: %.*s", (int) fan_mode.size(), fan_mode.data());
|
||||
}
|
||||
// Test get_custom_preset() returns std::string_view
|
||||
if (id(midea_unit).has_custom_preset()) {
|
||||
auto preset = id(midea_unit).get_custom_preset();
|
||||
// Check if empty
|
||||
if (!preset.empty()) {
|
||||
ESP_LOGD("test", "Custom preset: %.*s", (int) preset.size(), preset.data());
|
||||
}
|
||||
}
|
||||
transmitter_id: xmitr
|
||||
period: 1s
|
||||
num_attempts: 5
|
||||
|
||||
Reference in New Issue
Block a user