diff --git a/src/ir_Daikin.cpp b/src/ir_Daikin.cpp index 8aa6a73a2..bb5f45368 100644 --- a/src/ir_Daikin.cpp +++ b/src/ir_Daikin.cpp @@ -2205,7 +2205,7 @@ bool IRrecv::decodeDaikin160(decode_results *results, uint16_t offset, #if SEND_DAIKIN176 /// Send a Daikin176 (176-bit) A/C formatted message. -/// Status: Alpha / Untested on a real device. +/// Status: STABLE / Working on a real device. /// @param[in] data The message to be sent. /// @param[in] nbytes The number of bytes of message to be sent. /// @param[in] repeat The number of times the command is to be repeated. @@ -2322,34 +2322,42 @@ void IRDaikin176::off(void) { setPower(false); } /// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin176::setPower(const bool on) { remote_state[kDaikin176ByteModeButton] = 0; - setBit(&remote_state[kDaikin176BytePower], kDaikinBitPowerOffset, on); + setBit(&remote_state[kDaikin176ByteModePower], kDaikinBitPowerOffset, on); } /// Get the value of the current power setting. /// @return true, the setting is on. false, the setting is off. bool IRDaikin176::getPower(void) { - return GETBIT8(remote_state[kDaikin176BytePower], kDaikinBitPowerOffset); + return GETBIT8(remote_state[kDaikin176ByteModePower], kDaikinBitPowerOffset); } /// Get the operating mode setting of the A/C. /// @return The current operating mode setting. uint8_t IRDaikin176::getMode(void) { - return GETBITS8(remote_state[kDaikin176ByteMode], kHighNibble, kModeBitsSize); + return GETBITS8(remote_state[kDaikin176ByteModePower], kHighNibble, + kModeBitsSize); } /// Set the operating mode of the A/C. /// @param[in] mode The desired operating mode. void IRDaikin176::setMode(const uint8_t mode) { uint8_t altmode = 0; + // Daikin172 has some alternate/additional mode bits that need to be changed + // in line with the operating mode. The following few lines match up these + // bits with the corresponding operating bits. switch (mode) { - case kDaikinFan: altmode = 0; break; - case kDaikinDry: altmode = 7; break; - case kDaikin176Cool: altmode = 2; break; - default: this->setMode(kDaikin176Cool); return; - } - // Set the mode. - setBits(&remote_state[kDaikin176ByteMode], kHighNibble, kModeBitsSize, mode); - setBits(&remote_state[kDaikin176BytePower], kHighNibble, kModeBitsSize, + case kDaikin176Dry: altmode = 2; break; + case kDaikin176Fan: altmode = 6; break; + case kDaikin176Auto: + case kDaikin176Cool: + case kDaikin176Heat: altmode = 7; break; + default: setMode(kDaikin176Cool); return; + } + // Set the mode bits. + setBits(&remote_state[kDaikin176ByteModePower], kHighNibble, kModeBitsSize, + mode); + // Set the additional mode bits. + setBits(&remote_state[kDaikin176ByteAltMode], kHighNibble, kModeBitsSize, altmode); setTemp(_saved_temp); // Needs to happen after setTemp() as it will clear it. @@ -2361,10 +2369,11 @@ void IRDaikin176::setMode(const uint8_t mode) { /// @return The native equivilant of the enum. uint8_t IRDaikin176::convertMode(const stdAc::opmode_t mode) { switch (mode) { - case stdAc::opmode_t::kDry: return kDaikinDry; - case stdAc::opmode_t::kHeat: // Heat not supported, but fan is the closest. - case stdAc::opmode_t::kFan: return kDaikinFan; - default: return kDaikin176Cool; + case stdAc::opmode_t::kDry: return kDaikin176Dry; + case stdAc::opmode_t::kHeat: return kDaikin176Heat; + case stdAc::opmode_t::kFan: return kDaikin176Fan; + case stdAc::opmode_t::kAuto: return kDaikin176Auto; + default: return kDaikin176Cool; } } @@ -2373,9 +2382,10 @@ uint8_t IRDaikin176::convertMode(const stdAc::opmode_t mode) { /// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRDaikin176::toCommonMode(const uint8_t mode) { switch (mode) { - case kDaikinDry: return stdAc::opmode_t::kDry; - case kDaikinHeat: // There is no heat mode, but fan is the closest. - case kDaikinFan: return stdAc::opmode_t::kFan; + case kDaikin176Dry: return stdAc::opmode_t::kDry; + case kDaikin176Heat: return stdAc::opmode_t::kHeat; + case kDaikin176Fan: return stdAc::opmode_t::kFan; + case kDaikin176Auto: return stdAc::opmode_t::kAuto; default: return stdAc::opmode_t::kCool; } } @@ -2386,8 +2396,8 @@ void IRDaikin176::setTemp(const uint8_t temp) { uint8_t degrees = std::min(kDaikinMaxTemp, std::max(temp, kDaikinMinTemp)); _saved_temp = degrees; switch (getMode()) { - case kDaikinDry: - case kDaikinFan: + case kDaikin176Dry: + case kDaikin176Fan: degrees = kDaikin176DryFanTemp; } setBits(&remote_state[kDaikin176ByteTemp], kDaikin176TempOffset, @@ -2519,8 +2529,8 @@ String IRDaikin176::toString(void) { String result = ""; result.reserve(80); // Reserve some heap for the string to reduce fragging. result += addBoolToString(getPower(), kPowerStr, false); - result += addModeToString(getMode(), kDaikinAuto, kDaikin176Cool, kDaikinHeat, - kDaikinDry, kDaikinFan); + result += addModeToString(getMode(), kDaikin176Auto, kDaikin176Cool, + kDaikin176Heat, kDaikin176Dry, kDaikin176Fan); result += addTempToString(getTemp()); result += addFanToString(getFan(), kDaikin176FanMax, kDaikinFanMin, kDaikinFanMin, kDaikinFanMin, kDaikinFanMin); diff --git a/src/ir_Daikin.h b/src/ir_Daikin.h index 35e62302b..c47968486 100644 --- a/src/ir_Daikin.h +++ b/src/ir_Daikin.h @@ -31,6 +31,8 @@ // Brand: Daikin, Model: ARC423A5 remote (DAIKIN160) // Brand: Daikin, Model: FTE12HV2S A/C // Brand: Daikin, Model: BRC4C153 remote (DAIKIN176) +// Brand: Daikin, Model: FFQ35B8V1B A/C (DAIKIN176) +// Brand: Daikin, Model: BRC4C151 remote (DAIKIN176) // Brand: Daikin, Model: 17 Series A/C (DAIKIN128) // Brand: Daikin, Model: FTXB12AXVJU A/C (DAIKIN128) // Brand: Daikin, Model: FTXB09AXVJU A/C (DAIKIN128) @@ -342,9 +344,13 @@ const uint16_t kDaikin176Sections = 2; const uint16_t kDaikin176Section1Length = 7; const uint16_t kDaikin176Section2Length = kDaikin176StateLength - kDaikin176Section1Length; -const uint8_t kDaikin176Cool = 0b111; // 7 -const uint8_t kDaikin176BytePower = 14; -const uint8_t kDaikin176ByteMode = 12; +const uint8_t kDaikin176ByteAltMode = 12; +const uint8_t kDaikin176ByteModePower = 14; +const uint8_t kDaikin176Fan = 0b000; // 0 +const uint8_t kDaikin176Heat = 0b001; // 1 +const uint8_t kDaikin176Cool = 0b010; // 2 +const uint8_t kDaikin176Auto = 0b011; // 3 +const uint8_t kDaikin176Dry = 0b111; // 7 const uint8_t kDaikin176MaskMode = 0b01110000; const uint8_t kDaikin176ByteModeButton = 13; const uint8_t kDaikin176ModeButton = 0b00000100; diff --git a/test/IRac_test.cpp b/test/IRac_test.cpp index f91be3459..6b8501384 100644 --- a/test/IRac_test.cpp +++ b/test/IRac_test.cpp @@ -368,7 +368,7 @@ TEST(TestIRac, Daikin176) { IRac irac(kGpioUnused); IRrecv capture(kGpioUnused); char expected[] = - "Power: On, Mode: 7 (Cool), Temp: 26C, Fan: 1 (Low), Swing(H): 5 (Auto)"; + "Power: On, Mode: 2 (Cool), Temp: 26C, Fan: 1 (Low), Swing(H): 5 (Auto)"; ac.begin(); irac.daikin176(&ac, diff --git a/test/ir_Daikin_test.cpp b/test/ir_Daikin_test.cpp index f57888c23..6fd2f6755 100644 --- a/test/ir_Daikin_test.cpp +++ b/test/ir_Daikin_test.cpp @@ -2315,20 +2315,20 @@ TEST(TestDaikin176Class, FanControl) { IRDaikin176 ac(0); EXPECT_EQ( - "Power: Off, Mode: 7 (Cool), Temp: 9C, Fan: 1 (Low), Swing(H): 6 (Off)", + "Power: Off, Mode: 2 (Cool), Temp: 9C, Fan: 1 (Low), Swing(H): 6 (Off)", ac.toString()); ac.setFan(kDaikinFanMin); ac.setPower(true); EXPECT_EQ( - "Power: On, Mode: 7 (Cool), Temp: 9C, Fan: 1 (Low), Swing(H): 6 (Off)", + "Power: On, Mode: 2 (Cool), Temp: 9C, Fan: 1 (Low), Swing(H): 6 (Off)", ac.toString()); ac.setFan(kDaikinFanMin + 1); EXPECT_EQ( - "Power: On, Mode: 7 (Cool), Temp: 9C, Fan: 3 (High), Swing(H): 6 (Off)", + "Power: On, Mode: 2 (Cool), Temp: 9C, Fan: 3 (High), Swing(H): 6 (Off)", ac.toString()); ac.setFan(kDaikin176FanMax); EXPECT_EQ( - "Power: On, Mode: 7 (Cool), Temp: 9C, Fan: 3 (High), Swing(H): 6 (Off)", + "Power: On, Mode: 2 (Cool), Temp: 9C, Fan: 3 (High), Swing(H): 6 (Off)", ac.toString()); // Real state from remote @@ -2339,7 +2339,7 @@ TEST(TestDaikin176Class, FanControl) { 0x00, 0x20, 0x25}; ac.setRaw(state); EXPECT_EQ( - "Power: On, Mode: 7 (Cool), Temp: 26C, Fan: 3 (High), " + "Power: On, Mode: 2 (Cool), Temp: 26C, Fan: 3 (High), " "Swing(H): 5 (Auto)", ac.toString()); } @@ -2365,11 +2365,11 @@ TEST(TestDaikin176Class, SimulateIRacDaikin176) { ac.setFan(ac.convertFan(stdAc::fanspeed_t::kMax)); ac.setSwingHorizontal(kDaikin176SwingHOff); EXPECT_EQ( - "Power: On, Mode: 7 (Cool), Temp: 26C, Fan: 3 (High), Swing(H): 6 (Off)", + "Power: On, Mode: 2 (Cool), Temp: 26C, Fan: 3 (High), Swing(H): 6 (Off)", ac.toString()); ac.setSwingHorizontal(ac.convertSwingH(stdAc::swingh_t::kAuto)); EXPECT_EQ( - "Power: On, Mode: 7 (Cool), Temp: 26C, Fan: 3 (High), " + "Power: On, Mode: 2 (Cool), Temp: 26C, Fan: 3 (High), " "Swing(H): 5 (Auto)", ac.toString()); } @@ -2378,25 +2378,25 @@ TEST(TestDaikin176Class, OperatingMode) { IRDaikin176 ac(0); ac.begin(); - ac.setMode(kDaikinAuto); - EXPECT_EQ(kDaikin176Cool, ac.getMode()); + ac.setMode(kDaikin176Auto); + EXPECT_EQ(kDaikin176Auto, ac.getMode()); ac.setMode(kDaikin176Cool); EXPECT_EQ(kDaikin176Cool, ac.getMode()); - ac.setMode(kDaikinDry); - EXPECT_EQ(kDaikinDry, ac.getMode()); + ac.setMode(kDaikin176Dry); + EXPECT_EQ(kDaikin176Dry, ac.getMode()); - ac.setMode(kDaikinHeat); - EXPECT_EQ(kDaikin176Cool, ac.getMode()); + ac.setMode(kDaikin176Heat); + EXPECT_EQ(kDaikin176Heat, ac.getMode()); - ac.setMode(kDaikinFan); - EXPECT_EQ(kDaikinFan, ac.getMode()); + ac.setMode(kDaikin176Fan); + EXPECT_EQ(kDaikin176Fan, ac.getMode()); - ac.setMode(kDaikin176Cool + 1); + ac.setMode(kDaikin176Dry + 1); EXPECT_EQ(kDaikin176Cool, ac.getMode()); - ac.setMode(kDaikinAuto + 1); + ac.setMode(kDaikin176Auto + 1); EXPECT_EQ(kDaikin176Cool, ac.getMode()); ac.setMode(255); @@ -2406,7 +2406,7 @@ TEST(TestDaikin176Class, OperatingMode) { TEST(TestDaikin176Class, Temperature) { IRDaikin176 ac(0); ac.begin(); - ac.setMode(kDaikinAuto); + ac.setMode(kDaikin176Auto); ac.setTemp(0); EXPECT_EQ(kDaikinMinTemp, ac.getTemp()); @@ -2438,19 +2438,19 @@ TEST(TestDaikin176Class, Temperature) { EXPECT_EQ(29, ac.getTemp()); // Temp should be locked to kDaikin176DryFanTemp when in Dry or Fan Mode. - ac.setMode(kDaikinFan); + ac.setMode(kDaikin176Fan); EXPECT_EQ(kDaikin176DryFanTemp, ac.getTemp()); ac.setMode(kDaikin176Cool); EXPECT_EQ(29, ac.getTemp()); - ac.setMode(kDaikinDry); - EXPECT_EQ(kDaikinDry, ac.getMode()); + ac.setMode(kDaikin176Dry); + EXPECT_EQ(kDaikin176Dry, ac.getMode()); EXPECT_EQ(kDaikin176DryFanTemp, ac.getTemp()); ac.setMode(kDaikin176Cool); EXPECT_EQ(29, ac.getTemp()); - ac.setMode(kDaikinFan); + ac.setMode(kDaikin176Fan); ac.setTemp(25); EXPECT_EQ(kDaikin176DryFanTemp, ac.getTemp()); - ac.setMode(kDaikinHeat); + ac.setMode(kDaikin176Heat); EXPECT_EQ(25, ac.getTemp()); } @@ -2531,9 +2531,9 @@ TEST(TestDaikin176Class, ReconstructKnownStates) { ac.setFan(kDaikin176FanMax); ac.setSwingHorizontal(true); EXPECT_STATE_EQ(on_cool_25_max_auto, ac.getRaw(), kDaikin176Bits); - ac.setMode(kDaikinFan); + ac.setMode(kDaikin176Fan); EXPECT_STATE_EQ(on_fan_17_max_auto, ac.getRaw(), kDaikin176Bits); - ac.setMode(kDaikinDry); + ac.setMode(kDaikin176Dry); EXPECT_STATE_EQ(on_dry_17_max_auto, ac.getRaw(), kDaikin176Bits); ac.setMode(kDaikin176Cool); EXPECT_STATE_EQ(on_cool_25_max_auto_v2, ac.getRaw(), kDaikin176Bits);