mirror of
https://github.com/crankyoldgit/IRremoteESP8266.git
synced 2026-01-12 00:05:10 +08:00
Experimental basic support for Kelon 168 bit / 21 byte protocol. (#1747)
* Add `sendKelon168()` & `decodeKelon168()` * Add & extend unit test coverage. * Code style cleanup. For #1745 Ref #1744
This commit is contained in:
@@ -1050,8 +1050,12 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
|
||||
DPRINTLN("Attempting Teknopoint decode");
|
||||
if (decodeTeknopoint(results, offset)) return true;
|
||||
#endif // DECODE_TEKNOPOINT
|
||||
#if DECODE_KELON168
|
||||
DPRINTLN("Attempting Kelon 168-bit decode");
|
||||
if (decodeKelon168(results, offset)) return true;
|
||||
#endif // DECODE_KELON168
|
||||
#if DECODE_KELON
|
||||
DPRINTLN("Attempting Kelon decode");
|
||||
DPRINTLN("Attempting Kelon 48-bit decode");
|
||||
if (decodeKelon(results, offset)) return true;
|
||||
#endif // DECODE_KELON
|
||||
#if DECODE_SANYO_AC88
|
||||
|
||||
@@ -773,6 +773,11 @@ class IRrecv {
|
||||
bool decodeKelon(decode_results *results, uint16_t offset = kStartOffset,
|
||||
const uint16_t nbits = kKelonBits, const bool strict = true);
|
||||
#endif // DECODE_KELON
|
||||
#if DECODE_KELON168
|
||||
bool decodeKelon168(decode_results *results, uint16_t offset = kStartOffset,
|
||||
const uint16_t nbits = kKelon168Bits,
|
||||
const bool strict = true);
|
||||
#endif // DECODE_KELON168
|
||||
#if DECODE_BOSE
|
||||
bool decodeBose(decode_results *results, uint16_t offset = kStartOffset,
|
||||
const uint16_t nbits = kBoseBits, const bool strict = true);
|
||||
|
||||
@@ -847,6 +847,13 @@
|
||||
#define SEND_AIRTON _IR_ENABLE_DEFAULT_
|
||||
#endif // SEND_AIRTON
|
||||
|
||||
#ifndef DECODE_KELON168
|
||||
#define DECODE_KELON168 _IR_ENABLE_DEFAULT_
|
||||
#endif // DECODE_KELON168
|
||||
#ifndef SEND_KELON168
|
||||
#define SEND_KELON168 _IR_ENABLE_DEFAULT_
|
||||
#endif // SEND_KELON168
|
||||
|
||||
#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 || \
|
||||
@@ -862,6 +869,7 @@
|
||||
DECODE_VOLTAS || DECODE_MIRAGE || DECODE_HAIER_AC176 || \
|
||||
DECODE_TEKNOPOINT || DECODE_KELON || DECODE_TROTEC_3550 || \
|
||||
DECODE_SANYO_AC88 || DECODE_RHOSS || DECODE_HITACHI_AC264 || \
|
||||
DECODE_KELON168 || \
|
||||
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
|
||||
@@ -1013,8 +1021,9 @@ enum decode_type_t {
|
||||
AIRTON,
|
||||
COOLIX48, // 110
|
||||
HITACHI_AC264,
|
||||
KELON168,
|
||||
// Add new entries before this one, and update it to point to the last entry.
|
||||
kLastDecodeType = HITACHI_AC264,
|
||||
kLastDecodeType = KELON168,
|
||||
};
|
||||
|
||||
// Message lengths & required repeat values
|
||||
@@ -1134,6 +1143,8 @@ const uint16_t kInaxBits = 24;
|
||||
const uint16_t kInaxMinRepeat = kSingleRepeat;
|
||||
const uint16_t kJvcBits = 16;
|
||||
const uint16_t kKelonBits = 48;
|
||||
const uint16_t kKelon168StateLength = 21;
|
||||
const uint16_t kKelon168Bits = kKelon168StateLength * 8;
|
||||
const uint16_t kKelvinatorStateLength = 16;
|
||||
const uint16_t kKelvinatorBits = kKelvinatorStateLength * 8;
|
||||
const uint16_t kKelvinatorDefaultRepeat = kNoRepeat;
|
||||
|
||||
@@ -724,6 +724,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
|
||||
return kHitachiAc344Bits;
|
||||
case HITACHI_AC424:
|
||||
return kHitachiAc424Bits;
|
||||
case KELON168:
|
||||
return kKelon168Bits;
|
||||
case KELVINATOR:
|
||||
return kKelvinatorBits;
|
||||
case MILESTAG2:
|
||||
@@ -1227,6 +1229,11 @@ bool IRsend::send(const decode_type_t type, const uint8_t *state,
|
||||
sendHitachiAc424(state, nbytes);
|
||||
break;
|
||||
#endif // SEND_HITACHI_AC424
|
||||
#if SEND_KELON168
|
||||
case KELON168:
|
||||
sendKelon168(state, nbytes);
|
||||
break;
|
||||
#endif // SEND_KELON168
|
||||
#if SEND_KELVINATOR
|
||||
case KELVINATOR:
|
||||
sendKelvinator(state, nbytes);
|
||||
|
||||
@@ -760,6 +760,11 @@ class IRsend {
|
||||
void sendKelon(const uint64_t data, const uint16_t nbits = kKelonBits,
|
||||
const uint16_t repeat = kNoRepeat);
|
||||
#endif // SEND_KELON
|
||||
#if SEND_KELON168
|
||||
void sendKelon168(const unsigned char data[],
|
||||
const uint16_t nbytes = kKelon168StateLength,
|
||||
const uint16_t repeat = kNoRepeat);
|
||||
#endif // SEND_KELON168
|
||||
#if SEND_BOSE
|
||||
void sendBose(const uint64_t data, const uint16_t nbits = kBoseBits,
|
||||
const uint16_t repeat = kNoRepeat);
|
||||
|
||||
@@ -392,6 +392,7 @@ IRTEXT_CONST_BLOB_DECL(kAllProtocolNamesStr) {
|
||||
D_STR_AIRTON "\x0"
|
||||
D_STR_COOLIX48 "\x0"
|
||||
D_STR_HITACHI_AC264 "\x0"
|
||||
D_STR_KELON168 "\x0"
|
||||
///< New protocol strings should be added just above this line.
|
||||
"\x0" ///< This string requires double null termination.
|
||||
};
|
||||
|
||||
@@ -193,6 +193,7 @@ bool hasACState(const decode_type_t protocol) {
|
||||
case HITACHI_AC264:
|
||||
case HITACHI_AC344:
|
||||
case HITACHI_AC424:
|
||||
case KELON168:
|
||||
case KELVINATOR:
|
||||
case MIRAGE:
|
||||
case MITSUBISHI136:
|
||||
|
||||
117
src/ir_Kelon.cpp
117
src/ir_Kelon.cpp
@@ -1,7 +1,8 @@
|
||||
// Copyright 2021 Davide Depau
|
||||
// Copyright 2022 David Conran
|
||||
|
||||
/// @file
|
||||
/// @brief Support for Kelan AC protocol.
|
||||
/// @brief Support for Kelon AC protocols.
|
||||
/// Both sending and decoding should be functional for models of series
|
||||
/// KELON ON/OFF 9000-12000.
|
||||
/// All features of the standard remote are implemented.
|
||||
@@ -12,6 +13,7 @@
|
||||
/// - Fahrenheit.
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
#include "ir_Kelon.h"
|
||||
|
||||
@@ -39,8 +41,13 @@ const uint16_t kKelonZeroSpace = 600;
|
||||
const uint32_t kKelonGap = 2 * kDefaultMessageGap;
|
||||
const uint16_t kKelonFreq = 38000;
|
||||
|
||||
const uint32_t kKelon168FooterSpace = 8000;
|
||||
const uint16_t kKelon168Section1Size = 6;
|
||||
const uint16_t kKelon168Section2Size = 8;
|
||||
const uint16_t kKelon168Section3Size = 7;
|
||||
|
||||
#if SEND_KELON
|
||||
/// Send a Kelon message.
|
||||
/// Send a Kelon 48-bit message.
|
||||
/// Status: STABLE / Working.
|
||||
/// @param[in] data The data to be transmitted.
|
||||
/// @param[in] nbits Nr. of bits of data to be sent.
|
||||
@@ -52,12 +59,12 @@ void IRsend::sendKelon(const uint64_t data, const uint16_t nbits,
|
||||
kKelonBitMark, kKelonZeroSpace,
|
||||
kKelonBitMark, kKelonGap,
|
||||
data, nbits, kKelonFreq, false, // LSB First.
|
||||
repeat, 50);
|
||||
repeat, kDutyDefault);
|
||||
}
|
||||
#endif // SEND_KELON
|
||||
|
||||
#if DECODE_KELON
|
||||
/// Decode the supplied Kelon message.
|
||||
/// Decode the supplied Kelon 48-bit message.
|
||||
/// Status: STABLE / Working.
|
||||
/// @param[in,out] results Ptr to the data to decode & where to store the result
|
||||
/// @param[in] offset The starting index to use when attempting to decode the
|
||||
@@ -440,3 +447,105 @@ String IRKelonAc::toString() const {
|
||||
result += addBoolToString(true, kSwingVToggleStr);
|
||||
return result;
|
||||
}
|
||||
|
||||
#if SEND_KELON168
|
||||
/// Send a Kelon 168 bit / 21 byte message.
|
||||
/// Status: BETA / Probably works.
|
||||
/// @param[in] data The data to be transmitted.
|
||||
/// @param[in] nbytes Nr. of bytes of data to be sent.
|
||||
/// @param[in] repeat The number of times the command is to be repeated.
|
||||
void IRsend::sendKelon168(const uint8_t data[], const uint16_t nbytes,
|
||||
const uint16_t repeat) {
|
||||
assert(kKelon168StateLength == kKelon168Section1Size + kKelon168Section2Size +
|
||||
kKelon168Section3Size);
|
||||
// Enough bytes to send a proper message?
|
||||
if (nbytes < kKelon168StateLength) return;
|
||||
|
||||
for (uint16_t r = 0; r <= repeat; r++) {
|
||||
// Section #1 (48 bits)
|
||||
sendGeneric(kKelonHdrMark, kKelonHdrSpace,
|
||||
kKelonBitMark, kKelonOneSpace,
|
||||
kKelonBitMark, kKelonZeroSpace,
|
||||
kKelonBitMark, kKelon168FooterSpace,
|
||||
data, kKelon168Section1Size, kKelonFreq, false, // LSB First.
|
||||
0, // No repeats here
|
||||
kDutyDefault);
|
||||
// Section #2 (64 bits)
|
||||
sendGeneric(0, 0,
|
||||
kKelonBitMark, kKelonOneSpace,
|
||||
kKelonBitMark, kKelonZeroSpace,
|
||||
kKelonBitMark, kKelon168FooterSpace,
|
||||
data + kKelon168Section1Size, kKelon168Section2Size,
|
||||
kKelonFreq, false, // LSB First.
|
||||
0, // No repeats here
|
||||
kDutyDefault);
|
||||
// Section #3 (56 bits)
|
||||
sendGeneric(0, 0,
|
||||
kKelonBitMark, kKelonOneSpace,
|
||||
kKelonBitMark, kKelonZeroSpace,
|
||||
kKelonBitMark, kKelonGap,
|
||||
data + kKelon168Section1Size + kKelon168Section2Size,
|
||||
nbytes - (kKelon168Section1Size + kKelon168Section2Size),
|
||||
kKelonFreq, false, // LSB First.
|
||||
0, // No repeats here
|
||||
kDutyDefault);
|
||||
}
|
||||
}
|
||||
#endif // SEND_KELON168
|
||||
|
||||
#if DECODE_KELON168
|
||||
/// Decode the supplied Kelon 168 bit / 21 byte message.
|
||||
/// Status: BETA / Probably Working.
|
||||
/// @param[in,out] results Ptr to the data to decode & where to store the result
|
||||
/// @param[in] offset The starting index to use when attempting to decode the
|
||||
/// raw data. Typically/Defaults to kStartOffset.
|
||||
/// @param[in] nbits The number of data bits to expect.
|
||||
/// @param[in] strict Flag indicating if we should perform strict matching.
|
||||
/// @return True if it can decode it, false if it can't.
|
||||
bool IRrecv::decodeKelon168(decode_results *results, uint16_t offset,
|
||||
const uint16_t nbits, const bool strict) {
|
||||
if (strict && nbits != kKelon168Bits) return false;
|
||||
if (results->rawlen <= 2 * nbits + kHeader + kFooter * 2 - 1 + offset)
|
||||
return false; // Can't possibly be a valid Kelon 168 bit message.
|
||||
|
||||
uint16_t used = 0;
|
||||
|
||||
used = matchGeneric(results->rawbuf + offset, results->state,
|
||||
results->rawlen - offset, kKelon168Section1Size * 8,
|
||||
kKelonHdrMark, kKelonHdrSpace,
|
||||
kKelonBitMark, kKelonOneSpace,
|
||||
kKelonBitMark, kKelonZeroSpace,
|
||||
kKelonBitMark, kKelon168FooterSpace,
|
||||
false, _tolerance, 0, false);
|
||||
if (!used) return false; // Failed to match.
|
||||
offset += used;
|
||||
|
||||
used = matchGeneric(results->rawbuf + offset,
|
||||
results->state + kKelon168Section1Size,
|
||||
results->rawlen - offset, kKelon168Section2Size * 8,
|
||||
0, 0,
|
||||
kKelonBitMark, kKelonOneSpace,
|
||||
kKelonBitMark, kKelonZeroSpace,
|
||||
kKelonBitMark, kKelon168FooterSpace,
|
||||
false, _tolerance, 0, false);
|
||||
if (!used) return false; // Failed to match.
|
||||
offset += used;
|
||||
|
||||
used = matchGeneric(results->rawbuf + offset,
|
||||
results->state + (kKelon168Section1Size +
|
||||
kKelon168Section2Size),
|
||||
results->rawlen - offset,
|
||||
nbits - (kKelon168Section1Size +
|
||||
kKelon168Section2Size) * 8,
|
||||
0, 0,
|
||||
kKelonBitMark, kKelonOneSpace,
|
||||
kKelonBitMark, kKelonZeroSpace,
|
||||
kKelonBitMark, kKelonGap,
|
||||
true, _tolerance, 0, false);
|
||||
if (!used) return false; // Failed to match.
|
||||
|
||||
results->decode_type = decode_type_t::KELON168;
|
||||
results->bits = nbits;
|
||||
return true;
|
||||
}
|
||||
#endif // DECODE_KELON168
|
||||
|
||||
@@ -2,16 +2,23 @@
|
||||
|
||||
/// @file
|
||||
/// @brief Support for Kelan AC protocol.
|
||||
/// Both sending and decoding should be functional for models of series KELON
|
||||
/// ON/OFF 9000-12000.
|
||||
/// @note Both sending and decoding should be functional for models of series
|
||||
/// KELON ON/OFF 9000-12000.
|
||||
/// All features of the standard remote are implemented.
|
||||
///
|
||||
/// @note Unsupported:
|
||||
/// - Explicit on/off due to AC unit limitations
|
||||
/// - Explicit swing position due to AC unit limitations
|
||||
/// - Fahrenheit.
|
||||
///
|
||||
/// For KELON168:
|
||||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1745
|
||||
|
||||
// Supports:
|
||||
// Brand: Kelon, Model: ON/OFF 9000-12000
|
||||
// Brand: Kelon, Model: ON/OFF 9000-12000 (KELON)
|
||||
// Brand: Kelon, Model: DG11R2-01 remote (KELON168)
|
||||
// Brand: Kelon, Model: AST-09UW4RVETG00A A/C (KELON168)
|
||||
// Brand: Hisense, Model: AST-09UW4RVETG00A A/C (KELON168)
|
||||
|
||||
#ifndef IR_KELON_H_
|
||||
#define IR_KELON_H_
|
||||
@@ -71,84 +78,50 @@ class IRKelonAc {
|
||||
public:
|
||||
explicit IRKelonAc(uint16_t pin, bool inverted = false,
|
||||
bool use_modulation = true);
|
||||
|
||||
void stateReset(void);
|
||||
|
||||
#if SEND_KELON
|
||||
|
||||
void send(const uint16_t repeat = kNoRepeat);
|
||||
|
||||
/// Run the calibration to calculate uSec timing offsets for this platform.
|
||||
/// @return The uSec timing offset needed per modulation of the IR Led.
|
||||
/// @note This will produce a 65ms IR signal pulse at 38kHz.
|
||||
/// Only ever needs to be run once per object instantiation, if at all.
|
||||
int8_t calibrate(void) { return _irsend.calibrate(); }
|
||||
|
||||
/// Since the AC does not support actually setting the power state to a known
|
||||
/// value, this utility allow ensuring the AC is on or off by exploiting
|
||||
/// the fact that the AC, according to the user manual, will always turn on
|
||||
/// when setting it to "smart" or "super" mode.
|
||||
void ensurePower(const bool on);
|
||||
|
||||
#endif
|
||||
#endif // SEND_KELON
|
||||
|
||||
|
||||
void begin(void);
|
||||
|
||||
void setTogglePower(const bool toggle);
|
||||
|
||||
bool getTogglePower(void) const;
|
||||
|
||||
void setTemp(const uint8_t degrees);
|
||||
|
||||
uint8_t getTemp(void) const;
|
||||
|
||||
void setFan(const uint8_t speed);
|
||||
|
||||
uint8_t getFan(void) const;
|
||||
|
||||
void setDryGrade(const int8_t grade);
|
||||
|
||||
int8_t getDryGrade(void) const;
|
||||
|
||||
void setMode(const uint8_t mode);
|
||||
|
||||
uint8_t getMode(void) const;
|
||||
|
||||
void setToggleSwingVertical(const bool toggle);
|
||||
|
||||
bool getToggleSwingVertical(void) const;
|
||||
|
||||
void setSleep(const bool on);
|
||||
|
||||
bool getSleep(void) const;
|
||||
|
||||
void setSupercool(const bool on);
|
||||
|
||||
bool getSupercool(void) const;
|
||||
|
||||
void setTimer(const uint16_t mins);
|
||||
|
||||
uint16_t getTimer(void) const;
|
||||
|
||||
void setTimerEnabled(const bool on);
|
||||
|
||||
bool getTimerEnabled(void) const;
|
||||
|
||||
uint64_t getRaw(void) const;
|
||||
|
||||
void setRaw(const uint64_t new_code);
|
||||
|
||||
static uint8_t convertMode(const stdAc::opmode_t mode);
|
||||
|
||||
static uint8_t convertFan(const stdAc::fanspeed_t fan);
|
||||
|
||||
static stdAc::opmode_t toCommonMode(const uint8_t mode);
|
||||
|
||||
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
|
||||
|
||||
stdAc::state_t toCommon(const stdAc::state_t *prev = nullptr) const;
|
||||
|
||||
String toString(void) const;
|
||||
|
||||
private:
|
||||
@@ -166,5 +139,4 @@ class IRKelonAc {
|
||||
uint8_t _previousTemp = kKelonMinTemp;
|
||||
uint8_t _previousFan = kKelonFanAuto;
|
||||
};
|
||||
|
||||
#endif // IR_KELON_H_
|
||||
|
||||
@@ -826,6 +826,9 @@ D_STR_INDIRECT " " D_STR_MODE
|
||||
#ifndef D_STR_KELON
|
||||
#define D_STR_KELON "KELON"
|
||||
#endif // D_STR_KELON
|
||||
#ifndef D_STR_KELON168
|
||||
#define D_STR_KELON168 D_STR_KELON "168"
|
||||
#endif // D_STR_KELON168
|
||||
#ifndef D_STR_KELVINATOR
|
||||
#define D_STR_KELVINATOR "KELVINATOR"
|
||||
#endif // D_STR_KELVINATOR
|
||||
|
||||
@@ -425,12 +425,21 @@ TEST(TestIRKelonClass, toCommonToggles) {
|
||||
}
|
||||
|
||||
TEST(TestUtils, Housekeeping) {
|
||||
// KELON
|
||||
ASSERT_EQ("KELON", typeToString(decode_type_t::KELON));
|
||||
ASSERT_EQ(decode_type_t::KELON, strToDecodeType("KELON"));
|
||||
ASSERT_FALSE(hasACState(decode_type_t::KELON));
|
||||
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::KELON));
|
||||
ASSERT_EQ(kKelonBits, IRsend::defaultBits(decode_type_t::KELON));
|
||||
ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::KELON));
|
||||
|
||||
// KELON168
|
||||
ASSERT_EQ("KELON168", typeToString(decode_type_t::KELON168));
|
||||
ASSERT_EQ(decode_type_t::KELON168, strToDecodeType("KELON168"));
|
||||
ASSERT_TRUE(hasACState(decode_type_t::KELON168));
|
||||
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::KELON168));
|
||||
ASSERT_EQ(kKelon168Bits, IRsend::defaultBits(decode_type_t::KELON168));
|
||||
ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::KELON168));
|
||||
}
|
||||
|
||||
TEST(TestDecodeKelon, Discussion1744) {
|
||||
@@ -497,3 +506,96 @@ TEST(TestDecodeKelon, Discussion1744) {
|
||||
EXPECT_NE(KELON, irsend.capture.decode_type); // Not a KELON message
|
||||
EXPECT_NE(kKelonBits, irsend.capture.bits); // Not a 48 bit message.
|
||||
}
|
||||
|
||||
TEST(TestDecodeKelon168, RealExample) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/discussions/1744#discussioncomment-2061968
|
||||
const uint16_t rawData[343] = {
|
||||
8922, 4494, // Header
|
||||
548, 1714, 524, 1718, 524, 572, 524, 550, // Byte 0
|
||||
550, 556, 550, 560, 548, 586, 524, 1724,
|
||||
526, 564, 524, 1692, 550, 1696, 550, 552, // Byte 1
|
||||
550, 554, 550, 560, 548, 586, 524, 550,
|
||||
548, 1688, 550, 1694, 548, 548, 550, 552, // Byte 2
|
||||
548, 556, 548, 582, 524, 586, 524, 576,
|
||||
524, 540, 548, 568, 526, 572, 526, 548, // Byte 3
|
||||
550, 1702, 550, 1706, 550, 1734, 526, 574,
|
||||
526, 564, 526, 544, 550, 548, 548, 550, // Byte 4
|
||||
550, 554, 550, 582, 526, 586, 524, 550,
|
||||
548, 540, 550, 544, 550, 570, 526, 550, // Byte 5
|
||||
550, 558, 546, 582, 524, 586, 524, 562,
|
||||
524, 7978, // Section Footer
|
||||
548, 1690, 548, 568, 524, 1696, 548, 1700, // Byte 6
|
||||
548, 554, 550, 560, 548, 560, 550, 1722,
|
||||
526, 1686, 550, 1692, 548, 1696, 550, 576, // Byte 7
|
||||
524, 1704, 548, 558, 550, 562, 548, 550,
|
||||
550, 564, 524, 570, 524, 548, 548, 576, // Byte 8
|
||||
524, 578, 526, 558, 550, 586, 524, 574,
|
||||
524, 566, 524, 568, 526, 548, 548, 576, // Byte 9
|
||||
526, 556, 548, 558, 550, 560, 550, 550,
|
||||
550, 564, 526, 544, 548, 548, 548, 552, // Byte 10
|
||||
548, 556, 548, 582, 526, 564, 548, 550,
|
||||
550, 540, 548, 568, 526, 546, 550, 550, // Byte 11
|
||||
550, 580, 524, 558, 550, 560, 550, 1698,
|
||||
550, 542, 548, 542, 550, 546, 550, 1722, // Byte 12
|
||||
524, 1706, 548, 582, 526, 586, 524, 574,
|
||||
526, 1690, 548, 544, 550, 546, 550, 552, // Byte 13
|
||||
548, 1726, 526, 1730, 524, 1734, 526, 562,
|
||||
524, 7976, // Section footer
|
||||
550, 566, 524, 544, 550, 570, 526, 550, // Byte 14
|
||||
548, 554, 550, 1706, 550, 562, 548, 574,
|
||||
526, 542, 548, 544, 550, 572, 526, 548, // Byte 15
|
||||
552, 554, 550, 582, 526, 584, 526, 574,
|
||||
524, 542, 548, 544, 548, 572, 524, 552, // Byte 16
|
||||
548, 578, 524, 560, 548, 562, 548, 550,
|
||||
550, 540, 550, 546, 548, 572, 524, 576, // Byte 17
|
||||
526, 556, 548, 560, 546, 564, 548, 574,
|
||||
526, 540, 550, 546, 546, 546, 550, 1698, // Byte 18
|
||||
550, 1728, 524, 1706, 548, 564, 548, 574,
|
||||
524, 544, 548, 568, 526, 548, 548, 574, // Byte 19
|
||||
524, 554, 550, 558, 550, 562, 548, 550,
|
||||
550, 566, 524, 544, 548, 546, 552, 1698, // Byte 20
|
||||
548, 1702, 550, 560, 546, 586, 524, 538,
|
||||
546 // Footer
|
||||
}; // KELON 178D000070030683
|
||||
|
||||
const uint8_t expected[kKelon168StateLength] = {
|
||||
0x83, 0x06, 0x03, 0x70, 0x00, 0x00, 0x8D,
|
||||
0x17, 0x00, 0x00, 0x00, 0x80, 0x18, 0x71,
|
||||
0x20, 0x00, 0x00, 0x00, 0x38, 0x00, 0x18};
|
||||
|
||||
irsend.begin();
|
||||
irsend.reset();
|
||||
irsend.sendRaw(rawData, 343, 38000);
|
||||
irsend.makeDecodeResult();
|
||||
EXPECT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(decode_type_t::KELON168, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kKelon168Bits, irsend.capture.bits);
|
||||
EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
|
||||
EXPECT_EQ("", IRAcUtils::resultAcToString(&irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_FALSE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
|
||||
}
|
||||
|
||||
TEST(TestDecodeKelon168, SyntheticExample) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
|
||||
const uint8_t expected[kKelon168StateLength] = {
|
||||
0x83, 0x06, 0x03, 0x70, 0x00, 0x00, 0x8D,
|
||||
0x17, 0x00, 0x00, 0x00, 0x80, 0x18, 0x71,
|
||||
0x20, 0x00, 0x00, 0x00, 0x38, 0x00, 0x18};
|
||||
|
||||
irsend.begin();
|
||||
irsend.reset();
|
||||
irsend.sendKelon168(expected);
|
||||
irsend.makeDecodeResult();
|
||||
EXPECT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(decode_type_t::KELON168, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kKelon168Bits, irsend.capture.bits);
|
||||
EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
|
||||
EXPECT_EQ("", IRAcUtils::resultAcToString(&irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_FALSE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user