Tots els articles

Predir marees per a la seguretat en els esports aquàtics: un microservei petit i obsessivament precís

Publicat 19 de juny del 20263 min de lectura
  • MeteoTrail
  • Enginyeria
  • Muntanya

Idees clau

  • Les prediccions de marea astronòmica (FES2022b via pyfes) no són el nivell del mar observat — el temporal costaner, la pressió i l'empenta del vent queden exclosos per disseny.
  • Els valors per defecte que fallen tancat — sense CORS, tokens Bearer obligatoris, 503 amb Retry-After mentre carrega l'atles — importen també en serveis interns de màquina a màquina.
  • Retallar un atles de marea global de diversos gigabytes en un 'paquet' regional petit va reduir l'arrencada del pod de minuts a segons.

Ja hem escrit abans sobre MeteoTrail i sobre l'agregador d'alertes meteorològiques del govern que l'alimenta — tots dos van sorgir del mateix instint: els operadors d'esports aquàtics necessiten saber, amb precisió i amb antelació, quan les condicions se'ls giren en contra. Busseig, caiac, classes de surf — les cinc verticals que vam descriure a "Un motor de reserves, cinc esports" — comparteixen totes una dependència en què gairebé ningú pensa: l'alçada real del mar en un moment donat. Alguns punts d'immersió i embarcadors de caiac del catàleg de Lueira només són accessibles amb seguretat dins d'una finestra de marea concreta. Així que enguany vam construir un servei petit, deliberadament estret, per respondre bé a una sola pregunta: quina serà la marea astronòmica, en aquest punt, en aquest moment.

1. Una pregunta estreta i precisa

tides-service és un servei intern en FastAPI. Prediu marees astronòmiques fent servir l'atles global de marea oceànica FES2022b, mitjançant la llibreria de codi obert pyfes. Es consumeix de màquina a màquina, principalment des del backend de Lueira, i no està exposat públicament. Respon exactament a tres preguntes:

  • GET /v1/tides — una sèrie temporal d'alçades entre dos timestamps
  • GET /v1/tides/extremes — els esdeveniments de plenamar/baixamar d'un dia UTC donat
  • GET /v1/locations/check — si aquesta coordenada és a l'aigua o a terra, i si és a terra, quina és la cel·la mullada més propera dins d'un radi configurat

Totes tres estan protegides amb Bearer token. CORS està desactivat per defecte — la mateixa postura de fallada tancada que el requisit d'autenticació. I fins que l'atles de marea, de diversos gigabytes, ha acabat de carregar-se a memòria en arrencar, els dos endpoints de predicció retornen 503 amb una capçalera Retry-After i un cos {"code": "model_loading"}. GET /healthz és l'únic endpoint obert, i informa si aquell atles ha acabat de carregar-se.

Una resposta 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. El que la predicció de marea NO et diu

tides-service prediu només la marea astronòmica, relativa al Nivell Mitjà del Mar. Aquesta és l'alçada que la lluna i el sol, mitjançant la seva atracció gravitatòria, produirien en un punt i moment donats si no passés res més. No inclou el temporal costaner (storm surge), els efectes de la pressió atmosfèrica, l'empenta del vent (wind setup), ni cap altra contribució no astronòmica al nivell del mar observat.

Un sistema de baixes pressions profund pot elevar l'aigua notablement per sobre del que diu la marea astronòmica. Un vent de component marítim sostingut amuntega aigua contra la costa a sobre d'això. Res d'això apareix en una resposta de tides-service, per disseny. Una funcionalitat de seguretat per a reserves d'esports aquàtics no pot simplement tractar un número de tides-service com "el nivell de l'aigua" — és una dada precisa més entre diverses, juntament amb les dades de vent i pressió.

3. Reduir un atles de diversos gigabytes al que realment necessites

L'atles global complet FES2022b pesa diversos gigabytes, i tenim llicència per fer-lo servir però no per redistribuir-lo públicament segons els termes d'AVISO, així que viu en un DigitalOcean Space privat. En lloc que cada pod es baixi l'atles global complet en arrencar, vam escriure un script que retalla l'atles a una capsa delimitadora al voltant de la nostra àrea d'operació real — la península ibèrica, el golf de Biscaia i les Illes Canàries. L'arrencada va passar de minuts a segons.

La part delicada és que l'atles emmagatzema la longitud en la convenció de 0–360°. La nostra àrea d'operació creua el meridià de Greenwich, així que la capsa delimitadora es munta a cavall de 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 t'equivoques en aquesta costura no obtens un error — obtens una predicció de marea que està silenciosament equivocada just a la vora occidental de la regió.

4. Comprovar la nostra feina contra una autoritat portuària real

Juntament amb la suite de tests habitual, executem tests "golden" que comparen els extrems de marea predits per tides-service en una ubicació real — Zarautz, a la costa basca — contra les taules de marea publicades per Puertos del Estado. És la diferència entre "el nostre model està d'acord amb si mateix" i "el nostre model està d'acord amb la realitat".

Res d'això és una feina glamurosa. Però una resposta estreta i precisa a una sola pregunta de física, honestament delimitada, val més per a una funcionalitat de seguretat que un servei ampli de "condicions oceàniques" que difumina silenciosament la marea astronòmica amb tot el que altre afecta el nivell del mar.