From a7bdf65dacbd0fd7c247a3c7dc47c14904c9b4ae Mon Sep 17 00:00:00 2001 From: crankyoldgit Date: Wed, 18 Apr 2018 22:00:23 +1000 Subject: [PATCH 1/2] Initial support for G.I. Cable protocol * sendGICable() and decodeGICable() routines. * Add example & tools support. * Basic unit tests. * Based on data/info in Issue #447 Note: Untested against real devices. 39kHz frequency modulation based on external reference, but unverified. Observations indicate that it's _not_ 38kHz. --- examples/IRMQTTServer/IRMQTTServer.ino | 9 ++ src/IRrecv.cpp | 5 + src/IRrecv.h | 4 + src/IRremoteESP8266.h | 8 +- src/IRsend.cpp | 3 + src/IRsend.h | 4 + src/IRutils.cpp | 1 + src/ir_GICable.cpp | 119 +++++++++++++++++++++++ test/Makefile | 14 ++- test/ir_GICable_test.cpp | 129 +++++++++++++++++++++++++ tools/Makefile | 6 +- 11 files changed, 298 insertions(+), 4 deletions(-) create mode 100644 src/ir_GICable.cpp create mode 100644 test/ir_GICable_test.cpp diff --git a/examples/IRMQTTServer/IRMQTTServer.ino b/examples/IRMQTTServer/IRMQTTServer.ino index 9a7623d30..6d6ce7620 100644 --- a/examples/IRMQTTServer/IRMQTTServer.ino +++ b/examples/IRMQTTServer/IRMQTTServer.ino @@ -292,6 +292,7 @@ void handleRoot() { "" "" "" + "" "" "" "" @@ -1186,6 +1187,14 @@ void sendIRCode(int const ir_type, uint64_t const code, char const * code_str, repeat = std::max(repeat, (uint16_t) MITSUBISHI_MIN_REPEAT); irsend.sendMitsubishi2(code, bits, repeat); break; +#endif +#if SEND_GICABLE + case GICABLE: // 41 + if (bits == 0) + bits = GICABLE_BITS; + repeat = std::max(repeat, (uint16_t) GICABLE_BITS); + irsend.sendGICable(code, bits, repeat); + break; #endif } sendReqCounter++; diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index 022831b8d..62bb3a573 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -464,6 +464,11 @@ bool IRrecv::decode(decode_results *results, irparams_t *save) { if (decodeHitachiAC(results)) return true; #endif +#if DECODE_GICABLE + DPRINTLN("Attempting GICable decode"); + if (decodeGICable(results)) + return true; +#endif #if DECODE_HASH // decodeHash returns a hash on any input. // Thus, it needs to be last in the list. diff --git a/src/IRrecv.h b/src/IRrecv.h index 634165d4f..b173b9fe4 100644 --- a/src/IRrecv.h +++ b/src/IRrecv.h @@ -278,6 +278,10 @@ class IRrecv { bool decodeHitachiAC(decode_results *results, uint16_t nbits = HITACHI_AC_BITS, bool strict = true); #endif +#if DECODE_GICABLE + bool decodeGICable(decode_results *results, uint16_t nbits = GICABLE_BITS, + bool strict = true); +#endif }; #endif // IRRECV_H_ diff --git a/src/IRremoteESP8266.h b/src/IRremoteESP8266.h index d4806f7d5..263c6be5a 100644 --- a/src/IRremoteESP8266.h +++ b/src/IRremoteESP8266.h @@ -166,6 +166,9 @@ #define DECODE_HITACHI_AC true #define SEND_HITACHI_AC true +#define DECODE_GICABLE true +#define SEND_GICABLE true + #if (DECODE_ARGO || DECODE_DAIKIN || DECODE_FUJITSU_AC || DECODE_GREE || \ DECODE_KELVINATOR || DECODE_MITSUBISHI_AC || DECODE_TOSHIBA_AC || \ DECODE_TROTEC || DECODE_HAIER_AC || DECODE_HITACHI_AC) @@ -221,7 +224,8 @@ enum decode_type_t { CARRIER_AC, HAIER_AC, MITSUBISHI2, - HITACHI_AC + HITACHI_AC, + GICABLE }; // Message lengths & required repeat values @@ -239,6 +243,8 @@ enum decode_type_t { #define DENON_LEGACY_BITS 14U #define DISH_BITS 16U #define DISH_MIN_REPEAT 3U +#define GICABLE_BITS 16U +#define GICABLE_MIN_REPEAT 1U #define GREE_STATE_LENGTH 8U #define GREE_BITS (GREE_STATE_LENGTH * 8) #define HAIER_AC_STATE_LENGTH 9U diff --git a/src/IRsend.cpp b/src/IRsend.cpp index 5ca23e03f..d8e50f950 100644 --- a/src/IRsend.cpp +++ b/src/IRsend.cpp @@ -523,6 +523,9 @@ void IRsend::send(uint16_t type, uint64_t data, uint16_t nbits) { #endif #if SEND_MIDEA case MIDEA: sendMidea(data, nbits); break; +#endif +#if SEND_GICABLE + case GICABLE: sendGICable(data, nbits); break; #endif } } diff --git a/src/IRsend.h b/src/IRsend.h index b2cca97d5..2291b2755 100644 --- a/src/IRsend.h +++ b/src/IRsend.h @@ -246,6 +246,10 @@ void send(uint16_t type, uint64_t data, uint16_t nbits); uint16_t nbytes = HITACHI_AC_STATE_LENGTH, uint16_t repeat = 0); #endif +#if SEND_GICABLE + void sendGICable(uint64_t data, uint16_t nbits = GICABLE_BITS, + uint16_t repeat = GICABLE_MIN_REPEAT); +#endif protected: #ifdef UNIT_TEST diff --git a/src/IRutils.cpp b/src/IRutils.cpp index d08ba8eba..d5a765ad1 100644 --- a/src/IRutils.cpp +++ b/src/IRutils.cpp @@ -108,6 +108,7 @@ std::string typeToString(const decode_type_t protocol, case DENON: result = "DENON"; break; case DISH: result = "DISH"; break; case FUJITSU_AC: result = "FUJITSU_AC"; break; + case GICABLE: result = "GICABLE"; break; case GLOBALCACHE: result = "GLOBALCACHE"; break; case GREE: result = "GREE"; break; case HAIER_AC: result = "HAIER_AC"; break; diff --git a/src/ir_GICable.cpp b/src/ir_GICable.cpp new file mode 100644 index 000000000..2359acc43 --- /dev/null +++ b/src/ir_GICable.cpp @@ -0,0 +1,119 @@ +// Copyright 2018 David Conran + +#define __STDC_LIMIT_MACROS +#include +#include +#include "IRrecv.h" +#include "IRsend.h" +#include "IRutils.h" + +// GGGG IIIII CCCCC AAA BBBBB LL EEEEEEE +// GG GG III CC C AAAAA BB B LL EE +// GG III CC AA AA BBBBBB LL EEEEE +// GG GG ... III ... CC C AAAAAAA BB BB LL EE +// GGGGGG ... IIIII ... CCCCC AA AA BBBBBB LLLLLLL EEEEEEE +// +// Ref: +// https://github.com/cyborg5/IRLib2/blob/master/IRLibProtocols/IRLib_P09_GICable.h +// https://github.com/markszabo/IRremoteESP8266/issues/447 + +// Constants +#define GICABLE_HDR_MARK 9000U +#define GICABLE_HDR_SPACE 4400U +#define GICABLE_BIT_MARK 550U +#define GICABLE_ONE_SPACE 4400U +#define GICABLE_ZERO_SPACE 2200U +#define GICABLE_RPT_SPACE 2200U +#define GICABLE_MIN_COMMAND_LENGTH 99600U +#define GICABLE_MIN_GAP (GICABLE_MIN_COMMAND_LENGTH - \ + (GICABLE_HDR_MARK + GICABLE_HDR_SPACE + \ + GICABLE_BITS * (GICABLE_BIT_MARK + GICABLE_ONE_SPACE) + GICABLE_BIT_MARK)) + + +#if SEND_GICABLE +// Send a raw G.I. Cable formatted message. +// +// Args: +// data: The message to be sent. +// nbits: The number of bits of the message to be sent. +// Typically GICABLE_BITS. +// repeat: The number of times the command is to be repeated. +// +// Status: Alpha / Untested. +// +// Ref: +void IRsend::sendGICable(uint64_t data, uint16_t nbits, uint16_t repeat) { + sendGeneric(GICABLE_HDR_MARK, GICABLE_HDR_SPACE, + GICABLE_BIT_MARK, GICABLE_ONE_SPACE, + GICABLE_BIT_MARK, GICABLE_ZERO_SPACE, + GICABLE_BIT_MARK, GICABLE_MIN_GAP, GICABLE_MIN_COMMAND_LENGTH, + data, nbits, 39, true, 0, // Repeats are handled later. + 50); + // Message repeat sequence. + if (repeat) + sendGeneric(GICABLE_HDR_MARK, GICABLE_RPT_SPACE, + 0, 0, 0, 0, // No actual data sent. + GICABLE_BIT_MARK, GICABLE_MIN_GAP, GICABLE_MIN_COMMAND_LENGTH, + 0, 0, // No data to be sent. + 39, true, repeat - 1, 50); +} +#endif // SEND_GICABLE + +#if DECODE_GICABLE +// Decode the supplied G.I. Cable message. +// +// Args: +// results: Ptr to the data to decode and where to store the decode result. +// nbits: The number of data bits to expect. Typically GICABLE_BITS. +// strict: Flag indicating if we should perform strict matching. +// Returns: +// boolean: True if it can decode it, false if it can't. +// +// Status: Alpha / Not tested against a real device. +bool IRrecv::decodeGICable(decode_results *results, uint16_t nbits, + bool strict) { + if (results->rawlen < 2 * (nbits + HEADER + FOOTER) - 1) + return false; // Can't possibly be a valid GICABLE message. + if (strict && nbits != GICABLE_BITS) + return false; // Not strictly an GICABLE message. + + uint64_t data = 0; + uint16_t offset = OFFSET_START; + + // Header + if (!matchMark(results->rawbuf[offset++], GICABLE_HDR_MARK)) return false; + if (!matchSpace(results->rawbuf[offset++], GICABLE_HDR_SPACE)) return false; + + // Data + match_result_t data_result = matchData(&(results->rawbuf[offset]), nbits, + GICABLE_BIT_MARK, + GICABLE_ONE_SPACE, + GICABLE_BIT_MARK, + GICABLE_ZERO_SPACE); + if (data_result.success == false) return false; + data = data_result.data; + offset += data_result.used; + + // Footer + if (!matchMark(results->rawbuf[offset++], GICABLE_BIT_MARK)) return false; + if (offset < results->rawlen && + !matchAtLeast(results->rawbuf[offset++], GICABLE_MIN_GAP)) + return false; + + // Compliance + if (strict) { + // We expect a repeat frame. + if (!matchMark(results->rawbuf[offset++], GICABLE_HDR_MARK)) return false; + if (!matchSpace(results->rawbuf[offset++], GICABLE_RPT_SPACE)) return false; + if (!matchMark(results->rawbuf[offset++], GICABLE_BIT_MARK)) return false; + } + + // Success + results->bits = nbits; + results->value = data; + results->decode_type = GICABLE; + results->command = 0; + results->address = 0; + return true; +} +#endif // DECODE_GICABLE diff --git a/test/Makefile b/test/Makefile index 259683bf9..e4f4945fb 100644 --- a/test/Makefile +++ b/test/Makefile @@ -34,7 +34,7 @@ TESTS = IRutils_test IRsend_test ir_NEC_test ir_GlobalCache_test \ ir_Aiwa_test ir_Denon_test ir_Sanyo_test ir_Daikin_test ir_Coolix_test \ ir_Gree_test IRrecv_test ir_Pronto_test ir_Fujitsu_test ir_Nikai_test \ ir_Toshiba_test ir_Midea_test ir_Magiquest_test ir_Lasertag_test \ - ir_Carrier_test ir_Haier_test ir_Hitachi_test + ir_Carrier_test ir_Haier_test ir_Hitachi_test ir_GICable_test # All Google Test headers. Usually you shouldn't change this # definition. @@ -74,7 +74,8 @@ PROTOCOLS = ir_NEC.o ir_Sony.o ir_Samsung.o ir_JVC.o ir_RCMM.o ir_RC5_RC6.o \ ir_LG.o ir_Mitsubishi.o ir_Fujitsu.o ir_Sharp.o ir_Sanyo.o ir_Denon.o ir_Dish.o \ ir_Panasonic.o ir_Whynter.o ir_Coolix.o ir_Aiwa.o ir_Sherwood.o \ ir_Kelvinator.o ir_Daikin.o ir_Gree.o ir_Pronto.o ir_Nikai.o ir_Toshiba.o \ - ir_Midea.o ir_Magiquest.o ir_Lasertag.o ir_Carrier.o ir_Haier.o ir_Hitachi.o + ir_Midea.o ir_Magiquest.o ir_Lasertag.o ir_Carrier.o ir_Haier.o \ + ir_Hitachi.o ir_GICable.o # Common object files COMMON_OBJ = IRutils.o IRtimer.o IRsend.o IRrecv.o ir_GlobalCache.o \ @@ -415,3 +416,12 @@ ir_Hitachi_test.o : ir_Hitachi_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) ir_Hitachi_test : $(COMMON_OBJ) ir_Hitachi_test.o $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ + +ir_GICable.o : $(USER_DIR)/ir_GICable.cpp $(COMMON_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_GICable.cpp + +ir_GICable_test.o : ir_GICable_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -I$(USER_DIR) -c ir_GICable_test.cpp + +ir_GICable_test : $(COMMON_OBJ) ir_GICable_test.o + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ diff --git a/test/ir_GICable_test.cpp b/test/ir_GICable_test.cpp new file mode 100644 index 000000000..55aa22bf6 --- /dev/null +++ b/test/ir_GICable_test.cpp @@ -0,0 +1,129 @@ +// 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( + "m9000s4400" + "m550s2200m550s2200m550s2200m550s2200m550s2200m550s2200m550s2200m550s2200" + "m550s2200m550s2200m550s2200m550s2200m550s2200m550s2200m550s2200m550s2200" + "m550s41650" + "m9000s2200m550s87850", irsend.outputStr()); + irsend.sendGICable(0x8807); + EXPECT_EQ( + "m9000s4400" + "m550s4400m550s2200m550s2200m550s2200m550s4400m550s2200m550s2200m550s2200" + "m550s2200m550s2200m550s2200m550s2200m550s2200m550s4400m550s4400m550s4400" + "m550s30650" + "m9000s2200m550s87850", irsend.outputStr()); + irsend.sendGICable(0xFFFF); + EXPECT_EQ( + "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, GICABLE_BITS, 0); + EXPECT_EQ( + "m9000s4400" + "m550s4400m550s2200m550s2200m550s2200m550s4400m550s2200m550s2200m550s2200" + "m550s2200m550s2200m550s2200m550s2200m550s2200m550s4400m550s4400m550s4400" + "m550s30650", irsend.outputStr()); + // Send a command with 1 repeat. + irsend.sendGICable(0x8807, GICABLE_BITS, 1); + EXPECT_EQ( + "m9000s4400" + "m550s4400m550s2200m550s2200m550s2200m550s4400m550s2200m550s2200m550s2200" + "m550s2200m550s2200m550s2200m550s2200m550s2200m550s4400m550s4400m550s4400" + "m550s30650" + "m9000s2200m550s87850", irsend.outputStr()); + // Send a command with 3 repeats. + irsend.sendGICable(0x8807, GICABLE_BITS, 3); + EXPECT_EQ( + "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(GICABLE_BITS, 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/markszabo/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(GICABLE_BITS, 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/markszabo/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(GICABLE_BITS, irsend.capture.bits); + EXPECT_EQ(0x6C0E, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); +} diff --git a/tools/Makefile b/tools/Makefile index 696748bf4..0cd12fc71 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -34,7 +34,8 @@ PROTOCOLS = ir_NEC.o ir_Sony.o ir_Samsung.o ir_JVC.o ir_RCMM.o ir_RC5_RC6.o \ ir_Denon.o ir_Dish.o ir_Panasonic.o ir_Whynter.o ir_Coolix.o \ ir_Aiwa.o ir_Sherwood.o ir_Kelvinator.o ir_Daikin.o ir_Gree.o \ ir_Pronto.o ir_GlobalCache.o ir_Nikai.o ir_Toshiba.o ir_Midea.o \ - ir_Magiquest.o ir_Lasertag.o ir_Carrier.o ir_Haier.o ir_Hitachi.o + ir_Magiquest.o ir_Lasertag.o ir_Carrier.o ir_Haier.o ir_Hitachi.o \ + ir_GICable.o # Common object files COMMON_OBJ = IRutils.o IRtimer.o IRsend.o IRrecv.o $(PROTOCOLS) @@ -157,3 +158,6 @@ ir_Haier.o : $(USER_DIR)/ir_Haier.cpp $(USER_DIR)/ir_Haier.h $(GTEST_HEADERS) ir_Hitachi.o : $(USER_DIR)/ir_Hitachi.cpp $(GTEST_HEADERS) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Hitachi.cpp + +ir_GICable.o : $(USER_DIR)/ir_GICable.cpp $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_GICable.cpp From 797b67d634b19354aef23e30215a5750c2c3518e Mon Sep 17 00:00:00 2001 From: crankyoldgit Date: Sat, 21 Apr 2018 21:55:15 +1000 Subject: [PATCH 2/2] Change GIcable/JVC decode order. GICable "Zero" key is being decoded as a JVC signal. GICable has a manditory repeat code which it checks for. Move it before JVC decoding should make it match or discard correctly any JVC/GICable issues. Add a unit test for this case. --- src/IRrecv.cpp | 12 +++++++----- test/ir_GICable_test.cpp | 23 +++++++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index 62bb3a573..cac92f68e 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -358,6 +358,13 @@ bool IRrecv::decode(decode_results *results, irparams_t *save) { if (decodeLG(results, LG32_BITS, true)) return true; #endif +#if DECODE_GICABLE + // Note: Needs to happen before JVC decode, because it looks similar except + // with a required NEC-like repeat code. + DPRINTLN("Attempting GICable decode"); + if (decodeGICable(results)) + return true; +#endif #if DECODE_JVC DPRINTLN("Attempting JVC decode"); if (decodeJVC(results)) @@ -464,11 +471,6 @@ bool IRrecv::decode(decode_results *results, irparams_t *save) { if (decodeHitachiAC(results)) return true; #endif -#if DECODE_GICABLE - DPRINTLN("Attempting GICable decode"); - if (decodeGICable(results)) - return true; -#endif #if DECODE_HASH // decodeHash returns a hash on any input. // Thus, it needs to be last in the list. diff --git a/test/ir_GICable_test.cpp b/test/ir_GICable_test.cpp index 55aa22bf6..3eb5b67ae 100644 --- a/test/ir_GICable_test.cpp +++ b/test/ir_GICable_test.cpp @@ -127,3 +127,26 @@ TEST(TestDecodeGICable, RealExampleDecodeLEFT) { 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/markszabo/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(GICABLE_BITS, irsend.capture.bits); + EXPECT_EQ(0x0, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); +}