From 3909982a21ae5972df6a7f12a711afb231e7db40 Mon Sep 17 00:00:00 2001 From: crankyoldgit Date: Wed, 20 Oct 2021 23:11:25 +1000 Subject: [PATCH 1/2] [ELECTRA_AC] Add support for "IFeel" setting. * Add `(set|get)IFeel()` & `(set|get)IFeelTemp()` methods. * Add and update Unit test coverage. For #1644 Co-Authored-By: @Aculeasis --- src/ir_Electra.cpp | 42 ++++++++++++++++++++++-- src/ir_Electra.h | 21 ++++++++++-- test/IRac_test.cpp | 3 +- test/ir_Electra_test.cpp | 69 +++++++++++++++++++++++++++++++++++----- 4 files changed, 121 insertions(+), 14 deletions(-) diff --git a/src/ir_Electra.cpp b/src/ir_Electra.cpp index 7945cb0ad..5b547da1d 100644 --- a/src/ir_Electra.cpp +++ b/src/ir_Electra.cpp @@ -1,4 +1,4 @@ -// Copyright 2018, 2019 David Conran +// Copyright 2018-2021 David Conran /// @file /// @brief Support for Electra A/C protocols. /// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/AUXHeatpumpIR.cpp @@ -310,6 +310,37 @@ bool IRElectraAc::getTurbo(void) const { return _.Turbo; } +/// Get the IFeel mode of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRElectraAc::getIFeel(void) const { return _.IFeel; } + +/// Set the IFeel mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRElectraAc::setIFeel(const bool on) { + _.IFeel = on; + if (_.IFeel) + // Make sure there is a reasonable value in _.IFeelTemp + setIFeelTemp(getIFeelTemp()); + else + // Clear any previous stored temp.. + _.IFeelTemp = kElectraAcIFeelMinTemp; +} + +/// Set the temperature for the IFeel mode. +/// @param[in] temp The temperature in degrees celsius. +void IRElectraAc::setIFeelTemp(const uint8_t temp) { + _.IFeelTemp = std::min(kElectraAcIFeelMaxTemp, + std::max(kElectraAcIFeelMinTemp, temp)) + + kElectraAcIFeelTempDelta; +} + +/// Get the current temperature setting for the IFeel mode. +/// @return The current setting for temp. in degrees celsius. +uint8_t IRElectraAc::getIFeelTemp(void) const { + return std::max(kElectraAcIFeelTempDelta, _.IFeelTemp) - + kElectraAcIFeelTempDelta; +} + /// Convert the current internal state into its stdAc::state_t equivalent. /// @return The stdAc equivalent of the native settings. stdAc::state_t IRElectraAc::toCommon(void) const { @@ -342,7 +373,7 @@ stdAc::state_t IRElectraAc::toCommon(void) const { /// @return A human readable string. String IRElectraAc::toString(void) const { String result = ""; - result.reserve(130); // Reserve some heap for the string to reduce fragging. + result.reserve(160); // Reserve some heap for the string to reduce fragging. result += addBoolToString(_.Power, kPowerStr, false); result += addModeToString(_.Mode, kElectraAcAuto, kElectraAcCool, kElectraAcHeat, kElectraAcDry, kElectraAcFan); @@ -355,6 +386,13 @@ String IRElectraAc::toString(void) const { result += addToggleToString(getLightToggle(), kLightStr); result += addBoolToString(_.Clean, kCleanStr); result += addBoolToString(_.Turbo, kTurboStr); + result += addBoolToString(_.IFeel, kIFeelStr); + if (_.IFeel) { + result += kCommaSpaceStr; + result += kIFeelStr; + result += ' '; + result += addTempToString(getIFeelTemp(), true, false); + } return result; } diff --git a/src/ir_Electra.h b/src/ir_Electra.h index 886a92c56..85df532ca 100644 --- a/src/ir_Electra.h +++ b/src/ir_Electra.h @@ -1,4 +1,4 @@ -// Copyright 2019 David Conran +// Copyright 2019-2021 David Conran /// @file /// @brief Support for Electra A/C protocols. /// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/AUXHeatpumpIR.cpp @@ -9,6 +9,10 @@ // Brand: Electra, Model: Classic INV 17 / AXW12DCS A/C // Brand: Electra, Model: YKR-M/003E remote // Brand: Frigidaire, Model: FGPC102AB1 A/C +// Brand: Subtropic, Model: SUB-07HN1_18Y A/C +// Brand: Subtropic, Model: YKR-H/102E remote +// Brand: Centek, Model: SCT-65Q09 A/C +// Brand: Centek, Model: YKR-P/002E remote #ifndef IR_ELECTRA_H_ #define IR_ELECTRA_H_ @@ -46,10 +50,12 @@ union ElectraProtocol { uint8_t Turbo :1; uint8_t :1; // Byte 6 - uint8_t :5; + uint8_t :3; + uint8_t IFeel :1; + uint8_t :1; uint8_t Mode :3; // Byte 7 - uint8_t :8; + uint8_t IFeelTemp :8; // Byte 8 uint8_t :8; // Byte 9 @@ -93,6 +99,11 @@ const uint8_t kElectraAcLightToggleMask = 0x11; // and known OFF values of 0x08 (0b00001000) & 0x05 (0x00000101) const uint8_t kElectraAcLightToggleOff = 0x08; +// Re: Byte[7]. Or Delta == 0xA and Temperature are stored in last 6 bits, +// and bit 7 stores Unknown flag +const uint8_t kElectraAcIFeelTempDelta = 0x4A; +const uint8_t kElectraAcIFeelMinTemp = 0; // 0C +const uint8_t kElectraAcIFeelMaxTemp = 50; // 50C // Classes /// Class for handling detailed Electra A/C messages. @@ -130,6 +141,10 @@ class IRElectraAc { bool getLightToggle(void) const; void setTurbo(const bool on); bool getTurbo(void) const; + void setIFeel(const bool on); + bool getIFeel(void) const; + void setIFeelTemp(const uint8_t temp); + uint8_t getIFeelTemp(void) const; uint8_t* getRaw(void); void setRaw(const uint8_t new_code[], const uint16_t length = kElectraAcStateLength); diff --git a/test/IRac_test.cpp b/test/IRac_test.cpp index 7ff512e28..a6036dd1c 100644 --- a/test/IRac_test.cpp +++ b/test/IRac_test.cpp @@ -560,7 +560,8 @@ TEST(TestIRac, Electra) { IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 6 (Fan), Temp: 26C, Fan: 1 (High), " - "Swing(V): On, Swing(H): On, Light: Toggle, Clean: On, Turbo: On"; + "Swing(V): On, Swing(H): On, Light: Toggle, Clean: On, Turbo: On, " + "IFeel: Off"; ac.begin(); irac.electra(&ac, diff --git a/test/ir_Electra_test.cpp b/test/ir_Electra_test.cpp index 1fddf537b..4ba58b2fa 100644 --- a/test/ir_Electra_test.cpp +++ b/test/ir_Electra_test.cpp @@ -101,7 +101,8 @@ TEST(TestDecodeElectraAC, RealExampleDecode) { EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); EXPECT_EQ( "Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), " - "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off", + "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off, " + "IFeel: Off", IRAcUtils::resultAcToString(&irsend.capture)); stdAc::state_t r, p; ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p)); @@ -235,7 +236,8 @@ TEST(TestIRElectraAcClass, HumanReadable) { ac.setRaw(on_cool_32C_auto_voff); EXPECT_EQ( "Power: On, Mode: 1 (Cool), Temp: 32C, Fan: 5 (Auto), " - "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off", + "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off, " + "IFeel: Off", ac.toString()); uint8_t on_cool_16C_auto_voff[13] = { 0xC3, 0x47, 0xE0, 0x00, 0xA0, 0x00, 0x20, @@ -243,7 +245,8 @@ TEST(TestIRElectraAcClass, HumanReadable) { ac.setRaw(on_cool_16C_auto_voff); EXPECT_EQ( "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 5 (Auto), " - "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off", + "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off, " + "IFeel: Off", ac.toString()); uint8_t on_cool_16C_low_voff[13] = { 0xC3, 0x47, 0xE0, 0x00, 0x60, 0x00, 0x20, @@ -251,7 +254,8 @@ TEST(TestIRElectraAcClass, HumanReadable) { ac.setRaw(on_cool_16C_low_voff); EXPECT_EQ( "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 3 (Low), " - "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off", + "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off, " + "IFeel: Off", ac.toString()); } @@ -275,7 +279,8 @@ TEST(TestIRElectraAcClass, Clean) { ac.setRaw(on); EXPECT_EQ( "Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), " - "Swing(V): Off, Swing(H): Off, Light: Toggle, Clean: On, Turbo: Off", + "Swing(V): Off, Swing(H): Off, Light: Toggle, Clean: On, Turbo: Off, " + "IFeel: Off", ac.toString()); } @@ -301,7 +306,8 @@ TEST(TestIRElectraAcClass, Turbo) { ac.setRaw(on); EXPECT_EQ( "Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), " - "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: On", + "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: On, " + "IFeel: Off", ac.toString()); } @@ -325,7 +331,8 @@ TEST(TestIRElectraAcClass, LightToggle) { ac.setRaw(on); EXPECT_EQ( "Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), " - "Swing(V): Off, Swing(H): Off, Light: Toggle, Clean: On, Turbo: Off", + "Swing(V): Off, Swing(H): Off, Light: Toggle, Clean: On, Turbo: Off, " + "IFeel: Off", ac.toString()); } @@ -352,8 +359,54 @@ TEST(TestIRElectraAcClass, ConstructKnownState) { EXPECT_EQ( "Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), " - "Swing(V): Off, Swing(H): Off, Light: Toggle, Clean: On, Turbo: Off", + "Swing(V): Off, Swing(H): Off, Light: Toggle, Clean: On, Turbo: Off, " + "IFeel: Off", ac.toString()); EXPECT_STATE_EQ(on_cool_24C_fan1_swing_off_turbo_off_clean_on, ac.getRaw(), kElectraAcBits); } + +TEST(TestIRElectraAcClass, IFeel) { + IRElectraAc ac(kGpioUnused); + ac.stateReset(); + // Test a real example. + const uint8_t ifeel_on[kElectraAcStateLength] = { + 0xC3, 0x6F, 0xE0, 0x00, 0xA0, 0x00, 0x28, + 0x64, 0x00, 0x20, 0x00, 0x1E, 0x7C}; + ac.setRaw(ifeel_on); + EXPECT_TRUE(ac.getIFeel()); + EXPECT_EQ(26, ac.getIFeelTemp()); + EXPECT_EQ( + "Power: On, Mode: 1 (Cool), Temp: 21C, Fan: 5 (Auto), " + "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off, " + "IFeel: On, IFeel Temp: 26C", + ac.toString()); + + ac.stateReset(); + EXPECT_FALSE(ac.getIFeel()); + EXPECT_EQ(kElectraAcIFeelMinTemp, ac.getIFeelTemp()); + + ac.setIFeel(true); + EXPECT_TRUE(ac.getIFeel()); + EXPECT_EQ(kElectraAcIFeelMinTemp, ac.getIFeelTemp()); + + ac.setIFeelTemp(kElectraAcIFeelMaxTemp); + EXPECT_EQ(kElectraAcIFeelMaxTemp, ac.getIFeelTemp()); + + ac.setIFeelTemp(kElectraAcIFeelMaxTemp + 1); + EXPECT_EQ(kElectraAcIFeelMaxTemp, ac.getIFeelTemp()); + + ac.setIFeel(false); + EXPECT_FALSE(ac.getIFeel()); + EXPECT_EQ(kElectraAcIFeelMinTemp, ac.getIFeelTemp()); + EXPECT_EQ(0, ac._.IFeelTemp); + + ac.setIFeel(true); + ac.setIFeelTemp(kElectraAcIFeelMinTemp); + EXPECT_TRUE(ac.getIFeel()); + EXPECT_EQ(kElectraAcIFeelMinTemp, ac.getIFeelTemp()); + + ac.setIFeelTemp(26); // Celsius + EXPECT_TRUE(ac.getIFeel()); + EXPECT_EQ(26, ac.getIFeelTemp()); +} From 4087c0205467eafd6fd4708aefbbf1f0efc45846 Mon Sep 17 00:00:00 2001 From: crankyoldgit Date: Sun, 24 Oct 2021 07:37:20 +1000 Subject: [PATCH 2/2] Changes for Sensor Temp & silent update * Change IFeelTemp to SensorTemp. * Add support for the silent Sensor Temp updates. * Update & add to the Unit Tests. For #1644 --- src/ir_Electra.cpp | 75 ++++++++++++++++++++++++---------------- src/ir_Electra.h | 18 ++++++---- test/ir_Electra_test.cpp | 52 ++++++++++++++++++++-------- 3 files changed, 93 insertions(+), 52 deletions(-) diff --git a/src/ir_Electra.cpp b/src/ir_Electra.cpp index 5b547da1d..b4d670b88 100644 --- a/src/ir_Electra.cpp +++ b/src/ir_Electra.cpp @@ -319,26 +319,41 @@ bool IRElectraAc::getIFeel(void) const { return _.IFeel; } void IRElectraAc::setIFeel(const bool on) { _.IFeel = on; if (_.IFeel) - // Make sure there is a reasonable value in _.IFeelTemp - setIFeelTemp(getIFeelTemp()); + // Make sure there is a reasonable value in _.SensorTemp + setSensorTemp(getSensorTemp()); else // Clear any previous stored temp.. - _.IFeelTemp = kElectraAcIFeelMinTemp; + _.SensorTemp = kElectraAcSensorMinTemp; } -/// Set the temperature for the IFeel mode. +/// Get the silent Sensor Update setting of the message. +/// i.e. Is this _just_ a sensor temp update message from the remote? +/// @note The A/C just takes the sensor temp value from the message and +/// will not follow any of the other settings in the message. +/// @return true, the setting is on. false, the setting is off. +bool IRElectraAc::getSensorUpdate(void) const { return _.SensorUpdate; } + +/// Set the silent Sensor Update setting of the message. +/// i.e. Is this _just_ a sensor temp update message from the remote? +/// @note The A/C will just take the sensor temp value from the message and +/// will not follow any of the other settings in the message. If set, the A/C +/// unit will also not beep in response to the message. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRElectraAc::setSensorUpdate(const bool on) { _.SensorUpdate = on; } + +/// Set the Sensor temperature for the IFeel mode. /// @param[in] temp The temperature in degrees celsius. -void IRElectraAc::setIFeelTemp(const uint8_t temp) { - _.IFeelTemp = std::min(kElectraAcIFeelMaxTemp, - std::max(kElectraAcIFeelMinTemp, temp)) + - kElectraAcIFeelTempDelta; +void IRElectraAc::setSensorTemp(const uint8_t temp) { + _.SensorTemp = std::min(kElectraAcSensorMaxTemp, + std::max(kElectraAcSensorMinTemp, temp)) + + kElectraAcSensorTempDelta; } -/// Get the current temperature setting for the IFeel mode. +/// Get the current sensor temperature setting for the IFeel mode. /// @return The current setting for temp. in degrees celsius. -uint8_t IRElectraAc::getIFeelTemp(void) const { - return std::max(kElectraAcIFeelTempDelta, _.IFeelTemp) - - kElectraAcIFeelTempDelta; +uint8_t IRElectraAc::getSensorTemp(void) const { + return std::max(kElectraAcSensorTempDelta, _.SensorTemp) - + kElectraAcSensorTempDelta; } /// Convert the current internal state into its stdAc::state_t equivalent. @@ -374,24 +389,24 @@ stdAc::state_t IRElectraAc::toCommon(void) const { String IRElectraAc::toString(void) const { String result = ""; result.reserve(160); // Reserve some heap for the string to reduce fragging. - result += addBoolToString(_.Power, kPowerStr, false); - result += addModeToString(_.Mode, kElectraAcAuto, kElectraAcCool, - kElectraAcHeat, kElectraAcDry, kElectraAcFan); - result += addTempToString(getTemp()); - result += addFanToString(_.Fan, kElectraAcFanHigh, kElectraAcFanLow, - kElectraAcFanAuto, kElectraAcFanAuto, - kElectraAcFanMed); - result += addBoolToString(getSwingV(), kSwingVStr); - result += addBoolToString(getSwingH(), kSwingHStr); - result += addToggleToString(getLightToggle(), kLightStr); - result += addBoolToString(_.Clean, kCleanStr); - result += addBoolToString(_.Turbo, kTurboStr); - result += addBoolToString(_.IFeel, kIFeelStr); - if (_.IFeel) { - result += kCommaSpaceStr; - result += kIFeelStr; - result += ' '; - result += addTempToString(getIFeelTemp(), true, false); + if (!_.SensorUpdate) { + result += addBoolToString(_.Power, kPowerStr, false); + result += addModeToString(_.Mode, kElectraAcAuto, kElectraAcCool, + kElectraAcHeat, kElectraAcDry, kElectraAcFan); + result += addTempToString(getTemp()); + result += addFanToString(_.Fan, kElectraAcFanHigh, kElectraAcFanLow, + kElectraAcFanAuto, kElectraAcFanAuto, + kElectraAcFanMed); + result += addBoolToString(getSwingV(), kSwingVStr); + result += addBoolToString(getSwingH(), kSwingHStr); + result += addToggleToString(getLightToggle(), kLightStr); + result += addBoolToString(_.Clean, kCleanStr); + result += addBoolToString(_.Turbo, kTurboStr); + result += addBoolToString(_.IFeel, kIFeelStr); + } + if (_.IFeel || _.SensorUpdate) { + result += addIntToString(getSensorTemp(), kSensorTempStr, !_.SensorUpdate); + result += 'C'; } return result; } diff --git a/src/ir_Electra.h b/src/ir_Electra.h index 85df532ca..8fd4ee182 100644 --- a/src/ir_Electra.h +++ b/src/ir_Electra.h @@ -41,7 +41,9 @@ union ElectraProtocol { uint8_t :5; uint8_t SwingH :3; // Byte 3 - uint8_t :8; + uint8_t :6; + uint8_t SensorUpdate :1; + uint8_t :1; // Byte 4 uint8_t :5; uint8_t Fan :3; @@ -55,7 +57,7 @@ union ElectraProtocol { uint8_t :1; uint8_t Mode :3; // Byte 7 - uint8_t IFeelTemp :8; + uint8_t SensorTemp :8; // Byte 8 uint8_t :8; // Byte 9 @@ -101,9 +103,9 @@ const uint8_t kElectraAcLightToggleOff = 0x08; // Re: Byte[7]. Or Delta == 0xA and Temperature are stored in last 6 bits, // and bit 7 stores Unknown flag -const uint8_t kElectraAcIFeelTempDelta = 0x4A; -const uint8_t kElectraAcIFeelMinTemp = 0; // 0C -const uint8_t kElectraAcIFeelMaxTemp = 50; // 50C +const uint8_t kElectraAcSensorTempDelta = 0x4A; +const uint8_t kElectraAcSensorMinTemp = 0; // 0C +const uint8_t kElectraAcSensorMaxTemp = 50; // 50C // Classes /// Class for handling detailed Electra A/C messages. @@ -143,8 +145,10 @@ class IRElectraAc { bool getTurbo(void) const; void setIFeel(const bool on); bool getIFeel(void) const; - void setIFeelTemp(const uint8_t temp); - uint8_t getIFeelTemp(void) const; + void setSensorUpdate(const bool on); + bool getSensorUpdate(void) const; + void setSensorTemp(const uint8_t temp); + uint8_t getSensorTemp(void) const; uint8_t* getRaw(void); void setRaw(const uint8_t new_code[], const uint16_t length = kElectraAcStateLength); diff --git a/test/ir_Electra_test.cpp b/test/ir_Electra_test.cpp index 4ba58b2fa..9c1dedd09 100644 --- a/test/ir_Electra_test.cpp +++ b/test/ir_Electra_test.cpp @@ -366,7 +366,7 @@ TEST(TestIRElectraAcClass, ConstructKnownState) { ac.getRaw(), kElectraAcBits); } -TEST(TestIRElectraAcClass, IFeel) { +TEST(TestIRElectraAcClass, IFeelAndSensor) { IRElectraAc ac(kGpioUnused); ac.stateReset(); // Test a real example. @@ -375,38 +375,60 @@ TEST(TestIRElectraAcClass, IFeel) { 0x64, 0x00, 0x20, 0x00, 0x1E, 0x7C}; ac.setRaw(ifeel_on); EXPECT_TRUE(ac.getIFeel()); - EXPECT_EQ(26, ac.getIFeelTemp()); + EXPECT_EQ(26, ac.getSensorTemp()); EXPECT_EQ( "Power: On, Mode: 1 (Cool), Temp: 21C, Fan: 5 (Auto), " "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off, " - "IFeel: On, IFeel Temp: 26C", + "IFeel: On, Sensor Temp: 26C", ac.toString()); ac.stateReset(); EXPECT_FALSE(ac.getIFeel()); - EXPECT_EQ(kElectraAcIFeelMinTemp, ac.getIFeelTemp()); + EXPECT_EQ(kElectraAcSensorMinTemp, ac.getSensorTemp()); ac.setIFeel(true); EXPECT_TRUE(ac.getIFeel()); - EXPECT_EQ(kElectraAcIFeelMinTemp, ac.getIFeelTemp()); + EXPECT_EQ(kElectraAcSensorMinTemp, ac.getSensorTemp()); - ac.setIFeelTemp(kElectraAcIFeelMaxTemp); - EXPECT_EQ(kElectraAcIFeelMaxTemp, ac.getIFeelTemp()); + ac.setSensorTemp(kElectraAcSensorMaxTemp); + EXPECT_EQ(kElectraAcSensorMaxTemp, ac.getSensorTemp()); - ac.setIFeelTemp(kElectraAcIFeelMaxTemp + 1); - EXPECT_EQ(kElectraAcIFeelMaxTemp, ac.getIFeelTemp()); + ac.setSensorTemp(kElectraAcSensorMaxTemp + 1); + EXPECT_EQ(kElectraAcSensorMaxTemp, ac.getSensorTemp()); ac.setIFeel(false); EXPECT_FALSE(ac.getIFeel()); - EXPECT_EQ(kElectraAcIFeelMinTemp, ac.getIFeelTemp()); - EXPECT_EQ(0, ac._.IFeelTemp); + EXPECT_EQ(kElectraAcSensorMinTemp, ac.getSensorTemp()); + EXPECT_EQ(0, ac._.SensorTemp); ac.setIFeel(true); - ac.setIFeelTemp(kElectraAcIFeelMinTemp); + ac.setSensorTemp(kElectraAcSensorMinTemp); EXPECT_TRUE(ac.getIFeel()); - EXPECT_EQ(kElectraAcIFeelMinTemp, ac.getIFeelTemp()); + EXPECT_EQ(kElectraAcSensorMinTemp, ac.getSensorTemp()); - ac.setIFeelTemp(26); // Celsius + ac.setSensorTemp(26); // Celsius EXPECT_TRUE(ac.getIFeel()); - EXPECT_EQ(26, ac.getIFeelTemp()); + EXPECT_EQ(26, ac.getSensorTemp()); + + EXPECT_FALSE(ac.getSensorUpdate()); + ac.setSensorUpdate(true); + EXPECT_TRUE(ac.getSensorUpdate()); + EXPECT_EQ("Sensor Temp: 26C", ac.toString()); + ac.setSensorUpdate(false); + EXPECT_FALSE(ac.getSensorUpdate()); + + const uint8_t sensor_update_28C[kElectraAcStateLength] = { + 0xC3, 0x9F, 0xE0, 0x40, 0xA0, 0x00, 0x88, + 0x66, 0x00, 0x30, 0x00, 0x1E, 0x5E}; + ac.setRaw(sensor_update_28C); + EXPECT_TRUE(ac.getSensorUpdate()); + EXPECT_EQ(28, ac.getSensorTemp()); + EXPECT_EQ("Sensor Temp: 28C", ac.toString()); + ac.setSensorUpdate(false); + EXPECT_FALSE(ac.getSensorUpdate()); + EXPECT_EQ( + "Power: On, Mode: 4 (Heat), Temp: 27C, Fan: 5 (Auto), " + "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off, " + "IFeel: On, Sensor Temp: 28C", + ac.toString()); }