From 192abf95ce44edfbf5f98b1ec85457a64ed2d8c0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 28 Nov 2025 21:07:02 -0600 Subject: [PATCH] [fan] Use uint8_t for speed_count and fix tuya max=256 validation bug --- esphome/components/fan/fan_traits.h | 8 ++++---- esphome/components/hbridge/fan/__init__.py | 2 +- esphome/components/hbridge/fan/hbridge_fan.h | 4 ++-- esphome/components/speed/fan/__init__.py | 2 +- esphome/components/speed/fan/speed_fan.h | 4 ++-- esphome/components/template/fan/__init__.py | 2 +- esphome/components/template/fan/template_fan.h | 4 ++-- esphome/components/tuya/fan/__init__.py | 2 +- esphome/components/tuya/fan/tuya_fan.h | 4 ++-- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/esphome/components/fan/fan_traits.h b/esphome/components/fan/fan_traits.h index 24987fe984..e22ac916c5 100644 --- a/esphome/components/fan/fan_traits.h +++ b/esphome/components/fan/fan_traits.h @@ -11,7 +11,7 @@ namespace fan { class FanTraits { public: FanTraits() = default; - FanTraits(bool oscillation, bool speed, bool direction, int speed_count) + FanTraits(bool oscillation, bool speed, bool direction, uint8_t speed_count) : oscillation_(oscillation), speed_(speed), direction_(direction), speed_count_(speed_count) {} /// Return if this fan supports oscillation. @@ -23,9 +23,9 @@ class FanTraits { /// Set whether this fan supports speed levels. void set_speed(bool speed) { this->speed_ = speed; } /// Return how many speed levels the fan has - int supported_speed_count() const { return this->speed_count_; } + uint8_t supported_speed_count() const { return this->speed_count_; } /// Set how many speed levels this fan has. - void set_supported_speed_count(int speed_count) { this->speed_count_ = speed_count; } + void set_supported_speed_count(uint8_t speed_count) { this->speed_count_ = speed_count; } /// Return if this fan supports changing direction bool supports_direction() const { return this->direction_; } /// Set whether this fan supports changing direction @@ -61,7 +61,7 @@ class FanTraits { bool oscillation_{false}; bool speed_{false}; bool direction_{false}; - int speed_count_{}; + uint8_t speed_count_{}; std::vector preset_modes_{}; }; diff --git a/esphome/components/hbridge/fan/__init__.py b/esphome/components/hbridge/fan/__init__.py index 31a20a8981..7a86c1b6b7 100644 --- a/esphome/components/hbridge/fan/__init__.py +++ b/esphome/components/hbridge/fan/__init__.py @@ -39,7 +39,7 @@ CONFIG_SCHEMA = ( cv.Optional(CONF_DECAY_MODE, default="SLOW"): cv.enum( DECAY_MODE_OPTIONS, upper=True ), - cv.Optional(CONF_SPEED_COUNT, default=100): cv.int_range(min=1), + cv.Optional(CONF_SPEED_COUNT, default=100): cv.int_range(min=1, max=255), cv.Optional(CONF_ENABLE_PIN): cv.use_id(output.FloatOutput), cv.Optional(CONF_PRESET_MODES): validate_preset_modes, } diff --git a/esphome/components/hbridge/fan/hbridge_fan.h b/esphome/components/hbridge/fan/hbridge_fan.h index ec1e8ada0e..f6ffabfd30 100644 --- a/esphome/components/hbridge/fan/hbridge_fan.h +++ b/esphome/components/hbridge/fan/hbridge_fan.h @@ -15,7 +15,7 @@ enum DecayMode { class HBridgeFan : public Component, public fan::Fan { public: - HBridgeFan(int speed_count, DecayMode decay_mode) : speed_count_(speed_count), decay_mode_(decay_mode) {} + HBridgeFan(uint8_t speed_count, DecayMode decay_mode) : speed_count_(speed_count), decay_mode_(decay_mode) {} void set_pin_a(output::FloatOutput *pin_a) { pin_a_ = pin_a; } void set_pin_b(output::FloatOutput *pin_b) { pin_b_ = pin_b; } @@ -33,7 +33,7 @@ class HBridgeFan : public Component, public fan::Fan { output::FloatOutput *pin_b_; output::FloatOutput *enable_{nullptr}; output::BinaryOutput *oscillating_{nullptr}; - int speed_count_{}; + uint8_t speed_count_{}; DecayMode decay_mode_{DECAY_MODE_SLOW}; fan::FanTraits traits_; std::vector preset_modes_{}; diff --git a/esphome/components/speed/fan/__init__.py b/esphome/components/speed/fan/__init__.py index 3c495f3160..b5dbf03211 100644 --- a/esphome/components/speed/fan/__init__.py +++ b/esphome/components/speed/fan/__init__.py @@ -25,7 +25,7 @@ CONFIG_SCHEMA = ( cv.Optional(CONF_SPEED): cv.invalid( "Configuring individual speeds is deprecated." ), - cv.Optional(CONF_SPEED_COUNT, default=100): cv.int_range(min=1), + cv.Optional(CONF_SPEED_COUNT, default=100): cv.int_range(min=1, max=255), cv.Optional(CONF_PRESET_MODES): validate_preset_modes, } ) diff --git a/esphome/components/speed/fan/speed_fan.h b/esphome/components/speed/fan/speed_fan.h index e9a389e0f3..16e6c277ce 100644 --- a/esphome/components/speed/fan/speed_fan.h +++ b/esphome/components/speed/fan/speed_fan.h @@ -10,7 +10,7 @@ namespace speed { class SpeedFan : public Component, public fan::Fan { public: - SpeedFan(int speed_count) : speed_count_(speed_count) {} + SpeedFan(uint8_t speed_count) : speed_count_(speed_count) {} void setup() override; void dump_config() override; void set_output(output::FloatOutput *output) { this->output_ = output; } @@ -26,7 +26,7 @@ class SpeedFan : public Component, public fan::Fan { output::FloatOutput *output_; output::BinaryOutput *oscillating_{nullptr}; output::BinaryOutput *direction_{nullptr}; - int speed_count_{}; + uint8_t speed_count_{}; fan::FanTraits traits_; std::vector preset_modes_{}; }; diff --git a/esphome/components/template/fan/__init__.py b/esphome/components/template/fan/__init__.py index 72b20e1efe..1ab092ca0e 100644 --- a/esphome/components/template/fan/__init__.py +++ b/esphome/components/template/fan/__init__.py @@ -19,7 +19,7 @@ CONFIG_SCHEMA = ( { cv.Optional(CONF_HAS_DIRECTION, default=False): cv.boolean, cv.Optional(CONF_HAS_OSCILLATING, default=False): cv.boolean, - cv.Optional(CONF_SPEED_COUNT): cv.int_range(min=1), + cv.Optional(CONF_SPEED_COUNT): cv.int_range(min=1, max=255), cv.Optional(CONF_PRESET_MODES): validate_preset_modes, } ) diff --git a/esphome/components/template/fan/template_fan.h b/esphome/components/template/fan/template_fan.h index 052b385b93..a7bb75425d 100644 --- a/esphome/components/template/fan/template_fan.h +++ b/esphome/components/template/fan/template_fan.h @@ -13,7 +13,7 @@ class TemplateFan final : public Component, public fan::Fan { void dump_config() override; 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_speed_count(uint8_t count) { this->speed_count_ = count; } void set_preset_modes(std::initializer_list presets) { this->preset_modes_ = presets; } fan::FanTraits get_traits() override { return this->traits_; } @@ -22,7 +22,7 @@ class TemplateFan final : public Component, public fan::Fan { bool has_oscillating_{false}; bool has_direction_{false}; - int speed_count_{0}; + uint8_t speed_count_{0}; fan::FanTraits traits_; std::vector preset_modes_{}; }; diff --git a/esphome/components/tuya/fan/__init__.py b/esphome/components/tuya/fan/__init__.py index de95888b6b..dd8626115f 100644 --- a/esphome/components/tuya/fan/__init__.py +++ b/esphome/components/tuya/fan/__init__.py @@ -22,7 +22,7 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_SPEED_DATAPOINT): cv.uint8_t, cv.Optional(CONF_SWITCH_DATAPOINT): cv.uint8_t, cv.Optional(CONF_DIRECTION_DATAPOINT): cv.uint8_t, - cv.Optional(CONF_SPEED_COUNT, default=3): cv.int_range(min=1, max=256), + cv.Optional(CONF_SPEED_COUNT, default=3): cv.int_range(min=1, max=255), } ) .extend(cv.COMPONENT_SCHEMA), diff --git a/esphome/components/tuya/fan/tuya_fan.h b/esphome/components/tuya/fan/tuya_fan.h index 527efa8246..93b4fc39ae 100644 --- a/esphome/components/tuya/fan/tuya_fan.h +++ b/esphome/components/tuya/fan/tuya_fan.h @@ -9,7 +9,7 @@ namespace tuya { class TuyaFan : public Component, public fan::Fan { public: - TuyaFan(Tuya *parent, int speed_count) : parent_(parent), speed_count_(speed_count) {} + TuyaFan(Tuya *parent, uint8_t speed_count) : parent_(parent), speed_count_(speed_count) {} void setup() override; void dump_config() override; void set_speed_id(uint8_t speed_id) { this->speed_id_ = speed_id; } @@ -27,7 +27,7 @@ class TuyaFan : public Component, public fan::Fan { optional switch_id_{}; optional oscillation_id_{}; optional direction_id_{}; - int speed_count_{}; + uint8_t speed_count_{}; TuyaDatapointType speed_type_{}; TuyaDatapointType oscillation_type_{}; };