def test_unusual_gaps(self): """Tests for unusual Space Gaps in parse_and_report() function.""" # Tests for unusual Gaps. (Issue #482) output = StringIO.StringIO() input_str = """ uint16_t rawbuf[272] = {3485, 3512, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 3485, 3512, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 3485, 3512, 864, 13996, 3485, 3512, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 864, 3485, 3512, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 864, 3485, 3512, 864, 13996};""" analyse.parse_and_report(input_str, 200, True, output) self.assertEqual( output.getvalue(), 'Found 272 timing entries.\n' 'Potential Mark Candidates:\n' '[3485, 864]\n' 'Potential Space Candidates:\n' '[13996, 3512, 2620, 864]\n' '\n' 'Guessing encoding type:\n' 'Looks like it uses space encoding. Yay!\n' '\n' 'Guessing key value:\n' 'kHdrMark = 3485\n' 'kHdrSpace = 3512\n' 'kBitMark = 864\n' 'kOneSpace = 2620\n' 'kZeroSpace = 864\n' 'kSpaceGap = 13996\n' '\n' 'Decoding protocol based on analysis so far:\n' '\n' 'kHdrMark+kHdrSpace+01011111010111110100000001000000\n' ' Bits: 32\n' ' Hex: 0x5F5F4040 (MSB first)\n' ' 0x0202FAFA (LSB first)\n' ' Dec: 1600077888 (MSB first)\n' ' 33749754 (LSB first)\n' ' Bin: 0b01011111010111110100000001000000 (MSB first)\n' ' 0b00000010000000101111101011111010 (LSB first)\n' 'kHdrMark+kHdrSpace+01011111010111110100000001000000\n' ' Bits: 32\n' ' Hex: 0x5F5F4040 (MSB first)\n' ' 0x0202FAFA (LSB first)\n' ' Dec: 1600077888 (MSB first)\n' ' 33749754 (LSB first)\n' ' Bin: 0b01011111010111110100000001000000 (MSB first)\n' ' 0b00000010000000101111101011111010 (LSB first)\n' 'kHdrMark+kHdrSpace+GAP(13996)' 'kHdrMark+kHdrSpace+00101111001011110110110001101100\n' ' Bits: 32\n' ' Hex: 0x2F2F6C6C (MSB first)\n' ' 0x3636F4F4 (LSB first)\n' ' Dec: 791637100 (MSB first)\n' ' 909571316 (LSB first)\n' ' Bin: 0b00101111001011110110110001101100 (MSB first)\n' ' 0b00110110001101101111010011110100 (LSB first)\n' 'kHdrMark+kHdrSpace+00101111001011110110110001101100\n' ' Bits: 32\n' ' Hex: 0x2F2F6C6C (MSB first)\n' ' 0x3636F4F4 (LSB first)\n' ' Dec: 791637100 (MSB first)\n' ' 909571316 (LSB first)\n' ' Bin: 0b00101111001011110110110001101100 (MSB first)\n' ' 0b00110110001101101111010011110100 (LSB first)\n' 'kHdrMark+kHdrSpace+GAP(13996)\n' 'Total Nr. of suspected bits: 128\n' '\n' 'Generating a VERY rough code outline:\n' '\n' "// WARNING: This probably isn't directly usable. It's a guide only.\n" 'const uint16_t kHdrMark = 3485;\n' 'const uint16_t kBitMark = 864;\n' 'const uint16_t kHdrSpace = 3512;\n' 'const uint16_t kOneSpace = 2620;\n' 'const uint16_t kZeroSpace = 864;\n' 'const uint16_t kSpaceGap = 13996;\n' 'const uint16_t kXyzBits = 128;\n' 'const uint16_t kXyzStateLength = 16;\n' "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' '// Function should be safe up to 64 bits.\n' 'void IRsend::sendXyz(const uint64_t data, const uint16_t nbits,' ' const uint16_t repeat) {\n' ' enableIROut(38); // A guess. Most common frequency.\n' ' for (uint16_t r = 0; r <= repeat; r++) {\n' ' // Header\n' ' mark(kHdrMark);\n' ' space(kHdrSpace);\n' ' // Data\n' ' // e.g. data = 0x5F5F4040, nbits = 32\n' ' sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, data, nbits,' ' true);\n' ' // Header\n' ' mark(kHdrMark);\n' ' space(kHdrSpace);\n' ' // Data\n' ' // e.g. data = 0x5F5F4040, nbits = 32\n' ' sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, data, nbits,' ' true);\n' ' // Header\n' ' mark(kHdrMark);\n' ' space(kHdrSpace);\n' ' // Gap\n' ' mark(kBitMark);\n' ' space(kSpaceGap);\n' ' // Header\n' ' mark(kHdrMark);\n' ' space(kHdrSpace);\n' ' // Data\n' ' // e.g. data = 0x2F2F6C6C, nbits = 32\n' ' sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, data, nbits,' ' true);\n' ' // Header\n' ' mark(kHdrMark);\n' ' space(kHdrSpace);\n' ' // Data\n' ' // e.g. data = 0x2F2F6C6C, nbits = 32\n' ' sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, data, nbits,' ' true);\n' ' // Header\n' ' mark(kHdrMark);\n' ' space(kHdrSpace);\n' ' // Gap\n' ' mark(kBitMark);\n' ' space(kSpaceGap);\n' ' space(100000); // A 100% made up guess of the gap between' ' messages.\n' ' }\n' '}\n' '\n' '\n' '// Alternative >64 bit Function\n' 'void IRsend::sendXyz(uint8_t data[], uint16_t nbytes, uint16_t repeat)' ' {\n' ' // nbytes should typically be kXyzStateLength\n' ' // data should typically be:\n' ' // uint8_t data[kXyzStateLength] = {0x5F, 0x5F, 0x40, 0x40, 0x5F,' ' 0x5F, 0x40, 0x40, 0x2F, 0x2F, 0x6C, 0x6C, 0x2F, 0x2F, 0x6C, 0x6C};\n' ' // data[] is assumed to be in MSB order for this code.\n' ' for (uint16_t r = 0; r <= repeat; r++) {\n' ' sendGeneric(kHdrMark, kHdrSpace,\n' ' kBitMark, kOneSpace,\n' ' kBitMark, kZeroSpace,\n' ' kBitMark,\n' ' 100000, // 100% made-up guess at the message gap.\n' ' data, nbytes,\n' ' 38000, // Complete guess of the modulation' ' frequency.\n' ' true, 0, 50);\n' ' }\n' '}\n')
def test_unusual_gaps(self): """Tests for unusual Space Gaps in parse_and_report() function.""" # Tests for unusual Gaps. (Issue #482) output = StringIO.StringIO() input_str = """ uint16_t rawbuf[272] = {3485, 3512, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 3485, 3512, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 3485, 3512, 864, 13996, 3485, 3512, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 864, 3485, 3512, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 864, 3485, 3512, 864, 13996};""" analyse.parse_and_report(input_str, 200, True, output) self.assertEqual( output.getvalue(), 'Found 272 timing entries.\n' 'Potential Mark Candidates:\n' '[3485, 864]\n' 'Potential Space Candidates:\n' '[13996, 3512, 2620, 864]\n' '\n' 'Guessing encoding type:\n' 'Looks like it uses space encoding. Yay!\n' '\n' 'Guessing key value:\n' 'HDR_MARK = 3485\n' 'HDR_SPACE = 3512\n' 'BIT_MARK = 864\n' 'ONE_SPACE = 2620\n' 'ZERO_SPACE = 864\n' 'SPACE_GAP = 13996\n' '\n' 'Decoding protocol based on analysis so far:\n' '\n' 'HDR_MARK+HDR_SPACE+01011111010111110100000001000000\n' ' Bits: 32\n' ' Hex: 0x5F5F4040 (MSB first)\n' ' 0x0202FAFA (LSB first)\n' ' Dec: 1600077888 (MSB first)\n' ' 33749754 (LSB first)\n' ' Bin: 0b01011111010111110100000001000000 (MSB first)\n' ' 0b00000010000000101111101011111010 (LSB first)\n' 'HDR_MARK+HDR_SPACE+01011111010111110100000001000000\n' ' Bits: 32\n' ' Hex: 0x5F5F4040 (MSB first)\n' ' 0x0202FAFA (LSB first)\n' ' Dec: 1600077888 (MSB first)\n' ' 33749754 (LSB first)\n' ' Bin: 0b01011111010111110100000001000000 (MSB first)\n' ' 0b00000010000000101111101011111010 (LSB first)\n' 'HDR_MARK+HDR_SPACE+GAP(13996)' 'HDR_MARK+HDR_SPACE+00101111001011110110110001101100\n' ' Bits: 32\n' ' Hex: 0x2F2F6C6C (MSB first)\n' ' 0x3636F4F4 (LSB first)\n' ' Dec: 791637100 (MSB first)\n' ' 909571316 (LSB first)\n' ' Bin: 0b00101111001011110110110001101100 (MSB first)\n' ' 0b00110110001101101111010011110100 (LSB first)\n' 'HDR_MARK+HDR_SPACE+00101111001011110110110001101100\n' ' Bits: 32\n' ' Hex: 0x2F2F6C6C (MSB first)\n' ' 0x3636F4F4 (LSB first)\n' ' Dec: 791637100 (MSB first)\n' ' 909571316 (LSB first)\n' ' Bin: 0b00101111001011110110110001101100 (MSB first)\n' ' 0b00110110001101101111010011110100 (LSB first)\n' 'HDR_MARK+HDR_SPACE+GAP(13996)\n' 'Total Nr. of suspected bits: 128\n' '\n' 'Generating a VERY rough code outline:\n' '\n' "// WARNING: This probably isn't directly usable. It's a guide only.\n" '#define HDR_MARK 3485U\n' '#define BIT_MARK 864U\n' '#define HDR_SPACE 3512U\n' '#define ONE_SPACE 2620U\n' '#define ZERO_SPACE 864U\n' '#define SPACE_GAP = 13996U\n' '#define XYZ_BITS 128U\n' '#define XYZ_STATE_LENGTH 16U\n' "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' '// Function should be safe up to 64 bits.\n' 'void IRsend::sendXYZ(const uint64_t data, const uint16_t nbits,' ' const uint16_t repeat) {\n' ' enableIROut(38); // A guess. Most common frequency.\n' ' for (uint16_t r = 0; r <= repeat; r++) {\n' ' // Header\n' ' mark(HDR_MARK);\n' ' space(HDR_SPACE);\n' ' // Data\n' ' // e.g. data = 0x5F5F4040, nbits = 32\n' ' sendData(BIT_MARK, ONE_SPACE, BIT_MARK, ZERO_SPACE, data, nbits,' ' true);\n' ' // Header\n' ' mark(HDR_MARK);\n' ' space(HDR_SPACE);\n' ' // Data\n' ' // e.g. data = 0x5F5F4040, nbits = 32\n' ' sendData(BIT_MARK, ONE_SPACE, BIT_MARK, ZERO_SPACE, data, nbits,' ' true);\n' ' // Header\n' ' mark(HDR_MARK);\n' ' space(HDR_SPACE);\n' ' // Gap\n' ' mark(BIT_MARK);\n' ' space(SPACE_GAP);\n' ' // Header\n' ' mark(HDR_MARK);\n' ' space(HDR_SPACE);\n' ' // Data\n' ' // e.g. data = 0x2F2F6C6C, nbits = 32\n' ' sendData(BIT_MARK, ONE_SPACE, BIT_MARK, ZERO_SPACE, data, nbits,' ' true);\n' ' // Header\n' ' mark(HDR_MARK);\n' ' space(HDR_SPACE);\n' ' // Data\n' ' // e.g. data = 0x2F2F6C6C, nbits = 32\n' ' sendData(BIT_MARK, ONE_SPACE, BIT_MARK, ZERO_SPACE, data, nbits,' ' true);\n' ' // Header\n' ' mark(HDR_MARK);\n' ' space(HDR_SPACE);\n' ' // Gap\n' ' mark(BIT_MARK);\n' ' space(SPACE_GAP);\n' ' space(100000); // A 100% made up guess of the gap between' ' messages.\n' ' }\n' '}\n' '\n' '\n' '// Alternative >64 bit Function\n' 'void IRsend::sendXYZ(uint8_t data[], uint16_t nbytes, uint16_t repeat)' ' {\n' ' // nbytes should typically be XYZ_STATE_LENGTH\n' ' // data should typically be:\n' ' // uint8_t data[XYZ_STATE_LENGTH] = {0x5F, 0x5F, 0x40, 0x40, 0x5F,' ' 0x5F, 0x40, 0x40, 0x2F, 0x2F, 0x6C, 0x6C, 0x2F, 0x2F, 0x6C, 0x6C};\n' ' // data[] is assumed to be in MSB order for this code.\n' ' for (uint16_t r = 0; r <= repeat; r++) {\n' ' sendGeneric(HDR_MARK, HDR_SPACE,\n' ' BIT_MARK, ONE_SPACE,\n' ' BIT_MARK, ZERO_SPACE,\n' ' BIT_MARK\n' ' 100000, // 100% made-up guess at the message gap.\n' ' data, nbytes,\n' ' 38000, // Complete guess of the modulation' ' frequency.\n' ' true, 0, 50);\n' '}\n')
def test_parse_and_report(self): """Tests for the parse_and_report() function.""" # Without code generation. output = StringIO.StringIO() input_str = """ uint16_t rawbuf[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};""" analyse.parse_and_report(input_str, 200, False, output) self.assertEqual( output.getvalue(), 'Found 139 timing entries.\n' 'Potential Mark Candidates:\n' '[9008, 676]\n' 'Potential Space Candidates:\n' '[19990, 4496, 1680, 584]\n' '\n' 'Guessing encoding type:\n' 'Looks like it uses space encoding. Yay!\n' '\n' 'Guessing key value:\n' 'kHdrMark = 9008\n' 'kHdrSpace = 4496\n' 'kBitMark = 650\n' 'kOneSpace = 1657\n' 'kZeroSpace = 554\n' 'kSpaceGap = 19990\n' '\n' 'Decoding protocol based on analysis so far:\n' '\n' 'kHdrMark+kHdrSpace+10011000010100000000011000001010010GAP(19990)\n' ' Bits: 35\n' ' Hex: 0x4C2803052 (MSB first)\n' ' 0x250600A19 (LSB first)\n' ' Dec: 20443050066 (MSB first)\n' ' 9938405913 (LSB first)\n' ' Bin: 0b10011000010100000000011000001010010 (MSB first)\n' ' 0b01001010000011000000000101000011001 (LSB first)\n' 'kBitMark(UNEXPECTED)01000000110001000000000000001111\n' ' Bits: 32\n' ' Hex: 0x40C4000F (MSB first)\n' ' 0xF0002302 (LSB first)\n' ' Dec: 1086586895 (MSB first)\n' ' 4026540802 (LSB first)\n' ' Bin: 0b01000000110001000000000000001111 (MSB first)\n' ' 0b11110000000000000010001100000010 (LSB first)\n' '\n' 'Total Nr. of suspected bits: 67\n') # With code generation. output = StringIO.StringIO() input_str = """ uint16_t rawbuf[37] = {7930, 3952, 494, 1482, 520, 1482, 494, 1508, 494, 520, 494, 1482, 494, 520, 494, 1482, 494, 1482, 494, 3978, 494, 520, 494, 520, 494, 520, 494, 520, 520, 520, 494, 520, 494, 520, 494, 1482, 494};""" analyse.parse_and_report(input_str, 200, True, output) self.assertEqual( output.getvalue(), 'Found 37 timing entries.\n' 'Potential Mark Candidates:\n' '[7930, 520]\n' 'Potential Space Candidates:\n' '[3978, 1508, 520]\n' '\n' 'Guessing encoding type:\n' 'Looks like it uses space encoding. Yay!\n' '\n' 'Guessing key value:\n' 'kHdrMark = 7930\n' 'kHdrSpace = 3965\n' 'kBitMark = 496\n' 'kOneSpace = 1485\n' 'kZeroSpace = 520\n' '\n' 'Decoding protocol based on analysis so far:\n' '\n' 'kHdrMark+kHdrSpace+11101011\n' ' Bits: 8\n' ' Hex: 0xEB (MSB first)\n' ' 0xD7 (LSB first)\n' ' Dec: 235 (MSB first)\n' ' 215 (LSB first)\n' ' Bin: 0b11101011 (MSB first)\n' ' 0b11010111 (LSB first)\n' 'UNEXPECTED->kHdrSpace+00000001\n' ' Bits: 8\n' ' Hex: 0x01 (MSB first)\n' ' 0x80 (LSB first)\n' ' Dec: 1 (MSB first)\n' ' 128 (LSB first)\n' ' Bin: 0b00000001 (MSB first)\n' ' 0b10000000 (LSB first)\n' '\n' 'Total Nr. of suspected bits: 16\n' '\n' 'Generating a VERY rough code outline:\n' '\n' "// WARNING: This probably isn't directly usable. It's a guide only.\n" 'const uint16_t kHdrMark = 7930;\n' 'const uint16_t kBitMark = 496;\n' 'const uint16_t kHdrSpace = 3965;\n' 'const uint16_t kOneSpace = 1485;\n' 'const uint16_t kZeroSpace = 520;\n' 'const uint16_t kXyzBits = 16;\n' '// Function should be safe up to 64 bits.\n' 'void IRsend::sendXyz(const uint64_t data, const uint16_t nbits,' ' const uint16_t repeat) {\n' ' enableIROut(38); // A guess. Most common frequency.\n' ' for (uint16_t r = 0; r <= repeat; r++) {\n' ' // Header\n' ' mark(kHdrMark);\n' ' space(kHdrSpace);\n' ' // Data\n' ' // e.g. data = 0xEB, nbits = 8\n' ' sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, data, nbits,' ' true);\n' ' // Footer\n' ' mark(kBitMark);\n' ' space(kHdrSpace);\n' ' // Data\n' ' // e.g. data = 0x1, nbits = 8\n' ' sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, data, nbits,' ' true);\n' ' // Footer\n' ' mark(kBitMark);\n' ' space(100000); // A 100% made up guess of the gap between' ' messages.\n' ' }\n' '}\n')
def test_unusual_gaps(self): """Tests for unusual Space Gaps in parse_and_report() function.""" # Tests for unusual Gaps. (Issue #482) output = StringIO() input_str = """ uint16_t rawbuf[272] = {3485, 3512, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 3485, 3512, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 3485, 3512, 864, 13996, 3485, 3512, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 864, 3485, 3512, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 864, 3485, 3512, 864, 13996};""" analyse.parse_and_report(input_str, 200, True, "FOO", output) self.assertEqual( output.getvalue(), 'Found 272 timing entries.\n' 'Potential Mark Candidates:\n' '[3485, 864]\n' 'Potential Space Candidates:\n' '[13996, 3512, 2620, 864]\n' '\n' 'Guessing encoding type:\n' 'Looks like it uses space encoding. Yay!\n' '\n' 'Guessing key value:\n' 'kFOOHdrMark = 3485\n' 'kFOOHdrSpace = 3512\n' 'kFOOBitMark = 864\n' 'kFOOOneSpace = 2620\n' 'kFOOZeroSpace = 864\n' 'kFOOSpaceGap = 13996\n' '\n' 'Decoding protocol based on analysis so far:\n' '\n' 'kFOOHdrMark+kFOOHdrSpace+01011111010111110100000001000000\n' ' Bits: 32\n' ' Hex: 0x5F5F4040 (MSB first)\n' ' 0x0202FAFA (LSB first)\n' ' Dec: 1600077888 (MSB first)\n' ' 33749754 (LSB first)\n' ' Bin: 0b01011111010111110100000001000000 (MSB first)\n' ' 0b00000010000000101111101011111010 (LSB first)\n' 'kFOOHdrMark+kFOOHdrSpace+01011111010111110100000001000000\n' ' Bits: 32\n' ' Hex: 0x5F5F4040 (MSB first)\n' ' 0x0202FAFA (LSB first)\n' ' Dec: 1600077888 (MSB first)\n' ' 33749754 (LSB first)\n' ' Bin: 0b01011111010111110100000001000000 (MSB first)\n' ' 0b00000010000000101111101011111010 (LSB first)\n' 'kFOOHdrMark+kFOOHdrSpace+GAP(13996)kFOOHdrMark+kFOOHdrSpace+0010111100' '1011110110110001101100\n' ' Bits: 32\n' ' Hex: 0x2F2F6C6C (MSB first)\n' ' 0x3636F4F4 (LSB first)\n' ' Dec: 791637100 (MSB first)\n' ' 909571316 (LSB first)\n' ' Bin: 0b00101111001011110110110001101100 (MSB first)\n' ' 0b00110110001101101111010011110100 (LSB first)\n' 'kFOOHdrMark+kFOOHdrSpace+00101111001011110110110001101100\n' ' Bits: 32\n' ' Hex: 0x2F2F6C6C (MSB first)\n' ' 0x3636F4F4 (LSB first)\n' ' Dec: 791637100 (MSB first)\n' ' 909571316 (LSB first)\n' ' Bin: 0b00101111001011110110110001101100 (MSB first)\n' ' 0b00110110001101101111010011110100 (LSB first)\n' 'kFOOHdrMark+kFOOHdrSpace+GAP(13996)\n' 'Total Nr. of suspected bits: 128\n' '\n' 'Generating a VERY rough code outline:\n' '\n' '// Copyright 2019 David Conran (crankyoldgit)\n' '// Support for FOO protocol\n' '\n' '#include "IRrecv.h"\n' '#include "IRsend.h"\n' '#include "IRutils.h"\n' '\n' "// WARNING: This probably isn't directly usable. It's a guide only.\n" '\n' '// See https://github.com/crankyoldgit/IRremoteESP8266/wiki/' 'Adding-support-for-a-new-IR-protocol\n' '// for details of how to include this in the library.\n' 'const uint16_t kFOOHdrMark = 3485;\n' 'const uint16_t kFOOBitMark = 864;\n' 'const uint16_t kFOOHdrSpace = 3512;\n' 'const uint16_t kFOOOneSpace = 2620;\n' 'const uint16_t kFOOZeroSpace = 864;\n' 'const uint16_t kFOOSpaceGap = 13996;\n' 'const uint16_t kFOOFreq = 38000; // Hz. (Guessing the most common' ' frequency.)\n' 'const uint16_t kFOOBits = 128; // Move to IRremoteESP8266.h\n' 'const uint16_t kFOOStateLength = 16; // Move to IRremoteESP8266.h\n' 'const uint16_t kFOOOverhead = 16;\n' "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' '#if SEND_FOO\n' '// Function should be safe up to 64 bits.\n' 'void IRsend::sendFOO(const uint64_t data, const uint16_t nbits,' ' const uint16_t repeat) {\n' ' enableIROut(kFOOFreq);\n' ' for (uint16_t r = 0; r <= repeat; r++) {\n' ' uint64_t send_data = data;\n' ' // Header\n' ' mark(kFOOHdrMark);\n' ' space(kFOOHdrSpace);\n' ' // Data Section #1\n' ' // e.g. data = 0x5F5F4040, nbits = 32\n' ' sendData(kFOOBitMark, kFOOOneSpace, kFOOBitMark, kFOOZeroSpace,' ' send_data, 32, true);\n' ' send_data >>= 32;\n' ' // Header\n' ' mark(kFOOHdrMark);\n' ' space(kFOOHdrSpace);\n' ' // Data Section #2\n' ' // e.g. data = 0x5F5F4040, nbits = 32\n' ' sendData(kFOOBitMark, kFOOOneSpace, kFOOBitMark, kFOOZeroSpace,' ' send_data, 32, true);\n' ' send_data >>= 32;\n' ' // Header\n' ' mark(kFOOHdrMark);\n' ' space(kFOOHdrSpace);\n' ' // Gap\n' ' mark(kFOOBitMark);\n' ' space(kFOOSpaceGap);\n' ' // Header\n' ' mark(kFOOHdrMark);\n' ' space(kFOOHdrSpace);\n' ' // Data Section #3\n' ' // e.g. data = 0x2F2F6C6C, nbits = 32\n' ' sendData(kFOOBitMark, kFOOOneSpace, kFOOBitMark, kFOOZeroSpace,' ' send_data, 32, true);\n' ' send_data >>= 32;\n' ' // Header\n' ' mark(kFOOHdrMark);\n' ' space(kFOOHdrSpace);\n' ' // Data Section #4\n' ' // e.g. data = 0x2F2F6C6C, nbits = 32\n' ' sendData(kFOOBitMark, kFOOOneSpace, kFOOBitMark, kFOOZeroSpace,' ' send_data, 32, true);\n' ' send_data >>= 32;\n' ' // Header\n' ' mark(kFOOHdrMark);\n' ' space(kFOOHdrSpace);\n' ' // Gap\n' ' mark(kFOOBitMark);\n' ' space(kFOOSpaceGap);\n' ' space(kDefaultMessageGap); // A 100% made up guess of the gap' ' between messages.\n' ' }\n' '}\n' '#endif // SEND_FOO\n' '\n' '#if SEND_FOO\n' '// Alternative >64bit function to send FOO messages\n' '// Where data is:\n' '// uint8_t data[kFOOStateLength] = {0x5F, 0x5F, 0x40, 0x40, 0x5F,' ' 0x5F, 0x40, 0x40, 0x2F, 0x2F, 0x6C, 0x6C, 0x2F, 0x2F, 0x6C, 0x6C};\n' '//\n' '// Args:\n' '// data: An array of bytes containing the IR command.\n' '// It is assumed to be in MSB order for this code.\n' '// nbytes: Nr. of bytes of data in the array. (>=kFOOStateLength)\n' '// repeat: Nr. of times the message is to be repeated.\n' '//\n' '// Status: ALPHA / Untested.\n' 'void IRsend::sendFOO(const uint8_t data[], const uint16_t nbytes,' ' const uint16_t repeat) {\n' ' for (uint16_t r = 0; r < repeat; r++) {\n' ' uint16_t pos = 0;\n' ' // Data Section #1\n' ' // e.g.\n' ' // bits = 32; bytes = 4;\n' ' // *(data + pos) = {0x5F, 0x5F, 0x40, 0x40};\n' ' sendGeneric(kFOOHdrMark, kFOOHdrSpace,\n' ' kFOOBitMark, kFOOOneSpace,\n' ' kFOOBitMark, kFOOZeroSpace,\n' ' kFOOHdrMark, kFOOHdrSpace,\n' ' data + pos, 4, // Bytes\n' ' kFOOFreq, true, kNoRepeat, kDutyDefault);\n' ' pos += 4; // Adjust by how many bytes of data we sent\n' ' // Data Section #2\n' ' // e.g.\n' ' // bits = 32; bytes = 4;\n' ' // *(data + pos) = {0x5F, 0x5F, 0x40, 0x40};\n' ' sendGeneric(kFOOHdrMark, kFOOHdrSpace,\n' ' kFOOBitMark, kFOOOneSpace,\n' ' kFOOBitMark, kFOOZeroSpace,\n' ' kFOOHdrMark, kFOOHdrSpace,\n' ' data + pos, 4, // Bytes\n' ' kFOOFreq, true, kNoRepeat, kDutyDefault);\n' ' pos += 4; // Adjust by how many bytes of data we sent\n' ' // Data Section #3\n' ' // e.g.\n' ' // bits = 32; bytes = 4;\n' ' // *(data + pos) = {0x2F, 0x2F, 0x6C, 0x6C};\n' ' sendGeneric(kFOOHdrMark, kFOOHdrSpace,\n' ' kFOOBitMark, kFOOOneSpace,\n' ' kFOOBitMark, kFOOZeroSpace,\n' ' kFOOHdrMark, kFOOHdrSpace,\n' ' data + pos, 4, // Bytes\n' ' kFOOFreq, true, kNoRepeat, kDutyDefault);\n' ' pos += 4; // Adjust by how many bytes of data we sent\n' ' // Data Section #4\n' ' // e.g.\n' ' // bits = 32; bytes = 4;\n' ' // *(data + pos) = {0x2F, 0x2F, 0x6C, 0x6C};\n' ' sendGeneric(kFOOHdrMark, kFOOHdrSpace,\n' ' kFOOBitMark, kFOOOneSpace,\n' ' kFOOBitMark, kFOOZeroSpace,\n' ' kFOOHdrMark, kFOOHdrSpace,\n' ' data + pos, 4, // Bytes\n' ' kFOOFreq, true, kNoRepeat, kDutyDefault);\n' ' pos += 4; // Adjust by how many bytes of data we sent\n' ' }\n' '}\n' '#endif // SEND_FOO\n' '\n' "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't " 'work!\n' '#if DECODE_FOO\n' '// Function should be safe up to 64 bits.\n' 'bool IRrecv::decodeFOO(decode_results *results, const uint16_t nbits,' ' const bool strict) {\n' ' if (results->rawlen < 2 * nbits + kFOOOverhead)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kFOOBits)\n' ' return false;\n' '\n' ' uint16_t offset = kStartOffset;\n' ' uint64_t data = 0;\n' ' match_result_t data_result;\n' '\n' ' // Header\n' ' if (!matchMark(results->rawbuf[offset++], kFOOHdrMark))\n' ' return false;\n' ' if (!matchSpace(results->rawbuf[offset++], kFOOHdrSpace))\n' ' return false;\n' '\n' ' // Data Section #1\n' ' // e.g. data_result.data = 0x5F5F4040, nbits = 32\n' ' data_result = matchData(&(results->rawbuf[offset]), 32,\n' ' kFOOBitMark, kFOOOneSpace,\n' ' kFOOBitMark, kFOOZeroSpace);\n' ' offset += data_result.used;\n' ' if (data_result.success == false) return false; // Fail\n' ' data <<= 32; // Make room for the new bits of data.\n' ' data |= data_result.data;\n' '\n' ' // Header\n' ' if (!matchMark(results->rawbuf[offset++], kFOOHdrMark))\n' ' return false;\n' ' if (!matchSpace(results->rawbuf[offset++], kFOOHdrSpace))\n' ' return false;\n' '\n' ' // Data Section #2\n' ' // e.g. data_result.data = 0x5F5F4040, nbits = 32\n' ' data_result = matchData(&(results->rawbuf[offset]), 32,\n' ' kFOOBitMark, kFOOOneSpace,\n' ' kFOOBitMark, kFOOZeroSpace);\n' ' offset += data_result.used;\n' ' if (data_result.success == false) return false; // Fail\n' ' data <<= 32; // Make room for the new bits of data.\n' ' data |= data_result.data;\n' '\n' ' // Header\n' ' if (!matchMark(results->rawbuf[offset++], kFOOHdrMark))\n' ' return false;\n' ' if (!matchSpace(results->rawbuf[offset++], kFOOHdrSpace))\n' ' return false;\n' '\n' ' // Gap\n' ' if (!matchMark(results->rawbuf[offset++], kFOOBitMark))\n' ' return false;\n' ' if (!matchSpace(results->rawbuf[offset++], kFOOSpaceGap))\n' ' return false;\n' '\n' ' // Header\n' ' if (!matchMark(results->rawbuf[offset++], kFOOHdrMark))\n' ' return false;\n' ' if (!matchSpace(results->rawbuf[offset++], kFOOHdrSpace))\n' ' return false;\n' '\n' ' // Data Section #3\n' ' // e.g. data_result.data = 0x2F2F6C6C, nbits = 32\n' ' data_result = matchData(&(results->rawbuf[offset]), 32,\n' ' kFOOBitMark, kFOOOneSpace,\n' ' kFOOBitMark, kFOOZeroSpace);\n' ' offset += data_result.used;\n' ' if (data_result.success == false) return false; // Fail\n' ' data <<= 32; // Make room for the new bits of data.\n' ' data |= data_result.data;\n' '\n' ' // Header\n' ' if (!matchMark(results->rawbuf[offset++], kFOOHdrMark))\n' ' return false;\n' ' if (!matchSpace(results->rawbuf[offset++], kFOOHdrSpace))\n' ' return false;\n' '\n' ' // Data Section #4\n' ' // e.g. data_result.data = 0x2F2F6C6C, nbits = 32\n' ' data_result = matchData(&(results->rawbuf[offset]), 32,\n' ' kFOOBitMark, kFOOOneSpace,\n' ' kFOOBitMark, kFOOZeroSpace);\n' ' offset += data_result.used;\n' ' if (data_result.success == false) return false; // Fail\n' ' data <<= 32; // Make room for the new bits of data.\n' ' data |= data_result.data;\n' '\n' ' // Header\n' ' if (!matchMark(results->rawbuf[offset++], kFOOHdrMark))\n' ' return false;\n' ' if (!matchSpace(results->rawbuf[offset++], kFOOHdrSpace))\n' ' return false;\n' '\n' ' // Gap\n' ' if (!matchMark(results->rawbuf[offset++], kFOOBitMark))\n' ' return false;\n' ' if (!matchSpace(results->rawbuf[offset++], kFOOSpaceGap))\n' ' return false;\n' '\n' ' // Success\n' ' results->decode_type = decode_type_t::FOO;\n' ' results->bits = nbits;\n' ' results->value = data;\n' ' results->command = 0;\n' ' results->address = 0;\n' ' return true;\n' '}\n' '#endif // DECODE_FOO\n' '\n' '// Note: This should be 64+ bit safe.\n' '#if DECODE_FOO\n' '// Function should be safe over 64 bits.\n' 'bool IRrecv::decodeFOO(decode_results *results, const uint16_t nbits,' ' const bool strict) {\n' ' if (results->rawlen < 2 * nbits + kFOOOverhead)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kFOOBits)\n' ' return false;\n' '\n' ' uint16_t offset = kStartOffset;\n' ' uint16_t pos = 0;\n' ' uint16_t used = 0;\n' '\n' ' // Data Section #1\n' ' // e.g.\n' ' // bits = 32; bytes = 4;\n' ' // *(results->state + pos) = {0x5F, 0x5F, 0x40, 0x40};\n' ' used = matchGeneric(results->rawbuf + offset, results->state + pos,' '\n' ' results->rawlen - offset, 32,\n' ' kFOOHdrMark, kFOOHdrSpace,\n' ' kFOOBitMark, kFOOOneSpace,\n' ' kFOOBitMark, kFOOZeroSpace,\n' ' kFOOHdrMark, kFOOHdrSpace, true);\n' ' if (used == 0) return false; // We failed to find any data.\n' ' offset += used; // Adjust for how much of the message we read.\n' ' pos += 4; // Adjust by how many bytes of data we read\n' '\n' ' // Data Section #2\n' ' // e.g.\n' ' // bits = 32; bytes = 4;\n' ' // *(results->state + pos) = {0x5F, 0x5F, 0x40, 0x40};\n' ' used = matchGeneric(results->rawbuf + offset, results->state + pos,' '\n' ' results->rawlen - offset, 32,\n' ' kFOOHdrMark, kFOOHdrSpace,\n' ' kFOOBitMark, kFOOOneSpace,\n' ' kFOOBitMark, kFOOZeroSpace,\n' ' kFOOHdrMark, kFOOHdrSpace, true);\n' ' if (used == 0) return false; // We failed to find any data.\n' ' offset += used; // Adjust for how much of the message we read.\n' ' pos += 4; // Adjust by how many bytes of data we read\n' '\n' ' // Data Section #3\n' ' // e.g.\n' ' // bits = 32; bytes = 4;\n' ' // *(results->state + pos) = {0x2F, 0x2F, 0x6C, 0x6C};\n' ' used = matchGeneric(results->rawbuf + offset, results->state + pos,' '\n' ' results->rawlen - offset, 32,\n' ' kFOOHdrMark, kFOOHdrSpace,\n' ' kFOOBitMark, kFOOOneSpace,\n' ' kFOOBitMark, kFOOZeroSpace,\n' ' kFOOHdrMark, kFOOHdrSpace, true);\n' ' if (used == 0) return false; // We failed to find any data.\n' ' offset += used; // Adjust for how much of the message we read.\n' ' pos += 4; // Adjust by how many bytes of data we read\n' '\n' ' // Data Section #4\n' ' // e.g.\n' ' // bits = 32; bytes = 4;\n' ' // *(results->state + pos) = {0x2F, 0x2F, 0x6C, 0x6C};\n' ' used = matchGeneric(results->rawbuf + offset, results->state + pos,' '\n' ' results->rawlen - offset, 32,\n' ' kFOOHdrMark, kFOOHdrSpace,\n' ' kFOOBitMark, kFOOOneSpace,\n' ' kFOOBitMark, kFOOZeroSpace,\n' ' kFOOHdrMark, kFOOHdrSpace, true);\n' ' if (used == 0) return false; // We failed to find any data.\n' ' offset += used; // Adjust for how much of the message we read.\n' ' pos += 4; // Adjust by how many bytes of data we read\n' '\n' ' // Success\n' ' results->decode_type = decode_type_t::FOO;\n' ' results->bits = nbits;\n' ' return true;\n' '}\n' '#endif // DECODE_FOO\n')
def test_parse_and_report(self): """Tests for the parse_and_report() function.""" # Without code generation. output = StringIO() input_str = """ uint16_t rawbuf[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};""" analyse.parse_and_report(input_str, 200, False, "FOO", output) self.assertEqual( output.getvalue(), 'Found 139 timing entries.\n' 'Potential Mark Candidates:\n' '[9008, 676]\n' 'Potential Space Candidates:\n' '[19990, 4496, 1680, 584]\n' '\n' 'Guessing encoding type:\n' 'Looks like it uses space encoding. Yay!\n' '\n' 'Guessing key value:\n' 'kFOOHdrMark = 9008\n' 'kFOOHdrSpace = 4496\n' 'kFOOBitMark = 650\n' 'kFOOOneSpace = 1657\n' 'kFOOZeroSpace = 554\n' 'kFOOSpaceGap = 19990\n' '\n' 'Decoding protocol based on analysis so far:\n' '\n' 'kFOOHdrMark+kFOOHdrSpace+10011000010100000000011000001010010GAP(19990)' '\n' ' Bits: 35\n' ' Hex: 0x4C2803052 (MSB first)\n' ' 0x250600A19 (LSB first)\n' ' Dec: 20443050066 (MSB first)\n' ' 9938405913 (LSB first)\n' ' Bin: 0b10011000010100000000011000001010010 (MSB first)\n' ' 0b01001010000011000000000101000011001 (LSB first)\n' 'kFOOBitMark(UNEXPECTED)01000000110001000000000000001111\n' ' Bits: 32\n' ' Hex: 0x40C4000F (MSB first)\n' ' 0xF0002302 (LSB first)\n' ' Dec: 1086586895 (MSB first)\n' ' 4026540802 (LSB first)\n' ' Bin: 0b01000000110001000000000000001111 (MSB first)\n' ' 0b11110000000000000010001100000010 (LSB first)\n' '\n' 'Total Nr. of suspected bits: 67\n') # With code generation. output = StringIO() input_str = """ uint16_t rawbuf[37] = {7930, 3952, 494, 1482, 520, 1482, 494, 1508, 494, 520, 494, 1482, 494, 520, 494, 1482, 494, 1482, 494, 3978, 494, 520, 494, 520, 494, 520, 494, 520, 520, 520, 494, 520, 494, 520, 494, 1482, 494};""" analyse.parse_and_report(input_str, 200, True, "FOO", output) self.assertEqual( output.getvalue(), 'Found 37 timing entries.\n' 'Potential Mark Candidates:\n' '[7930, 520]\n' 'Potential Space Candidates:\n' '[3978, 1508, 520]\n' '\n' 'Guessing encoding type:\n' 'Looks like it uses space encoding. Yay!\n' '\n' 'Guessing key value:\n' 'kFOOHdrMark = 7930\n' 'kFOOHdrSpace = 3965\n' 'kFOOBitMark = 496\n' 'kFOOOneSpace = 1485\n' 'kFOOZeroSpace = 520\n' '\n' 'Decoding protocol based on analysis so far:\n' '\n' 'kFOOHdrMark+kFOOHdrSpace+11101011\n' ' Bits: 8\n' ' Hex: 0xEB (MSB first)\n' ' 0xD7 (LSB first)\n' ' Dec: 235 (MSB first)\n' ' 215 (LSB first)\n' ' Bin: 0b11101011 (MSB first)\n' ' 0b11010111 (LSB first)\n' 'UNEXPECTED->kFOOHdrSpace+00000001\n' ' Bits: 8\n' ' Hex: 0x01 (MSB first)\n' ' 0x80 (LSB first)\n' ' Dec: 1 (MSB first)\n' ' 128 (LSB first)\n' ' Bin: 0b00000001 (MSB first)\n' ' 0b10000000 (LSB first)\n' '\n' 'Total Nr. of suspected bits: 16\n' '\n' 'Generating a VERY rough code outline:\n' '\n' '// Copyright 2019 David Conran (crankyoldgit)\n' '// Support for FOO protocol\n' '\n' '#include "IRrecv.h"\n' '#include "IRsend.h"\n' '#include "IRutils.h"\n' '\n' "// WARNING: This probably isn't directly usable. It's a guide only.\n" '\n' '// See https://github.com/crankyoldgit/IRremoteESP8266/wiki/' 'Adding-support-for-a-new-IR-protocol\n' '// for details of how to include this in the library.\n' 'const uint16_t kFOOHdrMark = 7930;\n' 'const uint16_t kFOOBitMark = 496;\n' 'const uint16_t kFOOHdrSpace = 3965;\n' 'const uint16_t kFOOOneSpace = 1485;\n' 'const uint16_t kFOOZeroSpace = 520;\n' 'const uint16_t kFOOFreq = 38000; // Hz. (Guessing the most common' ' frequency.)\n' 'const uint16_t kFOOBits = 16; // Move to IRremoteESP8266.h\n' 'const uint16_t kFOOOverhead = 5;\n' '#if SEND_FOO\n' '// Function should be safe up to 64 bits.\n' 'void IRsend::sendFOO(const uint64_t data, const uint16_t nbits,' ' const uint16_t repeat) {\n' ' enableIROut(kFOOFreq);\n' ' for (uint16_t r = 0; r <= repeat; r++) {\n' ' uint64_t send_data = data;\n' ' // Header\n' ' mark(kFOOHdrMark);\n' ' space(kFOOHdrSpace);\n' ' // Data Section #1\n' ' // e.g. data = 0xEB, nbits = 8\n' ' sendData(kFOOBitMark, kFOOOneSpace, kFOOBitMark, kFOOZeroSpace,' ' send_data, 8, true);\n' ' send_data >>= 8;\n' ' // Footer\n' ' mark(kFOOBitMark);\n' ' space(kFOOHdrSpace);\n' ' // Data Section #2\n' ' // e.g. data = 0x1, nbits = 8\n' ' sendData(kFOOBitMark, kFOOOneSpace, kFOOBitMark, kFOOZeroSpace,' ' send_data, 8, true);\n' ' send_data >>= 8;\n' ' // Footer\n' ' mark(kFOOBitMark);\n' ' space(kDefaultMessageGap); // A 100% made up guess of the gap' ' between messages.\n' ' }\n' '}\n' '#endif // SEND_FOO\n' '\n' '#if DECODE_FOO\n' '// Function should be safe up to 64 bits.\n' 'bool IRrecv::decodeFOO(decode_results *results, const uint16_t nbits,' ' const bool strict) {\n' ' if (results->rawlen < 2 * nbits + kFOOOverhead)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kFOOBits)\n' ' return false;\n' '\n' ' uint16_t offset = kStartOffset;\n' ' uint64_t data = 0;\n' ' match_result_t data_result;\n' '\n' ' // Header\n' ' if (!matchMark(results->rawbuf[offset++], kFOOHdrMark))\n' ' return false;\n' ' if (!matchSpace(results->rawbuf[offset++], kFOOHdrSpace))\n' ' return false;\n' '\n' ' // Data Section #1\n' ' // e.g. data_result.data = 0xEB, nbits = 8\n' ' data_result = matchData(&(results->rawbuf[offset]), 8,\n' ' kFOOBitMark, kFOOOneSpace,\n' ' kFOOBitMark, kFOOZeroSpace);\n' ' offset += data_result.used;\n' ' if (data_result.success == false) return false; // Fail\n' ' data <<= 8; // Make room for the new bits of data.\n' ' data |= data_result.data;\n' '\n' ' // Footer\n' ' if (!matchMark(results->rawbuf[offset++], kFOOBitMark))\n' ' return false;\n' ' if (!matchSpace(results->rawbuf[offset++], kFOOHdrSpace))\n' ' return false;\n' '\n' ' // Data Section #2\n' ' // e.g. data_result.data = 0x1, nbits = 8\n' ' data_result = matchData(&(results->rawbuf[offset]), 8,\n' ' kFOOBitMark, kFOOOneSpace,\n' ' kFOOBitMark, kFOOZeroSpace);\n' ' offset += data_result.used;\n' ' if (data_result.success == false) return false; // Fail\n' ' data <<= 8; // Make room for the new bits of data.\n' ' data |= data_result.data;\n' '\n' ' // Footer\n' ' if (!matchMark(results->rawbuf[offset++], kFOOBitMark))\n' ' return false;\n' '\n' ' // Success\n' ' results->decode_type = decode_type_t::FOO;\n' ' results->bits = nbits;\n' ' results->value = data;\n' ' results->command = 0;\n' ' results->address = 0;\n' ' return true;\n' '}\n' '#endif // DECODE_FOO\n')