Posted in Python

Send Infrared (IR) remote signal with Python

Programmatically send IR remote signals using Python and Raspberry Pi

In today's connected world, we find ourselves surrounded by countless devices, each with its own remote control. Wouldn't it be amazing if we could harness the power to control these devices ourselves, using just a single tool? Well, with the magic of Python and Raspberry Pi, the ability to send and automate Infrared (IR) remote signals, becomes a reality.

In our increasingly digitized lives, Python, Raspberry Pi—provides a gateway to unlocking the potential of IR remote control. By leveraging their capabilities, we can tap into the fascinating world of IR communication, enabling us to interact with a wide range of devices such as TVs, air conditioners, audio systems, and more.

Prepare Raspberry Pi

First of all, we need to prepare the hardware and record IR codes in case we need them. I have already discussed about them here. You need to have:

Now, in our Raspberry Pi terminal, We need to modify boot configuration to enable IR transmission, to do so edit the boot config file by running:

sudo nano /boot/config.txt

There, find these lines:

#dtoverlay=gpio-ir,gpio_pin=17
#dtoverlay=gpio-ir-tx,gpio_pin=18

And uncomment only those lines to enable IR transmission:

dtoverlay=gpio-ir,gpio_pin=17
dtoverlay=gpio-ir-tx,gpio_pin=18

Now restart the Raspberry Pi by running sudo reboot.

Install LIRC module

From your Raspberry Pi terminal, install lirc

sudo apt update
sudo apt install lirc -y

Verify installation by checking lirc version, in my case it’s version 0.10.1 :

$ lircd --version
lircd 0.10.1

Now, we need to configure the lirc module. Open the options file in nano

sudo nano /etc/lirc/lirc_options.conf

and change the value of device to /dev/lirc0 and driver to default :

driver          = default
device          = /dev/lirc0

Now reboot the system by running sudo reboot and after rebooting, check whether the LIRC daemon is running or not.

sudo /etc/init.d/lircd status
 lircd.service - Flexible IR remote input/output application support
     Loaded: loaded (/lib/systemd/system/lircd.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2023-05-18 14:43:25 +06; 2 days ago
TriggeredBy:  lircd.socket
       Docs: man:lircd(8)
             <http://lirc.org/html/configure.html>
   Main PID: 520 (lircd)
      Tasks: 2 (limit: 779)
        CPU: 139ms
     CGroup: /system.slice/lircd.service
             └─520 /usr/sbin/lircd --nodaemon

Output of sudo /etc/init.d/lircd status

If it’s running, you will see **active (running)** mentioned in the terminal’s output.

Python time!

You may create a virtualenv for this project or install lirc globally. Let's install lirc for python:

pip install lirc

Now, make a python file, say smart_ir.py. Import lirc there and initialize LIRC Client :

import lirc

client = lirc.Client()

print(client.version())

If you see the version name printed, then everything is going well.

Now, get the list of remotes available in your system by running:

client.list_remotes()

Example Output: ['LG_TV', 'PANASONIC_AC']

You can also get a list of available keys/buttons for a remote by running:

client.list_remote_keys('LG_TV')

TV_REMOTE is your remote name. Example Output: ['POWER_ON','VOL_UP']

Now, to send IR signals to our device, we can call send_once(remote: str, key: str, repeat_count: int = 0) method where remote is the remote name, key is the key/button name, reapeat_count is the number of times the signal will be sent (default is 0; for 0, signal will be sent once, for 1, signal will be sent twice and so on).

We want to send POWER_ON signal for LG_TV once:

client.send_once('LG_TV', 'POWER_ON', 0)

As, we are talking with hardware it's always better to wrap our code with try except for unexpected exceptions.

from lirc.exceptions import LircdCommandFailure

try:
    client.send_once('LG_TV', 'POWER_ON', 0)
except LircdCommandFailure as e:
    print(e)

Finally, don't forget to close the connection by client.close().

That's it!

You can find the detail API specification here.