📜 ⬆️ ⬇️

Cubieboard A10. Learning to control the system from a remote control

Hello, Habr!


I decided to write an article about my experience with IR on Cubieboard.

Not so long ago, I ordered myself this wonderful device (I ordered it specifically for the future home server, and, therefore, only use the server OS on it). The choice fell on Cubian ( http://cubian.org/ ) because it’s your own bike. do not want.
')
It was supposed to deploy on the cube nginx, php5, samba, mocd and several of its services to control the relay unit.
During the study of the cube I decided to try to set up IR to receive commands from the console from the old TV tuner, I could not deploy the solution in the form of lirc, I began to look for other solutions, I did not find anything good.

I wrote my decision, which I am sharing with you now.

Initially, I wanted to get by with only bash, but I was not attracted to reread the device once a second or more / less often, why drive the processor into an empty one, heating the baby once more. Then the solution came in the direction of php, since it will still be installed.

Recently, I came across an article on Habré, my solution is close to the proposed @ ntfs1984, but not the same.
So as I am not allowed to comment, I decided to play in the sandbox.

Let's get started
Initially, after installing the system, the device is not available, since the corresponding modules are not loaded, in the case of cubieboard a10 and cubian - this is the sunxi_ir module
We check its loading by the lsmod command

I draw your attention, I execute all commands as root .
By default, the system does not load this module; for manual loading, you can use the command:
modprobe sunxi_ir 

If the module is launched successfully, modprobe will not say anything, but the cherished line will appear in the lsmod list. Also an important factor to make sure that everything worked, you need to check whether the input device appeared:

in my case it was event1
the surest way to check whether this device is to do it
 cat /dev/input/event1 | hexdump 
(Stop the process can be [Ctrl] + [C])
hexdump displays data in a “beautiful” format, plus we can find out the code of the pressed button in the same way, but you can do without it.

For each button pressed we get four lines, the first couple of lines - the button on the remote was pressed ( 0090 0001 ), the second - the button was released ( 0090 0000 ). You can get a lot of useful things from these lines, I didn’t go deep into it, but only paid attention to the button code (in the example, this is 0090 ). But I can say that 532a is the remote control code, if someone decides to tie the program to the console.
If everything is the same, go to the next step - setting autoload
 nano /etc/modules 

and add only one line at the end
sunxi_ir
This is the name of our module, which we downloaded above. An example of my modules :

Saved and left.

So, the preparations for working with IR are over, now let's move on to the most important part, this is writing a program that can read the device and perform the necessary actions.
We need a demon that will monitor the clicks, initially it was planned to follow somehow the device, and in the case of the pressed button - to perform. Immediately I will say that I did not want to create an infinite loop that would check in a second whether the button was pressed on the remote or not. I wanted to create such a program, which would work only by pressing, the rest of the time I was just dozing. As a result, the idea of ​​working with php files was born, when you can read the file bit by bit:
 #!/usr/bin/php5 <?php $dev="/dev/input/event1"; $f=fopen($dev, 'rb'); if($f){ while (!feof($f)){ $b=fread($f,32); //     64 , 32- ,  32 -  $d=bin2hex($b); // hex  $d=substr($d,18,8); //      $button=substr($d,0,4); // $key=substr($d,4); //0001  0000 switch($button){ case "0090": echo "POWER ".($key=="0001"?"down":"up")."\n"; } //  : /*if($key=="0001"){ if($button=="0090"){ //       } }else{ if($button=="0090"){ //       } } */ } } ?> 

Save the file as / tmp / tst
Let the file be executable
 chmod +x /tmp/ts 
Run, check:

Now, complicating the switch for each button, we get the processing of each button on the remote. Well and, in fact, not to display “empty” words, but to assign the necessary action.
By slightly complicating the program, we get (/ usr / sbin / mylirc):
 #!/usr/bin/php5 <?php function AccessFile($file,$access){ if(file_exists($file)){ // ! if($f=@fopen($file,$access)){fclose($f);}else{exit("not have access to $file\n");} }else{ return "$file not found (may not have access to the folder)\n"; } } $dev=""; $log=0; if(count($argv)==1){ exit("Use ".dirname( __FILE__ )."/".basename($_SERVER['SCRIPT_FILENAME'])." --device=device [--log=logfile]\n"); }else{ for($i=1;$i<count($argv);$i++){ $cmd=explode("=",$argv[$i]); switch($cmd[0]){ case "--device": $dev=$cmd[1]; echo AccessFile($cmd[1],"rb"); break; case "--log": $log=$cmd[1]; echo AccessFile($cmd[1],"w"); break; } } } if($dev==""){ exit("Use ".dirname( __FILE__ )."/".basename($_SERVER['SCRIPT_FILENAME'])." --device=device [--log=logfile]\n"); } include("/etc/mylirc/buttom_avermedia.php"); if($log){exec("echo `date` > $log");} $f=fopen($dev, 'rb'); if($f){ while (!feof($f)){ $b=fread($f,32); $d=bin2hex($b); $d=substr($d,18,8); $button =substr($d,0,4); $key =substr($d,4); $l=0; for($i=0;$i<count($command);$i++){ if(trim($button)==trim($command[$i][1]) && trim($key)==trim($command[$i][2])){ $l=1; if(trim($command[$i][3])!=""){ //  exec($command[$i][3]." > /dev/null 2>/dev/null &"); }else{ //  ,     : if($log){exec("echo ".$command[$i][0]." ".$command[$i][1]." cmd=null >> $log");}// } } } if(!$l){ //  ,      : if($log){exec("echo not buttom $button $key >> $log");}// } } } ?> 

The program writes logs if the corresponding parameter (- log) was passed and swears if the parameter --device is not passed
Settings file (/etc/mylirc/buttom_avermedia.php):
 <?php $command=array(); //: //, , ,  $command[]=array("POWER", "00ff","0001","led green 1"); $command[]=array("POWER", "00ff","0000",""); $command[]=array("NUMB 1", "0005","0001","led green 0"); $command[]=array("NUMB 1", "0005","0000",""); //   ?> 

The program led green 1 (0) (this is my script on bash, which I put in / usr / sbin /)
turned on and off a light bulb on a cube (green in the example), but you can execute any console command you wish. Execution goes from root, accordingly, it will need to take this into account and lower privileges to the desired user if necessary.
The program must be started at system startup as a daemon, so that you can start / stop / restart / check the operation of the program (/ usr / sbin / mylirc), which is based on the /etc/init.d/ssh script, rewritten and saved as /etc/init.d/01_lirc:
 #!/bin/sh ### BEGIN INIT INFO # Provides: 01_lirc # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: # Short-Description: LIRC on PHP server ### END INIT INFO set -e # /etc/init.d/01_lirc: start and stop the "LIRC on PHP" daemon test -x /usr/sbin/mylirc || exit 0 ( /usr/sbin/mylirc -\? 2>&1 | grep -q mylirc ) 2>/dev/null || exit 0 umask 022 . /lib/lsb/init-functions run_by_init() { ([ "$previous" ] && [ "$runlevel" ]) || [ "$runlevel" = S ] } export PATH="${PATH:+$PATH:}/usr/sbin:/sbin" case "$1" in start) log_daemon_msg "Starting LIRC on PHP deamon" "mylirc" || true if start-stop-daemon --quiet --oknodo --exec /usr/sbin/mylirc --background --start -- --device=/dev/input/event1 --log=/var/log/log_lirc; then log_end_msg 0 || true else log_end_msg 1 || true fi ;; stop) log_daemon_msg "Stopping LIRC on PHP deamon" "mylirc" || true if start-stop-daemon --stop --oknodo --name mylirc --retry=KILL/1; then log_end_msg 0 || true else log_end_msg 1 || true fi ;; restart) log_daemon_msg "Restarting LIRC on PHP deamon" "mylirc" || true start-stop-daemon --stop --oknodo --name mylirc --retry=KILL/1; if start-stop-daemon --quiet --oknodo --exec /usr/sbin/mylirc --background --start -- --device=/dev/input/event1 --log=/var/log/log_lirc; then log_end_msg 0 || true else log_end_msg 1 || true fi ;; status) ID=`(lsof | grep mylirc | grep /dev/ 2>&1) 1>/dev/null || echo 0;` if [ "$ID" = "0" ]; then echo "LIRC on PHP deamon \033[37;1;41m shutdown \033[0m"; else echo "LIRC on PHP deamon \033[37;1;42m started \033[0m"; fi tput sgr0 ;; *) log_action_msg "Usage: /etc/init.d/mylirc {start|stop|restart|status}" || true exit 1 esac exit 0 


Now you can check the operation of the daemon with the following commands:
 /etc/init.d/01_lirc start 
Stop:
 /etc/init.d/01_lirc stop 
Status:
 /etc/init.d/01_lirc status 

and similarly restart
To add a daemon to autoload, do the following:
 cd /etc/init.d/ update-rc.d 01_lirc defaults 

Remove from startup:
 cd /etc/init.d/ update-rc.d 01_lirc remove 


PS I skated the program, it has been stable for two weeks. Suggestions and comments are welcome.

Pss
edwardoid suggested creating a script that would generate a settings file (similar to /etc/mylirc/buttom_avermedia.php),
here is the result
 #!/usr/bin/php5 <?php declare(ticks = 1); pcntl_signal(SIGINT, "signal_handler"); function signal_handler($signal){ global $f,$out; if($signal==SIGINT){ fclose($f); exec('echo ?\> >> '.$out); exit("\n$out create!\n"); } } function AccessFile($file,$access){ if(file_exists($file)){ // ! if($f=@fopen($file,$access)){fclose($f);}else{exit("not have access to $file\n");} }else{ return "$file not found (may not have access to the folder)\n"; } } $dev=""; $out=""; if(count($argv)==1){ exit("Use ".dirname( __FILE__ )."/".basename($_SERVER['SCRIPT_FILENAME'])." --device=device --out=config.php\n"); }else{ for($i=1;$i<count($argv);$i++){ $cmd=explode("=",$argv[$i]); switch($cmd[0]){ case "--device": $dev=$cmd[1]; echo AccessFile($cmd[1],"rb"); break; case "--out": $out=$cmd[1]; echo AccessFile($cmd[1],"w"); break; } } } if(($dev=="")||($out=="")){ exit("Use ".dirname( __FILE__ )."/".basename($_SERVER['SCRIPT_FILENAME'])." --device=device --out=config.php\n"); } echo "press [Ctrl]+[C] to stop and press any button on the remote\n"; $f=fopen($dev, 'rb'); if($f){ exec('echo \<?php > '.$out); exec('echo " \$command=array();" >> '.$out); $i=0; $j=1; while (!feof($f)){ $b=fread($f,32); $b=bin2hex($b); $b=substr($b,18,8); $button =substr($b,0,4); $key =substr($b,4); $i=$i+($j++)%2; //  $but='$command[]=array("'.$i.'", "'.$button.'","'.$key.'",""); // #'.$i; exec('echo \' '.$but.'\' >> '.$out); echo $but."\n"; //   ,  ,       } } ?> 

Thanks for the idea!

Source: https://habr.com/ru/post/216615/


All Articles