FUJITSU: Improve handling of 10C Heat mode. (#1788)

* Better detect 10C heat mode.
* Report the temp as 10C when we detect it.
* Allow 10C heat mode to be activated via `IRac` interface.
  - Requires the following settings to activtate:
    - Suitable model (e.g. ARRAH2E or ARREW4E)
    - Mode: Fan
    - Fan Speed: Auto
    - Clean: True
    - SwingV: Off
    - SwingH: Off

* Update supported fujitsu models.
* Unit tests adjusted and added.

For #1780
This commit is contained in:
David Conran
2022-05-06 12:39:14 +10:00
committed by GitHub
parent 8b3539667d
commit 452a502bf0
5 changed files with 125 additions and 57 deletions

View File

@@ -118,7 +118,8 @@ struct state_t {
/// Fujitsu A/C model numbers
enum fujitsu_ac_remote_model_t {
ARRAH2E = 1, ///< (1) AR-RAH2E, AR-RAC1E, AR-RAE1E, AR-RCE1E (Default)
ARRAH2E = 1, ///< (1) AR-RAH2E, AR-RAC1E, AR-RAE1E, AR-RCE1E, AR-RAH2U,
///< AR-REG1U (Default)
///< Warning: Use on incorrect models can cause the A/C to lock
///< up, requring the A/C to be physically powered off to fix.
///< e.g. AR-RAH1U may lock up with a Swing command.

View File

@@ -184,7 +184,13 @@ void IRFujitsuAC::checkSum(void) {
}
}
if (_model != fujitsu_ac_remote_model_t::ARRY4) {
if (_model != fujitsu_ac_remote_model_t::ARREW4E) _.Clean = false;
switch (_model) {
case fujitsu_ac_remote_model_t::ARRAH2E:
case fujitsu_ac_remote_model_t::ARREW4E:
break;
default:
_.Clean = false;
}
_.Filter = false;
}
// Set the On/Off/Sleep timer Nr of mins.
@@ -290,7 +296,8 @@ void IRFujitsuAC::buildFromState(const uint16_t length) {
setCmd(kFujitsuAcCmdStayOn);
// Currently the only way we know how to tell ARRAH2E & ARRY4 apart is if
// either the raw Filter or Clean setting is on.
if (_model == fujitsu_ac_remote_model_t::ARRAH2E && (_.Filter || _.Clean))
if (_model == fujitsu_ac_remote_model_t::ARRAH2E && (_.Filter || _.Clean) &&
!get10CHeat())
setModel(fujitsu_ac_remote_model_t::ARRY4);
if (_state_length == kFujitsuAcStateLength && _.OutsideQuiet)
setModel(fujitsu_ac_remote_model_t::ARREB1E);
@@ -578,7 +585,7 @@ void IRFujitsuAC::setFilter(const bool on) {
bool IRFujitsuAC::getFilter(void) const {
switch (_model) {
case fujitsu_ac_remote_model_t::ARRY4: return _.Filter;
default: return false;
default: return false;
}
}
@@ -587,6 +594,7 @@ bool IRFujitsuAC::getFilter(void) const {
void IRFujitsuAC::set10CHeat(const bool on) {
switch (_model) {
// Only selected models support this.
case fujitsu_ac_remote_model_t::ARRAH2E:
case fujitsu_ac_remote_model_t::ARREW4E:
setClean(on); // 10C Heat uses the same bit as Clean
if (on) {
@@ -605,6 +613,7 @@ void IRFujitsuAC::set10CHeat(const bool on) {
/// @return true, the setting is on. false, the setting is off.
bool IRFujitsuAC::get10CHeat(void) const {
switch (_model) {
case fujitsu_ac_remote_model_t::ARRAH2E:
case fujitsu_ac_remote_model_t::ARREW4E:
return (_.Clean && _.Power && _.Mode == kFujitsuAcModeFan &&
_.Fan == kFujitsuAcFanAuto && _.Swing == kFujitsuAcSwingOff);
@@ -810,7 +819,11 @@ stdAc::state_t IRFujitsuAC::toCommon(const stdAc::state_t *prev) {
if (isLongCode() || prev == NULL) {
result.mode = toCommonMode(_.Mode);
result.celsius = getCelsius();
result.degrees = getTemp();
{
const float minHeat = result.celsius ? kFujitsuAcMinHeat
: kFujitsuAcMinHeatF;
result.degrees = get10CHeat() ? minHeat : getTemp();
}
result.fanspeed = toCommonFanSpeed(_.Fan);
uint8_t swing = _.Swing;
switch (result.model) {
@@ -848,7 +861,7 @@ stdAc::state_t IRFujitsuAC::toCommon(const stdAc::state_t *prev) {
/// @return A human readable string.
String IRFujitsuAC::toString(void) const {
String result = "";
result.reserve(100); // Reserve some heap for the string to reduce fragging.
result.reserve(180); // Reserve some heap for the string to reduce fragging.
fujitsu_ac_remote_model_t model = _model;
result += addModelToString(decode_type_t::FUJITSU_AC, model, false);
result += addIntToString(_.Id, kIdStr);
@@ -857,7 +870,12 @@ String IRFujitsuAC::toString(void) const {
result += addModeToString(_.Mode, kFujitsuAcModeAuto, kFujitsuAcModeCool,
kFujitsuAcModeHeat, kFujitsuAcModeDry,
kFujitsuAcModeFan);
result += addTempFloatToString(getTemp(), getCelsius());
{
const bool isCelsius = getCelsius();
const float minHeat = isCelsius ? kFujitsuAcMinHeat : kFujitsuAcMinHeatF;
result += addTempFloatToString(get10CHeat() ? minHeat : getTemp(),
isCelsius);
}
result += addFanToString(_.Fan, kFujitsuAcFanHigh, kFujitsuAcFanLow,
kFujitsuAcFanAuto, kFujitsuAcFanQuiet,
kFujitsuAcFanMed);
@@ -874,8 +892,14 @@ String IRFujitsuAC::toString(void) const {
result += addBoolToString(getFilter(), kFilterStr);
// FALL THRU
default: // e.g. ARREW4E
if (model == fujitsu_ac_remote_model_t::ARREW4E)
result += addBoolToString(get10CHeat(), k10CHeatStr);
switch (model) {
case fujitsu_ac_remote_model_t::ARRAH2E:
case fujitsu_ac_remote_model_t::ARREW4E:
result += addBoolToString(get10CHeat(), k10CHeatStr);
break;
default:
break;
}
result += addIntToString(_.Swing, kSwingStr);
result += kSpaceLBraceStr;
switch (_.Swing) {

View File

@@ -30,6 +30,7 @@
// Brand: Fujitsu, Model: AR-DL10 remote (ARDB1)
// Brand: Fujitsu, Model: ASU30C1 A/C (ARDB1)
// Brand: Fujitsu, Model: AR-RAH1U remote (ARREB1E)
// Brand: Fujitsu, Model: AR-RAH2U remote (ARRAH2E)
// Brand: Fujitsu, Model: ASU12RLF A/C (ARREB1E)
// Brand: Fujitsu, Model: AR-REW4E remote (ARREW4E)
// Brand: Fujitsu, Model: ASYG09KETA-B A/C (ARREW4E)
@@ -37,6 +38,7 @@
// Brand: Fujitsu, Model: ASTG09K A/C (ARREW4E)
// Brand: Fujitsu, Model: ASTG18K A/C (ARREW4E)
// Brand: Fujitsu, Model: AR-REW1E remote (ARREW4E)
// Brand: Fujitsu, Model: AR-REG1U remote (ARRAH2E)
#ifndef IR_FUJITSU_H_
#define IR_FUJITSU_H_
@@ -128,9 +130,11 @@ const uint8_t kFujitsuAcFanMed = 0x02;
const uint8_t kFujitsuAcFanLow = 0x03;
const uint8_t kFujitsuAcFanQuiet = 0x04;
const float kFujitsuAcMinHeat = 10; // 10C
const float kFujitsuAcMinTemp = 16; // 16C
const float kFujitsuAcMaxTemp = 30; // 30C
const uint8_t kFujitsuAcTempOffsetC = kFujitsuAcMinTemp;
const float kFujitsuAcMinHeatF = 50; // 50F
const float kFujitsuAcMinTempF = 60; // 60F
const float kFujitsuAcMaxTempF = 88; // 88F
const uint8_t kFujitsuAcTempOffsetF = 44;

View File

@@ -623,9 +623,9 @@ TEST(TestIRac, Fujitsu) {
"Model: 2 (ARDB1), Id: 0, Power: On, Mode: 1 (Cool), Temp: 19C, "
"Fan: 2 (Medium), Command: N/A";
std::string arrah2e_expected =
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 1 (Cool), Temp: 19C, "
"Fan: 2 (Medium), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A, "
"Sleep Timer: 03:00";
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 3 (Fan), Temp: 10C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, 10C Heat: On, "
"Swing: 0 (Off), Command: N/A, Sleep Timer: 03:00";
std::string arry4_expected =
"Model: 5 (ARRY4), Id: 0, Power: On, Mode: 1 (Cool), Temp: 19C, "
"Fan: 2 (Medium), Clean: On, Filter: On, Swing: 0 (Off), Command: N/A";
@@ -658,20 +658,21 @@ TEST(TestIRac, Fujitsu) {
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
ac._irsend.reset();
// Try to set the device to 10C Heat mode.
irac.fujitsu(&ac,
ARRAH2E, // Model
true, // Power
stdAc::opmode_t::kCool, // Mode
stdAc::opmode_t::kFan, // Mode (Fan needed for 10C Heat)
true, // Celsius
19, // Degrees
stdAc::fanspeed_t::kMedium, // Fan speed
stdAc::swingv_t::kOff, // Vertical swing
stdAc::swingh_t::kOff, // Horizontal swing
19, // Degrees (Ignored in 10C Heat)
stdAc::fanspeed_t::kAuto, // Fan speed (Auto needed for 10C)
stdAc::swingv_t::kOff, // Vertical swing (Ditto)
stdAc::swingh_t::kOff, // Horizontal swing (Ditto)
false, // Quiet
false, // Turbo (Powerful)
false, // Econo
true, // Filter
true, // Clean
true, // Clean (Needed for 10C Heat)
3 * 60); // Sleep
ASSERT_EQ(arrah2e_expected, ac.toString());
ac._irsend.makeDecodeResult();

View File

@@ -22,7 +22,7 @@ TEST(TestIRFujitsuACClass, GetRawDefault) {
EXPECT_STATE_EQ(expected_arrah2e, ac.getRaw(), 16 * 8);
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ("Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 1 (Cool), Temp: 24C, "
"Fan: 1 (High), Clean: Off, Filter: Off, "
"Fan: 1 (High), Clean: Off, Filter: Off, 10C Heat: Off, "
"Swing: 3 (Swing(V)+Swing(H)), Command: N/A, Timer: Off",
ac.toString());
@@ -45,7 +45,7 @@ TEST(TestIRFujitsuACClass, GetRawTurnOff) {
EXPECT_STATE_EQ(expected_arrah2e, ac.getRaw(), 7 * 8);
EXPECT_EQ(kFujitsuAcStateLengthShort, ac.getStateLength());
EXPECT_EQ("Model: 1 (ARRAH2E), Id: 0, Power: Off, Mode: 1 (Cool), Temp: 24C, "
"Fan: 1 (High), Clean: Off, Filter: Off, "
"Fan: 1 (High), Clean: Off, Filter: Off, 10C Heat: Off, "
"Swing: 3 (Swing(V)+Swing(H)), Command: N/A, Timer: Off",
ac.toString());
@@ -66,8 +66,8 @@ TEST(TestIRFujitsuACClass, GetRawStepHoriz) {
EXPECT_EQ(kFujitsuAcStateLengthShort, ac.getStateLength());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 1 (Cool), Temp: 24C, "
"Fan: 1 (High), Clean: Off, Filter: Off, Swing: 3 (Swing(V)+Swing(H)), "
"Command: Step Swing(H), Timer: Off",
"Fan: 1 (High), Clean: Off, Filter: Off, 10C Heat: Off, "
"Swing: 3 (Swing(V)+Swing(H)), Command: Step Swing(H), Timer: Off",
ac.toString());
}
@@ -80,8 +80,8 @@ TEST(TestIRFujitsuACClass, GetRawStepVert) {
EXPECT_EQ(kFujitsuAcStateLengthShort, ac.getStateLength());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 1 (Cool), Temp: 24C, "
"Fan: 1 (High), Clean: Off, Filter: Off, Swing: 3 (Swing(V)+Swing(H)), "
"Command: Step Swing(V), Timer: Off",
"Fan: 1 (High), Clean: Off, Filter: Off, 10C Heat: Off, "
"Swing: 3 (Swing(V)+Swing(H)), Command: Step Swing(V), Timer: Off",
ac.toString());
ac.setModel(ARDB1);
@@ -106,7 +106,7 @@ TEST(TestIRFujitsuACClass, GetRawWithSwingHoriz) {
0x90, 0x1, 0x24, 0x0, 0x0, 0x0, 0x20, 0xFB};
EXPECT_STATE_EQ(expected, ac.getRaw(), 16 * 8);
EXPECT_EQ("Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 1 (Cool), Temp: 25C, "
"Fan: 4 (Quiet), Clean: Off, Filter: Off, "
"Fan: 4 (Quiet), Clean: Off, Filter: Off, 10C Heat: Off, "
"Swing: 2 (Swing(H)), Command: N/A, Timer: Off",
ac.toString());
}
@@ -126,7 +126,7 @@ TEST(TestIRFujitsuACClass, GetRawWithFan) {
EXPECT_STATE_EQ(expected_arrah2e, ac.getRaw(), 16 * 8);
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ("Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 3 (Fan), Temp: 20C, "
"Fan: 2 (Medium), Clean: Off, Filter: Off, "
"Fan: 2 (Medium), Clean: Off, Filter: Off, 10C Heat: Off, "
"Swing: 2 (Swing(H)), Command: N/A, Timer: Off",
ac.toString());
@@ -149,7 +149,7 @@ TEST(TestIRFujitsuACClass, SetRaw) {
EXPECT_STATE_EQ(expected_default_arrah2e, ac.getRaw(),
ac.getStateLength() * 8);
EXPECT_EQ("Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 1 (Cool), Temp: 24C, "
"Fan: 1 (High), Clean: Off, Filter: Off, "
"Fan: 1 (High), Clean: Off, Filter: Off, 10C Heat: Off, "
"Swing: 3 (Swing(V)+Swing(H)), Command: N/A, "
"Timer: Off",
ac.toString());
@@ -363,7 +363,7 @@ TEST(TestDecodeFujitsuAC, SyntheticLongMessages) {
ac.setRaw(irsend.capture.state, irsend.capture.bits / 8);
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ("Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 1 (Cool), Temp: 18C, "
"Fan: 4 (Quiet), Clean: Off, Filter: Off, "
"Fan: 4 (Quiet), Clean: Off, Filter: Off, 10C Heat: Off, "
"Swing: 1 (Swing(V)), Command: N/A, "
"Timer: Off",
ac.toString());
@@ -539,8 +539,8 @@ TEST(TestDecodeFujitsuAC, Issue414) {
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 4 (Heat), Temp: 24C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A, "
"Timer: Off",
"Fan: 0 (Auto), Clean: Off, Filter: Off, 10C Heat: Off, Swing: 0 (Off), "
"Command: N/A, Timer: Off",
ac.toString());
// Resend it using the state this time.
@@ -719,7 +719,7 @@ TEST(TestIRFujitsuACClass, OutsideQuiet) {
// the option is set. Otheriwse they appear the same.
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 1 (Cool), Temp: 24C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), "
"Fan: 0 (Auto), Clean: Off, Filter: Off, 10C Heat: Off, Swing: 0 (Off), "
"Command: N/A, Timer: Off", ac.toString());
ac.setModel(fujitsu_ac_remote_model_t::ARREB1E);
EXPECT_EQ(
@@ -822,8 +822,8 @@ TEST(TestDecodeFujitsuAC, Issue726) {
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 0 (Auto), Temp: 24C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A, "
"Timer: Off",
"Fan: 0 (Auto), Clean: Off, Filter: Off, 10C Heat: Off, Swing: 0 (Off), "
"Command: N/A, Timer: Off",
ac.toString());
}
@@ -855,16 +855,16 @@ TEST(TestIRFujitsuACClass, Clean) {
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A, "
"Timer: Off",
"Fan: 0 (Auto), Clean: Off, Filter: Off, 10C Heat: Off, Swing: 0 (Off), "
"Command: N/A, Timer: Off",
ac.toString());
// Now it is in ARRAH2E model mode, it shouldn't accept setting it on.
ac.setClean(true);
EXPECT_EQ(fujitsu_ac_remote_model_t::ARRAH2E, ac.getModel());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A, "
"Timer: Off",
"Fan: 0 (Auto), Clean: Off, Filter: Off, 10C Heat: Off, Swing: 0 (Off), "
"Command: N/A, Timer: Off",
ac.toString());
// But ARRY4 does.
ac.setModel(fujitsu_ac_remote_model_t::ARRY4);
@@ -901,8 +901,8 @@ TEST(TestIRFujitsuACClass, Filter) {
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A, "
"Timer: Off",
"Fan: 0 (Auto), Clean: Off, Filter: Off, 10C Heat: Off, Swing: 0 (Off), "
"Command: N/A, Timer: Off",
ac.toString());
// Now it is in ARRAH2E model mode, it shouldn't accept setting it on.
ac.setFilter(true);
@@ -930,8 +930,8 @@ TEST(TestIRFujitsuACClass, Timers) {
EXPECT_EQ(0, ac.getOffSleepTimer());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 1 (High), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A, "
"On Timer: 12:00",
"Fan: 1 (High), Clean: Off, Filter: Off, 10C Heat: Off, Swing: 0 (Off), "
"Command: N/A, On Timer: 12:00",
ac.toString());
const uint8_t timer_on_8h30m[kFujitsuAcStateLength] = {
@@ -944,8 +944,8 @@ TEST(TestIRFujitsuACClass, Timers) {
EXPECT_EQ(0, ac.getOffSleepTimer());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 1 (High), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A, "
"On Timer: 08:30",
"Fan: 1 (High), Clean: Off, Filter: Off, 10C Heat: Off, "
"Swing: 0 (Off), Command: N/A, On Timer: 08:30",
ac.toString());
// TIMER OFF 11H
@@ -959,8 +959,8 @@ TEST(TestIRFujitsuACClass, Timers) {
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 1 (High), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A, "
"Off Timer: 11:00",
"Fan: 1 (High), Clean: Off, Filter: Off, 10C Heat: Off, "
"Swing: 0 (Off), Command: N/A, Off Timer: 11:00",
ac.toString());
// TIMER OFF 0.5H
@@ -974,8 +974,8 @@ TEST(TestIRFujitsuACClass, Timers) {
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 1 (High), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A, "
"Off Timer: 00:30",
"Fan: 1 (High), Clean: Off, Filter: Off, 10C Heat: Off, "
"Swing: 0 (Off), Command: N/A, Off Timer: 00:30",
ac.toString());
// TIMER SLEEP 3H
@@ -989,8 +989,8 @@ TEST(TestIRFujitsuACClass, Timers) {
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 1 (High), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A, "
"Sleep Timer: 03:00",
"Fan: 1 (High), Clean: Off, Filter: Off, 10C Heat: Off, "
"Swing: 0 (Off), Command: N/A, Sleep Timer: 03:00",
ac.toString());
// Re-construct a known timer state from scratch.
@@ -1007,8 +1007,8 @@ TEST(TestIRFujitsuACClass, Timers) {
ac.setOffTimer(30);
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 1 (High), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A, "
"Off Timer: 00:30",
"Fan: 1 (High), Clean: Off, Filter: Off, 10C Heat: Off, "
"Swing: 0 (Off), Command: N/A, Off Timer: 00:30",
ac.toString());
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_STATE_EQ(timer_off_30m, ac.getRaw(), ac.getStateLength() * 8);
@@ -1016,8 +1016,8 @@ TEST(TestIRFujitsuACClass, Timers) {
ac.setOnTimer(12 * 60);
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 1 (High), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A, "
"On Timer: 12:00",
"Fan: 1 (High), Clean: Off, Filter: Off, 10C Heat: Off, "
"Swing: 0 (Off), Command: N/A, On Timer: 12:00",
ac.toString());
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ(12 * 60, ac.getOnTimer());
@@ -1029,8 +1029,8 @@ TEST(TestIRFujitsuACClass, Timers) {
ac.setSleepTimer(3 * 60);
EXPECT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 1 (High), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A, "
"Sleep Timer: 03:00",
"Fan: 1 (High), Clean: Off, Filter: Off, 10C Heat: Off, "
"Swing: 0 (Off), Command: N/A, Sleep Timer: 03:00",
ac.toString());
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_STATE_EQ(timer_sleep_3h, ac.getRaw(), ac.getStateLength() * 8);
@@ -1118,7 +1118,7 @@ TEST(TestIRFujitsuACClass, Heat10Deg) {
0x69, 0x0B, 0x00, 0x23, 0x06, 0x23, 0x20, 0xEF};
ac.setRaw(heat_on, kFujitsuAcStateLength);
EXPECT_EQ(
"Model: 6 (ARREW4E), Id: 1, Power: On, Mode: 3 (Fan), Temp: 21C, "
"Model: 6 (ARREW4E), Id: 1, Power: On, Mode: 3 (Fan), Temp: 10C, "
"Fan: 0 (Auto), 10C Heat: On, Swing: 0 (Off), Command: N/A, "
"Outside Quiet: Off, Timer: Off",
ac.toString());
@@ -1134,7 +1134,7 @@ TEST(TestIRFujitsuACClass, Heat10Deg) {
ac.set10CHeat(true);
EXPECT_TRUE(ac.get10CHeat());
EXPECT_EQ(
"Model: 6 (ARREW4E), Id: 1, Power: On, Mode: 3 (Fan), Temp: 21C, "
"Model: 6 (ARREW4E), Id: 1, Power: On, Mode: 3 (Fan), Temp: 10C, "
"Fan: 0 (Auto), 10C Heat: On, Swing: 0 (Off), Command: N/A, "
"Outside Quiet: Off, Timer: Off",
ac.toString());
@@ -1408,3 +1408,41 @@ TEST(TestIRFujitsuACClass, toCommon_Issue1780HandlePrev) {
ASSERT_EQ(stdAc::opmode_t::kCool, result_inc_prev.mode);
ASSERT_EQ(stdAc::fanspeed_t::kMin, result_inc_prev.fanspeed);
}
TEST(TestIRFujitsuACClass, Improve10CHeat) {
IRFujitsuAC ac(kGpioUnused);
// Data from https://docs.google.com/spreadsheets/d/1RdmJdOZ3zxYlLXzluKTp4L6VVdjDXKgizwwIyTTG8MA/edit#gid=0&range=G2
const uint8_t Arrah2u_10CHeatOn[16] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30,
0x41, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x20, 0x64};
ASSERT_FALSE(ac.get10CHeat());
ac.setRaw(Arrah2u_10CHeatOn, 16);
ASSERT_TRUE(ac.get10CHeat());
ASSERT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 3 (Fan), Temp: 10C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, 10C Heat: On, Swing: 0 (Off), "
"Command: N/A, Timer: Off",
ac.toString());
EXPECT_EQ(decode_type_t::FUJITSU_AC, ac.toCommon().protocol);
ASSERT_TRUE(ac.get10CHeat());
EXPECT_EQ(fujitsu_ac_remote_model_t::ARRAH2E, ac.toCommon().model);
EXPECT_EQ(kFujitsuAcMinHeat, ac.toCommon().degrees);
ac.stateReset();
// Data from https://docs.google.com/spreadsheets/d/1RdmJdOZ3zxYlLXzluKTp4L6VVdjDXKgizwwIyTTG8MA/edit#gid=0&range=G8
const uint8_t Arreg1u_10CHeatOn[16] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30,
0x61, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x20, 0x44};
ASSERT_FALSE(ac.get10CHeat());
ac.setRaw(Arreg1u_10CHeatOn, 16);
ASSERT_TRUE(ac.get10CHeat());
ASSERT_EQ(
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 3 (Fan), Temp: 10C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, 10C Heat: On, Swing: 0 (Off), "
"Command: N/A, Timer: Off",
ac.toString());
EXPECT_EQ(decode_type_t::FUJITSU_AC, ac.toCommon().protocol);
ASSERT_TRUE(ac.get10CHeat());
EXPECT_EQ(fujitsu_ac_remote_model_t::ARRAH2E, ac.toCommon().model);
EXPECT_EQ(kFujitsuAcMinHeat, ac.toCommon().degrees);
}