diff --git a/README.md b/README.md index 98ffa6d..70a3191 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ An ESPHome component for the Winix C545 air purifier. - Full local control of the air purifier via Home Assistant or MQTT. - Physical device controls remain functional and changes are immediately reflected in the frontend. - AQI, AQI indicator, filter age, filter lifetime and light intensity sensors. -- Switches to control Plasmawave, Auto and Sleep modes. +- Switch to control Plasmawave. +- Auto and Sleep modes are implemented as fan presets. - Piggybacks on the OEM protocol with minimal hardware modifications required. - The OEM app can (theoretically) remain functional. @@ -105,8 +106,4 @@ switch: - platform: winix_c545 plasmawave: name: Plasmawave - auto: - name: Auto - sleep: - name: Sleep ``` diff --git a/components/winix_c545/switch.py b/components/winix_c545/switch.py index a65e597..09a3f5d 100644 --- a/components/winix_c545/switch.py +++ b/components/winix_c545/switch.py @@ -9,15 +9,8 @@ WinixC545PlasmawaveSwitch = winix_c545_ns.class_( "WinixC545PlasmawaveSwitch", switch.Switch) -WinixC545AutoSwitch = winix_c545_ns.class_( - "WinixC545AutoSwitch", switch.Switch) -WinixC545SleepSwitch = winix_c545_ns.class_( - "WinixC545SleepSwitch", switch.Switch) -# TODO auto and sleep should be presets not switches but fan doesn't support presets currently CONF_PLASMAWAVE = "plasmawave" -CONF_AUTO = "auto" -CONF_SLEEP = "sleep" CONFIG_SCHEMA = cv.Schema( { @@ -26,16 +19,6 @@ WinixC545PlasmawaveSwitch, device_class=DEVICE_CLASS_SWITCH, icon="mdi:lightning-bolt-outline", - ), - cv.Optional(CONF_AUTO): switch.switch_schema( - WinixC545AutoSwitch, - device_class=DEVICE_CLASS_SWITCH, - icon="mdi:auto-mode", - ), - cv.Optional(CONF_SLEEP): switch.switch_schema( - WinixC545SleepSwitch, - device_class=DEVICE_CLASS_SWITCH, - icon="mdi:sleep", ) } ) @@ -48,13 +31,3 @@ async def to_code(config) -> None: sw = await switch.new_switch(switch_config) await cg.register_parented(sw, config[CONF_WINIX_C545_ID]) cg.add(component.set_plasmawave_switch(sw)) - - if switch_config := config.get(CONF_AUTO): - sw = await switch.new_switch(switch_config) - await cg.register_parented(sw, config[CONF_WINIX_C545_ID]) - cg.add(component.set_auto_switch(sw)) - - if switch_config := config.get(CONF_SLEEP): - sw = await switch.new_switch(switch_config) - await cg.register_parented(sw, config[CONF_WINIX_C545_ID]) - cg.add(component.set_sleep_switch(sw)) diff --git a/components/winix_c545/winix_c545.cpp b/components/winix_c545/winix_c545.cpp index 8294f4e..5c69711 100644 --- a/components/winix_c545/winix_c545.cpp +++ b/components/winix_c545/winix_c545.cpp @@ -163,28 +163,6 @@ void WinixC545Component::publish_state_() { this->plasmawave_switch_->publish_state(state); break; } - - case StateKey::Auto: { - // Auto - if (this->auto_switch_ == nullptr) - continue; - - bool state = value == 1; - if (state != this->auto_switch_->state) - this->auto_switch_->publish_state(state); - break; - } - - case StateKey::Speed: { - // Sleep is a speed value - if (this->sleep_switch_ == nullptr) - continue; - - bool state = value == 6; - if (state != this->sleep_switch_->state) - this->sleep_switch_->publish_state(state); - break; - } } } @@ -438,8 +416,6 @@ void WinixC545Component::dump_config() { #ifdef USE_SWITCH LOG_SWITCH(" ", "Plasmawave Switch", this->plasmawave_switch_); - LOG_SWITCH(" ", "Auto Switch", this->auto_switch_); - LOG_SWITCH(" ", "Sleep Switch", this->sleep_switch_); #endif } @@ -503,6 +479,29 @@ void WinixC545Fan::update_state(const WinixStateMap &states) { // Speed has changed, publish this->speed = speed; + + // Set preset mode to Sleep if speed indicates sleep and Auto is not enabled + if (this->preset_mode != PRESET_AUTO) + this->preset_mode = (value == 6) ? PRESET_SLEEP : PRESET_NONE; + + publish = true; + + break; + } + + case StateKey::Auto: { + // Auto + std::string preset_mode = this->preset_mode; + if (value == 1) + preset_mode = PRESET_AUTO; + else if (this->preset_mode == PRESET_AUTO) + preset_mode = PRESET_NONE; + + if (preset_mode == this->preset_mode) + continue; + + // Preset has changed, publish + this->preset_mode = preset_mode; publish = true; break; @@ -529,6 +528,18 @@ void WinixC545Fan::control(const fan::FanCall &call) { states.emplace(StateKey::Speed, this->speed == 4 ? 5 : this->speed); } + if (this->preset_mode != call.get_preset_mode()) { + this->preset_mode = call.get_preset_mode(); + + // Update auto mode + if (this->preset_mode == PRESET_AUTO) + states.emplace(StateKey::Auto, 1); + + // Set sleep mode + if (this->preset_mode == PRESET_SLEEP) + states.emplace(StateKey::Speed, 6); + } + this->parent_->write_state(states); this->publish_state(); } diff --git a/components/winix_c545/winix_c545.h b/components/winix_c545/winix_c545.h index 8dade39..8e968d2 100644 --- a/components/winix_c545/winix_c545.h +++ b/components/winix_c545/winix_c545.h @@ -68,9 +68,6 @@ class WinixC545Component : public uart::UARTDevice, public Component { #ifdef USE_SWITCH SUB_SWITCH(plasmawave) - // TODO the following belong as presets, not switches - SUB_SWITCH(auto) - SUB_SWITCH(sleep) #endif public: @@ -121,16 +118,25 @@ class WinixC545Component : public uart::UARTDevice, public Component { class WinixC545Fan : public fan::Fan, public Parented { public: - fan::FanTraits get_traits() override { + WinixC545Fan() { // Only support speed control with 4 levels: Low, Med, High, Turbo - return fan::FanTraits(false, true, false, 4); + this->traits_ = fan::FanTraits(false, true, false, 4); + // Add presets + this->traits_.set_supported_preset_modes({PRESET_AUTO, PRESET_SLEEP}); } + fan::FanTraits get_traits() override { return this->traits_; } + void dump_config(); void update_state(const WinixStateMap &); protected: + const std::string PRESET_NONE{""}; + const std::string PRESET_SLEEP{"Sleep"}; + const std::string PRESET_AUTO{"Auto"}; + void control(const fan::FanCall &call) override; + fan::FanTraits traits_; }; class WinixC545Switch : public switch_::Switch, public Parented { @@ -150,16 +156,5 @@ class WinixC545PlasmawaveSwitch : public WinixC545Switch { WinixC545PlasmawaveSwitch() : WinixC545Switch(StateKey::Plasmawave) {} }; -class WinixC545AutoSwitch : public WinixC545Switch { - public: - WinixC545AutoSwitch() : WinixC545Switch(StateKey::Auto, 1, 2) {} -}; - -class WinixC545SleepSwitch : public WinixC545Switch { - public: - // Sleep switch operates on fan speed, switch to low when turned off - WinixC545SleepSwitch() : WinixC545Switch(StateKey::Speed, 6, 1) {} -}; - } // namespace winix_c545 } // namespace esphome \ No newline at end of file diff --git a/example.yaml b/example.yaml index fb19c90..6f43e5f 100644 --- a/example.yaml +++ b/example.yaml @@ -36,8 +36,4 @@ text_sensor: switch: - platform: winix_c545 plasmawave: - name: Plasmawave - auto: - name: Auto - sleep: - name: Sleep + name: Plasmawave \ No newline at end of file