Challenge: Translate IR received command into different IR transmit command

  • Hi guys,

    How it is possible to run an external command when specific IR command received by LIRC?

    Details:

    I have surround LED lighting behind the TV. The light is controlled with dedicated IR remote.

    Every time I turn the TV on and off, I should remember to turn the LEDs too. Not a big deal, just not comfortable.

    Once I managed to control Kodi with TV remote, I thought the same remote can control the LED light as well.

    And OpenELEC over Raspberry pi might be the translator.

    Possible solutions:

    1. When "Power" key received, transmit MQTT command to separate IR transmitter. The transmitter will do the rest. This requires additional MCU and depends on network. Not the best solution.

    2. When "Power" key received, bit-bang GPIO with codes of LED light controller. The IR LED need to be connected to the GPIO. This is wired solution, not the best too.

    What's optimal way to transmit IR command by receiving other IR command over LIRC?

  • Connect an IR sending LED with the RPi and send the fitting IR code to the TV backlight.

    Installation instructions about IR sending LED on RPi GPIO are available on the net.

    This sending process will be triggered when the RPi receives the "TV Power" button press over CEC.

    You can use LE's key mapping to start your script by "TV Power" button press.

    The RPi "knows" whether "TV Power" on/off means TV backlight on or off by using a variable at your script.

  • Hi Da Flex, thank you for quick response.

    Connect an IR sending LED with the RPi

    Seems my 2nd proposal isn't that bad :)

    This sending process will be triggered when the RPi receives the "TV Power" button press over CEC.

    You can use LE's key mapping to start your script by "TV Power" button press.

    So the question is: What to configure and where in Kodi file system to run my script on receive of "Power" IR signal? I guess it should be a reference in Lircmap.xml... but how? I'm lost at this point.

    The RPi "knows" whether "TV Power" on/off means

    That's cool! How do I read the status of TV power on/off?

  • With an IR transmitter connected to your RPi you could simply use irexec to execute irsend when a specific button is pressed.

    irexec is available in LE but not run by default - you'll need to start start it via autostart.sh or a systemd service.

    You'll probably need to delay the irsend call a bit (eg do it via a shell script and add a sleep 1 before), otherwise the IR signal from your remote (where you are pressing the button) will interfere with the IR signals transmitted by the RPi.

    so long,

    Hias

  • Thank you Hias.

    So far:

    - There's ready lircd.conf file for the LED controller I have. Is it useful for sending IR commands? Or lircd.conf is just for receiving commands?

    - I connected the IR LED with transistor amplifier to GPIO17 on Raspi. I know how to tell to LIRC which pin to listen (dtoverlay=gpio-ir,gpio_pin=18). How to configure other pin to transmit? I found an example for dtoverlay for lirc, I can't find similar example for gpio-ir.

  • With gpio-ir-tx it's similar as for gpio-ir, you can use gpio_pin=XX to use a different GPIO.

    Actually, it'd be best to connect the IR transmitter to GPIO 18 (and use a different one for receive), then you can use pwm-ir-tx instead of gpio-ir-tx (pwm-ir-tx uses the PWM to generate the carrier frequency and is therefor e more precise and less cpu intensive than the bit-banged gpio-ir-tx).

    With these 2 overlays loaded you'll get two /dev/lircX devices and you'll need to add some udev rules to create eg /dev/lirc-transmit and /dev/lirc-receive symlinks - it's not guaranteed that eg /dev/lirc0 will always be receive, this may change.

    As you already have a working lircd setup you can use that for receive - just change the device in lirc options to the /dev/lirc-receive one.

    To use lircd for transmitting you'd need to setup a second lircd instance (separate lircd.socket and lircd.service systemd units plus separate lirc options and lircd.conf files), which is a bit tricky. Also lircd has some nasty bugs when transmitting (I reported that aeons ago but it hasn't been fixed) - so better avoid lircd.

    You can use ir-ctl instead for sending, it doesn't require a background daemon and you can simply specify the lirc device and protocol+scancode (or alternatively a raw file which you can capture with ir-ctl -r, if the protocol isn't natively supported by ir-ctl). To find out the scancode+protocol simply run ir-keytable -p all -t on the receiving device and push buttons on the remote which you want to simulate.

    Also search this and the raspberry pi forum, I posted several more infos about IR there (search for my username and/or ir-ctl, gpio-ir, ir-keytable).

    so long,

    Hias

  • Hi grhhm!

    I don't know your complete setup, but I think you're on the right track.

    To call a TV RC power button script, you could wite something like that at /storage/.kodi/userdata/keymaps/remote.xml:

    Code
    <keymap>
      <global>
        <remote>
          <power>RunScript(/full/path/to/your/python/script)</power>
        </remote>
      </global>
    </keymap>

    Test this mapping by scripting a simple task, like creating a file.

    If your TV backlight RC power button acts the same way like the TV RC power button, then you probably don't need a variable for the on/off status. Acting the same way means, both devices only have one RC button for turning on and off.

    Maybe the LIRC solution of Hias is better, but it's good to have extra options.

  • Thank you so much, Matthias and Da Flex!

    <power>RunScript(/full/path/to/your/python/script)</power>

    That was the missing link in my understanding. Now I can invoke a script which can determine the current status and send appropriate command.

    better avoid lircd [for transmitting].

    You can use ir-ctl instead for sending...

    I like the variant of ir-ctl. I am able to record protocol and scancode! :)

    From ir-ctl help:

    Quote

    -d, --device=DEV lirc device to use

    It seems i must specify the sending LIRC, while "better avoid lircd" and in my config there still just one overlay. Is adding one more overlay to transmit as explained above will give ir-ctl ability to transmit via /dev/lirc0?

  • Yes, I was puzzling how to get RPi.GPIO lib couple days ago. Installed add-on "Raspberry Pi Tools" from LE GUI as the Internet recommends. Still can't import RPi.GPIO. Tried even download the latest tar.gz from RPi.GPIO · PyPI and install it manually => failed on missing compilers and dependencies... I am afraid to ruin the LE... so ir-ctl looks very reasonable way to go.

    Now I ran into other trouble:

    Code
    LibreELEC:~ # mount -o nolock,rw /flash
    mount: can't find /flash in /etc/fstab    // the trouble
    LibreELEC:~ # mount | grep flas
    /dev/mmcblk0p1 on /flash type vfat (ro,noatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)
    LibreELEC:~ # cat /etc/fstab
    LibreELEC:~ # grep flash /etc/mtab
    /dev/mmcblk0p1 /flash vfat ro,noatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro 0 0
    LibreELEC:~ #

    Just wanted to add another dtoverlay into /flash/config.txt.

    The Internet advises to write into /etc/fstab. I understand that /etc/fstab is created dynamically on LE boot. Correct? mtab looks OK... So if I add the line it will be removed on reboot...

    Please, help.

  • Yoohoo! Thank you Iridium... messed remount with nolock... :blush:

    The additional overlay made lirc0 transmitting!

    And LEDs are on/off with ir-ctl. Trying to make it working end-to-end.

    Update:

    As Hias said: lirc0 and lirc1 created with 2 overlays in random order.

    I found another discussion about configuring udev rules for lirc.

    /storage/.config/udev.rules.d can keep the rules.

    However, i don't see how to keep other files like:

    /etc/lirc/lirc_options.conf

    /etc/lirc/lirc_tx_options.conf

    /etc/systemd/system/lircd-tx.service

    And how to tell LE that lirc0 now is lirc-rx?

    Edited 2 times, last by grhhm (February 1, 2020 at 6:36 PM).

  • Thank you, guys, for your patience! Your vast knowledge made my project working.

    In addition to the "Controlling LibreELEC with LG TV IR remote guide" my contribution to the forum back is:

    The guide of IR command translation with LibreELEC.

    Purpose: Make additional IR device (LED strip in this case) to be controlled from TV remote. So TV + Kodi + Additional device are controlled with one IR RC. In this case, The TV remote turns TV and LED strip on/off + navigates in Kodi.

    High level explanation: The IR signal from TV IR RC is parsed by LIRC in RasPi and passed to Kodi as key_name pressed. Kodi applies proper action per each key_name. For navigation internal Kodi actions used. For LED control additional LIRC channel used as lirc_tx. Kodi runs stateful python script which runs shell command ir-ctl.

    Steps:

    1. As Hias advised above, connect IR receiver to GPIO17, powered by 3.3V. And connect the transmitting IR LED 940nm via simple transistor amplifier to GPIO18. Expose IR receiver towards you, and IR transmitter towards the IR LED controller. Done with the hardware!

    2. As advised here with minor mods:

    Code
    mount -oremount,rw /flash
    nano /flash/config.txt
      #add these lines above section [all]
      dtoverlay=gpio-ir,gpio_pin=17
      dtoverlay=pwm-ir-tx,gpio_pin=18
      #Ctrl+X -> Y -> Enter
    
    mount -oremount,ro /flash

    3. Configure udev rules:

    Code
    nano /storage/.config/udev.rules.d/71-lirc.rules
      #add these lines
      ACTION=="add", SUBSYSTEM=="lirc", DRIVERS=="gpio_ir_recv", SYMLINK+="lirc-rx"
      ACTION=="add", SUBSYSTEM=="lirc", DRIVERS=="gpio-ir-tx", SYMLINK+="lirc-tx"
      ACTION=="add", SUBSYSTEM=="lirc", DRIVERS=="pwm-ir-tx", SYMLINK+="lirc-tx"
      #Ctrl+X -> Y -> Enter

    4. Configure LIRC options for both RX and TX channels.

    5. Create LIRC TX service:

    6. As Da Flex advised, create keymap file /storage/.kodi/userdata/keymaps/remote.xml and paste into it:

    Code
    <keymap>
     <global>
      <remote>
       <power>RunScript(/storage/toggle_led.py)</power>
      </remote>
     </global>
    </keymap>

    7. Map Power key to action in /storage/.kodi/userdata/Lircmap.xml:

    Code
    <lircmap>
    ...
    <!--           Place your RC name here as stated in lircd.conf -->
            <remote device="LG_AKB72915207">
    ...
                    <power>KEY_POWER</power>
    ...
            </remote>
    ...
    </lircmap>

    At this step I commented out all <power> actions from other devices in Lircmap: I don't want any chance that something will shut the LE off.

    8. Place the LED toggling script in /storage/toggle_led.py:

    Just in case, make the script executable: chmod a+x /storage/toggle_led.py

    How did I get the IR codes? Hias explained above :) ir-ctl -r

    9. reboot

    After reboot you might test the LED work from the script by running it manually from bash.

    That's it.