// Copyright 2017 David Conran #include "ir_Daikin.h" #include "IRrecv.h" #include "IRrecv_test.h" #include "IRsend.h" #include "IRsend_test.h" #include "gtest/gtest.h" // Tests for sendDaikin(). // Test sending typical data only. TEST(TestSendDaikin, SendDataOnly) { IRsendTest irsend(0); irsend.begin(); uint8_t daikin_code[kDaikinStateLength] = { 0x11, 0xDA, 0x27, 0x00, 0xC5, 0x00, 0x00, 0xD7, 0x11, 0xDA, 0x27, 0xF0, 0x00, 0x00, 0x00, 0x20, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x41, 0x1E, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xE3}; irsend.reset(); irsend.sendDaikin(daikin_code); EXPECT_EQ( "f38000d50" "m428s428m428s428m428s428m428s428m428s428" "m428s29428" "m3650s1623" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280" "m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s428m428s1280m428s428m428s428m428s428m428s1280m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s1280m428s1280m428s428m428s1280m428s428m428s1280m428s1280" "m428s29428" "m3650s1623" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280" "m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s1280m428s1280m428s1280m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s1280m428s428m428s428" "m428s29428" "m3650s1623" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280" "m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s428m428s428m428s428m428s428m428s428m428s1280m428s428" "m428s428m428s1280m428s1280m428s1280m428s1280m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s1280m428s1280m428s428m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s1280m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s1280m428s428m428s428m428s428m428s1280m428s1280m428s1280" "m428s29428", irsend.outputStr()); } // Test sending with repeats. TEST(TestSendDaikin, SendWithRepeats) { IRsendTest irsend(0); irsend.begin(); irsend.reset(); uint8_t daikin_code[kDaikinStateLengthShort] = { 0x11, 0xDA, 0x27, 0xF0, 0x00, 0x00, 0x00, 0x20, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x41, 0x1E, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xE3}; irsend.reset(); irsend.sendDaikin(daikin_code, kDaikinStateLengthShort, 1); EXPECT_EQ( "f38000d50" "m428s428m428s428m428s428m428s428m428s428" "m428s29428m3650s1623" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280" "m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s428m428s1280m428s428m428s428m428s428m428s1280m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s1280m428s1280m428s428m428s1280m428s428m428s1280m428s1280" "m428s29428m3650s1623" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280" "m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s1280m428s1280m428s1280m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s1280m428s428m428s428" "m428s29428m3650s1623" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280" "m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s428m428s428m428s428m428s428m428s428m428s1280m428s428" "m428s428m428s1280m428s1280m428s1280m428s1280m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s1280m428s1280m428s428m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s1280m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s1280m428s428m428s428m428s428m428s1280m428s1280m428s1280" "m428s29428" "m428s428m428s428m428s428m428s428m428s428" "m428s29428m3650s1623" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280" "m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s428m428s1280m428s428m428s428m428s428m428s1280m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s1280m428s1280m428s428m428s1280m428s428m428s1280m428s1280" "m428s29428m3650s1623" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280" "m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s1280m428s1280m428s1280m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s1280m428s428m428s428" "m428s29428m3650s1623" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280" "m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s428m428s428m428s428m428s428m428s428m428s1280m428s428" "m428s428m428s1280m428s1280m428s1280m428s1280m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s1280m428s1280m428s428m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s1280m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s1280m428s428m428s428m428s428m428s1280m428s1280m428s1280" "m428s29428", irsend.outputStr()); } // Test sending atypical sizes. TEST(TestSendDaikin, SendUnexpectedSizes) { IRsendTest irsend(4); irsend.begin(); uint8_t daikin_short_code[kDaikinStateLengthShort - 1] = { 0x11, 0xDA, 0x27, 0xF0, 0x00, 0x00, 0x00, 0x20, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x41, 0x1E, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00}; irsend.reset(); irsend.sendDaikin(daikin_short_code, kDaikinStateLengthShort - 1); ASSERT_EQ("", irsend.outputStr()); uint8_t daikin_long_code[kDaikinStateLengthShort + 1] = { 0x11, 0xDA, 0x27, 0xF0, 0x00, 0x00, 0x00, 0x20, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x41, 0x1E, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xE3, 0x11}; irsend.reset(); irsend.sendDaikin(daikin_long_code, kDaikinStateLengthShort + 1); ASSERT_EQ( "f38000d50" "m428s428m428s428m428s428m428s428m428s428" "m428s29428m3650s1623" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280" "m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s428m428s1280m428s428m428s428m428s428m428s1280m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s1280m428s1280m428s428m428s1280m428s428m428s1280m428s1280" "m428s29428m3650s1623" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280" "m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s1280m428s1280m428s1280m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s1280m428s428m428s428" "m428s29428m3650s1623" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280" "m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s428m428s428m428s428m428s428m428s428m428s1280m428s428" "m428s428m428s1280m428s1280m428s1280m428s1280m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s1280m428s1280m428s428m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s1280m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s1280m428s428m428s428m428s428m428s1280m428s1280m428s1280" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s29428", irsend.outputStr()); } // Tests for IRDaikinESP class. TEST(TestDaikinClass, Power) { IRDaikinESP ac(0); ac.begin(); 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(TestDaikinClass, Temperature) { IRDaikinESP ac(0); ac.begin(); ac.setTemp(0); EXPECT_EQ(kDaikinMinTemp, ac.getTemp()); ac.setTemp(255); EXPECT_EQ(kDaikinMaxTemp, ac.getTemp()); ac.setTemp(kDaikinMinTemp); EXPECT_EQ(kDaikinMinTemp, ac.getTemp()); ac.setTemp(kDaikinMaxTemp); EXPECT_EQ(kDaikinMaxTemp, ac.getTemp()); ac.setTemp(kDaikinMinTemp - 1); EXPECT_EQ(kDaikinMinTemp, ac.getTemp()); ac.setTemp(kDaikinMaxTemp + 1); EXPECT_EQ(kDaikinMaxTemp, ac.getTemp()); ac.setTemp(kDaikinMinTemp + 1); EXPECT_EQ(kDaikinMinTemp + 1, ac.getTemp()); ac.setTemp(21); EXPECT_EQ(21, ac.getTemp()); ac.setTemp(25); EXPECT_EQ(25, ac.getTemp()); ac.setTemp(29); EXPECT_EQ(29, ac.getTemp()); } TEST(TestDaikinClass, OperatingMode) { IRDaikinESP ac(0); ac.begin(); ac.setMode(kDaikinAuto); EXPECT_EQ(kDaikinAuto, ac.getMode()); ac.setMode(kDaikinCool); EXPECT_EQ(kDaikinCool, ac.getMode()); ac.setMode(kDaikinHeat); EXPECT_EQ(kDaikinHeat, ac.getMode()); ac.setMode(kDaikinDry); EXPECT_EQ(kDaikinDry, ac.getMode()); ac.setMode(kDaikinFan); EXPECT_EQ(kDaikinFan, ac.getMode()); ac.setMode(kDaikinFan + 1); EXPECT_EQ(kDaikinAuto, ac.getMode()); ac.setMode(kDaikinAuto + 1); EXPECT_EQ(kDaikinAuto, ac.getMode()); ac.setMode(255); EXPECT_EQ(kDaikinAuto, ac.getMode()); } TEST(TestDaikinClass, VaneSwing) { IRDaikinESP ac(0); ac.begin(); ac.setSwingHorizontal(true); ac.setSwingVertical(false); ac.setSwingHorizontal(true); EXPECT_TRUE(ac.getSwingHorizontal()); EXPECT_FALSE(ac.getSwingVertical()); ac.setSwingVertical(true); EXPECT_TRUE(ac.getSwingHorizontal()); EXPECT_TRUE(ac.getSwingVertical()); ac.setSwingHorizontal(false); EXPECT_FALSE(ac.getSwingHorizontal()); EXPECT_TRUE(ac.getSwingVertical()); ac.setSwingVertical(false); EXPECT_FALSE(ac.getSwingHorizontal()); EXPECT_FALSE(ac.getSwingVertical()); } TEST(TestDaikinClass, QuietMode) { IRDaikinESP ac(0); ac.begin(); ac.setQuiet(true); EXPECT_TRUE(ac.getQuiet()); ac.setQuiet(false); EXPECT_FALSE(ac.getQuiet()); ac.setQuiet(true); EXPECT_TRUE(ac.getQuiet()); // Setting Econo mode should NOT change out of quiet mode. ac.setEcono(true); EXPECT_TRUE(ac.getQuiet()); ac.setEcono(false); EXPECT_TRUE(ac.getQuiet()); // But setting Powerful mode should exit out of quiet mode. ac.setPowerful(true); EXPECT_FALSE(ac.getQuiet()); } TEST(TestDaikinClass, PowerfulMode) { IRDaikinESP ac(0); ac.begin(); ac.setPowerful(true); EXPECT_TRUE(ac.getPowerful()); ac.setPowerful(false); EXPECT_FALSE(ac.getPowerful()); ac.setPowerful(true); EXPECT_TRUE(ac.getPowerful()); ac.setQuiet(true); EXPECT_FALSE(ac.getPowerful()); ac.setPowerful(true); ac.setEcono(true); EXPECT_FALSE(ac.getPowerful()); } TEST(TestDaikinClass, EconoMode) { IRDaikinESP ac(0); ac.begin(); ac.setEcono(true); EXPECT_TRUE(ac.getEcono()); ac.setEcono(false); EXPECT_FALSE(ac.getEcono()); ac.setEcono(true); EXPECT_TRUE(ac.getEcono()); // Setting Quiet mode should NOT change out of Econo mode. ac.setQuiet(true); EXPECT_TRUE(ac.getEcono()); ac.setQuiet(false); EXPECT_TRUE(ac.getEcono()); // But setting Powerful mode should exit out of Econo mode. ac.setPowerful(true); EXPECT_FALSE(ac.getEcono()); } TEST(TestDaikinClass, FanSpeed) { IRDaikinESP ac(0); ac.begin(); // Unexpected value should default to Auto. ac.setFan(0); EXPECT_EQ(kDaikinFanAuto, ac.getFan()); // Unexpected value should default to Auto. ac.setFan(255); EXPECT_EQ(kDaikinFanAuto, ac.getFan()); ac.setFan(kDaikinFanMax); EXPECT_EQ(kDaikinFanMax, ac.getFan()); // Beyond Max should default to Auto. ac.setFan(kDaikinFanMax + 1); EXPECT_EQ(kDaikinFanAuto, ac.getFan()); ac.setFan(kDaikinFanMax - 1); EXPECT_EQ(kDaikinFanMax - 1, ac.getFan()); ac.setFan(kDaikinFanMin); EXPECT_EQ(kDaikinFanMin, ac.getFan()); ac.setFan(kDaikinFanMin + 1); EXPECT_EQ(kDaikinFanMin + 1, ac.getFan()); // Beyond Min should default to Auto. ac.setFan(kDaikinFanMin - 1); EXPECT_EQ(kDaikinFanAuto, ac.getFan()); ac.setFan(3); EXPECT_EQ(3, ac.getFan()); ac.setFan(kDaikinFanAuto); EXPECT_EQ(kDaikinFanAuto, ac.getFan()); ac.setFan(kDaikinFanQuiet); EXPECT_EQ(kDaikinFanQuiet, ac.getFan()); } TEST(TestDaikinClass, CurrentTime) { IRDaikinESP ac(0); ac.begin(); ac.setCurrentTime(0); // 00:00 EXPECT_EQ(0, ac.getCurrentTime()); ac.setCurrentTime(754); // 12:34 EXPECT_EQ(754, ac.getCurrentTime()); ac.setCurrentTime(1439); // 23:59 EXPECT_EQ(1439, ac.getCurrentTime()); } TEST(TestDaikinClass, OnOffTimers) { IRDaikinESP ac(0); ac.begin(); // Both timers turned off. ac.disableOnTimer(); ac.disableOffTimer(); EXPECT_FALSE(ac.getOnTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getOnTime()); EXPECT_FALSE(ac.getOffTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getOffTime()); // Turn on just the On Timer. ac.enableOnTimer(123); EXPECT_TRUE(ac.getOnTimerEnabled()); EXPECT_EQ(123, ac.getOnTime()); EXPECT_FALSE(ac.getOffTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getOffTime()); // Now turn on the Off Timer. ac.enableOffTimer(754); EXPECT_TRUE(ac.getOffTimerEnabled()); EXPECT_EQ(754, ac.getOffTime()); EXPECT_TRUE(ac.getOnTimerEnabled()); EXPECT_EQ(123, ac.getOnTime()); // Turn off the just the On Timer. ac.disableOnTimer(); EXPECT_FALSE(ac.getOnTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getOnTime()); EXPECT_TRUE(ac.getOffTimerEnabled()); EXPECT_EQ(754, ac.getOffTime()); // Now turn off the Off Timer. ac.disableOffTimer(); EXPECT_FALSE(ac.getOffTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getOffTime()); EXPECT_FALSE(ac.getOnTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getOnTime()); // Use some canary values around the timers to ensure no accidental // bit flips happen. i.e. Neighbouring bytes in the state. // (Found some during testing on systems with different endian-ness) // Tests here to make sure it never happens again. ac.setSwingHorizontal(true); ac.setPowerful(true); ac.disableOffTimer(); ac.disableOnTimer(); ASSERT_TRUE(ac.getSwingHorizontal()); ASSERT_TRUE(ac.getPowerful()); ac.enableOnTimer(123); ac.enableOffTimer(456); ASSERT_TRUE(ac.getSwingHorizontal()); ASSERT_TRUE(ac.getPowerful()); ac.disableOffTimer(); ac.disableOnTimer(); ASSERT_TRUE(ac.getSwingHorizontal()); ASSERT_TRUE(ac.getPowerful()); ac.setSwingHorizontal(false); ac.setPowerful(false); ac.disableOffTimer(); ac.disableOnTimer(); ASSERT_FALSE(ac.getSwingHorizontal()); ASSERT_FALSE(ac.getPowerful()); ac.enableOnTimer(123); ac.enableOffTimer(456); ASSERT_FALSE(ac.getSwingHorizontal()); ASSERT_FALSE(ac.getPowerful()); ac.disableOffTimer(); ac.disableOnTimer(); ASSERT_FALSE(ac.getSwingHorizontal()); ASSERT_FALSE(ac.getPowerful()); } // Test Eye mode. TEST(TestDaikinClass, EyeSetting) { IRDaikinESP ac(0); ac.begin(); // The Eye setting is stored in the same byte as Econo mode. // Econo mode tests are there to make sure it isn't harmed and vice-versa. ac.setEcono(false); ac.setEye(false); ASSERT_FALSE(ac.getEye()); EXPECT_FALSE(ac.getEcono()); ac.setEye(true); ASSERT_TRUE(ac.getEye()); EXPECT_FALSE(ac.getEcono()); ac.setEcono(false); ASSERT_TRUE(ac.getEye()); EXPECT_FALSE(ac.getEcono()); ac.setEcono(true); ASSERT_TRUE(ac.getEye()); EXPECT_TRUE(ac.getEcono()); ac.setEye(false); ASSERT_FALSE(ac.getEye()); EXPECT_TRUE(ac.getEcono()); } // Test Mold mode. TEST(TestDaikinClass, MoldSetting) { IRDaikinESP ac(0); ac.begin(); ac.setMold(false); ASSERT_FALSE(ac.getMold()); ac.setMold(true); ASSERT_TRUE(ac.getMold()); ac.setMold(false); ASSERT_FALSE(ac.getMold()); } // Test Comfort mode. TEST(TestDaikinClass, ComfortSetting) { IRDaikinESP ac(0); ac.begin(); ac.setComfort(false); ASSERT_FALSE(ac.getComfort()); ac.setComfort(true); ASSERT_TRUE(ac.getComfort()); ac.setComfort(false); ASSERT_FALSE(ac.getComfort()); } // Test Sensor mode. TEST(TestDaikinClass, SensorSetting) { IRDaikinESP ac(0); ac.begin(); ac.setSensor(false); ASSERT_FALSE(ac.getSensor()); ac.setSensor(true); ASSERT_TRUE(ac.getSensor()); ac.setSensor(false); ASSERT_FALSE(ac.getSensor()); } TEST(TestDaikinClass, RenderTime) { EXPECT_EQ("0:00", IRDaikinESP::renderTime(0)); EXPECT_EQ("0:10", IRDaikinESP::renderTime(10)); EXPECT_EQ("1:00", IRDaikinESP::renderTime(1 * 60 + 0)); EXPECT_EQ("23:59", IRDaikinESP::renderTime(23 * 60 + 59)); } TEST(TestDaikinClass, SetAndGetRaw) { IRDaikinESP ac(0); uint8_t shortState[kDaikinStateLengthShort] = { 0x11, 0xDA, 0x27, 0x00, 0x42, 0x00, 0x00, 0x54, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x49, 0x1E, 0x00, 0xB0, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x4F}; uint8_t longState[kDaikinStateLength] = { 0x11, 0xDA, 0x27, 0x00, 0xC5, 0x00, 0x00, 0xD7, 0x11, 0xDA, 0x27, 0x00, 0x42, 0x00, 0x00, 0x54, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x49, 0x1E, 0x00, 0xB0, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x4F}; uint8_t expectedState[kDaikinStateLength] = { 0x11, 0xDA, 0x27, 0x00, 0xC5, 0x00, 0x00, 0xD7, 0x11, 0xDA, 0x27, 0x00, 0x42, 0x00, 0x00, 0x54, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x48, 0x2A, 0x00, 0xB0, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0xC0, 0x00, 0x02, 0x5C}; EXPECT_STATE_EQ(longState, ac.getRaw(), kDaikinBits); // toggle the power state. ac.setPower(!ac.getPower()); ac.setTemp(21); ac.setMold(true); EXPECT_STATE_EQ(expectedState, ac.getRaw(), kDaikinBits); ac.setRaw(longState); EXPECT_STATE_EQ(longState, ac.getRaw(), kDaikinBits); ac.setRaw(shortState, kDaikinStateLengthShort); EXPECT_STATE_EQ(longState, ac.getRaw(), kDaikinBits); } TEST(TestDaikinClass, ChecksumValidation) { uint8_t daikin_code[kDaikinStateLength] = { 0x11, 0xDA, 0x27, 0x00, 0xC5, 0x00, 0x00, 0xD7, 0x11, 0xDA, 0x27, 0xF0, 0x00, 0x00, 0x00, 0x02, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x41, 0x1E, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xE1}; EXPECT_TRUE(IRDaikinESP::validChecksum(daikin_code)); // Change the array so the checksum is invalid. daikin_code[0] ^= 0xFF; EXPECT_FALSE(IRDaikinESP::validChecksum(daikin_code)); // Restore the previous change, and change another byte. daikin_code[0] ^= 0xFF; daikin_code[4] ^= 0xFF; EXPECT_FALSE(IRDaikinESP::validChecksum(daikin_code)); daikin_code[4] ^= 0xFF; // Change something in the 2nd block. daikin_code[10] ^= 0xFF; EXPECT_FALSE(IRDaikinESP::validChecksum(daikin_code)); daikin_code[10] ^= 0xFF; EXPECT_TRUE(IRDaikinESP::validChecksum(daikin_code)); // Change something in the 3rd block. daikin_code[20] ^= 0xFF; EXPECT_FALSE(IRDaikinESP::validChecksum(daikin_code)); daikin_code[20] ^= 0xFF; EXPECT_TRUE(IRDaikinESP::validChecksum(daikin_code)); } // Test human readable output. TEST(TestDaikinClass, HumanReadable) { IRDaikinESP ac(0); EXPECT_EQ( "Power: On, Mode: 4 (HEAT), Temp: 15C, Fan: 11 (QUIET), " "Powerful: Off, Quiet: Off, Sensor: Off, Eye: Off, Mold: Off, " "Comfort: Off, Swing (Horizontal): Off, Swing (Vertical): Off, " "Current Time: 0:00, On Time: Off, Off Time: Off", ac.toString()); ac.setMode(kDaikinAuto); ac.setTemp(25); ac.setFan(kDaikinFanAuto); ac.setQuiet(true); ac.setSensor(true); ac.setEye(true); ac.setMold(true); ac.setSwingVertical(true); ac.setSwingHorizontal(true); ac.setCurrentTime(9 * 60 + 15); ac.enableOnTimer(8 * 60 + 0); ac.enableOffTimer(17 * 60 + 30); ac.setComfort(true); ac.off(); EXPECT_EQ( "Power: Off, Mode: 0 (AUTO), Temp: 25C, Fan: 10 (AUTO), " "Powerful: Off, Quiet: On, Sensor: On, Eye: On, Mold: On, Comfort: On, " "Swing (Horizontal): On, Swing (Vertical): On, " "Current Time: 9:15, On Time: 8:00, Off Time: 17:30", ac.toString()); } // Test general message construction after tweaking some settings. TEST(TestDaikinClass, MessageConstuction) { IRDaikinESP ac(0); IRsendTest irsend(4); ac.begin(); irsend.begin(); ac.setFan(kDaikinFanMin); ac.setMode(kDaikinCool); ac.setTemp(27); ac.setSwingVertical(false); ac.setSwingHorizontal(true); ac.setQuiet(false); ac.setPower(true); // Check everything for kicks. EXPECT_EQ(kDaikinFanMin, ac.getFan()); EXPECT_EQ(kDaikinCool, ac.getMode()); EXPECT_EQ(27, ac.getTemp()); EXPECT_FALSE(ac.getSwingVertical()); EXPECT_TRUE(ac.getSwingHorizontal()); EXPECT_FALSE(ac.getQuiet()); EXPECT_TRUE(ac.getPower()); irsend.reset(); irsend.sendDaikin(ac.getRaw()); EXPECT_EQ( "f38000d50" "m428s428m428s428m428s428m428s428m428s428" "m428s29428m3650s1623" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280" "m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s428m428s1280m428s428m428s428m428s428m428s1280m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s1280m428s1280m428s428m428s1280m428s428m428s1280m428s1280" "m428s29428m3650s1623" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280" "m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s428m428s428m428s428m428s1280m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s1280m428s428m428s1280m428s428m428s1280m428s428" "m428s29428m3650s1623" "m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428" "m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280" "m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s1280m428s428m428s428m428s1280m428s1280m428s1280m428s428m428s428" "m428s428m428s1280m428s1280m428s428m428s1280m428s1280m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s1280m428s1280m428s428m428s428" "m428s1280m428s1280m428s1280m428s1280m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s1280m428s1280m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s1280m428s1280m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s1280m428s1280" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428" "m428s428m428s1280m428s1280m428s428m428s428m428s1280m428s1280m428s1280" "m428s29428", irsend.outputStr()); } // Tests for decodeDaikin(). // Test decoding a message captured from a real IR remote. TEST(TestDecodeDaikin, RealExample) { IRDaikinESP ac(0); IRsendTest irsend(0); IRrecv irrecv(0); irsend.begin(); uint8_t expectedState[kDaikinStateLength] = { 0x11, 0xDA, 0x27, 0x00, 0xC5, 0x00, 0x00, 0xD7, 0x11, 0xDA, 0x27, 0x00, 0x42, 0x3A, 0x05, 0x93, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x3F, 0x3A, 0x00, 0xA0, 0x00, 0x0A, 0x25, 0x17, 0x01, 0x00, 0xC0, 0x00, 0x00, 0x32}; uint16_t rawData[583] = { 416, 446, 416, 446, 416, 446, 418, 446, 416, 446, 416, 25434, 3436, 1768, 390, 1336, 390, 446, 416, 446, 416, 446, 416, 1336, 390, 446, 416, 446, 416, 446, 416, 446, 416, 1336, 390, 448, 416, 1336, 390, 1336, 390, 448, 416, 1336, 390, 1336, 390, 1338, 388, 1338, 390, 1336, 390, 446, 416, 446, 416, 1336, 390, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 448, 416, 446, 416, 446, 416, 446, 416, 1336, 390, 446, 416, 1336, 390, 448, 416, 446, 416, 446, 416, 1336, 390, 1336, 390, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 448, 416, 446, 416, 446, 416, 446, 416, 448, 414, 448, 416, 448, 416, 1336, 390, 1336, 390, 1336, 390, 446, 414, 1336, 390, 448, 414, 1336, 390, 1336, 390, 34878, 3436, 1768, 390, 1336, 390, 446, 416, 448, 416, 446, 416, 1336, 390, 446, 416, 448, 416, 446, 416, 446, 416, 1336, 390, 446, 416, 1336, 390, 1336, 390, 446, 416, 1336, 390, 1336, 390, 1336, 390, 1336, 390, 1336, 392, 446, 414, 448, 416, 1336, 390, 446, 416, 446, 416, 446, 416, 446, 414, 448, 416, 446, 416, 448, 414, 448, 416, 446, 416, 446, 416, 446, 414, 1336, 390, 448, 416, 446, 416, 446, 416, 448, 416, 1336, 390, 446, 416, 446, 416, 1336, 390, 446, 416, 1336, 390, 1336, 390, 1336, 390, 446, 416, 446, 414, 1338, 390, 446, 416, 1336, 390, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 1336, 390, 1336, 390, 446, 416, 446, 416, 1336, 390, 446, 416, 446, 416, 1336, 390, 34876, 3436, 1768, 388, 1336, 390, 446, 416, 446, 416, 448, 416, 1336, 390, 446, 416, 446, 416, 446, 416, 448, 416, 1336, 390, 448, 414, 1336, 390, 1336, 390, 446, 416, 1336, 388, 1338, 388, 1336, 390, 1336, 390, 1336, 390, 446, 416, 446, 416, 1336, 390, 446, 420, 442, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 448, 416, 446, 416, 448, 416, 446, 416, 448, 416, 446, 416, 1336, 390, 1336, 390, 1336, 388, 1338, 390, 1336, 390, 1336, 392, 446, 416, 446, 416, 448, 416, 1334, 390, 446, 416, 1338, 388, 1336, 390, 1336, 390, 446, 416, 446, 416, 448, 414, 446, 416, 446, 416, 446, 416, 448, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 1336, 390, 446, 416, 1336, 390, 446, 414, 448, 416, 446, 416, 446, 416, 446, 416, 448, 416, 446, 416, 446, 416, 446, 416, 1336, 390, 446, 416, 1336, 390, 446, 416, 446, 416, 446, 416, 448, 416, 1338, 390, 444, 418, 1336, 390, 448, 416, 446, 416, 1336, 390, 446, 416, 446, 416, 1336, 390, 1336, 388, 1336, 390, 446, 416, 1336, 390, 448, 414, 448, 414, 448, 416, 1334, 390, 446, 416, 446, 416, 446, 416, 448, 416, 446, 416, 446, 416, 448, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 446, 416, 448, 416, 1336, 390, 1336, 390, 446, 416, 446, 416, 446, 416, 446, 414, 446, 416, 448, 416, 446, 416, 448, 414, 446, 418, 446, 416, 446, 416, 448, 416, 446, 416, 448, 416, 446, 416, 448, 416, 446, 416, 1336, 390, 446, 416, 446, 416, 1338, 390, 1336, 390, 446, 416, 446, 416}; // Captured by @sillyfrog irsend.reset(); irsend.sendRaw(rawData, 583, 38000); irsend.makeDecodeResult(); EXPECT_TRUE(irrecv.decode(&irsend.capture)); ASSERT_EQ(DAIKIN, irsend.capture.decode_type); ASSERT_EQ(kDaikinBits, irsend.capture.bits); EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); ac.setRaw(irsend.capture.state); EXPECT_EQ( "Power: On, Mode: 3 (COOL), Temp: 29C, Fan: 10 (AUTO), Powerful: On, " "Quiet: Off, Sensor: Off, Eye: Off, Mold: Off, Comfort: Off, " "Swing (Horizontal): Off, Swing (Vertical): Off, " "Current Time: 22:18, On Time: 21:30, Off Time: 6:10", ac.toString()); } // Decoding a message we entirely constructed based solely on a given state. TEST(TestDecodeDaikin, ShortSyntheticExample) { IRDaikinESP ac(0); IRsendTest irsend(0); IRrecv irrecv(0); irsend.begin(); uint8_t shortState[kDaikinStateLengthShort] = { 0x11, 0xDA, 0x27, 0x00, 0x42, 0x3A, 0x05, 0x93, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x3F, 0x3A, 0x00, 0xA0, 0x00, 0x0A, 0x25, 0x17, 0x01, 0x00, 0xC0, 0x00, 0x00, 0x32}; uint8_t longState[kDaikinStateLength] = { 0x11, 0xDA, 0x27, 0x00, 0xC5, 0x00, 0x00, 0xD7, 0x11, 0xDA, 0x27, 0x00, 0x42, 0x3A, 0x05, 0x93, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x3F, 0x3A, 0x00, 0xA0, 0x00, 0x0A, 0x25, 0x17, 0x01, 0x00, 0xC0, 0x00, 0x00, 0x32}; irsend.reset(); irsend.sendDaikin(shortState, kDaikinStateLengthShort); irsend.makeDecodeResult(); EXPECT_TRUE(irrecv.decode(&irsend.capture)); ASSERT_EQ(DAIKIN, irsend.capture.decode_type); ASSERT_EQ(kDaikinBits, irsend.capture.bits); EXPECT_STATE_EQ(longState, irsend.capture.state, irsend.capture.bits); ac.setRaw(irsend.capture.state); EXPECT_EQ( "Power: On, Mode: 3 (COOL), Temp: 29C, Fan: 10 (AUTO), Powerful: On, " "Quiet: Off, Sensor: Off, Eye: Off, Mold: Off, Comfort: Off, " "Swing (Horizontal): Off, Swing (Vertical): Off, " "Current Time: 22:18, On Time: 21:30, Off Time: 6:10", ac.toString()); } // Decoding a message we entirely constructed based solely on a given state. TEST(TestDecodeDaikin, LongSyntheticExample) { IRDaikinESP ac(0); IRsendTest irsend(0); IRrecv irrecv(0); irsend.begin(); uint8_t expectedState[kDaikinStateLength] = { 0x11, 0xDA, 0x27, 0x00, 0xC5, 0x00, 0x00, 0xD7, 0x11, 0xDA, 0x27, 0x00, 0x42, 0x3A, 0x05, 0x93, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x3F, 0x3A, 0x00, 0xA0, 0x00, 0x0A, 0x25, 0x17, 0x01, 0x00, 0xC0, 0x00, 0x00, 0x32}; irsend.reset(); irsend.sendDaikin(expectedState); irsend.makeDecodeResult(); EXPECT_TRUE(irrecv.decodeDaikin(&irsend.capture)); ASSERT_EQ(DAIKIN, irsend.capture.decode_type); ASSERT_EQ(kDaikinBits, irsend.capture.bits); EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); ac.setRaw(irsend.capture.state); EXPECT_EQ( "Power: On, Mode: 3 (COOL), Temp: 29C, Fan: 10 (AUTO), Powerful: On, " "Quiet: Off, Sensor: Off, Eye: Off, Mold: Off, Comfort: Off, " "Swing (Horizontal): Off, Swing (Vertical): Off, " "Current Time: 22:18, On Time: 21:30, Off Time: 6:10", ac.toString()); } // Test decoding a message captured from a real IR remote. TEST(TestDecodeDaikin2, RealExample) { IRsendTest irsend(0); IRrecv irrecv(0); irsend.begin(); uint8_t expectedState[kDaikin2StateLength] = { 0x11, 0xDA, 0x27, 0x00, 0x01, 0x7A, 0xC3, 0x70, 0x28, 0x0C, 0x80, 0x04, 0xB0, 0x16, 0x24, 0x00, 0x00, 0xBE, 0xD5, 0xF5, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x08, 0x26, 0x00, 0xA0, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0xC1, 0x80, 0x60, 0xE7}; // "Off" Data from https://github.com/markszabo/IRremoteESP8266/issues/582 uint16_t rawData[633] = { // Data supplied by @sheppy99 10024, 25180, 3494, 1732, 436, 1300, 436, 436, 432, 438, 430, 438, 426, 1306, 430, 442, 430, 438, 428, 440, 430, 440, 430, 1304, 432, 442, 428, 1308, 424, 1312, 428, 442, 428, 1306, 424, 1314, 426, 1308, 434, 1306, 426, 1308, 428, 444, 426, 442, 428, 1310, 428, 442, 424, 444, 426, 442, 426, 444, 424, 444, 426, 444, 424, 446, 422, 446, 422, 446, 422, 446, 418, 1318, 418, 450, 420, 448, 420, 448, 422, 448, 420, 450, 420, 448, 420, 450, 420, 452, 418, 1318, 420, 450, 420, 1318, 420, 1314, 418, 1318, 424, 1314, 424, 448, 422, 1316, 424, 1312, 426, 446, 422, 448, 420, 448, 422, 448, 422, 1314, 418, 1320, 416, 452, 420, 448, 420, 448, 422, 448, 422, 1314, 416, 1320, 422, 1316, 422, 450, 418, 450, 420, 448, 420, 448, 416, 1320, 418, 452, 418, 1316, 422, 448, 420, 450, 420, 450, 420, 448, 422, 1314, 418, 1320, 418, 450, 420, 448, 420, 448, 420, 450, 420, 450, 418, 450, 418, 450, 420, 450, 418, 452, 416, 452, 420, 450, 418, 1318, 420, 452, 418, 452, 418, 1322, 416, 452, 416, 452, 418, 452, 418, 452, 416, 454, 418, 452, 416, 456, 414, 452, 418, 454, 416, 1320, 410, 1324, 418, 452, 418, 1320, 416, 452, 418, 1320, 418, 1318, 420, 448, 420, 1316, 420, 450, 420, 450, 418, 450, 420, 450, 418, 452, 418, 1320, 418, 450, 418, 450, 416, 1322, 412, 458, 420, 450, 416, 452, 418, 452, 416, 452, 418, 452, 416, 454, 416, 452, 418, 452, 416, 454, 414, 454, 416, 454, 416, 454, 414, 456, 414, 454, 414, 456, 412, 454, 416, 456, 414, 456, 412, 1326, 412, 1320, 412, 1322, 414, 1322, 418, 1320, 420, 452, 418, 1318, 420, 1316, 422, 450, 420, 1314, 424, 448, 422, 1314, 422, 448, 422, 1314, 418, 1318, 424, 1316, 422, 448, 422, 1312, 424, 446, 422, 1314, 420, 1318, 422, 1316, 426, 1310, 426, 35166, 3500, 1724, 446, 1296, 444, 432, 436, 432, 438, 432, 436, 1296, 440, 434, 434, 436, 432, 436, 434, 436, 434, 1298, 438, 438, 432, 1304, 428, 1304, 432, 442, 430, 1302, 430, 1308, 430, 1306, 434, 1302, 432, 1306, 430, 440, 430, 438, 430, 1308, 434, 438, 430, 440, 428, 440, 430, 440, 428, 442, 426, 444, 428, 442, 426, 444, 426, 442, 426, 444, 424, 446, 422, 446, 424, 446, 424, 446, 422, 446, 424, 448, 420, 448, 422, 446, 422, 448, 422, 450, 420, 450, 414, 1320, 420, 450, 418, 450, 418, 448, 420, 450, 418, 452, 418, 1320, 418, 1316, 422, 450, 418, 452, 418, 1320, 420, 448, 418, 450, 420, 450, 418, 452, 416, 452, 418, 450, 418, 452, 416, 452, 418, 452, 416, 454, 416, 452, 416, 454, 416, 454, 414, 456, 416, 454, 414, 1322, 416, 454, 416, 1320, 418, 452, 416, 454, 414, 454, 416, 454, 414, 454, 414, 454, 414, 456, 414, 456, 412, 456, 414, 456, 414, 456, 412, 456, 414, 458, 406, 464, 410, 458, 412, 458, 410, 460, 410, 1326, 412, 1324, 414, 456, 412, 458, 412, 456, 414, 456, 412, 458, 410, 458, 414, 458, 410, 458, 408, 460, 410, 470, 400, 1324, 408, 1328, 410, 458, 410, 460, 414, 456, 410, 456, 414, 458, 412, 460, 410, 458, 412, 458, 412, 460, 408, 460, 410, 460, 408, 472, 396, 462, 408, 470, 402, 470, 396, 472, 400, 470, 398, 1326, 412, 460, 408, 472, 396, 472, 400, 470, 400, 472, 396, 1328, 410, 1324, 414, 458, 410, 458, 410, 458, 412, 458, 412, 460, 408, 460, 410, 460, 410, 1324, 414, 458, 410, 460, 408, 460, 410, 458, 410, 460, 410, 1326, 412, 1322, 416, 456, 412, 1322, 412, 1326, 416, 1322, 418, 452, 416, 454, 412, 1324, 418, 1320, 420, 1316, 420}; irsend.reset(); irsend.sendRaw(rawData, 633, 38000); irsend.makeDecodeResult(); ASSERT_TRUE(irrecv.decode(&irsend.capture)); ASSERT_EQ(DAIKIN2, irsend.capture.decode_type); ASSERT_EQ(kDaikin2Bits, irsend.capture.bits); EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); } // Decoding a message we entirely constructed based solely on a given state. TEST(TestDecodeDaikin2, SyntheticExample) { IRDaikin2 ac(0); IRsendTest irsend(0); IRrecv irrecv(0); irsend.begin(); uint8_t expectedState[kDaikin2StateLength] = { 0x11, 0xDA, 0x27, 0x00, 0x01, 0x7A, 0xC3, 0x70, 0x28, 0x0C, 0x80, 0x04, 0xB0, 0x16, 0x24, 0x00, 0x00, 0xBE, 0xD5, 0xF5, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x08, 0x26, 0x00, 0xA0, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0xC1, 0x80, 0x60, 0xE7}; irsend.reset(); irsend.sendDaikin2(expectedState); irsend.makeDecodeResult(); ASSERT_TRUE(irrecv.decode(&irsend.capture)); ASSERT_EQ(DAIKIN2, irsend.capture.decode_type); ASSERT_EQ(kDaikin2Bits, irsend.capture.bits); EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); ac.setRaw(irsend.capture.state); EXPECT_EQ( "Power: Off, Mode: 0 (AUTO), Temp: 19C, Fan: 10 (Auto), " "Swing (V): 5, Swing (H): 190 (Auto), " "Clock: 14:50, On Time: Off, Off Time: Off, Sleep Time: Off, " "Beep: 1 (Quiet), Light: 3 (Off), Mold: On, Clean: On, Fresh Air: Off, " "Eye: Off, Eye Auto: Off, Quiet: Off, Powerful: Off, Purify: Off, " "Econo: Off", ac.toString()); } TEST(TestDaikin2Class, CurrentTime) { IRDaikin2 ac(0); ac.begin(); ac.setCurrentTime(0); // 00:00 EXPECT_EQ(0, ac.getCurrentTime()); ac.setCurrentTime(754); // 12:34 EXPECT_EQ(754, ac.getCurrentTime()); ac.setCurrentTime(1439); // 23:59 EXPECT_EQ(1439, ac.getCurrentTime()); } TEST(TestDaikin2Class, OnOffTimers) { IRDaikin2 ac(0); ac.begin(); // Both timers turned off. ac.disableOnTimer(); ac.disableOffTimer(); EXPECT_FALSE(ac.getOnTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getOnTime()); EXPECT_FALSE(ac.getOffTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getOffTime()); // Turn on just the On Timer. ac.enableOnTimer(123); EXPECT_TRUE(ac.getOnTimerEnabled()); EXPECT_EQ(123, ac.getOnTime()); EXPECT_FALSE(ac.getOffTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getOffTime()); // Now turn on the Off Timer. ac.enableOffTimer(754); EXPECT_TRUE(ac.getOffTimerEnabled()); EXPECT_EQ(754, ac.getOffTime()); EXPECT_TRUE(ac.getOnTimerEnabled()); EXPECT_EQ(123, ac.getOnTime()); // Turn off the just the On Timer. ac.disableOnTimer(); EXPECT_FALSE(ac.getOnTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getOnTime()); EXPECT_TRUE(ac.getOffTimerEnabled()); EXPECT_EQ(754, ac.getOffTime()); // Now turn off the Off Timer. ac.disableOffTimer(); EXPECT_FALSE(ac.getOffTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getOffTime()); EXPECT_FALSE(ac.getOnTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getOnTime()); } TEST(TestDaikin2Class, LightAndBeep) { IRDaikin2 ac(0); ac.begin(); ac.setLight(kDaikinLightOff); EXPECT_EQ(kDaikinLightOff, ac.getLight()); ac.setBeep(kDaikinBeepOff); EXPECT_EQ(kDaikinBeepOff, ac.getBeep()); ac.setLight(kDaikinLightBright); EXPECT_EQ(kDaikinLightBright, ac.getLight()); EXPECT_EQ(kDaikinBeepOff, ac.getBeep()); ac.setBeep(kDaikinBeepLoud); EXPECT_EQ(kDaikinBeepLoud, ac.getBeep()); EXPECT_EQ(kDaikinLightBright, ac.getLight()); } TEST(TestDaikin2Class, FanSpeed) { IRDaikin2 ac(0); ac.begin(); // Unexpected value should default to Auto. ac.setFan(0); EXPECT_EQ(kDaikinFanAuto, ac.getFan()); // Unexpected value should default to Auto. ac.setFan(255); EXPECT_EQ(kDaikinFanAuto, ac.getFan()); ac.setFan(kDaikinFanMax); EXPECT_EQ(kDaikinFanMax, ac.getFan()); // Beyond Max should default to Auto. ac.setFan(kDaikinFanMax + 1); EXPECT_EQ(kDaikinFanAuto, ac.getFan()); ac.setFan(kDaikinFanMax - 1); EXPECT_EQ(kDaikinFanMax - 1, ac.getFan()); ac.setFan(kDaikinFanMin); EXPECT_EQ(kDaikinFanMin, ac.getFan()); ac.setFan(kDaikinFanMin + 1); EXPECT_EQ(kDaikinFanMin + 1, ac.getFan()); // Beyond Min should default to Auto. ac.setFan(kDaikinFanMin - 1); EXPECT_EQ(kDaikinFanAuto, ac.getFan()); ac.setFan(3); EXPECT_EQ(3, ac.getFan()); ac.setFan(kDaikinFanAuto); EXPECT_EQ(kDaikinFanAuto, ac.getFan()); ac.setFan(kDaikinFanQuiet); EXPECT_EQ(kDaikinFanQuiet, ac.getFan()); } // Test Mold mode. TEST(TestDaikin2Class, MoldSetting) { IRDaikin2 ac(0); ac.begin(); ac.setMold(false); ASSERT_FALSE(ac.getMold()); ac.setMold(true); ASSERT_TRUE(ac.getMold()); ac.setMold(false); ASSERT_FALSE(ac.getMold()); } // Test Auto Clean setting. TEST(TestDaikin2Class, CleanSetting) { IRDaikin2 ac(0); ac.begin(); ac.setClean(false); ASSERT_FALSE(ac.getClean()); ac.setClean(true); ASSERT_TRUE(ac.getClean()); ac.setClean(false); ASSERT_FALSE(ac.getClean()); } TEST(TestDaikin2Class, Temperature) { IRDaikin2 ac(0); ac.begin(); ac.setMode(kDaikinAuto); ac.setTemp(0); EXPECT_EQ(kDaikinMinTemp, ac.getTemp()); ac.setTemp(255); EXPECT_EQ(kDaikinMaxTemp, ac.getTemp()); ac.setTemp(kDaikinMinTemp); EXPECT_EQ(kDaikinMinTemp, ac.getTemp()); ac.setTemp(kDaikinMaxTemp); EXPECT_EQ(kDaikinMaxTemp, ac.getTemp()); ac.setTemp(kDaikinMinTemp - 1); EXPECT_EQ(kDaikinMinTemp, ac.getTemp()); ac.setTemp(kDaikinMaxTemp + 1); EXPECT_EQ(kDaikinMaxTemp, ac.getTemp()); ac.setTemp(kDaikinMinTemp + 1); EXPECT_EQ(kDaikinMinTemp + 1, ac.getTemp()); // Now try it with Cool mode, which should set the temp to kDaikin2MinCoolTemp ASSERT_TRUE(kDaikinMinTemp + 1 < kDaikin2MinCoolTemp); ac.setMode(kDaikinCool); EXPECT_EQ(kDaikin2MinCoolTemp, ac.getTemp()); ac.setTemp(kDaikin2MinCoolTemp - 1); EXPECT_EQ(kDaikin2MinCoolTemp, ac.getTemp()); ac.setTemp(kDaikin2MinCoolTemp + 1); EXPECT_EQ(kDaikin2MinCoolTemp + 1, ac.getTemp()); // Should be released from that requirement in other modes. ac.setMode(kDaikinAuto); ac.setTemp(kDaikin2MinCoolTemp - 1); EXPECT_EQ(kDaikin2MinCoolTemp - 1, ac.getTemp()); ac.setTemp(21); EXPECT_EQ(21, ac.getTemp()); ac.setTemp(25); EXPECT_EQ(25, ac.getTemp()); ac.setTemp(29); EXPECT_EQ(29, ac.getTemp()); } // Test Fresh Air settings. TEST(TestDaikin2Class, FreshAirSettings) { IRDaikin2 ac(0); ac.begin(); ac.setFreshAir(false); ac.setFreshAirHigh(false); ASSERT_FALSE(ac.getFreshAir()); ASSERT_FALSE(ac.getFreshAirHigh()); ac.setFreshAir(true); ASSERT_TRUE(ac.getFreshAir()); ASSERT_FALSE(ac.getFreshAirHigh()); ac.setFreshAirHigh(true); ASSERT_TRUE(ac.getFreshAir()); ASSERT_TRUE(ac.getFreshAirHigh()); ac.setFreshAir(false); ASSERT_FALSE(ac.getFreshAir()); ASSERT_TRUE(ac.getFreshAirHigh()); ac.setFreshAirHigh(false); ASSERT_FALSE(ac.getFreshAir()); ASSERT_FALSE(ac.getFreshAirHigh()); } // Test Eye mode. TEST(TestDaikin2Class, EyeSetting) { IRDaikin2 ac(0); ac.begin(); ac.setEye(false); ASSERT_FALSE(ac.getEye()); ac.setEye(true); ASSERT_TRUE(ac.getEye()); ac.setEye(false); ASSERT_FALSE(ac.getEye()); } // Test Econo setting. TEST(TestDaikin2Class, EconoSetting) { IRDaikin2 ac(0); ac.begin(); ac.setEcono(false); ASSERT_FALSE(ac.getEcono()); ac.setEcono(true); ASSERT_TRUE(ac.getEcono()); ac.setEcono(false); ASSERT_FALSE(ac.getEcono()); } TEST(TestDaikin2Class, SleepTimer) { IRDaikin2 ac(0); ac.begin(); // NOTE: On & Sleep timer share the same time location. // Both timers turned off. ac.disableOnTimer(); ac.disableSleepTimer(); EXPECT_FALSE(ac.getOnTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getOnTime()); EXPECT_FALSE(ac.getSleepTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getSleepTime()); // Turn on just the On Timer. ac.enableOnTimer(123); EXPECT_TRUE(ac.getOnTimerEnabled()); EXPECT_EQ(123, ac.getOnTime()); EXPECT_FALSE(ac.getSleepTimerEnabled()); EXPECT_EQ(123, ac.getSleepTime()); // Now turn on the Sleep Timer. This shoud disable the On Timer. ac.enableSleepTimer(754); EXPECT_TRUE(ac.getSleepTimerEnabled()); EXPECT_EQ(754, ac.getSleepTime()); EXPECT_FALSE(ac.getOnTimerEnabled()); EXPECT_EQ(754, ac.getOnTime()); // Turn off the just the On Timer. ac.disableOnTimer(); EXPECT_FALSE(ac.getOnTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getOnTime()); EXPECT_FALSE(ac.getSleepTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getSleepTime()); // Now turn on the On Timer and turn off the Sleep Timer. // Both should be off afterwards. ac.enableOnTimer(123); ac.disableSleepTimer(); EXPECT_FALSE(ac.getSleepTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getSleepTime()); EXPECT_FALSE(ac.getOnTimerEnabled()); EXPECT_EQ(kDaikinUnusedTime, ac.getOnTime()); } // Test Vertical Swing. TEST(TestDaikin2Class, Swing) { IRDaikin2 ac(0); ac.begin(); // Vertical ac.setSwingVertical(1); ASSERT_EQ(1, ac.getSwingVertical()); ac.setSwingVertical(3); ASSERT_EQ(3, ac.getSwingVertical()); ac.setSwingVertical(6); ASSERT_EQ(6, ac.getSwingVertical()); ac.setSwingVertical(kDaikin2SwingVBreeze); ASSERT_EQ(kDaikin2SwingVBreeze, ac.getSwingVertical()); ac.setSwingVertical(kDaikin2SwingVCirculate); ASSERT_EQ(kDaikin2SwingVCirculate, ac.getSwingVertical()); ac.setSwingVertical(kDaikin2SwingVAuto); ASSERT_EQ(kDaikin2SwingVAuto, ac.getSwingVertical()); ac.setSwingVertical(0); ASSERT_EQ(kDaikin2SwingVAuto, ac.getSwingVertical()); ac.setSwingVertical(7); ASSERT_EQ(kDaikin2SwingVAuto, ac.getSwingVertical()); ac.setSwingVertical(255); ASSERT_EQ(kDaikin2SwingVAuto, ac.getSwingVertical()); // Horizontal ac.setSwingHorizontal(kDaikin2SwingHAuto); ASSERT_EQ(kDaikin2SwingHAuto, ac.getSwingHorizontal()); ac.setSwingHorizontal(kDaikin2SwingHSwing); ASSERT_EQ(kDaikin2SwingHSwing, ac.getSwingHorizontal()); ac.setSwingHorizontal(0); ASSERT_EQ(0, ac.getSwingHorizontal()); ac.setSwingHorizontal(255); ASSERT_EQ(255, ac.getSwingHorizontal()); } TEST(TestDaikin2Class, QuietMode) { IRDaikin2 ac(0); ac.begin(); ac.setQuiet(true); EXPECT_TRUE(ac.getQuiet()); ac.setQuiet(false); EXPECT_FALSE(ac.getQuiet()); ac.setQuiet(true); EXPECT_TRUE(ac.getQuiet()); // But setting Powerful mode should exit out of quiet mode. ac.setPowerful(true); EXPECT_FALSE(ac.getQuiet()); } TEST(TestDaikin2Class, PowerfulMode) { IRDaikin2 ac(0); ac.begin(); ac.setPowerful(true); EXPECT_TRUE(ac.getPowerful()); ac.setPowerful(false); EXPECT_FALSE(ac.getPowerful()); ac.setPowerful(true); EXPECT_TRUE(ac.getPowerful()); ac.setQuiet(true); EXPECT_FALSE(ac.getPowerful()); } // Test Purify mode. TEST(TestDaikin2Class, PurifySetting) { IRDaikin2 ac(0); ac.begin(); ac.setPurify(false); ASSERT_FALSE(ac.getPurify()); ac.setPurify(true); ASSERT_TRUE(ac.getPurify()); ac.setPurify(false); ASSERT_FALSE(ac.getPurify()); } TEST(TestDaikin2Class, HumanReadable) { IRDaikin2 ac(0); ac.begin(); ac.setPower(true); ac.setMode(kDaikinCool); ac.setTemp(21); ac.setFan(kDaikinFanMax); ac.setSwingVertical(kDaikin2SwingVAuto); ac.setSwingHorizontal(kDaikin2SwingHSwing); ac.setCurrentTime(12 * 60 + 34); // 12:34 ac.disableOnTimer(); ac.enableOffTimer(20 * 60); // 20:00 ac.enableSleepTimer(4 * 60); // 4:00 ac.setBeep(kDaikinBeepLoud); ac.setLight(kDaikinLightDim); ac.setMold(true); ac.setClean(false); ac.setFreshAir(true); ac.setEye(true); ac.setEyeAuto(true); ac.setQuiet(false); ac.setPowerful(true); ac.setPurify(true); ac.setEcono(false); EXPECT_EQ( "Power: On, Mode: 3 (COOL), Temp: 21C, Fan: 5 (Max), " "Swing (V): 14 (Auto), Swing (H): 191 (Swing), Clock: 12:34, " "On Time: Off, Off Time: 20:00, Sleep Time: 4:00, Beep: 2 (Loud), " "Light: 2 (Dim), Mold: On, Clean: Off, Fresh Air: On, Eye: On, " "Eye Auto: On, Quiet: Off, Powerful: On, Purify: On, Econo: Off", ac.toString()); ac.setQuiet(true); ac.setMode(kDaikinHeat); ac.setBeep(kDaikinBeepQuiet); ac.setLight(kDaikinLightBright); ac.setTemp(32); ac.setFan(kDaikinFanMin); ac.setCurrentTime(23 * 60 + 45); // 23:45 ac.enableOnTimer(9 * 60 + 11); // 9:11 EXPECT_EQ( "Power: On, Mode: 4 (HEAT), Temp: 32C, Fan: 1 (Min), " "Swing (V): 14 (Auto), Swing (H): 191 (Swing), Clock: 23:45, " "On Time: 9:11, Off Time: 20:00, Sleep Time: Off, Beep: 1 (Quiet), " "Light: 1 (Bright), Mold: On, Clean: Off, Fresh Air: On, Eye: On, " "Eye Auto: On, Quiet: On, Powerful: Off, Purify: On, Econo: Off", ac.toString()); } // See if we can construct a known state. TEST(TestDaikin2Class, KnownConstruction) { IRDaikin2 ac(0); uint8_t expectedState[kDaikin2StateLength] = { 0x11, 0xDA, 0x27, 0x00, 0x01, 0x7A, 0xC3, 0x70, 0x28, 0x0C, 0x80, 0x04, 0xB0, 0x16, 0x24, 0x00, 0x00, 0xBE, 0xD5, 0xF5, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x08, 0x26, 0x00, 0xA0, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0xC1, 0x80, 0x60, 0xE7}; ac.begin(); ac.setPower(false); ac.setMode(kDaikinAuto); ac.setTemp(19); ac.setFan(kDaikinFanAuto); ac.setSwingVertical(5); ac.setSwingHorizontal(kDaikin2SwingHAuto); ac.setCurrentTime(14 * 60 + 50); // 14:50 ac.disableOnTimer(); ac.disableOffTimer(); ac.disableSleepTimer(); ac.setBeep(kDaikinBeepQuiet); ac.setLight(kDaikinLightOff); ac.setMold(true); ac.setClean(true); ac.setFreshAir(false); ac.setEye(false); ac.setEyeAuto(false); ac.setQuiet(false); ac.setPowerful(false); ac.setPurify(false); ac.setEcono(false); EXPECT_EQ( "Power: Off, Mode: 0 (AUTO), Temp: 19C, Fan: 10 (Auto), " "Swing (V): 5, Swing (H): 190 (Auto), " "Clock: 14:50, On Time: Off, Off Time: Off, Sleep Time: Off, " "Beep: 1 (Quiet), Light: 3 (Off), Mold: On, Clean: On, Fresh Air: Off, " "Eye: Off, Eye Auto: Off, Quiet: Off, Powerful: Off, Purify: Off, " "Econo: Off", ac.toString()); EXPECT_STATE_EQ(expectedState, ac.getRaw(), kDaikin2Bits); } TEST(TestUtils, Housekeeping) { ASSERT_EQ("DAIKIN", typeToString(decode_type_t::DAIKIN)); ASSERT_EQ(decode_type_t::DAIKIN, strToDecodeType("DAIKIN")); ASSERT_TRUE(hasACState(decode_type_t::DAIKIN)); ASSERT_EQ("DAIKIN2", typeToString(decode_type_t::DAIKIN2)); ASSERT_EQ(decode_type_t::DAIKIN2, strToDecodeType("DAIKIN2")); ASSERT_TRUE(hasACState(decode_type_t::DAIKIN2)); ASSERT_EQ("DAIKIN216", typeToString(decode_type_t::DAIKIN216)); ASSERT_EQ(decode_type_t::DAIKIN216, strToDecodeType("DAIKIN216")); ASSERT_TRUE(hasACState(decode_type_t::DAIKIN216)); } // https://github.com/markszabo/IRremoteESP8266/issues/582#issuecomment-453863879 TEST(TestDecodeDaikin2, Issue582DeepDecodeExample) { IRDaikin2 ac(0); const uint8_t state[kDaikin2StateLength] = { 0x11, 0xDA, 0x27, 0x00, 0x01, 0x30, 0x42, 0xF0, 0x28, 0x0C, 0x80, 0x04, 0xB0, 0x16, 0x24, 0x00, 0x00, 0xBE, 0xCE, 0xA3, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x09, 0x26, 0x00, 0xA0, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0xC1, 0x92, 0x60, 0xFA}; ac.setRaw(state); ASSERT_TRUE(ac.getMold()); ASSERT_TRUE(ac.getEye()); ASSERT_TRUE(ac.getPurify()); EXPECT_EQ( "Power: On, Mode: 0 (AUTO), Temp: 19C, Fan: 10 (Auto), " "Swing (V): 14 (Auto), Swing (H): 190 (Auto), Clock: 9:20, On Time: Off, " "Off Time: Off, Sleep Time: Off, Beep: 3 (Off), Light: 3 (Off), " "Mold: On, Clean: On, Fresh Air: Off, Eye: On, Eye Auto: Off, " "Quiet: Off, Powerful: Off, Purify: On, Econo: Off", ac.toString()); } // https://docs.google.com/spreadsheets/d/1f8EGfIbBUo2B-CzUFdrgKQprWakoYNKM80IKZN4KXQE/edit?ts=5c317775#gid=1023395743 TEST(TestDecodeDaikin2, Issue582PowerfulEconoFix) { IRDaikin2 ac(0); const uint8_t PowerfulOn[39] = { 0x11, 0xDA, 0x27, 0x00, 0x01, 0x3A, 0x43, 0xF0, 0x28, 0x0C, 0x80, 0x04, 0xB0, 0x16, 0x24, 0x00, 0x00, 0xBE, 0xCE, 0xAE, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x39, 0x28, 0x00, 0xA0, 0x00, 0x00, 0x06, 0x60, 0x01, 0x00, 0xC1, 0x90, 0x60, 0x2B}; const uint8_t PowerfulOff[39] = { 0x11, 0xDA, 0x27, 0x00, 0x01, 0x3A, 0x43, 0xF0, 0x28, 0x0C, 0x80, 0x04, 0xB0, 0x16, 0x24, 0x00, 0x00, 0xBE, 0xCE, 0xAE, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x39, 0x28, 0x00, 0xA0, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0xC1, 0x90, 0x60, 0x2A}; ac.setRaw(PowerfulOn); ASSERT_TRUE(ac.getPowerful()); EXPECT_EQ( "Power: On, Mode: 3 (COOL), Temp: 20C, Fan: 10 (Auto), " "Swing (V): 14 (Auto), Swing (H): 190 (Auto), Clock: 13:46, " "On Time: Off, Off Time: Off, Sleep Time: Off, Beep: 3 (Off), " "Light: 3 (Off), Mold: On, Clean: On, Fresh Air: Off, Eye: Off, " "Eye Auto: Off, Quiet: Off, Powerful: On, Purify: On, Econo: Off", ac.toString()); ac.setRaw(PowerfulOff); ASSERT_FALSE(ac.getPowerful()); EXPECT_EQ( "Power: On, Mode: 3 (COOL), Temp: 20C, Fan: 10 (Auto), " "Swing (V): 14 (Auto), Swing (H): 190 (Auto), Clock: 13:46, " "On Time: Off, Off Time: Off, Sleep Time: Off, Beep: 3 (Off), " "Light: 3 (Off), Mold: On, Clean: On, Fresh Air: Off, Eye: Off, " "Eye Auto: Off, Quiet: Off, Powerful: Off, Purify: On, Econo: Off", ac.toString()); const uint8_t EconoOn[39] = { 0x11, 0xDA, 0x27, 0x00, 0x01, 0x3B, 0x43, 0xF0, 0x28, 0x0C, 0x80, 0x04, 0xB0, 0x16, 0x24, 0x00, 0x00, 0xBE, 0xCE, 0xAF, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x39, 0x28, 0x00, 0xA0, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0xC1, 0x94, 0x60, 0x2E}; const uint8_t EconoOff[39] = { 0x11, 0xDA, 0x27, 0x00, 0x01, 0x3B, 0x43, 0xF0, 0x28, 0x0C, 0x80, 0x04, 0xB0, 0x16, 0x24, 0x00, 0x00, 0xBE, 0xCE, 0xAF, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x39, 0x28, 0x00, 0xA0, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0xC1, 0x90, 0x60, 0x2A}; ac.setRaw(EconoOn); ASSERT_TRUE(ac.getEcono()); EXPECT_EQ( "Power: On, Mode: 3 (COOL), Temp: 20C, Fan: 10 (Auto), " "Swing (V): 14 (Auto), Swing (H): 190 (Auto), Clock: 13:47, " "On Time: Off, Off Time: Off, Sleep Time: Off, Beep: 3 (Off), " "Light: 3 (Off), Mold: On, Clean: On, Fresh Air: Off, Eye: Off, " "Eye Auto: Off, Quiet: Off, Powerful: Off, Purify: On, Econo: On", ac.toString()); ac.setRaw(EconoOff); ASSERT_FALSE(ac.getEcono()); EXPECT_EQ( "Power: On, Mode: 3 (COOL), Temp: 20C, Fan: 10 (Auto), " "Swing (V): 14 (Auto), Swing (H): 190 (Auto), Clock: 13:47, " "On Time: Off, Off Time: Off, Sleep Time: Off, Beep: 3 (Off), " "Light: 3 (Off), Mold: On, Clean: On, Fresh Air: Off, Eye: Off, " "Eye Auto: Off, Quiet: Off, Powerful: Off, Purify: On, Econo: Off", ac.toString()); } // Tests for IRDaikin216 class. TEST(TestDaikin216Class, Power) { IRDaikin216 ac(0); ac.begin(); 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(TestDaikin216Class, Temperature) { IRDaikin216 ac(0); ac.begin(); ac.setTemp(0); EXPECT_EQ(kDaikinMinTemp, ac.getTemp()); ac.setTemp(255); EXPECT_EQ(kDaikinMaxTemp, ac.getTemp()); ac.setTemp(kDaikinMinTemp); EXPECT_EQ(kDaikinMinTemp, ac.getTemp()); ac.setTemp(kDaikinMaxTemp); EXPECT_EQ(kDaikinMaxTemp, ac.getTemp()); ac.setTemp(kDaikinMinTemp - 1); EXPECT_EQ(kDaikinMinTemp, ac.getTemp()); ac.setTemp(kDaikinMaxTemp + 1); EXPECT_EQ(kDaikinMaxTemp, ac.getTemp()); ac.setTemp(kDaikinMinTemp + 1); EXPECT_EQ(kDaikinMinTemp + 1, ac.getTemp()); ac.setTemp(21); EXPECT_EQ(21, ac.getTemp()); ac.setTemp(25); EXPECT_EQ(25, ac.getTemp()); ac.setTemp(29); EXPECT_EQ(29, ac.getTemp()); } TEST(TestDaikin216Class, OperatingMode) { IRDaikin216 ac(0); ac.begin(); ac.setMode(kDaikinAuto); EXPECT_EQ(kDaikinAuto, ac.getMode()); ac.setMode(kDaikinCool); EXPECT_EQ(kDaikinCool, ac.getMode()); ac.setMode(kDaikinHeat); EXPECT_EQ(kDaikinHeat, ac.getMode()); ac.setMode(kDaikinDry); EXPECT_EQ(kDaikinDry, ac.getMode()); ac.setMode(kDaikinFan); EXPECT_EQ(kDaikinFan, ac.getMode()); ac.setMode(kDaikinFan + 1); EXPECT_EQ(kDaikinAuto, ac.getMode()); ac.setMode(kDaikinAuto + 1); EXPECT_EQ(kDaikinAuto, ac.getMode()); ac.setMode(255); EXPECT_EQ(kDaikinAuto, ac.getMode()); } TEST(TestDaikin216Class, VaneSwing) { IRDaikin216 ac(0); ac.begin(); ac.setSwingHorizontal(true); ac.setSwingVertical(false); ac.setSwingHorizontal(true); EXPECT_TRUE(ac.getSwingHorizontal()); EXPECT_FALSE(ac.getSwingVertical()); ac.setSwingVertical(true); EXPECT_TRUE(ac.getSwingHorizontal()); EXPECT_TRUE(ac.getSwingVertical()); ac.setSwingHorizontal(false); EXPECT_FALSE(ac.getSwingHorizontal()); EXPECT_TRUE(ac.getSwingVertical()); ac.setSwingVertical(false); EXPECT_FALSE(ac.getSwingHorizontal()); EXPECT_FALSE(ac.getSwingVertical()); } TEST(TestDaikin216Class, FanSpeed) { IRDaikin216 ac(0); ac.begin(); // Unexpected value should default to Auto. ac.setFan(0); EXPECT_EQ(kDaikinFanAuto, ac.getFan()); // Unexpected value should default to Auto. ac.setFan(255); EXPECT_EQ(kDaikinFanAuto, ac.getFan()); ac.setFan(kDaikinFanMax); EXPECT_EQ(kDaikinFanMax, ac.getFan()); // Beyond Max should default to Auto. ac.setFan(kDaikinFanMax + 1); EXPECT_EQ(kDaikinFanAuto, ac.getFan()); ac.setFan(kDaikinFanMax - 1); EXPECT_EQ(kDaikinFanMax - 1, ac.getFan()); ac.setFan(kDaikinFanMin); EXPECT_EQ(kDaikinFanMin, ac.getFan()); ac.setFan(kDaikinFanMin + 1); EXPECT_EQ(kDaikinFanMin + 1, ac.getFan()); // Beyond Min should default to Auto. ac.setFan(kDaikinFanMin - 1); EXPECT_EQ(kDaikinFanAuto, ac.getFan()); ac.setFan(3); EXPECT_EQ(3, ac.getFan()); ac.setFan(kDaikinFanAuto); EXPECT_EQ(kDaikinFanAuto, ac.getFan()); ac.setFan(kDaikinFanQuiet); EXPECT_EQ(kDaikinFanQuiet, ac.getFan()); } TEST(TestDaikin216Class, Quiet) { IRDaikin216 ac(0); ac.begin(); ac.setQuiet(true); EXPECT_TRUE(ac.getQuiet()); ac.setQuiet(false); EXPECT_FALSE(ac.getQuiet()); ac.setQuiet(true); EXPECT_TRUE(ac.getQuiet()); } TEST(TestDaikin216Class, ExampleStates) { IRDaikin216 ac(0); ac.begin(); // https://github.com/markszabo/IRremoteESP8266/pull/690#issuecomment-487770194 uint8_t state[kDaikin216StateLength] = { 0x11, 0xDA, 0x27, 0xF0, 0x00, 0x00, 0x00, 0x02, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x21, 0xC0, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x53}; ac.setRaw(state); EXPECT_EQ( "Power: On, Mode: 2 (DRY), Temp: 32C, Fan: 10 (AUTO), " "Swing (Horizontal): Off, Swing (Vertical): Off, Quiet: Off", ac.toString()); } TEST(TestDaikin216Class, ReconstructKnownState) { IRDaikin216 ac(0); ac.begin(); // https://github.com/markszabo/IRremoteESP8266/issues/689#issue-438086949 uint8_t expectedState[kDaikin216StateLength] = { 0x11, 0xDA, 0x27, 0xF0, 0x00, 0x00, 0x00, 0x02, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x00, 0x26, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x98}; ac.setPower(false); ac.setMode(kDaikinAuto); ac.setTemp(19); ac.setFan(kDaikinFanAuto); ac.setSwingHorizontal(false); ac.setSwingVertical(false); ac.setQuiet(false); EXPECT_EQ( "Power: Off, Mode: 0 (AUTO), Temp: 19C, Fan: 10 (AUTO), " "Swing (Horizontal): Off, Swing (Vertical): Off, Quiet: Off", ac.toString()); EXPECT_STATE_EQ(expectedState, ac.getRaw(), kDaikin216Bits); } // https://github.com/markszabo/IRremoteESP8266/issues/689 TEST(TestDecodeDaikin216, RealExample) { IRsendTest irsend(0); IRrecv irrecv(0); // https://github.com/markszabo/IRremoteESP8266/issues/689#issue-438086949 uint16_t rawData[439] = { 3402, 1770, 382, 1340, 382, 480, 382, 478, 382, 480, 380, 1342, 382, 478, 356, 504, 382, 480, 380, 478, 384, 1342, 380, 480, 380, 1342, 382, 1342, 382, 478, 382, 1340, 382, 1340, 384, 1340, 382, 1342, 382, 1340, 380, 480, 382, 480, 382, 1296, 426, 480, 380, 480, 382, 480, 380, 480, 382, 480, 382, 478, 382, 1342, 382, 1342, 382, 1340, 356, 1368, 382, 478, 382, 480, 382, 478, 380, 480, 382, 480, 382, 480, 382, 478, 382, 480, 382, 478, 358, 504, 382, 480, 380, 480, 382, 480, 382, 480, 380, 480, 382, 478, 382, 480, 382, 478, 382, 480, 354, 506, 354, 506, 380, 480, 382, 480, 382, 480, 382, 480, 380, 1342, 382, 480, 382, 480, 382, 478, 382, 478, 382, 478, 384, 478, 382, 29652, 3426, 1772, 382, 1340, 382, 480, 380, 478, 382, 480, 382, 1342, 382, 480, 382, 480, 382, 478, 356, 506, 382, 1342, 380, 480, 382, 1340, 382, 1340, 382, 478, 356, 1366, 382, 1340, 384, 1340, 382, 1340, 382, 1342, 382, 478, 382, 478, 382, 1340, 382, 478, 382, 478, 382, 478, 382, 480, 382, 480, 384, 478, 358, 504, 382, 478, 382, 480, 382, 478, 382, 480, 382, 480, 382, 478, 382, 480, 382, 478, 382, 478, 382, 478, 382, 478, 384, 478, 382, 478, 360, 500, 358, 504, 382, 478, 382, 480, 382, 480, 382, 478, 382, 478, 382, 1340, 382, 1342, 382, 480, 380, 480, 382, 1342, 382, 478, 382, 480, 356, 506, 382, 478, 382, 480, 382, 480, 356, 506, 382, 478, 382, 480, 382, 478, 382, 480, 382, 478, 382, 480, 380, 480, 380, 480, 382, 1342, 382, 478, 382, 1342, 382, 480, 382, 480, 382, 478, 382, 478, 382, 480, 382, 478, 382, 480, 356, 504, 384, 478, 382, 480, 382, 480, 380, 480, 382, 478, 382, 480, 382, 480, 382, 478, 356, 504, 384, 478, 380, 480, 382, 480, 382, 480, 382, 478, 356, 506, 382, 478, 382, 480, 380, 480, 382, 478, 382, 480, 382, 478, 382, 480, 358, 504, 382, 478, 382, 478, 356, 504, 382, 478, 382, 480, 382, 478, 382, 478, 382, 478, 382, 480, 380, 480, 382, 480, 380, 480, 356, 506, 356, 504, 382, 480, 382, 478, 382, 478, 382, 478, 382, 478, 382, 480, 382, 478, 382, 480, 382, 480, 382, 1340, 382, 1342, 382, 478, 384, 478, 382, 478, 382, 480, 380, 480, 382, 478, 382, 480, 356, 506, 382, 478, 382, 480, 382, 478, 356, 506, 380, 480, 382, 478, 382, 478, 382, 478, 382, 480, 382, 480, 380, 480, 382, 1342, 382, 1340, 382, 480, 356, 504, 382, 1342, 382}; // UNKNOWN E0E32232 uint8_t expectedState[kDaikin216StateLength] = { // 8 bytes 0x11, 0xDA, 0x27, 0xF0, 0x00, 0x00, 0x00, 0x02, // 19 bytes 0x11, 0xDA, 0x27, 0x00, 0x00, 0x00, 0x26, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x98}; irsend.begin(); irsend.reset(); irsend.sendRaw(rawData, 439, 38000); irsend.makeDecodeResult(); ASSERT_TRUE(irrecv.decode(&irsend.capture)); ASSERT_EQ(DAIKIN216, irsend.capture.decode_type); ASSERT_EQ(kDaikin216Bits, irsend.capture.bits); EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); IRDaikin216 ac(0); ac.setRaw(irsend.capture.state); EXPECT_EQ( "Power: Off, Mode: 0 (AUTO), Temp: 19C, Fan: 10 (AUTO), " "Swing (Horizontal): Off, Swing (Vertical): Off, Quiet: Off", ac.toString()); } // https://github.com/markszabo/IRremoteESP8266/issues/689 TEST(TestDecodeDaikin216, SyntheticExample) { IRsendTest irsend(0); IRrecv irrecv(0); // https://github.com/markszabo/IRremoteESP8266/issues/689#issue-438086949 uint8_t expectedState[kDaikin216StateLength] = { // 8 bytes 0x11, 0xDA, 0x27, 0xF0, 0x00, 0x00, 0x00, 0x02, // 19 bytes 0x11, 0xDA, 0x27, 0x00, 0x00, 0x00, 0x26, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x98}; irsend.begin(); irsend.reset(); irsend.sendDaikin216(expectedState); irsend.makeDecodeResult(); ASSERT_TRUE(irrecv.decode(&irsend.capture)); ASSERT_EQ(DAIKIN216, irsend.capture.decode_type); ASSERT_EQ(kDaikin216Bits, irsend.capture.bits); EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); }