Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HAIER_AC176/HAIER_AC_YRW02] Add support degree Fahrenheit #1659

Merged
merged 5 commits into from
Nov 4, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 93 additions & 19 deletions src/ir_Haier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ void IRHaierAC176::stateReset(void) {
std::memset(_.raw, 0, sizeof _.raw);
_.Prefix = kHaierAcYrw02Prefix;
_.Prefix2 = kHaierAc176Prefix;
_.Temp = kHaierAcDefTemp - kHaierAcMinTemp;
_.Temp = kHaierAcYrw02DefTempC - kHaierAcYrw02MinTempC;
_.Health = true;
setFan(kHaierAcYrw02FanAuto);
_.Power = true;
Expand Down Expand Up @@ -654,27 +654,101 @@ void IRHaierAC176::setMode(uint8_t mode) {
/// @return The current operating mode setting.
uint8_t IRHaierAC176::getMode(void) const { return _.Mode; }

/// Set the temperature.
/// @param[in] celsius The temperature in degrees celsius.
void IRHaierAC176::setTemp(const uint8_t celsius) {
uint8_t temp = celsius;
if (temp < kHaierAcMinTemp)
temp = kHaierAcMinTemp;
else if (temp > kHaierAcMaxTemp)
temp = kHaierAcMaxTemp;
/// Set the default temperature units to use.
/// @param[in] on Use Fahrenheit as the units.
/// true is Fahrenheit, false is Celsius.
void IRHaierAC176::setUseFahrenheit(const bool on) { _.UseFahrenheit = on; }

uint8_t old_temp = getTemp();
if (old_temp == temp) return;
if (old_temp > temp)
_.Button = kHaierAcYrw02ButtonTempDown;
else
_.Button = kHaierAcYrw02ButtonTempUp;
_.Temp = temp - kHaierAcMinTemp;
/// Get the default temperature units in use.
/// @return true is Fahrenheit, false is Celsius.
bool IRHaierAC176::getUseFahrenheit(void) const { return _.UseFahrenheit; }

/// Set the temperature.
/// @param[in] degree The temperature in degrees.
/// @param[in] fahrenheit Use units of Fahrenheit and set that as units used.
void IRHaierAC176::setTemp(const uint8_t degree, const bool fahrenheit) {
if (fahrenheit) {
uint8_t temp = degree;
if (temp < kHaierAcYrw02MinTempF)
temp = kHaierAcYrw02MinTempF;
else if (temp > kHaierAcYrw02MaxTempF)
temp = kHaierAcYrw02MaxTempF;

uint8_t old_temp = getTemp();
if (old_temp == temp) return;
if (old_temp > temp)
_.Button = kHaierAcYrw02ButtonTempDown;
else
_.Button = kHaierAcYrw02ButtonTempUp;

if (degree >= 77) { temp++; }
if (degree >= 79) { temp++; }
crankyoldgit marked this conversation as resolved.
Show resolved Hide resolved
// See at IRHaierAC176::getTemp() comments for clarification
_.ExtraDegreeF = temp % 2;
_.Temp = (temp - kHaierAcYrw02MinTempF -_.ExtraDegreeF) >> 1;
_.UseFahrenheit = true;
} else {
uint8_t temp = degree;
if (temp < kHaierAcYrw02MinTempC)
temp = kHaierAcYrw02MinTempC;
else if (temp > kHaierAcYrw02MaxTempC)
temp = kHaierAcYrw02MaxTempC;

uint8_t old_temp = getTemp();
if (old_temp == temp) return;
if (old_temp > temp)
_.Button = kHaierAcYrw02ButtonTempDown;
else
_.Button = kHaierAcYrw02ButtonTempUp;
_.Temp = temp - kHaierAcYrw02MinTempC;
_.UseFahrenheit = false;
}
}
crankyoldgit marked this conversation as resolved.
Show resolved Hide resolved

/// Get the current temperature setting.
/// @return The current setting for temp. in degrees celsius.
uint8_t IRHaierAC176::getTemp(void) const { return _.Temp + kHaierAcMinTemp; }
uint8_t IRHaierAC176::getTemp(void) const {
if (!_.UseFahrenheit) { return _.Temp + kHaierAcYrw02MinTempC; }
uint8_t degree = _.Temp*2 + kHaierAcYrw02MinTempF + _.ExtraDegreeF;
// The way of coding the temperature in degree Fahrenheit is
// kHaierAcYrw02MinTempF + Temp*2 + ExtraDegreeF, for example
// Temp = 0b0011, ExtraDegreeF = 0b1, temperature is 60 + 3*2 + 1 = 67F
// But around 78F there is unconsistency, see table below
//
// | Fahrenheit | Temp | ExtraDegreeF |
// | 60F | 0b0000 | 0b0 |
// | 61F | 0b0000 | 0b1 |
// | 62F | 0b0001 | 0b0 |
// | 63F | 0b0001 | 0b1 |
// | 64F | 0b0010 | 0b0 |
// | 65F | 0b0010 | 0b1 |
// | 66F | 0b0011 | 0b0 |
// | 67F | 0b0011 | 0b1 |
// | 68F | 0b0100 | 0b0 |
// | 69F | 0b0100 | 0b1 |
// | 70F | 0b0101 | 0b0 |
// | 71F | 0b0101 | 0b1 |
// | 72F | 0b0110 | 0b0 |
// | 73F | 0b0110 | 0b1 |
// | 74F | 0b0111 | 0b0 |
// | 75F | 0b0111 | 0b1 |
// | 76F | 0b1000 | 0b0 |
// | Not Used | 0b1000 | 0b1 |
// | 77F | 0b1001 | 0b0 |
// | Not Used | 0b1001 | 0b1 |
// | 78F | 0b1010 | 0b0 |
// | 79F | 0b1010 | 0b1 |
// | 80F | 0b1011 | 0b0 |
// | 81F | 0b1011 | 0b1 |
// | 82F | 0b1100 | 0b0 |
// | 83F | 0b1100 | 0b1 |
// | 84F | 0b1101 | 0b0 |
// | 86F | 0b1110 | 0b0 |
// | 85F | 0b1101 | 0b1 |
if (degree >= 78) { degree--; }
if (degree >= 79) { degree--; }
crankyoldgit marked this conversation as resolved.
Show resolved Hide resolved
return degree;
}

/// Set the Health (filter) setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
Expand Down Expand Up @@ -1038,7 +1112,7 @@ stdAc::state_t IRHaierAC176::toCommon(void) const {
result.model = -1; // No models used.
result.power = _.Power;
result.mode = toCommonMode(_.Mode);
result.celsius = true;
result.celsius = !_.UseFahrenheit;
result.degrees = getTemp();
result.fanspeed = toCommonFanSpeed(_.Fan);
result.swingv = toCommonSwingV(_.SwingV);
Expand Down Expand Up @@ -1109,7 +1183,7 @@ String IRHaierAC176::toString(void) const {
result += addModeToString(_.Mode, kHaierAcYrw02Auto, kHaierAcYrw02Cool,
kHaierAcYrw02Heat, kHaierAcYrw02Dry,
kHaierAcYrw02Fan);
result += addTempToString(getTemp());
result += addTempToString(getTemp(), !_.UseFahrenheit);
result += addFanToString(_.Fan, kHaierAcYrw02FanHigh, kHaierAcYrw02FanLow,
kHaierAcYrw02FanAuto, kHaierAcYrw02FanAuto,
kHaierAcYrw02FanMed);
Expand Down
15 changes: 13 additions & 2 deletions src/ir_Haier.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ const uint8_t kHaierAcSleepBit = 0b01000000;
#define HAIER_AC_FAN_MED kHaierAcFanMed
#define HAIER_AC_FAN_HIGH kHaierAcFanHigh

const uint8_t kHaierAcYrw02MinTempC = 16;
const uint8_t kHaierAcYrw02MaxTempC = 30;
const uint8_t kHaierAcYrw02MinTempF = 60;
const uint8_t kHaierAcYrw02MaxTempF = 86;
const uint8_t kHaierAcYrw02DefTempC = 25;

const uint8_t kHaierAcYrw02Prefix = 0xA6;
const uint8_t kHaierAc176Prefix = 0xB7;

Expand Down Expand Up @@ -218,7 +224,10 @@ union HaierAc176Protocol{
// Byte 9
uint8_t :8;
// Byte 10
uint8_t :8;
uint8_t ExtraDegreeF :1;
uint8_t :4;
uint8_t UseFahrenheit:1;
uint8_t :2;
// Byte 11
uint8_t :8;
// Byte 12
Expand Down Expand Up @@ -365,7 +374,9 @@ class IRHaierAC176 {
void setButton(const uint8_t button);
uint8_t getButton(void) const;

void setTemp(const uint8_t temp);
void setUseFahrenheit(const bool on);
bool getUseFahrenheit(void) const;
void setTemp(const uint8_t temp, const bool fahrenheit = false);
uint8_t getTemp(void) const;

void setFan(const uint8_t speed);
Expand Down
61 changes: 49 additions & 12 deletions test/ir_Haier_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,24 +476,24 @@ TEST(TestHaierACYRW02Class, Temperature) {
IRHaierACYRW02 ac(kGpioUnused);
ac.begin();

ac.setTemp(kHaierAcMinTemp);
EXPECT_EQ(kHaierAcMinTemp, ac.getTemp());
ac.setTemp(kHaierAcYrw02MinTempC);
EXPECT_EQ(kHaierAcYrw02MinTempC, ac.getTemp());

ac.setButton(kHaierAcYrw02ButtonPower);
ac.setTemp(kHaierAcMinTemp + 1);
EXPECT_EQ(kHaierAcMinTemp + 1, ac.getTemp());
ac.setTemp(kHaierAcYrw02MinTempC + 1);
EXPECT_EQ(kHaierAcYrw02MinTempC + 1, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());

ac.setTemp(kHaierAcMaxTemp);
EXPECT_EQ(kHaierAcMaxTemp, ac.getTemp());
ac.setTemp(kHaierAcYrw02MaxTempC);
EXPECT_EQ(kHaierAcYrw02MaxTempC, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());

ac.setTemp(kHaierAcMinTemp - 1);
EXPECT_EQ(kHaierAcMinTemp, ac.getTemp());
ac.setTemp(kHaierAcYrw02MinTempC - 1);
EXPECT_EQ(kHaierAcYrw02MinTempC, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempDown, ac.getButton());

ac.setTemp(kHaierAcMaxTemp + 1);
EXPECT_EQ(kHaierAcMaxTemp, ac.getTemp());
ac.setTemp(kHaierAcYrw02MaxTempC + 1);
EXPECT_EQ(kHaierAcYrw02MaxTempC, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());

ac.setTemp(23);
Expand All @@ -504,8 +504,44 @@ TEST(TestHaierACYRW02Class, Temperature) {
EXPECT_EQ(23, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());

ac.setTemp(kHaierAcYrw02MinTempF, true);
EXPECT_EQ(kHaierAcYrw02MinTempF, ac.getTemp());

ac.setButton(kHaierAcYrw02ButtonPower);
ac.setTemp(kHaierAcYrw02MinTempF + 1, true);
EXPECT_EQ(kHaierAcYrw02MinTempF + 1, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());

ac.setTemp(kHaierAcYrw02MaxTempF, true);
EXPECT_EQ(kHaierAcYrw02MaxTempF, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());

ac.setTemp(kHaierAcYrw02MinTempF - 1, true);
EXPECT_EQ(kHaierAcYrw02MinTempF, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempDown, ac.getButton());

ac.setTemp(kHaierAcYrw02MaxTempF + 1, true);
EXPECT_EQ(kHaierAcYrw02MaxTempF, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());

ac.setTemp(66, true);
EXPECT_EQ(66, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempDown, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonPower);
ac.setTemp(66, true);
EXPECT_EQ(66, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());

// Test specific cases for converting to Fahrenheit
ac.setTemp(76, true);
EXPECT_EQ(76, ac.getTemp());
ac.setTemp(77, true);
EXPECT_EQ(77, ac.getTemp());
ac.setTemp(78, true);
EXPECT_EQ(78, ac.getTemp());

ac.setTemp(0);
EXPECT_EQ(kHaierAcMinTemp, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02MinTempC, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempDown, ac.getButton());

ac.setTemp(255);
Expand Down Expand Up @@ -760,12 +796,13 @@ TEST(TestHaierACYRW02Class, MessageConstuction) {
"Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
ac.toString());

ac.setTemp(75, true);
ac.setSwingV(kHaierAcYrw02SwingVMiddle);
ac.setHealth(false);
ac.setSleep(true);
ac.setTurbo(true);
EXPECT_EQ(
"Power: On, Button: 8 (Turbo), Mode: 1 (Cool), Temp: 21C, "
"Power: On, Button: 8 (Turbo), Mode: 1 (Cool), Temp: 75F, "
"Fan: 1 (High), Turbo: On, Quiet: Off, Swing(V): 2 (Middle), "
"Swing(H): 0 (Middle), Sleep: On, Health: Off, "
"Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
Expand Down