Чтобы отобразить доступность велосипедов в реальном времени в приложении, связывайте возвращаемое количество с показателем актуальности и условиями взятия транспортного средства. Наблюдение описывает, что источник знал в момент времени; оно не гарантирует, что велосипед будет доступен к прибытию.
Контракт мобильности ROOTE различает станции, отдельные транспортные средства и их состояния. Интерфейс должен выражать эти различия, не перепутывая неизвестное значение, пустую станцию и временно недоступный источник.
Разделение станции и отдельного транспортного средства
Станция может показывать счётчики велосипедов и свободных мест для возврата. Отдельное транспортное средство имеет состояние доступности и дополнительную информацию. Избегайте счёта станции как велосипеда или суммирования счётчиков, относящихся к одному запасу.
В DTO мобильности ROOTE поля availability.bikes и availability.docks могут быть неизвестны. Поля, связанные с приводом или аккумулятором, должны отображаться только при их наличии и интерпретироваться согласно контракту.
Чтение актуальности и отметок времени
| Поле | Интерпретация |
|---|---|
| freshness.state | Объявленное состояние: fresh, stale, unknown или static |
| freshness.source_updated_at | Дата обновления источника, если известна |
| freshness.received_at | Дата получения по контракту |
| freshness.expires_at | Указанный срок годности, если известен |
| availability.bikes | Известное количество или неизвестное значение |
| pickup.enabled и pickup.state | Информация о возможности взять велосипед на станции |
Время вашего запроса не обязательно совпадает со временем наблюдения. Результат, полученный в 10 часов, может содержать источник, обновлённый в 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 в подтверждённое взятие. Счётчик остаётся наблюдением. Отображайте контекст взятия, если ваш продукт помогает пользователю выбрать станцию.
Обновление без излишних вызовов
Настраивайте обновление под опубликованный срок, условия сервиса и поведение пользователя. Группируйте одинаковые запросы, избегайте фоновых вызовов на неактивной странице и отменяйте устаревшие запросы.
Локальный кеш не гарантирует свежесть источника. После ошибки можно сохранять последний датированный результат, если интерфейс явно показывает его как устаревший. Не снимайте это разграничение при первом успешном повторе, если источник остаётся stale.
Понимание связи с GBFS
GBFS описывает сервисы совместного использования и их публикуемые состояния. Прямая интеграция должна интерпретировать файлы, версии и отметки времени потока. Используя стандартизированный API, применяйте контракт API; не добавляйте поле GBFS, отсутствующее в ответе.
Выбор между GTFS, GTFS Realtime и GBFS
Тестирование ситуаций, вводящих пользователя в заблуждение
Проверьте реальные нули, неизвестные значения, превышение срока годности, отключённое взятие и ошибку после валидного результата. Также проверьте часовые пояса отображения. Положительный счётчик не должен показывать «велосипед зарезервирован», а недоступность не должна заменяться вымышленным нулём.
Обработка пустых ответов и ошибок
Применение этих правил в ИИ-помощнике
Руководство пользователя по поиску велосипеда
Часто задаваемые вопросы
Обеспечивает ли положительное количество велосипед при моём прибытии?
Нет. Это наблюдаемое значение, которое может измениться между поиском и вашим прибытием.
Можно ли заменить null на ноль?
Нельзя. null означает неизвестное значение; ноль — известное количество с другим смыслом.
Нужно ли обновлять каждую секунду?
Используйте указания по актуальности, ограничения сервиса и требования интерфейса. Произвольная частота не гарантирует более свежие данные.