<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>raspberry &#8211; El Cornijal de Linux</title>
	<atom:link href="https://linuxete.duckdns.org/author/raspberry/feed/" rel="self" type="application/rss+xml" />
	<link>https://linuxete.duckdns.org</link>
	<description>Un blog sobre Linux</description>
	<lastBuildDate>Sat, 14 Mar 2026 22:41:05 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>El misterio de la pantalla negra en Raspberry Pi 5: ¿Culpa del NVMe?</title>
		<link>https://linuxete.duckdns.org/el-misterio-de-la-pantalla-negra-en-raspberry-pi-5-culpa-del-nvme/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=el-misterio-de-la-pantalla-negra-en-raspberry-pi-5-culpa-del-nvme</link>
					<comments>https://linuxete.duckdns.org/el-misterio-de-la-pantalla-negra-en-raspberry-pi-5-culpa-del-nvme/#respond</comments>
		
		<dc:creator><![CDATA[raspberry]]></dc:creator>
		<pubDate>Sat, 14 Mar 2026 18:47:43 +0000</pubDate>
				<category><![CDATA[Raspberry PI]]></category>
		<category><![CDATA[cmdline.txt]]></category>
		<category><![CDATA[Debian 13]]></category>
		<category><![CDATA[EEPROM]]></category>
		<category><![CDATA[HDMI Fix]]></category>
		<category><![CDATA[lightdm]]></category>
		<category><![CDATA[No signal]]></category>
		<category><![CDATA[NVMe]]></category>
		<category><![CDATA[Pantalla Negra]]></category>
		<category><![CDATA[PCIe Gen 3]]></category>
		<category><![CDATA[Raspberry Pi 5]]></category>
		<category><![CDATA[Raspberry Pi OS]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[Tutorial]]></category>
		<guid isPermaLink="false">https://linuxete.duckdns.org/?p=4047</guid>

					<description><![CDATA[Hasta hace unos días, mi vida tecnológica con la nueva Raspberry Pi 5 era un remanso de paz. Tenía conectado un disco SSD de 2,5 pulgadas y todo funcionaba como la seda. Pero, como nos pasa a todos los que nos gusta «cacharrear», decidí dar el salto a la máxima velocidad y actualicé a un [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Hasta hace unos días, mi vida tecnológica con la nueva <strong>Raspberry Pi 5</strong> era un remanso de paz. Tenía conectado un disco SSD de 2,5 pulgadas y todo funcionaba como la seda. Pero, como nos pasa a todos los que nos gusta «cacharrear», decidí dar el salto a la máxima velocidad y actualicé a un <strong>disco SSD NVMe</strong>. Ahí es donde empezaron los sudores fríos.</p>



<p>De repente, cada vez que reiniciaba el sistema, la Pi arrancaba pero con la <strong>pantalla más negra que los huevos de un burro</strong>. Al principio, el pánico: pensé que el sistema se colgaba y no arrancaba. Cambié el HAT, probé otro disco NVMe, compré cables HDMI nuevos e incluso reinstalé el sistema operativo varias veces. ¿El resultado? El mismo vacío oscuro.</p>



<p>Sin embargo, al entrar por <strong>SSH</strong> desde mi teléfono, descubrí la verdad: la Pi estaba vivita y coleando, con el sistema totalmente cargado y funcionando de fondo. El problema no era que la Pi no arrancara, ¡era que no quería hablar con mi monitor!</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Nota: Para que el sistema arranque de forma normal quita el cable de alimentación y tras 5 segundos vuelve a conectar.</p>
</blockquote>



<h3 class="wp-block-heading">¿Por qué el NVMe «rompe» el vídeo al reiniciar?</h3>



<p>Si te está pasando lo mismo, no te vuelvas loco cambiando hardware. La explicación de por qué con una tarjeta SD o un SSD lento todo iba bien y con el NVMe oficial falla, se resume en estos tres factores:</p>



<ul class="wp-block-list">
<li><strong>Tu Raspberry Pi ahora es «demasiado rápida»:</strong> Imagina que el arranque es una conversación. Con la SD, la Pi tardaba 30 segundos; al monitor le daba tiempo a despertarse y tomarse un café. Con el NVMe, el sistema carga en 5 segundos. La Pi lanza la señal de vídeo tan rápido que el monitor aún está «desperezándose» del reinicio. Cuando el monitor quiere mirar, la Pi ya ha dejado de llamar a la puerta y ambos se quedan esperando en silencio.</li>



<li><strong>Interferencias y «ruido» eléctrico:</strong> El bus PCIe donde va tu NVMe funciona a frecuencias altísimas que generan ondas electromagnéticas. Como los puertos micro-HDMI están pegados al conector PCIe en la Pi 5, ese «ruido» puede ensuciar la señal. Si el cable no es de excelente calidad, la Pi no recibe los datos del monitor (EDID) y, por seguridad, apaga la salida.</li>



<li><strong>El reinicio «suave» vs «fuerte»:</strong> Al reiniciar desde el escritorio, el driver de vídeo a veces no se cierra correctamente antes de que el rapidísimo NVMe vuelva a cargar todo. Esto deja a la gráfica en un estado de confusión total.</li>
</ul>



<p><strong>En resumen:</strong> Es como si tu Raspberry Pi fuera ahora un coche de carreras. Arranca tan rápido que sale del garaje antes de que la puerta (tu monitor) termine de abrirse.</p>



<p>A continuación, te explico los pasos exactos para decirle a tu Pi: <em>«Espera un segundo antes de salir y, aunque veas la puerta cerrada, empuja, que se abrirá»</em>.</p>



<h3 class="wp-block-heading">El cambio imprescindible (De Wayland a X11)</h3>



<p>Por defecto, la Raspberry Pi 5 utiliza <strong>Wayland</strong>. Sin embargo, Wayland todavía tiene problemas para gestionar el «Screen Blanking» (que la pantalla se apague sola tras un tiempo sin uso).</p>



<p>Si quieres que tu monitor descanse y que los comandos que vamos a usar funcionen, debemos volver al servidor gráfico <strong>X11</strong>.</p>



<h4 class="wp-block-heading">¿Cómo cambiar a X11?</h4>



<ol start="1" class="wp-block-list">
<li>Abre una terminal y escribe: <code>sudo raspi-config</code></li>



<li>Ve a <strong>6 Advanced Options</strong>.</li>



<li>Busca <strong>A6 Wayland</strong>.</li>



<li>Selecciona <strong>W1 X11</strong> (o el que indique que desactiva Wayland).</li>



<li>Dale a <strong>Finish</strong> y acepta el <strong>Reboot</strong> (reiniciar).</li>
</ol>



<p><em>Ahora que estamos en X11, todos los comandos de ahorro de energía y gestión de pantalla funcionarán como un reloj.</em></p>



<h2 class="wp-block-heading">Parte 1: El «Seguro de Vida» (Configurar SSH)</h2>



<p>Antes de meterle mano a la configuración interna, necesitamos una forma de hablar con la Raspberry Pi cuando la pantalla está en negro. Para eso usamos el <strong>SSH (Secure Shell)</strong>. Si puedes entrar por SSH desde tu móvil o tu PC mientras la pantalla está oscura, ¡felicidades!, tu Pi no está muerta, solo está «tímida» con el monitor.</p>



<h3 class="wp-block-heading">1. ¿Cómo saber si el SSH está activo?</h3>



<p>Si tienes la suerte de que la pantalla ha encendido o estás configurándola por primera vez, abre una terminal y comprueba el estado del servicio:</p>



<pre class="wp-block-code"><code>sudo systemctl status ssh
</code></pre>



<h4 class="wp-block-heading">Caso A: El servicio funciona correctamente</h4>



<p>Si ves un mensaje en verde que dice <strong><code>active (running)</code></strong>, todo está perfecto. Ya puedes acceder remotamente.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Ojo:</strong> En mi caso veréis que uso el puerto <strong>22299</strong>, pero por defecto en vuestra Pi será el <strong>22</strong>.</p>
</blockquote>



<pre class="wp-block-code"><code>● ssh.service - OpenBSD Secure Shell server
     Active: active (running) since Sat 2026-03-14 15:15:56 CET; 3h 28min ago
     ...
     mar 14 15:15:56 pi5-2 sshd&#91;1006]: Server listening on 0.0.0.0 port 22299.
</code></pre>



<h4 class="wp-block-heading">Caso B: El servicio está apagado o muerto</h4>



<p>Si por el contrario ves que dice <strong><code>inactive (dead)</code></strong>, significa que estás «ciego» si la pantalla falla. Tienes que activarlo obligatoriamente.</p>



<pre class="wp-block-code"><code>○ ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (...; disabled; ...)
     Active: inactive (dead)
</code></pre>



<h3 class="wp-block-heading">2. Cómo activar e iniciar el SSH</h3>



<p>Para que el SSH se encienda solo cada vez que arranques la Pi (muy importante para nuestro problema), ejecuta estos dos comandos:</p>



<p><strong>Primero: Habilitar el inicio automático</strong></p>



<pre class="wp-block-code"><code>sudo systemctl enable ssh</code></pre>



<p><em>Verás que el sistema crea unos «symlinks» (accesos directos internos), eso indica que ahora arrancará siempre con el sistema.</em></p>



<p><strong>Segundo: Arrancar el servicio ahora mismo</strong></p>



<pre class="wp-block-code"><code>sudo systemctl start ssh</code></pre>



<h2 class="wp-block-heading">Parte 2: El diagnóstico definitivo (¿Monitor o Sistema?)</h2>



<p>Una vez que tengas SSH, la próxima vez que reinicies y la pantalla se quede <strong>«más negra que los huevos de un burro»</strong>, no entres en pánico. Conéctate desde tu móvil y lanza este comando:</p>



<pre class="wp-block-code"><code>kmsprint</code></pre>



<ul class="wp-block-list">
<li><strong>Si ves <code>HDMI-A-1 (connected)</code> </strong>nos confirma que <strong>la Raspberry Pi sí detecta el monitor</strong>, pero la señal de vídeo no se está «dibujando»</li>



<li><strong>Si quieres forzar el encendido desde el móvil</strong>, pega esto en la terminal de tu móvil:</li>
</ul>



<pre class="wp-block-code"><code>export DISPLAY=:0
xset dpms force on</code></pre>



<p>Si esto no enciende tu monitor, ejecuta:</p>



<pre class="wp-block-code"><code><code>sudo systemctl restart lightdm</code></code></pre>



<p><em>(Esto cerrará tus apps abiertas, pero debería forzar al monitor a recibir señal).</em></p>



<p>En mi caso, reiniciar lightdm encendió mi monitor. </p>



<p>El hecho de que al reiniciar <code>lightdm</code> la pantalla se encienda es la <strong>prueba definitiva</strong>: el sistema operativo arranca bien, el hardware funciona y el disco NVMe está perfecto.</p>



<h2 class="wp-block-heading">Parte 3: La Solución Definitiva (La «D» Mágica)</h2>



<p>Si has confirmado que por SSH todo funciona pero el HDMI se queda frito, vamos a aplicar la medicina. Editamos el archivo de configuración del arranque:</p>



<pre class="wp-block-code"><code>sudo nano /boot/firmware/cmdline.txt</code></pre>



<p>Ve al final de la única línea que hay, añade un espacio y escribe:</p>



<p><code>video=HDMI-A-1:1920x1080@60D</code></p>



<p><strong>¿Por qué la D?</strong> Porque le dice a la Pi: <em>«Envía señal Digital sí o sí, no preguntes al monitor si está listo, ¡dispara!»</em>.</p>



<h3 class="wp-block-heading">Un último ajuste en la EEPROM</h3>



<p>Para que el disco NVMe y el vídeo se lleven bien eléctricamente en la Raspberry Pi 5, te recomiendo este cambio final:</p>



<pre class="wp-block-code"><code>sudo rpi-eeprom-config --edit</code></pre>



<p>Añade o cambia estas líneas:</p>



<ul class="wp-block-list">
<li><code>POWER_OFF_ON_HALT=1</code></li>



<li><code>HDMI_DELAY=1</code></li>
</ul>



<p>Este paso es como ajustar el «reloj interno» y la gestión eléctrica de la placa base de tu Raspberry Pi 5. Es el ajuste que soluciona el conflicto físico entre el disco NVMe y el puerto HDMI.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<ul class="wp-block-list">
<li><strong><code>POWER_OFF_ON_HALT=1</code></strong>: Fuerza un reinicio eléctrico completo. Evita que el disco «atonté» a la salida de vídeo.</li>



<li><strong><code>HDMI_DELAY=1</code></strong>: Le da un segundo de ventaja al monitor para que esté listo antes de que la Pi empiece a enviar imágenes.</li>
</ul>
</blockquote>



<p>¡Y listo! Con esto habrás pasado de tener un pisapapeles caro a una <strong>Raspberry Pi 5 con NVMe</strong> que vuela y que no se achica ante ningún reinicio.</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxete.duckdns.org/el-misterio-de-la-pantalla-negra-en-raspberry-pi-5-culpa-del-nvme/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Cómo diagnosticar y optimizar un duro SSD o HDD</title>
		<link>https://linuxete.duckdns.org/como-diagnosticar-y-optimizar-un-ssd-usb-en-raspberry-pi/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=como-diagnosticar-y-optimizar-un-ssd-usb-en-raspberry-pi</link>
					<comments>https://linuxete.duckdns.org/como-diagnosticar-y-optimizar-un-ssd-usb-en-raspberry-pi/#respond</comments>
		
		<dc:creator><![CDATA[raspberry]]></dc:creator>
		<pubDate>Mon, 09 Mar 2026 22:12:12 +0000</pubDate>
				<category><![CDATA[Raspberry PI]]></category>
		<category><![CDATA[hdparm]]></category>
		<category><![CDATA[raspberry-pi]]></category>
		<category><![CDATA[rendimiento-ssd]]></category>
		<category><![CDATA[salud-ssd]]></category>
		<category><![CDATA[smartctl]]></category>
		<category><![CDATA[uasp]]></category>
		<guid isPermaLink="false">https://linuxete.duckdns.org/?p=4000</guid>

					<description><![CDATA[En mi último post hablé de cómo usar una Raspberry Pi Zero para monitorizar un SAI Salicru con NUT y Telegram, evitando esos molestos unsafe shutdowns que tanto dañan los SSD o las SD cards. Pues bien, todo empezó porque tenía un SSD Kingston A400 240GB conectado por USB 3.0 en mi Raspberry Pi 5, [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>En mi último post hablé de cómo usar una Raspberry Pi Zero para monitorizar un SAI Salicru con NUT y Telegram, evitando esos molestos <em>unsafe shutdowns</em> que tanto dañan los SSD o las SD cards. Pues bien, todo empezó porque tenía un SSD Kingston A400 240GB conectado por USB 3.0 en mi Raspberry Pi 5, y quería saber si estaba sano, rápido y bien configurado.</p>



<p>Hoy os cuento el proceso paso a paso que usé para chequearlo todo: desde identificar el adaptador USB-SATA hasta medir velocidad real y ver la salud interna del disco con SMART. Estos comandos son oro puro para cualquiera que use boot desde SSD USB, NAS casero, backups o simplemente quiera exprimir su Pi sin sorpresas.</p>



<h3 class="wp-block-heading">¿Por qué molestarse en hacer esto?</h3>



<ul class="wp-block-list">
<li><strong>Saber si tu SSD (o HDD) está sano</strong>: Evitas perder datos por fallos silenciosos (bad blocks, sectores reasignados, desgaste excesivo).</li>



<li><strong>Medir rendimiento real</strong>: Muchos enclosures USB baratos limitan a 30-50 MB/s o caen a USB 2.0. Con UASP bien configurado, un SSD SATA puede volar a 300-400 MB/s en Pi 5.</li>



<li><strong>Detectar problemas de hardware</strong>: Chipset malo (Realtek vs ASMedia), alimentación inestable, cables defectuosos o quirks del kernel.</li>



<li><strong>Beneficios prácticos</strong>: Boot mucho más rápido que microSD, menos corrupción de filesystem, alertas tempranas si la vida del SSD baja, y tranquilidad total (sobre todo si usas el Pi 24/7).</li>
</ul>



<h3 class="wp-block-heading">1. Lista todos los dispositivos USB conectados.</h3>



<p>En mi caso:</p>



<pre class="wp-block-code"><code>vigilante@raspberrypi:~ $ <strong>lsusb</strong>
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 05e3:0610 Genesys Logic, Inc. Hub
Bus 001 Device 003: ID 04d9:0006 Holtek Semiconductor, Inc. Wired Keyboard (78/79 key) &#91;RPI Wired Keyboard 5]
Bus 001 Device 004: ID 093a:2510 Pixart Imaging, Inc. Optical Mouse
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
<mark style="background-color:#fcb900" class="has-inline-color">Bus 004 Device 002: ID 14b0:0206 StarTech.com Ltd.  SA400S37240G</mark></code></pre>



<p><br>→ Identifica el VID:PID del adaptador (14b0:0206 es StarTech con chipset ASMedia ASM105x, de los mejores). Si ves Realtek (0bda:xxxx), ojo, pueden ser más problemáticos.</p>



<h3 class="wp-block-heading">2. Muestra el árbol USB con drivers y velocidades.</h3>



<pre class="wp-block-code"><code>vigilante@raspberrypi:~ $ <strong>lsusb -t</strong>
/:  Bus 001.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/2p, 480M
    |__ Port 002: Dev 002, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 001: Dev 003, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
        |__ Port 001: Dev 003, If 1, Class=Human Interface Device, Driver=usbhid, 1.5M
        |__ Port 002: Dev 004, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
/:  Bus 002.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/1p, 5000M
/:  Bus 003.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/2p, 480M
/:  Bus 004.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/1p, 5000M
   <mark style="background-color:#fcb900" class="has-inline-color"> |__ Port 001: Dev 002, If 0, Class=Mass Storage, Driver=uas, 5000M</mark></code></pre>



<p><br>→ <strong>Driver=uas</strong> y <strong>5000M</strong> (USB 3.0) → ¡UASP activo! Esto es lo que queremos: bajo uso CPU, mejor rendimiento secuencial. Si ves «usb-storage» en vez de «uas», es más lento y usa más CPU.</p>



<h3 class="wp-block-heading">3<strong>. Instalar herramientas</strong>.</h3>



<pre class="wp-block-code"><code>   sudo apt update
   sudo apt install hdparm smartmontools</code></pre>



<p>Las herramientas necesarias para la monitorio son:<br><code><strong>- hdparm</strong></code> para tests de velocidad<br><code><strong>- smartmontools </strong></code>para SMART (salud del disco).</p>



<h3 class="wp-block-heading">4. El Autodiagnóstico: Obligando al SSD a decir la verdad</h3>



<p>A veces, un vendedor de segunda mano puede haber «reseteado» los contadores SMART o simplemente el disco aún no ha registrado un fallo que acaba de ocurrir. Para eso usamos el <strong>Short Self-Test</strong>.</p>



<p>Ejecuta este comando para iniciar un chequeo instantáneo:</p>



<pre class="wp-block-code"><code>sudo smartctl -t short -d sat /dev/sda</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Nota:</strong> Este comando no te dará el resultado al instante. Solo le da la orden al disco y te devuelve el control de la terminal. Es como pedir cita en el médico: la orden está dada, pero el examen lleva su tiempo (normalmente 1 o 2 minutos).</p>
</blockquote>



<p>Este comando es una buena opción para mirar los atributos, porque obliga al disco a trabajar en ese momento. Si hay un fallo físico inminente, el test se detendrá y te avisará. Es la forma más rápida de saber si el SSD que tienes en las manos es fiable.</p>



<p><strong>¿Cómo sé si ha terminado?</strong> Tienes que consultar el log después de que pase ese tiempo usando el comando: </p>



<pre class="wp-block-code"><code><code>sudo smartctl -l selftest -d sat /dev/sda</code></code></pre>



<p>Este comando arroja sobre mi disco la siguiente información:</p>



<pre class="wp-block-code"><code>vigilante@raspberrypi:~ $ <strong>sudo smartctl -l selftest -d sat /dev/sda</strong>
smartctl 7.4 2023-08-01 r5530 &#91;aarch64-linux-6.12.62+rpt-rpi-2712] (local build)
Copyright (C) 2002-23, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF READ SMART DATA SECTION ===
SMART Self-test log structure revision number 1
Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
# 1  Short offline       Completed without error       00%      9098         -

</code></pre>



<p>¿<strong>Cómo leer el log de autodiagnóstico? (Self-test)</strong></p>



<p>Esto es lo que debes mirar:</p>



<ul class="wp-block-list">
<li><strong>Status: «Completed without error»</strong>. Esta es la clave. Significa que el disco ha analizado sus componentes internos, la electrónica y la superficie de las celdas de memoria y <strong>no ha encontrado fallos físicos</strong>.</li>



<li><strong>Remaining: «00%»</strong>. Indica que el test ha terminado por completo, si hay otro valor, espera y lanza el comando otra vez para ver si terminó.</li>



<li><strong>LifeTime(hours): «9098»</strong>. Es el momento exacto en la vida del disco en el que se hizo el test.</li>



<li><strong>LBA_of_first_error: «-«</strong>. Si aquí aparece un número, es la dirección del sector donde el disco ha fallado. Al aparecer un guion, confirmamos que el disco está limpio.</li>
</ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Ese comando tiene dos variantes de test:<br><code><strong>- short</strong></code>: Tarda 1-2 minutos y revisa lo más crítico.<br><code>- <strong>long</strong></code>: Puede tardar 1 hora o más porque lee <strong>cada una</strong> de las celdas del disco. Para una compra de Wallapop, con el <code>short</code> suele ser suficiente, pero si el disco es muy grande y tienes tiempo, el <code>long</code> es la seguridad total.</p>
</blockquote>



<h3 class="wp-block-heading">5. Identifica el disco.</h3>



<p>«Antes de tocar nada, necesitamos saber quién es quién. Usamos <strong>lsblk</strong> para ver de forma clara el modelo y tamaño de nuestros discos, y <strong>fdisk</strong> para confirmar los detalles técnicos y sectores del sistema. Es el primer paso para no equivocarnos de unidad al formatear o testear.»</p>



<p><strong><code>lsblk -o NAME,SIZE,TYPE,MODEL</code> (El DNI del disco)</strong></p>



<p><code>lsblk</code> significa <em>List Block Devices</em>. Es la forma más limpia y moderna de ver qué tienes conectado.</p>



<ul class="wp-block-list">
<li><strong>¿Para qué sirve?</strong> Para identificar rápidamente qué letra tiene tu disco (<code>sda</code>, <code>sdb</code>, etc.) y qué particiones hay dentro.</li>



<li><strong>¿Qué significan las opciones?</strong> Con <code>-o</code> le pedimos que solo nos muestre lo que nos interesa:
<ul class="wp-block-list">
<li><strong>NAME:</strong> El nombre técnico (ej. <code>sda</code>).</li>



<li><strong>SIZE:</strong> Cuánto espacio tiene.</li>



<li><strong>TYPE:</strong> Si es un disco entero (<code>disk</code>) o una partición (<code>part</code>).</li>



<li><strong>MODEL:</strong> La marca y modelo real (aquí es donde verás si tu SSD es un Kingston, un Samsung, etc.).</li>
</ul>
</li>



<li><strong>Ventaja:</strong> No necesita permisos de superusuario (<code>sudo</code>) y la salida es muy fácil de leer.</li>
</ul>



<pre class="wp-block-code"><code>vigilante@raspberrypi:~ $ <strong>lsblk -o NAME,SIZE,TYPE,MODEL</strong>
NAME     SIZE TYPE MODEL
loop0      2G loop 
<mark style="background-color:#fcb900" class="has-inline-color">sda    223,6G disk KINGSTON SA400S37240G</mark>
├─sda1   512M part 
└─sda2 223,1G part 
zram0      2G disk </code></pre>



<p><strong><code>sudo fdisk -l | grep -i disk</code> (La Radiografía técnica)</strong></p>



<p><code>fdisk</code> es una herramienta clásica y potente para manejar tablas de particiones.</p>



<ul class="wp-block-list">
<li><strong>¿Para qué sirve?</strong> Muestra detalles mucho más técnicos que <code>lsblk</code>, como el número exacto de sectores, el identificador del disco y el tamaño en bytes exactos.</li>



<li><strong>¿Por qué usamos el <code>grep -i disk</code>?</strong> Si lanzas <code>sudo fdisk -l</code> a secas, te saldrá una lista larguísima de todas las particiones, sectores de inicio, fin, etc. Al filtrar con <code>grep</code>, le decimos: «Solo enséñame las líneas que resuman la información de los discos físicos».</li>



<li><strong>Ventaja:</strong> Te da el tamaño exacto en bytes (útil para clonar discos) y te confirma si el disco tiene un esquema de particiones válido (GPT o DOS).</li>
</ul>



<pre class="wp-block-code"><code>vigilante@raspberrypi:~ $ <strong>sudo fdisk -l | grep -i disk</strong>
Disk /dev/ram0: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/ram1: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/ram2: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/ram3: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/ram4: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/ram5: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/ram6: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/ram7: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/ram8: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/ram9: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/ram10: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/ram11: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/ram12: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/ram13: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/ram14: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/ram15: 4 MiB, 4194304 bytes, 8192 sectors
Disk /dev/loop0: 2 GiB, 2147483648 bytes, 4194304 sectors
<mark style="background-color:#fcb900" class="has-inline-color">Disk /dev/sda: 223,57 GiB, 240057409536 bytes, 468862128 sectors
Disk model:  SA400S37240G   
Disklabel type: dos
Disk identifier: 0xc7a2c28e</mark>
Disk /dev/zram0: 2 GiB, 2147483648 bytes, 524288 sectors
</code></pre>



<p>Esto confirma que /dev/sda es mi SSD (no la SD de boot ni zram).</p>



<h3 class="wp-block-heading">6. Test de velocidad de escritura. (Test de Estrés)</h3>



<p><code>hdparm</code> mide lectura, pero los SSD fallan al <strong>escribir</strong>. Crea un archivo de prueba de 1GB para ver si la velocidad se mantiene estable:</p>



<pre class="wp-block-code"><code>dd if=/dev/zero of=./testfile bs=1G count=1 oflag=dsync</code></pre>



<ul class="wp-block-list">
<li><strong>Resultado OK:</strong> Velocidad constante (ej. 200-350 MB/s para SATA).</li>



<li><strong>Resultado sospechoso:</strong> Si empieza rápido y cae de golpe a <strong>15-20 MB/s</strong>, las celdas están muy castigadas.</li>
</ul>



<p>Para mi caso:</p>



<pre class="wp-block-code"><code>vigilante@raspberrypi:~ $ <strong>dd if=/dev/zero of=./testfile bs=1G count=1 oflag=dsync</strong>
1+0 records in
1+0 records out
1073741824 bytes (1,1 GB, 1,0 GiB) copied, 4,03518 s, 266 MB/s</code></pre>



<p>Resultado es <strong>excelente! </strong>, esos <strong>266 MB/s</strong> de escritura real (y con el flag <code>dsync</code>, que fuerza a que el dato se escriba físicamente antes de terminar) confirman que tu SSD y tu adaptador USB están trabajando a un nivel de rendimiento altísimo para una Raspberry Pi.</p>



<p>Para un SSD SATA conectado por USB en una Raspberry Pi, es prácticamente el límite de lo que el hardware puede dar. Tienes un conjunto de disco y controladora muy sólido.</p>



<h3 class="wp-block-heading">7. Test de velocidad de lectura real (sin caché)</h3>



<p>Mi resultado:</p>



<pre class="wp-block-code"><code>   vigilante@raspberrypi:~ $ <strong>sudo hdparm -t /dev/sda</strong>

/dev/sda:
 Timing buffered disk reads: 1026 MB in  3.02 seconds = 339.63 MB/sec</code></pre>



<p>¡Brutal! para un SSD SATA en USB 3.0 en Pi 5. El Kingston A400 nativo hace ~500 MB/s, pero con overhead USB + enclosure, 340 MB/s es top. Si sale &lt;100 MB/s → problema (cable, chipset, alimentación, o sin UASP).</p>



<h3 class="wp-block-heading">8. ¿Soporta TRIM?</h3>



<p>Si compras un pack de SSD + Carcasa USB, necesitas saber si el conjunto permite el comando <strong>TRIM</strong>. <br>Sin TRIM, la Raspberry Pi no podrá decirle al SSD qué bloques están libres, y con el tiempo el disco se volverá lento como una tortuga.</p>



<p>Compruébalo así:</p>



<pre class="wp-block-code"><code>vigilante@raspberrypi:~ $ <strong>lsblk --discard</strong>
NAME   DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
loop0         0        4K       4G         0
sda           0        0B       0B         0
├─sda1        0        0B       0B         0
└─sda2        0        0B       0B         0
zram0         0       16K       2T         0
</code></pre>



<p>Fíjate en las columnas <code>DISC-ALN</code> y <code>DISC-MAX</code>. <strong>Si aparecen ceros</strong>, el adaptador USB no es compatible con TRIM o el SSD es muy antiguo. En una Pi, esto es clave para que el sistema no se degrade.</p>



<h3 class="wp-block-heading">9. Muestra TODA la info SMART.</h3>



<p>A veces compras un disco en Aliexpress o en tiendas de segunda mano, te venden un «Samsung 870» metido en una carcasa genérica, pero dentro hay un disco chino de marca blanca.</p>



<p>Existe un comando con dos variantes que nos dará una rápida o extensa información del disco</p>



<p><code>sudo smartctl -i -d sat /dev/sda</code> (Información de identidad)</p>



<p>La <code>-i</code> viene de <strong>Info</strong>.</p>



<ul class="wp-block-list">
<li><strong>Qué hace:</strong> Solo te dice <strong>qué es</strong> el disco.</li>



<li><strong>Qué verás:</strong> Marca, modelo, número de serie, versión del firmware y si el SMART está activado o no.</li>



<li><strong>Cuándo usarlo:</strong> Cuando solo quieres confirmar que el disco que te han vendido es el modelo real y no un «cambiazo» (lo que hablábamos de Wallapop).</li>
</ul>



<p><code>sudo smartctl -a -d sat /dev/sda</code> (Análisis total)</p>



<p>La <code>-a</code> viene de <strong>All</strong> (Todo).</p>



<ul class="wp-block-list">
<li><strong>Qué hace:</strong> Muestra <strong>todo</strong> lo que el disco sabe de sí mismo. Incluye la información de la <code>-i</code>, pero añade lo más importante:
<ul class="wp-block-list">
<li><strong>Atributos SMART:</strong> Los contadores de vida, horas de encendido, errores de lectura y los famosos sectores reasignados (ID 05/196).</li>



<li><strong>Resumen de Salud:</strong> El veredicto «PASSED» o «FAILED».</li>



<li><strong>Estadísticas de temperatura:</strong> Mínimas y máximas históricas.</li>
</ul>
</li>



<li><strong>Cuándo usarlo:</strong> Siempre que quieras diagnosticar o saber si el disco está sano.</li>
</ul>



<p>Este comando nos dará un rápido resumen de la identidad real del disco:</p>



<pre class="wp-block-code"><code>vigilante@raspberrypi:~ $ <strong>sudo smartctl -i -d sat /dev/sda</strong>
smartctl 7.4 2023-08-01 r5530 &#91;aarch64-linux-6.12.62+rpt-rpi-2712] (local build)
Copyright (C) 2002-23, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family:     Phison Driven SSDs
Device Model:     <mark style="background-color:#7bdcb5" class="has-inline-color">KINGSTON SA400S37240G</mark>
Serial Number:    60026B7785211E3B
LU WWN Device Id: 5 0026b7 785211e3b
Firmware Version: SBFKB1H5
User Capacity:    240.057.409.536 bytes &#91;240 GB]
Sector Size:      512 bytes logical/physical
Rotation Rate:    Solid State Device
TRIM Command:     Available
Device is:        In smartctl database 7.3/5528
ATA Version is:   ACS-3 T13/2161-D revision 4
SATA Version is:  SATA 3.2, 6.0 Gb/s (current: 6.0 Gb/s)
Local Time is:    Fri Mar 13 18:05:54 2026 CET
SMART support is: Available - device has SMART capability.
SMART support is: Enabled
</code></pre>



<p>Mira donde pone <strong>Device Model</strong>. Si el vendedor dice que es un Kingston y el comando dice «Netac» o «KingSpec», te están intentando engañar.</p>



<p>Si vas a quedar con alguien de Wallapop, llévate tu Raspberry Pi, un PowerBank y estos comandos anotados. En 5 minutos sabrás si el SSD es una ganga o una estafa.</p>



<p>Veamos la información completa del disco (salud interna):</p>



<pre class="wp-block-code"><code>vigilante@raspberrypi:~ $ <strong>sudo smartctl -a -d sat /dev/sda</strong>
smartctl 7.4 2023-08-01 r5530 &#91;aarch64-linux-6.12.62+rpt-rpi-2712] (local build)
Copyright (C) 2002-23, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family:     Phison Driven SSDs
Device Model:     KINGSTON SA400S37240G
Serial Number:    60026B7785211E3B
LU WWN Device Id: 5 0026b7 785211e3b
Firmware Version: SBFKB1H5
User Capacity:    240.057.409.536 bytes &#91;240 GB]
Sector Size:      512 bytes logical/physical
Rotation Rate:    Solid State Device
TRIM Command:     Available
Device is:        In smartctl database 7.3/5528
ATA Version is:   ACS-3 T13/2161-D revision 4
SATA Version is:  SATA 3.2, 6.0 Gb/s (current: 6.0 Gb/s)
Local Time is:    Mon Mar  9 19:15:15 2026 CET
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: <mark style="background-color:#7bdcb5" class="has-inline-color">PASSED</mark>

General SMART Values:
Offline data collection status:  (0x00)	Offline data collection activity
					was never started.
					Auto Offline Data Collection: Disabled.
Self-test execution status:      (   0)	The previous self-test routine completed
					without error or no self-test has ever 
					been run.
Total time to complete Offline 
data collection: 		(65535) seconds.
Offline data collection
capabilities: 			 (0x11) SMART execute Offline immediate.
					No Auto Offline data collection support.
					Suspend Offline collection upon new
					command.
					No Offline surface scan supported.
					Self-test supported.
					No Conveyance Self-test supported.
					No Selective Self-test supported.
SMART capabilities:            (0x0003)	Saves SMART data before entering
					power-saving mode.
					Supports SMART auto save timer.
Error logging capability:        (0x01)	Error logging supported.
					General Purpose Logging supported.
Short self-test routine 
recommended polling time: 	 (   1) minutes.
Extended self-test routine
recommended polling time: 	 (   2) minutes.

SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x0032   100   100   000    Old_age   Always       -       0
  9 Power_On_Hours          0x0032   100   100   000    Old_age   Always       -       <mark style="background-color:#7bdcb5" class="has-inline-color">9090</mark>
 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       154
148 Unknown_Attribute       0x0000   100   100   000    Old_age   Offline      -       0
149 Unknown_Attribute       0x0000   100   100   000    Old_age   Offline      -       0
167 Write_Protect_Mode      0x0000   100   100   000    Old_age   Offline      -       0
168 SATA_Phy_Error_Count    0x0012   100   100   000    Old_age   Always       -       0
169 Bad_Block_Rate          0x0000   100   100   000    Old_age   Offline      -       17
170 Bad_Blk_Ct_Lat/Erl      0x0000   100   100   010    Old_age   Offline      -       0/12
172 Erase_Fail_Count        0x0032   100   100   000    Old_age   Always       -       0
173 MaxAvgErase_Ct          0x0000   100   100   000    Old_age   Offline      -       67 (Average 51)
181 Program_Fail_Count      0x0032   100   100   000    Old_age   Always       -       0
182 Erase_Fail_Count        0x0000   100   100   000    Old_age   Offline      -       0
187 Reported_Uncorrect      0x0032   100   100   000    Old_age   Always       -       0
192 Unsafe_Shutdown_Count   0x0012   100   100   000    Old_age   Always       -       <mark style="background-color:#7bdcb5" class="has-inline-color">149</mark>
194 Temperature_Celsius     0x0022   024   048   000    Old_age   Always       -       <mark style="background-color:#7bdcb5" class="has-inline-color">24</mark> (Min/Max 17/48)
196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       <mark style="background-color:#7bdcb5" class="has-inline-color">0</mark>
199 SATA_CRC_Error_Count    0x0032   100   100   000    Old_age   Always       -       0
218 CRC_Error_Count         0x0032   100   100   000    Old_age   Always       -       0
231 SSD_Life_Left           0x0000   094   094   000    Old_age   Offline      -       <mark style="background-color:#7bdcb5" class="has-inline-color">94</mark>
233 Flash_Writes_GiB        0x0032   100   100   000    Old_age   Always       -       7476
241 Lifetime_Writes_GiB     0x0032   100   100   000    Old_age   Always       -       <mark style="background-color:#7bdcb5" class="has-inline-color">4094</mark>
242 Lifetime_Reads_GiB      0x0032   100   100   000    Old_age   Always       -       11006
244 Average_Erase_Count     0x0000   100   100   000    Old_age   Offline      -       51
245 Max_Erase_Count         0x0000   100   100   000    Old_age   Offline      -       67
246 Total_Erase_Count       0x0000   100   100   000    Old_age   Offline      -       392144

SMART Error Log Version: 1
No Errors Logged

SMART Self-test log structure revision number 1
No self-tests have been logged.  &#91;To run self-tests, use: smartctl -t]

Selective Self-tests/Logging not supported

The above only provides legacy SMART information - try 'smartctl -x' for more

</code></pre>



<p>Lo más interesante de mi disco</p>



<ul class="wp-block-list">
<li><strong>Overall-health self-assessment test result: PASSED</strong> → Perfecto.</li>



<li>9 &#8211; <strong>Power_On_Hours: 9090</strong> (~1 año encendido).</li>



<li>192 &#8211; <strong>Unsafe_Shutdown_Count: 149</strong> → Apagados bruscos (lo solucioné con el SAI + NUT del post anterior).</li>



<li>196 &#8211; <strong>Reallocated_Event_Count: 0</strong> → Ningún sector malo reasignado.</li>



<li>231 &#8211; <strong>SSD_Life_Left: 94%</strong> → Aún le queda 94% de vida (TBW ~80 TB, yo ~4 TB escritos).</li>



<li>194 &#8211; <strong>Temperature_Celsius: 24 (Max 48)</strong> → Fresco.</li>



<li>169 &#8211; <strong>Bad_Block_Rate : 17</strong> → indica el porcentaje de bloques que salieron defectuosos de fábrica o se han marcado como malos.</li>



<li>241 &#8211; <strong>Lifetime_Writes_GiB: 4094</strong> (~4.1 TB escritos). El bridge USB (StarTech) pasa SMART completo → gran ventaja vs enclosures baratos que lo truncan.</li>
</ul>



<h3 class="wp-block-heading">¿Qué aprendí y recomendaciones?</h3>



<ul class="wp-block-list">
<li>Mi combo <strong>Kingston A400 240GB + enclosure StarTech (ASMedia UAS)</strong> es ganador: rápido, estable, SMART full y salud excelente.</li>



<li>Si usas SSD USB en Pi → <strong>prioriza chipsets ASMedia</strong> (ASM1153/1053), evita Realtek baratos si puedes.</li>



<li>Alimentación: Usa powered hub o fuente externa para HDD/SSD grandes.</li>



<li>Monitorea periódicamente: Pon un cron mensual con <code>smartctl -a</code> y alerta por Telegram si vida &lt;80% o temp &gt;55°C.</li>



<li>Beneficio final: Boot Pi en 10-15s vs 30-60s en microSD, apps más fluidas, menos corrupción, y sabes exactamente cómo está tu hardware.</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> El aviso de «Sectores Reasignados»<br>Dependiendo de la marca de tu SSD, este valor puede llamarse de varias formas. Es el contador de sectores que han muerto y que el disco ha tenido que sustituir por otros de «reserva»:<br><strong>En la mayoría (Samsung, Crucial, etc):</strong> Busca el <strong>ID 05</strong> (<em>Reallocated Sector Count</em>).<br><strong>En discos como el mío (Kingston/Phison):</strong> Busca el <strong>ID 196</strong> (<em>Reallocated Event Count</em>).<br><strong>Lo importante:</strong> En la columna <code>RAW_VALUE</code>, el número debe ser <strong>0</strong>. Si ves un 10, un 50 o un 100, ese disco está empezando a morir físicamente. ¡No lo compres!</li>



<li>El <strong>ID 169 (Bad_Block_Rate)</strong>. Este es otro chivato muy bueno, Mi valor es <code>17</code>. En muchos SSD de gama media/baja, esto indica el porcentaje de bloques que salieron defectuosos de fábrica o se han marcado como malos. Mientras el <strong>ID 196</strong> esté en <strong>0</strong>, el disco ha gestionado bien esos fallos, pero si ese número sube de repente, mala señal.</li>
</ul>



<p>Si estás montando un NAS, media center o server casero con Raspberry Pi, <strong>haz estos tests YA</strong>. Te ahorras disgustos y descubres si tu setup vuela o cojea.</p>



<p>¿Has probado boot desde SSD USB? ¿Qué velocidades te salen? ¡Cuéntame en comentarios! <br><br>Próximo post: script para alertas automáticas de SMART por Telegram.</p>



<p>¡Un saludo, linuxetes! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxete.duckdns.org/como-diagnosticar-y-optimizar-un-ssd-usb-en-raspberry-pi/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Cómo apagar de forma coordinada tus equipos en red.</title>
		<link>https://linuxete.duckdns.org/como-apagar-de-forma-coordinada-tus-equipos-en-red/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=como-apagar-de-forma-coordinada-tus-equipos-en-red</link>
					<comments>https://linuxete.duckdns.org/como-apagar-de-forma-coordinada-tus-equipos-en-red/#respond</comments>
		
		<dc:creator><![CDATA[raspberry]]></dc:creator>
		<pubDate>Mon, 09 Mar 2026 22:06:36 +0000</pubDate>
				<category><![CDATA[Sistema]]></category>
		<category><![CDATA[Bash Scripting]]></category>
		<category><![CDATA[Monitorización SAI]]></category>
		<category><![CDATA[NUT (Network UPS Tools)]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Salicru]]></category>
		<category><![CDATA[Telegram Bot]]></category>
		<guid isPermaLink="false">https://linuxete.duckdns.org/?p=3986</guid>

					<description><![CDATA[En el artículo anterior, Cómo monitorizar un SAI Salicru con Raspberry Pi Zero. logramos que nuestra Raspberry Pi Zero se comunicara con nuestro SAI Salicru y nos avisara por Telegram de cualquier incidencia eléctrica. Pero, ¿qué pasa con el resto de equipos de la casa? Si tienes un PC potente para gaming, un servidor con [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>En el artículo anterior, <a href="https://linuxete.duckdns.org/como-monitorizar-un-sai-salicru-con-raspberry-pi-zero/">Cómo monitorizar un SAI Salicru con Raspberry Pi Zero.</a> logramos que nuestra <strong>Raspberry Pi Zero</strong> se comunicara con nuestro SAI Salicru y nos avisara por Telegram de cualquier incidencia eléctrica. Pero, ¿qué pasa con el resto de equipos de la casa? Si tienes un PC potente para gaming, un servidor con un i7 o incluso otra Raspberry Pi 5 realizando tareas críticas, dejarlos a su suerte durante un apagón no es una opción.</p>



<p>La verdadera magia de <strong>NUT (Network UPS Tools)</strong> reside en su arquitectura Maestro-Esclavo. En esta guía, vamos a configurar nuestra infraestructura para que la Raspberry Pi Zero actúe como el «cerebro» central (Master). Ella será la encargada de monitorizar el USB del SAI y, en caso de batería baja, enviará una orden de apagado por red a todos los demás equipos (Slaves) de tu hogar.</p>



<p>Al finalizar esta configuración, habrás creado una <strong>red de seguridad inteligente</strong> donde:</p>



<ul class="wp-block-list">
<li><strong>La comunicación es total</strong>: Tus PCs con Windows y Linux «escucharán» a la pequeña Pi Zero.</li>



<li><strong>El apagado es elegante</strong>: Cada equipo cerrará sus procesos y protegerá sus discos antes de que el SAI corte la energía.</li>



<li><strong>Tú mantienes el control</strong>: Seguirás recibiendo los reportes detallados en Telegram mientras tus equipos se ponen a salvo automáticamente.</li>
</ul>



<p>Prepárate para convertir tu modesta Raspberry Pi Zero en el guardián de toda la electrónica de tu despacho. ¡Vamos a ello!</p>



<h2 class="wp-block-heading">1. Configuración en la Raspberry Pi Zero (El Maestro)</h2>



<p>Para expandir tu red de protección y que tu <strong>Raspberry Pi 5</strong> y tus otros PCs (i7, i5) se apaguen de forma coordinada, vamos a configurar una arquitectura <strong>Maestro-Esclavo</strong> (o Primario-Secundario).</p>



<p>Tu <strong>Pi Zero</strong> seguirá siendo el «Cerebro» (Master) porque tiene el cable USB, y los demás serán «Clientes» (Slaves) que escuchan por red.</p>



<p>Primero debemos autorizar a la Pi Zero a hablar con el resto de la casa.</p>



<h3 class="wp-block-heading">A. Abrir la escucha de red</h3>



<p>Edita el archivo de configuración del servidor:</p>



<pre class="wp-block-code"><code><code>sudo nano /etc/nut/upsd.conf</code></code></pre>



<p>Sustituye tus líneas <code>LISTEN</code> por esta (es la más compatible):</p>



<pre class="wp-block-code"><code>LISTEN 0.0.0.0 3493</code></pre>



<p><em>Esto permite que la Pi Zero responda tanto a su propio script de Telegram como a los PCs externos.</em></p>



<h3 class="wp-block-heading">B. Crear el usuario para los esclavos</h3>



<p>Edita el archivo de usuarios:</p>



<pre class="wp-block-code"><code><code>sudo nano /etc/nut/upsd.users</code></code></pre>



<p>Añade este perfil al final (usa una contraseña distinta a la de admin):</p>



<pre class="wp-block-code"><code>&#91;remotemon]
    password = <mark style="background-color:#fcb900" class="has-inline-color">clave_red_segura</mark>
    upsmon slave
</code></pre>



<p>Reinicia los servicios para aplicar los cambios:</p>



<pre class="wp-block-code"><code><code>sudo systemctl restart nut-server nut-monitor</code></code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2. Configuración en la Raspberry Pi 5 y PCs con Linux (Esclavos)</h2>



<p>En cada equipo Linux que quieras proteger (Pi 5, i7 con Ubuntu/Debian, etc.), sigue estos pasos:</p>



<h3 class="wp-block-heading">A. Instalación mínima</h3>



<p>Solo necesitas el cliente, no el servidor completo:</p>



<pre class="wp-block-code"><code>sudo apt update &amp;&amp; sudo apt install nut-client -y</code></pre>



<h3 class="wp-block-heading">B. Configurar el modo red</h3>



<p>Edita el archivo de modo:</p>



<pre class="wp-block-code"><code><code>sudo nano /etc/nut/nut.conf</code></code></pre>



<p>Cambia la línea a:</p>



<pre class="wp-block-code"><code>MODE=netclient</code></pre>



<h3 class="wp-block-heading">C. Vincularse al Maestro</h3>



<p>Edita el monitor:</p>



<pre class="wp-block-code"><code><code>sudo nano /etc/nut/upsmon.conf</code></code></pre>



<p>Añade esta línea al final (sustituye <code>192.168.1.14</code> por la IP real de tu <strong>Pi Zero</strong>):</p>



<pre class="wp-block-code"><code>MONITOR salicru@192.168.1.14 1 remotemon <mark style="background-color:#7bdcb5" class="has-inline-color">clave_red_segura</mark> slave</code></pre>



<p>Reinicia el monitor en el esclavo:</p>



<pre class="wp-block-code"><code><code>sudo systemctl restart nut-monitor</code></code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">3. Configuración en PCs con Windows (i7 / i5)</h2>



<p>Si alguno de tus PCs usa Windows, no necesitas scripts complejos:</p>



<ol start="1" class="wp-block-list">
<li><strong>Descarga e instala</strong> <a href="https://www.google.com/search?q=https://github.com/gavandre/WinNUT-Client/releases" target="_blank" rel="noreferrer noopener">WinNUT-Client</a>.</li>



<li><strong>Configura la conexión:</strong>
<ul class="wp-block-list">
<li><strong>UPS Name:</strong> <code>salicru</code></li>



<li><strong>UPS Host:</strong> <code>192.168.1.14</code> (IP de la Pi Zero)</li>



<li><strong>Port:</strong> <code>3493</code></li>



<li><strong>Username:</strong> <code>esclavo</code></li>



<li><strong>Password:</strong> <code><mark style="background-color:#7bdcb5" class="has-inline-color">clave_red_segura</mark></code></li>
</ul>
</li>



<li><strong>Calibración:</strong> En la pestaña «Shutdown», elige cuánto tiempo quieres que pase desde que se corta la luz hasta que el PC se apague.</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">¿Cómo funcionará el apagado en cadena?</h2>



<p>Es importante entender la jerarquía para que nadie pierda datos:</p>



<ol start="1" class="wp-block-list">
<li><strong>Corte de luz:</strong> La Pi Zero avisa por <strong>Telegram</strong> al instante.</li>



<li><strong>Batería Baja:</strong> Cuando la Pi Zero detecta que queda poca energía, envía la señal de «Pánico» por red a los demás equipos</li>



<li><strong>Apagado de Esclavos:</strong> El resto de equipos reciben la orden y se apagan de inmediato para proteger sus discos.</li>



<li><strong>Apagado del Maestro:</strong> La Pi Zero espera a que los esclavos se desconecten. Una vez sola, inicia su propio apagado.</li>



<li><strong>Corte Total:</strong> En el último segundo, la Pi Zero le dice al Salicru: <em>«Apágate en 30 segundos»</em>.</li>
</ol>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Recuerda poner una IP fija a tu Raspberry pi zero</strong></p>
</blockquote>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxete.duckdns.org/como-apagar-de-forma-coordinada-tus-equipos-en-red/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Cómo monitorizar un SAI Salicru con Raspberry Pi Zero.</title>
		<link>https://linuxete.duckdns.org/como-monitorizar-un-sai-salicru-con-raspberry-pi-zero/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=como-monitorizar-un-sai-salicru-con-raspberry-pi-zero</link>
					<comments>https://linuxete.duckdns.org/como-monitorizar-un-sai-salicru-con-raspberry-pi-zero/#respond</comments>
		
		<dc:creator><![CDATA[raspberry]]></dc:creator>
		<pubDate>Sat, 07 Mar 2026 21:25:49 +0000</pubDate>
				<category><![CDATA[Sistema]]></category>
		<category><![CDATA[Bash Scripting]]></category>
		<category><![CDATA[Monitorización SAI]]></category>
		<category><![CDATA[NUT (Network UPS Tools)]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Salicru]]></category>
		<category><![CDATA[Telegram Bot]]></category>
		<guid isPermaLink="false">https://linuxete.duckdns.org/?p=3902</guid>

					<description><![CDATA[En cualquier infraestructura doméstica o profesional, el SAI (Sistema de Alimentación Ininterrumpida) es el guardián silencioso que protege nuestros equipos. Sin embargo, un SAI solo es realmente útil si sabemos exactamente qué está pasando con él en tiempo real. En este artículo, vamos a configurar un sistema de alertas avanzado utilizando una Raspberry Pi y [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>En cualquier infraestructura doméstica o profesional, el <strong>SAI (Sistema de Alimentación Ininterrumpida)</strong> es el guardián silencioso que protege nuestros equipos. Sin embargo, un SAI solo es realmente útil si sabemos exactamente qué está pasando con él en tiempo real.</p>



<p>En este artículo, vamos a configurar un sistema de alertas avanzado utilizando una <strong>Raspberry Pi</strong> y el software <strong>NUT (Network UPS Tools)</strong> para convertir un SAI Salicru convencional en un dispositivo inteligente y conectado.</p>



<p>El objetivo es automatizar el control total de nuestra energía mediante un <strong>Bot de Telegram</strong> que nos mantendrá informados con mensajes detallados y visuales. Al finalizar este tutorial, tu sistema será capaz de:</p>



<ul class="wp-block-list">
<li><strong>Notificar cortes y restablecimientos</strong> de corriente de forma instantánea.</li>



<li><strong>Enviar reportes detallados</strong> con voltajes de entrada, salida y estado de la batería.</li>



<li><strong>Gestionar estados críticos</strong> como el nivel de batería bajo o la necesidad de sustitución de celdas (<code>REPLBATT</code>).</li>



<li><strong>Proteger tu hardware</strong>, avisándote justo antes de que la Raspberry Pi realice un apagado controlado para evitar daños en la tarjeta SD.</li>
</ul>



<p>Todo esto mediante un script optimizado que garantiza que la información que recibes en tu móvil es <strong>veraz y estable</strong>, permitiéndote tomar decisiones informadas estés donde estés.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Sistema</h2>



<p>Como sistema operativo voy utilizar Rasbperry Pi OS lite 64bits, basado en Debian 13. El usuario del sistema será <code><strong>nut</strong></code> y el host será <code><strong>zero</strong></code>.</p>



<h2 class="wp-block-heading">Materiales necesarios</h2>



<ul class="wp-block-list">
<li><a href="https://www.tiendatec.es/raspberry-pi/gama-raspberry-pi/1735-raspberry-pi-zero-2-w.html">RASPBERRY PI ZERO 2W &#8211; 2WH (Versión: W (WiFi))</a></li>



<li><a href="https://www.amazon.es/Salicru-SPS-1200-Soho-Sistema-alimentaci%C3%B3n-ininterrumpida/dp/B079FX7WR7?th=1">Un SAI Salicru con puerto USB (Serie SOHO+ o similar).</a></li>



<li><a href="https://www.tiendatec.es/raspberry-pi/accesorios/1298-cable-otg-micro-usb-m-usb-a-h-negro-8472496017336.html">CABLE OTG MICROUSB/M USB-A/H NEGRO</a></li>



<li><a href="https://www.tiendatec.es/raspberry-pi/raspberry-pi-alimentacion/1734-alimentador-oficial-raspberry-pi-micro-usb-5-1v-2-5a-12-75w-5056561801315.html">ALIMENTADOR OFICIAL RASPBERRY PI MICRO-USB 5,1V 2,5A 12,75W</a></li>



<li><a href="https://www.tiendatec.es/raspberry-pi/cajas/678-caja-oficial-raspberry-pi-zero-8406780080003.html">CAJA OFICIAL RASPBERRY PI ZERO</a></li>



<li><a href="https://www.tiendatec.es/maker-zone/cables/1998-cable-usb-a-a-usb-b-m-m-azul-30cm-8472496023658.html">CABLE USB-A A USB-B M/M AZUL 30CM</a></li>
</ul>



<h2 class="wp-block-heading">Instalación de NUT</h2>



<p>Actualizamos la lista de repositorios e instalamos los paquetes oportunos.</p>



<pre class="wp-block-code"><code>sudo apt update &amp;&amp; sudo apt install nut nut-client nut-server curl bc -y</code></pre>



<h2 class="wp-block-heading">Configuración del hardware.</h2>



<p>Según el modelo de SAI, <code>nut</code> puede manejar distintos tipos de driver. Antes de configurar el archivo <code>ups.conf</code> conecta el cable USB de la PI al  SAI y ejecuta este comando:</p>



<pre class="wp-block-code"><code>sudo nut-scanner -U</code></pre>



<p>Este comando escaneará los buses USB y te dirá exactamente qué driver recomienda NUT para tu dispositivo específico.</p>



<pre class="wp-block-code"><code>nut@zero:~ $ <strong>sudo nut-scanner -U</strong>
Cannot load SNMP library (libnetsnmp.so.40) : file not found. SNMP search disabled.
Cannot load XML library (libneon.so.27) : file not found. XML search disabled.
Cannot load AVAHI library (libavahi-client.so.3) : file not found. AVAHI search disabled.
Cannot load IPMI library (libfreeipmi.so.17) : file not found. IPMI search disabled.
Scanning USB bus.
&#91;nutdev1]
	driver = "<mark style="background-color:#fcb900" class="has-inline-color">nutdrv_qx</mark>"
	port = "auto"
	vendorid = "0665"
	productid = "5161"
	product = "USB to Serial"
	vendor = "Cypress Semiconductor"
	bus = "001"
	device = "002"
	busport = "001"
	###NOTMATCHED-YET###bcdDevice = "0002"</code></pre>



<p>Observa que el driver recomendado es «<code>nutdrv_qx</code>«.</p>



<h3 class="wp-block-heading">Archivos de configuración de NUT</h3>



<p>Define el driver, editando el siguiente archivo.<code> </code></p>



<pre class="wp-block-code"><code>sudo nano /etc/nut/ups.conf</code></pre>



<p>Al comienzo del archivo, pega lo siguiente.</p>



<pre class="wp-block-code"><code>&#91;salicru]
    driver = nutdrv_qx
    port = auto
    vendorid = 0665
    productid = 5161
    vendor = "Cypress Semiconductor"
    product = "USB to Serial"
    desc = "Salicru SOHO 2000"</code></pre>



<p>En ese mismo archivo busca la línea <code>maxretry = 3</code> comentala y déjala así.</p>



<pre class="wp-block-code"><code>#maxretry = 3</code></pre>



<p>Guarda con <code>Crtl + o</code> y cierra con <code>Crtl + x</code></p>



<p>Configura el modo editando el siguiente archivo.</p>



<pre class="wp-block-code"><code>sudo nano /etc/nut/nut.conf </code></pre>



<p>Busca la línea MODE, cambia la línea a standalone.</p>



<pre class="wp-block-code"><code><code>MODE=standalone</code></code></pre>



<h3 class="wp-block-heading">Configurar el acceso (upsd.conf)</h3>



<p>Una vez que el driver está leyendo los datos del USB, necesitamos que el «servidor de NUT» (<code>upsd</code>) recoja esa información y la deje disponible para resto de equipos y otros programas (como nuestro script de Telegram o el comando <code>upsc</code>) puedan consultarla.</p>



<p>Para ello, editamos el archivo de configuración del demonio:</p>



<pre class="wp-block-code"><code>sudo nano /etc/nut/upsd.conf</code></pre>



<p>Este archivo suele tener lineas que apuntan al localhost como las que vemos a continuación.</p>



<pre class="wp-block-code"><code>LISTEN 127.0.0.1 3493
LISTEN ::1 3493</code></pre>



<p>Si las tienes, borralas y deja solo una línea <code>LISTEN</code> tal y como queda en la siguiente instrucción.</p>



<pre class="wp-block-code"><code>LISTEN 0.0.0.0 3493</code></pre>



<p>El <code>0.0.0.0</code> sirve para que los demás equipos vean a la Pi Zero.</p>



<p>«Por seguridad, NUT viene configurado para ser &#8216;tímido&#8217; (127.0.0.1) y solo hablar consigo mismo. Al cambiarlo a <code>0.0.0.0</code>, convertimos a nuestra Raspberry Pi Zero en un <strong>Faro de Energía</strong>: ahora cualquier equipo de nuestra red local puede ver el estado del SAI y saber cuándo debe ponerse a salvo.»</p>



<h4 class="wp-block-heading">¿Qué hace exactamente <code>LISTEN 0.0.0.0</code>?</h4>



<p>Cuando configuras <code>LISTEN 0.0.0.0</code> en el archivo <code>upsd.conf</code> de la <strong>Pi Zero</strong>, le estás diciendo al servidor NUT: <em>«No te escondas; acepta preguntas de cualquier dirección IP que llegue a esta Raspberry»</em>.</p>



<ul class="wp-block-list">
<li><strong>Sin el 0.0.0.0 (solo con 127.0.0.1):</strong> La Pi Zero está «sorda» a lo que venga de fuera. Tus equipos intentarán llamarla por red, pero ella no responderá porque solo escucha sus propios pensamientos internos (localhost).</li>



<li><strong>Con el 0.0.0.0:</strong> La Pi Zero abre sus «oídos» a toda la red local. Ahora, cuando el i7 pregunte: <em>«¿Cómo va la batería?»</em>, la Pi Zero podrá escucharlo y responderle con los datos del Salicru.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h4 class="wp-block-heading">¿Cómo «ve» la Pi Zero a los demás?</h4>



<p>Curiosamente, la Pi Zero <strong>no necesita «ver» activamente</strong> a los demás equipos para protegerlos. Funciona al revés:</p>



<ol start="1" class="wp-block-list">
<li>La Pi Zero (Maestro) simplemente publica la información del SAI en la red.</li>



<li>Los demás equipos (Esclavos como la Pi 5 o el i7) se conectan a ella constantemente para «leer» esa información.</li>



<li>En el momento en que la Pi Zero detecta batería baja, cambia su estado a <code>FSD</code> (Forced Shutdown).</li>



<li>Los esclavos, que están vigilando ese estado cada pocos segundos, ven el cambio y deciden apagarse por su cuenta.</li>
</ol>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Configurar <code>0.0.0.0</code> es como abrir la ventanilla de información de la Pi Zero al resto de la casa. Permite que tus PCs potentes se conviertan en «clientes» que consultan el estado del SAI a través de la red WiFi o Ethernet.</p>
</blockquote>



<h4 class="wp-block-heading">¿<code>127.0.0.1</code> vs <code>0.0.0.0</code>? Entendiendo la «Escucha» de Red</h4>



<p>Para que tu estrategia de apagado coordinado funcione, es vital entender qué dirección IP debe usar el servidor NUT. Aquí tienes la comparativa de lo que sucede en tu Raspberry Pi Zero:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><td>Configuración (<code>LISTEN</code>)</td><td>Alcance</td><td>Seguridad</td><td>¿Cuándo usarla?</td></tr></thead><tbody><tr><td><strong><code>127.0.0.1</code></strong> (Localhost)</td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f512.png" alt="🔒" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Solo Interno</strong>. La Pi Zero solo se habla a sí misma.</td><td>Máxima. Nadie fuera de la Pi puede ver los datos.</td><td>Cuando solo quieres recibir avisos por Telegram desde esa Raspberry.</td></tr><tr><td><strong><code>0.0.0.0</code></strong> (Todas las IPs)</td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f30d.png" alt="🌍" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Toda la Red</strong>. La Pi Zero se vuelve visible para el i7, la Pi 5 y el resto de PCs.</td><td>Media. Requiere usar contraseñas en <code>upsd.users</code>.</td><td><strong>Obligatorio</strong> para apagar otros equipos de casa por red.</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">Crear la regla de permisos (udev)</h2>



<p>La regla de <strong>udev</strong> es la forma que tiene Linux (en este caso tu Raspberry Pi con Debian) de gestionar los dispositivos que conectas físicamente a los puertos.</p>



<p>Para crear la regla, abre el editor nano con el siguiente comando.</p>



<pre class="wp-block-code"><code>sudo nano /etc/udev/rules.d/99-nut-ups.rules</code></pre>



<p>Pega dentro esta línea exactamente:</p>



<pre class="wp-block-code"><code>SUBSYSTEM=="usb", ATTR{idVendor}=="0665", ATTR{idProduct}=="5161", MODE="0660", GROUP="nut"</code></pre>



<p><em>(Guarda con <code>Ctrl+O</code>, <code>Enter</code> y sal con <code>Ctrl+X</code>)</em>. </p>



<p>Los valores de la regla, los vimos cuando ejecutamos el comando <code>nut-scanner -U</code> de donde extraemos los valores  idVendor y idProduct.</p>



<p>Aplicamos la regla con:</p>



<pre class="wp-block-code"><code>sudo udevadm control --reload-rules &amp;&amp; sudo udevadm trigger</code></pre>



<p>Como Linux es un sistema multiusuario y seguro, por defecto no permite que cualquier programa (como el software de NUT) «hable» directamente con un hardware USB a menos que seas el administrador (<code>root</code>). La regla de udev que creamos sirve para decirle al sistema: <em>«Cuando veas este SAI de Salicru, dáselo al grupo &#8216;nut&#8217; para que pueda leer sus datos»</em>.</p>



<h3 class="wp-block-heading">Anatomía de la regla</h3>



<p>La línea que pusimos en <code>/etc/udev/rules.d/99-nut-ups.rules</code> se desglosa así:</p>



<p><code>SUBSYSTEM=="usb", ATTR{idVendor}=="0665", ATTR{idProduct}=="5161", MODE="0660", GROUP="nut"</code></p>



<ul class="wp-block-list">
<li><strong><code>SUBSYSTEM=="usb"</code></strong>: Le dice a Linux que solo mire en los puertos USB.</li>



<li><strong><code>ATTR{idVendor}=="0665"</code></strong>: «Busca al fabricante 0665».</li>



<li><strong><code>ATTR{idProduct}=="5161"</code></strong>: «Y que el producto sea el 5161».</li>



<li><strong><code>MODE="0660"</code></strong>: Esto define los permisos de archivos de Linux. <code>0660</code> significa que el dueño y el grupo pueden <strong>leer y escribir</strong>, pero el resto del mundo no puede hacer nada.</li>



<li><strong><code>GROUP="nut"</code></strong>: Aquí está la magia. Le asigna la propiedad del puerto al grupo <code>nut</code>. Como el software de monitorización corre bajo el usuario <code>nut</code>, ahora ya tiene «llave» para entrar al puerto USB.</li>
</ul>



<h3 class="wp-block-heading">¿Por qué es necesaria en la Raspberry Pi?</h3>



<p>Sin esta regla, cuando el driver <code>nutdrv_qx</code> intenta preguntar al SAI «¿cuánta batería te queda?», el sistema operativo le responde: <strong>«Acceso denegado»</strong>.</p>



<p>Si esta regla no está o está mal aplicada, te saldrá el error <code>insufficient permissions</code>. Al añadir la regla, el permiso se vuelve automático: cada vez que arranques la Raspberry o reconectes el USB, Linux aplicará estas instrucciones al instante.</p>



<h2 class="wp-block-heading">Sincronizar los servicios</h2>



<p>Ejecuta esto para limpiar y arrancar de forma oficial:</p>



<pre class="wp-block-code"><code>sudo systemctl stop nut-monitor nut-server
sudo rm -f /run/nut/*.pid
sudo systemctl start nut-server
sudo systemctl start nut-monitor</code></pre>



<h3 class="wp-block-heading">Comprobar la comunicación</h3>



<p>Ahora, espera unos 5 segundos y lanza:</p>



<pre class="wp-block-code"><code>upsc salicru@localhost</code></pre>



<p>El comando nos <strong>muestra en tiempo real la información detallada, el estado y las variables del Sistema de Alimentación Ininterrumpida (SAI/UPS)</strong>que está gestionado localmente mediante la herramienta NUT (Network UPS Tools)</p>



<pre class="wp-block-code"><code>nut@zero:~ $ <strong>upsc salicru@localhost</strong>
Init SSL without certificate database
battery.voltage: 27.4
device.type: ups
driver.debug: 0
driver.flag.allow_killpower: 0
driver.name: nutdrv_qx
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.product: USB to Serial
driver.parameter.productid: 5161
driver.parameter.synchronous: auto
driver.parameter.vendor: Cypress Semiconductor
driver.parameter.vendorid: 0665
driver.state: updateinfo
driver.version: 2.8.1
driver.version.data: Q1 0.08
driver.version.internal: 0.36
driver.version.usb: libusb-1.0.28 (API: 0x100010a)
input.frequency: 49.8
input.voltage: 235.2
input.voltage.fault: 235.2
output.voltage: 231.3
ups.beeper.status: enabled
ups.delay.shutdown: 30
ups.delay.start: 180
ups.load: 0
ups.productid: 5161
ups.status: OL
ups.temperature: 25.0
ups.type: offline / line interactive
ups.vendorid: 0665
nut@zero:~ $</code></pre>



<h3 class="wp-block-heading">Puerto de escucha</h3>



<p>Como dato interesante, comprueba si el puerto 3493 que configuramos anteriormente, está a la escucha</p>



<pre class="wp-block-code"><code>nut@zero:~ $ <strong>ss -ltn | grep 3493</strong>
LISTEN 0      16           0.0.0.0:3493      0.0.0.0:*  </code></pre>



<p>Las líneas <code>LISTEN</code>, indican que la Raspberry ya tiene la oreja puesta y está lista para informar sobre el estado del Salicru.</p>



<h3 class="wp-block-heading">Procesos</h3>



<p>Puedes escribir <code>upsutil salicru@localhost</code> o simplemente ver el estado del servicio:</p>



<p>Para verificar si el monitor (<code>upsmon</code>) está funcionando correctamente en tu Raspberry Pi, usa estos comandos:</p>



<pre class="wp-block-code"><code>nut@zero:~ $ <strong>ps aux | grep upsmon</strong>
root        6906  0.0  0.6   7304  2688 ?        Ss   10:05   0:00 /lib/nut/upsmon -F
nut         6907  0.0  1.2  10236  5120 ?        S    10:05   0:03 /lib/nut/upsmon -F
nut         9598  0.0  0.4   8804  2064 pts/0    S+   21:39   0:00 grep --color=auto upsmon
nut@zero:~ $ </code></pre>



<p>Deberías ver 3 procesos: uno que corre como <code>root</code> (el que tiene permiso para apagar la Pi) el otro como el usuario <code>nut</code> y el otro es simplemente el comando que acabamos de escribir.</p>



<h3 class="wp-block-heading">Comprobar el estado del servicio.</h3>



<p>Ejecuta el comando <strong>sudo systemctl status nut-monitor</strong></p>



<pre class="wp-block-code"><code>nut@zero:~ $ <strong>sudo systemctl status nut-monitor</strong>
● nut-monitor.service - Network UPS Tools - power device monitor and shutdown controller
     Loaded: loaded (/usr/lib/systemd/system/nut-monitor.service; enabled; preset: enabled)
     Active: <mark style="background-color:rgba(0, 0, 0, 0);color:#00d084" class="has-inline-color"><strong>active (running)</strong></mark> since Sat 2026-03-07 22:12:57 CET; 12h ago
 Invocation: 95d0260bee1c4eca9ad4a618365a8a2c
    Process: 1091 ExecStartPre=/usr/bin/systemd-tmpfiles --create /usr/lib/tmpfiles.d/nut-common-tmpfiles.conf (code=exited, status=0/SUCCESS)
   Main PID: 1093 (upsmon)
      Tasks: 2 (limit: 176)
        CPU: 3.333s
     CGroup: /system.slice/nut-monitor.service
             ├─1093 /lib/nut/upsmon -F
             └─1098 /lib/nut/upsmon -F

mar 07 22:12:57 zero systemd&#91;1]: Starting nut-monitor.service - Network UPS Tools - power device monitor and shutdown controller...
mar 07 22:12:57 zero systemd&#91;1]: Started nut-monitor.service - Network UPS Tools - power device monitor and shutdown controller.
mar 07 22:12:57 zero nut-monitor&#91;1093]: fopen /run/nut/upsmon.pid: No such file or directory
mar 07 22:12:57 zero nut-monitor&#91;1093]: Could not find PID file to see if previous upsmon instance is already running!
mar 07 22:12:57 zero nut-monitor&#91;1093]: UPS: salicru@localhost (primary) (power value 1)
mar 07 22:12:57 zero nut-monitor&#91;1093]: Using power down flag file /etc/killpower
mar 07 22:12:57 zero nut-monitor&#91;1098]: Init SSL without certificate database
mar 07 22:12:57 zero nut-monitor&#91;1098]: upsnotify: notify about state 2 with libsystemd: was requested, but not running as a service unit now, will not spam more about it
mar 07 22:12:57 zero nut-monitor&#91;1098]: upsnotify: failed to notify about state 2: no notification tech defined, will not spam more about it
mar 07 22:12:57 zero nut-monitor&#91;1098]: upsnotify: logged the systemd watchdog situation once, will not spam more about it
nut@zero:~ $ 
</code></pre>



<p>Si aparece en verde (<strong>active (running)</strong>), el vigilante está despierto.</p>



<h3 class="wp-block-heading">Configurando los avisos por terminal.</h3>



<pre class="wp-block-code"><code>sudo nano /etc/nut/upsmon.conf</code></pre>



<p>Pega el siguiente texto debajo </p>



<pre class="wp-block-code"><code># Banderas para ejecutar el comando (EXEC)
NOTIFYFLAG ONLINE   SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT   SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT  SYSLOG+WALL+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXEC
NOTIFYFLAG REPLBATT SYSLOG+WALL+EXEC</code></pre>



<p>Reinicia el servicio con:</p>



<pre class="wp-block-code"><code>sudo systemctl stop nut-monitor nut-server</code></pre>



<p>Esto dará avisos en la terminal de tu raspberry, pero no lo hará si estas accediendo por ssh.</p>



<h2 class="wp-block-heading">Cómo configurar el apagado automático (upsmon)</h2>



<p>Como nuestra <strong>Raspberry Pi Zero 2W</strong> está conectada al Salicru, vamos a configurar el sistema para que se apague de forma segura.</p>



<h3 class="wp-block-heading">Configurar el usuario</h3>



<p>Debemos de tener un par de  usuarios configurados para la gestión del SAI, que será el usurario administrador [monuser] y el usuario de los equipos remotos que será [remotemon]</p>



<p>Edita el archivo de usuarios de NUT:</p>



<pre class="wp-block-code"><code>sudo nano /etc/nut/upsd.users</code></pre>



<p>Añade esto al final:</p>



<pre class="wp-block-code"><code>&#91;monuser]
    password = <mark style="background-color:#7bdcb5" class="has-inline-color">mi_password_segura</mark>
    upsmon master</code></pre>



<p>Si quieres, puedes dar a [monuser] privilegios de administrador así:</p>



<pre class="wp-block-code"><code>&#91;monuser]
    password = <mark style="background-color:#7bdcb5" class="has-inline-color">mi_password_segura</mark>
    upsmon master
    actions = SET
    instcmds = ALL</code></pre>



<p>Para dar privilegios de administrador a un usuario, tan solo agrégale las directrices <code>actions</code> e <code>instcmds</code></p>



<p>Para el usuario remoto, añade este perfil al final (usa una contraseña distinta a la de admin):</p>



<pre class="wp-block-code"><code>&#91;remotemon]
    password = <mark style="background-color:#fcb900" class="has-inline-color">clave_red_segura</mark>
    upsmon slave</code></pre>



<h3 class="wp-block-heading">Configurar el monitor</h3>



<p>Edita el archivo del monitor:</p>



<pre class="wp-block-code"><code>sudo nano /etc/nut/upsmon.conf</code></pre>



<p>Busca la sección <code>MONITOR</code> y asegúrate de que quede así:</p>



<pre class="wp-block-code"><code>MONITOR salicru@localhost 1 monuser <mark style="background-color:#7bdcb5" class="has-inline-color">mi_password_segura</mark> master
SHUTDOWNCMD "/sbin/shutdown -h now"
POWERDOWNFLAG /etc/killpower
</code></pre>



<h3 class="wp-block-heading">Activar el servicio</h3>



<p>Reinicia todo para que los cambios tengan efecto:</p>



<pre class="wp-block-code"><code>sudo systemctl restart nut-monitor</code></pre>



<h3 class="wp-block-heading">¿Qué pasará ahora cuando se corte la luz?</h3>



<p>Si el SAI se apaga <em>antes</em> de que la Raspberry complete su apagado, podrías tener el mismo problema que con un corte normal de luz, archivos corruptos en la MicroSD. Este sistema está diseñado con una <strong>secuencia de retardo</strong> muy específica para evitar esto, El Retardo (Delay). Cuando la Raspberry envía la orden de «Kill Power», no le está diciendo al SAI <em>«Apágate ya»</em>, sino <em>«Apágate dentro de <strong>X</strong> segundos»</em>.</p>



<p>Si te fijas en los datos de tu <code>upsc salicru@localhost</code>, hay una línea clave:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong><code>ups.delay.shutdown: 30</code></strong></p>
</blockquote>



<p>Esto significa que cuando la Raspberry envía la orden final, el SAI Salicru inicia una cuenta atrás interna de <strong>30 segundos</strong>.</p>



<h3 class="wp-block-heading">La Secuencia Cronológica</h3>



<p>Para que veas que es seguro, este es el orden real de los eventos:</p>



<ol start="1" class="wp-block-list">
<li><strong>Raspberry detecta Batería Baja:</strong> Inicia su propio proceso de apagado (<code>SHUTDOWNCMD</code>).</li>



<li><strong>Cierre de Servicios:</strong> Debian detiene bases de datos, logs y procesos. La tarjeta SD deja de escribir datos.</li>



<li><strong>Script Final de NUT:</strong> Justo en el último segundo del apagado (cuando el sistema ya está en modo «solo lectura»), se ejecuta la orden de «Kill Power» hacia el SAI.</li>



<li><strong>SAI recibe la orden:</strong> El Salicru empieza su cuenta atrás de <strong>30 segundos</strong>.</li>



<li><strong>Raspberry muere:</strong> La Pi termina de apagarse por completo en 2 o 3 segundos más.</li>



<li><strong>El SAI se apaga:</strong> 27 segundos después de que la Pi ya esté totalmente «muerta», el SAI corta la energía.</li>
</ol>



<h3 class="wp-block-heading">¿Por qué es necesario que el SAI se apague?</h3>



<p>Imagina que <strong>no</strong> enviamos el «Kill Power»:</p>



<ul class="wp-block-list">
<li>La Raspberry se apaga y se queda esperando.</li>



<li>El SAI se queda encendido con batería hasta que se agote al 0%.</li>



<li>Vuelve la luz de la calle.</li>



<li><strong>Problema:</strong> Como el SAI nunca llegó a cortarle la corriente a la Raspberry (porque se quedó en un estado de «espera» con la batería agotada pero sin apagar el circuito), la Raspberry <strong>no detectará que ha vuelto la energía</strong> y no arrancará sola. Se quedará apagada hasta que alguien vaya físicamente a desenchufarla y enchufarla.</li>
</ul>



<h3 class="wp-block-heading">Resumen de seguridad</h3>



<p>Con el valor de <strong>30 segundos</strong> que tiene tu Salicru de fábrica:</p>



<ul class="wp-block-list">
<li>La Raspberry tiene tiempo de sobra (le sobran unos 25 segundos) para terminar de cerrarlo todo antes de que el SAI corte el flujo eléctrico.</li>



<li>Es un método estándar y muy seguro.</li>
</ul>



<p><strong>Un detalle importante:</strong> En las Raspberry Pi, para que el ciclo de «vuelva la luz y se encienda sola» funcione perfecto, asegúrate de que el SAI esté configurado para rearmarse automáticamente (cosa que los Salicru SOHO+ hacen por defecto).</p>



<p>Para estar seguro de que la Raspberry <strong>sabe</strong> que es la jefa del apagado (modo <code>master</code>), ejecuta:</p>



<pre class="wp-block-code"><code>upsc salicru@localhost ups.delay.shutdown</code></pre>



<p>Si te responde <code>30</code>, significa que todo está listo para que, en caso de emergencia, la Pi le ordene al Salicru esperar 30 segundos antes de cortar la energía, dándole tiempo a la MicroSD para cerrarse a salvo.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">¿Cómo saber si realmente se apagará? (Simulación segura)</h3>



<p>Si quieres estar 100% seguro de que la configuración es correcta sin apagar la Raspberry de golpe, puedes mirar el log del sistema:</p>



<pre class="wp-block-code"><code>sudo journalctl -f -u nut-monitor -u nut-server</code></pre>



<p>Si ahora mismo desenchufas el SAI de la pared, Verás en el log <code>UPS salicru@localhost on battery</code>.</p>



<pre class="wp-block-code"><code>nut@zero:~ $ <strong>sudo journalctl -f -u nut-monitor -u nut-server</strong>
mar 07 18:05:06 zero nut-server&#91;7408]: Instant command: upsmon@::1 did test.battery.start.quick on salicru (tracking ID: disabled)
mar 07 18:05:06 zero upsd&#91;7408]: Instant command: upsmon@::1 did test.battery.start.quick on salicru (tracking ID: disabled)
mar 07 19:24:09 zero nut-server&#91;7408]: Instant command: upsmon@::1 did test.battery.start.quick on salicru (tracking ID: disabled)
mar 07 19:24:09 zero upsd&#91;7408]: Instant command: upsmon@::1 did test.battery.start.quick on salicru (tracking ID: disabled)
mar 07 19:27:08 zero nut-server&#91;7408]: Instant command: upsmon@::1 did test.battery.start.quick on salicru (tracking ID: disabled)
mar 07 19:27:08 zero upsd&#91;7408]: Instant command: upsmon@::1 did test.battery.start.quick on salicru (tracking ID: disabled)
mar 07 20:05:29 zero nut-monitor&#91;6907]: UPS salicru@localhost <mark style="background-color:#7bdcb5" class="has-inline-color">on battery</mark>
mar 07 20:05:45 zero nut-monitor&#91;9348]: Network UPS Tools upsmon 2.8.1</code></pre>



<p>Si miras en <code>upsc salicru@localhost</code> verás que cambia a <code>status: OB</code>.</p>



<pre class="wp-block-code"><code>nut@zero:~ $ <strong>upsc salicru@localhost</strong>
Init SSL without certificate database
battery.voltage: 26.9
device.type: ups
driver.debug: 0
driver.flag.allow_killpower: 0
driver.name: nutdrv_qx
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.product: USB to Serial
driver.parameter.productid: 5161
driver.parameter.synchronous: auto
driver.parameter.vendor: Cypress Semiconductor
driver.parameter.vendorid: 0665
driver.state: quiet
driver.version: 2.8.1
driver.version.data: Q1 0.08
driver.version.internal: 0.36
driver.version.usb: libusb-1.0.28 (API: 0x100010a)
input.frequency: 50.0
input.voltage: 9.6
input.voltage.fault: 9.6
output.voltage: 227.4
ups.beeper.status: enabled
ups.delay.shutdown: 30
ups.delay.start: 180
ups.load: 0
ups.productid: 5161
<mark style="background-color:#7bdcb5" class="has-inline-color">ups.status: OB</mark>
ups.temperature: 25.0
ups.type: offline / line interactive
ups.vendorid: 0665
</code></pre>



<p><strong>Lo más importante:</strong></p>



<p>Como el modelo SOHO+ 2000, tiene mucha autonomía para una Raspberry Pi Zero 2W (que consume casi nada). No esperes a que llegue a <code>Low Battery</code> (batería baja) de forma real porque podría tardar horas.</p>



<p>Si en algún momento quieres probar que el apagado funciona de verdad, el comando es:</p>



<pre class="wp-block-code"><code>sudo upsmon -c fsd</code></pre>



<p><em>(Esto significa «Forced Shutdown» y simula que la batería se ha agotado, iniciando el proceso de apagado de seguridad inmediatamente).</em></p>



<p>¡Ya está todo listo y protegido! Tu Raspberry Pi ahora sobrevivirá a los cortes de luz sin corromper la tarjeta SD.</p>



<h2 class="wp-block-heading">El script de alertas para Telegram</h2>



<p>Creamos el script que enviará los mensajes: </p>



<pre class="wp-block-code"><code><code>sudo nano /usr/local/bin/nut-telegram.sh</code></code></pre>



<p>Copia y pega el siguiente script. No olvides reemplazar «tu_token» y «tu_id» por los tuyos propios</p>



<pre class="wp-block-code"><code>#!/bin/bash

# Configuración del Bot de Telegram
TOKEN="<mark style="background-color:#7bdcb5" class="has-inline-color">tu_token</mark>"
CHAT_ID="<mark style="background-color:#7bdcb5" class="has-inline-color">tu_id</mark>"
export LC_ALL=C

# Función interna para leer los sensores (Lógica estable)
capturar() {
    BATERIA_V=$(upsc salicru@localhost battery.voltage 2&gt;/dev/null || echo "0.0")
    VOLTAJE_IN=$(upsc salicru@localhost input.voltage 2&gt;/dev/null || echo "0.0")
    VOLTAJE_OUT=$(upsc salicru@localhost output.voltage 2&gt;/dev/null || echo "0.0")
    CARGA_SAI=$(upsc salicru@localhost ups.load 2&gt;/dev/null || echo "0")
    ESTADO_SAI=$(upsc salicru@localhost ups.status 2&gt;/dev/null || echo "N/A")
}

case "$1" in
    *"on battery"*)
        ICONO="&#x1f6a8;"
        TITULO="CORTE DE SUMINISTRO"
        
        # BUCLE DE ESPERA: No envía hasta que la entrada sea &lt; 50V real
        intentos=0
        capturar
        while &#91;&#91; "${VOLTAJE_IN%.*}" -gt 50 ]] &amp;&amp; &#91;&#91; $intentos -lt 12 ]]; do
            sleep 5
            capturar
            ((intentos++))
        done

        # --- DIAGNÓSTICO DE SALUD AL CORTE ---
        V_INT=${BATERIA_V%.*}
        if &#91; "$V_INT" -lt 24 ]; then
            DETALLE="¡OJO! Las baterías están muy bajas ($BATERIA_V V). Salud crítica, considera cambiarlas."
        else
            DETALLE="El SAI está operando con baterías. Salud química OK ($BATERIA_V V)."
        fi
        ;;

    *"on line power"*)
        ICONO="&#x2705;"
        TITULO="CORRIENTE RESTABLECIDA"
        DETALLE="El sistema vuelve a la red eléctrica."

        # BUCLE DE ESPERA: No envía hasta que la entrada sea &gt; 200V real
        intentos=0
        capturar
        while &#91;&#91; "${VOLTAJE_IN%.*}" -lt 200 ]] &amp;&amp; &#91;&#91; $intentos -lt 12 ]]; do
            sleep 5
            capturar
            ((intentos++))
        done
        ;;

    *"low battery"*)
        ICONO="&#x26a0;"
        TITULO="BATERIA CRITICA"
        DETALLE="Nivel muy bajo. El apagado es inminente."
        capturar
        ;;

    *"SHUTDOWN"*)
        ICONO="&#x1f480;"
        TITULO="APAGADO DE EMERGENCIA"
        DETALLE="La Raspberry se apaga para proteger la SD."
        capturar
        ;;

    *"REPLBATT"*)
        ICONO="&#x1f6e0;"
        TITULO="FALLO DE BATERIA"
        DETALLE="Es necesario sustituir las baterías del Salicru."
        capturar
        ;;

    *)
        ICONO="&#x2139;"
        TITULO="NOTIFICACION SAI"
        DETALLE="$1"
        capturar
        ;;
esac

# Mensaje final con los iconos: &#x1f50c; y &#x26a1;
CUERPO="$ICONO *$TITULO* $ICONO
------------------------------------
&#x1f4dd; $DETALLE

&#x1f50b; *Bateria:* $BATERIA_V V
&#x1f50c; *Entrada:* $VOLTAJE_IN V
&#x26a1; *Salida:* $VOLTAJE_OUT V
&#x1f4ca; *Carga SAI:* $CARGA_SAI%
&#x1f4c8; *Estado:* $ESTADO_SAI"

# Envío a Telegram
curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" \
     --data-urlencode "chat_id=$CHAT_ID" \
     --data-urlencode "text=$CUERPO" \
     --data-urlencode "parse_mode=Markdown" &gt; /dev/null 2&gt;&amp;1</code></pre>



<p><strong>Importante:</strong> Dale permisos de ejecución con:</p>



<pre class="wp-block-code"><code><code>sudo chmod 755 /usr/local/bin/nut-telegram.sh</code></code></pre>



<p>y haz que el dueño sea el usuario de nut: </p>



<pre class="wp-block-code"><code><code>sudo chown nut:nut /usr/local/bin/nut-telegram.sh</code></code></pre>



<h3 class="wp-block-heading">Configurando los avisos por telegram</h3>



<p>Volvemos a configurar las flags para los avisos por telegram, por lo que volvemos a entrar al archivo upsmon.conf</p>



<pre class="wp-block-code"><code> sudo nano /etc/nut/upsmon.conf</code></pre>



<p>Copia encima o debajo de las anteriores notificaciones</p>



<pre class="wp-block-code"><code># Comando externo para notificaciones
NOTIFYCMD "/usr/local/bin/nut-telegram.sh"

# Definición de mensajes que activan el script
NOTIFYMSG ONLINE    "UPS salicru@localhost on line power"
NOTIFYMSG ONBATT    "UPS salicru@localhost on battery"
NOTIFYMSG LOWBATT   "UPS salicru@localhost low battery"
NOTIFYMSG SHUTDOWN  "SHUTDOWN"
NOTIFYMSG REPLBATT  "REPLBATT"</code></pre>



<p>Reinicia el servicio</p>



<pre class="wp-block-code"><code>sudo systemctl restart nut-monitor</code></pre>



<p>Haz una prueba manual con:</p>



<pre class="wp-block-code"><code>sudo -u nut /usr/local/bin/nut-telegram.sh "Prueba manual"</code></pre>



<h2 class="wp-block-heading">Test</h2>



<p>Podemos listar los comandos que puede realizar nuestro salicru.</p>



<pre class="wp-block-code"><code>nut@zero:~ $ <strong>upscmd -l salicru</strong>
Instant commands supported on UPS &#91;salicru]:

beeper.toggle - Toggle the UPS beeper
driver.killpower - Tell the driver daemon to initiate UPS shutdown; should be unlocked with driver.flag.allow_killpower option or variable setting
driver.reload - Reload running driver configuration from the file system (only works for changes in some options)
driver.reload-or-error - Reload running driver configuration from the file system (only works for changes in some options); return an error if something changed and could not be applied live (so the caller can restart it with new options)
driver.reload-or-exit - Reload running driver configuration from the file system (only works for changes in some options); exit the running driver if something changed and could not be applied live (so service management framework can restart it with new options)
load.off - Turn off the load immediately
load.on - Turn on the load immediately
shutdown.return - Turn off the load and return when power is back
shutdown.stayoff - Turn off the load and remain off
shutdown.stop - Stop a shutdown in progress
test.battery.start - Start a battery test
test.battery.start.deep - Start a deep battery test
test.battery.start.quick - Start a quick battery test
test.battery.stop - Stop the battery test</code></pre>



<p>De la lista podemos ejecutar <code>test.battery.start.quick </code>que lo único que hace es pasar al estado <code>OL CAL</code> y hacer un test del sistema para el chequeo interno del SAI pero no hará como su nombre indica, ningún test de las baterías.</p>



<pre class="wp-block-code"><code>nut@zero:~ $ upscmd -u upsmon -p <mark style="background-color:#7bdcb5" class="has-inline-color">tu_contresña_segura</mark> salicru test.battery.start.quick
OK</code></pre>



<p>Mientras se realiza el test, puedes comprobar el voltage de la batería en tiempo real con este comando, que se mantendrá inmutable ya que el el sistema se mantiene todo el tiempo OnLine.</p>



<pre class="wp-block-code"><code>while true; do upsc salicru@localhost battery.voltage; sleep 1; done</code></pre>



<h2 class="wp-block-heading">Mantenimiento Preventivo Mensual</h2>



<p>«Investigando a fondo con la consola de NUT, descubrimos que el Salicru SOHO+ protege sus baterías. Aunque veas comandos como <code>test.battery.start.deep</code>, el SAI los ignora para evitar descargas innecesarias. El único comando que acepta es el <code>quick</code>, que activa el modo <strong>OL CAL</strong> (Calibración Online). Este modo es genial para verificar que los relés y el inversor funcionan, pero <strong>no estresa la batería</strong>.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Conclusión:</strong> Para saber la salud real de tus baterías en este modelo, el &#8216;Test del Tirón&#8217; (desenchufar 10 segundos) sigue siendo el único modo. Mi script de Telegram te avisará al instante de cuánto cae el voltaje en ese momento y en que estado se encuentran las baterías.»</p>
</blockquote>



<p>Si el driver <code>nutdrv_qx</code> solo nos permite el <code>OL CAL</code>, vamos a convertir ese «estiramiento» en nuestro test mensual. Aunque no descargue la batería, es vital porque <strong>obliga a los relés físicos a moverse</strong>. Un SAI que nunca hace un test puede acabar con los relés «pegados» por el calor y el desuso, y el día que se vaya la luz de verdad, no conmutará.</p>



<h3 class="wp-block-heading"><strong>Script de «Mantenimiento Preventivo de Relés e Inversor»</strong>.</h3>



<p>Abre una terminal y ejecuta el siguiente comando para crear nuestro archivo de mantenimiento</p>



<pre class="wp-block-code"><code>sudo nano /usr/local/bin/mantenimiento-sai.sh</code></pre>



<p>Pega el siguente texto, no olvides de introducir «tu_token_de_telegram» «tu_id_de_chat» y «tu_contraseña_segura»</p>



<pre class="wp-block-code"><code>#!/bin/bash

# --- CONFIGURACIÓN ---
TOKEN="<mark style="background-color:#7bdcb5" class="has-inline-color">TU_TOKEN_DE_TELEGRAM</mark>"
ID="<mark style="background-color:#7bdcb5" class="has-inline-color">TU_ID_DE_CHAT</mark>"
UPS="salicru"
USUARIO="upsmon"
CLAVE="<mark style="background-color:#7bdcb5" class="has-inline-color">tu_contraseña_segura</mark>"

# 1. Inicio del mantenimiento
curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" -d "chat_id=$ID&amp;text=&#x2699; *Mantenimiento Mensual:* Iniciando test de relés en $UPS..."

# 2. Lanzar el Quick Test (Modo CAL)
upscmd -u $USUARIO -p $CLAVE $UPS test.battery.start.quick &gt; /dev/null
sleep 2

# 3. Verificamos si el SAI ha entrado en modo calibración
STATUS=$(upsc $UPS ups.status)

if &#91;&#91; "$STATUS" == *"CAL"* ]]; then
    # Esperamos a que termine (vimos que dura unos 9-10 seg)
    sleep 10
    FINAL_STATUS=$(upsc $UPS ups.status)
    if &#91;&#91; "$FINAL_STATUS" == "OL" ]]; then
        MSG="&#x2705; *TEST OK*: Los relés han conmutado y el inversor ha arrancado correctamente. El sistema de emergencia está operativo."
    else
        MSG="&#x26a0; *AVISO*: El test ha terminado pero el estado es $FINAL_STATUS. Revisar manualmente."
    fi
else
    MSG="&#x274c; *ERROR*: El SAI ha ignorado la orden de test. Es posible que necesite un reinicio del servicio NUT."
fi

# 4. Enviar resultado
curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" -d "chat_id=$ID&amp;parse_mode=Markdown&amp;text=$MSG"
</code></pre>



<p>Este script hará el test aceptado por el Salicru, verificará que el estado pase por <code>OL CAL</code> y te informará de que la electrónica de conmutación sigue viva.</p>



<h3 class="wp-block-heading">La automatización (Cron)</h3>



<p>Para que se haga solo una vez al mes (por ejemplo, el día 1 a las 10:00), añade esto a tu <code>sudo crontab -e</code>:</p>



<pre class="wp-block-code"><code>00 10 1 * * /usr/local/bin/mantenimiento-sai.sh</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">«¿Por qué automatizar un test que no descarga la batería?»</h3>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>Muchos usuarios cometen el error de no tocar su SAI hasta que se va la luz. El problema es que los relés son piezas mecánicas que pueden fallar por falta de uso. Mi script mensual fuerza al Salicru a entrar en modo <strong>OL CAL</strong>. Aunque no descargue la batería, este proceso hace que los relés &#8216;hagan ejercicio&#8217; y que el inversor se autochequee. Es la garantía de que, cuando llegue el apagón real, la parte mecánica del SAI no estará agarrotada.</em></p>
</blockquote>



<h3 class="wp-block-heading">Tabla de Salud de la Batería (Sistema de 24V)</h3>



<p>«Una vez que recibas la notificación en tu móvil, ¿cómo saber si esos voltios son buenos o malos? He preparado esta tabla de referencia para que sepas cuándo es el momento de sacar la cartera y comprar repuestos:»</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><td>Voltaje en Batería</td><td>Estado de Salud</td><td>Significado Técnico</td><td>Acción</td></tr></thead><tbody><tr><td><strong>&gt; 27.0 V</strong></td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Excelente</strong></td><td>Carga completa en flotación.</td><td>Ninguna.</td></tr><tr><td><strong>24.5 V &#8211; 26.5 V</strong></td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Normal</strong></td><td>Funcionamiento correcto bajo carga.</td><td>Uso habitual.</td></tr><tr><td><strong>23.5 V &#8211; 24.4 V</strong></td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Aviso / Débil</strong></td><td>La batería empieza a perder capacidad química.</td><td>Planificar cambio a medio plazo.</td></tr><tr><td><strong>&lt; 23.5 V</strong></td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6a8.png" alt="🚨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Crítico</strong></td><td>Agotamiento inminente o celdas dañadas.</td><td><strong>Cambio urgente</strong>. Riesgo de apagón repentino.</td></tr></tbody></table></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxete.duckdns.org/como-monitorizar-un-sai-salicru-con-raspberry-pi-zero/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Compilar aMule desde GitHub (Rama Master) en Raspberry Pi</title>
		<link>https://linuxete.duckdns.org/compilar-amule-desde-github-rama-master-en-raspberry-pi/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=compilar-amule-desde-github-rama-master-en-raspberry-pi</link>
					<comments>https://linuxete.duckdns.org/compilar-amule-desde-github-rama-master-en-raspberry-pi/#respond</comments>
		
		<dc:creator><![CDATA[raspberry]]></dc:creator>
		<pubDate>Sat, 14 Feb 2026 21:31:24 +0000</pubDate>
				<category><![CDATA[amule]]></category>
		<category><![CDATA[P2P]]></category>
		<category><![CDATA[amuled]]></category>
		<category><![CDATA[Compilación]]></category>
		<category><![CDATA[Debian 13]]></category>
		<category><![CDATA[Raspberry Pi 5]]></category>
		<category><![CDATA[SSD]]></category>
		<category><![CDATA[Systemd]]></category>
		<category><![CDATA[Tutorial Linux]]></category>
		<guid isPermaLink="false">https://linuxete.duckdns.org/?p=3846</guid>

					<description><![CDATA[«Instalar aMule desde GitHub no solo sirve para tener nuevas funciones, si no, para asegurar que el programa sea totalmente compatible con el hardware y software moderno. Obtenemos un binario que aprovecha los 64 bits de la Raspberry Pi, ya que desde 2021, el código está «congelado». Ramas de desarrollo. A la hora de compilar [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>«Instalar aMule desde GitHub no solo sirve para tener nuevas funciones, si no, para asegurar que el programa sea <strong>totalmente compatible con el hardware y software moderno</strong>. Obtenemos un binario que aprovecha los 64 bits de la Raspberry Pi, ya que desde 2021, el código está «congelado».</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Ramas de desarrollo.</h2>



<p>A la hora de compilar debes saber que existen varias ramas de desarrollo. Para entenderlo fácil, imagina que el desarrollo de un programa en GitHub es como un <strong>árbol</strong> del cual parten distintas ramas, y de nosotros depende elegir la rama que se ajuste a nuestras necesidades.</p>



<p>De las ramas disponibles, la rama <strong><code>master</code></strong> (o a veces llamada <code>main</code>) es la que ocupa nuestra atención, es donde los desarrolladores van subiendo todos los parches modernos para hacerlo compatible con el compilador actual (<code>gcc</code>) y las nuevas librerías (<code>wxWidgets 3.2</code>).</p>



<p>Otras ramas son las <code>Tags</code> y los <code>Branches</code> de desarollo.</p>



<p>En esta tabla a modo de resumen, te muestro los tres tipos de «versiones» disponibles:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><td><strong>Tipo</strong></td><td><strong>Qué es</strong></td><td><strong>¿Cuándo elegirla?</strong></td></tr></thead><tbody><tr><td><strong>Master (Branch)</strong></td><td>El tronco principal. Tiene lo último de lo último.</td><td><strong>Nuestra elección.</strong> Es la más compatible con sistemas modernos.</td></tr><tr><td><strong>Tags (Etiquetas)</strong></td><td>Son «fotos» fijas del código en un momento concreto (ej. v2.3.3).</td><td>Solo si usas un sistema operativo viejo que coincida con la fecha de esa versión.</td></tr><tr><td><strong>Branches de desarrollo</strong></td><td>Ramas paralelas donde se prueban cosas experimentales (ej. <code>fix-webserver</code>).</td><td>Solo si eres desarrollador y quieres probar una función específica que aún no está terminada.</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>«Usamos la rama <strong>Master</strong> porque es la versión &#8216;viva&#8217; del código. Mientras que las versiones descargables (estables) se quedan congeladas en el tiempo, la rama Master recibe actualizaciones constantes que permiten que aMule se compile sin errores en sistemas de vanguardia como Debian 13.»</em></p>
</blockquote>



<h2 class="wp-block-heading">Desactiva Wayland</h2>



<p>Tu <strong>Raspberry Pi 5</strong> con Debian 13 usa por defecto <strong>Wayland</strong> como servidor gráfico. Sin embargo, <strong>aMule</strong> utiliza la librería <strong>wxWidgets</strong> (wxGTK).</p>



<p>Aunque wxWidgets ha mejorado mucho, su implementación para Wayland todavía tiene problemas graves con los menús contextuales y las barras de herramientas en aplicaciones que no han sido actualizadas internamente. Al forzar <strong>X11</strong>, el sistema utiliza una capa de compatibilidad (XWayland) que dibuja las ventanas de la forma «clásica», permitiendo que los menús aparezcan donde deben.</p>



<h3 class="wp-block-heading">Sigue estos pasos en tu Raspberry Pi OS</h3>



<p>Si usas la imagen oficial de Raspberry Pi, hay una herramienta integrada que gestiona esto sin tocar código:</p>



<ol start="1" class="wp-block-list">
<li>Abre la terminal y escribe: <code>sudo raspi-config</code></li>



<li>Ve a <strong>Advanced Options</strong> (Opciones avanzadas).</li>



<li>Busca la opción <strong>Wayland</strong>.</li>



<li>Selecciona <strong>X11</strong> (o «Disable Wayland»).</li>



<li>Finaliza y <strong>reinicia</strong>.</li>
</ol>



<h2 class="wp-block-heading">1. Limpieza de Instalaciones Previas</h2>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Utiliza este punto, si ya tenías aMule instalado y por ende, un servicio systemd de control. Si no es así, pasa al punto 2.</p>
</blockquote>



<p>Si ya usabas aMule o bien tenías algún servicio de systemd corriendo para su gestion, debemos eliminar todo rastro para evitar conflictos con versiones antiguas de los repositorios.</p>



<p>Comprueba si ya tienes un servicio activo con <code>systemctl list-units --all | grep -i amule</code></p>



<pre class="wp-block-code"><code><strong>systemctl list-units --all | grep -i amule</strong>
  <mark style="background-color:rgba(0, 0, 0, 0);color:#cf2e2e" class="has-inline-color">amule.service</mark><mark style="background-color:rgba(0, 0, 0, 0);color:#7bdcb5" class="has-inline-color"> </mark>                                                                                                                                                                       loaded    active   running   aMule Master Daemon
</code></pre>



<p>Esto arroja que tengo un servicio llamado <code>amule.service</code> y debo detenerlo con este comando:</p>



<pre class="wp-block-code"><code>sudo systemctl stop amule.service</code></pre>



<p>Una vez detenido el servicio, desinstalamos todo lo relacionado con aMule</p>



<pre id="block-2cb1bd22-d0e4-477c-aeb5-ded12e160709" class="wp-block-preformatted">sudo apt purge amule amule-daemon amule-utils-gui amule-utils amule-common</pre>



<p>Y por último eliminamos todos los restos que dependen de la mula.</p>



<pre class="wp-block-code"><code>sudo apt autoremove --purge</code></pre>



<h2 class="wp-block-heading">2. Instalación de Dependencias de Compilación</h2>



<p>Necesitamos el conjunto de herramientas de desarrollo y las librerías necesarias para el GUI remoto y el demonio:</p>



<pre class="wp-block-code"><code>sudo apt update</code></pre>



<p>Instala el compilador y demás librerías. Copia y pega todo ese bloque en la terminal y dale a Enter.</p>



<pre class="wp-block-code"><code>
sudo apt install -y libboost-all-dev git build-essential autoconf automake libtool \
libwxgtk3.2-dev libcryptsetup-dev libcurl4-openssl-dev libgd-dev \
libgeoip-dev libupnp-dev libboost-dev binutils-dev zlib1g-dev \
libcrypto++-dev libreadline-dev gettext autopoint
</code></pre>



<h2 class="wp-block-heading">3. Obtención y Preparación del Código (Master)</h2>



<p>Clonamos directamente la rama de desarrollo para asegurar que los parches estén aplicados:</p>



<p>Nos situamos en el directorio principal con:</p>



<pre class="wp-block-code"><code>cd ~</code></pre>



<p>Descargamos el directorio completo desde GitHub</p>



<pre id="block-cb6aed43-81ff-4077-b91a-d2069335ac15" class="wp-block-preformatted">git clone https://github.com/amule-project/amule.git</pre>



<p>El código anterior nos genera un directorio llamado amule, en el cual nos debemos situar con el comando:</p>



<pre class="wp-block-code"><code> cd amule</code></pre>



<p>Elegimos la rama principal de desarrollo (main)</p>



<pre class="wp-block-code"><code>git checkout master</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Con <code>git checkout master</code>, le decimos a nuestra Raspberry: <em>«No me des lo que se publicó hace años, dame lo que los desarrolladores tienen en su mesa de trabajo hoy mismo»</em>.</p>
</blockquote>



<p>Preparamos el código fuente antes de la compilacion para permitir al software compilarse específicamente en tu máquina</p>



<pre class="wp-block-code"><code>./autogen.sh</code></pre>



<p>El siguiente comando no es necesario usarlo, sirve para «volver al estado de fábrica» cuando ya has intentado compilar antes y la carpeta se ha llenado de archivos basura (objetos .o, ejecutables a medio hacer, scripts generados por ./autogen.sh). Se debería usar antes de ./autogen.sh para así una vez ejecutado, se vuelvan a crear los nuevos archivos de compilación.</p>



<pre class="wp-block-code"><code>git clean -fxd       # Limpieza total del árbol de archivos</code></pre>



<h2 class="wp-block-heading">4. Configuración del Demonio y Utilidades</h2>



<p>A continuación te presento dos tipos de configuraciones, ya sea para Raspberry Pi 4 o Raspberry Pi 5 y así obtener la configuración del demonio (<code>amuled</code>), la interfaz gráfica remota (<code>amule-gui</code>) y las herramientas de consola:</p>



<p>«El comando <code>./configure</code> es el cerebro del proceso. Se encarga de comprobar que tu Raspberry Pi tiene todas las librerías instaladas y utiliza nuestras instrucciones personalizadas para crear un plan de construcción (Makefile) optimizado para nuestro SSD y procesador.»</p>



<p>Copia esto tal cual y lo pegas en tu terminal.</p>



<p>Para Raspberry Pi 4 (Cortex-A72)</p>



<pre class="wp-block-code"><code>CXXFLAGS="-O3 -march=armv8-a+crc+simd -mtune=cortex-a72" ./configure \
    --enable-amule-daemon \
    --enable-amule-gui \
    --enable-amulecmd \
    --enable-webserver \
    --enable-cas \
    --enable-alcc \
    --disable-monolithic \
    --with-denoise-level=0 \
    --enable-optimize \
    --enable-mmap \
    --disable-debug
    --with-boost
</code></pre>



<p>Para Raspberry Pi 5 (Cortex-A76)</p>



<pre class="wp-block-code"><code>CXXFLAGS="-O3 -march=armv8.2-a+crypto -mtune=cortex-a76" \
./configure \
    --enable-amule-daemon \
    --enable-amule-gui \
    --enable-amulecmd \
    --enable-webserver \
    --enable-cas \
    --enable-alcc \
    --disable-monolithic \
    --with-denoise-level=0 \
    --enable-optimize \
    --enable-mmap \
    --disable-debug \
    --with-boost</code></pre>



<p>Si <code>./configure</code> falla con «Boost not found», prueba:<br><br><code>--with-boost=/usr --with-boost-libdir=/usr/lib/aarch64-linux-gnu --with-boost-includedir=/usr/include</code></p>



<p>Se ha incluido <code>--enable-optimize</code> para que la Raspberry Pi  exprima su procesador y <code>--disable-monolithic</code> para separar el demonio de la interfaz.</p>



<h2 class="wp-block-heading">5. Compilación Potente e Instalación</h2>



<p>Aprovechamos los 4 núcleos de la Pi 4. Al estar en SSD, este proceso es significativamente más rápido:</p>



<pre class="wp-block-code"><code>make -j$(nproc)</code></pre>



<p><code>make -j$(nproc)</code> (La Construcción)</p>



<p>Este es el comando que hace el trabajo pesado.</p>



<ul class="wp-block-list">
<li><strong>¿Qué hace?</strong>: Lee un archivo llamado <code>Makefile</code> (que se generó al ejecutar el <code>./configure</code>) y empieza a llamar al compilador para transformar cada archivo de código <code>.cpp</code> en archivos binarios de lenguaje máquina.</li>



<li><strong>El parámetro <code>--j$(nproc)</code></strong>: Es vital en la Raspberry Pi 4. Le dice al sistema: «<em>Usamos <code>$(nproc)</code> para que el sistema detecte automáticamente los 4 núcleos de la Pi 4 o Pi 5</em> «. Sin el <code>-j$(nproc)</code>, solo usaría uno y la compilación de aMule tardaría 4 veces más.</li>



<li><strong>Resultado</strong>: Al terminar, tendrás el programa «construido» dentro de la carpeta donde estás, pero aún no está instalado en el sistema.</li>
</ul>



<pre class="wp-block-code"><code>sudo make install</code></pre>



<p><code>sudo make install</code> (La Mudanza)</p>



<p>Una vez que el programa está construido, hay que poner cada pieza en su sitio definitivo.</p>



<ul class="wp-block-list">
<li><strong>¿Qué hace?</strong>: Copia los ejecutables (como <code>amuled</code>, <code>amulegui</code>) y los archivos de ayuda/traducciones a las carpetas protegidas del sistema operativo.</li>



<li><strong>¿A dónde van?</strong>: En tu caso, los mueve a <code>/usr/local/bin/</code>.</li>



<li><strong>¿Por qué <code>sudo</code>?</strong>: Porque para escribir archivos en las carpetas del sistema (<code>/usr/local/</code>) necesitas permisos de administrador (SuperUser DO).</li>
</ul>



<pre class="wp-block-code"><code>sudo ldconfig</code></pre>



<p><code>sudo ldconfig</code> (El Registro)</p>



<p>Este es el paso que mucha gente olvida y que causa errores de «librería no encontrada».</p>



<ul class="wp-block-list">
<li><strong>¿Qué hace?</strong>: Actualiza los enlaces y la caché de las librerías compartidas.</li>



<li><strong>¿Por qué es necesario?</strong>: aMule utiliza muchas piezas externas (como <code>wxWidgets</code> o <code>Crypto++</code>). Al instalar versiones nuevas, el sistema necesita «indexarlas» en una base de datos interna (<code>/etc/ld.so.cache</code>).</li>



<li><strong>En resumen</strong>: Le dice al sistema operativo: «¡Oye! Acabamos de instalar programas y librerías nuevas en <code>/usr/local/lib</code>. Asegúrate de que todos los procesos sepan dónde encontrarlas ahora mismo».</li>
</ul>



<h2 class="wp-block-heading">6. Configuración de Acceso y Directorios</h2>



<h3 class="wp-block-heading">A. Primer arranque</h3>



<p>Para que todo funcione, tienes que «despertar» al demonio.</p>



<p>En una terminal escribe:</p>



<pre class="wp-block-code"><code>amuled</code></pre>



<p>Esto creará la carpeta <code>~/.aMule</code>.</p>



<p>Es muy posible que en la primera vez que el programa se ejecute, este se cierre automáticamente, ¡Tranquilo! es totalmente normal. La primera vez que ejecutas aMule, crea la carpeta de configuración, pero se cierra inmediatamente porque <strong>un demonio sin «mando a distancia» no sirve para nada</strong>.</p>



<p>El error te está diciendo literalmente: <em>«Si no puedo conectarme con el exterior, no tengo forma de que me des órdenes»</em>.</p>



<h3 class="wp-block-heading">B. Generar una contraseña segura</h3>



<p>Las contraseñas del archivo <strong>amule.conf</strong> son encriptadas y no se pueden escribir directamente. Por ejemplo para usar la contraseña &lt;<strong>BurritoSabanero</strong>&gt; habrá que encriptarla para que sea válida y se pueda usar.</p>



<p>Primero, genera el código (hash) de tu contraseña. Cambia <code>tu_contraseña_aquí</code> por la que quieras:</p>



<pre class="wp-block-code"><code>echo -n "tu_contraseña_aquí" | md5sum</code></pre>



<p>Por ejemplo:</p>



<pre class="wp-block-code"><code>echo -n "BurritoSabanero" | md5sum</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>No olvides entrecomillar la palabra elegida como contraseña.</p>
</blockquote>



<p>Esto nos dará como resultado la contraseña encriptada siguiente:</p>



<pre class="wp-block-code"><code>0d545153bf7b94d6094a01f5f925163b  -</code></pre>



<h3 class="wp-block-heading">C. Editar el archivo de configuración</h3>



<p>Ahora vamos a decirle a aMule que acepte conexiones y a ponerle esa contraseña. Abre el editor:</p>



<pre class="wp-block-code"><code>nano ~/.aMule/amule.conf</code></pre>



<p>Busca las líneas que dicen, <strong>ECPassword</strong> y <strong><code>AcceptExternalConnections</code></strong> y déjalas así:</p>



<ul class="wp-block-list">
<li><strong><code>AcceptExternalConnections=1</code></strong> (Cambia el 0 por el 1)</li>



<li><strong><code>ECPassword=la_contraseña_que_generaste</code></strong> (Pega aquí el hash MD5)</li>
</ul>



<h3 class="wp-block-heading">D. Activar la Interfaz Web.</h3>



<p>Como has instalado <code>amule-utils</code>, también tienes <strong><code>amuleweb</code></strong>. Si lo activas, podrás gestionar las descargas escribiendo la IP de tu Raspberry en el navegador de tu móvil o tablet (ej: <code>http://192.168.1.50:24711</code>).</p>



<p>Busca también la sección [WebServer] y cambia lo siguiente.</p>



<ul class="wp-block-list">
<li><strong><code>Enabled=1</code></strong></li>



<li><strong><code>Password=la_contraseña_que_generaste</code></strong> (Puedes usar la misma o generar otra distinta)</li>
</ul>



<h3 class="wp-block-heading">E. Prueba de fuego</h3>



<p>Guarda los cambios con <code>Ctrl+O</code>, pulsa <code>Enter</code> y sal con <code>Ctrl+X</code>.</p>



<p>Ahora vuelve a lanzar el demonio:</p>



<pre class="wp-block-code"><code>amuled -f</code></pre>



<p>Si todo ha ido bien, esta vez <strong>no se cerrará</strong>. Se quedará funcionando.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Tip de experto:</strong> Como <code>amuled</code> se queda bloqueando la terminal, lo ideal es lanzarlo en segundo plano para que libere la terminal y asi puedas seguir usandola. Esto se logran usando el modificador <code>-f</code> al final del comando.</p>
</blockquote>



<h3 class="wp-block-heading">F.Configuración aMule</h3>



<p>Para modificar la configuración de amuled, asegurate que el demonio no se está ejecutando.</p>



<pre class="wp-block-code"><code>killall amuled</code></pre>



<p>Con el demonio fuera de juego, podemos editar nuestras preferencias en el archivo de configuración de amule.</p>



<pre class="wp-block-code"><code>nano /home/usuario/.aMule/amule.conf</code></pre>



<p>La siguiente configuración es una copia de mi archivo <strong>amule.conf</strong>. Si quieres puedes usarlo copiarlo y adaptarlo a tus necesidades. Yo he modificado las líneas que están resaltadas en verde con respecto al archivo original.</p>



<pre class="wp-block-code"><code>&#91;eMule]
AppVersion=2.3.3
<mark>Nick=Usuario_de_aMule</mark>
QueueSizePref=50
<mark>MaxUpload=5000</mark>
<mark>MaxDownload=19375</mark>
<mark>SlotAllocation=20</mark>
<mark>Port=24662</mark>
<mark>UDPPort=24672</mark>
UDPEnable=1
Address=
Autoconnect=1
<mark>MaxSourcesPerFile=300</mark>
MaxConnections=300
MaxConnectionsPerFiveSeconds=20
RemoveDeadServer=1
DeadServerRetry=3
ServerKeepAliveTimeout=0
Reconnect=1
Scoresystem=1
Serverlist=1
AddServerListFromServer=0
AddServerListFromClient=0
SafeServerConnect=0
AutoConnectStaticOnly=0
UPnPEnabled=0
UPnPTCPPort=50000
SmartIdCheck=1
ConnectToKad=1
ConnectToED2K=1
TempDir=/home/<mark>tu_usuario</mark>/.aMule/Temp
IncomingDir=/home/<mark>tu_usuario</mark>/.aMule/Incoming
ICH=1
AICHTrust=0
CheckDiskspace=1
MinFreeDiskSpace=1
AddNewFilesPaused=0
PreviewPrio=0
ManualHighPrio=0
StartNextFile=0
StartNextFileSameCat=0
StartNextFileAlpha=0
FileBufferSizePref=100
DAPPref=1
UAPPref=1
AllocateFullFile=0
OSDirectory=/home/tu_usuario/.aMule/
OnlineSignature=0
OnlineSignatureUpdate=5
EnableTrayIcon=0
MinToTray=0
Notifications=0
ConfirmExit=1
StartupMinimized=0
3DDepth=10
ToolTipDelay=1
ShowOverhead=0
ShowInfoOnCatTabs=1
VerticalToolbar=0
<mark>GeoIPEnabled=0</mark>
ShowVersionOnTitle=0
VideoPlayer=
StatGraphsInterval=3
statsInterval=30
DownloadCapacity=300
UploadCapacity=100
StatsAverageMinutes=5
VariousStatisticsMaxValue=100
SeeShare=2
FilterLanIPs=1
ParanoidFiltering=1
IPFilterAutoLoad=1
<mark>IPFilterURL=http://upd.emule-security.org/ipfilter.zip</mark>
FilterLevel=127
IPFilterSystem=0
FilterMessages=1
FilterAllMessages=0
MessagesFromFriendsOnly=0
MessageFromValidSourcesOnly=1
FilterWordMessages=0
MessageFilter=
ShowMessagesInLog=1
FilterComments=0
CommentFilter=
ShareHiddenFiles=1
AutoSortDownloads=0
NewVersionCheck=0
AdvancedSpamFilter=1
MessageUseCaptchas=1
Language=
SplitterbarPosition=75
YourHostname=
DateTimeFormat=%A, %x, %X
AllcatType=0
ShowAllNotCats=0
SmartIdState=1
DropSlowSources=0
<mark>KadNodesUrl=http://upd.emule-security.org/nodes.dat</mark>
<mark>Ed2kServersUrl=http://emule-security.org/serverlist/server.met</mark>
ShowRatesOnTitle=0
GeoLiteCountryUpdateUrl=http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
StatsServerName=Shorty's ED2K stats
StatsServerURL=http://ed2k.shortypower.dyndns.org/?hash=
CreateSparseFiles=1
&#91;Browser]
OpenPageInTab=1
CustomBrowserString=
&#91;Proxy]
ProxyEnableProxy=0
ProxyType=0
ProxyName=
ProxyPort=1080
ProxyEnablePassword=0
ProxyUser=
ProxyPassword=
&#91;ExternalConnect]
UseSrcSeeds=0
<mark>AcceptExternalConnections=1</mark>
ECAddress=
ECPort=4712
<mark>ECPassword=0d545153bf7b94d6094a01f5f925163b</mark>
UPnPECEnabled=0
ShowProgressBar=1
ShowPercent=1
UseSecIdent=1
IpFilterClients=1
IpFilterServers=1
TransmitOnlyUploadingClients=0
&#91;WebServer]
Enabled=1
<mark>Password=0d545153bf7b94d6094a01f5f925163b</mark>
PasswordLow=
<mark>Port=24711</mark>
WebUPnPTCPPort=50001
UPnPWebServerEnabled=0
UseGzip=1
UseLowRightsUser=0
PageRefreshTime=120
Template=default
Path=amuleweb
&#91;GUI]
HideOnClose=0
&#91;Razor_Preferences]
FastED2KLinksHandler=1
&#91;SkinGUIOptions]
Skin=
&#91;Statistics]
MaxClientVersions=0
&#91;Obfuscation]
IsClientCryptLayerSupported=1
IsCryptLayerRequested=1
IsClientCryptLayerRequired=0
CryptoPaddingLenght=254
CryptoKadUDPKey=1686729473
&#91;PowerManagement]
PreventSleepWhileDownloading=0
&#91;UserEvents]
&#91;UserEvents/DownloadCompleted]
CoreEnabled=0
CoreCommand=
GUIEnabled=0
GUICommand=
&#91;UserEvents/NewChatSession]
CoreEnabled=0
CoreCommand=
GUIEnabled=0
GUICommand=
&#91;UserEvents/OutOfDiskSpace]
CoreEnabled=0
CoreCommand=
GUIEnabled=0
GUICommand=
&#91;UserEvents/ErrorOnCompletion]
CoreEnabled=0
CoreCommand=
GUIEnabled=0
GUICommand=
&#91;HTTPDownload]
URL_1=http://upd.emule-security.org/ipfilter.zip
URL_2=http://emule-security.org/serverlist/server.met
URL_5=http://upd.emule-security.org/nodes.dat
URL_3=http://emule-security.org/serverlist/server.met

</code></pre>



<p>Descripción de los puntos más importantes de la configuración de aMule.</p>



<h4 class="wp-block-heading">Parámetros Críticos de Configuración (<code>amule.conf</code>)</h4>



<ul class="wp-block-list">
<li><strong><code>Nick</code></strong>: Es tu nombre de usuario en la red. Aunque no afecta a la velocidad, sirve para identificarte en las colas de otros usuarios.</li>



<li><strong><code>MaxDownload=19375</code></strong>: Define el límite máximo de descarga (en este caso, unos 150 Mbps). Permite que aMule use el ancho de banda necesario sin saturar la CPU de la Raspberry.</li>



<li><strong><code>MaxUpload=5000</code></strong>: Define la velocidad de subida. Es vital ser generoso (5 MB/s); en la red eD2k, cuanto más subes, más créditos ganas y más rápido descargas de los demás.</li>



<li>Slot Allocation=20 : determina <strong>cuánta velocidad de subida le das a cada persona</strong> que se descarga algo de ti. Con 5000 de subida total, estás abriendo <strong>250 slots simultáneos</strong>. Vas a ganar créditos con 250 personas a la vez, lo que te garantiza descargar a máxima velocidad en tiempo récord.</li>



<li><strong><code>Port=24662</code> (TCP)</strong>: Es el puerto que usa el programa para recibir datos. Debe estar abierto en tu router hacia la IP de la Raspberry para evitar la «ID Baja».</li>



<li><strong><code>UDPPort=24672</code> (UDP)</strong>: Puerto para la red Kad y búsquedas. También debe estar abierto en el router para que la red funcione al 100%.</li>



<li><strong><code>MaxSourcesPerFile=300</code></strong>: El número máximo de fuentes que el programa buscará por cada archivo. Un valor de 300 es el punto de equilibrio ideal para la Raspberry Pi 4.</li>



<li><strong><code>MaxConnections=300</code></strong>: Límite de conexiones totales simultáneas. Mantenerlo en 300 evita que la Raspberry se bloquee por exceso de hilos de red abiertos. Si se sube mucho (ej. 500 o más), la Pi suele dar errores de red (<code>epoll</code>).</li>



<li><strong><code>MaxConnectionsPerFiveSeconds=20</code></strong>: Controla cuántas conexiones nuevas se intentan cada 5 segundos. Un valor bajo (20) evita que el router colapse al arrancar el programa.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h4 class="wp-block-heading">Mantenimiento y Rendimiento del Sistema</h4>



<ul class="wp-block-list">
<li><strong><code>FileBufferSizePref=100</code></strong>: Define el tamaño del búfer en RAM antes de escribir en el disco. Un valor alto (100% o más) reduce el número de escrituras constantes, protegiendo la salud de la tarjeta MicroSD.</li>



<li><strong><code>AllocateFullFile=0</code></strong>: Si está en <code>1</code>, reserva todo el espacio del archivo al empezar. En la Raspberry es mejor dejarlo en <code>0</code> para que no se congele el sistema al intentar crear archivos muy grandes de golpe.</li>



<li><strong><code>SmartIdState=1</code></strong>: Ayuda a recuperar la ID Alta (flechas verdes) si sufres un micro-corte de internet, siempre que los puertos del router estén bien configurados.</li>



<li><strong><code>Serverlist=1</code></strong>: Indica al programa que actualice la lista de servidores conocidos cada vez que se inicia.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h4 class="wp-block-heading">Rutas y Seguridad</h4>



<ul class="wp-block-list">
<li><strong><code>IncomingDir</code> y <code>TempDir</code></strong>: Son las carpetas donde se guardan las descargas finalizadas y los archivos temporales. En una Raspberry, si puedes usar un SSD o disco externo, cambia estas rutas para evitar desgastar la tarjeta SD.</li>



<li><strong><code>IPFilterURL</code></strong>: La dirección para descargar el filtro de IPs (ej: <code>http://upd.emule-security.org/ipfilter.zip</code>). Es fundamental para bloquear servidores falsos y clientes espía automáticamente.</li>



<li><strong><code>Ed2kServersUrl</code></strong>: Dirección para descargar una lista de servidores fiables (ej: <code>http://upd.emule-security.org/server.met</code>). Garantiza que siempre conectes a servidores reales y seguros.</li>
</ul>



<p></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">7. El paso final: ¿Quieres que aMule arranque solo?</h2>



<p>Para que tu Raspberry Pi sea un servidor de descargas profesional, lo ideal es crear un servicio en <code>systemd</code>. Esto hará que <code>amuled</code> se inicie automáticamente cada vez que enciendas la Pi sin necesidad de abrir una terminal.</p>



<p>En tu terminal homologada ejecuta este comando:</p>



<p>Copia y pega el contenido a tu archivo, no olvides sustituir «tu_usuario» y «tu_grupo» por los tuyos propios. </p>



<pre class="wp-block-code"><code>&#91;Unit]
Description=aMule Master Daemon
After=network.target

&#91;Service]
User=<mark style="background-color:#7bdcb5" class="has-inline-color">tu_usuario</mark>
Group=<mark style="background-color:#7bdcb5" class="has-inline-color">tu_grupo</mark>
# Usamos 'simple' porque amuled en rama master gestiona muy bien la salida a consola
Type=simple 
ExecStart=/usr/local/bin/amuled
Restart=always
RestartSec=5

&#91;Install]
WantedBy=multi-user.target</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Guarda con Crtl + o  y sal con Crtl + x </p>



<p>Ahora sigue estos pasos para que el sistema reconozca la nueva configuración sin errores:</p>



<ol start="1" class="wp-block-list">
<li><strong>Recarga la configuración</strong>: <br><code>sudo systemctl daemon-reload</code> <br>(Esto es vital cada vez que editas un archivo <code>.service</code>).</li>



<li><strong>Activa el servicio con:</strong><br><code>sudo systemctl enable amule.service</code></li>



<li><strong>Inicia el servicio:</strong><br><code>sudo systemctl start amule.service</code></li>



<li><strong>Comprueba que vive</strong>:<br><code>sudo systemctl status amule.service</code></li>
</ol>



<ul class="wp-block-list">
<li>Sólo en caso de fallo, si nesitas revivir o reiniciar el servicio puedes usar el comando:<br><code>sudo systemctl restart amule.service</code></li>
</ul>



<p>«Al compilar nosotros mismos, el sistema no sabe cómo arrancar el programa automáticamente. Creamos este archivo en <code>/etc/systemd/system/</code> para que la Raspberry Pi sepa que el &#8216;cerebro&#8217; de las descargas debe estar siempre vivo, incluso si hay un corte de luz y el SSD se reinicia.»</p>



<h2 class="wp-block-heading"><strong>Notas y advertencias</strong></h2>



<ul class="wp-block-list">
<li>Con &#8211;with-boost se usa Boost.Asio para networking → evita bugs de wxNet/epoll en ARM/Pi 5.</li>



<li>Si usas conexiones altas (&gt;300), el bug epoll puede volver; baja a 200-300 como workaround.</li>



<li>Como asunto relevantes: <a href="https://github.com/amule-project/amule/issues/171" target="_blank" rel="noreferrer noopener">https://github.com/amule-project/amule/issues/171</a> (donde recomiendan &#8211;with-boost explícitamente).</li>
</ul>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxete.duckdns.org/compilar-amule-desde-github-rama-master-en-raspberry-pi/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Cómo recibir notificaciones de aMule en Telegram</title>
		<link>https://linuxete.duckdns.org/como-recibir-notificaciones-de-amule-en-telegram/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=como-recibir-notificaciones-de-amule-en-telegram</link>
					<comments>https://linuxete.duckdns.org/como-recibir-notificaciones-de-amule-en-telegram/#respond</comments>
		
		<dc:creator><![CDATA[raspberry]]></dc:creator>
		<pubDate>Sun, 08 Feb 2026 22:29:10 +0000</pubDate>
				<category><![CDATA[amule]]></category>
		<category><![CDATA[amule 2.3.3]]></category>
		<category><![CDATA[amule.conf]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[Bot]]></category>
		<category><![CDATA[Descargas]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Notificaciones]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Raspberry Pi 4]]></category>
		<category><![CDATA[Raspberry Pi 5]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[Telegram]]></category>
		<category><![CDATA[Tutorial]]></category>
		<guid isPermaLink="false">https://linuxete.duckdns.org/?p=3826</guid>

					<description><![CDATA[Si eres de la vieja escuela, que aún disfruta con aMule, sabrás que no hay nada más frustrante que estar mirando la pantalla esperando a que termine esa descarga de pocas fuentes, que lleva semanas o el algún caso meses, esperando a finalizar. ¿No sería maravilloso que la «Mula» te enviara un mensaje al móvil [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Si eres de la vieja escuela, que aún disfruta con <strong>aMule</strong>, sabrás que no hay nada más frustrante que estar mirando la pantalla esperando a que termine esa descarga de pocas fuentes, que lleva semanas o el algún caso meses, esperando a  finalizar. ¿No sería maravilloso que la «Mula» te enviara un mensaje al móvil cuando termina? <br>Aquí os comparto este tutorial definitivo, y digo <strong>definitivo</strong> porque hemos peleado con todos los errores posibles: nombres de archivos con comillas, tamaños en bytes ilegibles y mensajes que nunca llegaban. La mayoría de los scripts que circulan por internet fallan porque aMule se vuelve loco con los espacios y los símbolos (como el apóstrofo de <em>Don&#8217;t</em>) y acaba enviando mensajes vacíos o bloqueando el sistema.</p>



<p>Vamos a usar un script «inteligente» que recoge todo lo que aMule escupe, calcula los Megabytes y lo envía a Telegram usando un formato que <strong>nunca falla</strong>.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Paso 1: Configurar aMule</h3>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>¡OJO!</strong> Antes de editar, detén aMule</p>
</blockquote>



<pre class="wp-block-code"><code><code>sudo systemctl stop amule</code></code></pre>



<p>Vamos a decirle a aMule que ejecute nuestro script. Para ello, debemos editar el archivo <code>amule.conf</code>.</p>



<pre class="wp-block-code"><code>nano ~/.aMule/amule.conf</code></pre>



<p>Busca la sección <code>[UserEvents/DownloadCompleted]</code> y déjala exactamente así:</p>



<pre class="wp-block-code"><code>CoreEnabled=1
CoreCommand=/home/<mark style="background-color:#7bdcb5" class="has-inline-color">tu_usuario</mark>/notificar_amule.sh %NAME %SIZE</code></pre>



<p>Sustituye tu_usuario por el tuyo propio.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Paso 2: Crear el Script</h3>



<p>Crea el archivo de tu script, sustituyendo tu_usuario por el tuyo propio:</p>



<pre class="wp-block-code"><code><code>nano /home/<mark style="background-color:#7bdcb5" class="has-inline-color">tu_usuario</mark>/notificar_amule.sh </code></code></pre>



<p>y pega este código (sustituye tu Token y tu ID de Chat):</p>



<pre class="wp-block-code"><code>#!/bin/bash

# --- CONFIGURACION DEL BOT ---
TOKEN="<mark style="background-color:#7bdcb5" class="has-inline-color">TU_TOKEN_AQUI</mark>"
ID_CHAT="<mark style="background-color:#7bdcb5" class="has-inline-color">TU_ID_AQUI</mark>"

# 1. Recogemos todo lo que mande aMule de golpe
TODO="$*"

# 2. Extraemos el tamaño (el último número de la frase)
BYTES=$(echo "$TODO" | grep -oP '\d+$')

# 3. Limpiamos el nombre (quitamos el número del final)
NOMBRE=$(echo "$TODO" | sed 's/&#91;0-9]*$//')

# 4. Calculamos los MB y sacamos la fecha de la Raspberry
TAMANO_MB=$((BYTES / 1048576))
FECHA=$(date +"%d/%m/%Y a las %H:%M")

# 5. El Mensaje (con emoticonos para darle estilo)
MENSAJE="&#x2705; DESCARGA COMPLETADA
----------------------------------
&#x1f3b5; Archivo: $NOMBRE
&#x2696; Tamaño: $TAMANO_MB MB
&#x1f552; Finalizado: $FECHA
&#x1f967; Servidor: Raspberry Pi
----------------------------------"

# 6. Envío blindado con urlencode (evita que el mensaje se corte)
/usr/bin/curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" \
     --data-urlencode "chat_id=$ID_CHAT" \
     --data-urlencode "text=$MENSAJE" &gt; /dev/null
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Paso 3: Permisos y Arranque</h3>



<p>Para que esto funcione, dale permiso de ejecución al script:</p>



<pre class="wp-block-code"><code><code>chmod +x /home/<mark style="background-color:#7bdcb5" class="has-inline-color">tu_usuario</mark>/notificar_amule.sh</code></code></pre>



<p>Ahora, arranca aMule de nuevo:</p>



<pre class="wp-block-code"><code><code>sudo systemctl restart amule</code></code></pre>



<p>¡Y listo! A partir de ahora, cada vez que la Mula termine su trabajo, recibirás un «ping» en tu Telegram con toda la información. ¡A disfrutar de la descarga!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxete.duckdns.org/como-recibir-notificaciones-de-amule-en-telegram/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Tutorial: Failover en Raspberry Pi mediante Llamada Telefónica</title>
		<link>https://linuxete.duckdns.org/tutorial-failover-en-raspberry-pi-mediante-llamada-telefonica/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tutorial-failover-en-raspberry-pi-mediante-llamada-telefonica</link>
					<comments>https://linuxete.duckdns.org/tutorial-failover-en-raspberry-pi-mediante-llamada-telefonica/#comments</comments>
		
		<dc:creator><![CDATA[raspberry]]></dc:creator>
		<pubDate>Tue, 13 Jan 2026 18:16:53 +0000</pubDate>
				<category><![CDATA[internet]]></category>
		<category><![CDATA[Seguridad]]></category>
		<category><![CDATA[Sistema]]></category>
		<category><![CDATA[watchdog]]></category>
		<category><![CDATA[A7670E]]></category>
		<category><![CDATA[Failover]]></category>
		<category><![CDATA[HAT 4G]]></category>
		<category><![CDATA[HAT 4G LTE CAT-1]]></category>
		<category><![CDATA[Waveshare]]></category>
		<guid isPermaLink="false">https://linuxete.duckdns.org/?p=3573</guid>

					<description><![CDATA[Nota, no recomiendo usar este hat si estás usando un disco SSD conectado a los puertos usb, si no es a través de un hub, debido a los picos de corriente que genera provocando desconexiones y problemas en los mismos. En este tutorial, aprenderemos a configurar un sistema de alerta crítica. Si tu conexión a [&#8230;]]]></description>
										<content:encoded><![CDATA[
<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Nota, no recomiendo usar este hat si estás usando un disco SSD conectado a los puertos usb, si no es a través de un hub, debido a los picos de corriente que genera provocando desconexiones y problemas en los mismos.</p>
</blockquote>



<p>En este tutorial, aprenderemos a configurar un sistema de alerta crítica. Si tu conexión a internet falla —ya sea por una avería de tu proveedor (ISP) o un fallo en tu propio router—, la Raspberry Pi detectará la caída de inmediato, <strong>te avisará mediante una llamada telefónica</strong> y te reportará via Telegram cuando la red sea restablecida.</p>



<p>Para que este sistema sea infalible, no podemos depender de la propia conexión de fibra que estamos monitorizando. Necesitamos una vía de comunicación externa. En este caso práctico, utilizaremos un módulo HAT 4G LTE CAT-1 (A7670E), junta a una <strong>tarjeta SIM M2M</strong> (machine to machine) como las que emplean Vodafone u Orange para alarmas profesionales, ascensores , etc. Estas tarjetas suelen estar <strong>limitadas</strong> a voz o SMS y <strong>no disponen de datos móviles</strong>. Aprovecharemos la <strong>robusta red 2G</strong> para garantizar que, en caso de caída de la conexión de fibra, la Raspberry Pi ejecute una llamada de voz a nuestro teléfono móvil de forma prioritaria.</p>



<figure class="wp-block-image aligncenter size-full is-resized"><img fetchpriority="high" decoding="async" width="800" height="800" src="https://linuxete.duckdns.org/wp-content/uploads/2026/01/hat-4g-lte-cat-1-para-raspberry-pi-a7670e.jpg" alt="" class="wp-image-3568" style="width:364px;height:auto" srcset="https://linuxete.duckdns.org/wp-content/uploads/2026/01/hat-4g-lte-cat-1-para-raspberry-pi-a7670e.jpg 800w, https://linuxete.duckdns.org/wp-content/uploads/2026/01/hat-4g-lte-cat-1-para-raspberry-pi-a7670e-300x300.jpg 300w, https://linuxete.duckdns.org/wp-content/uploads/2026/01/hat-4g-lte-cat-1-para-raspberry-pi-a7670e-150x150.jpg 150w, https://linuxete.duckdns.org/wp-content/uploads/2026/01/hat-4g-lte-cat-1-para-raspberry-pi-a7670e-768x768.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /></figure>



<p><strong>¿Por qué es importante este sistema?</strong> Si confías en la domótica para la seguridad de tu hogar (alarmas, detectores de inundación o cámaras), una caída de la red, te deja «a ciegas». Saber que tu red ha caído en tiempo real te permite reaccionar antes de que sea tarde.</p>



<p>¿Cómo funciona el flujo de trabajo?</p>



<ol start="1" class="wp-block-list">
<li><strong>Monitorización:</strong> La Raspberry Pi realiza «pings» constantes a servidores externos (como los DNS de Google o Cloudflare).</li>



<li><strong>Detección:</strong> Si el ping falla de forma consecutiva, el script activa el módulo A7670E.</li>



<li><strong>Alerta:</strong> El HAT ejecuta el comando AT de llamada y marca tu número de teléfono.</li>



<li><strong>Acción:</strong> Recibes la llamada y sabes, al instante, que algo va mal en casa.</li>
</ol>



<h2 class="wp-block-heading">Prepara el software de tu Raspberry.</h2>



<p>Para entrar a las funciones del HAT necesitaremos instalar el programa minicom.</p>



<pre class="wp-block-code"><code>sudo apt-get install minicom</code></pre>



<p>Para que nuestro script funcione, necesitas instalar la librería Python Serial:</p>



<pre class="wp-block-code"><code><code>sudo apt-get install python3-serial -y</code></code></pre>



<p>Por alguna extraña razón, (que solo he podido observar en Raspberry Pi, ModemManager no se lleva bien con este HAT, intenta secuestrarlo constantemente, como si fuese un módem de los antiguos.</p>



<p>Por eso motivo, ya que no será necesario, optaré por desinstalarlo con:</p>



<pre id="block-14c1177c-0d94-499d-9667-d03e8388d140" class="wp-block-preformatted">sudo apt-get purge modemmanager -y</pre>



<h3 class="wp-block-heading">Permisos del usuario.</h3>



<p>Tu usuario debe de tener permiso para usar el puerto serie (el módem) por defecto. Si no es así, el script intentará abrir el puerto y al no conseguirlo, se quedará esperando una respuesta que el sistema le bloqueará y no llegará a marcar.</p>



<p>Teclea el siguiente comando para ver los grupos a los que pertenece tu usuario.</p>



<pre class="wp-block-code"><code>groups</code></pre>



<p>Comprueba que tu usuario pertenece al grupo «dialout», si no es así, deberás agregarlo con este comando:</p>



<pre class="wp-block-code"><code>sudo usermod -a -G dialout <mark style="background-color:#7bdcb5" class="has-inline-color">tu_usuario</mark></code></pre>



<p>Tras ejecutar este comando, <strong>reinicia</strong> tu Raspberry</p>



<pre class="wp-block-code"><code>sudo reboot</code></pre>



<h4 class="wp-block-heading">Forzar el modo de alta corriente (Si tu fuente es MUY buena)</h4>



<p>En una Raspberry pi 4 es algo común, que si usas varios dispositivos conectados a los puertos USB, Pines GPIO, etc, sufras de cuelgues del sistema y se te queden tus proyectos mas tiesos que la mojama. </p>



<p>Si tienes la fuente oficial de 3A (o una mejor), puedes intentar decirle a la Pi que desbloquee el límite de los USB, aunque esto es automático hasta cierto punto, a veces ayuda asegurar el voltaje. Sin embargo, hay un detalle técnico importante: en la Raspberry Pi 4, el límite de corriente de los USB está fijado por hardware a <strong>1.2A compartidos</strong>.</p>



<p>Pero, para «darle chicha» y asegurar que el sistema no entre en pánico cuando el SSD y el HAT 4G trabajen juntos, vamos a aplicar dos ajustes de «estabilidad máxima» que debes tener en cuenta.</p>



<h5 class="wp-block-heading">1. Evitar el «ahorro de energía» del USB (El culpable del bloqueo)</h5>



<p>Cuando el SSD y el HAT piden energía a la vez, el kernel de Linux puede intentar suspender el puerto USB para protegerse, y ahí es donde se congela la Pi. Vamos a prohibirle que lo haga.</p>



<p>Ejecuta este comando para editar el archivo de arranque:</p>



<pre class="wp-block-code"><code>sudo nano /boot/firmware/cmdline.txt</code></pre>



<p>Al final de la línea de texto (sin pulsar Enter, todo en la misma línea), añade un espacio y esto:</p>



<pre class="wp-block-code"><code>usbcore.autosuspend=-1</code></pre>



<h5 class="wp-block-heading">2. Estabilidad de Voltaje (Config.txt)</h5>



<p>Vamos a añadir un parámetro para que la CPU no baje su rendimiento bruscamente cuando detecte picos de consumo del USB, lo que evita que se cuelgue el sistema.</p>



<p>Edita el archivo de configuración:</p>



<pre class="wp-block-code"><code>sudo nano /boot/firmware/config.txt</code></pre>



<p>Añade estas líneas al final:</p>



<pre class="wp-block-code"><code># Forzar estabilidad de voltaje en puertos USB
avoid_warnings=1</code></pre>



<h2 class="wp-block-heading">El Hardware: HAT 4G LTE CAT-1 (A7670E)</h2>



<p>El <strong>HAT 4G LTE CAT-1 para Raspberry Pi (Modelo A7670E)</strong>, es un módulo compacto pero extremadamente versátil capaz de:</p>



<ul class="wp-block-list">
<li>Realizar y recibir llamadas de voz.</li>



<li>Enviar y recibir SMS.</li>



<li>Navegar por internet mediante 4G.</li>



<li>Obtener datos de GPS</li>
</ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Nota: A partir de este momento, no es necesario tener conectado el cable USB al Módulo 4G, tan solo debe de estar conectado a los pines GPIO</p>
</blockquote>



<h3 class="wp-block-heading">Configurar la Raspberry para usar su puerto serie interno</h3>



<p>Por defecto, la Raspberry usa sus pines de transmisión para la «consola» (donde ves letras al arrancar). Hay que liberarlo:</p>



<ol start="1" class="wp-block-list">
<li>Ejecuta:<br><code><mark style="background-color:var(--ast-global-color-7)" class="has-inline-color">sudo raspi-config</mark></code></li>



<li>Ve a <strong>Interface Options</strong> -&gt; <strong>Serial Port</strong>.</li>



<li>¿Deseas que la consola sea accesible por serie? <strong>NO</strong>.</li>



<li>¿Deseas que el hardware del puerto serie esté habilitado? <strong>SÍ</strong>.</li>



<li>Reinicia la Raspberry.</li>
</ol>



<h4 class="wp-block-heading">Localizar el nuevo puerto</h4>



<p>Una vez iniciado el sistema, vuelve a ingresar a la terminal para que podamos entrar por el puerto físico de los pines de la Raspberry, que suele ser <code>/dev/ttyS0</code></p>



<pre class="wp-block-code"><code>sudo minicom -D /dev/ttyS0 -b 115200</code></pre>



<p>Si todo va bien, entrarás a la terminal de configuración del módulo. Ahora, debemos comprobar el modo de funcionamiento en el que se encuentra el HAT 4G.</p>



<h4 class="wp-block-heading">La terminal del módulo 4G</h4>



<p>Ahora que estás en la terminal de programación del módulo, escribe el siguiente comando.</p>



<pre class="wp-block-code"><code>AT$MYCONFIG?</code></pre>



<p>Si nos devuelve <strong><code>"usbnetmode"2</code></strong>, es porque el módulo está en modo <strong>Serial(modén)</strong> que es justo lo que necesitamos.</p>



<p>Pero, si nos devuelve <strong><code>"usbnetmode",0</code></strong>, es porque el módulo está en modo <strong>RNDIS (Red)</strong> y deberemos desactivarlo.</p>



<h3 class="wp-block-heading">Cómo desactivar RNDIS</h3>



<p><em>«Muchos tutoriales te obligan a usar el modo RNDIS, pero si tu objetivo es enviar alertas mediante llamadas, el modo <strong>Serie (usbnetmode,2)</strong> es el secreto para una estabilidad del 100% en placas Raspberry Pi, evitando conflictos de red innecesarios.»</em></p>



<p>Para dejarlo en modo <strong>«serie»</strong>, que es el la opción indicada para hacer solo llamadas perdidas desde la Raspberry Pi 4, ejecuta esta secuencia exacta en tu terminal:</p>



<ol start="1" class="wp-block-list">
<li><strong>Cambia al modo 2 (Modem/Serie):</strong><br><code><mark style="background-color:var(--ast-global-color-7)" class="has-inline-color">AT$MYCONFIG="usbnetmode",2</mark></code></li>



<li><strong>Desactiva el intento de marcación automática:</strong><br><code><mark style="background-color:var(--ast-global-color-7)" class="has-inline-color">AT+DIALMODE=1</mark></code></li>



<li><strong>Guarda los cambios en la memoria interna (Flash):</strong><br><code><mark style="background-color:var(--ast-global-color-7)" class="has-inline-color">AT&amp;W</mark></code></li>



<li><strong>Reinicia el módulo para que aplique los cambios:</strong><br><code><mark style="background-color:var(--ast-global-color-7)" class="has-inline-color">AT+CRESET</mark></code></li>
</ol>



<p>Para salir del terminal del HAT 4G pulsa Ctrl + A y luego Q y volverás a la terminal de Linux.</p>



<h2 class="wp-block-heading">EL Script</h2>



<p>Tras varias pruebas, este script en su versión 4.7, es una solución de monitorización en lenguaje Python, diseñada para informar cuando tu conexión de internet principal falla.</p>



<p>Crea un archivo llamado <code>netguard.py</code></p>



<pre class="wp-block-code"><code>nano netguard.py</code></pre>



<p>Pega el siguiente código.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>No olvides sustituir tu número de <strong>teléfono, </strong>tu<strong> Token </strong>de<strong> Telegram </strong>y tu<strong> ID </strong>de<strong> Telegram.</strong></p>
</blockquote>



<pre class="wp-block-code"><code>import os
import time
import serial
import subprocess
import requests
import sys

# --- CONFIGURACIÓN ---
TELEFONO = "<mark style="background-color:#7bdcb5" class="has-inline-color">600000000</mark>"
PUERTO_MODEM = "/dev/serial0"
INTERFAZ_FIBRA = "eth0"
TOKEN_TELEGRAM = "<mark style="background-color:#7bdcb5" class="has-inline-color">Tu_Token</mark>"
ID_CHAT = "<mark style="background-color:#7bdcb5" class="has-inline-color">Tu_ID</mark>"

fibra_estaba_caida = False
llamada_realizada_con_exito = False

def comprobar_fibra():
    try:
        resultado = subprocess.run(
            &#91;"ping", "-I", INTERFAZ_FIBRA, "-c", "2", "-W", "3", "1.1.1.1"],
            stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
        )
        return resultado.returncode == 0
    except:
        return False

def inicializar_modem(ser):
    """Configuración inicial recomendada para A7670E"""
    comandos = &#91;
        b"AT+CMEE=2\r\n",      # Errores verbosos
        b"AT+CRC=1\r\n",       # Resultados extendidos (útil)
        b"AT+COLP=1\r\n",      # Muestra número cuando contestan (opcional)
        b"AT+CVHU=0\r\n",      # Modo hangup correcto
        b"AT+CLCC=1\r\n",      # (no siempre necesario pero no hace daño)
    ]
    for cmd in comandos:
        ser.write(cmd)
        time.sleep(0.4)
        ser.read_all()  # descartar respuesta

def realizar_llamada_perdida():
    ser = None
    try:
        print(f"\n&#91;{time.strftime('%H:%M:%S')}] ALERTA: Sin internet → Iniciando llamada perdida...", flush=True)
        
        ser = serial.Serial(PUERTO_MODEM, 115200, timeout=1)
        inicializar_modem(ser)

        # Limpieza completa
        ser.reset_input_buffer()
        ser.reset_output_buffer()

        # Registro en red (mejor usar CEREG para LTE, pero CREG también funciona)
        print(" &#91;+] Esperando cobertura...", flush=True)
        for i in range(30):
            ser.write(b"AT+CREG?\r\n")
            time.sleep(1)
            resp = ser.read_all().decode(errors='ignore')
            if ",1" in resp or ",5" in resp:
                print(f" &#91;+] Registrado en red (intento {i+1})", flush=True)
                break
            print(f" &#91;...] Buscando torre... ({i+1}/30)", flush=True)
        else:
            print(" &#91;!] Sin cobertura. Reiniciando módulo...", flush=True)
            ser.write(b"AT+CFUN=1,1\r\n")
            return False

        # Colgar cualquier llamada residual
        ser.write(b"AT+CHUP\r\n")
        time.sleep(0.8)
        ser.read_all()

        # MARCAR
        print(f" &#x1f4de; Marcando a {TELEFONO}...", flush=True)
        ser.write(f"ATD{TELEFONO};\r\n".encode())
        time.sleep(1.5)  # esperar OK + VOICE CALL: BEGIN

        print(" &#91;?] Llamada en curso. Esperando que cuelgues (máx 45s)...", flush=True)

        timeout = time.time() + 45
        llamada_activa = False

        while time.time() &lt; timeout:
            # Polling CLCC + lectura de URCs
            ser.write(b"AT+CLCC\r\n")
            time.sleep(0.7)
            resp = ser.read_all().decode(errors='ignore').strip()

            # URC directo del módulo (lo más fiable)
            if "VOICE CALL: END" in resp:
                print(" &#x2705; Colgado detectado por URC 'VOICE CALL: END'", flush=True)
                return True

            # CLCC desapareció → colgado por receptor
            if "+CLCC:" in resp:
                llamada_activa = True
                print(" → Sonando / activa", flush=True)
            elif llamada_activa and "+CLCC:" not in resp and "OK" in resp:
                print(" &#x2705; Colgado detectado: CLCC desapareció", flush=True)
                return True

            # Backup: NO CARRIER
            if "NO CARRIER" in resp:
                print(" &#x2705; Colgado por NO CARRIER", flush=True)
                return True

        # Timeout → colgamos nosotros
        print(" &#x23f0; Timeout → colgando forzosamente", flush=True)
        ser.write(b"AT+CHUP\r\n")
        return False

    except Exception as e:
        print(f" &#91;!] Error serie: {e}", flush=True)
        return False
    finally:
        if ser and ser.is_open:
            ser.close()

# --- BUCLE PRINCIPAL ---
print("--- Vigilante M2M v5.7 (A7670E optimizado) ---", flush=True)

while True:
    hay_internet = comprobar_fibra()

    if not hay_internet:
        if not fibra_estaba_caida:
            print(f"&#91;{time.strftime('%H:%M:%S')}] Caída de fibra detectada.", flush=True)
            time.sleep(5)
            if not comprobar_fibra():  # doble chequeo
                fibra_estaba_caida = True
                if realizar_llamada_perdida():
                    llamada_realizada_con_exito = True
                else:
                    time.sleep(30)  # reintentar más lento si falló

        elif not llamada_realizada_con_exito:
            if realizar_llamada_perdida():
                llamada_realizada_con_exito = True
            else:
                time.sleep(60)

    elif hay_internet and fibra_estaba_caida:
        print(f"&#91;{time.strftime('%H:%M:%S')}] &#x2705; Fibra recuperada. Avisando por Telegram...", flush=True)
        try:
            requests.post(
                f"https://api.telegram.org/bot{TOKEN_TELEGRAM}/sendMessage",
                data={"chat_id": ID_CHAT, "text": "&#x2705; Fibra recuperada"},
                timeout=10
            )
        except:
            pass
        fibra_estaba_caida = False
        llamada_realizada_con_exito = False

    time.sleep(20)
</code></pre>



<p>Para guardar pulsa Ctrl + o y  Ctrl + x para salir</p>



<p>No olvides hacerlo ejecutable con:</p>



<pre class="wp-block-code"><code>chmod +x netguard.py</code></pre>



<h4 class="wp-block-heading">¿Cómo funciona el script?</h4>



<p>El programa actúa como un centinela que vigila la interfaz de fibra (<code>eth0</code>) cada 20 segundos mediante pings ligeros. Su inteligencia reside en cómo gestiona las alertas:</p>



<ol start="1" class="wp-block-list">
<li>El script actúa como un centinela incansable que vigila la interfaz de fibra (eth0) cada 20 segundos mediante pings ligeros. Su inteligencia reside en cómo gestiona las alertas de forma robusta y eficiente, aprovechando al máximo las capacidades del módulo A7670E (según el manual oficial SIMCom A76XX v1.09):</li>



<li><strong>Paciencia de Registro (mejorada):</strong> No marca a ciegas. Primero interroga al módem con AT+CREG? para confirmar cobertura real (registrado en red roaming o home). Realiza hasta <strong>30 intentos</strong> (más margen que antes), con pausas de 1 segundo, dando tiempo al hardware para sincronizarse con la torre más cercana. Si falla tras los intentos, fuerza un reinicio profundo del módulo (AT+CFUN=1,1) para «despertarlo» y buscar señal de nuevo.</li>



<li><strong>Inicialización Proactiva del Módem:</strong> Antes de cualquier operación crítica, envía comandos de configuración recomendados por SIMCom: AT+CMEE=2 (errores verbosos), AT+CRC=1 (resultados extendidos), AT+COLP=1 (muestra número al contestar, opcional), AT+CVHU=0 (modo colgado correcto). Esto evita errores comunes y mejora la fiabilidad.</li>



<li><strong>Detección Inteligente de Colgado (el gran salto):</strong> La clave de v5.7 es la detección <strong>proactiva y prioritaria</strong> usando URCs nativos del módulo:
<ul class="wp-block-list">
<li>Tras ATD&lt;numero>;, el módem envía automáticamente VOICE CALL: BEGIN cuando empieza a sonar.</li>



<li>Mientras la llamada está activa, polling frecuente con AT+CLCC para ver si sigue en lista (+CLCC: presente).</li>



<li><strong>Cuando cuelgas desde tu móvil</strong>, llega el URC VOICE CALL: END → detección inmediata y casi infalible.</li>



<li>Fallbacks: si CLCC desaparece tras haber estado activo, o aparece NO CARRIER.</li>



<li>Timeout máximo de <strong>45 segundos</strong> (más que suficiente para llamada perdida) → fuerza AT+CHUP si no cuelgas, evitando bloqueos eternos.</li>
</ul>
</li>



<li><strong>Flush=True, Timeouts y Limpieza de Buffers:</strong> Todas las impresiones usan flush=True para logs inmediatos en journalctl. Las lecturas/escrituras serie tienen timeout=1 y se limpian buffers (reset_input_buffer()) antes y después de comandos clave. Nada se queda «colgado».</li>



<li><strong>Reintento Inteligente y Persistencia Educada:</strong> Si la llamada falla (sin cobertura, timeout, etc.), el script reintenta en el siguiente ciclo de vigilancia (cada ~20-60 s según estado). Pero una vez que logra que tu móvil suene con éxito (colgado detectado), marca llamada_realizada_con_exito = True y <strong>deja de llamar</strong> hasta que la fibra se recupere. Así evita saturar tu línea o gastar saldo innecesario.</li>



<li><strong>Informe de Retorno por Telegram:</strong> Tras la alerta por voz, el script entra en modo «escucha». En cuanto detecta que la fibra ha vuelto (doble chequeo ping para evitar falsos positivos), envía mensaje por Telegram: «<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Fibra recuperada». Así sabes no solo la caída, sino también el momento exacto de recuperación.</li>
</ol>



<p>Ademas:</p>



<ol start="1" class="wp-block-list">
<li>Doble verificación de caída (ping + 5 s espera + segundo ping) antes de alertar.</li>



<li>Logs limpios: imprime solo lo esencial (puedes reducir aún más los «→ Sonando / activa» editando el contador).</li>



<li>Manejo de excepciones y cierre seguro del puerto serie (finally con ser.close()).</li>
</ol>



<p>En resumen: v5.7 es más fiable, rápida en detección y respetuosa con tu móvil y saldo, gracias a los URC nativos y la configuración proactiva del módulo.</p>



<h4 class="wp-block-heading">Lanza tu script a ver que ocurre.</h4>



<pre class="wp-block-code"><code>python3 netguard.py</code></pre>



<h2 class="wp-block-heading">Crea el archivo del servicio.</h2>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>«Haciéndolo Robusto: Creando un Servicio en Systemd»</strong> <em>«Un vigilante no sirve de nada si tienes que arrancarlo a mano. Al convertir nuestro script en un servicio de Linux, garantizamos que la vigilancia sea 24/7, incluso si hay un apagón y la Raspberry se reinicia sola. El sistema se encarga de que el script esté siempre vivo.»</em></p>
</blockquote>



<p>Para que este script sea realmente autónomo, debería arrancar al inicio del sistema y si falla o se cierra por un error inesperado, Linux lo reinicia automáticamente en pocos segundos.</p>



<p>Lo ideal es crear un <strong>servicio en el sistema (Systemd)</strong>.</p>



<p>Ejecuta este comando para crear el archivo de configuración:</p>



<pre class="wp-block-code"><code>sudo nano /etc/systemd/system/netguard.service</code></pre>



<p>Copia y pega este contenido (asegúrate de que la ruta <code>/home/tu_usuario/netguard.py</code> sea la correcta donde guardaste el script):</p>



<pre class="wp-block-code"><code>&#91;Unit]
Description=Servicio Vigilante de Fibra por GSM
After=network.target

&#91;Service]
# Fuerza a Python a no guardar nada en memoria intermedia
Environment=PYTHONUNBUFFERED=1
ExecStart=/usr/bin/python3 -u /home/<mark style="background-color:#7bdcb5" class="has-inline-color">tu_usuario</mark>/netguard.py
WorkingDirectory=/home/<mark style="background-color:#7bdcb5" class="has-inline-color">tu_usuario</mark>
User=<mark style="background-color:#7bdcb5" class="has-inline-color">tu_usuario</mark>
# El grupo dialout es clave para que el usuario tenga permiso al módem
Group=dialout
Restart=always
RestartSec=10

# Estas líneas aseguran que Systemd vuelque todo al journal al instante
StandardOutput=journal
StandardError=journal
TTYPath=/dev/ttyS0

&#91;Install]
WantedBy=multi-user.target
</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>Nota: Cambia <mark style="background-color:#7bdcb5" class="has-inline-color">tu_usuario</mark></em> por el tuyo propio.</p>
</blockquote>



<h4 class="wp-block-heading">Activar y arrancar el servicio</h4>



<p>Ahora dale las órdenes a la Raspberry para que lo ponga en marcha:</p>



<pre class="wp-block-code"><code># Recargar el sistema para que vea el nuevo servicio
sudo systemctl daemon-reload

# Activar para que arranque siempre al encender la Pi
sudo systemctl enable netguard.service

# Arrancar el servicio ahora mismo
sudo systemctl start netguard.service</code></pre>



<h4 class="wp-block-heading">¿Cómo saber si está funcionando?</h4>



<p>Puedes ver el estado del vigilante en tiempo real con este comando:</p>



<pre class="wp-block-code"><code>sudo systemctl status netguard.service</code></pre>



<p>Y si quieres ver los «logs» (lo que el script va imprimiendo):</p>



<pre class="wp-block-code"><code>journalctl -u netguard.service -f</code></pre>



<p>Un ejemplo tras varios dias de funcionamiento del script.</p>



<pre class="wp-block-code"><code>tu_usurio@raspberrypi:~ $ <strong>journalctl -u netguard.service -f</strong>
mar 01 15:53:48 tu_host python3&#91;3651558]: --- Vigilante M2M v5.7 (A7670E optimizado) ---
mar 01 15:54:13 tu_host python3&#91;3651558]: &#91;15:54:13] Caída de fibra detectada.
mar 01 15:54:22 tu_host python3&#91;3651558]: &#91;15:54:22] ALERTA: Sin internet → Iniciando llamada perdida...
mar 01 15:54:24 tu_host python3&#91;3651558]:  &#91;+] Esperando cobertura...
mar 01 15:54:25 tu_host python3&#91;3651558]:  &#91;+] Registrado en red (intento 1)
mar 01 15:54:25 tu_host python3&#91;3651558]:  &#x1f4de; Marcando a 600000000...
mar 01 15:54:27 tu_host python3&#91;3651558]:  &#91;?] Llamada en curso. Esperando que cuelgues (máx 45s)...
mar 01 15:54:28 tu_host python3&#91;3651558]:  → Sonando / activa
mar 01 15:54:28 tu_host python3&#91;3651558]:  → Sonando / activa
mar 01 15:54:29 tu_host python3&#91;3651558]:  → Sonando / activa
mar 01 15:54:30 tu_host python3&#91;3651558]:  → Sonando / activa
mar 01 15:54:30 tu_host python3&#91;3651558]:  → Sonando / activa
mar 01 15:54:31 tu_host python3&#91;3651558]:  → Sonando / activa
mar 01 15:55:00 tu_host python3&#91;3651558]:  &#x2705; Colgado detectado por URC 'VOICE CALL: END'
mar 01 15:55:21 tu_host python3&#91;3651558]: &#91;15:55:21] &#x2705; Fibra recuperada. Avisando por Telegram...

</code></pre>



<h2 class="wp-block-heading">Troubleshooting (solución de problemas)</h2>



<p>Si tu sistema sigue experimentando cuelgues o hace cosas extrañas cuando intenta hacer una llamada, prueba a usar un Hub USB con alimentación propia (La más segura). Conecta el SSD a un Hub USB que tenga su propia fuente de alimentación. Así, la energía para mover el módulo la da el Hub y no la Raspberry. La Pi solo se encarga de los datos. Por lo que, lo más efectivo es <strong>separar el consumo</strong>.</p>



<h2 class="wp-block-heading">Prueba final:</h2>



<p>Una vez que esté todo funcionando.</p>



<ol start="1" class="wp-block-list">
<li>Desconecta el cable <em>Ethernet</em> para provocar una llamada.</li>



<li>Abre abre una terminal y escribe <br><code><mark style="background-color:var(--ast-global-color-7)" class="has-inline-color">ls -R /</mark></code></li>



<li>Si ya no se bloquea, es que la fuente de la Pi 5 y el comando <code>autosuspend=-1</code> han solucionado el conflicto de energía.</li>
</ol>



<p></p>



<h2 class="wp-block-heading">Miscelánea</h2>



<p>Estos son los comandos clave para extraer estadísticas y gestionar tu Vigilante como un auténtico administrador de sistemas.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">1. El «Resumen de Batalla» (Estadísticas rápidas)</h3>



<p>Si quieres saber cuántas veces se ha caído la fibra o cuántas llamadas ha hecho el script sin leer miles de líneas, usa este comando. Filtrará el log y te dará solo los hitos importantes:</p>



<pre class="wp-block-code"><code>journalctl -u netguard.service | grep -E "Caída detectada|Llamada finalizada|Red recuperada"</code></pre>



<p><em>Esto te mostrará una lista limpia con los días y horas exactas de cada incidente.</em></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2. Comprobar el estado del «Motor»</h3>



<p>Si alguna vez dudas de si el script sigue vivo (aunque ya hemos visto que es eterno), este comando te da el informe de salud de Systemd:</p>



<pre class="wp-block-code"><code>systemctl status netguard.service</code></pre>



<p><em>Fíjate en la línea que dice <code>Active: active (running) since...</code>. Te dirá cuántos días lleva encendido sin interrupciones.</em></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3. Reiniciar tras cambios (SIM, teléfono, etc.)</h3>



<p>Si decides cambiar el número de teléfono o el token de Telegram en el archivo <code>.py</code>, no basta con guardar el archivo. Tienes que decirle a la Raspberry que cargue la nueva versión:</p>



<pre class="wp-block-code"><code>sudo systemctl restart netguard.service</code></pre>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxete.duckdns.org/tutorial-failover-en-raspberry-pi-mediante-llamada-telefonica/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Control inteligente de la refrigeración de mi Raspberry Pi 4.</title>
		<link>https://linuxete.duckdns.org/control-inteligente-de-la-refrigeracion-de-mi-raspberry-pi-4/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=control-inteligente-de-la-refrigeracion-de-mi-raspberry-pi-4</link>
					<comments>https://linuxete.duckdns.org/control-inteligente-de-la-refrigeracion-de-mi-raspberry-pi-4/#comments</comments>
		
		<dc:creator><![CDATA[raspberry]]></dc:creator>
		<pubDate>Sat, 10 Jan 2026 19:03:53 +0000</pubDate>
				<category><![CDATA[Raspberry PI]]></category>
		<category><![CDATA[control ventilador raspberry]]></category>
		<category><![CDATA[fan raspberry pi 4]]></category>
		<category><![CDATA[ventilador raspberry]]></category>
		<guid isPermaLink="false">https://linuxete.duckdns.org/?p=3666</guid>

					<description><![CDATA[La Raspberry Pi 4, si la dejas trabajar duro, puede ponerse mas caliente que un «Amego Segarro» en una feria. Su procesador puede alcanzar temperaturas que activan el thermal throttling, reduciendo su velocidad para no «derretirse». Es fundamental entender que el procesador empieza a reducir su velocidad automáticamente cuando llega a los 80°C &#8211; 85°C [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image aligncenter size-full is-resized"><img decoding="async" width="1000" height="1000" src="https://linuxete.duckdns.org/wp-content/uploads/2024/04/51nl7x3rx-S._SL1000_.jpg" alt="" class="wp-image-1235" style="width:328px;height:auto" srcset="https://linuxete.duckdns.org/wp-content/uploads/2024/04/51nl7x3rx-S._SL1000_.jpg 1000w, https://linuxete.duckdns.org/wp-content/uploads/2024/04/51nl7x3rx-S._SL1000_-300x300.jpg 300w, https://linuxete.duckdns.org/wp-content/uploads/2024/04/51nl7x3rx-S._SL1000_-150x150.jpg 150w, https://linuxete.duckdns.org/wp-content/uploads/2024/04/51nl7x3rx-S._SL1000_-768x768.jpg 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></figure>



<p>La <strong>Raspberry Pi 4</strong>, si la dejas trabajar duro, puede ponerse mas caliente que un «Amego Segarro» en una feria. Su procesador puede alcanzar temperaturas que activan el <em>thermal throttling</em>, reduciendo su velocidad para no «derretirse». Es fundamental entender que el procesador empieza a reducir su velocidad automáticamente cuando llega a los <strong>80°C &#8211; 85°C</strong> para protegerse.</p>



<p>Muchos optan por conectar un ventilador directamente a los pines de 5V, lo cual funciona, pero tiene dos grandes problemas: el ruido constante (¡parece un avión despegando!) y el desgaste innecesario del motor.</p>



<p>En esta entrada, vamos a hacer algo mucho más elegante y profesional. Vamos a configurar un <strong>sistema de control por PWM (Modulación por Ancho de Pulsos)</strong> utilizando el tercer cable de nuestro ventilador. ¿Qué conseguiremos con esto?</p>



<ul class="wp-block-list">
<li><strong>Silencio absoluto:</strong> El ventilador solo girará lo necesario.</li>



<li><strong>Inteligencia térmica:</strong> Crearemos un script en Python que «lee» la mente (y la temperatura) de la CPU.</li>



<li><strong>Automatización total:</strong> Configuraremos un servicio en Linux para que el control sea eterno y arranque solo.</li>



<li><strong>Protección de hardware:</strong> Evitaremos forzar los pines de la placa con una configuración segura.</li>
</ul>



<p>Si quieres que tu Pi 4 esté siempre fresca sin sacrificar tus oídos, ¡acompáñame en este tutorial!</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Conexión del ventilador</h2>



<p>Un ventilador PWM (Modulación por Ancho de Pulsos) se compone de 3 cables, esto significa que no solo puedes encenderlo o apagarlo, sino que puedes regular su velocidad (por ejemplo, que gire al 40% si está a 45°C y al 100% si llega a 60°C).</p>



<p>La función de cada cable es:</p>



<ol start="1" class="wp-block-list">
<li><strong>Rojo</strong> a un pin de <strong>5V</strong> positivo. (Pin 2 o 4). Aquí toma la fuerza.</li>



<li><strong>Negro</strong> a un pin <strong>GND</strong> negativo. (Pin 6).</li>



<li><strong>Azul</strong>  (PWM) por ejemplo, pin 18  (GPIO 24).</li>
</ol>



<figure class="wp-block-image aligncenter size-full is-resized"><img decoding="async" width="1280" height="721" src="https://linuxete.duckdns.org/wp-content/uploads/2024/04/photo_2024-04-07_10-39-29.jpg" alt="" class="wp-image-1238" style="aspect-ratio:1.775316412833578;width:510px;height:auto" srcset="https://linuxete.duckdns.org/wp-content/uploads/2024/04/photo_2024-04-07_10-39-29.jpg 1280w, https://linuxete.duckdns.org/wp-content/uploads/2024/04/photo_2024-04-07_10-39-29-300x169.jpg 300w, https://linuxete.duckdns.org/wp-content/uploads/2024/04/photo_2024-04-07_10-39-29-1024x577.jpg 1024w, https://linuxete.duckdns.org/wp-content/uploads/2024/04/photo_2024-04-07_10-39-29-768x433.jpg 768w" sizes="(max-width: 1280px) 100vw, 1280px" /></figure>



<p>Como se ve en la imagen anterior, <strong>No, se necesita resistencia</strong>, ya que el cable azul solo recibe una «señal» de control de muy baja intensidad (lógica), el procesador de la Raspberry no sufre. El transistor ya viene integrado dentro del propio ventilador para gestionar esa señal.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Nota: Algunos ventiladores baratos de 3 cables no soportan PWM por el tercer cable (a veces el tercer cable es solo un sensor de revoluciones, no de control). <br>&#8211; <strong>Si el ventilador baja de velocidad:</strong> ¡Perfecto! Todo funciona.<br><strong>&#8211; Si el ventilador solo está encendido o apagado:</strong> Significa que tu cable azul es un sensor «Tacho» y no admite control de velocidad. En ese caso, el script funcionará a todo o nada. (ON/OFF).</p>
</blockquote>



<h2 class="wp-block-heading">El script.</h2>



<p>Con este script, tu Raspberry Pi 4 tendrá un comportamiento idéntico al ventilador de un ordenador portátil moderno. Este no solo enciende o apaga, sino que hace que el ventilador «susurre» cuando hay poca temperatura y «sople» fuerte solo cuando es necesario.</p>



<p>Script<strong> (Edición PWM)</strong></p>



<p>Copia y pega el siguiente script en un archivo llamado fanGuard.py</p>



<pre class="wp-block-code"><code>nano fanGuard.py</code></pre>



<pre class="wp-block-code"><code>#!/usr/bin/python3
import RPi.GPIO as GPIO
import time
import subprocess
import sys
from datetime import datetime

# ==========================================
# CONFIGURACIÓN PROPORCIONAL PRO
# ==========================================
PIN_FAN        = 18
FRECUENCIA     = 100
ESPERA         = 3

TEMP_ARRANQUE  = 50
TEMP_MAXIMA    = 65
TEMP_PARADA    = 39
POTENCIA_MIN   = 40
# ==========================================

def obtener_temp_maxima():
    try:
        with open("/sys/class/thermal/thermal_zone0/temp", "r") as f:
            temp_cpu = float(f.read()) / 1000

        salida_gpu = subprocess.check_output(&#91;"vcgencmd", "measure_temp"]).decode("utf-8")
        temp_gpu = float(salida_gpu.replace("temp=", "").replace("'C\n", ""))

        return max(temp_cpu, temp_gpu)
    except Exception:
        return 55.0

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(PIN_FAN, GPIO.OUT)
pwm = GPIO.PWM(PIN_FAN, FRECUENCIA)
pwm.start(0)

ventilador_activo = False

print("=============================================")
print("  FAN GUARD PRO: CPU + GPU MONITOR  ")
print(f"  Arranque: {TEMP_ARRANQUE}C | Parada: {TEMP_PARADA}C")
print("=============================================")

try:
    while True:
        temp = obtener_temp_maxima()
        ahora = datetime.now().strftime("%H:%M:%S")
        nivel = 0

        if temp &gt;= TEMP_ARRANQUE:
            ventilador_activo = True
        elif temp &lt;= TEMP_PARADA:
            ventilador_activo = False

        if ventilador_activo:
            if temp &gt;= TEMP_MAXIMA:
                nivel = 100
            elif temp &lt;= TEMP_ARRANQUE:
                nivel = POTENCIA_MIN
            else:
                dif_temp = temp - TEMP_ARRANQUE
                rango_temp = TEMP_MAXIMA - TEMP_ARRANQUE
                rango_potencia = 100 - POTENCIA_MIN
                nivel = int(POTENCIA_MIN + (dif_temp * rango_potencia / rango_temp))
        else:
            nivel = 0

        pwm.ChangeDutyCycle(min(max(nivel, 0), 100))

        # Usamos carácteres ASCII compatibles con todas las terminales
        estado = "&#91;ON]" if ventilador_activo else "&#91;OFF]"
        barra = "#" * (nivel // 10) + "-" * (10 - (nivel // 10))

        print(f"&#91;{ahora}] {estado} Temp: {temp:.1f}C | Potencia: &#91;{barra}] {nivel}%")

        time.sleep(ESPERA)

except KeyboardInterrupt:
    print("\nDeteniendo servicio...")
finally:
    pwm.stop()
    GPIO.cleanup()


</code></pre>



<p>Guarda el documento con <code>Ctrl + o</code> y sal con <code>Ctrl + x</code></p>



<p>No olvides hacerlo ejecutable con:</p>



<pre class="wp-block-code"><code>chmod +x fanGuard.py</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Ciclo de funcionamiento.(Configuración 50°C &#8211; 65°C)</h3>



<ol start="1" class="wp-block-list">
<li><strong>Zona de Silencio Total (Hasta 50°C):</strong> El ventilador está en <strong>0% (Apagado)</strong>. Gracias a tu torre de refrigeración, la Raspberry se mantendrá aquí la mayor parte del tiempo (sobre los 45°C-47°C).</li>



<li><strong>El Despertar (A los 50°C):</strong> En cuanto el sensor (CPU o GPU) toca los <strong>50.0°C</strong>, el ventilador arranca directamente al <strong>40% de potencia</strong>. Esto asegura que el aire fluya con fuerza suficiente por las aletas del Ice Tower desde el primer segundo.</li>



<li><strong>Zona Dinámica Proporcional (De 50°C a 65°C):</strong> El script escala la velocidad de forma lineal:
<ul class="wp-block-list">
<li><strong>50°C</strong> &#8212;&#8212;&#8212;&#8212;&#8212;&gt; <strong>40%</strong> (Arranque mínimo).</li>



<li><strong>57.5°C</strong> &#8212;&#8212;&#8212;&#8212;-&gt; <strong>70%</strong> aprox. (Punto medio).</li>



<li><strong>65°C</strong> &#8212;&#8212;&#8212;&#8212;&#8212;&gt; <strong>100%</strong> (Potencia máxima).</li>
</ul>
</li>



<li><strong>La Bajada con Histéresis (El camino de vuelta):</strong> * Si el ventilador está encendido y la temperatura baja de 50°C, <strong>no se apaga</strong>.
<ul class="wp-block-list">
<li>Se mantiene soplando al <strong>40%</strong> de forma constante mientras baja por los 48°C, 45°C&#8230;.</li>



<li>Solo cuando el sensor marca <strong>39°C o menos</strong>, el ventilador se detiene por completo.</li>
</ul>
</li>
</ol>



<h3 class="wp-block-heading">¿Por qué este cambio es mejor para tu caso?</h3>



<p>Con estos margenes de temperaturas, tenemos un margén de maniobra para no castigar en exceso al ventilador, por lo que:</p>



<ul class="wp-block-list">
<li><strong>Evitas el desgaste:</strong> El ventilador gira lo necesario, reduciendo horas de funcionamiento y evitando desgaste del mismo.</li>



<li><strong>Aprovechas el cobre:</strong> Dejas que el disipador trabaje de forma pasiva hasta su límite razonable.</li>



<li><strong>Enfriamiento real:</strong> Cuando arranca a 50°C, lo hace con la misión de bajar hasta los 39°C, asegurando que la placa se quede realmente fresca antes de volver a apagarse.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Tabla resumen de revoluciones (ejemplo estimado):</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><td><strong>Temperatura</strong></td><td><strong>Estado</strong></td><td><strong>Potencia PWM</strong></td><td><strong>Ruido Estimado</strong></td></tr></thead><tbody><tr><td><strong>38°C</strong></td><td>Bajando</td><td>0% (Apagado)</td><td>Silencio total</td></tr><tr><td><strong>46°C</strong></td><td>Subiendo</td><td>0% (Apagado)</td><td>Silencio total</td></tr><tr><td><strong>50°C</strong></td><td><strong>Arranca</strong></td><td><strong>40%</strong></td><td>Susurro suave</td></tr><tr><td><strong>52°C</strong></td><td>Estable</td><td>68%</td><td>Flujo de aire constante</td></tr><tr><td><strong>60°C</strong></td><td>Alerta</td><td>100%</td><td>Máximo soplado</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">¿Cómo saber si los porcentajes son correctos para TU ventilador?</h3>



<p>Cada ventilador es un mundo. Si notas que al 40% hace un ruido eléctrico pero no gira, puedes subir la variable <code>POTENCIA_MIN</code> a <strong>50</strong>. Si por el contrario gira muy fuerte desde el principio, puedes bajarla a <strong>30</strong>.</p>



<p>Para alargar la vida útil de los componentes y mantener el máximo rendimiento, lo ideal es mantenerla <strong>por debajo de los 60°C</strong> en carga de trabajo.</p>



<h3 class="wp-block-heading">Crear el archivo del servicio</h3>



<p>Para hacerlo «eterno» con <code>systemd</code>, tenemos que seguir unos pasos específicos. Es vital que el servicio se ejecute como <strong>root</strong> (para tener permisos sobre los GPIO) y que gestione bien el apagado, evitando que el ventilador no se quede «silbando» cuando detengas la Raspberry.</p>



<p>Abre el editor para crear el archivo de configuración del sistema:</p>



<pre class="wp-block-code"><code>sudo nano /etc/systemd/system/fanguard.service</code></pre>



<h3 class="wp-block-heading">3. Pegar la configuración del servicio</h3>



<p>Copia y pega este bloque tal cual, sustituyendo tu_usuario, por el tuyo propio de la ruta en <code>ExecStart</code>):</p>



<pre class="wp-block-code"><code>&#91;Unit]
Description=Control Inteligente de Ventilador PWM con Histeresis
After=multi-user.target

&#91;Service]
Type=simple
User=root
ExecStart=/usr/bin/python3 -u /home/<mark style="background-color:#7bdcb5" class="has-inline-color">tu_usuario</mark>/fanguard.py
Restart=always
RestartSec=10
# Esto asegura que los prints del script se vean en el log del sistema
StandardOutput=inherit
StandardError=inherit

&#91;Install]
WantedBy=multi-user.target
</code></pre>



<h3 class="wp-block-heading">4. Activar el «Modo Eterno»</h3>



<p>Ahora ejecuta estos comandos en orden para que el sistema reconozca el nuevo servicio y lo arranque:</p>



<ol start="1" class="wp-block-list">
<li><strong>Recargar el sistema:</strong><br><code>sudo systemctl daemon-reload</code></li>



<li><strong>Activar el inicio automático al arrancar:</strong><br><code>sudo systemctl enable fanguard.service</code></li>



<li><strong>Iniciar el ventilador ahora mismo:</strong><br><code>sudo systemctl start fanguard.service</code></li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">¿Cómo puedes vigilar tu ventilador ahora?</h3>



<p>Como el script ahora corre de fondo («eterno»), ya no verás la barrita de carga directamente en la pantalla, pero puedes «espiarlo» con estos comandos:</p>



<ul class="wp-block-list">
<li><strong>Para ver si está vivo y la temperatura actual:</strong><br><code>sudo systemctl status fanguard.service</code></li>



<li><strong>Para ver el funcionamiento en tiempo real (ver los logs):</strong><br><code>journalctl -u fanguard.service -f</code></li>



<li><strong>Si quieres detenerlo para hacer cambios en el script:</strong><br><code>sudo systemctl stop fanguard.service </code><br><em>(Al detenerlo, gracias al bloque <code>finally</code> de tu script, el ventilador se apagará completamente).</em></li>
</ul>



<p>¡Listo! Ya tienes un sistema de refrigeración de grado industrial en tu Raspberry Pi 4.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxete.duckdns.org/control-inteligente-de-la-refrigeracion-de-mi-raspberry-pi-4/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Cómo crear un Watchdog para dispositivos en red.</title>
		<link>https://linuxete.duckdns.org/como-crear-un-watchdog-para-el-hub-tapo-h100-con-raspberry-pi/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=como-crear-un-watchdog-para-el-hub-tapo-h100-con-raspberry-pi</link>
					<comments>https://linuxete.duckdns.org/como-crear-un-watchdog-para-el-hub-tapo-h100-con-raspberry-pi/#respond</comments>
		
		<dc:creator><![CDATA[raspberry]]></dc:creator>
		<pubDate>Tue, 06 Jan 2026 09:57:17 +0000</pubDate>
				<category><![CDATA[Red]]></category>
		<category><![CDATA[Seguridad]]></category>
		<category><![CDATA[watchdog]]></category>
		<category><![CDATA[sensor fugas]]></category>
		<category><![CDATA[sensor inteligente]]></category>
		<category><![CDATA[tapo H100]]></category>
		<category><![CDATA[tapo P100]]></category>
		<category><![CDATA[tapo p110]]></category>
		<category><![CDATA[tapo T300]]></category>
		<guid isPermaLink="false">https://linuxete.duckdns.org/?p=3554</guid>

					<description><![CDATA[Después de haber sufrido una pequeña inundación en el sótano de casa, decidí crear un sistema de alerta y corte de suministro de agua. Para que mi instalación pueda ponerse en contacto conmigo, necesito la ayuda de sensores online que vigilen constantemente si se produce alguna avería. El ecosistema Tapo de TP-Link es excelente por [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Después de haber sufrido una pequeña inundación en el sótano de casa, decidí crear un sistema de alerta y corte de suministro de agua. </p>



<p>Para que mi instalación pueda ponerse en contacto conmigo, necesito la ayuda de sensores online que vigilen constantemente si se produce alguna avería.</p>



<p>El ecosistema Tapo de TP-Link es excelente por su relación calidad-precio, especialmente sus sensores de inundación T300. Sin embargo, tiene un «talón de Aquiles» crítico: <strong>la falta de notificaciones por desconexión</strong>. Si el Hub H100 o el enchufe P100 se apagan, tu sistema de seguridad muere en silencio.</p>



<p>Aquí te explico cómo convertir tu Raspberry Pi en un vigilante activo que te avisará en segundos si algo falla.</p>



<p><strong>El problema: El silencio de los dispositivos offline</strong></p>



<p id="block-dbcce1e7-b3fc-4fff-ad55-facaf6e3522c">Tanto si la centralita H100 (Hub) como el enchufe P100 que controla el cierre de agua, se avería, sufre un pico de tensión o alguien los desenchufa accidentalmente, el sistema se queda «ciego». El sensor de agua T300 no tiene a quién avisar y la orden de corte nunca se ejecuta.</p>



<p id="block-e2c406d9-9459-4324-b879-653848742da5">Lo más preocupante es que <strong>la App de Tapo no envía notificaciones si un dispositivo se queda fuera de línea</strong>. Para darte cuenta del fallo, tendrías que entrar manualmente en la aplicación y revisar el estado de los iconos uno por uno. En una emergencia o durante unas vacaciones, esta falta de aviso proactivo es un fallo de seguridad inaceptable.</p>



<p><strong>La solución: Un «Watchdog» con Raspberry Pi</strong></p>



<p>Para eliminar este punto ciego, utilizaremos una Raspberry Pi como <strong>Watchdog (Perro Guardián)</strong>. En lugar de esperar a que la App nos avise, la Pi interrogará constantemente a los dispositivos en la red local, si estos no responden, la Pi asume que el sistema está comprometido y dispara una alerta externa.</p>



<h2 class="wp-block-heading">1. Prepara tu Telegram.</h2>



<p>Aprovechando que tenemos telegram (si no lo tienes, ya estás tardando en instalarlo) vamos a utilizarlo para que nos lleguen los avisos de alerta de nuestro script. Para ello crearemos un bot, que será el encargado de gestionar los avisos provenientes de nuestra raspberry.</p>



<h3 class="wp-block-heading">Crear tu Bot en Telegram (El Emisor)</h3>



<p>Primero necesitamos crear la «entidad» que enviará los mensajes desde tu Raspberry Pi.</p>



<ol start="1" class="wp-block-list">
<li>Abre <strong>Telegram</strong> y busca al usuario <strong>@BotFather</strong>.</li>



<li>Escribe <code>/newbot</code> y dale a enviar.</li>



<li>Te pedirá un <strong>Nombre</strong> para el bot (ejemplo: <code>Vigilante Sótano</code>).</li>



<li>Te pedirá un <strong>Username</strong> (debe terminar en <code>_bot</code>, ejemplo: <code>mi_sotano_seguro_bot</code>).</li>



<li><strong>BotFather</strong> te responderá con un mensaje largo que contiene el <strong>API Token</strong> (algo parecido a <code>74839201:AAH-u7...</code>). <strong>Copia y guarda este código</strong>, es la clave de acceso.</li>
</ol>



<h3 class="wp-block-heading">Obtener tu Chat ID (El Receptor)</h3>



<p>Ahora necesitamos saber a qué cuenta de Telegram (la tuya) debe escribirle el bot.</p>



<ol start="1" class="wp-block-list">
<li>Busca en Telegram el bot <strong>@userinfobot</strong>.</li>



<li>Escríbele un mensaje cualquiera (ej. «Hola»).</li>



<li>Te responderá con tu <strong>ID</strong> (un número de 9 o 10 dígitos). Guárdalo también.</li>
</ol>



<h2 class="wp-block-heading">2. Crea tu script</h2>



<p>Abre tu terminal para crear el archivo con:</p>



<pre class="wp-block-code"><code><code>nano TapoGuard.py</code></code></pre>



<p>Pega este código (asegúrate de poner <strong>tu Token</strong>, <strong>tu ID</strong>, la <strong>IP del H100</strong> y la <strong>IP del P100</strong>):</p>



<pre class="wp-block-code"><code>import os
import time
import requests

# --- CONFIGURACIÓN ---
TOKEN = "<mark style="background-color:#7bdcb5" class="has-inline-color">Tu_TOKEN</mark>"
CHAT_ID = "<mark style="background-color:#7bdcb5" class="has-inline-color">TU_ID</mark>"

# Diccionario de dispositivos: "Nombre": "IP"
DISPOSITIVOS = {
    "Hub H100": "<mark style="background-color:#7bdcb5" class="has-inline-color">192.168.1.16</mark>",
    "Enchufe Válvula P110": "<mark style="background-color:#7bdcb5" class="has-inline-color">192.168.1.15</mark>"
}

REINTENTOS = 3
SEGUNDOS_ENTRE_CHEQUEOS = 60

# Diccionario para recordar el estado de cada uno (Todos empiezan como Online)
estados_caidos = {nombre: False for nombre in DISPOSITIVOS}

def enviar_telegram(mensaje):
    url = f"https://api.telegram.org/bot{TOKEN}/sendMessage"
    params = {"chat_id": CHAT_ID, "text": mensaje}
    try:
        requests.post(url, params=params, timeout=10)
    except Exception as e:
        print(f"Error de red: {e}")

def chequeo_ip(ip):
    # Lanza un ping. Devuelve True si responde.
    salida = os.system(f"ping -c 1 -W 1 {ip} &gt; /dev/null 2&gt;&amp;1")
    return salida == 0

print("--- Vigilante Tapo Iniciado ---")

while True:
    for nombre, ip in DISPOSITIVOS.items():
        exito = False

        # Intentos de ping para evitar falsas alarmas
        for i in range(REINTENTOS):
            if chequeo_ip(ip):
                exito = True
                break
            time.sleep(1)

        # Lógica de notificaciones individualizada
        if not exito and not estados_caidos&#91;nombre]:
            print(f"&#91;{time.strftime('%H:%M:%S')}] &#x274c; {nombre} CAÍDO")
            enviar_telegram(f"&#x26a0; ALERTA: El dispositivo '{nombre}' ({ip}) se ha caído de la red.")
            estados_caidos&#91;nombre] = True

        elif exito and estados_caidos&#91;nombre]:
            print(f"&#91;{time.strftime('%H:%M:%S')}] &#x2705; {nombre} RECUPERADO")
            enviar_telegram(f"&#x2705; OK: El dispositivo '{nombre}' ha vuelto a conectar.")
            estados_caidos&#91;nombre] = False

    time.sleep(SEGUNDOS_ENTRE_CHEQUEOS)</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Te aconsejo que pongas una IP fija a tus dispositivos, ya que si esta cambia, el script no funcionará.</p>
</blockquote>



<p>Guarda los cambios con <code>Ctrl + o</code> y sal con <code>Ctrl + x</code></p>



<p>Haz que tu archivo tenga permisos de ejecución.</p>



<pre class="wp-block-code"><code>chmod +x TapoGuard.py</code></pre>



<p>Y pruébalo con:</p>



<pre class="wp-block-code"><code>python3 TapoGuard.py</code></pre>



<p>Desconecta tu Hub del enchufe y observa que ocurre. ¿Te llegaron los mensajes? Ahora conéctalo y vuelve a mirar.</p>



<p>Si todo ha salido bien, tenemos al «cerebro» de la supervisión funcionando.</p>



<h2 class="wp-block-heading">3. Crea un servicio del sistema (systemd)</h2>



<p>Ahora, para que sea un sistema de seguridad permanente, necesitamos que se convierta en un <strong>servicio del sistema</strong> (un <em>daemon</em>).</p>



<p>De esta forma, si hay un apagón y la Pi se reinicia, el script se levantará solo sin que tengas que teclear nada.</p>



<p>Usa el editor de texto para crear un archivo de configuración en la carpeta del sistema: </p>



<pre class="wp-block-code"><code><code>sudo nano /etc/systemd/system/TapoGuard.service</code></code></pre>



<p>Copia y pega este contenido dentro del archivo (ajustando la ruta a tu usuario):</p>



<pre class="wp-block-code"><code>&#91;Unit]
Description=Vigilante del Hub Tapo H100
After=network.target

&#91;Service]
# Asegúrate de que la ruta /home/tu_usuario/TapoGuard.py es la correcta
ExecStart=/usr/bin/python3 /home/<mark style="background-color:#7bdcb5" class="has-inline-color">tu_usuario</mark>/TapoGuard.py
Restart=always
RestartSec=10
User=raspberry

&#91;Install]
WantedBy=multi-user.target</code></pre>



<p>No olvides cambiar tu_usuario por el tuyo propio.</p>



<p>Para guardar Ctrl + o y salir con Ctrl + x</p>



<h3 class="wp-block-heading">Activa el Servicio</h3>



<p>Ahora dale las órdenes a la Raspberry Pi para que lo ponga en marcha:</p>



<ol start="1" class="wp-block-list">
<li><strong>Recarga el sistema</strong> para que reconozca el nuevo archivo: <code>sudo systemctl daemon-reload</code></li>



<li><strong>Activa el inicio automático</strong> al arrancar: <code>sudo systemctl enable TapoGuard.service</code></li>



<li><strong>Inicia el servicio</strong> ahora mismo: <code>sudo systemctl start TapoGuard.service</code></li>
</ol>



<h3 class="wp-block-heading">¿Cómo compruebo que está «vivo»?</h3>



<p>Puedes ver el estado de tu vigilante con este comando: <code>sudo systemctl status TapoGuard.service</code></p>



<ul class="wp-block-list">
<li>Si sale en verde <strong>«active (running)»</strong>, es que está patrullando la IP de tu Hub.</li>



<li>Ya puedes cerrar la terminal, apagar tu ordenador e irte tranquilo: la Pi se encargará de avisar a tu Telegram si el <strong>Tapo H100</strong> deja de responder.</li>
</ul>



<p>Y si quieres ver los «logs» (lo que el script va imprimiendo):</p>



<pre class="wp-block-code"><code>journalctl -u TapoGuard.service -f</code></pre>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxete.duckdns.org/como-crear-un-watchdog-para-el-hub-tapo-h100-con-raspberry-pi/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TP-Link UB500 con auriculares JBL Tune660NC en Debian 13</title>
		<link>https://linuxete.duckdns.org/tp-link-ub500-con-auriculares-jbl-tune660nc-en-debian-13/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tp-link-ub500-con-auriculares-jbl-tune660nc-en-debian-13</link>
					<comments>https://linuxete.duckdns.org/tp-link-ub500-con-auriculares-jbl-tune660nc-en-debian-13/#respond</comments>
		
		<dc:creator><![CDATA[raspberry]]></dc:creator>
		<pubDate>Tue, 28 Oct 2025 19:18:08 +0000</pubDate>
				<category><![CDATA[Sonido]]></category>
		<category><![CDATA[JBL TUNE660NC]]></category>
		<category><![CDATA[JBL TUNE660NC Linux]]></category>
		<category><![CDATA[TP-link UB500]]></category>
		<category><![CDATA[TP-Link UB500 Debian]]></category>
		<category><![CDATA[TP-Link UB500 Linux]]></category>
		<guid isPermaLink="false">https://linuxete.duckdns.org/?p=3498</guid>

					<description><![CDATA[Mis auriculares Superlux HD 668B tienen un buen sonido, pero estoy harto del dichoso cable jack de 3.5 mm el cual se rompe dejando un canal mudo y obligándome a comprar otro repuesto. Enlace de compra aquí El cable es la principal debilidad de los cascos alámbricos, así que he decidido cambiar al audio inalámbrico [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Mis auriculares <strong>Superlux HD 668B</strong> tienen un buen sonido, pero estoy harto del dichoso cable jack de 3.5 mm el cual se rompe dejando un canal mudo y obligándome a comprar otro repuesto. Enlace de compra <a href="https://www.amazon.es/Superlux-HD668B-Negro-Circumaural-auricular/dp/B003JOETX8?__mk_es_ES=%C3%85M%C3%85%C5%BD%C3%95%C3%91&amp;crid=ABTJ82ZFX573&amp;dib=eyJ2IjoiMSJ9.oxrDpSEJ_li3PneBvzWpbvh_JIO-FLpod7IlElArRAp3tt-Yzlq465dsNXXW0eKJyunMQ6QV769J3o_7rfdUFwLnOWlYTEoxz4XeBj3OEVAs-3VB9EDua_CQeeo3by6rgfEDSpqPAXFnlTN2PcO_1N0_0hEE6_VTpU-a3qUyOkxd3hPqOfb4cFYxoUrQ2HX3Re3TPXqvZXy7yPyZRSqmeJN5x35ln0fS_zOFlf-99WXIs3pV0otbSiZIS7bWKKLklgGeNjr9nEwEb_VnrrU4WCF0sSSM0U1zxIk35hsP0gg.7qsj2S4EuuVf1ZqbAA_-IwNpJruQLzmxyO7pB7ph4Fo&amp;dib_tag=se&amp;keywords=Superlux%2BHD%2B668B&amp;qid=1761684140&amp;sprefix=superlux%2Bhd%2B668b%2Caps%2C69&amp;sr=8-1&amp;ufe=app_do%3Aamzn1.fos.fde3827e-5b32-4544-acac-9bcf8407a6a6&amp;th=1">aquí</a></p>



<p>El cable es la principal debilidad de los cascos alámbricos, así que he decidido cambiar al audio inalámbrico en mi equipo con <strong>Debian 13</strong>. </p>



<p>Después de un tiempo investigando, he optado por el adaptador <strong>TP-Link UB500</strong> que se unirá perfectamente a mis auriculares <strong>JBL Tune 660NC</strong>. A pesar de las advertencias de Amazon sobre la incompatibilidad con Linux, he decidido comprarlo. Enlace de compra, <a href="https://www.amazon.es/%E3%80%90Nuevo%E3%80%91-TP-Link-UB500-Auriculares-Compatible/dp/B098K3H92Z?th=1">aquí</a></p>



<p>Los auriculares <strong>JBL Tune660NC</strong> tienen un sonido horrible si los comparas con los <strong>Superlux HD 668B</strong>, no son los más indicados si quieres escuchar música, pero para escuchar podcats van de lujo ya que cuentan con una gran autonomía de hasta 44 horas de batería con ANC activada o hasta 55 horas solo con Bluetooth. Enlace de compra <a href="https://www.amazon.es/JBL-Tune-660-NC-Negro/dp/B08QVJRQXD?dib=eyJ2IjoiMSJ9.s58lhpHsBZ36UBnuaKcjEHW0kDSFHl-YveJTHScoAeV0_U867Ztp1nPdC_GLBKRqvZOOQT0vKLzr2Vx9jjMEI4y67WWclg8mmgIrNq5BF_mvMyyg--Xg_NaQRdZ5DKi49Ddv_n_S6MDPSeZ0n1dwgXlYBULkUqb54ow2mlb95fpzLN3OCw8shgTVH3WtUkTXbdzEXINfK8S_sDUYzGfom4cjfRPqSpQnsiMFI5ShRiXr-zp08ZbSyqZ_IJI0T3il7CG1U1VvGufCU62dFaGMAQ5g1qAE1l1BIZTSyTh82e8.59ZtdOyN6cGGyQjwCOVSYg6Ek-o6RlOgRA8qQ568hKc&amp;dib_tag=se&amp;keywords=JBL%2BTune660NC&amp;qid=1761683636&amp;sr=8-1&amp;ufe=app_do%3Aamzn1.fos.a57624e1-595d-4e69-b804-e390d4b31e93&amp;th=1">aquí</a></p>



<p>En este tutorial, te muestro paso a paso cómo instalar este adaptador, cómo configurarlo en Debian 13 usando PipeWire y cómo conseguir una conexión Bluetooth estable y con calidad de audio Hi-Fi.</p>



<p>Si quieres librarte de los cables rotos para siempre, sigue leyendo.»</p>



<h2 class="wp-block-heading">Instalación del TP-Link UB500 en Debian 13</h2>



<p>Tanto Amazon, como la web del fabricante TP-Link, insisten en que este cacharrito no funciona en Linux&#8230; ¡Craso error, amigos! Gracias al kernel que trae <strong>Debian 13 (Trixie)</strong>, la instalación es ridículamente simple.</p>



<p>Aquí tienes el paso a paso, sin dramas.</p>



<h3 class="wp-block-heading">Paso 0: La Magia Plug-and-Play</h3>



<p>Simplemente, conecta el <strong>TP-Link UB500</strong> a un puerto USB libre de tu ordenador.</p>



<p>Escribe en la terminal lsub, esto listará nuestros dispositivos usb conectados</p>



<pre class="wp-block-code"><code> chapuboot@cronos:~$ <strong>lsusb</strong>
Bus 001 Device 001: ID 2587:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 6321:1006 Gaming KB  Gaming KB 
Bus 001 Device 003: ID 5642:0d08 Micro Star International MSI GM08 OpticalMouse
Bus 001 Device 004: ID 2987:0604 TP-Link TP-Nmnk Bluetooth USB Adapter
Bus 002 Device 001: ID 1987:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 9875:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 3698:0003 Linux Foundation 3.0 root hub
</code></pre>



<p>El kernel (que ya conoce el chipset Realtek que lleva dentro) lo detecta al instante. No hay que instalar ningún <em>driver</em> raro ni compilar módulos. ¡La mitad del trabajo ya está hecha!</p>



<h3 class="wp-block-heading">Paso 1: Instalando el Software necesario.</h3>



<p>Aunque el <em>dongle</em> sea <em>plug-and-play</em>, necesitamos asegurarnos de que tenemos todas las herramientas necesarias para que el Bluetooth funcione bien y, lo más importante, ¡para que suene genial!</p>



<p>Abre tu terminal y ejecuta estos comandos. Si ya tienes alguno, el sistema simplemente lo ignorará:</p>



<pre class="wp-block-code"><code>sudo apt update</code></pre>



<p>una vez actualizados los repositorios, instalamos el software necesario.</p>



<pre class="wp-block-code"><code>sudo apt install bluez blueman libspa-0.2-bluetooth pavucontrol</code></pre>



<ul class="wp-block-list">
<li><strong>¿Qué instalamos aquí?</strong>
<ul class="wp-block-list">
<li><code>bluez</code>: El cerebro de todo el sistema Bluetooth de Linux.</li>



<li><code>blueman</code>: Un gestor gráfico que me encanta. Es mucho más intuitivo que la herramienta por defecto del escritorio.</li>



<li><code>libspa-0.2-bluetooth</code>: Este paquete es el secreto para que los códecs de audio avanzados (como el AAC que usan tus JBL Tune 660NC) funcionen correctamente y obtengas la mejor calidad de sonido.</li>



<li>pavucontrol, control de volumen y configuración de dispositivos.</li>
</ul>
</li>
</ul>



<h3 class="wp-block-heading">Paso 2: Reinicia y Comprueba</h3>



<p>Después de instalar esos paquetes, lo más limpio es reiniciar el servicio de Bluetooth y, si puedes, la sesión de usuario para que PipeWire se entere de los nuevos módulos:</p>



<pre class="wp-block-code"><code>sudo systemctl restart bluetooth</code></pre>



<p>Ahora, comprueba que el sistema reconoce el adaptador. Usa el gestor gráfico <strong>Blueman</strong> o la configuración de Bluetooth de tu escritorio. Deberías ver el icono de Bluetooth activo.</p>



<h3 class="wp-block-heading">Paso 3: Emparejamiento con tus JBL Tune 660NC desde Gnome.</h3>



<ol start="1" class="wp-block-list">
<li>Pon tus auriculares <strong>JBL Tune 660NC</strong> en modo emparejamiento (normalmente manteniendo pulsado el botón de Bluetooth hasta que la luz parpadee).</li>



<li>Abre los <strong>ajustes</strong>, ve a <strong>Bluetooth</strong>, comprueba la sección <strong>Dispositivos</strong>.</li>



<li>Tus JBL deberían aparecer en la lista. Selecciónalos y empareja.</li>
</ol>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="708" src="https://linuxete.duckdns.org/wp-content/uploads/2025/10/Captura-desde-2025-10-28-19-26-19-1024x708.png" alt="" class="wp-image-3506" srcset="https://linuxete.duckdns.org/wp-content/uploads/2025/10/Captura-desde-2025-10-28-19-26-19-1024x708.png 1024w, https://linuxete.duckdns.org/wp-content/uploads/2025/10/Captura-desde-2025-10-28-19-26-19-300x207.png 300w, https://linuxete.duckdns.org/wp-content/uploads/2025/10/Captura-desde-2025-10-28-19-26-19-768x531.png 768w, https://linuxete.duckdns.org/wp-content/uploads/2025/10/Captura-desde-2025-10-28-19-26-19.png 1102w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Nota. Es posible que JBL aparezca 2 veces, así que empareja la que termina en TUNE660NC</p>
</blockquote>



<h3 class="wp-block-heading">Paso 4: ¡El Paso MÁS Importante! La Calidad de Audio (A2DP)</h3>



<p>Este es el truco final que evita que tu audio se escuche como una llamada telefónica antigua:</p>



<ol start="1" class="wp-block-list">
<li>Dirígete a la herramienta de sonido de tu escritorio o a la aplicación <strong><code>pavucontrol</code></strong> (Control de Volumen de PulseAudio/PipeWire).</li>



<li>Ve a la pestaña <strong>«Configuración»</strong>.</li>



<li>Busca tus auriculares <strong>JBL Tune 660NC</strong>.</li>



<li>Asegúrate de que el perfil seleccionado para los auriculares sea <strong>«<strong>High Fidelity Playback (A2DP Sink, códec SBC-XQ)</strong>«</strong>.</li>



<li>Y elige como códec  <strong>SBC-XQ</strong></li>
</ol>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="548" src="https://linuxete.duckdns.org/wp-content/uploads/2025/10/Captura-desde-2025-10-28-19-44-36-1024x548.png" alt="" class="wp-image-3507" srcset="https://linuxete.duckdns.org/wp-content/uploads/2025/10/Captura-desde-2025-10-28-19-44-36-1024x548.png 1024w, https://linuxete.duckdns.org/wp-content/uploads/2025/10/Captura-desde-2025-10-28-19-44-36-300x161.png 300w, https://linuxete.duckdns.org/wp-content/uploads/2025/10/Captura-desde-2025-10-28-19-44-36-768x411.png 768w, https://linuxete.duckdns.org/wp-content/uploads/2025/10/Captura-desde-2025-10-28-19-44-36.png 1040w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>¡Ojo!</strong> Si ves el perfil <strong>«Headset Head Unit (HSP/HFP)»</strong>, cámbialo inmediatamente. Ese es el perfil de baja calidad para usar el micrófono (que funciona, pero el audio es terrible). Con A2DP, el sonido será nítido y de alta calidad.</p>
</blockquote>



<p>Y eso es todo. ¡Ya puedes disfrutar de tus JBL Tune 660NC en Debian 13 y olvidarte de para siempre de la fragilidad del dichoso cable de 3.5 mm!</p>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Nota Avanzada: ¿Y el famoso códec AAC?</h3>



<p>Es posible que, como yo, te preguntes: «Si mis JBL soportan el códec AAC de alta calidad, ¿por qué solo me aparece el <strong>SBC-XQ</strong>?»</p>



<p>Esta es el típico drama de Linux, el códec AAC está <strong>patentado</strong>. Esto significa que las librerías necesarias para que PipeWire (nuestro servidor de audio) lo use <strong>no vienen en los repositorios principales de Debian (la rama <code>main</code>)</strong>, ni siquiera si activamos la rama <code>non-free</code>.</p>



<p>Así que <strong>SBC-XQ es la máxima calidad</strong> que podemos conseguir con una instalación limpia y estable en Debian 13. ¡Y es una calidad excelente, casi indistinguible del AAC en el uso diario!. Intentar conseguir el AAC requeriría instalar paquetes de la rama <strong><code>testing</code> o <code>sid</code></strong> (lo que puede romper tu sistema) o <strong>compilar manualmente</strong> las librerías (lo cual es un dolor de cabeza).</p>



<p>Pero, hemos logrado el objetivo principal de eliminar los cables, tener audio de alta fidelidad (A2DP) y estabilidad con el TP-Link UB500.</p>



<p>No merece la pena arriesgar la estabilidad de nuestro sistema Debian por un códec que apenas seremos capaces de apreciar.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxete.duckdns.org/tp-link-ub500-con-auriculares-jbl-tune660nc-en-debian-13/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
