feat: 全量同步 254 个常用的 Arduino 扩展库文件

This commit is contained in:
yczpf2019
2026-01-24 16:05:38 +08:00
parent c665ba662b
commit 397b9a23a3
6878 changed files with 2732224 additions and 1 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
// Copyright 2017 David Conran
#ifndef TEST_IRRECV_TEST_H_
#define TEST_IRRECV_TEST_H_
#include <iostream>
#include <sstream>
#include <string>
#include "IRutils.h"
#define EXPECT_STATE_EQ(a, b, c) \
for (uint8_t i = 0; i < c / 8; ++i) { \
EXPECT_EQ(a[i], b[i]) << "Expected state " \
"differs at i = " \
<< uint64ToString(i); \
}
#endif // TEST_IRRECV_TEST_H_

View File

@@ -0,0 +1,865 @@
// Copyright 2017,2019 David Conran
#include "IRsend_test.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRutils.h"
#include "gtest/gtest.h"
// Tests sendData().
// Test sending zero bits.
TEST(TestSendData, SendZeroBits) {
IRsendTest irsend(4);
irsend.begin();
irsend.sendData(1, 2, 3, 4, 0b1, 0, true);
EXPECT_EQ("", irsend.outputStr());
}
// Test sending zero and one.
TEST(TestSendData, SendSingleBit) {
IRsendTest irsend(4);
irsend.begin();
irsend.sendData(1, 2, 3, 4, 0b1, 1, true);
EXPECT_EQ("d50m1s2", irsend.outputStr());
irsend.sendData(1, 2, 3, 4, 0b0, 1, true);
EXPECT_EQ("d50m3s4", irsend.outputStr());
}
// Test sending bit order.
TEST(TestSendData, TestingBitSendOrder) {
IRsendTest irsend(4);
irsend.begin();
irsend.sendData(1, 2, 3, 4, 0b10, 2, true);
EXPECT_EQ("d50m1s2m3s4", irsend.outputStr());
irsend.sendData(1, 2, 3, 4, 0b10, 2, false);
EXPECT_EQ("d50m3s4m1s2", irsend.outputStr());
irsend.sendData(1, 2, 3, 4, 0b0001, 4, false);
EXPECT_EQ("d50m1s2m3s4m3s4m3s4", irsend.outputStr());
}
// Test sending typical data.
TEST(TestSendData, SendTypicalData) {
IRsendTest irsend(4);
irsend.begin();
irsend.sendData(1, 2, 3, 4, 0b1010110011110000, 16, true);
EXPECT_EQ(
"d50m1s2m3s4m1s2m3s4m1s2m1s2m3s4m3s4m1s2m1s2m1s2m1s2m3s4m3s4m3s4m3s4",
irsend.outputStr());
irsend.sendData(1, 2, 3, 4, 0x1234567890ABCDEF, 64, true);
EXPECT_EQ(
"d50"
"m3s4m3s4m3s4m1s2m3s4m3s4m1s2m3s4m3s4m3s4m1s2m1s2m3s4m1s2m3s4m3s4"
"m3s4m1s2m3s4m1s2m3s4m1s2m1s2m3s4m3s4m1s2m1s2m1s2m1s2m3s4m3s4m3s4"
"m1s2m3s4m3s4m1s2m3s4m3s4m3s4m3s4m1s2m3s4m1s2m3s4m1s2m3s4m1s2m1s2"
"m1s2m1s2m3s4m3s4m1s2m1s2m3s4m1s2m1s2m1s2m1s2m3s4m1s2m1s2m1s2m1s2",
irsend.outputStr());
}
// Test sending more than expected bits.
TEST(TestSendData, SendOverLargeData) {
IRsendTest irsend(4);
irsend.begin();
irsend.sendData(1, 2, 3, 4, 0xFFFFFFFFFFFFFFFF, 70, true);
EXPECT_EQ(
"d50"
"m3s4m3s4m3s4m3s4m3s4m3s4"
"m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2"
"m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2"
"m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2"
"m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2",
irsend.outputStr());
}
// Test inverting the output.
TEST(TestIRSend, InvertedOutput) {
IRsendTest irsend(4, true);
irsend.begin();
irsend.sendData(1, 2, 3, 4, 0b1, 1, true);
EXPECT_EQ("d50s1m2", irsend.outputStr());
irsend.sendData(1, 2, 3, 4, 0b0, 1, true);
EXPECT_EQ("d50s3m4", irsend.outputStr());
}
// Test we correctly pick up frequency changes.
TEST(TestIRSend, DetectFreqChanges) {
IRsendTest irsend(0);
irsend.begin();
irsend.enableIROut(40); // 40kHz
irsend.sendData(1, 2, 3, 4, 0b1, 1, true);
irsend.enableIROut(38); // 40kHz
irsend.sendData(1, 2, 3, 4, 0b1, 1, true);
irsend.enableIROut(40); // 40kHz
irsend.sendData(1, 2, 3, 4, 0b1, 1, true);
irsend.enableIROut(38); // 40kHz
irsend.sendData(1, 2, 3, 4, 0b1, 1, true);
EXPECT_EQ(
"f40000d50"
"m1s2"
"f38000"
"m1s2"
"f40000"
"m1s2"
"f38000"
"m1s2",
irsend.outputStr());
irsend.reset();
irsend.enableIROut(40); // 40kHz
irsend.sendData(1, 2, 3, 4, 0b1, 1, true);
irsend.enableIROut(40); // 40kHz
irsend.sendData(1, 2, 3, 4, 0b1, 1, true);
irsend.enableIROut(38); // 40kHz
irsend.sendData(1, 2, 3, 4, 0b1, 1, true);
irsend.enableIROut(38); // 40kHz
irsend.sendData(1, 2, 3, 4, 0b1, 1, true);
EXPECT_EQ(
"f40000d50"
"m1s2m1s2"
"f38000m1s2m1s2",
irsend.outputStr());
}
// Test we correctly pick up duty cycle changes.
TEST(TestIRSend, DetectDutyChanges) {
IRsendTest irsend(0);
irsend.begin();
irsend.sendGeneric(1, 2, 3, 4, 5, 6, 7, 8, 0b1, 1, 38000, true, 0, 33);
EXPECT_EQ(
"f38000d33"
"m1s2m3s4m7s8",
irsend.outputStr());
irsend.reset();
irsend.sendGeneric(1, 2, 3, 4, 5, 6, 7, 8, 0b1, 1, 38000, true, 0, 50);
irsend.sendGeneric(1, 2, 3, 4, 5, 6, 7, 8, 0b1, 1, 38000, true, 0, 33);
irsend.sendGeneric(1, 2, 3, 4, 5, 6, 7, 8, 0b1, 1, 38000, true, 0, 25);
EXPECT_EQ(
"f38000d50"
"m1s2m3s4m7s8"
"d33"
"m1s2m3s4m7s8"
"d25"
"m1s2m3s4m7s8",
irsend.outputStr());
}
// Test we correctly pick up frequency AND duty changes.
TEST(TestIRSend, DetectFreqAndDutyChanges) {
IRsendTest irsend(0);
irsend.begin();
irsend.sendGeneric(1, 2, 3, 4, 5, 6, 7, 8, 0b1, 1, 38000, true, 0, 50);
irsend.sendGeneric(1, 2, 3, 4, 5, 6, 7, 8, 0b1, 1, 38000, true, 0, 33);
irsend.sendGeneric(1, 2, 3, 4, 5, 6, 7, 8, 0b1, 1, 40000, true, 0, 25);
EXPECT_EQ(
"f38000d50"
"m1s2m3s4m7s8"
"d33"
"m1s2m3s4m7s8"
"f40000d25"
"m1s2m3s4m7s8",
irsend.outputStr());
}
// Test typical use of sendRaw().
TEST(TestSendRaw, GeneralUse) {
IRsendTest irsend(4);
IRrecv irrecv(0);
irsend.begin();
// NEC C3E0E0E8 as measured in #204
uint16_t rawData[67] = {
8950, 4500, 550, 1650, 600, 1650, 550, 550, 600, 500, 600, 550,
550, 550, 600, 1650, 550, 1650, 600, 1650, 600, 1650, 550, 1700,
550, 550, 600, 550, 550, 550, 600, 500, 600, 550, 550, 1650,
600, 1650, 600, 1650, 550, 550, 600, 500, 600, 500, 600, 550,
550, 550, 600, 1650, 550, 1650, 600, 1650, 600, 500, 650, 1600,
600, 500, 600, 550, 550, 550, 600};
irsend.sendRaw(rawData, 67, 38);
EXPECT_EQ(
"f38000d50"
"m8950s4500"
"m550s1650m600s1650m550s550m600s500m600s550m550s550m600s1650m550s1650"
"m600s1650m600s1650m550s1700m550s550m600s550m550s550m600s500m600s550"
"m550s1650m600s1650m600s1650m550s550m600s500m600s500m600s550m550s550"
"m600s1650m550s1650m600s1650m600s500m650s1600m600s500m600s550m550s550"
"m600",
irsend.outputStr());
irsend.reset();
irsend.sendRaw(rawData, 67, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeNEC(&irsend.capture, kStartOffset, kNECBits, false));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(32, irsend.capture.bits);
EXPECT_EQ(0xC3E0E0E8, irsend.capture.value);
EXPECT_EQ(
"f38000d50"
"m8950s4500"
"m550s1650m600s1650m550s550m600s500m600s550m550s550m600s1650m550s1650"
"m600s1650m600s1650m550s1700m550s550m600s550m550s550m600s500m600s550"
"m550s1650m600s1650m600s1650m550s550m600s500m600s500m600s550m550s550"
"m600s1650m550s1650m600s1650m600s500m650s1600m600s500m600s550m550s550"
"m600",
irsend.outputStr());
}
// Incorrect handling of decodes from Raw. i.e. There is no gap recorded at
// the end of a command when using the interrupt code. sendRaw() best emulates
// this for unit testing purposes. sendGC() and sendXXX() will add the trailing
// gap. Users won't see this in normal use.
TEST(TestSendRaw, NoTrailingGap) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
uint16_t rawData[67] = {
9000, 4500, 650, 550, 650, 1650, 600, 550, 650, 550, 600, 1650,
650, 550, 600, 1650, 650, 1650, 650, 1650, 600, 550, 650, 1650,
650, 1650, 650, 550, 600, 1650, 650, 1650, 650, 550, 650, 550,
650, 1650, 650, 550, 650, 550, 650, 550, 600, 550, 650, 550,
650, 550, 650, 1650, 600, 550, 650, 1650, 650, 1650, 650, 1650,
650, 1650, 650, 1650, 650, 1650, 600};
irsend.sendRaw(rawData, 67, 38);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
}
TEST(TestLowLevelSend, MarkFrequencyModulationAt38kHz) {
IRsendLowLevelTest irsend(0);
irsend.begin();
irsend.reset();
irsend.enableIROut(38000, 50);
EXPECT_EQ(5, irsend.mark(100));
EXPECT_EQ(
"[On]10usecs[Off]11usecs[On]10usecs[Off]11usecs[On]10usecs[Off]11usecs"
"[On]10usecs[Off]11usecs[On]10usecs[Off]6usecs",
irsend.low_level_sequence);
irsend.reset();
irsend.enableIROut(38000, 33);
EXPECT_EQ(5, irsend.mark(100));
EXPECT_EQ(
"[On]6usecs[Off]15usecs[On]6usecs[Off]15usecs[On]6usecs[Off]15usecs"
"[On]6usecs[Off]15usecs[On]6usecs[Off]10usecs",
irsend.low_level_sequence);
irsend.reset();
irsend.enableIROut(38000, 100);
EXPECT_EQ(1, irsend.mark(1000));
EXPECT_EQ("[On]1000usecs[Off]", irsend.low_level_sequence);
}
TEST(TestLowLevelSend, MarkFrequencyModulationAt36_7kHz) {
IRsendLowLevelTest irsend(0);
irsend.begin();
irsend.reset();
irsend.enableIROut(36700, 50);
EXPECT_EQ(5, irsend.mark(100));
EXPECT_EQ(
"[On]11usecs[Off]11usecs[On]11usecs[Off]11usecs[On]11usecs[Off]11usecs"
"[On]11usecs[Off]11usecs[On]11usecs[Off]1usecs",
irsend.low_level_sequence);
irsend.reset();
irsend.enableIROut(36700, 33);
EXPECT_EQ(5, irsend.mark(100));
EXPECT_EQ(
"[On]7usecs[Off]15usecs[On]7usecs[Off]15usecs[On]7usecs[Off]15usecs"
"[On]7usecs[Off]15usecs[On]7usecs[Off]5usecs",
irsend.low_level_sequence);
irsend.reset();
irsend.enableIROut(36700, 100);
EXPECT_EQ(1, irsend.mark(1000));
EXPECT_EQ("[On]1000usecs[Off]", irsend.low_level_sequence);
}
TEST(TestLowLevelSend, MarkFrequencyModulationAt40kHz) {
IRsendLowLevelTest irsend(0);
irsend.begin();
irsend.reset();
irsend.enableIROut(40000, 50);
EXPECT_EQ(5, irsend.mark(100));
EXPECT_EQ(
"[On]10usecs[Off]10usecs[On]10usecs[Off]10usecs[On]10usecs[Off]10usecs"
"[On]10usecs[Off]10usecs[On]10usecs[Off]10usecs",
irsend.low_level_sequence);
irsend.reset();
irsend.enableIROut(40000, 33);
EXPECT_EQ(5, irsend.mark(100));
EXPECT_EQ(
"[On]6usecs[Off]14usecs[On]6usecs[Off]14usecs[On]6usecs[Off]14usecs"
"[On]6usecs[Off]14usecs[On]6usecs[Off]14usecs",
irsend.low_level_sequence);
irsend.reset();
irsend.enableIROut(40000, 100);
EXPECT_EQ(1, irsend.mark(1000));
EXPECT_EQ("[On]1000usecs[Off]", irsend.low_level_sequence);
}
TEST(TestLowLevelSend, MarkNoModulation) {
IRsendLowLevelTest irsend(0, false, false);
irsend.begin();
irsend.reset();
irsend.enableIROut(38000, 50);
EXPECT_EQ(1, irsend.mark(1000));
EXPECT_EQ("[On]1000usecs[Off]", irsend.low_level_sequence);
irsend.reset();
irsend.enableIROut(36700, 25);
EXPECT_EQ(1, irsend.mark(1000));
EXPECT_EQ("[On]1000usecs[Off]", irsend.low_level_sequence);
irsend.reset();
irsend.enableIROut(40000, 75);
EXPECT_EQ(1, irsend.mark(1000));
EXPECT_EQ("[On]1000usecs[Off]", irsend.low_level_sequence);
}
TEST(TestLowLevelSend, SpaceFrequencyModulation) {
IRsendLowLevelTest irsend(0);
irsend.reset();
irsend.enableIROut(38000);
irsend.space(1000);
EXPECT_EQ("[Off]1000usecs", irsend.low_level_sequence);
irsend.reset();
irsend.enableIROut(40000, 75);
irsend.space(1000);
EXPECT_EQ("[Off]1000usecs", irsend.low_level_sequence);
irsend.reset();
irsend.enableIROut(38000, 100);
irsend.space(1000);
EXPECT_EQ("[Off]1000usecs", irsend.low_level_sequence);
irsend.reset();
irsend.enableIROut(38000, 33);
irsend.space(1000);
EXPECT_EQ("[Off]1000usecs", irsend.low_level_sequence);
}
TEST(TestLowLevelSend, SpaceNoModulation) {
IRsendLowLevelTest irsend(0, false, false);
irsend.begin();
irsend.reset();
irsend.enableIROut(38000, 50);
irsend.space(1000);
EXPECT_EQ("[Off]1000usecs", irsend.low_level_sequence);
irsend.reset();
irsend.enableIROut(36700, 25);
irsend.space(1000);
EXPECT_EQ("[Off]1000usecs", irsend.low_level_sequence);
irsend.reset();
irsend.enableIROut(40000, 75);
irsend.space(1000);
EXPECT_EQ("[Off]1000usecs", irsend.low_level_sequence);
}
// Test expected to work/produce a message for simple irsend:send()
TEST(TestSend, GenericSimpleSendMethod) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
ASSERT_TRUE(irsend.send(AIWA_RC_T501, 0x1234, kAiwaRcT501Bits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(AIWA_RC_T501, irsend.capture.decode_type);
EXPECT_EQ(kAiwaRcT501Bits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(CARRIER_AC, 0x1234, kCarrierAcBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(CARRIER_AC, irsend.capture.decode_type);
EXPECT_EQ(kCarrierAcBits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(COOLIX, 0x1234, kCoolixBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(COOLIX, irsend.capture.decode_type);
EXPECT_EQ(kCoolixBits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(DENON, 0x1234, kDenonBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(DENON, irsend.capture.decode_type);
EXPECT_EQ(kDenonBits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(DISH, 0x1234, kDishBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(DISH, irsend.capture.decode_type);
EXPECT_EQ(kDishBits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(GICABLE, 0x1234, kGicableBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(GICABLE, irsend.capture.decode_type);
EXPECT_EQ(kGicableBits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(GREE, 0x0009205000200050, kGreeBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(GREE, irsend.capture.decode_type);
EXPECT_EQ(kGreeBits, irsend.capture.bits);
// No simple value test for gree as it decodes to an Array.
irsend.reset();
ASSERT_TRUE(irsend.send(JVC, 0x1234, kJvcBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(JVC, irsend.capture.decode_type);
EXPECT_EQ(kJvcBits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(LASERTAG, 0x123, kLasertagBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x123, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(LG, 0x700992, kLgBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LG, irsend.capture.decode_type);
EXPECT_EQ(kLgBits, irsend.capture.bits);
EXPECT_EQ(0x700992, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(LG, 0x700992, kLg32Bits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LG, irsend.capture.decode_type);
EXPECT_EQ(kLg32Bits, irsend.capture.bits);
EXPECT_EQ(0x700992, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(LG2, 0x880094D, kLgBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LG2, irsend.capture.decode_type);
EXPECT_EQ(kLgBits, irsend.capture.bits);
EXPECT_EQ(0x880094D, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(LUTRON, 0x1234, kLutronBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LUTRON, irsend.capture.decode_type);
EXPECT_EQ(kLutronBits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(MAGIQUEST, 0x560F40020455, kMagiquestBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(MAGIQUEST, irsend.capture.decode_type);
EXPECT_EQ(kMagiquestBits, irsend.capture.bits);
EXPECT_EQ(0x560F40020455, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(MIDEA, 0xA18263FFFF6E, kMideaBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(MIDEA, irsend.capture.decode_type);
EXPECT_EQ(kMideaBits, irsend.capture.bits);
EXPECT_EQ(0xA18263FFFF6E, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(MITSUBISHI, 0x1234, kMitsubishiBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(MITSUBISHI, irsend.capture.decode_type);
EXPECT_EQ(kMitsubishiBits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(MITSUBISHI2, 0x1234, kMitsubishiBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(MITSUBISHI2, irsend.capture.decode_type);
EXPECT_EQ(kMitsubishiBits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(NIKAI, 0x1234, kNikaiBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(NIKAI, irsend.capture.decode_type);
EXPECT_EQ(kNikaiBits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(NEC, 0x4BB640BF, kNECBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0x4BB640BF, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(NEC_LIKE, 0x12345678, kNECBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(NEC_LIKE, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0x12345678, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(PANASONIC, 0x40040190ED7C, kPanasonicBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(kPanasonicBits, irsend.capture.bits);
EXPECT_EQ(0x40040190ED7C, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(PIONEER, 0x659A05FAF50AC53A, kPioneerBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(PIONEER, irsend.capture.decode_type);
EXPECT_EQ(kPioneerBits, irsend.capture.bits);
EXPECT_EQ(0x659A05FAF50AC53A, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(RC5, 0x175, kRC5Bits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(RC5, irsend.capture.decode_type);
EXPECT_EQ(kRC5Bits, irsend.capture.bits);
EXPECT_EQ(0x175, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(RC6, 0xC800F740C, kRC6_36Bits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(RC6, irsend.capture.decode_type);
EXPECT_EQ(kRC6_36Bits, irsend.capture.bits);
EXPECT_EQ(0xC800F740C, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(RCMM, 0x1234, kRCMMBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(RCMM, irsend.capture.decode_type);
EXPECT_EQ(kRCMMBits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(SAMSUNG, 0xE0E09966, kSamsungBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SAMSUNG, irsend.capture.decode_type);
EXPECT_EQ(kSamsungBits, irsend.capture.bits);
EXPECT_EQ(0xE0E09966, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(SAMSUNG36, 0x1234, kSamsung36Bits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SAMSUNG36, irsend.capture.decode_type);
EXPECT_EQ(kSamsung36Bits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(SANYO_LC7461, 0x2468DCB56A9, kSanyoLC7461Bits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SANYO_LC7461, irsend.capture.decode_type);
EXPECT_EQ(kSanyoLC7461Bits, irsend.capture.bits);
EXPECT_EQ(0x2468DCB56A9, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(SHARP, 0x7266, kSharpBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SHARP, irsend.capture.decode_type);
EXPECT_EQ(kSharpBits, irsend.capture.bits);
EXPECT_EQ(0x7266, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(SHERWOOD, 0x4BB640BF, kSherwoodBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kSherwoodBits, irsend.capture.bits);
EXPECT_EQ(0x4BB640BF, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(SONY, 0x1234, kSony20Bits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(kSony20Bits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(TECO, 0x1234, kTecoBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(TECO, irsend.capture.decode_type);
EXPECT_EQ(kTecoBits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(VESTEL_AC, 0xF4410001FF1201, kVestelAcBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(VESTEL_AC, irsend.capture.decode_type);
EXPECT_EQ(kVestelAcBits, irsend.capture.bits);
EXPECT_EQ(0xF4410001FF1201, irsend.capture.value);
irsend.reset();
ASSERT_TRUE(irsend.send(WHYNTER, 0x1234, kWhynterBits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(WHYNTER, irsend.capture.decode_type);
EXPECT_EQ(kWhynterBits, irsend.capture.bits);
EXPECT_EQ(0x1234, irsend.capture.value);
}
// Test some expected types to NOT work/produce a message via irsend:send()
TEST(TestSend, GenericSimpleSendMethodFailure) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Check nothing is sent for unexpected protocols
irsend.reset();
ASSERT_FALSE(irsend.send(KELVINATOR, 0x1234, kKelvinatorBits));
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decode(&irsend.capture));
// For every A/C protocol which decodes to having a state[].
for (int i = 0; i <= kLastDecodeType; i++) {
if (hasACState((decode_type_t)i) && i != GREE) { // Gree is an exception.
// Check it fails.
ASSERT_FALSE(irsend.send((decode_type_t)i, (uint64_t)0, 0));
}
}
// Test some other special cases.
ASSERT_FALSE(irsend.send(UNKNOWN, (uint64_t)0, 0));
ASSERT_FALSE(irsend.send(UNUSED, (uint64_t)0, 0));
ASSERT_FALSE(irsend.send(RAW, (uint64_t)0, 0));
ASSERT_FALSE(irsend.send(PRONTO, (uint64_t)0, 0));
ASSERT_FALSE(irsend.send(GLOBALCACHE, (uint64_t)0, 0));
}
// Test expected to work/produce a message for complex irsend:send()
TEST(TestSend, GenericComplexSendMethod) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
uint8_t kelvinator[kKelvinatorStateLength] = {
0x19, 0x0B, 0x80, 0x50, 0x00, 0x00, 0x00, 0xE0,
0x19, 0x0B, 0x80, 0x70, 0x00, 0x00, 0x10, 0xF0};
ASSERT_TRUE(irsend.send(KELVINATOR, kelvinator, kKelvinatorStateLength));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(KELVINATOR, irsend.capture.decode_type);
EXPECT_EQ(kKelvinatorStateLength * 8, irsend.capture.bits);
EXPECT_STATE_EQ(kelvinator, irsend.capture.state, irsend.capture.bits / 8);
irsend.reset();
uint8_t panasonic[kPanasonicAcStateLength] = {
0x02, 0x20, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x06, 0x02,
0x20, 0xE0, 0x04, 0x00, 0x4E, 0x2E, 0x80, 0xAF, 0x00,
0x00, 0x0E, 0xE0, 0x11, 0x00, 0x01, 0x00, 0x06, 0xB7};
ASSERT_TRUE(irsend.send(PANASONIC_AC, panasonic, kPanasonicAcStateLength));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(PANASONIC_AC, irsend.capture.decode_type);
EXPECT_EQ(kPanasonicAcStateLength * 8, irsend.capture.bits);
EXPECT_STATE_EQ(panasonic, irsend.capture.state, irsend.capture.bits / 8);
}
// Test some expected types to NOT work/produce a complex message via
// irsend:send()
TEST(TestSend, GenericComplexSendMethodFailure) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Check nothing is sent for unexpected protocols
uint8_t state[kStateSizeMax] = {};
irsend.reset();
ASSERT_FALSE(irsend.send(NEC, state, kNECBits));
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decode(&irsend.capture));
// For every A/C protocol which DOESN'T decode to having a state[].
for (int i = -1; i <= kLastDecodeType; i++) {
if (!hasACState((decode_type_t)i))
// Check it fails.
ASSERT_FALSE(irsend.send((decode_type_t)i, state, 0));
else // Or if it is okay.
ASSERT_TRUE(irsend.send((decode_type_t)i, state, 0));
}
}
TEST(TestSend, GenericSendExistsForEveryRealProtocol) {
IRsendTest irsend(0);
irsend.begin();
uint8_t state[kStateSizeMax] = {};
uint64_t value = 0;
for (int i = 1; i <= kLastDecodeType; i++) {
switch (i) {
// Protocols that don't have a generic send equiv.
case PRONTO:
case RAW:
case GLOBALCACHE:
// Protocols that are disabled because they don't work.
case SANYO:
break;
default:
EXPECT_TRUE(irsend.send((decode_type_t)i, state, 0) ||
irsend.send((decode_type_t)i, value, 0)) <<
"Protocol " << typeToString((decode_type_t)i) << "(" << i <<
") doesn't have a generic send option for it.";
}
}
}
TEST(TestSend, defaultBits) {
for (int i = 1; i <= kLastDecodeType; i++) {
switch (i) {
// Protocols that don't have have a default bit size.
case PRONTO:
case RAW:
case GLOBALCACHE:
case SANYO: // Not implemented / disabled.
// Deliberate no default size.
case FUJITSU_AC:
case MWM:
EXPECT_EQ(IRsend::defaultBits((decode_type_t)i), 0) <<
"Protocol " << typeToString((decode_type_t)i) << "(" << i <<
") doesn't have a correct value for it.";
break;
default:
EXPECT_GT(IRsend::defaultBits((decode_type_t)i), 0) <<
"Protocol " << typeToString((decode_type_t)i) << "(" << i <<
") doesn't have a correct value for it.";
}
}
}
// Tests sendManchester().
// Test sending zero bits.
TEST(TestSendManchester, SendZeroBits) {
IRsendTest irsend(0);
irsend.begin();
irsend.sendManchester(0, 0, 1, 0, 0, 0b1, 0);
EXPECT_EQ("", irsend.outputStr());
irsend.sendManchester(1, 2, 100, 3, 4, 0b1, 0);
EXPECT_EQ("f38000d50m1s2m3s4", irsend.outputStr());
}
// Test sending zero and one.
TEST(TestSendManchester, SendSingleBit) {
IRsendTest irsend(0);
irsend.begin();
irsend.sendManchester(1000, 2000, 100, 3000, 4000, 0b0, 1);
EXPECT_EQ("f38000d50m1000s2100m3100s4000", irsend.outputStr());
irsend.sendManchester(1000, 2000, 100, 3000, 4000, 0b0, 1, 38, true,
kNoRepeat, kDutyDefault, false);
EXPECT_EQ("f38000d50m1000s2000m100s100m3000s4000",
irsend.outputStr());
}
// Test sending bit order.
TEST(TestSendManchester, TestingBitSendOrder) {
IRsendTest irsend(0);
irsend.begin();
irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b10, 2);
EXPECT_EQ("f38000d50m1000s2000m100s200m3100", irsend.outputStr());
irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b10, 2, 38, false);
EXPECT_EQ("f38000d50m1000s2100m200s100m3000", irsend.outputStr());
irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b0001, 4, 38, true);
EXPECT_EQ("f38000d50m1000s2100m100s100m100s100m200s100m3000",
irsend.outputStr());
irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b0001, 4, 38, false);
EXPECT_EQ("f38000d50m1000s2000m100s200m100s100m100s100m3100",
irsend.outputStr());
}
// Test sending typical data.
TEST(TestSendManchester, SendTypicalData) {
IRsendTest irsend(0);
irsend.begin();
// Example from https://en.wikipedia.org/wiki/Manchester_code diagram
irsend.sendManchester(0, 0, 100, 0, 0, 0b10100111001, 11, 38, true);
EXPECT_EQ(
"f38000d50"
"m100s200m200s200m100s100m200s100m100s100m100s200m100s100m200s100",
irsend.outputStr());
irsend.sendManchester(100, 200, 1, 300, 0, 0x1234567890ABCDEF, 64, 38, true);
EXPECT_EQ(
"f38000d50"
"m100s201"
"m1s1m1s1m2s2m1s1m2s2m1s1m1s1m2s1m1s2m2s2m1s1m1s1m2s2m2s2m2s1m1s2m1s1m2s1"
"m1s1m1s1m1s2m1s1m1s1m2s2m1s1m2s2m1s1m1s1m1s1m2s2m2s2m2s2m2s1m1s1m1s1m1s2"
"m1s1m2s1m1s2m2s1m1s1m1s1m1s2m2s1m1s1m1s1m1s1"
"m300",
irsend.outputStr());
}
// Test sending more than expected bits.
TEST(TestSendManchester, SendOverLargeData) {
IRsendTest irsend(0);
irsend.begin();
irsend.sendManchester(100, 200, 1, 300, 0, 0xFFFFFFFFFFFFFFFF, 70, 38, true);
EXPECT_EQ(
"f38000d50"
"m100s201"
"m1s1m1s1m1s1m1s1m1s1m2s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1"
"m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1"
"m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1"
"m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1"
"m300",
irsend.outputStr());
}

View File

@@ -0,0 +1,155 @@
// Copyright 2017 David Conran
#ifndef TEST_IRSEND_TEST_H_
#define TEST_IRSEND_TEST_H_
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include <iostream>
#include <sstream>
#include <string>
#include "IRrecv.h"
#include "IRsend.h"
#include "IRtimer.h"
#define OUTPUT_BUF 10000U
#define RAW_BUF 10000U
#ifdef UNIT_TEST
// Used to help simulate elapsed time in unit tests.
extern uint32_t _IRtimer_unittest_now;
#endif // UNIT_TEST
class IRsendTest : public IRsend {
public:
uint32_t output[OUTPUT_BUF];
uint32_t freq[OUTPUT_BUF];
uint8_t duty[OUTPUT_BUF];
uint16_t last;
uint16_t rawbuf[RAW_BUF];
decode_results capture;
explicit IRsendTest(uint16_t x, bool i = false, bool j = true)
: IRsend(x, i, j) {
reset();
}
void reset() {
last = 0;
for (uint16_t i = 0; i < OUTPUT_BUF; i++) output[i] = 0;
for (uint16_t i = 0; i < RAW_BUF; i++) rawbuf[i] = 0;
}
std::string outputStr() {
std::stringstream result;
uint8_t lastduty = UINT8_MAX; // An impossible duty cycle value.
uint32_t lastfreq = 0; // An impossible frequency value.
if (last == 0 && output[0] == 0) return "";
for (uint16_t i = 0; i <= last; i++) {
// Display the frequency only if it changes.
if (freq[i] != lastfreq) {
result << "f";
result << freq[i];
lastfreq = freq[i];
}
// Display the duty cycle only if it changes.
if (duty[i] != lastduty) {
result << "d";
result << static_cast<uint16_t>(duty[i]);
lastduty = duty[i];
}
if ((i & 1) != outputOff) // Odd XOR outputOff
result << "s";
else
result << "m";
result << output[i];
}
reset();
return result.str();
}
void makeDecodeResult(uint16_t offset = 0) {
capture.decode_type = UNKNOWN;
capture.bits = 0;
capture.rawlen = last + 2 - offset;
capture.overflow = (last - offset >= (int16_t)RAW_BUF);
capture.repeat = false;
capture.address = 0;
capture.command = 0;
capture.value = 0;
capture.rawbuf = rawbuf;
for (uint16_t i = 0; (i < RAW_BUF - 1) && (offset < OUTPUT_BUF);
i++, offset++)
if (output[offset] / kRawTick > UINT16_MAX)
rawbuf[i + 1] = UINT16_MAX;
else
rawbuf[i + 1] = output[offset] / kRawTick;
}
void dumpRawResult() {
std::cout << std::dec;
if (capture.rawlen == 0) return;
std::cout << "uint16_t rawbuf[" << capture.rawlen - 1 << "] = {";
for (uint16_t i = 1; i < capture.rawlen; i++) {
if (i % 8 == 1) std::cout << std::endl << " ";
std::cout << (capture.rawbuf[i] * kRawTick);
// std::cout << "(" << capture.rawbuf[i] << ")";
if (i < capture.rawlen - 1) std::cout << ", ";
}
std::cout << "};" << std::endl;
}
void addGap(uint32_t usecs) { space(usecs); }
uint16_t mark(uint16_t usec) {
IRtimer::add(usec);
if (last >= OUTPUT_BUF) return 0;
if (last & 1) // Is odd? (i.e. last call was a space())
output[++last] = usec;
else
output[last] += usec;
duty[last] = _dutycycle;
freq[last] = _freq_unittest;
return 0;
}
void space(uint32_t time) {
IRtimer::add(time);
if (last >= OUTPUT_BUF) return;
if (last & 1) { // Is odd? (i.e. last call was a space())
output[last] += time;
} else {
output[++last] = time;
}
duty[last] = _dutycycle;
freq[last] = _freq_unittest;
}
};
#ifdef UNIT_TEST
class IRsendLowLevelTest : public IRsend {
public:
std::string low_level_sequence;
explicit IRsendLowLevelTest(uint16_t x, bool i = false, bool j = true)
: IRsend(x, i, j) {
reset();
}
void reset() { low_level_sequence = ""; }
protected:
void _delayMicroseconds(uint32_t usec) {
_IRtimer_unittest_now += usec;
std::ostringstream Convert;
Convert << usec;
low_level_sequence += Convert.str() + "usecs";
}
void ledOff() { low_level_sequence += "[Off]"; }
void ledOn() { low_level_sequence += "[On]"; }
};
#endif // UNIT_TEST
#endif // TEST_IRSEND_TEST_H_

View File

@@ -0,0 +1,746 @@
// Copyright 2017-2019 David Conran
#include "IRutils.h"
#include <stdint.h>
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests reverseBits().
// Tests reverseBits for typical use.
TEST(ReverseBitsTest, TypicalUse) {
EXPECT_EQ(0xF, reverseBits(0xF0, 8));
EXPECT_EQ(0xFFFF, reverseBits(0xFFFF0000, 32));
EXPECT_EQ(0x555500005555FFFF, reverseBits(0xFFFFAAAA0000AAAA, 64));
EXPECT_EQ(0, reverseBits(0, 64));
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, reverseBits(0xFFFFFFFFFFFFFFFF, 64));
}
// Tests reverseBits for bit size values <= 1
TEST(ReverseBitsTest, LessThanTwoBitsReversed) {
EXPECT_EQ(0x12345678, reverseBits(0x12345678, 1));
EXPECT_EQ(1234, reverseBits(1234, 0));
}
// Tests reverseBits for bit size larger than a uint64_t.
TEST(ReverseBitsTest, LargerThan64BitsReversed) {
EXPECT_EQ(0, reverseBits(0, 65));
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, reverseBits(0xFFFFFFFFFFFFFFFF, 100));
EXPECT_EQ(0x555500005555FFFF, reverseBits(0xFFFFAAAA0000AAAA, 3000));
}
// Tests reverseBits for bit sizes less than all the data stored.
TEST(ReverseBitsTest, LessBitsReversedThanInputHasSet) {
EXPECT_EQ(0xF8, reverseBits(0xF1, 4));
EXPECT_EQ(0xF5, reverseBits(0xFA, 4));
EXPECT_EQ(0x12345678FFFF0000, reverseBits(0x123456780000FFFF, 32));
}
// Tests for uint64ToString()
TEST(TestUint64ToString, TrivialCases) {
EXPECT_EQ("0", uint64ToString(0)); // Default base (10)
EXPECT_EQ("0", uint64ToString(0, 2)); // Base-2
EXPECT_EQ("0", uint64ToString(0, 8)); // Base-8
EXPECT_EQ("0", uint64ToString(0, 10)); // Base-10
EXPECT_EQ("0", uint64ToString(0, 16)); // Base-16
EXPECT_EQ("1", uint64ToString(1, 2)); // Base-2
EXPECT_EQ("2", uint64ToString(2, 8)); // Base-8
EXPECT_EQ("3", uint64ToString(3, 10)); // Base-10
EXPECT_EQ("4", uint64ToString(4, 16)); // Base-16
}
TEST(TestUint64ToString, NormalUse) {
EXPECT_EQ("12345", uint64ToString(12345));
EXPECT_EQ("100", uint64ToString(4, 2));
EXPECT_EQ("3039", uint64ToString(12345, 16));
EXPECT_EQ("123456", uint64ToString(123456));
EXPECT_EQ("1E240", uint64ToString(123456, 16));
EXPECT_EQ("FEEDDEADBEEF", uint64ToString(0xfeeddeadbeef, 16));
}
TEST(TestUint64ToString, Max64Bit) {
EXPECT_EQ("18446744073709551615", uint64ToString(UINT64_MAX)); // Default
EXPECT_EQ("1111111111111111111111111111111111111111111111111111111111111111",
uint64ToString(UINT64_MAX, 2)); // Base-2
EXPECT_EQ("1777777777777777777777", uint64ToString(UINT64_MAX, 8)); // Base-8
EXPECT_EQ("18446744073709551615", uint64ToString(UINT64_MAX, 10)); // Base-10
EXPECT_EQ("FFFFFFFFFFFFFFFF", uint64ToString(UINT64_MAX, 16)); // Base-16
}
TEST(TestUint64ToString, Max32Bit) {
EXPECT_EQ("4294967295", uint64ToString(UINT32_MAX)); // Default
EXPECT_EQ("37777777777", uint64ToString(UINT32_MAX, 8)); // Base-8
EXPECT_EQ("4294967295", uint64ToString(UINT32_MAX, 10)); // Base-10
EXPECT_EQ("FFFFFFFF", uint64ToString(UINT32_MAX, 16)); // Base-16
}
TEST(TestUint64ToString, InterestingCases) {
// Previous hacky-code didn't handle leading zeros in the lower 32 bits.
EXPECT_EQ("100000000", uint64ToString(0x100000000, 16));
EXPECT_EQ("100000001", uint64ToString(0x100000001, 16));
}
TEST(TestUint64ToString, SillyBases) {
// If we are given a silly base, we should defer to Base-10.
EXPECT_EQ("12345", uint64ToString(12345, 0)); // Super silly, makes no sense.
EXPECT_EQ("12345", uint64ToString(12345, 1)); // We don't do unary.
EXPECT_EQ("12345", uint64ToString(12345, 100)); // We can't print base-100.
EXPECT_EQ("12345", uint64ToString(12345, 37)); // Base-37 is one to far.
EXPECT_EQ("9IX", uint64ToString(12345, 36)); // But we *can* do base-36.
}
TEST(TestGetCorrectedRawLength, NoLargeValues) {
IRsendTest irsend(0);
IRrecv irrecv(1);
uint16_t test_data[7] = {1, 2, 3, 4, 5, 6, 7};
irsend.begin();
irsend.reset();
irsend.sendRaw(test_data, 7, 38000);
irsend.makeDecodeResult();
irrecv.decode(&irsend.capture);
EXPECT_EQ(7, getCorrectedRawLength(&irsend.capture));
}
TEST(TestGetCorrectedRawLength, WithLargeValues) {
IRsendTest irsend(0);
IRrecv irrecv(1);
uint16_t test_data[7] = {10, 20, 30, 40, 50, 60, 70};
irsend.begin();
irsend.reset();
irsend.sendRaw(test_data, 7, 38000);
irsend.makeDecodeResult();
irrecv.decode(&irsend.capture);
irsend.capture.rawbuf[3] = 60000;
ASSERT_EQ(2, kRawTick); // The following values rely on kRawTick being 2.
EXPECT_EQ(7 + 2, getCorrectedRawLength(&irsend.capture));
irsend.capture.rawbuf[4] = UINT16_MAX - 1;
EXPECT_EQ(7 + 2 * 2, getCorrectedRawLength(&irsend.capture));
irsend.capture.rawbuf[4] = UINT16_MAX;
EXPECT_EQ(7 + 2 * 2, getCorrectedRawLength(&irsend.capture));
}
TEST(TestResultToSourceCode, SimpleTests) {
IRsendTest irsend(0);
IRrecv irrecv(1);
uint16_t test_data[7] = {10, 20, 30, 40, 50, 60, 70};
irsend.begin();
irsend.reset();
irsend.sendRaw(test_data, 7, 38000);
irsend.makeDecodeResult();
irrecv.decode(&irsend.capture);
EXPECT_EQ(
"uint16_t rawData[7] = {10, 20, 30, 40, 50, 60, 70};"
" // UNKNOWN A5E5F35D\n",
resultToSourceCode(&irsend.capture));
// Stick in some large values.
irsend.capture.rawbuf[3] = 60000;
EXPECT_EQ(
"uint16_t rawData[9] = {10, 20, 65535, 0, 54465, 40,"
" 50, 60, 70}; // UNKNOWN A5E5F35D\n",
resultToSourceCode(&irsend.capture));
irsend.capture.rawbuf[5] = UINT16_MAX;
EXPECT_EQ(
"uint16_t rawData[11] = {10, 20, 65535, 0, 54465, 40,"
" 65535, 0, 65535, 60, 70}; // UNKNOWN A5E5F35D\n",
resultToSourceCode(&irsend.capture));
// Reset and put the large value in a space location.
irsend.reset();
irsend.sendRaw(test_data, 7, 38000);
irsend.makeDecodeResult();
irrecv.decode(&irsend.capture);
irsend.capture.rawbuf[4] = UINT16_MAX - 1;
EXPECT_EQ(
"uint16_t rawData[9] = {10, 20, 30, 65535, 0, 65533,"
" 50, 60, 70}; // UNKNOWN A5E5F35D\n",
resultToSourceCode(&irsend.capture));
}
TEST(TestResultToSourceCode, SimpleProtocols) {
IRsendTest irsend(0);
IRrecv irrecv(1);
irsend.begin();
// Generate a code which has address & command values.
irsend.reset();
irsend.sendNEC(irsend.encodeNEC(0x10, 0x20));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(NEC, irsend.capture.decode_type);
ASSERT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(
"uint16_t rawData[68] = {8960, 4480, 560, 560, 560, 560, 560, 560, "
"560, 560, 560, 1680, 560, 560, 560, 560, 560, 560, 560, 1680, "
"560, 1680, 560, 1680, 560, 1680, 560, 560, 560, 1680, 560, 1680, "
"560, 1680, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, "
"560, 1680, 560, 560, 560, 560, 560, 1680, 560, 1680, 560, 1680, "
"560, 1680, 560, 1680, 560, 560, 560, 1680, 560, 1680, 560, 40320 "
"}; // NEC 8F704FB\n"
"uint32_t address = 0x10;\n"
"uint32_t command = 0x20;\n"
"uint64_t data = 0x8F704FB;\n",
resultToSourceCode(&irsend.capture));
// Generate a code which DOESN'T have address & command values.
irsend.reset();
irsend.sendNikai(0xD0F2F);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(NIKAI, irsend.capture.decode_type);
ASSERT_EQ(kNikaiBits, irsend.capture.bits);
EXPECT_EQ(
"uint16_t rawData[52] = {4000, 4000, 500, 2000, 500, 2000, "
"500, 2000, 500, 2000, 500, 1000, 500, 1000, 500, 2000, 500, 1000, "
"500, 2000, 500, 2000, 500, 2000, 500, 2000, 500, 1000, 500, 1000, "
"500, 1000, 500, 1000, 500, 2000, 500, 2000, 500, 1000, 500, 2000, "
"500, 1000, 500, 1000, 500, 1000, 500, 1000, 500, 8500 };"
" // NIKAI D0F2F\n"
"uint64_t data = 0xD0F2F;\n",
resultToSourceCode(&irsend.capture));
}
TEST(TestResultToSourceCode, ComplexProtocols) {
IRsendTest irsend(0);
IRrecv irrecv(1);
irsend.begin();
uint8_t state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
0x00, 0x00, 0x00, 0x01};
irsend.reset();
irsend.sendToshibaAC(state);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type);
ASSERT_EQ(kToshibaACBits, irsend.capture.bits);
EXPECT_EQ(
"uint16_t rawData[296] = {4400, 4300, 542, 1622, 542, 1622, "
"542, 1622, 542, 1622, 542, 472, 542, 472, 542, 1622, 542, 472, "
"542, 472, 542, 472, 542, 472, 542, 472, 542, 1622, 542, 1622, "
"542, 472, 542, 1622, 542, 472, 542, 472, 542, 472, 542, 472, "
"542, 472, 542, 472, 542, 1622, 542, 1622, 542, 1622, 542, 1622, "
"542, 1622, 542, 1622, 542, 1622, 542, 1622, 542, 472, 542, 472, "
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
"542, 472, 542, 1622, 542, 472, 542, 472, 542, 472, 542, 472, "
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
"542, 472, 542, 472, 542, 472, 542, 1622, 542, 7048, 4400, 4300, "
"542, 1622, 542, 1622, 542, 1622, 542, 1622, 542, 472, 542, 472, "
"542, 1622, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
"542, 1622, 542, 1622, 542, 472, 542, 1622, 542, 472, 542, 472, "
"542, 472, 542, 472, 542, 472, 542, 472, 542, 1622, 542, 1622, "
"542, 1622, 542, 1622, 542, 1622, 542, 1622, 542, 1622, 542, 1622, "
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
"542, 472, 542, 472, 542, 472, 542, 1622, 542, 472, 542, 472, "
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 1622, "
"542, 7048 }; // TOSHIBA_AC\n"
"uint8_t state[9] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, "
"0x01};\n",
resultToSourceCode(&irsend.capture));
}
TEST(TestResultToTimingInfo, General) {
IRsendTest irsend(0);
IRrecv irrecv(1);
irsend.begin();
irsend.reset();
irsend.sendNEC(irsend.encodeNEC(0x10, 0x20));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(NEC, irsend.capture.decode_type);
ASSERT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(
"Raw Timing[68]:\n"
" + 8960, - 4480, + 560, - 560, + 560, - 560,"
" + 560, - 560, \n"
" + 560, - 560, + 560, - 1680, + 560, - 560,"
" + 560, - 560, \n"
" + 560, - 560, + 560, - 1680, + 560, - 1680,"
" + 560, - 1680, \n"
" + 560, - 1680, + 560, - 560, + 560, - 1680,"
" + 560, - 1680, \n"
" + 560, - 1680, + 560, - 560, + 560, - 560,"
" + 560, - 560, \n"
" + 560, - 560, + 560, - 560, + 560, - 1680,"
" + 560, - 560, \n"
" + 560, - 560, + 560, - 1680, + 560, - 1680,"
" + 560, - 1680, \n"
" + 560, - 1680, + 560, - 1680, + 560, - 560,"
" + 560, - 1680, \n"
" + 560, - 1680, + 560, - 40320\n",
resultToTimingInfo(&irsend.capture));
irsend.reset();
uint16_t rawData[9] = {10, 20, 30, 40, 50, 60, 70, 80, 90};
irsend.sendRaw(rawData, 9, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(
"Raw Timing[9]:\n"
" + 10, - 20, + 30, - 40, + 50, - 60,"
" + 70, - 80, \n"
" + 90\n",
resultToTimingInfo(&irsend.capture));
}
TEST(TestResultToHumanReadableBasic, SimpleCodes) {
IRsendTest irsend(0);
IRrecv irrecv(1);
irsend.begin();
irsend.reset();
irsend.sendNEC(irsend.encodeNEC(0x10, 0x20));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(NEC, irsend.capture.decode_type);
ASSERT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(
"Protocol : NEC\n"
"Code : 0x8F704FB (32 Bits)\n",
resultToHumanReadableBasic(&irsend.capture));
}
TEST(TestResultToHumanReadableBasic, ComplexCodes) {
IRsendTest irsend(0);
IRrecv irrecv(1);
irsend.begin();
uint8_t state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
0x00, 0x00, 0x00, 0x01};
irsend.reset();
irsend.sendToshibaAC(state);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type);
ASSERT_EQ(kToshibaACBits, irsend.capture.bits);
EXPECT_EQ(
"Protocol : TOSHIBA_AC\n"
"Code : 0xF20D03FC0100000001 (72 Bits)\n",
resultToHumanReadableBasic(&irsend.capture));
}
TEST(TestInvertBits, Normal) {
ASSERT_EQ(0xAAAA5555AAAA5555, invertBits(0x5555AAAA5555AAAA, 64));
ASSERT_EQ(0xAAAA5555, invertBits(0x5555AAAA, 32));
ASSERT_EQ(0xFFFFFFFFFFFFFFFF, invertBits(0x0, 64));
ASSERT_EQ(0x0, invertBits(invertBits(0x0, 64), 64));
ASSERT_EQ(0x2, invertBits(0x1, 2));
}
TEST(TestInvertBits, ZeroBits) {
ASSERT_EQ(0xAAAA5555AAAA5555, invertBits(0xAAAA5555AAAA5555, 0));
ASSERT_EQ(0x0, invertBits(0x0, 0));
ASSERT_EQ(0x1, invertBits(0x1, 0));
}
TEST(TestInvertBits, MoreThan64Bits) {
ASSERT_EQ(0xAAAA5555AAAA5555, invertBits(0x5555AAAA5555AAAA, 70));
ASSERT_EQ(0xFFFFFFFFFFFFFFFF, invertBits(0x0, 128));
}
TEST(TestCountBits, Pointer) {
uint8_t data[14] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
ASSERT_EQ(0, countBits(data, 0));
ASSERT_EQ(0, countBits(data, 1));
ASSERT_EQ(0, countBits(data, 1, true));
ASSERT_EQ(8, countBits(data, 1, false));
ASSERT_EQ(1, countBits(data, 2));
ASSERT_EQ(15, countBits(data, 2, false));
ASSERT_EQ(1, countBits(data + 1, 1));
ASSERT_EQ(2, countBits(data, 3));
ASSERT_EQ(4, countBits(data, 4));
ASSERT_EQ(25, countBits(data, 14));
ASSERT_EQ(25, countBits(data, 14));
ASSERT_EQ(14 * 8, countBits(data, 14, true) + countBits(data, 14, false));
ASSERT_EQ(125, countBits(data, 14, true, 100));
}
TEST(TestCountBits, Integer) {
uint64_t data = 0xAAAAAAAAAAAAAAAA;
ASSERT_EQ(0, countBits(data, 0));
ASSERT_EQ(0, countBits(data, 1));
ASSERT_EQ(0, countBits(data, 1, true));
ASSERT_EQ(1, countBits(data, 1, false));
ASSERT_EQ(1, countBits(data, 3));
ASSERT_EQ(2, countBits(data, 3, false));
ASSERT_EQ(4, countBits(data, 8));
ASSERT_EQ(4, countBits(data, 8, false));
ASSERT_EQ(32, countBits(data, 64));
ASSERT_EQ(32, countBits(data, 64, false));
data = 0;
ASSERT_EQ(0, countBits(data, 1, true));
ASSERT_EQ(1, countBits(data, 1, false));
ASSERT_EQ(0, countBits(data, 64));
ASSERT_EQ(64, countBits(data, 64, false));
data = 0xFFFFFFFFFFFFFFFF;
ASSERT_EQ(1, countBits(data, 1, true));
ASSERT_EQ(0, countBits(data, 1, false));
ASSERT_EQ(64, countBits(data, 64));
ASSERT_EQ(0, countBits(data, 64, false));
}
TEST(TestStrToDecodeType, strToDecodeType) {
EXPECT_EQ(decode_type_t::NEC, strToDecodeType("NEC"));
EXPECT_EQ(decode_type_t::KELVINATOR, strToDecodeType("KELVINATOR"));
EXPECT_EQ(decode_type_t::UNKNOWN, strToDecodeType("foo"));
}
TEST(TestUtils, htmlEscape) {
EXPECT_EQ("", irutils::htmlEscape(""));
EXPECT_EQ("No Changes", irutils::htmlEscape("No Changes"));
EXPECT_EQ("No\tChanges+_%^$@~`\n:\\",
irutils::htmlEscape("No\tChanges+_%^$@~`\n:\\"));
EXPECT_EQ("&quot;With Changes&quot;",
irutils::htmlEscape("\"With Changes\""));
EXPECT_EQ(
"&apos;&semi;&excl;&dash;&quot;&lt;&gt;&#equals;&amp;&num;&lcub;&rcub;"
"&lpar;&rpar;", irutils::htmlEscape("';!-\"<>=&#{}()"));
EXPECT_EQ("&quot;&quot;", irutils::htmlEscape("\"\""));
EXPECT_EQ(
"&amp;quot&semi;&amp;lt&semi;&amp;apos&semi;&amp;gt&semi;&amp;amp&semi;",
irutils::htmlEscape("&quot;&lt;&apos;&gt;&amp;"));
}
TEST(TestUtils, TemperatureConversion) {
// Freezing point of water.
ASSERT_EQ(32.0, celsiusToFahrenheit(0.0));
ASSERT_EQ(0.0, fahrenheitToCelsius(32.0));
// Boiling point of water.
ASSERT_EQ(212.0, celsiusToFahrenheit(100.0));
ASSERT_EQ(100.0, fahrenheitToCelsius(212.0));
// Room Temp. (RTP)
ASSERT_EQ(77.0, celsiusToFahrenheit(25.0));
ASSERT_EQ(25.0, fahrenheitToCelsius(77.0));
// Misc
ASSERT_EQ(-40.0, fahrenheitToCelsius(-40.0));
}
TEST(TestResultToRawArray, TypicalCase) {
IRsendTest irsend(0);
IRrecv irrecv(1);
irsend.begin();
// Generate a known message.
irsend.reset();
irsend.sendNikai(0xD0F2F);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(NIKAI, irsend.capture.decode_type);
ASSERT_EQ(kNikaiBits, irsend.capture.bits);
EXPECT_EQ(
"uint16_t rawData[52] = {4000, 4000, 500, 2000, 500, 2000, "
"500, 2000, 500, 2000, 500, 1000, 500, 1000, 500, 2000, 500, 1000, "
"500, 2000, 500, 2000, 500, 2000, 500, 2000, 500, 1000, 500, 1000, "
"500, 1000, 500, 1000, 500, 2000, 500, 2000, 500, 1000, 500, 2000, "
"500, 1000, 500, 1000, 500, 1000, 500, 1000, 500, 8500 };"
" // NIKAI D0F2F\n"
"uint64_t data = 0xD0F2F;\n",
resultToSourceCode(&irsend.capture));
uint16_t rawData[52] = { // Data taken from above.
4000, 4000, 500, 2000, 500, 2000, 500, 2000, 500, 2000, 500, 1000, 500,
1000, 500, 2000, 500, 1000, 500, 2000, 500, 2000, 500, 2000, 500, 2000,
500, 1000, 500, 1000, 500, 1000, 500, 1000, 500, 2000, 500, 2000, 500,
1000, 500, 2000, 500, 1000, 500, 1000, 500, 1000, 500, 1000, 500, 8500};
uint16_t * result = resultToRawArray(&irsend.capture);
ASSERT_EQ(52, getCorrectedRawLength(&irsend.capture));
EXPECT_STATE_EQ(rawData, result, getCorrectedRawLength(&irsend.capture));
if (result != NULL) delete[] result;
}
TEST(TestResultToRawArray, LargeValues) {
IRsendTest irsend(0);
IRrecv irrecv(1);
uint16_t test_data[9] = {10, 20, 30, 40, 50, 60, 70, 80, 90};
irsend.begin();
irsend.reset();
irsend.sendRaw(test_data, 9, 38000);
irsend.makeDecodeResult();
irrecv.decode(&irsend.capture);
uint16_t * result = resultToRawArray(&irsend.capture);
ASSERT_EQ(9, getCorrectedRawLength(&irsend.capture));
EXPECT_STATE_EQ(test_data, result, 9);
if (result != NULL) delete[] result;
// Stick in some large values.
irsend.capture.rawbuf[3] = 60000;
EXPECT_EQ(
"uint16_t rawData[11] = {10, 20, 65535, 0, 54465, 40, 50, 60, 70, "
"80, 90}; // UNKNOWN 54051FFD\n",
resultToSourceCode(&irsend.capture));
uint16_t large_test_data[11] = {
10, 20, 65535, 0, 54465, 40, 50, 60, 70, 80, 90};
ASSERT_EQ(11, getCorrectedRawLength(&irsend.capture));
result = resultToRawArray(&irsend.capture);
EXPECT_STATE_EQ(large_test_data, result, 11);
if (result != NULL) delete[] result;
}
TEST(TestUtils, TypeStringConversionRangeTests) {
ASSERT_EQ("UNKNOWN", typeToString((decode_type_t)(kLastDecodeType + 1)));
ASSERT_EQ("UNKNOWN", typeToString(decode_type_t::UNKNOWN));
for (int i = 0; i <= kLastDecodeType; i++) {
EXPECT_NE("UNKNOWN", typeToString((decode_type_t)i)) << "Protocol " << i <<
" doesn't have a valid string for it.";
EXPECT_EQ(i, strToDecodeType(typeToString((decode_type_t)i).c_str())) <<
"Protocol " << typeToString((decode_type_t)i) <<
" doesn't decode from a string correctly";
}
}
TEST(TestUtils, MinsToString) {
EXPECT_EQ("00:00", irutils::minsToString(0));
EXPECT_EQ("00:01", irutils::minsToString(1));
EXPECT_EQ("00:10", irutils::minsToString(10));
EXPECT_EQ("00:59", irutils::minsToString(59));
EXPECT_EQ("01:00", irutils::minsToString(60));
EXPECT_EQ("01:01", irutils::minsToString(61));
EXPECT_EQ("01:59", irutils::minsToString(60 + 59));
EXPECT_EQ("18:59", irutils::minsToString(18 * 60 + 59));
EXPECT_EQ("23:59", irutils::minsToString(23 * 60 + 59));
}
TEST(TestUtils, sumNibbles) {
// PTR/Array variant.
uint8_t testdata[] = {0x01, 0x23, 0x45};
EXPECT_EQ(0, irutils::sumNibbles(testdata, 0));
EXPECT_EQ(1, irutils::sumNibbles(testdata, 0, 1));
EXPECT_EQ(1, irutils::sumNibbles(testdata, 1));
EXPECT_EQ(2, irutils::sumNibbles(testdata, 1, 1));
EXPECT_EQ(15, irutils::sumNibbles(testdata, 3));
EXPECT_EQ(115, irutils::sumNibbles(testdata, 3, 100));
// Integer variant.
EXPECT_EQ(0x0, irutils::sumNibbles(0x0));
EXPECT_EQ(0x1, irutils::sumNibbles(0x1));
EXPECT_EQ(0xF, irutils::sumNibbles(0xF));
EXPECT_EQ(0x4, irutils::sumNibbles(0x1111));
EXPECT_EQ(0x8, irutils::sumNibbles(0x2222));
EXPECT_EQ(0x0, irutils::sumNibbles(0x4444));
EXPECT_EQ(0xA, irutils::sumNibbles(0x1234));
EXPECT_EQ(0xA, irutils::sumNibbles(0x4321));
EXPECT_EQ(0xE, irutils::sumNibbles(0xABCD));
EXPECT_EQ(0x1, irutils::sumNibbles(0x4AE5));
EXPECT_EQ(0xC, irutils::sumNibbles(0xFFFF));
EXPECT_EQ(0x1, irutils::sumNibbles(0xC005));
EXPECT_EQ(0x4, irutils::sumNibbles(0xC035));
EXPECT_EQ(0x2, irutils::sumNibbles(0x88C0051));
EXPECT_EQ(0x1, irutils::sumNibbles(0x88C0051, 1));
EXPECT_EQ(0x2, irutils::sumNibbles(0x88C0051, 1, 1));
EXPECT_EQ(0x6, irutils::sumNibbles(0x88C0051, 2));
EXPECT_EQ(0x6, irutils::sumNibbles(0x88C0051, 4));
EXPECT_EQ(0x2, irutils::sumNibbles(0x88C0051, 5));
EXPECT_EQ(0x22, irutils::sumNibbles(0x88C0051, 16, 0, false));
EXPECT_EQ(0x12, irutils::sumNibbles(0x88C0051, 5, 0, false));
EXPECT_EQ(0x22, irutils::sumNibbles(0x88C0051, 255, 0, false));
}
TEST(TestUtils, BCD) {
EXPECT_EQ(0, irutils::uint8ToBcd(0));
EXPECT_EQ(0, irutils::bcdToUint8(0));
EXPECT_EQ(1, irutils::uint8ToBcd(1));
EXPECT_EQ(10, irutils::bcdToUint8(0x10));
EXPECT_EQ(0x10, irutils::uint8ToBcd(10));
EXPECT_EQ(11, irutils::bcdToUint8(0x11));
EXPECT_EQ(0x11, irutils::uint8ToBcd(11));
EXPECT_EQ(99, irutils::bcdToUint8(0x99));
EXPECT_EQ(0x99, irutils::uint8ToBcd(99));
EXPECT_EQ(255, irutils::bcdToUint8(0x9A));
EXPECT_EQ(255, irutils::uint8ToBcd(100));
}
TEST(TestUtils, getBit) {
// uint8_t method.
EXPECT_FALSE(irutils::getBit((uint8_t)0, 0));
EXPECT_TRUE(irutils::getBit((uint8_t)1, 0));
EXPECT_FALSE(irutils::getBit((uint8_t)0b01, 1));
EXPECT_TRUE(irutils::getBit((uint8_t)0b10, 1));
EXPECT_FALSE(irutils::getBit((uint8_t)0b01111111, 7));
EXPECT_TRUE(irutils::getBit((uint8_t)0b10000000, 7));
// 8-bit macro method
EXPECT_FALSE(GETBIT8((uint8_t)0, 0));
EXPECT_TRUE(GETBIT8((uint8_t)1, 0));
EXPECT_FALSE(GETBIT8((uint8_t)0b01, 1));
EXPECT_TRUE(GETBIT8((uint8_t)0b10, 1));
EXPECT_FALSE(GETBIT8((uint8_t)0b01111111, 7));
EXPECT_TRUE(GETBIT8((uint8_t)0b10000000, 7));
// uint64_t method.
EXPECT_FALSE(irutils::getBit((uint64_t)0, 0));
EXPECT_TRUE(irutils::getBit((uint64_t)1, 0));
EXPECT_FALSE(irutils::getBit((uint64_t)0b01, 1));
EXPECT_TRUE(irutils::getBit((uint64_t)0b10, 1));
EXPECT_FALSE(irutils::getBit((uint64_t)0b01111111, 7));
EXPECT_TRUE(irutils::getBit((uint64_t)0b10000000, 7));
}
TEST(TestUtils, setBit) {
// uint8_t method.
EXPECT_EQ(0, irutils::setBit((uint8_t)0, 0, false));
EXPECT_EQ(0, irutils::setBit((uint8_t)1, 0, false));
EXPECT_EQ(1, irutils::setBit((uint8_t)0, 0, true));
EXPECT_EQ(1, irutils::setBit((uint8_t)1, 0, true));
EXPECT_EQ(0b101, irutils::setBit((uint8_t)0b101, 1, false));
EXPECT_EQ(0b100, irutils::setBit((uint8_t)0b110, 1, false));
EXPECT_EQ(0b111, irutils::setBit((uint8_t)0b101, 1, true));
EXPECT_EQ(0b110, irutils::setBit((uint8_t)0b110, 1, true));
EXPECT_EQ(0b11111111, irutils::setBit((uint8_t)0b01111111, 7, true));
EXPECT_EQ(0, irutils::setBit((uint8_t)0b10000000, 7, false));
// uint64_t method.
EXPECT_EQ(0, irutils::setBit((uint64_t)0, 0, false));
EXPECT_EQ(0, irutils::setBit((uint64_t)1, 0, false));
EXPECT_EQ(1, irutils::setBit((uint64_t)0, 0, true));
EXPECT_EQ(1, irutils::setBit((uint64_t)1, 0, true));
EXPECT_EQ(0b101, irutils::setBit((uint64_t)0b101, 1, false));
EXPECT_EQ(0b100, irutils::setBit((uint64_t)0b110, 1, false));
EXPECT_EQ(0b111, irutils::setBit((uint64_t)0b101, 1, true));
EXPECT_EQ(0b110, irutils::setBit((uint64_t)0b110, 1, true));
EXPECT_EQ(0b11111111, irutils::setBit((uint64_t)0b01111111, 7, true));
EXPECT_EQ(0, irutils::setBit((uint64_t)0b10000000, 7, false));
// uint8_t Pointer method.
uint8_t data = 0;
irutils::setBit(&data, 0, false);
EXPECT_EQ(0, data);
data = 1;
irutils::setBit(&data, 0, false);
ASSERT_EQ(0, data);
irutils::setBit(&data, 0, true);
ASSERT_EQ(1, data);
irutils::setBit(&data, 0, true);
ASSERT_EQ(1, data);
// uint64_t Pointer method.
uint64_t data64 = 0;
irutils::setBit(&data64, 38, true);
ASSERT_EQ(1ULL << 38, data64);
irutils::setBit(&data64, 38, true);
ASSERT_EQ(1ULL << 38, data64);
}
TEST(TestUtils, setBits8Bit) {
uint8_t data = 0b00000001;
// Trivial/corner cases.
irutils::setBits(&data, 0, 0, 0);
EXPECT_EQ(1, data);
irutils::setBits(&data, 0, 0, 17);
EXPECT_EQ(1, data);
irutils::setBits(&data, 22, 0, 22);
EXPECT_EQ(1, data);
irutils::setBits(&data, 8, 23, 3);
EXPECT_EQ(1, data);
irutils::setBits(&data, 8, 0, 3);
EXPECT_EQ(1, data);
// Single bit.
irutils::setBits(&data, 0, 1, 0);
EXPECT_EQ(0, data);
irutils::setBits(&data, 0, 1, 1);
EXPECT_EQ(0b1, data);
irutils::setBits(&data, 1, 1, 0);
EXPECT_EQ(0b1, data);
irutils::setBits(&data, 1, 1, 1);
EXPECT_EQ(0b11, data);
irutils::setBits(&data, 1, 1, 0);
EXPECT_EQ(0b1, data);
irutils::setBits(&data, 2, 1, 1);
EXPECT_EQ(0b101, data);
irutils::setBits(&data, 7, 1, 1);
EXPECT_EQ(0b10000101, data);
// Larger value than bits desired to be set.
irutils::setBits(&data, 5, 1, 255);
EXPECT_EQ(0b10100101, data);
// Set multiple bits
data = 0;
irutils::setBits(&data, 0, 8, 255);
EXPECT_EQ(0b11111111, data);
irutils::setBits(&data, 0, 8, 0);
EXPECT_EQ(0, data);
irutils::setBits(&data, 0, 4, 0xF);
EXPECT_EQ(0xF, data);
irutils::setBits(&data, 4, 4, 0xF);
EXPECT_EQ(0xFF, data);
irutils::setBits(&data, 4, 4, 0x3);
EXPECT_EQ(0x3F, data);
irutils::setBits(&data, 3, 4, 0x3);
EXPECT_EQ(0x1F, data);
irutils::setBits(&data, 1, 4, 0x3);
EXPECT_EQ(0b00000111, data);
irutils::setBits(&data, 1, 4, 0b1001);
EXPECT_EQ(0b00010011, data);
// Partial overrun.
irutils::setBits(&data, 6, 4, 0b1001);
EXPECT_EQ(0b01010011, data);
irutils::setBits(&data, 7, 4, 0b1001);
EXPECT_EQ(0b11010011, data);
}
TEST(TestUtils, setBits64Bit) {
uint64_t data = 1;
// Trivial/corner cases.
irutils::setBits(&data, 0, 0, 0);
EXPECT_EQ(1, data);
irutils::setBits(&data, 0, 0, 17);
EXPECT_EQ(1, data);
irutils::setBits(&data, 100, 0, 22);
EXPECT_EQ(1, data);
irutils::setBits(&data, 64, 23, 3);
EXPECT_EQ(1, data);
irutils::setBits(&data, 64, 0, 3);
EXPECT_EQ(1, data);
// Single bit.
irutils::setBits(&data, 0, 1, 0);
EXPECT_EQ(0, data);
irutils::setBits(&data, 0, 1, 1);
EXPECT_EQ(0b1, data);
irutils::setBits(&data, 1, 1, 0);
EXPECT_EQ(0b1, data);
irutils::setBits(&data, 1, 1, 1);
EXPECT_EQ(0b11, data);
irutils::setBits(&data, 1, 1, 0);
EXPECT_EQ(0b1, data);
irutils::setBits(&data, 2, 1, 1);
EXPECT_EQ(0b101, data);
irutils::setBits(&data, 7, 1, 1);
EXPECT_EQ(0b10000101, data);
// Larger value than bits desired to be set.
irutils::setBits(&data, 5, 1, 255);
EXPECT_EQ(0b10100101, data);
// Set multiple bits
data = 0;
irutils::setBits(&data, 0, 8, 255);
EXPECT_EQ(0b11111111, data);
irutils::setBits(&data, 0, 8, 0);
EXPECT_EQ(0, data);
irutils::setBits(&data, 0, 4, 0xF);
EXPECT_EQ(0xF, data);
irutils::setBits(&data, 4, 4, 0xF);
EXPECT_EQ(0xFF, data);
irutils::setBits(&data, 4, 4, 0x3);
EXPECT_EQ(0x3F, data);
irutils::setBits(&data, 3, 4, 0x3);
EXPECT_EQ(0x1F, data);
irutils::setBits(&data, 1, 4, 0x3);
EXPECT_EQ(0b00000111, data);
irutils::setBits(&data, 1, 4, 0b1001);
EXPECT_EQ(0b00010011, data);
// Partial overrun.
irutils::setBits(&data, 62, 4, 0b1001);
EXPECT_EQ(0x4000000000000013, data);
// General
irutils::setBits(&data, 32, 4, 0b1001);
EXPECT_EQ(0x4000000900000013, data);
}

View File

@@ -0,0 +1,159 @@
# SYNOPSIS:
#
# make [all] - makes everything.
# make TARGET - makes the given target.
# make run - makes everything and runs all the tests.
# make clean - removes all files generated by make.
# make install-googletest - install the googletest code suite
# Please tweak the following variable definitions as needed by your
# project, except GTEST_HEADERS, which you can use in your own targets
# but shouldn't modify.
# Points to the root of Google Test, relative to where this file is.
# Remember to tweak this if you move this file.
GTEST_DIR = ../lib/googletest/googletest
# Where to find user code.
USER_DIR = ../src
INCLUDES = -I$(USER_DIR) -I.
# Flags passed to the preprocessor.
# Set Google Test's header directory as a system directory, such that
# the compiler doesn't generate warnings in Google Test headers.
CPPFLAGS += -isystem $(GTEST_DIR)/include -DUNIT_TEST -D_IR_LOCALE_=en-AU
# Flags passed to the C++ compiler.
CXXFLAGS += -g -Wall -Wextra -Werror -pthread -std=gnu++11
# All tests produced by this Makefile. generated from all *_test.cpp files
TESTS = $(patsubst %.cpp,%,$(wildcard *_test.cpp))
# All Google Test headers. Usually you shouldn't change this
# definition.
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
$(GTEST_DIR)/include/gtest/internal/*.h
# House-keeping build targets.
all : $(TESTS)
clean :
rm -f $(TESTS) gtest.a gtest_main.a *.o
# Build and run all the tests.
run : all
failed=""; \
for unittest in $(TESTS); do \
./$${unittest} || failed="$${failed} $${unittest}"; \
done; \
if [ -n "$${failed}" ]; then \
echo "FAIL: :-( :-( Unit test(s)$${failed} failed! :-( :-("; exit 1; \
else \
echo "PASS: \o/ \o/ All unit tests passed. \o/ \o/"; \
fi
run_tests : run
install-googletest :
git clone -b v1.8.x https://github.com/google/googletest.git ../lib/googletest
# Builds gtest.a and gtest_main.a.
# Usually you shouldn't tweak such internal variables, indicated by a
# trailing _.
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
# All the IR protocol object files.
PROTOCOL_OBJS = $(patsubst %.cpp,%.o,$(wildcard $(USER_DIR)/ir_*.cpp))
PROTOCOLS = $(patsubst $(USER_DIR)/%,%,$(PROTOCOL_OBJS))
# All the IR Protocol header files.
PROTOCOLS_H = $(wildcard $(USER_DIR)/ir_*.h)
# Common object files
COMMON_OBJ = IRutils.o IRtimer.o IRsend.o IRrecv.o IRac.o ir_GlobalCache.o \
IRtext.o $(PROTOCOLS) gtest_main.a
# Common dependencies
COMMON_DEPS = $(USER_DIR)/IRrecv.h $(USER_DIR)/IRsend.h $(USER_DIR)/IRtimer.h \
$(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h \
$(USER_DIR)/IRac.h $(USER_DIR)/i18n.h $(USER_DIR)/IRtext.h \
$(PROTOCOLS_H)
# Common test dependencies
COMMON_TEST_DEPS = $(COMMON_DEPS) IRrecv_test.h IRsend_test.h
# For simplicity and to avoid depending on Google Test's
# implementation details, the dependencies specified below are
# conservative and not optimized. This is fine as Google Test
# compiles fast and for ordinary users its source rarely changes.
gtest-all.o : $(GTEST_SRCS_)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
$(GTEST_DIR)/src/gtest-all.cc
gtest_main.o : $(GTEST_SRCS_)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
$(GTEST_DIR)/src/gtest_main.cc
gtest.a : gtest-all.o
$(AR) $(ARFLAGS) $@ $^
gtest_main.a : gtest-all.o gtest_main.o
$(AR) $(ARFLAGS) $@ $^
# Keep all intermediate files.
.SECONDARY:
# Builds our test. A test should link with either gtest.a or
# gtest_main.a, depending on whether it defines its own main()
# function.
IRtext.o : $(USER_DIR)/IRtext.cpp $(USER_DIR)/IRtext.h $(USER_DIR)/IRremoteESP8266.h $(USER_DIR)/i18n.h $(USER_DIR)/locale/*.h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRtext.cpp
IRutils.o : $(USER_DIR)/IRutils.cpp $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h $(USER_DIR)/i18n.h $(USER_DIR)/IRtext.cpp $(USER_DIR)/IRtext.h $(USER_DIR)/locale/*.h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRutils.cpp
IRutils_test.o : IRutils_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRutils_test.cpp
IRutils_test : IRutils_test.o ir_NEC.o ir_Nikai.o ir_Toshiba.o IRtext.o $(COMMON_OBJ) gtest_main.a
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
IRtimer.o : $(USER_DIR)/IRtimer.cpp $(USER_DIR)/IRtimer.h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRtimer.cpp
IRsend.o : $(USER_DIR)/IRsend.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRremoteESP8266.h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRsend.cpp
IRsend_test.o : IRsend_test.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRrecv.h IRsend_test.h $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRsend_test.cpp
IRrecv.o : $(USER_DIR)/IRrecv.cpp $(USER_DIR)/IRrecv.h $(USER_DIR)/IRremoteESP8266.h $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRrecv.cpp
IRrecv_test.o : IRrecv_test.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRrecv.h IRsend_test.h $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRrecv_test.cpp
IRac.o : $(USER_DIR)/IRac.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRac.cpp
IRac_test.o : IRac_test.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRac_test.cpp
# new specific targets goes above this line
ir_%.o : $(USER_DIR)/ir_%.h $(USER_DIR)/ir_%.cpp $(COMMON_DEPS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_$*.cpp
ir_%.o : $(USER_DIR)/ir_%.cpp $(COMMON_DEPS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_$*.cpp
ir_%_test.o : ir_%_test.cpp $(USER_DIR)/ir_$%.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_$*_test.cpp
ir_%_test.o : ir_%_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_$*_test.cpp
%_test : $(COMMON_OBJ) %_test.o
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@

View File

@@ -0,0 +1,253 @@
// Copyright 2020 David Conran
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for decodeAirwell().
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1069
// Data from:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1069#issuecomment-604293514
TEST(TestDecodeAirwell, RealExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
// ON / OFF / 25 degrees heat
const uint16_t rawData_1[163] = {
2860, 3862,
1924, 1952, 1926, 1952, 956, 984, 1924, 1028, 952, 958, 980, 956, 982,
1882, 1016, 950, 1958, 1920, 1948, 1004, 954, 956, 984, 956, 952, 984,
974, 966, 974, 964, 974, 1888, 1010, 960, 1948, 1002, 946, 962, 978,
962, 976, 960, 948, 992, 978, 1886, 982, 984, 1924, 1954, 952, 986,
3892, 3862,
1924, 1954, 1924, 1954, 984, 952, 1956, 996, 954, 990, 948, 958, 980,
1882, 1016, 952, 1958, 1920, 1956, 994, 944, 962, 986, 956, 972, 962,
976, 962, 978, 964, 952, 1908, 1010, 960, 1948, 1002, 946, 960, 978,
962, 946, 990, 978, 960, 978, 1888, 1008, 954, 1952, 1928, 982, 956,
3920, 3830,
1946, 1934, 1954, 1922, 976, 962, 1946, 1006, 922, 990, 948, 988, 950,
1910, 1008, 964, 1922, 1952, 1924, 1030, 920, 984, 954, 986, 952, 986,
952, 984, 954, 986, 952, 1910, 1010, 960, 1928, 1024, 944, 996, 924,
984, 954, 988, 950, 984, 954, 1910, 1008, 960, 1920, 1958, 980, 958,
4800}; // UNKNOWN 565E2BB3
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData_1, 163, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type);
ASSERT_EQ(kAirwellBits, irsend.capture.bits);
EXPECT_EQ(0x2B0D0181B, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
const uint16_t rawData_2[175] = {
2862, 3892,
1894, 1060, 890, 1944, 952, 1014, 922, 1016, 1892, 1062, 886,
1020, 928, 1042, 896, 1938, 960, 1008, 920, 1020, 928, 1010, 928, 1012,
1896, 1056, 892, 1016, 922, 1020, 918, 1018, 920, 1018, 920, 1946, 950,
1014, 1894, 1062, 896, 1010, 928, 1010, 928, 1014, 924, 1014, 922, 1938,
960, 1012, 1896, 1984, 922, 1014,
3862, 3894,
1892, 1062, 896, 1936, 950, 1020, 928, 1008, 1898, 1056, 892, 1016, 952,
984, 954, 1910, 956, 1012, 924, 1014, 924, 1014, 922, 1014, 1892, 1060,
916, 992, 926, 1010, 928, 1014, 954, 982, 944, 1918, 958, 1010, 1896,
1058, 922, 986, 952, 988, 920, 1018, 950, 986, 952, 1914, 954, 1014,
1892, 1986, 922, 1016,
3860, 3896,
1898, 1054, 924, 1908, 958, 1012, 926, 1012, 1896, 1056, 942, 966, 952,
988, 950, 1910, 956, 1016, 922, 1016, 952, 988, 950, 986, 1922, 1032,
916, 990, 948, 960, 988, 984, 944, 960, 978, 1918, 978, 990, 1896, 1054,
924, 982, 946, 994, 954, 984, 954, 988, 950, 1910, 956, 1012, 1896, 1984,
922, 1018, 4768}; // UNKNOWN 1002DCC8
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData_2, 175, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type);
ASSERT_EQ(kAirwellBits, irsend.capture.bits);
EXPECT_EQ(0x270F8181B, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
TEST(TestDecodeAirwell, SyntheticExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
irsend.sendAirwell(0x2B0D0181B);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type);
EXPECT_EQ(kAirwellBits, irsend.capture.bits);
EXPECT_EQ(0x2B0D0181B, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_EQ(
"f38000d50"
"m2850s3800"
"m1900s1900m1900s1900m950s950m1900s950m950s950m950s950m950"
"s1900m950s950m1900s1900m1900s950m950s950m950s950m950s950"
"m950s950m950s950m950s1900m950s950m1900s950m950s950m950"
"s950m950s950m950s950m950s1900m950s950m1900s1900m950s950"
"m3800s3800"
"m1900s1900m1900s1900m950s950m1900s950m950s950m950s950m950"
"s1900m950s950m1900s1900m1900s950m950s950m950s950m950s950"
"m950s950m950s950m950s1900m950s950m1900s950m950s950m950"
"s950m950s950m950s950m950s1900m950s950m1900s1900m950s950"
"m3800s3800"
"m1900s1900m1900s1900m950s950m1900s950m950s950m950s950m950"
"s1900m950s950m1900s1900m1900s950m950s950m950s950m950s950"
"m950s950m950s950m950s1900m950s950m1900s950m950s950m950"
"s950m950s950m950s950m950s1900m950s950m1900s1900m950s950"
"m4750s100000",
irsend.outputStr());
irsend.reset();
irsend.sendAirwell(0x60080002);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type);
EXPECT_EQ(kAirwellBits, irsend.capture.bits);
EXPECT_EQ(0x60080002, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_EQ(
"f38000d50"
"m2850s2850"
"m950s950m950s950m950s1900m950s950m1900s950m950s950m950s950m950s950"
"m950s950m950s950m950s950m950s950m950s1900m1900s950m950s950m950s950"
"m950s950m950s950m950s950m950s950m950s950m950s950m950s950m950s950"
"m950s950m950s950m950s950m950s950m950s950m950s1900m1900s950"
"m2850s2850"
"m950s950m950s950m950s1900m950s950m1900s950m950s950m950s950m950s950"
"m950s950m950s950m950s950m950s950m950s1900m1900s950m950s950m950s950"
"m950s950m950s950m950s950m950s950m950s950m950s950m950s950m950s950"
"m950s950m950s950m950s950m950s950m950s950m950s1900m1900s950"
"m2850s2850"
"m950s950m950s950m950s1900m950s950m1900s950m950s950m950s950m950s950"
"m950s950m950s950m950s950m950s950m950s1900m1900s950m950s950m950s950"
"m950s950m950s950m950s950m950s950m950s950m950s950m950s950m950s950"
"m950s950m950s950m950s950m950s950m950s950m950s1900m1900s950"
"m3800s100000",
irsend.outputStr());
irsend.reset();
irsend.sendAirwell(0x70F8181B);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type);
EXPECT_EQ(kAirwellBits, irsend.capture.bits);
EXPECT_EQ(0x70F8181B, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1069
// Data from:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1069#issuecomment-607659677
TEST(TestDecodeAirwell, RealExample2) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
// "When I change from 22° to 23° :"
const uint16_t rawData[175] = {
2890, 2918,
924, 1006, 946, 1886, 1986, 1922, 978, 958, 1952, 1000, 952, 956, 974,
964, 976, 1884, 1016, 952, 1948, 1006, 944, 962, 980, 958, 982, 958, 952,
982, 978, 960, 980, 956, 986, 956, 974, 1888, 1014, 954, 1948, 1002, 948,
960, 980, 960, 950, 986, 1006, 962, 980, 1854, 1036, 932, 1948, 1928, 984,
954,
3918, 2920,
922, 1008, 942, 1888, 1984, 1926, 984, 950, 1952, 1000, 952, 956, 984,
956, 954, 1908, 1014, 952, 1948, 1002, 948, 960, 950, 986, 984, 956, 954,
984, 956, 984, 946, 992, 948, 992, 948, 1910, 1012, 958, 1954, 996, 922,
984, 956, 986, 956, 980, 950, 988, 954, 1910, 1010, 956, 1946, 1932, 978,
962,
3922, 2914,
918, 1010, 920, 1912, 1980, 1928, 982, 956, 1944, 1006, 924, 982, 958,
982, 948, 1912, 1008, 958, 1952, 1000, 920, 988, 952, 982, 958, 984, 958,
978, 952, 986, 986, 952, 958, 984, 946, 1912, 1010, 962, 1948, 1004, 926,
980, 950, 988, 952, 984, 956, 982, 948, 1916, 1016, 952, 1950, 1926, 984,
952, 4830}; // UNKNOWN 8E34167B
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData, 175, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type);
ASSERT_EQ(kAirwellBits, irsend.capture.bits);
EXPECT_EQ(0xB0C0181B, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
// Resend it as a synthetic to see if it decodes to the same value.
irsend.reset();
irsend.sendAirwell(0xB0C0181B);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type);
ASSERT_EQ(kAirwellBits, irsend.capture.bits);
EXPECT_EQ(0xB0C0181B, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
TEST(TestUtils, Housekeeping) {
ASSERT_EQ("AIRWELL", typeToString(decode_type_t::AIRWELL));
ASSERT_EQ(decode_type_t::AIRWELL, strToDecodeType("AIRWELL"));
ASSERT_FALSE(hasACState(decode_type_t::AIRWELL));
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::AIRWELL));
ASSERT_EQ(kAirwellBits, IRsend::defaultBits(decode_type_t::AIRWELL));
ASSERT_EQ(kAirwellMinRepeats, IRsend::minRepeats(decode_type_t::AIRWELL));
}
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1069
// Data from:
// https://docs.google.com/spreadsheets/d/1MeqVsgXQAMSiAx7zNunG8qbFcIT8tqZtcjLmMa0GEng/edit#gid=1053299474&range=M2:GW2
TEST(TestDecodeAirwell, RealExample3) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
const uint16_t rawData[193] = {
3010, 2852,
904, 1042, 872, 1052, 872, 1932, 904, 956, 1878, 1050, 874, 1046, 872,
956, 876, 1048, 872, 1044, 876, 1046, 874, 958, 872, 1050, 872, 1966,
1880, 956, 872, 1048, 874, 1048, 872, 1050, 872, 958, 872, 1050, 872,
1048, 872, 1050, 872, 958, 872, 1048, 872, 1050, 872, 1048, 872, 958, 872,
1050, 872, 1048, 872, 1050, 872, 1872, 1880, 1048,
2978, 2880,
872, 1048, 872, 1050, 872, 1964, 872, 958, 1880, 1050, 872, 1050, 872,
958, 872, 1050, 872, 1050, 872, 1050, 872, 958, 872, 1050, 872, 1964,
1882, 958, 870, 1050, 872, 1048, 872, 1050, 872, 958, 872, 1048, 872,
1050, 872, 1050, 872, 958, 872, 1050, 872, 1050, 872, 1050, 872, 958, 872,
1050, 872, 1050, 872, 1050, 872, 1874, 1880, 1050,
2978, 2880,
872, 1050, 872, 1050, 872, 1964, 872, 958, 1880, 1050, 872, 1050, 872,
958, 872, 1050, 872, 1050, 872, 1050, 872, 958, 872, 1050, 872, 1964,
1880, 958, 872, 1050, 872, 1050, 872, 1050, 872, 958, 872, 1052, 870,
1050, 872, 1050, 872, 958, 872, 1050, 872, 1050, 872, 1050, 872, 958, 872,
1050, 872, 1050, 872, 1050, 872, 1874, 1880, 1050, 3894};
irsend.reset();
irsend.sendRaw(rawData, 193, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeAirwell(&irsend.capture));
ASSERT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type);
ASSERT_EQ(kAirwellBits, irsend.capture.bits);
EXPECT_EQ(0x60080002, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}

View File

@@ -0,0 +1,357 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendAiwaRCT501().
// Test sending typical data only.
TEST(TestSendAiwa, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendAiwaRCT501(0x7F); // Aiwa Power Toggle.
EXPECT_EQ(
"f38000d33"
"m8960s4480"
"m560s560m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s23520"
"m8960s2240m560s96320",
irsend.outputStr());
}
// Test sending oversized data.
TEST(TestSendAiwa, SendOversizedData) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendAiwaRCT501(0x7F, 38); // 38 bits is over the maximum. Should fail.
EXPECT_EQ("", irsend.outputStr());
}
// Test sending with different repeats.
TEST(TestSendAiwa, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendAiwaRCT501(0x7F, kAiwaRcT501Bits, 0); // No repeats.
EXPECT_EQ(
"f38000d33"
"m8960s4480"
"m560s560m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s23520",
irsend.outputStr());
irsend.reset();
irsend.sendAiwaRCT501(0x7F, kAiwaRcT501Bits, 1); // 1 repeat.
EXPECT_EQ(
"f38000d33"
"m8960s4480"
"m560s560m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s23520"
"m8960s2240m560s96320",
irsend.outputStr());
irsend.reset();
irsend.sendAiwaRCT501(0x7F, kAiwaRcT501Bits, 2); // 2 repeats.
EXPECT_EQ(
"f38000d33"
"m8960s4480"
"m560s560m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s23520"
"m8960s2240m560s96320"
"m8960s2240m560s96320",
irsend.outputStr());
}
// Test sending an atypical data size.
TEST(TestSendAiwa, SendUnusualSize) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendAiwaRCT501(0x12, 8);
EXPECT_EQ(
"f38000d33"
"m8960s4480"
"m560s560m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s560m560s560m560s560m560s1680m560s560m560s560"
"m560s1680m560s560m560s1680m560s36960"
"m8960s2240m560s96320",
irsend.outputStr());
irsend.reset();
irsend.sendAiwaRCT501(0x1234567890, 37);
EXPECT_EQ(
"f38000d33"
"m8960s4480"
"m560s560m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s1680m560s560m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s1680m560s560m560s1680m560s560m560s560m560s560"
"m560s1680m560s560m560s1680m560s560m560s1680m560s1680m560s560m560s560"
"m560s1680m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s1680"
"m560s560m560s560m560s1680m560s560m560s560m560s560m560s560m560s1680"
"m560s22400"
"m8960s2240m560s96320",
irsend.outputStr());
}
// Tests for decodeAiwaRCT501().
// Decode normal Aiwa messages.
TEST(TestDecodeAiwa, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Aiwa 15-bit(42bit) message.
irsend.reset();
irsend.sendAiwaRCT501(0x7F);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset,
kAiwaRcT501Bits, true));
EXPECT_EQ(AIWA_RC_T501, irsend.capture.decode_type);
EXPECT_EQ(kAiwaRcT501Bits, irsend.capture.bits);
EXPECT_EQ(0x7F, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal Aiwa 15-bit(42bit) message.
irsend.reset();
irsend.sendAiwaRCT501(0x0);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset,
kAiwaRcT501Bits, true));
EXPECT_EQ(AIWA_RC_T501, irsend.capture.decode_type);
EXPECT_EQ(kAiwaRcT501Bits, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal Aiwa 15-bit(42bit) message.
irsend.reset();
irsend.sendAiwaRCT501(0x7FFF);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset,
kAiwaRcT501Bits, true));
EXPECT_EQ(AIWA_RC_T501, irsend.capture.decode_type);
EXPECT_EQ(kAiwaRcT501Bits, irsend.capture.bits);
EXPECT_EQ(0x7FFF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode normal repeated Aiwa messages.
TEST(TestDecodeAiwa, NormalDecodeWithRepeatAndStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Aiwa 15-bit(42bit) message with 2 repeats.
irsend.reset();
irsend.sendAiwaRCT501(0x7F, kAiwaRcT501Bits, 2);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset,
kAiwaRcT501Bits, true));
EXPECT_EQ(AIWA_RC_T501, irsend.capture.decode_type);
EXPECT_EQ(kAiwaRcT501Bits, irsend.capture.bits);
EXPECT_EQ(0x7F, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode unsupported Aiwa messages.
TEST(TestDecodeAiwa, DecodeWithNonStrictValues) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Confirm using sendNEC(data, 42, 1) can make a legal Aiwa message.
irsend.sendNEC(0x1D8113F00FF, 42, kAiwaRcT501MinRepeats);
irsend.makeDecodeResult();
// MUST pass with strict on.
ASSERT_TRUE(irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset,
kAiwaRcT501Bits, true));
ASSERT_EQ(0x7F, irsend.capture.value);
irsend.reset();
// Use sendNEC(data, 42) to make/send an illegal value Aiwa message.
// Value is illegal due to bad pre & post data.
irsend.sendNEC(0x1234567890A, 42, kAiwaRcT501MinRepeats);
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset,
kAiwaRcT501Bits, true));
// Should fail if strict off too.
ASSERT_FALSE(
irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset, kAiwaRcT501Bits,
false));
irsend.reset();
// Use sendNEC(data, 42) to make/send an illegal value Aiwa message.
// Value is illegal due to bad post data only.
irsend.sendNEC(0x1D8113F00FE, 42, kAiwaRcT501MinRepeats);
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset,
kAiwaRcT501Bits, true));
// Should fail if strict off too.
ASSERT_FALSE(
irrecv.decodeAiwaRCT501(&irsend.capture, kAiwaRcT501Bits, false));
irsend.reset();
// Use sendNEC(data, 42) to make/send an illegal value Aiwa message.
// Value is illegal due to bad pre data only.
irsend.sendNEC(0x0D8113F00FF, 42, kAiwaRcT501MinRepeats);
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset,
kAiwaRcT501Bits, true));
// Should fail if strict off too.
ASSERT_FALSE(
irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset, kAiwaRcT501Bits,
false));
}
// Decode unsupported Aiwa messages.
TEST(TestDecodeAiwa, DecodeWithNonStrictSizes) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendAiwaRCT501(0x0, 8); // Illegal size Aiwa 8-bit message.
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset,
kAiwaRcT501Bits, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset, 8, false));
EXPECT_EQ(AIWA_RC_T501, irsend.capture.decode_type);
EXPECT_EQ(8, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
irsend.reset();
irsend.sendAiwaRCT501(0x12345678, 32); // Illegal size Aiwa 32-bit message.
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset,
kAiwaRcT501Bits, true));
// Should fail with strict when we ask for the wrong bit size.
ASSERT_FALSE(irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset, 32,
true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset, 32,
false));
EXPECT_EQ(AIWA_RC_T501, irsend.capture.decode_type);
EXPECT_EQ(32, irsend.capture.bits);
EXPECT_EQ(0x12345678, irsend.capture.value);
}
// Decode (non-standard) 64-bit messages.
TEST(TestDecodeAiwa, Decode64BitMessages) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Illegal value & size Aiwa 37(64)-bit message.
irsend.sendAiwaRCT501(0x1FFFFFFFFF, 37);
irsend.makeDecodeResult();
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset, 37,
false));
EXPECT_EQ(AIWA_RC_T501, irsend.capture.decode_type);
EXPECT_EQ(37, irsend.capture.bits);
EXPECT_EQ(0x1FFFFFFFFF, irsend.capture.value);
// Reconfirm it by sending a true 64bit NEC message with the Aiwa prefix.
irsend.reset();
irsend.sendNEC(0x76044FFFFFFFFFFF, 64, kAiwaRcT501MinRepeats);
irsend.makeDecodeResult();
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset, 37,
false));
EXPECT_EQ(AIWA_RC_T501, irsend.capture.decode_type);
EXPECT_EQ(37, irsend.capture.bits);
EXPECT_EQ(0x1FFFFFFFFF, irsend.capture.value);
}
// Decode a 'real' example via GlobalCache
TEST(TestDecodeAiwa, DecodeGlobalCacheExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Aiwa Power Toggle from Global Cache.
uint16_t gc_test[95] = {
38000, 1, 89, 342, 171, 21, 21, 21, 64, 21, 64, 21, 64, 21, 21, 21,
64, 21, 64, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
64, 21, 21, 21, 21, 21, 21, 21, 64, 21, 21, 21, 21, 21, 64, 21,
64, 21, 64, 21, 64, 21, 64, 21, 64, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 64, 21, 64, 21, 64, 21,
64, 21, 64, 21, 64, 21, 64, 21, 64, 21, 875, 342, 171, 21, 3565};
irsend.sendGC(gc_test, 95);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeAiwaRCT501(&irsend.capture));
EXPECT_EQ(AIWA_RC_T501, irsend.capture.decode_type);
EXPECT_EQ(kAiwaRcT501Bits, irsend.capture.bits);
EXPECT_EQ(0x7F, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Confirm what the 42-bit NEC decode is.
ASSERT_TRUE(irrecv.decodeNEC(&irsend.capture, kStartOffset, 42, false));
EXPECT_EQ(0x1D8113F00FF, irsend.capture.value);
}
// Fail to decode a non-Aiwa example via GlobalCache
TEST(TestDecodeAiwa, FailToDecodeNonAiwaExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
uint16_t gc_test[39] = {38000, 1, 1, 322, 162, 20, 61, 20, 61, 20,
20, 20, 20, 20, 20, 20, 127, 20, 61, 9,
20, 20, 61, 20, 20, 20, 61, 20, 61, 20,
61, 20, 20, 20, 20, 20, 20, 20, 884};
irsend.sendGC(gc_test, 39);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeAiwaRCT501(&irsend.capture));
ASSERT_FALSE(
irrecv.decodeAiwaRCT501(&irsend.capture, kStartOffset, kAiwaRcT501Bits,
false));
}

View File

@@ -0,0 +1,351 @@
// Copyright 2019 David Conran
#include "IRac.h"
#include "ir_Amcor.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("AMCOR", typeToString(decode_type_t::AMCOR));
ASSERT_EQ(decode_type_t::AMCOR, strToDecodeType("AMCOR"));
ASSERT_TRUE(hasACState(decode_type_t::AMCOR));
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::AMCOR));
}
// Test sending typical data only.
TEST(TestSendAmcor, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
uint8_t expectedState[kAmcorStateLength] = {
0x01, 0x41, 0x36, 0x00, 0x00, 0x30, 0x00, 0x12};
irsend.reset();
irsend.sendAmcor(expectedState);
EXPECT_EQ(
"f38000d50"
"m8200s4200"
"m1500s600m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500"
"m1500s600m600s1500m600s1500m600s1500m600s1500m600s1500m1500s600m600s1500"
"m600s1500m1500s600m1500s600m600s1500m1500s600m1500s600m600s1500m600s1500"
"m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500"
"m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500"
"m600s1500m600s1500m600s1500m600s1500m1500s600m1500s600m600s1500m600s1500"
"m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500"
"m600s1500m1500s600m600s1500m600s1500m1500s600m600s1500m600s1500m600s1500"
"m1900s34300"
"m8200s4200"
"m1500s600m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500"
"m1500s600m600s1500m600s1500m600s1500m600s1500m600s1500m1500s600m600s1500"
"m600s1500m1500s600m1500s600m600s1500m1500s600m1500s600m600s1500m600s1500"
"m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500"
"m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500"
"m600s1500m600s1500m600s1500m600s1500m1500s600m1500s600m600s1500m600s1500"
"m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500m600s1500"
"m600s1500m1500s600m600s1500m600s1500m1500s600m600s1500m600s1500m600s1500"
"m1900s34300",
irsend.outputStr());
}
TEST(TestDecodeAmcor, SyntheticSelfDecode) {
IRsendTest irsend(0);
IRrecv irrecv(0);
IRAmcorAc ac(0);
uint8_t expectedState[kAmcorStateLength] = {
0x01, 0x41, 0x30, 0x00, 0x00, 0x30, 0x00, 0x0C};
irsend.begin();
irsend.reset();
irsend.sendAmcor(expectedState);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(AMCOR, irsend.capture.decode_type);
EXPECT_EQ(kAmcorBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Fan: 4 (Auto), Temp: 24C, Max: Off",
ac.toString());
}
TEST(TestDecodeAmcor, RealExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Data from Issue #834 captured by ldellus
// Turn on, cooling, 27 deg C.
uint16_t rawData[263] = {
8210, 4276, 1544, 480, 596, 1510, 596, 1510, 596, 1692, 388, 1534, 596,
1510, 596, 1510, 596, 1684, 1450, 480, 596, 1510, 570, 1534, 570, 1718, 386,
1536, 594, 1500, 1632, 482, 596, 1694, 362, 1550, 1632, 472, 1658, 456, 596,
1684, 1474, 446, 1634, 480, 572, 1534, 572, 1718, 362, 1558, 572, 1534, 570,
1534, 570, 1720, 360, 1558, 572, 1534, 570, 1534, 570, 1718, 360, 1560, 572,
1534, 570, 1534, 570, 1718, 362, 1560, 572, 1532, 572, 1534, 570, 1718, 362,
1558, 572, 1532, 572, 1534, 570, 1710, 1448, 472, 1634, 480, 572, 1534, 570,
1718, 362, 1558, 572, 1534, 570, 1534, 572, 1716, 362, 1560, 572, 1534, 572,
1534, 570, 1718, 362, 1550, 1634, 480, 570, 1536, 570, 1710, 1448, 482, 570,
1534, 570, 1536, 570, 1508, 1856, 34298,
// rawData[132] is here. (8218)
8218, 4314, 1502, 522, 530, 1576, 504, 1602, 504, 1786, 392, 1528, 504,
1600, 504, 1600, 504, 1770, 1414, 522, 528, 1578, 502, 1602, 504, 1784, 394,
1528, 504, 1584, 1574, 548, 528, 1762, 392, 1512, 1572, 530, 1600, 524, 528,
1744, 1390, 530, 1574, 546, 506, 1600, 504, 1784, 394, 1528, 504, 1600, 578,
1528, 504, 1784, 394, 1526, 504, 1600, 504, 1600, 506, 1784, 394, 1528, 504,
1602, 504, 1602, 504, 1784, 394, 1526, 506, 1600, 504, 1600, 506, 1784, 392,
1526, 506, 1600, 504, 1602, 502, 1768, 1390, 530, 1574, 548, 504, 1600, 504,
1786, 392, 1530, 504, 1600, 504, 1600, 504, 1786, 392, 1528, 504, 1600, 504,
1600, 506, 1784, 394, 1512, 1574, 548, 504, 1602, 504, 1768, 1388, 548, 504,
1602, 504, 1602, 502, 1574, 1792}; // UNKNOWN D510A6EF
uint8_t expectedState[kAmcorStateLength] = {
0x01, 0x41, 0x36, 0x00, 0x00, 0x30, 0x00, 0x12};
irsend.reset();
irsend.sendRaw(rawData, 263, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(AMCOR, irsend.capture.decode_type);
EXPECT_EQ(kAmcorBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
// Verify the repeat is the same decode.
irsend.reset();
irsend.sendRaw(rawData + 132, 131, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(AMCOR, irsend.capture.decode_type);
EXPECT_EQ(kAmcorBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
// https://github.com/crankyoldgit/IRremoteESP8266/issues/834#issuecomment-515700254
uint16_t rawData2[263] = {8252, 4294, 1518, 508, 544, 1560, 546, 1560, 570,
1718, 416, 1504, 546, 1560, 570, 1532, 572, 1718, 1414, 506, 544, 1560, 570,
1534, 570, 1718, 416, 1506, 544, 1558, 1598, 508, 544, 1746, 416, 1504, 546,
1560, 570, 1534, 1598, 690, 1414, 508, 544, 1560, 546, 1560, 544, 1746, 416,
1504, 546, 1560, 546, 1560, 570, 1718, 416, 1504, 544, 1560, 570, 1536, 544,
1744, 416, 1506, 570, 1534, 546, 1558, 546, 1744, 418, 1502, 572, 1534, 544,
1560, 570, 1720, 416, 1506, 544, 1560, 546, 1560, 544, 1744, 1414, 506,
1572, 534, 544, 1560, 570, 1720, 416, 1504, 570, 1536, 544, 1560, 572, 1718,
416, 1504, 570, 1542, 592, 1504, 570, 1720, 416, 1502, 1572, 534, 544, 1560,
572, 1718, 1414, 508, 544, 1560, 570, 1534, 570, 1508, 1840, 34174, 8230,
4292, 1546, 480, 546, 1560, 572, 1534, 570, 1718, 416, 1502, 572, 1532, 572,
1532, 572, 1718, 1440, 480, 570, 1534, 572, 1534, 572, 1716, 418, 1504, 572,
1532, 1626, 480, 572, 1718, 418, 1502, 574, 1534, 572, 1530, 1626, 662,
1442, 480, 572, 1534, 572, 1534, 572, 1716, 418, 1502, 574, 1542, 592, 1504,
598, 1692, 418, 1504, 572, 1532, 574, 1530, 574, 1716, 418, 1502, 598, 1508,
572, 1532, 598, 1692, 418, 1502, 598, 1508, 572, 1532, 574, 1716, 418, 1504,
598, 1508, 572, 1532, 574, 1716, 1442, 478, 1626, 480, 572, 1534, 572, 1718,
392, 1526, 574, 1532, 572, 1532, 572, 1716, 418, 1502, 598, 1508, 574, 1532,
598, 1700, 408, 1504, 1624, 480, 572, 1532, 574, 1716, 1440, 480, 572, 1532,
572, 1532, 572, 1506, 1814}; // UNKNOWN ADA838FB
uint8_t expectedState2[kAmcorStateLength] = {
0x01, 0x41, 0x18, 0x00, 0x00, 0x30, 0x00, 0x12};
irsend.reset();
irsend.sendRaw(rawData2, 263, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(AMCOR, irsend.capture.decode_type);
EXPECT_EQ(kAmcorBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState2, irsend.capture.state, irsend.capture.bits);
}
// Tests for IRAmcorAc class.
TEST(TestAmcorAcClass, Power) {
IRAmcorAc 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(TestAmcorAcClass, Temperature) {
IRAmcorAc ac(0);
ac.begin();
ac.setTemp(0);
EXPECT_EQ(kAmcorMinTemp, ac.getTemp());
ac.setTemp(255);
EXPECT_EQ(kAmcorMaxTemp, ac.getTemp());
ac.setTemp(kAmcorMinTemp);
EXPECT_EQ(kAmcorMinTemp, ac.getTemp());
ac.setTemp(kAmcorMaxTemp);
EXPECT_EQ(kAmcorMaxTemp, ac.getTemp());
ac.setTemp(kAmcorMinTemp - 1);
EXPECT_EQ(kAmcorMinTemp, ac.getTemp());
ac.setTemp(kAmcorMaxTemp + 1);
EXPECT_EQ(kAmcorMaxTemp, 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(TestAmcorAcClass, OperatingMode) {
IRAmcorAc ac(0);
ac.begin();
ac.setMode(kAmcorAuto);
EXPECT_EQ(kAmcorAuto, ac.getMode());
ac.setMode(kAmcorCool);
EXPECT_EQ(kAmcorCool, ac.getMode());
ac.setMode(kAmcorHeat);
EXPECT_EQ(kAmcorHeat, ac.getMode());
ac.setMode(kAmcorDry);
EXPECT_EQ(kAmcorDry, ac.getMode());
ac.setMode(kAmcorFan);
EXPECT_EQ(kAmcorFan, ac.getMode());
ac.setMode(kAmcorAuto + 1);
EXPECT_EQ(kAmcorAuto, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kAmcorAuto, ac.getMode());
}
TEST(TestAmcorAcClass, FanSpeed) {
IRAmcorAc ac(0);
ac.begin();
ac.setFan(0);
EXPECT_EQ(kAmcorFanAuto, ac.getFan());
ac.setFan(255);
EXPECT_EQ(kAmcorFanAuto, ac.getFan());
ac.setFan(kAmcorFanMax);
EXPECT_EQ(kAmcorFanMax, ac.getFan());
ac.setFan(kAmcorFanMax + 1);
EXPECT_EQ(kAmcorFanAuto, ac.getFan());
ac.setFan(kAmcorFanMax - 1);
EXPECT_EQ(kAmcorFanMax - 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(TestAmcorAcClass, Checksums) {
uint8_t state[kAmcorStateLength] = {
0x01, 0x41, 0x30, 0x00, 0x00, 0x30, 0x00, 0x0C};
ASSERT_EQ(0x0C, IRAmcorAc::calcChecksum(state));
EXPECT_TRUE(IRAmcorAc::validChecksum(state));
// Change the array so the checksum is invalid.
state[0] ^= 0xFF;
EXPECT_FALSE(IRAmcorAc::validChecksum(state));
// Restore the previous change, and change another byte.
state[0] ^= 0xFF;
state[4] ^= 0xFF;
EXPECT_FALSE(IRAmcorAc::validChecksum(state));
state[4] ^= 0xFF;
EXPECT_TRUE(IRAmcorAc::validChecksum(state));
// Additional known good states.
uint8_t knownGood1[kAmcorStateLength] = {
0x01, 0x11, 0x3E, 0x00, 0x00, 0x30, 0x00, 0x17};
EXPECT_TRUE(IRAmcorAc::validChecksum(knownGood1));
ASSERT_EQ(0x17, IRAmcorAc::calcChecksum(knownGood1));
uint8_t knownGood2[kAmcorStateLength] = {
0x01, 0x22, 0x26, 0x00, 0x00, 0x30, 0x00, 0x10};
EXPECT_TRUE(IRAmcorAc::validChecksum(knownGood2));
ASSERT_EQ(0x10, IRAmcorAc::calcChecksum(knownGood2));
uint8_t knownGood3[kAmcorStateLength] = {
0x01, 0x41, 0x24, 0x00, 0x00, 0xC0, 0x00, 0x18};
EXPECT_TRUE(IRAmcorAc::validChecksum(knownGood3));
ASSERT_EQ(0x18, IRAmcorAc::calcChecksum(knownGood3));
// For a recalculation.
uint8_t knownBad[kAmcorStateLength] = {
// Same as knownGood3 except for the checksum.
0x01, 0x41, 0x24, 0x00, 0x00, 0xC0, 0x00, 0x00};
EXPECT_FALSE(IRAmcorAc::validChecksum(knownBad));
IRAmcorAc ac(0);
ac.setRaw(knownBad);
EXPECT_STATE_EQ(knownGood3, ac.getRaw(), kAmcorBits);
}
TEST(TestAmcorAcClass, Max) {
IRAmcorAc ac(0);
ac.begin();
ac.setMode(kAmcorCool);
ac.setMax(true);
EXPECT_EQ(kAmcorCool, ac.getMode());
EXPECT_EQ(kAmcorMinTemp, ac.getTemp());
EXPECT_TRUE(ac.getMax());
ac.setMax(false);
EXPECT_EQ(kAmcorCool, ac.getMode());
EXPECT_EQ(kAmcorMinTemp, ac.getTemp());
EXPECT_FALSE(ac.getMax());
ac.setMode(kAmcorHeat);
ac.setMax(true);
EXPECT_EQ(kAmcorHeat, ac.getMode());
EXPECT_EQ(kAmcorMaxTemp, ac.getTemp());
EXPECT_TRUE(ac.getMax());
ac.setMax(false);
EXPECT_EQ(kAmcorHeat, ac.getMode());
EXPECT_EQ(kAmcorMaxTemp, ac.getTemp());
EXPECT_FALSE(ac.getMax());
ac.setMode(kAmcorAuto);
ac.setTemp(25);
ac.setMax(true);
EXPECT_EQ(kAmcorAuto, ac.getMode());
EXPECT_EQ(25, ac.getTemp());
EXPECT_FALSE(ac.getMax());
// Test known real data.
uint8_t lo[kAmcorStateLength] = {
0x01, 0x41, 0x18, 0x00, 0x00, 0x30, 0x03, 0x15};
uint8_t hi[kAmcorStateLength] = {
0x01, 0x12, 0x40, 0x00, 0x00, 0x30, 0x03, 0x0E};
ac.setRaw(lo);
EXPECT_EQ("Power: On, Mode: 1 (Cool), Fan: 4 (Auto), Temp: 12C, Max: On",
ac.toString());
ac.setRaw(hi);
EXPECT_EQ("Power: On, Mode: 2 (Heat), Fan: 1 (Low), Temp: 32C, Max: On",
ac.toString());
}

View File

@@ -0,0 +1,228 @@
// Copyright 2019 David Conran
#include "ir_Argo.h"
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
TEST(TestArgoACClass, toCommon) {
IRArgoAC ac(0);
ac.setPower(true);
ac.setMode(kArgoCool);
ac.setTemp(20);
ac.setFan(kArgoFan3);
ac.setMax(true);
ac.setNight(true);
// Now test it.
ASSERT_EQ(decode_type_t::ARGO, ac.toCommon().protocol);
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::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(0, ac.toCommon().sleep);
ASSERT_TRUE(ac.toCommon().turbo);
// Unsupported.
ASSERT_EQ(-1, ac.toCommon().model);
ASSERT_EQ(stdAc::swingv_t::kOff, ac.toCommon().swingv);
ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh);
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_FALSE(ac.toCommon().quiet);
ASSERT_EQ(-1, ac.toCommon().clock);
}
TEST(TestArgoACClass, MessageConstructon) {
IRArgoAC ac(0);
ac.setPower(true);
ac.setTemp(20);
ac.setMode(kArgoCool);
ac.setFan(kArgoFanAuto);
ac.setRoomTemp(21);
ac.setiFeel(true);
ac.setMax(true);
ac.setNight(true);
// Don't implicitly trust this. It's just a guess.
uint8_t expected[kArgoStateLength] = {
0xAC, 0xF5, 0x00, 0x24, 0x02, 0x00, 0x00, 0x00, 0x00, 0xAC, 0xD6, 0x01};
EXPECT_STATE_EQ(expected, ac.getRaw(), kArgoBits);
EXPECT_EQ(
"Power: On, Mode: 0 (Cool), Fan: 0 (Auto), Temp: 20C, Room Temp: 21C, "
"Max: On, IFeel: On, Night: On",
ac.toString());
}
// Tests for sendArgo().
// Test sending typical data only.
TEST(TestSendArgo, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
uint8_t data[kArgoStateLength] = {
0xAC, 0xF5, 0x00, 0x24, 0x02, 0x00, 0x00, 0x00, 0x00, 0xAC, 0xD6, 0x01};
irsend.sendArgo(data);
EXPECT_EQ(
"f38000d50"
"m6400s3300"
"m400s900m400s900m400s2200m400s2200m400s900m400s2200m400s900m400s2200"
"m400s2200m400s900m400s2200m400s900m400s2200m400s2200m400s2200m400s2200"
"m400s900m400s900m400s900m400s900m400s900m400s900m400s900m400s900"
"m400s900m400s900m400s2200m400s900m400s900m400s2200m400s900m400s900"
"m400s900m400s2200m400s900m400s900m400s900m400s900m400s900m400s900"
"m400s900m400s900m400s900m400s900m400s900m400s900m400s900m400s900"
"m400s900m400s900m400s900m400s900m400s900m400s900m400s900m400s900"
"m400s900m400s900m400s900m400s900m400s900m400s900m400s900m400s900"
"m400s900m400s900m400s900m400s900m400s900m400s900m400s900m400s900"
"m400s900m400s900m400s2200m400s2200m400s900m400s2200m400s900m400s2200"
"m400s900m400s2200m400s2200m400s900m400s2200m400s900m400s2200m400s2200"
"m400s2200m400s900m400s900m400s900m400s900m400s900m400s900"
"m400s900",
irsend.outputStr());
}
// Tests for decodeArgo().
// Decode normal Argo messages.
TEST(TestDecodeArgo, SyntheticDecode) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Synthesised Normal Argo message.
irsend.reset();
uint8_t expectedState[kArgoStateLength] = {
0xAC, 0xF5, 0x00, 0x24, 0x02, 0x00, 0x00, 0x00, 0x00, 0xAC, 0xD6, 0x01};
irsend.sendArgo(expectedState);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::ARGO, irsend.capture.decode_type);
EXPECT_EQ(kArgoBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"Power: On, Mode: 0 (Cool), Fan: 0 (Auto), Temp: 20C, Room Temp: 21C, "
"Max: On, IFeel: On, Night: On",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestArgoACClass, SetAndGetTemp) {
IRArgoAC ac(0);
ac.setTemp(25);
EXPECT_EQ(25, ac.getTemp());
ac.setTemp(kArgoMinTemp);
EXPECT_EQ(kArgoMinTemp, ac.getTemp());
ac.setTemp(kArgoMaxTemp);
EXPECT_EQ(kArgoMaxTemp, ac.getTemp());
ac.setTemp(kArgoMinTemp - 1);
EXPECT_EQ(kArgoMinTemp, ac.getTemp());
ac.setTemp(kArgoMaxTemp + 1);
EXPECT_EQ(kArgoMaxTemp, ac.getTemp());
}
TEST(TestArgoACClass, SetAndGetRoomTemp) {
IRArgoAC ac(0);
ac.setRoomTemp(25);
EXPECT_EQ(25, ac.getRoomTemp());
ac.setRoomTemp(kArgoTempDelta);
EXPECT_EQ(kArgoTempDelta, ac.getRoomTemp());
ac.setRoomTemp(kArgoMaxRoomTemp);
EXPECT_EQ(kArgoMaxRoomTemp, ac.getRoomTemp());
ac.setRoomTemp(kArgoTempDelta - 1);
EXPECT_EQ(kArgoTempDelta, ac.getRoomTemp());
ac.setRoomTemp(kArgoMaxRoomTemp + 1);
EXPECT_EQ(kArgoMaxRoomTemp, ac.getRoomTemp());
}
TEST(TestArgoACClass, SetAndGetMode) {
IRArgoAC ac(0);
ac.setMode(kArgoHeat);
EXPECT_EQ(kArgoHeat, ac.getMode());
ac.setMode(kArgoCool);
EXPECT_EQ(kArgoCool, ac.getMode());
ac.setMode(kArgoDry);
EXPECT_EQ(kArgoDry, ac.getMode());
ac.setMode(kArgoAuto);
EXPECT_EQ(kArgoAuto, ac.getMode());
ac.setMode(kArgoHeatAuto);
EXPECT_EQ(kArgoHeatAuto, ac.getMode());
ac.setMode(kArgoOff);
EXPECT_EQ(kArgoOff, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kArgoAuto, ac.getMode());
}
TEST(TestArgoACClass, SetAndGetFan) {
IRArgoAC ac(0);
ac.setFan(kArgoFan3);
EXPECT_EQ(kArgoFan3, ac.getFan());
ac.setFan(kArgoFan1);
EXPECT_EQ(kArgoFan1, ac.getFan());
ac.setFan(kArgoFanAuto);
EXPECT_EQ(kArgoFanAuto, ac.getFan());
ac.setFan(kArgoFan3);
EXPECT_EQ(kArgoFan3, ac.getFan());
ASSERT_NE(7, kArgoFan3);
// Now try some unexpected value.
ac.setFan(7);
EXPECT_EQ(kArgoFan3, ac.getFan());
}
TEST(TestArgoACClass, Night) {
IRArgoAC ac(0);
ac.setNight(false);
ASSERT_FALSE(ac.getNight());
ac.setNight(true);
ASSERT_TRUE(ac.getNight());
ac.setNight(false);
ASSERT_FALSE(ac.getNight());
}
TEST(TestArgoACClass, iFeel) {
IRArgoAC ac(0);
ac.setiFeel(false);
ASSERT_FALSE(ac.getiFeel());
ac.setiFeel(true);
ASSERT_TRUE(ac.getiFeel());
ac.setiFeel(false);
ASSERT_FALSE(ac.getiFeel());
}
TEST(TestArgoACClass, Power) {
IRArgoAC ac(0);
ac.setPower(false);
ASSERT_FALSE(ac.getPower());
ac.setPower(true);
ASSERT_TRUE(ac.getPower());
ac.setPower(false);
ASSERT_FALSE(ac.getPower());
}
TEST(TestArgoACClass, Max) {
IRArgoAC ac(0);
ac.setMax(false);
ASSERT_FALSE(ac.getMax());
ac.setMax(true);
ASSERT_TRUE(ac.getMax());
ac.setMax(false);
ASSERT_FALSE(ac.getMax());
}
TEST(TestUtils, Housekeeping) {
ASSERT_EQ("ARGO", typeToString(decode_type_t::ARGO));
ASSERT_EQ(decode_type_t::ARGO, strToDecodeType("ARGO"));
ASSERT_TRUE(hasACState(decode_type_t::ARGO));
}

View File

@@ -0,0 +1,614 @@
// Copyright 2018, 2020 David Conran
#include "ir_Carrier.h"
#include "IRac.h"
#include "IRrecv.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendCarrierAC()
// Test sending typical data only.
TEST(TestSendCarrierAC, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
irsend.sendCarrierAC(0x0);
EXPECT_EQ(
"f38000d50"
"m8532s4228"
"m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532"
"m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532"
"m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532"
"m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532"
"m628s20000"
"m8532s4228"
"m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320"
"m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320"
"m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320"
"m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320"
"m628s20000"
"m8532s4228"
"m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532"
"m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532"
"m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532"
"m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532"
"m628s20000",
irsend.outputStr());
irsend.reset();
irsend.sendCarrierAC(0x12345678);
EXPECT_EQ(
"f38000d50"
"m8532s4228"
"m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532"
"m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532"
"m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532"
"m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532"
"m628s20000"
"m8532s4228"
"m628s1320m628s1320m628s1320m628s532m628s1320m628s1320m628s532m628s1320"
"m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s1320"
"m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532m628s1320"
"m628s1320m628s532m628s532m628s532m628s532m628s1320m628s1320m628s1320"
"m628s20000"
"m8532s4228"
"m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532"
"m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532"
"m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532"
"m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532"
"m628s20000",
irsend.outputStr());
irsend.reset();
irsend.sendCarrierAC(0x4CCA541D);
EXPECT_EQ(
"f38000d50"
"m8532s4228"
"m628s532m628s1320m628s532m628s532m628s1320m628s1320m628s532m628s532"
"m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s532"
"m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532"
"m628s532m628s532m628s532m628s1320m628s1320m628s1320m628s532m628s1320"
"m628s20000"
"m8532s4228"
"m628s1320m628s532m628s1320m628s1320m628s532m628s532m628s1320m628s1320"
"m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s1320"
"m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320"
"m628s1320m628s1320m628s1320m628s532m628s532m628s532m628s1320m628s532"
"m628s20000"
"m8532s4228"
"m628s532m628s1320m628s532m628s532m628s1320m628s1320m628s532m628s532"
"m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s532"
"m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532"
"m628s532m628s532m628s532m628s1320m628s1320m628s1320m628s532m628s1320"
"m628s20000",
irsend.outputStr());
}
// Test sending typical data only.
TEST(TestSendCarrierAC, SendWithRepeats) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
irsend.sendCarrierAC(0x12345678, kCarrierAcBits, 2); // two repeats.
EXPECT_EQ(
"f38000d50"
"m8532s4228"
"m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532"
"m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532"
"m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532"
"m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532"
"m628s20000"
"m8532s4228"
"m628s1320m628s1320m628s1320m628s532m628s1320m628s1320m628s532m628s1320"
"m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s1320"
"m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532m628s1320"
"m628s1320m628s532m628s532m628s532m628s532m628s1320m628s1320m628s1320"
"m628s20000"
"m8532s4228"
"m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532"
"m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532"
"m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532"
"m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532"
"m628s20000"
"m8532s4228"
"m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532"
"m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532"
"m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532"
"m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532"
"m628s20000"
"m8532s4228"
"m628s1320m628s1320m628s1320m628s532m628s1320m628s1320m628s532m628s1320"
"m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s1320"
"m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532m628s1320"
"m628s1320m628s532m628s532m628s532m628s532m628s1320m628s1320m628s1320"
"m628s20000"
"m8532s4228"
"m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532"
"m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532"
"m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532"
"m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532"
"m628s20000"
"m8532s4228"
"m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532"
"m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532"
"m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532"
"m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532"
"m628s20000"
"m8532s4228"
"m628s1320m628s1320m628s1320m628s532m628s1320m628s1320m628s532m628s1320"
"m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s1320"
"m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532m628s1320"
"m628s1320m628s532m628s532m628s532m628s532m628s1320m628s1320m628s1320"
"m628s20000"
"m8532s4228"
"m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532"
"m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532"
"m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532"
"m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532"
"m628s20000",
irsend.outputStr());
}
// Tests for decodeCarrierAC().
// Decode normal "synthetic" messages.
TEST(TestDecodeCarrierAC, NormalDecodeWithStrict) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
irsend.sendCarrierAC(0x0);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeCarrierAC(&irsend.capture, kStartOffset,
kCarrierAcBits, true));
EXPECT_EQ(CARRIER_AC, irsend.capture.decode_type);
EXPECT_EQ(kCarrierAcBits, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
irsend.reset();
irsend.sendCarrierAC(0xB335ABE2);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeCarrierAC(&irsend.capture, kStartOffset,
kCarrierAcBits, true));
EXPECT_EQ(CARRIER_AC, irsend.capture.decode_type);
EXPECT_EQ(kCarrierAcBits, irsend.capture.bits);
EXPECT_EQ(0xB335ABE2, irsend.capture.value);
EXPECT_EQ(0xB335, irsend.capture.address);
EXPECT_EQ(0xABE2, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Do the last one again, & use the full decoder, not just protocol specific.
irsend.reset();
irsend.sendCarrierAC(0xB335ABE2);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(CARRIER_AC, irsend.capture.decode_type);
EXPECT_EQ(kCarrierAcBits, irsend.capture.bits);
EXPECT_EQ(0xB335ABE2, irsend.capture.value);
}
// Decode a "real" example message.
TEST(TestDecodeCarrierAC, RealExamples) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
// Data from Issue #385 captured by gnkarn
uint16_t rawData[203] = {
8532, 4216, 628, 1312, 628, 528, 628, 1312, 628, 1312, 628, 528,
628, 524, 628, 1316, 624, 1316, 628, 524, 628, 528, 628, 1312,
628, 1316, 624, 528, 628, 1312, 628, 528, 628, 1312, 628, 1312,
628, 528, 628, 1316, 624, 528, 628, 1312, 628, 528, 628, 1312,
628, 1316, 624, 1316, 628, 1312, 628, 1316, 628, 524, 628, 528,
628, 528, 624, 1316, 628, 528, 628, 20064, 8504, 4228, 628, 528,
628, 1312, 628, 528, 628, 528, 628, 1312, 628, 1316, 624, 532,
624, 528, 628, 1316, 628, 1312, 628, 528, 628, 528, 628, 1312,
628, 528, 628, 1316, 628, 528, 624, 528, 628, 1316, 628, 528,
628, 1316, 624, 528, 628, 1316, 628, 528, 624, 532, 624, 528,
628, 528, 628, 528, 628, 1316, 624, 1316, 628, 1316, 628, 528,
624, 1316, 628, 20076, 8528, 4212, 624, 1316, 628, 528, 628, 1316,
628, 1316, 624, 528, 628, 528, 628, 1316, 628, 1316, 628, 528,
624, 532, 624, 1316, 628, 1316, 628, 528, 628, 1316, 624, 528,
628, 1316, 628, 1316, 628, 528, 628, 1316, 624, 532, 624, 1316,
628, 532, 624, 1316, 628, 1316, 624, 1320, 624, 1316, 628, 1316,
628, 528, 628, 528, 628, 528, 628, 1316, 624, 532, 624};
irsend.sendRaw(rawData, 203, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(CARRIER_AC, irsend.capture.decode_type);
EXPECT_EQ(kCarrierAcBits, irsend.capture.bits);
EXPECT_EQ(0xB335ABE2, irsend.capture.value);
EXPECT_EQ(0xB335, irsend.capture.address);
EXPECT_EQ(0xABE2, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
TEST(TestUtils, Housekeeping) {
// CARRIER_AC
ASSERT_EQ("CARRIER_AC", typeToString(decode_type_t::CARRIER_AC));
ASSERT_EQ(decode_type_t::CARRIER_AC, strToDecodeType("CARRIER_AC"));
ASSERT_FALSE(hasACState(decode_type_t::CARRIER_AC));
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::CARRIER_AC));
ASSERT_EQ(kCarrierAcBits,
IRsend::defaultBits(decode_type_t::CARRIER_AC));
ASSERT_EQ(kCarrierAcMinRepeat,
IRsend::minRepeats(decode_type_t::CARRIER_AC));
// CARRIER_AC40
ASSERT_EQ("CARRIER_AC40", typeToString(decode_type_t::CARRIER_AC40));
ASSERT_EQ(decode_type_t::CARRIER_AC40, strToDecodeType("CARRIER_AC40"));
ASSERT_FALSE(hasACState(decode_type_t::CARRIER_AC40));
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::CARRIER_AC40));
ASSERT_EQ(kCarrierAc40Bits,
IRsend::defaultBits(decode_type_t::CARRIER_AC40));
ASSERT_EQ(kCarrierAc40MinRepeat,
IRsend::minRepeats(decode_type_t::CARRIER_AC40));
// CARRIER_AC64
ASSERT_EQ("CARRIER_AC64", typeToString(decode_type_t::CARRIER_AC64));
ASSERT_EQ(decode_type_t::CARRIER_AC64, strToDecodeType("CARRIER_AC64"));
ASSERT_FALSE(hasACState(decode_type_t::CARRIER_AC64));
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::CARRIER_AC64));
ASSERT_EQ(kCarrierAc64Bits,
IRsend::defaultBits(decode_type_t::CARRIER_AC64));
ASSERT_EQ(kCarrierAc64MinRepeat,
IRsend::minRepeats(decode_type_t::CARRIER_AC64));
}
/// Decode a "real" example message.
TEST(TestDecodeCarrierAC40, RealExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
// Data from:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1112#issuecomment-627961192
const uint16_t rawData[83] = {
8402, 4166,
562, 1550, 538, 1526, 562, 1552, 538, 1524, 566, 504, 538, 504, 540, 480,
564, 506, 538, 506, 538, 506, 538, 1550, 538, 1550, 540, 506, 538, 506,
538, 1550, 538, 506, 540, 478, 564, 480, 564, 506, 540, 1550, 538, 506,
540, 506, 538, 1524, 564, 506, 538, 1550, 538, 1550, 538, 482, 562, 482,
562, 506, 540, 504, 540, 482, 562, 506, 538, 1550, 538, 1550, 540, 1524,
564, 1526, 564, 480, 564, 1528, 562, 504, 540, 480,
564}; // UNKNOWN BCF4730D
irsend.sendRaw(rawData, 83, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(CARRIER_AC40, irsend.capture.decode_type);
EXPECT_EQ(kCarrierAc40Bits, irsend.capture.bits);
EXPECT_EQ(0xF03212C0F4, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
}
/// Send & Decode a synthetic message.
TEST(TestDecodeCarrierAC40, SyntheticExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
irsend.sendCarrierAC40(0xF03212C0F4);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(CARRIER_AC40, irsend.capture.decode_type);
EXPECT_EQ(kCarrierAc40Bits, irsend.capture.bits);
EXPECT_EQ(0xF03212C0F4, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
// Payload is sent a total of three times.
EXPECT_EQ(
"f38000d50"
// Initial
"m8402s4166"
"m547s1540m547s1540m547s1540m547s1540m547s497m547s497m547s497m547s497"
"m547s497m547s497m547s1540m547s1540m547s497m547s497m547s1540m547s497"
"m547s497m547s497m547s497m547s1540m547s497m547s497m547s1540m547s497"
"m547s1540m547s1540m547s497m547s497m547s497m547s497m547s497m547s497"
"m547s1540m547s1540m547s1540m547s1540m547s497m547s1540m547s497m547s497"
"m547s150000"
// Repeat #1
"m8402s4166"
"m547s1540m547s1540m547s1540m547s1540m547s497m547s497m547s497m547s497"
"m547s497m547s497m547s1540m547s1540m547s497m547s497m547s1540m547s497"
"m547s497m547s497m547s497m547s1540m547s497m547s497m547s1540m547s497"
"m547s1540m547s1540m547s497m547s497m547s497m547s497m547s497m547s497"
"m547s1540m547s1540m547s1540m547s1540m547s497m547s1540m547s497m547s497"
"m547s150000"
// Repeat #2
"m8402s4166"
"m547s1540m547s1540m547s1540m547s1540m547s497m547s497m547s497m547s497"
"m547s497m547s497m547s1540m547s1540m547s497m547s497m547s1540m547s497"
"m547s497m547s497m547s497m547s1540m547s497m547s497m547s1540m547s497"
"m547s1540m547s1540m547s497m547s497m547s497m547s497m547s497m547s497"
"m547s1540m547s1540m547s1540m547s1540m547s497m547s1540m547s497m547s497"
"m547s150000",
irsend.outputStr());
}
/// Decode a "real" example message.
TEST(TestDecodeCarrierAC64, RealExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
// Data from:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1127#issuecomment-629713855
const uint16_t rawData[131] = {
8940, 4556,
504, 616, 504, 616, 502, 1736, 504, 616, 504, 616, 504, 616, 502, 616,
502, 1736, 504, 1736, 502, 616, 504, 1736, 504, 616, 502, 1736, 504, 616,
502, 1736, 502, 616, 504, 616, 504, 1736, 502, 1736, 504, 1736, 502, 1736,
504, 616, 502, 1736, 502, 616, 504, 616, 504, 1736, 504, 1736, 504, 1736,
504, 616, 504, 1736, 502, 616, 502, 616, 504, 616, 504, 616, 502, 616,
502, 616, 504, 1736, 504, 616, 504, 616, 502, 616, 504, 616, 504, 616,
502, 616, 502, 616, 504, 616, 504, 616, 504, 616, 502, 616, 504, 616,
504, 616, 502, 616, 502, 616, 504, 616, 504, 616, 504, 1736, 504, 616,
504, 616, 504, 616, 504, 616, 504, 616, 504, 616, 504, 616, 502, 1736,
504, 586, 502};
irsend.sendRaw(rawData, 131, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(CARRIER_AC64, irsend.capture.decode_type);
EXPECT_EQ(kCarrierAc64Bits, irsend.capture.bits);
EXPECT_EQ(0x404000102E5E5584, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
EXPECT_EQ(
"Power: On, Mode: 1 (Heat), Temp: 30C, Fan: 1 (Low), Swing(V): On, "
"Sleep: Off, On Timer: Off, Off Timer: Off",
IRAcUtils::resultAcToString(&irsend.capture));
}
/// Send & Decode a synthetic message.
TEST(TestDecodeCarrierAC64, SyntheticExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
irsend.sendCarrierAC64(0x404000102E5E5584);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(CARRIER_AC64, irsend.capture.decode_type);
EXPECT_EQ(kCarrierAc64Bits, irsend.capture.bits);
EXPECT_EQ(0x404000102E5E5584, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
EXPECT_EQ(
"f38000d50m"
// Header
"8940s4556"
// Data
"m503s615m503s615m503s1736m503s615m503s615m503s615m503s615m503s1736"
"m503s1736m503s615m503s1736m503s615m503s1736m503s615m503s1736m503s615"
"m503s615m503s1736m503s1736m503s1736m503s1736m503s615m503s1736m503s615"
"m503s615m503s1736m503s1736m503s1736m503s615m503s1736m503s615m503s615"
"m503s615m503s615m503s615m503s615m503s1736m503s615m503s615m503s615"
"m503s615m503s615m503s615m503s615m503s615m503s615m503s615m503s615"
"m503s615m503s615m503s615m503s615m503s615m503s615m503s1736m503s615"
"m503s615m503s615m503s615m503s615m503s615m503s615m503s1736m503s615"
// Footer
"m503s100000",
irsend.outputStr());
}
// Tests for IRCarrierAc64 class.
TEST(TestCarrierAc64Class, Power) {
IRCarrierAc64 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());
ASSERT_EQ(36, kCarrierAc64PowerOffset);
}
TEST(TestCarrierAc64Class, Temperature) {
IRCarrierAc64 ac(kGpioUnused);
ac.begin();
ac.setTemp(0);
EXPECT_EQ(kCarrierAc64MinTemp, ac.getTemp());
ac.setTemp(255);
EXPECT_EQ(kCarrierAc64MaxTemp, ac.getTemp());
ac.setTemp(kCarrierAc64MinTemp);
EXPECT_EQ(kCarrierAc64MinTemp, ac.getTemp());
ac.setTemp(kCarrierAc64MaxTemp);
EXPECT_EQ(kCarrierAc64MaxTemp, ac.getTemp());
ac.setTemp(kCarrierAc64MinTemp - 1);
EXPECT_EQ(kCarrierAc64MinTemp, ac.getTemp());
ac.setTemp(kCarrierAc64MaxTemp + 1);
EXPECT_EQ(kCarrierAc64MaxTemp, 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(TestCarrierAc64Class, OperatingMode) {
IRCarrierAc64 ac(kGpioUnused);
ac.begin();
ac.setMode(kCarrierAc64Cool);
EXPECT_EQ(kCarrierAc64Cool, ac.getMode());
ac.setMode(kCarrierAc64Fan);
EXPECT_EQ(kCarrierAc64Fan, ac.getMode());
ac.setMode(kCarrierAc64Heat);
EXPECT_EQ(kCarrierAc64Heat, ac.getMode());
ac.setMode(kCarrierAc64Fan + 1);
EXPECT_EQ(kCarrierAc64Cool, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kCarrierAc64Cool, ac.getMode());
ac.setMode(0);
EXPECT_EQ(kCarrierAc64Cool, ac.getMode());
}
TEST(TestCarrierAc64Class, Sleep) {
IRCarrierAc64 ac(kGpioUnused);
ac.begin();
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
ac.setSleep(false);
EXPECT_FALSE(ac.getSleep());
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
}
TEST(TestCarrierAc64Class, SwingVertical) {
IRCarrierAc64 ac(kGpioUnused);
ac.begin();
ac.setSwingV(true);
EXPECT_TRUE(ac.getSwingV());
ac.setSwingV(false);
EXPECT_FALSE(ac.getSwingV());
ac.setSwingV(true);
EXPECT_TRUE(ac.getSwingV());
}
TEST(TestCarrierAc64Class, FanSpeed) {
IRCarrierAc64 ac(kGpioUnused);
ac.begin();
// Unexpected value should default to Auto.
ac.setFan(255);
EXPECT_EQ(kCarrierAc64FanAuto, ac.getFan());
ac.setFan(5);
EXPECT_EQ(kCarrierAc64FanAuto, ac.getFan());
ac.setFan(kCarrierAc64FanHigh);
EXPECT_EQ(kCarrierAc64FanHigh, ac.getFan());
// Beyond High should default to Auto.
ac.setFan(kCarrierAc64FanHigh + 1);
EXPECT_EQ(kCarrierAc64FanAuto, ac.getFan());
ac.setFan(kCarrierAc64FanMedium);
EXPECT_EQ(kCarrierAc64FanMedium, ac.getFan());
ac.setFan(kCarrierAc64FanLow);
EXPECT_EQ(kCarrierAc64FanLow, ac.getFan());
ac.setFan(kCarrierAc64FanAuto);
EXPECT_EQ(kCarrierAc64FanAuto, ac.getFan());
}
TEST(TestCarrierAc64Class, ChecksumAndSetGetRaw) {
IRCarrierAc64 ac(kGpioUnused);
const uint64_t valid = 0x90900030205C5584;
const uint64_t invalid = 0x9090003020505584;
ASSERT_NE(valid, invalid);
ASSERT_EQ(0x0C, IRCarrierAc64::calcChecksum(valid));
ASSERT_TRUE(IRCarrierAc64::validChecksum(valid));
ASSERT_FALSE(IRCarrierAc64::validChecksum(invalid));
ac.setRaw(valid);
ASSERT_EQ(valid, ac.getRaw());
ac.setRaw(invalid);
ASSERT_EQ(valid, ac.getRaw());
// Additional known states.
ASSERT_TRUE(IRCarrierAc64::validChecksum(0x109000002C2A5584));
ASSERT_TRUE(IRCarrierAc64::validChecksum(0x109000102C2B5584));
}
// Test human readable output.
TEST(TestCarrierAc64Class, HumanReadable) {
IRCarrierAc64 ac(kGpioUnused);
EXPECT_EQ(
"Power: Off, Mode: 2 (Cool), Temp: 28C, Fan: 0 (Auto), Swing(V): On, "
"Sleep: Off, On Timer: Off, Off Timer: Off",
ac.toString());
ac.setPower(true);
ac.setMode(kCarrierAc64Fan);
ac.setTemp(30);
ac.setFan(kCarrierAc64FanAuto);
ac.setSwingV(true);
EXPECT_EQ(
"Power: On, Mode: 3 (Fan), Temp: 30C, Fan: 0 (Auto), Swing(V): On, "
"Sleep: Off, On Timer: Off, Off Timer: Off",
ac.toString());
ac.setOffTimer(8* 60 + 37);
EXPECT_EQ(
"Power: On, Mode: 3 (Fan), Temp: 30C, Fan: 0 (Auto), Swing(V): On, "
"Sleep: Off, On Timer: Off, Off Timer: 08:00",
ac.toString());
ac.setOnTimer(5 * 60 + 59);
EXPECT_EQ(
"Power: On, Mode: 3 (Fan), Temp: 30C, Fan: 0 (Auto), Swing(V): On, "
"Sleep: Off, On Timer: 05:00, Off Timer: Off",
ac.toString());
ac.setOnTimer(59);
EXPECT_EQ(
"Power: On, Mode: 3 (Fan), Temp: 30C, Fan: 0 (Auto), Swing(V): On, "
"Sleep: Off, On Timer: Off, Off Timer: Off",
ac.toString());
ac.setSleep(true);
EXPECT_EQ(
"Power: On, Mode: 3 (Fan), Temp: 30C, Fan: 0 (Auto), Swing(V): On, "
"Sleep: On, On Timer: Off, Off Timer: Off",
ac.toString());
}
TEST(TestCarrierAc64Class, ReconstructKnownState) {
IRCarrierAc64 ac(kGpioUnused);
const uint64_t expected = 0x2030009020555584;
ac.begin();
ac.stateReset();
ASSERT_NE(expected, ac.getRaw());
ac.on();
ac.setMode(kCarrierAc64Heat);
ac.setTemp(16);
ac.setFan(kCarrierAc64FanLow);
ac.setSwingV(true);
ac.setOnTimer(3 * 60);
ac.setSleep(true);
EXPECT_EQ(expected, ac.getRaw());
EXPECT_EQ(
"Power: On, Mode: 1 (Heat), Temp: 16C, Fan: 1 (Low), Swing(V): On, "
"Sleep: On, On Timer: Off, Off Timer: Off",
ac.toString());
}

View File

@@ -0,0 +1,856 @@
// Copyright 2017-2018 David Conran
#include "ir_Coolix.h"
#include "IRac.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendCOOLIX().
// Test sending typical data only.
TEST(TestSendCoolix, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendCOOLIX(0x0);
EXPECT_EQ(
"f38000d50"
"m4692s4416"
"m552s552m552s552m552s552m552s552m552s552m552s552m552s552m552s552"
"m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656"
"m552s552m552s552m552s552m552s552m552s552m552s552m552s552m552s552"
"m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656"
"m552s552m552s552m552s552m552s552m552s552m552s552m552s552m552s552"
"m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656"
"m552s5244"
"m4692s4416"
"m552s552m552s552m552s552m552s552m552s552m552s552m552s552m552s552"
"m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656"
"m552s552m552s552m552s552m552s552m552s552m552s552m552s552m552s552"
"m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656"
"m552s552m552s552m552s552m552s552m552s552m552s552m552s552m552s552"
"m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656"
"m552s105244",
irsend.outputStr());
irsend.reset();
irsend.sendCOOLIX(0xAA55AA);
EXPECT_EQ(
"f38000d50"
"m4692s4416"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s5244"
"m4692s4416"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s105244",
irsend.outputStr());
irsend.reset();
irsend.sendCOOLIX(0xFFFFFF);
EXPECT_EQ(
"f38000d50"
"m4692s4416"
"m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656"
"m552s552m552s552m552s552m552s552m552s552m552s552m552s552m552s552"
"m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656"
"m552s552m552s552m552s552m552s552m552s552m552s552m552s552m552s552"
"m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656"
"m552s552m552s552m552s552m552s552m552s552m552s552m552s552m552s552"
"m552s5244"
"m4692s4416"
"m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656"
"m552s552m552s552m552s552m552s552m552s552m552s552m552s552m552s552"
"m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656"
"m552s552m552s552m552s552m552s552m552s552m552s552m552s552m552s552"
"m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656"
"m552s552m552s552m552s552m552s552m552s552m552s552m552s552m552s552"
"m552s105244",
irsend.outputStr());
}
// Test sending with different repeats.
TEST(TestSendCoolix, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendCOOLIX(0xAA55AA, kCoolixBits, 1); // 1 repeat.
EXPECT_EQ(
"f38000d50"
"m4692s4416"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s5244"
"m4692s4416"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s105244",
irsend.outputStr());
irsend.sendCOOLIX(0xAA55AA, kCoolixBits, 2); // 2 repeats.
EXPECT_EQ(
"f38000d50"
"m4692s4416"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s5244"
"m4692s4416"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s5244"
"m4692s4416"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656"
"m552s105244",
irsend.outputStr());
}
// Test sending an atypical data size.
TEST(TestSendCoolix, SendUnusualSize) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendCOOLIX(0x0, 8);
EXPECT_EQ(
"f38000d50"
"m4692s4416"
"m552s552m552s552m552s552m552s552m552s552m552s552m552s552m552s552"
"m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656"
"m552s5244"
"m4692s4416"
"m552s552m552s552m552s552m552s552m552s552m552s552m552s552m552s552"
"m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656"
"m552s105244",
irsend.outputStr());
irsend.reset();
irsend.sendCOOLIX(0x1234567890ABCDEF, 64);
EXPECT_EQ(
"f38000d50"
"m4692s4416"
"m552s552m552s552m552s552m552s1656m552s552m552s552m552s1656m552s552"
"m552s1656m552s1656m552s1656m552s552m552s1656m552s1656m552s552m552s1656"
"m552s552m552s552m552s1656m552s1656m552s552m552s1656m552s552m552s552"
"m552s1656m552s1656m552s552m552s552m552s1656m552s552m552s1656m552s1656"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s1656m552s552"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s552m552s1656"
"m552s552m552s1656m552s1656m552s1656m552s1656m552s552m552s552m552s552"
"m552s1656m552s552m552s552m552s552m552s552m552s1656m552s1656m552s1656"
"m552s1656m552s552m552s552m552s1656m552s552m552s552m552s552m552s552"
"m552s552m552s1656m552s1656m552s552m552s1656m552s1656m552s1656m552s1656"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s1656"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s552"
"m552s1656m552s1656m552s552m552s552m552s1656m552s1656m552s552m552s1656"
"m552s552m552s552m552s1656m552s1656m552s552m552s552m552s1656m552s552"
"m552s1656m552s1656m552s1656m552s552m552s1656m552s1656m552s1656m552s1656"
"m552s552m552s552m552s552m552s1656m552s552m552s552m552s552m552s552"
"m552s5244"
"m4692s4416"
"m552s552m552s552m552s552m552s1656m552s552m552s552m552s1656m552s552"
"m552s1656m552s1656m552s1656m552s552m552s1656m552s1656m552s552m552s1656"
"m552s552m552s552m552s1656m552s1656m552s552m552s1656m552s552m552s552"
"m552s1656m552s1656m552s552m552s552m552s1656m552s552m552s1656m552s1656"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s1656m552s552"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s552m552s1656"
"m552s552m552s1656m552s1656m552s1656m552s1656m552s552m552s552m552s552"
"m552s1656m552s552m552s552m552s552m552s552m552s1656m552s1656m552s1656"
"m552s1656m552s552m552s552m552s1656m552s552m552s552m552s552m552s552"
"m552s552m552s1656m552s1656m552s552m552s1656m552s1656m552s1656m552s1656"
"m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s1656"
"m552s552m552s1656m552s552m552s1656m552s552m552s1656m552s552m552s552"
"m552s1656m552s1656m552s552m552s552m552s1656m552s1656m552s552m552s1656"
"m552s552m552s552m552s1656m552s1656m552s552m552s552m552s1656m552s552"
"m552s1656m552s1656m552s1656m552s552m552s1656m552s1656m552s1656m552s1656"
"m552s552m552s552m552s552m552s1656m552s552m552s552m552s552m552s552"
"m552s105244",
irsend.outputStr());
// Bit sizes must be a multiple of 8.
irsend.reset();
irsend.sendCOOLIX(0x0, 17);
EXPECT_EQ("", irsend.outputStr());
}
// Tests for decodeCOOLIX().
// Decode normal Coolix messages.
TEST(TestDecodeCoolix, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Coolix 24-bit message.
irsend.reset();
irsend.sendCOOLIX(0x123456);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeCOOLIX(&irsend.capture, kStartOffset, kCoolixBits,
true));
EXPECT_EQ(COOLIX, irsend.capture.decode_type);
EXPECT_EQ(kCoolixBits, irsend.capture.bits);
EXPECT_EQ(0x123456, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal Coolix 24-bit message.
irsend.reset();
irsend.sendCOOLIX(0x0);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeCOOLIX(&irsend.capture, kStartOffset, kCoolixBits,
true));
EXPECT_EQ(COOLIX, irsend.capture.decode_type);
EXPECT_EQ(kCoolixBits, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal Coolix 24-bit message.
irsend.reset();
irsend.sendCOOLIX(0xFFFFFF);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeCOOLIX(&irsend.capture, kStartOffset, kCoolixBits,
true));
EXPECT_EQ(COOLIX, irsend.capture.decode_type);
EXPECT_EQ(kCoolixBits, irsend.capture.bits);
EXPECT_EQ(0xFFFFFF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode normal repeated Coolix messages.
TEST(TestDecodeCoolix, NormalDecodeWithRepeatAndStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Coolix 16-bit message with 2 repeats.
irsend.reset();
irsend.sendCOOLIX(0x123456, kCoolixBits, 2);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeCOOLIX(&irsend.capture, kStartOffset, kCoolixBits,
true));
EXPECT_EQ(COOLIX, irsend.capture.decode_type);
EXPECT_EQ(kCoolixBits, irsend.capture.bits);
EXPECT_EQ(0x123456, irsend.capture.value);
EXPECT_FALSE(irsend.capture.repeat);
irsend.makeDecodeResult(4 * kCoolixBits + 4);
ASSERT_TRUE(irrecv.decodeCOOLIX(&irsend.capture, kStartOffset, kCoolixBits,
true));
EXPECT_EQ(COOLIX, irsend.capture.decode_type);
EXPECT_EQ(kCoolixBits, irsend.capture.bits);
EXPECT_EQ(0x123456, irsend.capture.value);
irsend.makeDecodeResult(2 * (4 * kCoolixBits + 4));
ASSERT_TRUE(irrecv.decodeCOOLIX(&irsend.capture, kStartOffset, kCoolixBits,
true));
EXPECT_EQ(COOLIX, irsend.capture.decode_type);
EXPECT_EQ(kCoolixBits, irsend.capture.bits);
EXPECT_EQ(0x123456, irsend.capture.value);
}
// Decode unsupported Coolix messages.
TEST(TestDecodeCoolix, DecodeWithNonStrictSizes) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendCOOLIX(0x12, 8); // Illegal value Coolix 8-bit message.
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeCOOLIX(&irsend.capture, kStartOffset, kCoolixBits,
true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeCOOLIX(&irsend.capture, kStartOffset, 8, false));
EXPECT_EQ(COOLIX, irsend.capture.decode_type);
EXPECT_EQ(8, irsend.capture.bits);
EXPECT_EQ(0x12, irsend.capture.value);
irsend.reset();
irsend.sendCOOLIX(0x12345678, 32); // Illegal value Coolix 32-bit message.
irsend.makeDecodeResult();
// Shouldn't pass with strict when we ask for less bits than we got.
ASSERT_FALSE(irrecv.decodeCOOLIX(&irsend.capture, kStartOffset, kCoolixBits,
true));
irsend.makeDecodeResult();
// Should fail with strict when we ask for the wrong bit size.
ASSERT_FALSE(irrecv.decodeCOOLIX(&irsend.capture, kStartOffset, 32, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeCOOLIX(&irsend.capture, kStartOffset, 32, false));
EXPECT_EQ(COOLIX, irsend.capture.decode_type);
EXPECT_EQ(32, irsend.capture.bits);
EXPECT_EQ(0x12345678, irsend.capture.value);
// Decode should fail if asked to decode non-multiples of 8 bits.
irsend.reset();
irsend.sendCOOLIX(0x123456, kCoolixBits, 2);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeCOOLIX(&irsend.capture, kStartOffset, 9, false));
}
// Decode (non-standard) 64-bit messages.
TEST(TestDecodeCoolix, Decode64BitMessages) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Illegal size Coolix 64-bit message.
irsend.sendCOOLIX(0xFFFFFFFFFFFFFFFF, 64);
irsend.makeDecodeResult();
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeCOOLIX(&irsend.capture, kStartOffset, 64, false));
EXPECT_EQ(COOLIX, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, irsend.capture.value);
}
// Fail to decode a non-Coolix example via GlobalCache
TEST(TestDecodeCoolix, FailToDecodeNonCoolixExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Modified a few entries to unexpected values, based on previous test case.
uint16_t gc_test[39] = {38000, 1, 1, 322, 162, 20, 61, 20, 61, 20,
20, 20, 20, 20, 20, 20, 127, 20, 61, 9,
20, 20, 61, 20, 20, 20, 61, 20, 61, 20,
61, 20, 20, 20, 20, 20, 20, 20, 884};
irsend.sendGC(gc_test, 39);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeCOOLIX(&irsend.capture));
ASSERT_FALSE(irrecv.decodeCOOLIX(&irsend.capture, kStartOffset, kCoolixBits,
false));
}
// Tests for the IRCoolixAC class.
TEST(TestCoolixACClass, SetAndGetRaw) {
IRCoolixAC ircoolix(0);
ircoolix.setRaw(0xB21F28);
EXPECT_EQ(0xB21F28, ircoolix.getRaw());
ircoolix.setRaw(kCoolixDefaultState);
EXPECT_EQ(kCoolixDefaultState, ircoolix.getRaw());
}
TEST(TestCoolixACClass, SetAndGetTemp) {
IRCoolixAC ircoolix(0);
ircoolix.setTemp(25);
EXPECT_EQ(25, ircoolix.getTemp());
ircoolix.setTemp(kCoolixTempMin);
EXPECT_EQ(kCoolixTempMin, ircoolix.getTemp());
ircoolix.setTemp(kCoolixTempMax);
EXPECT_EQ(kCoolixTempMax, ircoolix.getTemp());
ircoolix.setTemp(kCoolixTempMin - 1);
EXPECT_EQ(kCoolixTempMin, ircoolix.getTemp());
ircoolix.setTemp(kCoolixTempMax + 1);
EXPECT_EQ(kCoolixTempMax, ircoolix.getTemp());
}
TEST(TestCoolixACClass, SetAndGetMode) {
IRCoolixAC ircoolix(0);
ircoolix.setMode(kCoolixHeat);
EXPECT_EQ(kCoolixHeat, ircoolix.getMode());
ircoolix.setMode(kCoolixCool);
EXPECT_EQ(kCoolixCool, ircoolix.getMode());
ircoolix.setMode(kCoolixDry);
EXPECT_EQ(kCoolixDry, ircoolix.getMode());
ircoolix.setMode(kCoolixAuto);
EXPECT_EQ(kCoolixAuto, ircoolix.getMode());
ircoolix.setMode(kCoolixFan);
EXPECT_EQ(kCoolixFan, ircoolix.getMode());
}
TEST(TestCoolixACClass, SetAndGetFan) {
IRCoolixAC ircoolix(0);
// This mode allows pretty much everything except Auto0 speed.
ircoolix.setMode(kCoolixCool);
ircoolix.setFan(kCoolixFanMax);
EXPECT_EQ(kCoolixFanMax, ircoolix.getFan());
ircoolix.setFan(kCoolixFanMin);
EXPECT_EQ(kCoolixFanMin, ircoolix.getFan());
ircoolix.setFan(kCoolixFanZoneFollow);
EXPECT_EQ(kCoolixFanZoneFollow, ircoolix.getFan());
ircoolix.setFan(kCoolixFanAuto);
EXPECT_EQ(kCoolixFanAuto, ircoolix.getFan());
ircoolix.setFan(kCoolixFanAuto0);
EXPECT_EQ(kCoolixFanAuto, ircoolix.getFan());
ircoolix.setFan(kCoolixFanMax);
EXPECT_EQ(kCoolixFanMax, ircoolix.getFan());
ASSERT_NE(3, kCoolixFanAuto);
// Now try some unexpected value.
ircoolix.setFan(3);
EXPECT_EQ(kCoolixFanAuto, ircoolix.getFan());
// These modes allows pretty much everything except Auto speed.
ircoolix.setMode(kCoolixDry);
EXPECT_EQ(kCoolixFanAuto0, ircoolix.getFan());
ircoolix.setFan(kCoolixFanMax);
EXPECT_EQ(kCoolixFanMax, ircoolix.getFan());
ircoolix.setFan(kCoolixFanAuto);
EXPECT_EQ(kCoolixFanAuto0, ircoolix.getFan());
ircoolix.setMode(kCoolixAuto);
EXPECT_EQ(kCoolixFanAuto0, ircoolix.getFan());
ircoolix.setFan(kCoolixFanMax);
EXPECT_EQ(kCoolixFanMax, ircoolix.getFan());
ircoolix.setFan(kCoolixFanAuto0);
EXPECT_EQ(kCoolixFanAuto0, ircoolix.getFan());
}
TEST(TestCoolixACClass, SetGetClearSensorTempAndZoneFollow) {
IRCoolixAC ircoolix(0);
ircoolix.setRaw(kCoolixDefaultState);
EXPECT_FALSE(ircoolix.getZoneFollow());
EXPECT_LT(kCoolixSensorTempMax, ircoolix.getSensorTemp());
ircoolix.setSensorTemp(25);
EXPECT_TRUE(ircoolix.getZoneFollow());
EXPECT_EQ(25, ircoolix.getSensorTemp());
// Lower bounds
ircoolix.setSensorTemp(kCoolixSensorTempMin);
EXPECT_TRUE(ircoolix.getZoneFollow());
EXPECT_EQ(kCoolixSensorTempMin, ircoolix.getSensorTemp());
ircoolix.setSensorTemp(kCoolixSensorTempMin - 1);
EXPECT_TRUE(ircoolix.getZoneFollow());
EXPECT_EQ(kCoolixSensorTempMin, ircoolix.getSensorTemp());
// Upper bounds
ircoolix.setSensorTemp(kCoolixSensorTempMax);
EXPECT_TRUE(ircoolix.getZoneFollow());
EXPECT_EQ(kCoolixSensorTempMax, ircoolix.getSensorTemp());
ircoolix.setSensorTemp(kCoolixSensorTempMax + 1);
EXPECT_TRUE(ircoolix.getZoneFollow());
EXPECT_EQ(kCoolixSensorTempMax, ircoolix.getSensorTemp());
// Clearing
ircoolix.clearSensorTemp();
EXPECT_FALSE(ircoolix.getZoneFollow());
EXPECT_LT(kCoolixSensorTempMax, ircoolix.getSensorTemp());
}
TEST(TestCoolixACClass, SpecialModesAndReset) {
IRCoolixAC ircoolix(0);
ASSERT_NE(kCoolixSwing, ircoolix.getRaw());
ircoolix.setSwing();
ASSERT_EQ(kCoolixSwing, ircoolix.getRaw());
ircoolix.setTurbo();
ASSERT_EQ(kCoolixTurbo, ircoolix.getRaw());
ircoolix.setSleep();
ASSERT_EQ(kCoolixSleep, ircoolix.getRaw());
ircoolix.setLed();
ASSERT_EQ(kCoolixLed, ircoolix.getRaw());
ircoolix.setClean();
ASSERT_EQ(kCoolixClean, ircoolix.getRaw());
ircoolix.stateReset();
ASSERT_NE(kCoolixClean, ircoolix.getRaw());
}
TEST(TestCoolixACClass, HumanReadable) {
IRCoolixAC ircoolix(0);
ircoolix.begin();
ircoolix.setPower(true);
// Initial starting point.
EXPECT_EQ(
"Power: On, Mode: 2 (Auto), Fan: 0 (Auto0), Temp: 25C, "
"Zone Follow: Off, Sensor Temp: Off",
ircoolix.toString());
ircoolix.setSensorTemp(24);
ircoolix.setTemp(22);
ircoolix.setMode(kCoolixCool);
ircoolix.setFan(kCoolixFanMin);
EXPECT_EQ(
"Power: On, Mode: 0 (Cool), Fan: 4 (Min), Temp: 22C, "
"Zone Follow: On, Sensor Temp: 24C",
ircoolix.toString());
ircoolix.setSwing();
EXPECT_EQ("Power: On, Swing: Toggle", ircoolix.toString());
ircoolix.setPower(false);
EXPECT_EQ("Power: Off", ircoolix.toString());
}
TEST(TestCoolixACClass, KnownExamples) {
IRCoolixAC ircoolix(0);
ircoolix.begin();
ircoolix.setPower(true);
ircoolix.setRaw(0b101100101011111111100100);
EXPECT_EQ(
"Power: On, Mode: 4 (Fan), Fan: 5 (Auto), Zone Follow: Off, "
"Sensor Temp: Off",
ircoolix.toString());
ircoolix.setRaw(0b101100101001111100000000);
EXPECT_EQ(
"Power: On, Mode: 0 (Cool), Fan: 4 (Min), Temp: 17C, "
"Zone Follow: Off, Sensor Temp: Off",
ircoolix.toString());
}
TEST(TestCoolixACClass, Issue579FanAuto0) {
IRCoolixAC ircoolix(0);
ircoolix.begin();
ircoolix.setPower(true);
ircoolix.setRaw(0xB21F28);
EXPECT_EQ(
"Power: On, Mode: 2 (Auto), Fan: 0 (Auto0), Temp: 20C, "
"Zone Follow: Off, Sensor Temp: Off",
ircoolix.toString());
}
TEST(TestCoolixACClass, RealCaptureExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
// From Issue #579
uint16_t powerOffRawData[199] = {
4444, 4434, 590, 1578, 698, 446, 590, 1578, 622, 1596, 622, 500,
644, 476, 644, 1548, 588, 532, 594, 530, 612, 1578, 590, 532,
588, 534, 672, 1518, 594, 1598, 590, 510, 612, 1580, 644, 480,
612, 1578, 644, 1548, 644, 1548, 594, 1598, 642, 506, 644, 1550,
644, 1548, 594, 1600, 644, 478, 644, 478, 642, 480, 644, 478,
642, 1548, 594, 530, 590, 532, 614, 1578, 644, 1548, 594, 1600,
588, 534, 566, 556, 588, 530, 590, 532, 586, 514, 612, 532,
588, 532, 590, 534, 588, 1578, 642, 1576, 642, 1550, 588, 1602,
588, 1580, 642, 4712, 4546, 4406, 588, 1606, 642, 478, 644, 1550,
590, 1604, 588, 534, 586, 532, 586, 1582, 642, 480, 642, 480,
668, 1550, 642, 480, 642, 478, 642, 1552, 612, 1578, 586, 538,
588, 1580, 674, 472, 590, 1602, 586, 1580, 618, 1576, 642, 1548,
594, 530, 590, 1584, 608, 1578, 644, 1550, 642, 480, 642, 478,
642, 480, 642, 480, 642, 1550, 590, 530, 592, 528, 592, 1602,
642, 1548, 592, 1604, 586, 584, 642, 480, 640, 480, 640, 480,
642, 480, 642, 480, 642, 480, 642, 480, 642, 1552, 590, 1604,
588, 1578, 642, 1552, 640, 1550, 592}; // COOLIX B27BE0
irsend.begin();
irsend.reset();
irsend.sendRaw(powerOffRawData, 199, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(COOLIX, irsend.capture.decode_type);
EXPECT_EQ(kCoolixBits, irsend.capture.bits);
EXPECT_EQ(kCoolixOff, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
// Tests to debug/fix:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/624
TEST(TestCoolixACClass, Issue624HandleSpecialStatesBetter) {
IRCoolixAC ac(0);
ac.begin();
ac.setPower(true);
// Default
EXPECT_EQ(
"Power: On, Mode: 2 (Auto), Fan: 0 (Auto0), Temp: 25C, Zone Follow: Off, "
"Sensor Temp: Off",
ac.toString());
EXPECT_EQ(0xB21FC8, ac.getRaw());
// Change of settings.
ac.setTemp(24);
ac.setMode(kCoolixCool);
ac.setFan(kCoolixFanAuto);
EXPECT_EQ(
"Power: On, Mode: 0 (Cool), Fan: 5 (Auto), Temp: 24C, Zone Follow: Off, "
"Sensor Temp: Off",
ac.toString());
EXPECT_EQ(0xB2BF40, ac.getRaw());
// Turn the unit off.
ac.setPower(false);
EXPECT_EQ(
"Power: Off",
ac.toString());
EXPECT_EQ(kCoolixOff, ac.getRaw());
// Repeat change of settings.
ac.setPower(true);
ac.setTemp(24);
ac.setMode(kCoolixCool);
ac.setFan(kCoolixFanAuto);
EXPECT_EQ(
"Power: On, Mode: 0 (Cool), Fan: 5 (Auto), Temp: 24C, Zone Follow: Off, "
"Sensor Temp: Off",
ac.toString());
EXPECT_EQ(0xB2BF40, ac.getRaw());
// Repeat change of settings.
ac.setTemp(24);
ac.setMode(kCoolixCool);
ac.setFan(kCoolixFanAuto);
EXPECT_EQ(
"Power: On, Mode: 0 (Cool), Fan: 5 (Auto), Temp: 24C, Zone Follow: Off, "
"Sensor Temp: Off",
ac.toString());
EXPECT_EQ(0xB2BF40, ac.getRaw());
}
TEST(TestCoolixACClass, toCommon) {
IRCoolixAC ac(0);
ac.begin();
ac.setPower(true);
ac.setMode(kCoolixCool);
ac.setTemp(20);
ac.setFan(kCoolixFanMax);
// Now test it.
ASSERT_EQ(decode_type_t::COOLIX, 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_FALSE(ac.toCommon().turbo);
ASSERT_FALSE(ac.toCommon().clean);
ASSERT_FALSE(ac.toCommon().light);
ASSERT_EQ(-1, ac.toCommon().sleep);
ASSERT_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kOff, ac.toCommon().swingv);
ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh);
// Unsupported.
ASSERT_FALSE(ac.toCommon().quiet);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().filter);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().clock);
}
TEST(TestCoolixACClass, Issue722) {
IRrecv irrecv(0);
IRCoolixAC ac(0);
// Auto 17C ON pressed
uint32_t on_auto_17c_fan_auto0 = 0xB21F08;
ac.begin();
ac.setPower(true);
ac.setMode(kCoolixAuto);
ac.setFan(kCoolixFanAuto);
ac.setTemp(17);
EXPECT_EQ(on_auto_17c_fan_auto0, ac.getRaw());
// Off
uint32_t off = 0xB27BE0;
ac.off();
EXPECT_EQ(off, ac.getRaw());
// ON Auto Temp 18C
uint32_t on_auto_18c_fan_auto0 = 0xB21F18;
ac.on();
ac.setTemp(18);
EXPECT_EQ(on_auto_18c_fan_auto0, ac.getRaw());
// Set Mode Cool 18C
uint32_t on_cool_18c_fan_auto = 0xB2BF10;
ac.setMode(kCoolixCool);
EXPECT_EQ(on_cool_18c_fan_auto, ac.getRaw());
// Set Mode DRY 18C
uint32_t on_dry_18c_fan_auto0 = 0xB21F14;
ac.setMode(kCoolixDry);
EXPECT_EQ(on_dry_18c_fan_auto0, ac.getRaw());
// Set Mode HEAT 18C
uint32_t on_heat_18c_fan_auto = 0xB2BF1C;
ac.setMode(kCoolixHeat);
EXPECT_EQ(on_heat_18c_fan_auto, ac.getRaw());
// Set mode FAN
uint32_t on_fan_18c_fan_auto = 0xB2BFE4;
ac.setMode(kCoolixFan);
EXPECT_EQ(on_fan_18c_fan_auto, ac.getRaw());
// Fan level 2 (initial was auto)
uint32_t on_fan_18c_fan_min = 0xB29FE4;
ac.setFan(kCoolixFanMin);
EXPECT_EQ(on_fan_18c_fan_min, ac.getRaw());
// Fan level 3
uint32_t on_fan_18c_fan_med = 0xB25FE4;
ac.setFan(kCoolixFanMed);
EXPECT_EQ(on_fan_18c_fan_med, ac.getRaw());
// Fan level 4
uint32_t on_fan_18c_fan_max = 0xB23FE4;
ac.setFan(kCoolixFanMax);
EXPECT_EQ(on_fan_18c_fan_max, ac.getRaw());
// Test sending the last message to verify the class send() method works.
ac.send();
ac._irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&ac._irsend.capture));
EXPECT_EQ(COOLIX, ac._irsend.capture.decode_type);
EXPECT_EQ(kCoolixBits, ac._irsend.capture.bits);
EXPECT_EQ(on_fan_18c_fan_max, ac._irsend.capture.value);
EXPECT_EQ(0x0, ac._irsend.capture.address);
EXPECT_EQ(0x0, ac._irsend.capture.command);
EXPECT_EQ(
// Raw data supplied by @mariusmotea
"f38000d50"
// 4434,4376,
"m4692s4416"
// 566,1614,592,504,566,1618,566,1616,568,528,564,532,564,1616,568,532,
"m552s1656m552s552m552s1656m552s1656m552s552m552s552m552s1656m552s552"
// 566,530,566,1620,568,528,566,530,566,1618,564,1618,566,530,564,1624,
"m552s552m552s1656m552s552m552s552m552s1656m552s1656m552s552m552s1656"
// 538,560,566,530,564,1620,566,1618,566,1618,566,1616,566,1616,566,1620,
"m552s552m552s552m552s1656m552s1656m552s1656m552s1656m552s1656m552s1656"
// 568,1620,566,1616,566,530,566,530,564,530,562,532,564,530,566,530,
"m552s1656m552s1656m552s552m552s552m552s552m552s552m552s552m552s552"
// 566,1622,566,1616,540,1642,566,528,566,530,566,1616,566,530,566,532,
"m552s1656m552s1656m552s1656m552s552m552s552m552s1656m552s552m552s552"
// 564,532,564,530,566,530,566,1614,566,1616,562,532,564,1620,566,1618,
"m552s552m552s552m552s552m552s1656m552s1656m552s552m552s1656m552s1656"
// 538,5254,4432,4364,566,1616,568,530,564,1620,568,1616,564,532,564,530,
"m552s5244m4692s4416m552s1656m552s552m552s1656m552s1656m552s552m552s552"
// 566,1616,566,532,564,532,566,1620,568,528,566,530,566,1616,564,1618,
"m552s1656m552s552m552s552m552s1656m552s552m552s552m552s1656m552s1656"
// 566,530,566,1622,566,532,566,528,566,1620,568,1614,566,1618,566,1618,
"m552s552m552s1656m552s552m552s552m552s1656m552s1656m552s1656m552s1656"
// 566,1614,568,1618,566,1622,568,1616,566,530,564,530,566,530,566,528,
"m552s1656m552s1656m552s1656m552s1656m552s552m552s552m552s552m552s552"
// 564,530,566,532,566,1622,564,1616,566,1616,564,532,564,530,564,1616,
"m552s552m552s552m552s1656m552s1656m552s1656m552s552m552s552m552s1656"
// 564,530,564,532,566,530,564,530,566,528,564,1618,564,1618,564,532,
"m552s552m552s552m552s552m552s552m552s552m552s1656m552s1656m552s552"
// 564,1620,566,1618,562 // Raw data matches what is expected.
"m552s1656m552s1656m552s105244", ac._irsend.outputStr());
}
TEST(TestCoolixACClass, Issue985) {
IRrecv irrecv(0);
IRCoolixAC ac(0);
// Test that if we ONLY turn the power off, it only sends a "power off" mesg.
// i.e. Code from: https://github.com/crankyoldgit/IRremoteESP8266/issues/985#issue-516210106
// First block in the first code included.
ac.setPower(false);
ac.send();
ac._irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&ac._irsend.capture));
EXPECT_EQ(COOLIX, ac._irsend.capture.decode_type);
EXPECT_EQ(kCoolixBits, ac._irsend.capture.bits);
EXPECT_EQ(kCoolixOff, ac._irsend.capture.value);
EXPECT_EQ("Power: Off", IRAcUtils::resultAcToString(&ac._irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
ac._irsend.reset();
// Turn the unit on, cool mode, and set the temp.
// Code from: https://github.com/crankyoldgit/IRremoteESP8266/issues/985#issue-516210106
// Second block in the first code included.
uint8_t aircon_temp = 20; // Random value chosen.
ac.setPower(true);
ac.setMode(kCoolixCool);
ac.setTemp(aircon_temp);
ac.send();
ac._irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&ac._irsend.capture));
EXPECT_EQ(COOLIX, ac._irsend.capture.decode_type);
EXPECT_EQ(kCoolixBits, ac._irsend.capture.bits);
EXPECT_NE(kCoolixOff, ac._irsend.capture.value);
EXPECT_EQ(
"Power: On, Mode: 0 (Cool), Fan: 5 (Auto), Temp: 20C, Zone Follow: Off, "
"Sensor Temp: Off", IRAcUtils::resultAcToString(&ac._irsend.capture));
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
ac._irsend.reset();
// Now repeat the first block again.
// i.e. Code from: https://github.com/crankyoldgit/IRremoteESP8266/issues/985#issue-516210106
// First block in the first code included.
ac.setPower(false);
ac.send();
ac._irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&ac._irsend.capture));
EXPECT_EQ(COOLIX, ac._irsend.capture.decode_type);
EXPECT_EQ(kCoolixBits, ac._irsend.capture.bits);
EXPECT_EQ(kCoolixOff, ac._irsend.capture.value);
EXPECT_EQ("Power: Off", IRAcUtils::resultAcToString(&ac._irsend.capture));
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestCoolixACClass, PowerStateWithSetRaw) {
IRrecv irrecv(kGpioUnused);
IRCoolixAC ac(kGpioUnused);
// Problem reported that power is always off via decodeToState()
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/pull/1040
// https://github.com/arendst/Tasmota/issues/7660
const uint32_t on_code = 0xB2BFCC; // A valid "on" message.
// Check the off case.
ac.setRaw(kCoolixOff);
ASSERT_FALSE(ac.getPower());
EXPECT_FALSE(ac.toCommon().power);
// Check the "on" case.
ac.setRaw(on_code);
ASSERT_TRUE(ac.getPower());
EXPECT_TRUE(ac.toCommon().power);
// Now check the reported decodeToState() is also fixed.
ac._irsend.reset();
ac.send();
ac._irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&ac._irsend.capture));
EXPECT_EQ(COOLIX, ac._irsend.capture.decode_type);
EXPECT_EQ(kCoolixBits, ac._irsend.capture.bits);
EXPECT_EQ(on_code, ac._irsend.capture.value);
EXPECT_EQ(
"Power: On, Mode: 3 (Heat), Fan: 5 (Auto), Temp: 25C, Zone Follow: Off, "
"Sensor Temp: Off", IRAcUtils::resultAcToString(&ac._irsend.capture));
stdAc::state_t result;
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &result));
EXPECT_TRUE(result.power);
// Recheck the off case to ensure it changes.
ac.setRaw(kCoolixOff);
ASSERT_FALSE(ac.getPower());
EXPECT_FALSE(ac.toCommon().power);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,362 @@
// Copyright 2020 David Conran
#include "IRac.h"
#include "ir_Delonghi.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("DELONGHI_AC", typeToString(decode_type_t::DELONGHI_AC));
ASSERT_EQ(decode_type_t::DELONGHI_AC, strToDecodeType("DELONGHI_AC"));
ASSERT_FALSE(hasACState(decode_type_t::DELONGHI_AC));
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::DELONGHI_AC));
ASSERT_EQ(kDelonghiAcBits, IRsend::defaultBits(decode_type_t::DELONGHI_AC));
ASSERT_EQ(kDelonghiAcDefaultRepeat,
IRsend::minRepeats(decode_type_t::DELONGHI_AC));
}
TEST(TestDecodeDelonghiAc, SyntheticSelfDecode) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
irsend.sendDelonghiAc(0x6900000D0D01FB53);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(DELONGHI_AC, irsend.capture.decode_type);
EXPECT_EQ(kDelonghiAcBits, irsend.capture.bits);
EXPECT_EQ(0x6900000D0D01FB53, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.command);
EXPECT_EQ(0, irsend.capture.address);
}
TEST(TestDecodeDelonghiAc, RealExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
// Data from:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1096#issue-610665633
uint16_t rawData[131] = {
8984, 4200,
608, 1516, 608, 1516, 612, 472, 556, 528, 560, 1564, 556, 528, 560, 1564,
564, 528, 552, 1572, 556, 1568, 556, 528, 552, 1572, 556, 1568, 560, 1564,
552, 1572, 556, 1576, 552, 1568, 560, 528, 560, 524, 556, 528, 552, 532,
560, 528, 552, 532, 556, 532, 560, 1564, 560, 528, 552, 1568, 560, 1564,
564, 524, 556, 528, 560, 524, 556, 536, 556, 1568, 560, 524, 556, 1568,
560, 1564, 584, 500, 588, 496, 584, 500, 592, 500, 588, 496, 584, 500,
592, 496, 584, 500, 588, 496, 584, 500, 592, 492, 584, 508, 584, 500,
588, 496, 584, 500, 592, 496, 584, 500, 580, 504, 584, 500, 580, 508,
584, 1544, 584, 500, 588, 496, 584, 1540, 588, 500, 580, 1540, 588, 1536,
588, 500,
592};
irsend.reset();
irsend.sendRaw(rawData, 263, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(DELONGHI_AC, irsend.capture.decode_type);
EXPECT_EQ(kDelonghiAcBits, irsend.capture.bits);
EXPECT_EQ(0x6900000D0D01FB53, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.command);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(
"Power: On, Mode: 0 (Cool), Fan: 3 (Low), Temp: 90F, "
"Turbo: Off, Sleep: Off, On Timer: 06:13, Off Timer: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
// Tests for IRDelonghiAc class.
TEST(TestIRDelonghiAcClass, Power) {
IRDelonghiAc 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());
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1096#issuecomment-622521726
ac.setRaw(0x5500000000010153); // Power on
EXPECT_TRUE(ac.getPower());
ac.setRaw(0x5400000000000153); // Power off
EXPECT_FALSE(ac.getPower());
}
TEST(TestIRDelonghiAcClass, Temperature) {
IRDelonghiAc ac(kGpioUnused);
ac.begin();
// Celsius
ac.setTemp(0);
EXPECT_EQ(kDelonghiAcTempMinC, ac.getTemp());
EXPECT_FALSE(ac.getTempUnit());
ac.setTemp(255);
EXPECT_EQ(kDelonghiAcTempMaxC, ac.getTemp());
EXPECT_FALSE(ac.getTempUnit());
ac.setTemp(kDelonghiAcTempMinC);
EXPECT_EQ(kDelonghiAcTempMinC, ac.getTemp());
EXPECT_FALSE(ac.getTempUnit());
ac.setTemp(kDelonghiAcTempMaxC);
EXPECT_EQ(kDelonghiAcTempMaxC, ac.getTemp());
EXPECT_FALSE(ac.getTempUnit());
ac.setTemp(kDelonghiAcTempMinC - 1);
EXPECT_EQ(kDelonghiAcTempMinC, ac.getTemp());
EXPECT_FALSE(ac.getTempUnit());
ac.setTemp(kDelonghiAcTempMaxC + 1);
EXPECT_EQ(kDelonghiAcTempMaxC, ac.getTemp());
EXPECT_FALSE(ac.getTempUnit());
ac.setTemp(19);
EXPECT_EQ(19, ac.getTemp());
EXPECT_FALSE(ac.getTempUnit());
ac.setTemp(21);
EXPECT_EQ(21, ac.getTemp());
EXPECT_FALSE(ac.getTempUnit());
ac.setTemp(25);
EXPECT_EQ(25, ac.getTemp());
EXPECT_FALSE(ac.getTempUnit());
ac.setTemp(29, false);
EXPECT_EQ(29, ac.getTemp());
EXPECT_FALSE(ac.getTempUnit());
// Fahrenheit
ac.setTemp(0, true);
EXPECT_EQ(kDelonghiAcTempMinF, ac.getTemp());
EXPECT_TRUE(ac.getTempUnit());
ac.setTemp(255, true);
EXPECT_EQ(kDelonghiAcTempMaxF, ac.getTemp());
EXPECT_TRUE(ac.getTempUnit());
ac.setTemp(kDelonghiAcTempMinF, true);
EXPECT_EQ(kDelonghiAcTempMinF, ac.getTemp());
EXPECT_TRUE(ac.getTempUnit());
ac.setTemp(kDelonghiAcTempMaxF, true);
EXPECT_EQ(kDelonghiAcTempMaxF, ac.getTemp());
EXPECT_TRUE(ac.getTempUnit());
ac.setTemp(kDelonghiAcTempMinF - 1, true);
EXPECT_EQ(kDelonghiAcTempMinF, ac.getTemp());
EXPECT_TRUE(ac.getTempUnit());
ac.setTemp(kDelonghiAcTempMaxF + 1, true);
EXPECT_EQ(kDelonghiAcTempMaxF, ac.getTemp());
EXPECT_TRUE(ac.getTempUnit());
ac.setTemp(66, true);
EXPECT_EQ(66, ac.getTemp());
EXPECT_TRUE(ac.getTempUnit());
ac.setTemp(75, true);
EXPECT_EQ(75, ac.getTemp());
EXPECT_TRUE(ac.getTempUnit());
ac.setTemp(80, true);
EXPECT_EQ(80, ac.getTemp());
EXPECT_TRUE(ac.getTempUnit());
ac.setTemp(88, true);
EXPECT_EQ(88, ac.getTemp());
EXPECT_TRUE(ac.getTempUnit());
}
TEST(TestIRDelonghiAcClass, OperatingMode) {
IRDelonghiAc ac(kGpioUnused);
ac.begin();
ac.setMode(kDelonghiAcAuto);
EXPECT_EQ(kDelonghiAcAuto, ac.getMode());
EXPECT_EQ(17, ac.getTemp()); // Check for special temp
EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan()); // Look for fan speed enforcement
ac.setMode(kDelonghiAcCool);
EXPECT_EQ(kDelonghiAcCool, ac.getMode());
// Check changing to another mode that has a fixed temp and back keeps the
// existing temp. Only for Cool mode.
ac.setTemp(22);
EXPECT_EQ(22, ac.getTemp());
ac.setMode(kDelonghiAcAuto);
EXPECT_NE(22, ac.getTemp());
ac.setMode(kDelonghiAcCool);
EXPECT_EQ(22, ac.getTemp());
ac.setMode(kDelonghiAcDry);
EXPECT_EQ(kDelonghiAcDry, ac.getMode());
EXPECT_EQ(17, ac.getTemp()); // Check for special temp
EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan()); // Look for fan speed enforcement
ac.setMode(kDelonghiAcFan);
EXPECT_EQ(kDelonghiAcFan, ac.getMode());
EXPECT_EQ(23, ac.getTemp()); // Check for special temp
EXPECT_NE(kDelonghiAcFanAuto, ac.getFan()); // Look for fan speed enforcement
ac.setMode(kDelonghiAcAuto + 1);
EXPECT_EQ(kDelonghiAcAuto, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kDelonghiAcAuto, ac.getMode());
}
TEST(TestIRDelonghiAcClass, FanSpeed) {
IRDelonghiAc ac(kGpioUnused);
ac.begin();
ac.setMode(kDelonghiAcCool); // All fan speeds available in this mode.
ac.setFan(0);
EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan());
ac.setFan(255);
EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan());
ac.setFan(kDelonghiAcFanHigh);
EXPECT_EQ(kDelonghiAcFanHigh, ac.getFan());
ac.setFan(kDelonghiAcFanLow + 1);
EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan());
ac.setFan(1);
EXPECT_EQ(1, ac.getFan());
ac.setFan(2);
EXPECT_EQ(2, ac.getFan());
ac.setFan(3);
EXPECT_EQ(3, ac.getFan());
// Confirm changing to fan mode handles speed behaviour correctly.
ac.setFan(kDelonghiAcFanLow);
ac.setMode(kDelonghiAcFan);
EXPECT_EQ(kDelonghiAcFanLow, ac.getFan());
ac.setMode(kDelonghiAcAuto);
EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan());
ac.setMode(kDelonghiAcFan);
EXPECT_NE(kDelonghiAcFanAuto, ac.getFan());
}
TEST(TestIRDelonghiAcClass, Boost) {
IRDelonghiAc ac(kGpioUnused);
ac.begin();
ac.setBoost(false);
EXPECT_FALSE(ac.getBoost());
ac.setBoost(true);
EXPECT_TRUE(ac.getBoost());
ac.setBoost(false);
EXPECT_FALSE(ac.getBoost());
}
TEST(TestIRDelonghiAcClass, Sleep) {
IRDelonghiAc ac(kGpioUnused);
ac.begin();
ac.setSleep(false);
EXPECT_FALSE(ac.getSleep());
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
ac.setSleep(false);
EXPECT_FALSE(ac.getSleep());
}
TEST(TestIRDelonghiAcClass, OnTimer) {
IRDelonghiAc ac(kGpioUnused);
ac.begin();
ac.setOnTimerEnabled(false);
EXPECT_FALSE(ac.getOnTimerEnabled());
ac.setOnTimerEnabled(true);
EXPECT_TRUE(ac.getOnTimerEnabled());
ac.setOnTimerEnabled(false);
EXPECT_FALSE(ac.getOnTimerEnabled());
ac.setOnTimer(0);
EXPECT_FALSE(ac.getOnTimerEnabled());
EXPECT_EQ(0, ac.getOnTimer());
ac.setOnTimer(1);
EXPECT_TRUE(ac.getOnTimerEnabled());
EXPECT_EQ(1, ac.getOnTimer());
ac.setOnTimer(61);
EXPECT_TRUE(ac.getOnTimerEnabled());
EXPECT_EQ(61, ac.getOnTimer());
ac.setOnTimerEnabled(false);
ac.setOnTimer(23 * 60 + 59);
EXPECT_TRUE(ac.getOnTimerEnabled());
EXPECT_EQ(23 * 60 + 59, ac.getOnTimer());
ac.setOnTimerEnabled(false);
ac.setOnTimer(24 * 60);
EXPECT_TRUE(ac.getOnTimerEnabled());
EXPECT_EQ(23 * 60 + 59, ac.getOnTimer());
}
TEST(TestIRDelonghiAcClass, OffTimer) {
IRDelonghiAc ac(kGpioUnused);
ac.begin();
ac.setOffTimerEnabled(false);
EXPECT_FALSE(ac.getOffTimerEnabled());
ac.setOffTimerEnabled(true);
EXPECT_TRUE(ac.getOffTimerEnabled());
ac.setOffTimerEnabled(false);
EXPECT_FALSE(ac.getOffTimerEnabled());
ac.setOffTimer(0);
EXPECT_FALSE(ac.getOffTimerEnabled());
EXPECT_EQ(0, ac.getOffTimer());
ac.setOffTimer(1);
EXPECT_TRUE(ac.getOffTimerEnabled());
EXPECT_EQ(1, ac.getOffTimer());
ac.setOffTimer(61);
EXPECT_TRUE(ac.getOffTimerEnabled());
EXPECT_EQ(61, ac.getOffTimer());
ac.setOffTimerEnabled(false);
ac.setOffTimer(23 * 60 + 59);
EXPECT_TRUE(ac.getOffTimerEnabled());
EXPECT_EQ(23 * 60 + 59, ac.getOffTimer());
ac.setOffTimerEnabled(false);
ac.setOffTimer(24 * 60);
EXPECT_TRUE(ac.getOffTimerEnabled());
EXPECT_EQ(23 * 60 + 59, ac.getOffTimer());
// Real Data
// From: https://github.com/crankyoldgit/IRremoteESP8266/issues/1096#issuecomment-623115619
// Setting off timer to 8:51 when the time on the remote displayed 16:05.
// (8:51 + 24:00 - 16:05 == 32:51 - 16:05 == 16:46) i.e. Turn off in 16h46m.
ac.setRaw(0xB12E210000000F53);
EXPECT_TRUE(ac.getOffTimerEnabled());
EXPECT_EQ(16 * 60 + 46, ac.getOffTimer());
EXPECT_FALSE(ac.getOnTimerEnabled());
EXPECT_EQ(0, ac.getOnTimer());
}

View File

@@ -0,0 +1,294 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendDenon().
// Test sending typical data only.
TEST(TestSendDenon, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendDenon(0x2278); // Denon AVR Power On. (Sharp)
EXPECT_EQ(
"f38000d33"
"m260s780m260s1820m260s780m260s780m260s780m260s1820m260s780m260s780"
"m260s1820m260s1820m260s1820m260s1820m260s780m260s780m260s780"
"m260s43602"
"m260s780m260s1820m260s780m260s780m260s780m260s780m260s1820m260s1820"
"m260s780m260s780m260s780m260s780m260s1820m260s1820m260s1820"
"m260s43602",
irsend.outputStr());
irsend.reset();
// Denon Eco Mode On. (Panasonic/Kaseikyo)
irsend.sendDenon(0x2A4C028D6CE3, kDenon48Bits);
EXPECT_EQ(
"f36700d50"
"m3456s1728"
"m432s432m432s432m432s1296m432s432m432s1296m432s432m432s1296m432s432"
"m432s432m432s1296m432s432m432s432m432s1296m432s1296m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s1296m432s432"
"m432s1296m432s432m432s432m432s432m432s1296m432s1296m432s432m432s1296"
"m432s432m432s1296m432s1296m432s432m432s1296m432s1296m432s432m432s432"
"m432s1296m432s1296m432s1296m432s432m432s432m432s432m432s1296m432s1296"
"m432s98928",
irsend.outputStr());
}
// Test sending with different repeats.
TEST(TestSendDenon, SendNormalWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendDenon(0x2278, kDenonBits, 1); // 1 repeat.
EXPECT_EQ(
"f38000d33"
"m260s780m260s1820m260s780m260s780m260s780m260s1820m260s780m260s780"
"m260s1820m260s1820m260s1820m260s1820m260s780m260s780m260s780"
"m260s43602"
"m260s780m260s1820m260s780m260s780m260s780m260s780m260s1820m260s1820"
"m260s780m260s780m260s780m260s780m260s1820m260s1820m260s1820"
"m260s43602"
"m260s780m260s1820m260s780m260s780m260s780m260s1820m260s780m260s780"
"m260s1820m260s1820m260s1820m260s1820m260s780m260s780m260s780"
"m260s43602"
"m260s780m260s1820m260s780m260s780m260s780m260s780m260s1820m260s1820"
"m260s780m260s780m260s780m260s780m260s1820m260s1820m260s1820"
"m260s43602",
irsend.outputStr());
irsend.sendDenon(0x2278, kDenonBits, 2); // 2 repeats.
EXPECT_EQ(
"f38000d33"
"m260s780m260s1820m260s780m260s780m260s780m260s1820m260s780m260s780"
"m260s1820m260s1820m260s1820m260s1820m260s780m260s780m260s780"
"m260s43602"
"m260s780m260s1820m260s780m260s780m260s780m260s780m260s1820m260s1820"
"m260s780m260s780m260s780m260s780m260s1820m260s1820m260s1820"
"m260s43602"
"m260s780m260s1820m260s780m260s780m260s780m260s1820m260s780m260s780"
"m260s1820m260s1820m260s1820m260s1820m260s780m260s780m260s780"
"m260s43602"
"m260s780m260s1820m260s780m260s780m260s780m260s780m260s1820m260s1820"
"m260s780m260s780m260s780m260s780m260s1820m260s1820m260s1820"
"m260s43602"
"m260s780m260s1820m260s780m260s780m260s780m260s1820m260s780m260s780"
"m260s1820m260s1820m260s1820m260s1820m260s780m260s780m260s780"
"m260s43602"
"m260s780m260s1820m260s780m260s780m260s780m260s780m260s1820m260s1820"
"m260s780m260s780m260s780m260s780m260s1820m260s1820m260s1820"
"m260s43602",
irsend.outputStr());
}
TEST(TestSendDenon, Send48BitWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendDenon(0x2A4C028D6CE3, kDenon48Bits, 1); // 1 repeat.
EXPECT_EQ(
"f36700d50"
"m3456s1728"
"m432s432m432s432m432s1296m432s432m432s1296m432s432m432s1296m432s432"
"m432s432m432s1296m432s432m432s432m432s1296m432s1296m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s1296m432s432"
"m432s1296m432s432m432s432m432s432m432s1296m432s1296m432s432m432s1296"
"m432s432m432s1296m432s1296m432s432m432s1296m432s1296m432s432m432s432"
"m432s1296m432s1296m432s1296m432s432m432s432m432s432m432s1296m432s1296"
"m432s98928"
"m3456s1728"
"m432s432m432s432m432s1296m432s432m432s1296m432s432m432s1296m432s432"
"m432s432m432s1296m432s432m432s432m432s1296m432s1296m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s1296m432s432"
"m432s1296m432s432m432s432m432s432m432s1296m432s1296m432s432m432s1296"
"m432s432m432s1296m432s1296m432s432m432s1296m432s1296m432s432m432s432"
"m432s1296m432s1296m432s1296m432s432m432s432m432s432m432s1296m432s1296"
"m432s98928",
irsend.outputStr());
irsend.sendDenon(0x2A4C028D6CE3, kDenon48Bits, 2); // 2 repeats.
EXPECT_EQ(
"f36700d50"
"m3456s1728"
"m432s432m432s432m432s1296m432s432m432s1296m432s432m432s1296m432s432"
"m432s432m432s1296m432s432m432s432m432s1296m432s1296m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s1296m432s432"
"m432s1296m432s432m432s432m432s432m432s1296m432s1296m432s432m432s1296"
"m432s432m432s1296m432s1296m432s432m432s1296m432s1296m432s432m432s432"
"m432s1296m432s1296m432s1296m432s432m432s432m432s432m432s1296m432s1296"
"m432s98928"
"m3456s1728"
"m432s432m432s432m432s1296m432s432m432s1296m432s432m432s1296m432s432"
"m432s432m432s1296m432s432m432s432m432s1296m432s1296m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s1296m432s432"
"m432s1296m432s432m432s432m432s432m432s1296m432s1296m432s432m432s1296"
"m432s432m432s1296m432s1296m432s432m432s1296m432s1296m432s432m432s432"
"m432s1296m432s1296m432s1296m432s432m432s432m432s432m432s1296m432s1296"
"m432s98928"
"m3456s1728"
"m432s432m432s432m432s1296m432s432m432s1296m432s432m432s1296m432s432"
"m432s432m432s1296m432s432m432s432m432s1296m432s1296m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s1296m432s432"
"m432s1296m432s432m432s432m432s432m432s1296m432s1296m432s432m432s1296"
"m432s432m432s1296m432s1296m432s432m432s1296m432s1296m432s432m432s432"
"m432s1296m432s1296m432s1296m432s432m432s432m432s432m432s1296m432s1296"
"m432s98928",
irsend.outputStr());
}
// Test sending an atypical data size.
TEST(TestSendDenon, SendUnusualSize) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendDenon(0x12, 8);
EXPECT_EQ(
"f38000d33"
"m260s780m260s780m260s780m260s1820m260s780m260s780m260s1820m260s780"
"m260s43602"
"m260s1820m260s1820m260s1820m260s780m260s1820m260s1820m260s780m260s1820"
"m260s43602",
irsend.outputStr());
irsend.reset();
irsend.sendDenon(0x1234567890ABCDEF, 64);
EXPECT_EQ(
"f36700d50"
"m3456s1728"
"m432s432m432s432m432s432m432s1296m432s432m432s432m432s1296m432s432"
"m432s432m432s432m432s1296m432s1296m432s432m432s1296m432s432m432s432"
"m432s432m432s1296m432s432m432s1296m432s432m432s1296m432s1296m432s432"
"m432s432m432s1296m432s1296m432s1296m432s1296m432s432m432s432m432s432"
"m432s1296m432s432m432s432m432s1296m432s432m432s432m432s432m432s432"
"m432s1296m432s432m432s1296m432s432m432s1296m432s432m432s1296m432s1296"
"m432s1296m432s1296m432s432m432s432m432s1296m432s1296m432s432m432s1296"
"m432s1296m432s1296m432s1296m432s432m432s1296m432s1296m432s1296m432s1296"
"m432s74736",
irsend.outputStr());
}
// Tests for decodeDenon().
// Decode normal Denon messages.
TEST(TestDecodeDenon, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Denon 15-bit message. (Sharp)
irsend.reset();
irsend.sendDenon(0x2278);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeDenon(&irsend.capture, kStartOffset, kDenonBits,
true));
EXPECT_EQ(DENON, irsend.capture.decode_type);
EXPECT_EQ(kDenonBits, irsend.capture.bits);
EXPECT_EQ(0x2278, irsend.capture.value);
EXPECT_EQ(0x2, irsend.capture.address);
EXPECT_EQ(0x79, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Legacy Denon 14-bit message.
irsend.reset();
irsend.sendDenon(0x1278, kDenonLegacyBits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeDenon(&irsend.capture, kStartOffset,
kDenonLegacyBits, true));
EXPECT_EQ(DENON, irsend.capture.decode_type);
EXPECT_EQ(kDenonLegacyBits, irsend.capture.bits);
EXPECT_EQ(0x1278, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal Denon 48-bit message. (Panasonic/Kaseikyo)
irsend.reset();
irsend.sendDenon(0x2A4C028D6CE3, kDenon48Bits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeDenon(&irsend.capture, kStartOffset,
kDenon48Bits, true));
EXPECT_EQ(DENON, irsend.capture.decode_type);
EXPECT_EQ(kDenon48Bits, irsend.capture.bits);
EXPECT_EQ(0x2A4C028D6CE3, irsend.capture.value);
EXPECT_EQ(0x2A4C, irsend.capture.address);
EXPECT_EQ(0x028D6CE3, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode a 'real' example via GlobalCache
TEST(TestDecodeDenon, DecodeGlobalCacheExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Denon AVR series Power On code from Global Cache. (Sharp style)
uint16_t gc_test_power[67] = {
38000, 1, 1, 10, 30, 10, 70, 10, 30, 10, 30, 10, 30, 10, 70, 10, 30,
10, 30, 10, 70, 10, 70, 10, 70, 10, 70, 10, 30, 10, 30, 10, 30, 10,
1657, 10, 30, 10, 70, 10, 30, 10, 30, 10, 30, 10, 30, 10, 70, 10, 70,
10, 30, 10, 30, 10, 30, 10, 30, 10, 70, 10, 70, 10, 70, 10, 1657};
irsend.sendGC(gc_test_power, 67);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeDenon(&irsend.capture, kStartOffset, kDenonBits,
true));
EXPECT_EQ(DENON, irsend.capture.decode_type);
EXPECT_EQ(kDenonBits, irsend.capture.bits);
EXPECT_EQ(0x2278, irsend.capture.value);
EXPECT_EQ(0x2, irsend.capture.address);
EXPECT_EQ(0x79, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Denon "Eco Mode Auto" code from Global Cache. (Panasonic style)
uint16_t gc_test_eco[103] = {
37000, 1, 1, 128, 64, 16, 16, 16, 16, 16, 48, 16, 16, 16, 48,
16, 16, 16, 48, 16, 16, 16, 16, 16, 48, 16, 16, 16, 16, 16,
48, 16, 48, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 48, 16, 16, 16, 48, 16, 16, 16, 16, 16,
16, 16, 48, 16, 48, 16, 16, 16, 48, 16, 16, 16, 48, 16, 48,
16, 16, 16, 48, 16, 48, 16, 16, 16, 16, 16, 48, 16, 48, 16,
48, 16, 16, 16, 16, 16, 16, 16, 48, 16, 48, 16, 2766};
irsend.reset();
irsend.sendGC(gc_test_eco, 103);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeDenon(&irsend.capture, kStartOffset, kDenon48Bits,
true));
EXPECT_EQ(DENON, irsend.capture.decode_type);
EXPECT_EQ(kDenon48Bits, irsend.capture.bits);
EXPECT_EQ(0x2A4C028D6CE3, irsend.capture.value);
EXPECT_EQ(0x2A4C, irsend.capture.address);
EXPECT_EQ(0x028D6CE3, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Fail to decode a non-Denon example via GlobalCache
TEST(TestDecodeDenon, FailToDecodeNonDenonExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
uint16_t gc_test[39] = {38000, 1, 1, 322, 162, 20, 61, 20, 61, 20,
20, 20, 20, 20, 20, 20, 127, 20, 61, 9,
20, 20, 61, 20, 20, 20, 61, 20, 61, 20,
61, 20, 20, 20, 20, 20, 20, 20, 884};
irsend.sendGC(gc_test, 39);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeDenon(&irsend.capture));
ASSERT_FALSE(irrecv.decodeDenon(&irsend.capture, kStartOffset,
kDenonLegacyBits, false));
ASSERT_FALSE(irrecv.decodeDenon(&irsend.capture, kStartOffset, kDenonBits,
false));
ASSERT_FALSE(irrecv.decodeDenon(&irsend.capture, kStartOffset, kDenon48Bits,
false));
}

View File

@@ -0,0 +1,341 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendDISH().
// Test sending typical data only.
TEST(TestSendDish, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendDISH(0x0);
EXPECT_EQ(
"f57600d50"
"m400s6100"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100",
irsend.outputStr());
irsend.reset();
irsend.sendDISH(0x9C00); // Power on.
EXPECT_EQ(
"f57600d50"
"m400s6100"
"m400s1700m400s2800m400s2800m400s1700m400s1700m400s1700m400s2800m400s2800"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100"
"m400s1700m400s2800m400s2800m400s1700m400s1700m400s1700m400s2800m400s2800"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100"
"m400s1700m400s2800m400s2800m400s1700m400s1700m400s1700m400s2800m400s2800"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100"
"m400s1700m400s2800m400s2800m400s1700m400s1700m400s1700m400s2800m400s2800"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100",
irsend.outputStr());
irsend.reset();
irsend.sendDISH(0xFFFF);
EXPECT_EQ(
"f57600d50"
"m400s6100"
"m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700"
"m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700"
"m400s6100"
"m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700"
"m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700"
"m400s6100"
"m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700"
"m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700"
"m400s6100"
"m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700"
"m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700m400s1700"
"m400s6100",
irsend.outputStr());
}
// Test sending with different repeats.
TEST(TestSendDish, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendDISH(0x9C00, kDishBits, 0); // 0 repeats.
EXPECT_EQ(
"f57600d50"
"m400s6100"
"m400s1700m400s2800m400s2800m400s1700m400s1700m400s1700m400s2800m400s2800"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100",
irsend.outputStr());
irsend.reset();
irsend.sendDISH(0x9C00, kDishBits, 1); // 1 repeat.
EXPECT_EQ(
"f57600d50"
"m400s6100"
"m400s1700m400s2800m400s2800m400s1700m400s1700m400s1700m400s2800m400s2800"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100"
"m400s1700m400s2800m400s2800m400s1700m400s1700m400s1700m400s2800m400s2800"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100",
irsend.outputStr());
irsend.sendDISH(0x9C00, kDishBits, 2); // 2 repeats.
EXPECT_EQ(
"f57600d50"
"m400s6100"
"m400s1700m400s2800m400s2800m400s1700m400s1700m400s1700m400s2800m400s2800"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100"
"m400s1700m400s2800m400s2800m400s1700m400s1700m400s1700m400s2800m400s2800"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100"
"m400s1700m400s2800m400s2800m400s1700m400s1700m400s1700m400s2800m400s2800"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100",
irsend.outputStr());
}
// Test sending an atypical data size.
TEST(TestSendDish, SendUnusualSize) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendDISH(0x0, 8);
EXPECT_EQ(
"f57600d50"
"m400s6100"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100"
"m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800m400s2800"
"m400s6100",
irsend.outputStr());
irsend.reset();
irsend.sendDISH(0x1234567890ABCDEF, 64);
EXPECT_EQ(
"f57600d50"
"m400s6100"
"m400s2800m400s2800m400s2800m400s1700m400s2800m400s2800m400s1700m400s2800"
"m400s2800m400s2800m400s1700m400s1700m400s2800m400s1700m400s2800m400s2800"
"m400s2800m400s1700m400s2800m400s1700m400s2800m400s1700m400s1700m400s2800"
"m400s2800m400s1700m400s1700m400s1700m400s1700m400s2800m400s2800m400s2800"
"m400s1700m400s2800m400s2800m400s1700m400s2800m400s2800m400s2800m400s2800"
"m400s1700m400s2800m400s1700m400s2800m400s1700m400s2800m400s1700m400s1700"
"m400s1700m400s1700m400s2800m400s2800m400s1700m400s1700m400s2800m400s1700"
"m400s1700m400s1700m400s1700m400s2800m400s1700m400s1700m400s1700m400s1700"
"m400s6100"
"m400s2800m400s2800m400s2800m400s1700m400s2800m400s2800m400s1700m400s2800"
"m400s2800m400s2800m400s1700m400s1700m400s2800m400s1700m400s2800m400s2800"
"m400s2800m400s1700m400s2800m400s1700m400s2800m400s1700m400s1700m400s2800"
"m400s2800m400s1700m400s1700m400s1700m400s1700m400s2800m400s2800m400s2800"
"m400s1700m400s2800m400s2800m400s1700m400s2800m400s2800m400s2800m400s2800"
"m400s1700m400s2800m400s1700m400s2800m400s1700m400s2800m400s1700m400s1700"
"m400s1700m400s1700m400s2800m400s2800m400s1700m400s1700m400s2800m400s1700"
"m400s1700m400s1700m400s1700m400s2800m400s1700m400s1700m400s1700m400s1700"
"m400s6100"
"m400s2800m400s2800m400s2800m400s1700m400s2800m400s2800m400s1700m400s2800"
"m400s2800m400s2800m400s1700m400s1700m400s2800m400s1700m400s2800m400s2800"
"m400s2800m400s1700m400s2800m400s1700m400s2800m400s1700m400s1700m400s2800"
"m400s2800m400s1700m400s1700m400s1700m400s1700m400s2800m400s2800m400s2800"
"m400s1700m400s2800m400s2800m400s1700m400s2800m400s2800m400s2800m400s2800"
"m400s1700m400s2800m400s1700m400s2800m400s1700m400s2800m400s1700m400s1700"
"m400s1700m400s1700m400s2800m400s2800m400s1700m400s1700m400s2800m400s1700"
"m400s1700m400s1700m400s1700m400s2800m400s1700m400s1700m400s1700m400s1700"
"m400s6100"
"m400s2800m400s2800m400s2800m400s1700m400s2800m400s2800m400s1700m400s2800"
"m400s2800m400s2800m400s1700m400s1700m400s2800m400s1700m400s2800m400s2800"
"m400s2800m400s1700m400s2800m400s1700m400s2800m400s1700m400s1700m400s2800"
"m400s2800m400s1700m400s1700m400s1700m400s1700m400s2800m400s2800m400s2800"
"m400s1700m400s2800m400s2800m400s1700m400s2800m400s2800m400s2800m400s2800"
"m400s1700m400s2800m400s1700m400s2800m400s1700m400s2800m400s1700m400s1700"
"m400s1700m400s1700m400s2800m400s2800m400s1700m400s1700m400s2800m400s1700"
"m400s1700m400s1700m400s1700m400s2800m400s1700m400s1700m400s1700m400s1700"
"m400s6100",
irsend.outputStr());
}
// Tests for decodeDISH().
// Decode normal Dish messages.
TEST(TestDecodeDish, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Dish 16-bit message.
irsend.reset();
irsend.sendDISH(0x9C00);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeDISH(&irsend.capture, kStartOffset, kDishBits,
true));
EXPECT_EQ(DISH, irsend.capture.decode_type);
EXPECT_EQ(kDishBits, irsend.capture.bits);
EXPECT_EQ(0x9C00, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode Dish messages with unsupported size/lengths.
TEST(TestDecodeDish, DecodeWithNonStrictSize) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendDISH(0x12, 8); // Illegal size Dish message. (smaller)
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeDISH(&irsend.capture, kStartOffset, kDishBits,
true));
irsend.makeDecodeResult();
// Should fail with strict when we ask for the wrong bit size.
ASSERT_FALSE(irrecv.decodeDISH(&irsend.capture, kStartOffset, 8, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeDISH(&irsend.capture, kStartOffset, 8, false));
EXPECT_EQ(DISH, irsend.capture.decode_type);
EXPECT_EQ(8, irsend.capture.bits);
EXPECT_EQ(0x12, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
irsend.sendDISH(0x12345678, 32); // Illegal size Dish message. (larger)
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeDISH(&irsend.capture, kStartOffset, kDishBits,
true));
irsend.makeDecodeResult();
// Should fail with strict when we ask for the wrong bit size.
ASSERT_FALSE(irrecv.decodeDISH(&irsend.capture, kStartOffset, 32, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeDISH(&irsend.capture, kStartOffset, 32, false));
EXPECT_EQ(DISH, irsend.capture.decode_type);
EXPECT_EQ(32, irsend.capture.bits);
EXPECT_EQ(0x12345678, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
// Decode (non-standard) 64-bit messages.
TEST(TestDecodeDish, Decode64BitMessages) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Illegal value & size Dish 64-bit message.
irsend.sendDISH(0xFFFFFFFFFFFFFFFF, 64);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeDISH(&irsend.capture, kStartOffset, 64, true));
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeDISH(&irsend.capture, kStartOffset, 64, false));
EXPECT_EQ(DISH, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, irsend.capture.value);
}
// Decode a 'real' example via GlobalCache
TEST(TestDecodeDish, DecodeGlobalCacheExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
/*
irsend.reset();
// Dish DTV Pal code from Global Cache.
uint16_t gc_test_dtv[27] = {58000, 1, 3, 22, 538, 22, 252, 22, 156, 22, 156,
22, 156, 22, 156, 22, 252, 22, 252, 22, 252, 22,
252, 22, 252, 22, 538};
irsend.sendGC(gc_test_dtv, 27);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeDISH(&irsend.capture, kDishBits, true));
EXPECT_EQ(DISH, irsend.capture.decode_type);
EXPECT_EQ(kDishBits, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
ASSERT_TRUE(irrecv.decodeDISH(&irsend.capture));
EXPECT_EQ(DISH, irsend.capture.decode_type);
EXPECT_EQ(kDishBits, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
*/
// Dish Hopper 3 code from Global Cache.
uint16_t gc_test_hopper[73] = {
58000, 1, 37, 23, 351, 23, 94, 23, 164, 23, 164, 23, 94, 23, 94, 23,
94, 23, 164, 23, 164, 23, 164, 23, 164, 23, 164, 23, 164, 23, 164, 23,
164, 23, 164, 23, 164, 23, 351, 23, 94, 23, 164, 23, 164, 23, 94, 23,
94, 23, 94, 23, 164, 23, 164, 23, 164, 23, 164, 23, 164, 23, 164, 23,
164, 23, 164, 23, 164, 23, 164, 23, 351};
irsend.reset();
irsend.sendGC(gc_test_hopper, 73);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeDISH(&irsend.capture, kStartOffset, kDishBits,
true));
EXPECT_EQ(DISH, irsend.capture.decode_type);
EXPECT_EQ(kDishBits, irsend.capture.bits);
EXPECT_EQ(0x9C00, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
ASSERT_TRUE(irrecv.decodeDISH(&irsend.capture));
EXPECT_EQ(DISH, irsend.capture.decode_type);
EXPECT_EQ(kDishBits, irsend.capture.bits);
EXPECT_EQ(0x9C00, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Fail to decode a non-Dish example via GlobalCache
TEST(TestDecodeDish, FailToDecodeNonDishExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Modified a few entries to unexpected values, based on previous test case.
uint16_t gc_test[39] = {38000, 1, 1, 322, 162, 20, 61, 20, 61, 20,
20, 20, 20, 20, 20, 20, 127, 20, 61, 9,
20, 20, 61, 20, 20, 20, 61, 20, 61, 20,
61, 20, 20, 20, 20, 20, 20, 20, 884};
irsend.sendGC(gc_test, 39);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeDISH(&irsend.capture));
ASSERT_FALSE(irrecv.decodeDISH(&irsend.capture, kStartOffset, kDishBits,
false));
}

View File

@@ -0,0 +1,152 @@
// Copyright 2020 Christian Nilsson
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for decodeDoshisha().
TEST(TestDecodeDoshisha, RealExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
// CH2 Light Level 1
const uint16_t rawData_1[83] = {
3404, 1718,
416, 1306, 416, 460, 438, 432, 412, 460, 464, 396, 488, 394, 488, 394,
488, 398, 460, 430, 468, 398, 484, 416, 468, 396, 488, 1264, 414, 460,
436, 1286, 524, 1210, 470, 390, 434, 456, 414, 1288, 458, 1290, 438, 434,
412, 458, 440, 434, 438, 418, 456, 432, 466, 1270, 438, 442, 438, 430,
414, 1316, 412, 460, 440, 432, 412, 460, 440, 1264, 458, 434, 436, 1268,
458, 436, 438, 412, 456, 1290, 438, 442, 436, 1290,
464}; // DOSHISHA 800B3048A5
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData_1, 83, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::DOSHISHA, irsend.capture.decode_type);
ASSERT_EQ(kDoshishaBits, irsend.capture.bits);
EXPECT_EQ(0x800B3048A5, irsend.capture.value);
EXPECT_EQ(0b1, irsend.capture.address);
EXPECT_EQ(0xA4, irsend.capture.command);
// CH2 OFF
const uint16_t rawData_2[83] = {
3434, 1700,
446, 1284, 442, 440, 442, 428, 444, 432, 440, 430, 442, 432, 472, 438,
444, 446, 416, 430, 470, 416, 470, 438, 444, 442, 470, 1242, 440, 430,
442, 1314, 390, 1344, 444, 440, 414, 432, 442, 1310, 412, 1318, 416, 458,
416, 434, 438, 432, 418, 484, 416, 458, 442, 1298, 416, 466, 420, 428,
442, 1316, 418, 432, 442, 430, 442, 434, 444, 1286, 440, 430, 444, 1288,
444, 430, 444, 430, 442, 432, 498, 386, 498, 1242,
474}; // DOSHISHA 800B3048A1
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData_2, 175, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::DOSHISHA, irsend.capture.decode_type);
ASSERT_EQ(kDoshishaBits, irsend.capture.bits);
EXPECT_EQ(0x800B3048A1, irsend.capture.value);
EXPECT_EQ(0b1, irsend.capture.address);
EXPECT_EQ(0xA0, irsend.capture.command);
// CH1 OFF
const uint16_t rawData_4[83] = {
3470, 1670,
444, 1294, 470, 408, 442, 430, 444, 412, 464, 440, 498, 386, 498, 388,
474, 418, 440, 430, 472, 414, 474, 412, 472, 414, 470, 1268, 444, 428,
448, 1284, 444, 1294, 472, 412, 446, 428, 442, 1284, 444, 1290, 444, 430,
446, 430, 442, 410, 490, 406, 446, 428, 472, 1270, 472, 414, 442, 410,
460, 1292, 444, 430, 442, 430, 444, 434, 444, 1286, 442, 432, 442, 1288,
446, 430, 442, 414, 486, 386, 516, 388, 446, 438,
446}; // DOSHISHA 800B3048A0
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData_4, 175, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::DOSHISHA, irsend.capture.decode_type);
ASSERT_EQ(kDoshishaBits, irsend.capture.bits);
EXPECT_EQ(0x800B3048A0, irsend.capture.value);
EXPECT_EQ(0b0, irsend.capture.address);
EXPECT_EQ(0xA0, irsend.capture.command);
}
TEST(TestDecodeDoshisha, SyntheticExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
irsend.sendDoshisha(0x800B3048A5);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::DOSHISHA, irsend.capture.decode_type);
EXPECT_EQ(kDoshishaBits, irsend.capture.bits);
EXPECT_EQ(0x800B3048A5, irsend.capture.value);
EXPECT_EQ(0b1, irsend.capture.address);
EXPECT_EQ(0xA4, irsend.capture.command);
EXPECT_EQ(
"f38000d50"
"m3412s1722"
"m420s1310m420s452m420s452m420s452m420s452m420s452m420s452"
"m420s452m420s452m420s452m420s452m420s452m420s1310m420s452"
"m420s1310m420s1310m420s452m420s452m420s1310m420s1310m420s452"
"m420s452m420s452m420s452m420s452m420s1310m420s452m420s452"
"m420s1310m420s452m420s452m420s452m420s1310m420s452m420s1310"
"m420s452m420s452m420s1310m420s452m420s1310"
"m420s100000",
irsend.outputStr());
irsend.reset();
irsend.sendDoshisha(0x800B3048D0);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::DOSHISHA, irsend.capture.decode_type);
EXPECT_EQ(kDoshishaBits, irsend.capture.bits);
EXPECT_EQ(0x800B3048D0, irsend.capture.value);
EXPECT_EQ(irsend.encodeDoshisha(0xD0, 0b0), irsend.capture.value);
EXPECT_EQ(0b0, irsend.capture.address);
EXPECT_EQ(0xD0, irsend.capture.command);
EXPECT_EQ(
"f38000d50"
"m3412s1722"
"m420s1310m420s452m420s452m420s452m420s452m420s452m420s452"
"m420s452m420s452m420s452m420s452m420s452m420s1310m420s452"
"m420s1310m420s1310m420s452m420s452m420s1310m420s1310m420s452"
"m420s452m420s452m420s452m420s452m420s1310m420s452m420s452m420"
"s1310m420s452m420s452m420s452m420s1310m420s1310m420s452m420s1310"
"m420s452m420s452m420s452m420s452"
"m420s100000",
irsend.outputStr());
}
TEST(TestEncodeDoshisha, SyntheticExample) {
IRsendTest irsend(kGpioUnused);
// kRcz01CheckExpected
EXPECT_EQ(0x800B304800, irsend.encodeDoshisha(0x00, 0b0));
// kRcz01CommandTimmer30
EXPECT_EQ(0x800B304892, irsend.encodeDoshisha(0x92, 0b0));
// kRcz01CommandLevel1
EXPECT_EQ(0x800B3048A5, irsend.encodeDoshisha(0xA4, 0b1));
EXPECT_EQ(0x800B3048A4, irsend.encodeDoshisha(0xA4, 0b0));
}
TEST(TestUtils, Housekeeping) {
ASSERT_EQ("DOSHISHA", typeToString(decode_type_t::DOSHISHA));
ASSERT_EQ(decode_type_t::DOSHISHA, strToDecodeType("DOSHISHA"));
ASSERT_FALSE(hasACState(decode_type_t::DOSHISHA));
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::DOSHISHA));
ASSERT_EQ(kDoshishaBits, IRsend::defaultBits(decode_type_t::DOSHISHA));
ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::DOSHISHA));
}

View File

@@ -0,0 +1,359 @@
// Copyright 2018, 2019 David Conran
#include "ir_Electra.h"
#include <algorithm>
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendElectraAC().
// Test sending typical data only.
TEST(TestSendElectraAC, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
uint8_t data[kElectraAcStateLength] = {0xC3, 0x87, 0xF6, 0x28, 0x60,
0x00, 0x20, 0x00, 0x00, 0x20,
0x00, 0x05, 0x0D};
irsend.sendElectraAC(data);
EXPECT_EQ(
"f38000d50"
"m9166s4470"
"m646s1647m646s1647m646s547m646s547m646s547m646s547m646s1647m646s1647"
"m646s1647m646s1647m646s1647m646s547m646s547m646s547m646s547m646s1647"
"m646s547m646s1647m646s1647m646s547m646s1647m646s1647m646s1647m646s1647"
"m646s547m646s547m646s547m646s1647m646s547m646s1647m646s547m646s547"
"m646s547m646s547m646s547m646s547m646s547m646s1647m646s1647m646s547"
"m646s547m646s547m646s547m646s547m646s547m646s547m646s547m646s547"
"m646s547m646s547m646s547m646s547m646s547m646s1647m646s547m646s547"
"m646s547m646s547m646s547m646s547m646s547m646s547m646s547m646s547"
"m646s547m646s547m646s547m646s547m646s547m646s547m646s547m646s547"
"m646s547m646s547m646s547m646s547m646s547m646s1647m646s547m646s547"
"m646s547m646s547m646s547m646s547m646s547m646s547m646s547m646s547"
"m646s1647m646s547m646s1647m646s547m646s547m646s547m646s547m646s547"
"m646s1647m646s547m646s1647m646s1647m646s547m646s547m646s547m646s547"
"m646s100000",
irsend.outputStr());
}
// Tests for decodeElectraAC().
// Decode normal ElectraAC messages.
TEST(TestDecodeElectraAC, SyntheticDecode) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Synthesised Normal ElectraAC message.
irsend.reset();
uint8_t expectedState[kElectraAcStateLength] = {0xC3, 0x87, 0xF6, 0x28, 0x60,
0x00, 0x20, 0x00, 0x00, 0x20,
0x00, 0x05, 0x0D};
irsend.sendElectraAC(expectedState);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(ELECTRA_AC, irsend.capture.decode_type);
EXPECT_EQ(kElectraAcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
}
// Decode a recorded example
TEST(TestDecodeElectraAC, RealExampleDecode) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Real ElectraAC message.
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/527
uint16_t rawData[211] = {
9166, 4470, 642, 1632, 642, 1632, 668, 534, 666, 534, 668, 534,
614, 536, 640, 1636, 640, 1646, 694, 1662, 612, 1628, 642, 1666,
664, 532, 668, 534, 666, 534, 666, 532, 666, 1644, 642, 532,
640, 1634, 668, 1632, 642, 538, 666, 1660, 610, 1666, 664, 1632,
642, 1672, 610, 536, 666, 534, 694, 532, 666, 1636, 614, 538,
666, 1632, 642, 536, 666, 544, 692, 534, 640, 558, 640, 534,
640, 540, 666, 534, 638, 1666, 638, 1636, 640, 550, 666, 534,
640, 540, 666, 534, 640, 540, 666, 536, 638, 540, 666, 536,
638, 550, 664, 536, 638, 540, 664, 536, 638, 540, 666, 534,
638, 1640, 664, 536, 692, 546, 664, 536, 664, 536, 664, 536,
664, 546, 612, 532, 636, 538, 664, 536, 664, 546, 612, 538,
638, 538, 638, 538, 664, 536, 690, 538, 662, 538, 664, 538,
662, 548, 664, 536, 662, 538, 662, 562, 638, 564, 636, 564,
636, 1668, 582, 556, 652, 572, 612, 568, 636, 564, 610, 570,
636, 556, 616, 550, 656, 566, 610, 570, 632, 578, 608, 1640,
662, 562, 642, 1686, 582, 570, 634, 566, 604, 576, 636, 566,
610, 578, 634, 1664, 584, 590, 660, 1636, 610, 1642, 664, 590,
610, 590, 636, 566, 634, 568, 686}; // UNKNOWN 9AD8CDB5
uint8_t expectedState[kElectraAcStateLength] = {0xC3, 0x87, 0xF6, 0x28, 0x60,
0x00, 0x20, 0x00, 0x00, 0x20,
0x00, 0x05, 0x0D};
irsend.reset();
irsend.sendRaw(rawData, 211, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(ELECTRA_AC, irsend.capture.decode_type);
ASSERT_EQ(kElectraAcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), "
"Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestIRElectraAcClass, Power) {
IRElectraAc 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(TestIRElectraAcClass, OperatingMode) {
IRElectraAc ac(0);
ac.begin();
ac.setMode(kElectraAcAuto);
EXPECT_EQ(kElectraAcAuto, ac.getMode());
ac.setMode(kElectraAcCool);
EXPECT_EQ(kElectraAcCool, ac.getMode());
ac.setMode(kElectraAcHeat);
EXPECT_EQ(kElectraAcHeat, ac.getMode());
ac.setMode(kElectraAcDry);
EXPECT_EQ(kElectraAcDry, ac.getMode());
ac.setMode(kElectraAcFan);
EXPECT_EQ(kElectraAcFan, ac.getMode());
ac.setMode(kElectraAcHeat + 1);
EXPECT_EQ(kElectraAcAuto, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kElectraAcAuto, ac.getMode());
}
TEST(TestIRElectraAcClass, SetAndGetTemp) {
IRElectraAc ac(0);
ac.setTemp(25);
EXPECT_EQ(25, ac.getTemp());
ac.setTemp(kElectraAcMinTemp);
EXPECT_EQ(kElectraAcMinTemp, ac.getTemp());
ac.setTemp(kElectraAcMinTemp - 1);
EXPECT_EQ(kElectraAcMinTemp, ac.getTemp());
ac.setTemp(kElectraAcMaxTemp);
EXPECT_EQ(kElectraAcMaxTemp, ac.getTemp());
ac.setTemp(kElectraAcMaxTemp + 1);
EXPECT_EQ(kElectraAcMaxTemp, ac.getTemp());
}
TEST(TestIRElectraAcClass, FanSpeed) {
IRElectraAc ac(0);
ac.begin();
ac.setFan(0);
EXPECT_EQ(kElectraAcFanAuto, ac.getFan());
ac.setFan(255);
EXPECT_EQ(kElectraAcFanAuto, ac.getFan());
ac.setFan(kElectraAcFanHigh);
EXPECT_EQ(kElectraAcFanHigh, ac.getFan());
ac.setFan(std::max(kElectraAcFanHigh, kElectraAcFanLow) + 1);
EXPECT_EQ(kElectraAcFanAuto, ac.getFan());
ac.setFan(kElectraAcFanHigh - 1);
EXPECT_EQ(kElectraAcFanAuto, 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(TestIRElectraAcClass, toCommon) {
IRElectraAc ac(0);
ac.setPower(true);
ac.setMode(kElectraAcCool);
ac.setTemp(20);
ac.setFan(kElectraAcFanHigh);
ac.setSwingV(true);
ac.setSwingH(true);
ac.setClean(true);
ac.setLightToggle(true);
// Now test it.
ASSERT_EQ(decode_type_t::ELECTRA_AC, ac.toCommon().protocol);
ASSERT_EQ(-1, ac.toCommon().model);
ASSERT_TRUE(ac.toCommon().power);
ASSERT_TRUE(ac.toCommon().celsius);
ASSERT_EQ(20, ac.toCommon().degrees);
ASSERT_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kAuto, ac.toCommon().swingv);
ASSERT_EQ(stdAc::swingh_t::kAuto, ac.toCommon().swingh);
ASSERT_TRUE(ac.toCommon().clean);
ASSERT_TRUE(ac.toCommon().light);
// Unsupported.
ASSERT_FALSE(ac.toCommon().turbo);
ASSERT_FALSE(ac.toCommon().filter);
ASSERT_FALSE(ac.toCommon().quiet);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().sleep);
ASSERT_EQ(-1, ac.toCommon().clock);
}
TEST(TestIRElectraAcClass, HumanReadable) {
IRElectraAc ac(0);
// Data from:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/778#issue-460052080
uint8_t on_cool_32C_auto_voff[13] = {
0xC3, 0xC7, 0xE0, 0x00, 0xA0, 0x00, 0x20,
0x00, 0x00, 0x20, 0x00, 0x40, 0x8A};
ac.setRaw(on_cool_32C_auto_voff);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 32C, Fan: 5 (Auto), "
"Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off",
ac.toString());
uint8_t on_cool_16C_auto_voff[13] = {
0xC3, 0x47, 0xE0, 0x00, 0xA0, 0x00, 0x20,
0x00, 0x00, 0x20, 0x00, 0x41, 0x0B};
ac.setRaw(on_cool_16C_auto_voff);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 5 (Auto), "
"Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off",
ac.toString());
uint8_t on_cool_16C_low_voff[13] = {
0xC3, 0x47, 0xE0, 0x00, 0x60, 0x00, 0x20,
0x00, 0x00, 0x20, 0x00, 0x41, 0xCB};
ac.setRaw(on_cool_16C_low_voff);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 3 (Low), "
"Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off",
ac.toString());
}
TEST(TestIRElectraAcClass, Clean) {
IRElectraAc ac(kGpioUnused);
ac.begin();
ac.setClean(true);
EXPECT_TRUE(ac.getClean());
ac.setClean(false);
EXPECT_FALSE(ac.getClean());
ac.setClean(true);
EXPECT_TRUE(ac.getClean());
ac.setClean(false);
// ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1033#issuecomment-581133127
uint8_t on[13] = {0xC3, 0x87, 0xE0, 0x00, 0x60, 0x00, 0x20, 0x00, 0x00, 0x24,
0x00, 0x19, 0xE7};
ac.setRaw(on);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), "
"Swing(V): Off, Swing(H): Off, Light: Toggle, Clean: On, Turbo: Off",
ac.toString());
}
TEST(TestIRElectraAcClass, Turbo) {
IRElectraAc ac(kGpioUnused);
ac.begin();
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
ac.setTurbo(false);
EXPECT_FALSE(ac.getTurbo());
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
ac.setTurbo(false);
// ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1033#issuecomment-583888046
const uint8_t on[13] = {
0xC3, 0x87, 0xE0, 0x00, 0x60, 0x40, 0x20, 0x00, 0x00, 0x20, 0x00, 0x08,
0x12};
ac.setRaw(on);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), "
"Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: On",
ac.toString());
}
TEST(TestIRElectraAcClass, LightToggle) {
IRElectraAc ac(kGpioUnused);
ac.begin();
ac.setLightToggle(true);
EXPECT_TRUE(ac.getLightToggle());
ac.setLightToggle(false);
EXPECT_FALSE(ac.getLightToggle());
ac.setLightToggle(true);
EXPECT_TRUE(ac.getLightToggle());
ac.setLightToggle(false);
// ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1033#issuecomment-581133127
uint8_t on[13] = {0xC3, 0x87, 0xE0, 0x00, 0x60, 0x00, 0x20, 0x00, 0x00, 0x24,
0x00, 0x19, 0xE7};
ac.setRaw(on);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), "
"Swing(V): Off, Swing(H): Off, Light: Toggle, Clean: On, Turbo: Off",
ac.toString());
}
TEST(TestIRElectraAcClass, ConstructKnownState) {
IRElectraAc ac(kGpioUnused);
// Data from:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1033#issuecomment-581133127
// A/C on - Cooling mode - 24° - Fan speed set to 1 - Light set to toggle
// - flaps off - turbo off - clean on
const uint8_t on_cool_24C_fan1_swing_off_turbo_off_clean_on[13] = {
0xC3, 0x87, 0xE0, 0x00, 0x60, 0x00, 0x20,
// 0x00, 0x00, 0x24, 0x00, 0x19, 0xE7}; // Real captured data
// TODO(ShonP40): Explain `state[11]` difference.
0x00, 0x00, 0x24, 0x00, 0x15, 0xE3}; // state[11] hacked to pass test.
ac.stateReset();
ac.on();
ac.setMode(kElectraAcCool);
ac.setTemp(24);
ac.setSwingH(false);
ac.setSwingV(false);
ac.setFan(kElectraAcFanLow);
ac.setLightToggle(true);
ac.setClean(true);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), "
"Swing(V): Off, Swing(H): Off, Light: Toggle, Clean: On, Turbo: Off",
ac.toString());
EXPECT_STATE_EQ(on_cool_24C_fan1_swing_off_turbo_off_clean_on,
ac.getRaw(), kElectraAcBits);
}

View File

@@ -0,0 +1,159 @@
// Copyright 2020 David Conran
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendEpson().
// Test sending typical data only.
TEST(TestSendEpson, SendDataOnly) {
IRsendTest irsend(kGpioUnused);
irsend.begin();
irsend.sendEpson(0xC1AA09F6);
EXPECT_EQ(
"f38000d33"
"m8960s4480"
"m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s560m560s560m560s560m560s1680m560s560m560s560m560s1680"
"m560s1680m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s560"
"m560s41440"
"m8960s4480"
"m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s560m560s560m560s560m560s1680m560s560m560s560m560s1680"
"m560s1680m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s560"
"m560s41440"
"m8960s4480"
"m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s560m560s560m560s560m560s1680m560s560m560s560m560s1680"
"m560s1680m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s560"
"m560s41440",
irsend.outputStr());
}
// Tests for decodeEpson().
// Decode normal Epson messages.
TEST(TestDecodeEpson, SyntheticSelfDecode) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
// Real-life Epson code from an actual capture/decode.
irsend.reset();
irsend.sendEpson(0xC1AA09F6);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(EPSON, irsend.capture.decode_type);
EXPECT_EQ(kEpsonBits, irsend.capture.bits);
EXPECT_EQ(0xC1AA09F6, irsend.capture.value);
EXPECT_EQ(0x5583, irsend.capture.address);
EXPECT_EQ(0x90, irsend.capture.command);
EXPECT_TRUE(irsend.capture.repeat);
}
// Decode a real Epson message.
TEST(TestDecodeEpson, RealMessageDecode) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
// Real-life Epson code from an actual capture/decode.
irsend.reset();
const uint16_t rawData_0[203] = {
8976, 4496, 542, 1690, 542, 1688, 542, 588, 518, 612, 542, 586, 518, 610,
518, 610, 542, 1688, 516, 1714, 542, 614, 516, 1688, 542, 612, 516, 1690,
540, 614, 514, 1690, 520, 638, 516, 584, 518, 612, 542, 586, 540, 588,
542, 1688, 520, 610, 540, 586, 520, 1712, 540, 1692, 542, 1688, 542, 1690,
520, 1710, 518, 610, 518, 1712, 518, 1716, 544, 584, 544, 40870,
8978, 4496, 542, 1690, 542, 1688, 520, 610, 542, 584, 516, 638, 514, 588,
540, 588, 540, 1690, 516, 1716, 516, 614, 542, 1688, 518, 612, 542, 1688,
540, 614, 514, 1692, 542, 588, 538, 590, 542, 586, 542, 612, 516, 612,
514, 1692, 516, 612, 540, 586, 520, 1712, 518, 1714, 542, 1688, 518, 1716,
542, 1688, 516, 614, 542, 1686, 518, 1714, 516, 612, 532, 40882,
8976, 4498, 516, 1716, 542, 1690, 540, 614, 516, 614, 516, 614, 514, 588,
540, 588, 544, 1688, 522, 1710, 518, 638, 516, 1688, 520, 636, 492, 1714,
542, 586, 542, 1690, 542, 588, 542, 584, 542, 612, 516, 612, 514, 614,
516, 1690, 542, 586, 542, 586, 540, 1690, 518, 1712, 518, 1716, 518, 1714,
542, 1690, 542, 586, 540, 1690, 542, 1690, 542, 588, 540};
irsend.sendRaw(rawData_0, 203, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(EPSON, irsend.capture.decode_type);
EXPECT_EQ(kEpsonBits, irsend.capture.bits);
EXPECT_EQ(0xC1AA09F6, irsend.capture.value);
EXPECT_EQ(0x5583, irsend.capture.address);
EXPECT_EQ(0x90, irsend.capture.command);
EXPECT_TRUE(irsend.capture.repeat);
}
TEST(TestDecodeEpson, RequiresARepeat) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
// Simulate sending only two messages (mesg + repeat)
irsend.reset();
irsend.sendEpson(0xC1AA09F6, kEpsonBits, 1);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(EPSON, irsend.capture.decode_type);
EXPECT_EQ(kEpsonBits, irsend.capture.bits);
EXPECT_EQ(0xC1AA09F6, irsend.capture.value);
EXPECT_EQ(0x5583, irsend.capture.address);
EXPECT_EQ(0x90, irsend.capture.command);
EXPECT_TRUE(irsend.capture.repeat);
// Simulate sending no repeats (just 1 message) which should fail to be
// detected as Epson.
irsend.reset();
irsend.sendEpson(0xC1AA09F6, kEpsonBits, 0);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_NE(EPSON, irsend.capture.decode_type);
}
TEST(TestDecodeEpson, DecodeOnlyIfRepeatIsTheSame) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
// Simulate sending only two identical messages.
// This should succeed.
irsend.reset();
irsend.sendEpson(0xC1AA09F6, kEpsonBits, 0);
irsend.sendEpson(0xC1AA09F6, kEpsonBits, 0);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(EPSON, irsend.capture.decode_type);
EXPECT_EQ(kEpsonBits, irsend.capture.bits);
EXPECT_EQ(0xC1AA09F6, irsend.capture.value);
EXPECT_EQ(0x5583, irsend.capture.address);
EXPECT_EQ(0x90, irsend.capture.command);
EXPECT_TRUE(irsend.capture.repeat);
// Simulate sending a repeat but with a different code.
// This should fail.
irsend.reset();
irsend.sendEpson(0xC1AA09F6, kEpsonBits, 0); // Valid code.
irsend.sendEpson(0x4BB640BF, kEpsonBits, 0); // Valid code but different.
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_NE(EPSON, irsend.capture.decode_type);
}
TEST(TestUtils, Housekeeping) {
ASSERT_EQ("EPSON", typeToString(decode_type_t::EPSON));
ASSERT_EQ(decode_type_t::EPSON, strToDecodeType("EPSON"));
ASSERT_FALSE(hasACState(decode_type_t::EPSON));
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::EPSON));
ASSERT_EQ(kEpsonBits, IRsendTest::defaultBits(decode_type_t::EPSON));
ASSERT_EQ(kEpsonMinRepeat, IRsendTest::minRepeats(decode_type_t::EPSON));
}

View File

@@ -0,0 +1,910 @@
// Copyright 2017 Jonny Graham, David Conran
#include "IRac.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "ir_Fujitsu.h"
#include "gtest/gtest.h"
// Tests for Fujitsu A/C methods.
// Test sending typical data only.
TEST(TestIRFujitsuACClass, GetRawDefault) {
IRFujitsuAC ac(0); // AR-RAH2E
ac.setSwing(kFujitsuAcSwingBoth);
ac.setMode(kFujitsuAcModeCool);
ac.setFanSpeed(kFujitsuAcFanHigh);
ac.setTemp(24);
ac.setCmd(kFujitsuAcCmdTurnOn);
uint8_t expected_arrah2e[16] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30,
0x81, 0x01, 0x31, 0x00, 0x00, 0x00, 0x20, 0xFD};
EXPECT_STATE_EQ(expected_arrah2e, ac.getRaw(), 16 * 8);
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ("Model: 1 (ARRAH2E), Power: On, Mode: 1 (Cool), Temp: 24C, "
"Fan: 1 (High), Clean: Off, Filter: Off, "
"Swing: 3 (Swing(V)+Swing(H)), Command: N/A",
ac.toString());
uint8_t expected_ardb1[15] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFC, 0x08, 0x30,
0x81, 0x01, 0x01, 0x00, 0x00, 0x00, 0x4D};
ac.setModel(ARDB1);
EXPECT_STATE_EQ(expected_ardb1, ac.getRaw(), 15 * 8);
EXPECT_EQ(kFujitsuAcStateLength - 1, ac.getStateLength());
EXPECT_EQ("Model: 2 (ARDB1), Power: On, Mode: 1 (Cool), Temp: 24C, "
"Fan: 1 (High), Command: N/A",
ac.toString());
}
TEST(TestIRFujitsuACClass, GetRawTurnOff) {
IRFujitsuAC ac(0);
ac.setModel(ARRAH2E);
ac.off();
uint8_t expected_arrah2e[7] = {0x14, 0x63, 0x0, 0x10, 0x10, 0x02, 0xFD};
EXPECT_STATE_EQ(expected_arrah2e, ac.getRaw(), 7 * 8);
EXPECT_EQ(kFujitsuAcStateLengthShort, ac.getStateLength());
EXPECT_EQ("Model: 1 (ARRAH2E), Power: Off, Mode: 1 (Cool), Temp: 24C, "
"Fan: 1 (High), Clean: Off, Filter: Off, "
"Swing: 3 (Swing(V)+Swing(H)), Command: N/A",
ac.toString());
ac.setModel(ARDB1);
uint8_t expected_ardb1[6] = {0x14, 0x63, 0x0, 0x10, 0x10, 0x02};
EXPECT_STATE_EQ(expected_ardb1, ac.getRaw(), 6 * 8);
EXPECT_EQ(kFujitsuAcStateLengthShort - 1, ac.getStateLength());
EXPECT_EQ("Model: 2 (ARDB1), Power: Off, Mode: 1 (Cool), Temp: 24C, "
"Fan: 1 (High), Command: N/A",
ac.toString());
}
TEST(TestIRFujitsuACClass, GetRawStepHoriz) {
IRFujitsuAC ac(0);
ac.stepHoriz();
uint8_t expected[7] = {0x14, 0x63, 0x0, 0x10, 0x10, 0x79, 0x86};
EXPECT_STATE_EQ(expected, ac.getRaw(), 7 * 8);
EXPECT_EQ(kFujitsuAcStateLengthShort, ac.getStateLength());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Power: On, Mode: 1 (Cool), Temp: 24C, "
"Fan: 1 (High), Clean: Off, Filter: Off, Swing: 3 (Swing(V)+Swing(H)), "
"Command: Step Swing(H)",
ac.toString());
}
TEST(TestIRFujitsuACClass, GetRawStepVert) {
IRFujitsuAC ac(0);
ac.setModel(ARRAH2E);
ac.stepVert();
uint8_t expected_arrah2e[7] = {0x14, 0x63, 0x0, 0x10, 0x10, 0x6C, 0x93};
EXPECT_STATE_EQ(expected_arrah2e, ac.getRaw(), 7 * 8);
EXPECT_EQ(kFujitsuAcStateLengthShort, ac.getStateLength());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Power: On, Mode: 1 (Cool), Temp: 24C, "
"Fan: 1 (High), Clean: Off, Filter: Off, Swing: 3 (Swing(V)+Swing(H)), "
"Command: Step Swing(V)",
ac.toString());
ac.setModel(ARDB1);
ac.stepVert();
uint8_t expected_ardb1[6] = {0x14, 0x63, 0x0, 0x10, 0x10, 0x6C};
EXPECT_STATE_EQ(expected_ardb1, ac.getRaw(), 6 * 8);
EXPECT_EQ(kFujitsuAcStateLengthShort - 1,
ac.getStateLength());
EXPECT_EQ("Model: 2 (ARDB1), Power: On, Mode: 1 (Cool), Temp: 24C, "
"Fan: 1 (High), Command: Step Swing(V)",
ac.toString());
}
TEST(TestIRFujitsuACClass, GetRawWithSwingHoriz) {
IRFujitsuAC ac(0);
ac.setCmd(kFujitsuAcCmdStayOn);
ac.setSwing(kFujitsuAcSwingHoriz);
ac.setMode(kFujitsuAcModeCool);
ac.setFanSpeed(kFujitsuAcFanQuiet);
ac.setTemp(25);
uint8_t expected[16] = {0x14, 0x63, 0x0, 0x10, 0x10, 0xFE, 0x9, 0x30,
0x90, 0x1, 0x24, 0x0, 0x0, 0x0, 0x20, 0xFB};
EXPECT_STATE_EQ(expected, ac.getRaw(), 16 * 8);
EXPECT_EQ("Model: 1 (ARRAH2E), Power: On, Mode: 1 (Cool), Temp: 25C, "
"Fan: 4 (Quiet), Clean: Off, Filter: Off, "
"Swing: 2 (Swing(H)), Command: N/A",
ac.toString());
}
TEST(TestIRFujitsuACClass, GetRawWithFan) {
IRFujitsuAC ac(0);
ac.setCmd(kFujitsuAcCmdStayOn);
ac.setSwing(kFujitsuAcSwingHoriz);
ac.setMode(kFujitsuAcModeFan);
ac.setFanSpeed(kFujitsuAcFanMed);
ac.setTemp(20); // temp doesn't matter for fan
// but it is sent by the RC anyway
ac.setModel(ARRAH2E);
uint8_t expected_arrah2e[16] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30,
0x40, 0x03, 0x22, 0x00, 0x00, 0x00, 0x20, 0x4B};
EXPECT_STATE_EQ(expected_arrah2e, ac.getRaw(), 16 * 8);
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ("Model: 1 (ARRAH2E), Power: On, Mode: 3 (Fan), Temp: 20C, "
"Fan: 2 (Medium), Clean: Off, Filter: Off, "
"Swing: 2 (Swing(H)), Command: N/A",
ac.toString());
ac.setModel(ARDB1);
uint8_t expected_ardb1[15] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFC, 0x08, 0x30,
0x40, 0x03, 0x02, 0x00, 0x00, 0x00, 0x8B};
EXPECT_EQ(kFujitsuAcStateLength - 1, ac.getStateLength());
EXPECT_STATE_EQ(expected_ardb1, ac.getRaw(), ac.getStateLength() * 8);
EXPECT_EQ("Model: 2 (ARDB1), Power: On, Mode: 3 (Fan), Temp: 20C, "
"Fan: 2 (Medium), Command: N/A", ac.toString());
}
TEST(TestIRFujitsuACClass, SetRaw) {
IRFujitsuAC ac(0);
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
uint8_t expected_default_arrah2e[kFujitsuAcStateLength] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30,
0x81, 0x01, 0x31, 0x00, 0x00, 0x00, 0x20, 0xFD};
EXPECT_STATE_EQ(expected_default_arrah2e, ac.getRaw(),
ac.getStateLength() * 8);
EXPECT_EQ("Model: 1 (ARRAH2E), Power: On, Mode: 1 (Cool), Temp: 24C, "
"Fan: 1 (High), Clean: Off, Filter: Off, "
"Swing: 3 (Swing(V)+Swing(H)), Command: N/A",
ac.toString());
// Now set a new state via setRaw();
// This state is a real state from an AR-DB1 remote.
uint8_t new_state1[kFujitsuAcStateLength - 1] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFC, 0x08, 0x30,
0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x9F};
ac.setRaw(new_state1, kFujitsuAcStateLength - 1);
EXPECT_EQ(kFujitsuAcStateLength - 1, ac.getStateLength());
EXPECT_STATE_EQ(new_state1, ac.getRaw(), ac.getStateLength() * 8);
EXPECT_EQ("Model: 2 (ARDB1), Power: On, Mode: 1 (Cool), Temp: 19C, "
"Fan: 0 (Auto), Command: N/A", ac.toString());
}
TEST(TestSendFujitsuAC, GenerateMessage) {
IRFujitsuAC ac(0);
IRsendTest irsend(0);
ac.begin();
irsend.begin();
ac.setCmd(kFujitsuAcCmdStayOn);
ac.setSwing(kFujitsuAcSwingBoth);
ac.setMode(kFujitsuAcModeCool);
ac.setFanSpeed(kFujitsuAcFanHigh);
ac.setTemp(24);
EXPECT_EQ(kFujitsuAcFanHigh, ac.getFanSpeed());
EXPECT_EQ(kFujitsuAcModeCool, ac.getMode());
EXPECT_EQ(24, ac.getTemp());
EXPECT_EQ(kFujitsuAcSwingBoth, ac.getSwing());
EXPECT_EQ(kFujitsuAcCmdStayOn, ac.getCmd());
irsend.reset();
irsend.sendFujitsuAC(ac.getRaw(), kFujitsuAcStateLength);
EXPECT_EQ(
"f38000d50"
"m3324s1574"
"m448s390m448s390m448s1182m448s390m448s1182m448s390m448s390m448s390"
"m448s1182m448s1182m448s390m448s390m448s390m448s1182m448s1182m448s390"
"m448s390m448s390m448s390m448s390m448s390m448s390m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s1182m448s390m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s1182m448s390m448s390m448s390"
"m448s390m448s1182m448s1182m448s1182m448s1182m448s1182m448s1182m448s1182"
"m448s1182m448s390m448s390m448s1182m448s390m448s390m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s1182m448s1182m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s390m448s390m448s390m448s1182"
"m448s1182m448s390m448s390m448s390m448s390m448s390m448s390m448s390"
"m448s1182m448s390m448s390m448s390m448s1182m448s1182m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s390m448s390m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s390m448s390m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s390m448s390m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s390m448s1182m448s390m448s390"
"m448s390m448s1182m448s1182m448s1182m448s1182m448s1182m448s1182m448s1182"
"m448s8100",
irsend.outputStr());
}
TEST(TestSendFujitsuAC, GenerateShortMessage) {
IRFujitsuAC ac(0);
IRsendTest irsend(0);
ac.begin();
irsend.begin();
ac.off();
EXPECT_EQ(kFujitsuAcCmdTurnOff, ac.getCmd());
irsend.reset();
irsend.sendFujitsuAC(ac.getRaw(), kFujitsuAcStateLengthShort);
EXPECT_EQ(
"f38000d50"
"m3324s1574m448s390m448s390m448s1182m448s390m448s1182m448s390m448s390m448"
"s390m448s1182m448s1182m448s390m448s390m448s390m448s1182m448s1182m448s390"
"m448s390m448s390m448s390m448s390m448s390m448s390m448s390m448s390m448s390"
"m448s390m448s390m448s390m448s1182m448s390m448s390m448s390m448s390m448s390"
"m448s390m448s390m448s1182m448s390m448s390m448s390m448s390m448s1182m448s390"
"m448s390m448s390m448s390m448s390m448s390m448s1182m448s390m448s1182m448"
"s1182m448s1182m448s1182m448s1182m448s1182m448s8100",
irsend.outputStr());
}
// Issue #275
TEST(TestSendFujitsuAC, Issue275) {
IRFujitsuAC ac(0);
IRsendTest irsend(0);
ac.begin();
irsend.begin();
irsend.reset();
ac.setCmd(kFujitsuAcCmdTurnOff);
irsend.sendFujitsuAC(ac.getRaw(), kFujitsuAcStateLengthShort);
EXPECT_EQ(
"f38000d50"
// Header
"m3324s1574"
// 0 0 1 0 1 0 0 0 (0x28)
"m448s390m448s390m448s1182m448s390m448s1182m448s390m448s390m448s390"
// 1 1 0 0 0 1 1 0 (0xC6)
"m448s1182m448s1182m448s390m448s390m448s390m448s1182m448s1182m448s390"
// 0 0 0 0 0 0 0 0 (0x00)
"m448s390m448s390m448s390m448s390m448s390m448s390m448s390m448s390"
// 0 0 0 0 1 0 0 0 (0x08)
"m448s390m448s390m448s390m448s390m448s1182m448s390m448s390m448s390"
// 0 0 0 0 1 0 0 0 (0x08)
"m448s390m448s390m448s390m448s390m448s1182m448s390m448s390m448s390"
// 0 1 0 0 0 0 0 0 (0x40)
"m448s390m448s1182m448s390m448s390m448s390m448s390m448s390m448s390"
// 1 0 1 1 1 1 1 1 (0xBF)
"m448s1182m448s390m448s1182m448s1182m448s1182m448s1182m448s1182m448s1182"
// Footer
"m448s8100", irsend.outputStr());
irsend.reset();
// Per report in Issue #275
uint16_t off[115] = {
3350, 1650,
450, 400, 450, 450, 450, 1250, 450, 400, 450, 1250, 450, 400, 450, 400,
450, 400, 450, 1250, 450, 1250, 450, 400, 450, 400, 450, 400, 450, 1250,
450, 1250, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400,
450, 400, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400,
450, 1250, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400,
450, 400, 450, 1250, 450, 400, 450, 400, 450, 400, 450, 400, 450, 1250,
450, 400, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400, 450, 1250,
450, 400, 450, 1250, 450, 1250, 450, 1250, 450, 1250, 450, 1250,
450, 1250, 450};
irsend.sendRaw(off, 115, 38);
EXPECT_EQ(
"f38000d50"
// Header
"m3350s1650"
// 0 0 1 0 1 0 0 0 (0x28)
"m450s400m450s450m450s1250m450s400m450s1250m450s400m450s400m450s400"
// 1 1 0 0 0 1 1 0 (0xC6)
"m450s1250m450s1250m450s400m450s400m450s400m450s1250m450s1250m450s400"
// 0 0 0 0 0 0 0 0 (0x00)
"m450s400m450s400m450s400m450s400m450s400m450s400m450s400m450s400"
// 0 0 0 0 1 0 0 0 (0x08)
"m450s400m450s400m450s400m450s400m450s1250m450s400m450s400m450s400"
// 0 0 0 0 1 0 0 0 (0x08)
"m450s400m450s400m450s400m450s400m450s1250m450s400m450s400m450s400"
// 0 1 0 0 0 0 0 0 (0x40)
"m450s400m450s1250m450s400m450s400m450s400m450s400m450s400m450s400"
// 1 0 1 1 1 1 1 1 (0xBF)
"m450s1250m450s400m450s1250m450s1250m450s1250m450s1250m450s1250m450s1250"
// Footer
"m450",
irsend.outputStr());
}
TEST(TestDecodeFujitsuAC, SyntheticShortMessages) {
IRsendTest irsend(0);
IRFujitsuAC ac(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
ac.setModel(ARRAH2E);
ac.setCmd(kFujitsuAcCmdTurnOff);
irsend.sendFujitsuAC(ac.getRaw(), ac.getStateLength());
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(FUJITSU_AC, irsend.capture.decode_type);
ASSERT_EQ(kFujitsuAcMinBits + 8, irsend.capture.bits);
uint8_t expected_arrah2e[7] = {0x14, 0x63, 0x0, 0x10, 0x10, 0x02, 0xFD};
EXPECT_STATE_EQ(expected_arrah2e, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"Model: 1 (ARRAH2E), Power: Off, Mode: 0 (Auto), Temp: 16C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
irsend.reset();
ac.setModel(ARDB1);
ac.setCmd(kFujitsuAcCmdTurnOff);
irsend.sendFujitsuAC(ac.getRaw(), ac.getStateLength());
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(FUJITSU_AC, irsend.capture.decode_type);
ASSERT_EQ(kFujitsuAcMinBits, irsend.capture.bits);
uint8_t expected_ardb1[6] = {0x14, 0x63, 0x0, 0x10, 0x10, 0x02};
EXPECT_STATE_EQ(expected_ardb1, irsend.capture.state, irsend.capture.bits);
}
TEST(TestDecodeFujitsuAC, SyntheticLongMessages) {
IRsendTest irsend(0);
IRFujitsuAC ac(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
ac.setModel(ARRAH2E);
ac.setCmd(kFujitsuAcCmdStayOn);
ac.setSwing(kFujitsuAcSwingVert);
ac.setMode(kFujitsuAcModeCool);
ac.setFanSpeed(kFujitsuAcFanQuiet);
ac.setTemp(18);
irsend.sendFujitsuAC(ac.getRaw(), ac.getStateLength());
ASSERT_EQ(kFujitsuAcStateLength, ac.getStateLength());
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeFujitsuAC(&irsend.capture));
ASSERT_EQ(FUJITSU_AC, irsend.capture.decode_type);
ASSERT_EQ(kFujitsuAcBits, irsend.capture.bits);
uint8_t expected_arrah2e[kFujitsuAcStateLength] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30,
0x20, 0x01, 0x14, 0x00, 0x00, 0x00, 0x20, 0x7B};
EXPECT_STATE_EQ(expected_arrah2e, irsend.capture.state, irsend.capture.bits);
ac.setRaw(irsend.capture.state, irsend.capture.bits / 8);
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ("Model: 1 (ARRAH2E), Power: On, Mode: 1 (Cool), Temp: 18C, "
"Fan: 4 (Quiet), Clean: Off, Filter: Off, "
"Swing: 1 (Swing(V)), Command: N/A",
ac.toString());
irsend.reset();
ac.setModel(ARDB1);
irsend.sendFujitsuAC(ac.getRaw(), ac.getStateLength());
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(FUJITSU_AC, irsend.capture.decode_type);
ASSERT_EQ(kFujitsuAcBits - 8, irsend.capture.bits);
uint8_t expected_ardb1[kFujitsuAcStateLength - 1] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFC, 0x08, 0x30,
0x20, 0x01, 0x04, 0x00, 0x00, 0x00, 0xAB};
EXPECT_STATE_EQ(expected_ardb1, irsend.capture.state, irsend.capture.bits);
ac.setRaw(irsend.capture.state, irsend.capture.bits / 8);
EXPECT_EQ(kFujitsuAcStateLength - 1, ac.getStateLength());
EXPECT_EQ("Model: 2 (ARDB1), Power: On, Mode: 1 (Cool), Temp: 18C, "
"Fan: 4 (Quiet), Command: N/A", ac.toString());
}
TEST(TestDecodeFujitsuAC, RealShortARDB1OffExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
IRFujitsuAC ac(0);
irsend.begin();
irsend.reset();
// "Off" Message recorded from an AR-DB1 remote.
uint16_t rawData[99] = {
3310, 1636, 440, 386, 440, 394, 442, 1210, 442, 390, 414, 1220,
444, 390, 446, 380, 446, 380, 436, 1216, 438, 1214, 438, 388,
438, 386, 438, 396, 410, 1222, 440, 1220, 442, 384, 442, 384,
442, 384, 442, 382, 444, 382, 442, 382, 444, 380, 446, 380,
446, 380, 444, 380, 436, 390, 436, 388, 436, 388, 438, 1214,
438, 386, 438, 388, 438, 386, 440, 386, 440, 384, 442, 384,
442, 384, 442, 1210, 444, 382, 444, 382, 444, 382, 444, 380,
446, 1206, 436, 390, 436, 388, 436, 388, 438, 388, 438, 396,
420, 388, 436};
irsend.sendRaw(rawData, 99, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(FUJITSU_AC, irsend.capture.decode_type);
ASSERT_EQ(kFujitsuAcMinBits, irsend.capture.bits);
uint8_t expected[6] = {0x14, 0x63, 0x0, 0x10, 0x10, 0x02};
EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
ac.setRaw(irsend.capture.state, irsend.capture.bits / 8);
EXPECT_EQ(kFujitsuAcStateLengthShort - 1, ac.getStateLength());
EXPECT_EQ("Model: 2 (ARDB1), Power: Off, Mode: 0 (Auto), Temp: 16C, "
"Fan: 0 (Auto), Command: N/A", ac.toString());
}
TEST(TestDecodeFujitsuAC, RealLongARDB1Example) {
IRsendTest irsend(0);
IRrecv irrecv(0);
IRFujitsuAC ac(0);
irsend.begin();
irsend.reset();
uint16_t rawData1[243] = {
3316, 1632, 444, 390, 438, 388, 436, 1216, 438, 388, 438, 1214,
438, 388, 438, 386, 440, 386, 440, 1212, 440, 1210, 442, 392,
412, 396, 442, 392, 444, 1208, 444, 1208, 444, 380, 444, 380,
446, 380, 436, 390, 436, 390, 436, 390, 436, 388, 438, 388,
438, 388, 438, 388, 438, 386, 438, 386, 440, 384, 440, 1210,
442, 384, 442, 382, 442, 384, 442, 384, 442, 382, 442, 382,
444, 382, 444, 1208, 444, 382, 444, 380, 446, 380, 436, 390,
436, 390, 436, 1214, 438, 1214, 438, 1212, 440, 1212, 440, 1220,
412, 1222, 440, 394, 442, 382, 442, 382, 444, 1208, 444, 382,
444, 380, 446, 380, 446, 380, 434, 390, 436, 388, 438, 388,
438, 388, 438, 1214, 438, 1212, 440, 386, 440, 394, 412, 1222,
440, 394, 442, 384, 442, 384, 442, 382, 442, 1208, 444, 390,
414, 394, 442, 1216, 446, 380, 436, 390, 436, 390, 436, 388,
436, 390, 436, 388, 438, 386, 440, 386, 440, 386, 438, 1212,
440, 386, 440, 384, 440, 384, 442, 392, 412, 396, 440, 394,
442, 382, 444, 382, 444, 382, 444, 380, 444, 380, 444, 382,
444, 380, 446, 380, 436, 388, 436, 390, 436, 388, 438, 388,
438, 388, 438, 388, 438, 386, 440, 386, 440, 386, 442, 384,
440, 386, 442, 384, 440, 384, 442, 384, 442, 382, 442, 382,
444, 1208, 444, 382, 444, 1208, 444, 380, 446, 1206, 436, 390,
436, 1216, 436};
irsend.sendRaw(rawData1, 243, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(FUJITSU_AC, irsend.capture.decode_type);
ASSERT_EQ(kFujitsuAcBits - 8, irsend.capture.bits);
uint8_t expected1[kFujitsuAcStateLength - 1] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFC, 0x08, 0x30,
0x21, 0x01, 0x04, 0x00, 0x00, 0x00, 0xAA};
EXPECT_STATE_EQ(expected1, irsend.capture.state, irsend.capture.bits);
ac.setRaw(irsend.capture.state, irsend.capture.bits / 8);
EXPECT_EQ(kFujitsuAcStateLength - 1, ac.getStateLength());
EXPECT_EQ("Model: 2 (ARDB1), Power: On, Mode: 1 (Cool), Temp: 18C, "
"Fan: 4 (Quiet), Command: N/A", ac.toString());
irsend.reset();
uint16_t rawData2[243] = {
3316, 1630, 436, 398, 438, 386, 438, 1212, 440, 384, 440, 1212,
442, 384, 442, 392, 414, 394, 442, 1218, 446, 1206, 436, 390,
436, 388, 438, 388, 438, 1214, 440, 1212, 440, 384, 442, 384,
442, 384, 442, 382, 444, 382, 444, 382, 444, 380, 446, 380,
444, 380, 436, 390, 436, 388, 438, 396, 418, 388, 438, 1232,
410, 396, 440, 394, 442, 384, 442, 384, 442, 382, 442, 392,
414, 392, 444, 1216, 446, 380, 436, 390, 436, 396, 418, 390,
436, 398, 438, 1214, 440, 1212, 440, 1210, 442, 1208, 444, 1216,
416, 1218, 444, 388, 436, 390, 436, 388, 438, 1214, 440, 386,
438, 386, 440, 386, 440, 384, 442, 384, 442, 384, 442, 382,
444, 382, 444, 1206, 446, 1206, 436, 390, 436, 388, 438, 388,
438, 386, 440, 394, 410, 396, 440, 1220, 442, 1210, 442, 392,
414, 394, 442, 1218, 446, 406, 410, 388, 436, 390, 436, 390,
436, 388, 438, 386, 440, 386, 440, 386, 440, 386, 440, 384,
442, 384, 442, 384, 442, 382, 444, 382, 444, 380, 446, 380,
446, 380, 436, 390, 436, 390, 436, 388, 438, 386, 438, 388,
438, 386, 440, 386, 440, 384, 442, 384, 442, 384, 442, 384,
442, 382, 444, 382, 444, 380, 446, 380, 446, 380, 436, 390,
436, 388, 436, 388, 438, 386, 438, 386, 440, 386, 440, 1212,
440, 1210, 442, 1210, 442, 1208, 444, 1208, 436, 390, 436, 388,
436, 1214, 440};
irsend.sendRaw(rawData2, 243, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(FUJITSU_AC, irsend.capture.decode_type);
ASSERT_EQ(kFujitsuAcBits - 8, irsend.capture.bits);
uint8_t expected2[kFujitsuAcStateLength - 1] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFC, 0x08, 0x30,
0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x9F};
EXPECT_STATE_EQ(expected2, irsend.capture.state, irsend.capture.bits);
ac.setRaw(irsend.capture.state, irsend.capture.bits / 8);
EXPECT_EQ(kFujitsuAcStateLength - 1, ac.getStateLength());
EXPECT_EQ("Model: 2 (ARDB1), Power: On, Mode: 1 (Cool), Temp: 19C, "
"Fan: 0 (Auto), Command: N/A", ac.toString());
}
TEST(TestDecodeFujitsuAC, Issue414) {
IRsendTest irsend(0);
IRrecv irrecv(0);
IRFujitsuAC ac(0);
// Capture as supplied by arpmota
uint16_t rawData[259] = {3352, 1574, 480, 350, 480, 346, 480, 1190, 458, 346,
508, 1140, 480, 346, 506, 346, 458, 346, 480, 1168, 480, 1192, 452, 374,
458, 346, 480, 346, 508, 1168, 480, 1140, 480, 346, 506, 346, 458, 346,
480, 346, 480, 346, 480, 346, 484, 372, 454, 374, 456, 346, 508, 318,
480, 374, 458, 374, 480, 318, 480, 1196, 452, 346, 480, 346, 484, 342,
484, 346, 480, 374, 458, 346, 506, 318, 508, 1170, 452, 346, 480, 374,
458, 346, 506, 318, 480, 1196, 452, 1190, 458, 1162, 480, 1196, 452,
1170, 480, 1190, 458, 1164, 480, 1196, 480, 318, 508, 346, 456, 1192,
480, 346, 456, 374, 452, 346, 480, 374, 458, 342, 484, 346, 508, 346,
456, 342, 512, 1164, 458, 1164, 508, 346, 456, 346, 480, 1190, 456, 342,
484, 346, 506, 346, 456, 374, 452, 346, 508, 346, 458, 1164, 508, 346,
458, 374, 452, 1168, 480, 374, 480, 318, 480, 374, 456, 346, 508, 318,
480, 346, 484, 374, 480, 318, 484, 342, 484, 374, 480, 318, 484, 342,
484, 346, 508, 318, 508, 346, 458, 346, 506, 318, 480, 374, 458, 346,
506, 318, 480, 346, 484, 374, 480, 318, 482, 372, 456, 346, 508, 318,
506, 348, 456, 342, 484, 346, 508, 318, 484, 374, 480, 318, 508, 318,
484, 346, 508, 318, 480, 374, 456, 346, 508, 346, 480, 318, 480, 346,
484, 374, 480, 320, 484, 1164, 508, 346, 458, 342, 512, 1164, 458, 1190,
454, 346, 484, 1164, 508, 346, 458, 1164, 480, 350, 480, 374, 480};
uint8_t state[16] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30, 0x81, 0x04, 0x00, 0x00,
0x00, 0x00, 0x20, 0x2B};
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData, 259, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(FUJITSU_AC, irsend.capture.decode_type);
ASSERT_EQ(kFujitsuAcBits, irsend.capture.bits);
EXPECT_STATE_EQ(state, irsend.capture.state, irsend.capture.bits);
ac.setRaw(irsend.capture.state, irsend.capture.bits / 8);
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Power: On, Mode: 4 (Heat), Temp: 24C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A",
ac.toString());
// Resend it using the state this time.
irsend.reset();
irsend.sendFujitsuAC(state, 16);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(FUJITSU_AC, irsend.capture.decode_type);
ASSERT_EQ(kFujitsuAcBits, irsend.capture.bits);
EXPECT_STATE_EQ(state, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"f38000d50"
"m3324s1574"
"m448s390m448s390m448s1182m448s390m448s1182m448s390m448s390m448s390"
"m448s1182m448s1182m448s390m448s390m448s390m448s1182m448s1182m448s390"
"m448s390m448s390m448s390m448s390m448s390m448s390m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s1182m448s390m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s1182m448s390m448s390m448s390"
"m448s390m448s1182m448s1182m448s1182m448s1182m448s1182m448s1182m448s1182"
"m448s1182m448s390m448s390m448s1182m448s390m448s390m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s1182m448s1182m448s390m448s390"
"m448s1182m448s390m448s390m448s390m448s390m448s390m448s390m448s1182"
"m448s390m448s390m448s1182m448s390m448s390m448s390m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s390m448s390m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s390m448s390m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s390m448s390m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s390m448s390m448s390m448s390"
"m448s390m448s390m448s390m448s390m448s390m448s1182m448s390m448s390"
"m448s1182m448s1182m448s390m448s1182m448s390m448s1182m448s390m448s390"
"m448s8100", irsend.outputStr());
}
TEST(TestIRFujitsuACClass, toCommon) {
IRFujitsuAC ac(0);
ac.setMode(kFujitsuAcModeCool);
ac.setTemp(20);
ac.setFanSpeed(kFujitsuAcFanQuiet);
ac.setSwing(kFujitsuAcSwingBoth);
// Now test it.
ASSERT_EQ(decode_type_t::FUJITSU_AC, ac.toCommon().protocol);
ASSERT_EQ(fujitsu_ac_remote_model_t::ARRAH2E, ac.toCommon().model);
ASSERT_TRUE(ac.toCommon().power);
ASSERT_TRUE(ac.toCommon().celsius);
ASSERT_EQ(20, ac.toCommon().degrees);
ASSERT_TRUE(ac.toCommon().quiet);
ASSERT_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kMin, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kAuto, ac.toCommon().swingv);
ASSERT_EQ(stdAc::swingh_t::kAuto, ac.toCommon().swingh);
// Unsupported.
ASSERT_FALSE(ac.toCommon().filter);
ASSERT_FALSE(ac.toCommon().clean);
ASSERT_FALSE(ac.toCommon().turbo);
ASSERT_FALSE(ac.toCommon().light);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().sleep);
ASSERT_EQ(-1, ac.toCommon().clock);
// Check off mode which is special.
ac.off();
ASSERT_FALSE(ac.toCommon().power);
ac.send();
ac.stateReset();
IRrecv irrecv(0);
ac._irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&ac._irsend.capture));
ASSERT_EQ(FUJITSU_AC, ac._irsend.capture.decode_type);
ac.setRaw(ac._irsend.capture.state, ac._irsend.capture.bits / 8);
// Now test it.
EXPECT_EQ( // Off mode technically has no temp, mode, fan, etc.
"Model: 1 (ARRAH2E), Power: Off, Mode: 0 (Auto), Temp: 16C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A",
ac.toString());
ASSERT_EQ(decode_type_t::FUJITSU_AC, ac.toCommon().protocol);
ASSERT_EQ(fujitsu_ac_remote_model_t::ARRAH2E, ac.toCommon().model);
ASSERT_FALSE(ac.toCommon().power);
ASSERT_TRUE(ac.toCommon().celsius);
ASSERT_EQ(16, ac.toCommon().degrees);
ASSERT_FALSE(ac.toCommon().quiet);
ASSERT_EQ(stdAc::opmode_t::kAuto, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kAuto, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kOff, ac.toCommon().swingv);
ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh);
// Unsupported.
ASSERT_FALSE(ac.toCommon().filter);
ASSERT_FALSE(ac.toCommon().clean);
ASSERT_FALSE(ac.toCommon().turbo);
ASSERT_FALSE(ac.toCommon().light);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().sleep);
ASSERT_EQ(-1, ac.toCommon().clock);
}
TEST(TestDecodeFujitsuAC, Issue716) {
IRsendTest irsend(0);
IRrecv irrecv(0);
IRFujitsuAC ac(0);
// Powerful command from a raw data capture.
// Capture as supplied by u4mzu4
uint16_t rawData[115] = {
3320, 1610, 432, 406, 432, 406, 432, 1220, 432, 406, 432, 1192, 458, 406,
432, 406, 432, 406, 432, 1218, 432, 1220, 432, 406, 432, 406, 432, 406,
432, 1192, 458, 1192, 460, 406, 432, 406, 432, 406, 432, 406, 432, 406,
432, 406, 432, 406, 432, 408, 432, 406, 432, 406, 430, 406, 432, 406, 432,
406, 432, 1190, 460, 406, 432, 408, 430, 406, 432, 406, 432, 406, 432,
406, 432, 406, 434, 1192, 458, 406, 432, 406, 432, 406, 432, 1194, 458,
406, 432, 406, 432, 1194, 456, 1196, 454, 1220, 432, 406, 432, 406, 432,
408, 430, 1194, 458, 1194, 456, 406, 432, 406, 430, 406, 432, 1194, 458,
1194, 458}; // FUJITSU_AC
uint8_t powerful[kFujitsuAcStateLengthShort] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0x39, 0xC6};
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData, 115, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(FUJITSU_AC, irsend.capture.decode_type);
ASSERT_EQ(kFujitsuAcStateLengthShort * 8, irsend.capture.bits);
EXPECT_STATE_EQ(powerful, irsend.capture.state, irsend.capture.bits);
ac.setRaw(irsend.capture.state, irsend.capture.bits / 8);
EXPECT_EQ(fujitsu_ac_remote_model_t::ARREB1E, ac.getModel());
EXPECT_EQ(kFujitsuAcStateLengthShort, ac.getStateLength());
EXPECT_EQ("Model: 3 (ARREB1E), Power: On, Mode: 0 (Auto), Temp: 16C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), "
"Command: Powerful, Outside Quiet: Off",
ac.toString());
// Economy (just from the state)
uint8_t econo[kFujitsuAcStateLengthShort] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0x09, 0xF6};
// Make sure we can't accidentally inherit the correct model.
ASSERT_NE(fujitsu_ac_remote_model_t::ARDB1,
fujitsu_ac_remote_model_t::ARREB1E);
ac.setModel(fujitsu_ac_remote_model_t::ARDB1);
ac.setRaw(econo, kFujitsuAcStateLengthShort);
EXPECT_EQ(fujitsu_ac_remote_model_t::ARREB1E, ac.getModel());
EXPECT_EQ(kFujitsuAcStateLengthShort, ac.getStateLength());
EXPECT_EQ("Model: 3 (ARREB1E), Power: On, Mode: 0 (Auto), Temp: 16C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), "
"Command: Econo, Outside Quiet: Off",
ac.toString());
}
TEST(TestIRFujitsuACClass, OutsideQuiet) {
IRsendTest irsend(0);
IRrecv irrecv(0);
IRFujitsuAC ac(0);
ASSERT_NE(fujitsu_ac_remote_model_t::ARDB1,
fujitsu_ac_remote_model_t::ARREB1E);
ASSERT_NE(fujitsu_ac_remote_model_t::ARRAH2E,
fujitsu_ac_remote_model_t::ARREB1E);
// States as supplied by u4mzu4
// https://github.com/crankyoldgit/IRremoteESP8266/issues/716#issuecomment-495852309
uint8_t off[kFujitsuAcStateLength] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30,
0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x2F};
uint8_t on[kFujitsuAcStateLength] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30,
0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xAF};
// Make sure we can't accidentally inherit the correct model.
ac.setModel(fujitsu_ac_remote_model_t::ARDB1);
ac.setRaw(off, kFujitsuAcStateLength);
EXPECT_EQ(fujitsu_ac_remote_model_t::ARRAH2E, ac.getModel());
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_FALSE(ac.getOutsideQuiet());
// We can really only tell the difference between ARRAH2E & ARREB1E if
// the option is set. Otheriwse they appear the same.
EXPECT_EQ(
"Model: 1 (ARRAH2E), Power: On, Mode: 1 (Cool), Temp: 24C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), "
"Command: N/A", ac.toString());
ac.setModel(fujitsu_ac_remote_model_t::ARREB1E);
EXPECT_EQ(
"Model: 3 (ARREB1E), Power: On, Mode: 1 (Cool), Temp: 24C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), "
"Command: N/A, Outside Quiet: Off",
ac.toString());
// Make sure we can't accidentally inherit the correct model.
ac.setModel(fujitsu_ac_remote_model_t::ARDB1);
ac.setRaw(on, kFujitsuAcStateLength);
EXPECT_EQ(fujitsu_ac_remote_model_t::ARREB1E, ac.getModel());
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_TRUE(ac.getOutsideQuiet());
EXPECT_EQ(
"Model: 3 (ARREB1E), Power: On, Mode: 1 (Cool), Temp: 24C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), "
"Command: N/A, Outside Quiet: On",
ac.toString());
ac.setOutsideQuiet(false);
EXPECT_FALSE(ac.getOutsideQuiet());
ac.setOutsideQuiet(true);
EXPECT_TRUE(ac.getOutsideQuiet());
ac.setOutsideQuiet(false);
EXPECT_FALSE(ac.getOutsideQuiet());
}
TEST(TestIRFujitsuACClass, toggleSwing) {
IRsendTest irsend(0);
IRrecv irrecv(0);
IRFujitsuAC ac(0);
ac.begin();
ac.setModel(ARJW2);
ac.setSwing(kFujitsuAcSwingOff);
ac.setCmd(kFujitsuAcCmdStayOn);
ASSERT_EQ(kFujitsuAcSwingOff, ac.getSwing());
ac.toggleSwingHoriz();
EXPECT_EQ(kFujitsuAcCmdToggleSwingHoriz, ac.getCmd());
EXPECT_EQ(kFujitsuAcSwingHoriz, ac.getSwing());
ac.toggleSwingHoriz();
EXPECT_EQ(kFujitsuAcCmdToggleSwingHoriz, ac.getCmd());
EXPECT_EQ(kFujitsuAcSwingOff, ac.getSwing());
ac.toggleSwingVert();
EXPECT_EQ(kFujitsuAcCmdToggleSwingVert, ac.getCmd());
EXPECT_EQ(kFujitsuAcSwingVert, ac.getSwing());
ac.toggleSwingVert();
EXPECT_EQ(kFujitsuAcCmdToggleSwingVert, ac.getCmd());
EXPECT_EQ(kFujitsuAcSwingOff, ac.getSwing());
// Both
ac.toggleSwingHoriz();
EXPECT_EQ(kFujitsuAcCmdToggleSwingHoriz, ac.getCmd());
ac.toggleSwingVert();
EXPECT_EQ(kFujitsuAcCmdToggleSwingVert, ac.getCmd());
EXPECT_EQ(kFujitsuAcSwingBoth, ac.getSwing());
ac.toggleSwingHoriz();
EXPECT_EQ(kFujitsuAcCmdToggleSwingHoriz, ac.getCmd());
EXPECT_EQ(kFujitsuAcSwingVert, ac.getSwing());
ac.toggleSwingHoriz();
EXPECT_EQ(kFujitsuAcSwingBoth, ac.getSwing());
EXPECT_EQ(
"Model: 4 (ARJW2), Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 1 (High), "
"Command: Toggle Swing(H)",
ac.toString());
// Test without the update set.
ac.toggleSwingHoriz(false);
EXPECT_EQ(kFujitsuAcSwingBoth, ac.getSwing());
EXPECT_EQ(kFujitsuAcCmdToggleSwingHoriz, ac.getCmd());
ac.toggleSwingVert(false);
EXPECT_EQ(kFujitsuAcSwingBoth, ac.getSwing());
EXPECT_EQ(kFujitsuAcCmdToggleSwingVert, ac.getCmd());
}
TEST(TestDecodeFujitsuAC, Issue726) {
IRsendTest irsend(0);
IRrecv irrecv(0);
IRFujitsuAC ac(0);
// fan:auto mode:auto temp:24 poweron
// Capture as supplied by huexpub
// Rawdata was very messy. Had to use `./auto_analyse_raw_data.py -r 250` to
// get it to parse due to timings being above tolerances.
uint8_t auto_auto_on_24[kFujitsuAcStateLength] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30,
0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x2F};
irsend.begin();
irsend.reset();
irsend.sendFujitsuAC(auto_auto_on_24, 16);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(FUJITSU_AC, irsend.capture.decode_type);
ASSERT_EQ(kFujitsuAcStateLength * 8, irsend.capture.bits);
EXPECT_STATE_EQ(auto_auto_on_24, irsend.capture.state, irsend.capture.bits);
ac.setRaw(irsend.capture.state, irsend.capture.bits / 8);
EXPECT_EQ(fujitsu_ac_remote_model_t::ARRAH2E, ac.getModel());
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Power: On, Mode: 0 (Auto), Temp: 24C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A",
ac.toString());
}
TEST(TestIRFujitsuACClass, Clean) {
IRFujitsuAC ac(0);
// Data from:
// https://docs.google.com/spreadsheets/d/1f8EGfIbBUo2B-CzUFdrgKQprWakoYNKM80IKZN4KXQE/edit#gid=646887633&range=A27:B30
uint8_t clean_off[kFujitsuAcStateLength] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30,
0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10};
uint8_t clean_on[kFujitsuAcStateLength] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30,
0xA0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08};
ac.setRaw(clean_on, kFujitsuAcStateLength);
EXPECT_TRUE(ac.getClean());
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ(
"Model: 5 (ARRY4), Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 0 (Auto), Clean: On, Filter: Off, Swing: 0 (Off), Command: N/A",
ac.toString());
ac.setClean(false);
EXPECT_FALSE(ac.getClean());
EXPECT_STATE_EQ(clean_off, ac.getRaw(), ac.getStateLength() * 8)
ac.setClean(true);
EXPECT_TRUE(ac.getClean());
EXPECT_STATE_EQ(clean_on, ac.getRaw(), ac.getStateLength() * 8)
ac.setRaw(clean_off, kFujitsuAcStateLength);
EXPECT_FALSE(ac.getClean());
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A",
ac.toString());
// Now it is in ARRAH2E model mode, it shouldn't accept setting it on.
ac.setClean(true);
EXPECT_EQ(fujitsu_ac_remote_model_t::ARRAH2E, ac.getModel());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A",
ac.toString());
// But ARRY4 does.
ac.setModel(fujitsu_ac_remote_model_t::ARRY4);
EXPECT_TRUE(ac.getClean());
EXPECT_EQ(
"Model: 5 (ARRY4), Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 0 (Auto), Clean: On, Filter: Off, Swing: 0 (Off), Command: N/A",
ac.toString());
}
TEST(TestIRFujitsuACClass, Filter) {
IRFujitsuAC ac(0);
// Data from:
// https://docs.google.com/spreadsheets/d/1f8EGfIbBUo2B-CzUFdrgKQprWakoYNKM80IKZN4KXQE/edit#gid=646887633&range=A27:B30
uint8_t filter_on[kFujitsuAcStateLength] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30,
0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x07};
uint8_t filter_off[kFujitsuAcStateLength] = {
0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30,
0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10};
ac.setRaw(filter_on, kFujitsuAcStateLength);
EXPECT_TRUE(ac.getFilter());
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ(
"Model: 5 (ARRY4), Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 0 (Auto), Clean: Off, Filter: On, Swing: 0 (Off), Command: N/A",
ac.toString());
ac.setFilter(false);
EXPECT_FALSE(ac.getFilter());
ac.setFilter(true);
EXPECT_TRUE(ac.getFilter());
ac.setRaw(filter_off, kFujitsuAcStateLength);
EXPECT_FALSE(ac.getFilter());
EXPECT_EQ(kFujitsuAcStateLength, ac.getStateLength());
EXPECT_EQ(
"Model: 1 (ARRAH2E), Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A",
ac.toString());
// Now it is in ARRAH2E model mode, it shouldn't accept setting it on.
ac.setFilter(true);
EXPECT_FALSE(ac.getFilter());
// But ARRY4 does.
ac.setModel(fujitsu_ac_remote_model_t::ARRY4);
EXPECT_TRUE(ac.getFilter());
EXPECT_EQ(
"Model: 5 (ARRY4), Power: On, Mode: 0 (Auto), Temp: 26C, "
"Fan: 0 (Auto), Clean: Off, Filter: On, Swing: 0 (Off), Command: N/A",
ac.toString());
}

View File

@@ -0,0 +1,167 @@
// Copyright 2018 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendGICable().
// Test sending typical data only.
TEST(TestSendGICable, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
irsend.sendGICable(0);
EXPECT_EQ(
"f39000d50"
"m9000s4400"
"m550s2200m550s2200m550s2200m550s2200m550s2200m550s2200m550s2200m550s2200"
"m550s2200m550s2200m550s2200m550s2200m550s2200m550s2200m550s2200m550s2200"
"m550s41650"
"m9000s2200m550s87850",
irsend.outputStr());
irsend.sendGICable(0x8807);
EXPECT_EQ(
"f39000d50"
"m9000s4400"
"m550s4400m550s2200m550s2200m550s2200m550s4400m550s2200m550s2200m550s2200"
"m550s2200m550s2200m550s2200m550s2200m550s2200m550s4400m550s4400m550s4400"
"m550s30650"
"m9000s2200m550s87850",
irsend.outputStr());
irsend.sendGICable(0xFFFF);
EXPECT_EQ(
"f39000d50"
"m9000s4400"
"m550s4400m550s4400m550s4400m550s4400m550s4400m550s4400m550s4400m550s4400"
"m550s4400m550s4400m550s4400m550s4400m550s4400m550s4400m550s4400m550s4400"
"m550s6450"
"m9000s2200m550s87850",
irsend.outputStr());
}
// Test sending with repeats.
TEST(TestSendGICable, SendWithRepeats) {
IRsendTest irsend(0);
irsend.begin();
// Send a command with 0 repeats.
irsend.sendGICable(0x8807, kGicableBits, 0);
EXPECT_EQ(
"f39000d50"
"m9000s4400"
"m550s4400m550s2200m550s2200m550s2200m550s4400m550s2200m550s2200m550s2200"
"m550s2200m550s2200m550s2200m550s2200m550s2200m550s4400m550s4400m550s4400"
"m550s30650",
irsend.outputStr());
// Send a command with 1 repeat.
irsend.sendGICable(0x8807, kGicableBits, 1);
EXPECT_EQ(
"f39000d50"
"m9000s4400"
"m550s4400m550s2200m550s2200m550s2200m550s4400m550s2200m550s2200m550s2200"
"m550s2200m550s2200m550s2200m550s2200m550s2200m550s4400m550s4400m550s4400"
"m550s30650"
"m9000s2200m550s87850",
irsend.outputStr());
// Send a command with 3 repeats.
irsend.sendGICable(0x8807, kGicableBits, 3);
EXPECT_EQ(
"f39000d50"
"m9000s4400"
"m550s4400m550s2200m550s2200m550s2200m550s4400m550s2200m550s2200m550s2200"
"m550s2200m550s2200m550s2200m550s2200m550s2200m550s4400m550s4400m550s4400"
"m550s30650"
"m9000s2200m550s87850"
"m9000s2200m550s87850"
"m9000s2200m550s87850",
irsend.outputStr());
}
// Tests for decodeGICable().
// Decode normal GICable messages.
TEST(TestDecodeGICable, SyntheticDecode) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Synthesised Normal GICable message.
irsend.reset();
irsend.sendGICable(0x8807);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(GICABLE, irsend.capture.decode_type);
EXPECT_EQ(kGicableBits, irsend.capture.bits);
EXPECT_EQ(0x8807, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
// Decode a recorded example
TEST(TestDecodeGICable, RealExampleDecodeOK) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Real GICable "OK/Select" message.
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/447
uint16_t rawData[39] = {9064, 4408, 580, 4408, 580, 2152, 578, 2150,
580, 2150, 580, 4408, 580, 2150, 580, 2150,
580, 2150, 580, 2150, 580, 2150, 580, 2150,
580, 2150, 580, 2150, 580, 4408, 580, 4408,
580, 4408, 580, 30622, 9066, 2148, 580};
irsend.reset();
irsend.sendRaw(rawData, 39, 39);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(GICABLE, irsend.capture.decode_type);
EXPECT_EQ(kGicableBits, irsend.capture.bits);
EXPECT_EQ(0x8807, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
TEST(TestDecodeGICable, RealExampleDecodeLEFT) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Real GICable "LEFT" message.
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/447
uint16_t rawData[39] = {9040, 4434, 554, 2176, 580, 4408, 554, 4434,
582, 2148, 554, 4434, 580, 4408, 556, 2174,
580, 2150, 580, 2150, 582, 2148, 556, 2176,
580, 2150, 580, 4408, 580, 4408, 580, 4408,
582, 2150, 580, 26078, 9066, 2148, 580};
irsend.reset();
irsend.sendRaw(rawData, 39, 39);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(GICABLE, irsend.capture.decode_type);
EXPECT_EQ(kGicableBits, irsend.capture.bits);
EXPECT_EQ(0x6C0E, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
TEST(TestDecodeGICable, RealExampleDecodeZEROKey) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Real GICable "Zero Key" message.
// Note: Zero key looks similar to a JVC message, hence this test.
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/447
uint16_t rawData[39] = {9036, 4434, 552, 2178, 552, 2178, 552, 2180,
550, 2178, 552, 2178, 550, 2180, 552, 2178,
552, 2178, 550, 2180, 552, 2178, 526, 2204,
552, 2178, 552, 2178, 526, 2204, 526, 2204,
526, 2204, 526, 41932, 9036, 2176, 552};
irsend.reset();
irsend.sendRaw(rawData, 39, 39);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(GICABLE, irsend.capture.decode_type);
EXPECT_EQ(kGicableBits, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}

View File

@@ -0,0 +1,73 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendGlobalCache().
// Test sending a typical command wihtout a repeat.
TEST(TestSendGlobalCache, NonRepeatingCode) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Modified NEC TV "Power On" from Global Cache with no repeats
uint16_t gc_test[71] = {38000, 1, 1, 342, 172, 21, 22, 21, 21, 21, 65, 21,
21, 21, 22, 21, 22, 21, 21, 21, 22, 21, 65, 21,
65, 21, 22, 21, 65, 21, 65, 21, 65, 21, 65, 21,
65, 21, 65, 21, 22, 21, 22, 21, 21, 21, 22, 21,
22, 21, 65, 21, 22, 21, 21, 21, 65, 21, 65, 21,
65, 21, 64, 22, 65, 21, 22, 21, 65, 21, 1519};
irsend.sendGC(gc_test, 71);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0x20DF827D, irsend.capture.value);
EXPECT_EQ(0x4, irsend.capture.address);
EXPECT_EQ(0x41, irsend.capture.command);
EXPECT_EQ(
"f38000d50"
"m8892s4472m546s572m546s546m546s1690m546s546m546s572m546s572"
"m546s546m546s572m546s1690m546s1690m546s572m546s1690m546s1690"
"m546s1690m546s1690m546s1690m546s1690m546s572m546s572m546s546"
"m546s572m546s572m546s1690m546s572m546s546m546s1690m546s1690"
"m546s1690m546s1664m572s1690m546s572m546s1690m546s39494",
irsend.outputStr());
}
// Test sending typical command with repeats.
TEST(TestSendGlobalCache, RepeatCode) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Sherwood (NEC-like) "Power On" from Global Cache with 2 repeats
uint16_t gc_test[75] = {
38000, 2, 69, 341, 171, 21, 64, 21, 64, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 64, 21, 64, 21, 21, 21, 64, 21, 21, 21,
21, 21, 21, 21, 64, 21, 21, 21, 64, 21, 21, 21, 21, 21, 21,
21, 64, 21, 21, 21, 21, 21, 21, 21, 21, 21, 64, 21, 64, 21,
64, 21, 21, 21, 64, 21, 64, 21, 64, 21, 1600, 341, 85, 21, 3647};
irsend.sendGC(gc_test, 75);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0xC1A28877, irsend.capture.value);
EXPECT_EQ(0x4583, irsend.capture.address);
EXPECT_EQ(0x11, irsend.capture.command);
EXPECT_EQ(
"f38000d50"
"m8866s4446m546s1664m546s1664m546s546m546s546m546s546m546s546"
"m546s546m546s1664m546s1664m546s546m546s1664m546s546m546s546"
"m546s546m546s1664m546s546m546s1664m546s546m546s546m546s546"
"m546s1664m546s546m546s546m546s546m546s546m546s1664m546s1664"
"m546s1664m546s546m546s1664m546s1664m546s1664m546s41600"
"m8866s2210m546s94822"
"m8866s2210m546s94822",
irsend.outputStr());
}

View File

@@ -0,0 +1,513 @@
// Copyright 2019 David Conran
#include "ir_Goodweather.h"
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
TEST(TestIRUtils, Goodweather) {
ASSERT_EQ("GOODWEATHER", typeToString(decode_type_t::GOODWEATHER));
ASSERT_EQ(decode_type_t::GOODWEATHER, strToDecodeType("GOODWEATHER"));
ASSERT_FALSE(hasACState(decode_type_t::GOODWEATHER));
}
// Tests for sendGoodweather().
// Test sending typical data only.
TEST(TestSendGoodweather, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
irsend.sendGoodweather(0x0);
EXPECT_EQ(
"f38000d50"
"m6820s6820"
"m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860"
"m580s580m580s580m580s580m580s580m580s580m580s580m580s580m580s580"
"m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860"
"m580s580m580s580m580s580m580s580m580s580m580s580m580s580m580s580"
"m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860"
"m580s580m580s580m580s580m580s580m580s580m580s580m580s580m580s580"
"m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860"
"m580s580m580s580m580s580m580s580m580s580m580s580m580s580m580s580"
"m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860"
"m580s580m580s580m580s580m580s580m580s580m580s580m580s580m580s580"
"m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860m580s1860"
"m580s580m580s580m580s580m580s580m580s580m580s580m580s580m580s580"
"m580s6820m580s100000",
irsend.outputStr());
irsend.reset();
}
// Tests for decodeGoodweather().
// Decode normal Goodweather messages.
TEST(TestDecodeGoodweather, SyntheticDecode) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Normal (made-up value) Goodweather 48-bit message.
irsend.reset();
irsend.sendGoodweather(0x1234567890AB);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::GOODWEATHER, irsend.capture.decode_type);
EXPECT_EQ(kGoodweatherBits, irsend.capture.bits);
EXPECT_EQ(0x1234567890AB, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal (Real) Goodweather 48-bit message.
irsend.reset();
irsend.sendGoodweather(0xD5276A030000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::GOODWEATHER, irsend.capture.decode_type);
EXPECT_EQ(kGoodweatherBits, irsend.capture.bits);
EXPECT_EQ(0xD5276A030000, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode a real example of a Goodweather message.
// https://github.com/crankyoldgit/IRremoteESP8266/issues/697#issuecomment-490209819
TEST(TestDecodeGoodweather, RealExampleDecode) {
IRsendTest irsend(0);
IRrecv irrecv(0);
IRGoodweatherAc ac(0);
irsend.begin();
ac.begin();
irsend.reset();
// Raw Goodweather 48-bit message.
uint16_t rawData_4624AB[197] = {
6828, 6828, 732, 1780, 652, 1830, 652, 1806, 678, 1830, 652, 1806, 678,
1830, 652, 1830, 652, 1834, 706, 518, 734, 508, 734, 514, 734, 510, 732,
510, 732, 510, 732, 510, 732, 514, 732, 1776, 706, 1780, 628, 1854, 628,
1832, 654, 1832, 654, 1856, 628, 1832, 634, 1876, 680, 536, 708, 536, 708,
536, 706, 538, 706, 538, 706, 538, 706, 536, 680, 564, 680, 1828, 708,
1758, 680, 1804, 680, 1828, 708, 1778, 732, 1754, 732, 1754, 732, 1756,
732, 490, 658, 586, 658, 586, 658, 586, 658, 586, 658, 584, 658, 586, 658,
586, 660, 1850, 704, 520, 658, 1828, 658, 1826, 658, 1826, 658, 586, 660,
584, 684, 1826, 730, 490, 686, 1824, 660, 560, 710, 532, 710, 534, 712,
1776, 712, 1774, 686, 560, 712, 1774, 712, 1798, 730, 492, 712, 1798, 684,
1798, 678, 568, 730, 1756, 686, 1796, 686, 532, 712, 532, 712, 1796, 728,
494, 712, 532, 738, 1772, 730, 492, 712, 532, 738, 506, 738, 1772, 660,
582, 728, 1736, 712, 558, 710, 1750, 710, 558, 710, 510, 738, 1748, 738,
508, 736, 1772, 684, 534, 736, 1772, 704, 518, 738, 1772, 660, 1824, 678,
6770, 684}; // COOLIX 4624AB
irsend.sendRaw(rawData_4624AB, 197, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::GOODWEATHER, irsend.capture.decode_type);
EXPECT_EQ(kGoodweatherBits, irsend.capture.bits);
EXPECT_EQ(0xD52462000000, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
ac.setRaw(irsend.capture.value);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 20C, Fan: 3 (Low), "
"Turbo: -, Light: -, Sleep: -, Swing: 0 (Fast), Command: 0 (Power)",
ac.toString());
uint16_t rawData_FAD2BE31[197] = {
6142, 7348, 570, 1612, 638, 1562, 620, 1584, 670, 1538, 566, 1638, 564,
1610, 618, 1582, 642, 1542, 638, 498, 622, 518, 618, 496, 622, 518, 596,
522, 596, 542, 618, 498, 618, 520, 594, 1590, 614, 1586, 618, 1588, 640,
1592, 538, 1614, 612, 1584, 620, 1584, 616, 1592, 564, 546, 596, 540, 596,
520, 620, 520, 594, 524, 618, 522, 650, 466, 616, 522, 670, 1532, 618, 1568,
590, 1610, 618, 1612, 640, 1530, 594, 1586, 618, 1616, 590, 1586, 640, 472,
618, 520, 672, 446, 618, 520, 646, 474, 616, 520, 622, 500, 614, 518, 624,
1612, 560, 1616, 590, 1584, 620, 520, 646, 1540, 612, 518, 622, 516, 596,
1586, 618, 518, 622, 498, 616, 520, 622, 1582, 616, 498, 620, 1582, 622,
1586, 586, 528, 616, 1582, 622, 498, 616, 518, 624, 1582, 614, 1592, 568,
544, 620, 1580, 648, 1542, 610, 520, 622, 1586, 666, 1536, 592, 518, 600,
542, 594, 1592, 590, 544, 620, 498, 616, 518, 622, 1580, 620, 496, 620,
1586, 618, 502, 610, 1584, 620, 518, 672, 446, 620, 1612, 592, 504, 608,
1586, 618, 518, 646, 1540, 612, 520, 600, 1604, 622, 1582, 596, 7382, 566};
// UNKNOWN FAD2BE31
irsend.reset();
irsend.sendRaw(rawData_FAD2BE31, 197, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::GOODWEATHER, irsend.capture.decode_type);
EXPECT_EQ(kGoodweatherBits, irsend.capture.bits);
EXPECT_EQ(0xD52668000000, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
ac.setRaw(irsend.capture.value);
EXPECT_EQ(
"Power: Off, Mode: 1 (Cool), Temp: 22C, Fan: 3 (Low), Turbo: -, "
"Light: -, Sleep: -, Swing: 2 (Off), Command: 0 (Power)",
ac.toString());
uint16_t rawData_5453D3AD[197] = {
6190, 7298, 668, 1542, 614, 1590, 590, 1582, 620, 1584, 566, 1624, 632,
1592, 616, 1588, 638, 1538, 594, 520, 620, 520, 594, 522, 620, 520, 586,
530, 618, 520, 640, 480, 616, 520, 642, 1544, 612, 1588, 622, 1576, 668,
1540, 564, 1640, 592, 1582, 646, 1558, 670, 1536, 594, 518, 622, 520, 594,
522, 620, 520, 566, 552, 618, 520, 614, 504, 618, 518, 666, 1520, 610,
1586, 618, 1612, 636, 1568, 564, 1590, 614, 1584, 620, 1582, 666, 1542,
614, 526, 590, 520, 596, 520, 622, 520, 566, 550, 620, 520, 588, 530, 618,
520, 668, 1536, 594, 520, 646, 1558, 668, 452, 616, 1584, 642, 498, 566,
550, 618, 1582, 668, 454, 612, 1582, 646, 496, 594, 1614, 666, 450, 662,
1536, 584, 1600, 612, 520, 642, 1590, 588, 502, 616, 520, 588, 1600, 612,
1586, 616, 520, 612, 1574, 610, 1584, 644, 496, 564, 1620, 636, 1562, 640,
524, 560, 530, 616, 1582, 644, 498, 620, 494, 670, 472, 622, 1558, 616,
520, 642, 1564, 594, 518, 646, 1558, 668, 454, 638, 494, 668, 1538, 616,
498, 642, 1558, 670, 454, 636, 1560, 642, 496, 614, 1592, 616, 1584, 620,
7350, 668}; // UNKNOWN 5453D3AD
irsend.reset();
irsend.sendRaw(rawData_5453D3AD, 197, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::GOODWEATHER, irsend.capture.decode_type);
EXPECT_EQ(kGoodweatherBits, irsend.capture.bits);
EXPECT_EQ(0xD5266A000000, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
ac.setRaw(irsend.capture.value);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 22C, Fan: 3 (Low), Turbo: -, "
"Light: -, Sleep: -, Swing: 2 (Off), Command: 0 (Power)",
ac.toString());
uint16_t rawData_B2354FBB[197] = {
6192, 7298, 592, 1616, 618, 1584, 620, 1558, 668, 1520, 636, 1562, 642,
1584, 590, 1614, 542, 1634, 622, 494, 668, 454, 638, 494, 670, 454, 638,
492, 646, 480, 636, 494, 672, 470, 622, 1560, 642, 1556, 672, 1534, 614,
1572, 636, 1584, 622, 1582, 644, 1534, 596, 1586, 642, 494, 666, 454, 640,
494, 668, 452, 640, 494, 668, 454, 638, 494, 670, 470, 620, 1562, 666,
470, 644, 1546, 634, 1584, 618, 1584, 644, 1534, 640, 1548, 636, 1560,
644, 520, 542, 1618, 638, 494, 670, 454, 636, 496, 670, 454, 634, 494,
672, 470, 620, 1564, 640, 496, 642, 1562, 616, 520, 622, 1558, 668, 450,
640, 494, 694, 1536, 566, 524, 644, 1558, 666, 456, 638, 1558, 644, 520,
572, 1588, 638, 1558, 644, 494, 590, 1596, 638, 1584, 620, 1584, 644, 454,
638, 1556, 672, 472, 620, 1562, 640, 1558, 646, 494, 644, 470, 646, 496,
566, 1618, 638, 494, 668, 1534, 646, 468, 674, 468, 568, 550, 670, 1530,
670, 454, 638, 1560, 644, 494, 622, 1582, 620, 494, 646, 496, 620, 1560,
644, 494, 668, 1522, 610, 518, 674, 1532, 614, 504, 640, 1584, 642, 1562,
616, 7332, 594}; // UNKNOWN B2354FBB
irsend.reset();
irsend.sendRaw(rawData_B2354FBB, 197, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::GOODWEATHER, irsend.capture.decode_type);
EXPECT_EQ(kGoodweatherBits, irsend.capture.bits);
EXPECT_EQ(0xD5286A020000, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
ac.setRaw(irsend.capture.value);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), Turbo: -, "
"Light: -, Sleep: -, Swing: 2 (Off), Command: 2 (Temp Up)",
ac.toString());
uint16_t rawData_71DD9105[197] = {
6190, 7296, 696, 1496, 634, 1562, 642, 1582, 640, 1564, 564, 1598, 638,
1558, 646, 1560, 588, 1616, 618, 520, 620, 494, 622, 494, 646, 494, 620,
496, 644, 494, 590, 528, 642, 494, 642, 1544, 638, 1584, 618, 1564, 804,
1394, 620, 1564, 640, 1558, 644, 1586, 562, 1616, 620, 492, 672, 470, 622,
494, 646, 494, 622, 494, 646, 494, 620, 498, 644, 492, 596, 520, 644, 494,
592, 1596, 612, 1584, 642, 1560, 614, 1612, 594, 1584, 620, 1558, 646,
1556, 644, 1562, 618, 520, 620, 494, 620, 494, 646, 494, 568, 548, 644,
494, 616, 1570, 638, 494, 670, 1534, 568, 550, 646, 1556, 616, 526, 618,
492, 672, 1532, 568, 550, 646, 1558, 640, 500, 618, 1560, 668, 470, 642,
1548, 658, 1536, 642, 520, 588, 504, 644, 492, 644, 478, 642, 1582, 618,
1586, 590, 506, 640, 1556, 646, 1584, 562, 1616, 620, 1558, 646, 1556,
670, 454, 638, 492, 648, 1558, 642, 478, 644, 492, 590, 530, 858, 1342,
642, 496, 618, 1564, 642, 492, 642, 1548, 636, 492, 648, 494, 622, 1562,
642, 492, 644, 1562, 618, 520, 620, 1558, 644, 476, 640, 1558, 646, 1558,
612, 7382, 594}; // UNKNOWN 71DD9105
irsend.reset();
irsend.sendRaw(rawData_71DD9105, 197, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::GOODWEATHER, irsend.capture.decode_type);
EXPECT_EQ(kGoodweatherBits, irsend.capture.bits);
EXPECT_EQ(0xD5276A030000, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
ac.setRaw(irsend.capture.value);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 23C, Fan: 3 (Low), "
"Turbo: -, Light: -, Sleep: -, Swing: 2 (Off), Command: 3 (Temp Down)",
ac.toString());
uint16_t rawData_C4F9E573[199] = {
6186, 7296, 648, 1558, 670, 1542, 612, 1584, 618, 1560, 668, 1534, 622,
1566, 638, 1558, 646, 1584, 590, 506, 640, 492, 642, 480, 640, 494, 644,
478, 640, 494, 668, 454, 614, 516, 648, 1560, 566, 1638, 618, 1584, 620,
1556, 672, 1534, 620, 1564, 640, 1584, 618, 1586, 564, 528, 670, 468, 640,
478, 642, 494, 644, 478, 640, 492, 670, 454, 638, 494, 670, 1560, 542,
1636, 644, 468, 670, 1534, 620, 1586, 618, 1558, 646, 1556, 670, 1534,
622, 492, 648, 494, 620, 1562, 642, 496, 642, 476, 642, 494, 696, 426,
642, 492, 646, 1558, 568, 548, 644, 494, 642, 1564, 618, 1584, 620, 494,
568, 548, 644, 1558, 644, 480, 636, 1584, 620, 1584, 644, 456, 634, 494,
672, 1560, 540, 1638, 618, 494, 728, 1476, 592, 524, 646, 492, 616, 1572,
638, 1560, 644, 492, 668, 1520, 638, 1562, 642, 494, 588, 1598, 638, 1560,
642, 494, 622, 498, 642, 1556, 646, 478, 638, 492, 646, 494, 620, 1584,
618, 522, 616, 1546, 612, 516, 648, 1556, 644, 476, 668, 468, 670, 1534,
620, 494, 648, 1556, 670, 452, 640, 1558, 644, 496, 646, 1536, 616, 1582,
646, 7326, 616, 41598, 230}; // UNKNOWN C4F9E573
irsend.reset();
irsend.sendRaw(rawData_C4F9E573, 199, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::GOODWEATHER, irsend.capture.decode_type);
EXPECT_EQ(kGoodweatherBits, irsend.capture.bits);
EXPECT_EQ(0xD52666040000, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 22C, Fan: 3 (Low), Turbo: -, Light: -, "
"Sleep: -, Swing: 1 (Slow), Command: 4 (Swing)",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestGoodweatherAcClass, toCommon) {
IRGoodweatherAc ac(0);
ac.setPower(true);
ac.setMode(kGoodweatherCool);
ac.setTemp(20);
ac.setFan(kGoodweatherFanHigh);
ac.setSwing(kGoodweatherSwingFast);
ac.setTurbo(true);
ac.setLight(true);
ac.setSleep(true);
// Now test it.
ASSERT_EQ(decode_type_t::GOODWEATHER, ac.toCommon().protocol);
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::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kAuto, ac.toCommon().swingv);
ASSERT_TRUE(ac.toCommon().turbo);
ASSERT_TRUE(ac.toCommon().light);
ASSERT_EQ(0, ac.toCommon().sleep);
// Unsupported.
ASSERT_EQ(-1, ac.toCommon().model);
ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh);
ASSERT_FALSE(ac.toCommon().quiet);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().filter);
ASSERT_FALSE(ac.toCommon().clean);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().clock);
}
TEST(TestGoodweatherAcClass, Temperature) {
IRGoodweatherAc ac(0);
ac.setTemp(kGoodweatherTempMin);
EXPECT_EQ(kGoodweatherTempMin, ac.getTemp());
ac.setTemp(kGoodweatherTempMin + 1);
EXPECT_EQ(kGoodweatherTempMin + 1, ac.getTemp());
ac.setTemp(kGoodweatherTempMax);
EXPECT_EQ(kGoodweatherTempMax, ac.getTemp());
ac.setTemp(kGoodweatherTempMin - 1);
EXPECT_EQ(kGoodweatherTempMin, ac.getTemp());
ac.setTemp(kGoodweatherTempMax + 1);
EXPECT_EQ(kGoodweatherTempMax, ac.getTemp());
ac.setTemp(23);
EXPECT_EQ(23, ac.getTemp());
ac.setTemp(27);
EXPECT_EQ(27, ac.getTemp());
ac.setTemp(22);
EXPECT_EQ(22, ac.getTemp());
ac.setTemp(25);
EXPECT_EQ(25, ac.getTemp());
ac.setTemp(0);
EXPECT_EQ(kGoodweatherTempMin, ac.getTemp());
ac.setTemp(255);
EXPECT_EQ(kGoodweatherTempMax, ac.getTemp());
}
TEST(TestGoodweatherAcClass, OperatingMode) {
IRGoodweatherAc ac(0);
ac.begin();
ac.setMode(kGoodweatherAuto);
EXPECT_EQ(kGoodweatherAuto, ac.getMode());
ac.setMode(kGoodweatherCool);
EXPECT_EQ(kGoodweatherCool, ac.getMode());
ac.setMode(kGoodweatherHeat);
EXPECT_EQ(kGoodweatherHeat, ac.getMode());
ac.setMode(kGoodweatherFan); // Should set fan speed to High.
EXPECT_EQ(kGoodweatherFan, ac.getMode());
ac.setMode(kGoodweatherDry);
EXPECT_EQ(kGoodweatherDry, ac.getMode());
ac.setMode(kGoodweatherHeat + 1);
EXPECT_EQ(kGoodweatherAuto, ac.getMode());
ac.setMode(kGoodweatherCool);
EXPECT_EQ(kGoodweatherCool, ac.getMode());
ac.setMode(kGoodweatherAuto - 1);
EXPECT_EQ(kGoodweatherAuto, ac.getMode());
ac.setMode(kGoodweatherCool);
ac.setMode(255);
EXPECT_EQ(kGoodweatherAuto, ac.getMode());
ac.setMode(kGoodweatherCool);
ac.setMode(0);
EXPECT_EQ(kGoodweatherAuto, ac.getMode());
}
TEST(TestGoodweatherAcClass, Power) {
IRGoodweatherAc ac(0);
ac.begin();
ac.setPower(true);
EXPECT_TRUE(ac.getPower());
ac.setPower(false);
EXPECT_EQ(false, ac.getPower());
ac.setPower(true);
EXPECT_TRUE(ac.getPower());
ac.off();
EXPECT_EQ(false, ac.getPower());
ac.on();
EXPECT_TRUE(ac.getPower());
}
TEST(TestGoodweatherAcClass, Light) {
IRGoodweatherAc ac(0);
ac.begin();
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
ac.setLight(false);
EXPECT_EQ(false, ac.getLight());
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
}
TEST(TestGoodweatherAcClass, Turbo) {
IRGoodweatherAc ac(0);
ac.begin();
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
ac.setTurbo(false);
EXPECT_EQ(false, ac.getTurbo());
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
}
TEST(TestGoodweatherAcClass, Sleep) {
IRGoodweatherAc ac(0);
ac.begin();
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
ac.setSleep(false);
EXPECT_EQ(false, ac.getSleep());
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
}
TEST(TestGoodweatherAcClass, FanSpeed) {
IRGoodweatherAc ac(0);
ac.begin();
// Unexpected value should default to Auto.
ac.setFan(255);
EXPECT_EQ(kGoodweatherFanAuto, ac.getFan());
ac.setFan(kGoodweatherFanLow);
EXPECT_EQ(kGoodweatherFanLow, ac.getFan());
ac.setFan(kGoodweatherFanMed);
EXPECT_EQ(kGoodweatherFanMed, ac.getFan());
ac.setFan(kGoodweatherFanHigh);
EXPECT_EQ(kGoodweatherFanHigh, ac.getFan());
ac.setFan(kGoodweatherFanAuto);
EXPECT_EQ(kGoodweatherFanAuto, ac.getFan());
// Beyond Low should default to Auto.
ac.setFan(kGoodweatherFanLow + 1);
EXPECT_EQ(kGoodweatherFanAuto, ac.getFan());
}
TEST(TestGoodweatherAcClass, SwingSpeed) {
IRGoodweatherAc ac(0);
ac.begin();
// Unexpected value should default to Off.
ac.setSwing(255);
EXPECT_EQ(kGoodweatherSwingOff, ac.getSwing());
ac.setSwing(kGoodweatherSwingSlow);
EXPECT_EQ(kGoodweatherSwingSlow, ac.getSwing());
ac.setSwing(kGoodweatherSwingOff);
EXPECT_EQ(kGoodweatherSwingOff, ac.getSwing());
ac.setSwing(kGoodweatherSwingFast);
EXPECT_EQ(kGoodweatherSwingFast, ac.getSwing());
// Beyond Off should default to Off.
ac.setSwing(kGoodweatherSwingOff + 1);
EXPECT_EQ(kGoodweatherSwingOff, ac.getSwing());
}
TEST(TestGoodweatherAcClass, Command) {
IRGoodweatherAc ac(0);
ac.begin();
ac.setCommand(kGoodweatherCmdMode);
EXPECT_EQ(kGoodweatherCmdMode, ac.getCommand());
// Unexpected value should not change anything.
ac.setCommand(255);
EXPECT_EQ(kGoodweatherCmdMode, ac.getCommand());
ac.setCommand(kGoodweatherCmdPower);
EXPECT_EQ(kGoodweatherCmdPower, ac.getCommand());
ac.setCommand(kGoodweatherCmdLight);
EXPECT_EQ(kGoodweatherCmdLight, ac.getCommand());
// Beyond Light should be ignored.
ac.setCommand(kGoodweatherCmdLight + 1);
EXPECT_EQ(kGoodweatherCmdLight, ac.getCommand());
}

View File

@@ -0,0 +1,763 @@
// Copyright 2017 David Conran
#include "ir_Gree.h"
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRremoteESP8266.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendGree().
// Test sending typical data only.
TEST(TestSendGreeChars, SendData) {
IRsendTest irsend(kGpioUnused);
irsend.begin();
uint8_t gree_code[kGreeStateLength] = {0x12, 0x34, 0x56, 0x78,
0x90, 0xAB, 0xCD, 0xEF};
irsend.reset();
irsend.sendGree(gree_code);
EXPECT_EQ(
"f38000d50"
"m9000s4500"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s540m620s540m620s1600m620s540m620s1600m620s1600m620s540m620s540"
"m620s540m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540"
"m620s540m620s540m620s540m620s1600m620s1600m620s1600m620s1600m620s540"
"m620s540m620s1600m620s540"
"m620s19000"
"m620s540m620s540m620s540m620s540m620s1600m620s540m620s540m620s1600"
"m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540m620s1600"
"m620s1600m620s540m620s1600m620s1600m620s540m620s540m620s1600m620s1600"
"m620s1600m620s1600m620s1600m620s1600m620s540m620s1600m620s1600m620s1600"
"m620s19000",
irsend.outputStr());
}
TEST(TestSendGreeUint64, SendData) {
IRsendTest irsend(kGpioUnused);
irsend.begin();
irsend.reset();
irsend.sendGree(0x1234567890ABCDEF);
EXPECT_EQ(
"f38000d50"
"m9000s4500"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s540m620s540m620s1600m620s540m620s1600m620s1600m620s540m620s540"
"m620s540m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540"
"m620s540m620s540m620s540m620s1600m620s1600m620s1600m620s1600m620s540"
"m620s540m620s1600m620s540"
"m620s19000"
"m620s540m620s540m620s540m620s540m620s1600m620s540m620s540m620s1600"
"m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540m620s1600"
"m620s1600m620s540m620s1600m620s1600m620s540m620s540m620s1600m620s1600"
"m620s1600m620s1600m620s1600m620s1600m620s540m620s1600m620s1600m620s1600"
"m620s19000",
irsend.outputStr());
}
// Test sending with repeats.
TEST(TestSendGreeChars, SendWithRepeats) {
IRsendTest irsend(kGpioUnused);
irsend.begin();
irsend.reset();
uint8_t gree_code[kGreeStateLength] = {0x12, 0x34, 0x56, 0x78,
0x90, 0xAB, 0xCD, 0xEF};
irsend.reset();
irsend.sendGree(gree_code, kGreeStateLength, 1);
EXPECT_EQ(
"f38000d50"
"m9000s4500"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s540m620s540m620s1600m620s540m620s1600m620s1600m620s540m620s540"
"m620s540m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540"
"m620s540m620s540m620s540m620s1600m620s1600m620s1600m620s1600m620s540"
"m620s540m620s1600m620s540"
"m620s19000"
"m620s540m620s540m620s540m620s540m620s1600m620s540m620s540m620s1600"
"m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540m620s1600"
"m620s1600m620s540m620s1600m620s1600m620s540m620s540m620s1600m620s1600"
"m620s1600m620s1600m620s1600m620s1600m620s540m620s1600m620s1600m620s1600"
"m620s19000"
"m9000s4500"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s540m620s540m620s1600m620s540m620s1600m620s1600m620s540m620s540"
"m620s540m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540"
"m620s540m620s540m620s540m620s1600m620s1600m620s1600m620s1600m620s540"
"m620s540m620s1600m620s540"
"m620s19000"
"m620s540m620s540m620s540m620s540m620s1600m620s540m620s540m620s1600"
"m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540m620s1600"
"m620s1600m620s540m620s1600m620s1600m620s540m620s540m620s1600m620s1600"
"m620s1600m620s1600m620s1600m620s1600m620s540m620s1600m620s1600m620s1600"
"m620s19000",
irsend.outputStr());
}
TEST(TestSendGreeUint64, SendWithRepeats) {
IRsendTest irsend(kGpioUnused);
irsend.begin();
irsend.reset();
irsend.sendGree(0x1234567890ABCDEF, kGreeBits, 1);
EXPECT_EQ(
"f38000d50"
"m9000s4500"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s540m620s540m620s1600m620s540m620s1600m620s1600m620s540m620s540"
"m620s540m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540"
"m620s540m620s540m620s540m620s1600m620s1600m620s1600m620s1600m620s540"
"m620s540m620s1600m620s540"
"m620s19000"
"m620s540m620s540m620s540m620s540m620s1600m620s540m620s540m620s1600"
"m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540m620s1600"
"m620s1600m620s540m620s1600m620s1600m620s540m620s540m620s1600m620s1600"
"m620s1600m620s1600m620s1600m620s1600m620s540m620s1600m620s1600m620s1600"
"m620s19000"
"m9000s4500"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s540m620s540m620s1600m620s540m620s1600m620s1600m620s540m620s540"
"m620s540m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540"
"m620s540m620s540m620s540m620s1600m620s1600m620s1600m620s1600m620s540"
"m620s540m620s1600m620s540"
"m620s19000"
"m620s540m620s540m620s540m620s540m620s1600m620s540m620s540m620s1600"
"m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540m620s1600"
"m620s1600m620s540m620s1600m620s1600m620s540m620s540m620s1600m620s1600"
"m620s1600m620s1600m620s1600m620s1600m620s540m620s1600m620s1600m620s1600"
"m620s19000",
irsend.outputStr());
}
// Test sending atypical sizes.
TEST(TestSendGreeChars, SendUnexpectedSizes) {
IRsendTest irsend(kGpioUnused);
irsend.begin();
uint8_t gree_short_code[kGreeStateLength - 1] = {0x12, 0x34, 0x56, 0x78,
0x90, 0xAB, 0xCD};
uint8_t gree_long_code[kGreeStateLength + 1] = {0x12, 0x34, 0x56, 0x78, 0x90,
0xAB, 0xCD, 0xEF, 0x12};
irsend.reset();
irsend.sendGree(gree_short_code, kGreeStateLength - 1);
ASSERT_EQ("", irsend.outputStr());
irsend.reset();
irsend.sendGree(gree_long_code, kGreeStateLength + 1);
ASSERT_EQ(
"f38000d50"
"m9000s4500"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s540m620s540m620s1600m620s540m620s1600m620s1600m620s540m620s540"
"m620s540m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540"
"m620s540m620s540m620s540m620s1600m620s1600m620s1600m620s1600m620s540"
"m620s540m620s1600m620s540"
"m620s19000"
"m620s540m620s540m620s540m620s540m620s1600m620s540m620s540m620s1600"
"m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540m620s1600"
"m620s1600m620s540m620s1600m620s1600m620s540m620s540m620s1600m620s1600"
"m620s1600m620s1600m620s1600m620s1600m620s540m620s1600m620s1600m620s1600"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s19000",
irsend.outputStr());
}
TEST(TestSendGreeUint64, SendUnexpectedSizes) {
IRsendTest irsend(kGpioUnused);
irsend.begin();
irsend.reset();
irsend.sendGree(0x1234567890ABCDEF, kGreeBits - 1);
ASSERT_EQ("", irsend.outputStr());
irsend.reset();
irsend.sendGree(0x1234567890ABCDEF, kGreeBits + 1);
ASSERT_EQ("", irsend.outputStr());
}
TEST(TestSendGree, CompareUint64ToCharResults) {
IRsendTest irsend_chars(4);
IRsendTest irsend_uint64(0);
uint8_t gree_code[kGreeStateLength] = {0x12, 0x34, 0x56, 0x78,
0x90, 0xAB, 0xCD, 0xEF};
irsend_chars.begin();
irsend_uint64.begin();
irsend_chars.reset();
irsend_uint64.reset();
irsend_chars.sendGree(gree_code);
irsend_uint64.sendGree(0x1234567890ABCDEF);
ASSERT_EQ(irsend_chars.outputStr(), irsend_uint64.outputStr());
uint8_t gree_zero_code[kGreeStateLength] = {0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
irsend_chars.reset();
irsend_uint64.reset();
irsend_chars.sendGree(gree_zero_code);
irsend_uint64.sendGree((uint64_t)0x0);
ASSERT_EQ(irsend_chars.outputStr(), irsend_uint64.outputStr());
}
// Tests for IRGreeAC class.
TEST(TestGreeClass, Power) {
IRGreeAC 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(TestGreeClass, Temperature) {
IRGreeAC ac(kGpioUnused);
ac.begin();
ac.setMode(kGreeCool);
ac.setTemp(0);
EXPECT_EQ(kGreeMinTempC, ac.getTemp());
ac.setTemp(255);
EXPECT_EQ(kGreeMaxTempC, ac.getTemp());
ac.setTemp(kGreeMinTempC);
EXPECT_EQ(kGreeMinTempC, ac.getTemp());
EXPECT_FALSE(ac.getUseFahrenheit());
ac.setTemp(kGreeMaxTempC);
EXPECT_EQ(kGreeMaxTempC, ac.getTemp());
ac.setTemp(kGreeMinTempC - 1);
EXPECT_EQ(kGreeMinTempC, ac.getTemp());
ac.setTemp(kGreeMaxTempC + 1);
EXPECT_EQ(kGreeMaxTempC, 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());
// Fahrenheit tests.
ac.setTemp(kGreeMinTempF, true);
ASSERT_TRUE(ac.getUseFahrenheit());
EXPECT_EQ(kGreeMinTempF, ac.getTemp());
ac.setTemp(kGreeMaxTempF, true);
ASSERT_TRUE(ac.getUseFahrenheit());
EXPECT_EQ(kGreeMaxTempF, ac.getTemp());
ac.setTemp(kGreeMaxTempF + 1, true);
ASSERT_TRUE(ac.getUseFahrenheit());
EXPECT_EQ(kGreeMaxTempF, ac.getTemp());
ac.setTemp(kGreeMaxTempF - 1, true);
ASSERT_TRUE(ac.getUseFahrenheit());
EXPECT_EQ(kGreeMaxTempF - 1, ac.getTemp());
ac.setTemp(kGreeMaxTempF - 2, true);
ASSERT_TRUE(ac.getUseFahrenheit());
EXPECT_EQ(kGreeMaxTempF - 2, ac.getTemp());
ac.setTemp(kGreeMinTempF - 1, true);
ASSERT_TRUE(ac.getUseFahrenheit());
EXPECT_EQ(kGreeMinTempF, ac.getTemp());
ac.setTemp(kGreeMinTempF + 1, true);
ASSERT_TRUE(ac.getUseFahrenheit());
EXPECT_EQ(kGreeMinTempF + 1, ac.getTemp());
ac.setTemp(kGreeMinTempF + 2, true);
ASSERT_TRUE(ac.getUseFahrenheit());
EXPECT_EQ(kGreeMinTempF + 2, ac.getTemp());
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1121#issuecomment-628946040
ac.setUseFahrenheit(false);
const uint8_t state[] = {0x09, 0x01, 0x20, 0x5C, 0x00, 0x20, 0x00, 0x20};
ac.setRaw(state);
EXPECT_TRUE(ac.getUseFahrenheit());
EXPECT_EQ(63, ac.getTemp());
EXPECT_EQ(
"Model: 2 (YBOFB), Power: On, Mode: 1 (Cool), Temp: 63F, Fan: 0 (Auto), "
"Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, "
"Swing(V) Mode: Manual, Swing(V): 0 (Last), Timer: Off, "
"Display Temp: 0 (Off)", ac.toString());
}
TEST(TestGreeClass, OperatingMode) {
IRGreeAC ac(kGpioUnused);
ac.begin();
ac.setTemp(17);
ac.setMode(kGreeAuto); // Auto should lock the temp to 25C.
EXPECT_EQ(kGreeAuto, ac.getMode());
EXPECT_EQ(25, ac.getTemp());
ac.setTemp(17);
EXPECT_EQ(25, ac.getTemp());
ac.setMode(kGreeCool);
EXPECT_EQ(kGreeCool, ac.getMode());
ac.setMode(kGreeHeat);
EXPECT_EQ(kGreeHeat, ac.getMode());
ASSERT_NE(kGreeFanMax, 1);
ac.setFan(kGreeFanMax);
ac.setMode(kGreeDry); // Dry should lock the fan to speed 1.
EXPECT_EQ(kGreeDry, ac.getMode());
EXPECT_EQ(1, ac.getFan());
ac.setFan(kGreeFanMax);
EXPECT_EQ(1, ac.getFan());
ac.setMode(kGreeFan);
EXPECT_EQ(kGreeFan, ac.getMode());
ac.setMode(kGreeHeat + 1);
EXPECT_EQ(kGreeAuto, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kGreeAuto, ac.getMode());
}
TEST(TestGreeClass, Light) {
IRGreeAC ac(kGpioUnused);
ac.begin();
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
ac.setLight(false);
EXPECT_FALSE(ac.getLight());
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
}
TEST(TestGreeClass, XFan) {
IRGreeAC ac(kGpioUnused);
ac.begin();
ac.setXFan(true);
EXPECT_TRUE(ac.getXFan());
ac.setXFan(false);
EXPECT_FALSE(ac.getXFan());
ac.setXFan(true);
EXPECT_TRUE(ac.getXFan());
}
TEST(TestGreeClass, Turbo) {
IRGreeAC ac(kGpioUnused);
ac.begin();
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
ac.setTurbo(false);
EXPECT_FALSE(ac.getTurbo());
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
}
TEST(TestGreeClass, IFeel) {
IRGreeAC ac(kGpioUnused);
ac.begin();
ac.setIFeel(true);
EXPECT_TRUE(ac.getIFeel());
ac.setIFeel(false);
EXPECT_FALSE(ac.getIFeel());
ac.setIFeel(true);
EXPECT_TRUE(ac.getIFeel());
// https://github.com/crankyoldgit/IRremoteESP8266/pull/770#issuecomment-504992209
uint8_t on[8] = {0x08, 0x09, 0x60, 0x50, 0x00, 0x44, 0x00, 0xF0};
uint8_t off[8] = {0x08, 0x09, 0x60, 0x50, 0x00, 0x40, 0x00, 0xF0};
ac.setRaw(off);
EXPECT_FALSE(ac.getIFeel());
ac.setRaw(on);
EXPECT_TRUE(ac.getIFeel());
}
TEST(TestGreeClass, WiFi) {
IRGreeAC ac(kGpioUnused);
ac.begin();
ac.setWiFi(true);
EXPECT_TRUE(ac.getWiFi());
ac.setWiFi(false);
EXPECT_FALSE(ac.getWiFi());
ac.setWiFi(true);
EXPECT_TRUE(ac.getWiFi());
// https://github.com/crankyoldgit/IRremoteESP8266/pull/770#issuecomment-504992209
uint8_t on[8] = {0x09, 0x09, 0x60, 0x50, 0x00, 0x40, 0x00, 0x00};
uint8_t off[8] = {0x09, 0x09, 0x60, 0x50, 0x00, 0x00, 0x00, 0xC0};
ac.setRaw(off);
EXPECT_FALSE(ac.getWiFi());
ac.setRaw(on);
EXPECT_TRUE(ac.getWiFi());
}
TEST(TestGreeClass, Sleep) {
IRGreeAC ac(kGpioUnused);
ac.begin();
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
ac.setSleep(false);
EXPECT_FALSE(ac.getSleep());
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
}
TEST(TestGreeClass, FanSpeed) {
IRGreeAC ac(kGpioUnused);
ac.begin();
ac.setFan(0);
EXPECT_EQ(0, ac.getFan());
ac.setFan(255);
EXPECT_EQ(kGreeFanMax, ac.getFan());
ac.setFan(kGreeFanMax);
EXPECT_EQ(kGreeFanMax, ac.getFan());
ac.setFan(kGreeFanMax + 1);
EXPECT_EQ(kGreeFanMax, ac.getFan());
ac.setFan(kGreeFanMax - 1);
EXPECT_EQ(kGreeFanMax - 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(TestGreeClass, VerticalSwing) {
IRGreeAC ac(kGpioUnused);
ac.begin();
EXPECT_FALSE(ac.getSwingVerticalAuto());
EXPECT_EQ(kGreeSwingLastPos, ac.getSwingVerticalPosition());
ac.setSwingVertical(true, kGreeSwingAuto);
EXPECT_TRUE(ac.getSwingVerticalAuto());
EXPECT_EQ(kGreeSwingAuto, ac.getSwingVerticalPosition());
ac.setSwingVertical(false, kGreeSwingMiddle);
EXPECT_FALSE(ac.getSwingVerticalAuto());
EXPECT_EQ(kGreeSwingMiddle, ac.getSwingVerticalPosition());
ac.setSwingVertical(true, kGreeSwingDownAuto);
EXPECT_TRUE(ac.getSwingVerticalAuto());
EXPECT_EQ(kGreeSwingDownAuto, ac.getSwingVerticalPosition());
// Out of bounds.
ac.setSwingVertical(false, 255);
EXPECT_FALSE(ac.getSwingVerticalAuto());
EXPECT_EQ(kGreeSwingLastPos, ac.getSwingVerticalPosition());
ac.setSwingVertical(false, kGreeSwingAuto);
EXPECT_FALSE(ac.getSwingVerticalAuto());
EXPECT_EQ(kGreeSwingLastPos, ac.getSwingVerticalPosition());
ac.setSwingVertical(true, 255);
EXPECT_TRUE(ac.getSwingVerticalAuto());
EXPECT_EQ(kGreeSwingAuto, ac.getSwingVerticalPosition());
ac.setSwingVertical(true, kGreeSwingDown);
EXPECT_TRUE(ac.getSwingVerticalAuto());
EXPECT_EQ(kGreeSwingAuto, ac.getSwingVerticalPosition());
}
TEST(TestGreeClass, SetAndGetRaw) {
IRGreeAC ac(kGpioUnused);
uint8_t initialState[kGreeStateLength] = {0x00, 0x09, 0x20, 0x50,
0x00, 0x20, 0x00, 0x50};
uint8_t expectedState[kGreeStateLength] = {0xA9, 0x05, 0xD0, 0x50,
0x00, 0x20, 0x00, 0xA0};
EXPECT_STATE_EQ(initialState, ac.getRaw(), kGreeBits);
// toggle the power state.
ac.setPower(!ac.getPower());
ac.setMode(kGreeCool);
ac.setTemp(21);
ac.setFan(2);
ac.setLight(false);
ac.setTurbo(true);
ac.setSleep(true);
ac.setXFan(true);
EXPECT_EQ(kGreeCool, ac.getMode());
EXPECT_EQ(21, ac.getTemp());
EXPECT_EQ(2, ac.getFan());
EXPECT_FALSE(ac.getLight());
EXPECT_TRUE(ac.getTurbo());
EXPECT_TRUE(ac.getSleep());
EXPECT_TRUE(ac.getXFan());
EXPECT_STATE_EQ(expectedState, ac.getRaw(), kGreeBits);
ac.setRaw(initialState);
EXPECT_STATE_EQ(initialState, ac.getRaw(), kGreeBits);
}
TEST(TestGreeClass, HumanReadable) {
IRGreeAC ac(kGpioUnused);
EXPECT_EQ(
"Model: 1 (YAW1F), Power: Off, Mode: 0 (Auto), Temp: 25C, Fan: 0 (Auto), "
"Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, "
"Swing(V) Mode: Manual, Swing(V): 0 (Last), "
"Timer: Off, Display Temp: 0 (Off)",
ac.toString());
ac.on();
ac.setMode(kGreeCool);
ac.setTemp(kGreeMinTempC);
ac.setFan(kGreeFanMax);
ac.setXFan(true);
ac.setSleep(true);
ac.setLight(false);
ac.setTurbo(true);
ac.setIFeel(true);
ac.setWiFi(true);
ac.setSwingVertical(true, kGreeSwingAuto);
ac.setTimer(12 * 60 + 30);
ac.setDisplayTempSource(3);
EXPECT_EQ(
"Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 3 (High), "
"Turbo: On, IFeel: On, WiFi: On, XFan: On, Light: Off, Sleep: On, "
"Swing(V) Mode: Auto, Swing(V): 1 (Auto), Timer: 12:30, "
"Display Temp: 3 (Outside)",
ac.toString());
}
// Tests for decodeGree().
// Decode a synthetic Gree message.
TEST(TestDecodeGree, NormalSynthetic) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
uint8_t gree_code[kGreeStateLength] = {0x00, 0x09, 0x20, 0x50,
0x00, 0x20, 0x00, 0x50};
irsend.reset();
irsend.sendGree(gree_code);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(GREE, irsend.capture.decode_type);
ASSERT_EQ(kGreeBits, irsend.capture.bits);
EXPECT_STATE_EQ(gree_code, irsend.capture.state, kGreeBits);
}
// Decode a real Gree message.
TEST(TestDecodeGree, NormalRealExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
IRGreeAC ac(kGpioUnused);
irsend.begin();
uint8_t gree_code[kGreeStateLength] = {0x19, 0x0A, 0x60, 0x50,
0x02, 0x23, 0x00, 0xF0};
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/386
uint16_t rawData[139] = {
9008, 4496, 644, 1660, 676, 530, 648, 558, 672, 1636, 646, 1660,
644, 556, 650, 584, 626, 560, 644, 580, 628, 1680, 624, 560,
648, 1662, 644, 582, 648, 536, 674, 530, 646, 580, 628, 560,
670, 532, 646, 562, 644, 556, 672, 536, 648, 1662, 646, 1660,
652, 554, 644, 558, 672, 538, 644, 560, 668, 560, 648, 1638,
668, 536, 644, 1660, 668, 532, 648, 560, 648, 1660, 674, 554,
622, 19990, 646, 580, 624, 1660, 648, 556, 648, 558, 674, 556,
622, 560, 644, 564, 668, 536, 646, 1662, 646, 1658, 672, 534,
648, 558, 644, 562, 648, 1662, 644, 584, 622, 558, 648, 562,
668, 534, 670, 536, 670, 532, 672, 536, 646, 560, 646, 558,
648, 558, 670, 534, 650, 558, 646, 560, 646, 560, 668, 1638,
646, 1662, 646, 1660, 646, 1660, 648}; // Issue #386
irsend.reset();
irsend.sendRaw(rawData, 139, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(GREE, irsend.capture.decode_type);
ASSERT_EQ(kGreeBits, irsend.capture.bits);
EXPECT_STATE_EQ(gree_code, irsend.capture.state, kGreeBits);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 26C, Fan: 1 (Low), "
"Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, "
"Swing(V) Mode: Manual, Swing(V): 2 (UNKNOWN), Timer: Off, "
"Display Temp: 3 (Outside)",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestGreeClass, toCommon) {
IRGreeAC ac(kGpioUnused);
ac.setPower(true);
ac.setMode(kGreeCool);
ac.setTemp(20);
ac.setFan(kGreeFanMax);
ac.setSwingVertical(false, kGreeSwingUp);
ac.setTurbo(true);
ac.setXFan(true);
ac.setLight(true);
ac.setSleep(true);
// Now test it.
ASSERT_EQ(decode_type_t::GREE, ac.toCommon().protocol);
ASSERT_EQ(gree_ac_remote_model_t::YAW1F, ac.toCommon().model);
ASSERT_TRUE(ac.toCommon().power);
ASSERT_TRUE(ac.toCommon().celsius);
ASSERT_EQ(20, ac.toCommon().degrees);
ASSERT_TRUE(ac.toCommon().turbo);
ASSERT_TRUE(ac.toCommon().clean);
ASSERT_TRUE(ac.toCommon().light);
ASSERT_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kHighest, ac.toCommon().swingv);
ASSERT_EQ(0, ac.toCommon().sleep);
// Unsupported.
ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh);
ASSERT_FALSE(ac.toCommon().quiet);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().filter);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().clock);
}
TEST(TestGreeClass, Issue814Power) {
IRGreeAC ac(kGpioUnused);
ac.begin();
// https://github.com/crankyoldgit/IRremoteESP8266/issues/814#issuecomment-511263921
uint8_t YBOFB_on[8] = {0x59, 0x07, 0x20, 0x50, 0x01, 0x20, 0x00, 0xC0};
uint8_t off[8] = {0x51, 0x07, 0x20, 0x50, 0x01, 0x20, 0x00, 0x40};
ac.on();
EXPECT_EQ(gree_ac_remote_model_t::YAW1F, ac.getModel());
ac.setRaw(off);
EXPECT_FALSE(ac.getPower());
ac.setRaw(YBOFB_on);
EXPECT_TRUE(ac.getPower());
EXPECT_EQ(gree_ac_remote_model_t::YBOFB, ac.getModel());
EXPECT_EQ(
"Model: 2 (YBOFB), Power: On, Mode: 1 (Cool), Temp: 23C, Fan: 1 (Low), "
"Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, "
"Swing(V) Mode: Auto, Swing(V): 1 (Auto), Timer: Off, "
"Display Temp: 0 (Off)",
ac.toString());
ac.off();
EXPECT_STATE_EQ(off, ac.getRaw(), kGreeBits);
ac.on();
EXPECT_STATE_EQ(YBOFB_on, ac.getRaw(), kGreeBits);
uint8_t YAW1F_on[8] = {0x59, 0x07, 0x60, 0x50, 0x01, 0x20, 0x00, 0xC0};
ac.setModel(gree_ac_remote_model_t::YAW1F);
EXPECT_STATE_EQ(YAW1F_on, ac.getRaw(), kGreeBits);
ac.off();
EXPECT_STATE_EQ(off, ac.getRaw(), kGreeBits);
ac.setModel(gree_ac_remote_model_t::YBOFB);
ac.on();
EXPECT_STATE_EQ(YBOFB_on, ac.getRaw(), kGreeBits);
}
TEST(TestGreeClass, Timer) {
IRGreeAC ac(kGpioUnused);
ac.begin();
ac.setTimer(0);
EXPECT_FALSE(ac.getTimerEnabled());
EXPECT_EQ(0, ac.getTimer());
ac.setTimer(29);
EXPECT_FALSE(ac.getTimerEnabled());
EXPECT_EQ(0, ac.getTimer());
ac.setTimer(30);
EXPECT_TRUE(ac.getTimerEnabled());
EXPECT_EQ(30, ac.getTimer());
ac.setTimer(60);
EXPECT_TRUE(ac.getTimerEnabled());
EXPECT_EQ(60, ac.getTimer());
ac.setTimer(90);
EXPECT_TRUE(ac.getTimerEnabled());
EXPECT_EQ(90, ac.getTimer());
ac.setTimer(10 * 60);
EXPECT_TRUE(ac.getTimerEnabled());
EXPECT_EQ(10 * 60, ac.getTimer());
ac.setTimer(23 * 60 + 59);
EXPECT_TRUE(ac.getTimerEnabled());
EXPECT_EQ(23 * 60 + 30, ac.getTimer());
ac.setTimer(24 * 60 + 1);
EXPECT_TRUE(ac.getTimerEnabled());
EXPECT_EQ(24 * 60, ac.getTimer());
ac.setTimer(24 * 60 + 30);
EXPECT_TRUE(ac.getTimerEnabled());
EXPECT_EQ(24 * 60, ac.getTimer());
}
TEST(TestGreeClass, DisplayTempSource) {
IRGreeAC ac(kGpioUnused);
ac.begin();
ac.setDisplayTempSource(1);
EXPECT_EQ(1, ac.getDisplayTempSource());
ac.setDisplayTempSource(2);
EXPECT_EQ(2, ac.getDisplayTempSource());
ac.setDisplayTempSource(3);
EXPECT_EQ(3, ac.getDisplayTempSource());
ac.setDisplayTempSource(1);
EXPECT_EQ(1, ac.getDisplayTempSource());
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1118#issuecomment-627674014
const uint8_t state[8] = {0x4C, 0x04, 0x60, 0x50, 0x01, 0x02, 0x00, 0xA0};
ac.setRaw(state);
EXPECT_EQ(2, ac.getDisplayTempSource());
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,119 @@
// Copyright 2019 crankyoldgit (David Conran)
#include "IRsend.h"
#include "IRsend_test.h"
#include "IRutils.h"
#include "gtest/gtest.h"
// General housekeeping
TEST(TestInax, Housekeeping) {
ASSERT_EQ("INAX", typeToString(INAX));
ASSERT_FALSE(hasACState(INAX));
}
// Tests for sendInax().
// Test sending typical data only.
TEST(TestSendInax, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
irsend.sendInax(0x5C32CD); // Small flush.
EXPECT_EQ(
"f38000d50"
"m9000s4500"
"m560s560m560s1675m560s560m560s1675m560s1675m560s1675m560s560m560s560"
"m560s560m560s560m560s1675m560s1675m560s560m560s560m560s1675m560s560"
"m560s1675m560s1675m560s560m560s560m560s1675m560s1675m560s560m560s1675"
"m560s40000"
"m9000s4500"
"m560s560m560s1675m560s560m560s1675m560s1675m560s1675m560s560m560s560"
"m560s560m560s560m560s1675m560s1675m560s560m560s560m560s1675m560s560"
"m560s1675m560s1675m560s560m560s560m560s1675m560s1675m560s560m560s1675"
"m560s40000",
irsend.outputStr());
irsend.reset();
}
// Test sending with different repeats.
TEST(TestSendInax, SendWithRepeats) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
irsend.sendInax(0x5C32CD, kInaxBits, 0); // 0 repeats.
EXPECT_EQ(
"f38000d50"
"m9000s4500"
"m560s560m560s1675m560s560m560s1675m560s1675m560s1675m560s560m560s560"
"m560s560m560s560m560s1675m560s1675m560s560m560s560m560s1675m560s560"
"m560s1675m560s1675m560s560m560s560m560s1675m560s1675m560s560m560s1675"
"m560s40000",
irsend.outputStr());
irsend.sendInax(0x5C32CD, kInaxBits, 2); // 2 repeats.
EXPECT_EQ(
"f38000d50"
"m9000s4500"
"m560s560m560s1675m560s560m560s1675m560s1675m560s1675m560s560m560s560"
"m560s560m560s560m560s1675m560s1675m560s560m560s560m560s1675m560s560"
"m560s1675m560s1675m560s560m560s560m560s1675m560s1675m560s560m560s1675"
"m560s40000"
"m9000s4500"
"m560s560m560s1675m560s560m560s1675m560s1675m560s1675m560s560m560s560"
"m560s560m560s560m560s1675m560s1675m560s560m560s560m560s1675m560s560"
"m560s1675m560s1675m560s560m560s560m560s1675m560s1675m560s560m560s1675"
"m560s40000"
"m9000s4500"
"m560s560m560s1675m560s560m560s1675m560s1675m560s1675m560s560m560s560"
"m560s560m560s560m560s1675m560s1675m560s560m560s560m560s1675m560s560"
"m560s1675m560s1675m560s560m560s560m560s1675m560s1675m560s560m560s1675"
"m560s40000",
irsend.outputStr());
}
// Tests for decodeInax().
// Decode normal Inax messages.
TEST(TestDecodeInax, SyntheticDecode) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Normal Inax 24-bit message.
irsend.reset();
irsend.sendInax(0x5C32CD);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(INAX, irsend.capture.decode_type);
EXPECT_EQ(kInaxBits, irsend.capture.bits);
EXPECT_EQ(0x5C32CD, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
}
// Decode real example via Issue #704
TEST(TestDecodeInax, DecodeExamples) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
// Inax Small Flush from Issue #309
uint16_t smallFlushRawData[51] = {
8996, 4474, 568, 556, 560, 1676, 568, 556, 562, 1676, 562, 1678, 566,
1674, 566, 558, 560, 560, 566, 556, 566, 556, 560, 1678, 562, 1676, 566,
556, 562, 560, 564, 1672, 566, 556, 562, 1676, 562, 1678, 562, 560, 564,
558, 564, 1674, 560, 1678, 564, 560, 566, 1670, 562};
irsend.sendRaw(smallFlushRawData, 51, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(INAX, irsend.capture.decode_type);
EXPECT_EQ(kInaxBits, irsend.capture.bits);
EXPECT_EQ(0x5C32CD, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
}

View File

@@ -0,0 +1,313 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendJVC().
// Test sending typical data only.
TEST(TestSendJVC, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendJVC(0xC2B8); // JVC VCR Power On.
EXPECT_EQ(
"f38000d33"
"m8400s4200"
"m525s1725m525s1725m525s525m525s525m525s525m525s525m525s1725m525s525"
"m525s1725m525s525m525s1725m525s1725m525s1725m525s525m525s525m525s525"
"m525s21675",
irsend.outputStr());
}
// Test sending with different repeats.
TEST(TestSendJVC, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendJVC(0xC2B8, kJvcBits, 1); // 1 repeat.
EXPECT_EQ(
"f38000d33"
"m8400s4200"
"m525s1725m525s1725m525s525m525s525m525s525m525s525m525s1725m525s525"
"m525s1725m525s525m525s1725m525s1725m525s1725m525s525m525s525m525s525"
"m525s21675"
"m525s1725m525s1725m525s525m525s525m525s525m525s525m525s1725m525s525"
"m525s1725m525s525m525s1725m525s1725m525s1725m525s525m525s525m525s525"
"m525s34275",
irsend.outputStr());
irsend.sendJVC(0xC2B8, kJvcBits, 2); // 2 repeats.
EXPECT_EQ(
"f38000d33"
"m8400s4200"
"m525s1725m525s1725m525s525m525s525m525s525m525s525m525s1725m525s525"
"m525s1725m525s525m525s1725m525s1725m525s1725m525s525m525s525m525s525"
"m525s21675"
"m525s1725m525s1725m525s525m525s525m525s525m525s525m525s1725m525s525"
"m525s1725m525s525m525s1725m525s1725m525s1725m525s525m525s525m525s525"
"m525s34275"
"m525s1725m525s1725m525s525m525s525m525s525m525s525m525s1725m525s525"
"m525s1725m525s525m525s1725m525s1725m525s1725m525s525m525s525m525s525"
"m525s34275",
irsend.outputStr());
}
// Test sending an atypical data size.
TEST(TestSendJVC, SendUnusualSize) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendJVC(0x0, 8);
EXPECT_EQ(
"f38000d33"
"m8400s4200"
"m525s525m525s525m525s525m525s525m525s525m525s525m525s525m525s525"
"m525s38475",
irsend.outputStr());
irsend.reset();
irsend.sendJVC(0x1234567890ABCDEF, 64);
EXPECT_EQ(
"f38000d33"
"m8400s4200"
"m525s525m525s525m525s525m525s1725m525s525m525s525m525s1725m525s525"
"m525s525m525s525m525s1725m525s1725m525s525m525s1725m525s525m525s525"
"m525s525m525s1725m525s525m525s1725m525s525m525s1725m525s1725m525s525"
"m525s525m525s1725m525s1725m525s1725m525s1725m525s525m525s525m525s525"
"m525s1725m525s525m525s525m525s1725m525s525m525s525m525s525m525s525"
"m525s1725m525s525m525s1725m525s525m525s1725m525s525m525s1725m525s1725"
"m525s1725m525s1725m525s525m525s525m525s1725m525s1725m525s525m525s1725"
"m525s1725m525s1725m525s1725m525s525m525s1725m525s1725m525s1725m525s1725"
"m525s10875",
irsend.outputStr());
}
// Tests for encodeJVC().
TEST(TestEncodeJVC, NormalEncoding) {
IRsendTest irsend(4);
EXPECT_EQ(0x0, irsend.encodeJVC(0, 0));
EXPECT_EQ(0x8080, irsend.encodeJVC(1, 1));
EXPECT_EQ(0x8040, irsend.encodeJVC(1, 2));
EXPECT_EQ(0xC2B8, irsend.encodeJVC(0x43, 0x1D));
EXPECT_EQ(0x55AA, irsend.encodeJVC(0xAA, 0x55));
EXPECT_EQ(0xFFFF, irsend.encodeJVC(0xFF, 0xFF));
}
// Tests for decodeJVC().
// Decode normal JVC messages.
TEST(TestDecodeJVC, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal JVC 16-bit message.
irsend.reset();
irsend.sendJVC(0xC2B8);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeJVC(&irsend.capture, kStartOffset, kJvcBits, true));
EXPECT_EQ(JVC, irsend.capture.decode_type);
EXPECT_EQ(kJvcBits, irsend.capture.bits);
EXPECT_EQ(0xC2B8, irsend.capture.value);
EXPECT_EQ(0x43, irsend.capture.address);
EXPECT_EQ(0x1D, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Synthesised Normal JVC 16-bit message.
irsend.reset();
irsend.sendJVC(irsend.encodeJVC(0x07, 0x99));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeJVC(&irsend.capture, kStartOffset, kJvcBits, true));
EXPECT_EQ(JVC, irsend.capture.decode_type);
EXPECT_EQ(kJvcBits, irsend.capture.bits);
EXPECT_EQ(0xE099, irsend.capture.value);
EXPECT_EQ(0x07, irsend.capture.address);
EXPECT_EQ(0x99, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Synthesised Normal JVC 16-bit message.
irsend.reset();
irsend.sendJVC(irsend.encodeJVC(0x1, 0x1));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeJVC(&irsend.capture, kStartOffset, kJvcBits, true));
EXPECT_EQ(JVC, irsend.capture.decode_type);
EXPECT_EQ(kJvcBits, irsend.capture.bits);
EXPECT_EQ(0x8080, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x1, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode normal repeated JVC messages.
TEST(TestDecodeJVC, NormalDecodeWithRepeatAndStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal JVC 16-bit message with 2 repeats.
irsend.reset();
irsend.sendJVC(0xC2B8, kJvcBits, 2);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeJVC(&irsend.capture, kStartOffset, kJvcBits, true));
EXPECT_EQ(JVC, irsend.capture.decode_type);
EXPECT_EQ(kJvcBits, irsend.capture.bits);
EXPECT_EQ(0xC2B8, irsend.capture.value);
EXPECT_EQ(0x43, irsend.capture.address);
EXPECT_EQ(0x1D, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
irsend.makeDecodeResult(2 * kJvcBits + 4);
ASSERT_TRUE(irrecv.decodeJVC(&irsend.capture, kStartOffset, kJvcBits, true));
EXPECT_EQ(JVC, irsend.capture.decode_type);
EXPECT_EQ(kJvcBits, irsend.capture.bits);
EXPECT_EQ(0xC2B8, irsend.capture.value);
EXPECT_TRUE(irsend.capture.repeat);
irsend.makeDecodeResult(2 * kJvcBits + 4 + 2 * kJvcBits + 2);
ASSERT_TRUE(irrecv.decodeJVC(&irsend.capture, kStartOffset, kJvcBits, true));
EXPECT_EQ(JVC, irsend.capture.decode_type);
EXPECT_EQ(kJvcBits, irsend.capture.bits);
EXPECT_EQ(0xC2B8, irsend.capture.value);
EXPECT_TRUE(irsend.capture.repeat);
// Simulate 'just' a JVC repeat command.
// JVC VCR Power On from Global Cache, but modified to be a repeat message.
uint16_t gc_test[37] = {38000, 1, 1, 20, 61, 20, 61, 20, 20, 20, 20, 20, 20,
20, 20, 20, 61, 20, 20, 20, 61, 20, 20, 20, 61, 20,
61, 20, 61, 20, 20, 20, 20, 20, 20, 20, 884};
irsend.reset();
irsend.sendGC(gc_test, 37);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeJVC(&irsend.capture));
EXPECT_EQ(JVC, irsend.capture.decode_type);
EXPECT_EQ(kJvcBits, irsend.capture.bits);
EXPECT_EQ(0xC2B8, irsend.capture.value);
EXPECT_EQ(0x43, irsend.capture.address);
EXPECT_EQ(0x1D, irsend.capture.command);
EXPECT_TRUE(irsend.capture.repeat);
}
// Decode unsupported JVC messages.
TEST(TestDecodeJVC, DecodeWithNonStrictValues) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendJVC(0x0, 8); // Illegal value JVC 8-bit message.
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeJVC(&irsend.capture, kStartOffset, kJvcBits, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeJVC(&irsend.capture, kStartOffset, 8, false));
EXPECT_EQ(JVC, irsend.capture.decode_type);
EXPECT_EQ(8, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
irsend.sendJVC(0x12345678, 32); // Illegal value JVC 32-bit message.
irsend.makeDecodeResult();
// Should not pass with strict when we ask for less bits than we got.
ASSERT_FALSE(irrecv.decodeJVC(&irsend.capture, kStartOffset, kJvcBits, true));
irsend.makeDecodeResult();
// Should fail with strict when we ask for the wrong bit size.
ASSERT_FALSE(irrecv.decodeJVC(&irsend.capture, kStartOffset, 32, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeJVC(&irsend.capture, kStartOffset, 32, false));
EXPECT_EQ(JVC, irsend.capture.decode_type);
EXPECT_EQ(32, irsend.capture.bits);
EXPECT_EQ(0x12345678, irsend.capture.value);
EXPECT_EQ(0x12346A, irsend.capture.address);
EXPECT_EQ(0x1E, irsend.capture.command);
// Illegal over length (36-bit) message.
irsend.reset();
irsend.sendJVC(irsend.encodeJVC(2, 3), 36);
irsend.makeDecodeResult();
// Shouldn't pass if strict off and the wrong expected bits.
ASSERT_FALSE(irrecv.decodeJVC(&irsend.capture, kStartOffset, kJvcBits,
false));
// Re-decode with correct bit size.
ASSERT_FALSE(irrecv.decodeJVC(&irsend.capture, kStartOffset, 36, true));
ASSERT_TRUE(irrecv.decodeJVC(&irsend.capture, kStartOffset, 36, false));
EXPECT_EQ(JVC, irsend.capture.decode_type);
EXPECT_EQ(36, irsend.capture.bits);
EXPECT_EQ(0x40C0, irsend.capture.value);
EXPECT_EQ(0x2, irsend.capture.address);
EXPECT_EQ(0x3, irsend.capture.command);
}
// Decode (non-standard) 64-bit messages.
TEST(TestDecodeJVC, Decode64BitMessages) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Illegal value & size JVC 64-bit message.
irsend.sendJVC(0xFFFFFFFFFFFFFFFF, 64);
irsend.makeDecodeResult();
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeJVC(&irsend.capture, kStartOffset, 64, false));
EXPECT_EQ(JVC, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, irsend.capture.value);
EXPECT_EQ(0xFFFFFFFF, irsend.capture.address);
EXPECT_EQ(0xFF, irsend.capture.command);
}
// Decode a 'real' example via GlobalCache
TEST(TestDecodeJVC, DecodeGlobalCacheExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// JVC VCR Power On from Global Cache.
uint16_t gc_test[39] = {38000, 1, 1, 322, 162, 20, 61, 20, 61, 20,
20, 20, 20, 20, 20, 20, 20, 20, 61, 20,
20, 20, 61, 20, 20, 20, 61, 20, 61, 20,
61, 20, 20, 20, 20, 20, 20, 20, 884};
// 38000,1,37,320,161,21,59,21,59,21,19,21,19,21,19,21,19,21,59,21,19,21,59,21,59,21,19,21,59,21,19,21,19,21,19,21,19,21,838,21,59,21,59,21,19,21,19,21,19,21,19,21,59,21,19,21,59,21,19,21,59,21,59,21,59,21,19,21,19,21,19,21,850};
irsend.sendGC(gc_test, 39);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeJVC(&irsend.capture));
EXPECT_EQ(JVC, irsend.capture.decode_type);
EXPECT_EQ(kJvcBits, irsend.capture.bits);
EXPECT_EQ(0xC2B8, irsend.capture.value);
EXPECT_EQ(0x43, irsend.capture.address);
EXPECT_EQ(0x1D, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Fail to decode a non-JVC example via GlobalCache
TEST(TestDecodeJVC, FailToDecodeNonJVCExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Modified a few entries to unexpected values, based on previous test case.
uint16_t gc_test[39] = {38000, 1, 1, 322, 162, 20, 61, 20, 61, 20,
20, 20, 20, 20, 20, 20, 127, 20, 61, 9,
20, 20, 61, 20, 20, 20, 61, 20, 61, 20,
61, 20, 20, 20, 20, 20, 20, 20, 884};
irsend.sendGC(gc_test, 39);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeJVC(&irsend.capture));
ASSERT_FALSE(irrecv.decodeJVC(&irsend.capture, kStartOffset, kJvcBits,
false));
}

View File

@@ -0,0 +1,566 @@
// Copyright 2017 David Conran
#include "ir_Kelvinator.h"
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRremoteESP8266.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendKelvinator().
// Test sending typical data only.
TEST(TestSendKelvinator, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
uint8_t kelv_code[kKelvinatorStateLength] = {
0x19, 0x0B, 0x80, 0x50, 0x00, 0x00, 0x00, 0xE0,
0x19, 0x0B, 0x80, 0x70, 0x00, 0x00, 0x10, 0xf0};
irsend.reset();
irsend.sendKelvinator(kelv_code);
EXPECT_EQ(
"f38000d50"
"m9010s4505"
"m680s1530m680s510m680s510m680s1530m680s1530m680s510m680s510m680s510"
"m680s1530m680s1530m680s510m680s1530m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s1530"
"m680s510m680s510m680s510m680s510m680s1530m680s510m680s1530m680s510"
"m680s510m680s1530m680s510"
"m680s19975"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s1530m680s1530m680s1530"
"m680s39950"
"m9010s4505"
"m680s1530m680s510m680s510m680s1530m680s1530m680s510m680s510m680s510"
"m680s1530m680s1530m680s510m680s1530m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s1530"
"m680s510m680s510m680s510m680s510m680s1530m680s1530m680s1530m680s510"
"m680s510m680s1530m680s510"
"m680s19975"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s1530m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s1530m680s1530m680s1530m680s1530"
"m680s39950",
irsend.outputStr());
}
// Test sending with repeats.
TEST(TestSendKelvinator, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
uint8_t kelv_code[kKelvinatorStateLength] = {
0x19, 0x0B, 0x80, 0x50, 0x00, 0x00, 0x00, 0xE0,
0x19, 0x0B, 0x80, 0x70, 0x00, 0x00, 0x10, 0xf0};
irsend.reset();
irsend.sendKelvinator(kelv_code, kKelvinatorStateLength, 1);
EXPECT_EQ(
"f38000d50"
"m9010s4505"
"m680s1530m680s510m680s510m680s1530m680s1530m680s510m680s510m680s510"
"m680s1530m680s1530m680s510m680s1530m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s1530"
"m680s510m680s510m680s510m680s510m680s1530m680s510m680s1530m680s510"
"m680s510m680s1530m680s510"
"m680s19975"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s1530m680s1530m680s1530"
"m680s39950"
"m9010s4505"
"m680s1530m680s510m680s510m680s1530m680s1530m680s510m680s510m680s510"
"m680s1530m680s1530m680s510m680s1530m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s1530"
"m680s510m680s510m680s510m680s510m680s1530m680s1530m680s1530m680s510"
"m680s510m680s1530m680s510"
"m680s19975"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s1530m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s1530m680s1530m680s1530m680s1530"
"m680s39950"
"m9010s4505"
"m680s1530m680s510m680s510m680s1530m680s1530m680s510m680s510m680s510"
"m680s1530m680s1530m680s510m680s1530m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s1530"
"m680s510m680s510m680s510m680s510m680s1530m680s510m680s1530m680s510"
"m680s510m680s1530m680s510"
"m680s19975"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s1530m680s1530m680s1530"
"m680s39950"
"m9010s4505"
"m680s1530m680s510m680s510m680s1530m680s1530m680s510m680s510m680s510"
"m680s1530m680s1530m680s510m680s1530m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s1530"
"m680s510m680s510m680s510m680s510m680s1530m680s1530m680s1530m680s510"
"m680s510m680s1530m680s510"
"m680s19975"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s1530m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s1530m680s1530m680s1530m680s1530"
"m680s39950",
irsend.outputStr());
}
// Test sending atypical sizes.
TEST(TestSendKelvinator, SendUnexpectedSizes) {
IRsendTest irsend(4);
irsend.begin();
uint8_t kelv_short_code[15] = {0x19, 0x0B, 0x80, 0x50, 0x00, 0x00, 0x00, 0xE0,
0x19, 0x0B, 0x80, 0x70, 0x00, 0x00, 0x10};
uint8_t kelv_long_code[17] = {0x19, 0x0B, 0x80, 0x50, 0x00, 0x00,
0x00, 0xE0, 0x19, 0x0B, 0x80, 0x70,
0x00, 0x00, 0x10, 0xf0, 0x00};
irsend.reset();
irsend.sendKelvinator(kelv_short_code, 15);
ASSERT_EQ("", irsend.outputStr());
irsend.reset();
// Shouldn't be different from the SendDataOnly. We just don't send the
// extra data.
irsend.sendKelvinator(kelv_long_code, 17);
ASSERT_EQ(
"f38000d50"
"m9010s4505"
"m680s1530m680s510m680s510m680s1530m680s1530m680s510m680s510m680s510"
"m680s1530m680s1530m680s510m680s1530m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s1530"
"m680s510m680s510m680s510m680s510m680s1530m680s510m680s1530m680s510"
"m680s510m680s1530m680s510"
"m680s19975"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s1530m680s1530m680s1530"
"m680s39950"
"m9010s4505"
"m680s1530m680s510m680s510m680s1530m680s1530m680s510m680s510m680s510"
"m680s1530m680s1530m680s510m680s1530m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s1530"
"m680s510m680s510m680s510m680s510m680s1530m680s1530m680s1530m680s510"
"m680s510m680s1530m680s510"
"m680s19975"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s1530m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s1530m680s1530m680s1530m680s1530"
"m680s39950",
irsend.outputStr());
}
// Tests for IRKelvinatorAC class.
TEST(TestKelvinatorClass, Power) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.on();
EXPECT_TRUE(irkelv.getPower());
irkelv.off();
EXPECT_FALSE(irkelv.getPower());
irkelv.setPower(true);
EXPECT_TRUE(irkelv.getPower());
irkelv.setPower(false);
EXPECT_FALSE(irkelv.getPower());
}
TEST(TestKelvinatorClass, Temperature) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setTemp(0);
EXPECT_EQ(kKelvinatorMinTemp, irkelv.getTemp());
irkelv.setTemp(255);
EXPECT_EQ(kKelvinatorMaxTemp, irkelv.getTemp());
irkelv.setTemp(kKelvinatorMinTemp);
EXPECT_EQ(kKelvinatorMinTemp, irkelv.getTemp());
irkelv.setTemp(kKelvinatorMaxTemp);
EXPECT_EQ(kKelvinatorMaxTemp, irkelv.getTemp());
irkelv.setTemp(kKelvinatorMinTemp - 1);
EXPECT_EQ(kKelvinatorMinTemp, irkelv.getTemp());
irkelv.setTemp(kKelvinatorMaxTemp + 1);
EXPECT_EQ(kKelvinatorMaxTemp, irkelv.getTemp());
irkelv.setTemp(17);
EXPECT_EQ(17, irkelv.getTemp());
irkelv.setTemp(21);
EXPECT_EQ(21, irkelv.getTemp());
irkelv.setTemp(25);
EXPECT_EQ(25, irkelv.getTemp());
irkelv.setTemp(29);
EXPECT_EQ(29, irkelv.getTemp());
}
TEST(TestKelvinatorClass, OperatingMode) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setTemp(24);
irkelv.setMode(kKelvinatorAuto);
EXPECT_EQ(kKelvinatorAuto, irkelv.getMode());
EXPECT_EQ(kKelvinatorAutoTemp, irkelv.getTemp());
irkelv.setMode(kKelvinatorCool);
EXPECT_EQ(kKelvinatorCool, irkelv.getMode());
irkelv.setMode(kKelvinatorHeat);
EXPECT_EQ(kKelvinatorHeat, irkelv.getMode());
irkelv.setTemp(24);
irkelv.setMode(kKelvinatorDry);
EXPECT_EQ(kKelvinatorDry, irkelv.getMode());
EXPECT_EQ(kKelvinatorAutoTemp, irkelv.getTemp());
irkelv.setMode(kKelvinatorFan);
EXPECT_EQ(kKelvinatorFan, irkelv.getMode());
irkelv.setMode(kKelvinatorHeat + 1);
EXPECT_EQ(kKelvinatorAuto, irkelv.getMode());
irkelv.setMode(255);
EXPECT_EQ(kKelvinatorAuto, irkelv.getMode());
}
TEST(TestKelvinatorClass, VaneSwing) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setSwingHorizontal(true);
irkelv.setSwingVertical(false);
irkelv.setSwingHorizontal(true);
EXPECT_TRUE(irkelv.getSwingHorizontal());
EXPECT_FALSE(irkelv.getSwingVertical());
irkelv.setSwingVertical(true);
EXPECT_TRUE(irkelv.getSwingHorizontal());
EXPECT_TRUE(irkelv.getSwingVertical());
irkelv.setSwingHorizontal(false);
EXPECT_FALSE(irkelv.getSwingHorizontal());
EXPECT_TRUE(irkelv.getSwingVertical());
irkelv.setSwingVertical(false);
EXPECT_FALSE(irkelv.getSwingHorizontal());
EXPECT_FALSE(irkelv.getSwingVertical());
}
TEST(TestKelvinatorClass, QuietMode) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setQuiet(true);
EXPECT_TRUE(irkelv.getQuiet());
irkelv.setQuiet(false);
EXPECT_FALSE(irkelv.getQuiet());
irkelv.setQuiet(true);
EXPECT_TRUE(irkelv.getQuiet());
}
TEST(TestKelvinatorClass, IonFilter) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setIonFilter(true);
EXPECT_TRUE(irkelv.getIonFilter());
irkelv.setIonFilter(false);
EXPECT_FALSE(irkelv.getIonFilter());
irkelv.setIonFilter(true);
EXPECT_TRUE(irkelv.getIonFilter());
}
TEST(TestKelvinatorClass, Light) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setLight(true);
EXPECT_TRUE(irkelv.getLight());
irkelv.setLight(false);
EXPECT_FALSE(irkelv.getLight());
irkelv.setLight(true);
EXPECT_TRUE(irkelv.getLight());
}
TEST(TestKelvinatorClass, XFan) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setXFan(true);
EXPECT_TRUE(irkelv.getXFan());
irkelv.setXFan(false);
EXPECT_FALSE(irkelv.getXFan());
irkelv.setXFan(true);
EXPECT_TRUE(irkelv.getXFan());
}
TEST(TestKelvinatorClass, TurboFan) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setTurbo(true);
EXPECT_TRUE(irkelv.getTurbo());
irkelv.setTurbo(false);
EXPECT_FALSE(irkelv.getTurbo());
irkelv.setFan(2);
irkelv.setTurbo(true);
EXPECT_TRUE(irkelv.getTurbo());
// Turbo mode is turned off if the temperature is changed.
irkelv.setFan(3);
EXPECT_FALSE(irkelv.getTurbo());
// But only when it is changed, not set to the same value again.
irkelv.setTurbo(true);
irkelv.setFan(3);
EXPECT_TRUE(irkelv.getTurbo());
}
TEST(TestKelvinatorClass, FanSpeed) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setFan(0);
EXPECT_EQ(0, irkelv.getFan());
irkelv.setFan(255);
EXPECT_EQ(kKelvinatorFanMax, irkelv.getFan());
irkelv.setFan(kKelvinatorFanMax);
EXPECT_EQ(kKelvinatorFanMax, irkelv.getFan());
irkelv.setFan(kKelvinatorFanMax + 1);
EXPECT_EQ(kKelvinatorFanMax, irkelv.getFan());
irkelv.setFan(kKelvinatorFanMax - 1);
EXPECT_EQ(kKelvinatorFanMax - 1, irkelv.getFan());
irkelv.setFan(1);
EXPECT_EQ(1, irkelv.getFan());
irkelv.setFan(1);
EXPECT_EQ(1, irkelv.getFan());
irkelv.setFan(3);
EXPECT_EQ(3, irkelv.getFan());
}
TEST(TestKelvinatorClass, Checksums) {
uint8_t kelv_code[kKelvinatorStateLength] = {
0x19, 0x0B, 0x80, 0x50, 0x00, 0x00, 0x00, 0xE0,
0x19, 0x0B, 0x80, 0x70, 0x00, 0x00, 0x10, 0xf0};
EXPECT_TRUE(IRKelvinatorAC::validChecksum(kelv_code));
// Change the array so the checksum is invalid.
kelv_code[0] ^= 0xFF;
EXPECT_FALSE(IRKelvinatorAC::validChecksum(kelv_code));
// Restore the previous change, and change another byte.
kelv_code[0] ^= 0xFF;
kelv_code[4] ^= 0xFF;
EXPECT_FALSE(IRKelvinatorAC::validChecksum(kelv_code));
kelv_code[4] ^= 0xFF;
// Change something in the 2nd block.
kelv_code[10] ^= 0xFF;
EXPECT_FALSE(IRKelvinatorAC::validChecksum(kelv_code));
kelv_code[10] ^= 0xFF;
EXPECT_TRUE(IRKelvinatorAC::validChecksum(kelv_code));
}
TEST(TestKelvinatorClass, SetAndGetRaw) {
IRKelvinatorAC irkelv(0);
uint8_t initialState[kKelvinatorStateLength] = {
0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0xA0,
0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xA0};
uint8_t expectedState[kKelvinatorStateLength] = {
0x08, 0x05, 0x20, 0x50, 0x00, 0x00, 0x00, 0x70,
0x08, 0x05, 0x20, 0x70, 0x00, 0x00, 0x00, 0x70};
EXPECT_STATE_EQ(initialState, irkelv.getRaw(), kKelvinatorBits);
// toggle the power state.
irkelv.setPower(!irkelv.getPower());
irkelv.setTemp(21);
irkelv.setLight(true);
EXPECT_STATE_EQ(expectedState, irkelv.getRaw(), kKelvinatorBits);
irkelv.setRaw(initialState);
EXPECT_STATE_EQ(initialState, irkelv.getRaw(), kKelvinatorBits);
}
TEST(TestKelvinatorClass, HumanReadable) {
IRKelvinatorAC irkelv(0);
EXPECT_EQ(
"Power: Off, Mode: 0 (Auto), Temp: 16C, Fan: 0 (Auto), Turbo: Off, "
"Quiet: Off, XFan: Off, Ion: Off, Light: Off, "
"Swing(H): Off, Swing(V): Off",
irkelv.toString());
irkelv.on();
irkelv.setMode(kKelvinatorCool);
irkelv.setTemp(25);
irkelv.setFan(kKelvinatorFanMax);
irkelv.setXFan(true);
irkelv.setIonFilter(true);
irkelv.setLight(true);
irkelv.setSwingHorizontal(true);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 25C, Fan: 5 (High), Turbo: Off, "
"Quiet: Off, XFan: On, Ion: On, Light: On, "
"Swing(H): On, Swing(V): Off",
irkelv.toString());
}
TEST(TestKelvinatorClass, MessageConstuction) {
IRKelvinatorAC irkelv(0);
IRsendTest irsend(4);
irkelv.begin();
irsend.begin();
irkelv.setFan(1);
irkelv.setMode(kKelvinatorCool);
irkelv.setTemp(27);
irkelv.setSwingVertical(false);
irkelv.setSwingHorizontal(true);
irkelv.setIonFilter(true);
irkelv.setQuiet(false);
irkelv.setLight(false);
irkelv.setPower(true);
irkelv.setTurbo(false);
irkelv.setXFan(true);
// Check everything for kicks.
EXPECT_EQ(1, irkelv.getFan());
EXPECT_EQ(kKelvinatorCool, irkelv.getMode());
EXPECT_EQ(27, irkelv.getTemp());
EXPECT_FALSE(irkelv.getSwingVertical());
EXPECT_TRUE(irkelv.getSwingHorizontal());
EXPECT_TRUE(irkelv.getIonFilter());
EXPECT_FALSE(irkelv.getQuiet());
EXPECT_FALSE(irkelv.getLight());
EXPECT_TRUE(irkelv.getPower());
EXPECT_FALSE(irkelv.getTurbo());
EXPECT_TRUE(irkelv.getXFan());
irsend.reset();
irsend.sendKelvinator(irkelv.getRaw());
EXPECT_EQ(
"f38000d50"
"m9010s4505"
"m680s1530m680s510m680s510m680s1530m680s1530m680s510m680s1530m680s510"
"m680s1530m680s1530m680s510m680s1530m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s1530m680s1530"
"m680s510m680s510m680s510m680s510m680s1530m680s510m680s1530m680s510"
"m680s510m680s1530m680s510"
"m680s19975"
"m680s510m680s510m680s510m680s510m680s1530m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s1530m680s1530m680s1530m680s1530"
"m680s39950"
"m9010s4505"
"m680s1530m680s510m680s510m680s1530m680s1530m680s510m680s1530m680s510"
"m680s1530m680s1530m680s510m680s1530m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s1530m680s1530"
"m680s510m680s510m680s510m680s510m680s1530m680s1530m680s1530m680s510"
"m680s510m680s1530m680s510"
"m680s19975"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s510m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s1530m680s510m680s510m680s510"
"m680s510m680s510m680s510m680s510m680s1530m680s1530m680s1530m680s1530"
"m680s39950",
irsend.outputStr());
}
// Decode a synthetic Kelvinator message.
TEST(TestDecodeKelvinator, NormalSynthetic) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
uint8_t kelv_code[kKelvinatorStateLength] = {
0x19, 0x0B, 0x80, 0x50, 0x00, 0x00, 0x00, 0xE0,
0x19, 0x0B, 0x80, 0x70, 0x00, 0x00, 0x10, 0xf0};
irsend.reset();
irsend.sendKelvinator(kelv_code);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(KELVINATOR, irsend.capture.decode_type);
ASSERT_EQ(kKelvinatorBits, irsend.capture.bits);
EXPECT_STATE_EQ(kelv_code, irsend.capture.state, kKelvinatorBits);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 27C, Fan: 1 (Low), Turbo: Off, "
"Quiet: Off, XFan: On, Ion: Off, Light: Off, "
"Swing(H): Off, Swing(V): Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestKelvinatorClass, toCommon) {
IRKelvinatorAC ac(0);
ac.setPower(true);
ac.setMode(kKelvinatorCool);
ac.setTemp(20);
ac.setFan(kKelvinatorFanMax);
ac.setIonFilter(true);
ac.setXFan(true);
ac.setQuiet(false);
ac.setTurbo(true);
ac.setLight(true);
ac.setSwingHorizontal(false);
ac.setSwingVertical(true);
// Now test it.
ASSERT_EQ(decode_type_t::KELVINATOR, ac.toCommon().protocol);
ASSERT_EQ(-1, ac.toCommon().model);
ASSERT_TRUE(ac.toCommon().power);
ASSERT_TRUE(ac.toCommon().celsius);
ASSERT_EQ(20, ac.toCommon().degrees);
ASSERT_TRUE(ac.toCommon().filter);
ASSERT_TRUE(ac.toCommon().clean);
ASSERT_FALSE(ac.toCommon().quiet);
ASSERT_TRUE(ac.toCommon().turbo);
ASSERT_TRUE(ac.toCommon().light);
ASSERT_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kAuto, ac.toCommon().swingv);
ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh);
// Unsupported.
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().sleep);
ASSERT_EQ(-1, ac.toCommon().clock);
}

View File

@@ -0,0 +1,874 @@
// Copyright 2017, 2019 David Conran
#include "ir_LG.h"
#include "IRac.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendLG().
// Test sending typical data only.
TEST(TestSendLG, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendLG(0x4B4AE51);
EXPECT_EQ(
"f38000d50"
"m8500s4250"
"m550s550m550s1600m550s550m550s550"
"m550s1600m550s550m550s1600m550s1600m550s550m550s1600m550s550m550s550"
"m550s1600m550s550m550s1600m550s550m550s1600m550s1600m550s1600m550s550"
"m550s550m550s1600m550s550m550s1600m550s550m550s550m550s550m550s1600"
"m550s50300",
irsend.outputStr());
irsend.reset();
irsend.sendLG(0xB4B4AE51, kLg32Bits);
EXPECT_EQ(
"f38000d33"
"m4480s4480"
"m560s1680m560s560m560s1680m560s1680m560s560m560s1680m560s560m560s560"
"m560s1680m560s560m560s1680m560s1680m560s560m560s1680m560s560m560s560"
"m560s1680m560s560m560s1680m560s560m560s1680m560s1680m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s560m560s560m560s1680"
"m560s44800"
"m8950s2250m550s96300",
irsend.outputStr());
}
// Test sending with different repeats.
TEST(TestSendLG, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendLG(0x4B4AE51, kLgBits, 1);
EXPECT_EQ(
"f38000d50"
"m8500s4250"
"m550s550m550s1600m550s550m550s550"
"m550s1600m550s550m550s1600m550s1600m550s550m550s1600m550s550m550s550"
"m550s1600m550s550m550s1600m550s550m550s1600m550s1600m550s1600m550s550"
"m550s550m550s1600m550s550m550s1600m550s550m550s550m550s550m550s1600"
"m550s50300"
"m8500s2250m550s96750",
irsend.outputStr());
irsend.reset();
irsend.sendLG(0xB4B4AE51, kLg32Bits, 1);
EXPECT_EQ(
"f38000d33"
"m4480s4480"
"m560s1680m560s560m560s1680m560s1680m560s560m560s1680m560s560m560s560"
"m560s1680m560s560m560s1680m560s1680m560s560m560s1680m560s560m560s560"
"m560s1680m560s560m560s1680m560s560m560s1680m560s1680m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s560m560s560m560s1680"
"m560s44800"
"m8950s2250m550s96300"
"m8950s2250m550s96300",
irsend.outputStr());
}
// Test sending an atypical data size.
TEST(TestSendLG, SendUnusualSize) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendLG(0x0, 31);
EXPECT_EQ(
"f38000d50"
"m8500s4250"
"m550s550m550s550m550s550m550s550m550s550m550s550m550s550m550s550"
"m550s550m550s550m550s550m550s550m550s550m550s550m550s550m550s550"
"m550s550m550s550m550s550m550s550m550s550m550s550m550s550m550s550"
"m550s550m550s550m550s550m550s550m550s550m550s550m550s550"
"m550s60650",
irsend.outputStr());
irsend.reset();
irsend.sendLG(0x0, 64);
EXPECT_EQ(
"f38000d33"
"m4480s4480"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s26880"
"m8950s2250m550s96300",
irsend.outputStr());
}
// Tests for encodeLG().
TEST(TestEncodeLG, NormalEncoding) {
IRsendTest irsend(4);
EXPECT_EQ(0x0, irsend.encodeLG(0, 0));
EXPECT_EQ(0x100011, irsend.encodeLG(1, 1));
EXPECT_EQ(0x100022, irsend.encodeLG(1, 2));
EXPECT_EQ(0x43001DE, irsend.encodeLG(0x43, 0x1D));
EXPECT_EQ(0xB4B4AE51, irsend.encodeLG(0xB4B, 0x4AE5));
EXPECT_EQ(0xAA0055A, irsend.encodeLG(0xAA, 0x55));
EXPECT_EQ(0xFFFFFFFC, irsend.encodeLG(0xFFFF, 0xFFFF));
}
// Tests for decodeLG().
// Decode normal LG messages.
TEST(TestDecodeLG, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal LG 28-bit message.
irsend.reset();
irsend.sendLG(0x4B4AE51, kLgBits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLgBits, true));
EXPECT_EQ(LG, irsend.capture.decode_type);
EXPECT_EQ(kLgBits, irsend.capture.bits);
EXPECT_EQ(0x4B4AE51, irsend.capture.value);
EXPECT_EQ(0x4B, irsend.capture.address);
EXPECT_EQ(0x4AE5, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal LG 32-bit message.
irsend.reset();
irsend.sendLG(0xB4B4AE51, kLg32Bits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLg32Bits, false));
EXPECT_EQ(LG, irsend.capture.decode_type);
EXPECT_EQ(kLg32Bits, irsend.capture.bits);
EXPECT_EQ(0xB4B4AE51, irsend.capture.value);
EXPECT_EQ(0xB4B, irsend.capture.address);
EXPECT_EQ(0x4AE5, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Synthesised Normal LG 28-bit message.
irsend.reset();
irsend.sendLG(irsend.encodeLG(0x07, 0x99));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLgBits, true));
EXPECT_EQ(LG, irsend.capture.decode_type);
EXPECT_EQ(kLgBits, irsend.capture.bits);
EXPECT_EQ(0x700992, irsend.capture.value);
EXPECT_EQ(0x07, irsend.capture.address);
EXPECT_EQ(0x99, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Synthesised Normal LG 32-bit message.
irsend.reset();
irsend.sendLG(irsend.encodeLG(0x800, 0x8000), kLg32Bits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLg32Bits, true));
EXPECT_EQ(LG, irsend.capture.decode_type);
EXPECT_EQ(kLg32Bits, irsend.capture.bits);
EXPECT_EQ(0x80080008, irsend.capture.value);
EXPECT_EQ(0x800, irsend.capture.address);
EXPECT_EQ(0x8000, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode normal repeated LG messages.
TEST(TestDecodeLG, NormalDecodeWithRepeatAndStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal LG 28-bit message with 2 repeats.
irsend.reset();
irsend.sendLG(irsend.encodeLG(0x07, 0x99), kLgBits, 2);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLgBits, true));
EXPECT_EQ(LG, irsend.capture.decode_type);
EXPECT_EQ(kLgBits, irsend.capture.bits);
EXPECT_EQ(0x700992, irsend.capture.value);
EXPECT_EQ(0x07, irsend.capture.address);
EXPECT_EQ(0x99, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal LG 32-bit message with 2 repeats.
irsend.reset();
irsend.sendLG(irsend.encodeLG(0x07, 0x99), kLg32Bits, 2);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLg32Bits, true));
EXPECT_EQ(LG, irsend.capture.decode_type);
EXPECT_EQ(kLg32Bits, irsend.capture.bits);
EXPECT_EQ(0x700992, irsend.capture.value);
EXPECT_EQ(0x07, irsend.capture.address);
EXPECT_EQ(0x99, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode unsupported LG message values.
TEST(TestDecodeLG, DecodeWithNonStrictValues) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Illegal values should be rejected when strict is on.
// Illegal LG 28-bit message value.
irsend.reset();
irsend.sendLG(0x1);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLgBits, true));
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLg32Bits, true));
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLg32Bits,
false));
ASSERT_TRUE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLgBits, false));
// Illegal LG 32-bit message value.
irsend.reset();
irsend.sendLG(0x1111111, kLg32Bits);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLg32Bits, true));
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLgBits, true));
ASSERT_TRUE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLg32Bits, false));
EXPECT_EQ(LG, irsend.capture.decode_type);
EXPECT_EQ(kLg32Bits, irsend.capture.bits);
EXPECT_EQ(0x1111111, irsend.capture.value);
EXPECT_EQ(0x11, irsend.capture.address);
EXPECT_EQ(0x1111, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
irsend.reset();
irsend.sendLG(0x1111111, kLg32Bits);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLgBits, false));
}
// Decode unsupported LG message sizes.
TEST(TestDecodeLG, DecodeWithNonStrictSizes) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Illegal sizes should be rejected when strict is on.
// Illegal LG 16-bit message size.
irsend.reset();
irsend.sendLG(irsend.encodeLG(0x07, 0x99), 16);
irsend.makeDecodeResult();
// Should fail when unexpected against different bit sizes.
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLgBits, true));
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLg32Bits, true));
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLgBits, false));
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLg32Bits,
false));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeLG(&irsend.capture, kStartOffset, 16, false));
EXPECT_EQ(LG, irsend.capture.decode_type);
EXPECT_EQ(16, irsend.capture.bits);
EXPECT_EQ(0x992, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x99, irsend.capture.command);
// Illegal LG 36-bit message size.
irsend.reset();
irsend.sendLG(0x123456789, 36); // Illegal value LG 36-bit message.
irsend.makeDecodeResult();
// Should fail when unexpected against different bit sizes.
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLgBits, true));
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLgBits, false));
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLg32Bits, true));
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLg32Bits,
false));
ASSERT_TRUE(irrecv.decodeLG(&irsend.capture, kStartOffset, 36, false));
EXPECT_EQ(LG, irsend.capture.decode_type);
EXPECT_EQ(36, irsend.capture.bits);
EXPECT_EQ(0x123456789, irsend.capture.value);
EXPECT_EQ(0x1234, irsend.capture.address);
EXPECT_EQ(0x5678, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode (non-standard) 64-bit messages.
TEST(TestDecodeLG, Decode64BitMessages) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Illegal value & size LG 64-bit message.
irsend.sendLG(0xFFFFFFFFFFFFFFFF, 64);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, 64, true));
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeLG(&irsend.capture, kStartOffset, 64, false));
EXPECT_EQ(LG, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, irsend.capture.value);
EXPECT_EQ(0xFFFFFFFF, irsend.capture.address);
EXPECT_EQ(0xFFFF, irsend.capture.command);
}
// Decode a 'real' example via GlobalCache
TEST(TestDecodeLG, DecodeGlobalCacheExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// TODO(anyone): Find a Global Cache example of the LG 28-bit message.
irsend.reset();
// LG (32-bit) code from Global Cache.
uint16_t gc_test[75] = {
38000, 1, 69, 341, 170, 21, 64, 21, 21, 21, 64, 21, 64, 21, 21,
21, 64, 21, 21, 21, 21, 21, 64, 21, 21, 21, 64, 21, 64, 21,
21, 21, 64, 21, 21, 21, 21, 21, 64, 21, 21, 21, 64, 21, 21,
21, 64, 21, 64, 21, 64, 21, 21, 21, 21, 21, 64, 21, 21, 21,
64, 21, 21, 21, 21, 21, 21, 21, 64, 21, 1517, 341, 85, 21, 3655};
irsend.sendGC(gc_test, 75);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLg32Bits, true));
EXPECT_EQ(LG, irsend.capture.decode_type);
EXPECT_EQ(kLg32Bits, irsend.capture.bits);
EXPECT_EQ(0xB4B4AE51, irsend.capture.value);
EXPECT_EQ(0xB4B, irsend.capture.address);
EXPECT_EQ(0x4AE5, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Fail to decode a non-LG example via GlobalCache
TEST(TestDecodeLG, FailToDecodeNonLGExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Modified a few entries to unexpected values, based on previous test case.
uint16_t gc_test[39] = {38000, 1, 1, 322, 162, 20, 61, 20, 61, 20,
20, 20, 20, 20, 20, 20, 127, 20, 61, 9,
20, 20, 61, 20, 20, 20, 61, 20, 61, 20,
61, 20, 20, 20, 20, 20, 20, 20, 884};
irsend.sendGC(gc_test, 39);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture));
ASSERT_FALSE(irrecv.decodeLG(&irsend.capture, kStartOffset, kLgBits, false));
}
// Tests for sendLG2().
// Test sending typical data only.
TEST(TestSendLG2, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
irsend.sendLG2(0x880094D);
EXPECT_EQ(
"f38000d50"
"m3200s9850"
"m550s1600m550s550m550s550m550s550m550s1600m550s550m550s550m550s550"
"m550s550m550s550m550s550m550s550m550s550m550s550m550s550m550s550"
"m550s1600m550s550m550s550m550s1600m550s550m550s1600m550s550m550s550"
"m550s1600m550s1600m550s550m550s1600"
"m550s55250",
irsend.outputStr());
}
TEST(TestDecodeLG2, SyntheticExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
irsend.sendLG2(0x880094D);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeLG(&irsend.capture));
ASSERT_EQ(LG2, irsend.capture.decode_type);
EXPECT_EQ(kLgBits, irsend.capture.bits);
EXPECT_EQ(0x880094D, irsend.capture.value);
}
// Verify decoding of LG variant 2 messages.
TEST(TestDecodeLG2, RealLG2Example) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
// From issue #548
uint16_t rawData[59] = {
3154, 9834, 520, 1634, 424, 606, 424, 568, 462, 570, 462, 1564,
508, 568, 458, 544, 500, 546, 508, 530, 508, 532, 506, 566,
464, 568, 460, 578, 464, 568, 464, 532, 506, 552, 474, 1592,
506, 568, 460, 570, 462, 1564, 506, 606, 424, 1640, 424, 616,
422, 570, 462, 1616, 460, 1584, 500, 544, 506, 1598, 490}; // UNKNOWN
// F6D13AE8
irsend.sendRaw(rawData, 59, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeLG(&irsend.capture));
ASSERT_EQ(LG2, irsend.capture.decode_type);
EXPECT_EQ(kLgBits, irsend.capture.bits);
EXPECT_EQ(0x880094D, irsend.capture.value);
}
// Tests for issue reported in
// https://github.com/crankyoldgit/IRremoteESP8266/issues/620
TEST(TestDecodeLG, Issue620) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Raw data as reported in initial comment of Issue #620
uint16_t rawData[59] = {
8886, 4152,
560, 1538, 532, 502, 532, 504, 530, 484, 558, 1536,
508, 516, 558, 502, 532, 484, 558, 502, 532, 500,
534, 508, 532, 502, 532, 1518, 558, 510, 532, 484,
556, 486, 556, 510, 532, 1518, 558, 1560, 532, 1528,
556, 504, 530, 506, 530, 1520, 558, 508, 534, 500,
532, 512, 530, 484, 556, 1536, 532}; // LG 8808721
irsend.sendRaw(rawData, 59, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LG, irsend.capture.decode_type);
EXPECT_EQ(28, irsend.capture.bits);
EXPECT_EQ(0x8808721, irsend.capture.value);
EXPECT_EQ(0x88, irsend.capture.address);
EXPECT_EQ(0x872, irsend.capture.command);
irsend.reset();
// Resend the same code as the report is a sent code doesn't decode
// to the same message code.
IRLgAc ac(0);
irsend.sendLG(0x8808721);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LG, irsend.capture.decode_type);
EXPECT_EQ(28, irsend.capture.bits);
EXPECT_EQ(0x8808721, irsend.capture.value);
EXPECT_EQ(0x88, irsend.capture.address);
EXPECT_EQ(0x872, irsend.capture.command);
ac.setRaw(irsend.capture.value);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ("Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 22C, Fan: 2 (Medium)",
ac.toString());
// The following seems to match the rawData above.
EXPECT_EQ(
"f38000d50"
"m8500s4250"
"m550s1600m550s550m550s550m550s550m550s1600"
"m550s550m550s550m550s550m550s550m550s550"
"m550s550m550s550m550s1600m550s550m550s550"
"m550s550m550s550m550s1600m550s1600m550s1600"
"m550s550m550s550m550s1600m550s550m550s550"
"m550s550m550s550m550s1600m550"
"s55550",
irsend.outputStr());
}
TEST(TestIRLgAcClass, SetAndGetPower) {
IRLgAc ac(0);
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(TestIRLgAcClass, SetAndGetTemp) {
IRLgAc ac(0);
ac.setTemp(25);
EXPECT_EQ(25, ac.getTemp());
ac.setTemp(kLgAcMinTemp);
EXPECT_EQ(kLgAcMinTemp, ac.getTemp());
ac.setTemp(kLgAcMinTemp - 1);
EXPECT_EQ(kLgAcMinTemp, ac.getTemp());
ac.setTemp(kLgAcMaxTemp);
EXPECT_EQ(kLgAcMaxTemp, ac.getTemp());
ac.setTemp(kLgAcMaxTemp + 1);
EXPECT_EQ(kLgAcMaxTemp, ac.getTemp());
}
TEST(TestIRLgAcClass, SetAndGetMode) {
IRLgAc ac(0);
ac.setMode(kLgAcCool);
ac.setFan(kLgAcFanAuto);
ac.setTemp(25);
EXPECT_EQ(25, ac.getTemp());
EXPECT_EQ(kLgAcCool, ac.getMode());
EXPECT_EQ(kLgAcFanAuto, ac.getFan());
ac.setMode(kLgAcHeat);
EXPECT_EQ(kLgAcHeat, ac.getMode());
ac.setMode(kLgAcDry);
EXPECT_EQ(kLgAcDry, ac.getMode());
}
TEST(TestIRLgAcClass, SetAndGetFan) {
IRLgAc ac(0);
ac.setMode(kLgAcCool);
ac.setFan(kLgAcFanAuto);
EXPECT_EQ(kLgAcFanAuto, ac.getFan());
ac.setFan(kLgAcFanLow);
EXPECT_EQ(kLgAcFanLow, ac.getFan());
ac.setFan(kLgAcFanHigh);
EXPECT_EQ(kLgAcFanHigh, ac.getFan());
ac.setFan(kLgAcFanAuto + 1);
EXPECT_EQ(kLgAcFanAuto, ac.getFan());
ac.setFan(kLgAcFanLow - 1);
EXPECT_EQ(kLgAcFanAuto, ac.getFan());
}
TEST(TestIRLgAcClass, toCommon) {
IRLgAc ac(0);
ac.setPower(true);
ac.setMode(kLgAcCool);
ac.setTemp(20);
ac.setFan(kLgAcFanHigh);
// Now test it.
ASSERT_EQ(decode_type_t::LG, ac.toCommon().protocol);
ASSERT_EQ(lg_ac_remote_model_t::GE6711AR2853M, 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::kMax, ac.toCommon().fanspeed);
// 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().clean);
ASSERT_FALSE(ac.toCommon().light);
ASSERT_FALSE(ac.toCommon().quiet);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().filter);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().sleep);
ASSERT_EQ(-1, ac.toCommon().clock);
// Change models
ac.setModel(AKB75215403);
ASSERT_EQ(lg_ac_remote_model_t::AKB75215403, ac.toCommon().model);
}
TEST(TestIRLgAcClass, HumanReadable) {
IRLgAc ac(0);
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: Off",
ac.toString());
ac.setMode(kLgAcHeat);
ac.setTemp(kLgAcMaxTemp);
ac.on();
ac.setFan(kLgAcFanHigh);
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 4 (Heat), Temp: 30C, Fan: 4 (High)",
ac.toString());
ac.setMode(kLgAcCool);
ac.setFan(kLgAcFanLow);
ac.setTemp(kLgAcMinTemp);
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 16C, Fan: 0 (Low)",
ac.toString());
ac.setTemp(ac.getTemp() + 1);
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 17C, Fan: 0 (Low)",
ac.toString());
ac.setTemp(ac.getTemp() - 1);
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 16C, Fan: 0 (Low)",
ac.toString());
ac.setPower(false);
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: Off",
ac.toString());
}
TEST(TestIRLgAcClass, SetAndGetRaw) {
IRLgAc ac(0);
ac.setRaw(0x8800A4E);
ASSERT_EQ(0x8800A4E, ac.getRaw());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 25C, Fan: 4 (High)",
ac.toString());
ac.setRaw(0x88C0051);
ASSERT_EQ(0x88C0051, ac.getRaw());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: Off",
ac.toString());
}
TEST(TestIRLgAcClass, MessageConstruction) {
IRLgAc ac(0);
ac.on();
ac.setMode(kLgAcCool);
ac.setTemp(25);
ac.setFan(kLgAcFanHigh);
ASSERT_EQ(0x8800A4E, ac.getRaw());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 25C, Fan: 4 (High)",
ac.toString());
}
TEST(TestIRLgAcClass, isValidLgAc) {
IRLgAc ac(0);
ac.setRaw(0x8800A4E);
ASSERT_TRUE(ac.isValidLgAc());
// Make the checksum wrong.
ac.setRaw(0x8800A4F);
ASSERT_FALSE(ac.isValidLgAc());
ac.setRaw(0x88C0051);
ASSERT_TRUE(ac.isValidLgAc());
// Use a wrong signature.
ac.setRaw(0x8000A4E);
ASSERT_FALSE(ac.isValidLgAc());
}
TEST(TestIRLgAcClass, calcChecksum) {
EXPECT_EQ(0x1, IRLgAc::calcChecksum(0x88C0051));
EXPECT_EQ(0x4, IRLgAc::calcChecksum(0x88C0354));
}
TEST(TestUtils, Housekeeping) {
ASSERT_EQ("LG", typeToString(decode_type_t::LG));
ASSERT_EQ(decode_type_t::LG, strToDecodeType("LG"));
ASSERT_FALSE(hasACState(decode_type_t::LG));
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::LG));
ASSERT_EQ("LG2", typeToString(decode_type_t::LG2));
ASSERT_EQ(decode_type_t::LG2, strToDecodeType("LG2"));
ASSERT_FALSE(hasACState(decode_type_t::LG2));
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::LG2));
}
TEST(TestIRLgAcClass, KnownExamples) {
IRLgAc ac(0);
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1008#issuecomment-570646648
// Temp
ac.setRaw(0x880C152);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 4 (Heat), Temp: 16C, Fan: 5 (Auto)",
ac.toString());
ac.setRaw(0x880CF50);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 4 (Heat), Temp: 30C, Fan: 5 (Auto)",
ac.toString());
// Modes
ac.setRaw(0x880960F);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 1 (Dry), Temp: 21C, Fan: 0 (Low)",
ac.toString());
ac.setRaw(0x880C758);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 4 (Heat), Temp: 22C, Fan: 5 (Auto)",
ac.toString());
ac.setRaw(0x8808855);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 23C, Fan: 5 (Auto)",
ac.toString());
// Fan speeds
ac.setRaw(0x880870F);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 22C, Fan: 0 (Low)",
ac.toString());
ac.setRaw(0x8808721);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 22C, Fan: 2 (Medium)",
ac.toString());
ac.setRaw(0x8808743);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 22C, Fan: 4 (High)",
ac.toString());
ac.setRaw(0x8808754);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 22C, Fan: 5 (Auto)",
ac.toString());
ac.setRaw(0x880A745);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 2 (Fan), Temp: 22C, Fan: 4 (High)",
ac.toString());
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1008#issuecomment-570794029
ac.setRaw(0x8800347);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 18C, Fan: 4 (High)",
ac.toString());
ac.setRaw(0x8808440);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 19C, Fan: 4 (High)",
ac.toString());
ac.setRaw(0x8800459);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 19C, Fan: 5 (Auto)",
ac.toString());
ac.setRaw(0x8809946);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 1 (Dry), Temp: 24C, Fan: 4 (High)",
ac.toString());
ac.setRaw(0x880A341);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 2 (Fan), Temp: 18C, Fan: 4 (High)",
ac.toString());
ac.setRaw(0x8810045);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 15C, Fan: 4 (High)",
ac.toString());
ac.setRaw(0x8810056);
ASSERT_TRUE(ac.isValidLgAc());
EXPECT_EQ(
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 15C, Fan: 5 (Auto)",
ac.toString());
}
// Verify decoding of LG2 message.
TEST(TestDecodeLG2, Issue1008) {
IRsendTest irsend(0);
IRrecv capture(0);
irsend.begin();
irsend.reset();
// From https://github.com/crankyoldgit/IRremoteESP8266/issues/1008#issuecomment-570794029
// First entry.
uint16_t rawData[59] = {
3272, 9844, 506, 1588, 536, 498, 534, 498, 536, 498, 534, 1540, 534, 506,
534, 498, 534, 500, 532, 500, 534, 498, 534, 498, 534, 506, 534, 500, 534,
498, 534, 498, 534, 498, 534, 500, 534, 498, 534, 1566, 508, 1566, 508,
500, 534, 1540, 534, 506, 534, 500, 534, 500, 534, 1560, 508, 1540, 534,
1558, 508}; // UNKNOWN AFC3034C
irsend.sendRaw(rawData, 59, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(capture.decode(&irsend.capture));
ASSERT_EQ(LG2, irsend.capture.decode_type);
EXPECT_EQ(kLgBits, irsend.capture.bits);
EXPECT_EQ(0x8800347, irsend.capture.value);
irsend.reset();
IRLgAc ac(0);
ac.setRaw(0x8800347);
ac.setModel(lg_ac_remote_model_t::AKB75215403); // aka. 2
ac.send();
char expected[] =
"Model: 2 (AKB75215403), "
"Power: On, Mode: 0 (Cool), Temp: 18C, Fan: 4 (High)";
ASSERT_EQ(expected, ac.toString());
ac._irsend.makeDecodeResult();
EXPECT_TRUE(capture.decode(&ac._irsend.capture));
ASSERT_EQ(LG2, ac._irsend.capture.decode_type);
ASSERT_EQ(kLgBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRLgAcClass, DifferentModels) {
IRLgAc ac(0);
IRrecv capture(0);
ac.setRaw(0x8800347);
ac.setModel(lg_ac_remote_model_t::GE6711AR2853M); // aka. 1
ac._irsend.reset();
ac.send();
char expected1[] =
"Model: 1 (GE6711AR2853M), "
"Power: On, Mode: 0 (Cool), Temp: 18C, Fan: 4 (High)";
ASSERT_EQ(expected1, ac.toString());
ac._irsend.makeDecodeResult();
EXPECT_TRUE(capture.decode(&ac._irsend.capture));
ASSERT_EQ(LG, ac._irsend.capture.decode_type); // Not "LG2"
ASSERT_EQ(kLgBits, ac._irsend.capture.bits);
ASSERT_EQ(expected1, IRAcUtils::resultAcToString(&ac._irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
ac.setModel(lg_ac_remote_model_t::AKB75215403); // aka. 2
ac._irsend.reset();
ac.send();
char expected2[] =
"Model: 2 (AKB75215403), "
"Power: On, Mode: 0 (Cool), Temp: 18C, Fan: 4 (High)";
ASSERT_EQ(expected2, ac.toString());
ac._irsend.makeDecodeResult();
EXPECT_TRUE(capture.decode(&ac._irsend.capture));
ASSERT_EQ(LG2, ac._irsend.capture.decode_type); // Not "LG"
ASSERT_EQ(kLgBits, ac._irsend.capture.bits);
ASSERT_EQ(expected2, IRAcUtils::resultAcToString(&ac._irsend.capture));
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}

View File

@@ -0,0 +1,349 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// LL AAA SSSSS EEEEEEE RRRRRR TTTTTTT AAA GGGG
// LL AAAAA SS EE RR RR TTT AAAAA GG GG
// LL AA AA SSSSS EEEEE RRRRRR TTT AA AA GG
// LL AAAAAAA SS EE RR RR TTT AAAAAAA GG GG
// LLLLLLL AA AA SSSSS EEEEEEE RR RR TTT AA AA GGGGGG
// Tests for sendLasertag().
// Test sending simplest case data only.
TEST(TestSendLasertag, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendLasertag(0x1); // Red 1
EXPECT_EQ(
"f36000d25"
"m333s333m333s333m333s333m333s333m333s333m333s333m333s333m333s333m333"
"s333m333s333m333s333m333s666m333s100000",
irsend.outputStr());
irsend.reset();
irsend.sendLasertag(0x2); // Red 2
EXPECT_EQ(
"f36000d25"
"m333s333m333s333m333s333m333s333m333s333m333s333m333s333"
"m333s333m333s333m333s333m333s666m666s100333",
irsend.outputStr());
irsend.reset();
irsend.sendLasertag(0x51); // Green 1
// Raw: (21)
// m364s364m332s336m384s276m332s364m332s304m416s584m692s724m640s360m304s332m392s612m380,
EXPECT_EQ(
// m364s364m332s336m384s276m332s364m332s304m416s584
// m692s724m640s360m304s332m392s612m380
"f36000d25"
"m333s333m333s333m333s333m333s333m333s333m333s666"
"m666s666m666s333m333s333m333s666m333s100000",
irsend.outputStr());
irsend.reset();
// Raw: (19)
// m332s308m412s280m360s336m332s304m444s248m332s644m744s612m696s692m668s636m360
irsend.sendLasertag(0x55); // Green 5
EXPECT_EQ(
// m332s308m412s280m360s336m332s304m444s248m332s644
// m744s612m696s692m668s636m360
"f36000d25"
"m333s333m333s333m333s333m333s333m333s333m333s666"
"m666s666m666s666m666s666m333s100000",
irsend.outputStr());
}
TEST(TestSendLasertag, SendDataWithRepeat) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendLasertag(0x1, kLasertagBits, 1); // Red 1, one repeat.
EXPECT_EQ(
"f36000d25"
"m333s333m333s333m333s333m333s333m333s333m333s333m333s333m333s333"
"m333s333m333s333m333s333m333s666m333s100000"
"m333s333m333s333m333s333m333s333m333s333m333s333m333s333m333s333"
"m333s333m333s333m333s333m333s666m333s100000",
irsend.outputStr());
irsend.reset();
irsend.sendLasertag(0x52, kLasertagBits, 2); // Green 2, two repeats.
EXPECT_EQ(
"f36000d25"
"m333s333m333s333m333s333m333s333m333s333m333s666m666s666m666s333"
"m333s666m666s100333"
"m333s333m333s333m333s333m333s333m333s333m333s666m666s666m666s333"
"m333s666m666s100333"
"m333s333m333s333m333s333m333s333m333s333m333s666m666s666m666s333"
"m333s666m666s100333",
irsend.outputStr());
}
TEST(TestSendLasertag, SmallestMessageSize) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendLasertag(0x1555); // Alternating bit pattern will be the smallest.
// i.e. 7 actual 'mark' pulses, which is a rawlen of 13.
EXPECT_EQ("f36000d25"
"m0s333m666s666m666s666m666s666m666s666m666s666m666s666m333s100000",
irsend.outputStr());
}
// Tests for decodeLasertag().
// Decode normal Lasertag messages.
TEST(TestDecodeLasertag, NormalSyntheticDecodeWithStrict) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Normal Lasertag 13-bit message.
irsend.reset();
irsend.sendLasertag(0x01); // Red 1
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x01, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address); // Unit 1
EXPECT_EQ(0x0, irsend.capture.command); // Team Red
EXPECT_FALSE(irsend.capture.repeat);
irsend.reset();
irsend.sendLasertag(0x02); // Red 2
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x02, irsend.capture.value);
EXPECT_EQ(0x2, irsend.capture.address); // Unit 2
EXPECT_EQ(0x0, irsend.capture.command); // Team Red
EXPECT_FALSE(irsend.capture.repeat);
irsend.reset();
irsend.sendLasertag(0x06); // Red 6
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x06, irsend.capture.value);
EXPECT_EQ(0x6, irsend.capture.address); // Unit 6
EXPECT_EQ(0x0, irsend.capture.command); // Team Red
EXPECT_FALSE(irsend.capture.repeat);
irsend.reset();
irsend.sendLasertag(0x51); // Green 1
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x51, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address); // Unit 1
EXPECT_EQ(0x5, irsend.capture.command); // Team Green
EXPECT_FALSE(irsend.capture.repeat);
irsend.reset();
irsend.sendLasertag(0x56); // Green 6
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x56, irsend.capture.value);
EXPECT_EQ(0x6, irsend.capture.address); // Unit
EXPECT_EQ(0x5, irsend.capture.command); // Team
EXPECT_FALSE(irsend.capture.repeat);
}
// Example data taken from: https://github.com/z3t0/Arduino-IRremote/issues/532
TEST(TestDecodeLasertag, RealExamples) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
uint16_t green3[21] = {360, 364, 272, 360, 420, 248, 360, 360, 332, 308, 388,
612, 692, 696, 636, 360, 332, 700, 300, 308, 416};
irsend.sendRaw(green3, 21, 36000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x53, irsend.capture.value);
EXPECT_EQ(0x3, irsend.capture.address); // Unit
EXPECT_EQ(0x5, irsend.capture.command); // Team
irsend.reset();
uint16_t green1[21] = {364, 364, 332, 336, 384, 276, 332, 364, 332, 304, 416,
584, 692, 724, 640, 360, 304, 332, 392, 612, 380};
irsend.sendRaw(green1, 21, 36000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x51, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address); // Unit
EXPECT_EQ(0x5, irsend.capture.command); // Team
irsend.reset();
uint16_t green4[19] = {336, 304, 412, 280, 360, 360, 304, 308, 420, 276,
332, 636, 744, 620, 688, 724, 640, 360, 304};
irsend.sendRaw(green4, 19, 36000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x54, irsend.capture.value);
EXPECT_EQ(0x4, irsend.capture.address); // Unit
EXPECT_EQ(0x5, irsend.capture.command); // Team
irsend.reset();
uint16_t unit15[25] = {280, 360, 360, 308, 332, 388, 308, 332, 360,
308, 360, 360, 304, 304, 412, 284, 304, 692,
364, 360, 276, 336, 416, 276, 328};
irsend.sendRaw(unit15, 25, 36000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x0F, irsend.capture.value);
EXPECT_EQ(0xF, irsend.capture.address); // Unit
EXPECT_EQ(0x0, irsend.capture.command); // Team
irsend.reset();
uint16_t red_unit2_1[23] = {406, 262, 384, 374, 256, 354, 306, 366,
252, 442, 256, 374, 358, 336, 278, 438,
246, 340, 380, 292, 304, 688, 746};
irsend.sendRaw(red_unit2_1, 23, 36000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x02, irsend.capture.value);
EXPECT_EQ(0x2, irsend.capture.address); // Unit
EXPECT_EQ(0x0, irsend.capture.command); // Team
irsend.reset();
uint16_t red_unit2_2[23] = {302, 306, 302, 392, 196, 476, 278, 352,
304, 348, 278, 438, 226, 382, 328, 366,
252, 458, 196, 392, 302, 688, 644};
irsend.sendRaw(red_unit2_2, 23, 36000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x02, irsend.capture.value);
EXPECT_EQ(0x2, irsend.capture.address); // Unit
EXPECT_EQ(0x0, irsend.capture.command); // Team
irsend.reset();
uint16_t red_unit2_3[23] = {196, 432, 304, 348, 328, 386, 304, 326,
302, 370, 252, 442, 272, 356, 278, 374,
276, 438, 274, 352, 302, 668, 622};
irsend.sendRaw(red_unit2_3, 23, 36000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x02, irsend.capture.value);
EXPECT_EQ(0x2, irsend.capture.address); // Unit
EXPECT_EQ(0x0, irsend.capture.command); // Team
irsend.reset();
uint16_t red_unit2_4[23] = {304, 390, 328, 324, 324, 346, 350, 364,
300, 330, 320, 310, 324, 388, 242, 366,
354, 318, 354, 340, 244, 726, 670};
irsend.sendRaw(red_unit2_4, 23, 36000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x02, irsend.capture.value);
EXPECT_EQ(0x2, irsend.capture.address); // Unit
EXPECT_EQ(0x0, irsend.capture.command); // Team
irsend.reset();
uint16_t red_unit1_1_issue532[25] = {
368, 352, 336, 308, 388, 276, 364, 356, 280, 360, 332, 336, 360,
360, 308, 300, 416, 280, 356, 360, 312, 328, 336, 636, 424};
irsend.sendRaw(red_unit1_1_issue532, 25, 36000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x01, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address); // Unit
EXPECT_EQ(0x0, irsend.capture.command); // Team
irsend.reset();
uint16_t red_unit1_2_issue532[25] = {
328, 400, 272, 360, 388, 280, 360, 364, 272, 364, 332, 336, 332,
388, 304, 308, 388, 280, 356, 364, 272, 368, 384, 612, 408};
irsend.sendRaw(red_unit1_2_issue532, 25, 36000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x01, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address); // Unit
EXPECT_EQ(0x0, irsend.capture.command); // Team
irsend.reset();
uint16_t red_unit1_3_issue532[25] = {
416, 284, 356, 336, 328, 336, 384, 308, 328, 368, 304, 308, 412,
280, 328, 368, 272, 368, 376, 312, 332, 392, 276, 700, 272};
irsend.sendRaw(red_unit1_3_issue532, 25, 36000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x01, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address); // Unit
EXPECT_EQ(0x0, irsend.capture.command); // Team
irsend.reset();
uint16_t red_unit2_1_issue532[23] = {308, 340, 408, 284, 332, 388, 276, 336,
356, 340, 332, 360, 300, 364, 360, 304,
280, 444, 276, 336, 384, 640, 696};
irsend.sendRaw(red_unit2_1_issue532, 23, 36000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x02, irsend.capture.value);
EXPECT_EQ(0x2, irsend.capture.address); // Unit
EXPECT_EQ(0x0, irsend.capture.command); // Team
irsend.reset();
uint16_t red_unit2_2_issue532[23] = {332, 308, 388, 280, 328, 420, 308, 304,
384, 308, 332, 364, 272, 368, 384, 276,
364, 360, 308, 332, 384, 612, 696};
irsend.sendRaw(red_unit2_2_issue532, 23, 36000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x02, irsend.capture.value);
EXPECT_EQ(0x2, irsend.capture.address); // Unit
EXPECT_EQ(0x0, irsend.capture.command); // Team
irsend.reset();
uint16_t red_unit2_3_issue532[23] = {392, 332, 340, 272, 448, 276, 364, 328,
340, 272, 396, 296, 340, 380, 312, 296,
400, 272, 364, 352, 284, 720, 672};
irsend.sendRaw(red_unit2_3_issue532, 23, 36000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(LASERTAG, irsend.capture.decode_type);
EXPECT_EQ(kLasertagBits, irsend.capture.bits);
EXPECT_EQ(0x02, irsend.capture.value);
EXPECT_EQ(0x2, irsend.capture.address); // Unit
EXPECT_EQ(0x0, irsend.capture.command); // Team
}

View File

@@ -0,0 +1,196 @@
// Copyright 2019 David Conran
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// General housekeeping
TEST(TestLego, Housekeeping) {
ASSERT_EQ("LEGOPF", typeToString(LEGOPF));
ASSERT_FALSE(hasACState(LEGOPF)); // Uses uint64_t, not uint8_t*.
}
// Tests for sendLego().
// Test sending typical data only.
TEST(TestSendLegoPf, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
irsend.sendLegoPf(0x1234);
EXPECT_EQ(
"f38000d50"
"m158s1026"
"m158s263m158s263m158s263m158s553m158s263m158s263m158s553m158s263"
"m158s263m158s263m158s553m158s553m158s263m158s553m158s263m158s263"
"m158s70472", irsend.outputStr());
irsend.reset();
irsend.send(LEGOPF, 0x1234, kLegoPfBits);
EXPECT_EQ(
"f38000d50"
"m158s1026"
"m158s263m158s263m158s263m158s553m158s263m158s263m158s553m158s263"
"m158s263m158s263m158s553m158s553m158s263m158s553m158s263m158s263"
"m158s70472", irsend.outputStr());
}
// Test sending typical repeat data.
TEST(TestSendLegoPf, SendDataWithRepeats) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
irsend.sendLegoPf(0x1234, kLegoPfBits, 1);
EXPECT_EQ(
"f38000d50"
"m0s32000"
"m158s1026"
"m158s263m158s263m158s263m158s553m158s263m158s263m158s553m158s263"
"m158s263m158s263m158s553m158s553m158s263m158s553m158s263m158s263"
"m158s70472"
"m158s1026"
"m158s263m158s263m158s263m158s553m158s263m158s263m158s553m158s263"
"m158s263m158s263m158s553m158s553m158s263m158s553m158s263m158s263"
"m158s70472"
"m158s1026"
"m158s263m158s263m158s263m158s553m158s263m158s263m158s553m158s263"
"m158s263m158s263m158s553m158s553m158s263m158s553m158s263m158s263"
"m158s150472"
"m158s1026"
"m158s263m158s263m158s263m158s553m158s263m158s263m158s553m158s263"
"m158s263m158s263m158s553m158s553m158s263m158s553m158s263m158s263"
"m158s150472"
"m158s1026"
"m158s263m158s263m158s263m158s553m158s263m158s263m158s553m158s263"
"m158s263m158s263m158s553m158s553m158s263m158s553m158s263m158s263"
"m158s150472", irsend.outputStr());
irsend.reset();
irsend.sendLegoPf(0x2345, kLegoPfBits, 2);
EXPECT_EQ(
"f38000d50"
"m0s16000"
"m158s1026"
"m158s263m158s263m158s553m158s263m158s263m158s263m158s553m158s553"
"m158s263m158s553m158s263m158s263m158s263m158s553m158s263m158s553"
"m158s70182"
"m158s1026"
"m158s263m158s263m158s553m158s263m158s263m158s263m158s553m158s553"
"m158s263m158s553m158s263m158s263m158s263m158s553m158s263m158s553"
"m158s70182"
"m158s1026"
"m158s263m158s263m158s553m158s263m158s263m158s263m158s553m158s553"
"m158s263m158s553m158s263m158s263m158s263m158s553m158s263m158s553"
"m158s182182"
"m158s1026"
"m158s263m158s263m158s553m158s263m158s263m158s263m158s553m158s553"
"m158s263m158s553m158s263m158s263m158s263m158s553m158s263m158s553"
"m158s182182"
"m158s1026"
"m158s263m158s263m158s553m158s263m158s263m158s263m158s553m158s553"
"m158s263m158s553m158s263m158s263m158s263m158s553m158s263m158s553"
"m158s182182", irsend.outputStr());
irsend.reset();
irsend.sendLegoPf(0x3456, kLegoPfBits, 7);
EXPECT_EQ(
"f38000d50"
"m158s1026"
"m158s263m158s263m158s553m158s553m158s263m158s553m158s263m158s263"
"m158s263m158s553m158s263m158s553m158s263m158s553m158s553m158s263"
"m158s69892"
"m158s1026"
"m158s263m158s263m158s553m158s553m158s263m158s553m158s263m158s263"
"m158s263m158s553m158s263m158s553m158s263m158s553m158s553m158s263"
"m158s69892"
"m158s1026"
"m158s263m158s263m158s553m158s553m158s263m158s553m158s263m158s263"
"m158s263m158s553m158s263m158s553m158s263m158s553m158s553m158s263"
"m158s213892"
"m158s1026"
"m158s263m158s263m158s553m158s553m158s263m158s553m158s263m158s263"
"m158s263m158s553m158s263m158s553m158s263m158s553m158s553m158s263"
"m158s213892"
"m158s1026"
"m158s263m158s263m158s553m158s553m158s263m158s553m158s263m158s263"
"m158s263m158s553m158s263m158s553m158s263m158s553m158s553m158s263"
"m158s213892"
"m158s1026"
"m158s263m158s263m158s553m158s553m158s263m158s553m158s263m158s263"
"m158s263m158s553m158s263m158s553m158s263m158s553m158s553m158s263"
"m158s213892"
"m158s1026"
"m158s263m158s263m158s553m158s553m158s263m158s553m158s263m158s263"
"m158s263m158s553m158s263m158s553m158s263m158s553m158s553m158s263"
"m158s213892", irsend.outputStr());
}
// Tests for decodeLego().
// Decode normal "synthetic" messages.
TEST(TestDecodeLegoPf, SyntheticDecode) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
irsend.sendLegoPf(0x000F);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LEGOPF, irsend.capture.decode_type);
EXPECT_EQ(kLegoPfBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(0x000F, irsend.capture.value);
EXPECT_EQ(1, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
irsend.reset();
irsend.sendLegoPf(0x100E);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LEGOPF, irsend.capture.decode_type);
EXPECT_EQ(kLegoPfBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(0x100E, irsend.capture.value);
EXPECT_EQ(2, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
irsend.reset();
irsend.sendLegoPf(0x221E);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LEGOPF, irsend.capture.decode_type);
EXPECT_EQ(kLegoPfBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(0x221E, irsend.capture.value);
EXPECT_EQ(3, irsend.capture.address);
EXPECT_EQ(0x21, irsend.capture.command);
// Test a bad LRC is not matched.
irsend.reset();
irsend.sendLegoPf(0x001F); // LRC should be 0xE, not 0xF.
irsend.makeDecodeResult();
irrecv.decode(&irsend.capture);
EXPECT_NE(LEGOPF, irsend.capture.decode_type);
}
// Decode normal "synthetic" message with releats.
TEST(TestDecodeLegoPf, SyntheticDecodeWithRepeat) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
irsend.sendLegoPf(0x330F, kLegoPfBits, 1);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LEGOPF, irsend.capture.decode_type);
EXPECT_EQ(kLegoPfBits, irsend.capture.bits);
EXPECT_EQ(0x330F, irsend.capture.value);
EXPECT_EQ(4, irsend.capture.address);
EXPECT_EQ(0x30, irsend.capture.command);
}

View File

@@ -0,0 +1,148 @@
// Copyright 2018 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendLutron().
// Test sending typical data only.
TEST(TestSendLutron, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
irsend.sendLutron(0);
EXPECT_EQ("f40000d40m2288s230080", irsend.outputStr());
irsend.sendLutron(0xAAAAAAAAA); // Longest possible sequence. (I think)
EXPECT_EQ(
"f40000d40"
"m2288s2288m2288s2288m2288s2288m2288s2288m2288s2288m2288s2288m2288s2288"
"m2288s2288m2288s2288m2288s2288m2288s2288m2288s2288m2288s2288m2288s2288"
"m2288s2288m2288s2288m2288s2288m2288s152288",
irsend.outputStr());
irsend.sendLutron(0x7FFFFFFFF);
EXPECT_EQ("f40000d40m82368s150000", irsend.outputStr());
irsend.sendLutron(0x7F88BD120);
EXPECT_EQ(
"f40000d40"
"m20592s6864m2288s6864m2288s2288m9152s2288m2288s6864m2288s4576m2288"
"s161440",
irsend.outputStr());
}
// Test sending with repeats.
TEST(TestSendLutron, SendWithRepeats) {
IRsendTest irsend(0);
irsend.begin();
// Send a command with 0 repeats.
irsend.sendLutron(0x7F88BD120, kLutronBits, 0);
EXPECT_EQ(
"f40000d40"
"m20592s6864m2288s6864m2288s2288m9152s2288m2288s6864m2288s4576m2288"
"s161440",
irsend.outputStr());
// Send a command with 1 repeat.
irsend.sendLutron(0x7F88BD120, kLutronBits, 1);
EXPECT_EQ(
"f40000d40"
"m20592s6864m2288s6864m2288s2288m9152s2288m2288s6864m2288s4576m2288"
"s161440"
"m20592s6864m2288s6864m2288s2288m9152s2288m2288s6864m2288s4576m2288"
"s161440",
irsend.outputStr());
// Send a command with 3 repeats.
irsend.sendLutron(0x7F88BD120, kLutronBits, 3);
EXPECT_EQ(
"f40000d40"
"m20592s6864m2288s6864m2288s2288m9152s2288m2288s6864m2288s4576m2288"
"s161440"
"m20592s6864m2288s6864m2288s2288m9152s2288m2288s6864m2288s4576m2288"
"s161440"
"m20592s6864m2288s6864m2288s2288m9152s2288m2288s6864m2288s4576m2288"
"s161440"
"m20592s6864m2288s6864m2288s2288m9152s2288m2288s6864m2288s4576m2288"
"s161440",
irsend.outputStr());
}
// Tests for decodeLutron().
// Decode normal Lutron messages.
TEST(TestDecodeLutron, SyntheticDecode) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Synthesised Normal Lutron messages.
irsend.reset();
irsend.sendLutron(0x7F88BD120);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LUTRON, irsend.capture.decode_type);
EXPECT_EQ(kLutronBits, irsend.capture.bits);
EXPECT_EQ(0x7F88BD120, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
irsend.sendLutron(0x0DEADBEEF);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LUTRON, irsend.capture.decode_type);
EXPECT_EQ(kLutronBits, irsend.capture.bits);
EXPECT_EQ(0x0DEADBEEF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
irsend.sendLutron(0x0);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LUTRON, irsend.capture.decode_type);
EXPECT_EQ(kLutronBits, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
irsend.sendLutron(0x7FFFFFFFF);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LUTRON, irsend.capture.decode_type);
EXPECT_EQ(kLutronBits, irsend.capture.bits);
EXPECT_EQ(0x7FFFFFFFF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
// Decode a documented example
TEST(TestDecodeLutron, DocumentedExampleFullOff) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Full Off code.
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/515
uint16_t rawData[14] = {20518, 6839, 2280, 6839, 2280, 2280, 9119,
2280, 2280, 6839, 2280, 4560, 2280, 11399};
irsend.reset();
irsend.sendRaw(rawData, 14, 40);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LUTRON, irsend.capture.decode_type);
EXPECT_EQ(kLutronBits, irsend.capture.bits);
EXPECT_EQ(0x7F88BD120, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
uint16_t pronto[18] = {0x0000, 0x0069, 0x0007, 0x0000, 0x032a, 0x010e,
0x005a, 0x010e, 0x005a, 0x005a, 0x0168, 0x005a,
0x005a, 0x010e, 0x005a, 0x00b4, 0x005a, 0x01c2};
irsend.reset();
irsend.sendPronto(pronto, 18);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(LUTRON, irsend.capture.decode_type);
EXPECT_EQ(kLutronBits, irsend.capture.bits);
EXPECT_EQ(0x7F88BD120, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}

View File

@@ -0,0 +1,126 @@
// Copyright 2017 David Conran
// Copyright 2018 Brett T. Warden
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// MM MM WW WW MM MM
// MMM MMM WW WW MMM MMM
// MM M MM WW W WW MM M MM
// MM MM WWW WWW MM MM
// MM MM WW WW MM MM
// Tests for sendMWM().
// Test sending simplest case data only.
TEST(TestSendMWM, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
unsigned char test1[] = {0x96, 0x19, 0x10, 0x24, 0x0A,
0x6B, 0x20, 0x03, 0x82};
/*
++--+-++--
+-++--+++-
+++++-+++-
+++-++-++-
++-+-++++-
+--+-+--+-
++++++-++-
+--++++++-
++-+++++--
*/
irsend.sendMWM(test1, sizeof(test1), 0);
EXPECT_EQ(
"f38000d25"
"m834s834m417s417m834s834"
"m417s417m834s834m1251s417"
"m2085s417m1251s417"
"m1251s417m834s417m834s417"
"m834s417m417s417m1668s417"
"m417s834m417s417m417s834m417s417"
"m2502s417m834s417"
"m417s834m2502s417"
"m834s417m2085s30834", irsend.outputStr());
irsend.reset();
unsigned char test2[] = {
0x99, 0x26, 0x66, 0x6E, 0xD1, 0x42, 0x06,
0x20, 0xD0, 0x32, 0xF0, 0x0B
// +-++--++--
// ++--++-++-
// ++--++--+-
// ++---+--+-
// +-+++-+---
// ++-++++-+-
// ++--+++++-
// ++++++-++-
// +++++-+---
// ++-++--++-
// +++++-----
// +--+-++++-
};
irsend.sendMWM(test2, sizeof(test2), 0);
EXPECT_EQ(
"f38000d25"
"m417s417m834s834m834s834"
"m834s834m834s417m834s417"
"m834s834m834s834m417s417"
"m834s1251m417s834m417s417"
"m417s417m1251s417m417s1251"
"m834s417m1668s417m417s417"
"m834s834m2085s417"
"m2502s417m834s417"
"m2085s417m417s1251"
"m834s417m834s834m834s417"
"m2085s2085"
"m417s834m417s417m1668s30417", irsend.outputStr());
}
// Tests for decodeMWM().
// Example data
TEST(TestDecodeMWM, RealExamples) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
uint16_t short_code[] = {
915, 793, 488, 366, 915, 793, 427, 366, 915, 793, 1281, 427,
2136, 366, 1281, 366, 915, 793, 427, 854, 854, 366, 1281, 854,
1708, 366, 488, 793, 854, 427, 427, 427, 427, 366, 854, 427,
2563, 366, 488, 793, 2563, 366, 488, 2075, 427, 34057};
unsigned char short_expected[] = {0x96, 0x19, 0x10, 0x36, 0x0C,
0x53, 0x02, 0x03, 0xDF};
irsend.sendRaw(short_code, sizeof(short_code) / sizeof(short_code[0]), 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(MWM, irsend.capture.decode_type);
EXPECT_EQ(8 * sizeof(short_expected) / sizeof(short_expected[0]),
irsend.capture.bits);
EXPECT_STATE_EQ(short_expected, irsend.capture.state, irsend.capture.bits);
irsend.reset();
uint16_t long_code[] = {
427, 427, 854, 854, 854, 793, 915, 793, 854, 366, 915, 366, 854,
854, 854, 793, 488, 366, 915, 1220, 427, 793, 488, 366, 488, 366,
1281, 427, 427, 1220, 915, 366, 1708, 366, 488, 366, 854, 854, 2136,
366, 2563, 366, 854, 427, 2136, 366, 488, 1220, 854, 427, 854, 793,
915, 366, 2136, 2075, 427, 793, 488, 366, 1708, 30517};
unsigned char long_expected[] = {0x99, 0x26, 0x66, 0x6E, 0xD1, 0x42,
0x06, 0x20, 0xD0, 0x32, 0xF0, 0x0B};
irsend.sendRaw(long_code, sizeof(long_code) / sizeof(long_code[0]), 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(MWM, irsend.capture.decode_type);
EXPECT_EQ(8 * sizeof(long_expected) / sizeof(long_expected[0]),
irsend.capture.bits);
EXPECT_STATE_EQ(long_expected, irsend.capture.state, irsend.capture.bits);
}
// vim: et:ts=2:sw=2

View File

@@ -0,0 +1,168 @@
// Copyright 2017 David Conran
#include "ir_Magiquest.h"
#include "IRrecv.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for encodeMagiQuest()
TEST(TestEncodeMagiQuest, General) {
IRsendTest irsend(0);
EXPECT_EQ(0x0, irsend.encodeMagiQuest(0x0, 0x0));
EXPECT_EQ(0x10001, irsend.encodeMagiQuest(0x1, 0x1));
EXPECT_EQ(0x20003, irsend.encodeMagiQuest(0x2, 0x3));
EXPECT_EQ(0x123456781234, irsend.encodeMagiQuest(0x12345678, 0x1234));
EXPECT_EQ(0xFFFFFFFFFFFF, irsend.encodeMagiQuest(0xFFFFFFFF, 0xFFFF));
}
// Tests for sendMagiQuest()
// Test sending typical data only.
TEST(TestSendMagiQuest, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
irsend.sendMagiQuest(0x0);
EXPECT_EQ(
"f36000d50"
"m280s850m280s850m280s850m280s850m280s850m280s850m280s850m280s850"
"m280s850m280s850m280s850m280s850m280s850m280s850m280s850m280s850"
"m280s850m280s850m280s850m280s850m280s850m280s850m280s850m280s850"
"m280s850m280s850m280s850m280s850m280s850m280s850m280s850m280s850"
"m280s850m280s850m280s850m280s850m280s850m280s850m280s850m280s850"
"m280s850m280s850m280s850m280s850m280s850m280s850m280s850m280s850"
"m280s850m280s850m280s850m280s850m280s850m280s850m280s850m280s100850",
irsend.outputStr());
irsend.reset();
irsend.sendMagiQuest(0x123456789ABC);
EXPECT_EQ(
"f36000d50"
"m280s850m280s850m280s850m280s850m280s850m280s850m280s850m280s850"
"m280s850m280s850m280s850m580s600m280s850m280s850m580s600m280s850"
"m280s850m280s850m580s600m580s600m280s850m580s600m280s850m280s850"
"m280s850m580s600m280s850m580s600m280s850m580s600m580s600m280s850"
"m280s850m580s600m580s600m580s600m580s600m280s850m280s850m280s850"
"m580s600m280s850m280s850m580s600m580s600m280s850m580s600m280s850"
"m580s600m280s850m580s600m580s600m580s600m580s600m280s850m280s100850",
irsend.outputStr());
}
// Test sending typical data only.
TEST(TestSendMagiQuest, SendWithRepeats) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
irsend.sendMagiQuest(0x12345678ABCD, kMagiquestBits, 2); // two repeats.
EXPECT_EQ(
"f36000d50"
"m280s850m280s850m280s850m280s850m280s850m280s850m280s850m280s850"
"m280s850m280s850m280s850m580s600m280s850m280s850m580s600m280s850"
"m280s850m280s850m580s600m580s600m280s850m580s600m280s850m280s850"
"m280s850m580s600m280s850m580s600m280s850m580s600m580s600m280s850"
"m280s850m580s600m580s600m580s600m580s600m280s850m280s850m280s850"
"m580s600m280s850m580s600m280s850m580s600m280s850m580s600m580s600"
"m580s600m580s600m280s850m280s850m580s600m580s600m280s850m580s100600"
"m280s850m280s850m280s850m280s850m280s850m280s850m280s850m280s850"
"m280s850m280s850m280s850m580s600m280s850m280s850m580s600m280s850"
"m280s850m280s850m580s600m580s600m280s850m580s600m280s850m280s850"
"m280s850m580s600m280s850m580s600m280s850m580s600m580s600m280s850"
"m280s850m580s600m580s600m580s600m580s600m280s850m280s850m280s850"
"m580s600m280s850m580s600m280s850m580s600m280s850m580s600m580s600"
"m580s600m580s600m280s850m280s850m580s600m580s600m280s850m580s100600"
"m280s850m280s850m280s850m280s850m280s850m280s850m280s850m280s850"
"m280s850m280s850m280s850m580s600m280s850m280s850m580s600m280s850"
"m280s850m280s850m580s600m580s600m280s850m580s600m280s850m280s850"
"m280s850m580s600m280s850m580s600m280s850m580s600m580s600m280s850"
"m280s850m580s600m580s600m580s600m580s600m280s850m280s850m280s850"
"m580s600m280s850m580s600m280s850m580s600m280s850m580s600m580s600"
"m580s600m580s600m280s850m280s850m580s600m580s600m280s850m580s100600",
irsend.outputStr());
}
// Tests for decodeMagiQuest().
// Decode normal "synthetic" messages.
TEST(TestDecodeMagiQuest, NormalDecodeWithStrict) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
irsend.sendMagiQuest(0x0);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeMagiQuest(&irsend.capture, kStartOffset,
kMagiquestBits, true));
EXPECT_EQ(MAGIQUEST, irsend.capture.decode_type);
EXPECT_EQ(kMagiquestBits, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
irsend.reset();
irsend.sendMagiQuest(irsend.encodeMagiQuest(0x1, 0x1));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeMagiQuest(&irsend.capture, kStartOffset,
kMagiquestBits, true));
EXPECT_EQ(MAGIQUEST, irsend.capture.decode_type);
EXPECT_EQ(kMagiquestBits, irsend.capture.bits);
EXPECT_EQ(0x10001, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x1, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
irsend.reset();
irsend.sendMagiQuest(irsend.encodeMagiQuest(0x12345678, 0xABCD));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeMagiQuest(&irsend.capture, kStartOffset,
kMagiquestBits, true));
EXPECT_EQ(MAGIQUEST, irsend.capture.decode_type);
EXPECT_EQ(kMagiquestBits, irsend.capture.bits);
EXPECT_EQ(0x12345678ABCD, irsend.capture.value);
EXPECT_EQ(0x12345678, irsend.capture.address);
EXPECT_EQ(0xABCD, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Do the last one again, & use the full decoder, not just protocol specific.
irsend.reset();
irsend.sendMagiQuest(irsend.encodeMagiQuest(0x12345678, 0xABCD));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(MAGIQUEST, irsend.capture.decode_type);
EXPECT_EQ(kMagiquestBits, irsend.capture.bits);
EXPECT_EQ(0x12345678ABCD, irsend.capture.value);
}
// Decode a "real" example message.
TEST(TestDecodeMagiQuest, RealExamples) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
uint16_t rawData[111] = {262, 842, 298, 858, 238, 866, 240, 890, 238, 866,
240, 862, 244, 886, 242, 860, 246, 858, 554, 604,
264, 840, 560, 622, 266, 836, 552, 604, 556, 626,
262, 866, 240, 864, 264, 838, 268, 862, 244, 886,
536, 620, 530, 628, 554, 628, 532, 624, 244, 858,
552, 604, 264, 840, 268, 862, 266, 838, 268, 888,
240, 864, 242, 860, 268, 862, 244, 860, 236, 868,
272, 832, 264, 866, 240, 890, 532, 598, 268, 834,
294, 836, 270, 834, 262, 866, 272, 858, 238, 866,
534, 622, 268, 836, 270, 860, 268, 862, 526, 604,
264, 892, 530, 600, 268, 836, 586, 598, 270, 834,
556}; // Data from PR #365 captured by coolacid
irsend.sendRaw(rawData, 111, 36000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(MAGIQUEST, irsend.capture.decode_type);
EXPECT_EQ(kMagiquestBits, irsend.capture.bits);
EXPECT_EQ(0x560F40020455, irsend.capture.value);
EXPECT_EQ(0x560F4002, irsend.capture.address); // Wand ID
EXPECT_EQ(0x0455, irsend.capture.command); // Magnitude
EXPECT_FALSE(irsend.capture.repeat);
}

View File

@@ -0,0 +1,954 @@
// Copyright 2017 David Conran
#include "ir_Midea.h"
#include "IRac.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendMidea().
// Test sending typical data only.
TEST(TestSendMidea, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendMidea(0x0);
EXPECT_EQ(
"f38000d50"
"m4480s4480"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s5600"
"m4480s4480"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s5600",
irsend.outputStr());
irsend.reset();
irsend.sendMidea(0x55AA55AA55AA);
EXPECT_EQ(
"f38000d50"
"m4480s4480"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s5600"
"m4480s4480"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s5600",
irsend.outputStr());
irsend.reset();
irsend.sendMidea(0xFFFFFFFFFFFF);
EXPECT_EQ(
"f38000d50"
"m4480s4480"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s5600"
"m4480s4480"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s5600",
irsend.outputStr());
}
// Test sending with different repeats.
TEST(TestSendMidea, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendMidea(0x55AA55AA55AA, kMideaBits, 1); // 1 repeat.
EXPECT_EQ(
"f38000d50"
"m4480s4480"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s5600"
"m4480s4480"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s5600"
"m4480s4480"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s5600"
"m4480s4480"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s5600",
irsend.outputStr());
irsend.sendMidea(0x55AA55AA55AA, kMideaBits, 2); // 2 repeats.
EXPECT_EQ(
"f38000d50"
"m4480s4480"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s5600"
"m4480s4480"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s5600"
"m4480s4480"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s5600"
"m4480s4480"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s5600"
"m4480s4480"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s5600"
"m4480s4480"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
"m560s5600",
irsend.outputStr());
}
// Test sending an atypical data size.
TEST(TestSendMidea, SendUnusualSize) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendMidea(0x0, 8);
EXPECT_EQ(
"f38000d50"
"m4480s4480"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s5600"
"m4480s4480"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s5600",
irsend.outputStr());
irsend.reset();
irsend.sendMidea(0x1234567890ABCDEF, 64);
EXPECT_EQ(
"f38000d50"
"m4480s4480"
"m560s560m560s560m560s560m560s1680m560s560m560s560m560s1680m560s560"
"m560s560m560s560m560s1680m560s1680m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s1680m560s560"
"m560s560m560s1680m560s1680m560s1680m560s1680m560s560m560s560m560s560"
"m560s1680m560s560m560s560m560s1680m560s560m560s560m560s560m560s560"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s1680"
"m560s1680m560s1680m560s560m560s560m560s1680m560s1680m560s560m560s1680"
"m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s1680m560s1680"
"m560s5600"
"m4480s4480"
"m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s560m560s1680"
"m560s1680m560s1680m560s560m560s560m560s1680m560s560m560s1680m560s1680"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s560m560s1680"
"m560s1680m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680"
"m560s560m560s1680m560s1680m560s560m560s1680m560s1680m560s1680m560s1680"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s560"
"m560s560m560s560m560s1680m560s1680m560s560m560s560m560s1680m560s560"
"m560s560m560s560m560s560m560s1680m560s560m560s560m560s560m560s560"
"m560s5600",
irsend.outputStr());
// Bit sizes must be a multiple of 8.
irsend.reset();
irsend.sendMidea(0x0, 17);
EXPECT_EQ("", irsend.outputStr());
}
// Tests for IRMideaAC class.
// Tests for controlling the power state.
TEST(TestMideaACClass, Power) {
IRMideaAC midea(0);
midea.begin();
midea.setRaw(0xA1026FFFFFE2); // Power off.
midea.on();
EXPECT_TRUE(midea.getPower());
EXPECT_EQ(0xA1826FFFFF62, midea.getRaw());
midea.off();
EXPECT_FALSE(midea.getPower());
EXPECT_EQ(0xA1026FFFFFE2, midea.getRaw());
midea.setPower(true);
EXPECT_TRUE(midea.getPower());
EXPECT_EQ(0xA1826FFFFF62, midea.getRaw());
midea.setPower(false);
EXPECT_FALSE(midea.getPower());
EXPECT_EQ(0xA1026FFFFFE2, midea.getRaw());
}
// Tests for the various Checksum routines.
TEST(TestMideaACClass, Checksums) {
IRMideaAC midea(0);
midea.begin();
// Known good states
EXPECT_EQ(0x62, IRMideaAC::calcChecksum(0xA1826FFFFF62));
EXPECT_EQ(0x70, IRMideaAC::calcChecksum(0xA18177FFFF70));
// Now without the checksum part.
EXPECT_EQ(0x62, IRMideaAC::calcChecksum(0xA1826FFFFF00));
EXPECT_EQ(0x70, IRMideaAC::calcChecksum(0xA18177FFFF00));
// Made up values.
EXPECT_EQ(0x00, IRMideaAC::calcChecksum(0x000000000000));
EXPECT_EQ(0xDF, IRMideaAC::calcChecksum(0x1234567890AB));
EXPECT_EQ(0xA0, IRMideaAC::calcChecksum(0xFFFFFFFFFFFF));
// Larger than expected value (full 64bit)
EXPECT_EQ(0xDF, IRMideaAC::calcChecksum(0xFF1234567890AB));
EXPECT_EQ(0xDF, IRMideaAC::calcChecksum(0x551234567890AB));
// Validity tests.
EXPECT_TRUE(IRMideaAC::validChecksum(0xA1826FFFFF62));
EXPECT_TRUE(IRMideaAC::validChecksum(0xA18177FFFF70));
EXPECT_FALSE(IRMideaAC::validChecksum(0x1234567890AB));
// Doing a setRaw() with a bad state should make a valid checksum on getRaw().
midea.setRaw(0xA1826FFFFF00);
EXPECT_EQ(0xA1826FFFFF62, midea.getRaw());
}
TEST(TestMideaACClass, OperatingMode) {
IRMideaAC midea(0);
midea.begin();
midea.setRaw(0xA1826FFFFF62); // Auto mode already set.
midea.setMode(kMideaACAuto);
EXPECT_EQ(kMideaACAuto, midea.getMode());
EXPECT_EQ(0xA1826FFFFF62, midea.getRaw()); // State shouldn't have changed.
midea.setMode(kMideaACCool);
EXPECT_EQ(kMideaACCool, midea.getMode());
EXPECT_EQ(0xA1806FFFFF61, midea.getRaw());
midea.setMode(kMideaACAuto);
EXPECT_EQ(kMideaACAuto, midea.getMode());
EXPECT_EQ(0xA1826FFFFF62, midea.getRaw());
midea.setMode(kMideaACHeat);
EXPECT_EQ(kMideaACHeat, midea.getMode());
EXPECT_EQ(0xA1836FFFFF63, midea.getRaw());
midea.setMode(kMideaACDry);
EXPECT_EQ(kMideaACDry, midea.getMode());
EXPECT_EQ(0xA1816FFFFF60, midea.getRaw());
midea.setMode(kMideaACFan);
EXPECT_EQ(kMideaACFan, midea.getMode());
EXPECT_EQ(0xA1846FFFFF66, midea.getRaw());
midea.setMode(255);
EXPECT_EQ(kMideaACAuto, midea.getMode());
EXPECT_EQ(0xA1826FFFFF62, midea.getRaw());
}
TEST(TestMideaACClass, FanSpeed) {
IRMideaAC midea(0);
midea.begin();
midea.setRaw(0xA1826FFFFF62); // Auto mode already set.
EXPECT_EQ(kMideaACFanAuto, midea.getFan());
midea.setFan(kMideaACFanLow);
EXPECT_EQ(kMideaACFanLow, midea.getFan());
EXPECT_EQ(0xA18A6FFFFF6C, midea.getRaw());
midea.setFan(255); // Setting an unexpected value defaults to auto.
EXPECT_EQ(kMideaACFanAuto, midea.getFan());
EXPECT_EQ(0xA1826FFFFF62, midea.getRaw());
midea.setFan(kMideaACFanMed);
EXPECT_EQ(kMideaACFanMed, midea.getFan());
EXPECT_EQ(0xA1926FFFFF7C, midea.getRaw());
midea.setFan(kMideaACFanHigh);
EXPECT_EQ(kMideaACFanHigh, midea.getFan());
EXPECT_EQ(0xA19A6FFFFF74, midea.getRaw());
midea.setFan(kMideaACFanAuto);
EXPECT_EQ(kMideaACFanAuto, midea.getFan());
EXPECT_EQ(0xA1826FFFFF62, midea.getRaw());
}
TEST(TestMideaACClass, Temperature) {
IRMideaAC midea(0);
midea.begin();
midea.setRaw(0xA1826FFFFF62); // 77F / 25C
EXPECT_EQ(77, midea.getTemp()); // F
EXPECT_EQ(77, midea.getTemp(false)); // F
EXPECT_EQ(25, midea.getTemp(true)); // F
midea.setTemp(0);
EXPECT_EQ(kMideaACMinTempF, midea.getTemp());
EXPECT_EQ(0xA18260FFFF6C, midea.getRaw());
midea.setTemp(255);
EXPECT_EQ(kMideaACMaxTempF, midea.getTemp());
EXPECT_EQ(0xA18278FFFF78, midea.getRaw());
midea.setTemp(0, true);
EXPECT_EQ(kMideaACMinTempF, midea.getTemp());
EXPECT_EQ(0xA18260FFFF6C, midea.getRaw());
midea.setTemp(255, true);
EXPECT_EQ(kMideaACMaxTempF, midea.getTemp());
EXPECT_EQ(0xA18278FFFF78, midea.getRaw());
// fahrenheit min/max etc.
midea.setTemp(kMideaACMinTempF);
EXPECT_EQ(kMideaACMinTempF, midea.getTemp());
midea.setTemp(kMideaACMaxTempF);
EXPECT_EQ(kMideaACMaxTempF, midea.getTemp());
midea.setTemp(kMideaACMinTempF - 1);
EXPECT_EQ(kMideaACMinTempF, midea.getTemp());
midea.setTemp(kMideaACMaxTempF + 1);
EXPECT_EQ(kMideaACMaxTempF, midea.getTemp());
// celsius min/max etc.
midea.setTemp(kMideaACMinTempC, true);
EXPECT_EQ(kMideaACMinTempC, midea.getTemp(true));
EXPECT_EQ(kMideaACMinTempF, midea.getTemp(false));
midea.setTemp(kMideaACMaxTempC, true);
EXPECT_EQ(kMideaACMaxTempC, midea.getTemp(true));
EXPECT_EQ(kMideaACMaxTempF, midea.getTemp(false));
midea.setTemp(kMideaACMinTempC - 1, true);
EXPECT_EQ(kMideaACMinTempC, midea.getTemp(true));
midea.setTemp(kMideaACMaxTempC + 1, true);
EXPECT_EQ(kMideaACMaxTempC, midea.getTemp(true));
EXPECT_EQ(kMideaACMaxTempF, midea.getTemp(false));
// General changes.
midea.setTemp(18, true); // C
EXPECT_EQ(18, midea.getTemp(true)); // C
EXPECT_EQ(64, midea.getTemp(false)); // F
midea.setTemp(21, true); // C
EXPECT_EQ(21, midea.getTemp(true)); // C
EXPECT_EQ(69, midea.getTemp(false)); // F
midea.setTemp(25, true); // C
EXPECT_EQ(25, midea.getTemp(true)); // C
EXPECT_EQ(77, midea.getTemp(false)); // F
midea.setTemp(30, true); // C
EXPECT_EQ(30, midea.getTemp(true)); // C
EXPECT_EQ(86, midea.getTemp(false)); // F
midea.setTemp(80, false); // F
EXPECT_EQ(27, midea.getTemp(true)); // C
EXPECT_EQ(80, midea.getTemp(false)); // F
midea.setTemp(70); // F
EXPECT_EQ(21, midea.getTemp(true)); // C
EXPECT_EQ(70, midea.getTemp(false)); // F
EXPECT_EQ(70, midea.getTemp()); // F
}
// Tests for controlling the sleep state.
TEST(TestMideaACClass, Sleep) {
IRMideaAC midea(0);
midea.begin();
midea.setRaw(0xA1826FFFFF62); // Sleep off.
EXPECT_FALSE(midea.getSleep());
midea.setSleep(true);
EXPECT_TRUE(midea.getSleep());
EXPECT_EQ(0xA1C26FFFFF22, midea.getRaw());
midea.setSleep(false);
EXPECT_FALSE(midea.getSleep());
EXPECT_EQ(0xA1826FFFFF62, midea.getRaw());
}
TEST(TestMideaACClass, HumanReadableOutput) {
IRMideaAC ac(0);
ac.begin();
ac.setRaw(0xA1826FFFFF62);
EXPECT_EQ(
"Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 25C/77F, Fan: 0 (Auto), "
"Sleep: Off, Swing(V) Toggle: Off", ac.toString());
ac.off();
ac.setTemp(25, true);
ac.setFan(kMideaACFanHigh);
ac.setMode(kMideaACDry);
ac.setSleep(true);
EXPECT_EQ(
"Power: Off, Mode: 1 (Dry), Celsius: Off, Temp: 25C/77F, Fan: 3 (High), "
"Sleep: On, Swing(V) Toggle: Off", ac.toString());
ac.setUseCelsius(true);
EXPECT_EQ(
"Power: Off, Mode: 1 (Dry), Celsius: On, Temp: 25C/77F, Fan: 3 (High), "
"Sleep: On, Swing(V) Toggle: Off", ac.toString());
ac.setRaw(0xA19867FFFF7E);
EXPECT_EQ(
"Power: On, Mode: 0 (Cool), Celsius: Off, Temp: 21C/69F, Fan: 3 (High), "
"Sleep: Off, Swing(V) Toggle: Off", ac.toString());
}
// Tests for decodeMidea().
// Decode normal Midea messages with strict set.
TEST(TestDecodeMidea, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Midea 48-bit message.
irsend.reset();
irsend.sendMidea(0x1234567890DF);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeMidea(&irsend.capture, kStartOffset, kMideaBits,
true));
EXPECT_EQ(MIDEA, irsend.capture.decode_type);
EXPECT_EQ(kMideaBits, irsend.capture.bits);
EXPECT_EQ(0x1234567890DF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal Midea 48-bit message.
irsend.reset();
irsend.sendMidea(0x0);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeMidea(&irsend.capture, kStartOffset, kMideaBits,
true));
EXPECT_EQ(MIDEA, irsend.capture.decode_type);
EXPECT_EQ(kMideaBits, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal Midea 48-bit message.
irsend.reset();
irsend.sendMidea(0xFFFFFFFFFFA0);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeMidea(&irsend.capture, kStartOffset, kMideaBits,
true));
EXPECT_EQ(MIDEA, irsend.capture.decode_type);
EXPECT_EQ(kMideaBits, irsend.capture.bits);
EXPECT_EQ(0xFFFFFFFFFFA0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Real Midea 48-bit message via just decode().
// i.e. No conficts with other decoders.
irsend.reset();
irsend.sendMidea(0xA18263FFFF6E);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(MIDEA, irsend.capture.decode_type);
EXPECT_EQ(kMideaBits, irsend.capture.bits);
EXPECT_EQ(0xA18263FFFF6E, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode normal repeated Midea messages.
TEST(TestDecodeMidea, NormalDecodeWithRepeatAndStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Midea 48-bit message with 2 repeats.
irsend.reset();
irsend.sendMidea(0xA18263FFFF6E, kMideaBits, 2);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeMidea(&irsend.capture, kStartOffset, kMideaBits,
true));
EXPECT_EQ(MIDEA, irsend.capture.decode_type);
EXPECT_EQ(kMideaBits, irsend.capture.bits);
EXPECT_EQ(0xA18263FFFF6E, irsend.capture.value);
EXPECT_FALSE(irsend.capture.repeat);
irsend.makeDecodeResult(2 * (2 * kMideaBits + 4));
ASSERT_TRUE(irrecv.decodeMidea(&irsend.capture, kStartOffset, kMideaBits,
true));
EXPECT_EQ(MIDEA, irsend.capture.decode_type);
EXPECT_EQ(kMideaBits, irsend.capture.bits);
EXPECT_EQ(0xA18263FFFF6E, irsend.capture.value);
irsend.makeDecodeResult(4 * (2 * kMideaBits + 4));
ASSERT_TRUE(irrecv.decodeMidea(&irsend.capture, kStartOffset, kMideaBits,
true));
EXPECT_EQ(MIDEA, irsend.capture.decode_type);
EXPECT_EQ(kMideaBits, irsend.capture.bits);
EXPECT_EQ(0xA18263FFFF6E, irsend.capture.value);
}
// Decode unsupported Midea messages.
TEST(TestDecodeMidea, DecodeWithNonStrictSizes) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendMidea(0x12, 8); // Illegal value Midea 8-bit message.
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeMidea(&irsend.capture, kStartOffset, kMideaBits,
true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeMidea(&irsend.capture, kStartOffset, 8, false));
EXPECT_EQ(MIDEA, irsend.capture.decode_type);
EXPECT_EQ(8, irsend.capture.bits);
EXPECT_EQ(0x12, irsend.capture.value);
irsend.reset();
irsend.sendMidea(0x12345678, 32); // Illegal value Midea 32-bit message.
irsend.makeDecodeResult();
// Shouldn't pass with strict when we ask for less bits than we got.
ASSERT_FALSE(irrecv.decodeMidea(&irsend.capture, kStartOffset, kMideaBits,
true));
irsend.makeDecodeResult();
// Should fail with strict when we ask for the wrong bit size.
ASSERT_FALSE(irrecv.decodeMidea(&irsend.capture, kStartOffset, 32, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeMidea(&irsend.capture, kStartOffset, 32, false));
EXPECT_EQ(MIDEA, irsend.capture.decode_type);
EXPECT_EQ(32, irsend.capture.bits);
EXPECT_EQ(0x12345678, irsend.capture.value);
// Decode should fail if asked to decode non-multiples of 8 bits.
irsend.reset();
irsend.sendMidea(0x123456, kMideaBits, 2);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeMidea(&irsend.capture, kStartOffset, 9, false));
}
// Decode (non-standard) 64-bit messages.
TEST(TestDecodeMidea, Decode64BitMessages) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Illegal size Midea 64-bit message.
irsend.sendMidea(0xFFFFFFFFFFFFFFFF, 64);
irsend.makeDecodeResult();
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeMidea(&irsend.capture, kStartOffset, 64, false));
EXPECT_EQ(MIDEA, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, irsend.capture.value);
}
// Fail to decode a non-Midea example via GlobalCache
TEST(TestDecodeMidea, FailToDecodeNonMideaExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Modified a few entries to unexpected values, based on previous test case.
uint16_t gc_test[39] = {38000, 1, 1, 322, 162, 20, 61, 20, 61, 20,
20, 20, 20, 20, 20, 20, 127, 20, 61, 9,
20, 20, 61, 20, 20, 20, 61, 20, 61, 20,
61, 20, 20, 20, 20, 20, 20, 20, 884};
irsend.sendGC(gc_test, 39);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeMidea(&irsend.capture));
ASSERT_FALSE(irrecv.decodeMidea(&irsend.capture, kStartOffset, kMideaBits,
false));
}
// Decode against a real capture reported by a user. See issue #354
TEST(TestDecodeMidea, DecodeRealExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
uint16_t rawData[199] = {
4366, 4470, 498, 1658, 522, 554, 498, 1658, 496, 580, 498, 580,
498, 578, 498, 580, 498, 1658, 498, 1658, 498, 578, 498, 578,
498, 580, 496, 582, 496, 578, 498, 1658, 498, 580, 498, 580,
498, 1656, 498, 1656, 500, 580, 498, 578, 502, 576, 500, 1656,
498, 1656, 500, 1654, 500, 1656, 500, 1656, 498, 1658, 498, 1656,
500, 1658, 498, 1656, 498, 1656, 500, 1656, 500, 1654, 500, 1578,
578, 1658, 498, 1656, 500, 1658, 498, 1656, 498, 1656, 500, 578,
498, 1638, 516, 1656, 500, 578, 500, 1656, 500, 1656, 498, 1658,
522, 554, 500, 5258, 4366, 4472, 498, 580, 498, 1658, 498, 580,
498, 1656, 500, 1600, 556, 1658, 500, 1656, 500, 578, 498, 578,
522, 1634, 498, 1588, 568, 1658, 498, 1656, 500, 1654, 498, 580,
498, 1658, 498, 1658, 498, 580, 496, 578, 500, 1654, 500, 1636,
518, 1656, 500, 578, 520, 558, 498, 578, 498, 580, 498, 576,
500, 578, 498, 580, 498, 578, 498, 578, 498, 580, 498, 578,
498, 580, 498, 580, 520, 556, 498, 580, 496, 580, 498, 578,
500, 578, 498, 1658, 498, 580, 498, 578, 498, 1656, 500, 578,
498, 580, 498, 580, 498, 1656, 522};
irsend.sendRaw(rawData, 199, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(MIDEA, irsend.capture.decode_type);
EXPECT_EQ(kMideaBits, irsend.capture.bits);
EXPECT_EQ(0xA18263FFFF6E, irsend.capture.value);
EXPECT_EQ(
"Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 18C/65F, Fan: 0 (Auto), "
"Sleep: Off, Swing(V) Toggle: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestMideaACClass, toCommon) {
IRMideaAC ac(0);
ac.setPower(true);
ac.setMode(kMideaACCool);
ac.setUseCelsius(true);
ac.setTemp(20, true);
ac.setFan(kMideaACFanHigh);
// Now test it.
ASSERT_EQ(decode_type_t::MIDEA, 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::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kOff, ac.toCommon().swingv);
// Unsupported.
ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh);
ASSERT_FALSE(ac.toCommon().turbo);
ASSERT_FALSE(ac.toCommon().clean);
ASSERT_FALSE(ac.toCommon().light);
ASSERT_FALSE(ac.toCommon().quiet);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().filter);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().sleep);
ASSERT_EQ(-1, ac.toCommon().clock);
}
// https://github.com/crankyoldgit/IRremoteESP8266/issues/819
TEST(TestMideaACClass, CelsiusRemoteTemp) {
IRMideaAC ac(0);
uint64_t on_cool_low_17c = 0xA18840FFFF56;
uint64_t on_cool_low_30c = 0xA1884DFFFF5D;
ac.on();
ac.setMode(kMideaACCool);
ac.setFan(kMideaACFanLow);
ac.setTemp(17, true);
EXPECT_FALSE(ac.getUseCelsius());
ac.setUseCelsius(true);
EXPECT_TRUE(ac.getUseCelsius());
EXPECT_EQ(on_cool_low_17c, ac.getRaw());
EXPECT_EQ(
"Power: On, Mode: 0 (Cool), Celsius: On, Temp: 17C/62F, Fan: 1 (Low), "
"Sleep: Off, Swing(V) Toggle: Off", ac.toString());
ac.setRaw(on_cool_low_17c);
EXPECT_EQ(17, ac.getTemp(true));
EXPECT_EQ(62, ac.getTemp(false));
EXPECT_EQ(
"Power: On, Mode: 0 (Cool), Celsius: On, Temp: 17C/62F, Fan: 1 (Low), "
"Sleep: Off, Swing(V) Toggle: Off", ac.toString());
ac.setTemp(17, true);
EXPECT_EQ(17, ac.getTemp(true));
EXPECT_EQ(62, ac.getTemp(false));
EXPECT_EQ(on_cool_low_17c, ac.getRaw());
ac.setRaw(on_cool_low_30c);
EXPECT_EQ(
"Power: On, Mode: 0 (Cool), Celsius: On, Temp: 30C/86F, Fan: 1 (Low), "
"Sleep: Off, Swing(V) Toggle: Off", ac.toString());
}
// https://github.com/crankyoldgit/IRremoteESP8266/issues/819
TEST(TestMideaACClass, SwingV) {
IRMideaAC ac(0);
ac.setSwingVToggle(false);
ASSERT_FALSE(ac.getSwingVToggle());
ac.setSwingVToggle(true);
ASSERT_TRUE(ac.getSwingVToggle());
EXPECT_EQ(
"Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 25C/77F, Fan: 0 (Auto), "
"Sleep: Off, Swing(V) Toggle: On", ac.toString());
ac.setSwingVToggle(false);
ASSERT_FALSE(ac.getSwingVToggle());
EXPECT_EQ(
"Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 25C/77F, Fan: 0 (Auto), "
"Sleep: Off, Swing(V) Toggle: Off", ac.toString());
ac.setRaw(kMideaACToggleSwingV);
EXPECT_EQ("Swing(V) Toggle: On", ac.toString());
}
// Test abusing the protocol for sending 6 arbitary bytes.
// See https://github.com/crankyoldgit/IRremoteESP8266/issues/887
TEST(TestDecodeMidea, Issue887) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
uint64_t hwaddr = 0x1234567890AB; // 48bits doen't conform to Midea checksum
irsend.sendMidea(hwaddr);
irsend.makeDecodeResult();
// Test normal operation, it shouldn't match.
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_NE(MIDEA, irsend.capture.decode_type);
irsend.reset();
irsend.sendMidea(hwaddr);
irsend.makeDecodeResult();
EXPECT_FALSE(irrecv.decodeMidea(&irsend.capture));
// Now test it with Midea's strict processing turned off!
irsend.reset();
irsend.sendMidea(hwaddr);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeMidea(&irsend.capture, kStartOffset, kMideaBits,
false));
EXPECT_EQ(MIDEA, irsend.capture.decode_type);
EXPECT_EQ(kMideaBits, irsend.capture.bits);
EXPECT_EQ(hwaddr, irsend.capture.value);
}
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1170
TEST(TestDecodeMidea24, RealExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
const uint16_t rawData[103] = {
8928, 4412, 590, 1630, 588, 538, 538, 544, 610, 516, 592, 516, 590, 538,
568, 536, 538, 568, 592, 518, 588, 1630, 588, 1630, 560, 1680, 592, 1628,
594, 1628, 592, 1650, 568, 1630, 558, 1680, 594, 1652, 568, 514, 592, 536,
538, 568, 594, 516, 588, 538, 566, 518, 560, 566, 588, 514, 594, 1630,
588, 1630, 590, 1630, 560, 1680, 594, 1630, 588, 1652, 568, 1650, 540,
1680, 590, 512, 594, 518, 586, 538, 566, 538, 536, 568, 592, 540, 564,
540, 566, 540, 538, 1680, 590, 1626, 592, 1630, 588, 1628, 538, 1702, 590,
1630, 590, 13318, 8916, 2166, 638}; // UNKNOWN 774B249A
irsend.sendRaw(rawData, 103, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(MIDEA24, irsend.capture.decode_type);
EXPECT_EQ(kMidea24Bits, irsend.capture.bits);
EXPECT_EQ(0x80C0C0, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
}
TEST(TestDecodeMidea24, SyntheticExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
irsend.sendMidea24(0x80C0C0);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(MIDEA24, irsend.capture.decode_type);
EXPECT_EQ(kMidea24Bits, irsend.capture.bits);
EXPECT_EQ(0x80C0C0, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
EXPECT_EQ(
"f38000d33"
"m8960s4480"
"m560s1680m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s22400"
"m8960s2240m560s96320",
irsend.outputStr());
}
TEST(TestUtils, Housekeeping) {
ASSERT_EQ("MIDEA", typeToString(decode_type_t::MIDEA));
ASSERT_EQ(decode_type_t::MIDEA, strToDecodeType("MIDEA"));
ASSERT_FALSE(hasACState(decode_type_t::MIDEA));
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::MIDEA));
ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::MIDEA));
ASSERT_EQ(kMideaBits, IRsend::defaultBits(decode_type_t::MIDEA));
ASSERT_EQ("MIDEA24", typeToString(decode_type_t::MIDEA24));
ASSERT_EQ(decode_type_t::MIDEA24, strToDecodeType("MIDEA24"));
ASSERT_FALSE(hasACState(decode_type_t::MIDEA24));
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::MIDEA24));
ASSERT_EQ(kSingleRepeat, IRsend::minRepeats(decode_type_t::MIDEA24));
ASSERT_EQ(kMidea24Bits, IRsend::defaultBits(decode_type_t::MIDEA24));
}
TEST(TestDecodeMidea24, RealExample2) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1170#issuecomment-639271003
const uint16_t rawData[103] = {
8926, 4412, 590, 1630, 536, 570, 608, 518, 594, 516, 588, 518, 588, 538,
538, 568, 592, 514, 590, 518, 588, 1630, 536, 1684, 610, 1628, 594, 1630,
588, 1630, 590, 1630, 560, 1680, 592, 1630, 588, 1650, 568, 538, 538, 568,
590, 514, 594, 538, 566, 518, 536, 594, 584, 516, 594, 518, 586, 1630,
588, 1650, 538, 1682, 592, 1630, 588, 1628, 588, 1630, 560, 1680, 590,
1626, 594, 538, 566, 538, 568, 536, 538, 570, 590, 538, 566, 538, 568,
538, 538, 568, 590, 1626, 594, 1650, 568, 1628, 558, 1662, 558, 1680, 592,
1650, 568, 13312, 8924, 2186, 588}; // UNKNOWN 774B249A
irsend.sendRaw(rawData, 103, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(MIDEA24, irsend.capture.decode_type);
EXPECT_EQ(kMidea24Bits, irsend.capture.bits);
EXPECT_EQ(0x80C0C0, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
// ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1170#issuecomment-639349316
const uint16_t rawData639349316[105] = {
8924, 4410, 596, 1628, 590, 538, 538, 568, 588, 520, 592, 516, 588, 518,
588, 516, 558, 568, 594, 538, 566, 1652, 568, 1650, 540, 1680, 590, 1628,
592, 1628, 590, 1628, 590, 1650, 540, 1680, 592, 1630, 590, 518, 586, 538,
538, 568, 590, 514, 616, 494, 588, 516, 588, 516, 560, 566, 590, 1630,
586, 1634, 564, 1652, 538, 1704, 566, 948, 254, 450, 564, 1654, 566,
1652, 540, 1682, 610, 518, 588, 516, 590, 514, 590, 514, 582, 526, 614,
436, 670, 512, 592, 514, 538, 1578, 718, 1602, 614, 1542, 676, 1626, 538,
1678, 586, 1634, 616, 13308, 8920, 2158, 626}; // UNKNOWN CBEC0079
irsend.reset();
irsend.sendRaw(rawData639349316, 105, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_NE(MIDEA24, irsend.capture.decode_type);
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1170#issuecomment-639358566
const uint16_t rawData639358566[103] = {
8920, 4412, 620, 1606, 614, 512, 592, 512, 536, 568, 618, 512, 590, 492,
614, 514, 514, 590, 594, 510, 620, 1624, 592, 1604, 590, 1632, 608, 1626,
606, 1616, 618, 1602, 618, 1602, 560, 1682, 622, 1602, 618, 512, 592, 510,
538, 568, 590, 512, 622, 488, 616, 490, 614, 488, 560, 568, 620, 1624,
594, 1604, 616, 1602, 536, 1684, 640, 1600, 618, 1598, 618, 1602, 590,
1630, 612, 512, 622, 510, 594, 514, 592, 512, 534, 568, 620, 512, 594,
488, 616, 488, 536, 1702, 594, 1622, 622, 1604, 614, 1624, 594, 1602, 610,
1630, 620, 13294, 8914, 2184, 596}; // UNKNOWN 774B249A
irsend.reset();
irsend.sendRaw(rawData639358566, 103, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(MIDEA24, irsend.capture.decode_type);
EXPECT_EQ(kMidea24Bits, irsend.capture.bits);
EXPECT_EQ(0x80C0C0, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
}
// See https://github.com/crankyoldgit/IRremoteESP8266/issues/1170#issuecomment-639468620
// for why this test exists.
TEST(TestDecodeMidea24, LargeTimeout) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused, 1000, 90); // Test with a large timeout value
irsend.begin();
irsend.reset();
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1170#issuecomment-639358566
const uint16_t rawData639358566[103] = {
8920, 4412, 620, 1606, 614, 512, 592, 512, 536, 568, 618, 512, 590, 492,
614, 514, 514, 590, 594, 510, 620, 1624, 592, 1604, 590, 1632, 608, 1626,
606, 1616, 618, 1602, 618, 1602, 560, 1682, 622, 1602, 618, 512, 592, 510,
538, 568, 590, 512, 622, 488, 616, 490, 614, 488, 560, 568, 620, 1624,
594, 1604, 616, 1602, 536, 1684, 640, 1600, 618, 1598, 618, 1602, 590,
1630, 612, 512, 622, 510, 594, 514, 592, 512, 534, 568, 620, 512, 594,
488, 616, 488, 536, 1702, 594, 1622, 622, 1604, 614, 1624, 594, 1602, 610,
1630, 620, 13294, 8914, 2184, 596}; // UNKNOWN 774B249A
irsend.reset();
irsend.sendRaw(rawData639358566, 103, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(MIDEA24, irsend.capture.decode_type);
EXPECT_EQ(kMidea24Bits, irsend.capture.bits);
EXPECT_EQ(0x80C0C0, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
}

View File

@@ -0,0 +1,925 @@
// Copyright 2019 David Conran
#include "ir_MitsubishiHeavy.h"
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRremoteESP8266.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// General housekeeping
TEST(TestMitsubishiHeavy, Housekeeping) {
ASSERT_EQ("MITSUBISHI_HEAVY_88", typeToString(MITSUBISHI_HEAVY_88));
ASSERT_TRUE(hasACState(MITSUBISHI_HEAVY_88));
ASSERT_EQ("MITSUBISHI_HEAVY_152", typeToString(MITSUBISHI_HEAVY_152));
ASSERT_TRUE(hasACState(MITSUBISHI_HEAVY_152));
}
// Tests for IRMitsubishiHeavy152Ac class.
TEST(TestMitsubishiHeavy152AcClass, Power) {
IRMitsubishiHeavy152Ac 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(TestMitsubishiHeavy152AcClass, Temperature) {
IRMitsubishiHeavy152Ac ac(0);
ac.begin();
ac.setMode(kMitsubishiHeavyCool);
ac.setTemp(0);
EXPECT_EQ(kMitsubishiHeavyMinTemp, ac.getTemp());
ac.setTemp(255);
EXPECT_EQ(kMitsubishiHeavyMaxTemp, ac.getTemp());
ac.setTemp(kMitsubishiHeavyMinTemp);
EXPECT_EQ(kMitsubishiHeavyMinTemp, ac.getTemp());
ac.setTemp(kMitsubishiHeavyMaxTemp);
EXPECT_EQ(kMitsubishiHeavyMaxTemp, ac.getTemp());
ac.setTemp(kMitsubishiHeavyMinTemp - 1);
EXPECT_EQ(kMitsubishiHeavyMinTemp, ac.getTemp());
ac.setTemp(kMitsubishiHeavyMaxTemp + 1);
EXPECT_EQ(kMitsubishiHeavyMaxTemp, ac.getTemp());
ac.setTemp(19);
EXPECT_EQ(19, 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(TestMitsubishiHeavy152AcClass, OperatingMode) {
IRMitsubishiHeavy152Ac ac(0);
ac.begin();
ac.setMode(kMitsubishiHeavyAuto);
EXPECT_EQ(kMitsubishiHeavyAuto, ac.getMode());
ac.setMode(kMitsubishiHeavyCool);
EXPECT_EQ(kMitsubishiHeavyCool, ac.getMode());
ac.setMode(kMitsubishiHeavyHeat);
EXPECT_EQ(kMitsubishiHeavyHeat, ac.getMode());
ac.setMode(kMitsubishiHeavyDry);
EXPECT_EQ(kMitsubishiHeavyDry, ac.getMode());
ac.setMode(kMitsubishiHeavyFan);
EXPECT_EQ(kMitsubishiHeavyFan, ac.getMode());
ac.setMode(kMitsubishiHeavyHeat + 1);
EXPECT_EQ(kMitsubishiHeavyAuto, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kMitsubishiHeavyAuto, ac.getMode());
}
TEST(TestMitsubishiHeavy152AcClass, Filter) {
IRMitsubishiHeavy152Ac ac(0);
ac.begin();
ac.setFilter(true);
EXPECT_TRUE(ac.getFilter());
ac.setFilter(false);
EXPECT_FALSE(ac.getFilter());
ac.setFilter(true);
EXPECT_TRUE(ac.getFilter());
}
TEST(TestMitsubishiHeavy152AcClass, Turbo) {
IRMitsubishiHeavy152Ac ac(0);
ac.begin();
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
ac.setTurbo(false);
EXPECT_FALSE(ac.getTurbo());
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
}
TEST(TestMitsubishiHeavy152AcClass, Econo) {
IRMitsubishiHeavy152Ac 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());
}
TEST(TestMitsubishiHeavy152AcClass, 3D) {
IRMitsubishiHeavy152Ac ac(0);
ac.begin();
ac.set3D(true);
EXPECT_TRUE(ac.get3D());
ac.set3D(false);
EXPECT_FALSE(ac.get3D());
ac.set3D(true);
EXPECT_TRUE(ac.get3D());
}
TEST(TestMitsubishiHeavy152AcClass, Night) {
IRMitsubishiHeavy152Ac ac(0);
ac.begin();
ac.setNight(true);
EXPECT_TRUE(ac.getNight());
ac.setNight(false);
EXPECT_FALSE(ac.getNight());
ac.setNight(true);
EXPECT_TRUE(ac.getNight());
}
TEST(TestMitsubishiHeavy152AcClass, Clean) {
IRMitsubishiHeavy152Ac ac(0);
ac.begin();
ac.setClean(true);
EXPECT_TRUE(ac.getClean());
ac.setClean(false);
EXPECT_FALSE(ac.getClean());
ac.setClean(true);
EXPECT_TRUE(ac.getClean());
}
TEST(TestMitsubishiHeavy152AcClass, FanSpeed) {
IRMitsubishiHeavy152Ac ac(0);
ac.begin();
ac.setFan(kMitsubishiHeavy152FanLow);
EXPECT_EQ(kMitsubishiHeavy152FanLow, ac.getFan());
ac.setFan(kMitsubishiHeavy152FanAuto);
EXPECT_EQ(kMitsubishiHeavy152FanAuto, ac.getFan());
ac.setFan(255);
EXPECT_EQ(kMitsubishiHeavy152FanAuto, ac.getFan());
ac.setFan(kMitsubishiHeavy152FanMax);
EXPECT_EQ(kMitsubishiHeavy152FanMax, ac.getFan());
ac.setFan(kMitsubishiHeavy152FanMax + 1);
EXPECT_EQ(kMitsubishiHeavy152FanAuto, ac.getFan());
ac.setFan(kMitsubishiHeavy152FanMax - 1);
EXPECT_EQ(kMitsubishiHeavy152FanMax - 1, ac.getFan());
ac.setFan(kMitsubishiHeavy152FanLow + 1);
EXPECT_EQ(kMitsubishiHeavy152FanLow + 1, ac.getFan());
ac.setFan(kMitsubishiHeavy152FanEcono);
EXPECT_EQ(kMitsubishiHeavy152FanEcono, ac.getFan());
ac.setFan(kMitsubishiHeavy152FanTurbo);
EXPECT_EQ(kMitsubishiHeavy152FanTurbo, ac.getFan());
}
TEST(TestMitsubishiHeavy152AcClass, VerticalSwing) {
IRMitsubishiHeavy152Ac ac(0);
ac.begin();
ac.setSwingVertical(kMitsubishiHeavy152SwingVAuto);
EXPECT_EQ(kMitsubishiHeavy152SwingVAuto, ac.getSwingVertical());
ac.setSwingVertical(kMitsubishiHeavy152SwingVHighest);
EXPECT_EQ(kMitsubishiHeavy152SwingVHighest, ac.getSwingVertical());
ac.setSwingVertical(kMitsubishiHeavy152SwingVHighest + 1);
EXPECT_EQ(kMitsubishiHeavy152SwingVHighest + 1, ac.getSwingVertical());
ac.setSwingVertical(kMitsubishiHeavy152SwingVOff);
EXPECT_EQ(kMitsubishiHeavy152SwingVOff, ac.getSwingVertical());
ac.setSwingVertical(kMitsubishiHeavy152SwingVOff + 1);
EXPECT_EQ(kMitsubishiHeavy152SwingVOff, ac.getSwingVertical());
// Out of bounds.
ac.setSwingVertical(255);
EXPECT_EQ(kMitsubishiHeavy152SwingVOff, ac.getSwingVertical());
}
TEST(TestMitsubishiHeavy152AcClass, HorizontalSwing) {
IRMitsubishiHeavy152Ac ac(0);
ac.begin();
ac.setSwingHorizontal(kMitsubishiHeavy152SwingHAuto);
EXPECT_EQ(kMitsubishiHeavy152SwingHAuto, ac.getSwingHorizontal());
ac.setSwingHorizontal(kMitsubishiHeavy152SwingHLeftMax);
EXPECT_EQ(kMitsubishiHeavy152SwingHLeftMax, ac.getSwingHorizontal());
ac.setSwingHorizontal(kMitsubishiHeavy152SwingHLeftMax + 1);
EXPECT_EQ(kMitsubishiHeavy152SwingHLeftMax + 1, ac.getSwingHorizontal());
ac.setSwingHorizontal(kMitsubishiHeavy152SwingHRightMax);
EXPECT_EQ(kMitsubishiHeavy152SwingHRightMax, ac.getSwingHorizontal());
ac.setSwingHorizontal(kMitsubishiHeavy152SwingHRightMax - 1);
EXPECT_EQ(kMitsubishiHeavy152SwingHRightMax - 1, ac.getSwingHorizontal());
ac.setSwingHorizontal(kMitsubishiHeavy152SwingHOff);
EXPECT_EQ(kMitsubishiHeavy152SwingHOff, ac.getSwingHorizontal());
ac.setSwingHorizontal(kMitsubishiHeavy152SwingHOff + 1);
EXPECT_EQ(kMitsubishiHeavy152SwingHOff, ac.getSwingHorizontal());
// Out of bounds.
ac.setSwingHorizontal(255);
EXPECT_EQ(kMitsubishiHeavy152SwingHOff, ac.getSwingHorizontal());
}
TEST(TestMitsubishiHeavy152AcClass, Checksums) {
IRMitsubishiHeavy152Ac ac(0);
ac.begin();
EXPECT_TRUE(ac.validChecksum(ac.getRaw()));
uint8_t expected[kMitsubishiHeavy152StateLength] = {
0xAD, 0x51, 0x3C, 0xE5, 0x1A, 0x0C, 0xF3, 0x07,
0xF8, 0x04, 0xFB, 0x00, 0xFF, 0x00, 0xFF, 0x00,
0xFF, 0x80, 0x7F};
EXPECT_TRUE(IRMitsubishiHeavy152Ac::validChecksum(expected));
// Screw up the "checksum" to test it fails.
expected[kMitsubishiHeavy152StateLength - 1] = 0x55;
EXPECT_FALSE(IRMitsubishiHeavy152Ac::validChecksum(expected));
// getting the after getRaw() should repair it.
ac.setRaw(expected);
EXPECT_TRUE(ac.validChecksum(ac.getRaw()));
EXPECT_TRUE(IRMitsubishiHeavy152Ac::validChecksum(ac.getRaw()));
}
TEST(TestMitsubishiHeavy152AcClass, HumanReadable) {
IRMitsubishiHeavy152Ac ac(0);
EXPECT_EQ(
"Power: Off, Mode: 0 (Auto), Temp: 17C, Fan: 0 (Auto), "
"Swing(V): 0 (Auto), Swing(H): 0 (Auto), Silent: Off, Turbo: Off, "
"Econo: Off, Night: Off, Filter: Off, 3D: Off, Clean: Off",
ac.toString());
ac.on();
ac.setMode(kMitsubishiHeavyCool);
ac.setTemp(kMitsubishiHeavyMinTemp);
ac.setFan(kMitsubishiHeavy152FanMax);
ac.setFilter(true);
ac.setNight(true);
ac.setTurbo(false);
ac.setSilent(true);
ac.setEcono(false);
ac.set3D(true);
ac.setSwingVertical(kMitsubishiHeavy152SwingVAuto);
ac.setSwingHorizontal(kMitsubishiHeavy152SwingHAuto);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 17C, Fan: 4 (Max), "
"Swing(V): 0 (Auto), Swing(H): 0 (Auto), Silent: On, Turbo: Off, "
"Econo: Off, Night: On, Filter: On, 3D: On, Clean: Off",
ac.toString());
ac.setMode(kMitsubishiHeavyHeat);
ac.setTemp(kMitsubishiHeavyMaxTemp);
ac.setFilter(true);
ac.setNight(false);
ac.setTurbo(true);
ac.setEcono(false);
ac.setSilent(false);
ac.set3D(false);
ac.setSwingVertical(kMitsubishiHeavy152SwingVLowest);
ac.setSwingHorizontal(kMitsubishiHeavy152SwingHLeftMax);
EXPECT_EQ(
"Power: On, Mode: 4 (Heat), Temp: 31C, Fan: 8 (Turbo), "
"Swing(V): 5 (Lowest), Swing(H): 1 (Max Left), Silent: Off, Turbo: On, "
"Econo: Off, Night: Off, Filter: On, 3D: Off, Clean: Off",
ac.toString());
ac.setClean(true);
ac.setEcono(true);
ac.setMode(kMitsubishiHeavyAuto);
ac.setSwingVertical(kMitsubishiHeavy152SwingVOff);
EXPECT_EQ(
"Power: On, Mode: 0 (Auto), Temp: 31C, Fan: 6 (Econo), "
"Swing(V): 6 (Off), Swing(H): 1 (Max Left), Silent: Off, "
"Turbo: Off, Econo: On, Night: Off, Filter: On, 3D: Off, Clean: On",
ac.toString());
ac.setClean(false);
ac.setTemp(25);
ac.setEcono(false);
ac.setMode(kMitsubishiHeavyDry);
ac.setSwingHorizontal(kMitsubishiHeavy152SwingHLeftRight);
EXPECT_EQ(
"Power: On, Mode: 2 (Dry), Temp: 25C, Fan: 0 (Auto), "
"Swing(V): 6 (Off), Swing(H): 7 (Left Right), Silent: Off, "
"Turbo: Off, Econo: Off, Night: Off, Filter: Off, 3D: Off, Clean: Off",
ac.toString());
}
TEST(TestMitsubishiHeavy152AcClass, ReconstructKnownExample) {
IRMitsubishiHeavy152Ac ac(0);
EXPECT_EQ(
"Power: Off, Mode: 0 (Auto), Temp: 17C, Fan: 0 (Auto), "
"Swing(V): 0 (Auto), Swing(H): 0 (Auto), Silent: Off, Turbo: Off, "
"Econo: Off, Night: Off, Filter: Off, 3D: Off, Clean: Off",
ac.toString());
ac.on();
ac.setMode(kMitsubishiHeavyHeat);
ac.setTemp(24);
ac.setFan(kMitsubishiHeavy152FanMax);
ac.setFilter(true);
ac.setNight(false);
ac.setTurbo(false);
ac.setSilent(false);
ac.setEcono(false);
ac.set3D(false);
ac.setClean(false);
ac.setSwingVertical(kMitsubishiHeavy152SwingVAuto);
ac.setSwingHorizontal(kMitsubishiHeavy152SwingHAuto);
EXPECT_EQ(
"Power: On, Mode: 4 (Heat), Temp: 24C, Fan: 4 (Max), "
"Swing(V): 0 (Auto), Swing(H): 0 (Auto), Silent: Off, Turbo: Off, "
"Econo: Off, Night: Off, Filter: Off, 3D: Off, Clean: Off",
ac.toString());
uint8_t expected[kMitsubishiHeavy152StateLength] = {
0xAD, 0x51, 0x3C, 0xE5, 0x1A, 0x0C, 0xF3, 0x07,
0xF8, 0x04, 0xFB, 0x00, 0xFF, 0x00, 0xFF, 0x00,
0xFF, 0x80, 0x7F};
EXPECT_STATE_EQ(expected, ac.getRaw(), kMitsubishiHeavy152Bits);
}
// Tests for IRMitsubishiHeavy88Ac class.
TEST(TestMitsubishiHeavy88AcClass, Power) {
IRMitsubishiHeavy88Ac 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(TestMitsubishiHeavy88AcClass, Temperature) {
IRMitsubishiHeavy88Ac ac(0);
ac.begin();
ac.setMode(kMitsubishiHeavyCool);
ac.setTemp(0);
EXPECT_EQ(kMitsubishiHeavyMinTemp, ac.getTemp());
ac.setTemp(255);
EXPECT_EQ(kMitsubishiHeavyMaxTemp, ac.getTemp());
ac.setTemp(kMitsubishiHeavyMinTemp);
EXPECT_EQ(kMitsubishiHeavyMinTemp, ac.getTemp());
ac.setTemp(kMitsubishiHeavyMaxTemp);
EXPECT_EQ(kMitsubishiHeavyMaxTemp, ac.getTemp());
ac.setTemp(kMitsubishiHeavyMinTemp - 1);
EXPECT_EQ(kMitsubishiHeavyMinTemp, ac.getTemp());
ac.setTemp(kMitsubishiHeavyMaxTemp + 1);
EXPECT_EQ(kMitsubishiHeavyMaxTemp, ac.getTemp());
ac.setTemp(19);
EXPECT_EQ(19, 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(TestMitsubishiHeavy88AcClass, OperatingMode) {
IRMitsubishiHeavy88Ac ac(0);
ac.begin();
ac.setMode(kMitsubishiHeavyAuto);
EXPECT_EQ(kMitsubishiHeavyAuto, ac.getMode());
ac.setMode(kMitsubishiHeavyCool);
EXPECT_EQ(kMitsubishiHeavyCool, ac.getMode());
ac.setMode(kMitsubishiHeavyHeat);
EXPECT_EQ(kMitsubishiHeavyHeat, ac.getMode());
ac.setMode(kMitsubishiHeavyDry);
EXPECT_EQ(kMitsubishiHeavyDry, ac.getMode());
ac.setMode(kMitsubishiHeavyFan);
EXPECT_EQ(kMitsubishiHeavyFan, ac.getMode());
ac.setMode(kMitsubishiHeavyHeat + 1);
EXPECT_EQ(kMitsubishiHeavyAuto, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kMitsubishiHeavyAuto, ac.getMode());
}
TEST(TestMitsubishiHeavy88AcClass, Turbo) {
IRMitsubishiHeavy88Ac ac(0);
ac.begin();
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
ac.setTurbo(false);
EXPECT_FALSE(ac.getTurbo());
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
}
TEST(TestMitsubishiHeavy88AcClass, Econo) {
IRMitsubishiHeavy88Ac 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());
}
TEST(TestMitsubishiHeavy88AcClass, 3D) {
IRMitsubishiHeavy88Ac ac(0);
ac.begin();
ac.set3D(true);
EXPECT_TRUE(ac.get3D());
ac.set3D(false);
EXPECT_FALSE(ac.get3D());
ac.set3D(true);
EXPECT_TRUE(ac.get3D());
}
TEST(TestMitsubishiHeavy88AcClass, Clean) {
IRMitsubishiHeavy88Ac ac(0);
ac.begin();
ac.setClean(true);
EXPECT_TRUE(ac.getClean());
ac.setClean(false);
EXPECT_FALSE(ac.getClean());
ac.setClean(true);
EXPECT_TRUE(ac.getClean());
}
TEST(TestMitsubishiHeavy88AcClass, FanSpeed) {
IRMitsubishiHeavy88Ac ac(0);
ac.begin();
ac.setFan(kMitsubishiHeavy88FanLow);
EXPECT_EQ(kMitsubishiHeavy88FanLow, ac.getFan());
ac.setFan(kMitsubishiHeavy88FanAuto);
EXPECT_EQ(kMitsubishiHeavy88FanAuto, ac.getFan());
ac.setFan(255);
EXPECT_EQ(kMitsubishiHeavy88FanAuto, ac.getFan());
ac.setFan(kMitsubishiHeavy88FanHigh);
EXPECT_EQ(kMitsubishiHeavy88FanHigh, ac.getFan());
ac.setFan(kMitsubishiHeavy88FanHigh + 1);
EXPECT_EQ(kMitsubishiHeavy88FanAuto, ac.getFan());
ac.setFan(kMitsubishiHeavy88FanHigh - 1);
EXPECT_EQ(kMitsubishiHeavy88FanHigh - 1, ac.getFan());
ac.setFan(kMitsubishiHeavy88FanLow + 1);
EXPECT_EQ(kMitsubishiHeavy88FanLow + 1, ac.getFan());
ac.setFan(kMitsubishiHeavy88FanEcono);
EXPECT_EQ(kMitsubishiHeavy88FanEcono, ac.getFan());
ac.setFan(kMitsubishiHeavy88FanTurbo);
EXPECT_EQ(kMitsubishiHeavy88FanTurbo, ac.getFan());
}
TEST(TestMitsubishiHeavy88AcClass, VerticalSwing) {
IRMitsubishiHeavy88Ac ac(0);
ac.begin();
ac.setSwingVertical(kMitsubishiHeavy88SwingVAuto);
EXPECT_EQ(kMitsubishiHeavy88SwingVAuto, ac.getSwingVertical());
ac.setSwingVertical(kMitsubishiHeavy88SwingVHighest);
EXPECT_EQ(kMitsubishiHeavy88SwingVHighest, ac.getSwingVertical());
ac.setSwingVertical(kMitsubishiHeavy88SwingVOff);
EXPECT_EQ(kMitsubishiHeavy88SwingVOff, ac.getSwingVertical());
ac.setSwingVertical(kMitsubishiHeavy88SwingVLowest + 1);
EXPECT_EQ(kMitsubishiHeavy88SwingVOff, ac.getSwingVertical());
ac.setSwingVertical(kMitsubishiHeavy88SwingVHigh + 1);
EXPECT_EQ(kMitsubishiHeavy88SwingVOff, ac.getSwingVertical());
// Out of bounds.
ac.setSwingVertical(255);
EXPECT_EQ(kMitsubishiHeavy88SwingVOff, ac.getSwingVertical());
}
TEST(TestMitsubishiHeavy88AcClass, HorizontalSwing) {
IRMitsubishiHeavy88Ac ac(0);
ac.begin();
ac.setSwingHorizontal(kMitsubishiHeavy88SwingHAuto);
EXPECT_EQ(kMitsubishiHeavy88SwingHAuto, ac.getSwingHorizontal());
ac.setSwingHorizontal(kMitsubishiHeavy88SwingHLeftMax);
EXPECT_EQ(kMitsubishiHeavy88SwingHLeftMax, ac.getSwingHorizontal());
ac.setSwingHorizontal(kMitsubishiHeavy88SwingHRightMax + 1);
EXPECT_EQ(kMitsubishiHeavy88SwingHOff, ac.getSwingHorizontal());
ac.setSwingHorizontal(kMitsubishiHeavy88SwingHRightMax);
EXPECT_EQ(kMitsubishiHeavy88SwingHRightMax, ac.getSwingHorizontal());
ac.setSwingHorizontal(kMitsubishiHeavy88SwingHRightMax + 1);
EXPECT_EQ(kMitsubishiHeavy88SwingHOff, ac.getSwingHorizontal());
ac.setSwingHorizontal(kMitsubishiHeavy88SwingHOff);
EXPECT_EQ(kMitsubishiHeavy88SwingHOff, ac.getSwingHorizontal());
ac.setSwingHorizontal(kMitsubishiHeavy88SwingH3D + 1);
EXPECT_EQ(kMitsubishiHeavy88SwingHOff, ac.getSwingHorizontal());
// Out of bounds.
ac.setSwingHorizontal(255);
EXPECT_EQ(kMitsubishiHeavy88SwingHOff, ac.getSwingHorizontal());
}
TEST(TestMitsubishiHeavy88AcClass, Checksums) {
IRMitsubishiHeavy88Ac ac(0);
ac.begin();
EXPECT_TRUE(ac.validChecksum(ac.getRaw()));
uint8_t expected[kMitsubishiHeavy88StateLength] = {
0xAD, 0x51, 0x3C, 0xD9, 0x26, 0x48, 0xB7, 0x00, 0xFF, 0x8A, 0x75};
EXPECT_TRUE(IRMitsubishiHeavy88Ac::validChecksum(expected));
// Screw up the "checksum" to test it fails.
expected[kMitsubishiHeavy88StateLength - 1] = 0x55;
EXPECT_FALSE(IRMitsubishiHeavy88Ac::validChecksum(expected));
// getting the after getRaw() should repair it.
ac.setRaw(expected);
EXPECT_TRUE(ac.validChecksum(ac.getRaw()));
EXPECT_TRUE(IRMitsubishiHeavy88Ac::validChecksum(ac.getRaw()));
}
TEST(TestMitsubishiHeavy88AcClass, HumanReadable) {
IRMitsubishiHeavy88Ac ac(0);
EXPECT_EQ(
"Power: Off, Mode: 0 (Auto), Temp: 17C, Fan: 0 (Auto), "
"Swing(V): 0 (Off), Swing(H): 0 (Off), "
"Turbo: Off, Econo: Off, 3D: Off, Clean: Off",
ac.toString());
ac.on();
ac.setMode(kMitsubishiHeavyCool);
ac.setTemp(kMitsubishiHeavyMinTemp);
ac.setFan(kMitsubishiHeavy88FanHigh);
ac.setTurbo(false);
ac.setEcono(false);
ac.set3D(true);
ac.setSwingVertical(kMitsubishiHeavy88SwingVAuto);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 17C, Fan: 4 (High), "
"Swing(V): 4 (Auto), Swing(H): 14 (3D), "
"Turbo: Off, Econo: Off, 3D: On, Clean: Off",
ac.toString());
ac.setMode(kMitsubishiHeavyHeat);
ac.setTemp(kMitsubishiHeavyMaxTemp);
ac.setTurbo(true);
ac.setEcono(false);
ac.set3D(false);
ac.setSwingVertical(kMitsubishiHeavy88SwingVLowest);
ac.setSwingHorizontal(kMitsubishiHeavy88SwingHLeftMax);
EXPECT_EQ(
"Power: On, Mode: 4 (Heat), Temp: 31C, Fan: 6 (Turbo), "
"Swing(V): 7 (Lowest), Swing(H): 1 (Max Left), Turbo: On, Econo: Off, "
"3D: Off, Clean: Off",
ac.toString());
ac.setClean(true);
ac.setEcono(true);
ac.setMode(kMitsubishiHeavyAuto);
ac.setSwingVertical(kMitsubishiHeavy88SwingVOff);
EXPECT_EQ(
"Power: On, Mode: 0 (Auto), Temp: 31C, Fan: 7 (Econo), "
"Swing(V): 0 (Off), Swing(H): 1 (Max Left), Turbo: Off, Econo: On, "
"3D: Off, Clean: On",
ac.toString());
ac.setClean(false);
ac.setTemp(25);
ac.setEcono(false);
ac.setMode(kMitsubishiHeavyDry);
ac.setSwingHorizontal(kMitsubishiHeavy88SwingHLeftRight);
EXPECT_EQ(
"Power: On, Mode: 2 (Dry), Temp: 25C, Fan: 0 (Auto), "
"Swing(V): 0 (Off), Swing(H): 6 (Left Right), Turbo: Off, Econo: Off, "
"3D: Off, Clean: Off",
ac.toString());
}
// Tests for decodeMitsubishiHeavy().
// Decode a real MitsubishiHeavy 152Bit message.
TEST(TestDecodeMitsubishiHeavy, ZmsRealExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
IRMitsubishiHeavy152Ac ac(0);
irsend.begin();
uint8_t expected[kMitsubishiHeavy152StateLength] = {
0xAD, 0x51, 0x3C, 0xE5, 0x1A, 0x0C, 0xF3, 0x07,
0xF8, 0x04, 0xFB, 0x00, 0xFF, 0x00, 0xFF, 0x00,
0xFF, 0x80, 0x7F};
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/660#issuecomment-480571466
uint16_t rawData[307] = {
3136, 1638, 364, 428, 366, 1224, 362, 432, 364, 430, 364, 1226, 362, 432,
364, 1224, 366, 428, 366, 430, 366, 1224, 362, 1228, 362, 1228, 362, 432,
364, 1224, 364, 432, 364, 1226, 364, 1224, 366, 1226, 364, 428, 364, 430,
364, 430, 364, 432, 366, 1226, 364, 1224, 364, 430, 364, 1226, 364, 428,
364, 1224, 368, 1224, 364, 428, 364, 430, 366, 430, 364, 1158, 430, 432,
366, 1222, 366, 430, 366, 430, 364, 1226, 364, 1224, 364, 1224, 364, 1224,
366, 1224, 364, 430, 364, 430, 364, 1228, 362, 1226, 364, 1226, 366, 1222,
366, 430, 364, 430, 364, 1224, 366, 1224, 364, 430, 364, 430, 364, 432,
364, 430, 364, 428, 364, 430, 364, 430, 366, 1226, 362, 1154, 434, 1228,
364, 1226, 362, 1226, 364, 1226, 364, 1228, 362, 1226, 362, 432, 364, 430,
364, 428, 364, 430, 364, 430, 364, 1228, 362, 1228, 362, 432, 364, 1224,
368, 1224, 364, 1226, 362, 1226, 364, 1226, 366, 428, 366, 430, 364, 1224,
364, 430, 366, 430, 366, 430, 364, 430, 364, 430, 364, 1226, 364, 1226,
366, 1224, 366, 1224, 366, 1226, 364, 1224, 366, 1224, 366, 1224, 366,
428, 364, 430, 366, 428, 364, 430, 364, 430, 366, 428, 364, 430, 364, 432,
364, 1226, 364, 1226, 364, 1226, 364, 1228, 364, 1222, 370, 1222, 362,
1228, 362, 1226, 362, 430, 364, 430, 364, 430, 364, 432, 364, 428, 364,
432, 364, 428, 364, 430, 366, 1226, 362, 1224, 364, 1226, 364, 1226, 364,
1226, 362, 1226, 366, 1224, 366, 1224, 364, 430, 364, 432, 364, 428, 364,
432, 364, 428, 364, 430, 366, 430, 364, 430, 364, 1226, 362, 1226, 364,
1224, 366, 1226, 362, 1228, 364, 1224, 366, 1224, 364, 430, 364, 432, 364,
428, 364, 430, 364, 430, 364, 430, 366, 430, 364, 430, 338, 1252, 362
}; // UNKNOWN 5138D49D
irsend.reset();
irsend.sendRaw(rawData, 307, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(MITSUBISHI_HEAVY_152, irsend.capture.decode_type);
ASSERT_EQ(kMitsubishiHeavy152Bits, irsend.capture.bits);
EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Power: On, Mode: 4 (Heat), Temp: 24C, Fan: 4 (Max), "
"Swing(V): 0 (Auto), Swing(H): 0 (Auto), Silent: Off, Turbo: Off, "
"Econo: Off, Night: Off, Filter: Off, 3D: Off, Clean: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
// Decode a Synthetic MitsubishiHeavy 152Bit message.
TEST(TestDecodeMitsubishiHeavy, ZmsSyntheticExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
IRMitsubishiHeavy152Ac ac(0);
irsend.begin();
uint8_t expected[kMitsubishiHeavy152StateLength] = {
0xAD, 0x51, 0x3C, 0xE5, 0x1A, 0x0C, 0xF3, 0x07,
0xF8, 0x04, 0xFB, 0x00, 0xFF, 0x00, 0xFF, 0x00,
0xFF, 0x80, 0x7F};
irsend.reset();
irsend.sendMitsubishiHeavy152(expected);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(MITSUBISHI_HEAVY_152, irsend.capture.decode_type);
ASSERT_EQ(kMitsubishiHeavy152Bits, irsend.capture.bits);
EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Power: On, Mode: 4 (Heat), Temp: 24C, Fan: 4 (Max), "
"Swing(V): 0 (Auto), Swing(H): 0 (Auto), Silent: Off, Turbo: Off, "
"Econo: Off, Night: Off, Filter: Off, 3D: Off, Clean: Off",
ac.toString());
}
// Decode a real MitsubishiHeavy 152Bit message.
TEST(TestDecodeMitsubishiHeavy, ZmsRealExample2) {
IRsendTest irsend(0);
IRrecv irrecv(0);
IRMitsubishiHeavy152Ac ac(0);
irsend.begin();
uint8_t expected[kMitsubishiHeavy152StateLength] = {
0xAD, 0x51, 0x3C, 0xE5, 0x1A, 0x04, 0xFB, 0x07,
0xF8, 0x04, 0xFB, 0x00, 0xFF, 0x00, 0xFF, 0x00,
0xFF, 0x80, 0x7F};
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/660#issuecomment-480571466
uint16_t rawData[307] = {
3196, 1580, 398, 390, 404, 1190, 400, 390, 402, 390, 402, 1192, 402, 388,
402, 1192, 400, 390, 402, 392, 402, 1192, 400, 1188, 400, 1188, 400, 390,
404, 1192, 398, 392, 400, 1192, 402, 1188, 400, 1190, 402, 388, 402, 392,
404, 392, 402, 392, 404, 1188, 400, 1190, 398, 392, 404, 1188, 398, 392,
402, 1192, 398, 1190, 400, 390, 404, 390, 402, 392, 404, 1188, 398, 392,
404, 1190, 400, 392, 400, 394, 402, 1192, 398, 1190, 398, 1192, 398, 1190,
400, 1190, 398, 392, 402, 1192, 398, 1190, 398, 1190, 398, 1192, 396,
1192, 398, 396, 400, 394, 398, 1194, 396, 394, 400, 394, 398, 396, 398,
396, 400, 402, 390, 394, 402, 392, 398, 396, 398, 1194, 396, 1194, 398,
1192, 398, 1192, 396, 1194, 396, 1192, 396, 1196, 398, 1190, 398, 392,
402, 392, 402, 394, 398, 394, 400, 394, 400, 1192, 398, 1192, 400, 390,
402, 1190, 398, 1190, 398, 1192, 402, 1188, 398, 1190, 400, 390, 402, 392,
402, 1190, 400, 390, 404, 390, 402, 394, 402, 392, 402, 390, 404, 1190,
400, 1188, 400, 1190, 400, 1190, 402, 1188, 402, 1188, 400, 1188, 402,
1190, 400, 388, 402, 394, 404, 392, 404, 388, 404, 390, 404, 392, 402,
394, 402, 390, 402, 1190, 402, 1186, 402, 1190, 400, 1190, 398, 1190, 402,
1186, 402, 1190, 400, 1188, 400, 390, 404, 392, 404, 390, 402, 392, 402,
392, 400, 394, 402, 392, 402, 394, 400, 1192, 400, 1190, 400, 1188, 400,
1192, 400, 1186, 402, 1190, 400, 1190, 400, 1188, 402, 388, 402, 390, 404,
392, 402, 392, 402, 392, 402, 392, 404, 392, 402, 392, 404, 1190, 400,
1190, 398, 1190, 400, 1190, 400, 1190, 400, 1188, 400, 1188, 400, 392,
402, 392, 404, 390, 402, 392, 402, 392, 402, 392, 402, 390, 402, 392, 402,
1192, 398}; // UNKNOWN A650F2C1
irsend.reset();
irsend.sendRaw(rawData, 307, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(MITSUBISHI_HEAVY_152, irsend.capture.decode_type);
ASSERT_EQ(kMitsubishiHeavy152Bits, irsend.capture.bits);
EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Power: Off, Mode: 4 (Heat), Temp: 24C, Fan: 4 (Max), "
"Swing(V): 0 (Auto), Swing(H): 0 (Auto), Silent: Off, Turbo: Off, "
"Econo: Off, Night: Off, Filter: Off, 3D: Off, Clean: Off",
ac.toString());
}
// Decode a Synthetic MitsubishiHeavy 88 Bit message.
TEST(TestDecodeMitsubishiHeavy, ZjsSyntheticExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
IRMitsubishiHeavy88Ac ac(0);
irsend.begin();
uint8_t expected[kMitsubishiHeavy88StateLength] = {
0xAD, 0x51, 0x3C, 0xD9, 0x26, 0x48, 0xB7, 0x00, 0xFF, 0x8A, 0x75};
irsend.reset();
irsend.sendMitsubishiHeavy88(expected);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(MITSUBISHI_HEAVY_88, irsend.capture.decode_type);
ASSERT_EQ(kMitsubishiHeavy88Bits, irsend.capture.bits);
EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Power: On, Mode: 2 (Dry), Temp: 25C, Fan: 0 (Auto), "
"Swing(V): 0 (Off), Swing(H): 6 (Left Right), Turbo: Off, Econo: Off, "
"3D: Off, Clean: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestMitsubishiHeavy152AcClass, toCommon) {
IRMitsubishiHeavy152Ac ac(0);
ac.setPower(true);
ac.setMode(kMitsubishiHeavyCool);
ac.setTemp(20);
ac.setFan(kMitsubishiHeavy152FanLow);
ac.setSwingVertical(kMitsubishiHeavy152SwingVHighest);
ac.setSwingHorizontal(kMitsubishiHeavy152SwingHRightMax);
ac.setTurbo(false);
ac.setEcono(true);
ac.setClean(true);
ac.setFilter(true);
ac.setSilent(true);
ac.setNight(true);
// Now test it.
ASSERT_EQ(decode_type_t::MITSUBISHI_HEAVY_152, 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::kMin, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kHighest, ac.toCommon().swingv);
ASSERT_EQ(stdAc::swingh_t::kRightMax, ac.toCommon().swingh);
ASSERT_FALSE(ac.toCommon().turbo);
ASSERT_TRUE(ac.toCommon().econo);
ASSERT_TRUE(ac.toCommon().clean);
ASSERT_TRUE(ac.toCommon().quiet);
ASSERT_TRUE(ac.toCommon().filter);
ASSERT_EQ(0, ac.toCommon().sleep);
// Unsupported.
ASSERT_FALSE(ac.toCommon().light);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().clock);
}
TEST(TestMitsubishiHeavy88AcClass, toCommon) {
IRMitsubishiHeavy88Ac ac(0);
ac.setPower(true);
ac.setMode(kMitsubishiHeavyCool);
ac.setTemp(20);
ac.setFan(kMitsubishiHeavy88FanLow);
ac.setSwingVertical(kMitsubishiHeavy88SwingVHighest);
ac.setSwingHorizontal(kMitsubishiHeavy88SwingHRightMax);
ac.setTurbo(false);
ac.setEcono(true);
ac.setClean(true);
// Now test it.
ASSERT_EQ(decode_type_t::MITSUBISHI_HEAVY_88, 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::kMin, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kHighest, ac.toCommon().swingv);
ASSERT_EQ(stdAc::swingh_t::kRightMax, ac.toCommon().swingh);
ASSERT_FALSE(ac.toCommon().turbo);
ASSERT_TRUE(ac.toCommon().econo);
ASSERT_TRUE(ac.toCommon().clean);
// Unsupported.
ASSERT_FALSE(ac.toCommon().quiet);
ASSERT_FALSE(ac.toCommon().light);
ASSERT_FALSE(ac.toCommon().filter);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().sleep);
ASSERT_EQ(-1, ac.toCommon().clock);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,98 @@
// Copyright 2020 David Conran
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for decodeMultibrackets().
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1103
TEST(TestDecodeMultibrackets, RealExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
// The 1 + ok keypress:
uint16_t rawData_1[7] = {20100, 20472, 15092, 30704, 20102, 20472, 15086};
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData_1, 7, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::MULTIBRACKETS, irsend.capture.decode_type);
ASSERT_EQ(kMultibracketsBits, irsend.capture.bits);
EXPECT_EQ(0x87, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
// ok keypress.
const uint16_t rawData_2[11] = {
25124, 5108, 5038, 5110, 5034, 40940, 25132, 5108, 5036, 5110, 5036};
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData_2, 11, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::MULTIBRACKETS, irsend.capture.decode_type);
ASSERT_EQ(kMultibracketsBits, irsend.capture.bits);
EXPECT_EQ(0xD4, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
TEST(TestDecodeMultibrackets, SyntheticExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
irsend.sendMultibrackets(0x87);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::MULTIBRACKETS, irsend.capture.decode_type);
EXPECT_EQ(kMultibracketsBits, irsend.capture.bits);
EXPECT_EQ(0x87, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
// Real data is:
// uint16_t rawData[7] = {20100, 20472, 15092, 30704, 20102, 20472, 15086};
EXPECT_EQ(
"f38000d50m20000s20000m15000s30000m20000s20000m15000s30000",
irsend.outputStr());
}
TEST(TestUtils, Housekeeping) {
ASSERT_EQ("MULTIBRACKETS", typeToString(decode_type_t::MULTIBRACKETS));
ASSERT_EQ(decode_type_t::MULTIBRACKETS, strToDecodeType("MULTIBRACKETS"));
ASSERT_FALSE(hasACState(decode_type_t::MULTIBRACKETS));
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::MULTIBRACKETS));
ASSERT_EQ(kMultibracketsBits,
IRsend::defaultBits(decode_type_t::MULTIBRACKETS));
ASSERT_EQ(kMultibracketsDefaultRepeat,
IRsend::minRepeats(decode_type_t::MULTIBRACKETS));
}
TEST(TestDecodeMultibrackets, ShortNoRepeatExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
// The 1 + ok keypress: (edited to be bare minimum)
uint16_t rawData[3] = {20100, 20472, 15092};
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData, 3, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::MULTIBRACKETS, irsend.capture.decode_type);
ASSERT_EQ(kMultibracketsBits, irsend.capture.bits);
EXPECT_EQ(0x87, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}

View File

@@ -0,0 +1,338 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendNEC().
// Test sending typical data only.
TEST(TestSendNEC, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.sendNEC(0);
EXPECT_EQ(
"f38000d33"
"m8960s4480m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s58240",
irsend.outputStr());
irsend.sendNEC(0xAA00FF55);
EXPECT_EQ(
"f38000d33"
"m8960s4480m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s1680m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s1680m560s560m560s1680m560s560m560s1680"
"m560s560m560s1680m560s560m560s1680m560s40320",
irsend.outputStr());
}
// Test sending different bit lengths.
TEST(TestSendNEC, SendSmallData) {
IRsendTest irsend(4);
irsend.begin();
irsend.sendNEC(0xA, 4); // Send only 4 data bits.
EXPECT_EQ("f38000d33m8960s4480m560s1680m560s560m560s1680m560s560m560s87360",
irsend.outputStr());
irsend.sendNEC(0, 8); // Send only 8 data bits.
EXPECT_EQ(
"f38000d33"
"m8960s4480m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s85120",
irsend.outputStr());
irsend.sendNEC(0x1234567890ABCDEF, 64); // Send 64 data bits.
EXPECT_EQ(
"f38000d33"
"m8960s4480m560s560m560s560m560s560m560s1680m560s560m560s560"
"m560s1680m560s560m560s560m560s560m560s1680m560s1680m560s560"
"m560s1680m560s560m560s560m560s560m560s1680m560s560m560s1680"
"m560s560m560s1680m560s1680m560s560m560s560m560s1680m560s1680"
"m560s1680m560s1680m560s560m560s560m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s560m560s560m560s560m560s1680m560s560"
"m560s1680m560s560m560s1680m560s560m560s1680m560s1680m560s1680"
"m560s1680m560s560m560s560m560s1680m560s1680m560s560m560s1680"
"m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s1680"
"m560s1680m560s22400",
irsend.outputStr());
}
// Test sending with repeats.
TEST(TestSendNEC, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.sendNEC(0, 8, 0); // Send a command with 0 repeats.
EXPECT_EQ(
"f38000d33"
"m8960s4480m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s85120",
irsend.outputStr());
irsend.sendNEC(0xAA, 8, 1); // Send a command with 1 repeat.
EXPECT_EQ(
"f38000d33"
"m8960s4480m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s1680m560s560m560s80640"
"m8960s2240m560s96320",
irsend.outputStr());
irsend.sendNEC(0xAA, 8, 3); // Send a command with 3 repeats.
EXPECT_EQ(
"f38000d33"
"m8960s4480m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s1680m560s560m560s80640"
"m8960s2240m560s96320"
"m8960s2240m560s96320"
"m8960s2240m560s96320",
irsend.outputStr());
}
// Tests for encodeNEC().
TEST(TestEncodeNEC, NormalNECEncoding) {
IRsendTest irsend(4);
EXPECT_EQ(0x807F40BF, irsend.encodeNEC(1, 2));
EXPECT_EQ(0x9A656897, irsend.encodeNEC(0x59, 0x16));
}
TEST(TestEncodeNEC, ExtendedNECEncoding) {
IRsendTest irsend(4);
EXPECT_EQ(0x9A806897, irsend.encodeNEC(0x159, 0x16));
}
TEST(TestEncodeNEC, CommandTrimmedTo8Bits) {
IRsendTest irsend(4);
EXPECT_EQ(irsend.encodeNEC(0x1, 0x2), irsend.encodeNEC(0x1, 0xF02));
EXPECT_EQ(irsend.encodeNEC(0xFFF0, 0x2), irsend.encodeNEC(0xFFF0, 0xF02));
}
// Tests for decodeNEC().
// Decode normal NEC messages.
TEST(TestDecodeNEC, NormalNECDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Synthesised Normal NEC message.
irsend.reset();
irsend.sendNEC(irsend.encodeNEC(0x1, 0x2));
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0x807F40BF, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x2, irsend.capture.command);
// Real-life Extended NEC code from an actual capture/decode.
irsend.reset();
irsend.sendNEC(0xC1A28877);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0xC1A28877, irsend.capture.value);
EXPECT_EQ(0x4583, irsend.capture.address);
EXPECT_EQ(0x11, irsend.capture.command);
// Test strict decoding rejects a NEC-like message.
irsend.reset();
irsend.sendNEC(0x0);
irsend.makeDecodeResult();
EXPECT_FALSE(irrecv.decodeNEC(&irsend.capture));
// Synthesised Normal NEC message with a repeat.
irsend.reset();
irsend.sendNEC(irsend.encodeNEC(0x1, 0x2), 32, 1);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0x807F40BF, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x2, irsend.capture.command);
}
// NEC-like messages without strict mode.
TEST(TestDecodeNEC, NormalNECDecodeWithoutStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendNEC(0x0);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture, kStartOffset, 32, false));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
irsend.reset();
irsend.sendNEC(0x12345678);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture, kStartOffset, 32, false));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0x12345678, irsend.capture.value);
EXPECT_EQ(0x2C48, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
}
// Short NEC-like messages (without strict naturally)
TEST(TestDecodeNEC, ShortNECDecodeWithoutStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendNEC(0x0, 16);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture, kStartOffset, 16, false));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(16, irsend.capture.bits);
EXPECT_EQ(0, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
// Expecting less than what was sent is not valid.
irsend.reset();
irsend.sendNEC(0x0, 32);
irsend.makeDecodeResult();
EXPECT_FALSE(irrecv.decodeNEC(&irsend.capture, kStartOffset, 16, false));
// Send 16 bits of data, but fail because we are expecting 17.
irsend.reset();
irsend.sendNEC(0x0, 16);
irsend.makeDecodeResult();
EXPECT_FALSE(irrecv.decodeNEC(&irsend.capture, kStartOffset, 17, false));
}
// Longer NEC-like messages (without strict naturally)
TEST(TestDecodeNEC, LongerNECDecodeWithoutStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendNEC(0x1234567890ABCDEF, 64);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture, kStartOffset, 64, false));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0x1234567890ABCDEF, irsend.capture.value);
EXPECT_EQ(0xD509, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
// Send 63 bits of data, but fail because we are expecting 64.
irsend.reset();
irsend.sendNEC(0x0, 63);
irsend.makeDecodeResult();
EXPECT_FALSE(irrecv.decodeNEC(&irsend.capture, kStartOffset, 64, false));
}
// Incorrect decoding reported in Issue #243
// Incorrect handling of decodes when there is no gap recorded at
// the end of a command when using the interrupt code. sendRaw() best emulates
// this for unit testing purposes. sendGC() and sendXXX() will add the trailing
// gap. Users won't see this in normal use.
TEST(TestDecodeNEC, NoTrailingGap_Issue243) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
uint16_t rawData[67] = {
9000, 4500, 650, 550, 650, 1650, 600, 550, 650, 550, 600, 1650,
650, 550, 600, 1650, 650, 1650, 650, 1650, 600, 550, 650, 1650,
650, 1650, 650, 550, 600, 1650, 650, 1650, 650, 550, 650, 550,
650, 1650, 650, 550, 650, 550, 650, 550, 600, 550, 650, 550,
650, 550, 650, 1650, 600, 550, 650, 1650, 650, 1650, 650, 1650,
650, 1650, 650, 1650, 650, 1650, 600};
irsend.sendRaw(rawData, 67, 38);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0x4BB640BF, irsend.capture.value);
EXPECT_EQ(0x6DD2, irsend.capture.address);
EXPECT_EQ(0x2, irsend.capture.command);
irsend.reset();
irsend.sendRaw(rawData, 67, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0x4BB640BF, irsend.capture.value);
// Add a zero length space to the message to test how it handles that as
// an end of command gap.
irsend.addGap(0);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0x4BB640BF, irsend.capture.value);
}
// Inconsistent decoding for unknown in Issue #264
// Reported issues decoding an Apple Remote. Apple doesn't appear to respect
// or use the command structure/checks in the NEC protocol.
TEST(TestDecodeNEC, NonStrictNECDecode_Issue264) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Slightly modified example than reported due to poor timings that are too
// far out of spec.
uint16_t rawData[67] = {
9150, 4650, 550, 600, 550, 1800, 600, 1750, 600, 1800, 550, 600,
550, 1800, 550, 1750, 600, 1750, 600, 1750, 600, 1750, 600, 1700,
600, 600, 600, 600, 550, 600, 600, 600, 600, 1750, 600, 1750,
600, 600, 550, 1800, 600, 600, 600, 600, 600, 600, 500, 600,
600, 600, 600, 600, 600, 1750, 600, 600, 600, 550, 600, 600,
600, 600, 600, 600, 600, 550, 600};
irsend.sendRaw(rawData, 67, 38);
irsend.makeDecodeResult();
EXPECT_FALSE(irrecv.decodeNEC(&irsend.capture)); // Not strictly NEC
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture, kStartOffset, kNECBits, false));
EXPECT_EQ(0x77E1A040, irsend.capture.value);
// Do it all again, but with a normal decode.
irsend.reset();
irsend.sendRaw(rawData, 67, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(NEC_LIKE, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0x77E1A040, irsend.capture.value);
}
TEST(TestDecodeNEC, AutoReceiveCalibration) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Data from Issue #264, for a remote that is slightly off spec.
// Should be matched as a NEC-like message however without self-calibrating
// the timings of the short spaces is out.
uint16_t rawData[67] = {
9150, 4600, 650, 600, 650, 1650, 650, 1700, 650, 1750, 650, 600,
650, 1700, 650, 1750, 650, 1750, 650, 1700, 650, 1700, 650, 1700,
650, 600, 650, 600, 650, 600, 600, 600, 650, 1750, 650, 1750,
650, 600, 650, 1700, 600, 600, 700, 550, 650, 550, 650, 600,
650, 600, 650, 600, 650, 1750, 600, 600, 650, 600, 650, 550,
650, 600, 650, 600, 650, 600, 600};
irsend.sendRaw(rawData, 67, 38);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture, kStartOffset, kNECBits, false));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0x77E1A040, irsend.capture.value);
}

View File

@@ -0,0 +1,438 @@
// Copyright 2019 David Conran (crankyoldgit)
#include "ir_Neoclima.h"
#include <algorithm>
#include "IRac.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "gtest/gtest.h"
TEST(TestUtils, Housekeeping) {
ASSERT_EQ("NEOCLIMA", typeToString(decode_type_t::NEOCLIMA));
ASSERT_EQ(decode_type_t::NEOCLIMA, strToDecodeType("NEOCLIMA"));
ASSERT_TRUE(hasACState(decode_type_t::NEOCLIMA));
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::NEOCLIMA));
}
// Test sending typical data only.
TEST(TestSendNeoclima, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
uint8_t state[kNeoclimaStateLength] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x6A, 0x00, 0x2A, 0xA5, 0x39};
irsend.reset();
irsend.sendNeoclima(state);
EXPECT_EQ(
"f38000d50"
"m6112s7391"
"m537s571m537s571m537s571m537s571m537s571m537s571m537s571m537s571"
"m537s571m537s571m537s571m537s571m537s571m537s571m537s571m537s571"
"m537s571m537s571m537s571m537s571m537s571m537s571m537s571m537s571"
"m537s571m537s571m537s571m537s571m537s571m537s571m537s571m537s571"
"m537s571m537s571m537s571m537s571m537s571m537s571m537s571m537s571"
"m537s571m537s571m537s571m537s571m537s571m537s571m537s571m537s571"
"m537s571m537s571m537s571m537s571m537s571m537s571m537s571m537s571"
"m537s571m537s1651m537s571m537s1651m537s571m537s1651m537s1651m537s571"
"m537s571m537s571m537s571m537s571m537s571m537s571m537s571m537s571"
"m537s571m537s1651m537s571m537s1651m537s571m537s1651m537s571m537s571"
"m537s1651m537s571m537s1651m537s571m537s571m537s1651m537s571m537s1651"
"m537s1651m537s571m537s571m537s1651m537s1651m537s1651m537s571m537s571"
"m537s7391"
"m537s100000",
irsend.outputStr());
}
// https://github.com/crankyoldgit/IRremoteESP8266/issues/764#issuecomment-503755096
TEST(TestDecodeNeoclima, RealExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
uint16_t rawData[197] = {
6112, 7392, 540, 602, 516, 578, 522, 604, 540, 554, 540, 554, 540, 576,
518, 576, 516, 554, 540, 608, 542, 554, 540, 554, 540, 576, 518, 604, 516,
556, 540, 576, 546, 580, 542, 578, 542, 602, 518, 554, 542, 554, 568, 582,
540, 554, 540, 582, 540, 578, 518, 582, 542, 576, 544, 530, 566, 534, 562,
534, 562, 552, 542, 582, 540, 604, 518, 608, 542, 554, 540, 582, 540, 604,
518, 580, 540, 606, 544, 554, 542, 554, 542, 580, 542, 576, 520, 554, 540,
578, 518, 578, 518, 582, 544, 552, 570, 580, 544, 580, 542, 554, 542, 604,
520, 576, 520, 580, 540, 556, 540, 556, 542, 584, 566, 580, 542, 1622,
542, 554, 542, 1620, 544, 604, 520, 1642, 518, 1674, 548, 560, 564, 580,
544, 554, 544, 552, 544, 554, 542, 556, 542, 576, 522, 554, 542, 556, 542,
580, 542, 1670, 520, 578, 520, 1622, 542, 580, 518, 1646, 520, 558, 568,
552, 546, 1628, 566, 580, 544, 1668, 522, 576, 520, 578, 520, 1670, 522,
576, 522, 1670, 496, 1676, 570, 560, 566, 532, 564, 1648, 544, 1670, 522,
1650, 544, 552, 544, 576, 520, 7390, 544}; // UNKNOWN EE182D95
uint8_t expectedState[kNeoclimaStateLength] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x6A, 0x00, 0x2A, 0xA5, 0x39};
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData, 197, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::NEOCLIMA, irsend.capture.decode_type);
ASSERT_EQ(kNeoclimaBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
IRNeoclimaAc ac(0);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 26C, Fan: 3 (Low), "
"Swing(V): Off, Swing(H): On, Sleep: Off, Turbo: Off, Hold: Off, "
"Ion: Off, Eye: Off, Light: Off, Follow: Off, 8C Heat: Off, Fresh: Off, "
"Button: 0 (Power)",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
// Self decode.
TEST(TestDecodeNeoclima, SyntheticExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
uint8_t expectedState[kNeoclimaStateLength] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x6A, 0x00, 0x2A, 0xA5, 0x39};
irsend.begin();
irsend.reset();
irsend.sendNeoclima(expectedState);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::NEOCLIMA, irsend.capture.decode_type);
ASSERT_EQ(kNeoclimaBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
}
TEST(TestIRNeoclimaAcClass, Power) {
IRNeoclimaAc 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());
EXPECT_EQ(kNeoclimaButtonPower, ac.getButton());
}
TEST(TestIRNeoclimaAcClass, OperatingMode) {
IRNeoclimaAc ac(0);
ac.begin();
ac.setMode(kNeoclimaAuto);
EXPECT_EQ(kNeoclimaAuto, ac.getMode());
EXPECT_EQ(kNeoclimaButtonMode, ac.getButton());
ac.setMode(kNeoclimaCool);
EXPECT_EQ(kNeoclimaCool, ac.getMode());
ac.setMode(kNeoclimaHeat);
EXPECT_EQ(kNeoclimaHeat, ac.getMode());
ASSERT_NE(kNeoclimaFanHigh, kNeoclimaFanLow);
ac.setFan(kNeoclimaFanHigh);
ac.setMode(kNeoclimaDry); // Dry should lock the fan to speed LOW.
EXPECT_EQ(kNeoclimaDry, ac.getMode());
EXPECT_EQ(kNeoclimaFanLow, ac.getFan());
ac.setFan(kNeoclimaFanHigh);
EXPECT_EQ(kNeoclimaFanLow, ac.getFan());
ac.setMode(kNeoclimaFan);
EXPECT_EQ(kNeoclimaFan, ac.getMode());
ac.setMode(kNeoclimaHeat + 1);
EXPECT_EQ(kNeoclimaAuto, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kNeoclimaAuto, ac.getMode());
}
TEST(TestIRNeoclimaAcClass, SetAndGetTemp) {
IRNeoclimaAc ac(0);
ac.setTemp(25);
EXPECT_EQ(25, ac.getTemp());
ac.setTemp(kNeoclimaMinTemp);
EXPECT_EQ(kNeoclimaMinTemp, ac.getTemp());
EXPECT_EQ(kNeoclimaButtonTempDown, ac.getButton());
ac.setTemp(kNeoclimaMinTemp - 1);
EXPECT_EQ(kNeoclimaMinTemp, ac.getTemp());
ac.setTemp(kNeoclimaMaxTemp);
EXPECT_EQ(kNeoclimaMaxTemp, ac.getTemp());
EXPECT_EQ(kNeoclimaButtonTempUp, ac.getButton());
ac.setTemp(kNeoclimaMaxTemp + 1);
EXPECT_EQ(kNeoclimaMaxTemp, ac.getTemp());
}
TEST(TestIRNeoclimaAcClass, FanSpeed) {
IRNeoclimaAc ac(0);
ac.begin();
ac.setFan(0);
EXPECT_EQ(0, ac.getFan());
ac.setFan(255);
EXPECT_EQ(kNeoclimaFanAuto, ac.getFan());
ac.setFan(kNeoclimaFanHigh);
EXPECT_EQ(kNeoclimaFanHigh, ac.getFan());
ac.setFan(std::max(kNeoclimaFanHigh, kNeoclimaFanLow) + 1);
EXPECT_EQ(kNeoclimaFanAuto, ac.getFan());
ac.setFan(kNeoclimaFanHigh - 1);
EXPECT_EQ(kNeoclimaFanHigh - 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());
EXPECT_EQ(kNeoclimaButtonFanSpeed, ac.getButton());
// Data from:
// https://drive.google.com/file/d/1kjYk4zS9NQcMQhFkak-L4mp4UuaAIesW/view
uint8_t fan_low[12] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x6A, 0x00, 0x29, 0xA5, 0x3D};
uint8_t fan_medium[12] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x4A, 0x00, 0x29, 0xA5, 0x1D};
uint8_t fan_high[12] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x2A, 0x00, 0x29, 0xA5, 0xFD};
uint8_t fan_auto[12] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0A, 0x00, 0x29, 0xA5, 0xDD};
ac.setRaw(fan_low);
EXPECT_EQ(kNeoclimaFanLow, ac.getFan());
EXPECT_EQ(kNeoclimaButtonFanSpeed, ac.getButton());
ac.setRaw(fan_medium);
EXPECT_EQ(kNeoclimaFanMed, ac.getFan());
EXPECT_EQ(kNeoclimaButtonFanSpeed, ac.getButton());
ac.setRaw(fan_high);
EXPECT_EQ(kNeoclimaFanHigh, ac.getFan());
EXPECT_EQ(kNeoclimaButtonFanSpeed, ac.getButton());
ac.setRaw(fan_auto);
EXPECT_EQ(kNeoclimaFanAuto, ac.getFan());
EXPECT_EQ(kNeoclimaButtonFanSpeed, ac.getButton());
}
TEST(TestIRNeoclimaAcClass, Sleep) {
IRNeoclimaAc ac(0);
ac.begin();
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
ac.setSleep(false);
EXPECT_FALSE(ac.getSleep());
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
EXPECT_EQ(kNeoclimaButtonSleep, ac.getButton());
}
TEST(TestIRNeoclimaAcClass, Turbo) {
IRNeoclimaAc ac(0);
ac.begin();
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
ac.setTurbo(false);
EXPECT_FALSE(ac.getTurbo());
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
EXPECT_EQ(kNeoclimaButtonTurbo, ac.getButton());
// Data from:
// https://drive.google.com/file/d/1tA09Gu_ZqDcHucscnqzv0V3cIUWOE0d1/view
uint8_t turbo_on[12] = {
0x00, 0x00, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x6A, 0x00, 0x88, 0xA5, 0xA9};
uint8_t turbo_off[12] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x6A, 0x00, 0x88, 0xA5, 0xA1};
ac.setRaw(turbo_on);
EXPECT_TRUE(ac.getTurbo());
EXPECT_EQ(kNeoclimaButtonTurbo, ac.getButton());
ac.setRaw(turbo_off);
EXPECT_EQ(kNeoclimaButtonTurbo, ac.getButton());
EXPECT_FALSE(ac.getTurbo());
}
TEST(TestIRNeoclimaAcClass, Fresh) {
IRNeoclimaAc ac(0);
ac.begin();
ac.setFresh(true);
EXPECT_TRUE(ac.getFresh());
ac.setFresh(false);
EXPECT_FALSE(ac.getFresh());
ac.setFresh(true);
EXPECT_TRUE(ac.getFresh());
EXPECT_EQ(kNeoclimaButtonFresh, ac.getButton());
// Data from:
// https://drive.google.com/file/d/1kjYk4zS9NQcMQhFkak-L4mp4UuaAIesW/view
uint8_t on[12] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x6A, 0x00, 0x29, 0xA5, 0xCD};
uint8_t off[12] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x6A, 0x00, 0x29, 0xA5, 0x4D};
ac.setRaw(on);
EXPECT_TRUE(ac.getFresh());
EXPECT_EQ(kNeoclimaButtonFresh, ac.getButton());
ac.setRaw(off);
EXPECT_EQ(kNeoclimaButtonFresh, ac.getButton());
EXPECT_FALSE(ac.getFresh());
}
TEST(TestIRNeoclimaAcClass, Hold) {
IRNeoclimaAc ac(0);
ac.begin();
ac.setHold(true);
EXPECT_TRUE(ac.getHold());
ac.setHold(false);
EXPECT_FALSE(ac.getHold());
ac.setHold(true);
EXPECT_TRUE(ac.getHold());
EXPECT_EQ(kNeoclimaButtonHold, ac.getButton());
}
TEST(TestIRNeoclimaAcClass, 8CHeat) {
IRNeoclimaAc ac(0);
ac.begin();
ac.set8CHeat(true);
EXPECT_TRUE(ac.get8CHeat());
ac.set8CHeat(false);
EXPECT_FALSE(ac.get8CHeat());
ac.set8CHeat(true);
EXPECT_TRUE(ac.get8CHeat());
EXPECT_EQ(kNeoclimaButton8CHeat, ac.getButton());
}
TEST(TestIRNeoclimaAcClass, Light) {
IRNeoclimaAc ac(0);
ac.begin();
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
ac.setLight(false);
EXPECT_FALSE(ac.getLight());
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
EXPECT_EQ(kNeoclimaButtonLight, ac.getButton());
}
TEST(TestIRNeoclimaAcClass, Ion) {
IRNeoclimaAc ac(0);
ac.begin();
ac.setIon(true);
EXPECT_TRUE(ac.getIon());
ac.setIon(false);
EXPECT_FALSE(ac.getIon());
ac.setIon(true);
EXPECT_TRUE(ac.getIon());
EXPECT_EQ(kNeoclimaButtonIon, ac.getButton());
}
TEST(TestIRNeoclimaAcClass, Eye) {
IRNeoclimaAc ac(0);
ac.begin();
ac.setEye(true);
EXPECT_TRUE(ac.getEye());
ac.setEye(false);
EXPECT_FALSE(ac.getEye());
ac.setEye(true);
EXPECT_TRUE(ac.getEye());
EXPECT_EQ(kNeoclimaButtonEye, ac.getButton());
}
TEST(TestIRNeoclimaAcClass, Follow) {
IRNeoclimaAc ac(0);
ac.begin();
/* DISABLED: See TODO in ir_Neoclima.cpp
ac.setFollow(true);
EXPECT_TRUE(ac.getFollow());
ac.setFollow(false);
EXPECT_FALSE(ac.getFollow());
ac.setFollow(true);
EXPECT_TRUE(ac.getFollow());
EXPECT_EQ(kNeoclimaButtonFollow, ac.getButton());
*/
uint8_t on_5F[12] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x0A, 0x5F, 0x89, 0xA5, 0xAA};
uint8_t on_5D[12] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x6A, 0x5D, 0x29, 0xA5, 0xA8};
uint8_t off[12] = {
0x00, 0x04, 0x00, 0x40, 0x00, 0x13, 0x00, 0x6B, 0x00, 0x29, 0xA5, 0x90};
ac.setRaw(on_5F);
EXPECT_TRUE(ac.getFollow());
ac.setRaw(off);
EXPECT_FALSE(ac.getFollow());
ac.setRaw(on_5D);
EXPECT_TRUE(ac.getFollow());
}
TEST(TestIRNeoclimaAcClass, ChecksumCalculation) {
uint8_t examplestate[kNeoclimaStateLength] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x6A, 0x00, 0x2A, 0xA5, 0x39};
const uint8_t originalstate[kNeoclimaStateLength] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x6A, 0x00, 0x2A, 0xA5, 0x39};
EXPECT_TRUE(IRNeoclimaAc::validChecksum(examplestate));
EXPECT_EQ(0x39, IRNeoclimaAc::calcChecksum(examplestate));
examplestate[11] = 0x12; // Set an incorrect checksum.
EXPECT_FALSE(IRNeoclimaAc::validChecksum(examplestate));
EXPECT_EQ(0x39, IRNeoclimaAc::calcChecksum(examplestate));
IRNeoclimaAc ac(0);
ac.setRaw(examplestate);
// Extracting the state from the object should have a correct checksum.
EXPECT_TRUE(IRNeoclimaAc::validChecksum(ac.getRaw()));
EXPECT_STATE_EQ(originalstate, ac.getRaw(), kNeoclimaBits);
examplestate[11] = 0x39; // Restore old checksum value.
// Change the state to force a different checksum.
examplestate[8] = 0x01;
EXPECT_FALSE(IRNeoclimaAc::validChecksum(examplestate));
EXPECT_EQ(0x3A, IRNeoclimaAc::calcChecksum(examplestate));
}
TEST(TestIRNeoclimaAcClass, toCommon) {
IRNeoclimaAc ac(0);
ac.setPower(true);
ac.setMode(kNeoclimaCool);
ac.setTemp(20);
ac.setFan(kNeoclimaFanHigh);
ac.setSwingV(true);
ac.setSwingH(true);
ac.setTurbo(false);
ac.setIon(true);
ac.setLight(true);
ac.setSleep(true);
// Now test it.
ASSERT_EQ(decode_type_t::NEOCLIMA, 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_FALSE(ac.toCommon().turbo);
ASSERT_TRUE(ac.toCommon().filter);
ASSERT_TRUE(ac.toCommon().light);
ASSERT_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kAuto, ac.toCommon().swingv);
ASSERT_EQ(stdAc::swingh_t::kAuto, ac.toCommon().swingh);
ASSERT_EQ(0, ac.toCommon().sleep);
// Unsupported.
ASSERT_FALSE(ac.toCommon().quiet);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().clean);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().clock);
}

View File

@@ -0,0 +1,222 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendNikai().
// Test sending typical data only.
TEST(TestSendNikai, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendNikai(0xD5F2A); // Nikai TV Power Off.
EXPECT_EQ(
"f38000d33"
"m4000s4000"
"m500s2000m500s2000m500s2000m500s2000m500s1000m500s1000m500s2000"
"m500s1000m500s2000m500s1000m500s2000m500s1000m500s1000m500s1000"
"m500s1000m500s1000m500s2000m500s2000m500s1000m500s2000m500s1000"
"m500s2000m500s1000m500s2000m500s8500",
irsend.outputStr());
irsend.reset();
}
// Test sending with different repeats.
TEST(TestSendNikai, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendNikai(0xD5F2A, kNikaiBits, 1); // 1 repeat.
EXPECT_EQ(
"f38000d33"
"m4000s4000"
"m500s2000m500s2000m500s2000m500s2000m500s1000m500s1000m500s2000"
"m500s1000m500s2000m500s1000m500s2000m500s1000m500s1000m500s1000"
"m500s1000m500s1000m500s2000m500s2000m500s1000m500s2000m500s1000"
"m500s2000m500s1000m500s2000m500s8500"
"m4000s4000"
"m500s2000m500s2000m500s2000m500s2000m500s1000m500s1000m500s2000"
"m500s1000m500s2000m500s1000m500s2000m500s1000m500s1000m500s1000"
"m500s1000m500s1000m500s2000m500s2000m500s1000m500s2000m500s1000"
"m500s2000m500s1000m500s2000m500s8500",
irsend.outputStr());
irsend.sendNikai(0xD5F2A, kNikaiBits, 2); // 2 repeat.
EXPECT_EQ(
"f38000d33"
"m4000s4000"
"m500s2000m500s2000m500s2000m500s2000m500s1000m500s1000m500s2000"
"m500s1000m500s2000m500s1000m500s2000m500s1000m500s1000m500s1000"
"m500s1000m500s1000m500s2000m500s2000m500s1000m500s2000m500s1000"
"m500s2000m500s1000m500s2000m500s8500"
"m4000s4000"
"m500s2000m500s2000m500s2000m500s2000m500s1000m500s1000m500s2000"
"m500s1000m500s2000m500s1000m500s2000m500s1000m500s1000m500s1000"
"m500s1000m500s1000m500s2000m500s2000m500s1000m500s2000m500s1000"
"m500s2000m500s1000m500s2000m500s8500"
"m4000s4000"
"m500s2000m500s2000m500s2000m500s2000m500s1000m500s1000m500s2000"
"m500s1000m500s2000m500s1000m500s2000m500s1000m500s1000m500s1000"
"m500s1000m500s1000m500s2000m500s2000m500s1000m500s2000m500s1000"
"m500s2000m500s1000m500s2000m500s8500",
irsend.outputStr());
}
// Tests for decodeNikai().
// Decode normal Nikai messages.
TEST(TestDecodeNikai, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Nikai 24-bit message.
irsend.reset();
irsend.sendNikai(0x123456);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeNikai(&irsend.capture, kStartOffset, kNikaiBits,
true));
EXPECT_EQ(NIKAI, irsend.capture.decode_type);
EXPECT_EQ(kNikaiBits, irsend.capture.bits);
EXPECT_EQ(0x123456, irsend.capture.value);
irsend.reset();
irsend.sendNikai(0x101);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeNikai(&irsend.capture, kStartOffset, kNikaiBits,
true));
EXPECT_EQ(NIKAI, irsend.capture.decode_type);
EXPECT_EQ(kNikaiBits, irsend.capture.bits);
EXPECT_EQ(0x101, irsend.capture.value);
}
// Decode normal repeated Nikai messages.
TEST(TestDecodeNikai, NormalDecodeWithRepeatAndStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Nikai 24-bit message.
irsend.reset();
irsend.sendNikai(0xD5F2A, kNikaiBits, 2);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeNikai(&irsend.capture, kStartOffset, kNikaiBits,
true));
EXPECT_EQ(NIKAI, irsend.capture.decode_type);
EXPECT_EQ(kNikaiBits, irsend.capture.bits);
EXPECT_EQ(0xD5F2A, irsend.capture.value);
}
TEST(TestDecodeNikai, NormalDecodeWithNonStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Illegal under length (16-bit) message
irsend.reset();
irsend.sendNikai(0x0, 16);
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeNikai(&irsend.capture, kStartOffset, kNikaiBits,
true));
// And it should fail when we expect more bits.
ASSERT_FALSE(irrecv.decodeNikai(&irsend.capture, kStartOffset, kNikaiBits,
false));
// Should pass if strict off if we ask for correct nr. of bits sent.
ASSERT_TRUE(irrecv.decodeNikai(&irsend.capture, kStartOffset, 16, false));
EXPECT_EQ(NIKAI, irsend.capture.decode_type);
EXPECT_EQ(16, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
// Should fail as we are expecting less bits than there are.
ASSERT_FALSE(irrecv.decodeNikai(&irsend.capture, kStartOffset, 12, false));
}
// Decode (non-standard) 64-bit messages.
// Decode unsupported Nikai messages.
TEST(TestDecodeNikai, Decode64BitMessages) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Illegal size Nikai 64-bit message.
irsend.sendNikai(0xFFFFFFFFFFFFFFFF, 64);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeNikai(&irsend.capture, kStartOffset, kNikaiBits,
true));
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeNikai(&irsend.capture, kStartOffset, 64, false));
EXPECT_EQ(NIKAI, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, irsend.capture.value);
}
// Decode real example via Issue #309
TEST(TestDecodeNikai, DecodeExamples) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Nikai TV Power Off from Issue #309
uint16_t rawdata_off[100] = {
4060, 3918, 508, 2004, 508, 2002, 510, 2002, 508, 2004, 506,
1050, 508, 1048, 510, 2004, 508, 1048, 508, 2002, 510, 1050,
508, 2004, 510, 1048, 508, 1050, 508, 1048, 508, 1050, 508,
1050, 508, 2004, 508, 2002, 510, 1048, 508, 2004, 508, 1050,
506, 2004, 508, 1048, 510, 2002, 456, 8446, 3956, 3998, 508,
2004, 508, 2002, 508, 2004, 508, 1978, 532, 1050, 508, 1050,
508, 2002, 508, 1050, 508, 2004, 508, 1050, 508, 2002, 510,
1050, 508, 1050, 508, 1048, 508, 1050, 508, 1050, 508, 2002,
510, 2002, 508, 1050, 508, 2002, 510, 1050, 508, 2002, 508};
irsend.sendRaw(rawdata_off, 100, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(NIKAI, irsend.capture.decode_type);
EXPECT_EQ(kNikaiBits, irsend.capture.bits);
EXPECT_EQ(0xD5F2A, irsend.capture.value);
// Nikai TV Volume Up from Issue #309
uint16_t rawdata_volup[52] = {
3972, 4002, 504, 1982, 526, 2010, 502, 2010, 502, 2010, 500,
1056, 502, 1056, 502, 2010, 500, 1056, 502, 2010, 502, 2010,
500, 2010, 502, 2010, 502, 1056, 502, 1056, 502, 1056, 500,
1056, 502, 2010, 502, 2010, 500, 1056, 502, 2008, 502, 1054,
504, 1054, 504, 1054, 500, 1056, 450};
irsend.reset();
irsend.sendRaw(rawdata_volup, 52, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(NIKAI, irsend.capture.decode_type);
EXPECT_EQ(kNikaiBits, irsend.capture.bits);
EXPECT_EQ(0xD0F2F, irsend.capture.value);
}
// Fail to decode a non-Nikai example via GlobalCache
TEST(TestDecodeNikai, FailToDecodeNonNikaiExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
uint16_t gc_test[71] = {38000, 1, 1, 172, 172, 22, 64, 22, 64, 22, 64, 22,
21, 22, 21, 22, 21, 22, 11, 22, 21, 22, 128, 22,
64, 22, 64, 22, 21, 22, 21, 22, 21, 22, 21, 22,
21, 22, 64, 22, 21, 22, 21, 22, 64, 22, 64, 22,
21, 22, 21, 22, 64, 22, 21, 22, 64, 22, 64, 22,
21, 22, 21, 22, 64, 22, 64, 22, 21, 22, 1820};
irsend.sendGC(gc_test, 71);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeNikai(&irsend.capture));
ASSERT_FALSE(irrecv.decodeNikai(&irsend.capture, kStartOffset, kNikaiBits,
false));
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,155 @@
// Copyright 2018 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "IRutils.h"
#include "gtest/gtest.h"
// Tests for sendPioneer().
// Test sending typical data only.
TEST(TestSendPioneer, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
irsend.sendPioneer(0);
EXPECT_EQ(
"f40000d33"
"m8544s4272"
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
"m534s37380"
"m8544s4272"
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
"m534s37380",
irsend.outputStr());
irsend.sendPioneer(0x55FF00AAAA00FF55);
EXPECT_EQ(
"f40000d33"
"m8544s4272"
"m534s534m534s1602m534s534m534s1602m534s534m534s1602m534s534m534s1602"
"m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602"
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
"m534s1602m534s534m534s1602m534s534m534s1602m534s534m534s1602m534s534"
"m534s25098"
"m8544s4272"
"m534s1602m534s534m534s1602m534s534m534s1602m534s534m534s1602m534s534"
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
"m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602"
"m534s534m534s1602m534s534m534s1602m534s534m534s1602m534s534m534s1602"
"m534s25098",
irsend.outputStr());
}
// Tests for IRutils.
TEST(TestIRUtils, TypeToString) { EXPECT_EQ("PIONEER", typeToString(PIONEER)); }
// Tests for encodePioneer().
TEST(TestEncodePioneer, SimpleEncoding) {
IRsendTest irsend(0);
IRrecv irrecv(0);
// Spotify button (A556+AF20)
// via
// https://www.pioneerelectronics.com/StaticFiles/PUSA/Files/Home%20Custom%20Install/2015%20Pioneer%20&%20Elite%20AVR%20IR%20with%20Hex_1.xls
EXPECT_EQ(0xA55A6A95F50A04FB, irsend.encodePioneer(0xA556, 0xAF20));
// "Source" from
// https://github.com/crankyoldgit/IRremoteESP8266/pull/547#issuecomment-429616582
EXPECT_EQ(0x659A05FAF50AC53A, irsend.encodePioneer(0xA6A0, 0xAFA3));
}
// Tests for decodePioneer().
// Synthesised Normal Pioneer message.
TEST(TestDecodePioneer, SyntheticPioneerDecode) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
irsend.sendPioneer(0x659A05FAF50AC53A);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(PIONEER, irsend.capture.decode_type);
EXPECT_EQ(kPioneerBits, irsend.capture.bits);
EXPECT_EQ(0x659A05FAF50AC53A, irsend.capture.value);
EXPECT_EQ(0xA6A0, irsend.capture.address);
EXPECT_EQ(0xAFA3, irsend.capture.command);
}
// Real long Pioneer message.
TEST(TestDecodePioneer, RealExampleLongDecodeSourceButton) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
// "Source" button.
// https://github.com/crankyoldgit/IRremoteESP8266/pull/547#issuecomment-429616582
uint16_t rawData[135] = {
8552, 4184, 596, 472, 592, 1524, 594, 1524, 594, 472, 592, 472,
598, 1520, 596, 472, 594, 1524, 592, 1524, 592, 472, 592, 472,
596, 1520, 598, 1520, 596, 472, 592, 1524, 592, 472, 592, 476,
592, 472, 592, 472, 592, 476, 592, 472, 592, 1524, 592, 472,
598, 1518, 598, 1520, 596, 1520, 596, 1520, 596, 1520, 596, 1520,
596, 472, 592, 1524, 592, 472, 598, 25282, 8552, 4182, 596, 1520,
598, 1518, 598, 1520, 596, 1520, 596, 472, 592, 1524, 592, 472,
598, 1520, 596, 472, 594, 472, 592, 472, 596, 472, 592, 1524,
592, 472, 592, 1524, 596, 472, 594, 1520, 596, 1520, 598, 472,
592, 472, 598, 472, 594, 1522, 594, 472, 592, 1524, 594, 472,
596, 472, 594, 1524, 592, 1524, 592, 1524, 592, 472, 594, 1524,
598, 472, 592};
irsend.sendRaw(rawData, 135, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(PIONEER, irsend.capture.decode_type);
EXPECT_EQ(kPioneerBits, irsend.capture.bits);
EXPECT_EQ(0x659A05FAF50AC53A, irsend.capture.value);
EXPECT_EQ(0xA6A0, irsend.capture.address);
EXPECT_EQ(0xAFA3, irsend.capture.command);
}
// Synthetic Pioneer message.
// For:
// https://github.com/crankyoldgit/IRremoteESP8266/pull/547#issuecomment-430800734
TEST(TestDecodePioneer, SyntheticPioneerMessage) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
irsend.sendPioneer(0x659A857AF50A3DC2, 64, 0);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(PIONEER, irsend.capture.decode_type);
EXPECT_EQ(kPioneerBits, irsend.capture.bits);
EXPECT_EQ(0x659A857AF50A3DC2, irsend.capture.value);
EXPECT_EQ(0xA6A1, irsend.capture.address);
EXPECT_EQ(0xAFBC, irsend.capture.command);
irsend.reset();
irsend.sendPioneer(0x659A857AF50A3DC2, 64, 0);
EXPECT_EQ(
"f40000d33"
"m8544s4272"
"m534s534m534s1602m534s1602m534s534m534s534m534s1602m534s534m534s1602"
"m534s1602m534s534m534s534m534s1602m534s1602m534s534m534s1602m534s534"
"m534s1602m534s534m534s534m534s534m534s534m534s1602m534s534m534s1602"
"m534s534m534s1602m534s1602m534s1602m534s1602m534s534m534s1602m534s534"
"m534s25098"
"m8544s4272"
"m534s1602m534s1602m534s1602m534s1602m534s534m534s1602m534s534m534s1602"
"m534s534m534s534m534s534m534s534m534s1602m534s534m534s1602m534s534"
"m534s534m534s534m534s1602m534s1602m534s1602m534s1602m534s534m534s1602"
"m534s1602m534s1602m534s534m534s534m534s534m534s534m534s1602m534s534"
"m534s25098",
irsend.outputStr());
}

View File

@@ -0,0 +1,437 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendPronto().
TEST(TestSendPronto, CodeTooShort) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
// Less entries than the smallest possible (practical) Pronto code.
uint16_t pronto_test[5] = {0x0000, 0x0067, 0x0034, 0x0000, 0x0000};
irsend.sendPronto(pronto_test, 5);
EXPECT_EQ("", irsend.outputStr()); // Should do nothing.
}
TEST(TestSendPronto, NormalSequenceTooLong) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
// The First 'Normal' sequence is declared to be longer than the data we have.
uint16_t pronto_test[6] = {0x0000, 0x0067, 0x0010, 0x0000, 0x0000, 0x0000};
irsend.sendPronto(pronto_test, 6);
EXPECT_EQ("", irsend.outputStr()); // Should do nothing.
}
TEST(TestSendPronto, RepeatSequenceTooLong) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
// The 2nd 'Repeat' sequence is declared to be longer than the data we have.
uint16_t pronto_test[6] = {0x0000, 0x0067, 0x0000, 0x0010, 0x0000, 0x0000};
irsend.sendPronto(pronto_test, 6);
EXPECT_EQ("", irsend.outputStr()); // Should do nothing.
}
TEST(TestSendPronto, BothSequencesTooLong) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
// All sequences are declared to be longer than the data we have.
uint16_t pronto_test[6] = {0x0000, 0x0067, 0x0010, 0x0010, 0x0000, 0x0000};
irsend.sendPronto(pronto_test, 6);
EXPECT_EQ("", irsend.outputStr()); // Should do nothing.
}
TEST(TestSendPronto, MoreDataThanNeededInNormal) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
// We should handle when we are given more data than needed. (normal seq.)
uint16_t pronto_test[8] = {0x0000, 0x0067, 0x0001, 0x0000,
0x0001, 0x0002, 0x0003, 0x0004};
irsend.sendPronto(pronto_test, 8);
EXPECT_EQ("f40244d50m24s49",
irsend.outputStr()); // Only send the data required.
}
TEST(TestSendPronto, MoreDataThanNeededInRepeat) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
// We should handle when we are given more data than needed. (repeat seq.)
uint16_t pronto_test[8] = {0x0000, 0x0067, 0x0000, 0x0001,
0x0001, 0x0002, 0x0003, 0x0004};
irsend.sendPronto(pronto_test, 8);
EXPECT_EQ("f40244d50m24s49",
irsend.outputStr()); // Only send the data required.
}
TEST(TestSendPronto, MoreDataThanNeededInBoth) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
// We should handle when we are given more data than needed. (repeat seq.)
uint16_t pronto_test[10] = {0x0000, 0x0067, 0x0001, 0x0001, 0x0001,
0x0002, 0x0003, 0x0004, 0x5, 0x6};
irsend.sendPronto(pronto_test, 10);
EXPECT_EQ("f40244d50m24s49",
irsend.outputStr()); // Only send the data required.
irsend.sendPronto(pronto_test, 10, 1);
EXPECT_EQ("f40244d50m24s49m74s99",
irsend.outputStr()); // Only the data required.
}
TEST(TestSendPronto, ShortestValidCodeThatSendsNothing) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
uint16_t pronto_test[6] = {0x0000, 0x0067, 0x0000, 0x0000, 0x0001, 0x0002};
irsend.sendPronto(pronto_test, 6);
EXPECT_EQ("", irsend.outputStr()); // Nothing Happens.
irsend.sendPronto(pronto_test, 6, 1);
EXPECT_EQ("", irsend.outputStr()); // Twice as much Nothing Happens. ;-)
}
// Test sending a Pronto code that only has a normal (first) sequence.
// i.e. No Pronto repeat sequence.
TEST(TestSendPronto, NonRepeatingCode) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// A random Pronto code I found on the Internet that has no repeat sequence.
// It was an example of a poor Pronto code.
// It turned out to be a 4 copies of a Sony 12-bit code. Who knew!?!
uint16_t pronto_test[108] = {
0x0000, 0x0067, 0x0034, 0x0000, 0x0060, 0x0018, 0x0018, 0x0018, 0x0018,
0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
0x0018, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
0x0018, 0x0018, 0x0452, 0x0060, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
0x0018, 0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
0x0018, 0x0452, 0x0060, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
0x0452, 0x0060, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0030,
0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018};
// Send the Pronto code without any repeats set.
irsend.reset();
irsend.sendPronto(pronto_test, 108);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(kSony12Bits, irsend.capture.bits);
EXPECT_EQ(0x10, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_EQ(
"f40244d50"
"m2390s597"
"m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597"
"m597s597m597s597m597s597m597s27539"
"m2390s597"
"m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597"
"m597s597m597s597m597s597m597s27539"
"m2390s597"
"m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597"
"m597s597m597s597m597s597m597s27539"
"m2390s597"
"m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597"
"m597s597m597s597m597s597m597s597",
irsend.outputStr());
// Now try repeating it.
// As it has no repeat sequence, we shouldn't repeat it. (I think)
irsend.reset();
irsend.sendPronto(pronto_test, 108, 3);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(kSony12Bits, irsend.capture.bits);
EXPECT_EQ(0x10, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_EQ(
"f40244d50"
"m2390s597"
"m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597"
"m597s597m597s597m597s597m597s27539"
"m2390s597"
"m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597"
"m597s597m597s597m597s597m597s27539"
"m2390s597"
"m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597"
"m597s597m597s597m597s597m597s27539"
"m2390s597"
"m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597"
"m597s597m597s597m597s597m597s597",
irsend.outputStr());
}
// Test sending a Pronto code that only has a repeat sequence (Sony).
TEST(TestSendPronto, RepeatSequenceOnlyForSony) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Sony 20-bit command.
uint16_t pronto_test[46] = {
0x0000, 0x0067, 0x0000, 0x0015, 0x0060, 0x0018, 0x0018, 0x0018,
0x0030, 0x0018, 0x0030, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018,
0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018,
0x0018, 0x0018, 0x0030, 0x0018, 0x0030, 0x0018, 0x0030, 0x0018,
0x0018, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018,
0x0018, 0x0018, 0x0030, 0x0018, 0x0018, 0x03f6};
// Send the Pronto code without any repeats set.
irsend.reset();
irsend.sendPronto(pronto_test, 46);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(kSony20Bits, irsend.capture.bits);
EXPECT_EQ(0x74B92, irsend.capture.value);
EXPECT_EQ(0x1A, irsend.capture.address);
EXPECT_EQ(0x24AE, irsend.capture.command);
EXPECT_EQ(
"f40244d50"
"m2390s597"
"m597s597m1195s597m1195s597m1195s597m597s597m1195s597m597s597m597s597"
"m1195s597m597s597m1195s597m1195s597m1195s597m597s597m597s597m1195s597"
"m597s597m597s597m1195s597m597s25248",
irsend.outputStr());
// Send the Pronto code with 2 repeats.
irsend.reset();
irsend.sendPronto(pronto_test, 46, kSonyMinRepeat);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(kSony20Bits, irsend.capture.bits);
EXPECT_EQ(0x74B92, irsend.capture.value);
EXPECT_EQ(0x1A, irsend.capture.address);
EXPECT_EQ(0x24AE, irsend.capture.command);
EXPECT_EQ(
"f40244d50"
"m2390s597"
"m597s597m1195s597m1195s597m1195s597m597s597m1195s597m597s597m597s597"
"m1195s597m597s597m1195s597m1195s597m1195s597m597s597m597s597m1195s597"
"m597s597m597s597m1195s597m597s25248"
"m2390s597"
"m597s597m1195s597m1195s597m1195s597m597s597m1195s597m597s597m597s597"
"m1195s597m597s597m1195s597m1195s597m1195s597m597s597m597s597m1195s597"
"m597s597m597s597m1195s597m597s25248"
"m2390s597"
"m597s597m1195s597m1195s597m1195s597m597s597m1195s597m597s597m597s597"
"m1195s597m597s597m1195s597m1195s597m1195s597m597s597m597s597m1195s597"
"m597s597m597s597m1195s597m597s25248",
irsend.outputStr());
}
// Test sending a Pronto code that only has a repeat sequence (Panasonic).
TEST(TestSendPronto, RepeatSequenceOnlyForPanasonic) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Panasonic Plasma TV Descrete code (Power On).
uint16_t pronto_test[104] = {
0x0000, 0x0071, 0x0000, 0x0032, 0x0080, 0x003F, 0x0010, 0x0010, 0x0010,
0x0030, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0030, 0x0010, 0x0010,
0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0030,
0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
0x0010, 0x0030, 0x0010, 0x0030, 0x0010, 0x0030, 0x0010, 0x0030, 0x0010,
0x0030, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0030,
0x0010, 0x0030, 0x0010, 0x0030, 0x0010, 0x0030, 0x0010, 0x0030, 0x0010,
0x0010, 0x0010, 0x0030, 0x0010, 0x0A98};
// Send the Pronto code without any repeats set.
irsend.reset();
irsend.sendPronto(pronto_test, 104);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(kPanasonicBits, irsend.capture.bits);
EXPECT_EQ(0x400401007C7D, irsend.capture.value);
EXPECT_EQ(0x4004, irsend.capture.address);
EXPECT_EQ(0x1007C7D, irsend.capture.command);
EXPECT_EQ(
"f36682d50"
"m3494s1719"
"m436s436m436s1310m436s436m436s436m436s436m436s436m436s436m436s436"
"m436s436m436s436m436s436m436s436m436s436m436s1310m436s436m436s436"
"m436s436m436s436m436s436m436s436m436s436m436s436m436s436m436s1310"
"m436s436m436s436m436s436m436s436m436s436m436s436m436s436m436s436"
"m436s436m436s1310m436s1310m436s1310m436s1310m436s1310m436s436m436s436"
"m436s436m436s1310m436s1310m436s1310m436s1310m436s1310m436s436m436s1310"
"m436s74037",
irsend.outputStr());
}
// Test sending a Pronto code that has a normal & arepeat sequence (NEC).
TEST(TestSendPronto, NormalPlusRepeatSequence) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// NEC 32 bit power on command.
uint16_t pronto_test[76] = {
0x0000, 0x006D, 0x0022, 0x0002, 0x0156, 0x00AB, 0x0015, 0x0015, 0x0015,
0x0015, 0x0015, 0x0015, 0x0015, 0x0040, 0x0015, 0x0040, 0x0015, 0x0015,
0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0040, 0x0015, 0x0040, 0x0015,
0x0040, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0040, 0x0015, 0x0040,
0x0015, 0x0040, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015,
0x0040, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015,
0x0015, 0x0040, 0x0015, 0x0040, 0x0015, 0x0040, 0x0015, 0x0015, 0x0015,
0x0040, 0x0015, 0x0040, 0x0015, 0x0040, 0x0015, 0x0040, 0x0015, 0x05FD,
0x0156, 0x0055, 0x0015, 0x0E4E};
// Send the Pronto code without any repeats set.
irsend.reset();
irsend.sendPronto(pronto_test, 76);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0x18E710EF, irsend.capture.value);
EXPECT_EQ(0x18, irsend.capture.address);
EXPECT_EQ(0x8, irsend.capture.command);
EXPECT_EQ(
"f38028d50"
"m8994s4497"
"m552s552m552s552m552s552m552s1683m552s1683m552s552m552s552m552s552"
"m552s1683m552s1683m552s1683m552s552m552s552m552s1683m552s1683m552s1683"
"m552s552m552s552m552s552m552s1683m552s552m552s552m552s552m552s552"
"m552s1683m552s1683m552s1683m552s552m552s1683m552s1683m552s1683m552s1683"
"m552s40317",
irsend.outputStr());
// Send it again with a single repeat.
irsend.reset();
irsend.sendPronto(pronto_test, 76, 1);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0x18E710EF, irsend.capture.value);
EXPECT_EQ(0x18, irsend.capture.address);
EXPECT_EQ(0x8, irsend.capture.command);
EXPECT_EQ(
"f38028d50"
"m8994s4497"
"m552s552m552s552m552s552m552s1683m552s1683m552s552m552s552m552s552"
"m552s1683m552s1683m552s1683m552s552m552s552m552s1683m552s1683m552s1683"
"m552s552m552s552m552s552m552s1683m552s552m552s552m552s552m552s552"
"m552s1683m552s1683m552s1683m552s552m552s1683m552s1683m552s1683m552s1683"
"m552s40317"
"m8994s2235m552s96310",
irsend.outputStr());
// Send it again with a two repeats.
irsend.reset();
irsend.sendPronto(pronto_test, 76, 2);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0x18E710EF, irsend.capture.value);
EXPECT_EQ(0x18, irsend.capture.address);
EXPECT_EQ(0x8, irsend.capture.command);
EXPECT_EQ(
"f38028d50"
"m8994s4497"
"m552s552m552s552m552s552m552s1683m552s1683m552s552m552s552m552s552"
"m552s1683m552s1683m552s1683m552s552m552s552m552s1683m552s1683m552s1683"
"m552s552m552s552m552s552m552s1683m552s552m552s552m552s552m552s552"
"m552s1683m552s1683m552s1683m552s552m552s1683m552s1683m552s1683m552s1683"
"m552s40317"
"m8994s2235m552s96310"
"m8994s2235m552s96310",
irsend.outputStr());
}
// Tests for #1034
TEST(TestSendPronto, Issue1034) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// JVC code allegedly.
uint16_t pronto_test[40] = {
0x0000, 0x006c, 0x0001, 0x0011, 0x0140, 0x00a0, 0x0014, 0x003c, 0x0014,
0x003c, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x003c,
0x0014, 0x0014, 0x0014, 0x003c, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014,
0x0014, 0x0014, 0x0014, 0x0014, 0x003c, 0x0014, 0x0014, 0x0014, 0x0014,
0x0014, 0x0014, 0x0014, 0x0384};
irsend.reset();
irsend.sendPronto(pronto_test, 40, 1);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(JVC, irsend.capture.decode_type);
EXPECT_EQ(kJvcBits, irsend.capture.bits);
EXPECT_EQ(0xc508, irsend.capture.value);
EXPECT_EQ(0xa3, irsend.capture.address);
EXPECT_EQ(0x10, irsend.capture.command);
}
// Tests for #1103
TEST(TestSendPronto, Issue1103) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Based on raw data:
// uint16_t rawData[7] = {20100, 20472, 15092, 30704, 20102, 20472, 15086};
// and output from `raw_to_pronto_code.py --hz 38000`:
// Pronto code = '0000 006D 0004 0000 02FB 0309 023D 048E 02FB 0309 023D 0ED8'
uint16_t pronto_test[12] = {
0x0000, 0x006D, 0x0004, 0x0000, 0x02FB, 0x0309, 0x023D, 0x048E,
0x02FB, 0x0309, 0x023D, 0x0ED8};
irsend.reset();
irsend.sendPronto(pronto_test, 12);
EXPECT_EQ(
"f38028d50m20066s20435m15069s30665m20066s20435m15069s99940",
irsend.outputStr());
// Which pretty much matches the `rawData` above.
// Shorter test.
// uint16_t rawData[4] = {20100, 20472, 15092, 30704};
// and output from `raw_to_pronto_code.py --hz 38000`:
// Pronto code = '0000 006D 0002 0000 02FB 0309 023D 048E'
uint16_t pronto_test2[8] = {
0x0000, 0x006D, 0x0002, 0x0000, 0x02FB, 0x0309, 0x023D, 0x048E};
irsend.reset();
irsend.sendPronto(pronto_test2, 8);
EXPECT_EQ(
"f38028d50m20066s20435m15069s30665",
irsend.outputStr());
// Which pretty much matches the `rawData` above.
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1103#issuecomment-628946514
uint16_t pronto_test_using_repeat[12] = {
0x0000, 0x006D, 0x0000, 0x0004, 0x02fb, 0x0309, 0x023d, 0x048e, 0x02fb,
0x0309, 0x023d, 0x0474};
irsend.reset();
irsend.sendPronto(pronto_test_using_repeat, 12);
EXPECT_EQ(
"f38028d50m20066s20435m15069s30665m20066s20435m15069s29982",
irsend.outputStr());
}

View File

@@ -0,0 +1,943 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// RRRRRR CCCCC 555555 RRRRRR CCCCC 555555 XX XX
// RR RR CC C 55 RR RR CC C 55 XX XX
// RRRRRR CC _____ 555555 RRRRRR CC _____ 555555 XXXX
// RR RR CC C 5555 RR RR CC C 5555 XX XX
// RR RR CCCCC 555555 RR RR CCCCC 555555 XX XX
// Tests for encodeRC5().
TEST(TestEncodeRC5, NormalEncoding) {
IRsendTest irsend(4);
EXPECT_EQ(0x0, irsend.encodeRC5(0, 0));
EXPECT_EQ(0x800, irsend.encodeRC5(0, 0, true));
EXPECT_EQ(0x41, irsend.encodeRC5(1, 1));
EXPECT_EQ(0x42, irsend.encodeRC5(1, 2));
EXPECT_EQ(0x7FF, irsend.encodeRC5(0x1F, 0x3F));
EXPECT_EQ(0xFFF, irsend.encodeRC5(0x1F, 0x3F, true));
EXPECT_EQ(0x7FF, irsend.encodeRC5(0xFF, 0xFF));
EXPECT_EQ(0xFFF, irsend.encodeRC5(0xFF, 0xFF, true));
EXPECT_EQ(0x175, irsend.encodeRC5(0x05, 0x35));
}
// Tests for encodeRC5X().
TEST(TestEncodeRC5X, NormalEncoding) {
IRsendTest irsend(4);
EXPECT_EQ(0x0, irsend.encodeRC5X(0, 0));
EXPECT_EQ(0x800, irsend.encodeRC5X(0, 0, true));
EXPECT_EQ(0x41, irsend.encodeRC5X(1, 1));
EXPECT_EQ(0x42, irsend.encodeRC5X(1, 2));
EXPECT_EQ(0x3FF, irsend.encodeRC5X(0x0F, 0x3F));
EXPECT_EQ(0x3FF, irsend.encodeRC5X(0x0F, 0x3F, false));
EXPECT_EQ(0xBFF, irsend.encodeRC5X(0x0F, 0x3F, true));
EXPECT_EQ(0x17FF, irsend.encodeRC5X(0x1F, 0x7F));
EXPECT_EQ(0x1FFF, irsend.encodeRC5X(0x1F, 0x7F, true));
EXPECT_EQ(0x17FF, irsend.encodeRC5X(0xFF, 0xFF));
EXPECT_EQ(0x1FFF, irsend.encodeRC5X(0xFF, 0xFF, true));
EXPECT_EQ(0x175, irsend.encodeRC5X(0x05, 0x35));
// Values of command <= 6-bits. i.e (<= 63 (0x3F)) should be the same
// as encodeRC5.
EXPECT_EQ(irsend.encodeRC5X(0, 0), irsend.encodeRC5(0, 0));
EXPECT_EQ(irsend.encodeRC5X(0, 0, true), irsend.encodeRC5(0, 0, true));
EXPECT_EQ(irsend.encodeRC5X(0x5, 0x35, false),
irsend.encodeRC5(0x5, 0x35, false));
EXPECT_EQ(irsend.encodeRC5X(0x5, 0x35, true),
irsend.encodeRC5(0x5, 0x35, true));
EXPECT_EQ(irsend.encodeRC5X(0x1F, 0x3F, true),
irsend.encodeRC5(0x1F, 0x3F, true));
EXPECT_NE(irsend.encodeRC5X(0x1F, 0x7F, true),
irsend.encodeRC5(0x1F, 0x7F, true));
}
// Tests for toggleRC5().
TEST(TestToggleRC5, GeneralUse) {
IRsendTest irsend(4);
EXPECT_EQ(0x800, irsend.toggleRC5(0x0));
EXPECT_EQ(0x0, irsend.toggleRC5(0x800));
EXPECT_EQ(0x0, irsend.toggleRC5(irsend.toggleRC5(0x0)));
EXPECT_EQ(irsend.encodeRC5(0x5, 0x35, false),
irsend.toggleRC5(irsend.encodeRC5(0x5, 0x35, true)));
}
// Tests for sendRC5().
// Test sending typical RC-5 & RC-5X data only.
TEST(TestSendRC5, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendRC5(0x0, kRC5Bits);
EXPECT_EQ(
"f36000d25"
"m889s889m1778s889m889s889m889s889m889s889m889s889m889"
"s889m889s889m889s889m889s889m889s889m889s889m889s90664",
irsend.outputStr());
irsend.reset();
irsend.sendRC5(0x1AAA, kRC5Bits);
EXPECT_EQ(
"f36000d25"
"m889s889m889s889m1778s1778m1778s1778m1778s1778"
"m1778s1778m1778s1778m1778s90664",
irsend.outputStr());
irsend.reset();
irsend.sendRC5(0x175, kRC5Bits);
EXPECT_EQ(
"f36000d25"
"m889s889m1778s889m889s889m889s1778m1778s1778"
"m889s889m889s889m1778s1778m1778s1778m889s89775",
irsend.outputStr());
irsend.reset();
irsend.sendRC5(0x3FFF, kRC5Bits);
EXPECT_EQ(
"f36000d25"
"m889s889m889s889m889s889m889s889m889s889m889s889m889s889"
"m889s889m889s889m889s889m889s889m889s889m889s889m889s89775",
irsend.outputStr());
irsend.reset();
irsend.sendRC5(0x0, kRC5XBits);
EXPECT_EQ(
"f36000d25"
"m889s889m1778s889m889s889m889s889m889s889m889s889m889"
"s889m889s889m889s889m889s889m889s889m889s889m889s90664",
irsend.outputStr());
irsend.reset();
irsend.sendRC5(0x1AAA, kRC5XBits);
EXPECT_EQ(
"f36000d25"
"m1778s1778m1778s1778m1778s1778m1778"
"s1778m1778s1778m1778s1778m1778s90664",
irsend.outputStr());
irsend.reset();
irsend.sendRC5(0x175, kRC5XBits);
EXPECT_EQ(
"f36000d25"
"m889s889m1778s889m889s889m889s1778m1778s1778"
"m889s889m889s889m1778s1778m1778s1778m889s89775",
irsend.outputStr());
irsend.reset();
irsend.sendRC5(0x3FFF, kRC5XBits);
EXPECT_EQ(
"f36000d25"
"m1778s1778m889s889m889s889m889s889m889s889m889s889m889"
"s889m889s889m889s889m889s889m889s889m889s889m889s89775",
irsend.outputStr());
}
// Test sending RC-5 & RC-5X with different repeats.
TEST(TestSendRC5, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendRC5(0x175, kRC5Bits, 1);
EXPECT_EQ(
"f36000d25"
"m889s889m1778s889m889s889m889s1778m1778s1778"
"m889s889m889s889m1778s1778m1778s1778m889s90664"
"m889s889m1778s889m889s889m889s1778m1778s1778"
"m889s889m889s889m1778s1778m1778s1778m889s88886",
irsend.outputStr());
irsend.reset();
irsend.sendRC5(0x175, kRC5Bits, 2);
EXPECT_EQ(
"f36000d25"
"m889s889m1778s889m889s889m889s1778m1778s1778"
"m889s889m889s889m1778s1778m1778s1778m889s90664"
"m889s889m1778s889m889s889m889s1778m1778s1778"
"m889s889m889s889m1778s1778m1778s1778m889s89775"
"m889s889m1778s889m889s889m889s1778m1778s1778"
"m889s889m889s889m1778s1778m1778s1778m889s88886",
irsend.outputStr());
irsend.reset();
irsend.sendRC5(0x175, kRC5XBits, 1);
EXPECT_EQ(
"f36000d25"
"m889s889m1778s889m889s889m889s1778m1778s1778"
"m889s889m889s889m1778s1778m1778s1778m889s90664"
"m889s889m1778s889m889s889m889s1778m1778s1778"
"m889s889m889s889m1778s1778m1778s1778m889s88886",
irsend.outputStr());
irsend.reset();
irsend.sendRC5(0x1175, kRC5XBits, 2);
EXPECT_EQ(
"f36000d25"
"m1778s889m889s889m889s889m889s1778m1778s1778"
"m889s889m889s889m1778s1778m1778s1778m889s90664"
"m1778s889m889s889m889s889m889s1778m1778s1778"
"m889s889m889s889m1778s1778m1778s1778m889s89775"
"m1778s889m889s889m889s889m889s1778m1778s1778"
"m889s889m889s889m1778s1778m1778s1778m889s88886",
irsend.outputStr());
}
// Tests for decodeRC5().
// Decode normal RC-5/RC5X messages.
TEST(TestDecodeRC5, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal RC-5 12-bit message.
irsend.reset();
irsend.sendRC5(0x175);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5Bits, true));
EXPECT_EQ(RC5, irsend.capture.decode_type);
EXPECT_EQ(kRC5Bits, irsend.capture.bits);
EXPECT_EQ(0x175, irsend.capture.value);
EXPECT_EQ(0x05, irsend.capture.address);
EXPECT_EQ(0x35, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal RC-5 12-bit message decoded as RC5-X.
irsend.reset();
irsend.sendRC5(0x175);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5XBits, true));
EXPECT_EQ(RC5, irsend.capture.decode_type);
EXPECT_EQ(kRC5Bits, irsend.capture.bits);
EXPECT_EQ(0x175, irsend.capture.value);
EXPECT_EQ(0x05, irsend.capture.address);
EXPECT_EQ(0x35, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// A RC-5X 13-bit message but with a value that is valid for RC-5 decoded
// as RC5-X.
irsend.reset();
irsend.sendRC5(0x175, kRC5XBits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5XBits, true));
EXPECT_EQ(RC5, irsend.capture.decode_type);
EXPECT_EQ(kRC5Bits, irsend.capture.bits);
EXPECT_EQ(0x175, irsend.capture.value);
EXPECT_EQ(0x05, irsend.capture.address);
EXPECT_EQ(0x35, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Synthesised Normal RC-5 12-bit message.
irsend.reset();
irsend.sendRC5(irsend.encodeRC5(0x00, 0x0B, true));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5Bits, true));
EXPECT_EQ(RC5, irsend.capture.decode_type);
EXPECT_EQ(kRC5Bits, irsend.capture.bits);
EXPECT_EQ(0x80B, irsend.capture.value);
EXPECT_EQ(0x00, irsend.capture.address);
EXPECT_EQ(0x0B, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Synthesised Normal RC-5X 13-bit message.
irsend.reset();
irsend.sendRC5(irsend.encodeRC5X(0x02, 0x41, true), kRC5XBits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5XBits, true));
EXPECT_EQ(RC5X, irsend.capture.decode_type);
EXPECT_EQ(kRC5XBits, irsend.capture.bits);
EXPECT_EQ(0x1881, irsend.capture.value);
EXPECT_EQ(0x02, irsend.capture.address);
EXPECT_EQ(0x41, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Synthesised Normal RC-5X 13-bit message should fail at being decoded
// as a normal RC-5 (12 bit) message.
irsend.reset();
irsend.sendRC5(irsend.encodeRC5X(0x02, 0x41, true), kRC5XBits);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5Bits, true));
}
// Decode normal repeated RC5 messages.
TEST(TestDecodeRC5, NormalDecodeWithRepeatAndStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal RC-5 12-bit (even) message with one repeat.
irsend.reset();
irsend.sendRC5(0x174, kRC5Bits, 1);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5Bits, true));
EXPECT_EQ(RC5, irsend.capture.decode_type);
EXPECT_EQ(kRC5Bits, irsend.capture.bits);
EXPECT_EQ(0x174, irsend.capture.value);
EXPECT_EQ(0x05, irsend.capture.address);
EXPECT_EQ(0x34, irsend.capture.command);
// Normal RC-5 12-bit (odd) message with one repeat.
irsend.reset();
irsend.sendRC5(0x175, kRC5Bits, 1);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5Bits, true));
EXPECT_EQ(RC5, irsend.capture.decode_type);
EXPECT_EQ(kRC5Bits, irsend.capture.bits);
EXPECT_EQ(0x175, irsend.capture.value);
EXPECT_EQ(0x05, irsend.capture.address);
EXPECT_EQ(0x35, irsend.capture.command);
// Synthesised Normal RC-5X 13-bit message with 2 repeats.
irsend.reset();
irsend.sendRC5(irsend.encodeRC5X(0x02, 0x41, true), kRC5XBits, 2);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5XBits, true));
EXPECT_EQ(RC5X, irsend.capture.decode_type);
EXPECT_EQ(kRC5XBits, irsend.capture.bits);
EXPECT_EQ(0x1881, irsend.capture.value);
EXPECT_EQ(0x02, irsend.capture.address);
EXPECT_EQ(0x41, irsend.capture.command);
}
// Decode unsupported RC5 messages.
TEST(TestDecodeRC5, DecodeWithNonStrictValues) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendRC5(0xFA, 8); // Illegal value RC5 8-bit message.
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5Bits, true));
ASSERT_FALSE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5XBits,
true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeRC5(&irsend.capture, kStartOffset, 8, false));
EXPECT_EQ(RC5, irsend.capture.decode_type);
EXPECT_EQ(8, irsend.capture.bits);
EXPECT_EQ(0xFA, irsend.capture.value);
EXPECT_EQ(0x3, irsend.capture.address);
EXPECT_EQ(0x3A, irsend.capture.command);
irsend.reset();
irsend.sendRC5(0x12345678, 32); // Illegal size RC5 32-bit message.
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5Bits, true));
ASSERT_FALSE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5XBits,
true));
irsend.makeDecodeResult();
// Should fail with strict when we ask for the wrong bit size.
ASSERT_FALSE(irrecv.decodeRC5(&irsend.capture, kStartOffset, 32, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeRC5(&irsend.capture, kStartOffset, 32, false));
EXPECT_EQ(RC5, irsend.capture.decode_type);
EXPECT_EQ(31, irsend.capture.bits);
EXPECT_EQ(0x12345678, irsend.capture.value);
irsend.reset();
irsend.sendRC5(0x87654321, 32); // Illegal size RC5 32-bit message.
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5Bits, true));
ASSERT_FALSE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5XBits,
true));
irsend.makeDecodeResult();
// Should fail with strict when we ask for the wrong bit size.
ASSERT_FALSE(irrecv.decodeRC5(&irsend.capture, kStartOffset, 32, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeRC5(&irsend.capture, kStartOffset, 32, false));
EXPECT_EQ(RC5X, irsend.capture.decode_type);
EXPECT_EQ(32, irsend.capture.bits);
EXPECT_EQ(0x87654321, irsend.capture.value);
}
// Decode (non-standard) 64-bit messages.
TEST(TestDecodeRC5, Decode64BitMessages) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Illegal size RC-5 64-bit message.
irsend.sendRC5(0xFFFFFFFFFFFFFFFF, 64);
irsend.makeDecodeResult();
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeRC5(&irsend.capture, kStartOffset, 64, false));
EXPECT_EQ(RC5X, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, irsend.capture.value);
}
// Fail to decode a non-RC-5 example via GlobalCache
TEST(TestDecodeRC5, FailToDecodeNonRC5Example) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
uint16_t gc_test[39] = {38000, 1, 1, 322, 162, 20, 61, 20, 61, 20,
20, 20, 20, 20, 20, 20, 127, 20, 61, 9,
20, 20, 61, 20, 20, 20, 61, 20, 61, 20,
61, 20, 20, 20, 20, 20, 20, 20, 884};
irsend.sendGC(gc_test, 39);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeRC5(&irsend.capture));
ASSERT_FALSE(irrecv.decodeRC5(&irsend.capture, kStartOffset, kRC5Bits,
false));
}
// RRRRRR CCCCC 666
// RR RR CC C 66
// RRRRRR CC _____ 666666
// RR RR CC C 66 66
// RR RR CCCCC 66666
// Tests for encodeRC6().
TEST(TestEncodeRC6, Mode0Encoding) {
IRsendTest irsend(4);
EXPECT_EQ(0x0, irsend.encodeRC6(0, 0, kRC6Mode0Bits));
EXPECT_EQ(0x1234, irsend.encodeRC6(0x12, 0x34, kRC6Mode0Bits));
EXPECT_EQ(0x12345, irsend.encodeRC6(0x123, 0x45, kRC6Mode0Bits));
EXPECT_EQ(0xFFFFF, irsend.encodeRC6(0xFFF, 0xFF, kRC6Mode0Bits));
EXPECT_EQ(0xFFF00, irsend.encodeRC6(0xFFFF, 0x00, kRC6Mode0Bits));
EXPECT_EQ(0xFF, irsend.encodeRC6(0x00, 0xFF, kRC6Mode0Bits));
}
TEST(TestEncodeRC6, 36BitEncoding) {
IRsendTest irsend(4);
EXPECT_EQ(0x0, irsend.encodeRC6(0, 0, kRC6_36Bits));
EXPECT_EQ(0x1234, irsend.encodeRC6(0x12, 0x34, kRC6_36Bits));
EXPECT_EQ(0x123456789, irsend.encodeRC6(0x1234567, 0x89, kRC6_36Bits));
EXPECT_EQ(0xFFFFFFFFF, irsend.encodeRC6(0xFFFFFFF, 0xFF, kRC6_36Bits));
EXPECT_EQ(0xFFFFFFFFF, irsend.encodeRC6(0xFFFFFFFF, 0xFF, kRC6_36Bits));
EXPECT_EQ(0xFFFFFFF00, irsend.encodeRC6(0xFFFFFFF, 0x00, kRC6_36Bits));
EXPECT_EQ(0xFF, irsend.encodeRC6(0x0, 0xFF, kRC6_36Bits));
EXPECT_EQ(0xFFFFFFFFF, irsend.encodeRC6(0xFFFFFFFF, 0xFF, kRC6_36Bits));
}
// Tests for toggleRC6().
// Normal use (RC-6 Mode 0)
TEST(TestToggleRC6, Mode0) {
IRsendTest irsend(4);
EXPECT_EQ(0x10000, irsend.toggleRC6(0x0));
EXPECT_EQ(irsend.toggleRC6(0x0), irsend.toggleRC6(0x0, kRC6Mode0Bits));
EXPECT_EQ(0x0, irsend.toggleRC6(0x10000));
EXPECT_EQ(0x0, irsend.toggleRC6(irsend.toggleRC6(0x0)));
}
// RC-6 36-bit use (Xbox 360)
TEST(TestToggleRC6, 36BitUse) {
IRsendTest irsend(4);
EXPECT_EQ(0x8000, irsend.toggleRC6(0x0, kRC6_36Bits));
EXPECT_EQ(0x0, irsend.toggleRC6(0x8000, kRC6_36Bits));
EXPECT_EQ(0x0,
irsend.toggleRC6(irsend.toggleRC6(0x0, kRC6_36Bits), kRC6_36Bits));
}
// Tests for sendRC6().
// Test sending typical RC-6 Mode-0 data only.
TEST(TestSendRC6, SendMode0DataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendRC6(0x0);
EXPECT_EQ(
"f36000d33"
"m2664s888"
"m444s888m444s444m444s444m444s888m888s444m444s444m444s444"
"m444s444m444s444m444s444m444s444m444s444m444s444m444s444"
"m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s83028",
irsend.outputStr());
irsend.reset();
irsend.sendRC6(0x1FFFF);
EXPECT_EQ(
"f36000d33"
"m2664s888"
"m444s888m444s444m444s444m1332s888m444s444m444s444m444s444"
"m444s444m444s444m444s444m444s444m444s444m444s444m444s444"
"m444s444m444s444m444s444m444s444m444s444m444"
"s83472",
irsend.outputStr());
irsend.reset();
irsend.sendRC6(0x15555);
EXPECT_EQ(
"f36000d33"
"m2664s888"
"m444s888m444s444m444s444m1332s1332m888s888m888s888"
"m888s888m888s888m888s888m888s888m888s888m888"
"s83472",
irsend.outputStr());
}
// Test sending typical RC-6 36-bit data only.
TEST(TestSendRC6, Send36BitDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendRC6(0x0, kRC6_36Bits);
EXPECT_EQ(
"f36000d33"
"m2664s888"
"m444s888m444s444m444s444m444"
"s888m888"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s83028",
irsend.outputStr());
irsend.reset();
irsend.sendRC6(0xFFFFFFFFF, kRC6_36Bits);
EXPECT_EQ(
"f36000d33"
"m2664s888"
"m444s444m444s444m444s444m444s444"
"m888s888"
"m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444"
"m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444"
"m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444"
"m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s83472",
irsend.outputStr());
irsend.reset();
irsend.sendRC6(0xAAAAAAAAAA, kRC6_36Bits);
EXPECT_EQ(
"f36000d33"
"m2664s888m444s444m444s888m888"
"s1332m1332"
"s888m888s888m888s888m888s888m888s888m888s888m888s888m888s888m888s888m888"
"s888m888s888m888s888m888s888m888s888m888s888m888s888m444s83028",
irsend.outputStr());
irsend.reset();
irsend.sendRC6(0xC800F740C, kRC6_36Bits); // Xbox 360 OnOff code
EXPECT_EQ(
"f36000d33"
"m2664s888"
"m444s444m444s444m444s888m444"
"s888m1332"
"s888m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m888s444m444s444m444s444m444s888m888s444m444"
"s444m444s888m888s888m444s444m444s444m444s444m444s444m444s444m888"
"s444m444s888m444s444m444s83028",
irsend.outputStr());
irsend.reset();
irsend.sendRC6(irsend.toggleRC6(0xC800F740C, kRC6_36Bits),
kRC6_36Bits); // Xbox 360 OnOff code (toggled)
EXPECT_EQ(
"f36000d33"
"m2664s888"
"m444s444m444s444m444s888m444"
"s888m1332"
"s888m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m888s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s888m888s888m444s444m444s444m444s444m444s444m444"
"s444m888s444m444s888m444s444m444s83028",
irsend.outputStr());
}
// Test sending RC-6 Mode 0 with different repeats.
TEST(TestSendRC6, SendMode0WithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendRC6(0x175, kRC6Mode0Bits, 0);
EXPECT_EQ(
"f36000d33"
"m2664s888"
"m444s888m444s444m444s444m444"
"s888m888"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m888s888m888"
"s444m444s444m444s888m888s888m888s83472",
irsend.outputStr());
irsend.reset();
irsend.sendRC6(0x175, kRC6Mode0Bits, 1);
EXPECT_EQ(
"f36000d33"
"m2664s888"
"m444s888m444s444m444s444m444"
"s888m888"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m888s888m888"
"s444m444s444m444s888m888s888m888s83472"
"m2664s888"
"m444s888m444s444m444s444m444"
"s888m888"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m888s888m888"
"s444m444s444m444s888m888s888m888s83472",
irsend.outputStr());
irsend.reset();
irsend.sendRC6(0x175, kRC6Mode0Bits, 2);
EXPECT_EQ(
"f36000d33"
"m2664s888"
"m444s888m444s444m444s444m444"
"s888m888"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m888s888m888"
"s444m444s444m444s888m888s888m888s83472"
"m2664s888"
"m444s888m444s444m444s444m444"
"s888m888"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m888s888m888"
"s444m444s444m444s888m888s888m888s83472"
"m2664s888"
"m444s888m444s444m444s444m444"
"s888m888"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m888s888m888"
"s444m444s444m444s888m888s888m888s83472",
irsend.outputStr());
}
// Test sending RC-6 36-bit with different repeats.
TEST(TestSendRC6, Send36BitWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendRC6(0x175, kRC6_36Bits, 0);
EXPECT_EQ(
"f36000d33"
"m2664s888"
"m444s888m444s444m444s444m444"
"s888m888"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m888s888m888"
"s444m444s444m444s888m888s888m888s83472",
irsend.outputStr());
irsend.reset();
irsend.sendRC6(0x175, kRC6_36Bits, 1);
EXPECT_EQ(
"f36000d33"
"m2664s888"
"m444s888m444s444m444s444m444"
"s888m888"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m888s888m888"
"s444m444s444m444s888m888s888m888s83472"
"m2664s888"
"m444s888m444s444m444s444m444"
"s888m888"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m888s888m888"
"s444m444s444m444s888m888s888m888s83472",
irsend.outputStr());
irsend.reset();
irsend.sendRC6(0x175, kRC6_36Bits, 2);
EXPECT_EQ(
"f36000d33"
"m2664s888"
"m444s888m444s444m444s444m444"
"s888m888"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m888s888m888"
"s444m444s444m444s888m888s888m888s83472"
"m2664s888"
"m444s888m444s444m444s444m444"
"s888m888"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m888s888m888"
"s444m444s444m444s888m888s888m888s83472"
"m2664s888"
"m444s888m444s444m444s444m444"
"s888m888"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m444s444m444"
"s444m444s444m444s444m444s444m444s444m444s444m444s444m888s888m888"
"s444m444s444m444s888m888s888m888s83472",
irsend.outputStr());
}
// Tests for decodeRC6().
// Decode normal RC-6 Mode 0 messages.
TEST(TestDecodeRC6, NormalMode0DecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal RC-6 Mode 0 (20-bit) message.
irsend.reset();
irsend.sendRC6(0x175);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6Mode0Bits,
true));
EXPECT_EQ(RC6, irsend.capture.decode_type);
EXPECT_EQ(kRC6Mode0Bits, irsend.capture.bits);
EXPECT_EQ(0x175, irsend.capture.value);
EXPECT_EQ(0x01, irsend.capture.address);
EXPECT_EQ(0x75, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal Synthesised RC-6 Mode 0 (20-bit) message.
irsend.reset();
irsend.sendRC6(irsend.encodeRC6(0x1234567, 0x89, kRC6Mode0Bits));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6Mode0Bits,
true));
EXPECT_EQ(RC6, irsend.capture.decode_type);
EXPECT_EQ(kRC6Mode0Bits, irsend.capture.bits);
EXPECT_EQ(0x56789, irsend.capture.value);
EXPECT_EQ(0x567, irsend.capture.address);
EXPECT_EQ(0x89, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Same again, but encoded manually.
irsend.reset();
irsend.sendRC6(0x123456789, kRC6Mode0Bits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6Mode0Bits,
true));
EXPECT_EQ(RC6, irsend.capture.decode_type);
EXPECT_EQ(kRC6Mode0Bits, irsend.capture.bits);
EXPECT_EQ(0x56789, irsend.capture.value);
EXPECT_EQ(0x567, irsend.capture.address);
EXPECT_EQ(0x89, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode normal RC-6 36-bit messages.
TEST(TestDecodeRC6, Normal36BitDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal RC-6 36-bit message.
irsend.reset();
irsend.sendRC6(0x175, kRC6_36Bits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6_36Bits,
true));
EXPECT_EQ(RC6, irsend.capture.decode_type);
EXPECT_EQ(kRC6_36Bits, irsend.capture.bits);
EXPECT_EQ(0x175, irsend.capture.value);
EXPECT_EQ(0x01, irsend.capture.address);
EXPECT_EQ(0x75, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal Synthesised RC-6 36-bit message.
irsend.reset();
irsend.sendRC6(irsend.encodeRC6(0x1234567, 0x89, kRC6_36Bits), kRC6_36Bits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6_36Bits,
true));
EXPECT_EQ(RC6, irsend.capture.decode_type);
EXPECT_EQ(kRC6_36Bits, irsend.capture.bits);
EXPECT_EQ(0x123456789, irsend.capture.value);
EXPECT_EQ(0x1234567, irsend.capture.address);
EXPECT_EQ(0x89, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode normal repeated RC6 Mode 0 messages.
TEST(TestDecodeRC6, NormalMode0DecodeWithRepeatAndStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal RC-6 Mode 0 (20-bit) even message with one repeat.
irsend.reset();
irsend.sendRC6(0x174, kRC6Mode0Bits, 1);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6Mode0Bits,
true));
EXPECT_EQ(RC6, irsend.capture.decode_type);
EXPECT_EQ(kRC6Mode0Bits, irsend.capture.bits);
EXPECT_EQ(0x174, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x74, irsend.capture.command);
// Normal RC-6 Mode 0 (20-bit) odd message with one repeat.
irsend.reset();
irsend.sendRC6(0x175, kRC6Mode0Bits, 1);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6Mode0Bits,
true));
EXPECT_EQ(RC6, irsend.capture.decode_type);
EXPECT_EQ(kRC6Mode0Bits, irsend.capture.bits);
EXPECT_EQ(0x175, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x75, irsend.capture.command);
}
// Decode normal repeated RC6 36-bit messages.
TEST(TestDecodeRC6, Normal36BitDecodeWithRepeatAndStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal RC-6 36-bit odd message with one repeat.
irsend.reset();
irsend.sendRC6(0x175, kRC6_36Bits, 1);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6_36Bits,
true));
EXPECT_EQ(RC6, irsend.capture.decode_type);
EXPECT_EQ(kRC6_36Bits, irsend.capture.bits);
EXPECT_EQ(0x175, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x75, irsend.capture.command);
// Normal RC-6 36-bit even message with one repeat.
irsend.reset();
irsend.sendRC6(0x174, kRC6_36Bits, 1);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6_36Bits,
true));
EXPECT_EQ(RC6, irsend.capture.decode_type);
EXPECT_EQ(kRC6_36Bits, irsend.capture.bits);
EXPECT_EQ(0x174, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x74, irsend.capture.command);
}
// Decode RC-6 messages without strict.
TEST(TestDecodeRC6, NormalDecodeWithoutStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal RC-6 Mode 0 (20-bit) message.
irsend.reset();
irsend.sendRC6(0x175, kRC6Mode0Bits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC6(&irsend.capture));
EXPECT_EQ(RC6, irsend.capture.decode_type);
EXPECT_EQ(kRC6Mode0Bits, irsend.capture.bits);
EXPECT_EQ(0x175, irsend.capture.value);
EXPECT_EQ(0x01, irsend.capture.address);
EXPECT_EQ(0x75, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal RC-6 Mode 0 (20-bit) message.
irsend.reset();
irsend.sendRC6(0x174, kRC6Mode0Bits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC6(&irsend.capture));
EXPECT_EQ(RC6, irsend.capture.decode_type);
EXPECT_EQ(kRC6Mode0Bits, irsend.capture.bits);
EXPECT_EQ(0x174, irsend.capture.value);
EXPECT_EQ(0x01, irsend.capture.address);
EXPECT_EQ(0x74, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal RC-6 36-bit message.
irsend.reset();
irsend.sendRC6(0x174, kRC6_36Bits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC6(&irsend.capture));
EXPECT_EQ(RC6, irsend.capture.decode_type);
EXPECT_EQ(kRC6_36Bits, irsend.capture.bits);
EXPECT_EQ(0x174, irsend.capture.value);
EXPECT_EQ(0x01, irsend.capture.address);
EXPECT_EQ(0x74, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal Synthesised RC-6 36-bit message.
irsend.reset();
irsend.sendRC6(irsend.encodeRC6(0x1234567, 0x89, kRC6_36Bits), kRC6_36Bits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC6(&irsend.capture));
EXPECT_EQ(RC6, irsend.capture.decode_type);
EXPECT_EQ(kRC6_36Bits, irsend.capture.bits);
EXPECT_EQ(0x123456789, irsend.capture.value);
EXPECT_EQ(0x1234567, irsend.capture.address);
EXPECT_EQ(0x89, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode a 'real' example via GlobalCache
TEST(TestDecodeRC6, Decode36BitGlobalCacheExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Xbox-360 Power On from Global Cache.
uint16_t gc_test[65] = {
36000, 1, 1, 96, 32, 16, 16, 16, 16, 16, 32, 16, 32, 48, 32, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 32, 16, 16, 16, 16, 16, 16, 32, 32, 16, 16, 16, 16, 32, 32, 32,
16, 16, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 16, 2476};
irsend.sendGC(gc_test, 65);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6_36Bits));
EXPECT_EQ(RC6, irsend.capture.decode_type);
EXPECT_EQ(kRC6_36Bits, irsend.capture.bits);
EXPECT_EQ(0xC800F742A, irsend.capture.value);
EXPECT_EQ(0xC800F74, irsend.capture.address);
EXPECT_EQ(0x2A, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Fail to decode a non-RC-6 example via GlobalCache
TEST(TestDecodeRC5, FailToDecodeNonRC6Example) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
uint16_t gc_test[39] = {38000, 1, 1, 322, 162, 20, 61, 20, 61, 20,
20, 20, 20, 20, 20, 20, 127, 20, 61, 9,
20, 20, 61, 20, 20, 20, 61, 20, 61, 20,
61, 20, 20, 20, 20, 20, 20, 20, 884};
irsend.sendGC(gc_test, 39);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeRC6(&irsend.capture));
ASSERT_FALSE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6Mode0Bits,
true));
ASSERT_FALSE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6Mode0Bits,
false));
ASSERT_FALSE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6_36Bits,
true));
ASSERT_FALSE(irrecv.decodeRC6(&irsend.capture, kRC6_36Bits, kStartOffset,
false));
irsend.reset();
irsend.sendRC5(0x0);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeRC6(&irsend.capture));
ASSERT_FALSE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6Mode0Bits,
true));
ASSERT_FALSE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6Mode0Bits,
false));
ASSERT_FALSE(irrecv.decodeRC6(&irsend.capture, kStartOffset, kRC6_36Bits,
true));
ASSERT_FALSE(irrecv.decodeRC6(&irsend.capture, kRC6_36Bits, kStartOffset,
false));
}

View File

@@ -0,0 +1,258 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendRCMM().
// Test sending typical data only.
TEST(TestSendRCMM, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendRCMM(0xe0a600);
EXPECT_EQ(
"f36000d33"
"m416s277"
"m166s777m166s611m166s277m166s277"
"m166s611m166s611m166s444m166s611m166s277m166s277m166s277m166s277"
"m166s19600",
irsend.outputStr());
irsend.reset();
irsend.sendRCMM(0x28e0a600UL, 32);
EXPECT_EQ(
"f36000d33"
"m416s277"
"m166s277m166s611m166s611m166s277m166s777m166s611m166s277m166s277"
"m166s611m166s611m166s444m166s611m166s277m166s277m166s277m166s277"
"m166s17160",
irsend.outputStr());
}
// Test sending with different repeats.
TEST(TestSendRCMM, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendRCMM(0x28e0a600, 32, 2); // 2 repeats.
EXPECT_EQ(
"f36000d33"
"m416s277"
"m166s277m166s611m166s611m166s277m166s777m166s611m166s277m166s277"
"m166s611m166s611m166s444m166s611m166s277m166s277m166s277m166s277"
"m166s17160"
"m416s277"
"m166s277m166s611m166s611m166s277m166s777m166s611m166s277m166s277"
"m166s611m166s611m166s444m166s611m166s277m166s277m166s277m166s277"
"m166s17160"
"m416s277"
"m166s277m166s611m166s611m166s277m166s777m166s611m166s277m166s277"
"m166s611m166s611m166s444m166s611m166s277m166s277m166s277m166s277"
"m166s17160",
irsend.outputStr());
}
// Test sending an atypical data size.
TEST(TestSendRCMM, SendUnusualSize) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendRCMM(0xE0, 8);
EXPECT_EQ(
"f36000d33"
"m416s277"
"m166s777m166s611m166s277m166s277"
"m166s24313",
irsend.outputStr());
irsend.reset();
irsend.sendRCMM(0x28e0a60000UL, 40);
EXPECT_EQ(
"f36000d33"
"m416s277"
"m166s277m166s611m166s611m166s277m166s777m166s611m166s277m166s277"
"m166s611m166s611m166s444m166s611m166s277m166s277m166s277m166s277"
"m166s277m166s277m166s277m166s277m166s15388",
irsend.outputStr());
}
// Tests for decodeRCMM().
// Decode normal RCMM messages.
TEST(TestDecodeRCMM, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal RCMM 24-bit message.
irsend.reset();
irsend.sendRCMM(0xe0a600);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRCMM(&irsend.capture, kStartOffset, kRCMMBits,
true));
EXPECT_EQ(RCMM, irsend.capture.decode_type);
EXPECT_EQ(kRCMMBits, irsend.capture.bits);
EXPECT_EQ(0xe0a600, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal RCMM 12-bit message.
irsend.reset();
irsend.sendRCMM(0x600, 12);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRCMM(&irsend.capture, kStartOffset, 12, true));
EXPECT_EQ(RCMM, irsend.capture.decode_type);
EXPECT_EQ(12, irsend.capture.bits);
EXPECT_EQ(0x600, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal RCMM 32-bit message.
irsend.reset();
irsend.sendRCMM(0x28e0a600, 32);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRCMM(&irsend.capture, kStartOffset, 32, true));
EXPECT_EQ(RCMM, irsend.capture.decode_type);
EXPECT_EQ(32, irsend.capture.bits);
EXPECT_EQ(0x28e0a600, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decodes should fail for illegal bit sizes when in strict mode.
TEST(TestDecodeRCMM, IllegalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Illegal RCMM 8-bit message.
irsend.reset();
irsend.sendRCMM(0x0, 8);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeRCMM(&irsend.capture, kStartOffset, 8, true));
ASSERT_FALSE(irrecv.decodeRCMM(&irsend.capture, kStartOffset, 12, true));
// Illegal RCMM 36-bit message.
irsend.reset();
irsend.sendRCMM(0x0, 36);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeRCMM(&irsend.capture, kStartOffset, 12, true));
ASSERT_FALSE(irrecv.decodeRCMM(&irsend.capture, kStartOffset, 36, true));
}
// Decodes without strict mode.
TEST(TestDecodeRCMM, DecodeWithoutStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Illegal RCMM 8-bit message.
irsend.reset();
irsend.sendRCMM(0x55, 8);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRCMM(&irsend.capture, kStartOffset, 8, false));
EXPECT_EQ(RCMM, irsend.capture.decode_type);
EXPECT_EQ(8, irsend.capture.bits);
EXPECT_EQ(0x55, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
ASSERT_TRUE(irrecv.decodeRCMM(&irsend.capture, kStartOffset, 12, false));
EXPECT_EQ(RCMM, irsend.capture.decode_type);
EXPECT_EQ(8, irsend.capture.bits);
EXPECT_EQ(0x55, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
// Illegal RCMM 36-bit message.
irsend.reset();
irsend.sendRCMM(0x123456789, 36);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeRCMM(&irsend.capture, kStartOffset, 12, false));
EXPECT_EQ(RCMM, irsend.capture.decode_type);
EXPECT_EQ(36, irsend.capture.bits);
EXPECT_EQ(0x123456789, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
ASSERT_TRUE(irrecv.decodeRCMM(&irsend.capture, kStartOffset, 24, false));
EXPECT_EQ(36, irsend.capture.bits);
EXPECT_EQ(0x123456789, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
ASSERT_TRUE(irrecv.decodeRCMM(&irsend.capture, kStartOffset, 36, false));
EXPECT_EQ(RCMM, irsend.capture.decode_type);
EXPECT_EQ(36, irsend.capture.bits);
EXPECT_EQ(0x123456789, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
// Decode (non-standard) 64-bit messages.
TEST(TestDecodeRCMM, Decode64BitMessages) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Illegal value & size RCMM 64-bit message.
irsend.sendRCMM(0xFEDCBA9876543210, 64);
irsend.makeDecodeResult();
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeRCMM(&irsend.capture, kStartOffset, 64, false));
EXPECT_EQ(RCMM, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFEDCBA9876543210, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
}
// Fail to decode a non-RCMM example via GlobalCache
TEST(TestDecodeRCMM, FailToDecodeNonRCMMExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Modified a few entries to unexpected values, based on previous test case.
uint16_t gc_test[39] = {38000, 1, 1, 322, 162, 20, 61, 20, 61, 20,
20, 20, 20, 20, 20, 20, 127, 20, 61, 9,
20, 20, 61, 20, 20, 20, 61, 20, 61, 20,
61, 20, 20, 20, 20, 20, 20, 20, 884};
irsend.sendGC(gc_test, 39);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeRCMM(&irsend.capture));
ASSERT_FALSE(irrecv.decodeRCMM(&irsend.capture, kStartOffset, kRCMMBits,
false));
}
// Issue 281 Debugging
TEST(TestDecodeRCMM, DebugIssue281) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Data from Issue #281 (shortened version)
uint16_t
rawData[36] = {448, 276, 150, 285, 164, 613, 163, 447, 162, 613,
164, 445, 164, 776, 167, 278, 163, 280, 163, 280,
162, 611, 168, 444, 163, 612, 164, 277, 168, 447,
157, 282, 165, 276, 165, 65535}; // Last value modified
// from 89729
irsend.reset();
irsend.sendRaw(rawData, 36, 36);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(RCMM, irsend.capture.decode_type);
EXPECT_EQ(32, irsend.capture.bits);
EXPECT_EQ(0x26702610, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,259 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for encodeSanyoLC7461().
TEST(TestEncodeSanyoLC7461, NormalEncoding) {
IRsendTest irsend(4);
EXPECT_EQ(0x1FFF00FF, irsend.encodeSanyoLC7461(0, 0));
EXPECT_EQ(0x3FFE01FE, irsend.encodeSanyoLC7461(1, 1));
EXPECT_EQ(0x3FFE02FD, irsend.encodeSanyoLC7461(1, 2));
EXPECT_EQ(0x3FFE000FF00, irsend.encodeSanyoLC7461(0x1FFF, 0xFF));
EXPECT_EQ(0x2AAAAAA55AA, irsend.encodeSanyoLC7461(0x1555, 0x55));
EXPECT_EQ(0x3FFE000FF00, irsend.encodeSanyoLC7461(0xFFFF, 0xFF));
EXPECT_EQ(0x1D8113F00FF, irsend.encodeSanyoLC7461(0xEC0, 0x0));
}
// Tests for sendSanyoLC7461().
// Test sending typical data only.
TEST(TestEncodeSanyoLC7461, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendSanyoLC7461(0x1D8113F00FF);
EXPECT_EQ(
"f38000d33"
"m8960s4480"
"m560s560m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s23520",
irsend.outputStr());
}
// Test sending with different repeats.
TEST(TestEncodeSanyoLC7461, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendSanyoLC7461(0x1D8113F00FF, kSanyoLC7461Bits, 1); // 1 repeat.
EXPECT_EQ(
"f38000d33"
"m8960s4480"
"m560s560m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s560"
"m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s560m560s560m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s1680m560s1680m560s23520"
"m8960s2240m560s96320",
irsend.outputStr());
}
// Tests for decodeSanyoLC7461().
// Decode normal Sanyo LC7461 messages.
TEST(TestDecodeSanyoLC7461, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Sanyo LC7461 42-bit message.
irsend.reset();
irsend.sendSanyoLC7461(0x1D8113F00FF);
irsend.makeDecodeResult();
ASSERT_TRUE(
irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, kSanyoLC7461Bits,
true));
EXPECT_EQ(SANYO_LC7461, irsend.capture.decode_type);
EXPECT_EQ(kSanyoLC7461Bits, irsend.capture.bits);
EXPECT_EQ(0x1D8113F00FF, irsend.capture.value);
EXPECT_EQ(0xEC0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Synthesised Normal Sanyo LC7461 42-bit message.
irsend.reset();
irsend.sendSanyoLC7461(irsend.encodeSanyoLC7461(0x1234, 0x56));
irsend.makeDecodeResult();
ASSERT_TRUE(
irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, kSanyoLC7461Bits,
true));
EXPECT_EQ(SANYO_LC7461, irsend.capture.decode_type);
EXPECT_EQ(kSanyoLC7461Bits, irsend.capture.bits);
EXPECT_EQ(0x2468DCB56A9, irsend.capture.value);
EXPECT_EQ(0x1234, irsend.capture.address);
EXPECT_EQ(0x56, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Synthesised Normal Sanyo LC7461 42-bit message.
irsend.reset();
irsend.sendSanyoLC7461(irsend.encodeSanyoLC7461(0x1, 0x1));
irsend.makeDecodeResult();
ASSERT_TRUE(
irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, kSanyoLC7461Bits,
true));
EXPECT_EQ(SANYO_LC7461, irsend.capture.decode_type);
EXPECT_EQ(kSanyoLC7461Bits, irsend.capture.bits);
EXPECT_EQ(0x3FFE01FE, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x1, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode normal repeated Sanyo LC7461 messages.
TEST(TestDecodeSanyoLC7461, NormalDecodeWithRepeatAndStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Sanyo LC7461 16-bit message with 1 repeat.
irsend.reset();
irsend.sendSanyoLC7461(0x3FFE01FE, kSanyoLC7461Bits, 1);
irsend.makeDecodeResult();
ASSERT_TRUE(
irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, kSanyoLC7461Bits,
true));
EXPECT_EQ(SANYO_LC7461, irsend.capture.decode_type);
EXPECT_EQ(kSanyoLC7461Bits, irsend.capture.bits);
EXPECT_EQ(0x3FFE01FE, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x1, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode unsupported Sanyo LC7461 messages.
TEST(TestDecodeSanyoLC7461, DecodeWithNonStrictValues) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendSanyoLC7461(0x0); // Illegal value Sanyo LC7461 message.
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(
irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, kSanyoLC7461Bits,
true));
// Should pass if strict off.
ASSERT_TRUE(
irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, kSanyoLC7461Bits,
false));
EXPECT_EQ(SANYO_LC7461, irsend.capture.decode_type);
EXPECT_EQ(kSanyoLC7461Bits, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
// Illegal value Sanyo LC7461 42-bit message.
irsend.sendSanyoLC7461(0x1234567890A);
irsend.makeDecodeResult();
ASSERT_FALSE(
irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, kSanyoLC7461Bits,
true));
// Should fail with strict when we ask for the wrong bit size.
ASSERT_FALSE(irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, 32,
true));
ASSERT_FALSE(irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, 64,
true));
// And should fail for a bad value.
ASSERT_FALSE(
irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, kSanyoLC7461Bits,
true));
// Should pass if strict off.
ASSERT_TRUE(
irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, kSanyoLC7461Bits,
false));
EXPECT_EQ(SANYO_LC7461, irsend.capture.decode_type);
EXPECT_EQ(kSanyoLC7461Bits, irsend.capture.bits);
EXPECT_EQ(0x1234567890A, irsend.capture.value);
EXPECT_EQ(0x91A, irsend.capture.address);
EXPECT_EQ(0x89, irsend.capture.command);
// Shouldn't pass if strict off and looking for a smaller size.
ASSERT_FALSE(irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, 34,
false));
}
// Decode (non-standard) 64-bit messages.
TEST(TestDecodeSanyoLC7461, Decode64BitMessages) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Illegal value & size Sanyo LC7461 64-bit message.
irsend.sendSanyoLC7461(0xFFFFFFFFFFFFFFFF, 64);
irsend.makeDecodeResult();
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, 64,
false));
EXPECT_EQ(SANYO_LC7461, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, irsend.capture.value);
EXPECT_EQ(0xFFFF, irsend.capture.address);
EXPECT_EQ(0xFF, irsend.capture.command);
}
// Decode a 'real' example via GlobalCache
TEST(TestDecodeSanyoLC7461, DecodeGlobalCacheExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
uint16_t gc_test[95] = {
38000, 1, 89, 342, 171, 21, 21, 21, 64, 21, 64, 21, 64, 21, 21, 21,
64, 21, 64, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
64, 21, 21, 21, 21, 21, 21, 21, 64, 21, 21, 21, 21, 21, 64, 21,
64, 21, 64, 21, 64, 21, 64, 21, 64, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 64, 21, 64, 21, 64, 21,
64, 21, 64, 21, 64, 21, 64, 21, 64, 21, 875, 342, 171, 21, 3565};
irsend.sendGC(gc_test, 95);
irsend.makeDecodeResult();
ASSERT_TRUE(
irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, kSanyoLC7461Bits,
true));
EXPECT_EQ(SANYO_LC7461, irsend.capture.decode_type);
EXPECT_EQ(kSanyoLC7461Bits, irsend.capture.bits);
EXPECT_EQ(0x1D8113F00FF, irsend.capture.value);
EXPECT_EQ(0xEC0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Confirm what the 42-bit NEC decode is.
ASSERT_TRUE(irrecv.decodeNEC(&irsend.capture, kStartOffset, 42, false));
EXPECT_EQ(0x1D8113F00FF, irsend.capture.value);
}
// Fail to decode a non-Sanyo LC7461 example via GlobalCache
TEST(TestDecodeSanyoLC7461, FailToDecodeNonSanyoLC7461Example) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Modified a few entries to unexpected values, based on previous test case.
uint16_t gc_test[39] = {38000, 1, 1, 322, 162, 20, 61, 20, 61, 20,
20, 20, 20, 20, 20, 20, 127, 20, 61, 9,
20, 20, 61, 20, 20, 20, 61, 20, 61, 20,
61, 20, 20, 20, 20, 20, 20, 20, 884};
irsend.sendGC(gc_test, 39);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeSanyoLC7461(&irsend.capture));
ASSERT_FALSE(
irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, kSanyoLC7461Bits,
false));
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,81 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendSherwood().
// Test sending typical data only.
TEST(TestSendSherwood, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendSherwood(0xC1A28877);
EXPECT_EQ(
"f38000d33"
"m8960s4480m560s1680m560s1680m560s560m560s560m560s560m560s560"
"m560s560m560s1680m560s1680m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s560m560s560"
"m560s1680m560s560m560s560m560s560m560s560m560s1680m560s1680"
"m560s1680m560s560m560s1680m560s1680m560s1680m560s42560"
"m8960s2240m560s96320",
irsend.outputStr());
}
// Test sending typical data with extra repeats.
TEST(TestSendSherwood, SendDataWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendSherwood(0xC1A28877, 32, 2);
EXPECT_EQ(
"f38000d33"
"m8960s4480m560s1680m560s1680m560s560m560s560m560s560m560s560"
"m560s560m560s1680m560s1680m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s560m560s560"
"m560s1680m560s560m560s560m560s560m560s560m560s1680m560s1680"
"m560s1680m560s560m560s1680m560s1680m560s1680m560s42560"
"m8960s2240m560s96320"
"m8960s2240m560s96320",
irsend.outputStr());
}
// Test sending typical data with explicit no repeats.
TEST(TestSendSherwood, SendDataWithZeroRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendSherwood(0xC1A28877, 32, 0);
// Should have a single NEC repeat, as we always send one.
EXPECT_EQ(
"f38000d33"
"m8960s4480m560s1680m560s1680m560s560m560s560m560s560m560s560"
"m560s560m560s1680m560s1680m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s560m560s560"
"m560s1680m560s560m560s560m560s560m560s560m560s1680m560s1680"
"m560s1680m560s560m560s1680m560s1680m560s1680m560s42560"
"m8960s2240m560s96320",
irsend.outputStr());
}
// Test that a typical Sherwood send decodes as the appropriate NEC value.
TEST(TestSendSherwood, DecodesAsNEC) {
IRsendTest irsend(4);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
irsend.sendSherwood(0xC1A28877);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(kNECBits, irsend.capture.bits);
EXPECT_EQ(0xC1A28877, irsend.capture.value);
EXPECT_EQ(0x4583, irsend.capture.address);
EXPECT_EQ(0x11, irsend.capture.command);
}

View File

@@ -0,0 +1,610 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendSony().
// Test sending typical data only.
TEST(TestSendSony, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendSony(0);
// We expect three 20-bit commands to be sent.
EXPECT_EQ(
"f40000d33"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s18600"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s18600"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s18600",
irsend.outputStr());
irsend.reset();
irsend.sendSony(0x240C, kSony20Bits);
// We expect three 20-bit commands to be sent.
EXPECT_EQ(
"f40000d33"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s16200"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s16200"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s16200",
irsend.outputStr());
irsend.reset();
irsend.sendSony(0x240C, kSony15Bits);
// We expect three 15-bit commands to be sent.
EXPECT_EQ(
"f40000d33"
"m2400s600m600s600m1200s600m600s600m600s600m1200s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
"m600s22200"
"m2400s600m600s600m1200s600m600s600m600s600m1200s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
"m600s22200"
"m2400s600m600s600m1200s600m600s600m600s600m1200s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
"m600s22200",
irsend.outputStr());
irsend.reset();
irsend.sendSony(0xA90, kSony12Bits);
// We expect three 15-bit commands to be sent.
EXPECT_EQ(
"f40000d33"
"m2400s600m1200s600m600s600m1200s600m600s600m1200s600m600s600"
"m600s600m1200s600m600s600m600s600m600s600m600s25800"
"m2400s600m1200s600m600s600m1200s600m600s600m1200s600m600s600"
"m600s600m1200s600m600s600m600s600m600s600m600s25800"
"m2400s600m1200s600m600s600m1200s600m600s600m1200s600m600s600"
"m600s600m1200s600m600s600m600s600m600s600m600s25800",
irsend.outputStr());
}
// Test sending with different repeats.
TEST(TestSendSony, SendWithDiffRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendSony(0x240C, kSony20Bits, 0); // Send a command with 0 repeats.
EXPECT_EQ(
"f40000d33"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s16200",
irsend.outputStr());
irsend.sendSony(0x240C, kSony20Bits, 1); // Send a command with 1 repeat.
EXPECT_EQ(
"f40000d33"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s16200"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s16200",
irsend.outputStr());
irsend.sendSony(0x240C, kSony20Bits, 3); // Send a command with 3 repeats.
EXPECT_EQ(
"f40000d33"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s16200"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s16200"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s16200"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s16200",
irsend.outputStr());
}
// Tests for encodeSony().
TEST(TestEncodeSony, NormalSonyEncoding) {
IRsendTest irsend(4);
EXPECT_EQ(0x0, irsend.encodeSony(kSony12Bits, 0, 0));
EXPECT_EQ(0xA90, irsend.encodeSony(kSony12Bits, 21, 1));
EXPECT_EQ(0xFFF, irsend.encodeSony(kSony12Bits, 0x7F, 0x1F));
EXPECT_EQ(0x0, irsend.encodeSony(kSony15Bits, 0, 0));
EXPECT_EQ(0x5480, irsend.encodeSony(kSony15Bits, 21, 1));
EXPECT_EQ(0x5455, irsend.encodeSony(kSony15Bits, 21, 0xAA));
EXPECT_EQ(0x7FFF, irsend.encodeSony(kSony15Bits, 0x7F, 0xFF));
EXPECT_EQ(0x0, irsend.encodeSony(kSony20Bits, 0, 0, 0));
EXPECT_EQ(0x81080, irsend.encodeSony(kSony20Bits, 1, 1, 1));
EXPECT_EQ(0xFFFFF, irsend.encodeSony(kSony20Bits, 0x7F, 0x1F, 0xFF));
}
TEST(TestEncodeSony, SonyEncodingWithOversizedValues) {
IRsendTest irsend(4);
EXPECT_EQ(0xFFF, irsend.encodeSony(kSony12Bits, 0xFFFF, 0xFFFF));
EXPECT_EQ(0x7FFF, irsend.encodeSony(kSony15Bits, 0xFFFF, 0xFFFF));
EXPECT_EQ(0xFFFFF, irsend.encodeSony(kSony20Bits, 0xFFFF, 0xFFFF, 0xFFFF));
}
// Tests for decodeSony().
// Decode normal Sony messages.
TEST(TestDecodeSony, NormalSonyDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Synthesised Normal Sony 20-bit message.
irsend.reset();
irsend.sendSony(irsend.encodeSony(kSony20Bits, 0x1, 0x1, 0x1));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(kSony20Bits, irsend.capture.bits);
EXPECT_EQ(0x81080, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x81, irsend.capture.command);
// Synthesised Normal Sony 15-bit message.
irsend.reset();
irsend.sendSony(irsend.encodeSony(kSony15Bits, 21, 1), kSony15Bits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(kSony15Bits, irsend.capture.bits);
EXPECT_EQ(0x5480, irsend.capture.value);
EXPECT_EQ(1, irsend.capture.address);
EXPECT_EQ(21, irsend.capture.command);
// Synthesised Normal Sony 12-bit message.
irsend.reset();
irsend.sendSony(irsend.encodeSony(kSony12Bits, 21, 1), kSony12Bits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(kSony12Bits, irsend.capture.bits);
EXPECT_EQ(0xA90, irsend.capture.value);
EXPECT_EQ(1, irsend.capture.address);
EXPECT_EQ(21, irsend.capture.command);
}
// Decode unexpected Sony messages. i.e longer than minimum etc.
TEST(TestDecodeSony, SonyDecodeWithUnexpectedLegalSize) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Synthesised Normal Sony 20-bit message decoded when looking for 12-bits
irsend.reset();
irsend.sendSony(irsend.encodeSony(kSony20Bits, 0x1, 0x1, 0x1));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSonyMinBits));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(kSony20Bits, irsend.capture.bits);
EXPECT_EQ(0x81080, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x81, irsend.capture.command);
// Synthesised Normal Sony 12-bit message when expecting 20-bits.
irsend.reset();
irsend.sendSony(irsend.encodeSony(kSony12Bits, 21, 1), kSony12Bits);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony20Bits));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(kSony12Bits, irsend.capture.bits);
EXPECT_EQ(0xA90, irsend.capture.value);
EXPECT_EQ(1, irsend.capture.address);
EXPECT_EQ(21, irsend.capture.command);
// 12-bit message should be regected when using strict and a different size.
irsend.reset();
irsend.sendSony(irsend.encodeSony(kSony12Bits, 21, 1), kSony12Bits);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony20Bits,
true));
ASSERT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony15Bits,
true));
// 15-bit message should be regected when using strict and a different size.
irsend.reset();
irsend.sendSony(irsend.encodeSony(kSony15Bits, 21, 1), kSony15Bits);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony12Bits,
true));
ASSERT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony20Bits,
true));
// 20-bit message should be regected when using strict and a different size.
irsend.reset();
irsend.sendSony(irsend.encodeSony(kSony20Bits, 1, 1, 1), kSony20Bits);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony12Bits,
true));
ASSERT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony15Bits,
true));
}
// Decode unsupported Sony messages. i.e non-standard sizes.
TEST(TestDecodeSony, SonyDecodeWithIllegalSize) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendSony(0xFF, 8); // Illegal 8-bit Sony-like message.
irsend.makeDecodeResult();
// Should fail with strict on.
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSonyMinBits,
true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony12Bits,
true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony15Bits,
true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony20Bits,
true));
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(8, irsend.capture.bits);
EXPECT_EQ(0xFF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
irsend.sendSony(0x1FFF, 13); // Illegal 13-bit Sony-like message.
irsend.makeDecodeResult();
// Should fail with strict on.
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSonyMinBits,
true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony12Bits,
true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony15Bits,
true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony20Bits,
true));
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(13, irsend.capture.bits);
EXPECT_EQ(0x1FFF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
irsend.sendSony(0x1FFFF, 17); // Illegal 17-bit Sony-like message.
irsend.makeDecodeResult();
// Should fail with strict on.
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSonyMinBits,
true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony12Bits,
true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony15Bits,
true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony20Bits,
true));
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(17, irsend.capture.bits);
EXPECT_EQ(0x1FFFF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
irsend.sendSony(0x1FFFFF, 21); // Illegal 21-bit Sony-like message.
irsend.makeDecodeResult();
// Should fail with strict on.
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSonyMinBits,
true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony12Bits,
true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony15Bits,
true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony20Bits,
true));
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(21, irsend.capture.bits);
EXPECT_EQ(0x1FFFFF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
// Illegal 64-bit (max) Sony-like message.
irsend.sendSony(0xFFFFFFFFFFFFFFFF, 64, 0);
irsend.makeDecodeResult();
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
TEST(TestDecodeSony, DecodeGlobalCacheExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Sony "Power On" from Global Cache.
uint16_t gc_test[29] = {40000, 1, 1, 96, 24, 24, 24, 48, 24, 48,
24, 48, 24, 24, 24, 48, 24, 24, 24, 48,
24, 24, 24, 24, 24, 24, 24, 24, 1013};
irsend.sendGC(gc_test, 29);
irsend.makeDecodeResult();
// Without strict.
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(12, irsend.capture.bits);
EXPECT_EQ(0x750, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x2E, irsend.capture.command);
// With strict and correct size.
ASSERT_TRUE(irrecv.decodeSony(&irsend.capture, kStartOffset, kSony12Bits,
true));
}
// Encoding & Decode 20 bit Sony messages. Issue #476
TEST(TestEncodeSony, Issue476) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
irsend.sendSony(0x6AB47, 20);
irsend.makeDecodeResult();
// Without strict.
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(20, irsend.capture.bits);
EXPECT_EQ(0x6AB47, irsend.capture.value); // 20 bits
EXPECT_EQ(0x1A, irsend.capture.address); // 5 bits
EXPECT_EQ(0x7156, irsend.capture.command); // 15 bits
EXPECT_EQ(0x56, 0x7156 & 0x7F); // command (lower 7 bits)
EXPECT_EQ(0xE2, (0x7156 >> 7) & 0xFF); // extended (top 8 of 15 bits)
EXPECT_EQ(0x6AB47, irsend.encodeSony(20, 0x56, 0x1A, 0xE2));
}
// Encoding & Decode 15 bit Sony messages. Issue #1018
TEST(TestEncodeSony, Issue1018) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
irsend.sendSony(0x240C, 15);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(15, irsend.capture.bits);
EXPECT_EQ(0x240C, irsend.capture.value); // 15 bits
EXPECT_EQ(0x30, irsend.capture.address);
EXPECT_EQ(0x12, irsend.capture.command);
EXPECT_EQ(
"f40000d33"
"m2400s600" // Message
"m600s600m1200s600m600s600m600s600m1200s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
"m600s22200"
"m2400s600" // Repeat #1
"m600s600m1200s600m600s600m600s600m1200s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
"m600s22200"
"m2400s600" // Repeat #2
"m600s600m1200s600m600s600m600s600m1200s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
"m600s22200",
irsend.outputStr());
irsend.reset();
uint16_t rawData[127] = {
2448, 550,
648, 544, 1250, 546, 648, 548, 648, 550, 1272, 524, 648, 550, 644, 550,
674, 524, 648, 550, 648, 544, 674, 524, 1270, 524, 1246, 550, 674, 524,
648, 22404,
2474, 524,
674, 520, 1250, 548, 648, 544, 674, 524, 1270, 524, 648, 550, 648, 546,
674, 524, 648, 546, 652, 546, 674, 524, 1270, 524, 1272, 522, 674, 520,
648, 22404,
2452, 544,
674, 524, 1270, 524, 674, 518, 674, 522, 1246, 550, 674, 524, 648, 544,
674, 524, 648, 546, 674, 524, 674, 518, 1276, 518, 1276, 524, 648, 546,
674, 22380,
2474, 520,
674, 524, 1250, 544, 674, 524, 674, 518, 1276, 520, 674, 522, 674, 524,
674, 520, 674, 524, 674, 524, 674, 518, 1276, 518, 1276, 524, 672, 524,
648}; // SONY 240C
irsend.sendRaw(rawData, 127, 40);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(15, irsend.capture.bits);
EXPECT_EQ(0x240C, irsend.capture.value); // 15 bits
EXPECT_EQ(0x30, irsend.capture.address);
EXPECT_EQ(0x12, irsend.capture.command);
EXPECT_EQ(
"f40000d50"
"m2448s550" // Message
"m648s544m1250s546m648s548m648s550m1272s524m648s550m644s550"
"m674s524m648s550m648s544m674s524m1270s524m1246s550m674s524"
"m648s22404"
"m2474s524" // Repeat #1
"m674s520m1250s548m648s544m674s524m1270s524m648s550m648s546"
"m674s524m648s546m652s546m674s524m1270s524m1272s522m674s520"
"m648s22404"
"m2452s544" // Repeat #2
"m674s524m1270s524m674s518m674s522m1246s550m674s524m648s544"
"m674s524m648s546m674s524m674s518m1276s518m1276s524m648s546"
"m674s22380"
"m2474s520" // Repeat #3
"m674s524m1250s544m674s524m674s518m1276s520m674s522m674s524"
"m674s520m674s524m674s524m674s518m1276s518m1276s524m672s524"
"m648",
irsend.outputStr());
// Now see if we can reproduce it with `sendSony`
irsend.reset();
irsend.sendSony(0x240C, 15, 3);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(15, irsend.capture.bits);
EXPECT_EQ(0x240C, irsend.capture.value); // 15 bits
EXPECT_EQ(0x30, irsend.capture.address);
EXPECT_EQ(0x12, irsend.capture.command);
// Compare expected result with real `rawData` result.
// Comparison notes:
// * Seems visually the same. i.e. '1' where '1's should be etc.
// * Timings are *roughly* the same. They should be within device
// tollerance.
// TL;DR: Looks fine/the same/as expected.
EXPECT_EQ(
"f40000d33"
"m2400s600" // Message
// "m2448s550" (Commented out data is from `rawData` sample above.)
"m600s600m1200s600m600s600m600s600m1200s600m600s600m600s600"
// "m648s544m1250s546m648s548m648s550m1272s524m648s550m644s550"
"m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
// "m674s524m648s550m648s544m674s524m1270s524m1246s550m674s524"
"m600s22200"
// "m648s22404"
"m2400s600" // Repeat #1
// "m2474s524"
"m600s600m1200s600m600s600m600s600m1200s600m600s600m600s600"
// "m674s520m1250s548m648s544m674s524m1270s524m648s550m648s546"
"m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
// "m674s524m648s546m652s546m674s524m1270s524m1272s522m674s520"
"m600s22200"
// "m648s22404"
"m2400s600" // Repeat #2
// "m2452s544"
"m600s600m1200s600m600s600m600s600m1200s600m600s600m600s600"
// "m674s524m1270s524m674s518m674s522m1246s550m674s524m648s544"
"m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
// "m674s524m648s546m674s524m674s518m1276s518m1276s524m648s546"
"m600s22200"
// "m674s22380"
"m2400s600" // Repeat #3
// "m2474s520"
"m600s600m1200s600m600s600m600s600m1200s600m600s600m600s600"
// "m674s524m1250s544m674s524m674s518m1276s520m674s522m674s524"
"m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
// "m674s520m674s524m674s524m674s518m1276s518m1276s524m672s524"
"m600s22200",
// "m648" // (Trailing space is ignored in real captures.)
irsend.outputStr());
// Now see if we can reproduce it with `sendSony38`
irsend.reset();
irsend.sendSony38(0x240C, 15);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(15, irsend.capture.bits);
EXPECT_EQ(0x240C, irsend.capture.value); // 15 bits
EXPECT_EQ(0x30, irsend.capture.address);
EXPECT_EQ(0x12, irsend.capture.command);
}
// Test sending typical data only.
TEST(TestSendSony38, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
irsend.sendSony38(0);
// We expect three 20-bit commands to be sent.
EXPECT_EQ(
"f38000d33"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s18600"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s18600"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s18600"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s18600",
irsend.outputStr());
irsend.reset();
irsend.sendSony38(0x240C, kSony20Bits);
// We expect three 20-bit commands to be sent.
EXPECT_EQ(
"f38000d33"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s16200"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s16200"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s16200"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s16200",
irsend.outputStr());
irsend.reset();
irsend.sendSony38(0x240C, kSony15Bits);
// We expect three 15-bit commands to be sent.
EXPECT_EQ(
"f38000d33"
"m2400s600m600s600m1200s600m600s600m600s600m1200s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
"m600s22200"
"m2400s600m600s600m1200s600m600s600m600s600m1200s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
"m600s22200"
"m2400s600m600s600m1200s600m600s600m600s600m1200s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
"m600s22200"
"m2400s600m600s600m1200s600m600s600m600s600m1200s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
"m600s22200",
irsend.outputStr());
irsend.reset();
irsend.sendSony38(0xA90, kSony12Bits);
// We expect three 15-bit commands to be sent.
EXPECT_EQ(
"f38000d33"
"m2400s600m1200s600m600s600m1200s600m600s600m1200s600m600s600"
"m600s600m1200s600m600s600m600s600m600s600m600s25800"
"m2400s600m1200s600m600s600m1200s600m600s600m1200s600m600s600"
"m600s600m1200s600m600s600m600s600m600s600m600s25800"
"m2400s600m1200s600m600s600m1200s600m600s600m1200s600m600s600"
"m600s600m1200s600m600s600m600s600m600s600m600s25800"
"m2400s600m1200s600m600s600m1200s600m600s600m1200s600m600s600"
"m600s600m1200s600m600s600m600s600m600s600m600s25800",
irsend.outputStr());
}

View File

@@ -0,0 +1,198 @@
// Copyright 2020 David Conran
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendSymphony().
// Test sending typical data only.
TEST(TestSendSymphony, SendDataOnly) {
IRsendTest irsend(kGpioUnused);
irsend.begin();
irsend.sendSymphony(0xD90);
EXPECT_EQ(
"f38000d50"
"m1250s400m1250s400m400s1250m1250s400m1250s400m400s1250m400s1250m1250s400"
"m400s1250m400s1250m400s1250"
"m400s7850"
"m1250s400m1250s400m400s1250m1250s400m1250s400m400s1250m400s1250m1250s400"
"m400s1250m400s1250m400s1250"
"m400s7850"
"m1250s400m1250s400m400s1250m1250s400m1250s400m400s1250m400s1250m1250s400"
"m400s1250m400s1250m400s1250"
"m400s7850"
"m1250s400m1250s400m400s1250m1250s400m1250s400m400s1250m400s1250m1250s400"
"m400s1250m400s1250m400s1250"
"m400s7850",
irsend.outputStr());
}
// Tests for decodeSymphony().
// Decode normal Symphony messages.
TEST(TestDecodeSymphony, SyntheticSelfDecode) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
// Real-life Symphony code from an actual capture/decode.
irsend.reset();
irsend.sendSymphony(0x123);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type);
EXPECT_EQ(kSymphonyBits, irsend.capture.bits);
EXPECT_EQ(0x123, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode a real Symphony message.
TEST(TestDecodeSymphony, RealMessageDecode) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
// Real-life Symphony code from an actual capture/decode.
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1057#issue-577216614
irsend.reset();
const uint16_t button_1[95] = {
1296, 412, 1294, 386, 420, 1224, 1322, 390, 1290, 390, 420, 1224, 452,
1220, 1314, 394, 420, 1222, 482, 1190, 480, 1192, 452, 7960,
1290, 420, 1290, 390, 418, 1226, 1318, 394, 1262, 416, 420, 1224, 454,
1220, 1292, 416, 422, 1222, 450, 1222, 452, 1218, 454, 8208,
1296, 414, 1292, 386, 418, 1226, 1292, 422, 1260, 420, 424, 1218, 454,
1226, 1312, 390, 420, 1224, 454, 1220, 482, 1186, 454, 7960,
1318, 392, 1264, 416, 392, 1252, 1318, 394, 1288, 394, 418, 1224, 452,
1224, 1292, 422, 414, 1222, 458, 1214, 450, 1222, 454};
irsend.sendRaw(button_1, 95, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type);
EXPECT_EQ(kSymphonyBits, irsend.capture.bits);
EXPECT_EQ(0xD90, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1057#issuecomment-596038442
irsend.reset();
const uint16_t power[23] = {
1308, 368, 1310, 368, 448, 1222, 1310, 372, 1308, 400, 442, 1198, 472,
1198, 1284, 396, 444, 1224, 470, 1200, 470, 1198, 472};
irsend.sendRaw(power, 23, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeSymphony(&irsend.capture));
EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type);
EXPECT_EQ(kSymphonyBits, irsend.capture.bits);
EXPECT_EQ(0xD90, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
irsend.reset();
const uint16_t swing[23] = {
1290, 418, 1286, 392, 422, 1248, 1284, 400, 1294, 386, 422, 1248, 422,
1250, 444, 1228, 424, 1248, 446, 1226, 1258, 420, 446};
irsend.sendRaw(swing, 23, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type);
EXPECT_EQ(kSymphonyBits, irsend.capture.bits);
EXPECT_EQ(0xD82, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1057#issuecomment-596543641
TEST(TestDecodeSymphony, RealMessageSentViaLibrary) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
// Generated by the library/ESP8266.
const uint16_t rawdata_lib[47] = {
1222, 430, 1250, 436, 410, 1242, 1274, 446, 1274, 412, 414, 1266, 410,
1264, 1252, 436, 436, 1240, 410, 1270, 438, 1242, 410, 8012, 1254, 434,
1258, 432, 438, 1240, 1276, 416, 1252, 434, 438, 1234, 412, 1270, 1250,
442, 412, 1264, 438, 1238, 410, 1270, 438};
irsend.sendRaw(rawdata_lib, 47, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type);
EXPECT_EQ(kSymphonyBits, irsend.capture.bits);
EXPECT_EQ(0xD90, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
irsend.reset();
// Generated by the real remote.
const uint16_t rawdata_remote[47] = {
1286, 396, 1286, 396, 446, 1226, 1288, 400, 1294, 388, 444, 1228, 446,
1226, 1286, 396, 444, 1226, 448, 1226, 468, 1204, 448, 7968, 1286, 396,
1286, 396, 470, 1202, 1286, 400, 1286, 396, 446, 1224, 448, 1226, 1288,
396, 446, 1226, 472, 1200, 448, 1226, 472};
irsend.sendRaw(rawdata_remote, 47, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type);
EXPECT_EQ(kSymphonyBits, irsend.capture.bits);
EXPECT_EQ(0xD90, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode a real SM5021 generated message.
// Note: This used to fail because it had a "long" mark before the gap in mesg.
TEST(TestDecodeSymphony, Issue1105) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1105#issuecomment-625327833
irsend.reset();
uint16_t rawData[191] = {
1324, 372, 1322, 398, 448, 1218, 476, 1216, 478, 1216, 478, 1218, 478,
1218, 476, 1218, 476, 1220, 474, 1220, 474, 1220, 1346, 7128, 1320, 402,
1290, 404, 440, 1252, 442, 1254, 440, 1254, 440, 1254, 440, 1254, 440,
1254, 440, 1254, 442, 1254, 440, 1254, 1288, 7186, 1288, 408, 1286, 408,
438, 1254, 440, 1254, 440, 1254, 440, 1254, 440, 1254, 440, 1256, 440,
1254, 440, 1254, 440, 1254, 1288, 7186, 1288, 408, 1286, 408, 438, 1254,
440, 1256, 440, 1254, 440, 1254, 440, 1254, 440, 1254, 438, 1256, 438,
1256, 440, 1254, 1288, 7188, 1288, 408, 1286, 408, 438, 1256, 438, 1256,
440, 1254, 438, 1256, 438, 1256, 438, 1256, 438, 1256, 438, 1256, 440,
1254, 1288, 7188, 1286, 408, 1286, 408, 440, 1254, 438, 1256, 438, 1256,
438, 1256, 440, 1254, 438, 1254, 440, 1256, 438, 1256, 440, 1256, 438,
8038, 1284, 408, 1286, 408, 438, 1282, 412, 1282, 414, 1280, 414, 1280,
414, 1282, 414, 1280, 412, 1276, 412, 1286, 414, 1282, 412, 8062, 1260,
434, 1262, 432, 414, 1280, 414, 1282, 412, 1282, 412, 1282, 412, 1282,
414, 1280, 414, 1282, 412, 1282, 412, 1282, 412}; // UNKNOWN 827AA7B
irsend.sendRaw(rawData, 191, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type);
EXPECT_EQ(kSymphonyBits, irsend.capture.bits);
EXPECT_EQ(0xC01, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
TEST(TestUtils, Housekeeping) {
ASSERT_EQ("SYMPHONY", typeToString(decode_type_t::SYMPHONY));
ASSERT_EQ(decode_type_t::SYMPHONY, strToDecodeType("SYMPHONY"));
ASSERT_FALSE(hasACState(decode_type_t::SYMPHONY));
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::SYMPHONY));
ASSERT_EQ(kSymphonyBits, IRsendTest::defaultBits(decode_type_t::SYMPHONY));
ASSERT_EQ(kSymphonyDefaultRepeat,
IRsendTest::minRepeats(decode_type_t::SYMPHONY));
}

View File

@@ -0,0 +1,462 @@
// Copyright 2019 David Conran
#include "ir_Tcl.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// General housekeeping
TEST(TestTcl112Ac, Housekeeping) {
ASSERT_EQ("TCL112AC", typeToString(TCL112AC));
ASSERT_TRUE(hasACState(TCL112AC));
}
// Tests for decodeTcl112Ac().
// Decode a real Tcl112Ac A/C example from Issue #619
TEST(TestDecodeTcl112Ac, DecodeRealExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
// Tcl112Ac A/C example from Issue #619 On.txt
uint16_t rawData[227] = {
3030, 1658, 494, 1066, 494, 1068, 498, 320, 494,
326, 498, 320, 494, 1068, 500, 320, 494, 332,
494, 1068, 500, 1062, 496, 324, 492, 1044, 524,
322, 492, 326, 498, 1062, 494, 1074, 494, 326,
500, 1062, 496, 1066, 490, 328, 496, 322, 492,
1070, 498, 322, 494, 332, 492, 1068, 498, 320,
494, 326, 498, 320, 496, 324, 500, 320, 494,
324, 490, 336, 500, 320, 496, 324, 490, 328,
496, 322, 492, 328, 498, 322, 492, 326, 498,
328, 496, 322, 492, 328, 498, 1064, 494, 326,
498, 320, 494, 1066, 490, 330, 496, 330, 494,
1066, 490, 1070, 498, 322, 492, 328, 498, 322,
492, 326, 498, 322, 492, 332, 492, 1068, 498,
1062, 494, 1066, 500, 318, 496, 324, 490, 328,
496, 324, 492, 334, 490, 328, 496, 324, 492,
328, 496, 322, 492, 328, 498, 320, 494, 1068,
500, 326, 500, 320, 492, 326, 500, 320, 496,
324, 500, 318, 496, 324, 490, 328, 496, 330,
496, 324, 490, 328, 496, 324, 490, 328, 498,
322, 492, 328, 498, 320, 492, 334, 492, 328,
498, 322, 494, 326, 498, 320, 494, 324, 500,
322, 492, 324, 490, 336, 498, 320, 494, 324,
500, 320, 496, 324, 490, 328, 498, 322, 492,
328, 496, 1070, 496, 1064, 492, 1070, 498, 322,
494, 326, 500, 320, 494, 324, 500, 320, 494,
324, 470}; // UNKNOWN CE60D6B9
uint8_t expectedState[kTcl112AcStateLength] = {
0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
0x07, 0x40, 0x00, 0x00, 0x00, 0x80, 0x03};
irsend.sendRaw(rawData, 227, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(TCL112AC, irsend.capture.decode_type);
EXPECT_EQ(kTcl112AcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
IRTcl112Ac ac(0);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Power: On, Mode: 3 (Cool), Temp: 24C, Fan: 0 (Auto), Econo: Off, "
"Health: Off, Light: On, Turbo: Off, Swing(H): Off, Swing(V): Off",
ac.toString());
}
// Decode a synthetic Tcl112Ac A/C example from Issue #619
TEST(TestDecodeTcl112Ac, DecodeSyntheticExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
uint8_t expectedState[kTcl112AcStateLength] = {0x23, 0xCB, 0x26, 0x01, 0x00,
0x24, 0x03, 0x07, 0x40, 0x00,
0x00, 0x00, 0x80, 0x03};
irsend.sendTcl112Ac(expectedState);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(TCL112AC, irsend.capture.decode_type);
EXPECT_EQ(kTcl112AcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
}
TEST(TestTcl112AcClass, Temperature) {
const uint8_t temp16C[kTcl112AcStateLength] = {
0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x80, 0xCB};
const uint8_t temp16point5C[kTcl112AcStateLength] = {
0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
0x0F, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xEB};
const uint8_t temp19point5C[kTcl112AcStateLength] = {
0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
0x0C, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xE8};
const uint8_t temp31C[kTcl112AcStateLength] = {
0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xBC};
IRTcl112Ac ac(0);
ac.setRaw(temp16C);
EXPECT_EQ(
"Power: On, Mode: 3 (Cool), Temp: 16C, Fan: 0 (Auto), Econo: Off, "
"Health: Off, Light: On, Turbo: Off, Swing(H): Off, Swing(V): Off",
ac.toString());
ac.setRaw(temp16point5C);
EXPECT_EQ(
"Power: On, Mode: 3 (Cool), Temp: 16.5C, Fan: 0 (Auto), Econo: Off, "
"Health: Off, Light: On, Turbo: Off, Swing(H): Off, Swing(V): Off",
ac.toString());
ac.setRaw(temp19point5C);
EXPECT_EQ(
"Power: On, Mode: 3 (Cool), Temp: 19.5C, Fan: 0 (Auto), Econo: Off, "
"Health: Off, Light: On, Turbo: Off, Swing(H): Off, Swing(V): Off",
ac.toString());
ac.setRaw(temp31C);
EXPECT_EQ(
"Power: On, Mode: 3 (Cool), Temp: 31C, Fan: 0 (Auto), Econo: Off, "
"Health: Off, Light: On, Turbo: Off, Swing(H): Off, Swing(V): Off",
ac.toString());
ac.setTemp(kTcl112AcTempMin);
EXPECT_EQ(kTcl112AcTempMin, ac.getTemp());
ac.setTemp(kTcl112AcTempMin + 1);
EXPECT_EQ(kTcl112AcTempMin + 1, ac.getTemp());
ac.setTemp(kTcl112AcTempMax);
EXPECT_EQ(kTcl112AcTempMax, ac.getTemp());
ac.setTemp(kTcl112AcTempMin - 1);
EXPECT_EQ(kTcl112AcTempMin, ac.getTemp());
ac.setTemp(kTcl112AcTempMax + 0.5);
EXPECT_EQ(kTcl112AcTempMax, ac.getTemp());
ac.setTemp(23);
EXPECT_EQ(23, ac.getTemp());
ac.setTemp(27.4);
EXPECT_EQ(27, ac.getTemp());
ac.setTemp(22.5);
EXPECT_EQ(22.5, ac.getTemp());
ac.setTemp(25.6);
EXPECT_EQ(25.5, ac.getTemp());
ac.setTemp(0);
EXPECT_EQ(kTcl112AcTempMin, ac.getTemp());
ac.setTemp(255);
EXPECT_EQ(kTcl112AcTempMax, ac.getTemp());
}
TEST(TestTcl112AcClass, OperatingMode) {
IRTcl112Ac ac(0);
ac.begin();
ac.setMode(kTcl112AcAuto);
EXPECT_EQ(kTcl112AcAuto, ac.getMode());
ac.setMode(kTcl112AcCool);
EXPECT_EQ(kTcl112AcCool, ac.getMode());
ac.setMode(kTcl112AcHeat);
EXPECT_EQ(kTcl112AcHeat, ac.getMode());
ac.setFan(kTcl112AcFanAuto);
ac.setMode(kTcl112AcFan); // Should set fan speed to High.
EXPECT_EQ(kTcl112AcFan, ac.getMode());
EXPECT_EQ(kTcl112AcFanHigh, ac.getFan());
ac.setMode(kTcl112AcDry);
EXPECT_EQ(kTcl112AcDry, ac.getMode());
ac.setMode(kTcl112AcHeat - 1);
EXPECT_EQ(kTcl112AcAuto, ac.getMode());
ac.setMode(kTcl112AcCool);
EXPECT_EQ(kTcl112AcCool, ac.getMode());
ac.setMode(kTcl112AcAuto + 1);
EXPECT_EQ(kTcl112AcAuto, ac.getMode());
ac.setMode(kTcl112AcCool);
ac.setMode(255);
EXPECT_EQ(kTcl112AcAuto, ac.getMode());
ac.setMode(kTcl112AcCool);
ac.setMode(0);
EXPECT_EQ(kTcl112AcAuto, ac.getMode());
const uint8_t automode[] = {
0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x08,
0x07, 0x00, 0x00, 0x00, 0x00, 0x80, 0x48};
ac.setRaw(automode);
EXPECT_EQ(
"Power: On, Mode: 8 (Auto), Temp: 24C, Fan: 0 (Auto), Econo: Off, "
"Health: Off, Light: On, Turbo: Off, Swing(H): Off, Swing(V): Off",
ac.toString());
}
TEST(TestTcl112AcClass, Power) {
IRTcl112Ac ac(0);
ac.begin();
ac.setPower(true);
EXPECT_TRUE(ac.getPower());
ac.setPower(false);
EXPECT_EQ(false, ac.getPower());
ac.setPower(true);
EXPECT_TRUE(ac.getPower());
ac.off();
EXPECT_EQ(false, ac.getPower());
ac.on();
EXPECT_TRUE(ac.getPower());
const uint8_t on[kTcl112AcStateLength] = {
0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x80, 0xCB};
ac.setRaw(on);
EXPECT_EQ(
"Power: On, Mode: 3 (Cool), Temp: 16C, Fan: 0 (Auto), Econo: Off, "
"Health: Off, Light: On, Turbo: Off, Swing(H): Off, Swing(V): Off",
ac.toString());
const uint8_t off[kTcl112AcStateLength] = {
0x23, 0xCB, 0x26, 0x01, 0x00, 0x20, 0x03,
0x07, 0x40, 0x00, 0x00, 0x00, 0x80, 0xCB};
ac.setRaw(off);
EXPECT_EQ(
"Power: Off, Mode: 3 (Cool), Temp: 24C, Fan: 0 (Auto), Econo: Off, "
"Health: Off, Light: On, Turbo: Off, Swing(H): Off, Swing(V): Off",
ac.toString());
}
TEST(TestTcl112AcClass, Checksum) {
uint8_t temp16C[kTcl112AcStateLength] = {
0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x80, 0xCB};
uint8_t temp31C[kTcl112AcStateLength] = {
0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xBC};
IRTcl112Ac ac(0);
EXPECT_EQ(0xCB, ac.calcChecksum(temp16C));
ac.setRaw(temp16C);
EXPECT_EQ(
"Power: On, Mode: 3 (Cool), Temp: 16C, Fan: 0 (Auto), Econo: Off, "
"Health: Off, Light: On, Turbo: Off, Swing(H): Off, Swing(V): Off",
ac.toString());
ac.setRaw(temp31C);
EXPECT_EQ(
"Power: On, Mode: 3 (Cool), Temp: 31C, Fan: 0 (Auto), Econo: Off, "
"Health: Off, Light: On, Turbo: Off, Swing(H): Off, Swing(V): Off",
ac.toString());
EXPECT_EQ(0xBC, ac.calcChecksum(temp31C));
EXPECT_TRUE(IRTcl112Ac::validChecksum(temp16C));
EXPECT_TRUE(IRTcl112Ac::validChecksum(temp31C));
EXPECT_TRUE(ac.validChecksum(temp31C));
ac.setRaw(temp16C);
EXPECT_TRUE(ac.validChecksum(ac.getRaw()));
ac.setTemp(31);
EXPECT_TRUE(ac.validChecksum(ac.getRaw()));
EXPECT_EQ(0xBC, ac.calcChecksum(ac.getRaw()));
}
TEST(TestTcl112AcClass, Econo) {
IRTcl112Ac ac(0);
ac.begin();
ac.setEcono(true);
EXPECT_TRUE(ac.getEcono());
ac.setEcono(false);
EXPECT_EQ(false, ac.getEcono());
ac.setEcono(true);
EXPECT_TRUE(ac.getEcono());
}
TEST(TestTcl112AcClass, Health) {
IRTcl112Ac ac(0);
ac.begin();
ac.setHealth(true);
EXPECT_TRUE(ac.getHealth());
ac.setHealth(false);
EXPECT_EQ(false, ac.getHealth());
ac.setHealth(true);
EXPECT_TRUE(ac.getHealth());
}
TEST(TestTcl112AcClass, Light) {
IRTcl112Ac ac(0);
ac.begin();
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
ac.setLight(false);
EXPECT_EQ(false, ac.getLight());
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
}
TEST(TestTcl112AcClass, SwingHorizontal) {
IRTcl112Ac ac(0);
ac.begin();
ac.setSwingHorizontal(true);
EXPECT_TRUE(ac.getSwingHorizontal());
ac.setSwingHorizontal(false);
EXPECT_EQ(false, ac.getSwingHorizontal());
ac.setSwingHorizontal(true);
EXPECT_TRUE(ac.getSwingHorizontal());
}
TEST(TestTcl112AcClass, SwingVertical) {
IRTcl112Ac ac(0);
ac.begin();
ac.setSwingVertical(true);
EXPECT_TRUE(ac.getSwingVertical());
ac.setSwingVertical(false);
EXPECT_EQ(false, ac.getSwingVertical());
ac.setSwingVertical(true);
EXPECT_TRUE(ac.getSwingVertical());
}
TEST(TestTcl112AcClass, Turbo) {
IRTcl112Ac ac(0);
ac.begin();
ac.setFan(kTcl112AcFanLow);
ac.setSwingHorizontal(false);
ac.setTurbo(false);
EXPECT_FALSE(ac.getTurbo());
EXPECT_FALSE(ac.getSwingVertical());
EXPECT_EQ(kTcl112AcFanLow, ac.getFan());
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
EXPECT_TRUE(ac.getSwingVertical());
EXPECT_EQ(kTcl112AcFanHigh, ac.getFan());
ac.setTurbo(false);
EXPECT_FALSE(ac.getTurbo());
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
}
TEST(TestTcl112AcClass, FanSpeed) {
IRTcl112Ac ac(0);
ac.begin();
// Unexpected value should default to Auto.
ac.setFan(255);
EXPECT_EQ(kTcl112AcFanAuto, ac.getFan());
ac.setFan(kTcl112AcFanLow);
EXPECT_EQ(kTcl112AcFanLow, ac.getFan());
ac.setFan(kTcl112AcFanMed);
EXPECT_EQ(kTcl112AcFanMed, ac.getFan());
ac.setFan(kTcl112AcFanHigh);
EXPECT_EQ(kTcl112AcFanHigh, ac.getFan());
ac.setFan(kTcl112AcFanAuto);
EXPECT_EQ(kTcl112AcFanAuto, ac.getFan());
// Beyond High should default to Auto.
ac.setFan(kTcl112AcFanHigh + 1);
EXPECT_EQ(kTcl112AcFanAuto, ac.getFan());
}
TEST(TestTcl112AcClass, toCommon) {
IRTcl112Ac ac(0);
ac.setPower(true);
ac.setMode(kTcl112AcCool);
ac.setTemp(20);
ac.setFan(kTcl112AcFanHigh);
ac.setSwingVertical(true);
ac.setSwingHorizontal(true);
ac.setTurbo(true);
ac.setHealth(true);
ac.setEcono(true);
ac.setLight(true);
// Now test it.
ASSERT_EQ(decode_type_t::TCL112AC, 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::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kAuto, ac.toCommon().swingv);
ASSERT_EQ(stdAc::swingh_t::kAuto, ac.toCommon().swingh);
ASSERT_TRUE(ac.toCommon().turbo);
ASSERT_TRUE(ac.toCommon().econo);
ASSERT_TRUE(ac.toCommon().light);
ASSERT_TRUE(ac.toCommon().filter);
// Unsupported.
ASSERT_FALSE(ac.toCommon().clean);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_FALSE(ac.toCommon().quiet);
ASSERT_EQ(-1, ac.toCommon().sleep);
ASSERT_EQ(-1, ac.toCommon().clock);
}
TEST(TestDecodeTcl112Ac, Issue744) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
uint16_t rawData[227] = {
3164, 1532, 584, 1082, 472, 1068, 580, 244, 602, 264, 542, 328, 530, 1034,
586, 262, 540, 326, 508, 1064, 582, 1082, 490, 328, 532, 1032, 586, 262,
544, 352, 478, 1060, 584, 1082, 486, 328, 502, 1058, 588, 1084, 472, 344,
530, 250, 600, 1086, 492, 322, 530, 258, 594, 1082, 494, 318, 510, 344,
530, 248, 600, 262, 544, 326, 504, 296, 578, 252, 598, 260, 550, 318, 506,
344, 530, 250, 600, 258, 546, 318, 508, 342, 532, 254, 596, 236, 606, 266,
524, 1066, 580, 242, 602, 266, 542, 1054, 574, 246, 604, 262, 550, 1088,
530, 1034, 588, 262, 542, 328, 504, 296, 582, 238, 606, 262, 546, 322,
508, 342, 530, 250, 602, 260, 544, 1052, 572, 252, 600, 260, 546, 320,
506, 344, 530, 254, 596, 264, 578, 268, 552, 316, 528, 256, 598, 260, 578,
272, 520, 372, 476, 294, 582, 240, 604, 266, 542, 328, 502, 294, 582, 238,
604, 268, 540, 322, 506, 346, 530, 244, 604, 260, 542, 354, 478, 298, 580,
240, 604, 262, 542, 326, 506, 342, 530, 250, 600, 260, 548, 318, 506, 344,
530, 250, 600, 260, 546, 320, 528, 322, 530, 254, 598, 262, 548, 316, 468,
380, 532, 250, 600, 260, 546, 1092, 500, 300, 578, 246, 602, 1082, 474,
346, 530, 248, 602, 260, 542, 1054, 570, 1090, 524}; // UNKNOWN 3338FACE
uint8_t expectedState[kTcl112AcStateLength] = {
0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC4};
irsend.sendRaw(rawData, 227, 38000);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(TCL112AC, irsend.capture.decode_type);
EXPECT_EQ(kTcl112AcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
IRTcl112Ac ac(0);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Power: On, Mode: 3 (Cool), Temp: 23C, Fan: 0 (Auto), Econo: Off, "
"Health: Off, Light: On, Turbo: Off, Swing(H): Off, Swing(V): Off",
ac.toString());
}

View File

@@ -0,0 +1,472 @@
// Copyright 2019 David Conran
#include "ir_Teco.h"
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// General housekeeping
TEST(TestTeco, Housekeeping) {
ASSERT_EQ("TECO", typeToString(TECO));
ASSERT_FALSE(hasACState(TECO)); // Uses uint64_t, not uint8_t*.
}
// Tests for sendTeco()
// Test sending typical data only.
TEST(TestSendTeco, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
irsend.sendTeco(0x250002BC9);
EXPECT_EQ(
"f38000d50"
"m9000s4440"
"m620s1650m620s580m620s580m620s1650m620s580m620s580m620s1650m620s1650"
"m620s1650m620s1650m620s580m620s1650m620s580m620s1650m620s580m620s580"
"m620s580m620s580m620s580m620s580m620s580m620s580m620s580m620s580"
"m620s580m620s580m620s580m620s580m620s1650m620s580m620s1650m620s580"
"m620s580m620s1650m620s580"
"m620s100000",
irsend.outputStr());
}
// Test sending typical data with repeats.
TEST(TestSendTeco, SendWithRepeats) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
irsend.sendTeco(0x250002BC9, kTecoBits, 2); // two repeats.
EXPECT_EQ(
"f38000d50"
"m9000s4440"
"m620s1650m620s580m620s580m620s1650m620s580m620s580m620s1650m620s1650"
"m620s1650m620s1650m620s580m620s1650m620s580m620s1650m620s580m620s580"
"m620s580m620s580m620s580m620s580m620s580m620s580m620s580m620s580"
"m620s580m620s580m620s580m620s580m620s1650m620s580m620s1650m620s580"
"m620s580m620s1650m620s580"
"m620s100000"
"m9000s4440"
"m620s1650m620s580m620s580m620s1650m620s580m620s580m620s1650m620s1650"
"m620s1650m620s1650m620s580m620s1650m620s580m620s1650m620s580m620s580"
"m620s580m620s580m620s580m620s580m620s580m620s580m620s580m620s580"
"m620s580m620s580m620s580m620s580m620s1650m620s580m620s1650m620s580"
"m620s580m620s1650m620s580"
"m620s100000"
"m9000s4440"
"m620s1650m620s580m620s580m620s1650m620s580m620s580m620s1650m620s1650"
"m620s1650m620s1650m620s580m620s1650m620s580m620s1650m620s580m620s580"
"m620s580m620s580m620s580m620s580m620s580m620s580m620s580m620s580"
"m620s580m620s580m620s580m620s580m620s1650m620s580m620s1650m620s580"
"m620s580m620s1650m620s580"
"m620s100000",
irsend.outputStr());
}
// Tests for IRTeco class.
TEST(TestTecoACClass, Power) {
IRTecoAc ac(0);
ac.begin();
ac.setPower(true);
EXPECT_TRUE(ac.getPower());
ac.setPower(false);
EXPECT_EQ(false, ac.getPower());
ac.setPower(true);
EXPECT_TRUE(ac.getPower());
ac.off();
EXPECT_EQ(false, ac.getPower());
ac.on();
EXPECT_TRUE(ac.getPower());
}
TEST(TestTecoACClass, OperatingMode) {
IRTecoAc ac(0);
ac.begin();
ac.setMode(kTecoAuto);
EXPECT_EQ(kTecoAuto, ac.getMode());
ac.setMode(kTecoCool);
EXPECT_EQ(kTecoCool, ac.getMode());
ac.setMode(kTecoHeat);
EXPECT_EQ(kTecoHeat, ac.getMode());
ac.setMode(kTecoFan);
EXPECT_EQ(kTecoFan, ac.getMode());
ac.setMode(kTecoDry);
EXPECT_EQ(kTecoDry, ac.getMode());
ac.setMode(kTecoAuto - 1);
EXPECT_EQ(kTecoAuto, ac.getMode());
ac.setMode(kTecoCool);
EXPECT_EQ(kTecoCool, ac.getMode());
ac.setMode(kTecoHeat + 1);
EXPECT_EQ(kTecoAuto, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kTecoAuto, ac.getMode());
}
TEST(TestTecoACClass, Temperature) {
IRTecoAc ac(0);
ac.begin();
ac.setTemp(kTecoMinTemp);
EXPECT_EQ(kTecoMinTemp, ac.getTemp());
ac.setTemp(kTecoMinTemp + 1);
EXPECT_EQ(kTecoMinTemp + 1, ac.getTemp());
ac.setTemp(kTecoMaxTemp);
EXPECT_EQ(kTecoMaxTemp, ac.getTemp());
ac.setTemp(kTecoMinTemp - 1);
EXPECT_EQ(kTecoMinTemp, ac.getTemp());
ac.setTemp(kTecoMaxTemp + 1);
EXPECT_EQ(kTecoMaxTemp, ac.getTemp());
ac.setTemp(23);
EXPECT_EQ(23, ac.getTemp());
ac.setTemp(0);
EXPECT_EQ(kTecoMinTemp, ac.getTemp());
ac.setTemp(255);
EXPECT_EQ(kTecoMaxTemp, ac.getTemp());
}
TEST(TestTecoACClass, FanSpeed) {
IRTecoAc ac(0);
ac.begin();
ac.setFan(kTecoFanLow);
ac.setFan(kTecoFanAuto);
EXPECT_EQ(kTecoFanAuto, ac.getFan());
ac.setFan(kTecoFanLow);
EXPECT_EQ(kTecoFanLow, ac.getFan());
ac.setFan(kTecoFanMed);
EXPECT_EQ(kTecoFanMed, ac.getFan());
ac.setFan(kTecoFanHigh);
EXPECT_EQ(kTecoFanHigh, ac.getFan());
ac.setFan(kTecoFanHigh);
EXPECT_EQ(kTecoFanHigh, ac.getFan());
}
TEST(TestTecoACClass, Swing) {
IRTecoAc ac(0);
ac.begin();
ac.setSwing(true);
EXPECT_TRUE(ac.getSwing());
ac.setSwing(false);
EXPECT_EQ(false, ac.getSwing());
ac.setSwing(true);
EXPECT_TRUE(ac.getSwing());
}
TEST(TestTecoACClass, Sleep) {
IRTecoAc ac(0);
ac.begin();
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
ac.setSleep(false);
EXPECT_EQ(false, ac.getSleep());
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
}
TEST(TestTecoACClass, Light) {
IRTecoAc ac(0);
ac.begin();
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
ac.setLight(false);
EXPECT_EQ(false, ac.getLight());
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/870#issue-484797174
ac.setRaw(0x250200A09);
EXPECT_TRUE(ac.getLight());
}
TEST(TestTecoACClass, Humid) {
IRTecoAc ac(0);
ac.begin();
ac.setHumid(true);
EXPECT_TRUE(ac.getHumid());
ac.setHumid(false);
EXPECT_EQ(false, ac.getHumid());
ac.setHumid(true);
EXPECT_TRUE(ac.getHumid());
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/870#issuecomment-524536810
ac.setRaw(0x250100A09);
EXPECT_TRUE(ac.getHumid());
}
TEST(TestTecoACClass, Save) {
IRTecoAc ac(0);
ac.begin();
ac.setSave(true);
EXPECT_TRUE(ac.getSave());
ac.setSave(false);
EXPECT_EQ(false, ac.getSave());
ac.setSave(true);
EXPECT_TRUE(ac.getSave());
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/870#issuecomment-524536810
ac.setRaw(0x250800A09);
EXPECT_TRUE(ac.getSave());
}
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/882
TEST(TestTecoACClass, Timer) {
IRTecoAc ac(0);
ac.begin();
ac.setTimer(60);
EXPECT_TRUE(ac.getTimerEnabled());
EXPECT_EQ(60, ac.getTimer());
ac.setTimer(0);
EXPECT_EQ(false, ac.getTimerEnabled());
EXPECT_EQ(0, ac.getTimer());
ac.setTimer(17 * 60 + 59);
EXPECT_TRUE(ac.getTimerEnabled());
EXPECT_EQ(17 * 60 + 30, ac.getTimer());
ac.setTimer(24 * 60 + 31);
EXPECT_TRUE(ac.getTimerEnabled());
EXPECT_EQ(24 * 60, ac.getTimer());
// Data from: https://github.com/crankyoldgit/IRremoteESP8266/issues/882#issuecomment-527079339
ac.setRaw(0x250218A49); // Timer On 1hr
EXPECT_TRUE(ac.getTimerEnabled());
EXPECT_EQ(60, ac.getTimer());
ac.setRaw(0x250219A49); // Timer On 1.5hr
EXPECT_TRUE(ac.getTimerEnabled());
EXPECT_EQ(60 + 30, ac.getTimer());
ac.setRaw(0x250200A49); // Timer Off
EXPECT_FALSE(ac.getTimerEnabled());
EXPECT_EQ(0, ac.getTimer());
ac.setRaw(0x25023DA41); // Timer On 23.5hrs
EXPECT_TRUE(ac.getTimerEnabled());
EXPECT_EQ(23 * 60 + 30, ac.getTimer());
}
TEST(TestTecoACClass, MessageConstuction) {
IRTecoAc ac(0);
EXPECT_EQ(
"Power: Off, Mode: 0 (Auto), Temp: 16C, Fan: 0 (Auto), Sleep: Off, "
"Swing: Off, Light: Off, Humid: Off, Save: Off, Timer: Off",
ac.toString());
ac.setPower(true);
ac.setMode(kTecoCool);
ac.setTemp(21);
ac.setFan(kTecoFanHigh);
ac.setSwing(false);
ac.setLight(false);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 21C, Fan: 3 (High), Sleep: Off, "
"Swing: Off, Light: Off, Humid: Off, Save: Off, Timer: Off",
ac.toString());
ac.setSwing(true);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 21C, Fan: 3 (High), Sleep: Off, "
"Swing: On, Light: Off, Humid: Off, Save: Off, Timer: Off",
ac.toString());
ac.setSwing(false);
ac.setFan(kTecoFanLow);
ac.setSleep(true);
ac.setMode(kTecoHeat);
EXPECT_EQ(
"Power: On, Mode: 4 (Heat), Temp: 21C, Fan: 1 (Low), Sleep: On, "
"Swing: Off, Light: Off, Humid: Off, Save: Off, Timer: Off",
ac.toString());
ac.setSleep(false);
EXPECT_EQ(
"Power: On, Mode: 4 (Heat), Temp: 21C, Fan: 1 (Low), Sleep: Off, "
"Swing: Off, Light: Off, Humid: Off, Save: Off, Timer: Off",
ac.toString());
ac.setTemp(25);
ac.setLight(true);
ac.setSave(true);
ac.setHumid(true);
ac.setTimer(18 * 60 + 37);
EXPECT_EQ(
"Power: On, Mode: 4 (Heat), Temp: 25C, Fan: 1 (Low), Sleep: Off, "
"Swing: Off, Light: On, Humid: On, Save: On, Timer: 18:30",
ac.toString());
}
TEST(TestTecoACClass, ReconstructKnownMessage) {
IRTecoAc ac(0);
const uint64_t expected = 0x250002BC9;
ASSERT_FALSE(ac.getRaw() == expected);
ac.setPower(true);
ac.setMode(kTecoCool);
ac.setTemp(27);
ac.setFan(kTecoFanAuto);
ac.setSleep(true);
ac.setSwing(true);
EXPECT_EQ(expected, ac.getRaw());
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 27C, Fan: 0 (Auto), Sleep: On, "
"Swing: On, Light: Off, Humid: Off, Save: Off, Timer: Off",
ac.toString());
}
// Tests for decodeTeco().
// Decode normal "synthetic" messages.
TEST(TestDecodeTeco, NormalDecodeWithStrict) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// With the specific decoder.
uint64_t expectedState = kTecoReset;
irsend.reset();
irsend.sendTeco(expectedState);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeTeco(&irsend.capture, kStartOffset, kTecoBits,
true));
EXPECT_EQ(TECO, irsend.capture.decode_type);
EXPECT_EQ(kTecoBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(expectedState, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
// With the all the decoders.
irsend.reset();
irsend.sendTeco(expectedState);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(TECO, irsend.capture.decode_type);
EXPECT_EQ(kTecoBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(expectedState, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
IRTecoAc ac(0);
ac.begin();
ac.setRaw(irsend.capture.value);
EXPECT_EQ(
"Power: Off, Mode: 0 (Auto), Temp: 16C, Fan: 0 (Auto), Sleep: Off, "
"Swing: Off, Light: Off, Humid: Off, Save: Off, Timer: Off",
ac.toString());
}
// Decode a real message from Raw Data.
TEST(TestDecodeTeco, RealNormalExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
uint16_t rawData1[73] = {
9076, 4442, 670, 1620, 670, 516, 670, 516, 666, 1626, 670, 516,
664, 520, 666, 1626, 666, 1626, 664, 1626, 666, 1626, 666, 520,
666, 1626, 666, 520, 666, 1626, 666, 520, 666, 516, 670, 514,
670, 516, 666, 520, 670, 516, 666, 520, 666, 516, 672, 514, 670,
516, 666, 520, 666, 516, 672, 514, 670, 516, 666, 1624, 666, 520,
666, 1626, 666, 520, 666, 516, 672, 1620, 670, 516, 670};
uint64_t expected1 = 0b01001010000000000000010101111001001; // 0x250002BC9
irsend.reset();
irsend.sendRaw(rawData1, 73, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(TECO, irsend.capture.decode_type);
EXPECT_EQ(kTecoBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(expected1, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 27C, Fan: 0 (Auto), Sleep: On, "
"Swing: On, Light: Off, Humid: Off, Save: Off, Timer: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
uint16_t rawData2[73] = {
9048, 4472, 636, 548, 636, 1654, 638, 546, 642, 1650, 642, 546, 638,
1654, 638, 1654, 638, 546, 638, 1654, 636, 546, 642, 1650, 640, 548,
636, 548, 638, 546, 636, 546, 642, 542, 642, 546, 638, 546, 638, 546,
636, 548, 642, 542, 642, 546, 636, 548, 636, 546, 642, 542, 642, 546,
638, 546, 638, 546, 636, 1654, 642, 542, 642, 1650, 642, 546, 638, 546,
638, 1654, 638, 546, 642}; // TECO 25000056A
uint64_t expected2 = 0b01001010000000000000000010101101010; // 0x25000056A
irsend.reset();
irsend.sendRaw(rawData2, 73, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(TECO, irsend.capture.decode_type);
EXPECT_EQ(kTecoBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(expected2, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
EXPECT_EQ(
"Power: On, Mode: 2 (Dry), Temp: 21C, Fan: 2 (Medium), Sleep: Off, "
"Swing: On, Light: Off, Humid: Off, Save: Off, Timer: Off",
IRAcUtils::resultAcToString(&irsend.capture));
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestTecoACClass, toCommon) {
IRTecoAc ac(0);
ac.setPower(true);
ac.setMode(kTecoCool);
ac.setTemp(20);
ac.setFan(kTecoFanHigh);
ac.setSwing(true);
ac.setSleep(true);
// Now test it.
ASSERT_EQ(decode_type_t::TECO, ac.toCommon().protocol);
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::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kAuto, ac.toCommon().swingv);
ASSERT_EQ(0, ac.toCommon().sleep);
// Unsupported.
ASSERT_EQ(-1, ac.toCommon().model);
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_FALSE(ac.toCommon().quiet);
ASSERT_EQ(-1, ac.toCommon().clock);
}

View File

@@ -0,0 +1,706 @@
// Copyright 2017 David Conran
#include "ir_Toshiba.h"
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for Toshiba A/C methods.
// Test sending typical data only.
TEST(TestSendToshibaAC, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
uint8_t toshiba_code[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
0x00, 0x00, 0x00, 0x00};
irsend.reset();
irsend.sendToshibaAC(toshiba_code);
EXPECT_EQ(
"f38000d50"
"m4400s4300"
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s7048"
"m4400s4300"
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s7048",
irsend.outputStr());
}
// Test sending with repeats.
TEST(TestSendToshibaAC, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
uint8_t toshiba_code[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
0x00, 0x00, 0x00, 0x00};
irsend.sendToshibaAC(toshiba_code, kToshibaACStateLength, 0);
EXPECT_EQ(
"f38000d50"
"m4400s4300"
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s7048",
irsend.outputStr());
irsend.reset();
irsend.sendToshibaAC(toshiba_code, kToshibaACStateLength, 2);
EXPECT_EQ(
"f38000d50"
"m4400s4300"
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s7048"
"m4400s4300"
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s7048"
"m4400s4300"
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s7048",
irsend.outputStr());
}
// Test sending atypical sizes.
TEST(TestSendToshibaAC, SendUnexpectedSizes) {
IRsendTest irsend(4);
irsend.begin();
uint8_t toshiba_short_code[8] = {0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08};
uint8_t toshiba_long_code[10] = {0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0A};
irsend.reset();
irsend.sendToshibaAC(toshiba_short_code, kToshibaACStateLength - 1);
ASSERT_EQ("", irsend.outputStr());
irsend.reset();
irsend.sendToshibaAC(toshiba_long_code, kToshibaACStateLength + 1);
ASSERT_EQ(
"f38000d50"
"m4400s4300"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623m543s1623"
"m543s472m543s472m543s472m543s472m543s1623m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s1623m543s472m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s1623m543s472m543s1623m543s472"
"m543s7048"
"m4400s4300"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623m543s1623"
"m543s472m543s472m543s472m543s472m543s1623m543s472m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s1623m543s472m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s1623m543s472m543s1623m543s472"
"m543s7048",
irsend.outputStr());
}
// Tests for IRToshibaAC class.
TEST(TestToshibaACClass, Power) {
IRToshibaAC toshiba(0);
toshiba.begin();
toshiba.on();
EXPECT_TRUE(toshiba.getPower());
toshiba.off();
EXPECT_FALSE(toshiba.getPower());
toshiba.setPower(true);
EXPECT_TRUE(toshiba.getPower());
toshiba.setPower(false);
EXPECT_FALSE(toshiba.getPower());
}
TEST(TestToshibaACClass, Temperature) {
IRToshibaAC toshiba(0);
toshiba.begin();
toshiba.setTemp(0);
EXPECT_EQ(kToshibaAcMinTemp, toshiba.getTemp());
toshiba.setTemp(255);
EXPECT_EQ(kToshibaAcMaxTemp, toshiba.getTemp());
toshiba.setTemp(kToshibaAcMinTemp);
EXPECT_EQ(kToshibaAcMinTemp, toshiba.getTemp());
toshiba.setTemp(kToshibaAcMaxTemp);
EXPECT_EQ(kToshibaAcMaxTemp, toshiba.getTemp());
toshiba.setTemp(kToshibaAcMinTemp - 1);
EXPECT_EQ(kToshibaAcMinTemp, toshiba.getTemp());
toshiba.setTemp(kToshibaAcMaxTemp + 1);
EXPECT_EQ(kToshibaAcMaxTemp, toshiba.getTemp());
toshiba.setTemp(17);
EXPECT_EQ(17, toshiba.getTemp());
toshiba.setTemp(21);
EXPECT_EQ(21, toshiba.getTemp());
toshiba.setTemp(25);
EXPECT_EQ(25, toshiba.getTemp());
toshiba.setTemp(30);
EXPECT_EQ(30, toshiba.getTemp());
}
TEST(TestToshibaACClass, OperatingMode) {
IRToshibaAC toshiba(0);
toshiba.begin();
toshiba.setMode(kToshibaAcAuto);
EXPECT_EQ(kToshibaAcAuto, toshiba.getMode());
toshiba.setMode(kToshibaAcCool);
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
toshiba.setMode(kToshibaAcHeat);
EXPECT_EQ(kToshibaAcHeat, toshiba.getMode());
toshiba.setMode(kToshibaAcDry);
EXPECT_EQ(kToshibaAcDry, toshiba.getMode());
toshiba.setMode(kToshibaAcHeat + 1);
EXPECT_EQ(kToshibaAcAuto, toshiba.getMode());
toshiba.setMode(255);
EXPECT_EQ(kToshibaAcAuto, toshiba.getMode());
// Setting the power off changes the underlying mode in the state to heat.
toshiba.setPower(true);
toshiba.setMode(kToshibaAcCool);
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
EXPECT_EQ(kToshibaAcCool, toshiba.getMode(true));
toshiba.setPower(false);
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
EXPECT_EQ(kToshibaAcHeat, toshiba.getMode(true));
}
TEST(TestToshibaACClass, FanSpeed) {
IRToshibaAC toshiba(0);
toshiba.begin();
toshiba.setFan(kToshibaAcFanAuto);
EXPECT_EQ(kToshibaAcFanAuto, toshiba.getFan());
toshiba.setFan(255);
EXPECT_EQ(kToshibaAcFanMax, toshiba.getFan());
toshiba.setFan(kToshibaAcFanMax);
EXPECT_EQ(kToshibaAcFanMax, toshiba.getFan());
toshiba.setFan(kToshibaAcFanMax - 1);
EXPECT_EQ(kToshibaAcFanMax - 1, toshiba.getFan());
toshiba.setFan(1);
EXPECT_EQ(1, toshiba.getFan());
toshiba.setFan(2);
EXPECT_EQ(2, toshiba.getFan());
toshiba.setFan(3);
EXPECT_EQ(3, toshiba.getFan());
toshiba.setFan(4);
EXPECT_EQ(4, toshiba.getFan());
toshiba.setFan(kToshibaAcFanMax + 1);
EXPECT_EQ(kToshibaAcFanMax, toshiba.getFan());
}
TEST(TestToshibaACClass, RawState) {
IRToshibaAC toshiba(0);
toshiba.begin();
uint8_t initial_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
0x00, 0x00, 0x00, 0x01};
uint8_t modified_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
0x00, 0xC1, 0x00, 0xC0};
// Verify the starting state.
EXPECT_STATE_EQ(initial_state, toshiba.getRaw(), kToshibaACBits);
EXPECT_TRUE(toshiba.getPower());
EXPECT_EQ(kToshibaAcAuto, toshiba.getMode());
EXPECT_EQ(kToshibaAcFanAuto, toshiba.getFan());
// Change some settings.
toshiba.setMode(kToshibaAcCool);
toshiba.setFan(kToshibaAcFanMax);
toshiba.setTemp(kToshibaAcMinTemp);
// Verify those were set.
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
EXPECT_EQ(kToshibaAcFanMax, toshiba.getFan());
EXPECT_EQ(kToshibaAcMinTemp, toshiba.getTemp());
// Retrieve the modified state.
EXPECT_STATE_EQ(modified_state, toshiba.getRaw(), kToshibaACBits);
// Set it back to the initial state.
toshiba.setRaw(initial_state);
// Check the new state was set correctly.
EXPECT_TRUE(toshiba.getPower());
EXPECT_EQ(kToshibaAcAuto, toshiba.getMode());
EXPECT_EQ(kToshibaAcFanAuto, toshiba.getFan());
EXPECT_STATE_EQ(initial_state, toshiba.getRaw(), kToshibaACBits);
}
TEST(TestToshibaACClass, Checksums) {
IRToshibaAC toshiba(0);
toshiba.begin();
uint8_t initial_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
0x00, 0x00, 0x00, 0x01};
uint8_t modified_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
0x00, 0xC1, 0x00, 0xC0};
uint8_t invalid_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
0x00, 0x00, 0x00, 0x00};
EXPECT_EQ(0x01, toshiba.calcChecksum(initial_state));
EXPECT_EQ(0xC0, toshiba.calcChecksum(modified_state));
// Check we can call it without instantiating the object.
EXPECT_EQ(0x01, IRToshibaAC::calcChecksum(initial_state));
// Use different lengths.
EXPECT_EQ(0x01, IRToshibaAC::calcChecksum(initial_state,
kToshibaACStateLength - 1));
EXPECT_EQ(0xFF, IRToshibaAC::calcChecksum(initial_state, 3));
// Minimum length that actually means anything.
EXPECT_EQ(0xF2, IRToshibaAC::calcChecksum(initial_state, 2));
// Technically, there is no such thing as a checksum for a length of < 2
// But test it anyway
EXPECT_EQ(0x00, IRToshibaAC::calcChecksum(initial_state, 1));
EXPECT_EQ(0x00, IRToshibaAC::calcChecksum(initial_state, 0));
// Validity tests.
EXPECT_TRUE(IRToshibaAC::validChecksum(initial_state));
EXPECT_TRUE(IRToshibaAC::validChecksum(modified_state));
EXPECT_FALSE(IRToshibaAC::validChecksum(invalid_state));
EXPECT_FALSE(IRToshibaAC::validChecksum(initial_state, 0));
EXPECT_FALSE(IRToshibaAC::validChecksum(initial_state, 1));
EXPECT_FALSE(IRToshibaAC::validChecksum(initial_state, 2));
}
TEST(TestToshibaACClass, HumanReadableOutput) {
IRToshibaAC toshiba(0);
toshiba.begin();
uint8_t initial_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
0x00, 0x00, 0x00, 0x01};
uint8_t modified_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
0x00, 0xC1, 0x00, 0xC0};
toshiba.setRaw(initial_state);
EXPECT_EQ("Power: On, Mode: 0 (Auto), Temp: 17C, Fan: 0 (Auto)",
toshiba.toString());
toshiba.setRaw(modified_state);
EXPECT_EQ("Power: On, Mode: 1 (Cool), Temp: 17C, Fan: 5 (High)",
toshiba.toString());
toshiba.off();
toshiba.setTemp(25);
toshiba.setFan(3);
toshiba.setMode(kToshibaAcDry);
EXPECT_EQ("Power: Off, Mode: 2 (Dry), Temp: 25C, Fan: 3 (Medium)",
toshiba.toString());
}
TEST(TestToshibaACClass, MessageConstuction) {
IRToshibaAC toshiba(0);
IRsendTest irsend(4);
toshiba.begin();
irsend.begin();
toshiba.setFan(1);
toshiba.setMode(kToshibaAcCool);
toshiba.setTemp(27);
toshiba.on();
// Check everything for kicks.
EXPECT_EQ(1, toshiba.getFan());
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
EXPECT_EQ(27, toshiba.getTemp());
EXPECT_TRUE(toshiba.getPower());
irsend.reset();
irsend.sendToshibaAC(toshiba.getRaw());
EXPECT_EQ(
"f38000d50"
"m4400s4300"
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s1623m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s1623m543s1623m543s1623m543s472m543s472m543s472m543s472m543s472"
"m543s7048"
"m4400s4300"
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s1623m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s1623m543s1623m543s1623m543s472m543s472m543s472m543s472m543s472"
"m543s7048",
irsend.outputStr());
// Turn off the power and re-check.
toshiba.setPower(false);
// Check everything for kicks.
EXPECT_EQ(1, toshiba.getFan());
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
EXPECT_EQ(27, toshiba.getTemp());
EXPECT_FALSE(toshiba.getPower());
irsend.reset();
irsend.sendToshibaAC(toshiba.getRaw());
EXPECT_EQ(
"f38000d50"
"m4400s4300"
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s1623m543s472m543s472m543s472m543s1623m543s1623m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s1623m543s472"
"m543s7048"
"m4400s4300"
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s1623m543s472m543s472m543s472m543s1623m543s1623m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s1623m543s472"
"m543s7048",
irsend.outputStr());
// Turn the power back on, and check nothing changed.
toshiba.on();
EXPECT_EQ(1, toshiba.getFan());
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
EXPECT_EQ(27, toshiba.getTemp());
EXPECT_TRUE(toshiba.getPower());
irsend.reset();
irsend.sendToshibaAC(toshiba.getRaw());
EXPECT_EQ(
"f38000d50"
"m4400s4300"
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s1623m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s1623m543s1623m543s1623m543s472m543s472m543s472m543s472m543s472"
"m543s7048"
"m4400s4300"
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472"
"m543s472m543s1623m543s472m543s472m543s472m543s472m543s472m543s1623"
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
"m543s1623m543s1623m543s1623m543s472m543s472m543s472m543s472m543s472"
"m543s7048",
irsend.outputStr());
}
// Decoding a message we entirely constructed based solely on a given state.
TEST(TestDecodeToshibaAC, SyntheticExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
uint8_t expectedState[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
0x00, 0x00, 0x00, 0x01};
irsend.reset();
irsend.sendToshibaAC(expectedState);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type);
ASSERT_EQ(kToshibaACBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"Power: On, Mode: 0 (Auto), Temp: 17C, Fan: 0 (Auto)",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
// Test decoding against captures from a real Toshiba A/C remote.
// Recorded by @mwildbolz
TEST(TestDecodeToshibaAC, RealExamples) {
IRToshibaAC toshiba(0);
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
uint16_t rawData1[295] = {
4442, 4292, 612, 1544, 616, 1544, 616, 1544, 612, 1548, 610, 468,
612, 468, 662, 1494, 640, 438, 616, 464, 614, 464, 616, 464,
612, 468, 610, 1544, 616, 1544, 616, 468, 612, 1544, 616, 464,
694, 386, 616, 464, 612, 468, 612, 468, 636, 444, 610, 1546,
616, 1544, 612, 1546, 614, 1546, 616, 1546, 740, 1420, 612, 1544,
616, 1546, 616, 464, 610, 468, 610, 470, 612, 468, 610, 468,
610, 470, 636, 438, 616, 464, 616, 464, 616, 1546, 636, 442,
612, 1546, 614, 1544, 616, 464, 614, 464, 610, 468, 612, 468,
612, 468, 612, 468, 636, 440, 614, 464, 616, 464, 616, 464,
612, 468, 636, 442, 638, 442, 662, 418, 610, 464, 616, 464,
616, 464, 610, 468, 612, 468, 636, 444, 610, 468, 638, 438,
614, 1546, 612, 1548, 612, 470, 610, 468, 636, 442, 612, 468,
612, 1544, 612, 7396, 4442, 4292, 610, 1546, 616, 1544, 612, 1548,
612, 1546, 616, 464, 616, 464, 616, 1544, 612, 468, 662, 418,
610, 468, 638, 442, 638, 438, 616, 1546, 616, 1544, 612, 468,
610, 1546, 616, 464, 616, 464, 642, 438, 616, 464, 612, 468,
610, 470, 610, 1546, 616, 1544, 612, 1546, 616, 1546, 614, 1546,
612, 1550, 610, 1544, 616, 1546, 614, 464, 642, 438, 610, 468,
612, 468, 612, 468, 612, 468, 610, 468, 638, 438, 614, 464,
616, 1544, 636, 444, 636, 1520, 616, 1544, 616, 464, 616, 464,
612, 468, 612, 468, 612, 468, 612, 468, 612, 464, 612, 470,
636, 442, 638, 442, 612, 470, 692, 384, 614, 464, 616, 464,
612, 468, 610, 468, 612, 468, 610, 470, 610, 464, 616, 464,
616, 464, 616, 464, 610, 1550, 610, 1546, 640, 444, 688, 386,
616, 464, 612, 468, 612, 1544, 642};
irsend.reset();
irsend.sendRaw(rawData1, 295, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type);
ASSERT_EQ(kToshibaACBits, irsend.capture.bits);
toshiba.setRaw(irsend.capture.state);
EXPECT_TRUE(toshiba.getPower());
EXPECT_EQ(23, toshiba.getTemp());
EXPECT_EQ(kToshibaAcFanAuto, toshiba.getFan());
EXPECT_EQ(kToshibaAcAuto, toshiba.getMode());
uint16_t rawData2[295] = {
4500, 4236, 636, 1520, 642, 1520, 640, 1520, 664, 1492, 642, 440,
668, 412, 642, 1518, 638, 438, 666, 414, 640, 438, 642, 438,
638, 442, 642, 1516, 640, 1520, 642, 438, 642, 1520, 636, 438,
668, 412, 640, 440, 666, 412, 642, 438, 668, 412, 640, 1516,
668, 1492, 642, 1520, 666, 1494, 638, 1520, 642, 1520, 668, 1490,
666, 1494, 642, 438, 638, 438, 668, 412, 668, 412, 642, 438,
642, 438, 664, 412, 642, 438, 642, 438, 642, 1518, 642, 434,
668, 412, 642, 438, 668, 412, 692, 388, 666, 412, 642, 434,
642, 438, 642, 1518, 668, 412, 668, 412, 640, 438, 638, 438,
642, 438, 640, 438, 668, 1492, 642, 440, 666, 412, 640, 438,
642, 438, 642, 434, 668, 412, 668, 412, 666, 414, 666, 1494,
640, 438, 642, 434, 668, 412, 642, 438, 642, 438, 668, 412,
668, 414, 640, 7362, 4474, 4262, 642, 1518, 638, 1520, 640, 1520,
668, 1494, 640, 434, 642, 438, 640, 1520, 642, 438, 642, 438,
642, 438, 642, 438, 642, 434, 668, 1494, 642, 1518, 638, 442,
638, 1520, 642, 438, 642, 438, 668, 414, 664, 408, 642, 438,
668, 412, 642, 1520, 666, 1494, 642, 1514, 642, 1518, 642, 1520,
636, 1520, 668, 1494, 666, 1494, 638, 438, 666, 414, 640, 440,
666, 412, 668, 412, 668, 412, 642, 434, 668, 412, 668, 412,
668, 1494, 642, 438, 642, 434, 642, 438, 642, 438, 642, 438,
642, 438, 642, 434, 646, 434, 642, 1518, 668, 412, 642, 438,
642, 434, 666, 414, 640, 438, 642, 438, 642, 1518, 642, 438,
642, 434, 668, 412, 642, 438, 642, 438, 642, 438, 642, 438,
642, 438, 640, 1520, 636, 438, 642, 438, 642, 438, 666, 414,
668, 412, 642, 440, 640, 438, 640};
irsend.reset();
irsend.sendRaw(rawData2, 295, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type);
ASSERT_EQ(kToshibaACBits, irsend.capture.bits);
toshiba.setRaw(irsend.capture.state);
EXPECT_TRUE(toshiba.getPower());
EXPECT_EQ(17, toshiba.getTemp());
EXPECT_EQ(3, toshiba.getFan());
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
uint16_t rawData3[295] = {
4474, 4262, 642, 1514, 642, 1520, 642, 1520, 642, 1514, 642, 438,
642, 438, 642, 1520, 636, 438, 642, 438, 642, 438, 642, 438,
642, 438, 640, 1520, 638, 1520, 642, 438, 640, 1520, 642, 438,
642, 434, 642, 438, 642, 438, 642, 438, 668, 414, 636, 1520,
642, 1520, 642, 1514, 642, 1520, 642, 1520, 640, 1518, 638, 1520,
666, 1494, 642, 438, 642, 434, 642, 438, 640, 438, 642, 438,
642, 440, 640, 434, 642, 438, 642, 438, 642, 1520, 642, 438,
642, 1514, 642, 1520, 640, 1520, 636, 438, 642, 438, 642, 438,
666, 414, 642, 1520, 636, 1520, 642, 438, 642, 438, 640, 438,
642, 434, 642, 1518, 642, 1520, 642, 438, 642, 434, 640, 438,
642, 438, 642, 438, 642, 440, 642, 438, 668, 408, 642, 1520,
642, 438, 642, 1520, 638, 1518, 642, 438, 642, 438, 640, 1520,
640, 438, 642, 7362, 4474, 4262, 642, 1518, 638, 1520, 640, 1520,
642, 1520, 638, 438, 642, 438, 642, 1518, 642, 438, 638, 438,
642, 438, 642, 438, 642, 438, 642, 1514, 642, 1520, 642, 438,
666, 1490, 642, 438, 642, 438, 642, 440, 640, 438, 642, 434,
640, 438, 642, 1520, 642, 1520, 636, 1520, 642, 1520, 642, 1514,
642, 1518, 642, 1518, 640, 1516, 642, 438, 642, 438, 642, 438,
640, 438, 638, 442, 642, 434, 642, 440, 640, 438, 642, 438,
642, 1518, 642, 438, 642, 1514, 642, 1520, 642, 1518, 642, 438,
642, 432, 642, 438, 642, 438, 642, 1520, 642, 1514, 642, 438,
642, 438, 642, 438, 642, 438, 642, 1514, 642, 1520, 642, 438,
642, 438, 638, 438, 642, 438, 642, 438, 640, 440, 642, 438,
640, 434, 642, 1520, 642, 438, 640, 1520, 668, 1490, 666, 414,
640, 438, 642, 1520, 642, 438, 636};
irsend.reset();
irsend.sendRaw(rawData3, 295, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type);
ASSERT_EQ(kToshibaACBits, irsend.capture.bits);
toshiba.setRaw(irsend.capture.state);
EXPECT_TRUE(toshiba.getPower());
EXPECT_EQ(24, toshiba.getTemp());
EXPECT_EQ(kToshibaAcFanMax, toshiba.getFan());
EXPECT_EQ(kToshibaAcHeat, toshiba.getMode());
uint16_t rawData4[295] = {
4474, 4262, 636, 1520, 640, 1520, 640, 1520, 638, 1518, 642, 438,
642, 438, 642, 1520, 636, 438, 642, 438, 642, 438, 642, 438,
636, 444, 636, 1520, 640, 1520, 642, 438, 638, 1524, 638, 438,
640, 438, 642, 438, 640, 438, 642, 438, 638, 438, 642, 1518,
642, 1520, 666, 1494, 636, 1520, 640, 1520, 640, 1520, 636, 1524,
638, 1520, 640, 440, 640, 438, 642, 438, 636, 444, 636, 438,
642, 438, 640, 440, 640, 438, 642, 438, 642, 1518, 638, 438,
642, 1518, 642, 438, 640, 1520, 636, 444, 636, 438, 640, 438,
642, 438, 668, 1494, 640, 438, 642, 1518, 636, 444, 636, 438,
640, 1520, 642, 1518, 642, 1520, 636, 444, 636, 438, 642, 438,
642, 438, 640, 440, 640, 438, 640, 440, 640, 438, 640, 1518,
642, 1520, 636, 1524, 636, 1518, 642, 438, 642, 1518, 642, 1518,
640, 438, 642, 7364, 4472, 4262, 642, 1518, 642, 1518, 638, 1518,
642, 1520, 642, 438, 642, 438, 640, 1520, 636, 440, 640, 438,
642, 438, 640, 438, 642, 438, 642, 1518, 636, 1524, 636, 438,
640, 1520, 642, 438, 642, 438, 640, 438, 636, 444, 636, 438,
668, 412, 642, 1518, 642, 1520, 642, 1520, 636, 1518, 642, 1518,
642, 1520, 636, 1520, 668, 1494, 642, 438, 636, 444, 664, 412,
642, 438, 668, 412, 642, 438, 636, 442, 638, 442, 638, 438,
642, 1518, 642, 438, 642, 1518, 638, 438, 642, 1518, 642, 440,
640, 438, 636, 444, 636, 444, 636, 1520, 642, 438, 642, 1520,
636, 444, 636, 438, 642, 1520, 640, 1520, 636, 1520, 668, 412,
642, 438, 642, 438, 642, 438, 638, 442, 636, 438, 642, 438,
668, 412, 640, 1520, 638, 1524, 636, 1520, 642, 1520, 636, 444,
638, 1522, 638, 1518, 640, 438, 642};
irsend.reset();
irsend.sendRaw(rawData4, 295, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type);
ASSERT_EQ(kToshibaACBits, irsend.capture.bits);
toshiba.setRaw(irsend.capture.state);
EXPECT_FALSE(toshiba.getPower());
EXPECT_EQ(22, toshiba.getTemp());
EXPECT_EQ(4, toshiba.getFan());
// Confirming the quirky behaviour that the 'Power OFF' signal
// sets the mode to heat.
// The previous state the remote was in was 'AUTO' just prior to
// sending the power off message.
EXPECT_EQ(kToshibaAcHeat, toshiba.getMode());
}
TEST(TestToshibaACClass, toCommon) {
IRToshibaAC ac(0);
ac.setPower(true);
ac.setMode(kToshibaAcCool);
ac.setTemp(20);
ac.setFan(kToshibaAcFanMax);
// Now test it.
ASSERT_EQ(decode_type_t::TOSHIBA_AC, ac.toCommon().protocol);
ASSERT_EQ(-1, ac.toCommon().model);
ASSERT_TRUE(ac.toCommon().power);
ASSERT_TRUE(ac.toCommon().celsius);
ASSERT_EQ(20, ac.toCommon().degrees);
ASSERT_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kMax, ac.toCommon().fanspeed);
// 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_FALSE(ac.toCommon().quiet);
ASSERT_EQ(-1, ac.toCommon().sleep);
ASSERT_EQ(-1, ac.toCommon().clock);
}

View File

@@ -0,0 +1,181 @@
// Copyright 2019 David Conran
#include "ir_Trotec.h"
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
TEST(TestTrotecESPClass, toCommon) {
IRTrotecESP ac(0);
ac.setPower(true);
ac.setMode(kTrotecCool);
ac.setTemp(20);
ac.setSpeed(kTrotecFanHigh);
ac.setSleep(true);
// Now test it.
ASSERT_EQ(decode_type_t::TROTEC, ac.toCommon().protocol);
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::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(0, ac.toCommon().sleep);
// Unsupported.
ASSERT_EQ(-1, ac.toCommon().model);
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_FALSE(ac.toCommon().quiet);
ASSERT_EQ(-1, ac.toCommon().clock);
}
TEST(TestTrotecESPClass, MessageConstructon) {
IRTrotecESP ac(0);
ac.setPower(true);
ac.setTemp(20);
ac.setMode(kTrotecCool);
ac.setSpeed(kTrotecFanMed);
ac.setSleep(true);
uint8_t expected[kTrotecStateLength] = {
0x12, 0x34, 0x29, 0x82, 0x00, 0x00, 0x00, 0x00, 0xAB};
EXPECT_STATE_EQ(expected, ac.getRaw(), kTrotecBits);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 20C, Fan: 2 (Medium), Sleep: On",
ac.toString());
}
// Tests for sendTrotec().
// Test sending typical data only.
TEST(TestSendTrotec, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
uint8_t data[kTrotecStateLength] = {
0x12, 0x34, 0x29, 0x82, 0x00, 0x00, 0x00, 0x00, 0xAB};
irsend.sendTrotec(data);
EXPECT_EQ(
"f36000d50"
"m5952s7364"
"m592s592m592s1560m592s592m592s592m592s1560m592s592m592s592m592s592"
"m592s592m592s592m592s1560m592s592m592s1560m592s1560m592s592m592s592"
"m592s1560m592s592m592s592m592s1560m592s592m592s1560m592s592m592s592"
"m592s592m592s1560m592s592m592s592m592s592m592s592m592s592m592s1560"
"m592s592m592s592m592s592m592s592m592s592m592s592m592s592m592s592"
"m592s592m592s592m592s592m592s592m592s592m592s592m592s592m592s592"
"m592s592m592s592m592s592m592s592m592s592m592s592m592s592m592s592"
"m592s592m592s592m592s592m592s592m592s592m592s592m592s592m592s592"
"m592s1560m592s1560m592s592m592s1560m592s592m592s1560m592s592m592s1560"
"m592s6184"
"m592s1500",
irsend.outputStr());
}
// Tests for decodeTrotec().
// Decode normal Trotec messages.
TEST(TestDecodeTrotec, SyntheticDecode) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Synthesised Normal Trotec message.
irsend.reset();
uint8_t expectedState[kTrotecStateLength] = {
0x12, 0x34, 0x29, 0x82, 0x00, 0x00, 0x00, 0x00, 0xAB};
irsend.sendTrotec(expectedState);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::TROTEC, irsend.capture.decode_type);
EXPECT_EQ(kTrotecBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 20C, Fan: 2 (Medium), Sleep: On",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestTrotecESPClass, SetAndGetTemp) {
IRTrotecESP ac(0);
ac.setTemp(25);
EXPECT_EQ(25, ac.getTemp());
ac.setTemp(kTrotecMinTemp);
EXPECT_EQ(kTrotecMinTemp, ac.getTemp());
ac.setTemp(kTrotecMaxTemp);
EXPECT_EQ(kTrotecMaxTemp, ac.getTemp());
ac.setTemp(kTrotecMinTemp - 1);
EXPECT_EQ(kTrotecMinTemp, ac.getTemp());
ac.setTemp(kTrotecMaxTemp + 1);
EXPECT_EQ(kTrotecMaxTemp, ac.getTemp());
}
TEST(TestTrotecESPClass, SetAndGetMode) {
IRTrotecESP ac(0);
ac.setMode(kTrotecFan);
EXPECT_EQ(kTrotecFan, ac.getMode());
ac.setMode(kTrotecCool);
EXPECT_EQ(kTrotecCool, ac.getMode());
ac.setMode(kTrotecAuto);
EXPECT_EQ(kTrotecAuto, ac.getMode());
ac.setMode(kTrotecDry);
EXPECT_EQ(kTrotecDry, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kTrotecAuto, ac.getMode());
}
TEST(TestTrotecESPClass, SetAndGetFan) {
IRTrotecESP ac(0);
ac.setSpeed(kTrotecFanHigh);
EXPECT_EQ(kTrotecFanHigh, ac.getSpeed());
ac.setSpeed(kTrotecFanLow);
EXPECT_EQ(kTrotecFanLow, ac.getSpeed());
ac.setSpeed(kTrotecFanMed);
EXPECT_EQ(kTrotecFanMed, ac.getSpeed());
ac.setSpeed(kTrotecFanHigh);
EXPECT_EQ(kTrotecFanHigh, ac.getSpeed());
ASSERT_NE(7, kTrotecFanHigh);
// Now try some unexpected value.
ac.setSpeed(7);
EXPECT_EQ(kTrotecFanHigh, ac.getSpeed());
}
TEST(TestTrotecESPClass, Sleep) {
IRTrotecESP ac(0);
ac.setSleep(false);
ASSERT_FALSE(ac.getSleep());
ac.setSleep(true);
ASSERT_TRUE(ac.getSleep());
ac.setSleep(false);
ASSERT_FALSE(ac.getSleep());
}
TEST(TestTrotecESPClass, Power) {
IRTrotecESP ac(0);
ac.setPower(false);
ASSERT_FALSE(ac.getPower());
ac.setPower(true);
ASSERT_TRUE(ac.getPower());
ac.setPower(false);
ASSERT_FALSE(ac.getPower());
}
TEST(TestUtils, Housekeeping) {
ASSERT_EQ("TROTEC", typeToString(decode_type_t::TROTEC));
ASSERT_EQ(decode_type_t::TROTEC, strToDecodeType("TROTEC"));
ASSERT_TRUE(hasACState(decode_type_t::TROTEC));
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::TROTEC));
}

View File

@@ -0,0 +1,545 @@
// Copyright 2019 David Conran
#include "ir_Vestel.h"
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendVestelAc()
// Test sending typical data only.
TEST(TestSendVestelAc, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
irsend.sendVestelAc(0x0F00D9001FEF201ULL);
EXPECT_EQ(
"f38000d50"
"m3110s9066"
"m520s1535m520s480m520s480m520s480m520s480m520s480m520s480m520s480"
"m520s480m520s1535m520s480m520s480m520s1535m520s1535m520s1535m520s1535"
"m520s480m520s1535m520s1535m520s1535m520s1535m520s1535m520s1535m520s1535"
"m520s1535m520s480m520s480m520s480m520s480m520s480m520s480m520s480"
"m520s480m520s480m520s480m520s480m520s1535m520s480m520s480m520s1535"
"m520s1535m520s480m520s1535m520s1535m520s480m520s480m520s480m520s480"
"m520s480m520s480m520s480m520s480m520s1535m520s1535m520s1535m520s1535"
"m520s100000",
irsend.outputStr());
}
// Test sending typical data with repeats.
TEST(TestSendVestelAc, SendWithRepeats) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
irsend.sendVestelAc(0x0F00D9001FEF201ULL, kVestelAcBits, 2); // two repeats.
EXPECT_EQ(
"f38000d50"
"m3110s9066"
"m520s1535m520s480m520s480m520s480m520s480m520s480m520s480m520s480"
"m520s480m520s1535m520s480m520s480m520s1535m520s1535m520s1535m520s1535"
"m520s480m520s1535m520s1535m520s1535m520s1535m520s1535m520s1535m520s1535"
"m520s1535m520s480m520s480m520s480m520s480m520s480m520s480m520s480"
"m520s480m520s480m520s480m520s480m520s1535m520s480m520s480m520s1535"
"m520s1535m520s480m520s1535m520s1535m520s480m520s480m520s480m520s480"
"m520s480m520s480m520s480m520s480m520s1535m520s1535m520s1535m520s1535"
"m520s100000"
"m3110s9066"
"m520s1535m520s480m520s480m520s480m520s480m520s480m520s480m520s480"
"m520s480m520s1535m520s480m520s480m520s1535m520s1535m520s1535m520s1535"
"m520s480m520s1535m520s1535m520s1535m520s1535m520s1535m520s1535m520s1535"
"m520s1535m520s480m520s480m520s480m520s480m520s480m520s480m520s480"
"m520s480m520s480m520s480m520s480m520s1535m520s480m520s480m520s1535"
"m520s1535m520s480m520s1535m520s1535m520s480m520s480m520s480m520s480"
"m520s480m520s480m520s480m520s480m520s1535m520s1535m520s1535m520s1535"
"m520s100000"
"m3110s9066"
"m520s1535m520s480m520s480m520s480m520s480m520s480m520s480m520s480"
"m520s480m520s1535m520s480m520s480m520s1535m520s1535m520s1535m520s1535"
"m520s480m520s1535m520s1535m520s1535m520s1535m520s1535m520s1535m520s1535"
"m520s1535m520s480m520s480m520s480m520s480m520s480m520s480m520s480"
"m520s480m520s480m520s480m520s480m520s1535m520s480m520s480m520s1535"
"m520s1535m520s480m520s1535m520s1535m520s480m520s480m520s480m520s480"
"m520s480m520s480m520s480m520s480m520s1535m520s1535m520s1535m520s1535"
"m520s100000",
irsend.outputStr());
}
// Tests for IRVestelAc class.
TEST(TestVestelAcClass, Power) {
IRVestelAc ac(0);
ac.begin();
ac.setPower(true);
EXPECT_TRUE(ac.getPower());
ac.setPower(false);
EXPECT_EQ(false, ac.getPower());
ac.setPower(true);
EXPECT_TRUE(ac.getPower());
ac.off();
EXPECT_EQ(false, ac.getPower());
ac.on();
EXPECT_TRUE(ac.getPower());
EXPECT_FALSE(ac.isTimeCommand());
}
TEST(TestVestelAcClass, OperatingMode) {
IRVestelAc ac(0);
ac.begin();
ac.setMode(kVestelAcAuto);
EXPECT_EQ(kVestelAcAuto, ac.getMode());
ac.setMode(kVestelAcCool);
EXPECT_EQ(kVestelAcCool, ac.getMode());
ac.setMode(kVestelAcHeat);
EXPECT_EQ(kVestelAcHeat, ac.getMode());
ac.setMode(kVestelAcFan);
EXPECT_EQ(kVestelAcFan, ac.getMode());
ac.setMode(kVestelAcDry);
EXPECT_EQ(kVestelAcDry, ac.getMode());
ac.setMode(kVestelAcAuto - 1);
EXPECT_EQ(kVestelAcAuto, ac.getMode());
ac.setMode(kVestelAcCool);
EXPECT_EQ(kVestelAcCool, ac.getMode());
ac.setMode(kVestelAcHeat + 1);
EXPECT_EQ(kVestelAcAuto, ac.getMode());
ac.setMode(255);
EXPECT_EQ(kVestelAcAuto, ac.getMode());
EXPECT_FALSE(ac.isTimeCommand());
}
TEST(TestVestelAcClass, Temperature) {
IRVestelAc ac(0);
ac.begin();
ac.setTemp(kVestelAcMinTempC);
EXPECT_EQ(kVestelAcMinTempC, ac.getTemp());
ac.setTemp(kVestelAcMinTempC + 1);
EXPECT_EQ(kVestelAcMinTempC + 1, ac.getTemp());
ac.setTemp(kVestelAcMaxTemp);
EXPECT_EQ(kVestelAcMaxTemp, ac.getTemp());
ac.setTemp(kVestelAcMinTempC - 1);
EXPECT_EQ(kVestelAcMinTempC, ac.getTemp());
ac.setTemp(kVestelAcMaxTemp + 1);
EXPECT_EQ(kVestelAcMaxTemp, ac.getTemp());
ac.setTemp(23);
EXPECT_EQ(23, ac.getTemp());
ac.setTemp(0);
EXPECT_EQ(kVestelAcMinTempC, ac.getTemp());
ac.setTemp(255);
EXPECT_EQ(kVestelAcMaxTemp, ac.getTemp());
EXPECT_FALSE(ac.isTimeCommand());
}
TEST(TestVestelAcClass, FanSpeed) {
IRVestelAc ac(0);
ac.begin();
ac.setFan(kVestelAcFanLow);
ac.setFan(kVestelAcFanAuto);
EXPECT_EQ(kVestelAcFanAuto, ac.getFan());
ac.setFan(kVestelAcFanLow);
EXPECT_EQ(kVestelAcFanLow, ac.getFan());
ac.setFan(kVestelAcFanMed);
EXPECT_EQ(kVestelAcFanMed, ac.getFan());
ac.setFan(kVestelAcFanHigh);
EXPECT_EQ(kVestelAcFanHigh, ac.getFan());
ac.setFan(kVestelAcFanHigh);
EXPECT_EQ(kVestelAcFanHigh, ac.getFan());
EXPECT_FALSE(ac.isTimeCommand());
}
TEST(TestVestelAcClass, Swing) {
IRVestelAc ac(0);
ac.begin();
ac.setSwing(true);
EXPECT_TRUE(ac.getSwing());
ac.setSwing(false);
EXPECT_EQ(false, ac.getSwing());
ac.setSwing(true);
EXPECT_TRUE(ac.getSwing());
EXPECT_FALSE(ac.isTimeCommand());
}
TEST(TestVestelAcClass, Ion) {
IRVestelAc ac(0);
ac.begin();
ac.setIon(true);
EXPECT_TRUE(ac.getIon());
ac.setIon(false);
EXPECT_EQ(false, ac.getIon());
ac.setIon(true);
EXPECT_TRUE(ac.getIon());
EXPECT_FALSE(ac.isTimeCommand());
}
TEST(TestVestelAcClass, Turbo) {
IRVestelAc ac(0);
ac.begin();
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
ac.setTurbo(false);
EXPECT_EQ(false, ac.getTurbo());
ac.setTurbo(true);
EXPECT_TRUE(ac.getTurbo());
EXPECT_FALSE(ac.isTimeCommand());
}
TEST(TestVestelAcClass, Sleep) {
IRVestelAc ac(0);
ac.begin();
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
ac.setSleep(false);
EXPECT_EQ(false, ac.getSleep());
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
EXPECT_FALSE(ac.isTimeCommand());
}
TEST(TestVestelAcClass, Time) {
IRVestelAc ac(0);
ac.begin();
ac.setTime(0);
EXPECT_EQ(0, ac.getTime());
EXPECT_TRUE(ac.isTimeCommand());
ac.setTime(1);
EXPECT_EQ(1, ac.getTime());
ac.setTime(1234);
EXPECT_EQ(1234, ac.getTime());
ac.setTime(23 * 60 + 59);
EXPECT_EQ(23 * 60 + 59, ac.getTime());
}
TEST(TestVestelAcClass, OnTimer) {
IRVestelAc ac(0);
ac.begin();
ac.setOnTimer(0);
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_TRUE(ac.isTimeCommand());
ac.setOnTimer(1);
EXPECT_EQ(0, ac.getOnTimer());
ac.setOnTimer(10);
EXPECT_EQ(10, ac.getOnTimer());
ac.setOnTimer(12 * 60 + 15); // we will round down to 10 min increments.
EXPECT_EQ(12 * 60 + 10, ac.getOnTimer());
ac.setOnTimer(23 * 60 + 50);
EXPECT_EQ(23 * 60 + 50, ac.getOnTimer());
}
TEST(TestVestelAcClass, OffTimer) {
IRVestelAc ac(0);
ac.begin();
ac.setOffTimer(0);
EXPECT_EQ(0, ac.getOffTimer());
EXPECT_TRUE(ac.isTimeCommand());
ac.setOffTimer(1);
EXPECT_EQ(0, ac.getOffTimer());
ac.setOffTimer(10);
EXPECT_EQ(10, ac.getOffTimer());
ac.setOffTimer(12 * 60 + 15); // we will round down to 10 min increments.
EXPECT_EQ(12 * 60 + 10, ac.getOffTimer());
ac.setOffTimer(23 * 60 + 50);
EXPECT_EQ(23 * 60 + 50, ac.getOffTimer());
}
TEST(TestVestelAcClass, Timer) {
IRVestelAc ac(0);
ac.begin();
ac.setTimer(0);
EXPECT_EQ(0, ac.getTimer());
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_TRUE(ac.isTimeCommand());
ac.setTimer(10);
EXPECT_EQ(10, ac.getTimer());
EXPECT_EQ(0, ac.getOnTimer());
ac.setTimer(12 * 60 + 15); // we will round down to 10 min increments.
EXPECT_EQ(12 * 60 + 10, ac.getTimer());
EXPECT_EQ(0, ac.getOnTimer());
ac.setTimer(23 * 60 + 50);
EXPECT_EQ(23 * 60 + 50, ac.getTimer());
EXPECT_EQ(0, ac.getOnTimer());
}
TEST(TestVestelAcClass, MessageConstuction) {
IRVestelAc ac(0);
EXPECT_EQ(
"Power: On, Mode: 0 (Auto), Temp: 25C, Fan: 13 (Auto Heat), Sleep: Off, "
"Turbo: Off, Ion: Off, Swing: Off",
ac.toString());
ac.setMode(kVestelAcCool);
ac.setTemp(21);
ac.setFan(kVestelAcFanHigh);
EXPECT_FALSE(ac.isTimeCommand());
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 21C, Fan: 11 (High), Sleep: Off, "
"Turbo: Off, Ion: Off, Swing: Off",
ac.toString());
ac.setSwing(true);
ac.setIon(true);
ac.setTurbo(true);
EXPECT_FALSE(ac.isTimeCommand());
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 21C, Fan: 11 (High), Sleep: Off, "
"Turbo: On, Ion: On, Swing: On",
ac.toString());
// Now change a few already set things.
ac.setSleep(true);
ac.setMode(kVestelAcHeat);
EXPECT_EQ(
"Power: On, Mode: 4 (Heat), Temp: 21C, Fan: 11 (High), Sleep: On, "
"Turbo: Off, Ion: On, Swing: On",
ac.toString());
EXPECT_FALSE(ac.isTimeCommand());
ac.setTemp(25);
ac.setPower(false);
EXPECT_EQ(
"Power: Off, Mode: 4 (Heat), Temp: 25C, Fan: 11 (High), Sleep: On, "
"Turbo: Off, Ion: On, Swing: On",
ac.toString());
EXPECT_FALSE(ac.isTimeCommand());
// Check that the checksum is valid.
EXPECT_TRUE(IRVestelAc::validChecksum(ac.getRaw()));
ac.setTime(23 * 60 + 59);
EXPECT_TRUE(ac.isTimeCommand());
EXPECT_EQ(
"Clock: 23:59, Timer: Off, On Timer: Off, Off Timer: Off",
ac.toString());
ac.setTimer(8 * 60 + 0);
EXPECT_TRUE(ac.isTimeCommand());
EXPECT_EQ(
"Clock: 23:59, Timer: 08:00, On Timer: Off, Off Timer: Off",
ac.toString());
ac.setOnTimer(7 * 60 + 40);
EXPECT_EQ(
"Clock: 23:59, Timer: Off, On Timer: 07:40, Off Timer: Off",
ac.toString());
ac.setOffTimer(17 * 60 + 10);
EXPECT_EQ(
"Clock: 23:59, Timer: Off, On Timer: 07:40, Off Timer: 17:10",
ac.toString());
ac.setTimer(8 * 60 + 0);
EXPECT_EQ(
"Clock: 23:59, Timer: 08:00, On Timer: Off, Off Timer: Off",
ac.toString());
ac.setTimer(0);
EXPECT_EQ(
"Clock: 23:59, Timer: Off, On Timer: Off, Off Timer: Off",
ac.toString());
ac.on();
EXPECT_FALSE(ac.isTimeCommand());
EXPECT_EQ(
"Power: On, Mode: 4 (Heat), Temp: 25C, Fan: 11 (High), Sleep: On, "
"Turbo: Off, Ion: On, Swing: On",
ac.toString());
}
// Tests for decodeVestelAc().
// Decode normal "synthetic" messages.
TEST(TestDecodeVestelAc, NormalDecodeWithStrict) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// With the specific decoder.
uint64_t expectedState = 0x0F00D9001FEF201ULL;
irsend.reset();
irsend.sendVestelAc(expectedState);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeVestelAc(&irsend.capture, kStartOffset,
kVestelAcBits, true));
EXPECT_EQ(VESTEL_AC, irsend.capture.decode_type);
EXPECT_EQ(kVestelAcBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(expectedState, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
// With the all the decoders.
irsend.reset();
irsend.sendVestelAc(expectedState);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(VESTEL_AC, irsend.capture.decode_type);
EXPECT_EQ(kVestelAcBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(expectedState, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
IRVestelAc ac(0);
ac.begin();
ac.setRaw(irsend.capture.value);
EXPECT_EQ(
"Power: On, Mode: 0 (Auto), Temp: 25C, Fan: 13 (Auto Heat), Sleep: Off, "
"Turbo: Off, Ion: Off, Swing: Off",
ac.toString());
}
// Decode a real message from Raw Data.
TEST(TestDecodeVestelAc, RealNormalExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
uint16_t rawData[115] = {
3098, 9080, 548, 1538, 526, 492, 526, 468, 524, 468, 526, 468,
550, 466, 526, 466, 526, 504, 540, 466, 526, 1538, 526, 466,
526, 466, 552, 1540, 522, 466, 526, 492, 526, 544, 526, 1536,
526, 1536, 552, 1536, 526, 1536, 552, 1536, 552, 1536, 526, 1536,
526, 1574, 542, 1536, 526, 492, 526, 466, 526, 494, 524, 468,
524, 468, 526, 492, 526, 502, 540, 468, 524, 494, 524, 468,
526, 468, 524, 468, 526, 492, 526, 468, 524, 520, 524, 1538,
524, 468, 524, 468, 524, 468, 524, 468, 524, 468, 524, 1538,
524, 506, 538, 468, 524, 468, 524, 1538, 524, 468, 550, 1538,
550, 1538, 524, 1538, 534, 1528, 544}; // VESTEL_AC
irsend.reset();
irsend.sendRaw(rawData, 115, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(VESTEL_AC, irsend.capture.decode_type);
EXPECT_EQ(kVestelAcBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(0xF4410001FF1201ULL, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
EXPECT_EQ(
"Power: On, Mode: 4 (Heat), Temp: 16C, Fan: 1 (Auto), Sleep: Off, "
"Turbo: Off, Ion: On, Swing: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestDecodeVestelAc, RealTimerExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
IRVestelAc ac(0);
irsend.begin();
uint16_t rawData[115] = {
3022, 9080, 546, 1536, 526, 466, 526, 492, 526, 468, 526, 492,
524, 468, 524, 494, 524, 504, 540, 492, 524, 1538, 526, 468,
524, 492, 526, 466, 552, 1536, 526, 1536, 526, 1570, 542, 492,
524, 1538, 550, 1538, 524, 1536, 526, 494, 524, 466, 526, 468,
524, 1574, 540, 1536, 550, 1536, 526, 468, 550, 1536, 526, 492,
526, 468, 524, 492, 526, 518, 526, 1536, 552, 1536, 550, 1536,
526, 494, 550, 1538, 526, 492, 524, 1538, 526, 504, 540, 466,
526, 1536, 526, 1536, 526, 468, 550, 1538, 524, 468, 524, 1538,
550, 1574, 540, 468, 550, 1538, 526, 492, 524, 468, 526, 466,
526, 468, 524, 494, 524, 468, 546}; // VESTEL_AC 2D6570B8EE201
irsend.reset();
irsend.sendRaw(rawData, 115, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(VESTEL_AC, irsend.capture.decode_type);
EXPECT_EQ(kVestelAcBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(0x2D6570B8EE201ULL, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
ac.begin();
ac.setRaw(irsend.capture.value);
EXPECT_EQ(
"Clock: 05:45, Timer: Off, On Timer: 14:00, Off Timer: 23:00",
ac.toString());
}
// General housekeeping
TEST(TestDecodeVestelAc, Housekeeping) {
ASSERT_EQ("VESTEL_AC", typeToString(VESTEL_AC));
ASSERT_FALSE(hasACState(VESTEL_AC)); // Uses uint64_t, not uint8_t*.
}
TEST(TestVestelAcClass, toCommon) {
IRVestelAc ac(0);
ac.setPower(true);
ac.setMode(kVestelAcCool);
ac.setTemp(20);
ac.setFan(kVestelAcFanHigh);
ac.setSwing(true);
ac.setTurbo(true);
ac.setIon(true);
// Now test it.
ASSERT_EQ(decode_type_t::VESTEL_AC, ac.toCommon().protocol);
ASSERT_EQ(-1, ac.toCommon().model);
ASSERT_TRUE(ac.toCommon().power);
ASSERT_TRUE(ac.toCommon().celsius);
ASSERT_EQ(20, ac.toCommon().degrees);
ASSERT_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kAuto, ac.toCommon().swingv);
ASSERT_TRUE(ac.toCommon().turbo);
ASSERT_TRUE(ac.toCommon().filter);
// Unsupported.
ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().light);
ASSERT_FALSE(ac.toCommon().clean);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_FALSE(ac.toCommon().quiet);
ASSERT_EQ(-1, ac.toCommon().sleep);
ASSERT_EQ(-1, ac.toCommon().clock);
}

View File

@@ -0,0 +1,598 @@
// Copyright 2018 David Conran
#include "ir_Whirlpool.h"
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendWhirlpoolAC().
// Test sending typical data only.
TEST(TestSendWhirlpoolAC, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
uint8_t data[kWhirlpoolAcStateLength] = {
0x83, 0x06, 0x10, 0x71, 0x00, 0x00, 0x91, 0x1F, 0x00, 0x00, 0x00,
0x00, 0x00, 0xEF, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02};
irsend.sendWhirlpoolAC(data);
EXPECT_EQ(
"f38000d50"
"m8950s4484"
"m597s1649m597s1649m597s533m597s533m597s533m597s533m597s533m597s1649"
"m597s533m597s1649m597s1649m597s533m597s533m597s533m597s533m597s533"
"m597s533m597s533m597s533m597s533m597s1649m597s533m597s533m597s533"
"m597s1649m597s533m597s533m597s533m597s1649m597s1649m597s1649m597s533"
"m597s533m597s533m597s533m597s533m597s533m597s533m597s533m597s533"
"m597s533m597s533m597s533m597s533m597s533m597s533m597s533m597s533"
"m597s7920"
"m597s1649m597s533m597s533m597s533m597s1649m597s533m597s533m597s1649"
"m597s1649m597s1649m597s1649m597s1649m597s1649m597s533m597s533m597s533"
"m597s533m597s533m597s533m597s533m597s533m597s533m597s533m597s533"
"m597s533m597s533m597s533m597s533m597s533m597s533m597s533m597s533"
"m597s533m597s533m597s533m597s533m597s533m597s533m597s533m597s533"
"m597s533m597s533m597s533m597s533m597s533m597s533m597s533m597s533"
"m597s533m597s533m597s533m597s533m597s533m597s533m597s533m597s533"
"m597s1649m597s1649m597s1649m597s1649m597s533m597s1649m597s1649m597s1649"
"m597s7920"
"m597s533m597s533m597s533m597s533m597s533m597s533m597s533m597s533"
"m597s533m597s1649m597s533m597s533m597s533m597s533m597s533m597s533"
"m597s533m597s533m597s533m597s533m597s533m597s533m597s533m597s533"
"m597s533m597s533m597s533m597s533m597s533m597s533m597s533m597s533"
"m597s533m597s533m597s533m597s533m597s533m597s533m597s533m597s533"
"m597s533m597s533m597s533m597s533m597s533m597s533m597s533m597s533"
"m597s533m597s1649m597s533m597s533m597s533m597s533m597s533m597s533"
"m597s100000",
irsend.outputStr());
}
// Tests for decodeWhirlpoolAC().
// Decode normal WhirlpoolAC messages.
TEST(TestDecodeWhirlpoolAC, SyntheticDecode) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Synthesised Normal WhirlpoolAC message.
irsend.reset();
uint8_t expectedState[kWhirlpoolAcStateLength] = {
0x83, 0x06, 0x10, 0x71, 0x00, 0x00, 0x91, 0x1F, 0x00, 0x00, 0x00,
0x00, 0x00, 0xEF, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02};
irsend.sendWhirlpoolAC(expectedState);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(WHIRLPOOL_AC, irsend.capture.decode_type);
EXPECT_EQ(kWhirlpoolAcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"Model: 1 (DG11J13A), Power Toggle: Off, Mode: 1 (Auto), Temp: 25C, "
"Fan: 0 (Auto), Swing: Off, Light: On, Clock: 17:31, On Timer: Off, "
"Off Timer: Off, Sleep: Off, Super: Off, Command: 2 (Temp)",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestDecodeWhirlpoolAC, Real26CFanAutoCoolingSwingOnClock1918) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
uint8_t expectedState[kWhirlpoolAcStateLength] = {
0x83, 0x06, 0x80, 0x82, 0x00, 0x00, 0x93, 0x12, 0x40, 0x00, 0x00,
0x00, 0x00, 0xC3, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07};
irsend.sendWhirlpoolAC(expectedState);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(WHIRLPOOL_AC, irsend.capture.decode_type);
EXPECT_EQ(kWhirlpoolAcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
IRWhirlpoolAc ac(0);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Model: 1 (DG11J13A), Power Toggle: Off, Mode: 2 (Cool), Temp: 26C, "
"Fan: 0 (Auto), Swing: On, Light: On, Clock: 19:18, On Timer: Off, "
"Off Timer: Off, Sleep: Off, Super: Off, Command: 7 (Swing)",
ac.toString());
}
TEST(TestDecodeWhirlpoolAC, RealTimerExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
// Dehumidify timer on 7:40 off 8:05
uint16_t rawData[343] = {
9092, 4556, 604, 1664, 604, 1674, 630, 514, 630, 518, 628, 522,
604, 550, 628, 530, 602, 1680, 630, 508, 630, 1644, 604, 1674,
604, 544, 604, 548, 630, 524, 604, 554, 620, 530, 630, 506,
602, 538, 602, 542, 604, 542, 604, 546, 630, 524, 602, 556,
628, 518, 604, 1666, 632, 1644, 604, 540, 602, 546, 604, 1680,
604, 1684, 604, 1686, 630, 520, 602, 534, 606, 538, 602, 540,
604, 544, 604, 548, 602, 552, 630, 528, 602, 546, 602, 536,
628, 510, 606, 540, 604, 544, 630, 522, 604, 554, 600, 554,
602, 528, 602, 8032, 604, 1666, 604, 1668, 602, 1676, 630, 518,
630, 520, 602, 550, 604, 554, 604, 1678, 630, 1640, 602, 1672,
602, 542, 602, 544, 628, 522, 630, 1658, 604, 554, 628, 1652,
630, 508, 602, 538, 630, 514, 630, 1652, 602, 546, 604, 550,
602, 554, 602, 546, 630, 1638, 604, 536, 630, 1646, 602, 544,
628, 522, 632, 524, 628, 528, 602, 1686, 594, 1666, 604, 1670,
602, 1674, 632, 516, 604, 546, 638, 518, 622, 534, 628, 518,
604, 532, 604, 536, 600, 550, 622, 1652, 630, 520, 602, 1684,
602, 554, 602, 544, 630, 506, 628, 512, 602, 540, 628, 518,
602, 550, 602, 552, 604, 554, 602, 544, 628, 1642, 602, 536,
632, 1646, 630, 516, 602, 1680, 630, 1656, 604, 1688, 602, 1660,
602, 8030, 604, 532, 604, 536, 604, 540, 602, 544, 628, 522,
602, 552, 602, 556, 602, 544, 602, 1666, 630, 510, 602, 1674,
604, 544, 628, 522, 602, 552, 630, 526, 628, 520, 602, 534,
630, 510, 604, 540, 602, 544, 606, 544, 604, 550, 604, 554,
602, 544, 604, 534, 602, 538, 602, 542, 604, 542, 604, 546,
604, 550, 632, 526, 604, 544, 630, 506, 604, 536, 604, 540,
628, 518, 602, 548, 604, 550, 604, 552, 630, 516, 602, 534,
604, 536, 630, 512, 604, 544, 602, 548, 630, 524, 602, 554,
602, 542, 604, 1666, 606, 532, 630, 1644, 602, 544, 630, 520,
604, 550, 604, 554, 602, 526, 598};
uint8_t expectedState[kWhirlpoolAcStateLength] = {
0x83, 0x06, 0x00, 0x73, 0x00, 0x00, 0x87, 0xA3, 0x08, 0x85, 0x07,
0x28, 0x00, 0xF5, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x05};
irsend.sendRaw(rawData, 343, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(WHIRLPOOL_AC, irsend.capture.decode_type);
EXPECT_EQ(kWhirlpoolAcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
IRWhirlpoolAc ac(0);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Model: 1 (DG11J13A), Power Toggle: Off, Mode: 3 (Dry), Temp: 25C, "
"Fan: 0 (Auto), Swing: Off, Light: On, Clock: 07:35, On Timer: 07:40, "
"Off Timer: 08:05, Sleep: Off, Super: Off, Command: 5 (On Timer)",
ac.toString());
}
// Decode a recorded example
TEST(TestDecodeWhirlpoolAC, RealExampleDecode) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
// Real WhirlpoolAC message.
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/509
uint16_t rawData[343] = {
8950, 4484, 598, 1642, 598, 1646, 594, 534, 594, 538, 602, 532,
598, 540, 600, 542, 598, 1650, 600, 522, 598, 1644, 596, 1650,
600, 532, 598, 538, 602, 536, 594, 548, 592, 538, 602, 518,
600, 524, 596, 532, 598, 532, 598, 1654, 596, 544, 596, 544,
596, 536, 594, 1644, 596, 528, 600, 528, 592, 538, 602, 1648,
602, 1654, 596, 1664, 598, 534, 594, 526, 594, 530, 598, 528,
602, 530, 600, 534, 596, 542, 598, 542, 598, 534, 596, 526,
594, 530, 600, 528, 602, 530, 600, 534, 596, 542, 598, 544,
596, 518, 602, 7916, 598, 1642, 598, 528, 600, 528, 602, 530,
600, 1652, 598, 542, 598, 544, 596, 1654, 596, 1644, 596, 1648,
602, 1644, 596, 1654, 596, 1656, 604, 536, 594, 548, 602, 528,
600, 520, 600, 524, 596, 532, 598, 532, 596, 538, 602, 536,
594, 546, 594, 538, 602, 518, 600, 524, 596, 532, 598, 532,
598, 536, 594, 544, 596, 544, 596, 536, 594, 526, 592, 530,
600, 528, 600, 530, 602, 532, 596, 542, 598, 542, 598, 534,
596, 524, 596, 528, 600, 526, 592, 538, 592, 542, 598, 540,
600, 540, 600, 530, 598, 522, 598, 526, 594, 534, 596, 534,
594, 540, 602, 536, 592, 548, 592, 538, 600, 1636, 594, 1648,
602, 1642, 598, 1652, 598, 538, 602, 1680, 570, 1662, 598, 1634,
596, 7924, 600, 520, 598, 526, 592, 534, 596, 534, 596, 540,
600, 536, 604, 538, 602, 530, 600, 520, 598, 1640, 600, 528,
600, 530, 600, 534, 594, 544, 596, 544, 596, 534, 596, 526,
594, 528, 600, 526, 594, 536, 592, 542, 598, 538, 602, 538,
602, 528, 600, 520, 600, 524, 596, 530, 600, 532, 598, 534,
596, 542, 598, 542, 598, 532, 598, 524, 596, 528, 602, 526,
594, 536, 594, 540, 600, 536, 594, 548, 592, 538, 602, 518,
602, 522, 596, 530, 600, 530, 600, 534, 596, 542, 598, 544,
596, 534, 596, 524, 594, 1644, 596, 532, 596, 534, 596, 538,
602, 536, 594, 546, 594, 520, 600};
uint8_t expectedState[kWhirlpoolAcStateLength] = {
0x83, 0x06, 0x10, 0x71, 0x00, 0x00, 0x91, 0x1F, 0x00, 0x00, 0x00,
0x00, 0x00, 0xEF, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02};
irsend.reset();
irsend.sendRaw(rawData, 343, 38000);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(WHIRLPOOL_AC, irsend.capture.decode_type);
EXPECT_EQ(kWhirlpoolAcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
IRWhirlpoolAc ac(0);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Model: 1 (DG11J13A), Power Toggle: Off, Mode: 1 (Auto), Temp: 25C, "
"Fan: 0 (Auto), Swing: Off, Light: On, Clock: 17:31, On Timer: Off, "
"Off Timer: Off, Sleep: Off, Super: Off, Command: 2 (Temp)",
ac.toString());
}
// Tests for IRWhirlpoolAc class.
TEST(TestIRWhirlpoolAcClass, SetAndGetRaw) {
uint8_t expectedState[kWhirlpoolAcStateLength] = {
0x83, 0x06, 0x10, 0x71, 0x00, 0x00, 0x91, 0x1F, 0x00, 0x00, 0x00,
0x00, 0x00, 0xEF, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02};
IRWhirlpoolAc ac(0);
ac.setRaw(expectedState);
EXPECT_STATE_EQ(expectedState, ac.getRaw(), kWhirlpoolAcBits);
}
TEST(TestIRWhirlpoolAcClass, SetAndGetTemp) {
IRWhirlpoolAc ac(0);
ac.setCommand(0); // Clear the previous command.
ac.setModel(DG11J13A);
ac.setTemp(25);
EXPECT_EQ(25, ac.getTemp());
EXPECT_EQ(kWhirlpoolAcCommandTemp, ac.getCommand());
ac.setTemp(kWhirlpoolAcMinTemp);
EXPECT_EQ(kWhirlpoolAcMinTemp, ac.getTemp());
ac.setTemp(kWhirlpoolAcMinTemp - 1);
EXPECT_EQ(kWhirlpoolAcMinTemp, ac.getTemp());
ac.setTemp(kWhirlpoolAcMaxTemp);
EXPECT_EQ(kWhirlpoolAcMaxTemp, ac.getTemp());
ac.setTemp(kWhirlpoolAcMaxTemp + 1);
EXPECT_EQ(kWhirlpoolAcMaxTemp, ac.getTemp());
ac.setModel(DG11J191); // Has a -2 offset on min/max temps.
ac.setTemp(25);
EXPECT_EQ(25, ac.getTemp());
EXPECT_EQ(kWhirlpoolAcCommandTemp, ac.getCommand());
ac.setTemp(kWhirlpoolAcMinTemp - 2);
EXPECT_EQ(kWhirlpoolAcMinTemp - 2, ac.getTemp());
ac.setTemp(kWhirlpoolAcMinTemp - 2 - 1);
EXPECT_EQ(kWhirlpoolAcMinTemp - 2 , ac.getTemp());
ac.setTemp(kWhirlpoolAcMaxTemp - 2);
EXPECT_EQ(kWhirlpoolAcMaxTemp - 2, ac.getTemp());
ac.setTemp(kWhirlpoolAcMaxTemp - 2 + 1);
EXPECT_EQ(kWhirlpoolAcMaxTemp - 2, ac.getTemp());
}
TEST(TestIRWhirlpoolAcClass, SetAndGetMode) {
IRWhirlpoolAc ac(0);
ac.setCommand(0); // Clear the previous command.
ac.setMode(kWhirlpoolAcCool);
EXPECT_EQ(kWhirlpoolAcCool, ac.getMode());
EXPECT_EQ(kWhirlpoolAcCommandMode, ac.getCommand());
ac.setMode(kWhirlpoolAcHeat);
EXPECT_EQ(kWhirlpoolAcHeat, ac.getMode());
ac.setMode(kWhirlpoolAcAuto);
EXPECT_EQ(kWhirlpoolAcAuto, ac.getMode());
EXPECT_EQ(kWhirlpoolAcCommand6thSense, ac.getCommand());
ac.setMode(kWhirlpoolAcDry);
EXPECT_EQ(kWhirlpoolAcDry, ac.getMode());
EXPECT_EQ(kWhirlpoolAcCommandMode, ac.getCommand());
}
TEST(TestIRWhirlpoolAcClass, SetAndGetFan) {
IRWhirlpoolAc ac(0);
ac.setCommand(0); // Clear the previous command.
ac.setFan(kWhirlpoolAcFanAuto);
EXPECT_EQ(kWhirlpoolAcFanAuto, ac.getFan());
EXPECT_EQ(kWhirlpoolAcCommandFanSpeed, ac.getCommand());
ac.setFan(kWhirlpoolAcFanLow);
EXPECT_EQ(kWhirlpoolAcFanLow, ac.getFan());
ac.setFan(kWhirlpoolAcFanMedium);
EXPECT_EQ(kWhirlpoolAcFanMedium, ac.getFan());
ac.setFan(kWhirlpoolAcFanHigh);
EXPECT_EQ(kWhirlpoolAcFanHigh, ac.getFan());
ac.setFan(kWhirlpoolAcFanAuto);
EXPECT_EQ(kWhirlpoolAcFanAuto, ac.getFan());
// Known state with a non-auto fan mode.
const uint8_t state[21] = {0x83, 0x06, 0x0B, 0x82, 0x00, 0x00, 0x93,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E,
0x00, 0x03, 0x00, 0x00, 0x08, 0x00, 0x0B};
ac.setRaw(state);
EXPECT_EQ(kWhirlpoolAcFanLow, ac.getFan());
}
TEST(TestIRWhirlpoolAcClass, SetAndGetSwing) {
IRWhirlpoolAc ac(0);
ac.setCommand(0); // Clear the previous command.
ac.setSwing(true);
EXPECT_TRUE(ac.getSwing());
EXPECT_EQ(kWhirlpoolAcCommandSwing, ac.getCommand());
ac.setSwing(false);
EXPECT_FALSE(ac.getSwing());
ac.setSwing(true);
EXPECT_TRUE(ac.getSwing());
}
TEST(TestIRWhirlpoolAcClass, SetAndGetLight) {
IRWhirlpoolAc ac(0);
ac.setCommand(0); // Clear the previous command.
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
ac.setLight(false);
EXPECT_FALSE(ac.getLight());
ac.setLight(true);
EXPECT_TRUE(ac.getLight());
}
TEST(TestIRWhirlpoolAcClass, SetAndGetClock) {
IRWhirlpoolAc ac(0);
ac.setClock(0);
EXPECT_EQ(0, ac.getClock());
ac.setClock(1);
EXPECT_EQ(1, ac.getClock());
ac.setClock(12 * 60 + 34);
EXPECT_EQ(12 * 60 + 34, ac.getClock());
ac.setClock(7 * 60 + 5);
EXPECT_EQ(7 * 60 + 5, ac.getClock());
ac.setClock(23 * 60 + 59);
EXPECT_EQ(23 * 60 + 59, ac.getClock());
ac.setClock(24 * 60 + 0);
EXPECT_EQ(0, ac.getClock());
ac.setClock(25 * 60 + 23);
EXPECT_EQ(1 * 60 + 23, ac.getClock());
}
TEST(TestIRWhirlpoolAcClass, OnOffTimers) {
IRWhirlpoolAc ac(0);
ac.setCommand(0); // Clear the previous command.
// On Timer
ac.enableOnTimer(false);
ac.setOnTimer(0);
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_FALSE(ac.isOnTimerEnabled());
EXPECT_EQ(kWhirlpoolAcCommandOnTimer, ac.getCommand());
ac.setOnTimer(1);
EXPECT_EQ(1, ac.getOnTimer());
ac.enableOnTimer(true);
ac.setOnTimer(12 * 60 + 34);
EXPECT_EQ(12 * 60 + 34, ac.getOnTimer());
EXPECT_TRUE(ac.isOnTimerEnabled());
ac.setOnTimer(7 * 60 + 5);
EXPECT_EQ(7 * 60 + 5, ac.getOnTimer());
ac.setOnTimer(23 * 60 + 59);
EXPECT_EQ(23 * 60 + 59, ac.getOnTimer());
ac.setOnTimer(24 * 60 + 0);
EXPECT_EQ(0, ac.getOnTimer());
ac.setOnTimer(25 * 60 + 23);
EXPECT_EQ(1 * 60 + 23, ac.getOnTimer());
// Off Timer
ac.enableOffTimer(false);
ac.setOffTimer(0);
EXPECT_EQ(0, ac.getOffTimer());
EXPECT_FALSE(ac.isOffTimerEnabled());
EXPECT_EQ(kWhirlpoolAcCommandOffTimer, ac.getCommand());
ac.setOffTimer(1);
EXPECT_EQ(1, ac.getOffTimer());
ac.enableOffTimer(true);
ac.setOffTimer(12 * 60 + 34);
EXPECT_EQ(12 * 60 + 34, ac.getOffTimer());
EXPECT_TRUE(ac.isOffTimerEnabled());
ac.setOffTimer(7 * 60 + 5);
EXPECT_EQ(7 * 60 + 5, ac.getOffTimer());
ac.setOffTimer(23 * 60 + 59);
EXPECT_EQ(23 * 60 + 59, ac.getOffTimer());
ac.setOffTimer(24 * 60 + 0);
EXPECT_EQ(0, ac.getOffTimer());
ac.setOffTimer(25 * 60 + 23);
EXPECT_EQ(1 * 60 + 23, ac.getOffTimer());
}
TEST(TestIRWhirlpoolAcClass, SetAndGetCommand) {
IRWhirlpoolAc ac(0);
ac.setCommand(0);
EXPECT_EQ(0, ac.getCommand());
ac.setCommand(kWhirlpoolAcCommandFanSpeed);
EXPECT_EQ(kWhirlpoolAcCommandFanSpeed, ac.getCommand());
ac.setCommand(255);
EXPECT_EQ(255, ac.getCommand());
}
TEST(TestIRWhirlpoolAcClass, SetAndGetPowerToggle) {
IRWhirlpoolAc ac(0);
ac.setCommand(0);
ac.setPowerToggle(false);
EXPECT_FALSE(ac.getPowerToggle());
ac.setPowerToggle(true);
EXPECT_TRUE(ac.getPowerToggle());
ac.setPowerToggle(false);
EXPECT_FALSE(ac.getPowerToggle());
// Known state with a power toggle in it.
uint8_t state[21] = {0x83, 0x06, 0x07, 0x82, 0x00, 0x00, 0x93,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x09};
ac.setRaw(state);
EXPECT_TRUE(ac.getPowerToggle());
}
TEST(TestIRWhirlpoolAcClass, SetAndGetModel) {
IRWhirlpoolAc ac(0);
ac.setTemp(19);
ac.setCommand(0); // Set model shouldn't change the command setting.
ac.setModel(DG11J191);
EXPECT_EQ(DG11J191, ac.getModel());
EXPECT_EQ(19, ac.getTemp());
EXPECT_EQ(0, ac.getCommand());
ac.setModel(DG11J13A);
EXPECT_EQ(DG11J13A, ac.getModel());
EXPECT_EQ(19, ac.getTemp());
ac.setModel(DG11J191);
EXPECT_EQ(DG11J191, ac.getModel());
EXPECT_EQ(19, ac.getTemp());
EXPECT_EQ(0, ac.getCommand());
// One of the models has a lower min temp. Check that desired temp is kept.
ac.setTemp(16);
ac.setCommand(0); // Set model shouldn't change the command setting.
EXPECT_EQ(16, ac.getTemp());
EXPECT_EQ(0, ac.getCommand());
ac.setModel(DG11J13A);
EXPECT_EQ(DG11J13A, ac.getModel());
EXPECT_EQ(18, ac.getTemp());
ac.setModel(DG11J191);
EXPECT_EQ(DG11J191, ac.getModel());
EXPECT_EQ(16, ac.getTemp());
EXPECT_EQ(0, ac.getCommand());
// Known states with different models.
uint8_t state_1[21] = {0x83, 0x06, 0x01, 0x30, 0x00, 0x00, 0x92,
0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95,
0x00, 0x02, 0x00, 0x00, 0x08, 0x00, 0x0A};
uint8_t state_2[21] = {0x83, 0x06, 0x00, 0x30, 0x00, 0x00, 0x8B,
0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02};
ac.setRaw(state_1);
EXPECT_EQ(DG11J191, ac.getModel());
ac.setRaw(state_2);
EXPECT_EQ(DG11J13A, ac.getModel());
}
TEST(TestIRWhirlpoolAcClass, SetAndGetSleep) {
IRWhirlpoolAc ac(0);
ac.setFan(kWhirlpoolAcFanAuto);
ac.setCommand(0);
ac.setSleep(false);
EXPECT_FALSE(ac.getSleep());
EXPECT_EQ(kWhirlpoolAcCommandSleep, ac.getCommand());
ac.setSleep(true);
EXPECT_TRUE(ac.getSleep());
EXPECT_EQ(kWhirlpoolAcCommandSleep, ac.getCommand());
EXPECT_EQ(kWhirlpoolAcFanLow, ac.getFan());
ac.setSleep(false);
EXPECT_FALSE(ac.getSleep());
// Known state with sleep mode in it.
uint8_t state[21] = {0x83, 0x06, 0x0B, 0x73, 0x00, 0x00, 0x90,
0x9E, 0x00, 0xA0, 0x17, 0x3A, 0x00, 0xFB,
0x00, 0x03, 0x00, 0x00, 0x08, 0x00, 0x0B};
ac.setRaw(state);
EXPECT_TRUE(ac.getSleep());
}
TEST(TestIRWhirlpoolAcClass, SetAndGetSuper) {
IRWhirlpoolAc ac(0);
ac.setFan(kWhirlpoolAcFanAuto);
ac.setMode(kWhirlpoolAcDry);
ac.setCommand(0);
ac.setSuper(false);
EXPECT_FALSE(ac.getSuper());
EXPECT_EQ(kWhirlpoolAcCommandSuper, ac.getCommand());
ac.setSuper(true);
EXPECT_TRUE(ac.getSuper());
EXPECT_EQ(kWhirlpoolAcCommandSuper, ac.getCommand());
EXPECT_EQ(kWhirlpoolAcFanHigh, ac.getFan());
EXPECT_EQ(kWhirlpoolAcCool, ac.getMode());
EXPECT_EQ(kWhirlpoolAcMinTemp, ac.getTemp());
ac.setSuper(false);
EXPECT_FALSE(ac.getSuper());
EXPECT_EQ(kWhirlpoolAcFanHigh, ac.getFan());
EXPECT_EQ(kWhirlpoolAcCool, ac.getMode());
EXPECT_EQ(kWhirlpoolAcMinTemp, ac.getTemp());
// When in heat mode, it should stay in heat mode.
ac.setFan(kWhirlpoolAcFanAuto);
ac.setMode(kWhirlpoolAcHeat);
ac.setSuper(true);
EXPECT_TRUE(ac.getSuper());
EXPECT_EQ(kWhirlpoolAcCommandSuper, ac.getCommand());
EXPECT_EQ(kWhirlpoolAcFanHigh, ac.getFan());
EXPECT_EQ(kWhirlpoolAcHeat, ac.getMode());
EXPECT_EQ(kWhirlpoolAcMaxTemp, ac.getTemp());
// Changing mode/temp/fan/power should cancel super,
ac.setMode(kWhirlpoolAcCool);
EXPECT_FALSE(ac.getSuper());
ac.setSuper(true);
ac.setTemp(25);
EXPECT_FALSE(ac.getSuper());
ac.setSuper(true);
ac.setFan(kWhirlpoolAcFanMedium);
EXPECT_FALSE(ac.getSuper());
ac.setSuper(true);
ac.setPowerToggle(true);
EXPECT_FALSE(ac.getSuper());
// Known state with Super mode in it.
uint8_t state[21] = {0x83, 0x06, 0x01, 0x02, 0x00, 0x90, 0x90,
0x9F, 0x00, 0xA0, 0x17, 0x3A, 0x00, 0x11,
0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x0C};
ac.setRaw(state);
EXPECT_TRUE(ac.getSuper());
}
// Build a known good message from scratch.
TEST(TestIRWhirlpoolAcClass, MessageConstruction) {
// Real example captured from a remote. (ref: RealTimerExample)
uint8_t expectedState[kWhirlpoolAcStateLength] = {
0x83, 0x06, 0x00, 0x73, 0x00, 0x00, 0x87, 0xA3, 0x08, 0x85, 0x07,
0x28, 0x00, 0xF5, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x05};
IRWhirlpoolAc ac(0);
ac.setModel(DG11J13A);
ac.setTemp(25);
ac.setPowerToggle(false);
ac.setMode(kWhirlpoolAcDry);
ac.setFan(kWhirlpoolAcFanAuto);
ac.setSwing(false);
ac.setLight(true);
ac.setClock(7 * 60 + 35);
ac.setOnTimer(7 * 60 + 40);
ac.setOffTimer(8 * 60 + 5);
ac.enableOffTimer(true);
ac.setSleep(false);
ac.setSuper(false);
ac.enableOnTimer(true);
EXPECT_EQ(
"Model: 1 (DG11J13A), Power Toggle: Off, Mode: 3 (Dry), Temp: 25C, "
"Fan: 0 (Auto), Swing: Off, Light: On, Clock: 07:35, On Timer: 07:40, "
"Off Timer: 08:05, Sleep: Off, Super: Off, Command: 5 (On Timer)",
ac.toString());
EXPECT_STATE_EQ(expectedState, ac.getRaw(), kWhirlpoolAcBits);
}
TEST(TestIRWhirlpoolAcClass, toCommon) {
IRWhirlpoolAc ac(0);
ac.setModel(whirlpool_ac_remote_model_t::DG11J13A);
ac.setPowerToggle(true);
ac.setMode(kWhirlpoolAcCool);
ac.setTemp(18);
ac.setFan(kWhirlpoolAcFanHigh);
ac.setSwing(true);
ac.setSuper(true);
ac.setLight(true);
ac.setSleep(false);
// Now test it.
ASSERT_EQ(decode_type_t::WHIRLPOOL_AC, ac.toCommon().protocol);
ASSERT_EQ(whirlpool_ac_remote_model_t::DG11J13A, ac.toCommon().model);
ASSERT_TRUE(ac.toCommon().power);
ASSERT_TRUE(ac.toCommon().celsius);
ASSERT_EQ(18, ac.toCommon().degrees);
ASSERT_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kAuto, ac.toCommon().swingv);
ASSERT_TRUE(ac.toCommon().turbo);
ASSERT_TRUE(ac.toCommon().light);
ASSERT_EQ(-1, ac.toCommon().sleep);
// Unsupported.
ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().filter);
ASSERT_FALSE(ac.toCommon().clean);
ASSERT_FALSE(ac.toCommon().beep);
ASSERT_FALSE(ac.toCommon().quiet);
ASSERT_EQ(-1, ac.toCommon().clock);
}

View File

@@ -0,0 +1,269 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendWhynter().
// Test sending typical data only.
TEST(TestSendWhynter, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendWhynter(0x0);
EXPECT_EQ(
"f38000d50"
"m750s750m2850s2850"
"m750s750m750s750m750s750m750s750m750s750m750s750m750s750m750s750"
"m750s750m750s750m750s750m750s750m750s750m750s750m750s750m750s750"
"m750s750m750s750m750s750m750s750m750s750m750s750m750s750m750s750"
"m750s750m750s750m750s750m750s750m750s750m750s750m750s750m750s750"
"m750s52050",
irsend.outputStr());
irsend.reset();
irsend.sendWhynter(0xFFFFFFFF);
EXPECT_EQ(
"f38000d50"
"m750s750m2850s2850"
"m750s2150m750s2150m750s2150m750s2150m750s2150m750s2150m750s2150m750s2150"
"m750s2150m750s2150m750s2150m750s2150m750s2150m750s2150m750s2150m750s2150"
"m750s2150m750s2150m750s2150m750s2150m750s2150m750s2150m750s2150m750s2150"
"m750s2150m750s2150m750s2150m750s2150m750s2150m750s2150m750s2150m750s2150"
"m750s12200",
irsend.outputStr());
irsend.reset();
irsend.sendWhynter(0x87654321);
EXPECT_EQ(
"f38000d50"
"m750s750m2850s2850"
"m750s2150m750s750m750s750m750s750m750s750m750s2150m750s2150m750s2150"
"m750s750m750s2150m750s2150m750s750m750s750m750s2150m750s750m750s2150"
"m750s750m750s2150m750s750m750s750m750s750m750s750m750s2150m750s2150"
"m750s750m750s750m750s2150m750s750m750s750m750s750m750s750m750s2150"
"m750s33850",
irsend.outputStr());
}
// Test sending with different repeats.
TEST(TestSendWhynter, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendWhynter(0x87654321, kWhynterBits, 0); // 0 repeats.
EXPECT_EQ(
"f38000d50"
"m750s750m2850s2850"
"m750s2150m750s750m750s750m750s750m750s750m750s2150m750s2150m750s2150"
"m750s750m750s2150m750s2150m750s750m750s750m750s2150m750s750m750s2150"
"m750s750m750s2150m750s750m750s750m750s750m750s750m750s2150m750s2150"
"m750s750m750s750m750s2150m750s750m750s750m750s750m750s750m750s2150"
"m750s33850",
irsend.outputStr());
irsend.reset();
irsend.sendWhynter(0x87654321, kWhynterBits, 1); // 1 repeat.
EXPECT_EQ(
"f38000d50"
"m750s750m2850s2850"
"m750s2150m750s750m750s750m750s750m750s750m750s2150m750s2150m750s2150"
"m750s750m750s2150m750s2150m750s750m750s750m750s2150m750s750m750s2150"
"m750s750m750s2150m750s750m750s750m750s750m750s750m750s2150m750s2150"
"m750s750m750s750m750s2150m750s750m750s750m750s750m750s750m750s2150"
"m750s33850"
"m750s750m2850s2850"
"m750s2150m750s750m750s750m750s750m750s750m750s2150m750s2150m750s2150"
"m750s750m750s2150m750s2150m750s750m750s750m750s2150m750s750m750s2150"
"m750s750m750s2150m750s750m750s750m750s750m750s750m750s2150m750s2150"
"m750s750m750s750m750s2150m750s750m750s750m750s750m750s750m750s2150"
"m750s33850",
irsend.outputStr());
irsend.reset();
irsend.sendWhynter(0x87654321, kWhynterBits, 2); // 2 repeats.
EXPECT_EQ(
"f38000d50"
"m750s750m2850s2850"
"m750s2150m750s750m750s750m750s750m750s750m750s2150m750s2150m750s2150"
"m750s750m750s2150m750s2150m750s750m750s750m750s2150m750s750m750s2150"
"m750s750m750s2150m750s750m750s750m750s750m750s750m750s2150m750s2150"
"m750s750m750s750m750s2150m750s750m750s750m750s750m750s750m750s2150"
"m750s33850"
"m750s750m2850s2850"
"m750s2150m750s750m750s750m750s750m750s750m750s2150m750s2150m750s2150"
"m750s750m750s2150m750s2150m750s750m750s750m750s2150m750s750m750s2150"
"m750s750m750s2150m750s750m750s750m750s750m750s750m750s2150m750s2150"
"m750s750m750s750m750s2150m750s750m750s750m750s750m750s750m750s2150"
"m750s33850"
"m750s750m2850s2850"
"m750s2150m750s750m750s750m750s750m750s750m750s2150m750s2150m750s2150"
"m750s750m750s2150m750s2150m750s750m750s750m750s2150m750s750m750s2150"
"m750s750m750s2150m750s750m750s750m750s750m750s750m750s2150m750s2150"
"m750s750m750s750m750s2150m750s750m750s750m750s750m750s750m750s2150"
"m750s33850",
irsend.outputStr());
}
// Test sending an atypical data size.
TEST(TestSendWhynter, SendUnusualSize) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendWhynter(0x0, 8);
EXPECT_EQ(
"f38000d50"
"m750s750m2850s2850"
"m750s750m750s750m750s750m750s750m750s750m750s750m750s750m750s750"
"m750s88050",
irsend.outputStr());
irsend.reset();
irsend.sendWhynter(0x1234567890ABCDEF, 64);
EXPECT_EQ(
"f38000d50"
"m750s750m2850s2850"
"m750s750m750s750m750s750m750s2150m750s750m750s750m750s2150m750s750"
"m750s750m750s750m750s2150m750s2150m750s750m750s2150m750s750m750s750"
"m750s750m750s2150m750s750m750s2150m750s750m750s2150m750s2150m750s750"
"m750s750m750s2150m750s2150m750s2150m750s2150m750s750m750s750m750s750"
"m750s2150m750s750m750s750m750s2150m750s750m750s750m750s750m750s750"
"m750s2150m750s750m750s2150m750s750m750s2150m750s750m750s2150m750s2150"
"m750s2150m750s2150m750s750m750s750m750s2150m750s2150m750s750m750s2150"
"m750s2150m750s2150m750s2150m750s750m750s2150m750s2150m750s2150m750s2150"
"m750s12200",
irsend.outputStr());
}
// Tests for decodeWhynter().
// Decode normal Whynter messages.
TEST(TestDecodeWhynter, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Whynter 32-bit message.
irsend.reset();
irsend.sendWhynter(0x87654321);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(WHYNTER, irsend.capture.decode_type);
EXPECT_EQ(kWhynterBits, irsend.capture.bits);
EXPECT_EQ(0x87654321, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode normal repeated Whynter messages.
TEST(TestDecodeWhynter, NormalDecodeWithRepeatAndStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Whynter 32-bit message with 2 repeats.
irsend.reset();
irsend.sendWhynter(0x87654321, kWhynterBits, 2);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(WHYNTER, irsend.capture.decode_type);
EXPECT_EQ(kWhynterBits, irsend.capture.bits);
EXPECT_EQ(0x87654321, irsend.capture.value);
EXPECT_FALSE(irsend.capture.repeat);
irsend.makeDecodeResult(2 * kWhynterBits + 6);
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(WHYNTER, irsend.capture.decode_type);
EXPECT_EQ(kWhynterBits, irsend.capture.bits);
EXPECT_EQ(0x87654321, irsend.capture.value);
irsend.makeDecodeResult(2 * (2 * kWhynterBits + 6));
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(WHYNTER, irsend.capture.decode_type);
EXPECT_EQ(kWhynterBits, irsend.capture.bits);
EXPECT_EQ(0x87654321, irsend.capture.value);
}
// Decode unsupported Whynter messages.
TEST(TestDecodeWhynter, DecodeWithNonStrictSizes) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendWhynter(0x12, 8); // Illegal sized Whynter 8-bit message.
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeWhynter(&irsend.capture, kStartOffset, kWhynterBits,
true));
ASSERT_FALSE(irrecv.decodeWhynter(&irsend.capture, kStartOffset, 8, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeWhynter(&irsend.capture, kStartOffset, 8, false));
EXPECT_EQ(WHYNTER, irsend.capture.decode_type);
EXPECT_EQ(8, irsend.capture.bits);
EXPECT_EQ(0x12, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
irsend.sendWhynter(0x1234567890, 40); // Illegal size Whynter 40-bit message.
irsend.makeDecodeResult();
// Shouldn't pass with strict when we ask for less bits than we got.
ASSERT_FALSE(irrecv.decodeWhynter(&irsend.capture, kStartOffset, kWhynterBits,
true));
irsend.makeDecodeResult();
// Should fail with strict when we ask for the wrong bit size.
ASSERT_FALSE(irrecv.decodeWhynter(&irsend.capture, kStartOffset, 40, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeWhynter(&irsend.capture, kStartOffset, 40, false));
EXPECT_EQ(WHYNTER, irsend.capture.decode_type);
EXPECT_EQ(40, irsend.capture.bits);
EXPECT_EQ(0x1234567890, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
// Decode (non-standard) 64-bit messages.
TEST(TestDecodeWhynter, Decode64BitMessages) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Illegal size Whynter 64-bit message.
irsend.sendWhynter(0xFFFFFFFFFFFFFFFF, 64);
irsend.makeDecodeResult();
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeWhynter(&irsend.capture, kStartOffset, 64, false));
EXPECT_EQ(WHYNTER, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
// Fail to decode a non-Whynter example via GlobalCache
TEST(TestDecodeWhynter, FailToDecodeNonWhynterExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Modified a few entries to unexpected values, based on previous test case.
uint16_t gc_test[39] = {38000, 1, 1, 322, 162, 20, 61, 20, 61, 20,
20, 20, 20, 20, 20, 20, 127, 20, 61, 9,
20, 20, 61, 20, 20, 20, 61, 20, 61, 20,
61, 20, 20, 20, 20, 20, 20, 20, 884};
irsend.sendGC(gc_test, 39);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeWhynter(&irsend.capture));
ASSERT_FALSE(irrecv.decodeWhynter(&irsend.capture, kStartOffset, kWhynterBits,
false));
}

View File

@@ -0,0 +1,312 @@
// Copyright 2020 Christian Nilsson
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for decodeZepeal().
TEST(TestDecodeZepeal, RealExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
// fuuryou (speed) one of 5 repeats
const uint16_t rawData_1[35] = {
2328, 3412,
424, 1314, 1302, 436, 1276, 454, 424, 1316,
1274, 464, 1274, 458, 454, 1278, 450, 1288,
1302, 432, 424, 1306, 424, 1306, 424, 1306,
428, 1304, 450, 1290, 1298, 430, 426, 1308,
426}; // UNKNOWN B5E66F84
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData_1, 35, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type);
ASSERT_EQ(kZepealBits, irsend.capture.bits);
EXPECT_EQ(0x6C82, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
// kiri/iri (off/on) short press
const uint16_t rawData_2[179] = {
2338, 3384,
426, 1314, 1300, 436, 1304, 428, 424, 1314,
1302, 440, 1300, 428, 424, 1306, 424, 1314,
1300, 432, 400, 1330, 400, 1332, 418, 1316,
422, 1308, 424, 1308, 400, 1338, 1300, 432,
426, 6728,
2352, 3384,
426, 1312, 1302, 436, 1276, 438, 442, 1316,
1300, 434, 1302, 430, 424, 1308, 422, 1298,
1318, 414, 468, 1280, 426, 1306, 452, 1280,
450, 1282, 400, 1332, 400, 1338, 1302, 412,
416, 6760,
2350, 3384,
400, 1340, 1300, 438, 1300, 412, 444, 1312,
1302, 434, 1302, 412, 442, 1308, 426, 1312,
1302, 430, 422, 1308, 424, 1304, 400, 1332,
424, 1306, 402, 1332, 422, 1318, 1300, 430,
398, 6754,
2354, 3364,
442, 1316, 1300, 438, 1300, 430, 422, 1316,
1328, 410, 1302, 430, 400, 1332, 400, 1338,
1302, 412, 418, 1334, 398, 1314, 444, 1306,
400, 1330, 424, 1308, 424, 1314, 1300, 430,
428, 6774,
2334, 3384,
400, 1338, 1302, 436, 1304, 430, 396, 1340,
1300, 436, 1302, 432, 452, 1280, 398, 1338,
1302, 428, 402, 1330, 426, 1310, 422, 1306,
426, 1306, 426, 1306, 404, 1336, 1274, 458,
424}; // UNKNOWN C2DCDDE5
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData_2, 179, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type);
ASSERT_EQ(kZepealBits, irsend.capture.bits);
EXPECT_EQ(0x6C81, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_EQ(
"f38000d50"
"m2338s3384"
"m426s1314m1300s436m1304s428m424s1314m1302s440m1300s428m424s1306m424s1314"
"m1300s432m400s1330m400s1332m418s1316m422s1308m424s1308m400s1338m1300s432"
"m426s6728"
"m2352s3384"
"m426s1312m1302s436m1276s438m442s1316m1300s434m1302s430m424s1308m422s1298"
"m1318s414m468s1280m426s1306m452s1280m450s1282m400s1332m400s1338m1302s412"
"m416s6760"
"m2350s3384"
"m400s1340m1300s438m1300s412m444s1312m1302s434m1302s412m442s1308m426s1312"
"m1302s430m422s1308m424s1304m400s1332m424s1306m402s1332m422s1318m1300s430"
"m398s6754"
"m2354s3364"
"m442s1316m1300s438m1300s430m422s1316m1328s410m1302s430m400s1332m400s1338"
"m1302s412m418s1334m398s1314m444s1306m400s1330m424s1308m424s1314m1300s430"
"m428s6774"
"m2334s3384"
"m400s1338m1302s436m1304s430m396s1340m1300s436m1302s432m452s1280m398s1338"
"m1302s428m402s1330m426s1310m422s1306m426s1306m426s1306m404s1336m1274s458"
"m424",
irsend.outputStr());
// rizumu/oyasumi (rhythm/sleep - mode)
const uint16_t rawData_3[143] = {
2354, 3386,
422, 1312, 1278, 462, 1300, 410, 442, 1316,
1300, 436, 1302, 412, 448, 1304, 398, 1338,
1300, 430, 426, 1306, 426, 1304, 400, 1332,
400, 1340, 1300, 430, 400, 1334, 426, 1304,
398, 6756,
2354, 3382,
424, 1294, 1346, 410, 1302, 410, 418, 1340,
1300, 434, 1304, 430, 398, 1332, 400, 1338,
1276, 456, 400, 1334, 400, 1330, 400, 1332,
398, 1342, 1298, 430, 422, 1308, 400, 1332,
398, 6754,
2356, 3382,
400, 1340, 1274, 464, 1298, 412, 444, 1314,
1300, 438, 1300, 412, 442, 1308, 400, 1338,
1300, 414, 418, 1330, 400, 1332, 400, 1330,
426, 1312, 1332, 380, 446, 1306, 424, 1308,
424, 6736,
2352, 3380,
402, 1338, 1302, 436, 1300, 412, 420, 1338,
1300, 436, 1300, 412, 418, 1332, 402, 1336,
1302, 408, 418, 1332, 424, 1308, 424, 1306,
398, 1340, 1276, 454, 400, 1314, 418, 1332,
426}; // UNKNOWN 712E7A7F
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData_3, 143, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type);
ASSERT_EQ(kZepealBits, irsend.capture.bits);
EXPECT_EQ(0x6C84, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
// kiri taimaa (off timer)
const uint16_t rawData_4[143] = {
2308, 3392,
444, 1314, 1302, 436, 1330, 382, 420, 1338,
1302, 436, 1302, 408, 444, 1308, 450, 1288,
1300, 410, 420, 1332, 424, 1308, 400, 1338,
1302, 430, 428, 1286, 444, 1306, 452, 1282,
424, 6728,
2354, 3362,
444, 1314, 1274, 464, 1302, 410, 420, 1338,
1300, 438, 1328, 384, 444, 1308, 398, 1338,
1274, 456, 424, 1306, 402, 1332, 424, 1312,
1302, 412, 442, 1308, 424, 1308, 398, 1334,
422, 6752,
2336, 3382,
422, 1316, 1302, 434, 1302, 430, 400, 1340,
1302, 434, 1302, 410, 444, 1310, 422, 1314,
1302, 410, 444, 1304, 428, 1304, 426, 1312,
1302, 428, 424, 1308, 424, 1308, 426, 1304,
426, 6736,
2354, 3382,
424, 1314, 1302, 438, 1300, 410, 418, 1338,
1304, 436, 1304, 406, 418, 1336, 398, 1338,
1300, 432, 424, 1306, 426, 1306, 450, 1286,
1302, 412, 418, 1336, 396, 1334, 424, 1306,
424}; // UNKNOWN AAD01FEF
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData_4, 143, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type);
ASSERT_EQ(kZepealBits, irsend.capture.bits);
EXPECT_EQ(0x6C88, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
// iri taimaa (on timer)
const uint16_t rawData_5[143] = {
2364, 3358,
424, 1316, 1298, 438, 1300, 432, 424, 1314,
1298, 440, 1300, 430, 424, 1310, 424, 1312,
1300, 436, 1302, 430, 424, 1308, 422, 1308,
424, 1308, 424, 1314, 1302, 438, 1302, 430,
422, 6730,
2354, 3384,
422, 1314, 1300, 438, 1302, 426, 426, 1312,
1300, 438, 1302, 412, 418, 1330, 426, 1316,
1302, 434, 1302, 430, 426, 1306, 424, 1306,
424, 1308, 426, 1312, 1302, 436, 1302, 430,
428, 6752,
2364, 3354,
428, 1308, 1304, 436, 1302, 428, 426, 1314,
1330, 408, 1304, 428, 402, 1330, 398, 1338,
1306, 432, 1280, 454, 426, 1302, 428, 1304,
430, 1302, 428, 1310, 1306, 434, 1304, 428,
428, 6788,
2336, 3382,
428, 1310, 1302, 434, 1304, 430, 426, 1310,
1306, 434, 1304, 430, 424, 1306, 402, 1336,
1302, 438, 1304, 426, 426, 1304, 402, 1330,
426, 1304, 400, 1336, 1306, 434, 1304, 428,
424}; // UNKNOWN F8FC587
irsend.begin();
irsend.reset();
irsend.sendRaw(rawData_5, 143, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type);
ASSERT_EQ(kZepealBits, irsend.capture.bits);
EXPECT_EQ(0x6CC3, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
TEST(TestDecodeZepeal, SyntheticExample) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
// power
irsend.sendZepeal(0x6C81);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type);
EXPECT_EQ(kZepealBits, irsend.capture.bits);
EXPECT_EQ(0x6C81, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_EQ(
"f38000d50"
"m2330s3380"
"m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300"
"m1300s420m420s1300m420s1300m420s1300m420s1300m420s1300m420s1300m1300s420"
"m420s6750"
"m2330s3380"
"m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300"
"m1300s420m420s1300m420s1300m420s1300m420s1300m420s1300m420s1300m1300s420"
"m420s6750"
"m2330s3380"
"m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300"
"m1300s420m420s1300m420s1300m420s1300m420s1300m420s1300m420s1300m1300s420"
"m420s6750"
"m2330s3380"
"m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300"
"m1300s420m420s1300m420s1300m420s1300m420s1300m420s1300m420s1300m1300s420"
"m420s6750"
"m2330s3380"
"m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300"
"m1300s420m420s1300m420s1300m420s1300m420s1300m420s1300m420s1300m1300s420"
"m420s6750",
irsend.outputStr());
irsend.reset();
irsend.sendZepeal(0x6Cff, kZepealBits, kNoRepeat);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type);
EXPECT_EQ(kZepealBits, irsend.capture.bits);
EXPECT_EQ(0x6Cff, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_EQ(
"f38000d50"
"m2330s3380"
"m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300"
"m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420"
"m420s6750",
irsend.outputStr());
irsend.reset();
// testing a non valid value
irsend.sendZepeal(0xffff, kZepealBits, kNoRepeat);
irsend.makeDecodeResult();
// strict check should fail
ASSERT_FALSE(irrecv.decodeZepeal(&irsend.capture, kStartOffset,
kZepealBits, true));
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(-1, irsend.capture.decode_type);
// non strict check should be ok
ASSERT_TRUE(irrecv.decodeZepeal(&irsend.capture, kStartOffset,
kZepealBits, false));
EXPECT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type);
EXPECT_EQ(kZepealBits, irsend.capture.bits);
EXPECT_EQ(0xffff, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_EQ(
"f38000d50"
"m2330s3380"
"m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420"
"m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420"
"m420s6750",
irsend.outputStr());
}
TEST(TestUtils, Housekeeping) {
ASSERT_EQ("ZEPEAL", typeToString(decode_type_t::ZEPEAL));
ASSERT_EQ(decode_type_t::ZEPEAL, strToDecodeType("ZEPEAL"));
ASSERT_FALSE(hasACState(decode_type_t::ZEPEAL));
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::ZEPEAL));
ASSERT_EQ(kZepealBits, IRsend::defaultBits(decode_type_t::ZEPEAL));
ASSERT_EQ(kZepealMinRepeat, IRsend::minRepeats(decode_type_t::ZEPEAL));
}