diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b242572 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "githubPullRequests.ignoredPullRequestBranches": [ + "main" + ] +} \ No newline at end of file diff --git a/components/toshiba_suzumi/toshiba_climate.cpp b/components/toshiba_suzumi/toshiba_climate.cpp index f0f6ef3..92ceed1 100644 --- a/components/toshiba_suzumi/toshiba_climate.cpp +++ b/components/toshiba_suzumi/toshiba_climate.cpp @@ -223,6 +223,10 @@ void ToshibaClimateUart::parseResponse(std::vector rawData) { switch (sensor) { case ToshibaCommandType::TARGET_TEMP: ESP_LOGI(TAG, "Received target temp: %d", value); + if (this->special_mode_ == SPECIAL_MODE::EIGHT_DEG) { + value -= SPECIAL_TEMP_OFFSET; + ESP_LOGI(TAG, "Note: Special Mode \"%s\" is active, shifting target temp to %d", SPECIAL_MODE_EIGHT_DEG, value); + } this->target_temperature = value; break; case ToshibaCommandType::FAN: { @@ -284,12 +288,14 @@ void ToshibaClimateUart::parseResponse(std::vector rawData) { this->power_state_ = climateState; break; } - case ToshibaCommandType::SPECIAL_MODE: { - auto special_mode = IntToSpecialMode(static_cast(value)); + case ToshibaCommandType::SPECIAL_MODE: { + this->special_mode_ = static_cast(value); + auto special_mode = IntToSpecialMode(this->special_mode_.value()); ESP_LOGI(TAG, "Received special mode: %d", value); if (special_mode_select_ != nullptr) { special_mode_select_->publish_state(special_mode); } + this->publish_state(); break; } default: @@ -348,7 +354,28 @@ void ToshibaClimateUart::control(const climate::ClimateCall &call) { if (call.get_target_temperature().has_value()) { auto target_temp = *call.get_target_temperature(); uint8_t intTemp = (uint8_t) target_temp; + bool special_mode_changed = false; + if (intTemp >= this->min_temp_ && this->special_mode_ == SPECIAL_MODE::EIGHT_DEG) { + this->special_mode_ = SPECIAL_MODE::STANDARD; + special_mode_changed = true; + ESP_LOGD(TAG, "Changing to Standard Mode"); + } + else if (intTemp < this->min_temp_ && this->special_mode_ != SPECIAL_MODE::EIGHT_DEG) + { + this->special_mode_ = SPECIAL_MODE::EIGHT_DEG; + special_mode_changed = true; + ESP_LOGD(TAG, "Changing to FrostGuard Mode"); + } + if (special_mode_changed) { + this->sendCmd(ToshibaCommandType::SPECIAL_MODE, static_cast(this->special_mode_.value())); + special_mode_select_->publish_state(IntToSpecialMode(this->special_mode_.value())); + } + ESP_LOGD(TAG, "Setting target temp to %d", intTemp); + if (this->special_mode_ == SPECIAL_MODE::EIGHT_DEG) { + intTemp += SPECIAL_TEMP_OFFSET; + ESP_LOGD(TAG, "Note: Special Mode \"%s\" active, shifting setpoint temp to %d", SPECIAL_MODE_EIGHT_DEG, intTemp); + } this->target_temperature = target_temp; this->sendCmd(ToshibaCommandType::TARGET_TEMP, intTemp); } @@ -408,9 +435,10 @@ ClimateTraits ToshibaClimateUart::traits() { traits.add_supported_custom_fan_mode(CUSTOM_FAN_LEVEL_4); traits.add_supported_custom_fan_mode(CUSTOM_FAN_LEVEL_5); - traits.set_visual_temperature_step(1); - traits.set_visual_min_temperature(this->min_temp_); + traits.set_visual_temperature_step(1); + traits.set_visual_min_temperature(SPECIAL_MODE_EIGHT_DEG_MIN_TEMP); traits.set_visual_max_temperature(MAX_TEMP); + return traits; } @@ -422,10 +450,21 @@ void ToshibaClimateUart::on_set_pwr_level(const std::string &value) { } void ToshibaClimateUart::on_set_special_mode(const std::string &value) { + auto new_special_mode = SpecialModeToInt(value); ESP_LOGD(TAG, "Setting special mode to %s", value.c_str()); - auto special_mode = SpecialModeToInt(value); - this->sendCmd(ToshibaCommandType::SPECIAL_MODE, static_cast(special_mode.value())); + this->sendCmd(ToshibaCommandType::SPECIAL_MODE, static_cast(new_special_mode.value())); special_mode_select_->publish_state(value); + if (new_special_mode != this->special_mode_) { + if (this->special_mode_ == SPECIAL_MODE::EIGHT_DEG && this->target_temperature < this->min_temp_) { + this->target_temperature = NORMAL_MODE_DEF_TEMP; + } + this->special_mode_ = new_special_mode; + if (new_special_mode == SPECIAL_MODE::EIGHT_DEG && this->target_temperature >= this->min_temp_) { + this->target_temperature = SPECIAL_MODE_EIGHT_DEG_DEF_TEMP; + } + + this->publish_state(); + } } void ToshibaPwrModeSelect::control(const std::string &value) { parent_->on_set_pwr_level(value); } diff --git a/components/toshiba_suzumi/toshiba_climate.h b/components/toshiba_suzumi/toshiba_climate.h index 417e04d..fcc8c0a 100644 --- a/components/toshiba_suzumi/toshiba_climate.h +++ b/components/toshiba_suzumi/toshiba_climate.h @@ -12,6 +12,11 @@ namespace toshiba_suzumi { static const char *const TAG = "ToshibaClimateUart"; static const uint8_t MAX_TEMP = 30; +static const uint8_t SPECIAL_TEMP_OFFSET = 16; +static const uint8_t SPECIAL_MODE_EIGHT_DEG_MIN_TEMP = 5; +static const uint8_t SPECIAL_MODE_EIGHT_DEG_MAX_TEMP = 13; +static const uint8_t SPECIAL_MODE_EIGHT_DEG_DEF_TEMP = 8; +static const uint8_t NORMAL_MODE_DEF_TEMP = 20; static const std::vector HANDSHAKE[6] = { {2, 255, 255, 0, 0, 0, 0, 2}, {2, 255, 255, 1, 0, 0, 1, 2, 254}, {2, 0, 0, 0, 0, 0, 2, 2, 2, 250}, @@ -58,6 +63,7 @@ class ToshibaClimateUart : public PollingComponent, public climate::Climate, pub uint32_t last_command_timestamp_ = 0; uint32_t last_rx_char_timestamp_ = 0; STATE power_state_ = STATE::OFF; + optional special_mode_ = SPECIAL_MODE::STANDARD; select::Select *pwr_select_ = nullptr; sensor::Sensor *outdoor_temp_sensor_ = nullptr; bool horizontal_swing_ = false;