From 930b289df725bcbf8a94e2f6082057811e85c44c Mon Sep 17 00:00:00 2001 From: David Date: Fri, 15 May 2020 09:35:27 +1000 Subject: [PATCH 1/5] Improve raw_to_pronto_code.py * Use lower-case hex code output for pronto codes. * Add option to send the raw code via the repeat section of the Pronto code, rather than the inital section. * Add synonym of `-g` for the gap arg. For #1103 --- tools/raw_to_pronto_code.py | 25 ++++++++++++++++++++----- tools/raw_to_pronto_code_test.py | 25 +++++++++++++++++++------ 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/tools/raw_to_pronto_code.py b/tools/raw_to_pronto_code.py index d91366d06..46cb0cedf 100755 --- a/tools/raw_to_pronto_code.py +++ b/tools/raw_to_pronto_code.py @@ -7,7 +7,9 @@ from auto_analyse_raw_data import convert_rawdata, add_rawdata_args, get_rawdata -def parse_and_report(rawdata_str, hertz, end_usecs, verbose, output=sys.stdout): +# pylint: disable=too-many-arguments +def parse_and_report(rawdata_str, hertz, end_usecs, use_repeat, verbose, + output=sys.stdout): """Analyse the rawdata c++ definition of a IR message.""" # Parse the input. @@ -29,15 +31,20 @@ def parse_and_report(rawdata_str, hertz, end_usecs, verbose, output=sys.stdout): if verbose: output.write("Pronto period is %f uSecs.\n" % period) # Add the lengths to the code. - result.append("%04X" % int(len(rawdata) / 2)) # Initial burst - result.append("%04X" % 0) # Repeat (not used by this program) + if use_repeat: + result.append("%04x" % 0) # No Initial burst + result.append("%04x" % int(len(rawdata) / 2)) # Repeat code length + else: + result.append("%04x" % int(len(rawdata) / 2)) # Initial burst code length + result.append("%04x" % 0) # No Repeat # Add the data. if verbose: output.write("Raw data: %s " % rawdata) for i in rawdata: - result.append("%04X" % int(i / period)) + result.append("%04x" % int(i / period)) output.write("Pronto code = '%s'\n" % " ".join(result)) +# pylint: enable=too-many-arguments def main(): @@ -54,6 +61,7 @@ def main(): dest="hertz", required=True) arg_parser.add_argument( + "-g", "--gap", "--endgap", type=int, @@ -67,10 +75,17 @@ def main(): action="store_true", dest="verbose", default=False) + arg_parser.add_argument( + "-r", + "--repeat_code", + action='store_true', + help="Send using the 'repeat' section of the pronto code.", + dest="use_repeat") add_rawdata_args(arg_parser) arg_options = arg_parser.parse_args() parse_and_report(get_rawdata(arg_options), arg_options.hertz, - arg_options.usecs, arg_options.verbose) + arg_options.usecs, arg_options.use_repeat, + arg_options.verbose) if __name__ == '__main__': diff --git a/tools/raw_to_pronto_code_test.py b/tools/raw_to_pronto_code_test.py index ce37ef2c6..22431a107 100755 --- a/tools/raw_to_pronto_code_test.py +++ b/tools/raw_to_pronto_code_test.py @@ -14,11 +14,11 @@ def test_parse_and_report_at_38000(self): input_str = """ uint16_t rawData[7] = { 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" - pronto.parse_and_report(input_str, 38000, 100000, False, output) + pronto.parse_and_report(input_str, 38000, 100000, False, False, output) self.assertEqual( output.getvalue(), "Pronto code = " - "'0000 006D 0004 0000 02FB 0309 023D 048E 02FB 0309 023D 0ED8'\n") + "'0000 006D 0004 0000 02fb 0309 023d 048e 02fb 0309 023d 0ed8'\n") def test_parse_and_report_at_36000(self): """Tests for the parse_and_report() function @ 36kHz.""" @@ -27,11 +27,11 @@ def test_parse_and_report_at_36000(self): input_str = """ uint16_t rawData[7] = { 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" - pronto.parse_and_report(input_str, 36000, 100000, False, output) + pronto.parse_and_report(input_str, 36000, 100000, False, False, output) self.assertEqual( output.getvalue(), "Pronto code = " - "'0000 0073 0004 0000 02D3 02E0 021F 0451 02D3 02E0 021F 0E10'\n") + "'0000 0073 0004 0000 02d3 02e0 021f 0451 02d3 02e0 021f 0e10'\n") def test_parse_and_report_at_57600(self): """Tests for the parse_and_report() function @ 57.6kHz.""" @@ -40,11 +40,24 @@ def test_parse_and_report_at_57600(self): input_str = """ uint16_t rawData[7] = { 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" - pronto.parse_and_report(input_str, 57600, 100000, False, output) + pronto.parse_and_report(input_str, 57600, 100000, False, False, output) self.assertEqual( output.getvalue(), "Pronto code = " - "'0000 0047 0004 0000 0485 049B 0365 06E8 0485 049B 0364 1680'\n") + "'0000 0047 0004 0000 0485 049b 0365 06e8 0485 049b 0364 1680'\n") + + def test_parse_and_report_at_38000_using_repeat_section(self): + """Tests for the parse_and_report() function @38kHz using repeat section.""" + + output = StringIO() + input_str = """ + uint16_t rawData[7] = { + 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" + pronto.parse_and_report(input_str, 38000, 30000, True, False, output) + self.assertEqual( + output.getvalue(), + "Pronto code = " + "'0000 006D 0000 0004 02fb 0309 023d 048e 02fb 0309 023d 0474'\n") if __name__ == '__main__': From dd5712a6cee91a16c3c3493c23f6ff7e259215b3 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 15 May 2020 09:58:42 +1000 Subject: [PATCH 2/5] Adjust test name to fix lint issue. --- tools/raw_to_pronto_code_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/raw_to_pronto_code_test.py b/tools/raw_to_pronto_code_test.py index 22431a107..96c8c4df6 100755 --- a/tools/raw_to_pronto_code_test.py +++ b/tools/raw_to_pronto_code_test.py @@ -46,7 +46,7 @@ def test_parse_and_report_at_57600(self): "Pronto code = " "'0000 0047 0004 0000 0485 049b 0365 06e8 0485 049b 0364 1680'\n") - def test_parse_and_report_at_38000_using_repeat_section(self): + def test_parse_and_report_using_repeat(self): """Tests for the parse_and_report() function @38kHz using repeat section.""" output = StringIO() From 88cd591fba2b7d415b3edeb05ee1f25bc90b0d95 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 15 May 2020 10:20:51 +1000 Subject: [PATCH 3/5] raw_to_pronto_code.py: Support generating code. * Add option to output the code array instead. * re-order command arguments in a more alphabetical/logical layout. --- tools/raw_to_pronto_code.py | 30 ++++++++++++++++++++---------- tools/raw_to_pronto_code_test.py | 24 ++++++++++++++++++++---- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/tools/raw_to_pronto_code.py b/tools/raw_to_pronto_code.py index 46cb0cedf..25420a7a4 100755 --- a/tools/raw_to_pronto_code.py +++ b/tools/raw_to_pronto_code.py @@ -8,8 +8,8 @@ # pylint: disable=too-many-arguments -def parse_and_report(rawdata_str, hertz, end_usecs, use_repeat, verbose, - output=sys.stdout): +def parse_and_report(rawdata_str, hertz, end_usecs, use_repeat, generate_code, + verbose, output=sys.stdout): """Analyse the rawdata c++ definition of a IR message.""" # Parse the input. @@ -43,7 +43,11 @@ def parse_and_report(rawdata_str, hertz, end_usecs, use_repeat, verbose, output.write("Raw data: %s " % rawdata) for i in rawdata: result.append("%04x" % int(i / period)) - output.write("Pronto code = '%s'\n" % " ".join(result)) + if generate_code: + output.write("uint16_t pronto[%d] = {0x%s};\n" % (len(result), + ", 0x".join(result))) + else: + output.write("Pronto code = '%s'\n" % " ".join(result)) # pylint: enable=too-many-arguments @@ -60,6 +64,12 @@ def main(): help="Frequency of the protocol to use in code generation. E.g. 38000Hz", dest="hertz", required=True) + arg_parser.add_argument( + "-c", + "--code", + action='store_true', + help="Output C/C++ code instead of human-readable.", + dest="generate_code") arg_parser.add_argument( "-g", "--gap", @@ -68,6 +78,12 @@ def main(): help="Nr. of uSeconds of gap to add to the end of the message.", dest="usecs", default=100000) + arg_parser.add_argument( + "-r", + "--repeat_code", + action='store_true', + help="Send using the 'repeat' section of the pronto code.", + dest="use_repeat") arg_parser.add_argument( "-v", "--verbose", @@ -75,17 +91,11 @@ def main(): action="store_true", dest="verbose", default=False) - arg_parser.add_argument( - "-r", - "--repeat_code", - action='store_true', - help="Send using the 'repeat' section of the pronto code.", - dest="use_repeat") add_rawdata_args(arg_parser) arg_options = arg_parser.parse_args() parse_and_report(get_rawdata(arg_options), arg_options.hertz, arg_options.usecs, arg_options.use_repeat, - arg_options.verbose) + arg_options.generate_code, arg_options.verbose) if __name__ == '__main__': diff --git a/tools/raw_to_pronto_code_test.py b/tools/raw_to_pronto_code_test.py index 96c8c4df6..56af7d157 100755 --- a/tools/raw_to_pronto_code_test.py +++ b/tools/raw_to_pronto_code_test.py @@ -14,7 +14,8 @@ def test_parse_and_report_at_38000(self): input_str = """ uint16_t rawData[7] = { 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" - pronto.parse_and_report(input_str, 38000, 100000, False, False, output) + pronto.parse_and_report(input_str, 38000, 100000, False, False, False, + output) self.assertEqual( output.getvalue(), "Pronto code = " @@ -27,7 +28,8 @@ def test_parse_and_report_at_36000(self): input_str = """ uint16_t rawData[7] = { 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" - pronto.parse_and_report(input_str, 36000, 100000, False, False, output) + pronto.parse_and_report(input_str, 36000, 100000, False, False, False, + output) self.assertEqual( output.getvalue(), "Pronto code = " @@ -40,7 +42,8 @@ def test_parse_and_report_at_57600(self): input_str = """ uint16_t rawData[7] = { 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" - pronto.parse_and_report(input_str, 57600, 100000, False, False, output) + pronto.parse_and_report(input_str, 57600, 100000, False, False, False, + output) self.assertEqual( output.getvalue(), "Pronto code = " @@ -53,12 +56,25 @@ def test_parse_and_report_using_repeat(self): input_str = """ uint16_t rawData[7] = { 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" - pronto.parse_and_report(input_str, 38000, 30000, True, False, output) + pronto.parse_and_report(input_str, 38000, 30000, True, False, False, output) self.assertEqual( output.getvalue(), "Pronto code = " "'0000 006D 0000 0004 02fb 0309 023d 048e 02fb 0309 023d 0474'\n") + def test_generate_code_output(self): + """Tests for the parse_and_report() function geneating code output.""" + + output = StringIO() + input_str = """ + uint16_t rawData[7] = { + 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" + pronto.parse_and_report(input_str, 38000, 30000, False, True, False, output) + self.assertEqual( + output.getvalue(), + "uint16_t pronto[12] = {0x0000, 0x006D, 0x0004, 0x0000, 0x02fb, " + "0x0309, 0x023d, 0x048e, 0x02fb, 0x0309, 0x023d, 0x0474};\n") + if __name__ == '__main__': unittest.main(verbosity=2) From cbc72f21ede5e9d59fe4319ab116fa5dfa6d5194 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 15 May 2020 11:01:23 +1000 Subject: [PATCH 4/5] Add more tests * Add a unit test for sendPronto using a repeat-based code. * Add ability to generate code output. * another attempt to fix pylint issue. --- test/ir_Pronto_test.cpp | 11 +++++++++++ tools/raw_to_pronto_code_test.py | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/test/ir_Pronto_test.cpp b/test/ir_Pronto_test.cpp index 07016248e..8331192bc 100644 --- a/test/ir_Pronto_test.cpp +++ b/test/ir_Pronto_test.cpp @@ -423,4 +423,15 @@ TEST(TestSendPronto, Issue1103) { "f38028d50m20066s20435m15069s30665", irsend.outputStr()); // Which pretty much matches the `rawData` above. + + // Ref: + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1103#issuecomment-628946514 + uint16_t pronto_test_using_repeat[12] = { + 0x0000, 0x006D, 0x0000, 0x0004, 0x02fb, 0x0309, 0x023d, 0x048e, 0x02fb, + 0x0309, 0x023d, 0x0474}; + irsend.reset(); + irsend.sendPronto(pronto_test_using_repeat, 12); + EXPECT_EQ( + "f38028d50m20066s20435m15069s30665m20066s20435m15069s29982", + irsend.outputStr()); } diff --git a/tools/raw_to_pronto_code_test.py b/tools/raw_to_pronto_code_test.py index 56af7d157..155409233 100755 --- a/tools/raw_to_pronto_code_test.py +++ b/tools/raw_to_pronto_code_test.py @@ -49,7 +49,7 @@ def test_parse_and_report_at_57600(self): "Pronto code = " "'0000 0047 0004 0000 0485 049b 0365 06e8 0485 049b 0364 1680'\n") - def test_parse_and_report_using_repeat(self): + def test_using_repeat(self): """Tests for the parse_and_report() function @38kHz using repeat section.""" output = StringIO() From 5a0a325ace34524911111a25188ffb319809e804 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 15 May 2020 11:14:54 +1000 Subject: [PATCH 5/5] Make sending via the repeat section the default. * Change arguments, code, & tests accordingly Fixes #1103 --- tools/raw_to_pronto_code.py | 25 +++++++++++++------------ tools/raw_to_pronto_code_test.py | 11 ++++++----- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/tools/raw_to_pronto_code.py b/tools/raw_to_pronto_code.py index 25420a7a4..307ae7121 100755 --- a/tools/raw_to_pronto_code.py +++ b/tools/raw_to_pronto_code.py @@ -8,8 +8,9 @@ # pylint: disable=too-many-arguments -def parse_and_report(rawdata_str, hertz, end_usecs, use_repeat, generate_code, - verbose, output=sys.stdout): +def parse_and_report(rawdata_str, hertz=38000, end_usecs=100000, + use_initial=False, generate_code=False, verbose=False, + output=sys.stdout): """Analyse the rawdata c++ definition of a IR message.""" # Parse the input. @@ -31,12 +32,12 @@ def parse_and_report(rawdata_str, hertz, end_usecs, use_repeat, generate_code, if verbose: output.write("Pronto period is %f uSecs.\n" % period) # Add the lengths to the code. - if use_repeat: - result.append("%04x" % 0) # No Initial burst - result.append("%04x" % int(len(rawdata) / 2)) # Repeat code length - else: + if use_initial: result.append("%04x" % int(len(rawdata) / 2)) # Initial burst code length - result.append("%04x" % 0) # No Repeat + result.append("%04x" % 0) # No Repeat code length + else: + result.append("%04x" % 0) # No Initial burst code length + result.append("%04x" % int(len(rawdata) / 2)) # Repeat code length # Add the data. if verbose: @@ -79,11 +80,11 @@ def main(): dest="usecs", default=100000) arg_parser.add_argument( - "-r", - "--repeat_code", + "-i", + "--initial_burst", action='store_true', - help="Send using the 'repeat' section of the pronto code.", - dest="use_repeat") + help="Send using only the 'inital burst' section of the pronto code.", + dest="use_initial") arg_parser.add_argument( "-v", "--verbose", @@ -94,7 +95,7 @@ def main(): add_rawdata_args(arg_parser) arg_options = arg_parser.parse_args() parse_and_report(get_rawdata(arg_options), arg_options.hertz, - arg_options.usecs, arg_options.use_repeat, + arg_options.usecs, arg_options.use_initial, arg_options.generate_code, arg_options.verbose) diff --git a/tools/raw_to_pronto_code_test.py b/tools/raw_to_pronto_code_test.py index 155409233..b7b029b66 100755 --- a/tools/raw_to_pronto_code_test.py +++ b/tools/raw_to_pronto_code_test.py @@ -14,7 +14,7 @@ def test_parse_and_report_at_38000(self): input_str = """ uint16_t rawData[7] = { 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" - pronto.parse_and_report(input_str, 38000, 100000, False, False, False, + pronto.parse_and_report(input_str, 38000, 100000, True, False, False, output) self.assertEqual( output.getvalue(), @@ -28,7 +28,7 @@ def test_parse_and_report_at_36000(self): input_str = """ uint16_t rawData[7] = { 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" - pronto.parse_and_report(input_str, 36000, 100000, False, False, False, + pronto.parse_and_report(input_str, 36000, 100000, True, False, False, output) self.assertEqual( output.getvalue(), @@ -42,7 +42,7 @@ def test_parse_and_report_at_57600(self): input_str = """ uint16_t rawData[7] = { 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" - pronto.parse_and_report(input_str, 57600, 100000, False, False, False, + pronto.parse_and_report(input_str, 57600, 100000, True, False, False, output) self.assertEqual( output.getvalue(), @@ -56,7 +56,8 @@ def test_using_repeat(self): input_str = """ uint16_t rawData[7] = { 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" - pronto.parse_and_report(input_str, 38000, 30000, True, False, False, output) + pronto.parse_and_report(input_str, 38000, 30000, False, False, False, + output) self.assertEqual( output.getvalue(), "Pronto code = " @@ -69,7 +70,7 @@ def test_generate_code_output(self): input_str = """ uint16_t rawData[7] = { 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" - pronto.parse_and_report(input_str, 38000, 30000, False, True, False, output) + pronto.parse_and_report(input_str, 38000, 30000, True, True, False, output) self.assertEqual( output.getvalue(), "uint16_t pronto[12] = {0x0000, 0x006D, 0x0004, 0x0000, 0x02fb, "