397 lines
13 KiB
C++
397 lines
13 KiB
C++
// Copyright 2021 Tom Rosenback
|
|
|
|
#include "IRac.h"
|
|
#include "ir_Rhoss.h"
|
|
#include "IRrecv.h"
|
|
#include "IRrecv_test.h"
|
|
#include "IRsend.h"
|
|
#include "IRsend_test.h"
|
|
#include "IRutils.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
TEST(TestUtils, Housekeeping) {
|
|
ASSERT_EQ("RHOSS", typeToString(decode_type_t::RHOSS));
|
|
ASSERT_EQ(decode_type_t::RHOSS, strToDecodeType("RHOSS"));
|
|
ASSERT_TRUE(hasACState(decode_type_t::RHOSS));
|
|
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::RHOSS));
|
|
}
|
|
|
|
// Test sending typical data only.
|
|
TEST(TestSendRhoss, SendDataOnly) {
|
|
IRsendTest irsend(kGpioUnused);
|
|
irsend.begin();
|
|
|
|
uint8_t expectedState[kRhossStateLength] = {
|
|
0xAA, 0x05, 0x60, 0x00, 0x50, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x33 };
|
|
|
|
irsend.reset();
|
|
irsend.sendRhoss(expectedState);
|
|
|
|
EXPECT_EQ(
|
|
"f38000d50"
|
|
"m3042s4248"
|
|
"m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457m648s1545"
|
|
"m648s1545m648s457m648s1545m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s1545m648s1545m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s1545m648s457m648s1545m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s1545"
|
|
"m648s457m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s1545m648s1545m648s457m648s457m648s1545m648s1545m648s457m648s457"
|
|
"m648s457m648"
|
|
"s100000",
|
|
irsend.outputStr());
|
|
}
|
|
|
|
// Test send typical data with repeats
|
|
TEST(TestSendRhoss, SendWithRepeats) {
|
|
IRsendTest irsend(kGpioUnused);
|
|
irsend.begin();
|
|
|
|
irsend.reset();
|
|
|
|
uint8_t expectedState[kRhossStateLength] = {
|
|
0xAA, 0x05, 0x60, 0x00, 0x50, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x33 };
|
|
|
|
irsend.sendRhoss(expectedState, kRhossStateLength, 0); // 0 repeats.
|
|
EXPECT_EQ(
|
|
"f38000d50"
|
|
"m3042s4248"
|
|
"m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457m648s1545"
|
|
"m648s1545m648s457m648s1545m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s1545m648s1545m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s1545m648s457m648s1545m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s1545"
|
|
"m648s457m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s1545m648s1545m648s457m648s457m648s1545m648s1545m648s457m648s457"
|
|
"m648s457m648"
|
|
"s100000",
|
|
irsend.outputStr());
|
|
|
|
irsend.sendRhoss(expectedState, kRhossStateLength, 2); // 2 repeats.
|
|
EXPECT_EQ(
|
|
"f38000d50"
|
|
"m3042s4248"
|
|
"m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457m648s1545"
|
|
"m648s1545m648s457m648s1545m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s1545m648s1545m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s1545m648s457m648s1545m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s1545"
|
|
"m648s457m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s1545m648s1545m648s457m648s457m648s1545m648s1545m648s457m648s457"
|
|
"m648s457m648"
|
|
"s100000"
|
|
"m3042s4248"
|
|
"m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457m648s1545"
|
|
"m648s1545m648s457m648s1545m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s1545m648s1545m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s1545m648s457m648s1545m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s1545"
|
|
"m648s457m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s1545m648s1545m648s457m648s457m648s1545m648s1545m648s457m648s457"
|
|
"m648s457m648"
|
|
"s100000"
|
|
"m3042s4248"
|
|
"m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457m648s1545"
|
|
"m648s1545m648s457m648s1545m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s1545m648s1545m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s1545m648s457m648s1545m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s1545"
|
|
"m648s457m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
|
|
"m648s1545m648s1545m648s457m648s457m648s1545m648s1545m648s457m648s457"
|
|
"m648s457m648"
|
|
"s100000",
|
|
irsend.outputStr());
|
|
}
|
|
|
|
// Test send raw data
|
|
TEST(TestSendRhoss, RawData) {
|
|
IRsendTest irsend(kGpioUnused);
|
|
IRrecv irrecv(kGpioUnused);
|
|
irsend.begin();
|
|
irsend.reset();
|
|
|
|
// Power on, mode cool, temp 20, fan auto, swing off
|
|
const uint16_t rawData[197] = {
|
|
3044, 4248,
|
|
648, 458, 650, 1540, 646, 458, 650, 1538,
|
|
650, 458, 650, 1538, 650, 458, 650, 1540, // byte 0
|
|
648, 458, 650, 458, 650, 1540, 646, 484,
|
|
624, 456, 650, 456, 650, 456, 650, 456, // byte 1
|
|
650, 456, 650, 456, 650, 456, 650, 456,
|
|
650, 458, 650, 1540, 650, 1538, 650, 456, // byte 2
|
|
650, 456, 650, 456, 650, 456, 650, 458,
|
|
650, 456, 650, 456, 650, 456, 650, 458, // byte 3
|
|
650, 458, 650, 456, 650, 458, 650, 458,
|
|
650, 458, 650, 1538, 650, 458, 650, 458, // byte 4
|
|
650, 458, 648, 458, 674, 434, 648, 458,
|
|
672, 434, 648, 458, 650, 458, 648, 1540, // byte 5
|
|
672, 434, 650, 458, 672, 1518, 644, 488,
|
|
622, 1540, 644, 464, 672, 1516, 672, 434, // byte 6
|
|
672, 434, 672, 434, 650, 458, 648, 458,
|
|
672, 434, 674, 434, 672, 434, 650, 458, // byte 7
|
|
672, 434, 648, 458, 650, 458, 672, 434,
|
|
672, 436, 648, 458, 648, 456, 650, 458, // byte 8
|
|
650, 458, 650, 456, 674, 434, 650, 458,
|
|
650, 456, 650, 458, 674, 432, 650, 458, // byte 9
|
|
650, 456, 650, 456, 650, 458, 648, 458,
|
|
674, 432, 650, 456, 674, 434, 650, 458, // byte 10
|
|
650, 458, 650, 1538, 650, 458, 650, 458,
|
|
650, 456, 650, 458, 650, 456, 650, 458, // byte 11
|
|
650, 456,
|
|
650 }; // UNKNOWN 93E7BDB2
|
|
|
|
irsend.sendRaw(rawData, 197, 38);
|
|
irsend.makeDecodeResult();
|
|
|
|
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
|
ASSERT_EQ(RHOSS, irsend.capture.decode_type);
|
|
EXPECT_EQ(kRhossBits, irsend.capture.bits);
|
|
|
|
uint8_t expected[kRhossStateLength] = {
|
|
0xAA, 0x04, 0x60, 0x00, 0x20, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x02 };
|
|
EXPECT_STATE_EQ(expected, irsend.capture.state, kRhossBits);
|
|
|
|
EXPECT_EQ(
|
|
"Power: On, Mode: 2 (Cool), Temp: 20C, Fan: 0 (Auto), Swing(V): Off",
|
|
IRAcUtils::resultAcToString(&irsend.capture));
|
|
|
|
stdAc::state_t r, p;
|
|
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
|
|
}
|
|
|
|
// Test synthetic decode
|
|
TEST(TestDecodeRhoss, SyntheticSelfDecode) {
|
|
IRsendTest irsend(kGpioUnused);
|
|
IRrecv irrecv(0);
|
|
IRRhossAc ac(0);
|
|
|
|
uint8_t expectedState[kRhossStateLength] = {
|
|
0xAA, 0x05, 0x60, 0x00, 0x50, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x33 };
|
|
|
|
irsend.begin();
|
|
irsend.reset();
|
|
irsend.sendRhoss(expectedState);
|
|
irsend.makeDecodeResult();
|
|
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
|
EXPECT_EQ(RHOSS, irsend.capture.decode_type);
|
|
EXPECT_EQ(kRhossBits, irsend.capture.bits);
|
|
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
|
|
ac.setRaw(irsend.capture.state);
|
|
EXPECT_EQ(
|
|
"Power: On, Mode: 5 (Auto), Temp: 21C, Fan: 0 (Auto), Swing(V): Off",
|
|
ac.toString());
|
|
}
|
|
|
|
// Test strict decoding
|
|
TEST(TestDecodeRhoss, StrictDecode) {
|
|
IRsendTest irsend(kGpioUnused);
|
|
IRrecv irrecv(0);
|
|
IRRhossAc ac(0);
|
|
|
|
uint8_t expectedState[kRhossStateLength] = {
|
|
0xAA, 0x05, 0x60, 0x00, 0x50, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x33 };
|
|
|
|
irsend.begin();
|
|
irsend.reset();
|
|
irsend.sendRhoss(expectedState);
|
|
irsend.makeDecodeResult();
|
|
ASSERT_TRUE(
|
|
irrecv.decodeRhoss(&irsend.capture,
|
|
kStartOffset, kRhossBits, true));
|
|
EXPECT_EQ(RHOSS, irsend.capture.decode_type);
|
|
EXPECT_EQ(kRhossBits, irsend.capture.bits);
|
|
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
|
|
ac.setRaw(irsend.capture.state);
|
|
EXPECT_EQ(
|
|
"Power: On, Mode: 5 (Auto), Temp: 21C, Fan: 0 (Auto), Swing(V): Off",
|
|
ac.toString());
|
|
}
|
|
|
|
// Tests for IRRhossAc class.
|
|
|
|
TEST(TestRhossAcClass, Power) {
|
|
IRRhossAc 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(TestRhossAcClass, Temperature) {
|
|
IRRhossAc ac(0);
|
|
ac.begin();
|
|
|
|
ac.setTemp(0);
|
|
EXPECT_EQ(kRhossTempMin, ac.getTemp());
|
|
|
|
ac.setTemp(255);
|
|
EXPECT_EQ(kRhossTempMax, ac.getTemp());
|
|
|
|
ac.setTemp(kRhossTempMin);
|
|
EXPECT_EQ(kRhossTempMin, ac.getTemp());
|
|
|
|
ac.setTemp(kRhossTempMax);
|
|
EXPECT_EQ(kRhossTempMax, ac.getTemp());
|
|
|
|
ac.setTemp(kRhossTempMin - 1);
|
|
EXPECT_EQ(kRhossTempMin, ac.getTemp());
|
|
|
|
ac.setTemp(kRhossTempMax + 1);
|
|
EXPECT_EQ(kRhossTempMax, 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(29);
|
|
EXPECT_EQ(29, ac.getTemp());
|
|
}
|
|
|
|
|
|
TEST(TestRhossAcClass, OperatingMode) {
|
|
IRRhossAc ac(0);
|
|
ac.begin();
|
|
|
|
ac.setMode(kRhossModeAuto);
|
|
EXPECT_EQ(kRhossModeAuto, ac.getMode());
|
|
|
|
ac.setMode(kRhossModeCool);
|
|
EXPECT_EQ(kRhossModeCool, ac.getMode());
|
|
|
|
ac.setMode(kRhossModeHeat);
|
|
EXPECT_EQ(kRhossModeHeat, ac.getMode());
|
|
|
|
ac.setMode(kRhossModeDry);
|
|
EXPECT_EQ(kRhossModeDry, ac.getMode());
|
|
|
|
ac.setMode(kRhossModeFan);
|
|
EXPECT_EQ(kRhossModeFan, ac.getMode());
|
|
|
|
ac.setMode(kRhossModeAuto + 1);
|
|
EXPECT_EQ(kRhossDefaultMode, ac.getMode());
|
|
|
|
ac.setMode(255);
|
|
EXPECT_EQ(kRhossDefaultMode, ac.getMode());
|
|
}
|
|
|
|
TEST(TestRhossAcClass, FanSpeed) {
|
|
IRRhossAc ac(0);
|
|
ac.begin();
|
|
|
|
ac.setFan(0);
|
|
EXPECT_EQ(kRhossFanAuto, ac.getFan());
|
|
|
|
ac.setFan(255);
|
|
EXPECT_EQ(kRhossFanAuto, ac.getFan());
|
|
|
|
ac.setFan(kRhossFanMax);
|
|
EXPECT_EQ(kRhossFanMax, ac.getFan());
|
|
|
|
ac.setFan(kRhossFanMax + 1);
|
|
EXPECT_EQ(kRhossFanAuto, ac.getFan());
|
|
|
|
ac.setFan(kRhossFanMax - 1);
|
|
EXPECT_EQ(kRhossFanMax - 1, ac.getFan());
|
|
|
|
ac.setFan(1);
|
|
EXPECT_EQ(1, ac.getFan());
|
|
|
|
ac.setFan(1);
|
|
EXPECT_EQ(1, ac.getFan());
|
|
|
|
ac.setFan(3);
|
|
EXPECT_EQ(3, ac.getFan());
|
|
}
|
|
|
|
TEST(TestRhossAcClass, Swing) {
|
|
IRRhossAc ac(0);
|
|
ac.begin();
|
|
|
|
ac.setSwing(false);
|
|
EXPECT_FALSE(ac.getSwing());
|
|
|
|
ac.setSwing(true);
|
|
EXPECT_TRUE(ac.getSwing());
|
|
}
|
|
|
|
TEST(TestRhossAcClass, Checksums) {
|
|
uint8_t state[kRhossStateLength] = {
|
|
0xAA, 0x05, 0x60, 0x00, 0x50, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x33 };
|
|
|
|
ASSERT_EQ(0x33, IRRhossAc::calcChecksum(state));
|
|
EXPECT_TRUE(IRRhossAc::validChecksum(state));
|
|
// Change the array so the checksum is invalid.
|
|
state[0] ^= 0xFF;
|
|
EXPECT_FALSE(IRRhossAc::validChecksum(state));
|
|
// Restore the previous change, and change another byte.
|
|
state[0] ^= 0xFF;
|
|
state[4] ^= 0xFF;
|
|
EXPECT_FALSE(IRRhossAc::validChecksum(state));
|
|
state[4] ^= 0xFF;
|
|
EXPECT_TRUE(IRRhossAc::validChecksum(state));
|
|
|
|
// Additional known good states.
|
|
uint8_t knownGood1[kRhossStateLength] = {
|
|
0xAA, 0x06, 0x60, 0x00, 0x50, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x34 };
|
|
EXPECT_TRUE(IRRhossAc::validChecksum(knownGood1));
|
|
ASSERT_EQ(0x34, IRRhossAc::calcChecksum(knownGood1));
|
|
|
|
uint8_t knownGood2[kRhossStateLength] = {
|
|
0xAA, 0x07, 0x60, 0x00, 0x50, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x35 };
|
|
EXPECT_TRUE(IRRhossAc::validChecksum(knownGood2));
|
|
ASSERT_EQ(0x35, IRRhossAc::calcChecksum(knownGood2));
|
|
|
|
uint8_t knownGood3[kRhossStateLength] = {
|
|
0xAA, 0x07, 0x60, 0x00, 0x53, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x38 };
|
|
EXPECT_TRUE(IRRhossAc::validChecksum(knownGood3));
|
|
ASSERT_EQ(0x38, IRRhossAc::calcChecksum(knownGood3));
|
|
|
|
// Validate calculation of checksum,
|
|
// same as knownGood3 except for the checksum.
|
|
uint8_t knownBad[kRhossStateLength] = {
|
|
0xAA, 0x07, 0x60, 0x00, 0x53, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
|
EXPECT_FALSE(IRRhossAc::validChecksum(knownBad));
|
|
IRRhossAc ac(0);
|
|
ac.setRaw(knownBad);
|
|
EXPECT_STATE_EQ(knownGood3, ac.getRaw(), kRhossBits);
|
|
}
|