Todos los artículos

Predecir mareas para la seguridad en deportes acuáticos: un microservicio pequeño y obsesivamente preciso

Publicado 19 jun 20264 min de lectura
  • MeteoTrail
  • Ingeniería
  • Montaña

Ideas clave

  • Las predicciones de marea astronómica (FES2022b vía pyfes) no son el nivel del mar observado — el temporal costero, la presión y el empuje del viento quedan excluidos por diseño.
  • Los valores por defecto que fallan cerrado — sin CORS, tokens Bearer obligatorios, 503 con Retry-After mientras carga el atlas — importan también en servicios internos de máquina a máquina.
  • Recortar un atlas de marea global de varios gigabytes en un 'paquete' regional pequeño redujo el arranque del pod de minutos a segundos.

Ya hemos escrito antes sobre MeteoTrail y sobre el agregador de alertas meteorológicas del gobierno que lo alimenta — ambos surgieron del mismo instinto: los operadores de deportes acuáticos necesitan saber, con precisión y con antelación, cuándo las condiciones se les ponen en contra. Buceo, kayak, clases de surf — las cinco verticales que describimos en "Un motor de reservas, cinco deportes" — comparten todas una dependencia en la que casi nadie piensa: la altura real del mar en un momento dado. Algunos puntos de inmersión y embarcaderos de kayak del catálogo de Lueira solo son accesibles con seguridad dentro de una ventana de marea concreta. Así que este año construimos un servicio pequeño, deliberadamente estrecho, para responder bien a una sola pregunta: cuál será la marea astronómica, en este punto, en este momento.

1. Una pregunta estrecha y precisa

tides-service es un servicio interno en FastAPI. Predice mareas astronómicas usando el atlas global de marea oceánica FES2022b, a través de la librería de código abierto pyfes. Se consume de máquina a máquina, principalmente desde el backend de Lueira, y no está expuesto públicamente. Responde exactamente a tres preguntas:

  • GET /v1/tides — una serie temporal de alturas entre dos timestamps
  • GET /v1/tides/extremes — los eventos de pleamar/bajamar de un día UTC dado
  • GET /v1/locations/check — si esta coordenada está en el agua o en tierra, y si está en tierra, cuál es la celda mojada más cercana dentro de un radio configurado

Las tres están protegidas con Bearer token. CORS está desactivado por defecto — la misma postura de fallo cerrado que el requisito de autenticación. Y hasta que el atlas de marea, de varios gigabytes, ha terminado de cargarse en memoria al arrancar, los dos endpoints de predicción devuelven 503 con una cabecera Retry-After y un cuerpo {"code": "model_loading"}. GET /healthz es el único endpoint abierto, y reporta si ese atlas ha terminado de cargarse.

Una respuesta simplificada de /v1/tides/extremes:

{
  "location": {"lat": 43.283, "lon": -2.170},
  "date": "2026-06-19",
  "reference": "MSL",
  "extremes": [
    {"type": "low",  "time": "2026-06-19T02:14:00Z", "height_m": 0.62},
    {"type": "high", "time": "2026-06-19T08:31:00Z", "height_m": 3.41},
    {"type": "low",  "time": "2026-06-19T14:42:00Z", "height_m": 0.58},
    {"type": "high", "time": "2026-06-19T20:59:00Z", "height_m": 3.55}
  ],
  "attribution": "FES2022 was produced by LEGOS, NOVELTIS and CLS; funded by CNES; distributed by AVISO, DOI 10.24400/527896/A01-2024.004."
}

2. Lo que la predicción de marea NO te dice

tides-service predice solo la marea astronómica, relativa al Nivel Medio del Mar. Esa es la altura que la luna y el sol, mediante su atracción gravitatoria, producirían en un punto y momento dados si no estuviera pasando nada más. No incluye el temporal costero (storm surge), los efectos de la presión atmosférica, el empuje del viento (wind setup), ni ninguna otra contribución no astronómica al nivel del mar observado.

Un sistema de bajas presiones profundo puede elevar el agua notablemente por encima de lo que dice la marea astronómica. Un viento de componente marítimo sostenido amontona agua contra la costa por encima de eso. Nada de eso aparece en una respuesta de tides-service, por diseño. Una funcionalidad de seguridad para reservas de deportes acuáticos no puede simplemente tratar un número de tides-service como "el nivel del agua" — es un dato preciso más entre varios, junto con los datos de viento y presión.

3. Reducir un atlas de varios gigabytes a lo que realmente necesitas

El atlas global completo FES2022b pesa varios gigabytes, y tenemos licencia para usarlo pero no para redistribuirlo públicamente según los términos de AVISO, así que vive en un DigitalOcean Space privado. En lugar de que cada pod descargue el atlas global completo al arrancar, escribimos un script que recorta el atlas a una caja delimitadora alrededor de nuestra área de operación real — la península ibérica, el golfo de Vizcaya y las Islas Canarias. El arranque pasó de minutos a segundos.

La parte delicada es que el atlas almacena la longitud en la convención de 0–360°. Nuestra área de operación cruza el meridiano de Greenwich, así que la caja delimitadora se monta a horcajadas sobre la costura 0/360:

REGION_BBOX = {
    "lat_min": 27.0, "lat_max": 46.5,
    "lon_ranges_0_360": [(342.0, 360.0), (0.0, 4.5)],
}

def crop_region(atlas, bbox):
    west, east = bbox["lon_ranges_0_360"]
    west_slice = atlas.sel(lon=slice(*west))
    east_slice = atlas.sel(lon=slice(*east))
    west_slice = west_slice.assign_coords(lon=west_slice.lon - 360)
    return xr.concat([west_slice, east_slice], dim="lon").sortby("lon")

Si te equivocas en esa costura no obtienes un error — obtienes una predicción de marea que está silenciosamente equivocada justo en el borde occidental de la región.

4. Comprobar nuestro trabajo contra una autoridad portuaria real

Junto con la suite de tests habitual, ejecutamos tests "golden" que comparan los extremos de marea predichos por tides-service en una ubicación real — Zarautz, en la costa vasca — contra las tablas de marea publicadas por Puertos del Estado. Es la diferencia entre "nuestro modelo está de acuerdo consigo mismo" y "nuestro modelo está de acuerdo con la realidad".

Nada de esto es un trabajo glamuroso. Pero una respuesta estrecha y precisa a una sola pregunta de física, honestamente delimitada, vale más para una funcionalidad de seguridad que un servicio amplio de "condiciones oceánicas" que difumina silenciosamente la marea astronómica con todo lo demás que afecta al nivel del mar.