
🌱 Proyecto THEMIS: “La Huella de una Pregunta” — Impacto Energético e Hídrico de la IA (Guía Didáctica para ESO y Bachillerato)
📋 Ficha SEO / Metadatos para WordPress
- Título para WordPress: Proyecto THEMIS: La Huella de una Pregunta — Midiendo el Impacto Energético e Hídrico de la IA en ESO
- Slug (URL amigable):
proyecto-themis-huella-ecologica-coste-energetico-hidrico-ia-eso - Extracto (Resumen para la portada): En la línea THEMIS de alfabetización de datos del IES Monterroso, el alumnado de Secundaria analiza la “huella física oculta” de la Inteligencia Artificial. Mediante la aplicación interactiva
app_huella.pyy medidores de enchufe, los estudiantes comparan el consumo directo de su portátil frente al gasto de electricidad y agua dulce en los grandes datacenters (DALL-E 3, Gemini, Midjourney). - Etiquetas / Palabras clave: aidarac, montesteam, ies monterroso, themis, huella ecologica, green ai, alfabetizacion de datos, 1eso, 2eso, uvicorn, fastapi, lm studio, qwen, sostenibilidad.
- Categorías: Alfabetización de Datos, Educación Secundaria (ESO), Green AI, Software Libre, Proyectos THEMIS.
1. Contexto Educativo y Línea THEMIS
Cuando el alumnado utiliza un generador de imágenes o un asistente de texto, tiende a percibir la tecnología como un proceso intangible. La línea THEMIS (alfabetización de datos, lectura crítica y pensamiento científico) de AIDARAC en el IES Monterroso desmonta esta visión relacionando cada consulta digital con recursos del planeta.
Para facilitar la comprensión en 1º y 2º de ESO, la aplicación separa de forma estricta los dos escenarios de procesamiento:
┌────────────────────────────────────────────────────────────────────────────────┐
│ 💻 MODO LOCAL (Tu Ordenador) │
├────────────────────────────────────────────────────────────────────────────────┤
│ • Energía eléctrica: Consume la luz de la batería o del enchufe del aula. │
│ • Agua dulce evaporada: EXACTAMENTE 0 ml. Los portátiles se enfrían con un │
│ pequeño ventilador de aire directo. │
└────────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────────┐
│ ☁️ MODO ONLINE (La Nube / Datacenters) │
├────────────────────────────────────────────────────────────────────────────────┤
│ • Energía eléctrica: Procesamiento en potentes servidores de GPU. │
│ A nivel unitario la electricidad está muy optimizada mediante "batching" │
│ (procesar peticiones de cientos de usuarios a la vez). │
│ • Agua dulce evaporada: DE 5 A 7 ml POR IMAGEN. Las grandes salas de │
│ servidores requieren torres de refrigeración evaporativa con agua dulce │
│ potable para evitar que las GPUs superen los 80 °C. │
└────────────────────────────────────────────────────────────────────────────────┘
2. Guía de Parámetros: ¿Qué influye en el cálculo?
Para que los estudiantes entiendan qué variables intervienen en la medición del consumo local, la aplicación incluye estos tres paneles explicativos:
Plaintext
┌────────────────────────────────────────────────────────────────────────────────┐
│ 🔌 1. CONSUMO DEL PC (Vatios / W) │
├────────────────────────────────────────────────────────────────────────────────┤
│ • ¿Qué es?: La potencia eléctrica que demanda el equipo en cada segundo. │
│ • Ejemplo real: En reposo (leyendo un archivo) gasta ~15 W. Al poner la CPU │
│ o GPU al 100% procesando datos, la potencia sube a 65 W o más. │
└────────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────────┐
│ ⏱️ 2. TIEMPO DE CPU (Segundos / s) │
├────────────────────────────────────────────────────────────────────────────────┤
│ • ¿Qué es?: La duración del trabajo intensivo del procesador. │
│ • Ejemplo real: Un modelo ligero o rápido tarda 10–15 s; un modelo complejo │
│ o una CPU menos potente puede requerir 60 s para completar la tarea. │
└────────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────────┐
│ 💡 3. RELACIÓN DE ENERGÍA Y TIEMPO │
├────────────────────────────────────────────────────────────────────────────────┤
│ La energía consumida es el producto de la potencia por el tiempo: │
│ │
│ Energía (Wh) = (Potencia (W) × Tiempo (s)) / 3600 │
│ │
│ • Si duplicas la Potencia (W) ──► Duplicas el consumo energético. │
│ • Si el Tiempo (s) se duplica ──► Duplicas el consumo energético. │
└────────────────────────────────────────────────────────────────────────────────┘
3. La Metáfora Didáctica: La Bicicleta vs. El Autobús
Para explicar por qué la Nube gasta más agua que electricidad en proporción respecto al portátil, utilizamos esta analogía en el aula:
- 🚲 Tu Portátil Local es como ir en Bicicleta: Haces todo el trabajo con tu propio esfuerzo. Si el trayecto es empinado (modelo pesado), tardarás más tiempo, pero no gastas ni una sola gota de agua del grifo y tu vehículo no necesita permanecer encendido cuando no lo usas.
- 🚌 La Nube es como ir en Autobús Público: Es un vehículo gigante y potente. Como lleva a muchos pasajeros juntos (batching), el gasto de combustible por persona parece moderado. Sin embargo, el autobús necesita torres de lavado constante con agua dulce y requiere garajes gigantescos encendidos las 24 horas del día.
4. Fórmulas de Cálculo Aplicadas
- Energía Eléctrica Local ($E_{\text{Wh}}$):
$$E_{\text{Wh}} = \frac{P_{\text{Watts}} \times t_{\text{segundos}}}{3600}$$ - Huella de Carbono Estimada ($\text{CO}_2$):
$$\text{Emisiones (g CO}_2) = E_{\text{kWh}} \times I_{\text{carbono}}$$(Intensidad media del mix eléctrico en España: ~160 g $\text{CO}_2$/kWh). - Consumo Hídrico en Datacenters (Nube):
$$\text{Agua Evaporada (ml)} \approx E_{\text{Nube (Wh)}} \times 1.75 \text{ ml/Wh}$$
5. Puesta en Marcha Técnica con Uvicorn
El entorno se ejecuta localmente mediante la arquitectura FastAPI/Uvicorn, conectándose a un LLM local (Qwen en LM Studio) para generar las reflexiones automáticas.
Pasos de ejecución:
- Instalación de dependencias:
PowerShellpip install fastapi uvicorn httpx - Lanzar el servidor con Uvicorn en el puerto
:8067:
PowerShelluvicorn app_huella:app --host 0.0.0.0 --port 8067 --reload - Acceso: Abrir
http://localhost:8067en el navegador del aula.

import asyncio
import os
import time
import httpx
from fastapi import FastAPI, HTTPException
from fastapi.responses import HTMLResponse, JSONResponse
from pydantic import BaseModel
app = FastAPI(title="MonteIA / THEMIS - Huella Energética e Hídrica de la IA")
LM_STUDIO_URL = "http://localhost:1234/v1/chat/completions"
class FootprintRequest(BaseModel):
prompt: str
power_watts: float = 65.0 # Potencia del equipo local en Vatios (ej: 65W portátil)
time_seconds: float = 60.0 # Tiempo de cálculo en la CPU/GPU local en segundos
model_cloud: str = "dall-e-3" # dall-e-3, midjourney, imagen-3, gpt-4o-text
HTML_CONTENT = """
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PROYECTO THEMIS - La Huella de una Pregunta</title>
<style>
:root {
--bg-page: #f8fafc;
--nav-bg: #0f172a;
--banner-bg: #1e1b4b;
--primary-blue: #0284c7;
--primary-red: #e11d48;
--primary-green: #059669;
--primary-amber: #d97706;
--text-main: #0f172a;
--border-color: #cbd5e1;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: var(--bg-page); color: var(--text-main); }
header {
background: var(--nav-bg);
color: white;
padding: 14px 24px;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
}
.header-left { display: flex; align-items: center; gap: 12px; }
.brand-logo { background: #38bdf8; color: #0f172a; font-weight: 900; padding: 6px 10px; border-radius: 6px; font-size: 18px; }
.header-titles h1 { font-size: 18px; font-weight: 800; letter-spacing: 0.5px; display: flex; align-items: center; gap: 8px; }
.header-pills { display: flex; gap: 6px; font-size: 11px; margin-bottom: 2px; }
.pill { padding: 2px 8px; border-radius: 4px; font-weight: 600; text-transform: uppercase; }
.pill-gray { background: rgba(255,255,255,0.15); color: #e2e8f0; }
.pill-red { background: var(--primary-red); color: white; }
.pill-green { background: var(--primary-green); color: white; }
.header-status { background: rgba(34, 197, 94, 0.15); border: 1px solid #22c55e; color: #86efac; padding: 6px 12px; border-radius: 20px; font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 6px; }
.status-dot { width: 8px; height: 8px; background: #22c55e; border-radius: 50%; display: inline-block; }
.container { max-width: 1200px; margin: 24px auto; padding: 0 16px; }
.banner {
background: var(--banner-bg);
color: white;
border-radius: 12px;
padding: 20px 24px;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 24px;
}
.banner-content { display: flex; align-items: center; gap: 16px; }
.banner-icon { background: rgba(255,255,255,0.1); padding: 12px; border-radius: 50%; font-size: 26px; }
.banner-text h2 { font-size: 12px; text-transform: uppercase; color: #818cf8; font-weight: 800; letter-spacing: 0.5px; }
.banner-text p { font-size: 18px; font-weight: 700; margin-top: 2px; }
.banner-badge { background: #312e81; border: 1px solid #6366f1; padding: 10px 14px; border-radius: 8px; font-size: 12px; color: #c7d2fe; max-width: 320px; font-weight: 500; }
.main-grid { display: grid; grid-template-columns: 1fr 1.25fr; gap: 24px; }
.card { background: white; border-radius: 12px; border: 1px solid var(--border-color); padding: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.02); }
.card-title { font-size: 14px; font-weight: 800; text-transform: uppercase; color: #475569; margin-bottom: 16px; display: flex; align-items: center; gap: 8px; }
label { font-size: 13px; font-weight: 700; color: #334155; display: block; margin-bottom: 6px; }
select, input[type="number"], textarea { width: 100%; padding: 10px 12px; border: 1px solid var(--border-color); border-radius: 8px; font-size: 14px; margin-bottom: 14px; font-family: inherit; }
textarea { height: 75px; resize: none; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
/* Cuadritos explicativos de parámetros */
.info-box-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 16px; }
.info-card { background: #f0f9ff; border: 1px solid #bae6fd; border-left: 4px solid var(--primary-blue); padding: 10px 12px; border-radius: 6px; font-size: 12px; color: #0369a1; line-height: 1.4; }
.info-card strong { color: #0369a1; display: block; margin-bottom: 3px; font-size: 12px; }
.btn-primary { width: 100%; padding: 12px; background: var(--primary-blue); color: white; border: none; border-radius: 8px; font-size: 15px; font-weight: 700; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 8px; transition: background 0.2s; }
.btn-primary:hover { background: #0369a1; }
.btn-primary:disabled { background: #94a3b8; cursor: not-allowed; }
.tabs { display: flex; border-bottom: 2px solid var(--border-color); margin-bottom: 16px; }
.tab-btn { padding: 8px 16px; border: none; background: none; font-weight: 700; font-size: 13px; color: #64748b; cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -2px; }
.tab-btn.active { color: var(--primary-blue); border-bottom-color: var(--primary-blue); }
.tab-content { display: none; }
.tab-content.active { display: block; }
/* COMPARATIVA SEPARADA LOCAL vs ONLINE */
.comparison-container { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; }
.mode-box { border-radius: 10px; padding: 16px; border: 2px solid var(--border-color); }
.mode-box.local { background: #f0fdf4; border-color: #86efac; }
.mode-box.cloud { background: #fff1f2; border-color: #fca5a5; }
.mode-header { font-size: 14px; font-weight: 800; text-transform: uppercase; margin-bottom: 12px; display: flex; align-items: center; gap: 6px; }
.mode-box.local .mode-header { color: #166534; }
.mode-box.cloud .mode-header { color: #9f1239; }
.metric-card { background: white; border-radius: 8px; padding: 10px 12px; margin-bottom: 8px; border: 1px solid rgba(0,0,0,0.06); }
.metric-label { font-size: 11px; font-weight: 700; text-transform: uppercase; color: #64748b; }
.metric-val { font-size: 18px; font-weight: 800; margin-top: 2px; }
.mode-box.local .metric-val { color: #15803d; }
.mode-box.cloud .metric-val { color: #be123c; }
.summary-banner { background: #fef3c7; border: 1px solid #fde68a; border-left: 4px solid var(--primary-amber); padding: 12px; border-radius: 8px; font-weight: 700; color: #92400e; margin-bottom: 16px; font-size: 13px; text-align: center; }
/* METÁFORA AUTOBÚS VS BICI */
.analogy-card { background: #faf5ff; border: 1px solid #e9d5ff; padding: 14px; border-radius: 8px; margin-bottom: 12px; }
.analogy-title { font-weight: 800; color: #6b21a8; font-size: 14px; margin-bottom: 6px; display: flex; align-items: center; gap: 6px; }
.analogy-text { font-size: 12.5px; color: #581c87; line-height: 1.5; }
.qwen-box { background: #f0f9ff; border: 1px solid #bae6fd; padding: 14px; border-radius: 8px; font-size: 13px; line-height: 1.5; color: #0369a1; }
.qwen-header { font-weight: 800; color: #0284c7; margin-bottom: 8px; display: flex; align-items: center; gap: 6px; }
.loader { display: none; text-align: center; padding: 20px; color: var(--primary-blue); font-weight: 700; }
</style>
</head>
<body>
<header>
<div class="header-left">
<div class="brand-logo">THEMIS</div>
<div class="header-titles">
<div class="header-pills">
<span class="pill pill-gray">IES MONTERROSO — 1º/2º ESO</span>
<span class="pill pill-green">ALFABETIZACIÓN DE DATOS</span>
</div>
<h1>PROYECTO THEMIS <span class="pill pill-red" style="font-size:10px;">PUERTO :8067</span></h1>
</div>
</div>
<div class="header-status">
<span class="status-dot"></span> Servidor Uvicorn Listo
</div>
</header>
<div class="container">
<div class="banner">
<div class="banner-content">
<div class="banner-icon">🌿</div>
<div class="banner-text">
<h2>TALLER DE IMPACTO AMBIENTAL Y CONSUMO DE LA IA</h2>
<p>La Huella Oculta: ¿Cuánto cuesta responder a una pregunta?</p>
</div>
</div>
<div class="banner-badge">
💡 <strong>Aprendizaje Clave:</strong> Tu portátil no gasta agua. Los Datacenters de la Nube necesitan evaporar litros de agua dulce para enfriarse.
</div>
</div>
<div class="main-grid">
<!-- COLUMNA IZQUIERDA: FORMULARIO Y EXPLICACIÓN DE PARÁMETROS -->
<div class="card">
<div class="card-title">
<span style="color:var(--primary-red);">⚙️</span> 1. CONFIGURA TU PRUEBA
</div>
<label for="presetSelect">Ejemplos recomendados para clase:</label>
<select id="presetSelect">
<option value="">-- Elige un ejemplo rápido --</option>
<option value="Un gato con traje espacial paseando por Marte en HD">Imagen 1: Gato en Marte (Alta calidad)</option>
<option value="Un coche deportivo rojo en una ciudad futurista">Imagen 2: Coche futurista</option>
<option value="Explica la fotosíntesis en tres frases sencillas">Texto 1: Pregunta sobre fotosíntesis</option>
</select>
<label for="promptInput">Consulta / Prompt a analizar:</label>
<textarea id="promptInput" placeholder="Escribe aquí tu petición a la IA...">Un gato con traje espacial paseando por Marte en HD</textarea>
<div class="form-row">
<div>
<label for="powerWatts">Consumo PC (Vatios - W):</label>
<input type="number" id="powerWatts" value="65" min="10" max="300">
</div>
<div>
<label for="timeSeconds">Tiempo CPU (Segundos - s):</label>
<input type="number" id="timeSeconds" value="60" min="1" max="600">
</div>
</div>
<!-- CUADRITOS EXPLICATIVOS DE PARÁMETROS -->
<div class="info-box-grid">
<div class="info-card">
<strong>🔌 1. CONSUMO PC (W):</strong>
La potencia de tu ordenador en cada instante. Un portátil normal gasta ~15W leyendo, pero sube a ~65W cuando la CPU/GPU trabaja al máximo.
</div>
<div class="info-card">
<strong>⏱️ 2. TIEMPO CPU (s):</strong>
Los segundos que tarda la máquina en pensar la respuesta. Si el modelo es muy pesado, la CPU tardará más tiempo activa.
</div>
</div>
<label for="cloudModel">Modelo Online para comparar:</label>
<select id="cloudModel">
<option value="dall-e-3">ChatGPT / DALL-E 3 (Imagen en Datacenter USA)</option>
<option value="midjourney">Midjourney v6 (Servidor GPU de alto consumo)</option>
<option value="imagen-3">Gemini Imagen 3 (Google Datacenter)</option>
<option value="gpt-4o-text">ChatGPT / GPT-4o (Solo Texto)</option>
</select>
<button class="btn-primary" id="calcBtn">
<span>⚡</span> Calcular Huella y Analizar con Qwen
</button>
</div>
<!-- COLUMNA DERECHA: RESULTADOS SEPARADOS Y METÁFORAS -->
<div class="card">
<div class="tabs">
<button class="tab-btn active" onclick="switchTab('tabMetrics', this)">📊 Comparativa Directa</button>
<button class="tab-btn" onclick="switchTab('tabAnalogy', this)">🚲 Metáfora para Clase</button>
<button class="tab-btn" onclick="switchTab('tabQwen', this)">🤖 Dictamen Qwen</button>
</div>
<div id="tabMetrics" class="tab-content active">
<div id="initialMsg" style="text-align:center; padding: 40px; color: #94a3b8;">
<span style="font-size:36px;">🔎</span><br><br>
Pulsa <strong>'Calcular Huella'</strong> para ver la comparativa separada de Energía y Agua.
</div>
<div id="resultsContent" style="display:none;">
<!-- MODO LOCAL VS MODO ONLINE TOTALMENTE SEPARADOS -->
<div class="comparison-container">
<!-- BLOQUE LOCAL -->
<div class="mode-box local">
<div class="mode-header">💻 MODO LOCAL (Tu Portátil)</div>
<div class="metric-card">
<div class="metric-label">⚡ Energía Eléctrica</div>
<div class="metric-val" id="valLocalEnergy">1.08 Wh</div>
</div>
<div class="metric-card">
<div class="metric-label">💧 Agua Potable Evaporada</div>
<div class="metric-val" style="color:#059669;">0 ml</div>
<div style="font-size:10px; color:#166534; font-weight:bold; margin-top:3px;">¡Ventilador de aire directo!</div>
</div>
<div class="metric-card">
<div class="metric-label">🌱 CO₂ Emitido</div>
<div class="metric-val" id="valLocalCo2" style="font-size:14px;">0.17 g</div>
</div>
</div>
<!-- BLOQUE ONLINE -->
<div class="mode-box cloud">
<div class="mode-header">☁️ MODO ONLINE (La Nube)</div>
<div class="metric-card">
<div class="metric-label">⚡ Energía Eléctrica</div>
<div class="metric-val" id="valCloudEnergy">3.80 Wh</div>
</div>
<div class="metric-card">
<div class="metric-label">💧 Agua Potable Evaporada</div>
<div class="metric-val" id="valCloudWater">6.6 ml</div>
<div style="font-size:10px; color:#9f1239; font-weight:bold; margin-top:3px;">Torres de refrigeración con agua dulce</div>
</div>
<div class="metric-card">
<div class="metric-label">🌱 CO₂ Emitido</div>
<div class="metric-val" id="valCloudCo2" style="font-size:14px;">1.44 g</div>
</div>
</div>
</div>
<div class="summary-banner" id="summaryText">
Resumen del impacto ambiental de la consulta.
</div>
</div>
</div>
<!-- METÁFORA PARA 1º/2º ESO -->
<div id="tabAnalogy" class="tab-content">
<div class="analogy-card">
<div class="analogy-title">🚲 Tu Portátil Local = Ir en Bicicleta</div>
<div class="analogy-text">
Haces todo el esfuerzo tú mismo. Puedes tardar un poquito más si la pendiente es empinada (si la CPU es lenta), pero <strong>no gastas ni una sola gota de agua del grifo</strong> ni mantienes gigantescos servidores encendidos en otro país.
</div>
</div>
<div class="analogy-card" style="background:#fff1f2; border-color:#fecdd3;">
<div class="analogy-title" style="color:#9f1239;">🚌 La Nube / Datacenters = Ir en Autobús Público</div>
<div class="analogy-text" style="color:#881337;">
El autobús es súper potente y lleva a muchas personas a la vez (proceso en lote o <i>batching</i>). Por eso el gasto de combustible por persona parece moderado. Sin embargo, <strong>el autobús necesita lavar sus motores con miles de litros de agua dulce constante</strong> y requiere cocheras gigantescas encendidas las 24 horas del día.
</div>
</div>
</div>
<!-- DICTAMEN QWEN -->
<div id="tabQwen" class="tab-content">
<div class="loader" id="qwenLoader">
🤖 Consultando a Qwen en LM Studio...
</div>
<div class="qwen-box" id="qwenBox">
<div class="qwen-header">💡 Explicación Adaptada para Secundaria</div>
<div id="qwenText">
Haz clic en 'Calcular Huella' para ver el análisis de la IA sobre los datos.
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function switchTab(tabId, btn) {
document.querySelectorAll('.tab-content').forEach(el => el.classList.remove('active'));
document.querySelectorAll('.tab-btn').forEach(el => el.classList.remove('active'));
document.getElementById(tabId).classList.add('active');
btn.classList.add('active');
}
document.getElementById('presetSelect').addEventListener('change', (e) => {
if (e.target.value) {
document.getElementById('promptInput').value = e.target.value;
}
});
document.getElementById('calcBtn').addEventListener('click', async () => {
const prompt = document.getElementById('promptInput').value.trim();
const powerWatts = parseFloat(document.getElementById('powerWatts').value) || 65;
const timeSeconds = parseFloat(document.getElementById('timeSeconds').value) || 60;
const cloudModel = document.getElementById('cloudModel').value;
if (!prompt) {
alert('Escribe una pregunta o prompt.');
return;
}
const btn = document.getElementById('calcBtn');
const initialMsg = document.getElementById('initialMsg');
const resultsContent = document.getElementById('resultsContent');
const qwenLoader = document.getElementById('qwenLoader');
const qwenText = document.getElementById('qwenText');
btn.disabled = true;
qwenLoader.style.display = 'block';
try {
const response = await fetch('/v1/calculate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: prompt,
power_watts: powerWatts,
time_seconds: timeSeconds,
model_cloud: cloudModel
})
});
if (!response.ok) throw new Error('Error en el cálculo');
const data = await response.json();
initialMsg.style.display = 'none';
resultsContent.style.display = 'block';
// Asignación de Métricas Locales
document.getElementById('valLocalEnergy').innerText = data.local_energy_wh.toFixed(2) + ' Wh';
document.getElementById('valLocalCo2').innerText = data.local_co2_g.toFixed(2) + ' g';
// Asignación de Métricas Nube
document.getElementById('valCloudEnergy').innerText = data.cloud_energy_wh.toFixed(2) + ' Wh';
document.getElementById('valCloudWater').innerText = '~' + data.cloud_water_ml.toFixed(1) + ' ml';
document.getElementById('valCloudCo2').innerText = data.cloud_co2_g.toFixed(2) + ' g';
// Banner Resumen
document.getElementById('summaryText').innerHTML =
`🌊 <strong>Diferencia clave:</strong> La Nube consume ${data.ratio.toFixed(1)}x más energía y evapora <strong>~${data.cloud_water_ml.toFixed(1)} ml de agua potable</strong>. ¡Tu portátil se enfría por aire y gasta 0 ml!`;
qwenText.innerText = data.qwen_analysis;
} catch (err) {
alert('No se pudo completar el análisis.');
} finally {
btn.disabled = false;
qwenLoader.style.display = 'none';
}
});
</script>
</body>
</html>
"""
@app.get("/", response_class=HTMLResponse)
async def serve_index():
return HTML_CONTENT
@app.post("/v1/calculate")
async def calculate_footprint(req: FootprintRequest):
# 1. Cálculo Energético Local (PC)
local_energy_wh = (req.power_watts * req.time_seconds) / 3600.0
local_co2_g = local_energy_wh * 0.16 # Mix eléctrico España
# 2. Factores para la Nube según investigación empírica
cloud_power_factors = {
"dall-e-3": {"energy_base_wh": 3.80, "co2_g": 1.44, "water_ml": 6.65, "name": "ChatGPT / DALL-E 3"},
"midjourney": {"energy_base_wh": 3.20, "co2_g": 1.21, "water_ml": 5.60, "name": "Midjourney v6"},
"imagen-3": {"energy_base_wh": 2.70, "co2_g": 1.02, "water_ml": 4.72, "name": "Gemini Imagen 3"},
"gpt-4o-text": {"energy_base_wh": 0.30, "co2_g": 0.11, "water_ml": 0.50, "name": "ChatGPT Texto (GPT-4o)"}
}
cloud_data = cloud_power_factors.get(req.model_cloud, cloud_power_factors["dall-e-3"])
# Ajuste suave por longitud del prompt
prompt_factor = min(1.4, max(0.8, len(req.prompt) / 45.0))
cloud_energy_wh = cloud_data["energy_base_wh"] * prompt_factor
cloud_co2_g = cloud_data["co2_g"] * prompt_factor
cloud_water_ml = cloud_data["water_ml"] * prompt_factor
ratio = cloud_energy_wh / max(0.001, local_energy_wh)
# 3. Respuesta con LM Studio / Qwen con la metáfora del autobús
qwen_analysis = ""
try:
async with httpx.AsyncClient(timeout=3.5) as client:
system_prompt = (
"Eres un docente de la línea THEMIS enseñando alfabetización de datos a alumnos de 1º y 2º de ESO. "
"Explica brevemente (máximo 3 frases) el resultado del cálculo: "
f"Prompt: '{req.prompt}'. Tu portátil consumió {local_energy_wh:.2f} Wh y 0 ml de agua dulce. "
f"La Nube ({cloud_data['name']}) consumió {cloud_energy_wh:.2f} Wh y evaporó {cloud_water_ml:.1f} ml de agua. "
"Usa la analogía de la bicicleta (portátil, 0ml agua) frente al autobús de la nube (evapora agua para enfriarse)."
)
payload = {
"messages": [
{"role": "system", "content": system_prompt},
{"role": "user", "content": "Genera el dictamen pedagógico."}
],
"temperature": 0.6,
"max_tokens": 180
}
res = await client.post(LM_STUDIO_URL, json=payload)
if res.status_code == 200:
qwen_analysis = res.json()["choices"][0]["message"]["content"]
except Exception:
qwen_analysis = (
f"Dictamen THEMIS: Ejecutar esta petición localmente consume {local_energy_wh:.2f} Wh de electricidad "
f"y exactamente 0 ml de agua dulce porque tu portátil se enfría solo con aire. "
f"En cambio, procesarlo en la nube con {cloud_data['name']} requiere unos {cloud_energy_wh:.2f} Wh "
f"y evapora aproximadamente {cloud_water_ml:.1f} ml de agua potable en las torres de refrigeración del servidor. "
"¡El gran impacto de la Nube no es solo la luz, sino el agua dulce potable que evapora!"
)
return JSONResponse({
"local_energy_wh": local_energy_wh,
"local_co2_g": local_co2_g,
"cloud_energy_wh": cloud_energy_wh,
"cloud_co2_g": cloud_co2_g,
"cloud_water_ml": cloud_water_ml,
"ratio": ratio,
"qwen_analysis": qwen_analysis
})
6. Dinámica de Debate THEMIS en el Aula
Durante la sesión práctica, el alumnado completa la hoja de trabajo analizando los siguientes puntos:
- El valor del agua potable: ¿Por qué un servidor en la Nube gasta agua dulce y no agua de mar? (El agua de mar corroería los sistemas de refrigeración).
- Efecto Rebote en el portátil: Si un ordenador muy antiguo tarda 5 minutos (300 s) al 100% de CPU en generar una respuesta, ¿sigue siendo más eficiente que la Nube?
- Uso Responsable: Identificar qué tareas justifican el uso de un modelo en la nube y cuáles deben resolverse con modelos locales reducidos o herramientas tradicionales para proteger los recursos hídricos y energéticos.
Etiqueta:1ESO, 2eso, AIDARAC, alfabetizacion de datos, fastapi, green ai, huella ecologica, ies monterroso, lm studio, montesteam, qwen, sostenibilidad, themis, uvicorn



