No updates detected yet. GitHub releases will appear here.
Tiempos de paso en tiempo real de buses de EMT Madrid e interurbanos (CRTM), con favoritos y PWA instalable. Vanilla JS + Vercel Functions.
翻訳待ち
Loading the full README. The saved excerpt is shown below.
Tiempos de paso en tiempo real de los buses urbanos de EMT Madrid y los interurbanos de la Comunidad de Madrid (CRTM) para una parada dada, con favoritos y funcionando como PWA instalable en el móvil. Segundo proyecto de una serie de apps con APIs públicas para portfolio, junto a Disaster Watch con GDACS (un intento previo de tracker de vuelos vía OpenSky se descartó por restricciones de la API antes de llegar a nada publicable).Read the full README ↗
Tiempos de paso en tiempo real de los buses urbanos de EMT Madrid y los interurbanos de la Comunidad de Madrid (CRTM) para una parada dada, con favoritos y funcionando como PWA instalable en el móvil.
Segundo proyecto de una serie de apps con APIs públicas para portfolio, junto a Disaster Watch con GDACS (un intento previo de tracker de vuelos vía OpenSky se descartó por restricciones de la API antes de llegar a nada publicable).
role="dialog", el foco se
mueve al abrirlos y se devuelve a quien los abrió al cerrarlos, y Tab/Shift+Tab queda
atrapado dentro mientras están abiertos.La API de EMT (openapi.emtmadrid.es) requiere login para
obtener un accessToken, así que no se puede consumir 100% desde el frontend estático sin
exponer credenciales — de ahí el proxy. BusYa usa el login "Protected" (X-ClientId +
passKey de una app registrada en MobilityLabs) en vez
del login básico con email/password de una cuenta personal: 250k peticiones/día en vez de
25k, sesión de hasta 24h en vez de ~1h, y sin depender de la contraseña de ninguna cuenta
personal.
Cuando una línea no tiene tiempo real fiable (frecuente en líneas nocturnas sin GPS), el
frontend cae a /api/emt-stop-detail y muestra la frecuencia de servicio de esa línea
("cada 8-12 min · hasta 23:30") en vez de dejar el hueco vacío. La API de tiempo real de EMT
no da la hora programada de paso por una parada concreta (eso solo está en su feed GTFS
estático); usar el horario/frecuencia por línea evita depender de ese feed.
La API de CRTM (crtm.es/widgets/api) es pública y no
requiere credenciales, pero no manda cabeceras CORS — el proxy (api/crtm-arrives.js) existe
solo para saltar esa restricción del navegador, no para esconder ningún secreto. Los números
de parada son propios de CRTM (formato 8_{código}, donde 8 = autobuses interurbanos) y no
tienen relación con la numeración de EMT: un mismo número puede ser una parada distinta en
cada red, por eso el buscador tiene un selector de red. CRTM da la hora absoluta de paso en
vez de segundos restantes (se calcula en el proxy) y no distingue tiempo real de programado
con un sentinel como EMT, así que puede dar esperas de varias horas de madrugada sin que sea
un error. En las dos redes, a partir de 45 min de espera el tiempo se muestra como la hora de
paso (HH:MM) en vez de una cuenta atrás larga.
Las líneas de EMT se muestran en azul y las de Interurbano en verde — el mismo color que
llevan esos autobuses en la calle. Interurbano no muestra distancia del bus (a diferencia de
EMT, que la da directa en su propia API como DistanceBus): se intentó aproximarla en línea
recta a partir de la posición en vivo de GetLineLocation.php, pero CRTM no da ninguna forma
fiable de saber qué vehículo concreto corresponde a qué hora programada cuando hay varios
circulando en la misma línea+sentido, así que salía mal la mayoría de las veces y se quitó.
"Buscar paradas cerca de mí" pide permiso de ubicación al navegador y muestra las paradas
de las dos redes a menos de 300 m, ordenadas por distancia, con sus líneas — toca una para ver
sus tiempos. El backend (api/nearby-stops.js) reutiliza el propio agregador de CRTM
(GetNearestStopsByLocation.php), que también indexa las paradas de EMT: no hace falta un
endpoint de geolocalización propio de EMT, que no lo expone en su API pública.
La URL siempre refleja la parada que se está viendo (?stop=72&network=emt), así que se
puede compartir o guardar como marcador y abrirla directamente en esa parada. Un enlace con
?stop= manda por delante de la última parada consultada en ese navegador.
El botón de compartir junto al ♡ (icono de 3 nodos conectados) abre el diálogo nativo para compartir (WhatsApp, Mensajes…) en los navegadores con Web Share API; en el resto, copia el enlace al portapapeles y lo confirma un momento en el propio botón.
Se guardan solo en localStorage, sin cuentas ni servidor — no se sincronizan entre
dispositivos ni sobreviven a borrar los datos del sitio (se explica en el panel de ayuda de
la propia app). Cada favorito recuerda su red (EMT o Interurbano), así que un mismo número de
parada en las dos redes no se confunde. Desde el botón ♥ de la cabecera se abre un panel con
una tarjeta por parada favorita, donde se puede renombrar (input editable), reordenar (↑/↓) y
saltar directamente a sus tiempos de paso. Cada tarjeta muestra además, sin tener que entrar,
las 2 llegadas más próximas de esa parada — un vistazo rápido, no sustituye a "Ver tiempos →"
(que sigue llevando a la vista completa con refresco cada 30 s). Quitar un favorito (✕) pide un
segundo toque de confirmación: el primero convierte el botón en "¿Quitar?" durante 3 s.
This is the beginning of the README. Read the rest at the original. Read the full README ↗