Improved IR handling, receiving and transmitting

Do you have questions about writing plugins or scripts in Python? Meet the coders here.
Post Reply
User avatar
Barf
Posts: 10
Joined: Thu Jun 08, 2006 7:35 am
Contact:

Improved IR handling, receiving and transmitting

Post by Barf » Thu Jan 16, 2020 12:11 pm

(First post since 2007 :wink: )

I have been asked by Kevin to give some suggestions on EGs handling of IR. Rather than continuing as an IrScrutinizer ticket, I like to answer here.

This article contains a high-level view of how I envision a system can be designed.

EG is a "deployment program". There is therefore a priori no need to incorporate use cases like "learning", if that it can be handled in another way, with a convenient coupling to EG. That another way I propose to be IrScrutinizer. So we can, and should, take "learning" out of the equation; the use cases that should be implemented. (Some improvement of the coupling may be necessary/desirable though.)

I have been working on a project called IrpTransmogrifer. The project, written in Java, carries the GPL3 license. It contains a data base of most IR protocols known to the Internet communities. (Additional protocols can easily be added.) This can be used not only to decode and to render IR signals, but also to generate executable code for different targets. For this, either XML transformations or
StringTemplate can be used.

Implementing code generation for a new target (e.g. Python) is a reasonably easy task -- say a few hundred lines of code.

EG already contains a decoder, eg/Classes/IrDecoder. Problem is that it is "not particularly good". It is written in a fairly ad-hoc way, does not
use standard parametrization, and (in the case I looked at, the NEC decoder, eg/Classes/IrDecoder/Nec.py) straightout wrong.

So my suggestion for IR recognition is to replace the IR decoder with code generated by IrpTransmogrifier. Note that it is not necessary (and hardly sensible) to support all (presently 199) protocols, only the ones we need. Of course, this is a considerable refactoring, and, IMHO, it makes no sense to invest further in the Python 2 environment.

In a similar fashion, code for rendering IR signals from the parameters can be created by IrpTransmogrifier. (Kevin, this eliminates your "signal normalization" (or it *is* your signal normalization?).) Differently put, a plugin can implement acting on an event like sendIR.NEC1.12.34.56.

"Friendly names" for IR signals: I do not see it as a very necessary feature. If it is desired (say that you want to say "Yamaha.IR.Power-on" instead of "NEC1.122.29"), it can be implemented as an extra translation layer. Otherwise, a plugin for, say, controlling a Yamaha AVR, should know to translate from Yamaha.power-on to NEC1.122.29. Moreover, this "mapping" should be done at system setup time, not deployment. A deployment-time invocation of, say, irdb.tk, is not an attractive solution.

Alternatively, it might be possible to "embed" IrpTransmogrifier, and during deployment call its decoding and rendering functions. This would require calling Java from Python, an area where I personally have no experience. Googling gives a number of more-or-less interesting hits, for example Py4J seems promising. However, it appears a bit of overkill in comparison to the previous solution. I would strongly advise to migrate EG to Python 3 first.

Whadduysay?

Bengt

User avatar
kgschlosser
Site Admin
Posts: 5498
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Improved IR handling, receiving and transmitting

Post by kgschlosser » Fri Jan 17, 2020 10:16 am

In terms of receiving and learning they are almost identical. The only difference is whether to display the received code to the user as a pronto code or to create an event in EventGhost with it. when an ir code gets returned from the receiver it includes the frequency of the code with it. So in all reality the code would not have to be decoded when learned. and the RLC can be converted to pronto code without having to decode. but that is the removal of a step and does not create additional work in order to add the ability.

Here is a use case for the friendly names for buttons.
I have 5 remotes tied into my system, a single copy of eventghost handles the button mappings of all of the remotes If I have a house full of guests say over Christmas the amount of information that is being spat out in the log is bonkers.
Now if there is a glitch somewhere with one of the remotes for a specific button If I has a screen full of this in the log

Code: Select all

NEC1.3A.C8.3F
NEC1.73.35.21
NEC1.35.7F.91
NEC1.73.A3.D4
NEC1.99.8F.A0
NEC1.A3.12.A9
NEC1.F7.45.E4
NEC1.A4.90.08
NEC1.FD.ED.D7
NEC1.75.09.BB
NEC1.04.52.58
NEC1.1C.26.61
NEC1.9C.0A.C4
NEC1.28.2C.5D
NEC1.27.F4.C0
NEC1.65.31.2A
NEC1.77.02.91
NEC1.E1.1D.BF
NEC1.A7.F0.97
NEC1.EB.00.CE
NEC1.BD.83.E6
NEC1.14.00.E3
NEC1.D4.00.E7
NEC1.43.A6.F6
NEC1.97.6F.E7
NEC1.00.FB.E7
NEC1.F3.E0.A7
NEC1.5B.DA.32
NEC1.05.A4.70
NEC1.8A.30.38
That would be a real pain to locate the offending button press

On the other hand if the log looked something like this.

Code: Select all

NEC1.Button.Start
NEC1.Source.RecordedTV
NEC1.Number.Star
NEC1.Menu.DVD
NEC1.Number.3
NEC1.Volume.Up
NEC1.Source.Music
NEC1.Number.6
NEC1.Navigation.Left
NEC1.Menu.Info
NEC1.Volume.Mute
NEC1.Menu.DVD
NEC1.Source.TV
NEC1.Number.3
NEC1.Number.Star
NEC1.Channel.Down
NEC1.Navigation.Right
NEC1.Number.8
NEC1.Number.2
NEC1.Volume.Up
NEC1.Navigation.Enter
NEC1.Volume.Down
NEC1.Source.Videos
NEC1.Number.3
NEC1.Source.Radio
NEC1.Button.Subtitle
NEC1.Media.FastForward
NEC1.Navigation.Down
NEC1.Channel.Up
NEC1.Media.Pause
locating the offending button just became easier.

That is one of the things that EG has going for it that other HA solutions do not.. ease of use. You do not have to be a programmer in order to use it. So if I sold my house to someone and the automation was included. It is going to be easier to understand what is taking place for the new owner.

For the most part all of the plugins made will run some kind of a decoding process on any data that it receives. It does this to produce a nice output to the user. one that they will understand. We could just dump the raw data and the same operation could be performed using that instead. This is less attractive to look at for 1. for 2 it would also be overwhelming/confusing for a "newbie" to see taking place. It would scare people away I would imagine, because of the appearance of it being complex.

My plans for a learning process is simply to decode the signal and to display the RLC code, pronto code, protocol, and known button name if one exists. If the user wants to name the button differently they can do that. they will also have the ability to save the code locally, if the code does not exist and they have opted to share it they will also be able to save it to our server so it will be available to other users. The saving process allows the user to be able to access the code in the transmit action configuration dialog using the friendly name they provided no copying and pasting of pronto codes will need to be done. If a user needs a code they can access our server right from EG to see if it has been shared. If it has they can select it which would cause the code to be saved locally for use. I am also going to add an option a user can use to only cause events for codes that have been saved. This would be so other remotes that are not handled by EG will get filtered out.

The other reason why the friendly names are of high importance is because of the amount of work involved to change a remote control. If it spits out a bunch of hex codes then each button would have to be remapped to the macro that is supposed to get run. Now on the other hand if it is a friendly name like Play, Pause, Stop. If there is a learn feature. that feature can be started.. the user would then be able to press each button on the remote. they can then go through the codes that have been learned and modify the name save the code and they are done. no need to remap the macros to button presses. easy to use!

Now.. one code at a time can be copied and pasted from a different program this would need to be done if wanting to use a save code mechanism like outlines above.. it would take a while to do. This same process would also need to be done if transmitting codes. So if a user wants to change a device out they have to sort through their configuration. locate the actions that have the pronto codes stored in them and change them for the new codes. a learn feature would allow then to do every single action from a single spot with no copying and pasting needed.

Not to mention the lack of software that supports the MCE IR receivers with the capacity to learn codes.
If you would care to point me to a learning program that has the ability to learn codes by using the MCE receiver correctly and is accurate and has support for more then the typical 10 or so protocols that are commonly seen, It could be considered as a possibility to go that route. I have attempted to locate such a piece of software and came up empty handed. the Windows variant of lirc is not a complete port and has not been updated since 2014. So no longer in development or being maintained so should not be considered when locating software that can do this.

Now the software you wrote provides decoding for a HUGE number of protocols. It exceeds any expectation I have for the number of protocols that are supported.. Because the program is written in java this causes a slow down in the decoding process. because of having to start the JVM each and every single time a code needs to be decoded. This process takes 1.2 seconds for each code received, for a computer that has 6 cores @ 3.8gHz, 32GB of memory and a 4 disk SSD RAID 0 array. the MCE IR is supported in Vista and can run on an 800mHz processor, IDE HDD and 512mb of memory. I would think that the JVM is going to take far longer to start on a machine of those kinds of specs. (if at all).

The solution needed is one where the decoder can be running all of the time and be asked to decode an ir signal or the decoder code is able to be run directly. this can be done in several ways.

A console application that loops reading stdin for new codes and exits only when a command to exit the program has been given. This allows EG to start it when EG starts and to stop it when EG stops. If EG creashes for some reason the process can be terminated provided the permissions permit it. and if not a message informing the user that they need to kill it manually can be done. This I would consider to be acceptable and has a small possibility of causing a system stability problems if crashing occurs.

A Windows server where ir codes can be passed over a socket connection or a named pipe. This is a very complex thing to do. and having EG install and remove the service when needed can have issues. the biggest one being permissions

Statically or dynamically linking to the code to be able to run it when needed. This would be an ideal way. no worries about having to install or uninstall a service or starting and stopping a spawned process. If a crash happens the linked files get closed with no possibility of having system stability issues. Because your application is written in Java this is not an option.

I have looked into using python modules like the one you linked to. they also will need to spawn a process for the JVM so system stability if a crash occurs can still exist.


You mentioned updating the code to python 3. We have done this for EG and seems to be good to go. EG is not so much an issue, it is the 400ish known plugins that are available for EG. There is only a small number of people that have the knowledge to be able to help in updating the plugins. Those same people also are depended on by their families, they do not have a large amount of time to invest to help. The plugins they have released were created because the person that wrote it had a need, and they wanted to share with everyone most of the plugins are not activly being maintained or updated they have worked without problems or issues. There are a large number of them that were written by newbies and altering them in any way may cause unexpected behavior that would need to be fixed, and fixing it might be harder then writing it over. I have plugins that I have written 4 years ago that fall into this category. There are also plugins that use extension modules or DLL files made specifically for use with EG. those extensions would also need to be updated and recompiled provided the source code for it is available.

Over the past year or so as plugins need maintenance done to them I have also made them python 3 compatible at the same time. There may be 50 or so that are good to go. those would be the more commonly used ones. This plugin is part of that process, it has not operated like it should and because of the complexity it is easier to write a new one. and the new one will operate better and will not depend on code that we do not have all of the source code for and do not have the ability to make changes to because of the inability to compile it.

I have been updating plugins as they need routine maintenance with only a single person making these updates it takes a long time to do. I to also have a wife that i report to. and I have a home that I am actively remodeling. Time is not as slim as others so I am able to make the updates and changes that I do. that time has to be shared with people that need help with EG. and that amount varies. It is being worked on, but it is a slow process.
If you like the work I have been doing then feel free to Image

Post Reply