From 755a6e5aa91c3df01ac975511a348e585ee50707 Mon Sep 17 00:00:00 2001 From: al Date: Tue, 4 Feb 2020 13:40:41 -0800 Subject: [PATCH 1/3] Introduce station_id and add fields to trips and status changes Addresses MDS Issues #428 and #438 --- provider/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/provider/README.md b/provider/README.md index ccd89dc5..e2f8b2e1 100644 --- a/provider/README.md +++ b/provider/README.md @@ -225,6 +225,13 @@ If the currency field is null, USD cents is implied. [Top][toc] + +### Station ID + +A station is where a vehicle may be picked up and/or returned. Each station must have a UUID that is unique within the Provider's system. This is not to be confused with the station ID that may be found from a [GBFS](https://github.com/NABSA/gbfs/) endpoint. + +[Top][toc] + ## Trips A trip represents a journey taken by a *mobility as a service* customer with a geo-tagged start and stop point. @@ -259,6 +266,8 @@ Schema: [`trips` schema][trips-schema] | `standard_cost` | Integer | Optional | The cost, in the currency defined in `currency`, that it would cost to perform that trip in the standard operation of the System (see [Costs & Currencies](#costs--currencies)) | | `actual_cost` | Integer | Optional | The actual cost, in the currency defined in `currency`, paid by the customer of the *mobility as a service* provider (see [Costs & Currencies](#costs--currencies)) | | `currency` | String | Optional, USD cents is implied if null.| An [ISO 4217 Alphabetic Currency Code](https://en.wikipedia.org/wiki/ISO_4217#Active_codes) representing the currency of the payee (see [Costs & Currencies](#costs--currencies)) | +| `station_start` | UUID | Required if Applicable | If a trip originates from a station, the [station id](#station-id) of the station | +| `station_end` | UUID | Required if Applicable | If a trip ends at a station, the [station id](#station-id) of the station | ### Trips Query Parameters @@ -342,6 +351,7 @@ Schema: [`status_changes` schema][sc-schema] | `event_time` | [timestamp][ts] | Required | Date/time that event occurred at. See [Event Times](#event-times) | | `publication_time` | [timestamp][ts] | Optional | Date/time that event became available through the status changes endpoint | | `event_location` | GeoJSON [Point Feature][geo] | Required | | +| `event_station_id` | UUID | Required if Applicable | If the event occurs at a station, the [station id](#station-id) of the station | | `battery_pct` | Float | Required if Applicable | Percent battery charge of device, expressed between 0 and 1 | | `associated_trip` | UUID | Required if Applicable | Trip UUID (foreign key to Trips API), required if `event_type_reason` is `user_pick_up` or `user_drop_off`, or for any other status change event that marks the end of a trip. | | `associated_ticket` | String | Optional | Identifier for an associated ticket inside an Agency-maintained 311 or CRM system. | From 173388fa0673f0430e3d401e93f93fb45afa327b Mon Sep 17 00:00:00 2001 From: al Date: Tue, 4 Feb 2020 14:47:57 -0800 Subject: [PATCH 2/3] Add /stations endpoint and associated definitions * add vehicle definition * add dock definition * add /stations endpoint (MDS Issue #374) * add status statuses definition --- provider/README.md | 87 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/provider/README.md b/provider/README.md index e2f8b2e1..613cf5e5 100644 --- a/provider/README.md +++ b/provider/README.md @@ -7,6 +7,7 @@ This specification contains a data standard for *mobility as a service* provider * [General Information](#general-information) * [Trips](#trips) * [Status Changes](#status-changes) +* [Stations](#stations) * [Realtime Data](#realtime-data) - [GBFS](#GBFS) - [Events](#events) @@ -232,6 +233,37 @@ A station is where a vehicle may be picked up and/or returned. Each station must [Top][toc] +### Vehicle + +This model should be compatible with the proposed [`/vehicles` endpoint](https://github.com/openmobilityfoundation/mobility-data-specification/pull/376). Its main purpose for now is to represent a vehicle that is at a [station](#stations). + +| Field | Type | Required/Optional | Comments | +| ----- | ---- | ----------------- | -------- | +| provider_id | UUID | Required | A UUID for the Provider, unique within MDS | +| device_id | UUID | | A unique device ID in UUID format, should match this device in Provider | +| vehicle_id | String | | The Vehicle Identification Number visible on the vehicle itself, should match this device in Provider | +| vehicle_type | Enum | Required | See [vehicle types](#vehicle-types) table | +| propulsion_type | Enum[] | Required | Array of [propulsion types](#propulsion-types); allows multiple values | + +[Top][toc] + +### Dock + +A dock can represents a space to park a singular vehicle, e.g. a dock for a bicycle or a parking space for a car. It is the complement to a [vehicle](#vehicle). + +| Field | Type | Required/Optional | Comments | +| ----- | ---- | ----------------- | -------- | +| vehicle_types | Enum[] | Required | Array of [vehicle types](#vehicle-types) that may occupy the dock | +| propulsion_types | Enum[] | Required | Array of [propulsion types](#propulsion-types) that may be at the dock | +| working | Boolean | Required | If true, denotes that the space may either accept or rent out vehicles. If false, the space can do neither | +| vehicle_present | Boolean | Required | | + +To clarify, if a dock has a state of `working: false` and `vehicle_present: true` one could infer that either the vehicle has been taken out of service at the dock, or that the dock is jammed. + +An empty dock a user is able to return a vehicle to would have the state `working: true` and `vehicle_present: false`. + +[Top][toc] + ## Trips A trip represents a journey taken by a *mobility as a service* customer with a geo-tagged start and stop point. @@ -391,6 +423,61 @@ Without an `event_time` query parameter, `/status_changes` shall return a `400 B [Top][toc] +## Stations + +A Station represents a station in a point in time, a “station state” to be verbose. Most commonly, this is a docked-bikeshare station, but we aim to let this support scooter corrals, or even parking spots for cars. + +This API allows a user to query the historical (and potentially realtime) state of a provider's system of stations. Providers should provide data on their entire system on a daily cadence at the very least. Then, coupled with the `/station_status_changes` endpoint below, one could "fast-forward" to any other point in the day to derive the state of the system then. + +Endpoint: `/stations` +Method: `GET` +Schema: To Be Generated +`data` Payload: `{ "stations": [] }`, an array of objects with the following structure + +| Field | Type | Required/Optional | Comments | +| ----- | ---- | ----------------- | ----- | +| `provider_id` | UUID | Required | A UUID for the Provider, unique within MDS | +| `provider_name` | String | Required | The public-facing name of the Provider | +| `station_id` | UUID | Required | A station ID unique to the provider's system | +| `gbfs_station_id` | String | Optional | If provided, should match the station_id in the GBFS endpoints | +| `name` | String | Required | Public name of the station | +| `location` | GeoJSON [Point Feature][geo] | Required | | +| `status` | Enum | Required | See [station statuses](#station-statuses) table | +| `reported_at` | [timestamp][ts] | Required | Timestamp when the state of the station was captured | +| `vehicle_types` | Enum[] | Required | Array of [vehicle types](#vehicle-types) the station supports; allows multiple values | +| `propulsion_types` | Enum[] | Required | Array of [propulsion types](#propulsion-types) the station supports; allows multiple values | +| `vehicles` | Vehicles[] | Required | Array of [vehicles](#vehicle) at the station. Will be empty if no vehicles are at the station | +| `docks` | Docks[] | Optional | Array of [docks](#dock) at the station. If this field is null, it is assumed that the number of docks is irrelevant (i.e. a warehouse where users can return or take as many vehicles as needed) | + +Folks familiar with [GBFS](https://github.com/NABSA/gbfs) will recognise some similarities, but keep in mind this is a “station state”, so it includes information on the vehicles and docks at a specific point in time as denoted by the `reported_at` field. + +### Stations Query Parameters + +The `/stations` API should allow querying stations with a combination of query parameters: + +| Parameter | Format | Expected Output | +| --------- | ------ | --------------- | +| `timestamp` | [timestamp][ts] | The most recent state of each station as of the specified time | +| `station_ids` | Comma-separated string | All stations whose `station_id` is in the list of station IDs | + +If `timestamp` is omitted, or in the future, the endpoint will return the most recent state of the stations. If `timestamp` is in the past, the state of the stations should be the most recent state up until the specified time. For example: if stations have `reported_at: 10` and `reported_at: 20`, and `timestamp=17` was supplied, the endpoint would return the state from `reported_at: 10`. + +Unless the `station_ids` filter is explicitly requested, the response is expected to return one `station` object per station in the system, thus returning the entire system. + +### Station Statuses + +| `status` | Description | +| -------- | ----------- | +| `open` | The station is open and available to rent out or accept vehicles | +| `closed` | The station is closed. Either because of operating hours, repairs, or a seasonal closure | +| `decommissioned` | The station is permanently closed and will be removed from the system | + +Some GBFS [station_status](https://github.com/NABSA/gbfs/blob/master/gbfs.md#station_statusjson) states such as `is_installed`, `is_renting`, or `is_returning` are purposefully omitted since they are more relevant for bikeshare riders than planners analysing historical data, but we're open to discussion of their inclusion if it helps users of MDS. + +If docked-bikeshare stations are closed be cause of a [Canadian winter](https://github.com/NABSA/gbfs/pull/202#issuecomment-565586255), we expect the status to just be `closed`. + +[Top][toc] + ## Realtime Data ### GBFS From 0b5caf3742c7b25f53819d12ce94d6abfba03dc2 Mon Sep 17 00:00:00 2001 From: al Date: Tue, 4 Feb 2020 14:50:01 -0800 Subject: [PATCH 3/3] Add /station_status_changes endpoint Continuing the proposal to address MDS #374. This results in two new endpoints, /stations and /station_status_changes, which will allow a user to recreate the state of the docked-bikeshare system at any point in time. --- provider/README.md | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/provider/README.md b/provider/README.md index 613cf5e5..8bddbde1 100644 --- a/provider/README.md +++ b/provider/README.md @@ -8,6 +8,7 @@ This specification contains a data standard for *mobility as a service* provider * [Trips](#trips) * [Status Changes](#status-changes) * [Stations](#stations) +* [Station Status Changes](#station-status-changes) * [Realtime Data](#realtime-data) - [GBFS](#GBFS) - [Events](#events) @@ -478,6 +479,71 @@ If docked-bikeshare stations are closed be cause of a [Canadian winter](https:// [Top][toc] +## Station Status Changes + +The above `/stations` endpoint provides "snapshots" of every station in the system at least once a day, at the very least. If a user wanted the state of a station at a point in time other than what the `/stations` endpoint provides, they would use this one, which gives them a stream of station status changes. + +A `station_status_change` represents the state of the station _after_ an event listed in the `change_type_reason` field. Otherwise, is the same as a `stations` object. + +Endpoint: `/stations_status_changes` +Method: `GET` +Schema: To Be Generated +`data` Payload: `{ "station_status_changes": [] }`, an array of objects with the following structure + +| Field | Type | Required/Optional | Comments | +| ----- | ---- | ----------------- | ----- | +| `provider_id` | UUID | Required | A UUID for the Provider, unique within MDS | +| `provider_name` | String | Required | The public-facing name of the Provider | +| `station_id` | UUID | Required | A station ID unique to the provider's system | +| `gbfs_station_id` | String | Optional | If provided, should match the station_id in the GBFS endpoints | +| `name` | String | Required | Public name of the station | +| `location` | GeoJSON [Point Feature][geo] | Required | | +| `status` | Enum | Required | See [station statuses](#station-statuses) table | +| `change_type_reason` | Enum | Required | See [station change type reasons](#station-change-type-reasons) table | +| `reported_at` | [timestamp][ts] | Required | Timestamp when the state of the station was captured | +| `vehicle_types` | Enum[] | Required | Array of [vehicle types](#vehicle-types) the station supports; allows multiple values | +| `propulsion_types` | Enum[] | Required | Array of [propulsion types](#propulsion-types) the station supports; allows multiple values | +| `vehicles` | Vehicles[] | Required | Array of [vehicles](#vehicle) at the station. Will be empty if no vehicles are at the station | +| `docks` | Docks[] | Optional | Array of [docks](#dock) at the station. If this field is null, it is assumed that the number of docks is irrelevant (i.e. a warehouse where users can return or take as many vehicles as needed) | + +People may attempt to draw some parallels with the GBFS [station_information](https://github.com/NABSA/gbfs/blob/master/gbfs.md#station_informationjson) and [station_status](https://github.com/NABSA/gbfs/blob/master/gbfs.md#station_statusjson) endpoints, but here the two new MDS endpoints return objects that are not so different from one another. The difference is that one endpoint is guaranteed to provide the state for once a day; whereas the other returns state changes that have happened. + +### Station Status Changes Query Parameters + +The `/station_status_changes` API should allow querying stations status changes with a combination of query parameters: + +| Parameter | Format | Expected Output | +| --------- | ------ | --------------- | +| `start_time` | [timestamp][ts] | station status changes where `start_time <= station_status_status_change.reported_at` | +| `end_time` | [timestamp][ts] | station status changes where `station_status_status_change.reported_at < end_time` | +| `station_ids` | Comma-separate list | All station states whose `station_id` is in the list of station IDs | + +Both `start_time` and `end_time` are required. If either is omitted, the `/station_status_changes` endpoint should return a `400: Bad Request` response. + +Unlike the `/stations` endpoint, it is possible for the `/station_status_changes` endpoint to return empty responses if no changes occurred during the specified time range. + +### Station Change Type Reasons + +| `change_type_reason` | Description | +| -------------------- | ----------- | +| `service_start` | The station is open | +| `service_end` | The station is closed | +| `maintenance` | The station is undergoing repairs, potentially changing some fields | +| `vehicle_drop_off` | A vehicle was returned by a user, so the `vehicles` and `docks` fields are updated | +| `vehicle_pick_up` | A vehicle was picked up by a user, so the `vehicles` and `docks` fields are updated | +| `vehicle_provider_drop_off` | A vehicle or more was/were dropped off up by the provider, so the `vehicles` and `docks` fields are updated | +| `vehicle_provider_pick_up` | A vehicle or more was/were picked up by the provider, so the `vehicles` and `docks` fields are updated | +| `vehicle_fueling` | A vehicle is now unavailable because it needs to be refueled | +| `vehicle_maintenance` | A vehicle is now unavailable because it needs to be repaired | +| `vehicle_unavailable` | A vehicle is now unavailable for other reasons | +| `vehicle_type_added` | The station offers a new vehicle type, changing the `vehicle_types` field and count fields | +| `vehicle_type_removed` | A vehicle type has been removed from the station, changing the `vehicle_types` field and count fields | +| `decommissioning` | The station is slated to be removed | + +We encourage providers to comment on any common change type reasons that are missing. + +[Top][toc] + ## Realtime Data ### GBFS