mirror of
https://github.com/esphome/esphome.git
synced 2025-10-28 21:53:48 +00:00
merge
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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};
|
||||
};
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -97,12 +97,11 @@ 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::CLIMATE_SWING_VERTICAL, climate::CLIMATE_SWING_BOTH}) {}
|
||||
: 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; }
|
||||
void set_horizontal_default(HorizontalDirection horizontal_direction) {
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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_) {
|
||||
|
||||
@@ -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};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user