# Disponibilité des vélos en temps réel : comment l’afficher dans une application ?

> Affichez la disponibilité des vélos avec l’API ROOTE : horodatage, fraîcheur, valeurs inconnues, rafraîchissement et données périmées dans votre application.

Source: https://www.roote.ai/fr/guides/disponibilite-velos-application/
Language: fr
Author: ROOTE

Pour afficher la disponibilité des vélos en temps réel dans une application, associez le nombre retourné à sa fraîcheur et aux possibilités de prise du véhicule. Une observation décrit ce que la source connaissait à un instant ; elle ne garantit pas qu’un vélo sera encore présent à l’arrivée.

Le contrat de mobilité ROOTE distingue les stations, les véhicules individuels et leurs états. L’interface doit traduire ces différences sans confondre une valeur inconnue, une station vide et une source temporairement indisponible.

## Séparer une station d’un véhicule individuel

Une station peut exposer des compteurs de vélos et de places de retour. Un véhicule individuel possède un état de disponibilité et d’autres informations éventuelles. Évitez de compter une station comme un vélo ou d’additionner des compteurs représentant le même stock.

Dans le DTO de mobilité ROOTE, availability.bikes et availability.docks peuvent être inconnus. Les champs de propulsion ou de batterie ne doivent être affichés que s’ils existent et sont interprétés selon le contrat.

[Contrat OpenAPI ROOTE](https://api.roote.ai/openapi.json)

## Lire la fraîcheur et les horodatages

| Champ | Interprétation |
| --- | --- |
| freshness.state | État annoncé : fresh, stale, unknown ou static |
| freshness.source_updated_at | Date de mise à jour de la source, si connue |
| freshness.received_at | Date de réception indiquée par le contrat |
| freshness.expires_at | Échéance de validité indiquée, si connue |
| availability.bikes | Quantité connue ou valeur inconnue |
| pickup.enabled et pickup.state | Informations sur la prise d’un vélo à la station |

L’heure de votre appel n’est pas automatiquement celle de l’observation. Un résultat reçu à 10 h peut contenir une source mise à jour à 9 h 45. N’affichez pas « mis à jour maintenant » à partir de la seule heure de réception de votre interface.

## Prévoir des états d’affichage distincts

| Donnée reçue | Affichage à prévoir |
| --- | --- |
| Quantité connue et donnée fraîche | Quantité observée et indication temporelle |
| Quantité égale à zéro | Aucun vélo observé, avec son contexte temporel |
| Quantité null | Disponibilité inconnue |
| État stale ou échéance dépassée | Donnée ancienne ; proposer une actualisation |
| pickup.enabled=false | Prise indisponible même si un compteur est positif |
| Erreur de recherche | Disponibilité momentanément indisponible, sans convertir en zéro |

Ne classez pas un état unknown ou static comme frais. Une information de station peut être stable alors que le compteur évolue rapidement. Conservez aussi les avertissements et les attributions exigées par la réponse.

## Un exemple de normalisation avant le rendu

La fonction suivante produit un état de présentation à partir d’une station déjà validée contre le schéma ROOTE. Elle n’est pas un validateur de réponse complet. Les libellés visibles doivent venir des clés de traduction de votre interface.

```
function availabilityView(station, now = Date.now()) {
  const freshness = station.freshness;
  const expiresAt = freshness.expires_at
    ? Date.parse(freshness.expires_at) : null;
  const expired = expiresAt !== null &&
    Number.isFinite(expiresAt) && expiresAt <= now;
  if (station.pickup.enabled === false ||
      station.pickup.state === 'unavailable_now') {
    return { state: 'pickup_unavailable', count: null };
  }
  if (expired || freshness.state === 'stale') {
    return { state: 'stale', count: null };
  }
  const count = station.availability.bikes;
  if (freshness.state !== 'fresh' || count === null ||
      !Number.isFinite(count) || count < 0) {
    return { state: 'unknown', count: null };
  }
  return {
    state: count === 0 ? 'empty' : 'observed', count,
    sourceUpdatedAt: freshness.source_updated_at,
    receivedAt: freshness.received_at,
    pickupState: station.pickup.state
  };
}
```

Même avec un état observed, ne transformez pas pickupState=unknown en prise confirmée. Le compteur reste une observation. Affichez le contexte de prise si votre produit aide l’utilisateur à choisir une station.

## Rafraîchir sans multiplier inutilement les appels

Adaptez le rafraîchissement à l’expiration publiée, aux conditions du service et au comportement de l’utilisateur. Regroupez les demandes identiques, évitez les appels en arrière-plan sur une page inactive et annulez ceux d’une recherche remplacée.

Un délai local de cache ne prouve pas la fraîcheur de la source. Après une erreur, vous pouvez conserver une dernière observation datée si votre interface la présente explicitement comme ancienne. N’effacez pas cette distinction à la première reprise réussie si la source reste stale.

## Comprendre le lien avec GBFS

GBFS décrit les services de mobilité partagée et leurs états publiés. Une intégration directe doit interpréter les fichiers, la version et les horodatages du flux. Avec une API normalisée, utilisez le contrat de l’API ; n’ajoutez pas un champ GBFS supposé absent de sa réponse.

[Choisir entre GTFS, GTFS Realtime et GBFS](https://www.roote.ai/fr/guides/gtfs-gtfs-rt-gbfs-differences/)

## Tester les situations qui trompent le lecteur

Testez un zéro réel, une valeur inconnue, une échéance dépassée, une prise désactivée et une erreur après un résultat valide. Vérifiez aussi les fuseaux horaires d’affichage. Un compteur positif ne doit jamais produire « vélo réservé » et une indisponibilité ne doit jamais produire un zéro inventé.

[Gérer les réponses vides et les erreurs](https://www.roote.ai/fr/guides/aucun-resultat-erreur-api/)

[Appliquer ces règles dans un assistant IA](https://www.roote.ai/fr/guides/creer-assistant-mobilite-adresse/)

[Guide utilisateur pour trouver un vélo](https://www.roote.ai/fr/guides/trouver-velo-libre-service/)

## Questions fréquentes

### Une quantité positive garantit-elle un vélo à mon arrivée ?

Non. Elle décrit une observation, qui peut changer entre la recherche et votre arrivée.

### Peut-on remplacer null par zéro ?

Non. null indique une valeur inconnue ; zéro est une quantité connue et porte un autre sens.

### Faut-il rafraîchir toutes les quelques secondes ?

Utilisez les indications de validité, les limites du service et les besoins de votre interface. Une fréquence arbitraire ne garantit pas une source plus fraîche.
