# Raspberry Pi

El objetivo de este curso es contaros qué es una Raspberry Pi, qué necesita para funcionar y algunos usos que podéis darle. Si además de realizar el curso consigo que la uséis me sentiré plenamente satisfecho.

# 1 - Introducción

Bienvenido/a al curso. En este primer capítulo vamos a hablar qué es una Raspberry Pi y sus características principales. ¡Espero que os guste!

# 1.1 ¿Qué es?

<p class="callout info">Lo primero que quiero hacer en este curso es disculparme con el lector/a de un perfil más técnico pues algunas de las cuestiones que voy a tratar las voy a enfocar con la idea de facilitar la asimilación de los diferentes conceptos tratados aún a costa de no ser 100% exacto en alguna cuestión.</p>

Una Raspberry Pi es un ordenador completo, pequeño y de un coste bajo. En sus reducidas dimensiones integra una [CPU](https://es.wikipedia.org/wiki/Unidad_central_de_procesamiento), una [GPU](https://es.wikipedia.org/wiki/Unidad_de_procesamiento_gr%C3%A1fico), memoria RAM, conectores USB, Bluetooth, Wifi, tarjeta de red alámbrica, salida de audio y vídeo y diferentes pines para conectar otros dispositivos.

Su aspecto es el siguiente:

[![Raspberry_Pi_4_Model_B_-_Side.jpg](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/raspberry-pi-4-model-b-side.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-02/raspberry-pi-4-model-b-side.jpg)

*Michael H. („Laserlicht“) / Wikimedia Commons / CC BY-SA 4.0*

Si bien he dicho que se trata de un ordenador completo verás en la propia imagen que no cuenta con monitor, teclado ni ratón que son los periféricos a los que estamos acostumbrados. Estos periféricos pueden ser conectados a la Raspberry Pi igual que a cualquier torre de ordenador. Puede que eches en falta también una fuente de alimentación y/o batería o un disco duro ¡no te preocupes! también está previsto. La Raspberry Pi se alimenta a través de un cargador externo similar al de nuestros teléfonos móvil. Este dispositivo y otros adicionales los trataremos en el [capítulo 1.5](https://libros.catedu.es/books/raspberry-pi/page/15-gadgets-adicionales "1.6 Gadgets adicionales") En cuanto al disco duro la Raspberry Pi está pensada para funcionar con una tarjeta micro SD o SD, en función del modelo, aunque también podremos conectarle un disco duro externo en alguno de sus conectores USB. En cuanto a sistemas operativos, la Raspberry Pi fue diseñada para ser utilizada con software libre pero en la actualidad también existe la posibilidad de utilizar la Raspberry Pi con sistemas operativos Windows.

En la actualidad, como veremos en el [capítulo 1.4](https://libros.catedu.es/books/raspberry-pi/page/14-modelos "1.4 Modelos"), coexisten diferentes modelos de Raspberry Pi a la venta además de todos aquellos modelos descontinuados.

Si quisiéramos dar una definición mas correcta a la facilitada en el primer párrafo realmente diríamos que una Raspberry Pi es una familia de ordenadores y [microcontroladores](https://es.wikipedia.org/wiki/Microcontrolador) y que la misma cuenta con diferentes modelos. La ventaja de la Raspberry Pi frente a otros dispositivos similares radica en sus dimensiones, consumo y bajo coste además de la gran comunidad con que cuenta y que comparte sus diferentes logros y desarrollos.

A continuación os facilito un cálculo del consumo de la Raspberry Pi modelo 2B:

> El bajo consumo de la Raspberry Pi permite dejarla conectada permanentemente con un coste mínimo. La Raspberry Pi consume 700 mA bajo 5 voltios, es decir 3,5 W. Durante un año, el consumo es de 3,5 W x 24 h x 365 d = 30.660 Wh, es decir, alrededor de 31 kWh. El kWh cuesta una media de 13 céntimos de euro y el almacenamiento de su servidor web sería de 4 euros/año, aproximadamente.
> 
> *https://www.ediciones-eni.com/open/mediabook.aspx?idR=e16c034bc59d2c89f5c47aa03615d7f9*

Si miramos la Raspberry Pi desde la parte superior vemos de modo mas claro los diferentes componentes que forman el ordenador:

[![rasp_esquema.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/rasp-esquema.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/rasp-esquema.png)

*Imagen obtenida de https://omniretro.com/tecnologia/raspberry-pi-4-especificaciones-caracteristicas/*

Muchos de los componentes que aparecen en el esquema anterior los veremos en apartados posteriores del curso

# 1.2 Software libre y Hardware libre

Con la aparición de los primeros modelos de Raspberry Pi se popularizó el concepto de **hardware libre** el cual, a diferencia del concepto de **software libre**, no era muy conocido. Bajo esta filosofía y junto a las ventajas antes mencionadas en capítulos anteriores la Raspberry Pi se popularizó si bien es cierto que existe cierta controversia en relación a si la Raspberry Pi debe considerarse hardware libre o no. En relación a esta controversia en la Wikipedia podemos leer:

> Aunque no se indica expresamente si es hardware libre o con derechos de marca, en su web oficial explican que disponen de contratos de distribución y venta con dos empresas, pero al mismo tiempo cualquiera puede convertirse en revendedor o redistribuidor de las tarjetas Raspberry Pi\], por lo que da a entender que es un producto con propiedad registrada, manteniendo el control de la plataforma, pero permitiendo su uso libre tanto a nivel educativo como particular.
> 
> *https://es.wikipedia.org/wiki/Raspberry\_Pi*

Veamos ahora qué son el hardware libre y el software libre.

## Software libre

Dado que ya existen definiciones muy precisas de qué es el software libre voy a citar una ya existente

> **El software libre es un software cuyo código fuente puede ser estudiado, modificado, y utilizado libremente con cualquier finalidad y redistribuido con cambios o mejoras sobre él**.​ Su definición está asociada al nacimiento del movimiento de software libre, encabezado por el activista y experto informático estadounidense Richard Stallman y la fundación que presidía en 1985,2​ la [Free Software Foundation](https://www.fsf.org/), una organización sin ánimo de lucro que pone la libertad del usuario informático como propósito ético fundamental.
> 
> **Un software es libre si otorga a los usuarios de manera adecuada las denominadas cuatro libertades: libertad de usar, estudiar, distribuir y mejorar**, de lo contrario no se trata de software libre. Existen diversos esquemas de distribución que no son libres, y si bien podemos distinguirlos sobre la base de cuánto les falta para llegar a ser libres, su uso bien puede ser considerado contrario a la ética en todos los casos por igual.
> 
> *https://es.wikipedia.org/wiki/Software\_libre*

En relación con el software libre, *free software* en inglés, existe la falsa creencia de que tiene que se gratis. Esta creencia puede deberse a que el término [*free*](https://www.wordreference.com/es/translation.asp?tranword=free) puede traducirse por libre o por gratis pero lo cierto es que el software libre no tiene por qué ser gratuito aunque lo es en su gran mayoría.

En contraposición al software libre nos encontramos el [software propietario](https://es.wikipedia.org/wiki/Software_propietario) también conocido como software privativo.

Vamos a ver algunos ejemplos:

<table border="1" id="bkmrk-tipo-software-libre-" style="border-collapse: collapse; width: 100%; height: 179.271px;"><colgroup><col style="width: 33.3333%;"></col><col style="width: 33.3333%;"></col><col style="width: 33.3333%;"></col></colgroup><tbody><tr style="height: 29.8785px;"><td class="align-center" style="height: 29.8785px;">**Tipo**</td><td class="align-center" style="height: 29.8785px;">**Software libre**</td><td class="align-center" style="height: 29.8785px;">**Software propietario**</td></tr><tr style="height: 29.8785px;"><td style="height: 29.8785px;">Sistemas operativos</td><td style="height: 29.8785px;">Vitalinux, Debian, Ubuntu, Fedora</td><td style="height: 29.8785px;">Windows, MacOS</td></tr><tr style="height: 29.8785px;"><td style="height: 29.8785px;">Ofimática</td><td style="height: 29.8785px;">Libre Office, Open Office</td><td style="height: 29.8785px;">Microsoft Office</td></tr><tr style="height: 29.8785px;"><td style="height: 29.8785px;">Multimedia</td><td style="height: 29.8785px;">VLC, GIMP, Audacity</td><td style="height: 29.8785px;">Microsoft Media Player, Photoshop</td></tr><tr style="height: 29.8785px;"><td style="height: 29.8785px;">Navegadores</td><td style="height: 29.8785px;">Firefox, Chromium</td><td style="height: 29.8785px;">Edge, Chrome</td></tr><tr style="height: 29.8785px;"><td style="height: 29.8785px;">Edición de vídeo</td><td style="height: 29.8785px;">Blender</td><td style="height: 29.8785px;">Corel Draw, Premiere</td></tr><tr><td>Diseño 3D</td><td>FreeCad</td><td>Autocad, Rhinoceros, Solid Works</td></tr></tbody></table>

## Hardware libre

De nuevo vamos a partir de una definición ya existente

> Se llama hardware libre(...) a aquellos dispositivos de hardware cuyas especificaciones y diagramas esquemáticos son de acceso público, ya sea bajo algún tipo de pago, o de forma gratuita. La filosofía del software libre es aplicable a la del hardware libre, y por eso forma parte de la cultura libre.
> 
> *https://es.wikipedia.org/wiki/Hardware\_libre*

En este apartado hay que mencionar otro dispositivo muy popular: [Arduino](https://www.arduino.cc/).

## Ventajas de la cultura libre

Pese a que en determinados ámbitos se considera que la cultura libre es para idealistas, gente que tiene trabajos remunerados y que esto es un entretenimiento lo cierto es que sin la cultura libre el mundo actual no sería tal y como lo conocemos y el ejemplo mas claro está en internet. La gran mayoría de páginas webs servidas en la actualidad lo son por unos [servidores web](https://es.wikipedia.org/wiki/Servidor_web) que son en su mayoría software libre. Lo mismo ocurre con el contenido que estás visualizando que no es mas que un lenguaje de marcado (HTML), maquetado con una hoja de estilos (CSS) y en la que se añaden unas acciones a través de unos scripts (JavaScript) renderizado por un navegador web (Firefox en mi caso). El hecho de que dichos lenguajes, protocolos y programas pertenezcan al mundo de la cultura libre permite que cualquier persona en cualquier lugar pueda ver como algo está hecho para aprender de ello y poder modificarlo. Si, como yo, eres docente estoy seguro que coincidirás conmigo en el potencial que esto tiene.

En general debemos huir de herramientas que no nos permitan tener a nuestra disposición el resultado de nuestro trabajo o que nos obliga a utilizar un determinado programa o pagar una determinada suscripción para acceder o modificar esos datos. Si utilizamos o contratamos los servicios de este tipo de empresas nuestros datos quedarán secuestrados y con ello el fruto de nuestro trabajo.

En el caso que nos ocupa, la Raspberry Pi, el hecho de tener a nuestra disposición soluciones de todo tipo que cualquier persona ha hecho y ha puesto a nuestra disposición ya no solo para utilizarlas sino también para ver como ha hecho algo tanto a nivel hardware como software nos abre todo un abanico de posibilidades. Por ello, en la siguiente página, la 1.3 vamos a hablar brevemente de la comunidad que hay detrás de la Raspberry Pi.

# 1.3 Documentación y comunidad

La página web oficial de Raspberry Pi es [https://www.raspberrypi.com/](https://www.raspberrypi.com/) y su logotipo es una frambuesa. El mismo lo encontramos serigrafiado en las distintas placas Raspberry Pi.

[![Raspberry_Pi_Logo.svg.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/raspberry-pi-logo-svg.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/raspberry-pi-logo-svg.png)

*https://upload.wikimedia.org/wikipedia/en/thumb/c/cb/Raspberry\_Pi\_Logo.svg/100px-Raspberry\_Pi\_Logo.svg.png*

Dentro de la página web oficial tenemos la sección de documentación [https://www.raspberrypi.com/documentation/](https://www.raspberrypi.com/documentation/) dónde nos encontraremos la información en inglés y clasificada en 3 apartados:

- Ordenadores
- Accesorios
- Microcontroladores

También aquí encontraremos un enlace a los foros oficiales de Raspberry Pi [https://forums.raspberrypi.com/](https://forums.raspberrypi.com/) aunque lo cierto es que en el motor de búsqueda que utilicemos si buscamos qué queremos hacer y a dicha búsqueda le añadimos la cadena "Raspberry Pi" encontraremos tutoriales sobre como hacer aquello que nos interesa.

Aunque la documentación oficial y las webs que os enlazo están en inglés existe muchísima información en castellano además de vídeos de youtube, canales en Reddit o grupos de Telegram dedicados al universo Raspberry Pi. Quizás este foro [https://www.fororaspberry.es/](https://www.fororaspberry.es/) sea el más popular de hablar hispana. La comunidad de reddit de Raspberry Pi es también muy popular [https://www.reddit.com/r/raspberry\_pi](https://www.reddit.com/r/raspberry_pi) (en inglés).

# 1.4 Modelos

A continuación vamos a ver algunos de los modelos de Raspberry Pi que se han lanzando al mercado. En el momento de redactar este material (febrero de 2023) el último modelo de Raspberry Pi es el modelo 4 B que puede ser adquirido en 3 variaciones distintas en función de la memoria RAM que estimemos vamos a necesitar. Lo relativo a otro tipo de gadgets lo veremos en el [capítulo 1.5](https://libros.catedu.es/books/raspberry-pi/page/15-gadgets-adicionales "1.5 Gadgets adicionales").

Por una parte voy a comparar los ordenadores y por otro lado los microcontroladores. Como punto de partida utilizamores esta tabla

![rasp_comparativa.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/rasp-comparativa.png)

*Imagen obtenida de https://aprendiendoarduino.wordpress.com/tag/modelos-raspberry-pi/*

## Ordenadores

En este apartado tenemos:

<table border="1" id="bkmrk-modelo-especificacio" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 36.9664%;"></col><col style="width: 63.0336%;"></col></colgroup><tbody><tr><td class="align-center">**Modelo**</td><td class="align-center">**Especificaciones**</td></tr><tr><td>Raspberry Pi 1 Model B+</td><td>[https://www.raspberrypi.com/products/raspberry-pi-1-model-b-plus/](https://www.raspberrypi.com/products/raspberry-pi-1-model-b-plus/ "https://www.raspberrypi.com/products/raspberry-pi-1-model-b-plus/")</td></tr><tr><td>Raspberry Pi 1 Model A+  
</td><td>[https://www.raspberrypi.com/products/raspberry-pi-1-model-a-plus/](https://www.raspberrypi.com/products/raspberry-pi-1-model-a-plus/ "https://www.raspberrypi.com/products/raspberry-pi-1-model-a-plus/")</td></tr><tr><td>Raspberry Pi 2 Model B  
</td><td>[https://www.raspberrypi.com/products/raspberry-pi-2-model-b/](https://www.raspberrypi.com/products/raspberry-pi-2-model-b/ "https://www.raspberrypi.com/products/raspberry-pi-2-model-b/")</td></tr><tr><td>Raspberry Pi 3 Model B  
</td><td>[https://www.raspberrypi.com/products/raspberry-pi-3-model-b/](https://www.raspberrypi.com/products/raspberry-pi-3-model-b/ "https://www.raspberrypi.com/products/raspberry-pi-3-model-b/")</td></tr><tr><td>Raspberry Pi 3 Model B+  
</td><td>[https://www.raspberrypi.com/products/raspberry-pi-3-model-b-plus/](https://www.raspberrypi.com/products/raspberry-pi-3-model-b-plus/ "https://www.raspberrypi.com/products/raspberry-pi-3-model-b-plus/")</td></tr><tr><td>Raspberry Pi 3 Model A+  
</td><td>[https://www.raspberrypi.com/products/raspberry-pi-3-model-a-plus/](https://www.raspberrypi.com/products/raspberry-pi-3-model-a-plus/ "https://www.raspberrypi.com/products/raspberry-pi-3-model-a-plus/")</td></tr><tr><td>Raspberry Pi 4 Model B  
</td><td>[https://www.raspberrypi.com/products/raspberry-pi-4-model-b/](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/ "https://www.raspberrypi.com/products/raspberry-pi-4-model-b/")</td></tr><tr><td>Raspberry Pi 400 unit  
</td><td>[https://www.raspberrypi.com/products/raspberry-pi-400-unit/](https://www.raspberrypi.com/products/raspberry-pi-400-unit/ "https://www.raspberrypi.com/products/raspberry-pi-400-unit/")</td></tr></tbody></table>

En la tabla anterior los primeros 7 modelos listados son todos bastante similares en cuanto a su apariencia pero creo que merece la pena detenerse en el último modelo listado que tiene el siguiente aspecto

![rpi_400.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/rpi-400.png)*Imagen obtenida de https://www.raspberrypi.com/products/raspberry-pi-400-unit/*

Como podemos apreciar tiene una apariencia mas amigable que los otros modelos en que únicamente necesitaríamos conectar un ratón, un monitor, una microSD y alimentación y estaríamos en disposición de trabajar. Podemos acceder al datasheet de este modelo aquí [https://datasheets.raspberrypi.com/rpi400/raspberry-pi-400-product-brief.pdf](https://datasheets.raspberrypi.com/rpi400/raspberry-pi-400-product-brief.pdf) Su precio ronda los 90 € por lo que resulta una opción mas que interesante en función del uso que vayamos a darle a nuestro equipo.

## Microcontroladores

En lo relativo a los microcontroladores tengo bastante menos experiencia y no vamos a utilizarlo en los siguientes apartados del curso pero a continuación te dejo un enlace a la parte específica de la gama Pico de Raspberry Pi que es la relativa a los microcontroladores [https://www.raspberrypi.com/products/raspberry-pi-pico/](https://www.raspberrypi.com/products/raspberry-pi-pico/)

[![rasp_pico_logo.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/rasp-pico-logo.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/rasp-pico-logo.png)

*Imagen obtenida de https://www.raspberrypi.com/products/raspberry-pi-pico/?variant=raspberry-pi-pico-h*

# 1.5 Gadgets adicionales

Son pocos los gadgets adicionales que una Raspberry Pi 4 modelo B necesita para funcionar. De hecho, podríamos decir que para funcionar únicamente necesita 2:

- Alimentador
- Tarjeta MicroSD

Pero Pablo, ¿y el teclado, el ratón o el monitor? Lo cierto es que no necesitamos tener conectados estos periféricos directamente a la Raspberry Pi. Algo frecuente es que en la raspberry Pi tengamos configurado el servicio de acceso por [SSH](https://es.wikipedia.org/wiki/Secure_Shell) y nos conectemos a la Raspberry Pi desde nuestro portatil u ordenador de sobremesa. Si no es el caso y queremos acceder de "modo local" a la raspberry Pi si que necesitaremos un monitor y un teclado y/o ratón.

## Alimentador

La Raspberry Pi 4 modelo B necesita de un alimentador para funcionar al igual que un ordenador de sobremesa requiere de una fuente de alimentación y un portátil de un transformador de corriente. En el caso que nos ocupa necesitaremos de un alimentador de 5,1 V y 3 A de corriente continua. Además, la interface de alimentación es de tipo USB C. El alimentador oficial tiene un coste inferior a 10 € y tiene este aspecto:

[![rasp_cargador.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/rasp-cargador.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/rasp-cargador.png)

*Imagen obtenida de https://www.raspberrypi.com/products/type-c-power-supply/?variant=raspberry-pi-psu-eu-w*

Por supuesto puedes utilizar otro alimentador mientras respetes las tensiones y corrientes que la Raspberry Pi necesita.

<p class="callout warning">Si utilizas un alimentador inadecuado puedes estropear tu Raspberry Pi</p>

En caso de estar utilizando un alimentador inadecuado y el sistema operativo Raspberry Pi OS (anteriormente llamado Rasbian) y que el alimentador no sea adecuado verás algo similar a lo que aparece en la siguiente imagen

*[![raspb_mal_alimentada.jpeg](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/raspb-mal-alimentada.jpeg)](https://libros.catedu.es/uploads/images/gallery/2023-02/raspb-mal-alimentada.jpeg)Imagen obtenida de https://github.com/MichaIng/DietPi/issues/3225*

## Periféricos de entrada

Podemos utilizar cualquier teclado o ratón que utilicen puerto USB . Aunque también hay teclado y ratones oficiales de Raspberry Pi. El teclado oficial está disponible en [https://www.raspberrypi.com/products/raspberry-pi-keyboard-and-hub/](https://www.raspberrypi.com/products/raspberry-pi-keyboard-and-hub/) y el ratón en [https://www.raspberrypi.com/products/raspberry-pi-mouse/](https://www.raspberrypi.com/products/raspberry-pi-mouse/)

<p class="callout warning">Asegúrate de conectar el teclado y el ratón en los puertos USB que no sean de tipo 3.X (los azules) así dejarás estos libres para conectar otros dispositivos (como discos duros) que requieran de mayor velocidad de funcionamiento</p>

Otros periféricos de entrada a considerar son las cámaras. Existen unos modelos oficiales que podemos encontrar en [https://www.raspberrypi.com/products/ ](https://www.raspberrypi.com/products/)y que dependerán del modelo de Raspberry Pi que tengamos

[![camaras.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/camaras.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/camaras.png)

*Imagen obtenida de https://www.raspberrypi.com/products/*

## Almacenamiento

Lo mas habitual y fácil es conectar una tarjeta micro SD a nuestra Raspberry Pi 4 modelo B (otros modelos requieren tarjeta SD en lugar de micro) y que en ella esté cargado el sistema operativo. Veremos como hacer esto en el [capítulo 2.1](https://libros.catedu.es/books/raspberry-pi/page/21-sistemas-operativos "2.1 Sistemas operativos"). También se puede hacer que la Raspberry Pi arranque a través de un disco duro externo que tengamos conectado a alguno de los puertos USB del dispositivo pero no es lo estandar. Lo que si suele hacerse es tener una tarjeta micro SD con el sistema operativo y un disco duro externo conectado en caso de que vayamos a utilizar la raspberry pi como centro de descargas o nube en casa u otros servicios que veremos a lo largo del capítulo 3.

[![sd_sizes.jpg](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/sd-sizes.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-02/sd-sizes.jpg)

*Imagen obtenida de https://www.cardwave.com/knowledge-hub/whats-the-difference-between-one-memory-card-and-another-size-matters/*

<p class="callout warning">A la hora de adquirir una tarjeta SD desconfía de las gangas pues es un mercado en el que no es extraño encontrar tarjetas *fakes* que prometen una capacidad y/o velocidad que luego no cumplen.</p>

Puedes verificar si una tarjeta SD es genuina con diferentes programas como [H2testw](https://www.heise.de/download/product/h2testw-50539), FakeFlashTest o ChipGenius.

## Periféricos de salida

En cuanto a los periféricos de salida lo mas habitual es conectar 1 o 2 monitores (la Raspberry Pi 4 modelo B soporta 2 monitores) a través de su interface HDMI. Recuerda que a través del HDMI tenemos tanto audio como vídeo. En la siguiente imagen podemos ver como conectar 2 monitores en 1 misma Raspberry Pi en los modelos Raspberry Pi 400 unit y Raspberry Pi 4 modelo B:

[![2-monitors.jpg](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/2-monitors.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-02/2-monitors.jpg)

*Imagen obtenida de https://core-electronics.com.au/guides/dual-monitors-raspberry-pi-4/*

Además de 1 o 2 monitores también puedes conectar cualquier otro dispositivo como impresoras (a través de wifi, usb o bluetooth) o cualquier otro periférico que puedas conectar a través de las interfaces existentes en el dispositivo.

Como en Raspberry Pi han pensando en (casi) todo también ponen a disposición de los/as usuarios/as la posibilidad de adquirir una pantalla táctil de fácil instalación (una pantalla táctil es un periféco de entrada-salida para ser correctos). La misma está accesible en [https://www.raspberrypi.com/products/raspberry-pi-touch-display/](https://www.raspberrypi.com/products/raspberry-pi-touch-display/) y tiene un coste en torno a 75€

*![tactil.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/tactil.png)Imagen obtenida de https://www.raspberrypi.com/products/raspberry-pi-touch-display/*

## Cajas y disipadores

Existe gran cantidad de modelos de carcasas y disipadores (tanto activos como pasivos) para Raspberry Pi. A continuación os dejo una imagen de las cajas oficiales de Raspberry Pi

[![carcasas.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/carcasas.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/carcasas.png)

*Imagen obtenida de https://www.raspberrypi.com/products/*

Puedes usar estos modelos o cualquier otro que te guste. También puedas optar por no usar carcasa. En este caso ten en cuenta que se trata de electrónica y tendrás que tener los cuidados que todo componente electrónico requiere y que son 2 básicamente: evitar el agua y evitar las altas temperaturas. Si tienes disipación activa también tendrás que asegurarte que el polvo y la suciedad no impidan el correcto funcionamiento de estos elementos de refrigeración.

Si tu idea es usar varios dispositivos también podría resultarte de interés este tipo de carcasas orientadas a la creación de clústers o simplemente por cuestiones de organización:

[![cluster-case.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/cluster-case.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/cluster-case.png)

*Imagen obtenida de https://thepihut.com/products/cluster-case-for-raspberry-pi*

En mi caso dispongo de 3 Raspberry Pi 2 modelo B y en 2 de ellas tengo una carcasa clónica. También dispongo de 2 Raspberry Pi 4 modelo B y en ninguna de ellas tengo carcasa pero si que tengo conectados ventiladores a los pines GPIO de la raspberry Pi pues este modelo se calienta algo mas que sus predecesores.

## Otros dispositivos

Lo cierto es que existe una gran cantidad de dispositivos para la Raspberry Pi pero en este apartado quiero hablar de 2 elementos que, en unión con la raspberry Pi, nos ofrecen una un mundo de posibilidades. Se trata de:

- <span style="text-decoration: underline;">las placas [Arduino](https://es.wikipedia.org/wiki/Arduino)</span> las cuales pueden ser conectadas a la Raspberry Pi de diferentes modos y que, entre otras cosas, nos permitirán contar con salidas digitales pues la Raspberry Pi únicamente cuenta con salidas digitales.

[![arduino.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/arduino.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/arduino.png)

*Imagen obtenida de https://www.amazon.es/Arduino-UNO-A000066-microcontrolador-ATmega328/dp/B008GRTSV6*

- <span style="text-decoration: underline;">Zigbee</span> lo trabajaremos en profundidad en el [capítulo 4.2](https://libros.catedu.es/books/raspberry-pi/page/43-domotica "4.2 Domótica") pero podemos adelantar que nos permitirá, básicamente, conectar multitud de dispositivos a nuestra Raspberry Pi de un modo similar al que tienen los dispositivos Bluetooth pero con un consumo inferior.

[![zigbee_usb.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/Dunzigbee-usb.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/Dunzigbee-usb.png)

*Imagen obtenida de https://es.aliexpress.com/item/32987952065.html*

# Kit de préstamo de CATEDU

Esta es el kit que hemos pensado desde CATEDU, los precios son orientativos e informativos, por supuesto que puedes realizar la compra donde quieras, pero siempre es positivo tener una información.

<iframe height="460" src="https://docs.google.com/spreadsheets/d/e/2PACX-1vQhhEGKJ63CyZhGW_pyXl3u01eZmb0afVbCI3dKYmuMKumtru9RMiibaAv7pjaZ5L_5-07H_O2dFdfX/pubhtml?widget=true&headers=false" style="width: 924px; height: 460px;" width="924"></iframe>

[![Imagen de WhatsApp 2023-06-14 a las 14.16.18.jpg](https://libros.catedu.es/uploads/images/gallery/2023-06/scaled-1680-/imagen-de-whatsapp-2023-06-14-a-las-14-16-18.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-06/imagen-de-whatsapp-2023-06-14-a-las-14-16-18.jpg)

# 2 - Primeros pasos

En este apartado vamos a introducir varios conceptos que necesitamos tener claro para empezar a trabajar con nuestra Raspberry Pi

# 2.1 Sistemas operativos

Como todo ordenador, **la Raspberry Pi necesita de un sistema operativo para funcionar**. Es bastante probable que si estás leyendo estos materiales desde un ordenador de sobremesa o portátil estés utilizando un buen sistema operativo como podría ser Vitalinux o cualquier otro derivado Linux como Ubuntu, Debian o Fedora. También pudiera ser estuvieses utilizando otro tipo de sistemas operativos propietarios como Windows o MacOs. Si estás utilizando una tableta o smartphone es bastante probable que esté utilizando Android o iOS. Todos ellos son sistemas operativos, pero ¿qué es un sistema operativo? sin complicarnos mucho podríamos decir que **un sistema operativo es el software que se ubica entre el hardware y las aplicaciones que tiene por encima**. Si quieres ampliar la información sobre qué son los sistemas operativos te dejo este [enlace](https://pabloruizsoria.gitbooks.io/oace/content/caracteristicas_y_funciones_fundamentales_de_un_si.html "apuntes de sistemas operativos") a materiales que preparé hace años para mi alumnado de FP básica.

Para trabajar con la Raspberry Pi nosotros/as vamos a trabajar con [Raspberry Pi OS](https://www.raspberrypi.com/software/ "Raspberry Pi OS") (antes llamado raspbian, seguro que en estos apuntes alguna vez me refiero al mismo de la manera antigua) que es un sistema operativo Linux que deriva a Debian optimizado para la Raspberry Pi por lo que si estás acostumbrado/a a trabajar con Vitalinux, Ubuntu o Debian no vas a notar ningún cambio.

[![raspian-logo.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/raspian-logo.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/raspian-logo.png)

*Imagen obtenida de https://pistachitos.com/guias/comenzando-con-raspbian/*

Además de este sistema operativo en la Raspberry Pi puedes instalar otros como:

- Raspberry Pi OS (Raspbian)
- Windows 10 IoT Cores
- LibreELEC
- RetroPie
- OSMC
- Ubuntu Desktop
- Ubuntu Core
- Ubuntu Server
- RISC OS
- Kali Linux
- Arch Linux ARM
- FreeNAS
- CentOS
- Fedora
- SUSE Linux Enterprise Server
- LineageOS
- ...

Por si tienes curiosidad sobre como instalar Windows 10 IoT (Internet de las cosas) te dejo un par de enlaces con información. El 1º en castellano sobre W10 y el 2º en inglés sobre W11: [https://www.ionos.es/digitalguide/servidores/know-how/sistemas-operativos-para-raspberry-pi/](https://www.ionos.es/digitalguide/servidores/know-how/sistemas-operativos-para-raspberry-pi/) y [https://www.tomshardware.com/how-to/install-windows-11-raspberry-pi](https://www.tomshardware.com/how-to/install-windows-11-raspberry-pi)

Si en alguna ocasión has instalado algún sistema operativo en algún ordenador es bastante probable que hayas hecho uso de algún CD o DVD o de algún USB que hayas establecido como 1er elemento de arranque y, a partir de ahí, hayas seguido las instrucciones. En Raspberry Pi esta instalación la haremos haciendo uso de imágenes. Sigue leyendo para saber qué son y cómo las usaremos.

## Imágenes

Si pensamos en una imagen quizás nos venga a la cabeza la representación gráfica de algo pero en este caso cuando utilizamos el término imagen lo que queremos indicar es la copia exacta de un disco. Esto nos permite utilizar una imagen existente de un sistema operativo y llevarla a nuestra Raspberry Pi de modo que será funcional. En este curso, en la mayoría de herramientas que utilicemos haremos uso de un sistema operativo y sobre él instalaremos diferentes servicios pero en alguna de las posibilidades que veamos también usaremos directamente una imagen que nos traerá ya todo configurado y listo para utilizar. Es el caso que veremos en el [capítulo 3.4 BOBcera. Videoconsola retro](https://libros.catedu.es/books/raspberry-pi/page/34-multibob-antes-bobcera-convierte-tu-raspberry-pi-en-una-videoconsola-retro "3.4 BOBcera. Videoconsola retro").

Si queremos grabar una imagen en nuestra tarjeta SD únicamente debemos seguir los pasos que nos indican en este vídeo:

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/ntaXWS8Lk34" width="560"></iframe>

En resumen:

1. De la web [https://www.raspberrypi.com/software/](https://www.raspberrypi.com/software/) descarga el programa que corresponde a tu sistema operativo
2. Instala la aplicación "Raspberry Pi Imager" que acabas de descargar
3. Introduce la tarjeta micro SD en un lector de tu ordenador
4. Ejecuta la aplicación
5. Elige qué versión de sistema operativo quieres instalar. Por ejemplo la versión de escritorio (Desktop) si no estás acostumbrado/a a trabajar solo con comandos
6. Deberías preconfigurar algunas cuestiones como: 
    1. nombre
    2. SSH, para conectarte posteriormente de modo remoto a la Raspberry Pi sin necesidad de conectarle teclado, ratón y monitor
    3. red WIFI
    4. locale (idioma)
7. Selecciona dónde está la tarjeta SD
8. Graba la imagen en la microSD
9. Cuando termine expúlsala del sistema operativo dónde hayas estado trabajado
10. Llévate la microSD a la Raspberry Pi y enciéndela. Debería arrancar el sistema operativo que has elegido.

<p class="callout warning">Si no pones un sistema operativo en la SD de tu Raspberry Pi no podrás usarla.</p>

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="569" src="https://docs.google.com/presentation/d/e/2PACX-1vR4wwk8BwdSEgk-aTQ_xgvrQYJ-cr2QhN_35Q-mYJxYedhT5P-vF6UkDbSsHJ5I_zLS7IqBirdNfI4t/embed?start=false&loop=false&delayms=3000" width="100%"></iframe>

- [CONECTANDO DESDE LA RED LOCAL](https://libros.catedu.es/books/raspberry-muy-basico/page/conectando-desde-red-local)
- [CONECTANDO DE FORMA TEXTUAL CON SSH](https://libros.catedu.es/books/raspberry-muy-basico/page/ssh)
- [CAMBIAR USUARIO Y CONTRASEÑA](https://libros.catedu.es/books/raspberry-muy-basico/page/6-cambiar-usuario-y-contrasena)
- [APAGAR](https://libros.catedu.es/books/raspberry-muy-basico/page/7-apagar)
- [CONECTANDO DE FORMA GRÁFICA: VNC](https://libros.catedu.es/books/raspberry-muy-basico/page/8-vnc)

## Control de versiones. Git. Github.

En este apartado realmente os quiero hablar de Github pero para hablaros de GitHub os he de hablar de Git y, a su vez, para hablaros de Git os tengo que hablar sobre el control de versiones así que vamos a ver, en el orden lógico, unas pinceladas de estos elementos.

**Control de versiones**: El control de versiones nos permite ver los diferentes cambios que un documento ha sufrido con el tiempo viendo quién ha hecho qué cambio, cuándo lo ha hecho y por qué lo ha hecho. Para ampliar la información leer [aquí](https://es.wikipedia.org/wiki/Control_de_versiones "Control de versiones").

**Git**: Es un software de control de versiones muy potente y muy sencillo de utilizar

[![512px-Git-logo.svg.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/512px-git-logo-svg.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/512px-git-logo-svg.png)

*Imagen obtenida de: https://commons.wikimedia.org/wiki/File:Git-logo.svg?uselang=es*

**Github**: Es una plataforma web que actúa como repositorio de proyectos que utilizan en control de versiones git. De esta plataforma vamos a descargar varios de los proyectos que pondremos en marcha en los capítulos 3 y 4 y me parece adecuado que conozcas algo mas de la misma que limitarme a decirte mas adelante que ejecutes tal o cual comando que tiene como factor común una URL de github. Como curiosidad te diré que en github puedes encontrar parte del código que se desarrolla en CATEDU. Su respositorio es https://github.com/catedu

[![github-mark.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/github-mark.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/github-mark.png)

*Imagen obtenida de https://github.com/logos*

## Docker. Docker-compose

Al igual que ocurría en el apartado anterior con github en el capítulo 3 y 4 haremos uso de docker y docker-compose y también me parece adecuado contarte qué son y cuales son ventajas en vez de que te limites a copias y pegar comandos.

Quizás hayas oído o utilizado en alguna ocasión [máquinas virtuales](https://es.wikipedia.org/wiki/M%C3%A1quina_virtual "máquinas virtuales") con Virtual Box, vmware u otras herramientas que permiten su uso y gestión. De ser así habrás visto que sobre tu sistema operativo has creado un hardware virtual y en ese hardware virtual has instalado otro sistema operativo y los distintos programas que te ha interesado. A ese conjunto es a lo que se llama máquina virtual. Si en esa máquina, por ejemplo, borras todo no afecta a tu sistema operativo anfitrión, lo cual te permite una serie de ventajas como probar determinados sistemas y/o programas sin poner en riesgo tu equipo anfitrión. De igual modo, si tienes un determinado programa que tienes que utilizar y solo funciona en un sistema operativo que no es el que utilizas puedes crear una máquina virtual con ese programa y ejecutarlo. Las ventajas parecen claras. Ahora vamos con la gran desventaja: son muy pesadas, requieren de muchos recursos. Por ello surgen los [contenedores](https://es.wikipedia.org/wiki/Virtualizaci%C3%B3n_a_nivel_de_sistema_operativo "contenedores") y su máximo exponente es Docker.

[![docker-logo.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/docker-logo.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/docker-logo.png)

*Imagen obtenida de [https://www.docker.com/company/newsroom/media-resources/](https://www.docker.com/company/newsroom/media-resources/)*

**Docker** y **Docker-compose** van a permitirnos levantar y tirar contenedores (dónde habrá distintos servicios) de un modo muy sencillo. Esto nos va a permitir que en nuestra Raspberry Pi podamos instalar diferentes utilidades sin que los requerimientos de unas afecten a los de otras. Son herramientas sencillas de utilizar y, en muchas ocasiones, copiaremos textos directamente de github que nos permitirán poner todo en marcha. De todos modos, para evitar el uso continuado del terminal que tanto nos gusta a los/as informáticos/as y tan poco al resto de usuarios/as en el capítulo 3 la primera herramienta que veremos será Portainer la cual nos permitirá gestionar los contenedores de un modo gráfico.

[![docker-compose-logo.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/docker-compose-logo.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/docker-compose-logo.png)

*Imagen obtenida de https://github.com/docker/compose*

Vamos a ver los comandos que deberemos ejecutar en la terminar de Raspberry Pi OS para instalar ambos servicios. Necesitarás conexión a internet en tu Raspberry Pi.

<p class="callout info">Si no quieres instalar docker y docker-compose del modo que te cuento a continuación echa un vistazo al [capítulo 3.3 Linux Media Delivery System (LMDS). Centro de descargas](https://libros.catedu.es/books/raspberry-pi/page/33-linux-media-delivery-system-lmds-centro-de-descargas "3.3 Linux Media Delivery System (LMDS). Centro de descargas") pues en el mismo, aunque harás uso del terminal, podrás instalar docker y docker-compose con un asistente.</p>

Empecemos por instalar docker:

```bash
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker ${USER}
sudo su - ${USER}
docker version
```

Tras ejecutar los comandos anteriores verás algo similar a:

[![docker-version.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/docker-version.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/docker-version.png)

*Elaboración propia*

<p class="callout warning">Ya no es necesario instalar docker-compose. Dejo a continuación TACHADO lo que había que hacer anteriormente por si alguien trabaja con versiones viejas de docker pero si acabáis de instalar docker según lo indicado anteriormente ya lo tenéis instalado y <span style="text-decoration: underline;">no deberíais ejecutar lo siguiente que que está tachado</span>.</p>

<s>Ahora terminemos instalando docker-compose:</s>

```bash
sudo apt-get install libffi-dev libssl-dev
sudo apt install python3-dev
sudo apt-get install -y python3 python3-pip
sudo pip3 install docker-compose
docker-compose version
```

<s>Tras ejecutar el último comando verás algo similar a la siguiente imagen:</s>

<s>[![docker-compose-version.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/docker-compose-version.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/docker-compose-version.png)</s>

<s>*Elaboración propia*</s>

<p class="callout warning">Si en algún lugar de los apuntes aparece algún comando que sea `docker-compose up -d` sustituye el guión por un espacio dejándolo así `docker compose up -d`</p>

Un concepto importante relativo a los contenedores es el de **volumen**. Simplificando, un volumen nos va a permitir compartir datos entre contenedores y/o la máquina anfitriona. Es decir, aunque un contenedor lo "tiremos" o borremos en la carpeta que hayamos establecido como volumen tendremos persistencia de datos.

# 2.2 Electrónica de Raspberry Pi 4 modelo B

La información que aquí detallo está obtenida principalmente de la página web oficial del producto [https://www.raspberrypi.com/products/raspberry-pi-4-model-b/specifications/](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/specifications/)

A continuación dejo una imagen mas completa que las anteriores dónde se ubica para cada este modelo dónde está cada componente

[![rpi4-esquema.jpeg](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/rpi4-esquema.jpeg)](https://libros.catedu.es/uploads/images/gallery/2023-02/rpi4-esquema.jpeg)

*Imagen obtenida de https://cosmicteq.co.za/Raspberry-Pi-4-Model-B-1GB-p506861692*

## CPU, RAM, GPU

Este modelo de Raspberry cuenta con con chip Broadcom BCM2711, Quad core Cortex-A72 (ARM v8) 64-bit SoC @ 1.5GHz. En cuanto a la memoria RAM es de tipo LPDDR4-3200 SDRAM y puede ser adquirida con 2, 4 u 8 GB de memoria RAM (la web oficial indica que también existe un modelo de 1GB pero nunca lo he visto comercializado).

Por si sirve de referencia, en mi caso, los modelos de Raspberry Pi 4 modelo B de que dispongo son los de 4GB. Uno de los modelos es el que se encarga de toda la domótica y el otro modelo se encarga del centro de descargas y multimedia, bloquedo de publicidad, portainer y alguna otra cuestión. En ocasiones desconecto una de ellas y le pongo una tarjeta microSD que tengo específica con la BOBcera (juegos de mi juventud). A continución pongo unas captura de pantalla del consumo de recursos de estas Raspberry Pi para que se veais que están sobrada:

[![htop-mediacenter.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/htop-mediacenter.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/htop-mediacenter.png)

*Consumo de recursos media center. Elaboración propia*

[![hassio-consumo.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/hassio-consumo.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/hassio-consumo.png)

*Consumo de recursos de Hassio. Elaboración propia*

Si tu idea es usar la Raspberry Pi para jugar probablemente te lleves una decepción pues la potencia de su GPU no es suficiente para correr juegos modernos.

## Audio

- 2 × micro-HDMI ports (up to 4kp60 supported): Por el conector HDMI además de audio tenemos vídeo.
- 4-pole stereo audio and composite video port

## Vídeo

- 2 × micro-HDMI ports (up to 4kp60 supported)
- 2-lane MIPI DSI display port: Orientado a conectar una pantalla. Mas información [aquí](https://en.wikipedia.org/wiki/Display_Serial_Interface "DSI").
- 2-lane MIPI CSI camera port: Orientado a conectar una cámara. Mas información [aquí](https://es.wikipedia.org/wiki/CSI_(bus_serie) "CSI").

## Conectividad

En cuanto a su conectividad la Raspberry nos ofrece en este modelo la posibilidad de conectarnos a la red a través de WIFI, cable de red o Bluetooth. En concreto estas son las posibilidades que ofrece:

- 2.4 GHz and 5.0 GHz IEEE 802.11ac wireless
- Bluetooth 5.0, BLE
- Gigabit Ethernet

<p class="callout warning">Si optas por instalar Raspberry Pi OS sin entorno gráfico deberás configurar la red desde el terminal. En este manual paso a paso te indican como hacerlo: https://bricolabs.cc/wiki/guias/raspberry\_pi\_-\_instalacion\_del\_sistema\_operativo\_y\_configuracion\_de\_red</p>

## Pinout

<p class="callout warning">El pinout que vamos a ver en este apartado es el del modelo de la Raspberry Pi 4 modelo B. Si no estás usando ese modelo asegúrate de cual es el pinout de tu dispositivo a fin de evitar conexiones incorrectas que dañen el dispositivo y/o los elementos que tengas conectados. No obstante la Raspberry Pi 4 tiene compatibilidad hacia atrás.</p>

Información obtenida de [https://www.raspberrypi.com/documentation/computers/raspberry-pi.html](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html) Este modelo dispone de 40 pines.

[![GPIO-Pinout-Diagram-2.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/gpio-pinout-diagram-2.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/gpio-pinout-diagram-2.png)

*Imagen obtenida de https://www.raspberrypi.com/documentation/computers/raspberry-pi.html*

Fíjate en la posición en la cual está colocada la Raspberry Pi y en como numera los pines (de izquierda a derecha y de arriba a abajo).

<p class="callout warning">Una cuestión importante es no confundir el nº de pin con el nº de GPIO</p>

Si te fijas en el pin nº 7 corresponde al GPIO nº 4. Cuando en el capítulo 4, a través de Python, queramos interactuar con el pin nº7 deberemos referenciarlo como GPIO nº 4.

En relación a los voltajes fíjate que hay 2 pines que funcionan a 5V y otros 2 que funcionan a 3,3V. También hay varios marcados como tierra (ground)

Los pines GPIO se consideran activos (a 1, en alto) con 3,3V mientras que se consideran inactivos (a 0, en bajo) con 0 V.

Como curiosidad, si desde el terminal de tu sistema operativo raspbian ejecutas el comando `pinout` verás algo similar a:

[![pinout.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/pinout.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/pinout.png)

*Elaboración propia*

# 3 - Algunas posibilidades

Vamos a ver en este capítulo algunas de las herramientas que considero pueden resultarnos de utilidad. El orden en que se muestran no se debe a nada por lo que si te decides a instalar alguna de estas herramientas puedes hacerlo con independencia de tener instaladas las que aparecen listadas con anterioridad. Lo que si "es requisito" para la gran mayoría de ellas es disponer de docker y docker-compose instalado si bien es cierto es que todas ellas pueden instalarse sin esta magnífica herramienta pero entonces perderemos la ventaja que nos aporta el trabajar con contenedores.  
Espero que estas herramientas te resulten de interés y si conoces cualquier otra que crees que puede resultar interesante háznoslo saber para valorar la inclusión de la misma a estos materiales

# Página nueva



# 3.1 Portainer. Gestión de contenedores

[![portainer-logo.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/portainer-logo.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/portainer-logo.png)

Imagen obtenida de https://www.portainer.io/

## Esta herramienta sirve para...

Gestionar los distintos contenedores, imágenes, stacks,... que tengamos en nuestra Raspberry Pi a través de un entorno gráfico en lugar de hacerlo a través del terminal del sistema operativo. Cuenta con una versión BE (Business Edition) y otra CE (Community Edition), usaremos la 2ª.

## Web de proyecto y otros enlaces de interés

Página web oficial: [https://www.portainer.io/](https://www.portainer.io/)

Repositorio de la versión CE en github: [https://github.com/portainer/portainer](https://github.com/portainer/portainer)

Documentación del proyecto: [https://docs.portainer.io/](https://docs.portainer.io/)

## Despliegue

<p class="callout info">Si crees que instalar portainer del modo que a continuación se explica es complicado puedes instalarlo a través del método que explicamos en el [capítulo 3.3 Linux Media Delivery System (LMDS)](https://libros.catedu.es/books/raspberry-pi/page/33-linux-media-delivery-system-lmds-centro-de-descargas "3.3 Linux Media Delivery System (LMDS). Centro de descargas"). No te librará de utilizar la terminal pero quizás te resulte mas amigable.</p>

En la propia documentación podemos encontrar como desplegar Portainer ( [https://docs.portainer.io/start/install-ce/server/docker/linux](https://docs.portainer.io/start/install-ce/server/docker/linux) ). Vamos a recopilar aquí qué hay que hacer y explicar los comandos

```bash
docker volume create portainer_data
docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
```

En la primera línea creamos un volumen llamado portainer\_data

En la segunda línea lanzamos, desplegamos un contenedor:

- -d (--detach): Ejecuta un contenedor en segundo plano.
- -p (--expose): Nos permite indicar qué puerto del contenedor se corresponde con qué puerto de la máquina anfitriona.
- --name: Nos permite establecer el nombre del contenedor.
- --restart: Nos permite establecer qué queremos que ocurra en caso de que el contenedor falle. En este caso establecemos que se reunicie siempre.
- -v (--volume): Nos permite mapear rutas del contenedor con rutas de la máquina anfitriona.
- El último parámetro que aparece en la ruta `portainer/portainer-ce:latest` es la imagen que se va a ejecutar.

<p class="callout warning">Visto y explicado cómo realizar la instalación según indica la documentación oficial, nosotros/as vamos a hacerlo de otro modo.</p>

La forma que hemos visto con anterioridad funciona. Podéis usarla sin ningún problema. Ahora bien, dado que en este curso desconozco el nivel de partida de cada compañero/a que lo cursa voy a optar por utilizar un modo de despliegue semejante para cada servicio y, por ello, voy a hacer uso de docker-compose. Vamos allá:

Para ello accedemos al terminal y escribimos lo siguiente:

```bash
cd $HOME
mkdir portainer
cd portainer
nano docker-compose.yml
```

Dentro del fichero escribimos el siguiente contenido:

```yaml
version: '2'
services:

  portainer:
    container_name: portainer
    image: portainer/portainer-ce
    restart: unless-stopped
    ports:
      - 9000:9000
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./volumes/data:/data
```

Para salir del fichero pulsaremos `control + x` y guardaremos los cambios. Posteriormente ponemos en marcha los contenedores con `docker compose up -d` Aparecerá en pantalla algo similar a

[![portainer-deploy.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/portainer-deploy.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/portainer-deploy.png)

*Elaboración propia*

Si queremos comprobar que el contenedor está en marcha podemos ejecutar `docker ps --all` lo que nos mostrará todos los contenedor que hay en la máquina. Si queremos ver si, concretamente, está disponible el que acabamos de crear podemos ejecutar docker `ps --all | grep portainer`. Obteniendo unos resultados similares a los siguientes:

[![docker-ps-grep-portainer.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/docker-ps-grep-portainer.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/docker-ps-grep-portainer.png)

*Elaboración propia*

También podemos tratar de acceder a la interface gráfica a través de un navegador web. Para ello accedemos a través del navegador la Raspberry Pi y al servicio Portainer del siguiente modo `http://<IP>:puerto` en mi caso tengo configurada la raspberry Pi con la IP `192.168.0.201` y portainer con el puerto `9000` por lo que escribo `http://192.168.0.201:9000` y así accedo a la interface web de portainer.

[![portainer-index.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/portainer-index.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/portainer-index.png)

*Elaboración propia*

## Funcionamiento

<p class="callout info">En el resto del curso el despliegue de los distintos servicios lo haré siempre a través de comandos pero debes saber que con esta herramienta puedes hacer lo mismo en un entorno gráfico.</p>

Como ya indicamos en la introducción esta herramienta es una interface web para docker lo cual facilitará enormemente la vida a aquellas personas que no estén acostumbradas a trabajar desde una interface de texto (terminal).

Nada mas acceder veremos una imagen como la que hemos visto un par de párrafos más arriba en ella podemos gestionar los usuarios, entornos, logs, parámetros de configuración... de este primer menú lateral no voy a comentaros nada. Si pinchamos en local veremos una imagen como la siguiente:

[![portainer-local.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/portainer-local.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/portainer-local.png)

*Elaboración propia*

En la misma os he remarcado 4 zonas:

- zona 1 (verde): Tenemos acceso a los diferentes contenedores, imágenes, redes y volúmenes de nuestro entorno local.
- zona 2 (azul claro): Acceso a las mismas secciones que teníamos antes de entrar en el entorno local.
- zona 3 (rojo): Información del entorno.
- zona 4 (morado): Similar a la zona 1 con algo de información adicional.

Si accedemos a, por ejemplo, `Containers` tendremos un listado de todos los contenedores descargados:

[![portainer-containers.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/portainer-containers.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/portainer-containers.png)

*Elaboración propia*

Dónde podemos ver si hay contenedores detenidos, fallando, sanos,... también podemos acceder al detalle de cualquiera de ellos y dentro del detalle detenerlo, reiniciarlo, pausarlo, borralo,... ver los logs, acceder al terminar del contenedor,... todo ello sin necesidad de conocer los comandos docker que hay por detrás:

[![portainer-container-details.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/portainer-container-details.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/portainer-container-details.png)

*Elaboración propia*

[![portainer-container-details-logs.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/portainer-container-details-logs.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/portainer-container-details-logs.png)

*Elaboración propia*

Es bastante probable que nunca tengáis que recurrir a estas opciones pero si en alguna ocasión las necesitáis no tendréis que buscar que con `docker logs nombre_del_contenedor --follow` podéis hacer lo mismo que haciendo 4 clicks.

Acceder a las secciones de `Images` o `Volumes` nos puede resultar muy útil para de un vistazo ver, respectivamente, que imágenes o volúmenes no están en uso y así borrarlas para que dejen de ocupar espacio en nuestro disco duro.

[![portainer-image.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/portainer-image.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/portainer-image.png)

*Elaboración propia*

Además, por si fuera poco, nos agrupa los contenedores por stacks de modo que nos facilita ver si los contenedores asociados a un determinado servicio (hay servicios que pueden requerir el funcionamiento de mas de 1 contenedor) están operativos o no.

[![portainer-stacks.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/portainer-stacks.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/portainer-stacks.png)

*Elaboración propia*

[![portainer-stack-details.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/portainer-stack-details.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/portainer-stack-details.png)

*Elaboración propia*

Y, ya para terminar pero no por ello menos importante, nos ofrece también la posibilidad de crear contenedores a partir de plantillas de aplicaciones preexistentes. Esta funcionalidad puede permitirnos desplegar servicios en segundos sin conocer ni un solo comando de docker (si bien no es lo deseable):

[![portainer-templates.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/portainer-templates.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/portainer-templates.png)

*Elaboración propia*

Como nos ocurrirá en servicios posteriores, esta herramienta podría dar por si misma para un curso dedicado. Os presento aquellas cuestiones que me parecen mas relevantes a fin de que seáis capaces de continuar vosotros/as desde este punto de partida.

# 3.2 DIUN. Notificador de nuevas imágenes

[![diun-logo.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/diun-logo.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/diun-logo.png)

*Imagen obtenida de https://crazymax.dev/diun/*

## Esta herramienta sirve para...

enterarnos cuando una nueva imagen (para docker) está disponible. DIUN son las siglas de Docker Image Update Notifier.

## Web de proyecto y otros enlaces de interés

Web del proyecto: [https://crazymax.dev/diun/](https://crazymax.dev/diun/)

Repositorio de código: [https://github.com/crazy-max/diun](https://github.com/crazy-max/diun)

## Puesta en marcha

Si bien hay varios modos de desplegar el servicio DIUN nosotros, en este curso, vamos a optar por hacerlo a través de docker-compose pues creo es el modo mas sencillo en el que podemos hacer convivir varios servicios sin que unos acepten a otros. Para ello accedemos al terminal y escribimos lo siguiente:

```
cd $HOME
mkdir diun
cd diun
nano docker-compose.yml
```

Dentro del fichero escribimos el siguiente contenido

```yaml
version: "3.5"

services:
  diun:
    image: crazymax/diun:latest
    container_name: diun
    command: serve
    volumes:
      - "./data:/data"
      - "./diun.yml:/diun.yml:ro"
      - "/var/run/docker.sock:/var/run/docker.sock"
    environment:
      - "TZ=Europe/Madrid"
      - "LOG_LEVEL=info"
      - "LOG_JSON=false"
    restart: always
```

Para salir del fichero pulsaremos `control + x` y guardaremos los cambios. Posteriormente ponemos en marcha los contenedores con `docker compose up -d` Aparecerá en pantalla algo similar a

[![diun-deploy.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/diun-deploy.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/diun-deploy.png)

*Elaboración propia*

Y, si queremos, podemos ejecutar `docker ps | grep diun` para comprobar si entre todos los contenedores docker en ejecución hay alguno con el nombre diun. Veremos algo similar a

[![diun-grep.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/diun-grep.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/diun-grep.png)

*Elaboración propia*

De acuerdo a la documentación sobre comandos que aparece en [https://crazymax.dev/diun/usage/command-line/](https://crazymax.dev/diun/usage/command-line/) podemos ejecutar cualquiera de los comandos que ahí aparecen ejecutando `docker exec diun comando` por ejemplo `docker exec diun diun image list` que nos mostrará algo similar a

[![diun-exec.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/diun-exec.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/diun-exec.png)

*Elaboración propia*

De todos modos, **lo interesante de esta herramienta es que sea ella misma quién nos notifique cuando hay una nueva imagen sin necesidad de que nosotros/as ejecutemos nada**. Para ello hay que configurar las notificaciones de acuerdo a la documentación que aparece aquí [https://crazymax.dev/diun/config/notif/](https://crazymax.dev/diun/config/notif/) ¡Vamos allá! En la terminal escribiremos:

```bash
cd $HOME/diun
nano diun.yml
```

Dentro del fichero, que será en el cual establezcamos los métodos de notificación, escribimos el siguiente contenido:

```yaml
watch:
  workers: 20
  schedule: "0 */6 * * *"
  firstCheckNotif: false

providers:
  docker:
    watchByDefault: true

notif:
  mail:
    host: localhost
    port: 25
    ssl: false
    insecureSkipVerify: false
    from: tu_email@tu_email.com
    to:
      - tu_email@tu_email.com
    templateTitle: "{{ .Entry.Image }} released"
    templateBody: |
      Docker tag {{ .Entry.Image }} which you subscribed to through {{ .Entry.Provider }} provider has been released.
  telegram:
    token: tu_token_en_telegram
    chatIDs:
      - el_id_de_tu_chat
    templateBody: |
      Docker tag {{ .Entry.Image }} which you subscribed to through {{ .Entry.Provider }} provider has been released.
```

A continuación reiniciamos el contenedor con los comandos

```bash
cd $HOME/diun
docker-compose down
docker-compose up -d
```

Para salir del fichero pulsaremos `control + x` , guardaremos los cambios y *¡et voilà!* ya están configuradas las notificaciones para Telegram y email. Deberás cambiar los valores a tus valores y establecer solo aquellos servicios a través de los que quieres que se te notifique.

## Cómo actualizar la imágenes

En mi caso lo tengo configurado para que me notifique a través de un bot de Telegram por ello recibo notificaciones con este aspecto:

[![diun-notificacion.jpg](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/diun-notificacion.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-02/diun-notificacion.jpg)

*Elaboración propia*

Si has instalado Portainer (lo hicimos en el capítulo anterior) es muy sencillo. Accedemos a través del navegador la Raspberry Pi y al servicio Portainer del siguiente modo `http://<IP>:puerto` en mi caso tengo configurada la raspberry Pi con la IP `192.168.0.201` y portainer con el puerto `9000` por lo que escribo `http://192.168.0.201:9000` y así accedo a la interface web de portainer.

[![portainer-index.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/portainer-index.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/portainer-index.png)

*Elaboración propia*

Pincho en el entorno local y accedo a una pantalla como la siguiente:

[![portainer-dashboard.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/portainer-dashboard.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/portainer-dashboard.png)

*Elaboración propia*

Selecciono imágenes, busco la que me interesa (en este ejemplo, la que corresponde a jackett) y pincho en ella. De modo que veré algo como

[![portainer-image-details.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/portainer-image-details.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/portainer-image-details.png)

*Elaboración propia*

Y ahora elijo la opción que dice "Pull from regirtry" (la 2ª opción).

*[![portainer-image-details-detail.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/portainer-image-details-detail.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/portainer-image-details-detail.png)*

*Elaboración propia*

Nos preguntará por el registro a usar pudiendo dejar la opción por defecto sin mayor problema y comenzará la descarga de la imagen. De este modo habremos descargado la última imagen disponible de, en este ejemplo, jackett.

Todo lo anterior podíamos haberlo hecho ejecutando desde el terminal `docker image pull linuxserver/jackett:latest`

<p class="callout warning">Con lo hecho hasta ahora habremos actualizado una determinada imagen PERO si algún contenedor está usando dicha imagen no pasará a utilizarla hasta que tiremos y levantemos el contenedor de nuevo</p>

# 3.3 Linux Media Delivery System (LMDS). Centro de descargas

## Esta herramienta sirve para...

disponer de un centro de descargas y centro de entretenimiento de diferente contenido multimedia.

## Web de proyecto y otros enlaces de interés

- Web del proyecto: [https://greenfrognest.com/](https://greenfrognest.com/)
- Repositorio de código: [https://github.com/GreenFrogSB/LMDS](https://github.com/GreenFrogSB/LMDS)
- Configurar el servicio con un disco duro externo [https://greenfrognest.com/LMDSUSBdrive.php#usbdrive](https://greenfrognest.com/LMDSUSBdrive.php#usbdrive)
- Preguntas precuentes [https://greenfrognest.com/faqlist.php](https://greenfrognest.com/faqlist.php)

## Instalación

En este caso no vamos a partir de un fichero docker-compose sino que vamos a clonar un respositorio de github y una vez clonado vamos a ejecutar un script que contiene. Dicho script se encargará de crear el fichero docker-compose.

```f#
cd $HOME
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install git
git clone https://github.com/GreenFrogSB/LMDS.git ~/LMDS
cd ~/LMDS
./deploy.sh
```

En las líneas 2 y 3 actualizamos repositorios y el sistema. En la línea 4 instalamos git (si ya está instalado no lo instalará). En la línea 5 copiamos el repositorio de github dónde está el código. En la línea 6 accedemos a la carpeta LMDS. En la línea 7 ejecutamos el script de LMDS que nos irá preguntando qué queremos instalar a través de un menú interactivo como el que se ve a continuación:

[![LMDS_main_menu.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/lmds-main-menu.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/lmds-main-menu.png)

La 1ª opción "Install Docker" nos permitirá instalar Docker y Docker-compose. Si no lo tenemos instalado deberemos seleccionarla. Si ya lo tenemos instalado podemos seleccionar directamente la 2ª opción "Build LMDS Stack" que nos mostrará una pantalla como la siguiente y que nos permitirá elegir qué servicios queremos instalar:

[![LMDS_stack.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/lmds-stack.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/lmds-stack.png)

Algunos de los contenedores que aquí aparecen ya los hemos visto en este curso, es el caso de Portainer, y otros los veremos mas adelante, es el caso de Pi-Hole. Centrándonos en el caso que nos ocupa, la "construcción" de un centro de descargas mi recomendación es seleccionar:

- **Sonarr**: Si queremos rastrear series.
- **Radarr**: Si queremos rastrear películas.
- **Lidarr**: Si queremos rastrear música.
- **Bazarr**: Subtítulos.
- **Jackett**: Para que actúe de intermediario entre los programas antes indicados y el cliente de descargas.
- **Deluge** o **qBittorrent** o **Transmision**: Clientes de descargas (yo usaré Deluge en este curso)
- **Portainer**: No es necesario para hacer funcionar el centro de descargas pero recomendaría su instalación para facilitarnos la gestión del stack.

Cuando pulsemos ok el script se encargará de crear el fichero docker-compose. Ahora, como ya sabemos, ejecutaremos el comando `docker compose up -d` y todo se pondrá en marcha. Tras ejecutar el comando veremos algo similar s:

[![lmds-deploy.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/lmds-deploy.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/lmds-deploy.png)

*Elaboración propia*

También podemos hacerlo desde Portainer si lo tenemos funcionando.

Si vemos el contenido del directorio veremos que aparece el fichero docker-compose-yml del cual podemos ver su contenido. En el mismo veremos que se han creado una serie de volúmenes. El contenido del directorio será semejante a lo que vemos en la siguiente imagen

[![LMDS_ls.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/lmds-ls.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/lmds-ls.png)

<p class="callout info">Se curioso/a y mira el contenido del fichero docker-compose.yml generado. Verlo es un buen modo de aprender.</p>

En el subapartado Funcionamiento vamos a explicar como configurar el centro de descargas.

Os dejo además un vídeo de youtube donde, en inglés, nos indican lo mismo que os indico arriba

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="315" src="https://www.youtube.com/embed/oLxsSQIqOMw" title="YouTube video player" width="560"></iframe>

<p class="callout info">Estamos instalando todo este *stack* con LMDS por facilitar la tarea pero podemos instalar individualmente cada programa a través de 1 fichero docker-compose</p>

<span style="color: rgb(34, 34, 34); font-size: 2.8275em; font-weight: 400;">Funcionamiento</span>

<p class="callout info">En mi caso tengo la raspberry conectada a la TV por cable HDMI por lo que únicamente debo seleccionar en la TV como entrada HDMI y ahí, con un ratón inalámbrico conectado a la raspberry, elegir el contenido a reproducir. Si no es vuestro caso deberéis recurrir a soluciones como Plex o Jellyfin, que el instalador también deja instalar.</p>

En este caso creo que lo mas sencillo es recurrir a un vídeo dónde nos explican como usar en conjunto todas estas herramientas:

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="315" src="https://www.youtube.com/embed/mvufLzlOS4I?start=490" title="YouTube video player" width="560"></iframe>

En el vídeo nos cuentan de un modo muy básico las diferentes posibilidades de cada herramienta pero si le dedicáis tiempo a ir mirando las diferentes configuraciones veréis que se tratan de programas muy potentes. Por ejemplo podemos seleccionar en qué idiomas queremos que busque el contenido o en qué calidad mínima estamos dispuestos a ver lo que descargue.

# 3.4 MultiBOB (Antes BOBcera). Convierte tu Raspberry Pi en una videoconsola retro

## Esta herramienta sirve para...

pasárselo bien jugando a juegos de hace unas cuantas décadas. Para jugar es altamente recomendable adquirir un mando que funcione por USB y que preferiblemente sea inalámbrico. En mi caso adquirí este mando [https://www.amazon.es/gp/product/B01KVC4K3O](https://www.amazon.es/gp/product/B01KVC4K3O) pero vale cualquiera que se pueda conectar por USB, WIFI o Bluetooth a la Raspberry Pi.

En el siguiente vídeo (de mas de 1h de duración) el creador del proyecto nos habla del mismo y nos muestra sus principales características:

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/NO56iPNd8Tc" width="560"></iframe>

## Web de proyecto y otros enlaces de interés

En este caso nuestro punto de partida es un canal de Telegram. El canal se llama "BOB - Mejores juegos viejunos para Raspberry pi0/1/2/3/4, Batocera,..." (podéis uniros al canal a través de este enlace [https://t.me/BOB\_retropie\_windows\_dudas](https://t.me/BOB_retropie_windows_dudas) ) y en la web [https://telegra.ph/Best-of-the-Best---Solo-los-mejores-juegos-09-25](https://telegra.ph/Best-of-the-Best---Solo-los-mejores-juegos-09-25) tenemos toda la información para comenzar. En este caso no se trata de algo exclusivo para la Raspberry Pi sino que de modo muy sencillo también podéis usarlo en sistemas operativos Windows y dispositivos varios.

En el caso que nos ocupa, la Raspberry Pi, tenemos toda la información necesaria para ponerla en marcha en [https://telegra.ph/BOBcera-juegos-BOB--Batocera-RaspberryPCWin-08-16](https://telegra.ph/BOBcera-juegos-BOB--Batocera-RaspberryPCWin-08-16) en ese caso no haremos uso de docker ni docker-compose sino que grabaremos la imagen en una tarjeta microSD, la introduciremos en la Raspberry Pi y ya estaremos listos/as para jugar.

<p class="callout warning">A la hora de descargar el fichero NO DESCARGUES TODO. Selecciona del fichero torrent únicamente aquello que se corresponda al dispositivo y/o sistema operativo que necesites.</p>

El fichero .torrent, a fecha de escribir este texto son 800GB, por ello, a la hora de ponerlo a descargar selecciona que se descargue únicamente lo que necesites. Mita la siguiente imagen:

[![multibob-que-descargar.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/multibob-que-descargar.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/multibob-que-descargar.png)

*Imagen obtenida de https://telegra.ph/BOBcera-juegos-BOB--Batocera-RaspberryPCWin-08-16*

# 3.5 Pi-hole. Privacidad en la navegación

[![pihole-logo.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/pihole-logo.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/pihole-logo.png)

*Imagen obtenida de https://github.com/pi-hole/docker-pi-hole/*

## Esta herramienta sirve para...

navegar por internet con menos publicidad y evitar muchos sistemas de rastreo. Encontrarás una solución similar en el capítulo [3.16 Adguard](https://libros.catedu.es/books/raspberry-pi/page/316-adguard-navega-por-internet-sin-anuncios-y-con-seguridad "3.16 Adguard. Navega por Internet sin anuncios y con seguridad").

## Web de proyecto y otros enlaces de interés

Web del proyecto: [https://pi-hole.net/](https://pi-hole.net/)

Repositorio de código: [https://github.com/pi-hole/docker-pi-hole/](https://github.com/pi-hole/docker-pi-hole/)

Documentación instalación con docker-compose: [https://github.com/pi-hole/docker-pi-hole/#quick-start](https://github.com/pi-hole/docker-pi-hole/#quick-start)

## Despliegue

<p class="callout info">Si crees que instalar portainer del modo que a continuación se explica es complicado puedes instalarlo a través del método que explicamos en el [capítulo 3.3 Linux Media Delivery System (LMDS)](https://libros.catedu.es/books/raspberry-pi/page/33-linux-media-delivery-system-lmds-centro-de-descargas "3.3 Linux Media Delivery System (LMDS). Centro de descargas"). No te librará de utilizar la terminal pero quizás te resulte mas amigable.</p>

Si accedemos al repositorio de código encontraremos directamente el fichero docker-compose.yml que necesitamos en [https://github.com/pi-hole/docker-pi-hole/#quick-start](https://github.com/pi-hole/docker-pi-hole/#quick-start) pero antes de crear el fichero haremos lo siguiente:

```bash
cd $HOME
mkdir pi-hole
cd pi-hole
nano docker-compose.yml
```

y dentro de este fichero copiaremos el contenido de la url anterior:

```yaml
version: "3"

# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/
services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    # For DHCP it is recommended to remove these ports and instead add: network_mode: "host"
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "67:67/udp" # Only required if you are using Pi-hole as your DHCP server
      - "8088:80/tcp"
    environment:
      TZ: 'Europe/Madrid'
      WEBPASSWORD: 'VUESTRA-CLAVE'
    # Volumes store your data between container upgrades
    volumes:
      - './etc-pihole:/etc/pihole'
      - './etc-dnsmasq.d:/etc/dnsmasq.d'
    #   https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
    cap_add:
      - NET_ADMIN # Required if you are using Pi-hole as your DHCP server, else not needed
    restart: unless-stopped
```

como en ocasiones anteriores, para guardar los cambios pulsaremos `control + x` y cuando nos pregunte aceptaremos. Una vez volvamos a estar en el terminal, escribiremos `docker compose up -d` para lanzar los servicios ubicados dentro del fichero docker-compose.yml. Veremos algo como:

[![pihole-deploy.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/pihole-deploy.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/pihole-deploy.png)

<p class="callout info">En el fichero docker-compose.yml puedes descomentar la línea WEBPASSWORD quitando el símbolo # inicial y, a continuación, establecer una contraseña de acceso que tu definas.</p>

## Funcionamiento

Lo más fácil y sencillo para hacer uso de esta herramienta es que en la configuración de la conexión de nuestros dipositivos (móviles, ordenadores, TVs,...) establezcamos como DNS primario la IP de nuestra raspberry. De este modo, cuando los dispositivos antes mencionados se conecten a internet nuestra Raspberry Pi a través de Pi-Hole actuará como servidor DNS y evitaremos una gran cantidad de publicidad y de rastreo en internet.

Si queremos ver las posibiliades de la herramienta accederemos a través del navegador la Raspberry Pi y al servicio Pi-hole del siguiente modo `http://<IP>:puerto` en mi caso tengo configurada la raspberry Pi con la IP `192.168.0.201` y Pi-hole con el puerto `8088` por lo que escribo `http://192.168.0.201:8088` y así accedo a la interface web.

*[![pi-hole-web.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/pi-hole-web.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/pi-hole-web.png)*

*Elaboración propia*

A continuación accedemos al panel de administración pinchando en el enlace que aparece. Vuestra contraseña será la que hayáis establecido en el fichero docker-compose en el atributo WEBPASSWORD.

[![pi-hole-user-pass.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/pi-hole-user-pass.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/pi-hole-user-pass.png)

*Elaboración propia*

Tras poner el usuario y contraseña accederéis al panel de control

[![pi-hole-dashboard.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/pi-hole-dashboard.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/pi-hole-dashboard.png)

*Elaboración propia*

Una vez que estéis un rato navegando por internet en los dispositivos en los que habéis cambiado el DNS empezaréis a ver la gran cantidad de información que bloquea. También podréis ver cuándo y a qué sitios se conecta qué dispositivo.

*[![pi-hole-dashboard-data.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/pi-hole-dashboard-data.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/pi-hole-dashboard-data.png)*

*Elaboración propia*

<p class="callout info">Lo que os he contado con anterioridad es el uso más básico de este servicio. Os animo a leer en la documentación y en manuales sus diferentes posibilidades a fin de sacarle el máximo jugo posible.</p>

# 3.6 ¿IP dinámica? No hay problema. DuckDNS

[![ducky_icon.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/ducky-icon.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/ducky-icon.png)

*Imagen obtenida de https://www.duckdns.org/*

## Esta herramienta sirve para...

facilitarnos el acceder a nuestra red de casa desde fuera de la misma.

Vamos a aclarar la afirmación anterior. Nuestro router (que conecta la red de nuestro domicilio con la red del exterior) tiene una IP en esa red exterior que va cambiando con el tiempo salvo que tengamos contratado con nuestro ISP el servicio de IP fija. Dado que aprenderse una IP es complicado y dado que ese dato cambia con el tiempo el servicio de duckdns es muy interesante pues nos permite "ponerle nombre" a nuestra IP ([DNS](https://es.wikipedia.org/wiki/Sistema_de_nombres_de_dominio "DNS")) ya que es más sencillo aprenderse pabloruizsoria.duckdns.org que 148.3.110.57 que, como hemos dicho, cambia con el tiempo. Este servicio no solo va a "poner nombre" a nuestra IP sino que va a hacer que cuando nuestra IP cambie el nombre pase a apuntar al nuevo valor de la IP.

Estaríamos hablando de un servicio [DDNS](https://es.wikipedia.org/wiki/DNS_din%C3%A1mico "DDNS") (DNS dinámico)

## Web de proyecto y otros enlaces de interés

Web de duck DNS: [https://www.duckdns.org/](https://www.duckdns.org/)

Repositorio que usaremos para instalar este servicio: [https://github.com/linuxserver/docker-duckdns](https://github.com/linuxserver/docker-duckdns)

## Despliegue

Primero deberemos acceder a la web [https://www.duckdns.org/](https://www.duckdns.org/) aquí crearemos un subdominio con el nombre que nos interese. De esta web nos interesará tanto el nombre del subdominio como el campo token que aparece en pantalla.

[![duckdns-dashboard.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/duckdns-dashboard.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/duckdns-dashboard.png)

*Elaboración propia*

Después, como con servicios anteriores, accedemos a la terminal y escribimos

```bash
cd $HOME
mkdir duckdns
cd duckdns
nano docker-compose.yml
```

Dentro del fichero escribimos el siguiente contenido

```yaml
version: "2.1"
services:
  duckdns:
    image: lscr.io/linuxserver/duckdns:latest
    container_name: duckdns
    environment:
      - PUID=1000 #optional
      - PGID=1000 #optional
      - TZ=Etc/UTC #optional
      - SUBDOMAINS=subdomain1_que_hayas_configurado,subdomain2_que_hayas_configurado
      - TOKEN=token_que_aparece_en_la_web_duckdns_mira_mi_imagen
      - LOG_FILE=false #optional
    volumes:
      - /path/to/appdata/config:/config #optional
    restart: unless-stopped
```

Para salir del fichero pulsaremos `control + x` y guardaremos los cambios. Posteriormente ponemos en marcha los contenedores con `docker compose up -d` Aparecerá en pantalla algo similar a

[![duckdns-deploy.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/duckdns-deploy.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/duckdns-deploy.png)

*Elaboración propia*

## Funcionamiento

Si ahora accedéis a [https://www.duckdns.org/](https://www.duckdns.org/) veréis que en el subdominio que acabáis de crear tiene un valor en current ip y que se ha actualizado hace poco.

# 3.7 WireGuard. Servidor de VPN

[![wireguard-logo.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/wireguard-logo.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/wireguard-logo.png)

*Imagen obtenida de https://www.wireguard.com/*

## Esta herramienta sirve para...

crear una [VPN](https://es.wikipedia.org/wiki/Red_privada_virtual "VPN") de un modo extremadamente sencillo.

> Genial Pablo pero... ¿¡¿¡ para que quiero yo una VPN ?!?!

Hasta el momento hemos ido desplegando diferentes servicios a los que hemos asignado diferentes puertos y cuando nos hemos querido conectar a ellos hemos escrito la IP que tiene la Raspberry Pi **<span style="text-decoration: underline;">dentro</span> de nuestra red** y el puerto que le hemos asignado en el fichero docker-compose. Ahora bien, es bastante probable que también queramos acceder a estos servicios desde **<span style="text-decoration: underline;">fuera</span> de nuestra red**. Aquí básicamente se nos abren 2 posibilidades:

1. Acceder al router y "abrir" puertos.
2. Crear una VPN y conectarnos a ella.

Vamos a optar por la segunda opción por seguridad y comodidad. Al conectarnos a la VPN que creemos será como si estuviésemos conectados a la red de casa por lo que para conectarnos a nuestros servicios seguiremos utilizando la misma IP y puerto que en nuestro domicilio. Con ello conseguimos exponer menos puertos de nuestro router al exterior (**seguridad**) y no tener que configurar nada en el router ni aprender nada (**comodidad**).

## Web de proyecto y otros enlaces de interés

Web del proyecto: [https://www.wireguard.com/](https://www.wireguard.com/)

Repositorio de código que podemos utilizar: [https://github.com/linuxserver/docker-wireguard](https://github.com/linuxserver/docker-wireguard)

## Despliegue

Como en ocasiones anteriores vamos a hacer con docker-compose para ello accedemos al terminal y escribimos

```bash
cd $HOME
mkdir wireguard
cd wireguard
nano docker-compose.yml
```

y dentro del fichero escribiremos el siguiente contenido

```
version: "2.1"
services:
  wireguard:
    image: lscr.io/linuxserver/wireguard:latest
    container_name: wireguard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Madrid
      - SERVERURL=vuestrodominio.duckdns.org #optional
      - SERVERPORT=51820 #optional
      - PEERS=1 #optional. Numero de personas que se vayan a conectar a la VPN
      - PEERDNS=auto #optional
      - INTERNAL_SUBNET=10.13.13.0 #optional
      - ALLOWEDIPS=0.0.0.0/0 #optional
      - PERSISTENTKEEPALIVE_PEERS= #optional
      - LOG_CONFS=true #optional
    volumes:
      - ./config:/config
      - /lib/modules:/lib/modules #optional
    ports:
      - 51820:51820/udp
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    restart: unless-stopped
```

como en ocasiones anteriores, para guardar los cambios pulsaremos control + x y cuando nos pregunte aceptaremos. Una vez volvamos a estar en el terminal, escribiremos `docker compose up -d` para lanzar los servicios ubicados dentro del fichero docker-compose. El resultado será similar a:

[![wireguard-deploy.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/wireguard-deploy.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/wireguard-deploy.png)

*Elaboración propia*

## Funcionamiento

Si prestamos atención al fichero docker-compose veremos que, en el apartado `volumes`, hemos creado uno volumen llamado `config`. Si desde `$HOME/wireguard` listamos el contenido del directorio con `ls -l` veremos que hay un directorio llamado config. Si accedemos al mismo `cd config` y listamos el contendio veremos que se han creado tantas carpetas `peerX` como PEERS hayamos establecido en el fichero docker-compose. En mi caso tengo 3. Si accedemos a una de esas carpetas dentro hay 2 ficheros relevantes los ficheros peerx.conf y peerx.png. El 1º tiene la configuración del fichero para conectarnos a la VPN con esos datos y el 2º tiene una imagen con un código QR que, una vez escaneado, nos configura directamente la VPN.

[![wireguard-commands.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/2FOwireguard-commands.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/2FOwireguard-commands.png)

*Elaboración propia*

### Configuración desde el teléfono móvil

Desde nuestro teléfono Android accedemos a [https://play.google.com/store/apps/details?id=com.wireguard.android](https://play.google.com/store/apps/details?id=com.wireguard.android) e instalamos el cliente de VPN. Una vez instalada la APP pulsamos en el símbolo + y seleccionamos escanear desde código QR. Escaneamos el fichero png comentado en el párrafo anterior y ya está configurada la conexión. Ahora, cada vez que queramos conectarnos a nuestra VPN desde fuera de nuestra red activaremos la VPN y estaremos a todos los efectos conectados a nuestra red. Dejo una serie de capturas de pantalla del proceso.

[![wireguard-add.jpg](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/wireguard-add.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-03/wireguard-add.jpg)

*Elaboración propia*

[![wireguard-escanear-qr.jpg](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/wireguard-escanear-qr.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-03/wireguard-escanear-qr.jpg)

*Elaboración propia*

[![wireguard-rename.jpg](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/wireguard-rename.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-03/wireguard-rename.jpg)

*Elaboración propia*

[![wireguard-activado.jpg](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/wireguard-activado.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-03/wireguard-activado.jpg)

*Elaboración propia*

Una vez hechos todos los pasos anteriores **y con la VPN activa** únicamente deberemos introducir en el navegador la IP que tiene nuestra Raspberry **en nuestra red local** y el puerto del servicio al que queramos acceder. De este modo nos estaremos conectando a este servicio desde fuera de nuestra red como si estuviéramos en ella.

# 3.8 Duplicati. Gestión de copias de seguridad

[![duplicati-fb-share-v1.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/duplicati-fb-share-v1.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/duplicati-fb-share-v1.png)

*Imagen obtenida de https://www.duplicati.com/*

## Esta herramienta sirve para...

Crear copias de seguridad

## Web de proyecto y otros enlaces de interés

Web del proyecto: [https://www.duplicati.com/](https://www.duplicati.com/)

Repositorio de código: https://github.com/linuxserver/docker-duplicati

## Despliegue

Como en ocasiones anteriores vamos a hacer con docker-compose para ello accedemos al terminal y escribimos

```bash
cd $HOME
mkdir duplicati
cd duplicati
nano docker-compose.yml
```

y dentro del fichero escribiremos el siguiente contenido

```
version: "2.1"
services:
  duplicati:
    image: lscr.io/linuxserver/duplicati:latest
    container_name: duplicati
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Madrid
      - CLI_ARGS= #optional
    volumes:
      - ./config:/config
      - ./backups:/backups
      - ./source:/source
    ports:
      - 8200:8200
    restart: unless-stopped
```

como en ocasiones anteriores, para guardar los cambios pulsaremos `control + x` y cuando nos pregunte aceptaremos. Una vez volvamos a estar en el terminal, escribiremos `docker compose up -d` para lanzar los servicios ubicados dentro del fichero docker-compose.yml. El resultado será similar al siguiente:

[![duplicati-deploy.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/duplicati-deploy.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/duplicati-deploy.png)

*Elaboración propia*

Si accedéis en vuestro navegador a la IP de la raspberry y al puerto que hemos establecido (8200). En mi caso sería [http://192.168.0.201:8200](http://192.168.0.201:8200) deberíais ver algo como:

[![dupliciti-web.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/dupliciti-web.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/dupliciti-web.png)

*Elaboración propia*

## Funcionamiento

Vamos a crear una nueva copia de seguridad. Para ello, a modo de ejemplo, voy a crear una copia de seguridad de lo que tengo en un servidor web propio dónde alojo mi proyecto personal [trivinet.com](https://www.trivinet.com/ "trivinet.com") (y que aprovecho la ocasión para recomendaros lo probéis con vuestro alumnado). De este servidor ya creo copias de seguridad y las saco a una Raspberry Pi diferente pero ahora voy a hacerlo de este modo. Vamos allá.

Seleccionaré la opción `Añadir copia de seguridad` y después `Configurar nueva copia de seguridad` para terminar pulsando `Siguiente`:

[![duplicati-1.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/duplicati-1.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/duplicati-1.png)

*Elaboración propia*

En esta pantalla estableceré el `nombre` que quiero darle a la copia de seguridad y si quiero `cifrar` la misma. Terminaré pulsando `Siguiente`:

[![duplicati-2.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/duplicati-2.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/duplicati-2.png)

*Elaboración propia*

En esta pantalla voy a indicarle el destino dónde quiero dejar la copia de seguridad. En este caso quiero conectarme a una máquina remota a través del protocolo SSH. Para ello debo darle la dirección de la máquina a la que voy a conectarme (IP y puerto), de igual modo debo indicar que ruta debe copiar y unas credenciales de acceso. Para asegurarme de que duplicati puede acceder pulsaré en conexión de prueba y una vez compruebe que todo es correcto seleccionaré siguiente:

[![duplicati-3.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/duplicati-3.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/duplicati-3.png)

*Elaboración propia*

Ahora debo elegir qué quiero copiar de mi máquina. Tengo la posibilidad de filtrar y expluir aquellos ficheros que no me interese copiar. Una vez seleccionado pulsaremos siguiente.

Ahora nos encontramos en la pantalla en la cual estableceremos las fechas y horas en las que queremos que se lleve a cabo la copia de seguridad. Una vez establecido aquello que nos interese pulsaremos siguiente.

Ya nos encontramos en la última pantalla en la cual podemos establecer una serie de opciones generales y avanzadas. Tras marcar aquello que nos interese seleccionaremos Guardar.

Si todo ha sido satisfactorio veremos ahora en la pantalla de inicio que se ha creado una tarea con los datos que hemos ido marcado,

[![duplicati-4.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/duplicati-4.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/duplicati-4.png)

*Elaboración propia*

<p class="callout warning">Recuerda que debes comprobar periódicamente que las copias de seguridad se están realizando. Además debes probar, también periódicamente, que las mismas contienen los datos que quieres guardar y que son funcionales. No quieras descubrir en un momento de necesidad y aquellos que creías que estaba sucediendo correctamente estab ocurriendo o no.</p>

# 3.9 File Browser. Explorador de ficheros en remoto

*[![filebrowser-logo.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/filebrowser-logo.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/filebrowser-logo.png)*

*Imagen obtenida de [https://github.com/filebrowser/filebrowser](https://github.com/filebrowser/filebrowser "filebrowser")*

## Esta herramienta sirve para...

gestionar carpetas y directorios a partir de una interface gráfica.

## Web de proyecto y otros enlaces de interés

Página web del proyecto: [https://filebrowser.org/](https://filebrowser.org/)

Repositorio de código: [https://github.com/filebrowser/filebrowser](https://github.com/filebrowser/filebrowser)

## Puesta en marcha

Como en ocasiones anteriores vamos a hacer con docker-compose para ello accedemos al terminal y escribimos

```bash
cd $HOME
mkdir file-browser
cd file-browser
nano docker-compose.yml
```

y dentro del fichero escribiremos el siguiente contenido

```
version: "3"

services:
  filebrowser:
    image: hurlenko/filebrowser
    user: "1000:1000"
    ports:
      - 8080:8080
    volumes:
      - /:/data
      - ./config:/config
    environment:
      - FB_BASEURL=/filebrowser
    restart: always

```

como en ocasiones anteriores, para guardar los cambios pulsaremos `control + x` y cuando nos pregunte aceptaremos. Una vez volvamos a estar en el terminal, escribiremos `docker compose up -d` para lanzar los servicios ubicados dentro del fichero docker-compose. El resultado será similar al siguiente:

[![file-browser-deploy.png.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/file-browser-deploy-png.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/file-browser-deploy-png.png)

*Elaboración propia*

Si ahora accedemos al servicio como venimos haciendo veremos algo similar a:

[![file-browser-admin.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/file-browser-admin.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/file-browser-admin.png)

*Elaboración propia*

El usuario y contraseña por defecto es `admin`.

<span style="color: rgb(34, 34, 34); font-size: 2.8275em; font-weight: 400;">Funcionamiento</span>

Una vez que hemos accedido con el usuario y contraseña por defecto accederemos a un entorno similar al que nos presenta Google Drive y a través del cuál podremos ver el contenido de nuestros directorios, crear ficheros, gestionar usuarios y sus permisos,... también podemos cambiarlo a castellano si nos es necesario.

[![filebrowser-home.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/filebrowser-home.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/filebrowser-home.png)

*Elaboración propia*

Con esta solución podemos resolver los espacios de almacenamiento gratuito que a día de hoy presentan soluciones como google drive y sus 15 GB gratuitos. En mi caso, conectado a la Raspberry Pi, tengo conectado un disco duro de 4TB en al cual almaceno una copia de seguridad de mis fotos, películas, series,...

<p class="callout info">En caso de que tengas problemas de almacenamiento en tu cuenta personal y gratuita de Google puedes hacer una copia de seguridad de tus datos con Google Takeout y una vez que tienes esos datos en tu poder puedes borrarlos de Google volviendo a conseguir espacio. Con soluciones como la que hemos visto en este apartado y en el siguiente podrás acceder a tu contenido multimedia sin limitaciones de espacio y sin pagar suscripciones.</p>

# 3.10 PhotoPrism. Alternativa a las nubes de fotos

[![photoprism-logo.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/photoprism-logo.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/photoprism-logo.png)

*Imagen obtenida de https://www.photoprism.app/*

## Esta herramienta sirve para...

gestionar tu contenido multimedia de un modo avanzado. Haciendo uso de la demo [https://demo.photoprism.app/library/browse](https://demo.photoprism.app/library/browse) podrás hacerte una idea de sus posibilidades.

## Web de proyecto y otros enlaces de interés

Web: [https://www.photoprism.app/](https://www.photoprism.app/)

Repositorio: [https://github.com/photoprism/photoprism](https://github.com/photoprism/photoprism)

## Puesta en marcha

Como en ocasiones anteriores vamos a hacer con docker-compose para ello accedemos al terminal y escribimos

```bash
cd $HOME
mkdir photoprism
cd photoprism
nano docker-compose.yml
```

y dentro del fichero copiaremos el siguiente contenido (adaptado del fichero visto en [https://dl.photoprism.app/docker/docker-compose.yml](https://dl.photoprism.app/docker/docker-compose.yml) ):

```
version: '3.5'

services:
  photoprism:
    image: photoprism/photoprism:latest
    depends_on:
      - mariadb
    ## Don't enable automatic restarts until PhotoPrism has been properly configured and tested!
    ## If the service gets stuck in a restart loop, this points to a memory, filesystem, network, or database issue:
    ## https://docs.photoprism.app/getting-started/troubleshooting/#fatal-server-errors
    # restart: unless-stopped
    security_opt:
      - seccomp:unconfined
      - apparmor:unconfined
    ports:
      - "2342:2342" # HTTP port (host:container)
    environment:
      PHOTOPRISM_ADMIN_USER: "admin"                 # superadmin username
      PHOTOPRISM_ADMIN_PASSWORD: "insecure"          # initial superadmin password (minimum 8 characters)
      PHOTOPRISM_AUTH_MODE: "password"               # authentication mode (public, password)
      PHOTOPRISM_SITE_URL: "http://photoprism.me:2342/"  # server URL in the format "http(s)://domain.name(:port)/(path)"
      PHOTOPRISM_ORIGINALS_LIMIT: 5000               # file size limit for originals in MB (increase for high-res video)
      PHOTOPRISM_HTTP_COMPRESSION: "gzip"            # improves transfer speed and bandwidth utilization (none or gzip)
      PHOTOPRISM_LOG_LEVEL: "info"                   # log level: trace, debug, info, warning, error, fatal, or panic
      PHOTOPRISM_READONLY: "false"                   # do not modify originals directory (reduced functionality)
      PHOTOPRISM_EXPERIMENTAL: "false"               # enables experimental features
      PHOTOPRISM_DISABLE_CHOWN: "false"              # disables updating storage permissions via chmod and chown on startup
      PHOTOPRISM_DISABLE_WEBDAV: "false"             # disables built-in WebDAV server
      PHOTOPRISM_DISABLE_SETTINGS: "false"           # disables settings UI and API
      PHOTOPRISM_DISABLE_TENSORFLOW: "false"         # disables all features depending on TensorFlow
      PHOTOPRISM_DISABLE_FACES: "false"              # disables face detection and recognition (requires TensorFlow)
      PHOTOPRISM_DISABLE_CLASSIFICATION: "false"     # disables image classification (requires TensorFlow)
      PHOTOPRISM_DISABLE_RAW: "false"                # disables indexing and conversion of RAW files
      PHOTOPRISM_RAW_PRESETS: "false"                # enables applying user presets when converting RAW files (reduces performance)
      PHOTOPRISM_JPEG_QUALITY: 85                    # a higher value increases the quality and file size of JPEG images and thumbnails (25-100)
      PHOTOPRISM_DETECT_NSFW: "false"                # automatically flags photos as private that MAY be offensive (requires TensorFlow)
      PHOTOPRISM_UPLOAD_NSFW: "true"                 # allows uploads that MAY be offensive (no effect without TensorFlow)
      # PHOTOPRISM_DATABASE_DRIVER: "sqlite"         # SQLite is an embedded database that doesn't require a server
      PHOTOPRISM_DATABASE_DRIVER: "mysql"            # use MariaDB 10.5+ or MySQL 8+ instead of SQLite for improved performance
      PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"     # MariaDB or MySQL database server (hostname:port)
      PHOTOPRISM_DATABASE_NAME: "photoprism"         # MariaDB or MySQL database schema name
      PHOTOPRISM_DATABASE_USER: "photoprism"         # MariaDB or MySQL database user name
      PHOTOPRISM_DATABASE_PASSWORD: "insecure"       # MariaDB or MySQL database user password
      PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App"
      PHOTOPRISM_SITE_DESCRIPTION: ""                # meta site description
      PHOTOPRISM_SITE_AUTHOR: ""                     # meta site author
    working_dir: "/photoprism" # do not change or remove
    ## Storage Folders: "~" is a shortcut for your home directory, "." for the current directory
    volumes:
      # "/host/folder:/photoprism/folder"                # Example
      - "~/Pictures:/photoprism/originals"               # Original media files (DO NOT REMOVE)
      # - "/example/family:/photoprism/originals/family" # *Additional* media folders can be mounted like this
      # - "~/Import:/photoprism/import"                  # *Optional* base folder from which files can be imported to originals
      - "./storage:/photoprism/storage"                  # *Writable* storage folder for cache, database, and sidecar files (DO NOT REMOVE)

  ## Database Server (recommended)
  ## see https://docs.photoprism.app/getting-started/faq/#should-i-use-sqlite-mariadb-or-mysql
  mariadb:
    ## If MariaDB gets stuck in a restart loop, this points to a memory or filesystem issue:
    ## https://docs.photoprism.app/getting-started/troubleshooting/#fatal-server-errors
    restart: unless-stopped
    image: mariadb:10.10
    security_opt: # see https://github.com/MariaDB/mariadb-docker/issues/434#issuecomment-1136151239
      - seccomp:unconfined
      - apparmor:unconfined
    command: mysqld --innodb-buffer-pool-size=512M --transaction-isolation=READ-COMMITTED --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max-connections=512 --innodb-rollback-on-timeout=OFF --innodb-lock-wait-timeout=120
    ## Never store database files on an unreliable device such as a USB flash drive, an SD card, or a shared network folder:
    volumes:
      - "./database:/var/lib/mysql" # DO NOT REMOVE
    environment:
      MARIADB_AUTO_UPGRADE: "1"
      MARIADB_INITDB_SKIP_TZINFO: "1"
      MARIADB_DATABASE: "photoprism"
      MARIADB_USER: "photoprism"
      MARIADB_PASSWORD: "insecure"
      MARIADB_ROOT_PASSWORD: "insecure"
```

como en ocasiones anteriores, para guardar los cambios pulsaremos `control + x` y cuando nos pregunte aceptaremos. Una vez volvamos a estar en el terminal, escribiremos `docker compose up -d` para lanzar los servicios ubicados dentro del fichero docker-compose. Le va a costar un buen rato extraer las imágenes y empezar el despliegue, paciencia. El resultado será similar al siguiente:

[![photoprism-deploy.png.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/photoprism-deploy-png.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/photoprism-deploy-png.png)

*Elaboración propia*

Se paciente, le cuesta un par de minutos arrancar. Si tras esa breve pausa accedemos al servicio como venimos haciendo, en este caso en el puerto 2342, veremos algo similar a:

[![photoprism-web.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/photoprism-web.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/photoprism-web.png)

*Elaboración propia*

El usuario y contraseña por defecto son `admin` y `insecure`. Fíjate que vienen establecidos en el fichero docker-compose.

<p class="callout warning">Este servicio está al limite en cuanto a la capacidad de la Raspberry Pi 4 modelo B de 4 GB. Valora si la solución que hemos visto en el capítulo anterior es suficiente para ti.</p>

# 3.11 PaperMerge. Gestión documental

[![papermerge-logo.jpg](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/papermerge-logo.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-02/papermerge-logo.jpg)

*Imagen obtenida de https://twitter.com/papermerge*

## Esta herramienta sirve para...

realizar la gestión documental a través de una interface web sencilla de utilizar. Cuenta con [OCR](https://es.wikipedia.org/wiki/Reconocimiento_%C3%B3ptico_de_caracteres "OCR") por lo que podremos buscar textos dentro de estos documentos.

## Web de proyecto y otros enlaces de interés

Página web: [https://papermerge.com/](https://papermerge.com/)

Repositorio de los proyectos que componen esta herramienta [https://github.com/papermerge](https://github.com/papermerge)

## Puesta en marcha

<p class="callout warning">La documentación del proyecto [https://docs.papermerge.io/Installation/docker-compose.html](https://docs.papermerge.io/Installation/docker-compose.html) recomienda no utilizar docker-compose para un sistema en producción.</p>

Como en ocasiones anteriores vamos a hacer con docker-compose para ello accedemos al terminal y escribimos

```bash
cd $HOME
mkdir papermarge
cd papermarge
nano .env
```

y dentro del fichero copiaremos el siguiente contenido:

```
APP_IMAGE=papermerge/papermerge
APP_TAG=latest
PAPERMERGE_JS_IMAGE=papermerge/papermerge.js
PAPERMERGE_JS_TAG=latest

TIMEZONE=Europe/Madrid

DB_USER=postgres
DB_NAME=postgres
DB_PASSWORD=postgres
DB_HOST=db
DB_PORT=5432

USE_HOSTNAME=papermerge.local

REDIS_HOST=redis
REDIS_PORT=6379

SECRET_KEY=12345abcdxyz

SUPERUSER_USERNAME=admin
SUPERUSER_EMAIL=admin@example.com
SUPERUSER_PASSWORD=admin
```

como en ocasiones anteriores, para guardar los cambios pulsaremos `control + x` y cuando nos pregunte aceptaremos.

Hasta ahora nunca habíamos utilizado ningún fichero `.env` pero lo correcto es establecer determinadas configuraciones en los mismos. Los ficheros `.env` son ficheros que no se comparten en el respositorio de código mientras que los ficheros `docker-compose.yml` si. Lo que suele hacerse es compartirse algún fichero como `env-sample` o de nombre similar de modo que cualquier persona pueda ver ahí los parámetros que debe configurar pero sin ver tus valores reales y le basta con renombrarlo a `.env`.

Ahora si. Vamos a crear el fichero `docker-compose.yml` para ello escribimos en el terminal

```bash
nano docker-compose.yml
```

y dentro del fichero copiamos el siguiente contenido:

```yaml
version: '3.7'
# Any top-level key starting with x- in a Docker Compose file will be
# ignored
x-backend: &backend  # yaml anchor definition
  image: ${APP_IMAGE}:${APP_TAG}
  volumes:
    - media_root:/app/media
    - xapian_index:/app/xapian_index
  environment:
    # PAPERMERGE__<section>__<variable>
    - PAPERMERGE__MAIN__SECRET_KEY=${SECRET_KEY}
    - PAPERMERGE__DATABASE__TYPE=postgres
    - PAPERMERGE__DATABASE__USER=${DB_USER}
    - PAPERMERGE__DATABASE__NAME=${DB_NAME}
    - PAPERMERGE__DATABASE__PASSWORD=${DB_PASSWORD}
    - PAPERMERGE__DATABASE__HOST=${DB_HOST}
    - PAPERMERGE__REDIS__HOST=${REDIS_HOST}
    - PAPERMERGE__REDIS__PORT=${REDIS_PORT}
    - PAPERMERGE__MAIN__TIMEZONE=${TIMEZONE}
    # path where xapian index data is stored
    - PAPERMERGE__SEARCH__PATH=/app/xapian_index
    - DJANGO_SUPERUSER_USERNAME=${SUPERUSER_USERNAME}
    - DJANGO_SUPERUSER_EMAIL=${SUPERUSER_EMAIL}
    - DJANGO_SUPERUSER_PASSWORD=${SUPERUSER_PASSWORD}
    - DJANGO_SETTINGS_MODULE=config.settings
services:
  worker: # celery worker
    <<: *backend
    command: worker
  ws_server:  # websockets server / daphne
    <<: *backend
    command: ws_server
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.ws_server.rule=Host(`${USE_HOSTNAME}`) && PathPrefix(`/ws/`)"
  backend:  # rest api backend / uwsgi
    <<: *backend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.backend.rule=Host(`${USE_HOSTNAME}`) && PathPrefix(`/api/`)"
  db:
    image: postgres:14.4
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_DB=${DB_NAME}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
  redis:
    image: 'redis:6'
    ports:
      - '6379:6379'
    volumes:
      - redis_data:/data
  traefik:
    image: "traefik:v2.6"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
  frontend: # emberjs
    image: ${PAPERMERGE_JS_IMAGE}:${PAPERMERGE_JS_TAG}
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.rule=Host(`${USE_HOSTNAME}`) && PathPrefix(`/`)"
volumes:
  postgres_data:
  media_root:
  xapian_index:
  redis_data:
```

como en ocasiones anteriores, para guardar los cambios pulsaremos `control + x` y cuando nos pregunte aceptaremos.

Ahora <span style="text-decoration: underline;">en el equipo desde el que vayamos a acceder al servicio</span> en el terminal escribiremos:

```
sudo nano /etc/hosts
```

Y en dicho fichero añade al final del mismo el texto

```
192.168.0.201       papermerge.local
# En lugar de 192.168.0.201 vosotros/a pondréis la IP de vuestra Raspberry Pi
```

como en ocasiones anteriores, para guardar los cambios pulsaremos `control + x` y cuando nos pregunte aceptaremos.

Una vez volvamos a estar en el terminal <span style="text-decoration: underline;">de la Raspberry Pi</span>, escribiremos `docker compose -f docker-compose.yml --env-file .env up -d` para lanzar los servicios ubicados dentro del fichero docker-compose. Le va a costar un buen rato extraer las imágenes y empezar el despliegue, paciencia. El resultado será similar al siguiente:

[![papermerge-deploy.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/papermerge-deploy.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/papermerge-deploy.png)

*Elaboración propia*

En esta ocasión, aprovechando que hemos modificado el fichero /etc/hosts vamos a acceder a este servicio a través de la dirección [http://papermerge.local](http://papermerge.local) y veremos algo como:

[![papermerge-web.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/papermerge-web.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/papermerge-web.png)

*Elaboración propia*

El usuario y contraseña por defecto son `admin` y `admin`. Fíjate que vienen establecidos en el fichero .env en los valores SUPERUSER\_USERNAME y SUPERUSER\_PASSWORD.

<p class="callout warning">Este servicio está al limite en cuanto a la capacidad de la Raspberry Pi 4 modelo B de 4 GB.</p>

# 3.12 Pi alert. ¿Intrusos en tu red?

[![pialert-logo.jpg](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/pialert-logo.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-02/pialert-logo.jpg)

*Imagen obtenida de https://devpost.com/software/pialert*

<p class="callout warning">Este proyecto lleva mas de 2 años sin ser actualizado</p>

## Esta herramienta sirve para...

detectar nuevos equipos conectados en nuestra red de modo que si aparece algún equipo nuevo del cuál no estamos al tanto detectaremos una conexión no permitida.

## Web de proyecto y otros enlaces de interés

Repositorio de código original: [https://github.com/pucherot/Pi.Alert](https://github.com/pucherot/Pi.Alert)

Imagen que utilizaremos: [https://registry.hub.docker.com/r/jokobsk/pi.alert](https://registry.hub.docker.com/r/jokobsk/pi.alert)

## Despliegue

Como en ocasiones anteriores vamos a hacer con docker-compose para ello accedemos al terminal y escribimos

```bash
cd $HOME
mkdir pialert
cd pialert
nano docker-compose.yml
```

y dentro del fichero escribiremos el siguiente contenido

```yaml
version: "3"
services:
  pialert:
    image: jokobsk/pi.alert
    ports:
      - "20211:20211/tcp"
    environment:
      - TZ=Europe/Madrid
    restart: unless-stopped
    volumes:
      - ./pialert_db:/home/pi/pialert/db
      - ./config/pialert.conf:/home/pi/pialert/config/pialert.conf
```

como en ocasiones anteriores, para guardar los cambios pulsaremos control + x y cuando nos pregunte aceptaremos. Una vez volvamos a estar en el terminal, escribiremos `docker compose up -d` para lanzar los servicios ubicados dentro del fichero docker-compose. Veremos algo similar a:

<span style="background-color: rgb(241, 196, 15);">[![pialert-deploy.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/pialert-deploy.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/pialert-deploy.png)</span>

*Elaboración propia*

Si accedéis en vuestro navegador a la IP de la raspberry y al puerto que hemos establecido (20211). En mi caso sería http://192.168.0.201:20211 deberíais ver algo como:

[![pialert-web.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/pialert-web.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/pialert-web.png)

*Elaboración propia*

## Funcionamiento

Nada mas acceder accederás a una pantalla como la anterior. En la mismas verás 4 partes claramente delimitadas:

- un menú lateral a la izquierda
- una parte central dividida en 3 franjas horizontales: 
    - botonera de dispositivos
    - gráfica con las horas y dispositivos encontrados (conectados y no conectados)
    - listado de elementos encontrados (nombre, tipo, IP, MAC, estado,...)

Del menú lateral nos interesará acceder a la sección de Configuración (Settings).

[![pialert-settings.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/pialert-settings.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/pialert-settings.png)

*Elaboración propia*

En este menú debes prestar especial atención a la opción que dice `Subnets to scan`, es decir, subredes a escanear. En mi caso, la red de mi casa es la 192.168.0.0/24 ¡ojo, lo habitual suele ser 192.168.**1**.0/24! y la interface de red que usa mi raspberry es eth0 de ahí mi configuración. En otras opciones que aparecen mas abajo podéis cambiar el idioma o configurar que os lleguen alertas de intrusión por email, MQTT (lo veremos en el apartado 4 de domótica). Webhooks u otras opciones.

Si pincháis en el nombre de un dispositivo aparecerá una pantalla como la siguiente

[![pialert-device.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/pialert-device.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/pialert-device.png)

*Elaboración propia*

En la cual podréis establecer algunas características del dispositivo como su nombre. Esto os ayudará en el futuro, en las estadísticas, a identificar el dispositivo.

# 3.13 Change detection. Monitoriza cambios en una web

[![changedetection-logo.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/changedetection-logo.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/changedetection-logo.png)

*Imagen obtenida de https://changedetection.io/*

## Esta herramienta sirve para...

que se nos notifique cuando una determinada web (o parte de una web) cambie. Es especialmente útil cuando queremos, por ejemplo, enterarnos de una nueva noticia que aparezca en la web del colegio de nuestros hijos/as o cuando estamos esperando una calificación de un proceso selectivo y no queremos estar accediendo continuamente a la página web a comprobarlo. Este servicio se encarga de monitorizar por nosotros/as la web que le indiquemos y avisarnos si hay cambios.

## Web de proyecto y otros enlaces de interés

Web del proyecto: [https://changedetection.io/](https://changedetection.io/)

Repositorio del proyecto: [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io)

## Despliegue

Como en ocasiones anteriores vamos a hacer con docker-compose para ello accedemos al terminal y escribimos

```bash
cd $HOME
mkdir change-detection
cd change-detection
nano docker-compose.yml
```

y dentro del fichero escribiremos el siguiente contenido

```yaml
version: '3.2'
services:
    changedetection:
      image: ghcr.io/dgtlmoon/changedetection.io
      container_name: changedetection
      hostname: changedetection
      volumes:
        - changedetection-data:/datastore
      ports:
        - 5000:5000
      restart: unless-stopped
volumes:
  changedetection-data:

```

como en ocasiones anteriores, para guardar los cambios pulsaremos control + x y cuando nos pregunte aceptaremos. Una vez volvamos a estar en el terminal, escribiremos `docker compose up -d` para lanzar los servicios ubicados dentro del fichero docker-compose. Veremos algo similar a:

[![changedetection-deploy.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/changedetection-deploy.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/changedetection-deploy.png)

*Elaboración propia*

Si accedéis en vuestro navegador a la IP de la raspberry y al puerto que hemos establecido (5000). En mi caso sería http://192.168.0.201:5000 deberíais ver algo como:

[![changedetection-dashboard.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/changedetection-dashboard.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/changedetection-dashboard.png)

*Elaboración propia*

## Funcionamiento

El funcionamiento es tremendamente sencillo. Por ejemplo, para borrar las 2 páginas webs que vienen monitorizadas por defecto únicamente deberemos marcar los checkboz que aparecen a su izquierda y marcar `delete`.

Si queremos añadir una nueva página a monitorizar es suficiente con introducir una url en el recuadro superior y pulsar `Watch`. Si introducimos una url y pulsamos en `Edit > Watch` entonces tendremos acceso a una pantalla como la siguiente

[![changedetection-create.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/changedetection-create.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/changedetection-create.png)

*Elaboración propia*

en la cual podremos establecer la frecuencia de comprobaciones o las notificaciones a recibir de esta web en concreto.

Si lo preferimos también podemos acceder a la configuración global en el menú superior en la opción de Settings que nos dará acceso a una configuración general de nuestro servicio como vemos a continuación

[![changedetection-settings.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/changedetection-settings.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/changedetection-settings.png)

*Elaboración propia*

<p class="callout warning">Si estableces un chequeo demasiado constante de una página web puede que la web en cuestión te bloquee el acceso a la misma al considerar que estás atacando la web. Sufrirías un *baneo*.</p>

# 3.14 Paperless-ngx. Gestión documental

## [![paperless-logo.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/paperless-logo.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/paperless-logo.png)

*Imagen obtenida de https://docs.paperless-ngx.com/*

## Esta herramienta sirve para...

la gestión documental. Al igual que vimos con PaperMerge, cuenta con OCR.

## Web de proyecto y otros enlaces de interés

Web del proyecto: [https://docs.paperless-ngx.com/](https://docs.paperless-ngx.com/)

Repositorio en github: [https://github.com/paperless-ngx/paperless-ngx](https://github.com/paperless-ngx/paperless-ngx)

## Despliegue

En esta ocasión vamos a variar ligeramente la forma de realizar el despliegue. Dentro del respositorio, la empresa desarrolladora ha creado un script que automatiza la instalación vía docker-compose y, dado que queremos simplicidad, haremos uso del mismo

<p class="callout warning">Cuidado con ejecutar cualquier script que encontréis en internet pues podría ser malicioso. </p>

Vamos allá, accedemos al terminal y escribimos:

```bash
cd $HOME
mkdir paperless
cd paperless
```

y ahora si, lanzamos el script del siguiente modo

```bash
bash -c "$(curl -L https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/install-paperless-ngx.sh)"
```

aparecerá un asistente que nos irá realizando una serie de preguntas para configurar el servicio y que tendrá un aspecto similar a este (remarco en un cuadrado rojo lo que he ido respondiendo):

[![paperless-deploy1.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/paperless-deploy1.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/paperless-deploy1.png)

[![paperless-deploy2.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/paperless-deploy2.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/paperless-deploy2.png)

[![paperless-deploy3.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/paperless-deploy3.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/paperless-deploy3.png)

[![paperless-deploy4.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/paperless-deploy4.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/paperless-deploy4.png)

*Elaboración propia*

Una vez terminemos (le costará un buen rato), como en ocasiones anteriores, accederemos al servicio a través del navegador escribiendo http://nuestra\_ip\_local:puerto En mi caso es [http://192.168.0.201:8000](http://192.168.0.201:8000)

[![paperless-login.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/paperless-login.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/paperless-login.png)

*Elaboración propia*

Si tienes problemas para acceder vuelve al terminal y escribe `docker-compose run --rm webserver createsuperuser` te pedirá que introduzcas un nuevo usuario y contraseña. A continuación tira el servicio con `docker-compose down` y cuando termine vuelve a levantarlo con `docker-compose up -d` . Con esto deberías poder acceder sin problema.

## Funcionamiento

La primera vez que accedas verás un aspecto similar al siguiente:

[![paperless-dashboard.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/paperless-dashboard.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/paperless-dashboard.png)

*Elaboración propia*

La herramienta tiene muchas posibilidades pero quizás lo mas interesante sea acceder a la sección documentos y allí arrastrar aquellos documentos que nos interese conservar (nóminas, facturas de la luz/gas/teléfono,...) Muchos de estos documentos están accesibles mientras somos clientes de una compañía pero dejan de estar a nuestro alcance cuando dejamos de ser clientes y, en ocasiones, nos pueden resultar de utilidad. En la imagen posterior he arrastrado una nómina

[![paperless-documents.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/paperless-documents.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/paperless-documents.png)

*Elaboración propia*

La potencia de la herramienta reside en que gracias a OCR y el sistema de etiquetas que incluye podemos ir almacenando documentos de modo que en el futuro resulte muy fácil encontrar la documentación que nos interese. Así, si en el ejemplo anterior, pulsamos en el lápiz que aparece justo del documento subido a modo de ejemplo podremos configurar una serie de parámetros:

[![paperless-detail.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/cS7paperless-detail.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/cS7paperless-detail.png)

*Elaboración propia*

Una vez clasificados los documentos podemos utilizar el buscador superior o el ubicado en documentos par localizar aquella información que nos interese.

[![paperless-search.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/paperless-search.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/paperless-search.png)

*Elaboración propia*

<p class="callout info">Este servicio es también bastante exigente para el hardware que incorpora una Raspberry Pi modelo 4. De todos modos, recuerda que lo que estamos haciendo con docker y docker-compose sobre la Raspberry Pi puedes replicarlo en cualquier otro sistema operativo que permita su ejecución y con un hardware mas potente.</p>

# 3.15 Jellyfin. Gestión de medios

*[![jellyfin-logo.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/jellyfin-logo.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/jellyfin-logo.png)*

*Imagen obtenida de https://jellyfin.org/*

## Esta herramienta sirve para...

gestionar nuestros ficheros de audio, vídeo, imagen, ebooks,... de un modo muy sencillo a través de una interface web.

## Web de proyecto y otros enlaces de interés

Web oficial [https://jellyfin.org/](https://jellyfin.org/)

Imagen del proyecto en docker hub: [https://hub.docker.com/r/jellyfin/jellyfin/](https://hub.docker.com/r/jellyfin/jellyfin/)

## Despliegue

Como en ocasiones anteriores vamos a hacer con docker-compose para ello accedemos al terminal y escribimos

```bash
cd $HOME
mkdir jellyfin
cd jellyfin
nano docker-compose.yml
```

y dentro del fichero escribiremos el siguiente contenido

```yaml
version: '3.3'
services:
    jellyfin:
        volumes:
            - './config:/config'
            - './cache:/cache'
            - '/direccion/donde/tengais/vuestros/media:/media'
        network_mode: host
        image: 'jellyfin/jellyfin:latest'
        ports:
          - "8089:80"
```

como en ocasiones anteriores, para guardar los cambios pulsaremos control + x y cuando nos pregunte aceptaremos. Una vez volvamos a estar en el terminal, escribiremos `docker compose up -d` para lanzar los servicios ubicados dentro del fichero docker-compose. Veremos algo similar a:

[![jellyfin-deploy.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/jellyfin-deploy.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/jellyfin-deploy.png)

*Elaboración propia*

Si accedéis en vuestro navegador a la IP de la raspberry y al puerto que hemos establecido (8089). En mi caso sería http://192.168.0.201:8096 deberíais ver algo como:

[![jellyfin-home.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/jellyfin-home.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/jellyfin-home.png)

*Elaboración propia*

Ahora es cuestión de ir siguiendo las instrucciones para crear un nuevo usuario y añadir bibliotecas de medios (carpetas dónde están los documentos de tipo media, es decir, vídeos, audios e imágenes). Una vez terminemos aparecerá una pantalla de acceso para introducir un usuario y contraseña.

[![jellyfin-login.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/jellyfin-login.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/jellyfin-login.png)

*Elaboración propia*

<span style="font-size: 2.8275em; font-weight: 400;">Funcionamiento</span>

Si durante la instalación hemos establecido alguna biblioteca de medios al acceder nos aparecerá en la pantalla principal (le costará un rato que aparezca todo el contenido):

[![jellyfin-fome.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/jellyfin-fome.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/jellyfin-fome.png)

*Elaboración propia*

De la pantalla anterior quizás lo mas relevante es la posibilidad de enviar contenido a otros dispositivos como un chromecast, fire tV o algunos modelos de televisores o pantallas táctiles al igual que podemos hacer desde las apps de Netflix, Disney+, HBO,... El botón en cuestión es

[![jellyfin-cast.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/jellyfin-cast.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/jellyfin-cast.png)

*Elaboración propia*

Desde ajustes &gt; Panel de control &gt; Bibliotecas puedes añadir nuevas bibliotecas de medios. Voy a enseñaros lo que podría ser la configuración de una de ellas:

[![jellyfin-add-media.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/jellyfin-add-media.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/jellyfin-add-media.png)

[![jellyfin-add-media2.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/jellyfin-add-media2.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/jellyfin-add-media2.png)

[![jellyfin-add-media3.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/jellyfin-add-media3.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/jellyfin-add-media3.png)

*Elaboración propia*

Tras establecer la nueva biblioteca de medios y regresar al panel de control veremos que ahí empieza a aparecer el contenido relacionado con esta bilioteca de medios:

[![jellyfin-dashboard.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/jellyfin-dashboard.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/jellyfin-dashboard.png)

*Elaboración propia*

<p class="callout info">En mi caso no utilizo un sistema como este pues tengo la raspberry pi conectada a la TV a través de HDMI. También tengo un teclado y un ratón inalámbrico conectados. Cuando quiero ver algo utilizo la aplicación kodi en lugar de este solución.</p>

Y, cuando estoy fuera de casa, conecto la VPN (wireguard) y con kodi desde mi teléfono móvil visualizo el contenido a través de kodi pero esta es también una buena solución.

# 3.16 Adguard. Navega por Internet sin anuncios y con seguridad

*[![adguard-logo.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/adguard-logo.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/adguard-logo.png)*

*Imagen obtenida de https://adguard.com/es/welcome.html*

## Esta herramienta sirve para...

como dicen en su web:

> Bloquea todo tipo de anuncios  
> Elimina elementos web molestos  
> Ahorra tráfico y acelera carga de páginas  
> Funciona para navegadores y aplicaciones  
> Mantiene la funcionalidad y la apariencia de sitios

## Web de proyecto y otros enlaces de interés

Web del proyecto [https://adguard.com/es/welcome.html](https://adguard.com/es/welcome.html)

Repositorio de código: [https://github.com/AdguardTeam/AdGuardHome](https://github.com/AdguardTeam/AdGuardHome)

Imagen docker oficial: [https://hub.docker.com/r/adguard/adguardhome](https://hub.docker.com/r/adguard/adguardhome "https://hub.docker.com/r/adguard/adguardhome")

## Despliegue

En esta ocasión he tenido muchas dudas sobre como recomendaros el despliegue del servicio pues es posible la instalación de un modo muy sencillo a través de cualquiera de estas 3 opciones

- vía **script**: simplemente ejecutando: `curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -v`
- vía **snap** (sistemas linux): en la snap store desde este enlace [https://snapcraft.io/adguard-home](https://snapcraft.io/adguard-home)
- vía **docker**

Por mantener cierta coherencia con lo trabajado en el curso voy a optar por seguir trabajando con docker y docker-compose pero lo cierto es que fuera del curso había sido mi 3ª elección debido a la simplicidad de los otros 2 sistemas. Vamos allá:

Accedemos a la terminal y escribimos

```bash
cd $HOME
mkdir adguard
cd adguard
nano docker-compose.yml
```

Dentro del fichero escribimos el siguiente contenido

```yaml
version: '3.3'
services:
    adguardhome:
        image: adguard/adguardhome
        container_name: adguardhome
        restart: unless-stopped
        volumes:
            - './workdir:/opt/adguardhome/work'
            - './confdir:/opt/adguardhome/conf'
        ports:
            - '53:53/tcp'
            - '53:53/udp'
            - '67:67/udp'
            - '80:80/tcp'
            - '443:443/tcp'
            - '443:443/udp'
            - '3000:3000/tcp'
            - '853:853/tcp'
            - '784:784/udp'
            - '853:853/udp'
            - '8853:8853/udp'
            - '5443:5443/tcp'
            - '5443:5443/udp'
```

Para salir del fichero pulsaremos `control + x` y guardaremos los cambios.

<p class="callout warning">Si algún otro servicio está utilizando los puertos que en este servicio vamos a utilizar se generará un conflicto y puede que ninguno de los servicios funcione o, mas probable, el último que pongamos en marcha.</p>

<p class="callout info">Para usar un puerto diferente puedes cambiar el valor que aparece ANTES de los : por un valor que no esté en uso. También puedes acceder al directorio dónde se encuentra el otro servicio y ejecutar `docker-compose down`.</p>

Posteriormente ponemos en marcha los contenedores con `docker compose up -d`. Si accedemos, como en ocasiones anteriores, a http://IP:PUERTO siendo en mi caso [http://192.168.0.201:3000](http://192.168.0.201:300) veremos algo como:

[![adguard-deployed.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/adguard-deployed.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/adguard-deployed.png)

*Elaboración propia*

## Funcionamiento

Una vez hemos accedido a la pantalla anterior es momento de configurar el servicio a través de la interface gráfica. A través de 5 pasos estableceremos los valores de configuración. No es necesario cambiar nada de la configuración. Si que deberás establecer un usuario y contraseña de acceso. En el paso 4 te dirá como debes configurar tus dispotivios para que adguard pueda hacer su tarea (si ya los tenías configurados con pi-hole no deberás hacer nada adicional). Una vez configurado la interface gráfica te pedirá el usuario y contraseña que has establecido y accederás a un panel de control como el siguiente:

[![adguard-login.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/adguard-login.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/adguard-login.png)

*Elaboración propia*

# 3.17 etc.

Como hemos visto con anterioridad, nuestra Raspberry Pi es un ordenador a todos los efectos y en el mismo tenemos un sistema operativo completo con lo que podemos llevar a cabo cualquier tarea que pueda automatizarse.

Por ejemplo, en mi caso, tengo una raspberry pi 2 model B con raspbian que cada noche a una determinada hora se conecta al servidor web dónde alojo el recurso didáctico [trivinet.com](https://www.trivinet.com/) y copia a la SD de esta raspberry Pi la última copia de seguridad que he hecho en ese servidor web. De este modo tengo la copia de seguridad en 2 ubicaciones distintas por si ocurriese algún desastre.

¿cómo programar tareas para que se ejecuten en fechas/concretas?

En sistemas operativos linux tenemos [cron](https://es.wikipedia.org/wiki/Cron_(Unix)) mientras que en sistemas operativos windows existe una herramienta llamada tareas programadas. En este curso nos centraremos en cómo hacerlo en Rasberry Pi os (anteriormente llamado Rasbian).

Para ver el contenido del fichero cron ejecutaremos el comando `crontab -l` mientras que para editar su contenido ejecutaremos `crontab -e` Pongo a continuación una captura de pantalla del resultado de ejecutar el primer comando visto en la máquina antes mencionada

[![crontab_l.png](https://libros.catedu.es/uploads/images/gallery/2023-02/scaled-1680-/WCAcrontab-l.png)](https://libros.catedu.es/uploads/images/gallery/2023-02/WCAcrontab-l.png)

En la imagen anterior podemos ver varias líneas que comienzan por # estas líneas son comentarios, es decir, cron las ignora. Si nos fijamos en la única línea que tenemos que no comienza por # tenemos lo siguiente

`0 5 * * * /home/pi/scripts/copiaSeguridad.sh`

¿y esto qué significa Pablo? pues que siempre que la fecha y hora sea:

- 0 minutos
- 5 horas
- de cualquier día (numérico)
- de cualquier mes
- de cualquier día de la semana (lunes a domingo)

se ejecutará el comando `/home/pi/scripts/copiaSeguridad.sh` Es decir, yo ahí estoy automatizando el que este comando se ejecute siempre a las 5 de la mañana.

En el siguiente enlace [https://geekflare.com/es/crontab-linux-with-real-time-examples-and-tools/](https://geekflare.com/es/crontab-linux-with-real-time-examples-and-tools/) podemos ver mas información sobre el uso de cron

Una vez que sabemos como programar tareas "únicamente" quedaría la creación del script cuaestión esta que requeriría de un curso por si solo.

<p class="callout info">Te animo a que si tienes un script que crees que puede resultar útil a cualquier compañero/a nos lo facilites a fin de recopilarlo en esta sección. Si por el contrario tienes la necesidad de un script para una tarea concreta háznoslo saber y trataremos de darle solución y publicarlo aquí</p>

# 4 - Posibilidades avanzadas

El objetivo de este capítulo es compartir con vosotros/as alguna cuestión de mayor dificultad a las ya planteadas en capítulos anteriores. Concretamente vamos a ver como montar un alojamiento en la nube similar a lo que vendría siento Google Drive. También vamos a usar nuestra Raspberry Pi para gestionar la domótica de nuestra vivienda y, para terminar, haremos uso de los distintos pines de nuestra Raspbery Pi

# 4.1 NextCloud. Tu nube personal

[![Nextcloud_Logo.svg.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/nextcloud-logo-svg.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/nextcloud-logo-svg.png)

*Imagen obtenida de [https://es.m.wikipedia.org/wiki/Archivo:Nextcloud\_Logo.svg](https://es.m.wikipedia.org/wiki/Archivo:Nextcloud_Logo.svg)*

## Esta herramienta sirve para...

Una vez mas vamos a recurrir a la wikipedia:

> Nextcloud es una serie de programas cliente-servidor que permiten la creación de servicios de alojamiento de archivos. Su funcionalidad es similar al software Dropbox, aunque Nextcloud es en su totalidad software de código abierto. Nextcloud permite a los usuarios crear servidores privados. Su modelo de desarrollo abierto permite añadir y/o modificar la funcionalidad del software del servidor en forma de aplicaciones.
> 
> *https://es.wikipedia.org/wiki/Nextcloud*

Y según lo anterior me podréis decir que en el apartado [3.9 File Browser. Explorador de ficheros en remoto](https://libros.catedu.es/books/raspberry-pi/page/39-file-browser-explorador-de-ficheros-en-remoto "3.9 File Browser. Explorador de ficheros en remoto") ya nos hemos dotado de una muy buena herramienta web que nos permite gestionar nuestros ficheros en remoto. En esta ocasión vamos a ver una herramienta que mejora las posibilidades (y aumenta la complejidad) de la anterior ya que cuenta entre otras con las siguientes características:

> - Los archivos Nextcloud son almacenados en estructuras de directorio convencionales y se pueden acceder a través del protocolo WebDAV si es necesario.
> - Los archivos son encriptados en la transmisión y opcionalmente durante el almacenamiento.
> - Los usuarios pueden manejar calendarios (CalDAV), contactos (CardDAV), tareas programadas y reproducir contenido multimedia (Ampache).
> - Permite la administración de usuarios y grupos de usuarios (vía OpenID o LDAP) y definir permisos de acceso.
> - Posibilidad de añadir aplicaciones (de un solo clic) y conexiones con Dropbox, Google Drive y Amazon S3.
> - Disponibilidad de acceso a diferentes bases de datos mediante SQLite, MariaDB, MySQL, Oracle Database, y PostgreSQL.
> - Disponibilidad de un software llamado Nextcloud box basado en Raspberry Pi que funciona en Ubuntu Core.
> - Posibilidad de integrar los editores en línea ONLYOFFICE mediante la aplicación oficial.
> 
> *https://es.wikipedia.org/wiki/Nextcloud*

que permiten dar un paso adelante con respecto a la solución que con anterioridad habíamos visto.

## Web de proyecto y otros enlaces de interés

Página web obficial del proyecto: [https://nextcloud.com/](https://nextcloud.com/)

Repositorio de código: [https://github.com/nextcloud/server](https://github.com/nextcloud/server)

Instrucciones de instalación en un servidor propio: [https://nextcloud.com/install/#instructions-server](https://nextcloud.com/install/#instructions-server)

## Despliegue

Como en ocasiones anteriores vamos a hacer con docker-compose para ello accedemos al terminal y escribimos

```bash
cd $HOME
mkdir nextcloud
cd nextcloud
nano docker-compose.yml
```

y dentro del fichero escribiremos el siguiente contenido (adaptado de [https://github.com/nextcloud/all-in-one/blob/main/docker-compose.yml](https://github.com/nextcloud/all-in-one/blob/main/docker-compose.yml)):

```
version: "3.7"

volumes:
  nextcloud_aio_mastercontainer:
    name: nextcloud_aio_mastercontainer # This line is not allowed to be changed

services:
  nextcloud:
    image: nextcloud/all-in-one:latest
    restart: always
    container_name: nextcloud-aio-mastercontainer # This line is not allowed to be changed
    volumes:
      - nextcloud_aio_mastercontainer:/mnt/docker-aio-config # This line is not allowed to be changed
      - /var/run/docker.sock:/var/run/docker.sock:ro # May be changed on macOS, Windows or docker rootless. See the applicable documentation. If adjusting, don't forget to also set 'DOCKER_SOCKET_PATH'!
    ports:
      - 80:80 # Can be removed when running behind a web server or reverse proxy (like Apache, Nginx and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
      - 8080:8080
      - 8443:8443 # Can be removed when running behind a web server or reverse proxy (like Apache, Nginx and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md

```

como en ocasiones anteriores, para guardar los cambios pulsaremos `control + x` y cuando nos pregunte aceptaremos.

<p class="callout warning">Si algún otro servicio está utilizando los puertos que en este servicio vamos a utilizar se generará un conflicto y puede que ninguno de los servicios funcione o, mas probable, el último que pongamos en marcha.</p>

<p class="callout info">Para usar un puerto diferente puedes cambiar el valor que aparece ANTES de los : por un valor que no esté en uso. También puedes acceder al directorio dónde se encuentra el otro servicio y ejecutar `docker-compose down`.</p>

Posteriormente ponemos en marcha los contenedores con `docker-compose up -d` (le costará un buen rato).

[![nextcloud-deploy-error.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/nextcloud-deploy-error.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/nextcloud-deploy-error.png)

*Elaboración propia*

En esta ocasión el despliegue nos ha fallado por lo que comentaba en la advertencia anterior. El mensaje de error nos indica que el puerto 8080 ya está en uso. Con `docker ps` voy a ver qué contenedores están utilizando qué puertos:

[![docker-ps.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/docker-ps.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/docker-ps.png)

*Elaboración propia*

Aquí veo que el servicio pihole es quién está usando actualmente ese puerto. Posibles soluciones:

- Detener pi-hole: accedo al directorio dónde está pi-hole y ejecuto `docker-compose down`. Esto hará que deje de funcionar.
- Cambiar en el fichero docker-compose.yml de nextcloud la línea que dice 8080:8080 por, por ejemplo, 8081:8080. Nosotros optaremos por esta segunda opción

tomemos la decisión que tomemos deberemos volver a acceder al directorio de nextcloud y ejecutar `docker-compse up -d`. Si ahora va bien veremos algo como:

[![nextclod-deploy.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/nextclod-deploy.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/nextclod-deploy.png)

*Elaboración propia*

Si accedemos, como en ocasiones anteriores, a http://IP:PUERTO siendo en mi caso [http://192.168.0.201:8081](http://192.168.0.201:8081 "http://192.168.0.201:8081") veremos un mensaje de error que nos indica que utilicemos el protocolo https así pues accederemos a https://IP:PUERTO que en mi caso es [https://192.168.0.201:8081](https://192.168.0.201:8081) es probable que nos aparezca un mensaje de certificado no válido, no hay problema, le indicamos que continúe y veremos algo como:

[![nextcloud-deployed.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/nextcloud-deployed.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/nextcloud-deployed.png)

*Elaboración propia*

## Funcionamiento

Anora la contraseña que genera nextcloud. En mi imagen fíjate que aparece justo encima del botón. Tras acceder llegaremos a una pantalla como la siguiente en la cual deberemos indicar un dominio que apunte a nuestra raspberry pi (podemos utilizar alguno que hayamos configurado con duckdns)

[![nextcloud-login.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/nextcloud-login.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/nextcloud-login.png)

*Elaboración propia*

Podemos trampear este paso si al final de nuestro fichero docker-compose.yml añadimos:

```yaml
    environment:
      SKIP_DOMAIN_VALIDATION: 'true'
```

Para recargar los cambios en el fichero docker-compose.yml deberemos tirar el servicio con `docker-compose down` y volver a levantarlo con `docker-compose up -d`. Si volvemos a acceder a la url anterior veremos algo como:

[![nextcloud-settingup.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/nextcloud-settingup.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/nextcloud-settingup.png)

*Elaboración propia*

Si pulsamos en `start containers` (le costará un buen rato) se pondrá en marcha el servicio y ya podremos disfrutar del mismo.

<p class="callout warning">Quizás una Raspberry Pi modelo 4 de 4 GB, como es mi caso, resulta insuficiente para un servicio tan potente como el descrito. Si ejecutamos el comando `htop` veremos que está saturada a mas no poder.</p>

# 4.2 Haciendo uso del pinout

Llegó el momento de *mancharnos las manos*

<p class="callout danger">Todos los montajes **deben hacerse** con la Raspberry Pi apagada.</p>

## Cuestiones previas

Antes de comenzar a trabajar con la raspberry Pi necesitamos tener claras algunas cuestiones como el pinout del modelo con el que estemos trabajando. Así, el pinout del modelo 4 es el siguiente:

[![GPIO-diagram-Raspberry-Pi-4.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/36Dgpio-diagram-raspberry-pi-4.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/36Dgpio-diagram-raspberry-pi-4.png)

*Imagen obtenida de [https://www.raspberrypi.com/documentation/computers/raspberry-pi.html](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html)*

Una cosa que han hecho muy bien desde Raspberry Pi es mantener la [retrocompatibilidad](https://es.wikipedia.org/wiki/Retrocompatibilidad "retrocompatibilidad") entre modelos así el pinout del modelo 2 B es el mismo que es de este modelo.

<p class="callout info">Para las prácticas que realizaré a continuación utilizaré una Raspberry Pi modelo 2 B. Las mismas deberían ser totalmente compatibles con modelos actuales.</p>

Vamos a hacer uso de resistencias para algunos montajes por ello te dejo a mano el código de colores de las resistencias:

[![pinout-cod-colores.jpg](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/pinout-cod-colores.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-03/pinout-cod-colores.jpg)

*Imagen obtenida de [https://i.ytimg.com/vi/ox8Su0lyFXo/maxresdefault.jpg](https://i.ytimg.com/vi/ox8Su0lyFXo/maxresdefault.jpg)*

También necesitaremos conocer los diferentes segmentos de un display

*[![pinout-display.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/pinout-display.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/pinout-display.png)*

*Imagen obtenida de [https://mvelectronica.com/storage/app/OPTOELECTRONICA/DISPLAY/D7S3A/2.png](https://mvelectronica.com/storage/app/OPTOELECTRONICA/DISPLAY/D7S3A/2.png)*

Lo último que tenemos que tener claro es el patillaje de un diodo LED

*[![pinout-anodo-catodo.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/pinout-anodo-catodo.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/pinout-anodo-catodo.png)*

*Imagen obtenida de [https://ebotics.com/es/actividad/proyecto-no-2-controlar-el-brillo-del-led/](https://ebotics.com/es/actividad/proyecto-no-2-controlar-el-brillo-del-led/)*

También recuerda:

- Ley de Ohm: V = R \* I (Tensión es igual a Resistencia por Intensidad) en sus respectivas unidades: 
    - Tensión se mide en Voltios (V)
    - Resistencia se mide en Ohmios (Ω)
    - Intensidad se mide en amperios (A)
- Un diodo sólo deja pasar la corriente en un determinado sentido por ello verifica que si no se enciende está conectado en la posición correcta (si no luce también puede ser que esté quemado)

## Ejemplo de cálculo

Si queremos actuar sobre algún dispositivo lo haremos a través de los pines que podemos encender y apagar a través del software. Si recurrimos a la [documentación de Raspberry Pi](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html "documentación de Raspberry Pi") indican "*A GPIO pin designated as an output pin can be set to high (3.3V) or low (0V).*" Es decir, cuando establezcamos que un pin está encendido (a HIGH, a 1, son todo sinónimos) significa que estaremos estableciendo que en ese pin hay 3,3V mientras que si establecemos que un pin está apagado (a LOW, a 0, son todo sinónimos) significa que estamos estableciendo que en ese pin hay 0V. Además la corriente máxima con la que pueden funcionar un GPIO en la Raspberry es 16mA.

Así, si queremos utilizar un diodo LED rojo que funciona con 1,7 V y 20mA tendremos un *exceso* de 1,6V (los 3,3V que genera la salida de la Raspberry menos los 1,7V que requiere el LED rojo) ese *exceso* de tensión tendremos que *dárselos* a otro componente para que no se queme el LED por ello en nuestro diseño meteremos una resistencia, que no tendrá mas objetivo que ser ella la que consuma ese *exceso* de 1,6V. ¿Y de cuánto tendrá que ser esa resistencia? Sabemos que en esa resistencia tiene que haber 1,6V y que por ella van a circular 16mA =0,016A (lo ideal sería 20mA pero la Raspberry nos lo limita a 16mA), usamos la Ley de Ohm R=V/I=1,6/0,016 = 100 Ω. Por lo que junto a nuestro led rojo deberemos usar una resistencia de 100 Ω que coincide con un valor standard comercial. Si el valor calculado no coincide con un valor comercial, hay que elegir el inmediato superior (el inferior proporcionaría más corriente y tenemos la limitación de los 16mA de la Raspberry que no queremos quemarlo).

La potencia que "sufrirá" esa resistencia será P= VI = 1.6Vx16mA=27mW por lo tanto cualquier resistencia comercial es válida pues lo mínimo es 1/8W la más común son las 1/4W.

De la misma forma podemos hacer los cálculos para otros colores de Leds, ([aquí para descargar la hoja de cálculo](https://docs.google.com/spreadsheets/d/1bmlsaV8fV8TT1LySV2Mka2byHtnHI3b8/edit?usp=sharing&ouid=103474539184416151174&rtpof=true&sd=true)) pero como podemos ver, algunos colores no funcionarían con la Raspberry pues necesitan más tensión de la que proporciona la Raspberry

[![2023-04-17 14_09_29-Microsoft Excel - calculo-resistencia-led.xlsx.jpg](https://libros.catedu.es/uploads/images/gallery/2023-04/scaled-1680-/2023-04-17-14-09-29-microsoft-excel-calculo-resistencia-led-xlsx.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-04/2023-04-17-14-09-29-microsoft-excel-calculo-resistencia-led-xlsx.jpg)

Fuente de datos Wikipedia [https://es.wikipedia.org/wiki/Circuito\_de\_LED](https://es.wikipedia.org/wiki/Circuito_de_LED)

Normalmente en placas como Arduino trabaja a 5V por lo que las resistencias son mayores :

[![led_1.png](https://libros.catedu.es/uploads/images/gallery/2023-05/scaled-1680-/led-1.png)](https://libros.catedu.es/uploads/images/gallery/2023-05/led-1.png)

*Imagen de [https://todotecnologia-eso.blogspot.com/](https://todotecnologia-eso.blogspot.com/) Licencia CC-BY-SA-NC*

## Encender y apagar un led  


### Materiales

- 1 led
- <span style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);">1 resistencia de 100Ω / 1/4W</span>
- 2 cables
- placa de conexiones

### Conexiones

1. Resistencia al cátodo del led
2. ánodo del led a pin 7 (pin, no GPIO)
3. Resistencia a pin 25 (tierra)

### Programa

Nos dirigiremos a la terminal y allí escribiremos

```bash
nano led.py
```

con ello se abrirá el editor nano y estaremos trabajando sobre el fichero led.py que si no existe se creará y si existe trabajaremos sobre el existente. A continuación escribiremos el código python que aparece a continuación:

```python
# Importamos la biblioteca que nos permite pausar la ejecución del programa
import time
# Importamos la biblioteca que nos permite conectar a los GPIO pins
# otros dispositivos. GPIO -> General Purpose Input Output
import RPi.GPIO as GPIO
# A partir de aquí configuramos la plcada
# 1ero: borramos cualquier configuración previa
GPIO.cleanup()
# 2ndo: establecemos el modo de trabajo de la raspi
GPIO.setmode(GPIO.BOARD)
# 3ero: Indicamos que el pin 7 actuará como salida
GPIO.setup(7,GPIO.OUT)
# Bucle infinito
while True:
  # Escribo en el terminal el texto enciendo
  print("enciendo")
  # Pongo tensión en el pin 7
  GPIO.output(7,GPIO.HIGH)
  # Detengo la ejecución del programa 2 segundos
  time.sleep(2)
  # Escribo en el terminal
  print("apago")
  # Quito la tensión del pin 7
  GPIO.output(7,GPIO.LOW)
  # Pauso la ejecución del programa 2 segundos
  time.sleep(2)
```

para salir del editor pulsaremos `control + x` y aceptaremos los cambios. Tras ello, si ejecutamos `ls -l` veremos listado el directorio en el que nos encontramos y ahí veremos nuestro fichero. Lo ejecutaremos escribiendo `python led.py`

En el terminal veremos algo similar a

[![led-working-terminal.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/led-working-terminal.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/led-working-terminal.png)

*Elaboración propia*

Si las conexiones que hemos realizado son correctas veremos como el led va encendiéndose y apagándose. Para detener la ejecución del programa pulsaremos `control + c`. Dejo a continuación alguna foto del programa funcionando:

[![conexiones-placa.jpg](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/conexiones-placa.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-07/conexiones-placa.jpg)

*Conexiones en la protoboard. Elaboración propia*

[![conexiones-raspy.jpg](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/conexiones-raspy.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-07/conexiones-raspy.jpg)

*Conexiones en la Raspberry Pi. Elaboración propia*

[![led-on.jpg](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/led-on.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-07/led-on.jpg)

*Mensaje de led encendido y led encendido. Elaboración propia*

[![led-off.jpg](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/led-off.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-07/led-off.jpg)

*Mensaje de led apagado y led apagado. Elaboración propia*

## Semáforo  


### Materiales

- 1 led rojo
- 1 led amarillo
- 1 led verde
- <span style="background-color: rgb(255, 255, 255);">1 resistencia de 100 Ω y dos de 82 Ω pero si se utilizan todos de <span style="background-color: rgb(255, 255, 255);"> 100 Ω no pasa nada.</span></span>
- 4 cables
- placa de conexiones

### Conexiones

1. Una resistencia al cátodo de cada led
2. ánodo del led rojo a pin 3 (pin, no GPIO)
3. ánodo del led amarillo a pin 5 (pin, no GPIO)
4. ánodo del led verde a pin 7 (pin, no GPIO)
5. Resistencias a pin 25 (tierra)

### Programa

Al igual que en el caso anterior crearemos el fichero con nano y lo ejecutaremos con python. Esa parte no varía por lo que no me repito. El nombre que le pongáis al programa no es importante.

## [![pinout-programa2.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/pinout-programa2.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/pinout-programa2.png)

*Elaboración propia*

## Display de 7 segmentos

Esta práctica variará en función de si usamos un display de cátodo común o de ánodo común, tenlo en cuenta.

### Materiales

- Display de 7 segmentos
- <span style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);">4 resistencias de 82 Ω o 100 Ω</span>
- 5 cables
- placa de conexiones

### Conexiones

Si utilizas un display de cátodo común serán las siguientes:

- Cátodo del display a pin 25 (tierra)
- Pin 3 a resistencia y esta a segmento f.
- Pin 5 a resistencia y esta a segmento e.
- Pin 7 a resistencia y esta a segmento b.
- Pin 11 a resistencia y esta a segmento c.

Si utilizas un display de ánodo común serán las siguientes:

- Ánodo del display a pin 1 (3,3V)
- Pin 3 a resistencia y esta a segmento f.
- Pin 5 a resistencia y esta a segmento e.
- Pin 7 a resistencia y esta a segmento b.
- Pin 11 a resistencia y esta a segmento c.

### Programa

Al igual que en el caso anterior crearemos el fichero con nano y lo ejecutaremos con python. Esa parte no varía por lo que no me repito. El nombre que le pongáis al programa no es importante.

El programa encenderá un lateral del *display* y luego otro de modo infinito. Te propongo que modifiques el programa y las conexiones para convertir esta práctica en una cuenta atrás.

[![pinout-programa3.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/pinout-programa3.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/pinout-programa3.png)

*Elaboración propia*

## Otras prácticas

Con mi alumnado de FP básica otras prácticas que he llevado a cabo han sido:

- encender el led cuando no hay luz (haciendo uso del LDR)
- un detector de humedad (que suene un sonido y/o se enciende una luz cuando el circuito se cierra con la humedad)

<p class="callout info">En internet existen multitud de prácticas para realizar con la Raspberry Pi.</p>

# 4.3 Domótica

De nuevo vamos a tomar prestada una definición de la wikipedia:

> **Se llama domótica a los sistemas capaces de automatizar una vivienda** o edificación **de cualquier tipo, aportando servicios de gestión energética, seguridad, bienestar y comunicación, y que pueden estar integrados por medio de redes interiores y exteriores de comunicación**, cableadas o inalámbricas, **y cuyo control goza de cierta facilidad, desde dentro y fuera del hogar.** Se podría definir como la integración de la tecnología en el diseño inteligente de un recinto cerrado.
> 
> *https://es.wikipedia.org/wiki/Dom%C3%B3tica*

En nuestro caso, dado que vamos a trabajar con una Raspberry Pi, vamos a ver una solución que yo considero perfecta para este ordenador. Se trata de Home Assintant pero antes de entrar en el meollo de la cuestión vamos a hablar de protocolos.

## Protocolos de comunicación  


> En informática y telecomunicación, **un protocolo de comunicaciones es un sistema de reglas que permiten que dos o más entidades** (computadoras, teléfonos celulares, etc.) **de un sistema de comunicación se comuniquen entre ellas para transmitir información por medio de cualquier tipo de variación de una magnitud física**. Se trata de las reglas o el estándar que define la sintaxis, semántica y sincronización de la comunicación, así como también los posibles métodos de recuperación de errores. Los protocolos pueden ser implementados por hardware, por software, o por una combinación de ambos.
> 
> **También se define como un conjunto de normas que permite la comunicación entre ordenadores**, estableciendo la forma de identificación de estos en la red, la forma de transmisión de los datos y la forma en que la información debe procesarse.
> 
> **Los sistemas de comunicación utilizan formatos bien definidos (protocolo) para intercambiar mensajes. Cada mensaje tiene un significado exacto** destinado a obtener una respuesta de un rango de posibles respuestas predeterminadas para esa situación en particular. Normalmente, el comportamiento especificado es independiente de cómo se va a implementar. Los protocolos de comunicación tienen que estar acordados por las partes involucradas. Para llegar a dicho acuerdo, un protocolo puede ser desarrollado dentro de estándar técnico(...)
> 
> https://es.wikipedia.org/wiki/Protocolo\_de\_comunicaciones

En este punto puede ser que os estéis preguntando por qué os estoy contando qué son los protocolos de comunicaciones. En este apartado vamos a trabajar con distintos *gadget*, sensores, que pueden utilizar diferentes protocolos. Además, algunos de los sensores que voy a comentar funcionan con protocolos que la Raspberry Pi no soporta por lo que requieren de algún hardware adicional. Vamos a enumerar algunos de los protocolos que me parecen mas relevantes de cara a usar domótica en la Raspberry Pi:

- **Wi-Fi**: Soportado directamente por la raspberry pi.
- **Bluetooth**: Soportado directamente por la raspberry pi.
- **Zigbee**: No soportado por la raspberry pi directamente. Se trata de un protocolo de comunicación inalámbrica de bajo consumo. Ideal para dispositivos que requieren comunicaciones seguras con baja tasa de envío de datos y una gran vida útil de sus baterías. Necesita de un adaptador (USB) que conectaremos a la Raspberry Pi y que le dará a la Raspberry la posibilidad de comunicarse a través de este protocolo.
- **MQTT** (alias *mosquito*): es un protocolo de mensajería ligero con un consumo muy bajo de energía. Requiere de un *broker de mensajería*.

### Zigbee

Mi adaptador zigbee-USB, un CC2531*,* lo adquirí por unos 6 € aquí [https://es.aliexpress.com/item/32971386349.html](https://es.aliexpress.com/item/32971386349.html) requiere ser programado (*flasheado*). Se puede flashear "facilmente" con un dispositivo similar a [https://es.aliexpress.com/item/32976509073.html](https://es.aliexpress.com/item/32976509073.html) que cuesta unos 8€ y estando obligados/as a utilizar Windows. También se puede flashear desde la Raspberry Pi utilizando este método [https://www.zigbee2mqtt.io/guide/adapters/flashing/alternative\_flashing\_methods.html](https://www.zigbee2mqtt.io/guide/adapters/flashing/alternative_flashing_methods.html) (yo no lo he probado)

[![domotica-adaptador-zigbee.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/domotica-adaptador-zigbee.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/domotica-adaptador-zigbee.png)

*Imagen obtenida de https://es.aliexpress.com/item/32971386349.html*

<p class="callout warning">Puede ser que el dispositivo que tengas entre tus manos ya esté flasheado si otro compañero/a lo ha flasheado en una edición anterior del curso. Si así lo deseas puedes volver a flashearlo sin dañarlo.</p>

Os dejo un videotutorial que explica como *flashear* el dispositivo por si os animáis a utilizar la tecnología Zigbee. Os dejo también el enlace al vídeo ya que hay veces que no carga incrustado en este manual [https://youtu.be/70Eav-prgMk](https://youtu.be/70Eav-prgMk) En esta página del curso he anexionado (aparecen arriba a la izquierda) también los ficheros necesarios por si en el futuro dejan de estar disponibles en su ubicación actual.

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="315" src="https://www.youtube.com/embed/70Eav-prgMk" title="YouTube video player" width="560"></iframe>

Os dejo alguna foto de las conexiones del proceso de flasheo por si no lo veis correctamente en el vídeo:

[![IMG_20230721_191807.jpg](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/img-20230721-191807.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-07/img-20230721-191807.jpg)

[![IMG_20230721_191825.jpg](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/img-20230721-191825.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-07/img-20230721-191825.jpg)

[![IMG_20230721_191831.jpg](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/img-20230721-191831.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-07/img-20230721-191831.jpg)

[![IMG_20230721_191817.jpg](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/img-20230721-191817.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-07/img-20230721-191817.jpg)

*Elaboración propia*

<p class="callout warning">El ccdebugger en ocasiones le cuesta MUCHO cambiar el led de rojo a verde. Es cuestión de insistir, reiniciar,... La primera vez que lo hice me costó 2 minutos. La segunda vez que lo hice me costó 20 minutos.</p>

Os dejo unas capturas de pantalla del programa de flasheo:

[![antes-flash.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/antes-flash.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/antes-flash.png)

[![post-flash.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/post-flash.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/post-flash.png)

*Elaboración propia*

## Tipos de dispositivos IoT

A la hora de adquirir dispositivos [IoT](https://es.wikipedia.org/wiki/Internet_de_las_cosas "Internet de las cosas") los encontraremos de 2 tipos:

- conectados a la luz
- con batería/pilas

en algunos casos tiene sentido que estén conectados a la luz, es el caso de un termostato de la calefacción o un motor para subir/bajar las persianas, mientras que otros, como un sensor de temperatura o un actuador de radiador, tiene mas sentido que funcionen con batería/pilas en lugar de tener que llevar un enchufe a cada radiador o a cada punto dónde queramos medir

Además de la clasificación anterior, nos encontraremos básicamente dispositivos de 2 tipos: Wi-Fi y Zigbee pero no Bluetooth ¿por qué? por el consumo. Los dispositivos que utilizan el protocolo Bluetooth consumen mucha mas batería que los que usan, por ejemplo, zigbee. Nadie quiere un dispositivo IoT al que tiene que cambiarle las pilas cada mes cuando existe uno equivalente al que puede cambiarle la pila cada 2 años.

## Privacidad

Una cuestión que yo considero MUY importante es el que el acceso a nuestros datos o a la funcionalidad del hardware no requiera de tener acceso a la nube de una determinada empresa por cuestiones ya no solo de privacidad sino por el hecho de que si esa empresa cierra su nube o establece un servicio de pago estamos condenados a pagar o cambiar el dispositivo con las implicaciones medioambientales y económicas que ello supone. Muchos fabricantes, como [tuya](https://www.tuya.com/ "tuya"), plantean que para usar sus dispositivos Zigbee debes adquirir su hub (concentrador) y posteriormente este hub, a través de su app o web, te dará los datos que recopila o te permitirá interactuar con tus dispositivos. Frente a esta filosofía está la posibilidad de utilizar un software propio al que conectemos nuestros dispositivos (WiFi o Zigbee) y de la compañía que queramos (tuya, sonoff,...) sin depender de nubes de terceros. Además, con soluciones como las que hemos visto en el capítulo 3 para la creación de VPNs, podremos acceder a nuestro dispositivo desde cualquier lugar. Por ello en el siguiente apartado vamos a hablar de Home Assistant.

## Home Assistant  


[![hassio-logo.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/hassio-logo.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/hassio-logo.png)

*Imagen obtenida de https://design.home-assistant.io/#brand/logo*

<p class="callout info">Hassio, por si mismo, requeriría de un curso dedicado de una cantidad importante de horas por ello vamos a centrarnos en aquello mas relevante.</p>

Antes de comenzar voy a mostraros mi instalación de Home Assistant con los diferentes sensores, gráficas y automatizaciones que tengo así como por qué empecé a montar este sistema y qué quiero hacer en el futuro.

Inicialmente monté esto para ubicar en cada dormitorio un sensor de temperatura y posteriormete ubicar un actuador de apertura/cierre en cada radiador. La idea era abrir o cerrar cada radiador de modo automático en función de la temperatura de cada estancia. Con posterioridad leí que estos actuadores con tanta apertura/cierre acababan estropeandose y por ello desistí de instalar estos actuadores en los radiadores pero la mecha ya estaba prendida.

En la actualidad tengo los siguientes sensores/actuadores:

- sensor de apertura: en la puerta de entrada a mi domicilio
- sensor de presencia: en la primera estancia a la que se accede desde la puerta de entrada
- sensor de temperatura y humedad en salón
- sensor de temperatura y humedad en el dormitorio principal
- termostato
- sensor de consumo: en el cuadro eléctrico de casa
- sensor de apertura: frigorífico
- receptor/emisor de infrarrojos
- detección de aparatos en red de casa

Todos, excepto el último, funcionan con zigbee mientras que el último hace uso de wifi.

[![hassio-zigbee2mqtt.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/hassio-zigbee2mqtt.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/hassio-zigbee2mqtt.png)

*Elaboración propia*

Estos sensores me permiten obtener valores del instante en que realice la consulta pero también históricos. También me permite actuar directamente sobre los sensores como el termostato. Todo ello se configura en unos dashboards muy sencillos como los que vemos a continuación

[![hassio-overview1.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/hassio-overview1.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/hassio-overview1.png)

*Elaboración propia*

[![hassio-overview2.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/hassio-overview2.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/hassio-overview2.png)

*Elaboración propia*

[![hassio-overview3.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/hassio-overview3.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/hassio-overview3.png)

*Elaboración propia*

A partir de lo anterior se pueden crear diferentes automatizaciones. Por ejemplo yo tengo creadas las siguientes:

- Frigo abierto: Mi frigorífico no tiene sensor avisador si te dejas la puerta abierta por lo que intenté hacer un avisador en caso de que estuviese abierto mas de 10s. Mis hijas arrancaron el sensor antes de ponerlo en marcha.
- Frigo cerrado:
- Puerta de casa abierta: Me manda un mensaje por telegram cada vez la puerta de casa se abre. Lo uso a modo de alarma
- Puerta de casa cerrada:
- Termostato temperatura medida cambió por debajo de 19ºC: Lo tengo creado para pruebas con el termostato

[![hassio-automatizaciones.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/hassio-automatizaciones.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/hassio-automatizaciones.png)

*Elaboración propia*

[![hassio-automatizacion-detalle.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/hassio-automatizacion-detalle.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/hassio-automatizacion-detalle.png)

*Elaboración propia*

Visto lo que yo tengo es momento de empezar por la **instalación**: Home Assistant ([https://www.home-assistant.io/](https://www.home-assistant.io/ "https://www.home-assistant.io/")) puede ser instalado dockerizado o puede ser instalado directamente como un sistema operativo en una tarjeta SD dedicada. En mi caso opto por la 2ª opción pues como vemos en la imagen posterior el hecho de tenerlo instalado de este modo me permite disfrutar de todas las posibilidades de la herramienta.

[![hassio-compare-installation-methods.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/hassio-compare-installation-methods.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/hassio-compare-installation-methods.png)

*Imagen obtenida de https://www.home-assistant.io/installation/*

En la dirección [https://www.home-assistant.io/installation/](https://www.home-assistant.io/installation/) tenemos a nuestra disposición las diferentes formas de instalación. En el caso de elegir la instalación vía sistema operativo descargaremos la imagen y la instalaremos tal como vimos en el [capítulo 2.1.1](https://libros.catedu.es/link/8793#bkmrk-2.1.1-im%C3%A1genes "capítulo 2.1.1"). Os dejo también un tutorial por si os resulta de utilidad *https://domoticaencasa.es/video-tutorial-instalacion-de-home-assistant/*

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="315" src="https://www.youtube.com/embed/Ncg9unb2gZs" title="YouTube video player" width="560"></iframe>

Si vais a trabajar con dispositivos Zigbee necesitaréis conocer qué es Zigbbe2Mqtt por ello os dejo este enlace [https://domoticaencasa.es/video-funciona-mqtt-integrar-home-assistant/](https://domoticaencasa.es/video-funciona-mqtt-integrar-home-assistant/) a un tutorial que explica como funciona y como integrarlo en Home Assistant. Os dejo también un vídeo:

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="315" src="https://www.youtube.com/embed/YPS5xI6Bx3I" title="YouTube video player" width="560"></iframe>

El protocolo MQTT se usa en robótica educativa, por ejemplo [aquí en el curso ESP32 en el Aula con Arduinoblocks](https://libros.catedu.es/books/esp32-en-el-aula/page/mqtt-que-es)

Si te quedas con ganas de mas voy a recomendarte esta serie de 8 vídeos dónde indican como proceder con hassio y zigbee:

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="438" src="https://www.youtube.com/embed/FGTLpdgvfPI" style="width: 780px; height: 438px;" title="YouTube video player" width="780"></iframe>

Una función muy interesante es la de que hassio nos envíe notificaciones en Telegram por ello os dejo un enlace a este tutorial [https://domoticaencasa.es/home-assistant-9-notificaciones-telegram/](https://domoticaencasa.es/home-assistant-9-notificaciones-telegram/) dónde explica como hacerlo. Este canal os puede resultar también de gran utilidad para los servicios que hemos desplegado a lo largo del capítulo 3.

### Integraciones

Si además de las integraciones que pone por defecto a tu disposición Home Assistant quieres hacer uso de otras no oficiales puedes instalar HACS que nos permite acceder a cientos, si no miles, de proyectos que la comunidad ha creado. Para instalar HACS es suficiente con seguir estas instrucciones:

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="439" src="https://www.youtube.com/embed/4-uJjhKU8CE" style="width: 780px; height: 439px;" title="YouTube video player" width="780"></iframe>

# 5 - Bonus track

# 5.1 Establece IP fija a tu Raspberry Pi

Puede resultar interesante que vuestra Raspberry Pi tenga una IP fija dentro de vuestra red en lugar de una variable. Por ello vamos a ver como hacerlo desde la interface gráfica y desde la terminal.

## Desde la interface gráfica

<p class="callout warning">Si tienes instalada interface gráfica es preferible establecer la configuración desde la misma en lugar de usar el terminal.</p>

Si has instalado raspbian con interface gráfica puedes configrar una IP fija siguiendo los siguientes pasos:

[![IMG_20230325_092001.jpg](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/img-20230325-092001.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-03/img-20230325-092001.jpg)

[![IMG_20230325_092646.jpg](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/img-20230325-092646.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-03/img-20230325-092646.jpg)

[![IMG_20230325_092738.jpg](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/img-20230325-092738.jpg)](https://libros.catedu.es/uploads/images/gallery/2023-03/img-20230325-092738.jpg)

*Elaboración propia*

Como vemos en la primera imagen hacemos click derecho encima del símbolo de la red y en la pantalla que se abre elegimos la opción `Wireless & wired network settings` lo que nos dará acceso a una pantalla como la que vemos en último lugar. En esta pantalla deberemos de elegir arriba la interface sobre la que queremos establecer los valores de configuración, en mi caso, al querer establecer esta configuración para la interface cableada elegiré `eth0` pero si queréis establecer IP fija para vuestra wireless deberéis de elegir `wlan0`. A continuación establezco la IP que quiero utilizar en IPv4 Address, en mi caso 192.168.0.201, en Router establezco la IP de mi router, en mi caso 192.168.0.1 y en DNS establezco la IP de quién quiero que actúe como DNS, en mi caso 8.8.8.8 que se trata de un DNS de Google pero lo habitual es establecer también la IP del router o del servicio PI-Hole que hemos configurado con anterioridad y así nos haga de filtro publicitario y de rastreo.

## Desde el terminal

Edita el fichero de configuración dhcpcd.conf con el comando nano /etc/dhcpcd.conf y, al final del fichero, añade las siguientes líneas:

```
interface [TU_INTERFACE]
static_routers=[LA_IP_DE_TU_ROUTER]
static domain_name_servers=[LA_IP_DE_TU_DNS]
static ip_address=[LA_IP_QUE_QUIERES_UTILIZAR]/[LA_MASCARA_DE_RED]
```

en interface escribirás eth0 o wlan0 en función de si quieres configurar, respectivamente, tu interface de red cableada o inalámbrica.

En mi caso el fichero quedaría del siguiente modo:

```
interface eth0
static_routers=192.168.0.1
static domain_name_servers=8.8.8.8
static ip_address=192.168.0.201/24
```

<p class="callout warning">Recuerda que la red de mi domicilio es 192.168.0.0/24 pero que lo habitual es que sea 192.168.1.0/24 por lo que tendrás que adaptar esta configuración a tu realidad</p>

## Mas manuales e información

En esta página web podéis encontrar mas información, en inglés, sobre como establecer una IP estática a vuestra Raspberry Pi en el sistema operativo Raspbian [https://www.tomshardware.com/how-to/static-ip-raspberry-pi](https://www.tomshardware.com/how-to/static-ip-raspberry-pi) Otra información en castellano [https://www.ionos.es/digitalguide/servidores/configuracion/como-asignar-una-ip-fija-a-raspberry-pi/](https://www.ionos.es/digitalguide/servidores/configuracion/como-asignar-una-ip-fija-a-raspberry-pi/)

# Página nueva



# 5.3 Comparte tu disco (Samba)

Puede resultaros de utilidad el compartir un directorio que tenéis en vuestra Raspberry Pi con otros dispositivos de la red. Ya hemos visto como hacerlo a través de interface web con soluciones como [3.9 File Browser. Explorador de ficheros en remoto](https://libros.catedu.es/books/raspberry-pi/page/39-file-browser-explorador-de-ficheros-en-remoto "3.9 File Browser. Explorador de ficheros en remoto") pero quizás a nivel de sistema operativo también os interese poder acceder a dicho contenido. Si ese es tu caso te interesará configurar este protocolo.

En mi caso me permite acceder a directorios de la Raspberry Pi desde mi equipo Vitalinux (que imagino a estas alturas del curso te lo habré recomendado ya alguna que otra vez pero aún así te recomiendo) como si fueran una carpeta mas de mi máquina:

[![samba-1.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/samba-1.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/samba-1.png)

[![samba-2.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/samba-2.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/samba-2.png)

[![samba-3.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/samba-3.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/samba-3.png)

*Elaboración propia*

## ¿qué es Samba?

> Samba es una implementación libre del protocolo de archivos compartidos de Microsoft Windows (antiguamente llamado SMB, renombrado posteriormente a CIFS) para sistemas de tipo UNIX.
> 
> https://es.wikipedia.org/wiki/Samba\_(software)

## ¿Cómo configurarlo?

Primero descargaremos e instalaremos el paquete pues no viene por defecto en Raspberry Pi OS por defecto. Lo haremos del siguiente modo:

```bash
sudo apt update
sudo apt install samba samba-common-bin smbclient cifs-utils
```

Ahora llega el momento de decirle a Samba qué directorios debe compartir. Para ello editaremos el fichero de configuración smb.conf con el comando sudo nano /etc/samba/smb.conf y, al final del fichero, añadiremos tantas estructuras como la que veremos a continuación como directorios queramos compartir:

```bash
[share]
    path = /home/pi/shared
    read only = no
    public = yes
    writable = yes
```

Así, en mi caso, que tengos compartidos 3 directorios diferentes, el contenido del fichero es el siguiente:

```bash
[pifotos]
  path = /mnt/Expansion/fotos
  guest ok = yes
  writeable = yes
  browseable = yes
  create mask = 0777
  directory mask = 0777

[pipelis]
  path = /mnt/Expansion/media/movies
  guest ok = yes
  writeable = yes
  browseable = yes
  create mask = 0777
  directory mask = 0777

[piseries]
  path = /mnt/Expansion/media/tvshows
  guest ok = yes
  writeable = yes
  browseable = yes
  create mask = 0777
  directory mask = 0777
```

En principio no es necesario realizar más cambios para una configuración básica.

## Mas información

En la documentación oficial, en el apartado [https://www.raspberrypi.com/documentation/computers/remote-access.html#samba-smbcifs](https://www.raspberrypi.com/documentation/computers/remote-access.html#samba-smbcifs) , podréis encontrar mas información sobre como configuar este servicio y muchos otros.

# 5.4 Otras utilidades

## raspi-config

Si desde el terminal <span style="text-align: justify;">ejecutas el comando </span>`sudo raspi-config`<span style="text-align: justify;"> </span>

[![ipfija-comando.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/ipfija-comando.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/ipfija-comando.png)

*Elaboración propia*

accederás a una pantalla como la siguiente

[![iija-interface.png](https://libros.catedu.es/uploads/images/gallery/2023-03/scaled-1680-/iija-interface.png)](https://libros.catedu.es/uploads/images/gallery/2023-03/iija-interface.png)

*Elaboración propia*

<p class="callout info">Para moverte por esta pantalla deberás hacer uso de las flechas del techado, del tabulador, de la tecla escape y de la tecla enter.</p>

En esta pantalla podrás configurar una serie de parámetros de funcionamiento de la Raspberry Pi.

## composerize

Puede ser que en ocasiones, leyendo determinada documentación, encontréis como ejecutar un determinado servicio a través de docker pero no de docker-compose. Recordad que ambas soluciones son funcionales pero si por lo que sea os parece más fácil/cómodo/x ejecutarlo a través de docker-compose podéis hacer uso de esta herramienta online [https://www.composerize.com/](https://www.composerize.com/) a través de la cual podéis convertir cualquier comando docker a su equivalente docker-compose.

# 6 - Kit robótica

# 6.1 Material

A la hora de realizar este curso se te ha ofrecido la posibilidad de disponer de un kit de robótica. El kit está formado por el siguiente material:

[![kit-completo-comp.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/kit-completo-comp.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/kit-completo-comp.png)

*Elaboración propia*

En la imagen anterior aparece todo el material que conforma el kit. Ahora vamos a verlo por partes.

## Raspberry Pi

En esta imagen vemos la Raspberry Pi montada en su caja oficial junto al ventilador ya conectado. También aparece el cargador oficial del dispositivo

[![kit-raspberry-comp.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/kit-raspberry-comp.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/kit-raspberry-comp.png)

*Elaboración propia*

## Accesorios

En la siguiente imagen podemos ver una serie de accesarios que nos harán la vida mas fácil. Tenemos:

- una tarjeta microSD de 64GB con adaptador
- un adaptador de microSD/SD a USB 3.0 lo que nos facilitará la vida a la hora de instalar la imagen con el sistema operativo
- un cable HDMI para sacar la imagen de nuestra Raspberry Pi a un monitor
- un mini teclado inalámbrico que nos facilitará la introducción de comandos y nos evitará tener que conectar uno propio. De todos modos, por comodidad y ergonomía, resultaría interesante conectarse a la RaspberryPi a través de SSH y utilizar un teclado "de verdad"

[![kit-accesorios-comp.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/kit-accesorios-comp.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/kit-accesorios-comp.png)

*Elaboración propia*

## Electrónica

En la siguiente imagen podemos ver la placa protoboard de ensayo. Una serie de resistencias, incluído una de tipo LDR, unos LEDs de diferentes colores y un *display* de 8 segmentos. Con este material podremos llevar a cabo cualquiera de las prácticas propuestas durante el curso.

[![kit-electronica-comp.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/kit-electronica-comp.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/kit-electronica-comp.png)

*Elaboración propia*

## Domótica - Zigbee

Y ya, por último, en esta imagen podemos encontrar:

- El fasheador: arriba a la izquierda
- Sensores de temperatura-humedad y de apertura de puertas: abajo del todo
- El zigbee cc2531 (que irá conectado a la Raspberry Pi) y que debemos flashear. Será lo que permita que la Raspberry Pi pueda comunicarse haciendo uso del protocolo Zibgee

[![kit-domotica-zigbee-comp.png](https://libros.catedu.es/uploads/images/gallery/2023-07/scaled-1680-/kit-domotica-zigbee-comp.png)](https://libros.catedu.es/uploads/images/gallery/2023-07/kit-domotica-zigbee-comp.png)

*Elaboración propia*

# 7 Otros kits de robótica con Raspberry (fuera de curso)

# Crowpi2

<p class="callout warning"><span style="color: rgb(0, 0, 0);">ATENCION los tutoriales y lecciones que muestra CrowPi2 están **EN INGLÉS**</span></p>

### **<span style="color: rgb(22, 145, 121);">¿Qué es?</span>**

Crowpi2 es básicamente un ordenador adaptado para robótica pero que el microprocesador es una Raspberry. Es decir, tiene teclado, pantalla, alimentación... y un sinfín de sensores y actuadores para realizar experimentos con la Raspberry Pi

[![CrowPi2sliver-4-_5.webp](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/crowpi2sliver-4-5.webp)](https://libros.catedu.es/uploads/images/gallery/2024-12/crowpi2sliver-4-5.webp)Fuente [https://www.crowpi.cc/](https://www.crowpi.cc/)

A la hora de comprar hay que tener en cuenta de pedir teclado español y que no suele incluir la Raspbery. Sale por unos [365€](https://robotopia.es/kits-educativos/300-90-crowpi2.html#/52-opciones_crowpi2-con_raspberry_pi_4gb)

Los sensores que lleva integrados son   
[![2024-12-20 19_40_01-CrowPi2_Rasspberry_Pi_Laptop_User_Manual.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-20-19-40-01-crowpi2-rasspberry-pi-laptop-user-manual.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-20-19-40-01-crowpi2-rasspberry-pi-laptop-user-manual.png)  
Fuente Manual CrowPi2 descargable [aquí](https://www.manualslib.com/download/3143192/Elecrow-Crowpi2.html)

Para ver en qué pin GPIO esta conectado cada sensor y actuador ver [https://github.com/Elecrow-RD/CrowPi2](https://github.com/Elecrow-RD/CrowPi2)

Si se quiere utilizar la placa board (10) con los pines GPIO diréctamente, poner el switch (6) en OFF, en caso contrario dejarlo en ON para poder usar los elementos de Crowpi

### <span style="color: rgb(22, 145, 121);">**Configuración hardware**</span>

<span style="color: rgb(0, 0, 0);">Conectamos nuestra Raspberry Pi en el Crowpi tal y como dicen las instrucciones, sobre todo hay que fijarse en conectar la alimentación, y display. Manual CrowPi2 descargable [aquí](https://www.manualslib.com/download/3143192/Elecrow-Crowpi2.html).</span>

### <span style="color: rgb(22, 145, 121);">**Configuración software**</span>

Tenemos que bajar la imagen oficial, que es un Raspbian con programas educativos, sobre todo el Crowpi2 que hablaremos más adelante. Para descargar la imagen, [aquí tienes la página oficial. ](https://www.crowpi.cc/blogs/news/how-to-update-the-crowpi2-os-image)Para grabarla en una tarjeta SD (recomendable 32G) podemos usar [balenaetcher](https://etcher.balena.io/)

Una vez instalado, arrancar Crowpi2 con la tarjeta, configurar teclado, wifi (1 en la figura) y recomendamos activar SSH y VNC y cámara web (2) para poder manejar Crowpi2 desde otro ordenador.

[![2024-12-20 20_41_31-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-20-20-41-31-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-20-20-41-31-192-168-1-46-raspberrypi-realvnc-viewer.png)

luego en el terminal, recomendamos actualizar el software con las instrucciones:

```
sudo apt-get update
sudo apt-get dist-upgrade
```

### <span style="color: rgb(22, 145, 121);">**Programa educativo Crowpi**</span>

Está preinstalado en la imagen oficial de Crowpi2 y lo tenemos accesible en estos dos sitios

[![2024-12-20 20_39_16-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-20-20-39-16-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-20-20-39-16-192-168-1-46-raspberrypi-realvnc-viewer.png)

Al arrancar sale esta ventana

[![2024-12-20 21_06_47-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-20-21-06-47-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-20-21-06-47-192-168-1-46-raspberrypi-realvnc-viewer.png)

### <span style="color: rgb(22, 145, 121);">**Programa educativo Crowpi Learning**</span>

En el momento de arrancar este programa nos encontramos con un diálogo de logueo. Se puede crear usuarios sin necesidad de cofirmación ni Internet (email, etc..) perfecto para alumnos menores de edad.

<p class="callout success">Esto es excelente pues nos permite usar el mismo Crowpi2 para distintos alumnos y cada uno va a su ritmo pues graba las lecciones que se han logrado</p>

[![2024-12-20 21_03_22-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-20-21-03-22-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-20-21-03-22-192-168-1-46-raspberrypi-realvnc-viewer.png)

Al loguearse nos pregunta qué tipo de programación deseamo

[![2024-12-20 21_14_31-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-20-21-14-31-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-20-21-14-31-192-168-1-46-raspberrypi-realvnc-viewer.png)

### <span style="color: rgb(22, 145, 121);">**Programa educativo Crowpi Learning Scratch**</span>

<span style="color: rgb(0, 0, 0);">Nos enseña 16 lecciones, qué lecciones son las que hemos hecho (1), por cual vamos (2) y cuales nos quedan por hacer. Hasta que no se completa una lección no permite pasar a la siguiente.</span>

<span style="color: rgb(0, 0, 0);">[![2024-12-20 21_16_29-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-20-21-16-29-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-20-21-16-29-192-168-1-46-raspberrypi-realvnc-viewer.png)</span>

<span style="color: rgb(0, 0, 0);">Las lecciones enseñan paso a paso las instrucciones con vídeos para poder hacer los programas y el editor Scratch para ir realizándolo :</span>

<span style="color: rgb(0, 0, 0);">[![2024-12-20 21_22_21-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-20-21-22-21-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-20-21-22-21-192-168-1-46-raspberrypi-realvnc-viewer.png)</span>

### <span style="color: rgb(22, 145, 121);">**Programa educativo Crowpi Learning Python**</span>

<span style="color: rgb(22, 145, 121);"><span style="color: rgb(0, 0, 0);">Nos enseña 32 lecciones, qué lecciones son las que hemos hecho (1), por cual vamos (2) y cuales nos quedan por hacer. Hasta que no se completa una lección no permite pasar a la siguiente.</span></span>

<span style="color: rgb(22, 145, 121);"><span style="color: rgb(0, 0, 0);">[![2024-12-20 21_24_16-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-20-21-24-16-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-20-21-24-16-192-168-1-46-raspberrypi-realvnc-viewer.png)</span></span>

<span style="color: rgb(22, 145, 121);"><span style="color: rgb(0, 0, 0);">En las lecciones (1) se explica paso a paso el código a realizar (2) junto con explicaciones de los sensores (3) y al lado el editor Thomy (4) para ir realizando el programa y poder ejecutarlo (5)</span></span>

<span style="color: rgb(22, 145, 121);"><span style="color: rgb(0, 0, 0);">[![2024-12-20 21_26_50-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-20-21-26-50-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-20-21-26-50-192-168-1-46-raspberrypi-realvnc-viewer.png)</span></span>

<p class="callout warning"><span style="color: rgb(22, 145, 121);"><span style="color: rgb(0, 0, 0);">Para el manejo del 8x8 RGB LED Matriz de necesita esta librería y da error  
from rpi\_ws281x import PixelStrip, Color  
si sabes cómo solucionar este problema, ponte en contacto con Catedu [www.catedu.es](https://www.catedu.es) - información</span></span></p>

### <span style="color: rgb(22, 145, 121);">**Programa educativo Crowpi AI**</span>

<span style="color: rgb(22, 145, 121);">**[![2024-12-21 09_10_47-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-21-09-10-47-192-168-1-46-raspberrypi-realvnc-viewer.png) ](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-21-09-10-47-192-168-1-46-raspberrypi-realvnc-viewer.png)[![2024-12-21 09_11_35-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-21-09-11-35-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-21-09-11-35-192-168-1-46-raspberrypi-realvnc-viewer.png)**</span>

##### <span style="color: rgb(22, 145, 121);">**Programa educativo Crowpi AI Speech Recognition**</span>

<span style="color: rgb(0, 0, 0);">Se basa en el software y máquina de entrenar [https://snowboy.kitt.ai/](https://snowboy.kitt.ai/) pero como puedes ver está ya sin mantenimiento luego las lecciones que enseña Crowpi Learning no sirven.</span>

##### **<span style="color: rgb(22, 145, 121);">Programa educativo Crowpi AI- Face Recognition- instalación Open CV3</span>**

<span style="color: rgb(0, 0, 0);">Para utilizar el reconocimiento de imagen, tenemos que utilizar el software OpenCV3 **no utilizar la guía que muestra Install Open CV3, está obsoleta** simplemente en un terminal ejecutar la instrucción</span>

```
sudo apt install python3-opencv
```

##### **<span style="color: rgb(22, 145, 121);">Programa educativo Crowpi AI- Face Recognition- Test de la cámara</span>**

<span style="color: rgb(22, 145, 121);"><span style="color: rgb(0, 0, 0);">Vamos a probarlo con este programa que visualiza capturas en gris y en color</span></span>

```
import numpy as np
import cv2

cap = cv2.VideoCapture(0)
cap.set(3,640)
cap.set(4,480)

while(True):
    ret, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    cv2.imshow('frame', frame)
    cv2.imshow('gray', gray)
    
    k=cv2.waitKey(30) & 0xff
    if k == 27:
        break
    
cap.release()
cv2.destroyAllWindows()
```

Extraído de [https://peppe8o.com/crowpi2-reviewing-the-famous-all-in-one-stem-solution/](https://peppe8o.com/crowpi2-reviewing-the-famous-all-in-one-stem-solution/)

El resultado

<span style="color: rgb(22, 145, 121);">[![2024-12-21 09_18_26-.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-21-09-18-26.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-21-09-18-26.png)</span>

Un programa más elaborado lo tienes pinchando en el primer tutorial

[![2024-12-22 08_57_57-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-22-08-57-57-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-22-08-57-57-192-168-1-46-raspberrypi-realvnc-viewer.png)  
<span style="color: rgb(0, 0, 0);">Fuente: Tutorial Learning Crowpi2</span>

Al abrir, nos encontramos la ruta del programa **SimpleCamTest.py** (1) lo abrimos (2) y nos fijamos en la explicaciones del código del tutorial (3)

[![2024-12-22 08_58_58-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-22-08-58-58-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-22-08-58-58-192-168-1-46-raspberrypi-realvnc-viewer.png)

El resultado es el mismo pero el programa es más elaborado con la ventaja de que está explicado paso a paso en el tutorial.

##### **<span style="color: rgb(22, 145, 121);">Programa educativo Crowpi AI- Face Recognition- Reconocimiento facial</span>**

<span style="color: rgb(0, 0, 0);">Un programa sencillo sería</span>

```
import numpy as np
import cv2

faceCascade=cv2.CascadeClassifier('/home/pi/Documents/Face_recognition/Cascades/haarcascade_frontalface_default.xml')

cap = cv2.VideoCapture(0)
cap.set(3,640)
cap.set(4,480)

while(True):
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces=faceCascade.detectMultiScale(
        gray,
        scaleFactor=1.2,
        minNeighbors=5,
        minSize=(20,20)
    )
    
    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
        roi_gray=gray[y:y+h, x:x+w]
        roi_color=img[y:y+h, x:x+w]
    
    
    cv2.imshow('video', img)
    
    k=cv2.waitKey(30) & 0xff
    if k == 27:
        break
    
cap.release()
cv2.destroyAllWindows()
```

Extraído de [https://peppe8o.com/crowpi2-reviewing-the-famous-all-in-one-stem-solution/](https://peppe8o.com/crowpi2-reviewing-the-famous-all-in-one-stem-solution/)

El resultado  
[![2024-12-21 09_25_31-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-21-09-25-31-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-21-09-25-31-192-168-1-46-raspberrypi-realvnc-viewer.png)

Un programa más elaborado es el que sale en su tutorial en este botón:

[![2024-12-22 10_04_32-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-22-10-04-32-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-22-10-04-32-192-168-1-46-raspberrypi-realvnc-viewer.png)  
<span style="color: rgb(0, 0, 0);">Fuente: Tutorial Learning Crowpi2</span>

El programa **faceDection.py** esta en este directorio

[![2024-12-22 10_05_38-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-22-10-05-38-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-22-10-05-38-192-168-1-46-raspberrypi-realvnc-viewer.png)

Es importante que esté en el mismo sitio que la carpeta **Cascades** tal y como explica en (1)

**Cascades** es una carpeta que contendrá los patrones de las caras. Como dice su tutorial (2) puedes descargarlos desde [https://github.com/opencv/opencv/tree/master/data/haarcascades](https://github.com/opencv/opencv/tree/master/data/haarcascades) y ponerlos en la carpeta Cascades. El programa se explica paso a paso en el tutorial (3)

[![2024-12-22 10_09_00-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-22-10-09-00-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-22-10-09-00-192-168-1-46-raspberrypi-realvnc-viewer.png)

##### **<span style="color: rgb(22, 145, 121);">Programa educativo Crowpi AI- Face Recognition- 01-Data collection</span>**

<span style="color: rgb(0, 0, 0);">Entramos en el siguiente tutorial</span>

**[![2024-12-22 10_24_49-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-22-10-24-49-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-22-10-24-49-192-168-1-46-raspberrypi-realvnc-viewer.png)** <span style="color: rgb(0, 0, 0);">Fuente: Tutorial Learning Crowpi2</span>

En el mismo directorio que antes encontramos **FacialRecognitionProyect**, nos encontramos el siguiente programa <span style="background-color: rgb(251, 238, 184);">**01\_face\_dataset.py**</span>

```
''''
Capture multiple Faces from multiple users to be stored on a DataBase (dataset directory)
    ==> Faces will be stored on a directory: dataset/ (if does not exist, pls create one)
    ==> Each face will have a unique numeric integer ID as 1, 2, 3, etc                       

Based on original code by Anirban Kar: https://github.com/thecodacus/Face-Recognition    

Developed by Marcelo Rovai - MJRoBot.org @ 21Feb18    

'''

import cv2
import os

cam = cv2.VideoCapture(0)
cam.set(3, 640) # set video width
cam.set(4, 480) # set video height

face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

# For each person, enter one numeric face id
face_id = input('\n enter user id end press <return> ==>  ')

print("\n [INFO] Initializing face capture. Look the camera and wait ...")
# Initialize individual sampling face count
count = 0

while(True):

    ret, img = cam.read()
    #img = cv2.flip(img, -1) # flip video image vertically
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_detector.detectMultiScale(gray, 1.3, 5)

    for (x,y,w,h) in faces:

        cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2)     
        count += 1

        # Save the captured image into the datasets folder
        cv2.imwrite("dataset/User." + str(face_id) + '.' + str(count) + ".jpg", gray[y:y+h,x:x+w])

        cv2.imshow('image', img)

    k = cv2.waitKey(100) & 0xff # Press 'ESC' for exiting video
    if k == 27:
        break
    elif count >= 30: # Take 30 face sample and stop video
         break

# Do a bit of cleanup
print("\n [INFO] Exiting Program and cleanup stuff")
cam.release()
cv2.destroyAllWindows()
```

El archivo de datos de captura de la cara esta en [https://github.com/Mjrovai/OpenCV-Face-Recognition/blob/master/FacialRecognition/haarcascade\_frontalface\_default.xml](https://github.com/Mjrovai/OpenCV-Face-Recognition/blob/master/FacialRecognition/haarcascade_frontalface_default.xml)[,](https://github.com/Mjrovai/OpenCV-Face-Recognition/blob/master/FacialRecognition/haarcascade_frontalface_default.xml) **no hace falta que te la descargues** ya lo tienes en la carpeta **dataset**

Si ejecutamos el programa, nos pide un identificador **ID** que tiene que ser un entero&gt;0 si ponemos 1, se abre la webcam y nos hace 30 fotos y los graba como 1.1.jpg hasta 1.30.jpg y si ponemos 2 nos hace otros 30 y los almacena en la carpeta **dataset**. Podemos poner tantos ID como queramos.  
Aquí he experimentado con mi cara y con George Cloneey, no hace falta decir cual quien es quien el ID 1 y el 2 😊

[![2024-12-22 10_21_22-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-22-10-21-22-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-22-10-21-22-192-168-1-46-raspberrypi-realvnc-viewer.png)

##### **<span style="color: rgb(22, 145, 121);">Programa educativo Crowpi AI- Face Recognition- 02-Train</span>**

<span style="color: rgb(0, 0, 0);">En el siguiente tutorial</span>

<span style="color: rgb(0, 0, 0);">[![2024-12-22 10_32_04-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-22-10-32-04-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-22-10-32-04-192-168-1-46-raspberrypi-realvnc-viewer.png)  
Fuente: Tutorial Learning Crowpi2  
</span>

<span style="color: rgb(0, 0, 0);">Y ahora con las imágenes que hemos almacenado con los identificadores, en mi caso 1 y 2 con mi cara y con George Clooney, luego hay que entrenar a la máquina virtual y lo almacena en el fichero **<span style="background-color: rgb(251, 238, 184);">trainer.yml</span>**</span>

<span style="color: rgb(0, 0, 0);">[![2024-12-22 10_39_07-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-22-10-39-07-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-22-10-39-07-192-168-1-46-raspberrypi-realvnc-viewer.png)</span>

<span style="color: rgb(0, 0, 0);">Fuente: Tutorial Learning Crowpi2</span>

<span style="color: #000000;">El tutorial lo explica muy bien el proceso (1) y al ejecutarlo, nos dice si face trained (2) o no :</span>

[![2024-12-22 10_38_12-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-22-10-38-12-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-22-10-38-12-192-168-1-46-raspberrypi-realvnc-viewer.png)

El programa se llama <span style="background-color: rgb(251, 238, 184);">**02-face-training.py**</span>

```
''''
Training Multiple Faces stored on a DataBase:
	==> Each face should have a unique numeric integer ID as 1, 2, 3, etc                       
	==> LBPH computed model will be saved on trainer/ directory. (if it does not exist, pls create one)
	==> for using PIL, install pillow library with "pip install pillow"

Based on original code by Anirban Kar: https://github.com/thecodacus/Face-Recognition    

Developed by Marcelo Rovai - MJRoBot.org @ 21Feb18   

'''

import cv2
import numpy as np
from PIL import Image
import os

# Path for face image database
path = 'dataset'

recognizer = cv2.face.LBPHFaceRecognizer_create()
detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml");

# function to get the images and label data
def getImagesAndLabels(path):

    imagePaths = [os.path.join(path,f) for f in os.listdir(path)]     
    faceSamples=[]
    ids = []

    for imagePath in imagePaths:

        PIL_img = Image.open(imagePath).convert('L') # convert it to grayscale
        img_numpy = np.array(PIL_img,'uint8')

        id = int(os.path.split(imagePath)[-1].split(".")[1])
        faces = detector.detectMultiScale(img_numpy)

        for (x,y,w,h) in faces:
            faceSamples.append(img_numpy[y:y+h,x:x+w])
            ids.append(id)

    return faceSamples,ids

print ("\n [INFO] Training faces. It will take a few seconds. Wait ...")
faces,ids = getImagesAndLabels(path)
recognizer.train(faces, np.array(ids))

# Save the model into trainer/trainer.yml
recognizer.write('trainer/trainer.yml') # recognizer.save() worked on Mac, but not on Pi

# Print the numer of faces trained and end program
print("\n [INFO] {0} faces trained. Exiting Program".format(len(np.unique(ids))))
```

##### **<span style="color: rgb(22, 145, 121);">Programa educativo Crowpi AI- Face Recognition- Recognizer</span>**

<span style="color: rgb(0, 0, 0);">Entramos en el siguiente tutorial:</span>

<span style="color: rgb(0, 0, 0);">[![2024-12-22 11_03_37-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-22-11-03-37-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-22-11-03-37-192-168-1-46-raspberrypi-realvnc-viewer.png)  
Fuente: Tutorial Learning Crowpi2  
</span>

<span style="color: rgb(0, 0, 0);">Y ahora utilizará el entrenamiento almacenado en **trainer.yml** que hemos creado anteriormente para reconocer las imágenes</span>

<span style="color: rgb(0, 0, 0);">[![2024-12-22 11_03_21-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-22-11-03-21-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-22-11-03-21-192-168-1-46-raspberrypi-realvnc-viewer.png)  
Fuente: Tutorial Learning Crowpi2</span>

<span style="color: rgb(0, 0, 0);">El fichero <span style="background-color: rgb(251, 238, 184);">**03\_face\_recognition.py**</span></span>

```
''''
Real Time Face Recogition
    ==> Each face stored on dataset/ dir, should have a unique numeric integer ID as 1, 2, 3, etc                       
    ==> LBPH computed model (trained faces) should be on trainer/ dir
Based on original code by Anirban Kar: https://github.com/thecodacus/Face-Recognition    

Developed by Marcelo Rovai - MJRoBot.org @ 21Feb18  

'''

import cv2
import numpy as np
import os 

recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('trainer/trainer.yml')
cascadePath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath);

font = cv2.FONT_HERSHEY_SIMPLEX

#iniciate id counter
id = 1

# names related to ids: example ==> Marcelo: id=1,  etc
names = ['None', 'George Clooney', 'Javier Quintana', 'Javier', 'Z', 'W'] 

# Initialize and start realtime video capture
cam = cv2.VideoCapture(0)
cam.set(3, 640) # set video widht
cam.set(4, 480) # set video height

# Define min window size to be recognized as a face
minW = 0.1*cam.get(3)
minH = 0.1*cam.get(4)

while True:

    ret, img =cam.read()
    #img = cv2.flip(img, -1) # Flip vertically

    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale( 
        gray,
        scaleFactor = 1.2,
        minNeighbors = 5,
        minSize = (int(minW), int(minH)),
       )

    for(x,y,w,h) in faces:

        cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)

        id, confidence = recognizer.predict(gray[y:y+h,x:x+w])

        # Check if confidence is less them 100 ==> "0" is perfect match 
        if (confidence < 70):
            id = names[id]
            confidence = "  {0}%".format(round(100 - confidence))
        else:
            id = "unknown"
            confidence = "  {0}%".format(round(100 - confidence))
        
        cv2.putText(img, str(id), (x+5,y-5), font, 1, (255,255,255), 2)
#        cv2.putText(img, str(confidence), (x+5,y+h-5), font, 1, (255,255,0), 1)  
    
    cv2.imshow('camera',img) 

    k = cv2.waitKey(10) & 0xff # Press 'ESC' for exiting video
    if k == 27:
        break

# Do a bit of cleanup
print("\n [INFO] Exiting Program and cleanup stuff")
cam.release()
cv2.destroyAllWindows()
```

<span style="color: rgb(0, 0, 0);">Como veis, funciona perfectamente: </span>

<span style="color: rgb(0, 0, 0);">[![2024-12-22 11_21_35-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-22-11-21-35-192-168-1-46-raspberrypi-realvnc-viewer.png) ](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-22-11-21-35-192-168-1-46-raspberrypi-realvnc-viewer.png)[![2024-12-22 11_19_47-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-22-11-19-47-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-22-11-19-47-192-168-1-46-raspberrypi-realvnc-viewer.png)</span>

<span style="color: rgb(0, 0, 0);">Es broooomaaa 😁😁 le he cambiado el orden en la instrucción de la línea 26 :</span>

```
names = ['None', 'George Clooney', 'Javier Quintana', 'Tony', 'Z', 'W'] 
```

##### **<span style="color: rgb(22, 145, 121);">Programa educativo Crowpi AI- Face Recognition- Play with hardware</span>**

[![2024-12-22 11_26_32-192.168.1.46 (raspberrypi) - RealVNC Viewer.png](https://libros.catedu.es/uploads/images/gallery/2024-12/scaled-1680-/2024-12-22-11-26-32-192-168-1-46-raspberrypi-realvnc-viewer.png)](https://libros.catedu.es/uploads/images/gallery/2024-12/2024-12-22-11-26-32-192-168-1-46-raspberrypi-realvnc-viewer.png)

<p class="callout danger">El programa siguiente es 03\_face\_recognition\_RGB.py **NO FUNCIONA**</p>

<p class="callout danger">El programa visualiza por la matriz 8x8 RGB LED la cara alegre o triste pero se necesita esta librería y da error  
from rpi\_ws281x import PixelStrip, Color  
si sabes cómo solucionar este problema, ponte en contacto con Catedu www.catedu.es - información</p>

<details id="bkmrk-03_face_recognition_"><summary>03\_face\_recognition\_RGB</summary>

<div>''''</div><div>03_face_recognition_RGB.py</div><div>  
</div><div>Real Time Face Recogition</div><div> ==&gt; Each face stored on dataset/ dir, should have a unique numeric integer ID as 1, 2, 3, etc </div><div> ==&gt; LBPH computed model (trained faces) should be on trainer/ dir</div><div>Based on original code by Anirban Kar: https://github.com/thecodacus/Face-Recognition </div><div>  
</div><div>Developed by Marcelo Rovai - MJRoBot.org @ 21Feb18 </div><div>  
</div><div>'''</div><div>  
</div><div>import cv2</div><div>import numpy as np</div><div>import os</div><div>import threading</div><div>import time</div><div>from rpi_ws281x import PixelStrip, Color</div><div>import RPi.GPIO as GPIO</div><div>  
</div><div>count = 0</div><div>class RGB_Matrix:</div><div>  
</div><div> def __init__(self):</div><div>  
</div><div> # LED strip configuration:</div><div> self.LED_COUNT = 64 # Number of LED pixels.</div><div> self.LED_PIN = 12 # GPIO pin connected to the pixels (18 uses PWM!).</div><div> self.LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz)</div><div> self.LED_DMA = 10 # DMA channel to use for generating signal (try 10)</div><div> self.LED_BRIGHTNESS = 10 # Set to 0 for darkest and 255 for brightest</div><div> self.LED_INVERT = False # True to invert the signal (when using NPN transistor level shift)</div><div> self.LED_CHANNEL = 0 # set to '1' for GPIOs 13, 19, 41, 45 or 53</div><div>  
</div><div> self.RIGHT_BORDER = [7,15,23,31,39,47,55,63]</div><div> self.LEFT_BORDER = [0,8,16,24,32,40,48,56]</div><div>  
</div><div> # Define functions which animate LEDs in various ways.</div><div> def clean(self,strip):</div><div> # wipe all the LED's at once</div><div> for i in range(strip.numPixels()):</div><div> strip.setPixelColor(i, Color(0, 0, 0))</div><div> strip.show()</div><div> def clean_up(self,strip):</div><div> clean = []</div><div> for pixel in clean:</div><div> strip.setPixelColor(pixel, Color(0,0,0))</div><div> strip.show()</div><div> def run_clean(self):</div><div> # Create NeoPixel object with appropriate configuration.</div><div> strip = PixelStrip(self.LED_COUNT, self.LED_PIN, self.LED_FREQ_HZ, self.LED_DMA, self.LED_INVERT, self.LED_BRIGHTNESS, self.LED_CHANNEL)</div><div> # Intialize the library (must be called once before other functions).</div><div> strip.begin()</div><div> # do stuff</div><div> try:</div><div> print('test animations.')</div><div> self.clean_up(strip)</div><div> except KeyboardInterrupt:</div><div> # clean the matrix LED before interruption</div><div> self.clean(strip)</div><div>  
</div><div>  
</div><div>  
</div><div> def demo_happy(self,strip):</div><div>  
</div><div> happy_smiley = [2,3,4,5,9,14,16,18,21,23,24,31,32,34,37,39,40,42,43,44,45,47,49,54,58,59,60,61]</div><div>  
</div><div>\# show the happy smiley on the RGB screen</div><div> for pixel in happy_smiley:</div><div> strip.setPixelColor(pixel, Color(0,255,0))</div><div>  
</div><div> strip.show()</div><div>  
</div><div>  
</div><div>  
</div><div>  
</div><div> def demo_sad(self,strip):</div><div>  
</div><div> sad_smiley = [2,3,4,5,9,14,16,18,21,23,24,31,32,34,35,36,37,39,40,42,45,47,49,54,58,59,60,61]</div><div>  
</div><div>  
</div><div>  
</div><div> # show the sad smiley on the RGB screen</div><div> for pixel in sad_smiley:</div><div> strip.setPixelColor(pixel, Color(255,0,0))</div><div>  
</div><div> strip.show()</div><div>  
</div><div>  
</div><div> def run_happy(self):</div><div> # Create NeoPixel object with appropriate configuration.</div><div> strip = PixelStrip(self.LED_COUNT, self.LED_PIN, self.LED_FREQ_HZ, self.LED_DMA, self.LED_INVERT, self.LED_BRIGHTNESS, self.LED_CHANNEL)</div><div> # Intialize the library (must be called once before other functions).</div><div> strip.begin()</div><div> # do stuff</div><div> try:</div><div> print('test animations.')</div><div> self.demo_happy(strip)</div><div> except KeyboardInterrupt:</div><div> # clean the matrix LED before interruption</div><div> self.clean(strip)</div><div> def run_sad(self):</div><div> # Create NeoPixel object with appropriate configuration.</div><div> strip = PixelStrip(self.LED_COUNT, self.LED_PIN, self.LED_FREQ_HZ, self.LED_DMA, self.LED_INVERT, self.LED_BRIGHTNESS, self.LED_CHANNEL)</div><div> # Intialize the library (must be called once before other functions).</div><div> strip.begin()</div><div> # do stuff</div><div> try:</div><div> print('test animations.')</div><div> self.demo_sad(strip)</div><div> except KeyboardInterrupt:</div><div> # clean the matrix LED before interruption</div><div> self.clean(strip)</div><div>  
</div><div>  
</div><div>matrix = RGB_Matrix()</div><div>  
</div><div>recognizer = cv2.face.LBPHFaceRecognizer_create()</div><div>recognizer.read('trainer/trainer.yml')</div><div>cascadePath = "haarcascade_frontalface_default.xml"</div><div>faceCascade = cv2.CascadeClassifier(cascadePath);</div><div>  
</div><div>font = cv2.FONT_HERSHEY_SIMPLEX</div><div>\#font = cv2.</div><div>  
</div><div>\#iniciate id counter</div><div>id = 1</div><div>  
</div><div>\# names related to ids: example ==&gt; Marcelo: id=1, etc</div><div>names = ['None', 'Javier Quintana', 'George Clooney', 'Tony', 'Z', 'W'] </div><div>  
</div><div>\# Initialize and start realtime video capture</div><div>cam = cv2.VideoCapture(0)</div><div>cam.set(3, 1000) # set video widht</div><div>cam.set(4, 750) # set video height</div><div>  
</div><div>  
</div><div>\# Define min window size to be recognized as a face</div><div>minW = 0.1*cam.get(3)</div><div>\#3</div><div>minH = 0.1*cam.get(4)</div><div>\#4</div><div>try:</div><div> while True:</div><div> </div><div> ret, img =cam.read()</div><div> #img = cv2.flip(img, -1) # Flip vertically</div><div> gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)</div><div>  
</div><div> faces = faceCascade.detectMultiScale( </div><div> gray,</div><div> scaleFactor = 1.2,</div><div> minNeighbors = 5,</div><div> minSize = (int(minW), int(minH)),</div><div> )</div><div>  
</div><div> for(x,y,w,h) in faces:</div><div>  
</div><div> cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)</div><div>  
</div><div>  
</div><div> id, confidence = recognizer.predict(gray[y:y+h,x:x+w])</div><div> # Check if confidence is less them 100 ==&gt; "0" is perfect match </div><div> if (confidence &lt; 60):</div><div> t3 = threading.Thread(target = matrix.run_clean)</div><div> t3.start()</div><div> cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)</div><div> id = names[id]</div><div> confidence = " {0}%".format(round(100 - confidence))</div><div> cv2.putText(img, str(id), (x+5,y-5), font, 1, (0,255,0), 2)</div><div> print("\n Successful")</div><div> count = count + 1</div><div> if count &gt; 20:</div><div> cam.release()</div><div> cv2.destroyAllWindows()</div><div> os.system("/home/pi/Documents/Face_recognition/gif/AI-succeed-gif")</div><div> t1 = threading.Thread(target = matrix.run_happy)</div><div> t1.start()</div><div> #GPIO.cleanup()</div><div> time.sleep(3)</div><div> matrix.run_clean()</div><div>  
</div><div> else:</div><div> count = 0</div><div> t2 = threading.Thread(target = matrix.run_sad)</div><div> t2.start()</div><div> cv2.rectangle(img, (x,y), (x+w,y+h), (0,0,255), 2)</div><div> id = "unknown"</div><div> confidence = " {0}%".format(round(100 - confidence))</div><div> cv2.putText(img, str(id), (x+5,y-5), font, 1, (0,0,255), 2)</div><div> </div><div> </div><div> cv2.moveWindow("camera",500,250)</div><div> cv2.imshow('camera',img) </div><div>  
</div><div> k = cv2.waitKey(10) &amp; 0xff # Press 'ESC' for exiting video</div><div> if k == 27:</div><div> break</div><div>  
</div><div> # Do a bit of cleanup</div><div> print("\n [INFO] Exiting Program and cleanup stuff")</div><div> cam.release()</div><div> cv2.destroyAllWindows()</div><div>except KeyboardInterrupt:</div><div> GPIO.cleanup()</div><div> matrix.run_clean()</div></details><p class="callout danger">**El programa anterior 03\_face\_recognition\_RGB.py NO FUNCIONA** cuando detecta una cara nos da el siguiente error  
si sabes cómo solucionar este problema, ponte en contacto con Catedu www.catedu.es - información  
</p>

```
Exception in thread Thread-431:
Traceback (most recent call last):
  File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
 etc..
```

**La solución es no utilizarlo y utilizar el fichero 03\_face\_recognition.py** que sí que funciona.

**¿Cómo?** En las líneas 58-59-60 meter qué queremos que haga el hardware del Crowpi cuando detecte una cara:

```
if (confidence < 70):
            id = names[id]
            confidence = "  {0}%".format(round(100 - confidence))
```

Para ello creamos una función, por ejemplo lo he llamado **Hardware(id)** que haga lo que queremos que haga cuando detecte la cara id, por ejemplo si detecta la cara id=3 que suene el vibrador

```
import RPi.GPIO as GPIO
import time

# define vibration pin
vibration_pin = 27
# Set board mode to GPIO.BCM
GPIO.setmode(GPIO.BCM)
# Setup vibration pin to OUTPUT
GPIO.setup(vibration_pin, GPIO.OUT)

def Hardware(id):
    nombre=names[id]
    if (id==3):
        # turn on vibration
        GPIO.output(vibration_pin, GPIO.HIGH)
        # wait half a second
        time.sleep(0.5)
        # turn off vibration
        GPIO.output(vibration_pin, GPIO.LOW)
```

Por lo tanto en el fichero 03\_face\_recognition.py y en las líneas 58-59-60 metemos Hardware(id)

```
 if (confidence < 70):
            # aquí pongo qué quiero que haga cuando detecta una cara conocida
            Hardware(id)
            # fin
            id = names[id]
            confidence = "  {0}%".format(round(100 - confidence))
```

El resultado es:

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="599" src="https://www.youtube.com/embed/VBcv-qqY1xU" title="CROWPI2 detección de cara con IA OpenCV3" width="337"></iframe>

El fichero modificado es

```
''''
Real Time Face Recogition
    ==> Each face stored on dataset/ dir, should have a unique numeric integer ID as 1, 2, 3, etc                       
    ==> LBPH computed model (trained faces) should be on trainer/ dir
Based on original code by Anirban Kar: https://github.com/thecodacus/Face-Recognition    

Developed by Marcelo Rovai - MJRoBot.org @ 21Feb18  

'''

import cv2
import numpy as np
import os

#MIO LIBRERIAS Y CONFIGURACIóN VIBRADOR
import RPi.GPIO as GPIO
import time
# define vibration pin
vibration_pin = 27
# Set board mode to GPIO.BCM
GPIO.setmode(GPIO.BCM)
# Setup vibration pin to OUTPUT
GPIO.setup(vibration_pin, GPIO.OUT)
################################################
           

recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('trainer/trainer.yml')
cascadePath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath);

font = cv2.FONT_HERSHEY_SIMPLEX

#iniciate id counter
id = 1

# names related to ids: example ==> Marcelo: id=1,  etc
names = ['None', 'George Clooney', 'Javier Quintana', 'Javier', 'Z', 'W'] 

# Initialize and start realtime video capture
cam = cv2.VideoCapture(0)
cam.set(3, 640) # set video widht
cam.set(4, 480) # set video height

# Define min window size to be recognized as a face
minW = 0.1*cam.get(3)
minH = 0.1*cam.get(4)

#MIO mi función cuando detecta una cara
def Hardware(id):
    nombre=names[id]
    if (id==3):
        # turn on vibration
        GPIO.output(vibration_pin, GPIO.HIGH)
        # wait half a second
        time.sleep(0.5)
        # turn off vibration
        GPIO.output(vibration_pin, GPIO.LOW)
    
        

while True:

    ret, img =cam.read()
    #img = cv2.flip(img, -1) # Flip vertically

    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale( 
        gray,
        scaleFactor = 1.2,
        minNeighbors = 5,
        minSize = (int(minW), int(minH)),
       )

    for(x,y,w,h) in faces:

        cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)

        id, confidence = recognizer.predict(gray[y:y+h,x:x+w])

        # Check if confidence is less them 100 ==> "0" is perfect match 
        if (confidence < 70):
            #MIO aquí pongo qué quiero que haga cuando detecta una cara conocida
            Hardware(id)
            # fin
            id = names[id]
            confidence = "  {0}%".format(round(100 - confidence))
            
        else:
            id = "unknown"
            confidence = "  {0}%".format(round(100 - confidence))
        
        cv2.putText(img, str(id), (x+5,y-5), font, 1, (255,255,255), 2)
#        cv2.putText(img, str(confidence), (x+5,y+h-5), font, 1, (255,255,0), 1)  
    
    cv2.imshow('camera',img) 

    k = cv2.waitKey(10) & 0xff # Press 'ESC' for exiting video
    if k == 27:
        break

# Do a bit of cleanup

print("\n [INFO] Exiting Program and cleanup stuff")
cam.release()
cv2.destroyAllWindows()
# MIO
#cleaup GPIO
GPIO.cleanup()

```

# Picobricks

Pico Bricks pertenece a las placas electrónicas con sensores y actuadores básicos para poder hacer proyectos maker

<span style="color: rgb(22, 145, 121);">**[![2024-12-26 09_23_28-Pico Bricks IDE book - PDF-XChange Viewer.png](https://maker.robotistan.com/wp-content/uploads/2023/01/picobricks-2.gif)](https://maker.robotistan.com/wp-content/uploads/2023/01/picobricks-2.gif)**</span>

<span style="color: rgb(0, 0, 0);">{{@12666#bkmrk-programaci%C3%93n-por-blo}}</span>

<span style="color: rgb(0, 0, 0);">**PARA SABER DE ESTA PLACA Y HACER PROYECTOS VER [https://libros.catedu.es/books/pico-bricks](https://libros.catedu.es/books/pico-bricks)**</span>

# Créditos

Autor:

- CAPÍTULOS 1 AL 6 
    - CATEDU 2023 por Pablo Ruiz Soria
- CAPITULO 7 
    - CATEDU 2024 por Javier Quintana
- CAPÍTULO 8 
    - 2026 por Pablo Ruiz Soria

Cualquier observación o detección de error en [soporte.catedu.es](https://catedu.es/soporte-catedu/)

Los contenidos se distribuyen bajo licencia **Creative Commons** tipo **BY-NC-SA** excepto en los párrafos que se indique lo contrario.

[![image-1648462225402.gif](https://libros.catedu.es/uploads/images/gallery/2022-03/image-1648462225402.gif)](https://libros.catedu.es/uploads/images/gallery/2022-03/image-1648462225402.gif)

[![image-1648462299882.png](https://libros.catedu.es/uploads/images/gallery/2022-03/scaled-1680-/image-1648462299882.png)](https://libros.catedu.es/uploads/images/gallery/2022-03/image-1648462299882.png)

[![image-1648462361893.png](https://libros.catedu.es/uploads/images/gallery/2022-03/scaled-1680-/image-1648462361893.png)](https://libros.catedu.es/uploads/images/gallery/2022-03/image-1648462361893.png)

# 8 - La famiglia

Capítulo para tratar otros componentes de la familia Raspberry Pi

# Microcontroladores: Pico

## Introducción

¿Qué es un microcontrolador? en la [Wikipedia](https://es.wikipedia.org/wiki/Microcontrolador) podemos encontrar la siguiente definición:

```
Un microcontrolador es un circuito integrado programable, capaz de ejecutar las órdenes grabadas en su memoria. Está compuesto de varios bloques funcionales que cumplen una tarea específica. Un microcontrolador incluye en su interior las tres principales unidades funcionales de una computadora: unidad central de procesamiento, memoria y periféricos de entrada/salida.
```

Y si la Raspberry Pi Pico es un microntrolador, ¿qué es la raspberry Pi? Esta pregunta la tenemos ya respondida en [https://libros.catedu.es/link/8787#bkmrk-una-raspberry-pi-es-](https://libros.catedu.es/link/8787#bkmrk-una-raspberry-pi-es-)

La diferencia fundamental entre una Raspberry Pi 1/2/3/4/5 y una Raspberry Pi Pico 1/2 es que pertenecen a **categorías de dispositivos completamente distintas**: la primera es un ordenador completo (SBC), mientras que la segunda es un microcontrolador diseñado para tareas específicas de control electrónico:

- **Raspberry Pi** 4: Es una **computadora** de placa única (Single Board Computer). Ejecuta un sistema operativo completo (normalmente Linux/Raspberry Pi OS), tiene escritorio, navegador web y permite multitarea como un PC convencional.
- **Raspberry Pi Pico** 2 W: Es un **microcontrolador**. No tiene sistema operativo; en su lugar, ejecuta un único programa que tú le cargas (firmware). Es similar a un Arduino y está diseñada para interactuar directamente con sensores, motores y luces de forma eficiente y en tiempo real.

En la página web de Raspberry Pi podemos encontrar una sección para los **microcontroladores** de la familia. Concretamente, en la dirección [https://www.raspberrypi.com/products/raspberry-pi-pico-2/](https://www.raspberrypi.com/products/raspberry-pi-pico-2/) , podemos encontrar información sobre la Raspberry Pi Pico 2.

## Características principales de la Raspberry Pi Pico 2

Todas las variantes Pico 2 comparten la misma base de hardware principal, porque todas usan el RP2350. Según Raspberry Pi, las características generales son [Documentación oficial](https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html) :

- Microcontrolador: RP2350
- CPU: elección entre: 
    - 2 núcleos Arm Cortex-M33
    - 2 núcleos Hazard3 RISC-V
- Frecuencia: hasta 150 MHz
- SRAM: 520 KB
- Flash integrada: 4 MB
- GPIO: 26 pines multipropósito
- USB: USB 1.1 con soporte host y device
- PIO: 12 máquinas de estado PIO
- Periféricos: 
    - 2 × UART
    - 2 × SPI
    - 2 × I2C
    - 3 × ADC de 12 bits
    - PWM
- Voltaje de entrada: 1.8 V a 5.5 V
- Temperatura operativa: -20 °C a +85 °C
- Compatibilidad: compatible en hardware y software con la generación Pico anterior

Además, el RP2350 añade funciones de seguridad importantes, como:

- Arm TrustZone
- arranque firmado
- almacenamiento OTP
- aceleración SHA-256
- protecciones frente a ataques por fallos

El pinout de la raspberry pi pico 2 w es el siguiente:

[![pinout.png](https://libros.catedu.es/uploads/images/gallery/2026-03/scaled-1680-/pinout.png)](https://libros.catedu.es/uploads/images/gallery/2026-03/pinout.png)

### Versiones

<table border="1" id="bkmrk-variante-wi-fi-bluet" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 32.062%;"></col><col style="width: 24.7914%;"></col><col style="width: 20.9741%;"></col><col style="width: 22.2917%;"></col></colgroup><tbody><tr><td class="align-center">**Variante**</td><td class="align-center">**Wi-Fi**</td><td class="align-center">**Bluetooth**</td><td class="align-center">**Headers presoldados**</td></tr><tr><td>Raspberry Pi Pico 2</td><td class="align-center">No</td><td class="align-center">No</td><td class="align-center">No</td></tr><tr><td>Raspberry Pi Pico 2 with headers</td><td class="align-center">No</td><td class="align-center">No</td><td class="align-center">Si</td></tr><tr><td>Raspberry Pi Pico 2 W</td><td class="align-center">Si</td><td class="align-center">Si</td><td class="align-center">No</td></tr><tr><td>Raspberry Pi Pico 2 W with headers</td><td class="align-center">Si</td><td class="align-center">Si</td><td class="align-center">Si</td></tr></tbody></table>

## Algunos proyectos

Con Arduino IDE versión 2.x podemos trabajar con la placa. Si usas Linux es probable que para que te detecte la placa tengas que ejecutar el comando `sudo usermod -a -G dialout $USER` para añadir al usuario al grupo dialout (deberás reiniciar la sesión). Además, con independencia del sistema operativo que utilices deberás añadir a las placas disponibles la Raspberry Pi Pico. Para ello, dirígete a file &gt; Preferences &gt; Additional boards manager URLs y añade la url [https://github.com/earlephilhower/arduino-pico/releases/download/global/package\_rp2040\_index.json](https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json) Reinicia el IDE, conecta la microcontroladora y debería estar lista para funcionar.

### Encender y apagar un led

La placa tiene integrado un led junto al conector USB. Para encenderlo y apagarlo alternativamente copia y pega el siguiente código:

```
void setup() {
  pinMode(LED_BUILTIN, OUTPUT); // Indicamos que el LED integrado en la placa funcione como salida
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);  // Enciende el LED
  delay(1000);                       // Espera 1 segundo
  digitalWrite(LED_BUILTIN, LOW);   // Apaga el LED
  delay(1000);                       // Espera 1 segundo
}
```

Ahora compila y envía a la microcontroladora. En cuanto el código esté en ella debería empezar a parpadear el led integrado en la placa

### Activar un GPIO en concreto

Para determinados proyectos puede ser que nos interese encender y apagar un GPIO concreto. En el siguiente ejemplo vamos a encender y apagar cada 3 segundos el GPIO 0 (cero). Para ello copia y pega el siguiente código:

```
void setup() {
  pinMode(0, OUTPUT);      // Configura GPIO0 como salida
}

void loop() {
  digitalWrite(0, HIGH);   // Enciende GPIO0 (pone tensión en él)
  delay(3000);
  digitalWrite(0, LOW);
  delay(3000);
}
```

En el GPIO 0 alternarás cada 3 segundos 3,3V con 0 V de tensión. La corriente por defecto será de 4mA. En caso de querer variar la corriente debrás usar la función gpio\_set\_drive\_strength tras haber importado la bibilioteca correspondiente:

```
#include "hardware/gpio.h"

void setup() {
  pinMode(0, OUTPUT);
  
  // Opciones: GPIO_DRIVE_STRENGTH_2MA, _4MA, _8MA, _12MA
  gpio_set_drive_strength(0, GPIO_DRIVE_STRENGTH_12MA);
  
  digitalWrite(0, HIGH);
}

void loop() {
  // tu código
}
```

### Leer entrada digital GPIO

Puedes hacer uso de cualquier GPIO. El código es el siguiente:

```
void setup() {
  Serial.begin(115200);
  pinMode(1, INPUT);          // GPIO1 como entrada
  // Si no tienes resistencia externa, usa la pull-up interna:
  // pinMode(1, INPUT_PULLUP);
  // o pull-down:
  // pinMode(1, INPUT_PULLDOWN);
}

void loop() {
  int valor = digitalRead(1);  // Lee GPIO1: devuelve HIGH (1) o LOW (0)
  Serial.println(valor);
  delay(100);
}
```

Para ver la salida de Serial.println dirígete a arduinoIDE &gt; tools &gt; Serial Monitor

### Leer entrada analógica GPIO

**GPIO26, 27 y 28 son los únicos que funcionan de modo analógico**. El código es el siguiente:

```
void setup() {
  Serial.begin(115200);
  // No hace falta pinMode para analogRead
}

void loop() {
  int valor = analogRead(26);        // 0–4095 (12 bits)
  float tension = valor * 3.3 / 4095.0;
  Serial.print("Tensión: ");
  Serial.println(tension);
  delay(100);
}
```

### Pulsación de botón

```
void setup() {
  Serial.begin(115200);
  pinMode(1, INPUT_PULLUP);  // Botón entre GPIO1 y GND
}

void loop() {
  if (digitalRead(1) == LOW) {  // LOW = pulsado (con pull-up)
    Serial.println("Botón pulsado");
  }
  delay(50);
}
```

### Sensor de movimiento

```
void setup() {
  pinMode(1, INPUT);   // Señal del PIR
  pinMode(0, OUTPUT);  // LED
}

void loop() {
  if (digitalRead(1) == HIGH) {  // PIR activa HIGH al detectar
    digitalWrite(0, HIGH);       // Enciende LED
  } else {
    digitalWrite(0, LOW);
  }
  delay(100);
}
```

### Detección de agua

```
void setup() {
  Serial.begin(115200);
  pinMode(1, INPUT_PULLDOWN);  // Sensor de nivel
}

void loop() {
  if (digitalRead(1) == HIGH) {
    Serial.println("Nivel de agua alto");
  }
  delay(500);
}
```

### Temperatura con termistor

Analógico. Has de usar los pines indicados anteriormente. En el ejemplo se usa GPIO26.

```
void loop() {
  int raw = analogRead(26);
  float tension = raw * 3.3 / 4095.0;
  // Con divisor de tensión 10kΩ + NTC 10kΩ:
  float resistencia = 10000.0 * tension / (3.3 - tension);
  // Fórmula Steinhart-Hart simplificada:
  float tempK = 1.0 / (log(resistencia / 10000.0) / 3950.0 + 1.0 / 298.15);
  float tempC = tempK - 273.15;
  Serial.print("Temperatura: ");
  Serial.print(tempC);
  Serial.println(" °C");
  delay(1000);
}
```

### Otros

Y tu, ¿qué montajes has realizado?

# AI HAT+ y AI Camera

<p class="callout warning">Este proyecto nace de la intención de montar en mi centro una herramienta de IA de uso local que no dependa (y no envíe) datos a internet. Spoiler: No sale bien.</p>

## IA HAT+

### Qué es

[![placa.png](https://libros.catedu.es/uploads/images/gallery/2026-03/scaled-1680-/placa.png)](https://libros.catedu.es/uploads/images/gallery/2026-03/placa.png)

Es una "placa" o tarjeta de expansión que se encaja encima de una Raspberry Pi (HAT significa Hardware Attached on Top). Añade potencia extra para procesar Inteligencia Artificial localmente (sin depender de internet). Permite que la computadora reconozca objetos, caras o voces de forma mucho más rápida y eficiente de lo que podría hacerlo sola. Es, básicamente, darle un "cerebro especializado" a una computadora pequeña para que pueda realizar tareas de IA sin trabarse.

### Enlaces de interés

- AI HAT+ (la que he usado para las pruebas documentadas mas abajo) 
    - Página oficial: [https://www.raspberrypi.com/products/ai-hat/](https://www.raspberrypi.com/products/ai-hat/)
    - Documentación oficial: [https://www.raspberrypi.com/documentation/accessories/ai-hat-plus.html](https://www.raspberrypi.com/documentation/accessories/ai-hat-plus.html)
    - Resumen: [https://pip-assets.raspberrypi.com/categories/1081-raspberry-pi-ai-hat/documents/RP-008133-DS-1-raspberry-pi-ai-hat-plus-product-brief.pdf?disposition=inline](https://pip-assets.raspberrypi.com/categories/1081-raspberry-pi-ai-hat/documents/RP-008133-DS-1-raspberry-pi-ai-hat-plus-product-brief.pdf?disposition=inline)
- AI HAT+ 2 
    - Página oficial [https://www.raspberrypi.com/products/ai-hat-plus-2/](https://www.raspberrypi.com/products/ai-hat-plus-2/)
    - Proyectos de la empresa fabricante https://github.com/hailo-ai/hailo-apps

### Características principales

1. Potencia de cálculo (NPU)  
    Su corazón es un acelerador Hailo-8L. Dependiendo del modelo, ofrece un rendimiento de 13 o 26 TOPS (Tera Operaciones por Segundo). Esto permite procesar redes neuronales complejas (como detección de objetos en tiempo real o segmentación de imágenes) de forma fluida.
2. Conexión de alta velocidad   
    Se conecta directamente al puerto PCIe 2.0 de la Raspberry Pi 5. Esto es clave porque permite que los datos viajen mucho más rápido entre el procesador principal y el chip de IA, evitando los "cuellos de botella" que tenían los modelos anteriores por USB.
3. Integración total (Plug &amp; Play)  
    Al ser un accesorio oficial, el sistema operativo Raspberry Pi OS la reconoce automáticamente. No necesitas instalar controladores complicados; las librerías de cámara estándar (como rpicam-apps) ya vienen preparadas para usar este hardware.
4. Eficiencia energética y térmica  
    Está diseñada para consumir poca energía mientras trabaja a máxima potencia. Además, su formato permite que el ventilador oficial de la Raspberry Pi 5 siga funcionando debajo de ella, manteniendo todo el sistema fresco.
5. Formato HAT+  
    Sigue el nuevo estándar HAT+, lo que significa que es más delgada, permite el apilamiento de otras placas y tiene una gestión de energía más inteligente que los HAT antiguos.

### Versiones

En este momento, según la documentación de la web de la Raspberry nos encontramos con las siguientes versiones hardware:

<table border="1" id="bkmrk-versi%C3%B3n-chip-rendimi" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 16.329%;"></col><col style="width: 11.0846%;"></col><col style="width: 14.6623%;"></col><col style="width: 57.9241%;"></col></colgroup><tbody><tr><td class="align-center">**Versión**</td><td class="align-center">**Chip**</td><td class="align-center">**Rendimiento**</td><td class="align-center">**RAM**</td></tr><tr><td>AI HAT+ 13 TOPS</td><td>Hailo-8L</td><td class="align-right">13 TOPS</td><td>Comparte la de la Raspberry Pi.</td></tr><tr><td>AI HAT+ 26 TOPS</td><td>Hailo-8L</td><td class="align-right">26 TOPS</td><td>Comparte la de la Raspberry Pi.</td></tr><tr><td>AI HAT+2</td><td>Hailo-10</td><td class="align-right">40 TOPS</td><td>Tiene 8 GB dedicados en la propia placa</td></tr></tbody></table>

## AI Camera

<p class="callout danger">En la documentación de este producto hacen especial hincapié en no manejarlo si tenemos riesgo de pasarle electricidad estática pues el producto es tremendamente sensible a este tipo de corrientes.</p>

### Qué es

[![producto.png](https://libros.catedu.es/uploads/images/gallery/2026-03/scaled-1680-/producto.png)](https://libros.catedu.es/uploads/images/gallery/2026-03/producto.png)

Es un módulo de cámara oficial que combina un sensor de imagen de alta calidad (Sony IMX500) con un procesador de IA (NPU) **integrado en el mismo hardware**. Sirve para dotar de visión artificial a cualquier modelo de Raspberry Pi (desde la Zero hasta la 5) sin sobrecargar el procesador principal. Como la cámara hace el trabajo sucio de la IA, el procesador de tu Raspberry Pi queda libre para otras tareas. Puede ejecutar modelos de detección de objetos a una velocidad de fotogramas muy alta y con muy baja latencia

### Enlaces de interés

- Página oficial: [https://www.raspberrypi.com/products/ai-camera/](https://www.raspberrypi.com/products/ai-camera/)
- Documentación oficial https://www.raspberrypi.com/documentation/accessories/ai-camera.html
- Resumen: [https://pip-assets.raspberrypi.com/categories/1044-raspberry-pi-ai-camera/documents/RP-008147-DS-1-ai-camera-product-brief.pdf?disposition=inline](https://pip-assets.raspberrypi.com/categories/1044-raspberry-pi-ai-camera/documents/RP-008147-DS-1-ai-camera-product-brief.pdf?disposition=inline)

### Características principales

1. Sensor de imagen inteligente (Sony IMX500): Es el primer sensor de visión con procesamiento de IA integrado. Combina un sensor de 12.3 megapíxeles con un acelerador lógico (NPU) en el mismo chip. Esto permite capturar la imagen y analizarla en microsegundos.
2. Procesamiento "On-board" (NPU integrada)
3. Potencia: Ofrece un rendimiento de 2.3 TOPS (Tera Operaciones por Segundo): La Raspberry Pi no tiene que "pensar" para reconocer objetos; la cámara le envía directamente los metadatos (por ejemplo: "Hay una persona en estas coordenadas con un 95% de certeza").
4. Compatibilidad universal   
    A diferencia de los AI HAT+ (que solo funcionan con la Raspberry Pi 5), la AI Camera se conecta mediante el puerto CSI (cámara) estándar. Esto la hace compatible con:  
    Raspberry Pi 4 y 5.  
    Raspberry Pi Zero / Zero 2 W.  
    Modelos antiguos (3B+, etc.).
5. Resolución: 4056 x 3040 píxeles.
6. Posee enfoque **manual** ajustable, lo que permite nitidez tanto en objetos cercanos como lejanos.
7. Campo de visión (FoV): 76 grados, ideal para vigilancia y robótica estándar.
8. Baja latencia: Al procesar la IA en el sensor, no hay retrasos por el envío de datos pesados a través de cables.
9. Ahorro de energía: Consume mucho menos que un HAT de IA externo, lo que la hace perfecta para proyectos que funcionan con baterías.
10. Software "Plug &amp; Play": Está totalmente integrada en el ecosistema oficial. Utiliza las librerías rpicam-apps, por lo que puedes ejecutar modelos de detección de objetos o segmentación con comandos muy sencillos, sin necesidad de instalar complejos entornos de programación.

[![diseno.png](https://libros.catedu.es/uploads/images/gallery/2026-03/scaled-1680-/diseno.png)](https://libros.catedu.es/uploads/images/gallery/2026-03/diseno.png)

### Versiones

En este momento no existen versiones de este hardware. Hay que tener en cuenta que si existen otras cámaras compatibles con la raspberry pi pero estas no incorporan chips de IA y, por tanto, el trabajo deberá hacerlo la raspberry pi o una placa de expansión específica con lo que perderemos la ventaja de este chip.

### Montaje

El montaje de la cámara en la Raspberry Pi 5 ha resultado muy sencillo. Se ha utilizado una pulsera anti estática para evitar los riesgos indicados por el fabricante. En la Raspberry Pi se dispone de 2 bahías dónde conectarla (la 0 y la 1). En mi caso la he conectado a la ranura 0. En la caja venían 2 cables para conectar la cámara. Uno mas ancho que otro. He tenido que utilizar el estrecho. En el proyecto indico como verificar que está correctamente instalada.

## Proyectos

Los proyectos que a continuación se indican se han realizado con el siguiente hardware:

- Raspberry Pi 5 de 16 GB de RAM
- Cargador oficial de Raspberry Pi 5
- Tarjeta microSD oficial de 128 GB (en previsión de descarga de modelo IA de gran tamaño)
- Raspberry Pi IA HAT+ en su versión de 26 TOPs 
    - el término TOPs es una unidad de medida que se utiliza para cuantificar el rendimiento de los procesadores diseñados para ejecutar tareas de IA. Sus siglas significan Tera Operations Per Second (Billones de operaciones por segundo)
- Raspberry Pi IA Camera

No nos ha sido posible encontrar en el mercado la versión AI HAT+2 (40 TOPs y memoria dedicada). Probablemente llevándose el desarrollo de la práctica principal a ese hardware se hubiera cumplido el objetivo inicial.

Todo ensablado queda como se ve en la siguiente imagen:

<span style="background-color: rgb(251, 238, 184);">(TO DO)</span>

### Creación de un LLM de uso local sin dependencia de internet

Como ya se adelantó anteriormente, la idea era montar una IA generativa en local que nos asegurase el no envío de nuestros datos de trabajo al exterior. A continuación enumero los diferentes pasos realizados. Comenzamos:

1. Con Raspberry Pi imager cargo en la SD la imagen del sistema operativo para la raspberry pi 5
2. Actualizamos sistema y borramos paquetes innecesarios 
    1. Ejecutamos en terminal `sudo apt update && sudo apt upgrade -y && sudo apt autoremove -y && sudo apt clean`
3. Instalamos Ollama 
    1. Nos va a permitir gestionar modelos de lenguaje
    2. Web de Ollama con información [https://ollama.com/](https://ollama.com/)
    3. Ejecutamos en terminal `curl -fsSL https://ollama.com/install.sh | sh`
    4. Tras instalarlo merece la pena fijarse en 3 líneas que arroja el instalador: 
        1. `The Ollama API is now available at 127.0.0.1:11434` Nos indica dónde ha montado por defecto un servidor al cual lanzarle peticiones
        2. `Install complete. Run "ollama" from the command line.` Nos indica cual es el comando que deberamos usar para trabajar con Ollama
        3. `WARNING: No NVIDIA/AMD GPU detected. Ollama will run in CPU-only mode.` Aquí ya nos advierte de que el funcionamiento de Ollama no va a ser óptimo
4. Descargamos un modelo para trabajar con él 
    1. Enumero los que en este momento (abril de 2026) corren en el hw con el que contamos: 
        1. llama3.2:3b (rápido y ligero)
        2. mistral:7b (más capaz, mas lento)
        3. phi3:mini (muy eficiente para su tamaño)
        4. gemma2:2b (excelente relación calidad/velocidad)
    2. Instalamos 1 de ellos. Los demás se haría de modo análogo 
        1. Ejecutamos en el terminal `ollama pull phi3:mini`
5. Lo probamos a través de una llamada al API REST (documentación del endpoint que vamos a usar [https://docs.ollama.com/api/generate](https://docs.ollama.com/api/generate) ) 
    1. Escribimos en el terminal:
    2. `curl http://127.0.0.1:11434/api/generate -d '{ "model": "phi3:mini", "prompt": "Explica qué es una raspberry pi", "stream": false }'`
    3. Y esperamos por aproximadamete **4 minutos** para ver el resultado. Luego con este modelo, no es funcional
6. Vamos a descargar otro modelo mas ligero y repetir la consulta para ese modelo: 
    1. `ollama pull llama3.2:3b`
    2. `curl http://127.0.0.1:11434/api/generate -d '{ "model": "llama3.2:3b", "prompt": "Explica qué es una raspberry pi", "stream": false }'` en esta ocasión la respuesta se ha demorado **2 minutos** lo cual sigue haciendo, bajo mi punto de vista, al modelo poco eficiente como sustituto de las IAs comerciales.
7. Vamos a preparar una interfaz web para quienes no quieran usar el terminal. 
    1. Uaremos docker, si no lo tienes instalado, tines que instalarlo: 
        1. Consulta la documentación en web oficial para hacerlo. Yo te dejo a continuación lo que en la fecha actual he hecho yo para instalarlo
        2. `sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-doc podman-docker containerd runc | cut -f1)`
        3. ```bash
            # Add Docker's official GPG key:
            sudo apt update
            sudo apt install ca-certificates curl
            sudo install -m 0755 -d /etc/apt/keyrings
            sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
            sudo chmod a+r /etc/apt/keyrings/docker.asc
            
            # Add the repository to Apt sources:
            sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
            Types: deb
            URIs: https://download.docker.com/linux/debian
            Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
            Components: stable
            Architectures: $(dpkg --print-architecture)
            Signed-By: /etc/apt/keyrings/docker.asc
            EOF
            
            sudo apt update
            ```
        4. `sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin`
        5. `sudo systemctl status docker`
        6. `sudo groupadd docker` quizás te diga que ya existe
        7. `sudo usermod -aG docker $USER`
        8. `sudo groupadd docker`
        9. `sudo systemctl <span class="nb">enable</span> containerd.service`
        10. Reiniciamos
    2. Ahora ejecutaremos en el terminal `docker run -d -p 3000:8080 --add-host=host.docker.internal:host-gateway -e OLLAMA_BASE_URL=http://host.docker.internal:11434 ghcr.io/open-webui/open-webui:main`
    3. Si ahora accedemos en el navegador a [http://localhost:3000](http://localhost:3000) tendremos acceso a una interface web para interactuar con la IA que hemos preparado y/o con openIA

En las llamadas a curl hemos utilizado 3 parámetros:

- model: Obligatorio. Nombre del modelo a usar.
- promt: Obligatorio. Texto de entrada.
- stream: `true` devuelve tokens uno a uno, `false` espera respuesta completa

Puede resultar interesante conocer estos otros:

- system: Define el comportamiento/personalidad del modelo
- options 
    - temperature: valores entre 0.0 y 1.0. Recomendado 0.7. Determinista y precio 0.0. Creativo y variado 1.0
    - top\_p: diversidad del vocabulario. Recomendado 0.9
    - top\_k: limita el número de tokens candidatos en cada paso
    - num\_predict: máximo de tokens a generar en la respuesta (-1: sin límite)
    - num\_ctx: tamaño de la ventana de contexto (memoria del modelo). Cuanto mas alto mas conversación recuerda pero uso mas RAM.
    - repeat\_penalty: penaliza repetir las mismas palabras (Sin penalización 1.0. Penalización alta 1.3)
    - seed: fija la semilla aleatoria. Útil para reproducir exactamente la misma respuesta
- format: formato de salida. "jason" obliga al modelo a responder en un JSON válido
- keep\_alive: tiempo que el modelo permanece cargado en RAM tras la llamada (5 minutos 5m. Descarga inmediata 0) Mas permanencia, mas consumo de RAM.

Aquí un ejemplo completo:

```json
{
  "model": "llama3.2:3b",
  "prompt": "Explica qué es una Raspberry Pi",
  "stream": false,

  "system": "Eres un asistente experto en electrónica",

  "options": {
    "temperature": 0.7,
    "top_p": 0.9,
    "top_k": 40,
    "num_predict": 512,
    "num_ctx": 2048,
    "repeat_penalty": 1.1,
    "seed": 42
  },

  "format": "json",
  "keep_alive": "5m"
}
```

La documentación completa de la API la tenemos disponible en [https://docs.ollama.com/api/introduction](https://docs.ollama.com/api/introduction) Además de /api/generate puede resultarte interesante probar /api/chat

### Tratando de optimizar el funcionamiento

Tras buscar información en internet he encontrado que al hacer uso de ollama para correr un LLM no estamos realmente haciendo uso del HAT y que el HAT en si (esta versión del HAT) no está pensada para correr LLMs sino para ejecutar modelos relacionados con reconocimiento de imagen y audio así que descarto esa función y vamos a focalizarnos en los 2 siguientes

### AI HAT+ sin cámara: procesamiento de vídeo

Vamos a tratar de detectar elementos de un vídeo que descarguemos de internet

<p class="callout warning">Para resumir lo hecho en 8 pasos he realizado multitud de pruebas e interacciones con la IA para conseguir resultados</p>

1. Actualizamos el sistema `sudo apt update && sudo apt upgrade -y`
2. Instalamos las bibliotecas del HAT `sudo apt install hailo-all -y`
3. Reiniciamos `sudo reboot`
4. Verificamos instalación `python3 -c "from hailo_platform import VDevice; print('HailoRT OK')"`
5. Instalamos dependencias: `pip3 install opencv-python numpy --break-system-packages`
6. Creamos el script `nano ~/detector_trafico.py`
    1. ```python
        import cv2
        import numpy as np
        from hailo_platform import VDevice, HEF, HailoStreamInterface, InferVStreams, ConfigureParams, InputVStreamParams, OutputVStreamParams, FormatType
        import time
        
        HEF_PATH = "/usr/share/hailo-models/yolov8s_h8.hef"
        VIDEO_PATH = "/home/pi/trafico2.mp4"
        OUTPUT_PATH = "/home/pi/trafico2_out.mp4"
        
        COCO_LABELS = [
            "person","bicycle","car","motorcycle","airplane","bus","train","truck",
            "boat","traffic light","fire hydrant","stop sign","parking meter","bench",
            "bird","cat","dog","horse","sheep","cow","elephant","bear","zebra","giraffe",
            "backpack","umbrella","handbag","tie","suitcase","frisbee","skis","snowboard",
            "sports ball","kite","baseball bat","baseball glove","skateboard","surfboard",
            "tennis racket","bottle","wine glass","cup","fork","knife","spoon","bowl",
            "banana","apple","sandwich","orange","broccoli","carrot","hot dog","pizza",
            "donut","cake","chair","couch","potted plant","bed","dining table","toilet",
            "tv","laptop","mouse","remote","keyboard","cell phone","microwave","oven",
            "toaster","sink","refrigerator","book","clock","vase","scissors","teddy bear",
            "hair drier","toothbrush"
        ]
        
        COLORS = [(0,255,0),(0,0,255),(255,0,0),(0,255,255),(255,0,255),(255,255,0)]
        
        def letterbox(img, new_shape=(640, 640)):
            h, w = img.shape[:2]
            scale = min(new_shape[0]/h, new_shape[1]/w)
            new_w, new_h = int(w * scale), int(h * scale)
            resized = cv2.resize(img, (new_w, new_h))
            top = (new_shape[0] - new_h) // 2
            bottom = new_shape[0] - new_h - top
            left = (new_shape[1] - new_w) // 2
            right = new_shape[1] - new_w - left
            padded = cv2.copyMakeBorder(resized, top, bottom, left, right, cv2.BORDER_CONSTANT, value=(114,114,114))
            return padded, scale, left, top
        
        def run_detection():
            cap = cv2.VideoCapture(VIDEO_PATH)
            if not cap.isOpened():
                print(f"Error: No se pudo abrir {VIDEO_PATH}")
                return
        
            fps = cap.get(cv2.CAP_PROP_FPS) or 30
            w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
            h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
            out = cv2.VideoWriter(OUTPUT_PATH, cv2.VideoWriter_fourcc(*'mp4v'), fps, (w, h))
            print(f"Procesando vídeo: {w}x{h} @ {fps} FPS")
        
            with VDevice() as target:
                hef = HEF(HEF_PATH)
                configure_params = ConfigureParams.create_from_hef(hef, interface=HailoStreamInterface.PCIe)
                network_groups = target.configure(hef, configure_params)
                network_group = network_groups[0]
                network_group_params = network_group.create_params()
        
                input_info = hef.get_input_vstream_infos()[0]
                input_h, input_w = input_info.shape[0], input_info.shape[1]
        
                input_vstreams_params = InputVStreamParams.make(network_group, format_type=FormatType.UINT8)
                output_vstreams_params = OutputVStreamParams.make(network_group, format_type=FormatType.FLOAT32)
        
                frame_count = 0
                t_start = time.time()
        
                with InferVStreams(network_group, input_vstreams_params, output_vstreams_params) as infer_pipeline:
                    with network_group.activate(network_group_params):
                        while cap.isOpened():
                            ret, frame = cap.read()
                            if not ret:
                                break
        
                            lb, scale, pad_left, pad_top = letterbox(frame, (input_h, input_w))
                            rgb = cv2.cvtColor(lb, cv2.COLOR_BGR2RGB)
                            input_data = {input_info.name: np.expand_dims(rgb.astype(np.uint8), axis=0)}
        
                            raw_detections = infer_pipeline.infer(input_data)
        
                            for output_name, val in raw_detections.items():
                                batch0 = val[0]
                                for cls_id, class_dets in enumerate(batch0):
                                    dets = np.array(class_dets)
                                    if dets.ndim == 2 and len(dets) > 0:
                                        for d in dets:
                                            conf = float(d[4])
                                            if conf > 0.4:
                                                # Formato: [y1, x1, y2, x2] normalizado
                                                x1 = int((d[1] * input_w - pad_left) / scale)
                                                y1 = int((d[0] * input_h - pad_top) / scale)
                                                x2 = int((d[3] * input_w - pad_left) / scale)
                                                y2 = int((d[2] * input_h - pad_top) / scale)
                                                # Clamp para evitar coordenadas fuera de imagen
                                                x1, x2 = max(0, x1), min(w, x2)
                                                y1, y2 = max(0, y1), min(h, y2)
                                                label = COCO_LABELS[cls_id] if cls_id < len(COCO_LABELS) else f"ID:{cls_id}"
                                                color = COLORS[cls_id % len(COLORS)]
                                                cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2)
                                                cv2.putText(frame, f"{label} {conf:.2f}", (x1, y1 - 5),
                                                            cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
        
                            out.write(frame)
                            frame_count += 1
                            if frame_count % 30 == 0:
                                elapsed = time.time() - t_start
                                print(f"Frame {frame_count} | FPS: {frame_count/elapsed:.1f}")
        
            cap.release()
            out.release()
            elapsed = time.time() - t_start
            print(f"\n✅ COMPLETADO")
            print(f"Frames: {frame_count} | Tiempo: {elapsed:.1f}s | FPS: {frame_count/elapsed:.1f}")
            print(f"📹 Guardado en: {OUTPUT_PATH}")
        
        if __name__ == "__main__":
            run_detection()
        ```
7. Ejecutamos python3 ~/detector\_trafico.py 
    1. Necesitarás tener un vídeo llamado trafico.mp4 en /home/pi o cambiar la ruta
    2. El resultado lo verás en trafico\_out.mp4

Abro simultáneamente el vídeo original y el generado con la detección de objetos y este es el resultado:

[![vs.png](https://libros.catedu.es/uploads/images/gallery/2026-03/scaled-1680-/vs.png)](https://libros.catedu.es/uploads/images/gallery/2026-03/vs.png)

En la imagen se puede ver que detecta coches y la probabilidad con la que "cree" que son coches. En el vídeo también aparecen personas, motocicletas, camiones,... y todas ellas las va detectando mientras varía el porcentaje de seguridad (1: implica seguridad plena y 0: nada seguridad)

<p class="callout warning">El proceso de poner este proyecto en marcha me ha llevado aproximadamente 5h y ha sido poco intuitivo y por momentos parecía orientado al fracaso.</p>

<p class="callout info">En estas 5h en que la raspberry pi ha estado trabajando junto con el hat ninguna de las placas se ha sobrecalentado mas allá de lo razonable y la sensación de fluided del dispositivo ha sido total.</p>

### AI HAT+ y AI cámara

Lo primero ha sido verificar que la cámara estaba correctamente instalada, para ello:

```
sudo apt update
sudo apt install libcamera-apps
rpicam-hello --list-cameras
```

Lo que en mi caso ha devuelto:

```
Available cameras
-----------------
0 : imx500 [4056x3040 10-bit RGGB] (/base/axi/pcie@1000120000/rp1/i2c@88000/imx500@1a)
    Modes: 'SRGGB10_CSI2P' : 2028x1520 [30.02 fps - (0, 0)/4056x3040 crop]
                             4056x3040 [10.00 fps - (0, 0)/4056x3040 crop]
```

Lo que significa que ha encontrado la cámara conectada, su tipo y sus características.

Si quieres ver qué se está viendo por la cámara dispones del comando `rpicam-hello -t 0` mientras que si quieres hacer una foto puedes usar `rpicam-still -o foto.jpg`

Ahora comenzaremos con la **parte de IA** de la cámara:

```bash
sudo apt update
sudo apt install imx500-all
```

En `/usr/share/rpi-camera-assets/` se habrán guardado los ficheros .json de demostración que incorpora el paquete.

Podemos probar diferentes modos de funcionamiento con `rpicam-hello -t 0 --post-process-file /usr/share/rpi-camera-assets/imx500_mobilenet_ssd.json` y con `rpicam-hello -t 0 --post-process-file /usr/share/rpi-camera-assets/imx500_posenet.json` Los comandos anteriores funcionarán respectivamente para la detección de objetos y la detección de esqueleto (brazos, piernas y tronco)