Skip to content

bengtmartensson/IrpTransmogrifier

Repository files navigation

IrpTransmogrifier

Java CI with Maven + Upload

Parser for IRP notation protocols, with rendering, code generation, recognition applications.

This is a new program, written from scratch, that is intended to replace IrpMaster, DecodeIR, and (most of) ExchangeIR, and much more like potentially replacing "all" hand written decoders/renderers. The project consists of an API library that is also callable from the command line as a command line program. A GUI is possible, as well as the integration in GUI programs, like IrScrutinizer.

Acknowledgement

I would like to acknowledge the influence of the JP1 forum, both the programs (in particular of course DecodeIR, and the discussions (in particular with Dave Reed ("3FG") and Graham Dixon ("mathdon")). This work surely would not exist without the JP1 forum.

Background

This program can be considered as a successor of IrpMaster. The Irp parser therein is based upon a ANTLR3 grammar. The "new version" ANTLR4 is really not a new version, but a completely different tool, fixing most of the quirks that were irritating in IrpMaster (like the "ugliness" of embedding actions within the grammar, no left recursion, and much more). Unfortunately, this means that using version 4 instead of version 3 is not like updating a compiler or such, but "necessitates" a complete rewrite of the actions.

But that is of course not all: Both DecodeIR by John Fine and the Analyzer by Graham Dixon have shown to be essentially impossible to maintain and extend. Although DecodeIR and IrpMaster (through the data base IrpProtocols.ini) agree on most (but not all) protocols, this consists of two different, dis-coupled sources of protocol information. Finally, to be able to generate code from the IRP form is a natural wish.

Use cases

The reason for this project is not (just) to migrate IrpMaster to ANTLR4 -- version 3 is still operational, and no more broken than it was at the start. There are a number of interesting use cases for a nice parser/tree traverser:

Rendering

This use case corresponds to IrpMaster. It is probably to be implemented as a traversing of the parse tree of an IRP protocol, with numerical values assigned to the parameters.

In the present implementation, only one infinite repeat is allowed. (A realistic protocol, or use case, requiring more than one infinite repeat is not known to me.) Also, individual bitfields are restricted to 63 bits of length or less. (This is inherited from the use of Java's long type. It may be removed in the future.) With the exception of these restriction, the implementations should be complete, down to specification holes. There are also a few extensions to the IRP notation as described in the official documentation.

In IrScrutinizer, the word "generate" is used instead of "render". These words can be considered as synonyms (here).

Recognition

This use case corresponds to a dynamic version of DecodeIR: given a numerical IR signal, find the parameter/protocol combination(s) that could have generated the given signal. This is implemented by trying to parse the given signal with respect to the candidate protocols. It is thus very systematic, but comparatively slow.

It is not claimed that all protocols in the protocol data base are recognizable. Non-recognizable protocols are to be marked by setting the decodable parameter to false. To be recognizable, the IRP protocol should preferably adhere to some additional rules:

  • The "+" form of repetitions is discouraged in favor of the "*" form.
  • The width and shift of a Bitfield must be constant.
  • The decoder is capable of simple equation solving (e.g. Arctech), but not of complicated equation solving.

Presently all but two protocols (zenith, nec1-shirriff, (bitfield width as parameter), fujitsu_aircon (would require non-trivial equation solving)) are recognizable. It is not guaranteed that new protocols automatically will be recognizable.

Loose matches, Guessing

Many captured signals are not quite correct according to their protocol. However, the firmware in a receiving device is often "forgiving", and accepts slightly flawed signals. It is thus desirable for a program of this type to find a near match, "guess", when an real match fails. This is known as loose mode, opposite of "strict" mode. For practical reasons, the loose mode is the default in the command line usage. The strict mode is enabled using the decode option --strict.

Code generation for rendering and/or decoding

For a particular protocol, generate target code (C, C++, Java, Python,...) that can render or decode signals with the selected protocol. As opposed to the previous use cases, efficency (memory, execution time) (for the generated code) is potentially an issue. This should be able to generate protocol renders for e.g. the Arduino libraries IrRemote, IrLib, and AGirs. At least in the first version, not all protocols describable by IRPs need to be supported. Not implemented in the first phase: Protocols with hierarchical bitspecs (rc6*, replay, arctech, entone), protocols with bitspec lenght as parameter (zenith, nec1-shirrif). Also default are not implemented, e.g. NEC1 has to be called with 3 parameters.

Two mechanisms are available: XML and Stringtemplate. The program does not come with an XSLT engine, so this has to be invoked independently on the XML export. The program just invokes the template, without caring what it does; if it generates a renderer or decoder. The user is instead governs this by invoking the style sheets or templates (s)he want using the --target (-t) option to the code sub subcommand. (For this reason, there is no --renderer or --decoder option to the code sub command.) It is also possible to pass target-specific parameters to the code generators using the --parameter (-p) argument.

Targets:

  • Lircd.conf generation from IrScrutinizer. This is based on an XSLT-transformation (lirc.xsd) and generates an XSLT (version 1) file that can work with IrScrutinizer. Handling of definitions as well as expressions as bitfields not implemented, as well as a few other things (search for "omitted" in the above file), otherwise works. "90% complete", see this issue. To create: see (or execute) the shell script tools/generate-lirc.sh. In short, this generates the xml export, and then invokes xslt transformations on that xml file.
  • Java. Essentially for testing. This is essentially working both for rendering and decoding, including a generated test rig (see the test project). Targets: java-decoder java-decoder-test java-renderer java-renderer-test. Not quite finished, see this issue.

Some possible future targets:

General code analysis

Not really connected to parsing IRP, but fits in the general framework. This has been inspired by to the Analyzer and the RepeatFinder in Graham Dixon's ExchangeIR (Java translation).

Protocol Data Base

The "ini"-file IrpProtocols.ini of IrpMaster has been replaced by an XML file, per default called IrpProtocols.xml. The XML format is defined by the W3C schema irp-protocols, and has the name space http://www.harctoolbox.org/irp-protocols. This format has many advantages in comparison with the simpler previous format, for example, it can contain embedded XHTLM fragments. It also can contain different parameters that can be used by different programs, for example, tolerance parameters for decoding. Arbitrary string-valued parameters are permitted. It is up to an interpreting program to determine the semantic.

There is also an XSLT stylesheet, which technically translates the XML to HTML, allowing for a user friendly reading of IrpProtocols.xml in the browser.

API documentation

Up-to-date API documentation, generated by Javadoc, is found here.

Integration in Maven projects

This project can be integrated into other projects using Maven. For this, include the lines

        <dependency>
            <groupId>org.harctoolbox</groupId>
            <artifactId>IrpTransmogrifier</artifactId>
            <version>1.2.3</version>  <!-- or another supported version -->
        </dependency>

in the pom.xml of the importing project.

Installation

Unpack the binary distribution in a new, empty directory. Start the program by invoking the wrapper (irptransmogrifier.bat on Windows, irptransmogrifier.sh on Unix-like systems like Linux and MacOS.) from the command line. Modify and/or relocate the wrapper(s) if desired or necessary. Do not double click the wrappers, since this program runs only from the command line.

Also, do not use the wrapper irptransmogrifier in the top top directory of the source tree. This is intended for development only, not by users.

Building from sources

The project uses Maven as build system. Any modern IDE should be able to open/import and build it (as Maven project). Of course, Maven can also be run from the command line, like

mvn install

Dependencies

The program depends on ANTLR4 (license), Stringtemplate, (license), as well as the command line decoder JCommander. (licensed under the Apache 2 license). When using Maven for building, these are automatically downloaded and installed.

Usage

Using from the command line, this is a command with sub commands. Before the sub command, common options can be given. After the command, command-specific options can be specified. Commands and option names can be abbreviated, as long as the abbreviation is unique. They are matched case sensitively, and can be abbreviated as long as the abbreviation is unambiguous.

The command

irptransmogrifier help --short

lists the subcommands. A command like

irptransmogrifier analyze --help

gives the usage for the subcommand analyze, while a command like

irptransmogrifier analyze --help

gives a possibly somewhat longer description for the subcommand analyze.

The subcommands are briefly described next.

Subcommand analyze

The "analyze" command takes as input one or several sequences or signals, and computes an IRP form that corresponds to the given input (within the specified tolerances). The input can be given either as Pronto Hex or in raw form, optionally with signs (ignored). Several raw format input sequences can be given by enclosing the individual sequences in brackets ("[]"). However, if using the --intro-repeat-ending option, the sequences are instead interpreted as intro-, repeat-, and (optionally) ending sequences of an IR signal.

For raw sequences, an explicit modulation frequency can be given with the --frequency option. Otherwise the default frequency, 38000Hz, will be assumed. If this option is given together with a Pronto type signal (which contains a modulation frequency), it is ignored.

Using the option --input, instead the content of a file can be taken as input, containing sequences to be analyzed, one per line, blank lines ignored. Using the option --namedinput, the sequences may have names, immediately preceeding the sequence. In both cases, the data is taken as IrSequences. IrSignals, with intro-, repeat-, and ending, are coerced into IrSequences.

In the Harctoolbox world, IR sequences start with a flash (mark) and ends with a non-zero gap (space). In some other "worlds", the last gap is omitted. These signal are in general rejected. The option --trailinggap <duration> adds a dummy duration to the end of each IR sequence lacking a final gap.

Input sequences can be pre-processed using the options --chop, --clean, and --repeatfinder.

The cleaner works according to this idea: The collected durations found in the sequence(s) are bundled into "bins" (disjoint intervals), according to absolutetolerance and relativetolerance. Every duration belonging to a bin is "close" (determined by those parameters) to the bin middle. All the durations within the bin are then replaced by the average of its members. It is thus not guaranteed that the distance between a duration and its relacement will be consistent with absolutetolerance and relativetolerance.

The input sequence(s) are matched using different "decoders". Normally the "best" decoder match is output. With the --all option, all decoder matches are output.

The options --statistics and --dump-repeatfinder (the latter forces the repeatfinder to be on) can be used to print extra information. The common options --absolutetolerance, --relativetolerance, --minrepeatgap determine how the repeat finder breaks the input data. The options --extent, --invert, --lsb, --maxmicroseconds, --maxparameterwidth, --maxroundingerror, --maxunits, --parameterwidths, --radix, and --timebase determine how the computed IRP is displayed.

Subcommand bitfield

The "bitfield" command computes the value and the binary form corresponding to the bitfield given as input. Using the --nameengine argument, the bitfield can also refer to names.

As an alternatively, the "expression" command may be used.

Subcommand code

Used for generating code for different targets.

Subcommand decode

The "decode" command takes as input one or several sequences or signals, and output one or many protocol/parameter combinations that corresponds to the given input (within the specified tolerances). The input can be given either as Pronto Hex or in raw form, optionally with signs (ignored). Several raw format input sequences can be given by enclosing the individual sequences in brackets ("[]").

For raw sequences, an explicit modulation frequency can be given with the --frequency option. Otherwise the default frequency, 38000Hz, will be assumed.

Using the option --input, instead the content of a file can be taken as input, containing sequences to be analyzed, one per line, blank lines ignored. Using the option --namedinput, the sequences may have names, immediately preceeding the signal.

In the Harctoolbox world, IR sequences start with a flash (mark) and ends with a non-zero gap (space). In some other "worlds", the last gap is omitted. These signal are in general rejected. The option --trailinggap <duration> adds a dummy duration to the end of each IR sequence lacking a final gap.

Input sequences can be pre-processed using the options --clean, and --repeatfinder.

The common options --absolutetolerance, --relativetolerance, --minrepeatgap determine how the repeat finder breaks the input data.

Subcommand help

This command list the syntax for the command(s) given as argument, default all. Also see the option --describe.

Subcommand lirc

This command reads a Lirc configuration, from a file, directory, or an URL, and computes a correponding IRP form.

Subcommand list

This command list miscellaneous properties of the protocol(s) given as arguments.

Subcommand render

This command is used to compute an IR signal from one or more protocols ("render" it). The protocol can be given either by name(s) (or regular expression if using the --regexp option), or, using the --irp options, given explicitly as an IRP form. The parameters can be either given directly with the -n option,or the --random option can be used to generate random, but valid parameters. With the --count or --number-repeats option, instead an IR sequence is computed,containing the desired number of repeats.

Subcommand version

Reports version number and license.

Usage message

Usage: IrpTransmogrifier [options] [command] [command options]
  Options:
    -a, --absolutetolerance
      Absolute tolerance in microseconds, used when comparing durations.
      Default: 100.0.
    -b, --blacklist
      List of protocols to be removed from the data base
    -C, --commentStart
      Character(s) to be considered starting a line comment in input and
      namedInput files.
    -c, --configfiles
      Pathname(s) of IRP database file(s) in XML format. Default is the one in
      the jar file. Can be given several times.
    --describe
      Print a possibly longer documentation for the present command.
    -f, --frequencytolerance
      Frequency tolerance in Hz. Negative disables frequency check. Default:
      2000.0.
    -h, -?, --help
      Print help for this command.
    -e, --encoding, --iencoding
      Encoding used to read input.
      Default: UTF-8
    -i, --irp
      Explicit IRP string to use as protocol definition.
    --logclasses
      List of (fully qualified) classes and their log levels, in the form
      class1:level1|class2:level2|...
      Default: <empty string>
    -L, --logfile
      Log file. If empty, log to stderr.
    -F, --logformat
      Log format, as in class java.util.logging.SimpleFormatter.
      Default: [%2$s] %4$s: %5$s%n
    -l, --loglevel
      Log level { OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL
      }
      Default: WARNING
    --min-leadout
      Threshold for leadout when decoding. Default: 20000.0.
    -g, --minrepeatgap
      Minimum gap required to end a repetition.
      Default: 5000.0
    --oencoding
      Encoding used in generated output.
      Default: UTF-8
    -o, --output
      Name of output file. Default: stdout.
    -O, --override
      Let given command line parameters override the protocol parameters in
      IrpProtoocols.xml
      Default: false
    -q, --quiet
      Quitest possible operation, typically to be used from scripts.
      Default: false
    --regexp
      Interpret protocol/decoder argument as regular expressions.
      Default: false
    -r, --relativetolerance
      Relative tolerance as a number < 1. Default: 0.3.
    --seed
      Set seed for the pseudo random number generation. If not specified, will
      be random, different between program invocations.
    -s, --sort
      Sort the protocols alphabetically on output.
      Default: false
    -t, --tsv, --csv
      Use tabs in output to optimize for the import in spreadsheet programs as
      cvs.
      Default: false
    -u, --url-decode
      URL-decode protocol names, (understanding %20 for example).
      Default: false
    --validate
      Validate IRP database files against the schema, abort if not valid.
      Default: false
    --version
      Report version. Deprecated; use the command "version" instead.
      Default: false
    -x, --xmllog
      Write the log in XML format.
      Default: false
  Commands:
    help      Describe the syntax of program and commands.
      Usage: help [options] commands
        Options:
          --describe
            Print a possibly longer documentation for the present command.
          -h, -?, --help
            Print help for this command.
          -l, --logging
            Describe the logging related options only.
            Default: false
          -c, --common, --options
            Describe the common options only.
            Default: false
          -s, --short
            Produce a short usage message.
            Default: false

    version      Report version and license.
      Usage: version [options]
        Options:
          --describe
            Print a possibly longer documentation for the present command.
          -h, -?, --help
            Print help for this command.
          -s, --short
            Issue only the version number of the program proper.
            Default: false

    list      List protocols and their properties.
      Usage: list [options] List of protocols (default all)
        Options:
          -a, --all
            Implies (almost) all of the "list xxx"-options.
            Default: false
          --check-sorted
            Check if the protocol are alphabetically.
            Default: false
          -c, --classify
            Classify the protocol(s).
            Default: false
          --describe
            Print a possibly longer documentation for the present command.
          --gui, --display
            Display parse diagram.
            Default: false
          --documentation
            Print (possible longer) documentation, as a dumb rendering of the
            HTML documenation.
            Default: false
          -d, --dump
            Print the IRP data base as DOC tree stringified, including initial
            XML comments.
            Default: false
          -h, -?, --help
            Print help for this command.
          --html
            Print (possible longer) documentation as HTML.
            Default: false
          -i, --irp
            List IRP form, as given in the database (unparsed, i.e. preserving
            comments and whitespace, not taking --radix into account).
            Default: false
          -m, --mindiff
            Compute minimal difference between contained durations.
            Default: false
          --name
            List protocol name, also if --quiet is given.
            Default: false
          -n, --normalform
            List the normal form.
            Default: false
          --prefer-overs
            List all protocol's prefer-overs, recursively.
            Default: false
          -r, --radix
            Radix of parameter output.
            Default: 10
          --stringtree
            Produce stringtree.
            Default: false
          --warnings
            Issue warnings for some problematic IRP constructs.
            Default: false
          -w, --weight
            Compute weight of the protocols.
            Default: false
          -x, --xml
            Like dump, but without XML comments.
            Default: false

    render      Render signal from parameters
      Usage: render [options] protocol(s) or pattern (default all)
        Options:
          -#, --count
            Generate am IR sequence with count number of transmissions
          -d, --decode
            Send the rendered signal to the decoder (for
            debugging/development).
            Default: false
          --describe
            Print a possibly longer documentation for the present command.
          -h, -?, --help
            Print help for this command.
          -m, --modulate
            Generate modulated form (EXPERIMENTAL)
            Default: false
          -n, --nameengine, --parameters
            Name Engine to use
            Default: <empty string>
          --number-repeats
            Generate an IR sequence containing the given number of repeats
          -P, --printparameters
            Print actual parameters values, for example by --random
            Default: false
          -p, --pronto, --ccf, --hex
            Generate Pronto hex.
            Default: false
          --random
            Generate random, valid, parameters
            Default: false
          -R, --raw-without-signs
            Generate raw form without signs.
            Default: false
          -r, --signed-raw
            Generate raw form.
            Default: false

    decode      Decode IR signal given as argument
      Usage: decode [options] durations in micro seconds, alternatively pronto
            hex
        Options:
          -c, --clean
            Invoke cleaner on signal
            Default: false
          --describe
            Print a possibly longer documentation for the present command.
          -R, --dump-repeatfinder
            Print the result of the repeatfinder.
            Default: false
          -f, --frequency
            Set modulation frequency.
          -g, --girr
            Generate output in Girr format (only)
            Default: false
          -h, -?, --help
            Print help for this command.
          -l, --ignoreleadinggarbage
            Accept decodes starting with undecodable pairs.
            Default: false
          -i, --input
            File/URL from which to take inputs, one per line.
          -k, --keep-defaulted
            In output, do not remove parameters that are equal to their
            defaults.
            Default: false
          -n, --namedinput
            File/URL from which to take inputs, one line name, data one line.
          -a, --all, --no-prefer-over
            Output all decodes; ignore prefer-over.
            Default: false
          -p, --protocol
            Comma separated list of protocols to try match (default all).
          --radix
            Radix used for printing of output parameters.
            Default: 10
          --recursive
            Apply decoder recursively, (for long signals).
            Default: false
          -r, --repeatfinder
            Invoke repeat finder on input sequence
            Default: false
          -s, --strict
            Require intro- and repeat sequences to match exactly.
            Default: false
          -T, --trailinggap
            Trailing gap (in micro seconds) added to sequences of odd length.
          --xslt
            File/URL name of XSLT transformation that will be applied to
            --input or --namedinput argument

    demodulate      Demodulate IrSequence given as argument (EXPERIMENTAL).
      Usage: demodulate [options] durations in micro seconds, alternatively
            pronto hex
        Options:
          --describe
            Print a possibly longer documentation for the present command.
          -h, -?, --help
            Print help for this command.
          -t, --threshold
            Threshold used for demodulating, in micro seconds.
            Default: 35.0

    analyze      Analyze signal: tries to find an IRP form with parameters.
      Usage: analyze [options] durations in microseconds, or pronto hex.
        Options:
          -a, --all
            List all decoder outcomes, instead of only the one with lowest
            weight.
            Default: false
          -b, --bit-usage
            Create bit usage report. (Not with --all.)
            Default: false
          -c, --chop
            Chop input sequence into several using threshold (in milliseconds)
            given as argument.
          -C, --clean
            Output the cleaned sequence(s).
            Default: false
          -d, --decoder
            Use only the decoders matching argument (regular expression, or
            prefix). Use the argument "list" to list the available decoders.
          --describe
            Print a possibly longer documentation for the present command.
          -R, --dump-repeatfinder
            Print the result of the repeatfinder.
            Default: false
          --eliminate-vars
            Eliminate variables in output form.
            Default: false
          -e, --extent
            Output the last gap as an extent.
            Default: false
          --fatgirr
            Generate Girr file in fat format. Inhibits all other output.
            Default: false
          -f, --frequency
            Modulation frequency of raw signal.
          -g, --girr
            Generate Girr file. Inhibits all other output.
            Default: false
          -h, -?, --help
            Print help for this command.
          -i, --input
            File/URL from which to take inputs, one sequence per line.
          --ire, --intro-repeat-ending
            Consider the argument as begin, repeat, and ending sequence.
            Default: false
          -I, --invert
            Invert the order in bitspec.
            Default: false
          -l, --lsb
            Force lsb-first bitorder for the parameters.
            Default: false
          -u, --maxmicroseconds
            Maximal duration to be expressed as micro seconds.
            Default: 10000.0
          -M, --maxparameterwidth
            Maximal parameter width.
            Default: 63
          --maxroundingerror
            Maximal rounding errors for expressing as multiple of time unit.
            Default: 0.3
          -m, --maxunits
            Maximal multiplier of time unit in durations.
            Default: 30.0
          -n, --namedinput
            File/URL from which to take inputs, one line name, data one line.
          -P, --parameterspecs
            Compute a dumb parameter specs in the IRP.
            Default: false
          -p, --parametertable
            Create parameter table.
            Default: false
          -w, --parameterwidths
            Comma separated list of either parameter widths or name:width
            pairs.
            Default: []
          --radix
            Radix used for printing of output parameters.
            Default: 16
          -r, --repeatfinder
            Invoke the repeatfinder.
            Default: false
          -s, --statistics
            Print some statistics.
            Default: false
          -t, --timebase
            Force time unit , in microseconds (no suffix), or in periods (with
            suffix "p").
          --timings
            Print the total timings of the compute IRP form.
            Default: false
          -T, --trailinggap
            Dummy trailing gap (in micro seconds) added to sequences of odd
            length.
          --validate
            Validate that the resulted protocol can be used for rendering and
            produces the same signal.
            Default: false
          --xslt
            File/URL name of XSLT transformation that will be applied to
            --input or --namedinput argument

    code      Generate code for the given target(s)
      Usage: code [options] protocols
        Options:
          --describe
            Print a possibly longer documentation for the present command.
          -d, --directory
            Directory in whicht the generate output files will be written, if
            not using the --output option.
          -h, -?, --help
            Print help for this command.
          --inspect
            Fire up stringtemplate inspector on generated code (if sensible)
            Default: false
          -p, --parameter
            Specify target dependent parameters to the code generators.
            Default: []
          -s, --stdirectory
            Directory containing st (string template) files for code
            generation.
            Default: st
        * -t, --target
            Target(s) for code generation. Use ? for a list.
            Default: []

    bitfield      Evaluate bitfield given as argument.
      Usage: bitfield [options] bitfield
        Options:
          --describe
            Print a possibly longer documentation for the present command.
          -h, -?, --help
            Print help for this command.
          -l, --lsb
            Output bitstream with least significant bit first.
            Default: false
          -n, --nameengine, --parameters
            Define a name engine for resolving the bitfield.
            Default: <empty string>
          --xml
            Generate XML and write to file given as argument.

    expression      Evaluate expression given as argument.
      Usage: expression [options] expression
        Options:
          --describe
            Print a possibly longer documentation for the present command.
          --gui, --display
            Display parse diagram.
            Default: false
          -h, -?, --help
            Print help for this command.
          -n, --nameengine, --parameters
            Define a name engine to use for evaluating.
            Default: <empty string>
          -r, --radix
            Radix for outputting result.
            Default: 10
          --stringtree
            Output stringtree.
            Default: false
          --xml
            Generate XML and write to file argument.

    lirc      Convert Lirc configuration files to IRP form.
      Usage: lirc [options] Lirc config files/directories/URLs; empty for
            <stdin>.
        Options:
          -c, --commands
            Also list the commands if the remotes.
            Default: false
          --describe
            Print a possibly longer documentation for the present command.
          -h, -?, --help
            Print help for this command.



For documentation, see http://www.harctoolbox.org/IrpTransmogrifier.html