diff --git a/components/daikin_s21/climate/daikin_s21_climate.cpp b/components/daikin_s21/climate/daikin_s21_climate.cpp index cc3cc30..cb59767 100644 --- a/components/daikin_s21/climate/daikin_s21_climate.cpp +++ b/components/daikin_s21/climate/daikin_s21_climate.cpp @@ -54,7 +54,7 @@ climate::ClimateTraits DaikinS21Climate::traits() { climate::CLIMATE_MODE_COOL, climate::CLIMATE_MODE_HEAT, climate::CLIMATE_MODE_FAN_ONLY, climate::CLIMATE_MODE_DRY}); - traits.set_supported_custom_fan_modes({"Automatic", "1", "2", "3", "4", "5"}); + traits.set_supported_custom_fan_modes({"Automatic", "Silent", "1", "2", "3", "4", "5"}); traits.set_supported_swing_modes({ climate::CLIMATE_SWING_OFF, @@ -232,6 +232,8 @@ const std::string DaikinS21Climate::d2e_fan_mode(DaikinFanMode mode) { return "4"; case DaikinFanMode::Speed5: return "5"; + case DaikinFanMode::Silent: + return "Silent"; case DaikinFanMode::Auto: default: return "Automatic"; @@ -241,6 +243,8 @@ const std::string DaikinS21Climate::d2e_fan_mode(DaikinFanMode mode) { DaikinFanMode DaikinS21Climate::e2d_fan_mode(std::string mode) { if (mode == "Automatic") return DaikinFanMode::Auto; + if (mode == "Silent") + return DaikinFanMode::Silent; if (mode == "1") return DaikinFanMode::Speed1; if (mode == "2") diff --git a/components/daikin_s21/s21.cpp b/components/daikin_s21/s21.cpp index 45d6e56..88c99e3 100644 --- a/components/daikin_s21/s21.cpp +++ b/components/daikin_s21/s21.cpp @@ -37,6 +37,8 @@ std::string daikin_fan_mode_to_string(DaikinFanMode mode) { switch (mode) { case DaikinFanMode::Auto: return "Auto"; + case DaikinFanMode::Silent: + return "Silent"; case DaikinFanMode::Speed1: return "1"; case DaikinFanMode::Speed2: @@ -85,6 +87,8 @@ int16_t temp_bytes_to_c10(std::vector &bytes) { return temp_bytes_to_c10(&bytes[0]); } +int16_t temp_f9_byte_to_c10(uint8_t *bytes) { return (*bytes / 2 - 64) * 10; } + uint8_t c10_to_setpoint_byte(int16_t setpoint) { return (setpoint + 3) / 5 + 28; } @@ -220,10 +224,16 @@ bool DaikinS21::read_frame(std::vector &payload) { bytes.pop_back(); uint8_t calc_csum = s21_checksum(bytes); if (calc_csum != frame_csum) { - ESP_LOGW(TAG, "Checksum mismatch: %x (frame) != %x (calc from %s)", - frame_csum, calc_csum, - hex_repr(&bytes[0], bytes.size()).c_str()); - return false; + // This sometimes happens with G9 reply, no idea why + if (bytes[0] == 0x47 && bytes[1] == 0x39) { + calc_csum += 2; + } + if (calc_csum != frame_csum) { + ESP_LOGW(TAG, "Checksum mismatch: %x (frame) != %x (calc from %s)", + frame_csum, calc_csum, + hex_repr(&bytes[0], bytes.size()).c_str()); + return false; + } } break; } @@ -307,6 +317,10 @@ bool DaikinS21::parse_response(std::vector rcode, this->swing_v = payload[0] & 1; this->swing_h = payload[0] & 2; return true; + case '9': // F9 -> G9 -- Inside temperature + this->temp_inside = temp_f9_byte_to_c10(&payload[0]); + this->temp_outside = temp_f9_byte_to_c10(&payload[1]); + return true; } break; case 'S': // R -> S @@ -354,10 +368,15 @@ bool DaikinS21::run_queries(std::vector queries) { } void DaikinS21::update() { - std::vector queries = {"F1", "F5", "RH", "RI", "Ra", "RL", "Rd"}; - if (this->run_queries(queries) && !this->ready) { - ESP_LOGI(TAG, "Daikin S21 Ready"); - this->ready = true; + std::vector queries = {"F1", "F5", "Rd"}; + // These queries might fail but they won't affect the basic functionality + std::vector failable_queries = {"F9", "RH", "RI", "Ra", "RL"}; + if (this->run_queries(queries)) { + this->run_queries(failable_queries); + if(!this->ready) { + ESP_LOGI(TAG, "Daikin S21 Ready"); + this->ready = true; + } } if (this->debug_protocol) { this->dump_state(); diff --git a/components/daikin_s21/s21.h b/components/daikin_s21/s21.h index a725622..9004f96 100644 --- a/components/daikin_s21/s21.h +++ b/components/daikin_s21/s21.h @@ -17,6 +17,7 @@ enum class DaikinClimateMode : uint8_t { enum class DaikinFanMode : uint8_t { Auto = 'A', + Silent = 'B', Speed1 = '3', Speed2 = '4', Speed3 = '5', diff --git a/components/s21_sim/s21_sim.cpp b/components/s21_sim/s21_sim.cpp index f7a55f3..704d418 100644 --- a/components/s21_sim/s21_sim.cpp +++ b/components/s21_sim/s21_sim.cpp @@ -189,6 +189,8 @@ void S21SIM::handle_req(std::vector req) { // nak } else if (code == "F8") { res.assign({'G', '8', '0', 0x00, 0x00, 0x00}); + } else if (code == "F9") { + res.assign({'G', '9', 0xB2, 0xB4, 0xFF, 0x30}); } else if (code == "FU0F") { // ?? // nak } else if (code == "RH") { // Inside temp