Raspberry Pi & GNU/Linux: montando un sistema embebido con una interfaz web

2020-03-22 - Categorías: GNU/Linux / PHP
Raspberry Pi, montando sistema embebido con una web..

Ya hace tiempo que no escribo con tantos problemas que está habiendo con el COVID19.. así que aquí estoy de nuevo tratando de no perder las buenas costumbres. Aquí que traigo un codekata para la Raspberry Pi. Se trata de un tutorial para montar un sistema embebido con una interfaz web en una Raspberry Pi.

Imaginemos por ejemplo que la Raspberry maneja una serie de relés que encienden y apagan dispositivos, se podrían manejar desde una web. O imaginemos quizá que esta Raspberry te pudiera hacer una encuesta desde una tableta, y en función a tus respuestas, iluminar el café, chocolate o perfume de la tienda que más te va a gustar. O quizá quieres montar una API REST para interactuar con varias Raspberry que tenemos conectadas en la red de tu casa o local, para hacer algo más complejo. Así se podría coordinar las tareas en red que le corresponda a cada Raspberry, desde alguna unidad central. Si te parece interesante, sigue leyendo que este es tu post.. 😉

Empezando, qué necesitamos, y porqué de una web

Para este codekata se necesita una Raspberry Pi, tenerle instalado el sistema operativo oficial llamado Raspbian, o uno de los compatibles derivados de la distribución Debian o un GNU/Linux similar.

El montar el sistema completo con una interfaz web es la forma más estándar a día de hoy, que podemos elegir para un dispositivo de este estilo. Es decir, poniendo una interfaz web no necesitas de una aplicación de móvil, ni de un programa de Windows, Mac, GNU/Linux.. especial, que sea capaz de interactuar con tu sistema. El proyecto final funcionará por completo sin necesitar instalar ningún programa. Esto es así porque, a día de hoy, desde cualquier dispositivo tenemos navegadores. Creo que está de más enrollarme con más explicaciones. Así que vamos con el granito de arena en todo esto de la informática..

Manos a la obra, primer paso, instalando Apache

Lo siguiente será entonces conectar a la Raspberry Pi para instalar Apache desde un terminal, o desde la misma Raspberry abrimos un terminal y hacemos:

sudo apt install apache2

..si todo ha ido bien, después de la instalación debemos de poder ver la siguiente pantalla si accedemos a la dirección IP donde está la Raspberry. En mi caso la tengo en la IP 192.168.1.2, con lo que se puede ver en mi caso en http://192.168.1.2/ que Apache funciona:

Apache recién instalado en la Raspberry Pi.

Para este codekata he elegido PHP por ser el lenguaje más usado en el mundo de las webs.

Instalando PHP en la Raspberry Pi

Ahora tenemos que ir de nuevo a un terminal en la Raspberry Pi. A fecha de hoy la última versión de PHP en producción es la 7.4, así que para instalarla tenemos que seguir los siguientes pasos:

sudo apt -y install lsb-release apt-transport-https ca-certificates
sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php.list
sudo apt-get update

Después de haber configurado el último repositorio, para poder disfrutar de PHP 7.4, podemos instalar todos los módulos que se necesiten según el proyecto. Por ejemplo:

sudo apt -y install php7.4-curl php7.4-fpm php7.4-gd php7.4-imap php7.4-intl php7.4-json php7.4-mbstring php7.4-mysql php7.4-opcache php7.4-soap php7.4-xml php7.4-xmlrpc php7.4-zip

Ya tenemos con esto los principales programas para correr webs en la Raspberry, vamos ahora a enlazarlos.

Configurando PHP y Apache

Es práctica recomendada utilizar Apache Events y PHP FPM para conseguir el mejor rendimiento de la web. Para hacer esto hay que hacer una serie de ajustes. Comenzamos renombrando el fichero:

/var/www/html/index.html

..por..

/var/www/html/index.html.bak

..y creamos un fichero PHP para luego comprobar que todo funciona, que se llame:

/var/www/html/index.php

..y con el contenido siguiente:

<?php
phpinfo();

Ahora toca configurar Apache para que funcione con PHP y FPM. Podemos comprobar si tenemos Apache con Events ya activado usando:

sudo apache2ctl -M

Si no está el módulo activado, lo podemos activar haciendo lo siguiente. Además, necesitaremos también otros módulos, todo esto junto se puede configurar así:

sudo a2enmod mpm_event
sudo a2enmod proxy proxy_http proxy_fcgi
sudo service apache2 restart

Ahora toca configurar el host del fichero /etc/apache2/sites-enabled/000-default.conf para hacer que Apache ejecute los ficheros PHP con el servicio llamado php7.4-fpm. Le podemos poner el siguiente código:

<VirtualHost *:80>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        #ServerName www.example.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf

        <FilesMatch \.php$>
            # Apache 2.4.10+ can proxy to unix socket
            SetHandler "proxy:unix:/var/run/php/php7.4-fpm.sock|fcgi://localhost/"
        </FilesMatch>
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

Sólo ha hecho falta añadir la directiva de manejo de los ficheros PHP mediante el servicio del sistema que corre a la escucha en el puerto UNIX /var/run/php/php7.4-fpm.sock. Ahora si todo ha ido bien, ya podemos ir al navegador y veremos que tenemos la Raspberry corriendo Apache y PHP FPM correctamente. Debemos de ver algo parecido a lo siguiente:

Raspberry Pi corriendo Apache y PHP 7.4 con FPM.

Muy importante para tener el máximo rendimiento del sistema que PHP corra independiente. Esto lo comprobamos en la configuración Server API que tiene que ser FPM/FastCGI. Otras cosas que quedan pendientes son el tunear las configuraciones de Apache y PHP FPM, material para otro post 🙄

Instalando una base de datos

A partir de aquí ya tenemos para montar la web con PHP. Si queremos usar una base de datos podríamos instalar por ejemplo Mariadb haciendo lo siguiente:

sudo apt install mariadb-server

Otra base de datos con consume muy pocos recursos, y de muy alto rendimiento es PostgreSQL. Muy interesante entonces para usar en un PC de pocos recursos como la Raspberry Pi. La podemos instalar haciendo lo siguiente:

sudo apt install postgresql

En el caso de PostgresSQL y PHP necesitaríamos habilitar el módulo de PHP para poder luego programar la conexión haciendo lo siguiente:

sudo apt install php7.4-pgsql

La base de datos se sale un poco del tema principal, así que sigamos para terminar con unos casos de uso. Sólo queda el probar el usode los pines GPIO, que son lo especial de tener una Raspberry.

Probando desde PHP los pines GPIO

Para terminar, queda el ver cómo interactuar con lo más especial que tiene la Raspberry Pi, los pines GPIO. Tenemos varias formas de realizar acciones sobre ellos, sea cual se el lenguaje de programación que queramos usar. Ya que la interfaz web en este post está hecha en PHP, sigamos en PHP. Podemos entonces usar el sistema de ficheros para hacer un pequeño ejemplo de poner un pin a 1 y a 0. La misma idea nos serviría para lanzar programas en Python o Java desde PHP. Incluso si la web se sirviera a través de Apache Tomcat o con Apache con mod_wsgi, el esquema general seguiría siendo el mismo, pero variando un poco las configuraciones. De nuevo material para otro post..

Vamos entonces a modificar el fichero /var/www/html/index.php y ponemos un par de botones. Vamos a probarlo para que realicen las acciones de poner un pin a 1 o a 0. Arrancamos editando el index.php así:

<html>
<body>
<a href="put1inGpio.php">Put 1</a>
<a href="put0inGpio.php">Put 0</a>
</body>
</html>

Si recargamos la página veremos algo como lo siguiente en el navegador:

Vamos a darle un poco de estilo al HTML, para que se vea mejor desde dispositivos como móviles y tablets. Podemos editar el index.php a algo tal que así:

<html>
<head><title>Using GPIO</title></head>
<body>
<style>
a {
    width: 100%;
    font-size: 400%;
    text-align: center;
    display: block;
    background-color: #808080;
    border-radius: 20px;
    color: white;
    text-decoration: none;
    font-weight: bold;
}
</style>
<a href="put1inGpio.php">Put 1</a><br>
<a href="put0inGpio.php">Put 0</a>
</body>
</html>

..con esto se verán ahora los botones tal que así:

Lo siguiente es el código PHP para el fichero put1inGpio.php. En mi caso tengo un octo relé, y el primer relé corresponde al pin 12, con lo que el primer fichero queda tal que así:

<?php
system("echo 12 > /sys/class/gpio/export");
usleep(0.2*1000000);
system("echo out > /sys/class/gpio/gpio12/direction");
system("echo 1 > /sys/class/gpio/gpio12/value");
header('Location: http://192.168.1.2/');

..y el segundo fichero put0inGpio.sh quedó tal que así:

<?php
system("echo 12 > /sys/class/gpio/export");
usleep(0.2*1000000);
system("echo out > /sys/class/gpio/gpio12/direction");
system("echo 0 > /sys/class/gpio/gpio12/value");
header('Location: http://192.168.1.2/');

Los dos scripts son prácticamente iguales. Se podrían refactorizar en uno sólo. O en el mismo index.php, esto ya dependerá de lo que estés construyendo. Sólo queda la última cosa..

Configurando los permisos de usuario para manejar los GPIO desde Apache y PHP

Quedará darle permisos a los ficheros y añadir al grupo de usuarios de GPIO al usuario que corre la web para que pueda alterar los valores del GPIO. Esto se consigue añadiendo al grupo GPIO, a cualquier usuario que lo necesite. En este caso, www-data es el usuario de Apache y PHP-FPM, con lo que haciendo lo siguiente queda resuelto:

sudo chown -R www-data:www-data /var/www
sudo usermod -aG gpio www-data
sudo service apache2 restart
sudo service php7.4-fpm

Ahora sí que sí. Si todo ha ido bien en el code-kata, ya podemos desde una interfaz web, desde cualquier dispositivo con un navegador, manejar los GPIO de la Raspberry Pi. De aquí en adelante es cuestión de ponerle imaginación 😜 y a jugar con los códigos fuentes!

Terminando, enlaces con más información

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

 

© 2020 JnjSite.com - MIT license

Sitio hecho con WordPress, diseño y programación del tema por Jnj.