1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-28 21:53:48 +00:00
This commit is contained in:
J. Nick Koston
2025-10-21 17:16:04 -10:00
parent a59fdd8e04
commit dfa51a5137
15 changed files with 137 additions and 82 deletions

View File

@@ -989,7 +989,7 @@ message ListEntitiesClimateResponse {
bool supports_current_temperature = 5; // Deprecated: use feature_flags
bool supports_two_point_target_temperature = 6; // Deprecated: use feature_flags
repeated ClimateMode supported_modes = 7 [(container_pointer) = "std::set<climate::ClimateMode>"];
repeated ClimateMode supported_modes = 7 [(container_pointer_no_template) = "climate::ClimateModeMask"];
float visual_min_temperature = 8;
float visual_max_temperature = 9;
float visual_target_temperature_step = 10;
@@ -998,11 +998,11 @@ message ListEntitiesClimateResponse {
// Deprecated in API version 1.5
bool legacy_supports_away = 11 [deprecated=true];
bool supports_action = 12; // Deprecated: use feature_flags
repeated ClimateFanMode supported_fan_modes = 13 [(container_pointer) = "std::set<climate::ClimateFanMode>"];
repeated ClimateSwingMode supported_swing_modes = 14 [(container_pointer) = "std::set<climate::ClimateSwingMode>"];
repeated string supported_custom_fan_modes = 15 [(container_pointer) = "std::set"];
repeated ClimatePreset supported_presets = 16 [(container_pointer) = "std::set<climate::ClimatePreset>"];
repeated string supported_custom_presets = 17 [(container_pointer) = "std::set"];
repeated ClimateFanMode supported_fan_modes = 13 [(container_pointer_no_template) = "climate::ClimateFanModeMask"];
repeated ClimateSwingMode supported_swing_modes = 14 [(container_pointer_no_template) = "climate::ClimateSwingModeMask"];
repeated string supported_custom_fan_modes = 15 [(container_pointer) = "std::vector"];
repeated ClimatePreset supported_presets = 16 [(container_pointer_no_template) = "climate::ClimatePresetMask"];
repeated string supported_custom_presets = 17 [(container_pointer) = "std::vector"];
bool disabled_by_default = 18;
string icon = 19 [(field_ifdef) = "USE_ENTITY_ICON"];
EntityCategory entity_category = 20;

View File

@@ -1377,16 +1377,16 @@ class ListEntitiesClimateResponse final : public InfoResponseProtoMessage {
#endif
bool supports_current_temperature{false};
bool supports_two_point_target_temperature{false};
const std::set<climate::ClimateMode> *supported_modes{};
const climate::ClimateModeMask *supported_modes{};
float visual_min_temperature{0.0f};
float visual_max_temperature{0.0f};
float visual_target_temperature_step{0.0f};
bool supports_action{false};
const std::set<climate::ClimateFanMode> *supported_fan_modes{};
const std::set<climate::ClimateSwingMode> *supported_swing_modes{};
const std::set<std::string> *supported_custom_fan_modes{};
const std::set<climate::ClimatePreset> *supported_presets{};
const std::set<std::string> *supported_custom_presets{};
const climate::ClimateFanModeMask *supported_fan_modes{};
const climate::ClimateSwingModeMask *supported_swing_modes{};
const std::vector<std::string> *supported_custom_fan_modes{};
const climate::ClimatePresetMask *supported_presets{};
const std::vector<std::string> *supported_custom_presets{};
float visual_current_temperature_step{0.0f};
bool supports_current_humidity{false};
bool supports_target_humidity{false};

View File

@@ -99,9 +99,8 @@ enum BedjetCommand : uint8_t {
static const uint8_t BEDJET_FAN_SPEED_COUNT = 20;
static const char *const BEDJET_FAN_STEP_NAMES[BEDJET_FAN_SPEED_COUNT] = BEDJET_FAN_STEP_NAMES_;
static constexpr const char *const BEDJET_FAN_STEP_NAMES[BEDJET_FAN_SPEED_COUNT] = BEDJET_FAN_STEP_NAMES_;
static const std::string BEDJET_FAN_STEP_NAME_STRINGS[BEDJET_FAN_SPEED_COUNT] = BEDJET_FAN_STEP_NAMES_;
static const std::set<std::string> BEDJET_FAN_STEP_NAMES_SET BEDJET_FAN_STEP_NAMES_;
} // namespace bedjet
} // namespace esphome

View File

@@ -43,7 +43,7 @@ class BedJetClimate : public climate::Climate, public BedJetClient, public Polli
});
// It would be better if we had a slider for the fan modes.
traits.set_supported_custom_fan_modes(BEDJET_FAN_STEP_NAMES_SET);
traits.set_supported_custom_fan_modes(BEDJET_FAN_STEP_NAMES);
traits.set_supported_presets({
// If we support NONE, then have to decide what happens if the user switches to it (turn off?)
// climate::CLIMATE_PRESET_NONE,

View File

@@ -9,12 +9,17 @@ namespace climate {
// Type aliases for climate enum bitmasks
// These replace std::set<EnumType> to eliminate red-black tree overhead
using ClimateModeMask = EnumBitmask<ClimateMode, 8>; // 7 values (OFF, HEAT_COOL, COOL, HEAT, FAN_ONLY, DRY, AUTO)
using ClimateFanModeMask =
EnumBitmask<ClimateFanMode, 16>; // 10 values (ON, OFF, AUTO, LOW, MEDIUM, HIGH, MIDDLE, FOCUS, DIFFUSE, QUIET)
using ClimateSwingModeMask = EnumBitmask<ClimateSwingMode, 8>; // 4 values (OFF, BOTH, VERTICAL, HORIZONTAL)
using ClimatePresetMask =
EnumBitmask<ClimatePreset, 8>; // 8 values (NONE, HOME, AWAY, BOOST, COMFORT, ECO, SLEEP, ACTIVITY)
// Bitmask size constants - sized to fit all enum values
constexpr int CLIMATE_MODE_BITMASK_SIZE = 8; // 7 values (OFF, HEAT_COOL, COOL, HEAT, FAN_ONLY, DRY, AUTO)
constexpr int CLIMATE_FAN_MODE_BITMASK_SIZE =
16; // 10 values (ON, OFF, AUTO, LOW, MEDIUM, HIGH, MIDDLE, FOCUS, DIFFUSE, QUIET)
constexpr int CLIMATE_SWING_MODE_BITMASK_SIZE = 8; // 4 values (OFF, BOTH, VERTICAL, HORIZONTAL)
constexpr int CLIMATE_PRESET_BITMASK_SIZE = 8; // 8 values (NONE, HOME, AWAY, BOOST, COMFORT, ECO, SLEEP, ACTIVITY)
using ClimateModeMask = EnumBitmask<ClimateMode, CLIMATE_MODE_BITMASK_SIZE>;
using ClimateFanModeMask = EnumBitmask<ClimateFanMode, CLIMATE_FAN_MODE_BITMASK_SIZE>;
using ClimateSwingModeMask = EnumBitmask<ClimateSwingMode, CLIMATE_SWING_MODE_BITMASK_SIZE>;
using ClimatePresetMask = EnumBitmask<ClimatePreset, CLIMATE_PRESET_BITMASK_SIZE>;
} // namespace climate
} // namespace esphome
@@ -25,12 +30,16 @@ using ClimatePresetMask =
namespace esphome {
// ClimateMode specialization (7 values: 0-6)
template<> constexpr int EnumBitmask<climate::ClimateMode, 8>::enum_to_bit(climate::ClimateMode mode) {
template<>
constexpr int EnumBitmask<climate::ClimateMode, climate::CLIMATE_MODE_BITMASK_SIZE>::enum_to_bit(
climate::ClimateMode mode) {
return static_cast<int>(mode); // Direct mapping: enum value = bit position
}
template<> constexpr climate::ClimateMode EnumBitmask<climate::ClimateMode, 8>::bit_to_enum(int bit) {
// Compile-time lookup array mapping bit positions to enum values
template<>
inline climate::ClimateMode EnumBitmask<climate::ClimateMode, climate::CLIMATE_MODE_BITMASK_SIZE>::bit_to_enum(
int bit) {
// Lookup array mapping bit positions to enum values
static constexpr climate::ClimateMode MODES[] = {
climate::CLIMATE_MODE_OFF, // bit 0
climate::CLIMATE_MODE_HEAT_COOL, // bit 1
@@ -40,15 +49,20 @@ template<> constexpr climate::ClimateMode EnumBitmask<climate::ClimateMode, 8>::
climate::CLIMATE_MODE_DRY, // bit 5
climate::CLIMATE_MODE_AUTO, // bit 6
};
return (bit >= 0 && bit < 7) ? MODES[bit] : climate::CLIMATE_MODE_OFF;
static constexpr int MODE_COUNT = 7;
return (bit >= 0 && bit < MODE_COUNT) ? MODES[bit] : climate::CLIMATE_MODE_OFF;
}
// ClimateFanMode specialization (10 values: 0-9)
template<> constexpr int EnumBitmask<climate::ClimateFanMode, 16>::enum_to_bit(climate::ClimateFanMode mode) {
template<>
constexpr int EnumBitmask<climate::ClimateFanMode, climate::CLIMATE_FAN_MODE_BITMASK_SIZE>::enum_to_bit(
climate::ClimateFanMode mode) {
return static_cast<int>(mode); // Direct mapping: enum value = bit position
}
template<> constexpr climate::ClimateFanMode EnumBitmask<climate::ClimateFanMode, 16>::bit_to_enum(int bit) {
template<>
inline climate::ClimateFanMode EnumBitmask<climate::ClimateFanMode,
climate::CLIMATE_FAN_MODE_BITMASK_SIZE>::bit_to_enum(int bit) {
static constexpr climate::ClimateFanMode MODES[] = {
climate::CLIMATE_FAN_ON, // bit 0
climate::CLIMATE_FAN_OFF, // bit 1
@@ -61,30 +75,40 @@ template<> constexpr climate::ClimateFanMode EnumBitmask<climate::ClimateFanMode
climate::CLIMATE_FAN_DIFFUSE, // bit 8
climate::CLIMATE_FAN_QUIET, // bit 9
};
return (bit >= 0 && bit < 10) ? MODES[bit] : climate::CLIMATE_FAN_ON;
static constexpr int MODE_COUNT = 10;
return (bit >= 0 && bit < MODE_COUNT) ? MODES[bit] : climate::CLIMATE_FAN_ON;
}
// ClimateSwingMode specialization (4 values: 0-3)
template<> constexpr int EnumBitmask<climate::ClimateSwingMode, 8>::enum_to_bit(climate::ClimateSwingMode mode) {
template<>
constexpr int EnumBitmask<climate::ClimateSwingMode, climate::CLIMATE_SWING_MODE_BITMASK_SIZE>::enum_to_bit(
climate::ClimateSwingMode mode) {
return static_cast<int>(mode); // Direct mapping: enum value = bit position
}
template<> constexpr climate::ClimateSwingMode EnumBitmask<climate::ClimateSwingMode, 8>::bit_to_enum(int bit) {
template<>
inline climate::ClimateSwingMode EnumBitmask<climate::ClimateSwingMode,
climate::CLIMATE_SWING_MODE_BITMASK_SIZE>::bit_to_enum(int bit) {
static constexpr climate::ClimateSwingMode MODES[] = {
climate::CLIMATE_SWING_OFF, // bit 0
climate::CLIMATE_SWING_BOTH, // bit 1
climate::CLIMATE_SWING_VERTICAL, // bit 2
climate::CLIMATE_SWING_HORIZONTAL, // bit 3
};
return (bit >= 0 && bit < 4) ? MODES[bit] : climate::CLIMATE_SWING_OFF;
static constexpr int MODE_COUNT = 4;
return (bit >= 0 && bit < MODE_COUNT) ? MODES[bit] : climate::CLIMATE_SWING_OFF;
}
// ClimatePreset specialization (8 values: 0-7)
template<> constexpr int EnumBitmask<climate::ClimatePreset, 8>::enum_to_bit(climate::ClimatePreset preset) {
template<>
constexpr int EnumBitmask<climate::ClimatePreset, climate::CLIMATE_PRESET_BITMASK_SIZE>::enum_to_bit(
climate::ClimatePreset preset) {
return static_cast<int>(preset); // Direct mapping: enum value = bit position
}
template<> constexpr climate::ClimatePreset EnumBitmask<climate::ClimatePreset, 8>::bit_to_enum(int bit) {
template<>
inline climate::ClimatePreset EnumBitmask<climate::ClimatePreset, climate::CLIMATE_PRESET_BITMASK_SIZE>::bit_to_enum(
int bit) {
static constexpr climate::ClimatePreset PRESETS[] = {
climate::CLIMATE_PRESET_NONE, // bit 0
climate::CLIMATE_PRESET_HOME, // bit 1
@@ -95,7 +119,8 @@ template<> constexpr climate::ClimatePreset EnumBitmask<climate::ClimatePreset,
climate::CLIMATE_PRESET_SLEEP, // bit 6
climate::CLIMATE_PRESET_ACTIVITY, // bit 7
};
return (bit >= 0 && bit < 8) ? PRESETS[bit] : climate::CLIMATE_PRESET_NONE;
static constexpr int PRESET_COUNT = 8;
return (bit >= 0 && bit < PRESET_COUNT) ? PRESETS[bit] : climate::CLIMATE_PRESET_NONE;
}
} // namespace esphome

View File

@@ -150,6 +150,9 @@ class ClimateTraits {
void set_supported_custom_fan_modes(std::initializer_list<std::string> modes) {
this->supported_custom_fan_modes_ = modes;
}
template<size_t N> void set_supported_custom_fan_modes(const char *const (&modes)[N]) {
this->supported_custom_fan_modes_.assign(modes, modes + N);
}
const std::vector<std::string> &get_supported_custom_fan_modes() const { return this->supported_custom_fan_modes_; }
bool supports_custom_fan_mode(const std::string &custom_fan_mode) const {
return vector_contains(this->supported_custom_fan_modes_, custom_fan_mode);
@@ -171,6 +174,9 @@ class ClimateTraits {
void set_supported_custom_presets(std::initializer_list<std::string> presets) {
this->supported_custom_presets_ = presets;
}
template<size_t N> void set_supported_custom_presets(const char *const (&presets)[N]) {
this->supported_custom_presets_.assign(presets, presets + N);
}
const std::vector<std::string> &get_supported_custom_presets() const { return this->supported_custom_presets_; }
bool supports_custom_preset(const std::string &custom_preset) const {
return vector_contains(this->supported_custom_presets_, custom_preset);

View File

@@ -3,6 +3,7 @@
#include <utility>
#include "esphome/components/climate/climate.h"
#include "esphome/components/climate/climate_mode_bitmask.h"
#include "esphome/components/remote_base/remote_base.h"
#include "esphome/components/remote_transmitter/remote_transmitter.h"
#include "esphome/components/sensor/sensor.h"
@@ -24,16 +25,18 @@ class ClimateIR : public Component,
public remote_base::RemoteTransmittable {
public:
ClimateIR(float minimum_temperature, float maximum_temperature, float temperature_step = 1.0f,
bool supports_dry = false, bool supports_fan_only = false, std::set<climate::ClimateFanMode> fan_modes = {},
std::set<climate::ClimateSwingMode> swing_modes = {}, std::set<climate::ClimatePreset> presets = {}) {
bool supports_dry = false, bool supports_fan_only = false,
climate::ClimateFanModeMask fan_modes = climate::ClimateFanModeMask(),
climate::ClimateSwingModeMask swing_modes = climate::ClimateSwingModeMask(),
climate::ClimatePresetMask presets = climate::ClimatePresetMask()) {
this->minimum_temperature_ = minimum_temperature;
this->maximum_temperature_ = maximum_temperature;
this->temperature_step_ = temperature_step;
this->supports_dry_ = supports_dry;
this->supports_fan_only_ = supports_fan_only;
this->fan_modes_ = std::move(fan_modes);
this->swing_modes_ = std::move(swing_modes);
this->presets_ = std::move(presets);
this->fan_modes_ = fan_modes;
this->swing_modes_ = swing_modes;
this->presets_ = presets;
}
void setup() override;
@@ -60,9 +63,9 @@ class ClimateIR : public Component,
bool supports_heat_{true};
bool supports_dry_{false};
bool supports_fan_only_{false};
std::set<climate::ClimateFanMode> fan_modes_ = {};
std::set<climate::ClimateSwingMode> swing_modes_ = {};
std::set<climate::ClimatePreset> presets_ = {};
climate::ClimateFanModeMask fan_modes_{};
climate::ClimateSwingModeMask swing_modes_{};
climate::ClimatePresetMask presets_{};
sensor::Sensor *sensor_{nullptr};
};

View File

@@ -171,26 +171,38 @@ void HaierClimateBase::toggle_power() {
PendingAction({ActionRequest::TOGGLE_POWER, esphome::optional<haier_protocol::HaierMessage>()});
}
void HaierClimateBase::set_supported_swing_modes(const std::set<climate::ClimateSwingMode> &modes) {
void HaierClimateBase::set_supported_swing_modes(climate::ClimateSwingModeMask modes) {
this->traits_.set_supported_swing_modes(modes);
if (!modes.empty())
this->traits_.add_supported_swing_mode(climate::CLIMATE_SWING_OFF);
}
void HaierClimateBase::set_supported_swing_modes(std::initializer_list<climate::ClimateSwingMode> modes) {
this->set_supported_swing_modes(climate::ClimateSwingModeMask(modes));
}
void HaierClimateBase::set_answer_timeout(uint32_t timeout) { this->haier_protocol_.set_answer_timeout(timeout); }
void HaierClimateBase::set_supported_modes(const std::set<climate::ClimateMode> &modes) {
void HaierClimateBase::set_supported_modes(climate::ClimateModeMask modes) {
this->traits_.set_supported_modes(modes);
this->traits_.add_supported_mode(climate::CLIMATE_MODE_OFF); // Always available
this->traits_.add_supported_mode(climate::CLIMATE_MODE_HEAT_COOL); // Always available
}
void HaierClimateBase::set_supported_presets(const std::set<climate::ClimatePreset> &presets) {
void HaierClimateBase::set_supported_modes(std::initializer_list<climate::ClimateMode> modes) {
this->set_supported_modes(climate::ClimateModeMask(modes));
}
void HaierClimateBase::set_supported_presets(climate::ClimatePresetMask presets) {
this->traits_.set_supported_presets(presets);
if (!presets.empty())
this->traits_.add_supported_preset(climate::CLIMATE_PRESET_NONE);
}
void HaierClimateBase::set_supported_presets(std::initializer_list<climate::ClimatePreset> presets) {
this->set_supported_presets(climate::ClimatePresetMask(presets));
}
void HaierClimateBase::set_send_wifi(bool send_wifi) { this->send_wifi_signal_ = send_wifi; }
void HaierClimateBase::send_custom_command(const haier_protocol::HaierMessage &message) {

View File

@@ -1,8 +1,8 @@
#pragma once
#include <chrono>
#include <set>
#include "esphome/components/climate/climate.h"
#include "esphome/components/climate/climate_mode_bitmask.h"
#include "esphome/components/uart/uart.h"
#include "esphome/core/automation.h"
// HaierProtocol
@@ -60,9 +60,12 @@ class HaierClimateBase : public esphome::Component,
void send_power_off_command();
void toggle_power();
void reset_protocol() { this->reset_protocol_request_ = true; };
void set_supported_modes(const std::set<esphome::climate::ClimateMode> &modes);
void set_supported_swing_modes(const std::set<esphome::climate::ClimateSwingMode> &modes);
void set_supported_presets(const std::set<esphome::climate::ClimatePreset> &presets);
void set_supported_modes(esphome::climate::ClimateModeMask modes);
void set_supported_modes(std::initializer_list<esphome::climate::ClimateMode> modes);
void set_supported_swing_modes(esphome::climate::ClimateSwingModeMask modes);
void set_supported_swing_modes(std::initializer_list<esphome::climate::ClimateSwingMode> modes);
void set_supported_presets(esphome::climate::ClimatePresetMask presets);
void set_supported_presets(std::initializer_list<esphome::climate::ClimatePreset> presets);
bool valid_connection() const { return this->protocol_phase_ >= ProtocolPhases::IDLE; };
size_t available() noexcept override { return esphome::uart::UARTDevice::available(); };
size_t read_array(uint8_t *data, size_t len) noexcept override {

View File

@@ -1033,9 +1033,9 @@ haier_protocol::HandlerError HonClimate::process_status_message_(const uint8_t *
{
// Swing mode
ClimateSwingMode old_swing_mode = this->swing_mode;
const std::set<ClimateSwingMode> &swing_modes = traits_.get_supported_swing_modes();
bool vertical_swing_supported = swing_modes.find(CLIMATE_SWING_VERTICAL) != swing_modes.end();
bool horizontal_swing_supported = swing_modes.find(CLIMATE_SWING_HORIZONTAL) != swing_modes.end();
const auto &swing_modes = traits_.get_supported_swing_modes();
bool vertical_swing_supported = swing_modes.contains(CLIMATE_SWING_VERTICAL);
bool horizontal_swing_supported = swing_modes.contains(CLIMATE_SWING_HORIZONTAL);
if (horizontal_swing_supported &&
(packet.control.horizontal_swing_mode == (uint8_t) hon_protocol::HorizontalSwingMode::AUTO)) {
if (vertical_swing_supported &&

View File

@@ -97,11 +97,10 @@ const float TEMP_MAX = 100; // Celsius
class HeatpumpIRClimate : public climate_ir::ClimateIR {
public:
HeatpumpIRClimate()
: climate_ir::ClimateIR(
TEMP_MIN, TEMP_MAX, 1.0f, true, true,
std::set<climate::ClimateFanMode>{climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MEDIUM,
climate::CLIMATE_FAN_HIGH, climate::CLIMATE_FAN_AUTO},
std::set<climate::ClimateSwingMode>{climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_HORIZONTAL,
: climate_ir::ClimateIR(TEMP_MIN, TEMP_MAX, 1.0f, true, true,
{climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MEDIUM, climate::CLIMATE_FAN_HIGH,
climate::CLIMATE_FAN_AUTO},
{climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_HORIZONTAL,
climate::CLIMATE_SWING_VERTICAL, climate::CLIMATE_SWING_BOTH}) {}
void setup() override;
void set_protocol(Protocol protocol) { this->protocol_ = protocol; }

View File

@@ -19,6 +19,9 @@ using climate::ClimateTraits;
using climate::ClimateMode;
using climate::ClimateSwingMode;
using climate::ClimateFanMode;
using climate::ClimateModeMask;
using climate::ClimateSwingModeMask;
using climate::ClimatePresetMask;
class AirConditioner : public ApplianceBase<dudanov::midea::ac::AirConditioner>, public climate::Climate {
public:
@@ -40,20 +43,31 @@ class AirConditioner : public ApplianceBase<dudanov::midea::ac::AirConditioner>,
void do_power_on() { this->base_.setPowerState(true); }
void do_power_off() { this->base_.setPowerState(false); }
void do_power_toggle() { this->base_.setPowerState(this->mode == ClimateMode::CLIMATE_MODE_OFF); }
void set_supported_modes(const std::set<ClimateMode> &modes) { this->supported_modes_ = modes; }
void set_supported_swing_modes(const std::set<ClimateSwingMode> &modes) { this->supported_swing_modes_ = modes; }
void set_supported_presets(const std::set<ClimatePreset> &presets) { this->supported_presets_ = presets; }
void set_custom_presets(const std::set<std::string> &presets) { this->supported_custom_presets_ = presets; }
void set_custom_fan_modes(const std::set<std::string> &modes) { this->supported_custom_fan_modes_ = modes; }
void set_supported_modes(ClimateModeMask modes) { this->supported_modes_ = modes; }
void set_supported_modes(std::initializer_list<ClimateMode> modes) {
this->supported_modes_ = ClimateModeMask(modes);
}
void set_supported_swing_modes(ClimateSwingModeMask modes) { this->supported_swing_modes_ = modes; }
void set_supported_swing_modes(std::initializer_list<ClimateSwingMode> modes) {
this->supported_swing_modes_ = ClimateSwingModeMask(modes);
}
void set_supported_presets(ClimatePresetMask presets) { this->supported_presets_ = presets; }
void set_supported_presets(std::initializer_list<ClimatePreset> presets) {
this->supported_presets_ = ClimatePresetMask(presets);
}
void set_custom_presets(const std::vector<std::string> &presets) { this->supported_custom_presets_ = presets; }
void set_custom_presets(std::initializer_list<std::string> presets) { this->supported_custom_presets_ = presets; }
void set_custom_fan_modes(const std::vector<std::string> &modes) { this->supported_custom_fan_modes_ = modes; }
void set_custom_fan_modes(std::initializer_list<std::string> modes) { this->supported_custom_fan_modes_ = modes; }
protected:
void control(const ClimateCall &call) override;
ClimateTraits traits() override;
std::set<ClimateMode> supported_modes_{};
std::set<ClimateSwingMode> supported_swing_modes_{};
std::set<ClimatePreset> supported_presets_{};
std::set<std::string> supported_custom_presets_{};
std::set<std::string> supported_custom_fan_modes_{};
ClimateModeMask supported_modes_{};
ClimateSwingModeMask supported_swing_modes_{};
ClimatePresetMask supported_presets_{};
std::vector<std::string> supported_custom_presets_{};
std::vector<std::string> supported_custom_fan_modes_{};
Sensor *outdoor_sensor_{nullptr};
Sensor *humidity_sensor_{nullptr};
Sensor *power_sensor_{nullptr};

View File

@@ -71,10 +71,10 @@ class ToshibaClimate : public climate_ir::ClimateIR {
return TOSHIBA_RAS_2819T_TEMP_C_MAX;
return TOSHIBA_GENERIC_TEMP_C_MAX; // Default to GENERIC for unknown models
}
std::set<climate::ClimateSwingMode> toshiba_swing_modes_() {
climate::ClimateSwingModeMask toshiba_swing_modes_() {
return (this->model_ == MODEL_GENERIC)
? std::set<climate::ClimateSwingMode>{}
: std::set<climate::ClimateSwingMode>{climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_VERTICAL};
? climate::ClimateSwingModeMask()
: climate::ClimateSwingModeMask{climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_VERTICAL};
}
void encode_(remote_base::RemoteTransmitData *data, const uint8_t *message, uint8_t nbytes, uint8_t repeat);
bool decode_(remote_base::RemoteReceiveData *data, uint8_t *message, uint8_t nbytes);

View File

@@ -306,18 +306,12 @@ climate::ClimateTraits TuyaClimate::traits() {
traits.add_supported_preset(climate::CLIMATE_PRESET_NONE);
}
if (this->swing_vertical_id_.has_value() && this->swing_horizontal_id_.has_value()) {
std::set<climate::ClimateSwingMode> supported_swing_modes = {
climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_BOTH, climate::CLIMATE_SWING_VERTICAL,
climate::CLIMATE_SWING_HORIZONTAL};
traits.set_supported_swing_modes(std::move(supported_swing_modes));
traits.set_supported_swing_modes({climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_BOTH,
climate::CLIMATE_SWING_VERTICAL, climate::CLIMATE_SWING_HORIZONTAL});
} else if (this->swing_vertical_id_.has_value()) {
std::set<climate::ClimateSwingMode> supported_swing_modes = {climate::CLIMATE_SWING_OFF,
climate::CLIMATE_SWING_VERTICAL};
traits.set_supported_swing_modes(std::move(supported_swing_modes));
traits.set_supported_swing_modes({climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_VERTICAL});
} else if (this->swing_horizontal_id_.has_value()) {
std::set<climate::ClimateSwingMode> supported_swing_modes = {climate::CLIMATE_SWING_OFF,
climate::CLIMATE_SWING_HORIZONTAL};
traits.set_supported_swing_modes(std::move(supported_swing_modes));
traits.set_supported_swing_modes({climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_HORIZONTAL});
}
if (fan_speed_id_) {

View File

@@ -147,7 +147,7 @@ template<typename EnumType, int MaxBits = 16> class EnumBitmask {
// Must be provided by template specialization
// These convert between enum values and bit positions (0, 1, 2, ...)
static constexpr int enum_to_bit(EnumType value);
static constexpr EnumType bit_to_enum(int bit);
static EnumType bit_to_enum(int bit); // Not constexpr due to static array limitation in C++20
bitmask_t mask_{0};
};