Tasmota/lib/lib_basic/IRremoteESP8266/test/ir_Truma_test.cpp
2021-05-29 14:48:27 +02:00

288 lines
8.3 KiB
C++

// Copyright 2021 David Conran (crankyoldgit)
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for decodeTruma().
TEST(TestDecodeTruma, RealExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
// 16 / AUTO / -
const uint16_t rawData[117] = {
20194, 1028, 1798, 628, 558, 662, 1190, 640,
1190, 638, 1190, 634, 1190, 638, 1188, 640,
1164, 662, 558, 658, 1192, 636, 1166, 662,
1190, 638, 1164, 658, 1190, 638, 582, 640,
556, 662, 558, 660, 1188, 638, 558, 662,
558, 662, 1190, 634, 1188, 638, 556, 664,
558, 662, 556, 660, 556, 664, 558, 662,
556, 664, 556, 662, 556, 664, 558, 662,
558, 662, 558, 660, 556, 664, 556, 664,
556, 664, 556, 660, 558, 664, 578, 640,
580, 640, 556, 660, 556, 664, 556, 664,
556, 664, 580, 636, 556, 664, 556, 664,
556, 664, 556, 660, 556, 664, 1188, 638,
1188, 640, 554, 662, 1188, 640, 1188, 638,
554, 666, 1164, 654, 582};
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData, 117, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::TRUMA, irsend.capture.decode_type);
ASSERT_EQ(kTrumaBits, irsend.capture.bits);
EXPECT_EQ(0x49ffffffe6e081, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_EQ(
"Power: On, Mode: 0 (Auto), Temp: 16C, Fan: 4 (High), Quiet: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestDecodeTruma, SyntheticExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
// 16 / AUTO / -
irsend.sendTruma(0x49ffffffe6e081);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::TRUMA, irsend.capture.decode_type);
EXPECT_EQ(kTrumaBits, irsend.capture.bits);
EXPECT_EQ(0x49ffffffe6e081, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_EQ(
"f38000d50"
"m20200s1000"
"m1800s630"
"m600s630m1200s630m1200s630m1200s630m1200s630m1200s630m1200s630m600s630"
"m1200s630m1200s630m1200s630m1200s630m1200s630m600s630m600s630m600s630"
"m1200s630m600s630m600s630m1200s630m1200s630m600s630m600s630m600s630"
"m600s630m600s630m600s630m600s630m600s630m600s630m600s630m600s630"
"m600s630m600s630m600s630m600s630m600s630m600s630m600s630m600s630"
"m600s630m600s630m600s630m600s630m600s630m600s630m600s630m600s630"
"m600s630m1200s630m1200s630m600s630m1200s630m1200s630m600s630m1200s630"
"m600s100000",
irsend.outputStr());
}
TEST(TestUtils, Housekeeping) {
ASSERT_EQ("TRUMA", typeToString(decode_type_t::TRUMA));
ASSERT_EQ(decode_type_t::TRUMA, strToDecodeType("TRUMA"));
ASSERT_FALSE(hasACState(decode_type_t::TRUMA));
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::TRUMA));
ASSERT_EQ(kTrumaBits, IRsend::defaultBits(decode_type_t::TRUMA));
ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::TRUMA));
}
// Tests for IRTrumaAc class.
TEST(TestTrumaAcClass, Power) {
IRTrumaAc ac(kGpioUnused);
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(TestTrumaAcClass, toCommon) {
IRTrumaAc ac(kGpioUnused);
ac.setPower(true);
ac.setMode(kTrumaCool);
ac.setTemp(20);
ac.setFan(kTrumaFanHigh);
ac.setQuiet(false);
// Now test it.
ASSERT_EQ(decode_type_t::TRUMA, 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_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kHigh, ac.toCommon().fanspeed);
ASSERT_FALSE(ac.toCommon().quiet);
// Unsupported.
ASSERT_EQ(stdAc::swingv_t::kOff, ac.toCommon().swingv);
ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh);
ASSERT_FALSE(ac.toCommon().turbo);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().light);
ASSERT_FALSE(ac.toCommon().filter);
ASSERT_FALSE(ac.toCommon().clean);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().sleep);
ASSERT_EQ(-1, ac.toCommon().clock);
}
TEST(TestTrumaAcClass, HumanReadableOutput) {
IRTrumaAc ac(kGpioUnused);
ac.begin();
// Data from https://docs.google.com/spreadsheets/d/1k-RHu0vSIB6IweiTZSa3Rxy3Z_qPUtqwcqot8uXVO6I/edit#gid=0
const uint64_t on_25_auto = 0x52FFFFFFEFE081;
const uint64_t on_17_cool_med = 0x54FFFFFFE7EA81;
ac.setRaw(on_25_auto);
EXPECT_EQ("Power: On, Mode: 0 (Auto), Temp: 25C, Fan: 4 (High), Quiet: Off",
ac.toString());
ac.setRaw(on_17_cool_med);
EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 17C, Fan: 5 (Medium), Quiet: Off",
ac.toString());
ac.setTemp(25);
ac.setFan(kTrumaFanLow);
ac.setMode(kTrumaFan);
EXPECT_EQ("Power: On, Mode: 3 (Fan), Temp: 25C, Fan: 6 (Low), Quiet: Off",
ac.toString());
ac.off();
EXPECT_EQ("Power: Off, Temp: 25C, Fan: 6 (Low), Quiet: Off",
ac.toString());
}
TEST(TestTrumaAcClass, FanSpeed) {
IRTrumaAc ac(kGpioUnused);
ac.begin();
ac.on();
ac.setMode(kTrumaCool); // Cool allows all options.
ac.setFan(kTrumaFanLow);
EXPECT_EQ(kTrumaFanLow, ac.getFan());
ac.setFan(0);
EXPECT_EQ(kTrumaFanHigh, ac.getFan());
ac.setFan(255);
EXPECT_EQ(kTrumaFanHigh, ac.getFan());
ac.setFan(kTrumaFanMed);
EXPECT_EQ(kTrumaFanMed, ac.getFan());
ac.setFan(kTrumaFanHigh);
EXPECT_EQ(kTrumaFanHigh, ac.getFan());
ac.setFan(kTrumaFanQuiet);
EXPECT_EQ(kTrumaFanQuiet, ac.getFan());
ac.setMode(kTrumaAuto); // Quiet should not be available/an option now.
EXPECT_NE(kTrumaFanQuiet, ac.getFan());
ac.setFan(kTrumaFanQuiet);
EXPECT_NE(kTrumaFanQuiet, ac.getFan());
}
TEST(TestTrumaAcClass, OperatingMode) {
IRTrumaAc ac(kGpioUnused);
ac.begin();
ac.on(); // Power on state allows all modes.
ac.setMode(kTrumaAuto);
EXPECT_EQ(kTrumaAuto, ac.getMode());
ac.setMode(kTrumaCool);
EXPECT_EQ(kTrumaCool, ac.getMode());
ac.setMode(kTrumaFan);
EXPECT_EQ(kTrumaFan, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kTrumaAuto, ac.getMode());
ac.off(); // Off, only allows the fan mode.
EXPECT_EQ(kTrumaFan, ac.getMode());
ac.setMode(kTrumaCool);
EXPECT_EQ(kTrumaFan, ac.getMode());
}
TEST(TestTrumaAcClass, Temperature) {
IRTrumaAc ac(kGpioUnused);
ac.begin();
ac.setTemp(0);
EXPECT_EQ(kTrumaMinTemp, ac.getTemp());
ac.setTemp(255);
EXPECT_EQ(kTrumaMaxTemp, ac.getTemp());
ac.setTemp(kTrumaMinTemp);
EXPECT_EQ(kTrumaMinTemp, ac.getTemp());
ac.setTemp(kTrumaMaxTemp);
EXPECT_EQ(kTrumaMaxTemp, ac.getTemp());
ac.setTemp(kTrumaMinTemp - 1);
EXPECT_EQ(kTrumaMinTemp, ac.getTemp());
ac.setTemp(kTrumaMaxTemp + 1);
EXPECT_EQ(kTrumaMaxTemp, 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(TestTrumaAcClass, Checksums) {
IRTrumaAc ac(kGpioUnused);
ac.begin();
uint64_t valid = 0x52FFFFFFEFE081;
uint64_t invalid = 0x51FFFFFFEFE081;
EXPECT_EQ(0x52, ac.calcChecksum(valid));
EXPECT_EQ(0x52, ac.calcChecksum(invalid));
// Check we can call it without instantiating the object.
EXPECT_EQ(0x52, IRTrumaAc::calcChecksum(valid));
EXPECT_TRUE(IRTrumaAc::validChecksum(valid));
EXPECT_FALSE(IRTrumaAc::validChecksum(invalid));
ac.setRaw(invalid);
EXPECT_EQ(valid, ac.getRaw());
}
TEST(TestTrumaAcClass, KnownMessageConstuction) {
IRTrumaAc ac(kGpioUnused);
ac.begin();
const uint64_t on_17_cool_med = 0x54FFFFFFE7EA81;
ac.on();
ac.setMode(kTrumaCool);
ac.setFan(kTrumaFanMed);
ac.setTemp(17);
ac.setQuiet(false);
EXPECT_EQ(on_17_cool_med, ac.getRaw());
const uint64_t off_16_auto = 0x50FFFFFFE6E781; // 4DFFFFFFE6E481
ac.setMode(kTrumaAuto);
ac.setTemp(16);
ac.setFan(kTrumaFanHigh);
ac.off();
EXPECT_EQ(off_16_auto, ac.getRaw());
EXPECT_EQ("Power: Off, Temp: 16C, Fan: 4 (High), Quiet: Off", ac.toString());
}