superguardado: comando limpieza (limpia procesos atascados de la Pi) + limpiar.py
This commit is contained in:
1
.obsidian/app.json
vendored
Normal file
1
.obsidian/app.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
.obsidian/appearance.json
vendored
Normal file
1
.obsidian/appearance.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
33
.obsidian/core-plugins.json
vendored
Normal file
33
.obsidian/core-plugins.json
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"file-explorer": true,
|
||||
"global-search": true,
|
||||
"switcher": true,
|
||||
"graph": true,
|
||||
"backlink": true,
|
||||
"canvas": true,
|
||||
"outgoing-link": true,
|
||||
"tag-pane": true,
|
||||
"footnotes": false,
|
||||
"properties": true,
|
||||
"page-preview": true,
|
||||
"daily-notes": true,
|
||||
"templates": true,
|
||||
"note-composer": true,
|
||||
"command-palette": true,
|
||||
"slash-command": false,
|
||||
"editor-status": true,
|
||||
"bookmarks": true,
|
||||
"markdown-importer": false,
|
||||
"zk-prefixer": false,
|
||||
"random-note": false,
|
||||
"outline": true,
|
||||
"word-count": true,
|
||||
"slides": false,
|
||||
"audio-recorder": false,
|
||||
"workspaces": false,
|
||||
"file-recovery": true,
|
||||
"publish": false,
|
||||
"sync": true,
|
||||
"bases": true,
|
||||
"webviewer": false
|
||||
}
|
||||
22
.obsidian/graph.json
vendored
Normal file
22
.obsidian/graph.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"collapse-filter": true,
|
||||
"search": "",
|
||||
"showTags": false,
|
||||
"showAttachments": false,
|
||||
"hideUnresolved": false,
|
||||
"showOrphans": true,
|
||||
"collapse-color-groups": true,
|
||||
"colorGroups": [],
|
||||
"collapse-display": true,
|
||||
"showArrow": false,
|
||||
"textFadeMultiplier": 0,
|
||||
"nodeSizeMultiplier": 1,
|
||||
"lineSizeMultiplier": 1,
|
||||
"collapse-forces": true,
|
||||
"centerStrength": 0.518713248970312,
|
||||
"repelStrength": 10,
|
||||
"linkStrength": 1,
|
||||
"linkDistance": 250,
|
||||
"scale": 1,
|
||||
"close": false
|
||||
}
|
||||
189
.obsidian/workspace.json
vendored
Normal file
189
.obsidian/workspace.json
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
{
|
||||
"main": {
|
||||
"id": "926bba7b6257cb83",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "d8f7c226097458c7",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "72506070fed1a695",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "graph",
|
||||
"state": {},
|
||||
"icon": "lucide-git-fork",
|
||||
"title": "Vista gráfica"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"direction": "vertical"
|
||||
},
|
||||
"left": {
|
||||
"id": "84a364de2999912b",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "8bab02b5105eeb5b",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "487dc72c4c2ad06f",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "file-explorer",
|
||||
"state": {
|
||||
"sortOrder": "alphabetical",
|
||||
"autoReveal": false,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-folder-closed",
|
||||
"title": "Explorador de archivos"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "245580e4caa54b56",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "search",
|
||||
"state": {
|
||||
"query": "",
|
||||
"matchingCase": false,
|
||||
"explainSearch": false,
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical"
|
||||
},
|
||||
"icon": "lucide-search",
|
||||
"title": "Buscar"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "e78680f9daec255d",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "bookmarks",
|
||||
"state": {
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-bookmark",
|
||||
"title": "Marcadores"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 300
|
||||
},
|
||||
"right": {
|
||||
"id": "2a664eeb01bb6a0e",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "7d195b329221cd02",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "1ebc95b7268f14a7",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "backlink",
|
||||
"state": {
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical",
|
||||
"showSearch": false,
|
||||
"searchQuery": "",
|
||||
"backlinkCollapsed": false,
|
||||
"unlinkedCollapsed": true
|
||||
},
|
||||
"icon": "links-coming-in",
|
||||
"title": "Enlaces entrantes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "a3196bc4461f5957",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "outgoing-link",
|
||||
"state": {
|
||||
"linksCollapsed": false,
|
||||
"unlinkedCollapsed": true
|
||||
},
|
||||
"icon": "links-going-out",
|
||||
"title": "Enlaces salientes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "464b357dcc7110d9",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "tag",
|
||||
"state": {
|
||||
"sortOrder": "frequency",
|
||||
"useHierarchy": true,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-tags",
|
||||
"title": "Etiquetas"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "fce335174b5a3979",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "all-properties",
|
||||
"state": {
|
||||
"sortOrder": "frequency",
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-archive",
|
||||
"title": "Todas las propiedades"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "139ea07527216a59",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "outline",
|
||||
"state": {
|
||||
"followCursor": false,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-list",
|
||||
"title": "Esquema"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 300,
|
||||
"collapsed": true
|
||||
},
|
||||
"left-ribbon": {
|
||||
"hiddenItems": {
|
||||
"switcher:Abrir selector rápido": false,
|
||||
"graph:Abrir vista gráfica": false,
|
||||
"canvas:Crear nuevo lienzo": false,
|
||||
"daily-notes:Abrir la nota de hoy": false,
|
||||
"templates:Insertar plantilla": false,
|
||||
"command-palette:Abrir paleta de comandos": false,
|
||||
"bases:Crear nueva base": false
|
||||
}
|
||||
},
|
||||
"active": "72506070fed1a695",
|
||||
"lastOpenFiles": [
|
||||
"vigilancia/__pycache__/limpiar.cpython-313.pyc",
|
||||
"vigilancia/limpiar.py"
|
||||
]
|
||||
}
|
||||
82
vigilancia/limpiar.py
Normal file
82
vigilancia/limpiar.py
Normal file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Limpieza de procesos de la Pi: mata procesos zombie/atascados, reinicia servicios si es necesario."""
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import config
|
||||
|
||||
def sh(cmd):
|
||||
try:
|
||||
return subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=15).stdout.strip()
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
def limpiar():
|
||||
informe = []
|
||||
|
||||
# 1. Procesos Python atascados (CPU > 50% durante >60s)
|
||||
ps = sh("ps aux | grep python3 | grep -v grep")
|
||||
for linea in ps.splitlines():
|
||||
if not linea: continue
|
||||
parts = linea.split()
|
||||
try:
|
||||
cpu = float(parts[2])
|
||||
pid = parts[1]
|
||||
cmd = " ".join(parts[10:])
|
||||
if cpu > 50 and "minipc" in cmd:
|
||||
informe.append(f"Matando proceso atascado PID {pid} ({cpu}% CPU): {cmd[:50]}")
|
||||
sh(f"kill -9 {pid}")
|
||||
except (IndexError, ValueError):
|
||||
pass
|
||||
|
||||
# 2. Zombie processes
|
||||
zombies = sh("ps aux | awk '$8==\"Z\" {print $2}'")
|
||||
for z in zombies.splitlines():
|
||||
if z.strip():
|
||||
informe.append(f"Zombie PID {z.strip()} limpiado")
|
||||
sh(f"kill -9 {z.strip()}")
|
||||
|
||||
# 3. Procesos python viejos (>2h, sin ser servicios principales)
|
||||
ps2 = sh("ps aux | grep python3 | grep -v grep")
|
||||
for linea in ps2.splitlines():
|
||||
if not linea: continue
|
||||
parts = linea.split()
|
||||
try:
|
||||
pid = parts[1]
|
||||
starttime = parts[8]
|
||||
cmd = " ".join(parts[10:])
|
||||
if "tv_api" not in cmd and "pi_bot" not in cmd and "http.server" not in cmd:
|
||||
if "python" in cmd.lower() or "vigilancia" in cmd.lower():
|
||||
informe.append(f"Proceso residual PID {pid}: {cmd[:60]}")
|
||||
except (IndexError, ValueError):
|
||||
pass
|
||||
|
||||
# 4. Limpiar cache del sistema
|
||||
sh("echo 'raspberry' | sudo -S sync")
|
||||
sh("echo 'raspberry' | sudo -S sh -c 'echo 3 > /proc/sys/vm/drop_caches'")
|
||||
informe.append("Caché del sistema limpiado")
|
||||
|
||||
# 5. Verificar servicios
|
||||
for svc in ["tv-api", "pi-bot"]:
|
||||
st = sh(f"systemctl is-active {svc}")
|
||||
if st != "active":
|
||||
informe.append(f"⚠️ Servicio {svc} no activo: {st}")
|
||||
sh(f"echo 'raspberry' | sudo -S systemctl restart {svc}")
|
||||
|
||||
# 6. Estado final
|
||||
temp = sh("vcgencmd measure_temp")
|
||||
load = sh("cat /proc/loadavg | cut -d' ' -f1")
|
||||
mem = sh("free -h | awk 'NR==2{print $2\" total, \"$7\" libre\"}'")
|
||||
|
||||
if not informe:
|
||||
informe.append("✅ Todo limpio, sin procesos atascados")
|
||||
|
||||
informe.append(f"\nEstado: temp={temp} | load={load} | mem={mem}")
|
||||
return "\n".join(informe)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(limpiar())
|
||||
@@ -137,6 +137,15 @@ def procesar(texto, chat_id):
|
||||
log(f"panorama: {r.stdout.strip()[-200:]}")
|
||||
except Exception as e:
|
||||
log(f"panorama error: {e}")
|
||||
elif t in ("limpieza", "/limpieza", "limpiar", "/limpiar"):
|
||||
enviar("🧹 Ejecutando limpieza...", chat_id)
|
||||
try:
|
||||
from limpiar import limpiar
|
||||
resultado = limpiar()
|
||||
enviar(f"<pre>{resultado}</pre>", chat_id)
|
||||
except Exception as e:
|
||||
log(f"limpieza error: {e}")
|
||||
enviar(f"❌ Error: {e}", chat_id)
|
||||
elif t.startswith("youtube ") or t.startswith("/youtube "):
|
||||
url = texto.split(" ", 1)[1].strip()
|
||||
if not url:
|
||||
@@ -151,7 +160,8 @@ def procesar(texto, chat_id):
|
||||
"<b>tv <mensaje></b> — mensaje rápido a la tele\n"
|
||||
"<b>alarma <mensaje></b> — secuencia completa (sirena x3)\n"
|
||||
"<b>youtube <URL></b> — reproduce YouTube y apaga al terminar\n"
|
||||
"<b>panorama</b> — fotos de las cámaras",
|
||||
"<b>panorama</b> — fotos de las cámaras\n"
|
||||
"<b>limpieza</b> — limpia procesos atascados de la Pi",
|
||||
chat_id)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user