# Доступність велосипедів у реальному часі: як її відобразити в додатку?

> Відображайте доступність велосипедів за допомогою API ROOTE: позначки часу, свіжість, невідомі значення, оновлення та прострочені дані у вашому додатку.

Source: https://www.roote.ai/uk/guides/disponibilnist-velosipediv-v-realnomu-chasi-yak-vidobraziti-v-dodatku/
Language: uk
Author: ROOTE

Щоб відобразити доступність велосипедів у реальному часі в додатку, поєднуйте кількість, що повертається, з її свіжістю та можливостями взяття транспортного засобу. Спостереження описує те, що джерело знало в певний момент; воно не гарантує, що велосипед все ще буде доступним при вашому прибутті.

Контракт мобільності ROOTE відрізняє станції, окремі транспортні засоби та їх стани. Інтерфейс повинен відображати ці відмінності, не плутаючи невідоме значення, пусту станцію та тимчасово недоступне джерело.

## Розмежуйте станцію та окремий транспортний засіб

Станція може показувати лічильники велосипедів і місць для повернення. Окремий транспортний засіб має стан доступності та іншу можливу інформацію. Уникайте підрахунку станції як велосипеда або додавання лічильників, які представляють той самий запас.

У DTO мобільності ROOTE поля availability.bikes і availability.docks можуть бути невідомими. Поля щодо приводу або акумулятора слід відображати лише за наявності та згідно з контрактом.

[Контракт OpenAPI ROOTE](https://api.roote.ai/openapi.json)

## Читання свіжості та позначок часу

| Поле | Інтерпретація |
| --- | --- |
| freshness.state | Заявлений стан: fresh, stale, unknown або static |
| freshness.source_updated_at | Дата оновлення джерела, якщо відома |
| freshness.received_at | Дата отримання згідно з контрактом |
| freshness.expires_at | Вказаний термін дії, якщо відомий |
| availability.bikes | Відома кількість або невідоме значення |
| pickup.enabled і pickup.state | Інформація про взяття велосипеда зі станції |

Час вашого виклику не є автоматично часом спостереження. Результат, отриманий о 10:00, може містити джерело, оновлене о 9:45. Не відображайте «оновлено зараз» лише на основі часу прийому в інтерфейсі.

## Передбачте окремі стани відображення

| Отримані дані | Що відобразити |
| --- | --- |
| Відома кількість і свіжі дані | Спостережена кількість і часова позначка |
| Кількість дорівнює нулю | Велосипеди не спостерігалися, з часовим контекстом |
| Кількість null | Доступність невідома |
| Стан stale або перевищено термін дії | Старі дані; запропонуйте оновлення |
| pickup.enabled=false | Взяття недоступне, навіть якщо лічильник додатній |
| Помилка пошуку | Доступність тимчасово недоступна, не перетворюйте на нуль |

Не класифікуйте стан unknown або static як свіжий. Інформація про станцію може бути стабільною, хоча лічильник змінюється швидко. Також зберігайте попередження та атрибуції, які вимагає відповідь.

## Приклад нормалізації перед відображенням

Наступна функція формує стан представлення для станції, уже перевіреної за схемою ROOTE. Вона не є повним валідатором відповіді. Видимі позначення мають надходити з ключів перекладу вашого інтерфейсу.

```
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
  };
}
```

Навіть із станом observed не перетворюйте pickupState=unknown на підтверджене взяття. Лічильник залишається спостереженням. Показуйте контекст взяття, якщо ваш продукт допомагає користувачу обрати станцію.

## Оновлюйте без зайвого множення викликів

Підлаштовуйте оновлення до опублікованого терміну дії, умов сервісу та поведінки користувача. Об’єднуйте однакові запити, уникайте викликів у фоні на неактивній сторінці та скасовуйте запити, що замінено новими пошуками.

Локальний час кешу не доводить свіжість джерела. Після помилки можна зберегти останнє dated спостереження, якщо ваш інтерфейс явно показує його як старе. Не скасовуйте це розмежування при першому вдалому оновленні, якщо джерело лишається stale.

## Розуміння зв’язку з GBFS

GBFS описує послуги спільної мобільності та їх опубліковані стани. Пряме інтегрування має інтерпретувати файли, версію і позначки часу потоку. З уніфікованим API використовуйте контракт API; не додавайте поле GBFS, якого, ймовірно, немає у відповіді.

[Вибір між GTFS, GTFS Realtime і GBFS](https://www.roote.ai/uk/guides/gtfs-gtfs-rt-ta-gbfs-yaki-vidminy/)

## Тестування ситуацій, що вводять читача в оману

Перевірте реальний нуль, невідоме значення, перевищений термін, вимкнене взяття і помилку після валідного результату. Також перевірте часові пояси відображення. Позитивний лічильник ніколи не повинен показувати «зарезервований велосипед», а недоступність — вигаданий нуль.

[Обробка порожніх відповідей і помилок](https://www.roote.ai/uk/guides/vidchynyj-rezultat-chy-pomylka-api-yak-rozyznyty/)

[Застосування правил у асистенті ШІ](https://www.roote.ai/uk/guides/yak-stvoriti-asistenta-yakij-znajde-mobilnist-navkolo-adresi/)

[Керівництво користувача для пошуку велосипеда](https://www.roote.ai/uk/guides/yak-znayty-velosyped-vilnoservisno-poblyzy-sebe/)

## Поширені запитання

### Чи гарантує позитивна кількість наявність велосипеда при моєму прибутті?

Ні. Вона описує спостереження, що може змінитись між пошуком і вашим прибуттям.

### Чи можна замінити null на нуль?

Ні. null означає невідоме значення; нуль — відома кількість і має інше значення.

### Чи потрібно оновлювати кожні кілька секунд?

Використовуйте індикатори дійсності, обмеження сервісу та потреби інтерфейсу. Випадкова частота не гарантує свіжішого джерела.
