Tasmota/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Mirage_test.cpp

592 lines
19 KiB
C++

// Copyright 2020-2021 David Conran
#include "ir_Mirage.h"
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
TEST(TestUtils, Housekeeping) {
ASSERT_EQ("MIRAGE", typeToString(decode_type_t::MIRAGE));
ASSERT_EQ(decode_type_t::MIRAGE, strToDecodeType("MIRAGE"));
ASSERT_TRUE(hasACState(decode_type_t::MIRAGE));
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::MIRAGE));
ASSERT_EQ(kMirageBits, IRsend::defaultBits(decode_type_t::MIRAGE));
ASSERT_EQ(kMirageMinRepeat, IRsend::minRepeats(decode_type_t::MIRAGE));
}
// Tests for decodeMirage().
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1289
// Data from:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1289#issuecomment-705826015
// But it is corrected to adjust for poor capture.
TEST(TestDecodeMirage, RealExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
const uint16_t rawData[243] = {
8360, 4248, 582, 518, 556, 1582, 586, 1572, 528, 572, 556, 1590, 526, 572,
554, 1586, 528, 578, 558, 1582, 556, 542, 558, 1598, 528, 572, 556, 1590,
528, 1610, 556, 1600, 554, 546, 556, 544, 558, 542, 558, 542, 676, 400,
606, 492, 582, 542, 556, 544, 556, 542, 558, 544, 556, 542, 556, 544, 558,
542, 556, 544, 530, 570, 586, 516, 584, 514, 558, 542, 558, 542, 558, 542,
554, 546, 558, 542, 558, 1582, 534, 542, 580, 552, 528, 1610, 556, 544,
554, 546, 554, 544, 556, 544, 556, 544, 558, 542, 558, 552, 558, 542, 558,
542, 558, 542, 556, 544, 558, 542, 558, 542, 554, 544, 584, 516, 558, 542,
528, 572, 588, 512, 556, 544, 532, 568, 560, 542, 558, 542, 560, 540, 560,
538, 530, 570, 558, 542, 558, 542, 560, 540, 558, 542, 558, 542, 530, 568,
558, 542, 558, 542, 532, 570, 530, 570, 558, 542, 558, 542, 558, 542, 530,
570, 530, 568, 560, 540, 560, 540, 532, 568, 558, 542, 558, 542, 532, 568,
560, 542, 532, 568, 532, 568, 530, 570, 532, 570, 530, 570, 558, 540, 560,
540, 558, 534, 558, 542, 556, 1600, 558, 1592, 558, 542, 560, 1590, 530,
570, 530, 570, 556, 544, 560, 540, 556, 544, 558, 1582, 556, 544, 558,
1600, 556, 542, 560, 542, 532, 568, 558, 542, 610, 1538, 504, 1646, 582,
518, 528, 572, 528, 1612, 556, 544, 528, 580, 554}; // UNKNOWN 28DACDC4
const uint8_t expected[kMirageStateLength] = {
0x56, 0x75, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x16, 0x14, 0x26};
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData, 243, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::MIRAGE, irsend.capture.decode_type);
ASSERT_EQ(kMirageBits, irsend.capture.bits);
EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"Model: 1 (KKG9AC1), Power: On, Mode: 2 (Cool), Temp: 25C, "
"Fan: 0 (Auto), Turbo: Off, Sleep: Off, Light: Off, "
"Swing(V): 0 (Off), Clock: 14:16",
IRAcUtils::resultAcToString(&irsend.capture));
}
TEST(TestDecodeMirage, SyntheticExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
const uint8_t expected[kMirageStateLength] = {
0x56, 0x75, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x16, 0x14, 0x26};
irsend.begin();
irsend.reset();
irsend.sendMirage(expected);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::MIRAGE, irsend.capture.decode_type);
ASSERT_EQ(kMirageBits, irsend.capture.bits);
EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"Model: 1 (KKG9AC1), Power: On, Mode: 2 (Cool), Temp: 25C, "
"Fan: 0 (Auto), Turbo: Off, Sleep: Off, Light: Off, "
"Swing(V): 0 (Off), Clock: 14:16",
IRAcUtils::resultAcToString(&irsend.capture));
}
// Data from:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1289#issuecomment-705624234
TEST(TestDecodeMirage, RealExampleWithDodgyHardwareCapture) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
const uint16_t rawData[243] = {
8360, 4248, 582, 518, 556, 1582, 586, 1572, 528, 572, 556, 1590, 526, 572,
554, 1586, 528, 578, 558, 1582, 556, 542, 558, 1598, 528, 572, 556, 1590,
528, 1610, 556, 1600, 554, 546, 556, 544, 558, 542, 558, 542, 676, 400,
606, 492, 582, 542, 556, 544, 556, 542, 558, 544, 556, 542, 556, 544, 558,
542, 556, 544, 530, 570, 586, 516, 584, 514, 558, 542, 558, 542, 558, 542,
554, 546, 558, 542, 558, 1582,
734, 342, // Really poor data here.
580, 552, 528, 1610, 556, 544, 554, 546, 554, 544, 556, 544, 556, 544,
558, 542, 558, 552, 558, 542, 558, 542, 558, 542, 556, 544, 558, 542, 558,
542, 554, 544, 584, 516, 558, 542, 528, 572, 588, 512, 556, 544, 532, 568,
560, 542, 558, 542, 560, 540, 560, 538, 530, 570, 558, 542, 558, 542, 560,
540, 558, 542, 558, 542, 530, 568, 558, 542, 558, 542, 532, 570, 530, 570,
558, 542, 558, 542, 558, 542, 530, 570, 530, 568, 560, 540, 560, 540, 532,
568, 558, 542, 558, 542, 532, 568, 560, 542, 532, 568, 532, 568, 530, 570,
532, 570, 530, 570, 558, 540, 560, 540, 558, 534, 558, 542, 556, 1600,
558, 1592, 558, 542, 560, 1590, 530, 570, 530, 570, 556, 544, 560, 540,
556, 544, 558, 1582, 556, 544, 558, 1600, 556, 542, 560, 542, 532, 568,
558, 542, 610, 1538, 504, 1646, 582, 518, 528, 572, 528, 1612, 556, 544,
528, 580, 554}; // UNKNOWN 28DACDC4
const uint8_t expected[kMirageStateLength] = {
0x56, 0x75, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x16, 0x14, 0x26};
irrecv.setTolerance(kTolerance + 10); // Bump tolerance to match poor data.
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData, 243, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::MIRAGE, irsend.capture.decode_type);
ASSERT_EQ(kMirageBits, irsend.capture.bits);
EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"Model: 1 (KKG9AC1), Power: On, Mode: 2 (Cool), Temp: 25C, "
"Fan: 0 (Auto), Turbo: Off, Sleep: Off, Light: Off, "
"Swing(V): 0 (Off), Clock: 14:16",
IRAcUtils::resultAcToString(&irsend.capture));
}
TEST(TestMirageAcClass, Power) {
IRMirageAc ac(kGpioUnused);
ac.begin();
ac.setModel(mirage_ac_remote_model_t::KKG9AC1);
ac.on();
EXPECT_TRUE(ac.getPower());
ac.on();
EXPECT_TRUE(ac.getPower());
ac.off();
EXPECT_FALSE(ac.getPower());
ac.off();
EXPECT_FALSE(ac.getPower());
ac.setPower(true);
EXPECT_TRUE(ac.getPower());
ac.setPower(false);
EXPECT_FALSE(ac.getPower());
const uint8_t on[kMirageStateLength] = {
0x56, 0x75, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x16, 0x14, 0x26};
ac.setRaw(on);
EXPECT_TRUE(ac.getPower());
const uint8_t off[kMirageStateLength] = {
0x56, 0x6C, 0x00, 0x00, 0x21, 0xD8, 0x00, 0x00,
0x0C, 0x00, 0x0C, 0x2C, 0x23, 0x01, 0x61};
ac.setRaw(off);
EXPECT_FALSE(ac.getPower());
ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
ac.on();
EXPECT_TRUE(ac.getPower());
ac.off();
EXPECT_FALSE(ac.getPower());
ac.setPower(true);
EXPECT_TRUE(ac.getPower());
ac.setPower(false);
EXPECT_FALSE(ac.getPower());
}
TEST(TestMirageAcClass, OperatingMode) {
IRMirageAc ac(kGpioUnused);
ac.begin();
ac.setMode(kMirageAcCool);
EXPECT_EQ(kMirageAcCool, ac.getMode());
ac.setMode(kMirageAcHeat);
EXPECT_EQ(kMirageAcHeat, ac.getMode());
ac.setMode(kMirageAcDry);
EXPECT_EQ(kMirageAcDry, ac.getMode());
ac.setMode(kMirageAcFan);
EXPECT_EQ(kMirageAcFan, ac.getMode());
ac.setMode(kMirageAcRecycle);
EXPECT_EQ(kMirageAcRecycle, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kMirageAcCool, ac.getMode());
}
TEST(TestMirageAcClass, HumanReadable) {
IRMirageAc ac(kGpioUnused);
ac.begin();
// Tests for the KKG9AC1 model.
EXPECT_EQ(
"Model: 1 (KKG9AC1), Power: On, Mode: 2 (Cool), Temp: 16C, "
"Fan: 0 (Auto), Turbo: Off, Sleep: Off, Light: Off, "
"Swing(V): 13 (Auto), Clock: 00:00",
ac.toString());
// Ref: https://docs.google.com/spreadsheets/d/1Ucu9mOOIIJoWQjUJq_VCvwgV3EwKaRk8K2AuZgccYEk/edit#gid=0&range=C7
// 0x56710000201A00000C000C26010041
const uint8_t cool_21c_auto[kMirageStateLength] = {
0x56, 0x71, 0x00, 0x00, 0x20, 0x1A, 0x00, 0x00,
0x0C, 0x00, 0x0C, 0x26, 0x01, 0x00, 0x41};
ac.setRaw(cool_21c_auto);
EXPECT_EQ(
"Model: 1 (KKG9AC1), Power: On, Mode: 2 (Cool), Temp: 21C, "
"Fan: 0 (Auto), Turbo: Off, Sleep: Off, Light: Off, "
"Swing(V): 13 (Auto), Clock: 00:01",
ac.toString());
const uint8_t SyntheticExample[kMirageStateLength] = {
0x56, 0x75, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x16, 0x14, 0x26};
ac.setRaw(SyntheticExample);
EXPECT_EQ(
"Model: 1 (KKG9AC1), Power: On, Mode: 2 (Cool), Temp: 25C, "
"Fan: 0 (Auto), Turbo: Off, Sleep: Off, Light: Off, "
"Swing(V): 0 (Off), Clock: 14:16",
ac.toString());
// Tests for the KKG29AC1 model.
ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
EXPECT_EQ(
"Model: 2 (KKG29AC1), Power: On, Mode: 2 (Cool), Temp: 25C, "
"Fan: 0 (Auto), Turbo: Off, Sleep: Off, Quiet: Off, Light: -, "
"Swing(V): Off, Swing(H): Off, "
"Filter: Off, Clean: -, On Timer: Off, Off Timer: Off, "
"IFeel: Off",
ac.toString());
}
TEST(TestMirageAcClass, Temperature) {
IRMirageAc ac(kGpioUnused);
ac.begin();
ac.setTemp(0);
EXPECT_EQ(kMirageAcMinTemp, ac.getTemp());
ac.setTemp(255);
EXPECT_EQ(kMirageAcMaxTemp, ac.getTemp());
ac.setTemp(kMirageAcMinTemp);
EXPECT_EQ(kMirageAcMinTemp, ac.getTemp());
ac.setTemp(kMirageAcMaxTemp);
EXPECT_EQ(kMirageAcMaxTemp, ac.getTemp());
ac.setTemp(kMirageAcMinTemp - 1);
EXPECT_EQ(kMirageAcMinTemp, ac.getTemp());
ac.setTemp(kMirageAcMaxTemp + 1);
EXPECT_EQ(kMirageAcMaxTemp, ac.getTemp());
ac.setTemp(17);
EXPECT_EQ(17, ac.getTemp());
ac.setTemp(21);
EXPECT_EQ(21, ac.getTemp());
ac.setTemp(25);
EXPECT_EQ(25, ac.getTemp());
ac.setTemp(30);
EXPECT_EQ(30, ac.getTemp());
}
TEST(TestMirageAcClass, FanSpeed) {
IRMirageAc ac(kGpioUnused);
ac.begin();
ac.setFan(kMirageAcFanAuto);
EXPECT_EQ(kMirageAcFanAuto, ac.getFan());
ac.setFan(kMirageAcFanLow);
EXPECT_EQ(kMirageAcFanLow, ac.getFan());
ac.setFan(kMirageAcFanMed);
EXPECT_EQ(kMirageAcFanMed, ac.getFan());
ac.setFan(kMirageAcFanHigh);
EXPECT_EQ(kMirageAcFanHigh, ac.getFan());
ac.setFan(255);
EXPECT_EQ(kMirageAcFanAuto, ac.getFan());
}
TEST(TestMirageAcClass, Turbo) {
IRMirageAc ac(kGpioUnused);
ac.begin();
ac.setModel(mirage_ac_remote_model_t::KKG9AC1);
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
ac.setTurbo(false);
EXPECT_FALSE(ac.getTurbo());
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
ac.setTurbo(false);
EXPECT_FALSE(ac.getTurbo());
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
}
TEST(TestMirageAcClass, Light) {
IRMirageAc ac(kGpioUnused);
ac.begin();
ac.setModel(mirage_ac_remote_model_t::KKG9AC1);
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
ac.setLight(false);
EXPECT_FALSE(ac.getLight());
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
ac.setLight(false);
EXPECT_FALSE(ac.getLight());
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
}
TEST(TestMirageAcClass, Sleep) {
IRMirageAc ac(kGpioUnused);
ac.begin();
ac.setModel(mirage_ac_remote_model_t::KKG9AC1);
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
ac.setSleep(false);
EXPECT_FALSE(ac.getSleep());
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
ac.setSleep(false);
EXPECT_FALSE(ac.getSleep());
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
}
TEST(TestMirageAcClass, Clock) {
IRMirageAc ac(kGpioUnused);
ac.begin();
ac.setModel(mirage_ac_remote_model_t::KKG9AC1); // This model supports time.
ac.setClock(0);
EXPECT_EQ(0, ac.getClock());
ac.setClock(12 * 60 * 60 + 30 * 60 + 59); // aka. 12:30:59
EXPECT_EQ(12 * 60 * 60 + 30 * 60 + 59, ac.getClock());
ac.setClock(23 * 60 * 60 + 59 * 60 + 59); // aka. 23:59:59
EXPECT_EQ(23 * 60 * 60 + 59 * 60 + 59, ac.getClock());
ac.setClock(24 * 60 * 60); // aka. 24:00:00
EXPECT_EQ(23 * 60 * 60 + 59 * 60 + 59, ac.getClock()); // aka. 23:59:59
ac.setModel(mirage_ac_remote_model_t::KKG29AC1); // This model has no clock.
EXPECT_EQ(0, ac.getClock());
ac.setClock(12 * 60 * 60 + 30 * 60 + 59); // aka. 12:30:59
EXPECT_EQ(0, ac.getClock());
}
TEST(TestMirageAcClass, Checksums) {
IRMirageAc ac(kGpioUnused);
ac.begin();
const uint8_t SyntheticExample[kMirageStateLength] = {
0x56, 0x75, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x16, 0x14, 0x26};
EXPECT_TRUE(IRMirageAc::validChecksum(SyntheticExample));
EXPECT_EQ(0x26, IRMirageAc::calculateChecksum(SyntheticExample));
}
TEST(TestMirageAcClass, SwingV) {
IRMirageAc ac(kGpioUnused);
ac.begin();
// Set the model to one with full swingv support.
ac.setModel(mirage_ac_remote_model_t::KKG9AC1);
ac.setSwingV(kMirageAcSwingVAuto);
EXPECT_EQ(kMirageAcSwingVAuto, ac.getSwingV());
ac.setSwingV(kMirageAcSwingVHigh);
EXPECT_EQ(kMirageAcSwingVHigh, ac.getSwingV());
ac.setSwingV(0xFF);
EXPECT_EQ(kMirageAcSwingVAuto, ac.getSwingV());
ac.setSwingV(kMirageAcSwingVLowest);
EXPECT_EQ(kMirageAcSwingVLowest, ac.getSwingV());
ac.setSwingV(kMirageAcSwingVLowest - 1);
EXPECT_EQ(kMirageAcSwingVAuto, ac.getSwingV());
// Set the model to one with limited swingv support.
ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
ac.setSwingV(kMirageAcSwingVAuto);
EXPECT_EQ(kMirageAcSwingVAuto, ac.getSwingV());
ac.setSwingV(kMirageAcSwingVOff);
EXPECT_EQ(kMirageAcSwingVOff, ac.getSwingV());
ac.setSwingV(kMirageAcSwingVHigh);
EXPECT_EQ(kMirageAcSwingVAuto, ac.getSwingV());
ac.setSwingV(0xFF);
EXPECT_EQ(kMirageAcSwingVAuto, ac.getSwingV());
ac.setSwingV(kMirageAcSwingVOff);
EXPECT_EQ(kMirageAcSwingVOff, ac.getSwingV());
}
TEST(TestMirageAcClass, SwingH) {
IRMirageAc ac(kGpioUnused);
ac.begin();
ac.setModel(mirage_ac_remote_model_t::KKG9AC1);
ac.setSwingH(true);
EXPECT_FALSE(ac.getSwingH());
ac.setSwingH(false);
EXPECT_FALSE(ac.getSwingH());
ac.setSwingH(true);
EXPECT_FALSE(ac.getSwingH());
ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
ac.setSwingH(true);
EXPECT_TRUE(ac.getSwingH());
ac.setSwingH(false);
EXPECT_FALSE(ac.getSwingH());
ac.setSwingH(true);
EXPECT_TRUE(ac.getSwingH());
}
TEST(TestMirageAcClass, Filter) {
IRMirageAc ac(kGpioUnused);
ac.begin();
ac.setModel(mirage_ac_remote_model_t::KKG9AC1); // No Support
ac.setFilter(true);
EXPECT_FALSE(ac.getFilter());
ac.setFilter(false);
EXPECT_FALSE(ac.getFilter());
ac.setFilter(true);
EXPECT_FALSE(ac.getFilter());
ac.setModel(mirage_ac_remote_model_t::KKG29AC1); // Supported
ac.setFilter(true);
EXPECT_TRUE(ac.getFilter());
ac.setFilter(false);
EXPECT_FALSE(ac.getFilter());
ac.setFilter(true);
EXPECT_TRUE(ac.getFilter());
}
TEST(TestMirageAcClass, Quiet) {
IRMirageAc ac(kGpioUnused);
ac.begin();
ac.setModel(mirage_ac_remote_model_t::KKG9AC1); // No Support
ac.setQuiet(true);
EXPECT_FALSE(ac.getQuiet());
ac.setQuiet(false);
EXPECT_FALSE(ac.getQuiet());
ac.setQuiet(true);
EXPECT_FALSE(ac.getQuiet());
ac.setModel(mirage_ac_remote_model_t::KKG29AC1); // Supported
ac.setQuiet(true);
EXPECT_TRUE(ac.getQuiet());
ac.setQuiet(false);
EXPECT_FALSE(ac.getQuiet());
ac.setQuiet(true);
EXPECT_TRUE(ac.getQuiet());
}
TEST(TestMirageAcClass, CleanToggle) {
IRMirageAc ac(kGpioUnused);
ac.begin();
ac.setModel(mirage_ac_remote_model_t::KKG9AC1);
ac.setCleanToggle(true);
EXPECT_FALSE(ac.getCleanToggle());
ac.setCleanToggle(false);
EXPECT_FALSE(ac.getCleanToggle());
ac.setCleanToggle(true);
EXPECT_FALSE(ac.getCleanToggle());
ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
ac.setCleanToggle(true);
EXPECT_TRUE(ac.getCleanToggle());
ac.setCleanToggle(false);
EXPECT_FALSE(ac.getCleanToggle());
ac.setCleanToggle(true);
EXPECT_TRUE(ac.getCleanToggle());
ac.send(); // Should be reset when sent.
EXPECT_FALSE(ac.getCleanToggle());
}
TEST(TestMirageAcClass, Timers) {
IRMirageAc ac(kGpioUnused);
ac.begin();
ac.setModel(mirage_ac_remote_model_t::KKG9AC1); // No timer support
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_EQ(0, ac.getOffTimer());
ac.setOnTimer(12 * 60 + 37); // 12:37
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_EQ(0, ac.getOffTimer());
ac.setOffTimer(17 * 60 + 5); // 17:05
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_EQ(0, ac.getOffTimer());
ac.setModel(mirage_ac_remote_model_t::KKG29AC1); // Timer supported
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_EQ(0, ac.getOffTimer());
ac.setOnTimer(12 * 60 + 37); // 12:37
EXPECT_EQ(12 * 60 + 37, ac.getOnTimer());
EXPECT_EQ(0, ac.getOffTimer());
ac.setOffTimer(17 * 60 + 5); // 17:05
EXPECT_EQ(17 * 60 + 5, ac.getOffTimer());
EXPECT_EQ(12 * 60 + 37, ac.getOnTimer());
ac.setOnTimer(0); // Off/Disabled
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_EQ(17 * 60 + 5, ac.getOffTimer());
ac.setOffTimer(0); // Off/Disabled
EXPECT_EQ(0, ac.getOffTimer());
EXPECT_EQ(0, ac.getOnTimer());
ac.setOnTimer(12 * 60 + 37); // 12:37
ac.setOffTimer(17 * 60 + 5); // 17:05
ac.setModel(mirage_ac_remote_model_t::KKG9AC1); // No timer support
EXPECT_EQ(0, ac.getOffTimer());
EXPECT_EQ(0, ac.getOnTimer());
}
TEST(TestMirageAcClass, IFeelAndSensorTemp) {
IRMirageAc ac(kGpioUnused);
ac.begin();
ac.setModel(mirage_ac_remote_model_t::KKG9AC1); // No support
EXPECT_FALSE(ac.getIFeel());
EXPECT_EQ(0, ac.getSensorTemp());
ac.setIFeel(true);
EXPECT_FALSE(ac.getIFeel());
EXPECT_EQ(0, ac.getSensorTemp());
ac.setSensorTemp(20); // 20C
EXPECT_FALSE(ac.getIFeel());
EXPECT_EQ(0, ac.getSensorTemp());
ac.setModel(mirage_ac_remote_model_t::KKG29AC1); // Supported
EXPECT_FALSE(ac.getIFeel());
EXPECT_EQ(0, ac.getSensorTemp());
ac.setIFeel(true);
EXPECT_TRUE(ac.getIFeel());
EXPECT_EQ(0, ac.getSensorTemp());
ac.setSensorTemp(25); // 25C
EXPECT_TRUE(ac.getIFeel());
EXPECT_EQ(25, ac.getSensorTemp());
ac.setIFeel(false);
EXPECT_FALSE(ac.getIFeel());
}
TEST(TestMirageAcClass, getModel) {
IRMirageAc ac(kGpioUnused);
ac.begin();
const uint8_t KKG9AC1[kMirageStateLength] = {
0x56, 0x6C, 0x00, 0x00, 0x20, 0xD8, 0x00, 0x00,
0x0C, 0x32, 0x0B, 0x00, 0x32, 0x0F, 0x64};
EXPECT_EQ(mirage_ac_remote_model_t::KKG9AC1, IRMirageAc::getModel(KKG9AC1));
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1573#issuecomment-955722044
const uint8_t KKG29AC1[kMirageStateLength] = {
0x56, 0x74, 0x00, 0x00, 0x12, 0x00, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D};
EXPECT_EQ(mirage_ac_remote_model_t::KKG29AC1, IRMirageAc::getModel(KKG29AC1));
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1573#issuecomment-962362540
const uint8_t KKG29AC1_2[kMirageStateLength] = {
0x56, 0x72, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19};
EXPECT_EQ(mirage_ac_remote_model_t::KKG29AC1,
IRMirageAc::getModel(KKG29AC1_2));
}