diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index 2524dfe17..d20aaa7ca 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -830,6 +830,12 @@ bool IRrecv::decode(decode_results *results, irparams_t *save, if (decodeHitachiAC(results, offset, kHitachiAc344Bits, true, false)) return true; #endif // DECODE_HITACHI_AC344 +#if DECODE_HITACHI_AC264 + // HitachiAC264 should be checked before HitachiAC + DPRINTLN("Attempting Hitachi AC264 decode"); + if (decodeHitachiAC(results, offset, kHitachiAc264Bits, true, false)) + return true; +#endif // DECODE_HITACHI_AC264 #if DECODE_HITACHI_AC2 // HitachiAC2 should be checked before HitachiAC DPRINTLN("Attempting Hitachi AC2 decode"); diff --git a/src/IRrecv.h b/src/IRrecv.h index 75070172d..379e45902 100644 --- a/src/IRrecv.h +++ b/src/IRrecv.h @@ -590,11 +590,13 @@ class IRrecv { const uint16_t nbits = kHaierAC176Bits, const bool strict = true); #endif // DECODE_HAIER_AC176 -#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC2 || DECODE_HITACHI_AC344) +#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC2 || DECODE_HITACHI_AC264 || \ + DECODE_HITACHI_AC344) bool decodeHitachiAC(decode_results *results, uint16_t offset = kStartOffset, const uint16_t nbits = kHitachiAcBits, const bool strict = true, const bool MSBfirst = true); -#endif +#endif // (DECODE_HITACHI_AC || DECODE_HITACHI_AC2 || DECODE_HITACHI_AC264 || + // DECODE_HITACHI_AC344) #if DECODE_HITACHI_AC1 bool decodeHitachiAC1(decode_results *results, uint16_t offset = kStartOffset, const uint16_t nbits = kHitachiAc1Bits, diff --git a/src/IRremoteESP8266.h b/src/IRremoteESP8266.h index 8342830af..26a05414c 100644 --- a/src/IRremoteESP8266.h +++ b/src/IRremoteESP8266.h @@ -490,6 +490,13 @@ #define SEND_HITACHI_AC3 _IR_ENABLE_DEFAULT_ #endif // SEND_HITACHI_AC3 +#ifndef DECODE_HITACHI_AC264 +#define DECODE_HITACHI_AC264 _IR_ENABLE_DEFAULT_ +#endif // DECODE_HITACHI_AC264 +#ifndef SEND_HITACHI_AC264 +#define SEND_HITACHI_AC264 _IR_ENABLE_DEFAULT_ +#endif // SEND_HITACHI_AC264 + #ifndef DECODE_HITACHI_AC344 #define DECODE_HITACHI_AC344 _IR_ENABLE_DEFAULT_ #endif // DECODE_HITACHI_AC344 @@ -854,7 +861,7 @@ DECODE_HITACHI_AC344 || DECODE_CORONA_AC || DECODE_SANYO_AC || \ DECODE_VOLTAS || DECODE_MIRAGE || DECODE_HAIER_AC176 || \ DECODE_TEKNOPOINT || DECODE_KELON || DECODE_TROTEC_3550 || \ - DECODE_SANYO_AC88 || DECODE_RHOSS || \ + DECODE_SANYO_AC88 || DECODE_RHOSS || DECODE_HITACHI_AC264 || \ false) // Add any DECODE to the above if it uses result->state (see kStateSizeMax) // you might also want to add the protocol to hasACState function @@ -1005,8 +1012,9 @@ enum decode_type_t { RHOSS, AIRTON, COOLIX48, // 110 + HITACHI_AC264, // Add new entries before this one, and update it to point to the last entry. - kLastDecodeType = COOLIX48, + kLastDecodeType = HITACHI_AC264, }; // Message lengths & required repeat values @@ -1116,6 +1124,8 @@ const uint16_t kHitachiAc3StateLength = 27; const uint16_t kHitachiAc3Bits = kHitachiAc3StateLength * 8; const uint16_t kHitachiAc3MinStateLength = 15; const uint16_t kHitachiAc3MinBits = kHitachiAc3MinStateLength * 8; +const uint16_t kHitachiAc264StateLength = 33; +const uint16_t kHitachiAc264Bits = kHitachiAc264StateLength * 8; const uint16_t kHitachiAc344StateLength = 43; const uint16_t kHitachiAc344Bits = kHitachiAc344StateLength * 8; const uint16_t kHitachiAc424StateLength = 53; diff --git a/src/IRsend.cpp b/src/IRsend.cpp index e0a66e068..642be72d3 100644 --- a/src/IRsend.cpp +++ b/src/IRsend.cpp @@ -718,6 +718,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { return kHitachiAc2Bits; case HITACHI_AC3: return kHitachiAc3Bits; + case HITACHI_AC264: + return kHitachiAc264Bits; case HITACHI_AC344: return kHitachiAc344Bits; case HITACHI_AC424: @@ -1210,6 +1212,11 @@ bool IRsend::send(const decode_type_t type, const uint8_t *state, sendHitachiAc3(state, nbytes); break; #endif // SEND_HITACHI_AC3 +#if SEND_HITACHI_AC264 + case HITACHI_AC264: + sendHitachiAc264(state, nbytes); + break; +#endif // SEND_HITACHI_AC264 #if SEND_HITACHI_AC344 case HITACHI_AC344: sendHitachiAc344(state, nbytes); diff --git a/src/IRsend.h b/src/IRsend.h index 1213bebe1..6528d95ee 100644 --- a/src/IRsend.h +++ b/src/IRsend.h @@ -592,6 +592,11 @@ class IRsend { // different sizes const uint16_t repeat = kHitachiAcDefaultRepeat); #endif // SEND_HITACHI_AC3 +#if SEND_HITACHI_AC264 + void sendHitachiAc264(const unsigned char data[], + const uint16_t nbytes = kHitachiAc264StateLength, + const uint16_t repeat = kHitachiAcDefaultRepeat); +#endif // SEND_HITACHI_AC264 #if SEND_HITACHI_AC344 void sendHitachiAc344(const unsigned char data[], const uint16_t nbytes = kHitachiAc344StateLength, diff --git a/src/IRtext.cpp b/src/IRtext.cpp index 077e7b0e7..ad99e7e74 100644 --- a/src/IRtext.cpp +++ b/src/IRtext.cpp @@ -391,6 +391,7 @@ IRTEXT_CONST_BLOB_DECL(kAllProtocolNamesStr) { D_STR_RHOSS "\x0" D_STR_AIRTON "\x0" D_STR_COOLIX48 "\x0" + D_STR_HITACHI_AC264 "\x0" ///< New protocol strings should be added just above this line. "\x0" ///< This string requires double null termination. }; diff --git a/src/IRutils.cpp b/src/IRutils.cpp index e1f889966..bb1029440 100644 --- a/src/IRutils.cpp +++ b/src/IRutils.cpp @@ -190,6 +190,7 @@ bool hasACState(const decode_type_t protocol) { case HITACHI_AC1: case HITACHI_AC2: case HITACHI_AC3: + case HITACHI_AC264: case HITACHI_AC344: case HITACHI_AC424: case KELVINATOR: diff --git a/src/ir_Hitachi.cpp b/src/ir_Hitachi.cpp index 49781997e..ca2a7fcf9 100644 --- a/src/ir_Hitachi.cpp +++ b/src/ir_Hitachi.cpp @@ -56,7 +56,8 @@ using irutils::checkInvertedBytePairs; using irutils::invertBytePairs; using irutils::minsToString; -#if (SEND_HITACHI_AC || SEND_HITACHI_AC2 || SEND_HITACHI_AC344) +#if (SEND_HITACHI_AC || SEND_HITACHI_AC2 || SEND_HITACHI_AC264 || \ + SEND_HITACHI_AC344) /// Send a Hitachi 28-byte/224-bit A/C formatted message. (HITACHI_AC) /// Status: STABLE / Working. /// @param[in] data The message to be sent. @@ -68,13 +69,20 @@ void IRsend::sendHitachiAC(const unsigned char data[], const uint16_t nbytes, if (nbytes < kHitachiAcStateLength) return; // Not enough bytes to send a proper message. - const bool MSBfirst = (nbytes == kHitachiAc344StateLength) ? false : true; + bool MSBfirst = true; + switch (nbytes) { + case kHitachiAc264StateLength: + case kHitachiAc344StateLength: + MSBfirst = false; + } + sendGeneric(kHitachiAcHdrMark, kHitachiAcHdrSpace, kHitachiAcBitMark, kHitachiAcOneSpace, kHitachiAcBitMark, kHitachiAcZeroSpace, kHitachiAcBitMark, kHitachiAcMinGap, data, nbytes, 38, MSBfirst, repeat, 50); } -#endif // (SEND_HITACHI_AC || SEND_HITACHI_AC2 || SEND_HITACHI_AC344) +#endif // (SEND_HITACHI_AC || SEND_HITACHI_AC2 || SEND_HITACHI_AC264 || + // SEND_HITACHI_AC344) #if SEND_HITACHI_AC1 /// Send a Hitachi 13 byte/224-bit A/C formatted message. (HITACHI_AC1) @@ -82,7 +90,7 @@ void IRsend::sendHitachiAC(const unsigned char data[], const uint16_t nbytes, /// @param[in] data The message to be sent. /// @param[in] nbytes The number of bytes of message to be sent. /// @param[in] repeat The number of times the command is to be repeated. -/// @note Basically the same as sendHitatchiAC() except different size & header. +/// @note Basically the same as sendHitachiAC() except different size & header. /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/453 void IRsend::sendHitachiAC1(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { @@ -97,7 +105,7 @@ void IRsend::sendHitachiAC1(const unsigned char data[], const uint16_t nbytes, #if SEND_HITACHI_AC2 /// Send a Hitachi 53 byte/424-bit A/C formatted message. (HITACHI_AC2) -/// Basically the same as sendHitatchiAC() except different size. +/// Basically the same as sendHitachiAC() except different size. /// Status: STABLE / Expected to work. /// @param[in] data The message to be sent. /// @param[in] nbytes The number of bytes of message to be sent. @@ -112,7 +120,7 @@ void IRsend::sendHitachiAC2(const unsigned char data[], const uint16_t nbytes, #if SEND_HITACHI_AC344 /// Send a Hitachi A/C 43-byte/344-bit message. (HITACHI_AC344) -/// Basically the same as sendHitatchiAC() except different size. +/// Basically the same as sendHitachiAC() except different size. /// Status: Beta / Probably works. /// @param[in] data An array of bytes containing the IR command. /// @param[in] nbytes Nr. of bytes of data in the array. @@ -827,7 +835,7 @@ String IRHitachiAc1::toString(void) const { } #if (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2 || \ - DECODE_HITACHI_AC344) + DECODE_HITACHI_AC344 || DECODE_HITACHI_AC264) /// Decode the supplied Hitachi A/C message. /// Status: STABLE / Expected to work. /// @param[in,out] results Ptr to the data to decode & where to store the result @@ -835,7 +843,7 @@ String IRHitachiAc1::toString(void) const { /// raw data. Typically/Defaults to kStartOffset. /// @param[in] nbits The number of data bits to expect. /// Typically kHitachiAcBits, kHitachiAc1Bits, kHitachiAc2Bits, -/// kHitachiAc344Bits +/// kHitachiAc344Bits, kHitachiAc264Bits /// @param[in] strict Flag indicating if we should perform strict matching. /// @param[in] MSBfirst Is the data per byte stored in MSB First (true) or /// LSB First order(false)? @@ -843,6 +851,7 @@ String IRHitachiAc1::toString(void) const { /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/417 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/453 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1729 bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict, const bool MSBfirst) { @@ -853,6 +862,7 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, case kHitachiAcBits: case kHitachiAc1Bits: case kHitachiAc2Bits: + case kHitachiAc264Bits: case kHitachiAc344Bits: break; // Okay to continue. default: @@ -879,16 +889,20 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, // Compliance if (strict) { - if (nbits / 8 == kHitachiAcStateLength && - !IRHitachiAc::validChecksum(results->state, kHitachiAcStateLength)) - return false; - if (nbits / 8 == kHitachiAc1StateLength && - !IRHitachiAc1::validChecksum(results->state, kHitachiAc1StateLength)) - return false; - if (nbits / 8 == kHitachiAc344StateLength && - !IRHitachiAc3::hasInvertedStates(results->state, - kHitachiAc344StateLength)) - return false; + const uint16_t nbytes = nbits / 8; + switch (nbytes) { + case kHitachiAcStateLength: + if (!IRHitachiAc::validChecksum(results->state, nbytes)) return false; + break; + case kHitachiAc1StateLength: + if (!IRHitachiAc1::validChecksum(results->state, nbytes)) return false; + break; + case kHitachiAc264StateLength: + case kHitachiAc344StateLength: + if (!IRHitachiAc3::hasInvertedStates(results->state, nbytes)) + return false; + break; + } } // Success @@ -899,6 +913,9 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, case kHitachiAc2Bits: results->decode_type = decode_type_t::HITACHI_AC2; break; + case kHitachiAc264Bits: + results->decode_type = decode_type_t::HITACHI_AC264; + break; case kHitachiAc344Bits: results->decode_type = decode_type_t::HITACHI_AC344; break; @@ -913,7 +930,7 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, return true; } #endif // (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2 || - // DECODE_HITACHI_AC344) + // DECODE_HITACHI_AC344 || DECODE_HITACHI_AC264) #if SEND_HITACHI_AC424 /// Send a Hitachi 53-byte/424-bit A/C formatted message. (HITACHI_AC424) @@ -1578,3 +1595,24 @@ String IRHitachiAc344::toString(void) const { result += ')'; return result; } + + +#if SEND_HITACHI_AC264 +/// Send a Hitachi 33-byte/264-bit A/C message (HITACHI_AC264) +/// Basically the same as sendHitachiAC() except different size. +/// Status: STABLE / Reported as working. +/// @param[in] data An array of bytes containing the IR command. +/// @param[in] nbytes Nr. of bytes of data in the array. +/// @param[in] repeat Nr. of times the message is to be repeated. (Default = 0). +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1729 +void IRsend::sendHitachiAc264(const unsigned char data[], const uint16_t nbytes, + const uint16_t repeat) { + if (nbytes < kHitachiAc264StateLength) + return; // Not enough bytes to send a proper message. + sendHitachiAC(data, nbytes, repeat); +} +#endif // SEND_HITACHI_AC264 + +#if DECODE_HITACHI_AC264 +// For Decoding HITACHI_AC264, see `decodeHitachiAC` +#endif // DECODE_HITACHI_AC264 diff --git a/src/ir_Hitachi.h b/src/ir_Hitachi.h index 32167596f..316614dc0 100644 --- a/src/ir_Hitachi.h +++ b/src/ir_Hitachi.h @@ -7,6 +7,7 @@ /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1056 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1060 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1729 // Supports: // Brand: Hitachi, Model: RAS-35THA6 remote @@ -19,6 +20,8 @@ // Brand: Hitachi, Model: R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1) // Brand: Hitachi, Model: RAS-22NK A/C (HITACHI_AC344) // Brand: Hitachi, Model: RF11T1 remote (HITACHI_AC344) +// Brand: Hitachi, Model: RAR-2P2 remote (HITACHI_AC264) +// Brand: Hitachi, Model: RAK-25NH5 A/C (HITACHI_AC264) #ifndef IR_HITACHI_H_ #define IR_HITACHI_H_ diff --git a/src/locale/defaults.h b/src/locale/defaults.h index d8142e20e..c412ce972 100644 --- a/src/locale/defaults.h +++ b/src/locale/defaults.h @@ -800,19 +800,22 @@ D_STR_INDIRECT " " D_STR_MODE #define D_STR_HITACHI_AC "HITACHI_AC" #endif // D_STR_HITACHI_AC #ifndef D_STR_HITACHI_AC1 -#define D_STR_HITACHI_AC1 "HITACHI_AC1" +#define D_STR_HITACHI_AC1 D_STR_HITACHI_AC "1" #endif // D_STR_HITACHI_AC1 #ifndef D_STR_HITACHI_AC2 -#define D_STR_HITACHI_AC2 "HITACHI_AC2" +#define D_STR_HITACHI_AC2 D_STR_HITACHI_AC "2" #endif // D_STR_HITACHI_AC2 #ifndef D_STR_HITACHI_AC3 -#define D_STR_HITACHI_AC3 "HITACHI_AC3" +#define D_STR_HITACHI_AC3 D_STR_HITACHI_AC "3" #endif // D_STR_HITACHI_AC3 +#ifndef D_STR_HITACHI_AC264 +#define D_STR_HITACHI_AC264 D_STR_HITACHI_AC "264" +#endif // D_STR_HITACHI_AC264 #ifndef D_STR_HITACHI_AC344 -#define D_STR_HITACHI_AC344 "HITACHI_AC344" +#define D_STR_HITACHI_AC344 D_STR_HITACHI_AC "344" #endif // D_STR_HITACHI_AC344 #ifndef D_STR_HITACHI_AC424 -#define D_STR_HITACHI_AC424 "HITACHI_AC424" +#define D_STR_HITACHI_AC424 D_STR_HITACHI_AC "424" #endif // D_STR_HITACHI_AC424 #ifndef D_STR_INAX #define D_STR_INAX "INAX" diff --git a/test/ir_Hitachi_test.cpp b/test/ir_Hitachi_test.cpp index 2bbbd29e9..10fb0b6ea 100644 --- a/test/ir_Hitachi_test.cpp +++ b/test/ir_Hitachi_test.cpp @@ -856,6 +856,15 @@ TEST(TestUtils, Housekeeping) { IRsend::defaultBits(decode_type_t::HITACHI_AC344)); ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::HITACHI_AC344)); + + ASSERT_EQ("HITACHI_AC264", typeToString(decode_type_t::HITACHI_AC264)); + ASSERT_EQ(decode_type_t::HITACHI_AC264, strToDecodeType("HITACHI_AC264")); + ASSERT_TRUE(hasACState(decode_type_t::HITACHI_AC264)); + ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::HITACHI_AC264)); + ASSERT_EQ(kHitachiAc264Bits, + IRsend::defaultBits(decode_type_t::HITACHI_AC264)); + ASSERT_EQ(kNoRepeat, + IRsend::minRepeats(decode_type_t::HITACHI_AC264)); } // Decode a 'real' HitachiAc424 message. @@ -1984,3 +1993,98 @@ TEST(TestIRHitachiAc344Class, SwingV) { ac.setSwingV(false); EXPECT_FALSE(ac.getSwingV()); } + +// Decode a 'real' HitachiAc264 message. +TEST(TestDecodeHitachiAc264, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + const uint8_t expected[kHitachiAc264StateLength] = { + 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xCC, 0x33, 0x92, + 0x6D, 0x13, 0xEC, 0x6C, 0x93, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x16, 0xE9, 0xC1, 0x3E, 0x00, + 0xFF, 0x00, 0xFF}; + + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1729#issuecomment-1006938712 + const uint16_t rawData[531] = { + 3392, 1752, 372, 1356, 344, 504, 344, 504, 344, 480, 370, 480, 370, 478, + 370, 478, 372, 480, 370, 478, 370, 480, 370, 478, 370, 480, 370, 1330, + 370, 478, 370, 480, 370, 478, 370, 478, 370, 480, 370, 478, 370, 480, 370, + 504, 346, 504, 344, 480, 370, 504, 346, 478, 370, 478, 370, 478, 372, 480, + 370, 480, 370, 504, 346, 1330, 370, 480, 370, 1356, 346, 1330, 370, 1354, + 346, 1328, 370, 1330, 370, 1328, 370, 478, 372, 1330, 370, 1328, 370, + 1356, 346, 1354, 344, 1328, 372, 1354, 344, 1356, 344, 1330, 370, 1328, + 372, 480, 370, 478, 370, 504, 346, 478, 372, 476, 372, 504, 346, 480, 370, + 504, 344, 478, 372, 504, 344, 1328, 372, 1328, 372, 478, 370, 504, 346, + 1330, 370, 1328, 372, 1328, 370, 1356, 344, 478, 370, 478, 370, 1356, 344, + 1328, 372, 480, 370, 478, 372, 504, 346, 1330, 370, 478, 370, 480, 370, + 1330, 370, 478, 370, 480, 370, 1328, 370, 1330, 370, 480, 372, 1352, 346, + 1328, 372, 504, 346, 1328, 370, 1328, 370, 480, 370, 1328, 372, 1328, 370, + 504, 344, 478, 372, 1330, 370, 478, 370, 480, 370, 480, 370, 478, 370, + 480, 370, 1356, 346, 1328, 370, 480, 370, 1330, 370, 1330, 370, 1330, 370, + 478, 370, 506, 344, 1328, 372, 1328, 372, 478, 372, 1330, 370, 1328, 372, + 478, 370, 1330, 370, 1328, 372, 504, 344, 480, 370, 1330, 370, 504, 344, + 504, 346, 1354, 346, 504, 346, 478, 372, 478, 370, 480, 370, 478, 370, + 492, 358, 478, 370, 478, 370, 1328, 372, 1330, 370, 1328, 372, 1354, 346, + 1328, 372, 1328, 370, 1330, 370, 1328, 372, 476, 372, 504, 346, 478, 372, + 480, 370, 480, 370, 504, 344, 478, 370, 480, 370, 1328, 370, 1330, 372, + 1328, 370, 1330, 370, 1330, 370, 1330, 368, 1330, 370, 1330, 370, 480, + 370, 480, 370, 478, 370, 504, 344, 480, 370, 478, 370, 504, 344, 478, 372, + 1328, 370, 1330, 370, 1330, 370, 1330, 370, 1328, 372, 1356, 344, 1330, + 370, 1330, 370, 480, 370, 478, 370, 482, 368, 480, 370, 480, 370, 480, + 370, 480, 370, 480, 370, 1330, 370, 1354, 346, 1330, 370, 1354, 346, 1330, + 370, 1330, 370, 1330, 370, 1330, 370, 504, 346, 480, 370, 478, 372, 478, + 372, 504, 344, 480, 370, 480, 370, 504, 344, 1330, 370, 1328, 370, 1330, + 372, 1328, 370, 1354, 346, 1328, 370, 1330, 370, 1330, 370, 478, 370, + 1330, 370, 1328, 372, 480, 370, 1330, 370, 480, 370, 480, 370, 480, 370, + 1356, 344, 478, 370, 506, 344, 1330, 370, 478, 370, 1330, 372, 1354, 346, + 1354, 346, 1328, 370, 478, 372, 478, 370, 480, 370, 504, 346, 480, 370, + 1328, 370, 1330, 370, 478, 370, 1330, 370, 1328, 370, 1330, 372, 1354, + 344, 1328, 372, 504, 346, 478, 370, 504, 346, 504, 346, 478, 370, 478, + 370, 482, 368, 480, 370, 478, 370, 480, 370, 1328, 372, 1328, 370, 1330, + 370, 1328, 370, 1328, 370, 1330, 370, 1354, 346, 1328, 372, 478, 370, 478, + 370, 478, 372, 478, 372, 478, 372, 478, 372, 478, 370, 478, 372, 1330, + 370, 1328, 370, 1328, 372, 1328, 372, 1330, 444, 1256, 370, 1330, 370, + 1330, 442}; + + irsend.reset(); + irsend.sendRaw(rawData, 531, kHitachiAcFreq); + irsend.makeDecodeResult(); + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(HITACHI_AC264, irsend.capture.decode_type); + ASSERT_EQ(kHitachiAc264Bits, irsend.capture.bits); + EXPECT_STATE_EQ(expected, irsend.capture.state, kHitachiAc264Bits); + EXPECT_EQ( + "", + IRAcUtils::resultAcToString(&irsend.capture)); + stdAc::state_t r, p; + ASSERT_FALSE(IRAcUtils::decodeToState(&irsend.capture, &r, &p)); +} + +// Decode a 'Synthetic' HitachiAc264 message. +TEST(TestDecodeHitachiAc264, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1729#issuecomment-1006938712 + const uint8_t expected[kHitachiAc264StateLength] = { + 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xCC, 0x33, 0x92, + 0x6D, 0x13, 0xEC, 0x6C, 0x93, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x16, 0xE9, 0xC1, 0x3E, 0x00, + 0xFF, 0x00, 0xFF}; + + irsend.reset(); + irsend.sendHitachiAc264(expected); + irsend.makeDecodeResult(); + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(HITACHI_AC264, irsend.capture.decode_type); + ASSERT_EQ(kHitachiAc264Bits, irsend.capture.bits); + EXPECT_STATE_EQ(expected, irsend.capture.state, kHitachiAc264Bits); + EXPECT_EQ( + "", + IRAcUtils::resultAcToString(&irsend.capture)); + stdAc::state_t r, p; + ASSERT_FALSE(IRAcUtils::decodeToState(&irsend.capture, &r, &p)); +}