<?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>Sistema &#8211; El Cornijal de Linux</title>
	<atom:link href="https://linuxete.duckdns.org/category/sistema/feed/" rel="self" type="application/rss+xml" />
	<link>https://linuxete.duckdns.org</link>
	<description>Un blog sobre Linux</description>
	<lastBuildDate>Wed, 11 Mar 2026 21:03:00 +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>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>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>Como liberar memoria búfer/caché en Linux</title>
		<link>https://linuxete.duckdns.org/como-liberar-memoria-bufer-cache-en-linux/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=como-liberar-memoria-bufer-cache-en-linux</link>
					<comments>https://linuxete.duckdns.org/como-liberar-memoria-bufer-cache-en-linux/#respond</comments>
		
		<dc:creator><![CDATA[raspberry]]></dc:creator>
		<pubDate>Sun, 10 Aug 2025 21:35:04 +0000</pubDate>
				<category><![CDATA[Sistema]]></category>
		<category><![CDATA[free_mem]]></category>
		<category><![CDATA[script memory]]></category>
		<guid isPermaLink="false">https://linuxete.duckdns.org/?p=2877</guid>

					<description><![CDATA[Linux utiliza la RAM de manera muy eficiente. A diferencia de Windows, que intenta mantener mucha memoria «libre», el kernel de Linux usa la RAM no utilizada para almacenar datos que podría necesitar en el futuro, como caché de disco y buffers. Esto hace que el sistema sea más rápido, ya que acceder a la [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Linux utiliza la RAM de manera muy eficiente. A diferencia de Windows, que intenta mantener mucha memoria «libre», el kernel de Linux usa la RAM no utilizada para almacenar datos que podría necesitar en el futuro, como caché de disco y buffers. Esto hace que el sistema sea más rápido, ya que acceder a la RAM es mucho más rápido que acceder al disco.</p>



<p>Tanto la memoria de <strong>buffers</strong> como la de <strong>caché</strong> se consideran «disponibles» porque el kernel puede liberarla instantáneamente si un programa necesita más RAM.</p>



<ul class="wp-block-list">
<li><strong>Buffers:</strong> Se usa para almacenar bloques de archivos que están en espera para ser escritos en el disco.</li>



<li><strong>Caché:</strong> Se usa para almacenar datos de archivos que se han leído recientemente del disco.</li>
</ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Nota: Para el kernel de Linux, la memoria libre es memoria desperdiciada.</p>
</blockquote>



<h2 class="wp-block-heading">Comando free -h</h2>



<p>Comprobar el uso de la memoria es tan fácil como escribir lo siguiente en la terminal:</p>



<pre class="wp-block-code"><code>raspberry@pi5:~
$ <strong>free -h</strong>
               total       usado       libre  compartido   búf/caché   disponible
Mem:           7,9Gi       1,8Gi       323Mi        94Mi       6,2Gi       6,1Gi
Inter:         199Mi          0B       199Mi
</code></pre>



<p>El comando <code>free -h</code> te da una visión detallada y precisa de la situación. Te muestra varias categorías de memoria:</p>



<ul class="wp-block-list">
<li><strong><code>total</code></strong>: La cantidad total de RAM física.</li>



<li><strong><code>usado</code></strong>: La memoria que está siendo utilizada activamente por los procesos del sistema.</li>



<li><strong><code>libre</code></strong>: La memoria que no está siendo utilizada para nada. En un sistema Linux bien optimizado, este valor suele ser muy bajo.</li>



<li><strong><code>buff/cache</code></strong>: La memoria utilizada para buffers y caché de disco.</li>



<li><strong><code>disponible</code></strong>: Este es el valor más importante para entender la memoria «realmente disponible». Es la memoria <code>"libre"</code> más la memoria de <code>"buff/cache"</code> que el sistema puede liberar rápidamente si es necesario. Es la mejor estimación de cuánta memoria hay disponible para nuevos programas sin usar la memoria de intercambio (swap).</li>
</ul>



<h2 class="wp-block-heading">Comando htop</h2>



<p><code>htop</code> adopta un enfoque diferente, a menudo para simplificar la visualización en su barra de progreso. Por lo general, calcula la memoria «usada» de una manera que puede ser engañosa para algunos usuarios.</p>



<pre class="wp-block-code"><code>raspberry@pi5:~
$ htop</code></pre>



<p>Así es como htop desglosa el uso de la memoria:</p>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" width="440" height="206" src="https://linuxete.duckdns.org/wp-content/uploads/2025/08/mem.png" alt="" class="wp-image-2878" srcset="https://linuxete.duckdns.org/wp-content/uploads/2025/08/mem.png 440w, https://linuxete.duckdns.org/wp-content/uploads/2025/08/mem-300x140.png 300w" sizes="(max-width: 440px) 100vw, 440px" /></figure>



<ul class="wp-block-list">
<li><strong>Verde</strong>: Memoria usada por procesos de usuario.</li>



<li><strong>Azul</strong>: Memoria usada para <strong>buffers</strong> (E/S de disco).</li>



<li><strong>Amarillo/Naranja</strong>: Memoria usada para <strong>caché</strong> (archivos de disco).</li>



<li><strong>Rosa/Fucsia</strong>: Memoria usada por el <strong>kernel</strong> del sistema.</li>



<li><strong>Lila/Magenta</strong>: Memoria de <strong>swap</strong> (si está activado y en uso).</li>
</ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Una barra de memoria llena en htop no siempre significa que tu sistema esté en problemas. De hecho, a menudo indica que Linux está utilizando la memoria RAM de manera muy eficiente.</p>
</blockquote>



<h2 class="wp-block-heading">Liberar Memoria buffer/cache</h2>



<p>Hay algunas situaciones específicas donde liberar la caché y los búferes puede ser beneficioso:</p>



<ul class="wp-block-list">
<li><strong>Entornos con recursos limitados:</strong> En sistemas con poca RAM, como una Raspberry Pi o un servidor con poca memoria, liberar la caché de forma manual puede ser una solución rápida para liberar memoria para nuevas aplicaciones o procesos que la necesiten, evitando que el sistema comience a usar el espacio de intercambio (swap) de forma prematura.</li>



<li><strong>Pruebas de rendimiento (benchmarking):</strong> Si estás realizando pruebas para medir la velocidad de entrada/salida (I/O) de un disco, es crucial que las pruebas se realicen directamente sobre el disco y no sobre los datos que ya están en la caché. Limpiar la caché asegura que cada prueba parta de las mismas condiciones iniciales.</li>



<li><strong>Problemas de rendimiento inexplicables:</strong> En raras ocasiones, un sistema puede volverse lento debido a que la caché está llena de datos obsoletos o corruptos. Liberar la caché puede ser un paso de diagnóstico para ver si el rendimiento mejora.</li>



<li><strong>Después de tareas intensivas en I/O:</strong> Si has realizado una tarea que ha consumido muchos recursos, como una copia de seguridad grande o la edición de vídeo, y has notado que el sistema se ha vuelto lento, liberar la caché puede ayudar a que el sistema vuelva a su estado normal más rápidamente.</li>
</ul>



<p>Es importante recordar, que liberar la caché de forma manual no es una solución a largo plazo para los problemas de rendimiento. El kernel de Linux liberará la caché automáticamente cuando un proceso necesite más memoria. Liberar la caché del sistema puede causar una breve lentitud inicial mientras el sistema vuelve a cargar los datos necesarios en la memoria, sin embargo, no hay riesgo de pérdida de datos. La mayoría de los sistemas Linux gestionan la memoria de forma eficiente por sí mismos, por lo que este tipo de intervención manual solo es necesaria en las situaciones anteriormente descritas.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Recuerda: Forzar esta acción puede causar una ralentización temporal, ya que el sistema tendrá que volver a leer los datos del disco la próxima vez que los necesite, en lugar de acceder a ellos directamente desde la RAM.</p>
</blockquote>



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



<p>Una vez entendido lo anteriormente descrito, si deseas crear un script para liberar memoria de forma automática, abre una terminal y escribe:</p>



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



<p><br>Pega lo siguiente en la ventana que se abre</p>



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

# Este script libera la memoria caché del sistema Linux.
# Requiere permisos de superusuario (sudo).

# Muestra el uso de la memoria antes de liberar la caché.
echo "Uso de la memoria antes de liberar la caché:"
free -h
echo "---"

# Sincroniza el sistema de archivos para asegurar que los datos en caché se esc&gt;
sync

# Limpia los cachés de la página, los dentry y los inodos.
# El valor '3' en /proc/sys/vm/drop_caches hace esto.
echo "Liberando la memoria caché..."
sudo sh -c 'echo 3 &gt; /proc/sys/vm/drop_caches'

# Muestra el uso de la memoria después de liberar la caché.
echo "---"
echo "Uso de la memoria después de liberar la caché:"
free -h

echo "Proceso completado."</code></pre>



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



<pre class="wp-block-code"><code>sudo chmod +x /usr/local/bin/liberar_memoria.sh</code></pre>



<p>En este momento puedes ejecutar desde una terminal el script así</p>



<pre class="wp-block-code"><code>raspberry@pi5:~
$ liberar_memoria.sh</code></pre>



<p>Para hacer esto automáticamente, creamos una tarea que se ejecute a las 5.00 a.m horas todos los días y limpie la memoria.</p>



<pre class="wp-block-code"><code>crontab -e</code></pre>



<p>Copiamos y pegamos lo siguiente al final de la línea.</p>



<pre class="wp-block-code"><code>0 5 * * * /usr/local/bin/liberar_memoria.sh &gt;&gt; /home/tu_usuario/freeMen.log 2&gt;&amp;1</code></pre>



<p>Ctrl + o para guardar Ctrl + x para salir</p>



<p>Ahora una vez al dia, a las 5.00 a.m se limpiará la memoria de tu equipo 24/7/365</p>



<h3 class="wp-block-heading">Ahora sabemos:</h3>



<p>Que si tu sistema se vuelve lento, observa la memoria ocupada, (barra llena, color verde), o si la parte lila (swap) empieza a crecer, podría ser una señal de que necesitas controlar mediante un script la liberación de memoria o necesitas comprar más RAM para tu carga de trabajo actual.</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxete.duckdns.org/como-liberar-memoria-bufer-cache-en-linux/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
