My task now is to learn how to send commands to air conditioners and other devices in the house. Initially, these devices have only IR remote control. To solve this problem, I have a Raspberry Pi and IR transceiver shield. In the article you can find configs, teams, tips and a little theory. From the software will be LIRC (Linux Infrared Remote Control) and Python.
I found LIRC with the help of Google. In the process of research, I found out that LIRC works with both transmitters and receivers of IR signals, can decode the received signal and perform some actions in connection with this. Now I do not need signal reception, but in the future it may be useful. If you mess with LIRC yourself, reading the LIRC Configuration Guide is highly recommended.
apt-get update apt-get install lirc
# /etc/modules ( ) lirc_dev lirc_rpi gpio_in_pin=18 gpio_out_pin=17
# /etc/lirc/hardware.conf ( , ) LIRCD_ARGS="--uinput --listen" LOAD_MODULES=true DRIVER="default" DEVICE="/dev/lirc0" MODULES="lirc_rpi"
# /boot/config.txt ( lirc, ) dtoverlay=lirc-rpi,gpio_in_pin=18,gpio_out_pin=17
# /etc/lirc/lirc_options.conf ( ) driver = default device = /dev/lirc0
reboot sudo /etc/init.d/lircd status
First you need to create a configuration file with data sequences for all the necessary commands. I continue to call this file lircd.conf
, but on each device itself it creates its own file my_device_name.lircd.conf
in the /etc/lirc/lircd.conf.d
directory.
The file format is described here . If you have a remote control, you can write the signals transmitted by it to a file using the irrecord utility.
/etc/init.d/lircd stop irrecord -d /dev/lirc0 ~/my_device.lircd.conf mv ~/my_device.lircd.conf /etc/lirc/lircd.conf.d/
irrecord
analyzes the sequences and tries to determine the protocol and time parameters. In some cases, irrecord
fails in the analysis, so it is possible to save the sequence as it was accepted in a raw form, there is a --force
switch for this.
But even with --force
irrecord
tries to analyze something, and may also fail. Then you can record the sequences using mode2
and create the file yourself.
mode2
prints sequentially the duration of the presence and absence of a signal, from which the transmitted data is composed. Duration is measured in microseconds (1e-6 seconds). In the raw format, the same durations are indicated in lircd.conf, starting with 'pulse' (the leading 'space' is not needed). Accordingly, there should always be an odd number of numbers (it starts and ends with the presence of a signal - 'pulse').
For automation, I made a script for recording that asks for the name of the command, runs mode2
for 5 seconds, remembers and finally prints the result in the format ready for lircd.conf (see under the spoiler).
#!/usr/bin/env python3 import io import sys import os r = """begin remote name DEVICE_NAME_CHANGE_ME flags RAW_CODES eps 30 aeps 100 gap 19037 begin raw_codes """ while True: print() print("enter the command name, or just press Enter to finish") a = sys.stdin.readline().rstrip("\n\r") if not a: break first_space = True n = 0 r += " name " + a + "\n" for line in os.popen('timeout 5s mode2 -d /dev/lirc0 2> /dev/null').read().split('\n'): words = line.split() if len(words) < 2: continue if words[0] != 'space' and words[0] != 'pulse': continue if first_space and words[0] == 'space': first_space = False continue if n % 4 == 0: r += "\n " r += words[1] + " " n = n+1 if n > 5: print ("got", n, "values, looks good") else: print ("no signal, something went wrong") r += "\n\n" r += """ end raw_codes end remote """ print() print(r) print()
irrecord --analyse
file, you can try to "recognize" it again using irrecord --analyse
. This is not always successful, do not rush to throw away the old file. My statistics are as follows: the remote control from the LG TV was easy to understand, all air conditioners and a vacuum cleaner required manual creation, the vacuum cleaner was then processed by --analyse
.
Just as an example: this is what the file for my vacuum cleaner looks like .
For its intended purpose, the LIRC should turn the received and recognized IR signal into a Linux input event. Therefore, by default, we are required to have the command names in lircd.conf from the standard list. You can see a list of valid names:
irrecord --list-namespace
Air conditioners do not fall under this pattern. The requirement for names can be turned off by adding a parameter when writing:
irrecord --disable-namespace ....
Check the receiver helps mode2
utility, which prints all visible signals.
/etc/init.d/lircd stop mode2 -d /dev/lirc0
It is easiest to check the transmission if there is another receiver and mode2
running on it. In especially hopeless cases, you can change the value at the output of the GPIO and check with a tester or oscilloscope where the signal goes. The gpio
team is part of the wiringpi package.
while sleep 1; do gpio -g toggle 17 done
You can look at the logs using journalctl
, in particular, this allows you to see errors in the configuration file:
journalctl -b 0 /usr/sbin/lircd
There is an irsend
utility for transmitting recorded commands. She can also show a list of known devices, and a list of known commands for each device. Pay attention to the "empty arguments" in the example below, they are needed there.
irsend
is a client for lircd
, so if something went wrong, look in the logs (see above).
# irsend LIST "" "" # LG_TV irsend LIST LG_TV "" # ON irsend SEND_ONCE LG_TV ON
Theoretically, there is another possibility - send commands to lircd through its socket. I did not understand.
Almost all libraries are just a kit over irsend
. The only library I found that compiles the client for the API via the socket does not work on Raspberry (another version of lircd is needed). Therefore, there is little sense in them; I can call the command myself:
import subprocess subprocess.call(["irsend", "send_once", "BEDROOM_AC", "OFF"])
I use a ready-made board, there are a lot of them on Amazon and AliExpress . You can google it like "Raspberry infrared sheild." It uses GPIO 17 for output, and GPIO 18 for input, as can be seen from the configs above.
There is a place on the board for the second (additional) LED D2, which is not installed by default. When using two LEDs, they are connected in series . Therefore, in the absence of LED D2, you must close the jumper SJ1. I was surprised to find that on all my boards the jumper was initially open. I had to modify the soldering iron.
It works: the signal is transmitted, the devices see it and react correctly to it.
Much depends on the position of the diode emitter, it must be precisely aimed at the receiver. One fixed transmitter cannot control all the devices in the room. Cloning a Raspberry Pi-based solution for each gadget is expensive, you need to either modify the emitter to "cover a larger area" or find a cheaper platform.
LIRC was originally created to convert IR signals into standard Linux events of input devices. Therefore, it is natural for him that one button is one code. For some devices (most Air conditioner) this is not so: when you click on any button, the remote control transmits a data packet containing the complete state of the device (on, operating mode, temperature, fan operation modes, time, timer, etc.). There is no way to build a multi-component package based on several parameters in LIRC, therefore, it helps as a quick tool out of the box, but then you will have to look for something else. Although for most cases, the recorded data with the usual fan settings and without exotic modes is enough.
Source: https://habr.com/ru/post/461195/