# Manual de instalación y operación

## Gateway Lartek L5-SNMP/LILO — firmware 1.3-rc10

### 1. Descripción funcional

El L5-SNMP/LILO es un gateway basado en STM32F103C8T6 que concentra mediciones de sensores y las publica por Ethernet mediante SNMP. Puede trabajar en dos modos principales:

- **LILO:** comunica hasta nueve nodos sobre un bus de un solo hilo. Cada nodo posee una dirección única de tres caracteres y normalmente publica la medición `v0`.
- **Dallas:** lee un sensor DS18B20 conectado a PB11 y entrega la temperatura en décimas de grado Celsius.

En modo LILO, el equipo consulta periódicamente los parámetros configurados y también acepta reportes espontáneos. Los valores se pueden consultar por USB, Telnet o SNMP. El gateway no envía traps SNMP.

La versión 1.3-rc10 incluye:

- watchdog independiente (IWDG) permanente, con plazo nominal de 10 segundos;
- reinicio preventivo automático cada 24 horas;
- registro de la causa del último reinicio y del tiempo encendido;
- configuración persistente en dos regiones alternadas de Flash, con CRC y validación;
- alta automática de nodos LILO mediante `addme`/`added`;
- aprendizaje pasivo de nodos durante cinco minutos mediante `params.auto`;
- supervisión del enlace físico del ENC28J60 y recuperación automática de Ethernet;
- reinicio de Ethernet cada seis horas y cada 30 minutos sin actividad SNMP, Telnet o serie.

### 2. Interfaces e indicadores

**USB serie:** puerto serie virtual a 115200 bit/s. No requiere contraseña y es la interfaz recomendada para instalación y recuperación.

**Ethernet:** permite acceso por Telnet en el puerto TCP 23 y consultas SNMPv1 en el puerto configurado —161 de fábrica—. No genera notificaciones SNMP espontáneas.

**Bus LILO:** usa PB12 como RX y TX half-duplex, a 4800 bit/s, 8N1 y sin inversión. La salida es open-drain; la línea necesita un pull-up externo. La alimentación del bus depende de la revisión de hardware: este firmware no conmuta PA0.

**LED verde, PC13:** indica principalmente el estado de Ethernet. Permanece encendido cuando la red está operativa y se apaga durante inicialización, comprobaciones o error.

**LED rojo, PB6:** produce un pulso ante actividad LILO o una solicitud SNMP.

Al arrancar, ambos LED destellan durante aproximadamente tres segundos. Durante la prueba `killme`, ambos quedan encendidos hasta que actúa el watchdog y el equipo vuelve a iniciar.

### 3. Acceso a la consola

Los comandos se escriben en minúsculas y se terminan con Enter. En los comandos que asignan un valor conviene conservar exactamente el espacio posterior a los dos puntos, por ejemplo `net.ip: 192.168.1.20`.

- Por **USB**, abrir el monitor serie a 115200 bit/s. Los comandos se aceptan directamente.
- Por **Telnet**, conectarse a la IP del equipo, puerto 23, e ingresar la contraseña. La contraseña de fábrica es `lartek`; debe cambiarse antes de instalar el equipo. Después de cuatro intentos incorrectos el acceso se bloquea durante 60 segundos. La sesión se cierra tras cinco minutos sin actividad.

Telnet no cifra la contraseña ni el tráfico. Debe utilizarse solamente desde una red de gestión confiable.

Salvo que se indique lo contrario, los cambios de configuración se aplican primero en RAM. Ejecutar `config.save` para conservarlos después de un reinicio. El alta `addme`, los SET SNMP que modifican configuración y el cierre normal de `params.auto` realizan su propio guardado.

### 4. Puesta en marcha recomendada

1. Conectar por USB y ejecutar `info`, `status` y `estado`.
2. Definir un ID de inventario, una dirección LILO de tres caracteres y una MAC única.
3. Seleccionar el bus y configurar Ethernet y SNMP.
4. Ejecutar `config.save` y comprobar que responda `save verificado`.
5. Reiniciar con `reboot` y verificar nuevamente `status`, `estado`, `config?`, `net?` y `params?`.
6. Incorporar los nodos por su pulsador, con `params.auto` o manualmente.

No instalar varios equipos con la misma MAC ni con la misma dirección LILO.

### 5. Lista de comandos

#### Estado, sesión y mantenimiento

| Comando | Función |
|---|---|
| `?` | Muestra los grupos principales de comandos. |
| `info` | Informa producto, versión, ID y dirección LILO. |
| `status` | Muestra segundos encendido, causa y banderas de reset, y estado del watchdog. |
| `estado` | Muestra el estado de Ethernet, la IP efectiva y los valores activos. |
| `m1` / `m0` | Activa o detiene el monitor de valores cada dos segundos. El monitor se detiene solo después de 15 minutos. |
| `se1` / `se0` | Activa o desactiva el eco de caracteres por USB. Requiere `config.save` para persistir. |
| `reboot` | Reinicia el microcontrolador por software aproximadamente un segundo después. |
| `killme` | Fuerza un bloqueo para probar el IWDG. Usar únicamente durante una prueba controlada. |
| `passwd` | Cambia interactivamente la contraseña de Telnet y la guarda de inmediato. Se usa desde una sesión Telnet autenticada. |
| `exit` | Cierra la sesión Telnet. |

Las causas más habituales informadas por `status` son `software`, `watchdog independiente (IWDG)`, `encendido/baja tension` y `pin NRST`. El reinicio manual y el automático de 24 horas aparecen como reinicio por software.

#### Identidad y bus

| Comando | Función |
|---|---|
| `id?` | Consulta el ID de inventario, de hasta siete caracteres. |
| `id: GW-001` | Asigna el ID. Una vez asignado, primero debe restablecerse con `id: ####` para poder cambiarlo. |
| `bus?` | Consulta el modo de bus actual. |
| `bus: lilo` | Activa el bus LILO por PB12. |
| `bus: dallas` | Activa un DS18B20 por PB11; utiliza `param1` con código `temp`. Al seleccionar este modo se reconstruye la tabla de parámetros en RAM. |
| `lilo?` | Consulta dirección, tipo y nombre LILO del gateway. |
| `lilo.address: G01` | Configura la dirección LILO del gateway. Debe contener exactamente tres caracteres y ser única en el bus. |
| `lilo.name: GW1` | Configura el nombre LILO; en esta versión se conservan tres caracteres. |
| `lilo: 007v0?` | Envía a `007` el mensaje `v0?` y muestra la respuesta o un timeout. Es una prueba de diagnóstico. |

#### Ethernet

El prefijo `ethernet` es alias de `net`; por ejemplo, `ethernet?` equivale a `net?`.

| Comando | Función |
|---|---|
| `net?` | Muestra la configuración, IP efectiva, estado interno, enlace físico, segundos desde la última actividad y diagnóstico de reinicios de Ethernet. |
| `net.mac: 18:0a:1a:91:40:01` | Configura la MAC. Debe ser única para cada equipo. |
| `net.ip: 192.168.1.20` | Configura una IP fija. Usar `0.0.0.0` para DHCP. |
| `net.subnet: 255.255.255.0` | Configura la máscara de red. |
| `net.gateway: 192.168.1.1` | Configura la puerta de enlace. |
| `net.dns: 192.168.1.1` | Configura el servidor DNS. |
| `net.start` | Reinicia la inicialización de Ethernet con los valores que están en RAM. |

La máscara (`net.subnet`) debe corresponder a la red: por ejemplo, `255.255.255.0` en una red /24. No ingresar allí la dirección del gateway. Después de modificarla, ejecutar `config.save` y `net.start`. El firmware conserva la máscara guardada al actualizar; no la corrige automáticamente.

En la respuesta de `net?`, `.status` describe el estado interno de la máquina Ethernet y `.link` consulta el enlace físico real del ENC28J60 (`up`, `down` o `unknown`). Un `.status: ok` por sí solo no demuestra conectividad extremo a extremo.

`.last_activity_seconds` cuenta el tiempo desde la última solicitud SNMP válida, conexión o comando Telnet, o comando serie. `.restart_count` cuenta los reinicios de Ethernet solicitados desde que arrancó el microcontrolador y `.last_restart_reason` puede indicar `startup`, `manual`, `periodic`, `idle`, `link_restored` o `error`.

Ethernet se reinicia preventivamente cada seis horas. Además, si transcurren 30 minutos sin las actividades anteriores, se reinicia y el temporizador vuelve a quedar armado. Cuando se detecta que un enlace caído volvió a subir, también se reinicializa la interfaz.

#### SNMP

Usar **SNMPv1**, la comunidad de lectura configurada (`public` de fábrica) y el puerto UDP configurado (`161` de fábrica). Cada solicitud admite un solo OID. Para recorrer el árbol, usar WALK basado en GET NEXT con un OID por paquete; GET BULK y SNMPv2c/v3 no están implementados.

Desde 1.3-rc9, una consulta incompatible, con comunidad incorrecta o malformada se descarta liberando la escucha para los demás clientes. Se corrige además una pérdida de consultas introducida en rc8 cuando llegaban entre dos comprobaciones de recepción. No se requiere `net.start` para recuperarse de esos descartes.

Una vez obtenida una IP válida, SNMP y Telnet se inicializan en las siguientes pasadas del programa, sin la espera adicional de cinco a siete segundos de versiones anteriores. La obtención de IP por DHCP conserva sus tiempos internos.

| Comando | Función |
|---|---|
| `snmp?` | Consulta comunidades, puerto, contacto, nombre y ubicación. |
| `snmp.getcom: lectura` | Configura la comunidad de lectura, máximo 20 caracteres. |
| `snmp.setcom: escritura` | Configura la comunidad de escritura, máximo 20 caracteres. |
| `snmp.port: 161` | Configura el puerto UDP del agente SNMP. |
| `snmp.contact: soporte@empresa` | Configura `sysContact`. |
| `snmp.name: SalaMaquinas` | Configura `sysName`. |
| `snmp.location: Planta 1` | Configura `sysLocation`. |

Desde 1.3-rc10 se eliminaron el envío de traps, los comandos `trap?`, `trap.*` y `paramN.ttl`, y el OID de destino `1.3.6.1.2.1.52686.4.1`. Los ajustes antiguos se ignoran aunque estuvieran habilitados. Las consultas de mediciones, GET NEXT/WALK y los demás SET SNMP siguen disponibles; no es necesario borrar la configuración al actualizar desde otra versión 1.3.

Después de cambiar el puerto o las comunidades SNMP, guardar y ejecutar `net.start` o `reboot` para reinicializar el agente.

Los nueve valores están disponibles en los OID `1.3.6.1.2.1.52686.1.0` a `1.3.6.1.2.1.52686.1.8`. También se exponen los objetos estándar `sysDescr`, `sysUpTime`, `sysContact`, `sysName` y `sysLocation`. El agente implementa SNMPv1.

#### Parámetros y aprendizaje LILO

`N` puede valer de 0 a 8; la capacidad total es de nueve parámetros.

| Comando | Función |
|---|---|
| `params?` | Lista los nueve códigos y muestra `.auto: on` si hay una ventana de aprendizaje activa. |
| `paramN?` | Muestra código, valor, calificador y errores del parámetro N. |
| `paramN.code: 007v0` | Asocia manualmente el parámetro N a la medición `v0` del nodo `007`. |
| `paramN.code:` | Deja libre el parámetro N. |
| `params.auto` | Abre durante cinco minutos una ventana de aprendizaje. Agrega los nodos nuevos que reporten `v0`, conserva los existentes y guarda la tabla al terminar. |
| `params.clear` | Vacía la tabla en RAM y cancela el aprendizaje. No guarda automáticamente. |

El antiguo comando `params.discover` ya no está disponible.

**Alta por pulsador:** en modo LILO no hace falta abrir una ventana. Cuando un nodo transmite `addme` por broadcast, el gateway toma los tres caracteres de origen, guarda el código `<ID>v0` en el primer lugar libre y recién entonces responde `added` a la dirección específica del nodo. Si el nodo ya estaba asociado, conserva su configuración y vuelve a responder. Si la tabla está llena o falla la escritura en Flash, no envía la confirmación.

#### Persistencia y diagnóstico

| Comando | Función |
|---|---|
| `config.save` | Guarda y verifica la configuración. Alterna entre las copias A y B; si nada cambió evita otra escritura. |
| `config.load` | Recupera la última copia válida. Se recomienda reiniciar después para reinicializar todos los servicios. |
| `config.default` | Restaura en RAM la mayoría de los valores de fábrica. Conserva la MAC actual y no reasigna el ID ni la dirección LILO. Luego debe ejecutarse `config.save`. |
| `config?` | Muestra la copia activa (`config_slot`), su secuencia (`config_sequence`) y el resultado del último guardado (`config_last_save`). |
| `debug?` | Muestra los diagnósticos activos. |
| `debug: 1` / `debug: 0` | Activa o desactiva todos los diagnósticos. |
| `debug.main: 1` | Diagnóstico general. También existen `debug.ethernet`, `debug.lilo`, `debug.snmp`, `debug.params` y `debug.dallas`; usar `0` para desactivar. |

### 6. Ejemplos

#### Configuración inicial con IP fija

~~~text
config.default
id: GW-001
bus: lilo
lilo.address: G01
lilo.name: GW1
net.mac: 18:0a:1a:91:40:01
net.ip: 192.168.1.20
net.subnet: 255.255.255.0
net.gateway: 192.168.1.1
net.dns: 192.168.1.1
snmp.getcom: monitor
snmp.setcom: administrar
config.save
reboot
~~~

Después del arranque:

~~~text
info
status
estado
config?
net?
params?
~~~

Cambiar la contraseña Telnet conectándose con la clave vigente y ejecutando `passwd`.

#### Uso de DHCP

~~~text
net.ip: 0.0.0.0
config.save
net.start
~~~

Esperar la negociación y consultar `estado` o `net?` para conocer la IP asignada.

#### Alta automática por pulsador

1. Confirmar `bus: lilo` y al menos un lugar libre con `params?`.
2. Pulsar el botón de aprendizaje del nodo.
3. El nodo transmite `addme`; el gateway guarda, responde `added` y comienza a consultar `<ID>v0`.
4. Ejecutar `params?` y luego `paramN?` sobre el lugar ocupado.
5. Ejecutar `reboot` y confirmar que la asociación continúa presente.

#### Aprender todos los nodos que reportan

Para conservar la lista existente y sumar nodos:

~~~text
params.auto
~~~

Mantener el equipo encendido durante los cinco minutos. Para reconstruir completamente la tabla:

~~~text
params.clear
params.auto
~~~

Esta segunda secuencia borra la lista en RAM y guarda el resultado nuevo al cerrar la ventana. No reiniciar el equipo antes de que terminen los cinco minutos.

#### Alta manual y consulta de una medición

~~~text
param0.code: 007v0
config.save
param0?
~~~

#### Prueba de reinicio y watchdog

~~~text
reboot
status
~~~

Después de `reboot`, la causa debe incluir `software` y el tiempo encendido debe ser bajo, indicando que comenzó nuevamente. Para probar el watchdog en banco:

~~~text
killme
~~~

El equipo deja de responder, enciende ambos LED y debe reiniciar por IWDG aproximadamente diez segundos después. Al reconectar el USB, `status` debe informar `watchdog independiente (IWDG)`.

### 7. Carga del firmware

Para compilar con Arduino 1.8.13 seleccionar:

- placa **Generic STM32F103C series**;
- variante **STM32F103C8 Lartek (62K + 2K config)**;
- método de carga **STLink**;
- CPU **72 MHz**;
- optimización **Smallest**.

El BIN se carga manualmente con STM32 ST-Link Utility en `0x08000000`. La versión compilada se comprueba con `info`. No usar una variante con bootloader DFU ni otra distribución de memoria.

Las dos últimas páginas de Flash, `0x0800F800` y `0x0800FC00`, contienen la configuración A/B. Un borrado total elimina ambas copias. Si se desea comenzar desde cero, esto es válido, pero luego deben provisionarse como mínimo MAC, ID, dirección LILO, red, contraseña y comunidades antes de conectar el equipo a producción.

### 8. Recomendaciones de operación

- Usar una MAC y una dirección LILO únicas por gateway.
- Cambiar la contraseña y las comunidades predeterminadas.
- Confirmar cada instalación con `status`, `estado`, `net?` —incluido `.link: up`—, `params?` y una consulta SNMP real.
- Después de configurar, comprobar `.config_last_save: ok` mediante `config?`.
- Probar `killme` solamente en banco o durante una ventana de mantenimiento.
- Mantener respaldo del BIN instalado y de los valores particulares de cada equipo.
- Antes de actualizar una instalación existente, recordar que un borrado total de Flash también borra la configuración.

Este manual describe el comportamiento del firmware 1.3-rc10. Las notas técnicas y limitaciones detalladas se encuentran en `RELEASE_1.3.md`, `RELEASE_1.3_RC4_PB12.md`, `RELEASE_1.3_RC5_PARAMS_AUTO.md`, `RELEASE_1.3_RC6_STATUS.md`, `RELEASE_1.3_RC7_ETHERNET.md`, `RELEASE_1.3_RC8_SNMP.md`, `RELEASE_1.3_RC9_RECEPCION.md` y `RELEASE_1.3_RC10_SIN_TRAPS.md`.
