diff --git a/src/ir_Haier.cpp b/src/ir_Haier.cpp index bc919efe9..00e84c03e 100644 --- a/src/ir_Haier.cpp +++ b/src/ir_Haier.cpp @@ -1578,7 +1578,7 @@ void IRHaierAC160::setMode(uint8_t mode) { default: setMode(kHaierAcYrw02Auto); // Unexpected, default to auto mode. } - _.AuxHeat = (_.Mode == kHaierAcYrw02Heat); // Set this bit only if heat mode. + _.AuxHeating = (_.Mode == kHaierAcYrw02Heat); // Set only if heat mode. } /// Get the operating mode setting of the A/C. @@ -1751,6 +1751,17 @@ void IRHaierAC160::setQuiet(const bool on) { } } +/// Get the value of the Aux Heating setting. +/// @return true, the setting is on. false, the setting is off. +bool IRHaierAC160::getAuxHeating(void) const { return _.AuxHeating; } + +/// Change the Aux Heating setting. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRHaierAC160::setAuxHeating(const bool on) { + _.Button = kHaierAc160ButtonAuxHeating; + _.AuxHeating = on; +} + /// Get the value of the current Light toggle setting. /// @return true, the setting is on. false, the setting is off. /// @note This setting seems to be controlled just by the button setting. @@ -2071,6 +2082,9 @@ String IRHaierAC160::toString(void) const { case kHaierAc160ButtonLight: result += kLightStr; break; + case kHaierAc160ButtonAuxHeating: + result += kHeatingStr; + break; case kHaierAcYrw02ButtonCFAB: result += kCelsiusFahrenheitStr; break; @@ -2137,6 +2151,7 @@ String IRHaierAC160::toString(void) const { tmode != kHaierAcYrw02OnTimer) ? minsToString(getOffTimer()) : kOffStr, kOffTimerStr); result += addBoolToString(_.Lock, kLockStr); + result += addBoolToString(_.AuxHeating, kHeatingStr); return result; } // End of IRHaierAC160 class. diff --git a/src/ir_Haier.h b/src/ir_Haier.h index 9ea205c5c..4f33a0283 100644 --- a/src/ir_Haier.h +++ b/src/ir_Haier.h @@ -195,6 +195,7 @@ const uint8_t kHaierAcYrw02ButtonSleep = 0b01011; const uint8_t kHaierAcYrw02ButtonTimer = 0b10000; const uint8_t kHaierAcYrw02ButtonLock = 0b10100; const uint8_t kHaierAc160ButtonLight = 0b10101; +const uint8_t kHaierAc160ButtonAuxHeating = 0b10110; const uint8_t kHaierAc160ButtonClean = 0b11001; const uint8_t kHaierAcYrw02ButtonCFAB = 0b11010; @@ -294,7 +295,7 @@ union HaierAc160Protocol{ // Byte 4 uint8_t :6; uint8_t Power :1; - uint8_t AuxHeat :1; + uint8_t AuxHeating :1; // Byte 5 uint8_t OffTimerHrs :5; uint8_t Fan :3; @@ -604,6 +605,8 @@ class IRHaierAC160 { void setTurbo(const bool on); bool getQuiet(void) const; void setQuiet(const bool on); + bool getAuxHeating(void) const; + void setAuxHeating(const bool on); uint8_t getSwingV(void) const; void setSwingV(const uint8_t pos); diff --git a/test/IRac_test.cpp b/test/IRac_test.cpp index ce89d0d23..b0475e023 100644 --- a/test/IRac_test.cpp +++ b/test/IRac_test.cpp @@ -828,7 +828,7 @@ TEST(TestIRac, Haier160) { "Power: On, Button: 5 (Power), Mode: 1 (Cool), Temp: 23C, " "Fan: 2 (Medium), Turbo: On, Quiet: Off, Swing(V): 4 (High), Sleep: On, " "Clean: On, Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, " - "Lock: Off"; + "Lock: Off, Heating: Off"; ac.begin(); irac.haier160(&ac, true, // Power diff --git a/test/ir_Haier_test.cpp b/test/ir_Haier_test.cpp index dcc60961a..ab9a8c02d 100644 --- a/test/ir_Haier_test.cpp +++ b/test/ir_Haier_test.cpp @@ -1590,7 +1590,8 @@ TEST(TestDecodeHaierAC160, RealExample) { EXPECT_EQ( "Power: On, Button: 5 (Power), Mode: 1 (Cool), Temp: 26C, Fan: 3 (Low), " "Turbo: Off, Quiet: Off, Swing(V): 12 (Auto), Sleep: Off, Clean: Off, " - "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off", + "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off, " + "Heating: Off", IRAcUtils::resultAcToString(&irsend.capture)); stdAc::state_t result, prev; ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev)); @@ -1617,7 +1618,8 @@ TEST(TestDecodeHaierAC160, SyntheticExample) { EXPECT_EQ( "Power: On, Button: 5 (Power), Mode: 1 (Cool), Temp: 26C, Fan: 3 (Low), " "Turbo: Off, Quiet: Off, Swing(V): 12 (Auto), Sleep: Off, Clean: Off, " - "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off", + "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off, " + "Heating: Off", IRAcUtils::resultAcToString(&irsend.capture)); stdAc::state_t result, prev; ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev)); @@ -1655,15 +1657,15 @@ TEST(TestHaierAC160Class, OperatingMode) { ac.setMode(kHaierAcYrw02Cool); EXPECT_EQ(kHaierAcYrw02Cool, ac.getMode()); - EXPECT_FALSE(ac._.AuxHeat); + EXPECT_FALSE(ac.getAuxHeating()); ac.setMode(kHaierAcYrw02Heat); EXPECT_EQ(kHaierAcYrw02Heat, ac.getMode()); - EXPECT_TRUE(ac._.AuxHeat); + EXPECT_TRUE(ac.getAuxHeating()); ac.setMode(kHaierAcYrw02Fan); EXPECT_EQ(kHaierAcYrw02Fan, ac.getMode()); - EXPECT_FALSE(ac._.AuxHeat); + EXPECT_FALSE(ac.getAuxHeating()); ac.setMode(kHaierAcYrw02Dry); EXPECT_EQ(kHaierAcYrw02Dry, ac.getMode()); @@ -1791,7 +1793,7 @@ TEST(TestHaierAC160Class, CleanMode) { "Power: On, Button: 25 (Clean), Mode: 1 (Cool), Temp: 26C, " "Fan: 3 (Low), Turbo: Off, Quiet: Off, Swing(V): 12 (Auto), " "Sleep: Off, Clean: On, Timer Mode: 0 (N/A), " - "On Timer: Off, Off Timer: Off, Lock: Off", + "On Timer: Off, Off Timer: Off, Lock: Off, Heating: Off", ac.toString()); // No clean set. // https://docs.google.com/spreadsheets/d/1RNJ7esbArS5fy1lmiM-i1PekXSNojCMad4WuuyunsC8/edit#gid=2048081808&range=FR4 @@ -1804,7 +1806,7 @@ TEST(TestHaierAC160Class, CleanMode) { "Power: On, Button: 5 (Power), Mode: 1 (Cool), Temp: 26C, " "Fan: 3 (Low), Turbo: Off, Quiet: Off, Swing(V): 12 (Auto), " "Sleep: Off, Clean: Off, Timer Mode: 0 (N/A), " - "On Timer: Off, Off Timer: Off, Lock: Off", + "On Timer: Off, Off Timer: Off, Lock: Off, Heating: Off", ac.toString()); } @@ -1974,6 +1976,38 @@ TEST(TestHaierAC160Class, Light) { "Power: On, Button: 21 (Light), Mode: 1 (Cool), Temp: 26C, " "Fan: 3 (Low), Turbo: Off, Quiet: Off, Swing(V): 12 (Auto), " "Sleep: Off, Clean: Off, Timer Mode: 0 (N/A), " - "On Timer: Off, Off Timer: Off, Lock: Off", + "On Timer: Off, Off Timer: Off, Lock: Off, Heating: Off", + ac.toString()); +} + +TEST(TestHaierAC160Class, AuxHeating) { + IRHaierAC160 ac(kGpioUnused); + ac.begin(); + + ac.setAuxHeating(true); + EXPECT_TRUE(ac.getAuxHeating()); + EXPECT_EQ(kHaierAc160ButtonAuxHeating, ac.getButton()); + + ac.setButton(kHaierAcYrw02ButtonTempUp); + ac.setAuxHeating(false); + EXPECT_FALSE(ac.getAuxHeating()); + EXPECT_EQ(kHaierAc160ButtonAuxHeating, ac.getButton()); + + ac.setAuxHeating(true); + EXPECT_TRUE(ac.getAuxHeating()); + EXPECT_EQ(kHaierAc160ButtonAuxHeating, ac.getButton()); + + // https://docs.google.com/spreadsheets/d/1RNJ7esbArS5fy1lmiM-i1PekXSNojCMad4WuuyunsC8/edit#gid=2048081808&range=A124:W143 + const uint8_t aux_button_off[kHaierAC160StateLength] = { + 0xA6, 0xAC, 0x00, 0x00, 0x40, 0x60, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x16, 0x88, 0xB5, 0x00, 0x60, 0x00, 0x00, 0x15}; + ac.setRaw(aux_button_off); + EXPECT_FALSE(ac.getAuxHeating()); + EXPECT_EQ(kHaierAc160ButtonAuxHeating, ac.getButton()); + EXPECT_EQ( + "Power: On, Button: 22 (Heating), Mode: 4 (Heat), Temp: 26C, " + "Fan: 3 (Low), Turbo: Off, Quiet: Off, Swing(V): 12 (Auto), " + "Sleep: Off, Clean: Off, Timer Mode: 0 (N/A), " + "On Timer: Off, Off Timer: Off, Lock: Off, Heating: Off", ac.toString()); }