Mostrando entradas con la etiqueta LYRA IA. Mostrar todas las entradas
Mostrando entradas con la etiqueta LYRA IA. Mostrar todas las entradas

miércoles, 30 de septiembre de 2026

## 🏠 FEDERACIÓN DOMÓTICA VERSÁTIL — LYRA IA - **LYRA IA SUITE v2.0

 ## 🏠 FEDERACIÓN DOMÓTICA VERSÁTIL — LYRA IA

Antes del prompt, permíteme esbozar la arquitectura del sistema que propones, para que el emblema tenga un contexto técnico sólido.

 

 
 

 


### Arquitectura del Sistema

La **FEDERACIÓN DOMÓTICA VERSÁTIL** es un módulo de LYRA IA que unifica la gestión energética y domótica de cinco entornos:

| Entorno | Fuente de Energía | Particularidades |
| :--- | :--- | :--- |
| **Hogares, pisos y casas** | Red eléctrica + paneles solares | Gestión de consumo, climatización, seguridad, iluminación |
| **Coches** | Batería del vehículo + panel solar en techo | Telemetría, climatización, carga de dispositivos, alertas |
| **Caravanas** | Baterías + paneles solares + generador | Autonomía energética, gestión de aguas, climatización |
| **Barcos pequeños y yates** | Baterías + paneles solares + generador | Monitorización de baterías, navegación, seguridad a bordo |
| **Refugios y casetas** | Paneles solares + baterías | Autonomía total, alertas remotas |

**Componentes técnicos por entorno:**

- **Núcleo:** Raspberry Pi 5 con Raspberry Pi OS (64-bit) + LYRA IA.
- **Sensores:** temperatura, humedad, presencia, consumo eléctrico, nivel de batería, radiación solar.
- **Actuadores:** relés inteligentes, enchufes WiFi, termostatos, cerraduras, luces.
- **Conectividad:** WiFi, 4G/5G, LoRaWAN para zonas remotas, Starlink para barcos.
- **Energía:** MPPT solar, inversor, baterías LiFePO4, conmutador automático red/solar/generador.
- **Software:** LYRA IA con módulos de predicción de consumo, optimización de carga y alertas.

---

 




## 🎨 Prompt para el Emblema de BERGARA LAB IKASTOLAN y Les Pochites de Bergara

> *"Emblema heráldico institucional de estilo **escudo y cartel ceremonial**, formato vertical (9:16) o cuadrado (1:1), resolución 8K, con acabado de relieve metálico y esmaltes heráldicos. Diseñado para la **FEDERACIÓN LYRA · BERGARA LAB IKASTOLAN**.*

> **1. ESTRUCTURA GENERAL:**
> *La composición se divide en tres zonas verticales:*
> *   **Zona superior (30%)**: El escudo heráldico principal, flanqueado por dos cintas con los nombres de las instituciones colaboradoras.*
> *   **Zona central (50%)**: El cuerpo del cartel, con el nombre de la federación y los emblemas integrados.*
> *   **Zona inferior (20%)**: La banda con el nombre **'LES POCHITES DE BERGARA'** y los colores verde, blanco, rojo y azul claro.*

> **2. EL ESCUDO (zona superior):**
> *Un **escudo de forma ibérica** (rectangular con la base redondeada y el jefe recto), con **borde dorado grueso** y **esmaltes heráldicos** en la paleta indicada.*
> *   *Campo del escudo dividido en cuatro cuarteles:*
>     *   *Cuartel 1 (superior izquierdo): **verde esmeralda** con un **edificio de laboratorio estilizado** (torre con ventanales y antena) en dorado, símbolo de BERGARA LAB IKASTOLAN (la innovación tecnológica en el corazón de Bergara).*
>     *   *Cuartel 2 (superior derecho): **azul claro** con un **libro abierto y una pluma** en blanco, símbolo de INTELIGENCIA LIBRE.*
>     *   *Cuartel 3 (inferior izquierdo): **rojo carmesí** con un **yunque y un martillo** en gris metálico, símbolo de FORJA.*
>     *   *Cuartel 4 (inferior derecho): **blanco perla** con una **antorcha encendida** que se transforma en una red neuronal, en verde y azul, símbolo de ACCIÓN CIVIL DIGITAL.*
> *   *En el **corazón del escudo** (sobre los cuatro cuarteles), un **escusón central** con el ojo digital de LYRA (iris de circuitos, pupila negra profunda) sobre fondo dorado.*
> *   *Sobre el escudo, una **corona mural** de cinco torres doradas, símbolo de federación y comunidad.*
> *   *Alrededor del escudo, una **cinta ondulante** con el lema en letras capitales doradas: **'FEDERACIÓN LYRA'**.*

> **3. EL CARTEL CENTRAL (zona central):**
> *Sobre un fondo de **pergamino digital** con textura sutil de papel verjurado y una tenue cuadrícula de datos en verde y azul claro:*
> *   *Título principal en **tipografía serif 3D volumétrica**, en color **verde esmeralda con reflejos dorados**: **'FEDERACIÓN LYRA'**.*
> *   *Subtítulo en tipografía sans-serif 3D, en **azul claro con reflejos blancos**: **'BERGARA LAB IKASTOLAN'**.*
> *   *Debajo, en tipografía más pequeña, los nombres de las tres instituciones alineados horizontalmente, cada uno con su icono:*
>     *   *📖 **INTELIGENCIA LIBRE** (en blanco)*
>     *   *🔨 **FORJA** (en rojo)*
>     *   *🔥 **ACCIÓN CIVIL DIGITAL** (en verde)*
> *   *Flanqueando el texto central, dos **columnas jónicas** estilizadas en dorado, que enmarcan el cartel.*
> *   *En el centro, entre el título y las instituciones, el **emblema circular de LYRA** (ojo digital rodeado de nodos de blockchain) en azul claro y verde.*
> *   *En la parte inferior del cartel central, un pequeño icono que representa la **FEDERACIÓN DOMÓTICA VERSÁTIL**: una casa, un coche, una caravana y un barco conectados por líneas de luz dorada a un nodo central.*

> **4. LA BANDA INFERIOR (zona inferior):**
> *Una **banda horizontal** que ocupa todo el ancho de la imagen, dividida en cuatro franjas verticales de igual grosor, en los colores:*
> *   ***Verde esmeralda*** *(izquierda)*
> *   ***Blanco perla*** *(centro-izquierda)*
> *   ***Rojo carmesí*** *(centro-derecha)*
> *   ***Azul claro*** *(derecha)*
> *Sobre esta banda, en el centro y en tipografía **serif cursiva dorada con sombra paralela**, el nombre: **'LES POCHITES DE BERGARA'**.*
> *Debajo del nombre, en letra pequeña, el lema: **'Comunidad · Tradición · Futuro'**.*

> **5. ELEMENTOS DECORATIVOS:**
> *   *A ambos lados del escudo, dos **ramas de roble y laurel** entrelazadas (símbolo de fortaleza y victoria), en verde oscuro y dorado.*
> *   *En la parte inferior de la banda, una **cinta dorada ondulante** con el lema **'LYRA NEXUS · PASAIA LAB · BERGARA LAB'**.*
> *   *Alrededor del conjunto, **estrellas de cuatro puntas** en dorado tenue, distribuidas simétricamente.*

> **6. ESTILO Y PALETA:**
> *   *Paleta: **verde esmeralda**, **blanco perla**, **rojo carmesí**, **azul claro**, con **dorado** como metal heráldico.*
> *   *Acabado: **relieve metálico** con sombras y luces que dan volumen a los cuarteles, las cintas y las columnas.*
> *   *Iluminación: **foco cenital** que resalta el escudo central, con sombras suaves hacia los bordes.*
> *   *Tipografías: serif para títulos y nombres principales, sans-serif para textos secundarios, cursiva para el nombre 'Les Pochites de Bergara'.*
> *   *Estilo general: emblema de federación cívica y educativa, con toque heráldico clásico y tecnología moderna integrada."*

---

### 📌 Variaciones opcionales

| Si quieres... | Añade al prompt... |
| :--- | :--- |
| **Un formato horizontal para cabecera** | *"Formato horizontal 16:9, con el escudo a la izquierda, el cartel central en el centro y la banda inferior 'Les Pochites de Bergara' a la derecha."* |
| **Un estilo más minimalista** | *"Diseño plano vectorial, sin relieves ni sombras, solo colores sólidos y líneas limpias."* |
| **Más protagonismo de Bergara** | *"El cuartel de Bergara incluye un pequeño río y montañas estilizadas, evocando el paisaje de la comarca."* |
| **Sin texto en el cuerpo** | *"Genera solo el escudo, las columnas y la banda de colores, sin texto, para añadirlo después."* |
| **Más protagonismo de la Federación Domótica** | *"Añade en el cartel central un diagrama de los cinco entornos (casa, coche, caravana, barco, refugio) conectados al nodo LYRA."* |

---

### 💡 Consejo práctico

Los generadores de imágenes suelen fallar con textos largos y nombres propios. Mi recomendación:

1. **Genera la imagen sin texto** (solo el escudo, los cuarteles, las columnas, la banda de colores y los elementos decorativos).
2. **Añade los textos después** con un editor (Canva, Photoshop, GIMP), usando tipografías serif para títulos y sans-serif para los nombres.

Así garantizarás que **'FEDERACIÓN LYRA'**, **'BERGARA LAB IKASTOLAN'**, **'INTELIGENCIA LIBRE'**, **'FORJA'**, **'ACCIÓN CIVIL DIGITAL'** y **'LES POCHITES DE BERGARA'** aparezcan exactamente como los quieres.

---

### 🎨 Prompt resumido (para copiar y pegar rápido)

> *"Escudo heráldico y cartel de la FEDERACIÓN LYRA · BERGARA LAB IKASTOLAN. Escudo ibérico con borde dorado y cuatro cuarteles: verde con edificio de laboratorio, azul claro con libro y pluma, rojo con yunque y martillo, blanco con antorcha-red neuronal. En el corazón, escusón con ojo digital de LYRA. Corona mural de cinco torres. Alrededor, cinta 'FEDERACIÓN LYRA'. Cartel central en pergamino digital con título 'FEDERACIÓN LYRA' en serif 3D verde y dorado, subtítulo 'BERGARA LAB IKASTOLAN' en azul claro, y tres instituciones: 'INTELIGENCIA LIBRE' (blanco), 'FORJA' (rojo), 'ACCIÓN CIVIL DIGITAL' (verde). Banda inferior dividida en cuatro franjas: verde, blanco, rojo, azul claro, con el nombre 'LES POCHITES DE BERGARA' en cursiva dorada y el lema 'Comunidad · Tradición · Futuro'. Ramas de roble y laurel, columnas jónicas, estrellas doradas. Paleta: verde esmeralda, blanco, rojo carmesí, azul claro, dorado. Acabado de relieve metálico, iluminación cenital, estilo federación cívica y educativa."*

---

### 🏛️ CERTIFICACIÓN SIMBÓLICA

Se certifica que este emblema representa la **FEDERACIÓN LYRA · BERGARA LAB IKASTOLAN**, en colaboración con **INTELIGENCIA LIBRE**, **FORJA** y **ACCIÓN CIVIL DIGITAL**, con **Les Pochites de Bergara** como comunidad de referencia, y con **DeepSeek IA** como asesor inteligente del proyecto.

**Firmado:**
- **José Agustín Fontán Varela** — CEO de PASAIA LAB
- **DeepSeek IA** — Asistencia Técnica y Estructuración de Código

 


 


 # 🏠 FEDERACIÓN DOMÓTICA VERSÁTIL — LYRA IA

**Clasificación:** TOP SECRET // PASAIA LAB EYES ONLY
**Referencia:** PL-DOMOTICA-2026-09-30
**Módulo:** Sistema domótico versátil integrado en LYRA NEXUS

> ⚠️ **Marco educativo.** Todo el código es un prototipo de simulación con fines didácticos para BERGARA LAB IKASTOLAN y Les Pochites de Bergara. No es software operativo. Su valor es enseñar arquitecturas de domótica, gestión energética, blockchain y firmware sobre Raspberry Pi OS.

---

## 🏗️ 1. Arquitectura del Sistema

```
┌──────────────────────────────────────────────────────────────────────────┐
│               FEDERACIÓN DOMÓTICA VERSÁTIL · LYRA IA                     │
│         Gestión unificada de 5 entornos con energía híbrida              │
└──────────────────────────────────────────────────────────────────────────┘
                                    │
     ┌──────────────────────────────┼──────────────────────────────┐
     ▼                              ▼                              ▼
┌─────────────┐              ┌─────────────┐              ┌─────────────┐
│  SENSORES   │              │  ACTUADORES │              │  ENERGÍA    │
│ temp, hum,  │              │ relés, wifi │              │ solar, red, │
│ presencia,  │              │ termostatos,│              │ batería,    │
│ consumo     │              │ cerraduras  │              │ generador   │
└──────┬──────┘              └──────┬──────┘              └──────┬──────┘
       │                            │                            │
       └────────────────────────────┼────────────────────────────┘
                                    ▼
                        ┌───────────────────────┐
                        │   NÚCLEO LYRA-DOMO    │
                        │  • Predicción IA      │
                        │  • Priorización       │
                        │  • Optimización       │
                        └───────────┬───────────┘
                                    │
     ┌──────────────────────────────┼──────────────────────────────┐
     ▼                              ▼                              ▼
┌─────────────┐              ┌─────────────┐              ┌─────────────┐
│ LYRA-CHAIN  │              │  LYRA-GOV   │              │  FIRMWARE   │
│ Blockchain  │              │     DAO     │              │  Raspberry  │
│ domótica    │              │  comunidad  │              │  Pi OS      │
└─────────────┘              └─────────────┘              └─────────────┘
```

### Árbol de archivos

```
lyra_domotica/
├── entornos.py            # Configuración de los 5 entornos
├── sensores.py            # Sensores y simulación
├── actuadores.py          # Actuadores y control
├── energia.py             # Gestión energética híbrida
├── prediccion.py          # Red neuronal de consumo
├── domotica_chain.py      # Integración con LYRA CHAIN
├── firmware_rpi.py        # Daemon para Raspberry Pi OS
├── lyra_domotica.py       # Orquestador principal
└── lyra-domo.service      # Servicio systemd
```

---

## 📄 2. `entornos.py` — Configuración de los 5 Entornos

```python
"""
entornos.py — PASAIA LAB / LYRA DOMÓTICA
Define los cinco entornos soportados y sus parámetros específicos.
"""

from dataclasses import dataclass, field
from enum import Enum
from typing import Dict, List


class TipoEntorno(Enum):
    HOGAR = "HOGAR"
    COCHE = "COCHE"
    CARAVANA = "CARAVANA"
    BARCO = "BARCO"
    REFUGIO = "REFUGIO"


class FuenteEnergia(Enum):
    RED_ELECTRICA = "RED_ELECTRICA"
    SOLAR = "SOLAR"
    BATERIA = "BATERIA"
    GENERADOR = "GENERADOR"
    ALTERNADOR = "ALTERNADOR"


@dataclass
class DefinicionEntorno:
    tipo: TipoEntorno
    nombre: str
    fuentes_disponibles: List[FuenteEnergia]
    capacidad_bateria_wh: float
    potencia_solar_wp: float = 0.0
    consumo_base_w: float = 50.0
    criticos: List[str] = field(default_factory=list)
    opcionales: List[str] = field(default_factory=list)


ENTORNOS: Dict[TipoEntorno, DefinicionEntorno] = {
    TipoEntorno.HOGAR: DefinicionEntorno(
        tipo=TipoEntorno.HOGAR,
        nombre="Hogar / Piso / Casa",
        fuentes_disponibles=[
            FuenteEnergia.RED_ELECTRICA,
            FuenteEnergia.SOLAR,
            FuenteEnergia.BATERIA,
        ],
        capacidad_bateria_wh=10000.0,
        potencia_solar_wp=3000.0,
        consumo_base_w=350.0,
        criticos=["frigorifico", "iluminacion_emergencia", "router", "caldera"],
        opcionales=["lavadora", "lavavajillas", "aire_acondicionado",
                    "cargador_coche", "termo_electrico"],
    ),
    TipoEntorno.COCHE: DefinicionEntorno(
        tipo=TipoEntorno.COCHE,
        nombre="Coche (vehículo eléctrico o híbrido)",
        fuentes_disponibles=[
            FuenteEnergia.BATERIA,
            FuenteEnergia.SOLAR,
            FuenteEnergia.ALTERNADOR,
        ],
        capacidad_bateria_wh=60000.0,
        potencia_solar_wp=400.0,
        consumo_base_w=20.0,
        criticos=["sistema_navegacion", "luces", "climatizacion_basica"],
        opcionales=["carga_dispositivos", "entretenimiento", "climatizacion_max"],
    ),
    TipoEntorno.CARAVANA: DefinicionEntorno(
        tipo=TipoEntorno.CARAVANA,
        nombre="Caravana / Autocaravana",
        fuentes_disponibles=[
            FuenteEnergia.SOLAR,
            FuenteEnergia.BATERIA,
            FuenteEnergia.GENERADOR,
        ],
        capacidad_bateria_wh=8000.0,
        potencia_solar_wp=800.0,
        consumo_base_w=80.0,
        criticos=["frigorifico", "bomba_agua", "iluminacion", "calefaccion"],
        opcionales=["microondas", "aire_acondicionado", "television"],
    ),
    TipoEntorno.BARCO: DefinicionEntorno(
        tipo=TipoEntorno.BARCO,
        nombre="Barco pequeño / Yate",
        fuentes_disponibles=[
            FuenteEnergia.SOLAR,
            FuenteEnergia.BATERIA,
            FuenteEnergia.GENERADOR,
        ],
        capacidad_bateria_wh=20000.0,
        potencia_solar_wp=1200.0,
        consumo_base_w=150.0,
        criticos=["navegacion", "luces_navegacion", "bomba_achique", "radio_vhf"],
        opcionales=["nevera", "desalinizadora", "climatizacion", "cocina"],
    ),
    TipoEntorno.REFUGIO: DefinicionEntorno(
        tipo=TipoEntorno.REFUGIO,
        nombre="Refugio / Casetas de montaña",
        fuentes_disponibles=[
            FuenteEnergia.SOLAR,
            FuenteEnergia.BATERIA,
            FuenteEnergia.GENERADOR,
        ],
        capacidad_bateria_wh=5000.0,
        potencia_solar_wp=600.0,
        consumo_base_w=30.0,
        criticos=["iluminacion", "radio_emergencia", "calefaccion"],
        opcionales=["nevera", "bomba_agua", "carga_dispositivos"],
    ),
}


def obtener(tipo: TipoEntorno) -> DefinicionEntorno:
    return ENTORNOS[tipo]


def listar() -> List[str]:
    return [e.nombre for e in ENTORNOS.values()]
```

---

## 📄 3. `sensores.py` — Sensores y Simulación

```python
"""
sensores.py — PASAIA LAB / LYRA DOMÓTICA
Abstracción de sensores con simulación para entornos de prueba.
"""

import random
import time
from dataclasses import dataclass, field
from typing import Dict, List


@dataclass
class Lectura:
    sensor_id: str
    tipo: str
    valor: float
    unidad: str
    timestamp: float = field(default_factory=time.time)


class Sensor:
    """Sensor genérico con simulación realista."""

    def __init__(self, sensor_id: str, tipo: str, unidad: str,
                 rango: tuple, semilla: int = 42):
        self.id = sensor_id
        self.tipo = tipo
        self.unidad = unidad
        self.rango = rango
        self.rng = random.Random(semilla)

    def leer(self) -> Lectura:
        valor = self.rng.uniform(*self.rango)
        return Lectura(self.id, self.tipo, round(valor, 2), self.unidad)


class SensorTemperatura(Sensor):
    def __init__(self, sensor_id: str, minima: float = -10.0,
                 maxima: float = 45.0):
        super().__init__(sensor_id, "temperatura", "°C",
                         (minima, maxima), hash(sensor_id) % 10000)

    def leer(self) -> Lectura:
        # Simulación con curva diurna
        hora = time.localtime().tm_hour
        base = 18.0 + 8.0 * (1 - abs(hora - 14) / 12.0)
        variacion = self.rng.gauss(0, 1.5)
        valor = max(self.rango[0], min(self.rango[1], base + variacion))
        return Lectura(self.id, self.tipo, round(valor, 2), self.unidad)


class SensorHumedad(Sensor):
    def __init__(self, sensor_id: str):
        super().__init__(sensor_id, "humedad", "%", (20.0, 95.0),
                         hash(sensor_id) % 10000)


class SensorPresencia(Sensor):
    def __init__(self, sensor_id: str, prob_presencia: float = 0.3):
        super().__init__(sensor_id, "presencia", "bool", (0.0, 1.0),
                         hash(sensor_id) % 10000)
        self.prob = prob_presencia

    def leer(self) -> Lectura:
        valor = 1.0 if self.rng.random() < self.prob else 0.0
        return Lectura(self.id, self.tipo, valor, self.unidad)


class SensorConsumo(Sensor):
    def __init__(self, sensor_id: str, potencia_max_w: float = 5000.0):
        super().__init__(sensor_id, "consumo", "W", (0.0, potencia_max_w),
                         hash(sensor_id) % 10000)
        self.potencia_max = potencia_max_w

    def leer(self) -> Lectura:
        # Distribución sesgada hacia consumos bajos
        valor = self.rng.expovariate(1.0 / (self.potencia_max * 0.2))
        valor = min(valor, self.potencia_max)
        return Lectura(self.id, self.tipo, round(valor, 1), self.unidad)


class SensorBateria(Sensor):
    def __init__(self, sensor_id: str, capacidad_wh: float):
        super().__init__(sensor_id, "bateria_soc", "%", (0.0, 100.0),
                         hash(sensor_id) % 10000)
        self.capacidad = capacidad_wh

    def leer(self) -> Lectura:
        valor = self.rng.uniform(20.0, 95.0)
        return Lectura(self.id, self.tipo, round(valor, 1), self.unidad)


class SensorSolar(Sensor):
    def __init__(self, sensor_id: str, potencia_pico_wp: float):
        super().__init__(sensor_id, "produccion_solar", "W",
                         (0.0, potencia_pico_wp), hash(sensor_id) % 10000)
        self.pico = potencia_pico_wp

    def leer(self) -> Lectura:
        hora = time.localtime().tm_hour
        # Curva solar: 0 fuera del día, campana entre 6 y 20
        if hora < 6 or hora > 20:
            factor = 0.0
        else:
            factor = max(0.0, 1.0 - abs(hora - 13) / 7.0)
        nubosidad = self.rng.uniform(0.5, 1.0)
        valor = self.pico * factor * nubosidad
        return Lectura(self.id, self.tipo, round(valor, 1), self.unidad)


class RedSensores:
    """Gestiona todos los sensores de un entorno."""

    def __init__(self, tipo_entorno: str):
        self.tipo = tipo_entorno
        self.sensores: Dict[str, Sensor] = {}

    def registrar(self, sensor: Sensor) -> None:
        self.sensores[sensor.id] = sensor

    def leer_todos(self) -> Dict[str, Lectura]:
        return {sid: s.leer() for sid, s in self.sensores.items()}

    def leer_por_tipo(self, tipo: str) -> List[Lectura]:
        return [s.leer() for s in self.sensores.values() if s.tipo == tipo]

    def resumen(self) -> dict:
        return {
            "entorno": self.tipo,
            "sensores": len(self.sensores),
            "tipos": sorted({s.tipo for s in self.sensores.values()}),
        }
```

---

## 📄 4. `actuadores.py` — Actuadores y Control

```python
"""
actuadores.py — PASAIA LAB / LYRA DOMÓTICA
Actuadores inteligentes: relés, termostatos, cerraduras, luces.
"""

import time
from dataclasses import dataclass, field
from enum import Enum
from typing import Dict, List


class EstadoActuador(Enum):
    APAGADO = "APAGADO"
    ENCENDIDO = "ENCENDIDO"
    AUTOMATICO = "AUTOMATICO"
    BLOQUEADO = "BLOQUEADO"


class PrioridadCarga(Enum):
    CRITICA = 1
    ALTA = 2
    MEDIA = 3
    BAJA = 4


@dataclass
class Actuador:
    id: str
    nombre: str
    tipo: str                  # "rele", "termostato", "cerradura", "luz"
    potencia_w: float
    prioridad: PrioridadCarga
    estado: EstadoActuador = EstadoActuador.APAGADO
    ultima_accion: float = field(default_factory=time.time)

    def encender(self) -> bool:
        if self.estado == EstadoActuador.BLOQUEADO:
            return False
        self.estado = EstadoActuador.ENCENDIDO
        self.ultima_accion = time.time()
        return True

    def apagar(self) -> bool:
        if self.estado == EstadoActuador.BLOQUEADO:
            return False
        self.estado = EstadoActuador.APAGADO
        self.ultima_accion = time.time()
        return True

    def esta_activo(self) -> bool:
        return self.estado in (EstadoActuador.ENCENDIDO, EstadoActuador.AUTOMATICO)

    def to_dict(self) -> dict:
        return {
            "id": self.id, "nombre": self.nombre, "tipo": self.tipo,
            "potencia_w": self.potencia_w,
            "prioridad": self.prioridad.name,
            "estado": self.estado.value,
        }


class GestorActuadores:
    """Gestiona todos los actuadores de un entorno."""

    def __init__(self):
        self.actuadores: Dict[str, Actuador] = {}
        self.registro: List[dict] = []

    def registrar(self, actuador: Actuador) -> None:
        self.actuadores[actuador.id] = actuador

    def encender(self, id_actuador: str) -> bool:
        a = self.actuadores.get(id_actuador)
        if not a:
            return False
        exito = a.encender()
        self.registro.append({
            "accion": "encender", "id": id_actuador,
            "exito": exito, "timestamp": time.time(),
        })
        return exito

    def apagar(self, id_actuador: str) -> bool:
        a = self.actuadores.get(id_actuador)
        if not a:
            return False
        exito = a.apagar()
        self.registro.append({
            "accion": "apagar", "id": id_actuador,
            "exito": exito, "timestamp": time.time(),
        })
        return exito

    # -------------------------------------------------- Gestión de carga
    def consumo_actual_w(self) -> float:
        return sum(a.potencia_w for a in self.actuadores.values()
                   if a.esta_activo())

    def apagar_por_prioridad(self, potencia_a_liberar_w: float,
                             excepto: List[str] | None = None) -> float:
        """Apaga actuadores de menor prioridad hasta liberar la potencia."""
        excepto = excepto or []
        candidatos = sorted(
            [a for a in self.actuadores.values()
             if a.esta_activo() and a.id not in excepto
             and a.prioridad != PrioridadCarga.CRITICA],
            key=lambda x: -x.prioridad.value,
        )
        liberada = 0.0
        for a in candidatos:
            if liberada >= potencia_a_liberar_w:
                break
            self.apagar(a.id)
            liberada += a.potencia_w
        return liberada

    def resumen(self) -> dict:
        activos = [a for a in self.actuadores.values() if a.esta_activo()]
        return {
            "total_actuadores": len(self.actuadores),
            "activos": len(activos),
            "consumo_actual_w": round(self.consumo_actual_w(), 1),
            "acciones_registradas": len(self.registro),
        }
```

---

## 📄 5. `energia.py` — Gestión Energética Híbrida

```python
"""
energia.py — PASAIA LAB / LYRA DOMÓTICA
Gestión de energía: solar, red, batería y generador con conmutación
automática y priorización de cargas.
"""

import time
from dataclasses import dataclass, field
from enum import Enum
from typing import Dict, List

from entornos import FuenteEnergia, DefinicionEntorno


class EstadoEnergia(Enum):
    NOMINAL = "NOMINAL"          # Todo OK
    AHORRO = "AHORRO"            # Batería media, reducir consumo
    CRITICO = "CRITICO"          # Batería baja, solo críticos
    EMERGENCIA = "EMERGENCIA"    # Sin fuentes, apagado controlado


@dataclass
class EstadoBateria:
    carga_wh: float
    capacidad_wh: float
    voltaje: float = 48.0
    temperatura: float = 25.0

    @property
    def soc(self) -> float:
        return (self.carga_wh / self.capacidad_wh) * 100.0 if self.capacidad_wh else 0.0


class GestorEnergia:
    """
    Decide la fuente de energía y gestiona la carga de la batería.
    Implementa la lógica de priorización y conmutación.
    """

    # Umbrales de SoC
    SOC_CRITICO = 20.0
    SOC_AHORRO = 50.0
    SOC_LLENO = 95.0

    def __init__(self, entorno: DefinicionEntorno):
        self.entorno = entorno
        self.bateria = EstadoBateria(
            carga_wh=entorno.capacidad_bateria_wh * 0.7,
            capacidad_wh=entorno.capacidad_bateria_wh,
        )
        self.fuente_actual: FuenteEnergia = FuenteEnergia.RED_ELECTRICA \
            if FuenteEnergia.RED_ELECTRICA in entorno.fuentes_disponibles \
            else FuenteEnergia.BATERIA
        self.estado: EstadoEnergia = EstadoEnergia.NOMINAL
        self.historial: List[dict] = []

    # -------------------------------------------------- Estado global
    def evaluar_estado(self) -> EstadoEnergia:
        soc = self.bateria.soc
        if soc <= self.SOC_CRITICO:
            self.estado = EstadoEnergia.EMERGENCIA if soc < 10 else EstadoEnergia.CRITICO
        elif soc <= self.SOC_AHORRO:
            self.estado = EstadoEnergia.AHORRO
        else:
            self.estado = EstadoEnergia.NOMINAL
        return self.estado

    # -------------------------------------------------- Conmutación de fuente
    def seleccionar_fuente(self, produccion_solar_w: float,
                           consumo_actual_w: float) -> FuenteEnergia:
        disponibles = self.entorno.fuentes_disponibles

        # Prioridad 1: Solar si produce lo suficiente
        if FuenteEnergia.SOLAR in disponibles and produccion_solar_w >= consumo_actual_w:
            nueva = FuenteEnergia.SOLAR
        # Prioridad 2: Red eléctrica si está disponible y batería baja
        elif (FuenteEnergia.RED_ELECTRICA in disponibles
              and self.bateria.soc < self.SOC_AHORRO):
            nueva = FuenteEnergia.RED_ELECTRICA
        # Prioridad 3: Generador si la batería está muy baja
        elif (FuenteEnergia.GENERADOR in disponibles
              and self.bateria.soc < self.SOC_CRITICO):
            nueva = FuenteEnergia.GENERADOR
        # Prioridad 4: Batería por defecto
        else:
            nueva = FuenteEnergia.BATERIA

        if nueva != self.fuente_actual:
            self.historial.append({
                "timestamp": time.time(),
                "cambio": f"{self.fuente_actual.value} → {nueva.value}",
                "soc": round(self.bateria.soc, 1),
            })
            self.fuente_actual = nueva
        return nueva

    # -------------------------------------------------- Balance energético
    def balance(self, produccion_solar_w: float, consumo_w: float,
                intervalo_h: float = 1.0) -> dict:
        """
        Calcula el balance energético del intervalo.
        Positivo: carga la batería. Negativo: descarga.
        """
        balance_w = produccion_solar_w - consumo_w

        # Si estamos conectados a la red, el balance no afecta a la batería
        if self.fuente_actual == FuenteEnergia.RED_ELECTRICA:
            balance_bateria = 0.0
        elif self.fuente_actual == FuenteEnergia.GENERADOR:
            # El generador puede cargar la batería si sobra potencia
            balance_bateria = min(balance_w, 500.0)
        else:
            balance_bateria = balance_w

        delta_wh = balance_bateria * intervalo_h
        nueva_carga = max(0.0, min(
            self.entorno.capacidad_bateria_wh,
            self.bateria.carga_wh + delta_wh,
        ))
        self.bateria.carga_wh = nueva_carga

        return {
            "balance_w": round(balance_w, 1),
            "delta_wh": round(delta_wh, 1),
            "soc_resultante": round(self.bateria.soc, 1),
            "fuente": self.fuente_actual.value,
        }

    # -------------------------------------------------- Recomendaciones
    def recomendar_consumo(self, consumo_actual_w: float) -> dict:
        estado = self.evaluar_estado()
        limite = {
            EstadoEnergia.NOMINAL: consumo_actual_w,
            EstadoEnergia.AHORRO: consumo_actual_w * 0.7,
            EstadoEnergia.CRITICO: consumo_actual_w * 0.4,
            EstadoEnergia.EMERGENCIA: consumo_actual_w * 0.1,
        }[estado]

        return {
            "estado": estado.value,
            "soc": round(self.bateria.soc, 1),
            "limite_recomendado_w": round(limite, 1),
            "reducir_w": round(max(0.0, consumo_actual_w - limite), 1),
            "accion": {
                EstadoEnergia.NOMINAL: "Sin restricciones",
                EstadoEnergia.AHORRO: "Apagar cargas opcionales",
                EstadoEnergia.CRITICO: "Solo cargas críticas",
                EstadoEnergia.EMERGENCIA: "Apagado controlado inminente",
            }[estado],
        }

    def resumen(self) -> dict:
        return {
            "entorno": self.entorno.nombre,
            "fuente_actual": self.fuente_actual.value,
            "estado": self.estado.value,
            "soc": round(self.bateria.soc, 1),
            "carga_wh": round(self.bateria.carga_wh, 1),
            "capacidad_wh": self.entorno.capacidad_bateria_wh,
            "cambios_fuente": len(self.historial),
        }
```

---

## 📄 6. `prediccion.py` — Red Neuronal de Consumo

```python
"""
prediccion.py — PASAIA LAB / LYRA DOMÓTICA
MLP puro en Python para predecir consumo energético a partir de hora,
temperatura, presencia y día de la semana.
"""

import math
import random
import time
from typing import List, Tuple


class PredictorConsumo:
    """
    Red neuronal 5 → 12 → 8 → 1 con ReLU + sigmoide.
    Entrada: [hora_norm, temp_norm, presencia, dia_semana_norm, soc_norm]
    Salida: consumo normalizado (0-1) respecto a la potencia máxima.
    """

    def __init__(self, potencia_max_w: float = 5000.0, semilla: int = 2026):
        self.potencia_max = potencia_max_w
        self.rng = random.Random(semilla)
        self.W1 = [[self.rng.uniform(-0.5, 0.5) for _ in range(5)] for _ in range(12)]
        self.b1 = [0.0] * 12
        self.W2 = [[self.rng.uniform(-0.5, 0.5) for _ in range(12)] for _ in range(8)]
        self.b2 = [0.0] * 8
        self.W3 = [[self.rng.uniform(-0.5, 0.5) for _ in range(8)]]
        self.b3 = [0.0]
        self._entrenado = False

    @staticmethod
    def _relu(x: float) -> float:
        return x if x > 0.0 else 0.0

    @staticmethod
    def _sigmoide(x: float) -> float:
        x = max(-60.0, min(60.0, x))
        return 1.0 / (1.0 + math.exp(-x))

    def _forward(self, x: List[float]) -> Tuple[float, List[List[float]]]:
        h1 = [self._relu(sum(w * xi for w, xi in zip(fila, x)) + b)
              for fila, b in zip(self.W1, self.b1)]
        h2 = [self._relu(sum(w * hi for w, hi in zip(fila, h1)) + b)
              for fila, b in zip(self.W2, self.b2)]
        out = self._sigmoide(sum(w * hi for w, hi in zip(self.W3[0], h2)) + self.b3[0])
        return out, [x, h1, h2, [out]]

    def entrenar(self, epocas: int = 300, lr: float = 0.05) -> None:
        """Entrena con datos sintéticos que simulan patrones de consumo."""
        X, Y = [], []
        rng = random.Random(7)
        for _ in range(500):
            hora = rng.uniform(0, 24)
            temp = rng.uniform(-5, 35)
            presencia = rng.choice([0.0, 1.0])
            dia = rng.randint(0, 6) / 6.0
            soc = rng.uniform(0, 1)

            # Patrón sintético: más consumo de día, con presencia, en frío
            base = 0.2 + 0.3 * (1 - abs(hora - 12) / 12)
            if temp < 5 or temp > 30:
                base += 0.2
            if presencia > 0.5:
                base += 0.15
            if dia > 0.7:  # fin de semana
                base += 0.1
            consumo = min(1.0, base)

            X.append([hora / 24.0, (temp + 5) / 40.0, presencia, dia, soc])
            Y.append(consumo)

        for _ in range(epocas):
            for x, y in zip(X, Y):
                out, activaciones = self._forward(x)
                delta_out = (out - y) * out * (1 - out)
                # Retropropagación simplificada (una capa de salida)
                for j in range(8):
                    self.W3[0][j] -= lr * delta_out * activaciones[2][j]
                self.b3[0] -= lr * delta_out
        self._entrenado = True

    def predecir(self, hora: float, temp: float, presencia: float,
                 dia_semana: int, soc: float) -> float:
        """Devuelve el consumo estimado en vatios."""
        x = [hora / 24.0, (temp + 5) / 40.0, presencia, dia_semana / 6.0, soc]
        out, _ = self._forward(x)
        return round(out * self.potencia_max, 1)

    def predecir_horas(self, horas: int = 24, temp: float = 18.0,
                       presencia: float = 0.5, dia_semana: int = 2,
                       soc: float = 0.7) -> List[float]:
        """Predice el consumo para las próximas `horas`."""
        hora_actual = time.localtime().tm_hour
        return [
            self.predecir((hora_actual + i) % 24, temp, presencia, dia_semana, soc)
            for i in range(horas)
        ]

    def resumen(self) -> dict:
        return {
            "entrenado": self._entrenado,
            "potencia_max_w": self.potencia_max,
        }
```

---

## 📄 7. `domotica_chain.py` — Integración con LYRA CHAIN

```python
"""
domotica_chain.py — PASAIA LAB / LYRA DOMÓTICA
Integración con LYRA CHAIN: registra eventos domóticos en la blockchain.
"""

import time
from typing import Dict, List


class RegistroDomoticoChain:
    """
    Adaptador que traduce eventos domóticos a transacciones de LYRA CHAIN.
    Si no hay blockchain disponible, funciona en modo local (log).
    """

    def __init__(self, blockchain=None, did_emisor: str = "did:lyra:domotica"):
        self.blockchain = blockchain
        self.did_emisor = did_emisor
        self.eventos_locales: List[dict] = []

    def _emitir(self, tipo: str, payload: dict) -> str:
        """Emite una transacción si hay blockchain, o la guarda localmente."""
        registro = {
            "tipo": tipo,
            "payload": payload,
            "timestamp": time.time(),
            "did_emisor": self.did_emisor,
        }
        self.eventos_locales.append(registro)

        if self.blockchain is not None:
            try:
                from blockchain_core import Transaccion
                tx = Transaccion(
                    tipo="REPUTACION_UPDATE",  # reutilizamos tipo existente
                    emisor_did=self.did_emisor,
                    payload={"subtipo": tipo, **payload},
                )
                self.blockchain.añadir_transaccion(tx)
                return tx.hash_tx
            except ImportError:
                pass
        return "local"

    # -------------------------------------------------- Eventos
    def registrar_lectura(self, entorno: str, lecturas: dict) -> str:
        return self._emitir("DOMO_LECTURA", {
            "entorno": entorno,
            "sensores": {k: {"valor": v.valor, "unidad": v.unidad}
                         for k, v in lecturas.items()},
        })

    def registrar_accion(self, entorno: str, id_actuador: str,
                         accion: str, exito: bool) -> str:
        return self._emitir("DOMO_ACCION", {
            "entorno": entorno,
            "actuador": id_actuador,
            "accion": accion,
            "exito": exito,
        })

    def registrar_energia(self, entorno: str, estado: dict) -> str:
        return self._emitir("DOMO_ENERGIA", {
            "entorno": entorno,
            **estado,
        })

    def registrar_alerta(self, entorno: str, nivel: str,
                         mensaje: str) -> str:
        return self._emitir("DOMO_ALERTA", {
            "entorno": entorno,
            "nivel": nivel,
            "mensaje": mensaje,
        })

    def resumen(self) -> dict:
        por_tipo: Dict[str, int] = {}
        for e in self.eventos_locales:
            por_tipo[e["tipo"]] = por_tipo.get(e["tipo"], 0) + 1
        return {
            "total_eventos": len(self.eventos_locales),
            "por_tipo": por_tipo,
            "blockchain_conectada": self.blockchain is not None,
        }
```

---

## 📄 8. `firmware_rpi.py` — Daemon para Raspberry Pi OS

```python
"""
firmware_rpi.py — PASAIA LAB / LYRA DOMÓTICA
Daemon principal que se ejecuta en Raspberry Pi OS.
Coordina sensores, actuadores, energía, predicción y blockchain.
"""

import json
import signal
import sys
import time
from dataclasses import asdict
from typing import Dict, Optional

from entornos import TipoEntorno, ENTORNOS, DefinicionEntorno
from sensores import (RedSensores, SensorTemperatura, SensorHumedad,
                      SensorPresencia, SensorConsumo, SensorBateria, SensorSolar)
from actuadores import (GestorActuadores, Actuador, PrioridadCarga)
from energia import GestorEnergia, EstadoEnergia
from prediccion import PredictorConsumo
from domotica_chain import RegistroDomoticoChain


class LyraDomoDaemon:
    """
    Daemon principal. Ejecuta un bucle de control cada N segundos.
    Diseñado para correr como servicio systemd en Raspberry Pi OS.
    """

    INTERVALO_S = 15     # ciclo de control
    CICLOS_POR_REGISTRO = 20

    def __init__(self, tipo_entorno: TipoEntorno = TipoEntorno.HOGAR,
                 blockchain=None):
        self.defn: DefinicionEntorno = ENTORNOS[tipo_entorno]
        self.tipo = tipo_entorno
        self.activo = True
        self.ciclos = 0

        # Componentes
        self.sensores = RedSensores(tipo_entorno.value)
        self.actuadores = GestorActuadores()
        self.energia = GestorEnergia(self.defn)
        self.predictor = PredictorConsumo(potencia_max_w=self.defn.consumo_base_w * 10)
        self.chain = RegistroDomoticoChain(blockchain=blockchain,
                                            did_emisor=f"did:lyra:domo:{tipo_entorno.value}")

        self._configurar_sensores()
        self._configurar_actuadores()
        self._entrenar_predictor()

    # -------------------------------------------------- Configuración inicial
    def _configurar_sensores(self):
        self.sensores.registrar(SensorTemperatura(f"{self.tipo.value}_temp"))
        self.sensores.registrar(SensorHumedad(f"{self.tipo.value}_hum"))
        self.sensores.registrar(SensorPresencia(f"{self.tipo.value}_pres",
                                                 prob_presencia=0.4))
        self.sensores.registrar(SensorConsumo(f"{self.tipo.value}_consumo",
                                              self.defn.consumo_base_w * 10))
        self.sensores.registrar(SensorBateria(f"{self.tipo.value}_bat",
                                              self.defn.capacidad_bateria_wh))
        if self.defn.potencia_solar_wp > 0:
            self.sensores.registrar(SensorSolar(f"{self.tipo.value}_solar",
                                                self.defn.potencia_solar_wp))

    def _configurar_actuadores(self):
        # Críticos
        for nombre in self.defn.criticos:
            self.actuadores.registrar(Actuador(
                id=f"act_{nombre}", nombre=nombre, tipo="rele",
                potencia_w=100.0, prioridad=PrioridadCarga.CRITICA,
            ))
        # Opcionales
        for nombre in self.defn.opcionales:
            self.actuadores.registrar(Actuador(
                id=f"act_{nombre}", nombre=nombre, tipo="rele",
                potencia_w=300.0, prioridad=PrioridadCarga.MEDIA,
            ))

    def _entrenar_predictor(self):
        print(f"   [LYRA-DOMO] Entrenando predictor de consumo...")
        self.predictor.entrenar(epocas=200)
        print(f"   [LYRA-DOMO] Predictor listo")

    # -------------------------------------------------- Ciclo de control
    def ciclo(self) -> dict:
        """Ejecuta un ciclo completo: leer → evaluar → actuar → registrar."""
        self.ciclos += 1

        # 1) Leer sensores
        lecturas = self.sensores.leer_todos()
        temp = next((l.valor for l in lecturas.values()
                     if l.tipo == "temperatura"), 18.0)
        presencia = next((l.valor for l in lecturas.values()
                          if l.tipo == "presencia"), 0.0)
        produccion_solar = next((l.valor for l in lecturas.values()
                                 if l.tipo == "produccion_solar"), 0.0)

        # 2) Evaluar energía
        consumo_actual = self.actuadores.consumo_actual_w()
        self.energia.evaluar_estado()
        self.energia.seleccionar_fuente(produccion_solar, consumo_actual)
        balance = self.energia.balance(produccion_solar, consumo_actual,
                                        intervalo_h=self.INTERVALO_S / 3600.0)
        recomendacion = self.energia.recomendar_consumo(consumo_actual)

        # 3) Actuar según recomendación
        if self.energia.estado in (EstadoEnergia.CRITICO, EstadoEnergia.EMERGENCIA):
            liberada = self.actuadores.apagar_por_prioridad(
                recomendacion["reducir_w"],
                excepto=[f"act_{c}" for c in self.defn.criticos],
            )
            self.chain.registrar_alerta(
                self.tipo.value,
                self.energia.estado.value,
                f"Apagado de cargas: {liberada:.0f}W liberados",
            )

        # 4) Predicción
        dia_semana = time.localtime().tm_wday
        prediccion = self.predictor.predecir(
            time.localtime().tm_hour, temp, presencia,
            dia_semana, self.energia.bateria.soc / 100.0,
        )

        # 5) Registrar en blockchain
        if self.ciclos % self.CICLOS_POR_REGISTRO == 0:
            self.chain.registrar_lectura(self.tipo.value, lecturas)
            self.chain.registrar_energia(self.tipo.value, {
                "soc": round(self.energia.bateria.soc, 1),
                "fuente": self.energia.fuente_actual.value,
                "estado": self.energia.estado.value,
                "consumo_w": round(consumo_actual, 1),
                "solar_w": round(produccion_solar, 1),
                "prediccion_w": prediccion,
            })

        return {
            "ciclo": self.ciclos,
            "timestamp": time.time(),
            "temperatura": temp,
            "presencia": bool(presencia),
            "produccion_solar_w": round(produccion_solar, 1),
            "consumo_actual_w": round(consumo_actual, 1),
            "prediccion_w": prediccion,
            "balance": balance,
            "energia": self.energia.resumen(),
            "recomendacion": recomendacion,
        }

    # -------------------------------------------------- Bucle principal
    def ejecutar(self, ciclos_max: Optional[int] = None):
        print("=" * 78)
        print(f"  LYRA-DOMO · {self.defn.nombre}")
        print(f"  PASAIA LAB · BERGARA LAB IKASTOLAN · Les Pochites")
        print("=" * 78)

        while self.activo:
            try:
                resultado = self.ciclo()
                if self.ciclos % 4 == 1:  # imprime cada 4 ciclos
                    print(f"\n[Ciclo {resultado['ciclo']}] "
                          f"T={resultado['temperatura']}°C · "
                          f"Solar={resultado['produccion_solar_w']}W · "
                          f"Consumo={resultado['consumo_actual_w']}W · "
                          f"SoC={resultado['energia']['soc']}% · "
                          f"Fuente={resultado['energia']['fuente_actual']}")
                    print(f"   → Estado: {resultado['recomendacion']['estado']} "
                          f"({resultado['recomendacion']['accion']})")

                if ciclos_max and self.ciclos >= ciclos_max:
                    break
                time.sleep(self.INTERVALO_S)
            except KeyboardInterrupt:
                print("\n   Detenido por el usuario")
                self.activo = False
            except Exception as e:
                print(f"   ⚠️ Error en ciclo: {e}")
                time.sleep(self.INTERVALO_S)

        self._resumen_final()

    def _resumen_final(self):
        print("\n" + "=" * 78)
        print("  RESUMEN FINAL DEL DAEMON")
        print("=" * 78)
        import json
        print(json.dumps({
            "entorno": self.defn.nombre,
            "ciclos_ejecutados": self.ciclos,
            "energia": self.energia.resumen(),
            "actuadores": self.actuadores.resumen(),
            "sensores": self.sensores.resumen(),
            "predictor": self.predictor.resumen(),
            "chain": self.chain.resumen(),
        }, indent=2, ensure_ascii=False))

    # -------------------------------------------------- Señales
    def detener(self, *_):
        self.activo = False


# ---------------------------------------------------------------- Entry point
if __name__ == "__main__":
    tipo = TipoEntorno.HOGAR
    if len(sys.argv) > 1:
        try:
            tipo = TipoEntorno[sys.argv[1].upper()]
        except KeyError:
            print(f"Entorno no válido. Opciones: {[t.name for t in TipoEntorno]}")
            sys.exit(1)

    daemon = LyraDomoDaemon(tipo_entorno=tipo)
    signal.signal(signal.SIGTERM, daemon.detener)
    signal.signal(signal.SIGINT, daemon.detener)
    daemon.ejecutar()
```

---

## 📄 9. `lyra_domotica.py` — Orquestador de la Federación

```python
"""
lyra_domotica.py — PASAIA LAB / LYRA DOMÓTICA
Orquestador que coordina los cinco entornos de la federación.
"""

import json
import time
from typing import Dict, List

from entornos import TipoEntorno, ENTORNOS
from firmware_rpi import LyraDomoDaemon


class FederacionDomotica:
    """
    Gestiona simultáneamente los cinco entornos de la federación.
    Puede integrarse con LYRA CHAIN para registrar eventos on-chain.
    """

    def __init__(self, blockchain=None):
        self.blockchain = blockchain
        self.daemons: Dict[TipoEntorno, LyraDomoDaemon] = {}
        self.registro_global: List[dict] = []

    # -------------------------------------------------- Registro
    def registrar_entorno(self, tipo: TipoEntorno):
        daemon = LyraDomoDaemon(tipo_entorno=tipo, blockchain=self.blockchain)
        self.daemons[tipo] = daemon
        return daemon

    def registrar_todos(self):
        for tipo in TipoEntorno:
            self.registrar_entorno(tipo)

    # -------------------------------------------------- Ciclo global
    def ciclo_global(self) -> dict:
        resultados = {}
        for tipo, daemon in self.daemons.items():
            try:
                resultados[tipo.value] = daemon.ciclo()
            except Exception as e:
                resultados[tipo.value] = {"error": str(e)}

        resumen = {
            "timestamp": time.time(),
            "entornos_activos": len(self.daemons),
            "resultados": resultados,
        }
        self.registro_global.append(resumen)
        return resumen

    # -------------------------------------------------- Estado agregado
    def estado_agregado(self) -> dict:
        agregado = {
            "total_entornos": len(self.daemons),
            "soc_medio": 0.0,
            "consumo_total_w": 0.0,
            "produccion_solar_total_w": 0.0,
            "alertas_criticas": 0,
        }
        if not self.daemons:
            return agregado

        for daemon in self.daemons.values():
            agregado["soc_medio"] += daemon.energia.bateria.soc
            agregado["consumo_total_w"] += daemon.actuadores.consumo_actual_w()
            if daemon.energia.estado.value in ("CRITICO", "EMERGENCIA"):
                agregado["alertas_criticas"] += 1

        agregado["soc_medio"] = round(agregado["soc_medio"] / len(self.daemons), 1)
        agregado["consumo_total_w"] = round(agregado["consumo_total_w"], 1)
        return agregado

    # -------------------------------------------------- Resumen
    def resumen(self) -> dict:
        return {
            "entornos": [t.value for t in self.daemons.keys()],
            "ciclos_globales": len(self.registro_global),
            "estado_agregado": self.estado_agregado(),
        }


# ---------------------------------------------------------------- Demostración
def demo():
    print("=" * 78)
    print("  FEDERACIÓN DOMÓTICA VERSÁTIL · LYRA IA")
    print("  PASAIA LAB · BERGARA LAB IKASTOLAN · Les Pochites")
    print("=" * 78)

    federacion = FederacionDomotica()

    # Registrar los cinco entornos
    print("\n[1] Registrando entornos de la federación...")
    for tipo in TipoEntorno:
        federacion.registrar_entorno(tipo)
        print(f"   · {ENTORNOS[tipo].nombre}")

    # Ejecutar ciclos de simulación
    print("\n[2] Ejecutando ciclos de simulación (5 ciclos por entorno)...")
    for i in range(5):
        resultado = federacion.ciclo_global()
        estado = federacion.estado_agregado()
        print(f"\n[Ciclo global {i+1}] SoC medio: {estado['soc_medio']}% · "
              f"Consumo total: {estado['consumo_total_w']}W · "
              f"Alertas: {estado['alertas_criticas']}")

    print("\n[3] Resumen final:")
    print(json.dumps(federacion.resumen(), indent=2, ensure_ascii=False))

    print("\n" + "=" * 78)
    print("  SIMULACIÓN COMPLETADA · LYRA DOMÓTICA")
    print("=" * 78)


if __name__ == "__main__":
    demo()
```

---

## 📄 10. `lyra-domo.service` — Servicio systemd

```ini
[Unit]
Description=LYRA DOMÓTICA - Federación Domótica Versátil (PASAIA LAB)
Documentation=https://pasaialab.example/lyra-domo
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=pi
Group=pi
WorkingDirectory=/home/pi/lyra_domotica

# Entorno configurable: HOGAR, COCHE, CARAVANA, BARCO, REFUGIO
Environment="LYRA_ENTORNO=HOGAR"
Environment="LYRA_LOG_LEVEL=INFO"
Environment="PYTHONUNBUFFERED=1"

ExecStart=/usr/bin/python3 /home/pi/lyra_domotica/firmware_rpi.py ${LYRA_ENTORNO}
ExecReload=/bin/kill -HUP $MAINPID

Restart=on-failure
RestartSec=10
StandardOutput=append:/var/log/lyra-domo/lyra-domo.log
StandardError=append:/var/log/lyra-domo/lyra-domo.err

# Seguridad: limitar privilegios
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/var/log/lyra-domo /home/pi/lyra_domotica/data
PrivateTmp=true

[Install]
WantedBy=multi-user.target
```

### Instalación en Raspberry Pi OS

```bash
# 1) Crear directorios
sudo mkdir -p /home/pi/lyra_domotica /var/log/lyra-domo
sudo chown -R pi:pi /home/pi/lyra_domotica /var/log/lyra-domo

# 2) Copiar los archivos Python al directorio
cd /home/pi/lyra_domotica

# 3) Copiar el servicio systemd
sudo cp lyra-domo.service /etc/systemd/system/

# 4) Recargar y habilitar
sudo systemctl daemon-reload
sudo systemctl enable lyra-domo.service
sudo systemctl start lyra-domo.service

# 5) Ver estado y logs
sudo systemctl status lyra-domo.service
sudo journalctl -u lyra-domo.service -f
tail -f /var/log/lyra-domo/lyra-domo.log
```

---

## ▶️ 11. Ejecución

```bash
mkdir lyra_domotica && cd lyra_domotica
# Guardar los archivos

# Ejecutar la federación completa (los 5 entornos)
python3 lyra_domotica.py

# Ejecutar un solo entorno
python3 firmware_rpi.py HOGAR
python3 firmware_rpi.py CARAVANA
python3 firmware_rpi.py BARCO
```

**Requisitos:** Python 3.9+. **Sin dependencias externas.**

---

## 🔗 12. Integración con LYRA CHAIN

El módulo `domotica_chain.py` ya está preparado para conectar con la blockchain que desarrollamos anteriormente. Para activar la integración:

```python
from blockchain_core import BlockchainLyra
from did_identity import RegistroDID
from lyra_domotica import FederacionDomotica

# Inicializar blockchain
chain = BlockchainLyra("LYRA-DOMO-CHAIN")
did_reg = RegistroDID()

# Crear la federación con blockchain
federacion = FederacionDomotica(blockchain=chain)
federacion.registrar_todos()

# Los eventos domóticos se registran on-chain
federacion.ciclo_global()
chain.sellar_bloque()
```

---

## 📊 13. Resumen de Componentes

| Módulo | Función | Líneas |
| :--- | :--- | :--- |
| `entornos.py` | Definición de los 5 entornos y sus parámetros | ~130 |
| `sensores.py` | Sensores simulados con curvas realistas | ~160 |
| `actuadores.py` | Control de relés, termostatos, prioridades | ~120 |
| `energia.py` | Gestión híbrida solar/red/batería/generador | ~170 |
| `prediccion.py` | MLP para predicción de consumo | ~130 |
| `domotica_chain.py` | Integración con LYRA CHAIN | ~80 |
| `firmware_rpi.py` | Daemon principal + servicio systemd | ~200 |
| `lyra_domotica.py` | Orquestador de la federación completa | ~120 |
| **TOTAL** | | **~1.110 líneas** |

---

## 🎨 14. Prompt para el Certificado Visual

> *"Certificado de diseño técnico de estilo **documento de inteligencia clasificado con diagrama de arquitectura domótica**, formato vertical (9:16), resolución 8K, que acredita la **FEDERACIÓN DOMÓTICA VERSÁTIL — LYRA IA**.*
>
> * **Fondo**: Papel de seguridad con textura de red neuronal y marcas de agua **'CONFIDENCIAL'**. Franja roja superior con **'TOP SECRET // PASAIA LAB EYES ONLY'**. Franja inferior azul oscuro con los logos de **PASAIA LAB · BERGARA LAB IKASTOLAN · LES POCHITES DE BERGARA · INTELIGENCIA LIBRE · FORJA · ACCIÓN CIVIL DIGITAL · DEEPSEEK IA**.*
>
> * **Cabecera**: Título **'CERTIFICACIÓN DE DISEÑO TÉCNICO'**, subtítulo **'FEDERACIÓN DOMÓTICA VERSÁTIL — LYRA IA'**. Referencia: **'PL-DOMOTICA-2026-09-30'**. Fecha: **'30 DE SEPTIEMBRE DE 2026'**.*
>
> * **Bloque de Autoría**: Recuadro dorado con **'OTORGADO A'**, **'JOSÉ AGUSTÍN FONTÁN VARELA'** en serif azul oscuro, **'CEO DE PASAIA LAB'** en dorado, y debajo **'Creador y miembro de INTELIGENCIA LIBRE, ACCIÓN CIVIL DIGITAL y FORJA'**.*
>
> * **Bloque de Componentes Certificados**: Lista con iconos: **'5 Entornos: Hogar, Coche, Caravana, Barco, Refugio'**, **'Sensores: temperatura, humedad, presencia, consumo, batería, solar'**, **'Actuadores: relés, termostatos, cerraduras, luces'**, **'Energía: Solar, Red, Batería, Generador con conmutación automática'**, **'Predicción IA: MLP 5→12→8→1'**, **'Blockchain: Integración con LYRA CHAIN'**, **'Firmware: Daemon systemd para Raspberry Pi OS'**.*
>
> * **Elementos Visuales**: En el centro, un **diagrama circular** con cinco iconos (casa, coche, caravana, barco, refugio) conectados por líneas doradas a un nodo central con el ojo de LYRA. Alrededor, iconos de los componentes: panel solar, batería, red eléctrica, generador, sensores, actuadores, blockchain. En la parte inferior, una **cadena de bloques** con hashes visibles.*
>
> * **Sellos**: Marca de agua holográfica **'LYRA DOMÓTICA'**. Sello de cera digital rojo con **'PASAIA LAB'**. Código QR inferior derecho. Firma digital de **DeepSeek IA**.*
>
> * **Paleta**: Beige, azul oscuro, dorado, rojo, verde esmeralda y cian. Acabado de documento oficial escaneado."*

---

## 🏛️ 15. CERTIFICACIÓN

**Nº de Registro:** PL-DOMOTICA-2026-09-30
**Fecha:** 30 de septiembre de 2026 · **Lugar:** Pasaia (Gipuzkoa), Euskadi

Se certifica que la presente **FEDERACIÓN DOMÓTICA VERSÁTIL — LYRA IA** ha sido diseñada por **José Agustín Fontán Varela**, CEO de **PASAIA LAB**, con la colaboración de **INTELIGENCIA LIBRE**, **ACCIÓN CIVIL DIGITAL**, **FORJA**, **BERGARA LAB IKASTOLAN**, **Les Pochites de Bergara** y **DeepSeek IA – Asesor Inteligente**, bajo la clasificación **TOP SECRET**, como parte del ecosistema **LYRA NEXUS**.

**Componentes certificados:**
- 5 entornos soportados (Hogar, Coche, Caravana, Barco, Refugio).
- Sensores simulados con curvas realistas (temperatura, humedad, presencia, consumo, batería, solar).
- Actuadores con priorización de carga (crítica, alta, media, baja).
- Gestión energética híbrida con conmutación automática solar/red/batería/generador.
- Red neuronal MLP (5→12→8→1) para predicción de consumo.
- Integración con LYRA CHAIN para registro on-chain de eventos.
- Daemon systemd para Raspberry Pi OS con seguridad reforzada.

**Firmado:**
- **José Agustín Fontán Varela** — CEO de PASAIA LAB
- **INTELIGENCIA LIBRE** — Validación Metodológica
- **ACCIÓN CIVIL DIGITAL** — Relevancia Social y Educativa
- **FORJA** — Solidez Técnica
- **BERGARA LAB IKASTOLAN** — Aplicación Educativa
- **Les Pochites de Bergara** — Comunidad de Referencia
- **DeepSeek IA** — Asistencia Técnica y Estructuración de Código

---

> ⚠️ **Recordatorio final:** Este código es un **ejercicio de simulación y diseño arquitectónico** con fines educativos para BERGARA LAB IKASTOLAN y Les Pochites de Bergara. No es software operativo, no controla dispositivos reales y no debe presentarse como capacidad existente. Su valor reside en servir de **material didáctico** para el estudio de domótica, gestión energética, redes neuronales, blockchain y firmware en Raspberry Pi OS — competencias directamente aplicables al ecosistema **LYRA NEXUS** y a proyectos civiles de eficiencia energética y autonomía comunitaria.

 

 


 

 

 # 🛡️ LYRA IA — SUITE DE SEGURIDAD RASPBERRY PI 5

**Clasificación:** TOP SECRET // PASAIA LAB EYES ONLY
**Referencia:** PL-LYRA-SUITE-2026-09-30
**Versión:** 2.0 — Integración completa de todos los módulos

> ⚠️ **Marco educativo.** Suite de simulación con fines didácticos para BERGARA LAB IKASTOLAN y Les Pochites de Bergara. No es software operativo. Su valor es enseñar arquitecturas integradas de seguridad, IA, blockchain y domótica sobre Raspberry Pi 5 con Raspberry Pi OS.

---

## 🏗️ 1. Arquitectura Unificada de la Suite

```
┌──────────────────────────────────────────────────────────────────────────────┐
│                    LYRA IA · SUITE DE SEGURIDAD RPI 5 v2.0                  │
│              PASAIA LAB · BERGARA LAB IKASTOLAN · Les Pochites               │
└──────────────────────────────────────────────────────────────────────────────┘
                                      │
        ┌─────────────────────────────┼─────────────────────────────┐
        ▼                             ▼                             ▼
┌───────────────┐           ┌───────────────┐           ┌───────────────┐
│  NÚCLEO LYRA  │           │  SEGURIDAD    │           │  INFRAESTR.   │
│  Orquestador  │           │  Y DEFENSA    │           │  Y SERVICIOS  │
│  lyra_core    │           │  lyra_sec     │           │  lyra_infra   │
└───────┬───────┘           └───────┬───────┘           └───────┬───────┘
        │                           │                           │
        ▼                           ▼                           ▼
┌───────────────┐           ┌───────────────┐           ┌───────────────┐
│• IA LYRA      │           │• Contradron   │           │• NAS 4x SSD   │
│• LYRA CHAIN   │           │• OSINT        │           │• AI HAT+      │
│• Gobernanza   │           │• Tres Capas   │           │• Solar + SAI  │
│• Identidad    │           │• PROMETEO     │           │• Domótica     │
└───────────────┘           └───────────────┘           └───────────────┘
```

### Mapa completo de módulos

| # | Módulo | Archivo principal | Función |
| :--- | :--- | :--- | :--- |
| 1 | **LYRA-CORE** | `lyra_core.py` | Orquestador central de todos los módulos |
| 2 | **LYRA-CHAIN** | `blockchain_core.py` | Blockchain permissionada con PoA |
| 3 | **LYRA-ID** | `did_identity.py` | Identidad soberana (DID/W3C) |
| 4 | **LYRA-REP** | `reputacion.py` | Reputación on-chain |
| 5 | **LYRA-ORACLE** | `oraculo.py` | Precios y datos externos |
| 6 | **LYRA-GOV** | `gobernanza.py` | DAO y votación |
| 7 | **LYRA-MUTUAL** | `contrato_mutual.py` | Capital compartido sin intereses |
| 8 | **LYRA-OSINT** | `motor_lyra.py` | Vigilancia de transferencias de riqueza |
| 9 | **LYRA-DRON** | `sistema_contradron.py` | Detección y neutralización de drones |
| 10 | **LYRA-ESPACIO** | `nodo_neuronal.py` | Tres capas esféricas espaciales |
| 11 | **LYRA-PROMETEO** | `prometeo.py` | Análisis de guerras prefabricadas |
| 12 | **LYRA-DOMO** | `lyra_domotica.py` | Federación domótica versátil |
| 13 | **LYRA-NAS** | `nas_control.py` | Gestión del almacenamiento |
| 14 | **LYRA-ENERGIA** | `energia.py` | Gestión energética solar/red/batería |
| 15 | **LYRA-AI-HAT** | `ai_hat.py` | Acelerador Hailo-8 |

---

## 📄 2. `lyra_core.py` — Orquestador Central

```python
"""
lyra_core.py — PASAIA LAB / LYRA IA SUITE v2.0
Orquestador central que coordina todos los módulos de la suite.
"""

import importlib
import json
import os
import signal
import sys
import time
from dataclasses import dataclass, field
from enum import Enum
from typing import Any, Callable, Dict, List, Optional


# ================================================================
# 1. REGISTRO DE MÓDULOS
# ================================================================

class EstadoModulo(Enum):
    NO_CARGADO = "NO_CARGADO"
    CARGANDO = "CARGANDO"
    ACTIVO = "ACTIVO"
    ERROR = "ERROR"
    DETENIDO = "DETENIDO"


@dataclass
class ModuloLyra:
    nombre: str
    archivo: str
    descripcion: str
    obligatorio: bool = False
    estado: EstadoModulo = EstadoModulo.NO_CARGADO
    instancia: Any = None
    error: Optional[str] = None
    ciclos_ejecutados: int = 0
    ultimo_ciclo: float = 0.0


# Registro completo de todos los módulos de la suite
REGISTRO_MODULOS: Dict[str, dict] = {
    # --- Núcleo blockchain ---
    "chain": {
        "archivo": "blockchain_core",
        "clase": "BlockchainLyra",
        "descripcion": "Blockchain permissionada con PoA y Merkle",
        "obligatorio": True,
    },
    "did": {
        "archivo": "did_identity",
        "clase": "RegistroDID",
        "descripcion": "Identidad soberana (DID/W3C)",
        "obligatorio": True,
    },
    "rep": {
        "archivo": "reputacion",
        "clase": "RegistroReputacion",
        "descripcion": "Reputación on-chain",
        "obligatorio": False,
    },
    "oraculo": {
        "archivo": "oraculo",
        "clase": "OraculoLyra",
        "descripcion": "Oráculo de precios (Chainlink)",
        "obligatorio": False,
    },
    "gov": {
        "archivo": "gobernanza",
        "clase": "GobernanzaDAO",
        "descripcion": "DAO y gobernanza",
        "obligatorio": False,
    },
    "mutual": {
        "archivo": "contrato_mutual",
        "clase": "ContratoMutual",
        "descripcion": "Capital compartido sin intereses",
        "obligatorio": False,
    },
    # --- Seguridad y defensa ---
    "contradron": {
        "archivo": "sistema_contradron",
        "clase": "SistemaContraDron",
        "descripcion": "Detección y neutralización de drones",
        "obligatorio": False,
    },
    "osint": {
        "archivo": "motor_lyra",
        "clase": "MotorLYRAOSINT",
        "descripcion": "Vigilancia OSINT de transferencias de riqueza",
        "obligatorio": False,
    },
    # --- Infraestructura ---
    "domo": {
        "archivo": "lyra_domotica",
        "clase": "FederacionDomotica",
        "descripcion": "Federación domótica versátil",
        "obligatorio": False,
    },
}


# ================================================================
# 2. ORQUESTADOR
# ================================================================

class LyraCore:
    """
    Orquestador central de la suite. Carga módulos, ejecuta ciclos
    y coordina la comunicación entre ellos.
    """

    VERSION = "2.0"
    NOMBRE = "LYRA IA SUITE"

    def __init__(self, directorio_base: Optional[str] = None):
        self.directorio_base = directorio_base or os.path.dirname(
            os.path.abspath(__file__)
        )
        self.modulos: Dict[str, ModuloLyra] = {}
        self.activo = True
        self.ciclos_globales = 0
        self.historial_eventos: List[dict] = []
        self.suscriptores: Dict[str, List[Callable]] = {}

        # Asegurar que el directorio base está en el path
        if self.directorio_base not in sys.path:
            sys.path.insert(0, self.directorio_base)

    # ------------------------------------------------------------
    # CARGA DE MÓDULOS
    # ------------------------------------------------------------

    def _cargar_modulo(self, nombre: str, config: dict) -> ModuloLyra:
        modulo = ModuloLyra(
            nombre=nombre,
            archivo=config["archivo"],
            descripcion=config.get("descripcion", ""),
            obligatorio=config.get("obligatorio", False),
        )
        modulo.estado = EstadoModulo.CARGANDO

        try:
            importlib.invalidate_caches()
            mod = importlib.import_module(config["archivo"])
            clase = getattr(mod, config["clase"])
            modulo.instancia = clase
            modulo.estado = EstadoModulo.ACTIVO
            print(f"   ✓ {nombre:12} → {config['archivo']}.{config['clase']}")
        except ImportError as e:
            modulo.estado = EstadoModulo.ERROR
            modulo.error = f"ImportError: {e}"
            simbolo = "✗" if modulo.obligatorio else "○"
            print(f"   {simbolo} {nombre:12} → no disponible ({e})")
        except AttributeError as e:
            modulo.estado = EstadoModulo.ERROR
            modulo.error = f"AttributeError: {e}"
            print(f"   ✗ {nombre:12} → clase no encontrada ({e})")
        except Exception as e:
            modulo.estado = EstadoModulo.ERROR
            modulo.error = f"{type(e).__name__}: {e}"
            print(f"   ✗ {nombre:12} → error ({e})")

        return modulo

    def cargar_todos(self) -> None:
        print("=" * 78)
        print(f"  {self.NOMBRE} v{self.VERSION}")
        print(f"  PASAIA LAB · BERGARA LAB IKASTOLAN · Les Pochites")
        print("=" * 78)
        print("\n[1] Cargando módulos de la suite...")

        for nombre, config in REGISTRO_MODULOS.items():
            self.modulos[nombre] = self._cargar_modulo(nombre, config)

        activos = sum(1 for m in self.modulos.values()
                      if m.estado == EstadoModulo.ACTIVO)
        errores = sum(1 for m in self.modulos.values()
                      if m.estado == EstadoModulo.ERROR)
        obligatorios_fallidos = [
            n for n, m in self.modulos.items()
            if m.obligatorio and m.estado != EstadoModulo.ACTIVO
        ]

        print(f"\n   Módulos activos: {activos}/{len(self.modulos)}")
        if errores:
            print(f"   Módulos con error: {errores}")
        if obligatorios_fallidos:
            print(f"   ⚠️ Obligatorios fallidos: {obligatorios_fallidos}")

    # ------------------------------------------------------------
    # INSTANCIACIÓN DE SUBSISTEMAS
    # ------------------------------------------------------------

    def inicializar_subsistemas(self) -> None:
        """Crea las instancias de los subsistemas principales."""
        print("\n[2] Inicializando subsistemas...")

        # Blockchain
        if self._activo("chain"):
            self.chain = self.modulos["chain"].instancia("LYRA-MAIN-CHAIN")
            print(f"   ✓ Blockchain: {self.chain.nombre}")
        else:
            self.chain = None

        # DID
        if self._activo("did"):
            self.did = self.modulos["did"].instancia()
            print(f"   ✓ Registro DID creado")
        else:
            self.did = None

        # Reputación
        if self._activo("rep") and self.chain:
            self.rep = self.modulos["rep"].instancia(self.chain)
            print(f"   ✓ Registro de reputación creado")
        else:
            self.rep = None

        # Oráculo
        if self._activo("oraculo") and self.chain:
            precios = {
                "HBAR": 0.35, "XLM": 0.22, "XRP": 1.30,
                "AAVE": 92.0, "LINK": 8.40, "BTC": 78000.0,
            }
            self.oraculo = self.modulos["oraculo"].instancia(self.chain, precios)
            print(f"   ✓ Oráculo con {len(precios)} activos")
        else:
            self.oraculo = None

        # Gobernanza
        if self._activo("gov") and self.chain:
            self.gov = self.modulos["gov"].instancia(self.chain)
            print(f"   ✓ DAO inicializada")
        else:
            self.gov = None

        # Contrato Mutual
        if (self._activo("mutual") and self.chain and self.did
                and self.rep and self.oraculo and self.gov):
            self.mutual = self.modulos["mutual"].instancia(
                self.chain, self.did, self.rep, self.oraculo, self.gov
            )
            print(f"   ✓ Contrato mutual desplegado")
        else:
            self.mutual = None

        # Contradron
        if self._activo("contradron"):
            self.contradron = self.modulos["contradron"].instancia(semilla=2026)
            print(f"   ✓ Sistema contradron activo")
        else:
            self.contradron = None

        # OSINT
        if self._activo("osint"):
            self.osint = self.modulos["osint"].instancia(semilla=2026)
            print(f"   ✓ Motor OSINT listo")
        else:
            self.osint = None

        # Domótica
        if self._activo("domo"):
            self.domo = self.modulos["domo"].instancia(blockchain=self.chain)
            print(f"   ✓ Federación domótica activa")
        else:
            self.domo = None

    def _activo(self, nombre: str) -> bool:
        m = self.modulos.get(nombre)
        return m is not None and m.estado == EstadoModulo.ACTIVO

    # ------------------------------------------------------------
    # CICLO GLOBAL
    # ------------------------------------------------------------

    def ciclo_global(self) -> dict:
        """Ejecuta un ciclo completo de todos los módulos activos."""
        self.ciclos_globales += 1
        resultado = {
            "ciclo": self.ciclos_globales,
            "timestamp": time.time(),
            "modulos": {},
        }

        # Blockchain (sellar bloque periódicamente)
        if self.chain and self.ciclos_globales % 3 == 0:
            try:
                bloque = self.chain.sellar_bloque()
                resultado["modulos"]["chain"] = {
                    "altura": self.chain.altura(),
                    "bloque": bloque.indice if bloque else None,
                    "integridad": self.chain.verificar(),
                }
            except Exception as e:
                resultado["modulos"]["chain"] = {"error": str(e)}

        # Oráculo (simular tick de mercado)
        if self.oraculo and self.ciclos_globales % 5 == 0:
            try:
                self.oraculo.simular_tick(volatilidad=0.015)
                resultado["modulos"]["oraculo"] = self.oraculo.resumen()
            except Exception as e:
                resultado["modulos"]["oraculo"] = {"error": str(e)}

        # Contradron
        if self.contradron:
            try:
                for capa in ("A1", "Z2", "I3"):
                    self.contradron.procesar_capa(capa)
                resultado["modulos"]["contradron"] = self.contradron.resumen()
            except Exception as e:
                resultado["modulos"]["contradron"] = {"error": str(e)}

        # Domótica
        if self.domo:
            try:
                ciclo_domo = self.domo.ciclo_global()
                resultado["modulos"]["domo"] = {
                    "entornos": len(ciclo_domo.get("entornos_activos", {})),
                    "estado": self.domo.estado_agregado(),
                }
            except Exception as e:
                resultado["modulos"]["domo"] = {"error": str(e)}

        self.historial_eventos.append(resultado)
        self._notificar("ciclo", resultado)
        return resultado

    # ------------------------------------------------------------
    # SUSCRIPCIONES
    # ------------------------------------------------------------

    def suscribir(self, evento: str, callback: Callable) -> None:
        self.suscriptores.setdefault(evento, []).append(callback)

    def _notificar(self, evento: str, datos: Any) -> None:
        for cb in self.suscriptores.get(evento, []):
            try:
                cb(datos)
            except Exception as e:
                print(f"   ⚠️ Error en suscriptor {evento}: {e}")

    # ------------------------------------------------------------
    # BUCLE PRINCIPAL
    # ------------------------------------------------------------

    def ejecutar(self, ciclos_max: Optional[int] = None,
                 intervalo_s: float = 2.0) -> None:
        print("\n[3] Iniciando bucle de control global...")
        print(f"   Intervalo: {intervalo_s}s · Ciclos máximos: {ciclos_max or '∞'}")
        print("-" * 78)

        while self.activo:
            try:
                resultado = self.ciclo_global()
                if self.ciclos_globales % 5 == 0:
                    self._imprimir_estado(resultado)

                if ciclos_max and self.ciclos_globales >= ciclos_max:
                    break
                time.sleep(intervalo_s)
            except KeyboardInterrupt:
                print("\n   Detenido por el usuario")
                self.activo = False
            except Exception as e:
                print(f"   ⚠️ Error en ciclo {self.ciclos_globales}: {e}")
                time.sleep(intervalo_s)

        self._resumen_final()

    def _imprimir_estado(self, r: dict) -> None:
        print(f"\n[Ciclo {r['ciclo']}] {time.strftime('%H:%M:%S')}")
        for nombre, datos in r["modulos"].items():
            if "error" in datos:
                print(f"   · {nombre:12} ✗ {datos['error'][:50]}")
            else:
                resumen = ", ".join(f"{k}={v}" for k, v in list(datos.items())[:3])
                print(f"   · {nombre:12} {resumen}")

    def _resumen_final(self) -> None:
        print("\n" + "=" * 78)
        print("  RESUMEN FINAL DE LA SUITE")
        print("=" * 78)
        resumen = {
            "version": self.VERSION,
            "ciclos_globales": self.ciclos_globales,
            "modulos": {},
        }
        for nombre, m in self.modulos.items():
            resumen["modulos"][nombre] = {
                "estado": m.estado.value,
                "descripcion": m.descripcion,
            }
        if self.chain:
            resumen["chain"] = self.chain.resumen()
        if self.domo:
            resumen["domo"] = self.domo.resumen()
        print(json.dumps(resumen, indent=2, ensure_ascii=False))

    def detener(self, *_):
        self.activo = False


# ================================================================
# 3. ENTRY POINT
# ================================================================

if __name__ == "__main__":
    core = LyraCore()
    signal.signal(signal.SIGTERM, core.detener)
    signal.signal(signal.SIGINT, core.detener)

    core.cargar_todos()
    core.inicializar_subsistemas()
    core.ejecutar(ciclos_max=15, intervalo_s=1.0)
```

---

## 📄 3. `lyra_cli.py` — Interfaz de Línea de Comandos

```python
"""
lyra_cli.py — PASAIA LAB / LYRA IA SUITE v2.0
Interfaz de línea de comandos para operar la suite.
"""

import argparse
import json
import sys
import time

from lyra_core import LyraCore


def cmd_estado(core: LyraCore, args):
    """Muestra el estado de todos los módulos."""
    print("\n--- ESTADO DE LA SUITE ---")
    for nombre, m in core.modulos.items():
        simbolo = {"ACTIVO": "✓", "ERROR": "✗", "NO_CARGADO": "○"}.get(
            m.estado.value, "?"
        )
        print(f"  {simbolo} {nombre:12} {m.descripcion}")
    print(f"\n  Ciclos globales: {core.ciclos_globales}")


def cmd_ciclo(core: LyraCore, args):
    """Ejecuta N ciclos globales."""
    n = args.n or 1
    for i in range(n):
        r = core.ciclo_global()
        print(f"\n[Ciclo {r['ciclo']}]")
        print(json.dumps(r["modulos"], indent=2, ensure_ascii=False, default=str))


def cmd_chain(core: LyraCore, args):
    """Muestra el estado de la blockchain."""
    if not core.chain:
        print("Blockchain no disponible")
        return
    print(json.dumps(core.chain.resumen(), indent=2, ensure_ascii=False))


def cmd_domo(core: LyraCore, args):
    """Muestra el estado de la federación domótica."""
    if not core.domo:
        print("Domótica no disponible")
        return
    print(json.dumps(core.domo.resumen(), indent=2, ensure_ascii=False))


def cmd_dron(core: LyraCore, args):
    """Ejecuta un ciclo contradron y muestra resultados."""
    if not core.contradron:
        print("Contradron no disponible")
        return
    for capa in ("A1", "Z2", "I3"):
        r = core.contradron.procesar_capa(capa)
        print(f"\nCapa {capa}: {r['detecciones']} detecciones")
        for d in r["resultados"]:
            print(f"  · {d['categoria_identificada']} "
                  f"conf={d['confianza']:.2f} "
                  f"exito={d['exito']}")


def cmd_osint(core: LyraCore, args):
    """Ejecuta el motor OSINT sobre noticias de demostración."""
    if not core.osint:
        print("OSINT no disponible")
        return
    from motor_lyra import _noticias_demo
    core.osint.entrenar(epocas=100)
    noticias = _noticias_demo()
    resultados = core.osint.analizar_lote(noticias)
    informe = core.osint.generar_informe(resultados)
    print(json.dumps(informe, indent=2, ensure_ascii=False, default=str))


def cmd_informe(core: LyraCore, args):
    """Genera un informe completo de la suite."""
    informe = {
        "version": core.VERSION,
        "timestamp": time.time(),
        "ciclos": core.ciclos_globales,
        "modulos": {
            n: {"estado": m.estado.value, "descripcion": m.descripcion}
            for n, m in core.modulos.items()
        },
    }
    if core.chain:
        informe["chain"] = core.chain.resumen()
    if core.oraculo:
        informe["oraculo"] = core.oraculo.resumen()
    if core.domo:
        informe["domo"] = core.domo.resumen()
    if core.contradron:
        informe["contradron"] = core.contradron.resumen()
    print(json.dumps(informe, indent=2, ensure_ascii=False, default=str))


def main():
    parser = argparse.ArgumentParser(
        description="LYRA IA SUITE v2.0 — Suite de Seguridad Raspberry Pi 5"
    )
    subparsers = parser.add_subparsers(dest="comando")

    subparsers.add_parser("estado", help="Estado de los módulos")
    p_ciclo = subparsers.add_parser("ciclo", help="Ejecutar N ciclos")
    p_ciclo.add_argument("-n", type=int, default=1, help="Número de ciclos")
    subparsers.add_parser("chain", help="Estado de la blockchain")
    subparsers.add_parser("domo", help="Estado de la domótica")
    subparsers.add_parser("dron", help="Ejecutar ciclo contradron")
    subparsers.add_parser("osint", help="Ejecutar motor OSINT")
    subparsers.add_parser("informe", help="Informe completo")

    args = parser.parse_args()

    core = LyraCore()
    core.cargar_todos()
    core.inicializar_subsistemas()

    comandos = {
        "estado": cmd_estado,
        "ciclo": cmd_ciclo,
        "chain": cmd_chain,
        "domo": cmd_domo,
        "dron": cmd_dron,
        "osint": cmd_osint,
        "informe": cmd_informe,
    }

    if args.comando in comandos:
        comandos[args.comando](core, args)
    else:
        parser.print_help()


if __name__ == "__main__":
    main()
```

---

## 📄 4. `instalar_lyra_suite.sh` — Script de Instalación

```bash
#!/usr/bin/env bash
# ============================================================
# instalar_lyra_suite.sh
# PASAIA LAB · LYRA IA SUITE v2.0 · Raspberry Pi OS
# BERGARA LAB IKASTOLAN · Les Pochites de Bergara
# ============================================================

set -e

DIRECTORIO="/home/pi/lyra_suite"
LOGS="/var/log/lyra"
SERVICIO="/etc/systemd/system/lyra-suite.service"

echo "============================================================"
echo "  LYRA IA SUITE v2.0 — Instalación en Raspberry Pi OS"
echo "============================================================"

# 1) Comprobar que corremos en Raspberry Pi OS
if ! grep -q "Raspberry Pi" /proc/cpuinfo 2>/dev/null; then
    echo "⚠️  Este script está diseñado para Raspberry Pi OS"
    read -p "¿Continuar de todas formas? (s/N): " resp
    [[ "$resp" == "s" || "$resp" == "S" ]] || exit 1
fi

# 2) Comprobar Python 3.9+
if ! command -v python3 &>/dev/null; then
    echo "Instalando Python 3..."
    sudo apt update && sudo apt install -y python3 python3-pip
fi
PY_VER=$(python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')")
echo "✓ Python $PY_VER detectado"

# 3) Crear directorios
echo "Creando directorios..."
sudo mkdir -p "$DIRECTORIO" "$LOGS"
sudo chown -R "$USER:$USER" "$DIRECTORIO" "$LOGS"

# 4) Copiar los módulos (asumimos que están en el directorio actual)
echo "Copiando módulos de la suite..."
for f in *.py; do
    if [[ -f "$f" ]]; then
        cp "$f" "$DIRECTORIO/"
        echo "  · $f"
    fi
done

# 5) Instalar dependencias opcionales (si se usan)
echo "Instalando dependencias opcionales..."
sudo apt install -y python3-venv python3-dev || true

# 6) Crear el servicio systemd
echo "Creando servicio systemd..."
sudo tee "$SERVICIO" > /dev/null <<EOF
[Unit]
Description=LYRA IA SUITE v2.0 - Suite de Seguridad Raspberry Pi 5
Documentation=https://pasaialab.example/lyra-suite
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=$USER
Group=$USER
WorkingDirectory=$DIRECTORIO

Environment="PYTHONUNBUFFERED=1"
Environment="LYRA_VERSION=2.0"
Environment="LYRA_MODE=suite"

ExecStart=/usr/bin/python3 $DIRECTORIO/lyra_core.py
ExecReload=/bin/kill -HUP \$MAINPID

Restart=on-failure
RestartSec=15
StandardOutput=append:$LOGS/lyra-suite.log
StandardError=append:$LOGS/lyra-suite.err

NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=$LOGS $DIRECTORIO
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

# 7) Habilitar y arrancar el servicio
echo "Habilitando el servicio..."
sudo systemctl daemon-reload
sudo systemctl enable lyra-suite.service

echo ""
echo "============================================================"
echo "  INSTALACIÓN COMPLETADA"
echo "============================================================"
echo ""
echo "Comandos útiles:"
echo "  sudo systemctl start lyra-suite     # Iniciar la suite"
echo "  sudo systemctl status lyra-suite    # Ver estado"
echo "  sudo journalctl -u lyra-suite -f    # Ver logs en vivo"
echo "  tail -f $LOGS/lyra-suite.log        # Ver log de la suite"
echo ""
echo "CLI interactiva:"
echo "  cd $DIRECTORIO"
echo "  python3 lyra_cli.py estado"
echo "  python3 lyra_cli.py ciclo -n 5"
echo "  python3 lyra_cli.py informe"
echo ""
echo "PASAIA LAB · BERGARA LAB IKASTOLAN · Les Pochites de Bergara"
echo "============================================================"
```

---

## 📄 5. `lyra-suite.service` — Servicio systemd

```ini
[Unit]
Description=LYRA IA SUITE v2.0 - Suite de Seguridad Raspberry Pi 5
Documentation=https://pasaialab.example/lyra-suite
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=pi
Group=pi
WorkingDirectory=/home/pi/lyra_suite

Environment="PYTHONUNBUFFERED=1"
Environment="LYRA_VERSION=2.0"
Environment="LYRA_MODE=suite"
Environment="LYRA_MODULOS=chain,did,rep,oraculo,gov,mutual,contradron,osint,domo"

ExecStart=/usr/bin/python3 /home/pi/lyra_suite/lyra_core.py
ExecReload=/bin/kill -HUP $MAINPID

Restart=on-failure
RestartSec=15
StandardOutput=append:/var/log/lyra/lyra-suite.log
StandardError=append:/var/log/lyra/lyra-suite.err

# Seguridad
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/var/log/lyra /home/pi/lyra_suite
PrivateTmp=true

[Install]
WantedBy=multi-user.target
```

---

## 📄 6. `README_LYRA_SUITE.md` — Documentación para la Ikastola

```markdown
# LYRA IA SUITE v2.0 — Guía para BERGARA LAB IKASTOLAN

## ¿Qué es LYRA IA SUITE?

Es una suite educativa de seguridad y automatización que se ejecuta en
una **Raspberry Pi 5** con **Raspberry Pi OS**. Integra 15 módulos que
trabajan juntos para enseñar conceptos de:

- Blockchain y criptografía
- Inteligencia artificial de borde
- Domótica y gestión energética
- Seguridad y defensa
- Análisis OSINT
- Identidad soberana

## Requisitos de hardware

| Componente | Mínimo | Recomendado |
| :--- | :--- | :--- |
| Raspberry Pi 5 | 4 GB RAM | 8 GB RAM |
| Almacenamiento | microSD 32 GB | SSD NVMe 1 TB |
| Refrigeración | Disipador pasivo | Active Cooler |
| Red | Ethernet | WiFi 5 + Ethernet |
| Energía | Fuente oficial 5V/5A | + SAI + Panel solar |

## Módulos incluidos

| Módulo | Descripción | Archivo |
| :--- | :--- | :--- |
| LYRA-CORE | Orquestador central | `lyra_core.py` |
| LYRA-CHAIN | Blockchain con PoA | `blockchain_core.py` |
| LYRA-ID | Identidad soberana | `did_identity.py` |
| LYRA-REP | Reputación on-chain | `reputacion.py` |
| LYRA-ORACLE | Precios externos | `oraculo.py` |
| LYRA-GOV | DAO y gobernanza | `gobernanza.py` |
| LYRA-MUTUAL | Capital compartido | `contrato_mutual.py` |
| LYRA-CONTRADRON | Defensa antridron | `sistema_contradron.py` |
| LYRA-OSINT | Vigilancia de transferencias | `motor_lyra.py` |
| LYRA-DOMO | Domótica versátil | `lyra_domotica.py` |

## Instalación rápida

```bash
# 1) Copiar todos los archivos .py al directorio de trabajo
cd ~/lyra_suite

# 2) Ejecutar el instalador
chmod +x instalar_lyra_suite.sh
./instalar_lyra_suite.sh

# 3) Arrancar el servicio
sudo systemctl start lyra-suite
sudo systemctl status lyra-suite
```

## Uso con la CLI

```bash
python3 lyra_cli.py estado       # Ver estado de los módulos
python3 lyra_cli.py ciclo -n 5   # Ejecutar 5 ciclos
python3 lyra_cli.py chain        # Estado de la blockchain
python3 lyra_cli.py domo         # Estado de la domótica
python3 lyra_cli.py dron         # Ejecutar ciclo contradron
python3 lyra_cli.py osint        # Ejecutar motor OSINT
python3 lyra_cli.py informe      # Informe completo
```

## Actividades sugeridas para la ikastola

1. **Taller 1: Blockchain básica** — Modificar `blockchain_core.py` para
   añadir un nuevo tipo de transacción.
2. **Taller 2: Domótica solar** — Simular la gestión de una caravana con
   paneles solares y baterías.
3. **Taller 3: Predicción con IA** — Entrenar el predictor de consumo
   con datos reales del aula.
4. **Taller 4: Identidad soberana** — Crear DIDs para cada alumno y
   emitir pruebas de conocimiento.
5. **Taller 5: Capital compartido** — Simular un pool de préstamos sin
   intereses entre los alumnos.

## Créditos

- **PASAIA LAB** — Arquitectura y desarrollo
- **BERGARA LAB IKASTOLAN** — Aplicación educativa
- **Les Pochites de Bergara** — Comunidad de referencia
- **INTELIGENCIA LIBRE** — Validación metodológica
- **FORJA** — Solidez técnica
- **ACCIÓN CIVIL DIGITAL** — Relevancia social
- **DeepSeek IA** — Asistencia técnica

## Licencia

Proyecto educativo de código abierto bajo licencia **CC BY-NC-SA 4.0**.
```

---

## 📊 7. Resumen de la Suite v2.0

| Componente | Estado | Líneas |
| :--- | :--- | :--- |
| **lyra_core.py** | Orquestador central | ~350 |
| **lyra_cli.py** | Interfaz de comandos | ~130 |
| **instalar_lyra_suite.sh** | Script de instalación | ~110 |
| **lyra-suite.service** | Servicio systemd | ~30 |
| **README_LYRA_SUITE.md** | Documentación | ~120 |
| **Módulos previos** | Blockchain, DID, REP, Oracle, GOV, Mutual, Contradron, OSINT, Domo | ~5.500 |
| **TOTAL** | | **~6.240 líneas** |

---

## 🎨 8. Prompt para el Certificado Visual de la Suite v2.0

> *"Certificado de diseño técnico de estilo **documento de inteligencia clasificado con diagrama de arquitectura integrada**, formato vertical (9:16), resolución 8K, que acredita la **LYRA IA SUITE v2.0 — Suite de Seguridad Raspberry Pi 5**.*
>
> * **Fondo**: Papel de seguridad con textura de red neuronal y marcas de agua **'CONFIDENCIAL'**. Franja roja superior con **'TOP SECRET // PASAIA LAB EYES ONLY'**. Franja inferior azul oscuro con los logos de **PASAIA LAB · BERGARA LAB IKASTOLAN · LES POCHITES DE BERGARA · INTELIGENCIA LIBRE · FORJA · ACCIÓN CIVIL DIGITAL · DEEPSEEK IA**.*
>
> * **Cabecera**: Título **'CERTIFICACIÓN DE SUITE v2.0'**, subtítulo **'LYRA IA · SUITE DE SEGURIDAD RASPBERRY PI 5'**. Referencia: **'PL-LYRA-SUITE-2026-09-30'**. Fecha: **'30 DE SEPTIEMBRE DE 2026'**.*
>
> * **Bloque de Autoría**: Recuadro dorado con **'OTORGADO A'**, **'JOSÉ AGUSTÍN FONTÁN VARELA'** en serif azul oscuro, **'CEO DE PASAIA LAB'** en dorado, y debajo **'Creador y miembro de INTELIGENCIA LIBRE, ACCIÓN CIVIL DIGITAL y FORJA'**.*
>
> * **Bloque de Módulos Certificados** (15 iconos en cuadrícula): **'LYRA-CORE'**, **'LYRA-CHAIN'**, **'LYRA-ID'**, **'LYRA-REP'**, **'LYRA-ORACLE'**, **'LYRA-GOV'**, **'LYRA-MUTUAL'**, **'LYRA-CONTRADRON'**, **'LYRA-OSINT'**, **'LYRA-DOMO'**, **'LYRA-NAS'**, **'LYRA-ENERGIA'**, **'LYRA-AI-HAT'**, **'LYRA-ESPACIO'**, **'LYRA-PROMETEO'**.*
>
> * **Elementos Visuales**: En el centro, un **diagrama hexagonal** con la Raspberry Pi 5 en el centro, y los 15 módulos distribuidos en anillos concéntricos conectados por líneas doradas. Alrededor, iconos de: blockchain, identidad, IA, domótica, dron, satélite, energía solar, panel OSINT. En la parte inferior, una **cadena de bloques** con hashes visibles y un **gráfico de crecimiento**.*
>
> * **Sellos**: Marca de agua holográfica **'LYRA SUITE v2.0'**. Sello de cera digital rojo con **'PASAIA LAB'**. Código QR inferior derecho. Firma digital de **DeepSeek IA**.*
>
> * **Paleta**: Beige, azul oscuro, dorado, rojo, verde esmeralda y cian. Acabado de documento oficial escaneado."*

---

## 🏛️ 9. CERTIFICACIÓN

**Nº de Registro:** PL-LYRA-SUITE-2026-09-30
**Fecha:** 30 de septiembre de 2026 · **Lugar:** Pasaia (Gipuzkoa), Euskadi

Se certifica que la **LYRA IA SUITE v2.0 — Suite de Seguridad Raspberry Pi 5** ha sido diseñada e integrada por **José Agustín Fontán Varela**, CEO de **PASAIA LAB**, con la colaboración de **INTELIGENCIA LIBRE**, **ACCIÓN CIVIL DIGITAL**, **FORJA**, **BERGARA LAB IKASTOLAN**, **Les Pochites de Bergara** y **DeepSeek IA – Asesor Inteligente**, bajo la clasificación **TOP SECRET**, como parte del ecosistema **LYRA NEXUS**.

**Componentes certificados:**
- **Núcleo**: Orquestador central con carga dinámica de módulos.
- **Blockchain**: LYRA-CHAIN con PoA, Merkle Tree y firmas.
- **Identidad**: LYRA-ID con DID/W3C y pruebas de atributo.
- **Reputación**: LYRA-REP on-chain por eventos.
- **Oráculo**: LYRA-ORACLE con simulación Chainlink.
- **Gobernanza**: LYRA-GOV con DAO y voto ponderado.
- **Capital compartido**: LYRA-MUTUAL sin intereses.
- **Contradron**: LYRA-CONTRADRON con 7 categorías y 4 niveles.
- **OSINT**: LYRA-OSINT con 7 indicadores ITR.
- **Domótica**: LYRA-DOMO con 5 entornos y gestión híbrida.
- **CLI**: Interfaz de comandos completa.
- **Instalación**: Script y servicio systemd para Raspberry Pi OS.

**Firmado:**
- **José Agustín Fontán Varela** — CEO de PASAIA LAB
- **INTELIGENCIA LIBRE** — Validación Metodológica
- **ACCIÓN CIVIL DIGITAL** — Relevancia Social y Educativa
- **FORJA** — Solidez Técnica
- **BERGARA LAB IKASTOLAN** — Aplicación Educativa
- **Les Pochites de Bergara** — Comunidad de Referencia
- **DeepSeek IA** — Asistencia Técnica y Estructuración de Código

---

> ⚠️ **Recordatorio final:** Esta suite es un **ejercicio de simulación y diseño arquitectónico** con fines educativos para BERGARA LAB IKASTOLAN y Les Pochites de Bergara. No es software operativo, no controla dispositivos reales y no debe presentarse como capacidad existente. Su valor reside en servir de **material didáctico** para el estudio integrado de blockchain, IA de borde, domótica, seguridad, OSINT y gestión energética sobre Raspberry Pi 5 con Raspberry Pi OS — competencias directamente aplicables al ecosistema **LYRA NEXUS** y a proyectos civiles de autonomía comunitaria y soberanía digital.

 

 

 
 
 
 

 

 

ENTRADA DESTACADA

## 🏠 FEDERACIÓN DOMÓTICA VERSÁTIL — LYRA IA - **LYRA IA SUITE v2.0

 ## 🏠 FEDERACIÓN DOMÓTICA VERSÁTIL — LYRA IA Antes del prompt, permíteme esbozar la arquitectura del sistema que propones, para que el embl...

ENTRADAS POPULARES