Skip to content

Commit

Permalink
[HAIER_AC176/HAIER_AC_YRW02] Implement Quiet setting. (#1635)
Browse files Browse the repository at this point in the history
* Change `setTurbo()` & `getTurbo()` to operate on Booleans only.
* Add `setQuiet()` & `getQuiet()` methods.
* Limit Quiet & Turbo to `Cool` & `Heat` operating modes.
* Quiet & Turbo are mutually exclusive.

* Improve unit testing.
* General code style cleanups.

Ref #1634
FYI @PtilopsisLeucotis
  • Loading branch information
crankyoldgit authored Oct 12, 2021
1 parent 1cb83e0 commit e313139
Show file tree
Hide file tree
Showing 6 changed files with 546 additions and 593 deletions.
11 changes: 7 additions & 4 deletions src/IRac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1116,20 +1116,21 @@ void IRac::haier(IRHaierAC *ac,
/// @param[in] fan The speed setting for the fan.
/// @param[in] swingv The vertical swing setting.
/// @param[in] turbo Run the device in turbo/powerful mode.
/// @param[in] quiet Run the device in quiet mode.
/// @param[in] filter Turn on the (ion/pollen/etc) filter mode.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
void IRac::haier176(IRHaierAC176 *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const bool turbo,
const bool filter, const int16_t sleep) {
const bool quiet, const bool filter, const int16_t sleep) {
ac->begin();
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
ac->setSwing(ac->convertSwingV(swingv));
// No Horizontal Swing setting available.
// No Quiet setting available.
ac->setQuiet(quiet);
ac->setTurbo(turbo);
// No Light setting available.
ac->setHealth(filter);
Expand All @@ -1150,20 +1151,22 @@ void IRac::haier176(IRHaierAC176 *ac,
/// @param[in] fan The speed setting for the fan.
/// @param[in] swingv The vertical swing setting.
/// @param[in] turbo Run the device in turbo/powerful mode.
/// @param[in] quiet Run the device in quiet mode.
/// @param[in] filter Turn on the (ion/pollen/etc) filter mode.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
void IRac::haierYrwo2(IRHaierACYRW02 *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const bool turbo,
const bool filter, const int16_t sleep) {
const bool quiet, const bool filter,
const int16_t sleep) {
ac->begin();
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
ac->setSwing(ac->convertSwingV(swingv));
// No Horizontal Swing setting available.
// No Quiet setting available.
ac->setQuiet(quiet);
ac->setTurbo(turbo);
// No Light setting available.
ac->setHealth(filter);
Expand Down
4 changes: 2 additions & 2 deletions src/IRac.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,15 +262,15 @@ void electra(IRElectraAc *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool turbo, const bool filter,
const bool turbo, const bool quiet, const bool filter,
const int16_t sleep = -1);
#endif // SEND_HAIER_AC176
#if SEND_HAIER_AC_YRW02
void haierYrwo2(IRHaierACYRW02 *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool turbo, const bool filter,
const bool turbo, const bool quiet, const bool filter,
const int16_t sleep = -1);
#endif // SEND_HAIER_AC_YRW02
#if SEND_HITACHI_AC
Expand Down
117 changes: 48 additions & 69 deletions src/ir_Haier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -629,24 +629,27 @@ uint8_t IRHaierAC176::getButton(void) const {
/// Set the operating mode of the A/C.
/// @param[in] mode The desired operating mode.
void IRHaierAC176::setMode(uint8_t mode) {
uint8_t new_mode = mode;
_.Button = kHaierAcYrw02ButtonMode;
switch (mode) {
case kHaierAcYrw02Auto:
case kHaierAcYrw02Cool:
case kHaierAcYrw02Dry:
case kHaierAcYrw02Fan:
// Turbo & Quiet is only available in Cool/Heat mode.
_.Turbo = false;
_.Quiet = false;
// FALL-THRU
case kHaierAcYrw02Cool:
case kHaierAcYrw02Heat:
case kHaierAcYrw02Fan: break;
default: new_mode = kHaierAcYrw02Auto; // Unexpected, default to auto mode.
_.Button = kHaierAcYrw02ButtonMode;
_.Mode = mode;
break;
default:
setMode(kHaierAcYrw02Auto); // Unexpected, default to auto mode.
}
_.Mode = new_mode;
}

/// Get the operating mode setting of the A/C.
/// @return The current operating mode setting.
uint8_t IRHaierAC176::getMode(void) const {
return _.Mode;
}
uint8_t IRHaierAC176::getMode(void) const { return _.Mode; }

/// Set the temperature.
/// @param[in] celsius The temperature in degrees celsius.
Expand All @@ -668,9 +671,7 @@ void IRHaierAC176::setTemp(const uint8_t celsius) {

/// 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 { return _.Temp + kHaierAcMinTemp; }

/// Set the Health (filter) setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
Expand All @@ -681,15 +682,11 @@ void IRHaierAC176::setHealth(const bool on) {

/// Get the Health (filter) setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
bool IRHaierAC176::getHealth(void) const {
return _.Health;
}
bool IRHaierAC176::getHealth(void) const { return _.Health; }

/// Get the value of the current power setting.
/// @return true, the setting is on. false, the setting is off.
bool IRHaierAC176::getPower(void) const {
return _.Power;
}
bool IRHaierAC176::getPower(void) const { return _.Power; }

/// Change the power setting.
/// @param[in] on true, the setting is on. false, the setting is off.
Expand All @@ -706,9 +703,7 @@ void IRHaierAC176::off(void) { setPower(false); }

/// Get the Sleep setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
bool IRHaierAC176::getSleep(void) const {
return _.Sleep;
}
bool IRHaierAC176::getSleep(void) const { return _.Sleep; }

/// Set the Sleep setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
Expand All @@ -718,30 +713,42 @@ void IRHaierAC176::setSleep(const bool on) {
}

/// Get the Turbo setting of the A/C.
/// @return The current turbo speed setting.
uint8_t IRHaierAC176::getTurbo(void) const {
return _.Turbo;
}
/// @return The current turbo setting.
bool IRHaierAC176::getTurbo(void) const { return _.Turbo; }

/// Set the Turbo setting of the A/C.
/// @param[in] speed The desired turbo speed setting.
/// @note Valid speeds are kHaierAcYrw02TurboOff, kHaierAcYrw02TurboLow, &
/// kHaierAcYrw02TurboHigh.
void IRHaierAC176::setTurbo(uint8_t speed) {
switch (speed) {
case kHaierAcYrw02TurboOff:
case kHaierAcYrw02TurboLow:
case kHaierAcYrw02TurboHigh:
_.Turbo = speed;
/// @param[in] on The desired turbo setting.
/// @note Turbo & Quiet can't be on at the same time, and only in Heat/Cool mode
void IRHaierAC176::setTurbo(const bool on) {
switch (getMode()) {
case kHaierAcYrw02Cool:
case kHaierAcYrw02Heat:
_.Turbo = on;
_.Button = kHaierAcYrw02ButtonTurbo;
if (on) _.Quiet = false;
}
}

/// Get the Quiet setting of the A/C.
/// @return The current Quiet setting.
bool IRHaierAC176::getQuiet(void) const { return _.Quiet; }

/// Set the Quiet setting of the A/C.
/// @param[in] on The desired Quiet setting.
/// @note Turbo & Quiet can't be on at the same time, and only in Heat/Cool mode
void IRHaierAC176::setQuiet(const bool on) {
switch (getMode()) {
case kHaierAcYrw02Cool:
case kHaierAcYrw02Heat:
_.Quiet = on;
_.Button = kHaierAcYrw02ButtonTurbo;
if (on) _.Turbo = false;
}
}

/// Get the current fan speed setting.
/// @return The current fan speed.
uint8_t IRHaierAC176::getFan(void) const {
return _.Fan;
}
uint8_t IRHaierAC176::getFan(void) const { return _.Fan; }

/// Set the speed of the fan.
/// @param[in] speed The desired setting.
Expand Down Expand Up @@ -948,20 +955,6 @@ stdAc::swingv_t IRHaierAC176::toCommonSwingV(const uint8_t pos) {
}
}

/// Convert the Turbo setting of the A/C into native turbo setting.
/// @param[in] speed The enum to be converted.
/// @return true, the setting is on. false, the setting is off.
bool IRHaierAC176::toCommonTurbo(const uint8_t speed) {
return speed == kHaierAcYrw02TurboHigh;
}

/// Convert the Turbo setting of the A/C into native quiet setting.
/// @param[in] speed The enum to be converted.
/// @return true, the setting is on. false, the setting is off.
bool IRHaierAC176::toCommonQuiet(const uint8_t speed) {
return speed == kHaierAcYrw02TurboLow;
}

/// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings.
stdAc::state_t IRHaierAC176::toCommon(void) const {
Expand All @@ -976,8 +969,8 @@ stdAc::state_t IRHaierAC176::toCommon(void) const {
result.swingv = toCommonSwingV(_.Swing);
result.filter = _.Health;
result.sleep = _.Sleep ? 0 : -1;
result.quiet = toCommonQuiet(_.Turbo);
result.turbo = toCommonTurbo(_.Turbo);
result.turbo = _.Turbo;
result.quiet = _.Quiet;
// Not supported.
result.swingh = stdAc::swingh_t::kOff;
result.econo = false;
Expand Down Expand Up @@ -1036,22 +1029,8 @@ String IRHaierAC176::toString(void) const {
result += addFanToString(_.Fan, kHaierAcYrw02FanHigh, kHaierAcYrw02FanLow,
kHaierAcYrw02FanAuto, kHaierAcYrw02FanAuto,
kHaierAcYrw02FanMed);
result += addIntToString(_.Turbo, kTurboStr);
result += kSpaceLBraceStr;
switch (_.Turbo) {
case kHaierAcYrw02TurboOff:
result += kOffStr;
break;
case kHaierAcYrw02TurboLow:
result += kLowStr;
break;
case kHaierAcYrw02TurboHigh:
result += kHighStr;
break;
default:
result += kUnknownStr;
}
result += ')';
result += addBoolToString(_.Turbo, kTurboStr);
result += addBoolToString(_.Quiet, kQuietStr);
result += addIntToString(_.Swing, kSwingStr);
result += kSpaceLBraceStr;
switch (_.Swing) {
Expand Down
62 changes: 7 additions & 55 deletions src/ir_Haier.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2018 crankyoldgit
// Copyright 2018-2021 crankyoldgit
/// @file
/// @brief Support for Haier A/C protocols.
/// The specifics of reverse engineering the protocols details:
Expand Down Expand Up @@ -133,51 +133,6 @@ const uint8_t kHaierAcSleepBit = 0b01000000;
#define HAIER_AC_FAN_MED kHaierAcFanMed
#define HAIER_AC_FAN_HIGH kHaierAcFanHigh

/// Native representation of a Haier YRW02 A/C message.
union HaierYRW02Protocol{
uint8_t raw[kHaierACYRW02StateLength]; ///< The state in native form
struct {
// Byte 0
uint8_t Prefix;
// Byte 1
uint8_t Swing:4;
uint8_t Temp :4; // 16C~30C
// Byte 2
uint8_t :8;
// Byte 3
uint8_t :1;
uint8_t Health:1;
uint8_t :6;
// Byte 4
uint8_t :6;
uint8_t Power:1;
uint8_t :1;
// Byte 5
uint8_t :5;
uint8_t Fan:3;
// Byte 6
uint8_t :6;
uint8_t Turbo:2;
// Byte 7
uint8_t :5;
uint8_t Mode:3;
// Byte 8
uint8_t :7;
uint8_t Sleep:1;
// Byte 9
uint8_t :8;
// Byte 10
uint8_t :8;
// Byte 11
uint8_t :8;
// Byte 12
uint8_t Button:4;
uint8_t :4;
// Byte 13
uint8_t Sum;
};
};

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

Expand All @@ -193,10 +148,6 @@ const uint8_t kHaierAcYrw02FanMed = 0b010;
const uint8_t kHaierAcYrw02FanLow = 0b011;
const uint8_t kHaierAcYrw02FanAuto = 0b101; // HAIER_AC176 uses `0` in Fan2

const uint8_t kHaierAcYrw02TurboOff = 0x0;
const uint8_t kHaierAcYrw02TurboHigh = 0x1;
const uint8_t kHaierAcYrw02TurboLow = 0x2;

const uint8_t kHaierAcYrw02Auto = 0b000; // 0
const uint8_t kHaierAcYrw02Cool = 0b001; // 1
const uint8_t kHaierAcYrw02Dry = 0b010; // 2
Expand Down Expand Up @@ -244,7 +195,8 @@ union HaierAc176Protocol{
uint8_t Fan :3;
// Byte 6
uint8_t OffTimerMins:6;
uint8_t Turbo :2;
uint8_t Turbo :1;
uint8_t Quiet :1;
// Byte 7
uint8_t OnTimerHrs :5;
uint8_t Mode :3;
Expand Down Expand Up @@ -295,8 +247,6 @@ union HaierAc176Protocol{
#define HAIER_AC_YRW02_FAN_LOW kHaierAcYrw02FanLow
#define HAIER_AC_YRW02_FAN_AUTO kHaierAcYrw02FanAuto
#define HAIER_AC_YRW02_TURBO_OFF kHaierAcYrw02TurboOff
#define HAIER_AC_YRW02_TURBO_HIGH kHaierAcYrw02TurboHigh
#define HAIER_AC_YRW02_TURBO_LOW kHaierAcYrw02TurboLow
#define HAIER_AC_YRW02_AUTO kHaierAcYrw02Auto
#define HAIER_AC_YRW02_COOL kHaierAcYrw02Cool
#define HAIER_AC_YRW02_DRY kHaierAcYrw02Dry
Expand Down Expand Up @@ -422,8 +372,10 @@ class IRHaierAC176 {
bool getHealth(void) const;
void setHealth(const bool on);

uint8_t getTurbo(void) const;
void setTurbo(const uint8_t speed);
bool getTurbo(void) const;
void setTurbo(const bool on);
bool getQuiet(void) const;
void setQuiet(const bool on);

uint8_t getSwing(void) const;
void setSwing(const uint8_t pos);
Expand Down
Loading

0 comments on commit e313139

Please sign in to comment.