Files
IRremoteESP8266/test/ir_Haier_test.cpp
David Conran 48f2db23dd HAIER_AC160: Experimental detail support. (#1852)
* This is basically a cut & paste of the `IRHaierAC176` class.
  - Without some features. e.g. SwingH
  - Modified values for SwingV
* Rough unit test coverage for new code.
  - Needs more real data to confirm etc.
* Add in support required for `IRac` class to work with this protocol.
* Add Light support
  - Report the button press code.
  - Make a guess at how the setting works.
    - i.e. The button code toggles the light on and off.
  - Adjust `toCommon()` to handle previous state.
  - Handle the light toggles appropriately.
  - Add a unit test case.
* Add AuxHeating setting.
* Add support for setting/getting Health/Filter status.

Fixes #1804
2022-08-17 15:00:09 +10:00

2034 lines
74 KiB
C++

// Copyright 2018 David Conran
#include "ir_Haier.h"
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendHaierAC()
// Test sending typical data only.
TEST(TestSendHaierAC, SendDataOnly) {
IRsendTest irsend(kGpioUnused);
irsend.begin();
uint8_t haier_zero[kHaierACStateLength] = {0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
irsend.reset();
irsend.sendHaierAC(haier_zero);
EXPECT_EQ(
"f38000d50"
"m3000s3000m3000s4300"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s150000",
irsend.outputStr());
uint8_t haier_test[kHaierACStateLength] = {0xA5, 0x01, 0x20, 0x01, 0x00,
0xC0, 0x20, 0x00, 0xA7};
irsend.reset();
irsend.sendHaierAC(haier_test);
EXPECT_EQ(
"f38000d50"
"m3000s3000m3000s4300"
"m520s1650m520s650m520s1650m520s650m520s650m520s1650m520s650m520s1650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s1650"
"m520s650m520s650m520s1650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s1650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s1650m520s1650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s1650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s1650m520s650m520s1650m520s650m520s650m520s1650m520s1650m520s1650"
"m520s150000",
irsend.outputStr());
}
// Test sending typical data with repeats.
TEST(TestSendHaierAC, SendWithRepeats) {
IRsendTest irsend(kGpioUnused);
irsend.begin();
irsend.reset();
uint8_t haier_test[kHaierACStateLength] = {0xA5, 0x01, 0x20, 0x01, 0x00,
0xC0, 0x20, 0x00, 0xA7};
irsend.reset();
irsend.sendHaierAC(haier_test, kHaierACStateLength, 2); // two repeats.
EXPECT_EQ(
"f38000d50"
"m3000s3000m3000s4300"
"m520s1650m520s650m520s1650m520s650m520s650m520s1650m520s650m520s1650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s1650"
"m520s650m520s650m520s1650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s1650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s1650m520s1650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s1650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s1650m520s650m520s1650m520s650m520s650m520s1650m520s1650m520s1650"
"m520s150000"
"m3000s3000m3000s4300"
"m520s1650m520s650m520s1650m520s650m520s650m520s1650m520s650m520s1650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s1650"
"m520s650m520s650m520s1650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s1650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s1650m520s1650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s1650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s1650m520s650m520s1650m520s650m520s650m520s1650m520s1650m520s1650"
"m520s150000"
"m3000s3000m3000s4300"
"m520s1650m520s650m520s1650m520s650m520s650m520s1650m520s650m520s1650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s1650"
"m520s650m520s650m520s1650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s1650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s1650m520s1650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s1650m520s650m520s650m520s650m520s650m520s650"
"m520s650m520s650m520s650m520s650m520s650m520s650m520s650m520s650"
"m520s1650m520s650m520s1650m520s650m520s650m520s1650m520s1650m520s1650"
"m520s150000",
irsend.outputStr());
}
// Tests for IRHaierAC class.
TEST(TestHaierACClass, Command) {
IRHaierAC ac(kGpioUnused);
ac.begin();
ac.setCommand(kHaierAcCmdOff);
EXPECT_EQ(kHaierAcCmdOff, ac.getCommand());
ac.setCommand(kHaierAcCmdOn);
EXPECT_EQ(kHaierAcCmdOn, ac.getCommand());
ac.setCommand(kHaierAcCmdMode);
EXPECT_EQ(kHaierAcCmdMode, ac.getCommand());
ac.setCommand(kHaierAcCmdFan);
EXPECT_EQ(kHaierAcCmdFan, ac.getCommand());
ac.setCommand(kHaierAcCmdTempUp);
EXPECT_EQ(kHaierAcCmdTempUp, ac.getCommand());
ac.setCommand(kHaierAcCmdTempDown);
EXPECT_EQ(kHaierAcCmdTempDown, ac.getCommand());
ac.setCommand(kHaierAcCmdSleep);
EXPECT_EQ(kHaierAcCmdSleep, ac.getCommand());
ac.setCommand(kHaierAcCmdTimerSet);
EXPECT_EQ(kHaierAcCmdTimerSet, ac.getCommand());
ac.setCommand(kHaierAcCmdTimerCancel);
EXPECT_EQ(kHaierAcCmdTimerCancel, ac.getCommand());
ac.setCommand(kHaierAcCmdHealth);
EXPECT_EQ(kHaierAcCmdHealth, ac.getCommand());
ac.setCommand(kHaierAcCmdSwing);
EXPECT_EQ(kHaierAcCmdSwing, ac.getCommand());
ac.setCommand(kHaierAcCmdOn);
EXPECT_EQ(kHaierAcCmdOn, ac.getCommand());
ac.setCommand(kHaierAcCmdOff);
EXPECT_EQ(kHaierAcCmdOff, ac.getCommand());
// Test unexpected values.
ac.setCommand(0b00001110);
EXPECT_EQ(kHaierAcCmdOff, ac.getCommand());
ac.setCommand(0b00001111);
EXPECT_EQ(kHaierAcCmdOff, ac.getCommand());
ac.setCommand(0b00000100);
EXPECT_EQ(kHaierAcCmdOff, ac.getCommand());
}
TEST(TestHaierACClass, OperatingMode) {
IRHaierAC ac(kGpioUnused);
ac.begin();
ac.setMode(kHaierAcAuto);
EXPECT_EQ(kHaierAcAuto, ac.getMode());
ac.setMode(kHaierAcCool);
EXPECT_EQ(kHaierAcCool, ac.getMode());
ac.setMode(kHaierAcHeat);
EXPECT_EQ(kHaierAcHeat, ac.getMode());
ac.setMode(kHaierAcFan);
EXPECT_EQ(kHaierAcFan, ac.getMode());
ac.setMode(kHaierAcDry);
EXPECT_EQ(kHaierAcDry, ac.getMode());
ac.setMode(kHaierAcAuto - 1);
EXPECT_EQ(kHaierAcAuto, ac.getMode());
ac.setMode(kHaierAcCool);
EXPECT_EQ(kHaierAcCool, ac.getMode());
ac.setMode(kHaierAcFan + 1);
EXPECT_EQ(kHaierAcAuto, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kHaierAcAuto, ac.getMode());
}
TEST(TestHaierACClass, Temperature) {
IRHaierAC ac(kGpioUnused);
ac.begin();
ac.setTemp(kHaierAcMinTemp);
EXPECT_EQ(kHaierAcMinTemp, ac.getTemp());
ac.setCommand(kHaierAcCmdOn);
ac.setTemp(kHaierAcMinTemp + 1);
EXPECT_EQ(kHaierAcMinTemp + 1, ac.getTemp());
EXPECT_EQ(kHaierAcCmdTempUp, ac.getCommand());
ac.setTemp(kHaierAcMaxTemp);
EXPECT_EQ(kHaierAcMaxTemp, ac.getTemp());
EXPECT_EQ(kHaierAcCmdTempUp, ac.getCommand());
ac.setTemp(kHaierAcMinTemp - 1);
EXPECT_EQ(kHaierAcMinTemp, ac.getTemp());
EXPECT_EQ(kHaierAcCmdTempDown, ac.getCommand());
ac.setTemp(kHaierAcMaxTemp + 1);
EXPECT_EQ(kHaierAcMaxTemp, ac.getTemp());
EXPECT_EQ(kHaierAcCmdTempUp, ac.getCommand());
ac.setTemp(23);
EXPECT_EQ(23, ac.getTemp());
EXPECT_EQ(kHaierAcCmdTempDown, ac.getCommand());
ac.setCommand(kHaierAcCmdOn);
ac.setTemp(23);
EXPECT_EQ(23, ac.getTemp());
EXPECT_EQ(kHaierAcCmdOn, ac.getCommand());
ac.setTemp(0);
EXPECT_EQ(kHaierAcMinTemp, ac.getTemp());
EXPECT_EQ(kHaierAcCmdTempDown, ac.getCommand());
ac.setTemp(255);
EXPECT_EQ(kHaierAcMaxTemp, ac.getTemp());
EXPECT_EQ(kHaierAcCmdTempUp, ac.getCommand());
}
TEST(TestHaierACClass, FanSpeed) {
IRHaierAC ac(kGpioUnused);
ac.begin();
ac.setFan(kHaierAcFanLow);
ac.setCommand(kHaierAcCmdOn);
ac.setFan(kHaierAcFanAuto);
EXPECT_EQ(kHaierAcFanAuto, ac.getFan());
EXPECT_EQ(kHaierAcCmdFan, ac.getCommand());
ac.setFan(kHaierAcFanLow);
EXPECT_EQ(kHaierAcFanLow, ac.getFan());
ac.setFan(kHaierAcFanMed);
EXPECT_EQ(kHaierAcFanMed, ac.getFan());
ac.setFan(kHaierAcFanHigh);
EXPECT_EQ(kHaierAcFanHigh, ac.getFan());
ac.setCommand(kHaierAcCmdOn);
ac.setFan(kHaierAcFanHigh);
EXPECT_EQ(kHaierAcFanHigh, ac.getFan());
EXPECT_EQ(kHaierAcCmdOn, ac.getCommand());
}
TEST(TestHaierACClass, SwingV) {
IRHaierAC ac(kGpioUnused);
ac.begin();
ac.setFan(kHaierAcFanLow);
ac.setCommand(kHaierAcCmdOn);
ac.setSwingV(kHaierAcSwingVOff);
EXPECT_EQ(kHaierAcSwingVOff, ac.getSwingV());
ac.setSwingV(kHaierAcSwingVUp);
EXPECT_EQ(kHaierAcSwingVUp, ac.getSwingV());
EXPECT_EQ(kHaierAcCmdSwing, ac.getCommand());
ac.setSwingV(kHaierAcSwingVDown);
EXPECT_EQ(kHaierAcSwingVDown, ac.getSwingV());
EXPECT_EQ(kHaierAcCmdSwing, ac.getCommand());
ac.setSwingV(kHaierAcSwingVChg);
EXPECT_EQ(kHaierAcSwingVChg, ac.getSwingV());
EXPECT_EQ(kHaierAcCmdSwing, ac.getCommand());
}
TEST(TestHaierACClass, CurrentTime) {
IRHaierAC ac(kGpioUnused);
ac.begin();
EXPECT_EQ(0, ac.getCurrTime());
ac.setCurrTime(1);
EXPECT_EQ(1, ac.getCurrTime());
ac.setCurrTime(60);
EXPECT_EQ(60, ac.getCurrTime());
ac.setCurrTime(61);
EXPECT_EQ(61, ac.getCurrTime());
ac.setCurrTime(18 * 60 + 34); // 18:34
EXPECT_EQ(1114, ac.getCurrTime());
ac.setCurrTime(23 * 60 + 59); // 23:59
EXPECT_EQ(kHaierAcMaxTime, ac.getCurrTime()); // 23:59
ac.setCurrTime(23 * 60 + 59 + 1); // 24:00
EXPECT_EQ(kHaierAcMaxTime, ac.getCurrTime()); // 23:59
ac.setCurrTime(UINT16_MAX);
EXPECT_EQ(kHaierAcMaxTime, ac.getCurrTime()); // 23:59
}
TEST(TestHaierACClass, Timers) {
IRHaierAC ac(kGpioUnused);
ac.begin();
ac.setCommand(kHaierAcCmdOn);
// Off by default.
EXPECT_GT(0, ac.getOnTimer());
EXPECT_GT(0, ac.getOffTimer());
EXPECT_EQ(kHaierAcCmdOn, ac.getCommand());
// On Timer.
ac.setOnTimer(6 * 60); // 6am
EXPECT_EQ(6 * 60, ac.getOnTimer()); // 6am
EXPECT_GT(0, ac.getOffTimer());
EXPECT_EQ(kHaierAcCmdTimerSet, ac.getCommand());
ac.setCommand(kHaierAcCmdOn);
EXPECT_EQ(6 * 60, ac.getOnTimer()); // 6am
EXPECT_GT(0, ac.getOffTimer());
EXPECT_EQ(kHaierAcCmdOn, ac.getCommand());
ac.cancelTimers();
EXPECT_GT(0, ac.getOnTimer());
EXPECT_GT(0, ac.getOffTimer());
EXPECT_EQ(kHaierAcCmdTimerCancel, ac.getCommand());
// Off Timer.
ac.setOffTimer(18 * 60 + 30); // 6:30pm
EXPECT_GT(0, ac.getOnTimer());
EXPECT_EQ(18 * 60 + 30, ac.getOffTimer()); // 6:30pm
EXPECT_EQ(kHaierAcCmdTimerSet, ac.getCommand());
ac.setCommand(kHaierAcCmdOn);
EXPECT_GT(0, ac.getOnTimer());
EXPECT_EQ(18 * 60 + 30, ac.getOffTimer()); // 6:30pm
EXPECT_EQ(kHaierAcCmdOn, ac.getCommand());
ac.cancelTimers();
EXPECT_GT(0, ac.getOnTimer());
EXPECT_GT(0, ac.getOffTimer());
EXPECT_EQ(kHaierAcCmdTimerCancel, ac.getCommand());
// Both Timers.
ac.setOnTimer(6 * 60); // 6am
EXPECT_EQ(kHaierAcCmdTimerSet, ac.getCommand());
ac.setOffTimer(18 * 60 + 30); // 6:30pm
EXPECT_EQ(kHaierAcCmdTimerSet, ac.getCommand());
EXPECT_EQ(6 * 60, ac.getOnTimer()); // 6am
EXPECT_EQ(18 * 60 + 30, ac.getOffTimer()); // 6:30pm
ac.cancelTimers();
EXPECT_GT(0, ac.getOnTimer());
EXPECT_GT(0, ac.getOffTimer());
EXPECT_EQ(kHaierAcCmdTimerCancel, ac.getCommand());
}
TEST(TestHaierACClass, MessageConstuction) {
IRHaierAC ac(kGpioUnused);
EXPECT_EQ(
"Command: 1 (On), Mode: 0 (Auto), Temp: 25C, Fan: 1 (Low), "
"Swing(V): 0 (Off), Sleep: Off, Health: Off, "
"Clock: 00:00, On Timer: Off, Off Timer: Off",
ac.toString());
ac.setMode(kHaierAcCool);
ac.setTemp(21);
ac.setFan(kHaierAcFanHigh);
EXPECT_EQ(
"Command: 3 (Fan), Mode: 1 (Cool), Temp: 21C, Fan: 3 (High), "
"Swing(V): 0 (Off), Sleep: Off, Health: Off, "
"Clock: 00:00, On Timer: Off, Off Timer: Off",
ac.toString());
ac.setSwingV(kHaierAcSwingVChg);
ac.setHealth(true);
ac.setSleep(true);
ac.setCurrTime(615); // 10:15am
EXPECT_EQ(
"Command: 8 (Sleep), Mode: 1 (Cool), Temp: 21C, Fan: 3 (High), "
"Swing(V): 3 (Change), Sleep: On, Health: On, "
"Clock: 10:15, On Timer: Off, Off Timer: Off",
ac.toString());
ac.setOnTimer(800); // 1:20pm
ac.setOffTimer(1125); // 6:45pm
ac.setCommand(kHaierAcCmdOn);
EXPECT_EQ(
"Command: 1 (On), Mode: 1 (Cool), Temp: 21C, Fan: 3 (High), "
"Swing(V): 3 (Change), Sleep: On, Health: On, "
"Clock: 10:15, On Timer: 13:20, Off Timer: 18:45",
ac.toString());
// Now change a few already set things.
ac.setMode(kHaierAcHeat);
EXPECT_EQ(
"Command: 2 (Mode), Mode: 3 (Heat), Temp: 21C, Fan: 3 (High), "
"Swing(V): 3 (Change), Sleep: On, Health: On, "
"Clock: 10:15, On Timer: 13:20, Off Timer: 18:45",
ac.toString());
ac.setTemp(25);
EXPECT_EQ(
"Command: 6 (Temp Up), Mode: 3 (Heat), Temp: 25C, Fan: 3 (High), "
"Swing(V): 3 (Change), Sleep: On, Health: On, "
"Clock: 10:15, On Timer: 13:20, Off Timer: 18:45",
ac.toString());
uint8_t expectedState[kHaierACStateLength] = {0xA5, 0x96, 0xEA, 0xCF, 0x32,
0x6D, 0x6D, 0x54, 0x54};
EXPECT_STATE_EQ(expectedState, ac.getRaw(), kHaierACBits);
// Check that the checksum is valid.
EXPECT_TRUE(IRHaierAC::validChecksum(ac.getRaw()));
// Now load up some random data.
uint8_t randomState[kHaierACStateLength] = {0x52, 0x49, 0x50, 0x20, 0x54,
0x61, 0x6C, 0x69, 0x61};
EXPECT_FALSE(IRHaierAC::validChecksum(randomState));
ac.setRaw(randomState);
EXPECT_EQ(
"Command: 9 (Timer Set), Mode: 3 (Heat), Temp: 20C, Fan: 3 (High), "
"Swing(V): 1 (Up), Sleep: On, Health: Off, "
"Clock: 16:32, On Timer: Off, Off Timer: Off",
ac.toString());
// getRaw() should correct the checksum.
EXPECT_TRUE(IRHaierAC::validChecksum(ac.getRaw()));
}
// Tests for the IRHaierACYRW02 class.
TEST(TestHaierACYRW02Class, Button) {
IRHaierACYRW02 ac(kGpioUnused);
ac.begin();
ac.setButton(kHaierAcYrw02ButtonPower);
EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonMode);
EXPECT_EQ(kHaierAcYrw02ButtonMode, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonSleep);
EXPECT_EQ(kHaierAcYrw02ButtonSleep, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonFan);
// Test unexpected values.
ac.setButton(0xFF);
EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
ac.setButton(0x10);
EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
}
TEST(TestHaierACYRW02Class, OperatingMode) {
IRHaierACYRW02 ac(kGpioUnused);
ac.begin();
ac.setButton(kHaierAcYrw02ButtonPower);
ac.setMode(kHaierAcYrw02Auto);
EXPECT_EQ(kHaierAcYrw02Auto, ac.getMode());
EXPECT_EQ(kHaierAcYrw02ButtonMode, ac.getButton());
ac.setMode(kHaierAcYrw02Cool);
EXPECT_EQ(kHaierAcYrw02Cool, ac.getMode());
ac.setMode(kHaierAcYrw02Heat);
EXPECT_EQ(kHaierAcYrw02Heat, ac.getMode());
ac.setMode(kHaierAcYrw02Fan);
EXPECT_EQ(kHaierAcYrw02Fan, ac.getMode());
ac.setMode(kHaierAcYrw02Dry);
EXPECT_EQ(kHaierAcYrw02Dry, ac.getMode());
ac.setMode(kHaierAcYrw02Auto - 1);
EXPECT_EQ(kHaierAcYrw02Auto, ac.getMode());
ac.setMode(kHaierAcYrw02Cool);
EXPECT_EQ(kHaierAcYrw02Cool, ac.getMode());
ac.setMode(kHaierAcYrw02Fan + 1);
EXPECT_EQ(kHaierAcYrw02Auto, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kHaierAcYrw02Auto, ac.getMode());
}
TEST(TestHaierACYRW02Class, Temperature) {
IRHaierACYRW02 ac(kGpioUnused);
ac.begin();
ac.setTemp(kHaierAcYrw02MinTempC);
EXPECT_EQ(kHaierAcYrw02MinTempC, ac.getTemp());
ac.setButton(kHaierAcYrw02ButtonPower);
ac.setTemp(kHaierAcYrw02MinTempC + 1);
EXPECT_EQ(kHaierAcYrw02MinTempC + 1, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
ac.setTemp(kHaierAcYrw02MaxTempC);
EXPECT_EQ(kHaierAcYrw02MaxTempC, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
ac.setTemp(kHaierAcYrw02MinTempC - 1);
EXPECT_EQ(kHaierAcYrw02MinTempC, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempDown, ac.getButton());
ac.setTemp(kHaierAcYrw02MaxTempC + 1);
EXPECT_EQ(kHaierAcYrw02MaxTempC, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
ac.setTemp(23);
EXPECT_EQ(23, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempDown, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonPower);
ac.setTemp(23);
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(24);
EXPECT_EQ(kHaierAcYrw02ButtonCFAB, ac.getButton());
ac.setTemp(0);
EXPECT_EQ(kHaierAcYrw02MinTempC, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempDown, ac.getButton());
ac.setTemp(255);
EXPECT_EQ(kHaierAcMaxTemp, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
}
TEST(TestHaierACYRW02Class, HealthMode) {
IRHaierACYRW02 ac(kGpioUnused);
ac.begin();
ac.setHealth(true);
EXPECT_TRUE(ac.getHealth());
EXPECT_EQ(kHaierAcYrw02ButtonHealth, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setHealth(false);
EXPECT_FALSE(ac.getHealth());
EXPECT_EQ(kHaierAcYrw02ButtonHealth, ac.getButton());
ac.setHealth(true);
EXPECT_TRUE(ac.getHealth());
EXPECT_EQ(kHaierAcYrw02ButtonHealth, ac.getButton());
}
TEST(TestHaierACYRW02Class, Power) {
IRHaierACYRW02 ac(kGpioUnused);
ac.begin();
ac.setPower(true);
EXPECT_TRUE(ac.getPower());
EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setPower(false);
EXPECT_FALSE(ac.getPower());
EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());
ac.setPower(true);
EXPECT_TRUE(ac.getPower());
EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());
ac.off();
EXPECT_FALSE(ac.getPower());
ac.on();
EXPECT_TRUE(ac.getPower());
}
TEST(TestHaierACYRW02Class, SleepMode) {
IRHaierACYRW02 ac(kGpioUnused);
ac.begin();
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
EXPECT_EQ(kHaierAcYrw02ButtonSleep, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setSleep(false);
EXPECT_FALSE(ac.getSleep());
EXPECT_EQ(kHaierAcYrw02ButtonSleep, ac.getButton());
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
EXPECT_EQ(kHaierAcYrw02ButtonSleep, ac.getButton());
}
TEST(TestHaierACYRW02Class, TurboAndQuiet) {
IRHaierACYRW02 ac(kGpioUnused);
ac.begin();
ac.setMode(kHaierAcYrw02Cool); // Turbo & Quiet is allowed in this mode.
ac.setTurbo(false);
ac.setQuiet(false);
EXPECT_FALSE(ac.getTurbo());
EXPECT_FALSE(ac.getQuiet());
EXPECT_EQ(kHaierAcYrw02ButtonTurbo, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
EXPECT_FALSE(ac.getQuiet());
EXPECT_EQ(kHaierAcYrw02ButtonTurbo, ac.getButton());
ac.setQuiet(true);
EXPECT_FALSE(ac.getTurbo());
EXPECT_TRUE(ac.getQuiet());
EXPECT_EQ(kHaierAcYrw02ButtonTurbo, ac.getButton());
ac.setTurbo(false);
ac.setQuiet(false);
EXPECT_FALSE(ac.getTurbo());
EXPECT_FALSE(ac.getQuiet());
EXPECT_EQ(kHaierAcYrw02ButtonTurbo, ac.getButton());
ac.setMode(kHaierAcYrw02Auto); // Turbo & Quiet is not allowed in this mode.
EXPECT_FALSE(ac.getTurbo());
EXPECT_FALSE(ac.getQuiet());
ac.setTurbo(true);
EXPECT_FALSE(ac.getTurbo());
EXPECT_NE(kHaierAcYrw02ButtonTurbo, ac.getButton());
ac.setQuiet(true);
EXPECT_FALSE(ac.getQuiet());
EXPECT_NE(kHaierAcYrw02ButtonTurbo, ac.getButton());
}
TEST(TestHaierACYRW02Class, Fan) {
IRHaierACYRW02 ac(kGpioUnused);
ac.begin();
ac.setFan(kHaierAcYrw02FanAuto);
EXPECT_EQ(kHaierAcYrw02FanAuto, ac.getFan());
EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setFan(kHaierAcYrw02FanLow);
EXPECT_EQ(kHaierAcYrw02FanLow, ac.getFan());
EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
ac.setFan(kHaierAcYrw02FanHigh);
EXPECT_EQ(kHaierAcYrw02FanHigh, ac.getFan());
EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
ac.setFan(kHaierAcYrw02FanMed);
EXPECT_EQ(kHaierAcYrw02FanMed, ac.getFan());
EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
// Test unexpected values.
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setFan(0x00);
EXPECT_EQ(kHaierAcYrw02FanMed, ac.getFan());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
}
TEST(TestHaierACYRW02Class, SwingV) {
IRHaierACYRW02 ac(kGpioUnused);
ac.begin();
ac.setSwingV(kHaierAcYrw02SwingVOff);
EXPECT_EQ(kHaierAcYrw02SwingVOff, ac.getSwingV());
EXPECT_EQ(kHaierAcYrw02ButtonSwingV, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setSwingV(kHaierAcYrw02SwingVAuto);
EXPECT_EQ(kHaierAcYrw02SwingVAuto, ac.getSwingV());
EXPECT_EQ(kHaierAcYrw02ButtonSwingV, ac.getButton());
ac.setSwingV(kHaierAcYrw02SwingVTop);
EXPECT_EQ(kHaierAcYrw02SwingVTop, ac.getSwingV());
EXPECT_EQ(kHaierAcYrw02ButtonSwingV, ac.getButton());
ac.setSwingV(kHaierAcYrw02SwingVDown);
EXPECT_EQ(kHaierAcYrw02SwingVDown, ac.getSwingV());
EXPECT_EQ(kHaierAcYrw02ButtonSwingV, ac.getButton());
// Test unexpected values.
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setSwingV(0xFF);
EXPECT_EQ(kHaierAcYrw02SwingVDown, ac.getSwingV());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
// Test the mode-dependant positions.
ac.setMode(kHaierAcYrw02Auto);
ac.setSwingV(kHaierAcYrw02SwingVMiddle);
EXPECT_EQ(kHaierAcYrw02SwingVMiddle, ac.getSwingV());
EXPECT_EQ(kHaierAcYrw02ButtonSwingV, ac.getButton());
ac.setMode(kHaierAcYrw02Heat);
ac.setSwingV(kHaierAcYrw02SwingVMiddle);
EXPECT_EQ(kHaierAcYrw02SwingVBottom, ac.getSwingV());
ac.setSwingV(kHaierAcYrw02SwingVAuto);
EXPECT_EQ(kHaierAcYrw02SwingVAuto, ac.getSwingV());
ac.setSwingV(kHaierAcYrw02SwingVBottom);
EXPECT_EQ(kHaierAcYrw02SwingVBottom, ac.getSwingV());
ac.setMode(kHaierAcYrw02Cool);
ac.setSwingV(kHaierAcYrw02SwingVBottom);
EXPECT_EQ(kHaierAcYrw02SwingVMiddle, ac.getSwingV());
}
TEST(TestHaierACYRW02Class, SwingH) {
IRHaierACYRW02 ac(kGpioUnused);
ac.begin();
ac.setSwingH(kHaierAcYrw02SwingVOff);
EXPECT_EQ(kHaierAcYrw02SwingHMiddle, ac.getSwingH());
EXPECT_EQ(kHaierAcYrw02ButtonSwingH, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setSwingH(kHaierAcYrw02SwingHLeftMax);
EXPECT_EQ(kHaierAcYrw02SwingHLeftMax, ac.getSwingH());
EXPECT_EQ(kHaierAcYrw02ButtonSwingH, ac.getButton());
ac.setSwingH(kHaierAcYrw02SwingHLeft);
EXPECT_EQ(kHaierAcYrw02SwingHLeft, ac.getSwingH());
EXPECT_EQ(kHaierAcYrw02ButtonSwingH, ac.getButton());
ac.setSwingH(kHaierAcYrw02SwingHRight);
EXPECT_EQ(kHaierAcYrw02SwingHRight, ac.getSwingH());
EXPECT_EQ(kHaierAcYrw02ButtonSwingH, ac.getButton());
ac.setSwingH(kHaierAcYrw02SwingHRightMax);
EXPECT_EQ(kHaierAcYrw02SwingHRightMax, ac.getSwingH());
EXPECT_EQ(kHaierAcYrw02ButtonSwingH, ac.getButton());
ac.setSwingH(kHaierAcYrw02SwingHAuto);
EXPECT_EQ(kHaierAcYrw02SwingHAuto, ac.getSwingH());
EXPECT_EQ(kHaierAcYrw02ButtonSwingH, ac.getButton());
// Test unexpected values.
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setSwingH(0xFF);
EXPECT_EQ(kHaierAcYrw02SwingHAuto, ac.getSwingH());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
}
TEST(TestHaierACYRW02Class, Lock) {
IRHaierACYRW02 ac(kGpioUnused);
ac.begin();
ac.setLock(true);
EXPECT_TRUE(ac.getLock());
EXPECT_EQ(kHaierAcYrw02ButtonLock, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setLock(false);
EXPECT_FALSE(ac.getLock());
EXPECT_EQ(kHaierAcYrw02ButtonLock, ac.getButton());
ac.setLock(true);
EXPECT_TRUE(ac.getLock());
EXPECT_EQ(kHaierAcYrw02ButtonLock, ac.getButton());
}
TEST(TestHaierACYRW02Class, MessageConstuction) {
IRHaierACYRW02 ac(kGpioUnused);
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: On, Button: 5 (Power), "
"Mode: 0 (Auto), Temp: 25C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
"Swing(V): 0 (Off), Swing(H): 0 (Middle), Sleep: Off, Health: On, "
"Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
ac.toString());
ac.setMode(kHaierAcYrw02Cool);
ac.setTemp(21);
ac.setFan(kHaierAcYrw02FanHigh);
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: On, Button: 4 (Fan), "
"Mode: 1 (Cool), Temp: 21C, Fan: 1 (High), Turbo: Off, Quiet: Off, "
"Swing(V): 0 (Off), Swing(H): 0 (Middle), Sleep: Off, Health: On, "
"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(
"Model: 1 (V9014557-A), 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",
ac.toString());
}
// Decode "real" state messages.
TEST(TestHaierACYRW02Class, RealStates) {
uint8_t expectedState1[kHaierACYRW02StateLength] = {
0xA6, 0xE1, 0x00, 0x00, 0x40, 0x20, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x6E};
IRHaierACYRW02 ac(kGpioUnused);
ac.setRaw(expectedState1);
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: On, Button: 7 (Health), "
"Mode: 4 (Heat), Temp: 30C, Fan: 1 (High), Turbo: Off, Quiet: Off, "
"Swing(V): 1 (Highest), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
"Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
ac.toString());
uint8_t expectedState2[kHaierACYRW02StateLength] = {
0xA6, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x05, 0x75};
ac.setRaw(expectedState2);
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: Off, Button: 5 (Power), "
"Mode: 4 (Heat), Temp: 30C, Fan: 1 (High), Turbo: Off, Quiet: Off, "
"Swing(V): 0 (Off), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
"Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
ac.toString());
uint8_t expectedState3[kHaierACYRW02StateLength] = {
0xA6, 0x02, 0x00, 0x02, 0x40, 0x20, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2B};
ac.setRaw(expectedState3);
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: On, Button: 1 (Temp Down), "
"Mode: 1 (Cool), Temp: 16C, Fan: 1 (High), Turbo: Off, Quiet: Off, "
"Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: On, "
"Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
ac.toString());
// cool 25, health, fan auto, vertical swing auto, sleep on
uint8_t expectedState4[kHaierACYRW02StateLength] = {
0xA6, 0x9C, 0x00, 0x02, 0x40, 0xA8, 0x00,
0x20, 0x80, 0x00, 0x00, 0x00, 0x0B, 0xD7};
ac.setRaw(expectedState4);
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: On, Button: 11 (Sleep), "
"Mode: 1 (Cool), Temp: 25C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
"Swing(V): 12 (Auto), Swing(H): 0 (Middle), Sleep: On, Health: On, "
"Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
ac.toString());
// cool 25, health, fan 3, vertical swing auto, sleep on
uint8_t expectedState5[kHaierACYRW02StateLength] = {
0xA6, 0x9C, 0x00, 0x02, 0x40, 0x27, 0x36,
0x20, 0x80, 0x00, 0x00, 0x00, 0x04, 0x85};
ac.setRaw(expectedState5);
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: On, Button: 4 (Fan), "
"Mode: 1 (Cool), Temp: 25C, Fan: 1 (High), Turbo: Off, Quiet: Off, "
"Swing(V): 12 (Auto), Swing(H): 0 (Middle), Sleep: On, Health: On, "
"Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
ac.toString());
}
// Tests for decodeHaierAC().
// Decode normal "synthetic" messages.
TEST(TestDecodeHaierAC, NormalDecodeWithStrict) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
uint8_t expectedState[kHaierACStateLength] = {0xA5, 0x01, 0x20, 0x01, 0x00,
0xC0, 0x20, 0x00, 0xA7};
// With the specific decoder.
irsend.reset();
irsend.sendHaierAC(expectedState);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeHaierAC(&irsend.capture, kStartOffset, kHaierACBits,
true));
EXPECT_EQ(HAIER_AC, irsend.capture.decode_type);
EXPECT_EQ(kHaierACBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
// With the all the decoders.
irsend.reset();
irsend.sendHaierAC(expectedState);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(HAIER_AC, irsend.capture.decode_type);
EXPECT_EQ(kHaierACBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
}
// Decode a "real" example message.
TEST(TestDecodeHaierAC, RealExample1) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
// Data from Issue #404 captured by kuzin2006,
// ON COOL 16C FAN LOW ALL OFF 12:00AM
uint16_t rawData[149] = {
3030, 3044, 3030, 4304, 576, 1694, 550, 582, 552, 1704, 552, 714, 550,
582, 550, 1706, 552, 582, 550, 1836, 552, 582, 578, 568, 550, 582,
550, 714, 550, 582, 550, 582, 552, 582, 550, 1836, 552, 582, 552,
580, 580, 1692, 550, 712, 552, 582, 550, 582, 552, 580, 550, 714,
552, 582, 550, 582, 552, 582, 578, 698, 552, 580, 552, 582, 552,
582, 552, 1836, 552, 580, 552, 582, 552, 582, 550, 714, 578, 568,
550, 582, 550, 582, 552, 714, 550, 1706, 550, 1706, 550, 582, 550,
714, 552, 582, 580, 566, 552, 582, 550, 714, 552, 580, 552, 580,
552, 1706, 550, 714, 550, 582, 552, 582, 578, 568, 552, 712, 552,
582, 550, 582, 550, 582, 550, 712, 552, 582, 550, 582, 552, 582,
578, 722, 552, 1704, 550, 582, 550, 1706, 550, 736, 550, 582, 550,
1706, 550, 1704, 552, 1704, 578};
uint8_t expectedState[kHaierACStateLength] = {0xA5, 0x01, 0x20, 0x01, 0x00,
0xC0, 0x20, 0x00, 0xA7};
irsend.sendRaw(rawData, 149, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(HAIER_AC, irsend.capture.decode_type);
EXPECT_EQ(kHaierACBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"Command: 1 (On), Mode: 1 (Cool), Temp: 16C, Fan: 1 (Low), "
"Swing(V): 0 (Off), Sleep: Off, Health: Off, "
"Clock: 00:01, On Timer: Off, Off Timer: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
// Decode a "real" example message.
TEST(TestDecodeHaierAC, RealExample2) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
// Data from Issue #404 captured by kuzin2006
// TEMP 21C
uint16_t rawData[149] = {
3028, 3046, 3028, 4304, 576, 1694, 552, 582, 550, 1704, 552, 714,
550, 582, 552, 1704, 550, 582, 550, 1836, 552, 582, 578, 1690,
552, 1704, 552, 712, 550, 582, 550, 1706, 550, 1706, 552, 712,
550, 582, 552, 582, 578, 1690, 552, 714, 552, 580, 552, 582,
552, 582, 550, 712, 552, 582, 550, 582, 550, 582, 578, 698,
552, 582, 550, 584, 550, 582, 552, 1836, 550, 582, 550, 582,
550, 582, 550, 712, 578, 568, 550, 582, 550, 582, 550, 714,
552, 1706, 550, 1706, 552, 580, 550, 714, 550, 582, 580, 568,
550, 582, 550, 714, 550, 582, 550, 582, 550, 1706, 552, 712,
550, 582, 550, 582, 580, 568, 552, 712, 550, 584, 550, 582,
550, 584, 550, 712, 550, 582, 550, 582, 550, 582, 578, 722,
550, 582, 552, 580, 552, 582, 550, 738, 550, 1706, 550, 1704,
552, 582, 550, 582, 578};
uint8_t expectedState[kHaierACStateLength] = {0xA5, 0x66, 0x20, 0x01, 0x00,
0xC0, 0x20, 0x00, 0x0C};
irsend.sendRaw(rawData, 149, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(HAIER_AC, irsend.capture.decode_type);
EXPECT_EQ(kHaierACBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
IRHaierAC ac(kGpioUnused);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Command: 6 (Temp Up), Mode: 1 (Cool), Temp: 22C, Fan: 1 (Low), "
"Swing(V): 0 (Off), Sleep: Off, Health: Off, "
"Clock: 00:01, On Timer: Off, Off Timer: Off",
ac.toString());
}
// Decode a "real" example message.
TEST(TestDecodeHaierAC, RealExample3) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
// Data from Issue #404 captured by kuzin2006
// HEALTH ON
uint16_t rawData[149] = {
3030, 3044, 3030, 4302, 578, 1692, 550, 582, 550, 1706, 550, 714,
550, 582, 552, 1706, 550, 582, 550, 1836, 552, 1706, 578, 1690,
552, 1704, 552, 714, 550, 1706, 552, 1706, 550, 582, 550, 714,
552, 582, 550, 582, 578, 1690, 550, 714, 552, 582, 552, 582,
550, 582, 550, 714, 550, 584, 550, 582, 550, 582, 578, 700,
552, 1706, 550, 582, 550, 582, 552, 1836, 550, 582, 550, 582,
552, 1706, 550, 714, 578, 568, 552, 582, 552, 582, 550, 714,
550, 1706, 550, 1706, 550, 582, 552, 712, 552, 582, 580, 568,
550, 582, 550, 714, 550, 582, 550, 582, 550, 1706, 550, 714,
550, 582, 550, 582, 578, 568, 552, 712, 552, 582, 550, 582,
550, 582, 550, 712, 550, 584, 550, 582, 552, 582, 578, 722,
552, 1704, 550, 582, 550, 1706, 550, 1862, 550, 1706, 550, 582,
550, 1704, 552, 582, 578};
uint8_t expectedState[kHaierACStateLength] = {0xA5, 0xEC, 0x20, 0x09, 0x20,
0xC0, 0x20, 0x00, 0xBA};
irsend.sendRaw(rawData, 149, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(HAIER_AC, irsend.capture.decode_type);
EXPECT_EQ(kHaierACBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
IRHaierAC ac(kGpioUnused);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Command: 12 (Health), Mode: 1 (Cool), Temp: 30C, Fan: 1 (Low), "
"Swing(V): 0 (Off), Sleep: Off, Health: On, "
"Clock: 00:09, On Timer: Off, Off Timer: Off",
ac.toString());
}
// Decode normal "synthetic" messages.
TEST(TestDecodeHaierAC_YRW02, NormalDecode) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
uint8_t expectedState[kHaierACYRW02StateLength] = {
0xA6, 0x12, 0x00, 0x02, 0x40, 0x20, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x3F};
irsend.reset();
irsend.sendHaierACYRW02(expectedState);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(HAIER_AC_YRW02, irsend.capture.decode_type);
EXPECT_EQ(kHaierACYRW02Bits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
}
// Decode a "real" example message.
TEST(TestDecodeHaierAC_YRW02, RealExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
// Data from Issue #485 captured by non7top
uint16_t rawData[229] = {
2998, 3086, 2998, 4460, 568, 1640, 596, 492, 514, 1690, 590, 496,
566, 532, 592, 1596, 570, 1618, 518, 584, 590, 538, 524, 536,
568, 532, 590, 1596, 516, 612, 568, 538, 522, 1638, 586, 500,
512, 614, 568, 538, 520, 538, 586, 538, 566, 540, 520, 538,
586, 538, 522, 538, 588, 538, 568, 538, 520, 538, 586, 538,
566, 538, 520, 540, 588, 1596, 590, 536, 568, 538, 520, 1592,
640, 538, 520, 540, 588, 538, 568, 538, 516, 562, 566, 538,
518, 542, 586, 540, 566, 1596, 590, 538, 566, 538, 516, 544,
586, 538, 516, 542, 588, 540, 564, 540, 468, 590, 588, 538,
566, 540, 466, 590, 588, 538, 514, 544, 588, 538, 566, 538,
468, 1692, 606, 526, 466, 592, 588, 538, 568, 490, 588, 538,
566, 540, 466, 592, 588, 538, 566, 538, 466, 592, 588, 538,
568, 492, 586, 540, 566, 540, 468, 590, 588, 538, 568, 516,
488, 590, 588, 538, 568, 492, 588, 538, 566, 518, 488, 590,
588, 540, 564, 518, 490, 590, 588, 538, 562, 496, 588, 538,
566, 518, 488, 590, 588, 538, 562, 522, 488, 588, 590, 538,
560, 498, 588, 540, 564, 522, 486, 590, 590, 538, 560, 524,
488, 588, 588, 1598, 514, 608, 564, 1600, 548, 536, 586, 538,
568, 1594, 590, 1618, 578, 1606, 606, 1582, 590, 1596, 590, 1616,
580};
uint8_t expectedState[kHaierACYRW02StateLength] = {
0xA6, 0x12, 0x00, 0x02, 0x40, 0x20, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x3F};
irsend.sendRaw(rawData, 229, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(HAIER_AC_YRW02, irsend.capture.decode_type);
EXPECT_EQ(kHaierACYRW02Bits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
IRHaierACYRW02 ac(kGpioUnused);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: On, Button: 5 (Power), "
"Mode: 1 (Cool), Temp: 17C, Fan: 1 (High), Turbo: Off, Quiet: Off, "
"Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: On, "
"Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
ac.toString());
}
// Default state of the remote needed to include hidden data.
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/668
TEST(TestHaierAcIssues, Issue668) {
IRHaierAC ac(kGpioUnused);
IRHaierAC acText(1);
IRrecv irrecv(kGpioUnused);
ac.begin();
// Turn on the AC.
ac._irsend.reset();
char expected_on[] =
"Command: 1 (On), Mode: 1 (Cool), Temp: 25C, Fan: 1 (Low), "
"Swing(V): 0 (Off), Sleep: Off, Health: Off, Clock: 00:00, "
"On Timer: Off, Off Timer: Off";
// State taken from real capture:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/668#issuecomment-483531895
uint8_t expected_on_state[9] = {
0xA5, 0x91, 0x20, 0x00, 0x0C, 0xC0, 0x20, 0x00, 0x42};
ac.setMode(kHaierAcCool);
ac.setCommand(kHaierAcCmdOn);
EXPECT_EQ(expected_on, ac.toString());
ac.send();
ac._irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&ac._irsend.capture));
ASSERT_EQ(HAIER_AC, ac._irsend.capture.decode_type);
EXPECT_EQ(kHaierACBits, ac._irsend.capture.bits);
EXPECT_STATE_EQ(expected_on_state,
ac._irsend.capture.state, ac._irsend.capture.bits);
acText.setRaw(ac._irsend.capture.state);
EXPECT_EQ(expected_on, acText.toString());
// Set the temp to 25C
ac._irsend.reset();
ac.setTemp(25);
EXPECT_EQ(expected_on, ac.toString());
ASSERT_EQ(25, ac.getTemp());
ac.send();
ac._irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&ac._irsend.capture));
ASSERT_EQ(HAIER_AC, ac._irsend.capture.decode_type);
EXPECT_EQ(kHaierACBits, ac._irsend.capture.bits);
EXPECT_STATE_EQ(expected_on_state,
ac._irsend.capture.state, ac._irsend.capture.bits);
acText.setRaw(ac._irsend.capture.state);
EXPECT_EQ(expected_on, acText.toString());
// Increase the temp by 1.
ac._irsend.reset();
char expected_temp_plus_one[] =
"Command: 6 (Temp Up), Mode: 1 (Cool), Temp: 26C, Fan: 1 (Low), "
"Swing(V): 0 (Off), Sleep: Off, Health: Off, Clock: 00:00, "
"On Timer: Off, Off Timer: Off";
// State taken from real capture:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/668#issuecomment-483531895
uint8_t expected_temp_plus_one_state[9] = {
0xA5, 0xA6, 0x20, 0x00, 0x0C, 0xC0, 0x20, 0x00, 0x57};
ASSERT_EQ(25, ac.getTemp());
ac.setTemp(ac.getTemp() + 1);
ASSERT_EQ(26, ac.getTemp());
EXPECT_EQ(expected_temp_plus_one, ac.toString());
ac.send();
ac._irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&ac._irsend.capture));
ASSERT_EQ(HAIER_AC, ac._irsend.capture.decode_type);
EXPECT_EQ(kHaierACBits, ac._irsend.capture.bits);
EXPECT_STATE_EQ(expected_temp_plus_one_state,
ac._irsend.capture.state, ac._irsend.capture.bits);
acText.setRaw(ac._irsend.capture.state);
EXPECT_EQ(expected_temp_plus_one, acText.toString());
// Decrease the temp by 1.
ac._irsend.reset();
char expected_temp_minus_one[] =
"Command: 7 (Temp Down), Mode: 1 (Cool), Temp: 25C, Fan: 1 (Low), "
"Swing(V): 0 (Off), Sleep: Off, Health: Off, Clock: 00:00, "
"On Timer: Off, Off Timer: Off";
ASSERT_EQ(26, ac.getTemp());
ac.setTemp(ac.getTemp() - 1);
ASSERT_EQ(25, ac.getTemp());
EXPECT_EQ(expected_temp_minus_one, ac.toString());
ac.send();
ac._irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&ac._irsend.capture));
ASSERT_EQ(HAIER_AC, ac._irsend.capture.decode_type);
EXPECT_EQ(kHaierACBits, ac._irsend.capture.bits);
acText.setRaw(ac._irsend.capture.state);
EXPECT_EQ(expected_temp_minus_one, acText.toString());
}
TEST(TestHaierACClass, toCommon) {
IRHaierAC ac(kGpioUnused);
ac.setCommand(kHaierAcCmdOn);
ac.setMode(kHaierAcCool);
ac.setTemp(20);
ac.setFan(kHaierAcFanHigh);
ac.setSwingV(kHaierAcSwingVChg);
ac.setHealth(true);
ac.setSleep(true);
// Now test it.
ASSERT_EQ(decode_type_t::HAIER_AC, ac.toCommon().protocol);
ASSERT_EQ(-1, ac.toCommon().model);
ASSERT_TRUE(ac.toCommon().power);
ASSERT_TRUE(ac.toCommon().celsius);
ASSERT_EQ(20, ac.toCommon().degrees);
ASSERT_TRUE(ac.toCommon().filter);
ASSERT_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kAuto, ac.toCommon().swingv);
ASSERT_EQ(0, ac.toCommon().sleep);
// Unsupported.
ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh);
ASSERT_FALSE(ac.toCommon().turbo);
ASSERT_FALSE(ac.toCommon().light);
ASSERT_FALSE(ac.toCommon().quiet);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().clean);
ASSERT_TRUE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().clock);
}
TEST(TestHaierACYRW02Class, toCommon) {
IRHaierACYRW02 ac(kGpioUnused);
ac.setPower(true);
ac.setMode(kHaierAcYrw02Cool);
ac.setTemp(20);
ac.setFan(kHaierAcYrw02FanHigh);
ac.setSwingV(kHaierAcYrw02SwingVTop);
ac.setSwingH(kHaierAcYrw02SwingHRightMax);
ac.setHealth(true);
ac.setSleep(true);
ac.setTurbo(true);
// Now test it.
ASSERT_EQ(decode_type_t::HAIER_AC_YRW02, ac.toCommon().protocol);
ASSERT_EQ(1, ac.toCommon().model);
ASSERT_TRUE(ac.toCommon().power);
ASSERT_TRUE(ac.toCommon().celsius);
ASSERT_EQ(20, ac.toCommon().degrees);
ASSERT_TRUE(ac.toCommon().filter);
ASSERT_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kHighest, ac.toCommon().swingv);
ASSERT_EQ(stdAc::swingh_t::kRightMax, ac.toCommon().swingh);
ASSERT_EQ(0, ac.toCommon().sleep);
ASSERT_TRUE(ac.toCommon().turbo);
ASSERT_FALSE(ac.toCommon().quiet);
// Unsupported.
ASSERT_FALSE(ac.toCommon().light);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().clean);
ASSERT_TRUE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().clock);
}
TEST(TestDecodeHaierAC176, RealExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1480
const uint16_t rawData[357] = {
3096, 2948, 3048, 4388, 588, 1610, 614, 498, 586, 1612, 612, 500, 612,
500, 586, 1610, 588, 1612, 612, 502, 586, 1612, 612, 500, 612, 500, 614,
500, 612, 498, 586, 1610, 586, 1612, 612, 502, 612, 500, 612, 500, 612,
500, 612, 500, 612, 500, 612, 500, 612, 500, 612, 504, 612, 500, 612, 500,
612, 500, 612, 500, 612, 500, 612, 500, 612, 500, 612, 502, 614, 498, 586,
1612, 612, 500, 612, 500, 612, 500, 612, 500, 612, 500, 612, 502, 586,
1612, 612, 500, 586, 1610, 612, 500, 612, 498, 612, 500, 614, 478, 634,
502, 612, 500, 612, 500, 612, 500, 612, 500, 612, 500, 612, 500, 612, 498,
614, 504, 612, 500, 614, 500, 586, 1612, 612, 500, 612, 500, 612, 500,
612, 500, 612, 502, 612, 500, 612, 500, 612, 500, 612, 500, 612, 500, 612,
500, 612, 500, 612, 504, 614, 500, 612, 500, 612, 498, 614, 500, 612, 500,
612, 500, 612, 500, 612, 482, 632, 500, 612, 502, 610, 500, 614, 500, 612,
500, 612, 500, 612, 480, 632, 504, 612, 480, 632, 500, 612, 500, 612, 480,
632, 500, 612, 500, 612, 500, 612, 502, 612, 500, 612, 500, 612, 500, 612,
500, 612, 500, 586, 1612, 612, 500, 586, 1616, 612, 500, 612, 500, 586,
1610, 588, 1612, 612, 502, 612, 500, 614, 498, 586, 1614, 586, 1612, 612,
500, 586, 1610, 586, 1592, 632, 498, 586, 1610, 588, 1610, 586, 1614, 614,
500, 612, 480, 632, 500, 612, 500, 612, 500, 612, 500, 614, 498, 612, 500,
614, 500, 614, 500, 612, 500, 612, 500, 614, 498, 614, 498, 614, 500, 612,
504, 612, 500, 612, 500, 612, 500, 612, 498, 612, 502, 612, 500, 614, 498,
612, 502, 612, 500, 612, 498, 614, 500, 612, 500, 612, 500, 612, 500, 612,
500, 614, 502, 612, 500, 614, 478, 634, 498, 614, 500, 612, 500, 612, 500,
612, 500, 612, 482, 634, 500, 612, 500, 612, 500, 612, 500, 614, 498, 614,
500, 612, 480, 632, 502, 586, 1610, 614, 478, 608, 1610, 588, 1610, 612,
498, 586, 1610, 588, 1610, 586, 1606, 612}; // UNKNOWN ABFAD961
irsend.sendRaw(rawData, 357, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(HAIER_AC176, irsend.capture.decode_type);
EXPECT_EQ(kHaierAC176Bits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
const uint8_t expectedState[kHaierAC176StateLength] = {
0xA6, 0x86, 0x00, 0x00, 0x40, 0xA0, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x31,
0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB7};
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
}
// Decode normal "synthetic" messages.
TEST(TestDecodeHaierAC176, SyntheticDecode) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
const uint8_t expectedState[kHaierAC176StateLength] = {
0xA6, 0x86, 0x00, 0x00, 0x40, 0xA0, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x31,
0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB7};
irsend.reset();
irsend.sendHaierAC176(expectedState);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(HAIER_AC176, irsend.capture.decode_type);
EXPECT_EQ(kHaierAC176Bits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: On, Button: 5 (Power), "
"Mode: 1 (Cool), Temp: 24C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
"Swing(V): 6 (UNKNOWN), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
"Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t result, prev;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev));
}
TEST(TestUtils, Housekeeping) {
ASSERT_EQ("HAIER_AC", typeToString(decode_type_t::HAIER_AC));
ASSERT_EQ(decode_type_t::HAIER_AC, strToDecodeType("HAIER_AC"));
ASSERT_TRUE(hasACState(decode_type_t::HAIER_AC));
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::HAIER_AC));
ASSERT_EQ(kHaierACBits, IRsend::defaultBits(decode_type_t::HAIER_AC));
ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::HAIER_AC));
ASSERT_EQ("HAIER_AC_YRW02", typeToString(decode_type_t::HAIER_AC_YRW02));
ASSERT_EQ(decode_type_t::HAIER_AC_YRW02, strToDecodeType("HAIER_AC_YRW02"));
ASSERT_TRUE(hasACState(decode_type_t::HAIER_AC_YRW02));
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::HAIER_AC_YRW02));
ASSERT_EQ(kHaierACYRW02Bits,
IRsend::defaultBits(decode_type_t::HAIER_AC_YRW02));
ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::HAIER_AC_YRW02));
ASSERT_EQ("HAIER_AC176", typeToString(decode_type_t::HAIER_AC176));
ASSERT_EQ(decode_type_t::HAIER_AC176, strToDecodeType("HAIER_AC176"));
ASSERT_TRUE(hasACState(decode_type_t::HAIER_AC176));
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::HAIER_AC176));
ASSERT_EQ(kHaierAC176Bits, IRsend::defaultBits(decode_type_t::HAIER_AC176));
ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::HAIER_AC176));
ASSERT_EQ("HAIER_AC160", typeToString(decode_type_t::HAIER_AC160));
ASSERT_EQ(decode_type_t::HAIER_AC160, strToDecodeType("HAIER_AC160"));
ASSERT_TRUE(hasACState(decode_type_t::HAIER_AC160));
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::HAIER_AC160));
ASSERT_EQ(kHaierAC160Bits, IRsend::defaultBits(decode_type_t::HAIER_AC160));
ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::HAIER_AC160));
}
TEST(TestHaierAC176Class, BuildKnownState) {
IRHaierAC176 ac(kGpioUnused);
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1480#issuecomment-884920033
// heat, 24 C, fan max
ac.setTemp(24);
ac.setMode(kHaierAcYrw02Heat);
ac.setFan(kHaierAcYrw02FanHigh);
EXPECT_TRUE(ac.validChecksum(ac.getRaw()));
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: On, Button: 4 (Fan), "
"Mode: 4 (Heat), Temp: 24C, Fan: 1 (High), Turbo: Off, Quiet: Off, "
"Swing(V): 0 (Off), Swing(H): 0 (Middle), Sleep: Off, Health: On, "
"Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
ac.toString());
/* Disabled pending:
https://github.com/crankyoldgit/IRremoteESP8266/issues/1480#issuecomment-885636790
const uint8_t expectedState[kHaierAC176StateLength] = {
0xA6, 0x0A, 0x00, 0x00, 0x40, 0x20, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0x94,
0xB7, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xF7};
EXPECT_STATE_EQ(expectedState, ac.getRaw(), kHaierAC176StateLength);
*/
}
TEST(TestHaierAC176Class, Timers) {
IRHaierAC176 ac(kGpioUnused);
EXPECT_EQ(kHaierAcYrw02NoTimers, ac.getTimerMode());
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_EQ(0, ac.getOffTimer());
// On Timer
ac.setOnTimer(1);
EXPECT_EQ(kHaierAcYrw02OnTimer, ac.getTimerMode());
EXPECT_EQ(1, ac.getOnTimer());
ac.setOnTimer(0);
EXPECT_EQ(kHaierAcYrw02NoTimers, ac.getTimerMode());
EXPECT_EQ(0, ac.getOnTimer());
ac.setOnTimer(1 * 60);
EXPECT_EQ(kHaierAcYrw02OnTimer, ac.getTimerMode());
EXPECT_EQ(1 * 60, ac.getOnTimer());
ac.setOnTimer(2 * 60 + 37);
EXPECT_EQ(kHaierAcYrw02OnTimer, ac.getTimerMode());
EXPECT_EQ(2 * 60 + 37, ac.getOnTimer());
ac.setOnTimer(23 * 60 + 59); // Max
EXPECT_EQ(kHaierAcYrw02OnTimer, ac.getTimerMode());
EXPECT_EQ(23 * 60 + 59, ac.getOnTimer());
ac.setOnTimer(24 * 60); // Beyond max
EXPECT_EQ(kHaierAcYrw02OnTimer, ac.getTimerMode());
EXPECT_EQ(23 * 60 + 59, ac.getOnTimer()); // Max
ac.setOnTimer(0);
EXPECT_EQ(kHaierAcYrw02NoTimers, ac.getTimerMode());
EXPECT_EQ(0, ac.getOnTimer());
// Off Timer
ac.setOffTimer(1);
EXPECT_EQ(kHaierAcYrw02OffTimer, ac.getTimerMode());
EXPECT_EQ(1, ac.getOffTimer());
ac.setOffTimer(0);
EXPECT_EQ(kHaierAcYrw02NoTimers, ac.getTimerMode());
EXPECT_EQ(0, ac.getOffTimer());
ac.setOffTimer(1 * 60);
EXPECT_EQ(kHaierAcYrw02OffTimer, ac.getTimerMode());
EXPECT_EQ(1 * 60, ac.getOffTimer());
ac.setOffTimer(2 * 60 + 37);
EXPECT_EQ(kHaierAcYrw02OffTimer, ac.getTimerMode());
ac.setOffTimer(23 * 60 + 59); // Max
EXPECT_EQ(kHaierAcYrw02OffTimer, ac.getTimerMode());
EXPECT_EQ(23 * 60 + 59, ac.getOffTimer());
ac.setOffTimer(24 * 60); // Beyond max
EXPECT_EQ(kHaierAcYrw02OffTimer, ac.getTimerMode());
EXPECT_EQ(23 * 60 + 59, ac.getOffTimer()); // Max
ac.setOffTimer(0);
EXPECT_EQ(kHaierAcYrw02NoTimers, ac.getTimerMode());
EXPECT_EQ(0, ac.getOffTimer());
// Real data.
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1480#issuecomment-894804106
const uint8_t timer30m[kHaierAC176StateLength] = {
0xA6, 0x82, 0x00, 0x40, 0x00, 0xA0, 0x00, 0x00, 0x1E, 0x00, 0x00,
0x00, 0x10, 0x36, 0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB7};
const uint8_t timeroff[kHaierAC176StateLength] = {
0xA6, 0x82, 0x00, 0x00, 0x40, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x18, 0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB7};
// https://docs.google.com/spreadsheets/d/1wdOVS08wgK2pEP7hTZLYMmrQ9FZVmLpZF2HjNQaVxlU/edit#gid=0&range=A65
const uint8_t timeroffthenon[kHaierAC176StateLength] = {
0xA6, 0x82, 0x00, 0xA0, 0x40, 0xA0, 0x1E, 0x08, 0x00, 0x00, 0x00,
0x00, 0x10, 0xDE, 0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB7};
ac.setRaw(timer30m);
EXPECT_EQ(kHaierAcYrw02OnTimer, ac.getTimerMode());
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: Off, Button: 16 (Timer), "
"Mode: 0 (Auto), Temp: 24C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
"Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
"Timer Mode: 2 (On), On Timer: 00:30, Off Timer: Off, Lock: Off",
ac.toString());
ac.setRaw(timeroff);
EXPECT_EQ(kHaierAcYrw02NoTimers, ac.getTimerMode());
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: On, Button: 16 (Timer), "
"Mode: 0 (Auto), Temp: 24C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
"Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
"Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
ac.toString());
ac.setRaw(timeroffthenon);
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: On, Button: 16 (Timer), "
"Mode: 0 (Auto), Temp: 24C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
"Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
"Timer Mode: 5 (Off-On), On Timer: 08:00, Off Timer: 00:30, Lock: Off",
ac.toString());
ac.setTimerMode(kHaierAcYrw02OnThenOffTimer);
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: On, Button: 16 (Timer), "
"Mode: 0 (Auto), Temp: 24C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
"Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
"Timer Mode: 4 (On-Off), On Timer: 08:00, Off Timer: 00:30, Lock: Off",
ac.toString());
ac.setTimerMode(kHaierAcYrw02OffTimer);
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_EQ(30, ac.getOffTimer());
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: On, Button: 16 (Timer), "
"Mode: 0 (Auto), Temp: 24C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
"Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
"Timer Mode: 1 (Off), On Timer: Off, Off Timer: 00:30, Lock: Off",
ac.toString());
ac.setTimerMode(kHaierAcYrw02NoTimers);
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_EQ(0, ac.getOffTimer());
EXPECT_EQ(
"Model: 1 (V9014557-A), Power: On, Button: 16 (Timer), "
"Mode: 0 (Auto), Temp: 24C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
"Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
"Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
ac.toString());
}
TEST(TestHaierAC176Class, Models) {
IRHaierAC176 ac(kGpioUnused);
ac.begin();
EXPECT_EQ(haier_ac176_remote_model_t::V9014557_A, ac.getModel());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setModel(haier_ac176_remote_model_t::V9014557_B);
EXPECT_EQ(haier_ac176_remote_model_t::V9014557_B, ac.getModel());
EXPECT_EQ(kHaierAcYrw02ButtonCFAB, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempDown);
ac.setModel(haier_ac176_remote_model_t::V9014557_A);
EXPECT_EQ(haier_ac176_remote_model_t::V9014557_A, ac.getModel());
EXPECT_EQ(kHaierAcYrw02ButtonCFAB, ac.getButton());
// Real data.
const uint8_t setmodelb[kHaierAC176StateLength] = {
0x59, 0x82, 0x00, 0x00, 0x40, 0x60, 0x00, 0xC0, 0x00, 0x00, 0x00,
0x00, 0x1A, 0x55, 0xB7, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x77};
ac.setRaw(setmodelb);
EXPECT_EQ(haier_ac176_remote_model_t::V9014557_B, ac.getModel());
EXPECT_EQ(
"Model: 2 (V9014557-B), Power: On, Button: 26 (Celsius/Fahrenheit), "
"Mode: 6 (Fan), Temp: 24C, Fan: 3 (Low), Turbo: Off, Quiet: Off, "
"Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
"Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
ac.toString());
}
TEST(TestDecodeHaierAC160, RealExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1804#issue-1236115063
const uint16_t rawData[325] = {
3078, 3002,
3058, 4338,
590, 1612, 588, 516, 584, 1588, 586, 542, 560, 540, 560, 1590, 584, 1618,
584, 542, 558, 1592, 584, 542, 582, 1594, 584, 542, 582, 1592, 560, 1642,
560, 516, 558, 544, 558, 542, 558, 542, 582, 518, 558, 542, 558, 516, 558,
542, 558, 542, 582, 520, 558, 542, 558, 542, 564, 510, 608, 492, 558, 542,
582, 520, 558, 542, 558, 544, 582, 492, 608, 1594, 558, 544, 558, 542,
582, 494, 608, 494, 558, 544, 558, 542, 558, 544, 558, 1616, 582, 1620,
560, 542, 558, 542, 582, 494, 558, 542, 558, 542, 558, 544, 556, 542, 582,
520, 580, 494, 582, 520, 582, 520, 558, 542, 558, 542, 582, 520, 582, 492,
608, 1592, 582, 520, 558, 544, 558, 516, 584, 518, 558, 542, 582, 520,
580, 520, 582, 520, 580, 492, 584, 516, 556, 544, 582, 518, 580, 520, 580,
520, 580, 494, 606, 494, 580, 520, 580, 520, 582, 520, 580, 520, 556, 518,
608, 492, 580, 520, 556, 544, 580, 520, 580, 520, 580, 494, 606, 494, 580,
520, 580, 520, 580, 520, 580, 520, 580, 494, 606, 496, 578, 522, 580, 520,
580, 520, 580, 520, 580, 494, 606, 494, 580, 520, 580, 520, 580, 1594,
608, 494, 580, 1620, 580, 522, 580, 520, 580, 494, 578, 1620, 582, 520,
580, 1596, 582, 1620, 582, 1594, 608, 1594, 582, 522, 580, 1594, 582,
1620, 582, 520, 580, 1596, 582, 520, 580, 1620, 582, 494, 606, 496, 580,
522, 580, 522, 580, 520, 580, 520, 580, 496, 604, 496, 580, 520, 580,
1620, 582, 1594, 582, 522, 578, 522, 580, 522, 578, 522, 580, 496, 580,
522, 578, 522, 578, 522, 578, 524, 578, 522, 578, 496, 578, 522, 578, 522,
578, 546, 554, 522, 578, 522, 578, 520, 556, 546, 554, 546, 554, 546, 556,
544, 556, 546, 554, 520, 554, 544, 556, 1620, 582, 544, 556, 1594, 580,
546, 556, 1594, 580}; // UNKNOWN B6B57D85
const uint8_t expectedState[kHaierAC160StateLength] = {
0xA6, 0xAC, 0x00, 0x00, 0x40, 0x60, 0x00, 0x20, 0x00, 0x00,
0x00, 0x00, 0x05, 0x17, 0xB5, 0x00, 0x60, 0x00, 0x00, 0x15};
irsend.sendRaw(rawData, 325, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(HAIER_AC160, irsend.capture.decode_type);
ASSERT_EQ(kHaierAC160Bits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"Power: On, Button: 5 (Power), Mode: 1 (Cool), Temp: 26C, Fan: 3 (Low), "
"Turbo: Off, Quiet: Off, Health: Off, Swing(V): 12 (Auto), Sleep: Off, "
"Clean: 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));
}
// Decoding a message we entirely constructed based solely on a given state.
TEST(TestDecodeHaierAC160, SyntheticExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
const uint8_t expectedState[kHaierAC160StateLength] = {
0xA6, 0xAC, 0x00, 0x00, 0x40, 0x60, 0x00, 0x20, 0x00, 0x00,
0x00, 0x00, 0x05, 0x17, 0xB5, 0x00, 0x60, 0x00, 0x00, 0x15};
irsend.reset();
irsend.sendHaierAC160(expectedState);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(HAIER_AC160, irsend.capture.decode_type);
ASSERT_EQ(kHaierAC160Bits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"Power: On, Button: 5 (Power), Mode: 1 (Cool), Temp: 26C, Fan: 3 (Low), "
"Turbo: Off, Quiet: Off, Health: Off, Swing(V): 12 (Auto), Sleep: Off, "
"Clean: 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));
}
// Tests for the IRHaierAC160 class.
TEST(TestHaierAC160Class, Button) {
IRHaierAC160 ac(kGpioUnused);
ac.begin();
ac.setButton(kHaierAcYrw02ButtonPower);
EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonMode);
EXPECT_EQ(kHaierAcYrw02ButtonMode, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonSleep);
EXPECT_EQ(kHaierAcYrw02ButtonSleep, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonFan);
// Test unexpected values.
ac.setButton(0xFF);
EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
ac.setButton(0x10);
EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
}
TEST(TestHaierAC160Class, OperatingMode) {
IRHaierAC160 ac(kGpioUnused);
ac.begin();
ac.setButton(kHaierAcYrw02ButtonPower);
ac.setMode(kHaierAcYrw02Auto);
EXPECT_EQ(kHaierAcYrw02Auto, ac.getMode());
EXPECT_EQ(kHaierAcYrw02ButtonMode, ac.getButton());
ac.setMode(kHaierAcYrw02Cool);
EXPECT_EQ(kHaierAcYrw02Cool, ac.getMode());
EXPECT_FALSE(ac.getAuxHeating());
ac.setMode(kHaierAcYrw02Heat);
EXPECT_EQ(kHaierAcYrw02Heat, ac.getMode());
EXPECT_TRUE(ac.getAuxHeating());
ac.setMode(kHaierAcYrw02Fan);
EXPECT_EQ(kHaierAcYrw02Fan, ac.getMode());
EXPECT_FALSE(ac.getAuxHeating());
ac.setMode(kHaierAcYrw02Dry);
EXPECT_EQ(kHaierAcYrw02Dry, ac.getMode());
ac.setMode(kHaierAcYrw02Auto - 1);
EXPECT_EQ(kHaierAcYrw02Auto, ac.getMode());
ac.setMode(kHaierAcYrw02Cool);
EXPECT_EQ(kHaierAcYrw02Cool, ac.getMode());
ac.setMode(kHaierAcYrw02Fan + 1);
EXPECT_EQ(kHaierAcYrw02Auto, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kHaierAcYrw02Auto, ac.getMode());
}
TEST(TestHaierAC160Class, Temperature) {
IRHaierAC160 ac(kGpioUnused);
ac.begin();
ac.setTemp(kHaierAcYrw02MinTempC);
EXPECT_EQ(kHaierAcYrw02MinTempC, ac.getTemp());
ac.setButton(kHaierAcYrw02ButtonPower);
ac.setTemp(kHaierAcYrw02MinTempC + 1);
EXPECT_EQ(kHaierAcYrw02MinTempC + 1, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
ac.setTemp(kHaierAcYrw02MaxTempC);
EXPECT_EQ(kHaierAcYrw02MaxTempC, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
ac.setTemp(kHaierAcYrw02MinTempC - 1);
EXPECT_EQ(kHaierAcYrw02MinTempC, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempDown, ac.getButton());
ac.setTemp(kHaierAcYrw02MaxTempC + 1);
EXPECT_EQ(kHaierAcYrw02MaxTempC, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
ac.setTemp(23);
EXPECT_EQ(23, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempDown, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonPower);
ac.setTemp(23);
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(24);
EXPECT_EQ(kHaierAcYrw02ButtonCFAB, ac.getButton());
ac.setTemp(0);
EXPECT_EQ(kHaierAcYrw02MinTempC, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempDown, ac.getButton());
ac.setTemp(255);
EXPECT_EQ(kHaierAcMaxTemp, ac.getTemp());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
}
TEST(TestHaierAC160Class, CleanMode) {
IRHaierAC160 ac(kGpioUnused);
ac.begin();
ac.setClean(true);
EXPECT_TRUE(ac.getClean());
EXPECT_EQ(kHaierAc160ButtonClean, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setClean(false);
EXPECT_FALSE(ac.getClean());
EXPECT_EQ(kHaierAc160ButtonClean, ac.getButton());
ac.setClean(true);
EXPECT_TRUE(ac.getClean());
EXPECT_EQ(kHaierAc160ButtonClean, ac.getButton());
ac.stateReset();
EXPECT_FALSE(ac.getClean());
// clean button pressed.
// https://docs.google.com/spreadsheets/d/1RNJ7esbArS5fy1lmiM-i1PekXSNojCMad4WuuyunsC8/edit#gid=2048081808&range=FR22
const uint8_t clean_on[kHaierAC160StateLength] = {
0xA6, 0xAC, 0x00, 0x00, 0x40, 0x60, 0x00, 0x20, 0x00, 0x00,
0x10, 0x00, 0x19, 0x3B, 0xB5, 0x40, 0x60, 0x00, 0x00, 0x55};
ac.setRaw(clean_on);
EXPECT_TRUE(ac.getClean());
EXPECT_EQ(
"Power: On, Button: 25 (Clean), Mode: 1 (Cool), Temp: 26C, "
"Fan: 3 (Low), Turbo: Off, Quiet: Off, Health: Off, Swing(V): 12 (Auto), "
"Sleep: Off, Clean: On, Timer Mode: 0 (N/A), "
"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
const uint8_t clean_off[kHaierAC160StateLength] = {
0xA6, 0xAC, 0x00, 0x00, 0x40, 0x60, 0x00, 0x20, 0x00, 0x00,
0x00, 0x00, 0x05, 0x17, 0xB5, 0x00, 0x60, 0x00, 0x00, 0x15};
ac.setRaw(clean_off);
EXPECT_FALSE(ac.getClean());
EXPECT_EQ(
"Power: On, Button: 5 (Power), Mode: 1 (Cool), Temp: 26C, "
"Fan: 3 (Low), Turbo: Off, Quiet: Off, Health: 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());
}
TEST(TestHaierAC160Class, Power) {
IRHaierAC160 ac(kGpioUnused);
ac.begin();
ac.setPower(true);
EXPECT_TRUE(ac.getPower());
EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setPower(false);
EXPECT_FALSE(ac.getPower());
EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());
ac.setPower(true);
EXPECT_TRUE(ac.getPower());
EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());
ac.off();
EXPECT_FALSE(ac.getPower());
ac.on();
EXPECT_TRUE(ac.getPower());
}
TEST(TestHaierAC160Class, SleepMode) {
IRHaierAC160 ac(kGpioUnused);
ac.begin();
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
EXPECT_EQ(kHaierAcYrw02ButtonSleep, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setSleep(false);
EXPECT_FALSE(ac.getSleep());
EXPECT_EQ(kHaierAcYrw02ButtonSleep, ac.getButton());
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
EXPECT_EQ(kHaierAcYrw02ButtonSleep, ac.getButton());
}
TEST(TestHaierAC160Class, Health) {
IRHaierAC160 ac(kGpioUnused);
ac.begin();
ac.setHealth(true);
EXPECT_TRUE(ac.getHealth());
EXPECT_EQ(kHaierAcYrw02ButtonHealth, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setHealth(false);
EXPECT_FALSE(ac.getHealth());
EXPECT_EQ(kHaierAcYrw02ButtonHealth, ac.getButton());
ac.setHealth(true);
EXPECT_TRUE(ac.getHealth());
EXPECT_EQ(kHaierAcYrw02ButtonHealth, ac.getButton());
}
TEST(TestHaierAC160Class, TurboAndQuiet) {
IRHaierAC160 ac(kGpioUnused);
ac.begin();
ac.setMode(kHaierAcYrw02Cool); // Turbo & Quiet is allowed in this mode.
ac.setTurbo(false);
ac.setQuiet(false);
EXPECT_FALSE(ac.getTurbo());
EXPECT_FALSE(ac.getQuiet());
EXPECT_EQ(kHaierAcYrw02ButtonTurbo, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
EXPECT_FALSE(ac.getQuiet());
EXPECT_EQ(kHaierAcYrw02ButtonTurbo, ac.getButton());
ac.setQuiet(true);
EXPECT_FALSE(ac.getTurbo());
EXPECT_TRUE(ac.getQuiet());
EXPECT_EQ(kHaierAcYrw02ButtonTurbo, ac.getButton());
ac.setTurbo(false);
ac.setQuiet(false);
EXPECT_FALSE(ac.getTurbo());
EXPECT_FALSE(ac.getQuiet());
EXPECT_EQ(kHaierAcYrw02ButtonTurbo, ac.getButton());
ac.setMode(kHaierAcYrw02Auto); // Turbo & Quiet is not allowed in this mode.
EXPECT_FALSE(ac.getTurbo());
EXPECT_FALSE(ac.getQuiet());
ac.setTurbo(true);
EXPECT_FALSE(ac.getTurbo());
EXPECT_NE(kHaierAcYrw02ButtonTurbo, ac.getButton());
ac.setQuiet(true);
EXPECT_FALSE(ac.getQuiet());
EXPECT_NE(kHaierAcYrw02ButtonTurbo, ac.getButton());
}
TEST(TestHaierAC160Class, Fan) {
IRHaierAC160 ac(kGpioUnused);
ac.begin();
ac.setFan(kHaierAcYrw02FanAuto);
EXPECT_EQ(kHaierAcYrw02FanAuto, ac.getFan());
EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setFan(kHaierAcYrw02FanLow);
EXPECT_EQ(kHaierAcYrw02FanLow, ac.getFan());
EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
ac.setFan(kHaierAcYrw02FanHigh);
EXPECT_EQ(kHaierAcYrw02FanHigh, ac.getFan());
EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
ac.setFan(kHaierAcYrw02FanMed);
EXPECT_EQ(kHaierAcYrw02FanMed, ac.getFan());
EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
// Test unexpected values.
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setFan(0x00);
EXPECT_EQ(kHaierAcYrw02FanMed, ac.getFan());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
}
TEST(TestHaierAC160Class, SwingV) {
IRHaierAC160 ac(kGpioUnused);
ac.begin();
ac.setSwingV(kHaierAc160SwingVOff);
EXPECT_EQ(kHaierAc160SwingVOff, ac.getSwingV());
EXPECT_EQ(kHaierAcYrw02ButtonSwingV, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setSwingV(kHaierAc160SwingVAuto);
EXPECT_EQ(kHaierAc160SwingVAuto, ac.getSwingV());
EXPECT_EQ(kHaierAcYrw02ButtonSwingV, ac.getButton());
ac.setSwingV(kHaierAc160SwingVTop);
EXPECT_EQ(kHaierAc160SwingVTop, ac.getSwingV());
EXPECT_EQ(kHaierAcYrw02ButtonSwingV, ac.getButton());
ac.setSwingV(kHaierAc160SwingVLow);
EXPECT_EQ(kHaierAc160SwingVLow, ac.getSwingV());
EXPECT_EQ(kHaierAcYrw02ButtonSwingV, ac.getButton());
// Test unexpected values.
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setSwingV(0xFF);
EXPECT_EQ(kHaierAc160SwingVLow, ac.getSwingV());
EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
}
TEST(TestHaierAC160Class, Light) {
IRHaierAC160 ac(kGpioUnused);
ac.begin();
ac.setLightToggle(true);
EXPECT_TRUE(ac.getLightToggle());
EXPECT_EQ(kHaierAc160ButtonLight, ac.getButton());
ac.setButton(kHaierAcYrw02ButtonTempUp);
ac.setLightToggle(false);
EXPECT_FALSE(ac.getLightToggle());
EXPECT_NE(kHaierAc160ButtonLight, ac.getButton());
ac.setLightToggle(true);
EXPECT_TRUE(ac.getLightToggle());
EXPECT_EQ(kHaierAc160ButtonLight, ac.getButton());
const uint8_t light_press[kHaierAC160StateLength] = {
0xA6, 0xAC, 0x00, 0x00, 0x40, 0x60, 0x00, 0x20, 0x00, 0x00,
0x00, 0x00, 0x15, 0x27, 0xB5, 0x00, 0x60, 0x00, 0x00, 0x15};
ac.setRaw(light_press);
EXPECT_TRUE(ac.getLightToggle());
EXPECT_EQ(kHaierAc160ButtonLight, ac.getButton());
EXPECT_EQ(
"Power: On, Button: 21 (Light), Mode: 1 (Cool), Temp: 26C, "
"Fan: 3 (Low), Turbo: Off, Quiet: Off, Health: 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());
}
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, Health: 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());
}