diff --git a/README.md b/README.md index a99aed84..08723ed6 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ - [Modes](#modes) - [Versions](#versions) - [Technical Information](#technical-information) + - [Data Validation](#data-validation) - [Get Involved](#get-involved) - [Membership](#membership) - [Cities Using MDS](#cities-using-mds) @@ -125,6 +126,12 @@ The MDS specification is versioned using Git tags and [semantic versioning](http * [MDS Releases](https://github.com/openmobilityfoundation/governance/wiki/Releases) - current/recommended versions, timeline * [Release Guidelines](https://github.com/openmobilityfoundation/governance/blob/main/technical/ReleaseGuidelines.md) +## Data Validation + +To help with MDS data and feed validation, please see our OpenAPI schema description in the OMF [mds-openapi](https://github.com/openmobilityfoundation/mds-openapi) repository. Browsable interactive documentation is also linked to in that repository. + +Starting with MDS 2.0, OpenAPI documents describe MDS endpoints and allow for [schema](/schema) validation, expanding on the JSON Schemas formerly housed in this repository. + [Top][toc] # Get Involved @@ -170,6 +177,7 @@ To add yourself to the [agency list](/agencies.csv) and add your [Policy Require Over four dozen mobility service providers (MSPs) around the world use MDS, allowing them to create tools around a single data standard for multiple cities. - See our **[list of providers using MDS](https://www.openmobilityfoundation.org/mds-users/#mobility-providers-using-mds)**. For a table list with unique IDs, see the MDS [provider list](/providers.csv) which includes both service operators and data solution providers. +- A provider needs a unique ID for each [mode](#modes) they operate under. To add yourself to the provider list, please let us know [via our website](https://www.openmobilityfoundation.org/get-in-touch/) or open an [Issue](https://github.com/openmobilityfoundation/mobility-data-specification/issues) or [Pull Request](https://github.com/openmobilityfoundation/mobility-data-specification/pulls). Find out how in our [Adding an Provider ID](https://github.com/openmobilityfoundation/mobility-data-specification/wiki/Adding-an-MDS-Provider-ID) help document. @@ -179,7 +187,8 @@ To add yourself to the provider list, please let us know [via our website](https An open source approach to data specifications benefits cities and companies by creating a space for collaborative development, reducing costs, and nurturing a healthy, competitive ecosystem for mobility services and software tools. The open model promotes a competitive ecosystem for software tools built by dozens of software companies providing their services to cities, agencies, and providers. -- See our **[list of third party software companies using MDS](https://www.openmobilityfoundation.org/mds-users/#software-companies-using-mds)** and an article about the [benefits of an open approach](https://www.openmobilityfoundation.org/why-open-behind-omfs-unique-open-source-model/). For a table list with unique IDs, see the MDS [provider list](/providers.csv) which includes both service operators and data solution providers. +- See our **[list of third party software companies using MDS](https://www.openmobilityfoundation.org/mds-users/#software-companies-using-mds)** and an article about the [benefits of an open approach](https://www.openmobilityfoundation.org/why-open-behind-omfs-unique-open-source-model/). +- For a table list with unique IDs, see the MDS [provider list](/providers.csv) which includes both service operators and data solution providers. To add yourself to the provider list (as a data solution providers), please let us know [via our website](https://www.openmobilityfoundation.org/get-in-touch/) or open an [Issue](https://github.com/openmobilityfoundation/mobility-data-specification/issues) or [Pull Request](https://github.com/openmobilityfoundation/mobility-data-specification/pulls). Find out how in our [Adding an Provider ID](https://github.com/openmobilityfoundation/mobility-data-specification/wiki/Adding-an-MDS-Provider-ID) help document. diff --git a/ReleaseNotes.md b/ReleaseNotes.md index d93c3d45..629c4a30 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,3 +1,112 @@ +## 2.0.0 + +> Released 2023-05-09 + +> [Release Plan](https://github.com/openmobilityfoundation/governance/wiki/Release-2.0.0) + +The 2.0.0 major release includes support for new mobility modes, clarity around Policy, and the alignment of the data and structure of Agency and Provider. + +### CHANGES + +See the closed PRs tagged with [Milestone 2.0.0](https://github.com/openmobilityfoundation/mobility-data-specification/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.0.0) and [Issues](https://github.com/openmobilityfoundation/mobility-data-specification/issues?q=is%3Aissue+milestone%3A2.0.0+is%3Aclosed) for a full list of changes. + +#### **_Admin/General Changes_** + +- Update [state machine diagrams](https://docs.google.com/presentation/d/1fHdq1efbN5GSFDLF4en-oA_BYPXQKbbIbHff6iROJKA/edit?usp=sharing) and create 4 new diagrams for each mode +- [Remove Schema and instead link to OpenAPI repo](https://github.com/openmobilityfoundation/mobility-data-specification/issues/281) + - OpenAPI support in place of JSON Schema allows easier building of real-time MDS endpoint validation, and interactive documentation on Stoplight. +- [Remove Geography from Policy](https://github.com/openmobilityfoundation/mobility-data-specification/issues/816) +- [Authorization consistency across MDS](https://github.com/openmobilityfoundation/mobility-data-specification/issues/584) +- [Make GBFS optional for some modes](https://github.com/openmobilityfoundation/mobility-data-specification/issues/769) +- [Align vehicle types to GBFS](https://github.com/openmobilityfoundation/mobility-data-specification/issues/692) + - Updated MDS alignment with GBFS to include all of their vehicle types (including seated scooter) and the addition of new ones for modes (bus, truck, delivery robot, motorcycle), all propulsion types, and to require GBFS for only micromobility and car share (delivery robots and passenger services are option, but not well supported in GBFS). +- [Added maintenance_pick_up event for out of PROW work](https://github.com/openmobilityfoundation/mobility-data-specification/issues/595) +- Ability to send tip overs, surface type, and parking validation [data if available from sensors](https://github.com/openmobilityfoundation/mobility-data-specification/pull/829) + - New optional fields to include sensors now available and in use in the field by many micromobility companies for tip overs, surface type, and parking validation. +- [Vertical accuracy for GPS telemetry](https://github.com/openmobilityfoundation/mobility-data-specification/issues/661) +- All vehicle states are now clearly in or out of the right of way, [no unknown state](https://github.com/openmobilityfoundation/mobility-data-specification/issues/770) +- Many [new provider IDs added](https://github.com/openmobilityfoundation/mobility-data-specification/pulls?q=is%3Apr+is%3Aclosed+label%3A%22identifier+change%22+milestone%3A2.0.0) + +#### **_Modes Architecture_** + +- [Support for multiple modes/services in MDS](https://github.com/openmobilityfoundation/mobility-data-specification/issues/574) + - Updates the base of MDS to have some shared objects and fields, and specific fields as needed for each mode. + - Adds specific modes to MDS, with help from Member Networks, and existing real world data exchanges between operators, agencies, and solution providers. + - Operators must register a unique UUID for each mode they operate under. + +**Passenger Services** +- [Passenger services/TNC/taxi support ](https://github.com/openmobilityfoundation/mobility-data-specification/issues/95) + +**Delivery Robots** +- [Support for vehicles like delivery robots](https://github.com/openmobilityfoundation/mobility-data-specification/issues/782) + +**Car Share** +- [Carshare Support](https://github.com/openmobilityfoundation/mobility-data-specification/issues/640) + +**Work to bring modes together** + +- [Add a "Data Provider UUID" to MDS](https://github.com/openmobilityfoundation/mobility-data-specification/issues/805) + - New data provider id allows endpoints to include who is producing and serving up the data. Software companies and solution providers are [encouraged to register](https://github.com/openmobilityfoundation/mobility-data-specification/tree/feature-modes-cleanup#software-companies-using-mds) for their own global UUID now to serve up operator or agency data with MDS. +- [Support for Modes in Policy](https://github.com/openmobilityfoundation/mobility-data-specification/issues/614) - specify which mode your policy applies to + +#### **_Policy Reimagining_** + +A reimagining of Policy, including top ten most common policies are clearly defined, edge cases (dwell time, trip definition, rule units, updating/ending policies, lookback periods) are clarified, Stops is out of beta, and Policy feeds are public + +- [Multimodal support in Policy](https://github.com/openmobilityfoundation/mobility-data-specification/issues/614) +- [Clarification on possible values of rule_units](https://github.com/openmobilityfoundation/mobility-data-specification/issues/704) +- [Move Stops out of beta](https://github.com/openmobilityfoundation/mobility-data-specification/issues/674) +- [Policy is now public](https://github.com/openmobilityfoundation/mobility-data-specification/pull/824/) +- [Updating and ending policy clarification](https://github.com/openmobilityfoundation/mobility-data-specification/pull/834) +- [Lookback period clarification ](https://github.com/openmobilityfoundation/mobility-data-specification/issues/749) + +**Policy Requirements** + +Requirements now supports linking to external use cases, and is moved out of beta because of adoption. + +- [Support to reference external use cases](https://github.com/openmobilityfoundation/mobility-data-specification/issues/681) +- [Move out of beta](https://github.com/openmobilityfoundation/mobility-data-specification/issues/682) + +#### **_Agency/Provider Unification_** + +The difference between Agency and Provider is that with Agency operators PUSH data to cities, and with Provider cities PULL data from operators. Both share the same data types, referenced in a new file, with the same endpoints and fields available. + +- [MDS Agency and Provider Unification](https://github.com/openmobilityfoundation/mobility-data-specification/issues/759) + - Endpoints are now identical + - Data objects are now identical, referenced in new data-type.md file + - Distinction between Agency and Provider is now simply pushing data to agencies, or pulling data from operators +- [Adding trips endpoint to Agency](https://github.com/openmobilityfoundation/mobility-data-specification/issues/550) +- [Adding trip data to Agency](https://github.com/openmobilityfoundation/mobility-data-specification/issues/722) +(https://github.com/openmobilityfoundation/mobility-data-specification/issues/770) + - Trip telemetry points are no longer in the trips endpoint directly, instead referenced in their own telemetry endpoint. Start and end location only is available in trips. + +#### **_Provider_** + +Reports have a new adaptive scooter special group type, and improved formatting. + +- [Updates to provider reports](https://github.com/openmobilityfoundation/mobility-data-specification/pulls?q=is%3Apr+is%3Aclosed+label%3AReports) including header, date format, column names, and adaptive scooter special group type + +#### **_Geography_** + +- [Geography is now public, and removed from Policy](https://github.com/openmobilityfoundation/mobility-data-specification/pull/824/files) + +#### **_Jurisdiction_** + +- [Jurisdiction is now public](https://github.com/openmobilityfoundation/mobility-data-specification/pull/824/files) + +#### **_Technical Updates_** + +As part of the OpenAPI schema work, a number of technical updates were made to ensure the spec was internally consistent. A full list can be found for all issues and PRs in [this date range](https://github.com/openmobilityfoundation/mobility-data-specification/issues?q=milestone%3A2.0.0+created%3A%3E2023-04-15+updated%3A%3C2023-05-09). + +- [OpenAPI Schema](https://github.com/openmobilityfoundation/mobility-data-specification/issues/281) definitions, created in [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repo +- [HTTP error and bulk responses](https://github.com/openmobilityfoundation/mobility-data-specification/issues/856) +- [Accessibility 'options' renamed to 'attributes'](https://github.com/openmobilityfoundation/mobility-data-specification/issues/847) for consistency +- [Add missing event types from main list](https://github.com/openmobilityfoundation/mobility-data-specification/issues/845) +- [Fix car share event types](https://github.com/openmobilityfoundation/mobility-data-specification/issues/843) +- [Updated fare_attributes.payment_type list](https://github.com/openmobilityfoundation/mobility-data-specification/issues/844) +- [Use last_updated consistently](https://github.com/openmobilityfoundation/mobility-data-specification/issues/842) across responses +- [Remove extra 'data' hierarchy](https://github.com/openmobilityfoundation/mobility-data-specification/issues/841) in responses in some endpoints + ## 1.2.0 > Released: 2021-11-04 diff --git a/agency/README.md b/agency/README.md index 1f046f66..33882304 100644 --- a/agency/README.md +++ b/agency/README.md @@ -15,9 +15,10 @@ This specification contains a collection of RESTful APIs used to specify the dig * [Responses and Error Messages](#responses-and-error-messages) * [GBFS](#gbfs) * [Vehicles](#vehicles) - * [Vehicle - Status](#vehicle---status) * [Vehicle - Register](#vehicle---register) * [Vehicle - Update](#vehicle---update) + * [Vehicle - List](#vehicle---list) + * [Vehicle - Status](#vehicle---status) * [Trips](#trips) * [Telemetry](#telemetry) * [Events](#events) @@ -52,13 +53,19 @@ Versioning must be implemented as specified in the [Versioning section][versioni ### Modes -MDS is intended to be used for multiple transportation modes, including its original micromobility (e-scooters, bikes, etc.) mode, as well as additional modes such as taxis, car share, and delivery bots. A given `provider_id` shall be associated with a single mobility [mode], so that the mode does not have to be specified in each data structure and API call. A provider implementing more than one mode shall [register](/README.md#providers-using-mds) a unique `provider_id` for each mode. +MDS is intended to be used for multiple transportation modes, including its original micromobility (e-scooters, bikes, etc.) mode, as well as additional modes such as taxis, car share, and delivery bots. A given `provider_id` shall be associated with a single mobility [mode][modes], so that the mode does not have to be specified in each data structure and API call. A provider implementing more than one mode shall [register](/README.md#providers-using-mds) a unique `provider_id` for each mode. [Top][toc] ### Responses and Error Messages -See the [Responses][responses] and [Error Messages][error-messages] sections. +The response to a client request must include a valid HTTP status code defined in the [IANA HTTP Status Code Registry][iana]. + +The response must set the `Content-Type` header as specified in the [Versioning section][versioning]. + +Response bodies must be a `UTF-8` encoded JSON object + +See the [Responses][responses], [Error Messages][error-messages], and [Bulk Responses][bulk-responses] sections, and the [schema][schema] for more details. [Top][toc] @@ -68,26 +75,94 @@ See the [GBFS Requirement](/README.md#gbfs-requirement) language for more detail [Top][toc] +### Data Schema + +See the [Endpoints](#endpoints) below for information on their specific schema, and the [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for full details and interactive documentation. + +[Top][toc] + ## Vehicles +The `/vehicles` endpoints allow providers to register and update the properties of their fleet vehicles, and query current vehicle properties and status. + +### Vehicle - Register + +The `/vehicles` registration endpoint is used to register vehicles for use in the Agency's jurisdiction. + +**Endpoint**: `/vehicles` +**Method:** `POST` +**Payload:** An array of [Vehicles](/data-types.md#vehicles) + +#### Responses + +_Possible HTTP Status Codes_: +201, +400, +401, +406, +409, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. + +[Top][toc] + +#### Error Codes: + +| `error` | `error_description` | `error_details`[] | +| -------------------- | ------------------------------------------------- | ------------------------------- | +| `bad_param` | A validation error occurred | Array of parameters with errors | +| `missing_param` | A required parameter is missing | Array of missing parameters | +| `already_registered` | A vehicle with `device_id` is already registered | | + +### Vehicle - Update + +The `/vehicles` update endpoint is used to change vehicle information, should some aspect of the vehicle change, such as the `vehicle_id`. Each vehicle must already be registered. + +**Endpoint**: `/vehicles` +**Method:** `PUT` +**Payload:** An array of [Vehicles](/data-types.md#vehicles) + +#### Responses + +_Possible HTTP Status Codes_: +200, +400, +401, +406, +409, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. + +#### Error Codes: + +| `error` | `error_description` | `error_details`[] | +| -------------------- | ------------------------------------------------- | ------------------------------- | +| `bad_param` | A validation error occurred | Array of parameters with errors | +| `unregistered` | This `device_id` is unregistered | | + +[Top][toc] + +### Vehicle - List + The `/vehicles` endpoint returns the specified vehicle (if a device_id is provided) or a list of known vehicles. Providers can only retrieve data for vehicles in their registered fleet. Contains vehicle properties that do not change often. **Endpoint**: `/vehicles/{device_id}` -**Method:** `POST` +**Method:** `GET` **Payload:** An array of [Vehicles](/data-types.md#vehicles) -Path Params: +_Path Parameters:_ -| Param | Type | Required/Optional | Description | +| Path Parameters | Type | Required/Optional | Description | | ------------ | ---- | ----------------- | ------------------------------------------- | | `device_id` | UUID | Optional | If provided, retrieve the specified vehicle | -200 Success Response: - If `device_id` is specified, `GET` will return an array with a single vehicle record, otherwise it will be a list of vehicle records with pagination details per the [JSON API](https://jsonapi.org/format/#fetching-pagination) spec: ```json { + "version": "2.0.0", "vehicles": [ ... ] "links": { "first": "https://...", @@ -98,9 +173,17 @@ If `device_id` is specified, `GET` will return an array with a single vehicle re } ``` -404 Failure Response: +#### Responses -_No content returned on vehicle not found._ +_Possible HTTP Status Codes_: +200, +400 (with parameter), +401, +404, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. [Top][toc] @@ -109,21 +192,20 @@ _No content returned on vehicle not found._ The `/vehicles/status` endpoint returns information about the specified vehicle (if a device_id is provided) or a list of known vehicles current state. Providers can only retrieve data for vehicles in their registered fleet. Contains specific vehicle properties that are updated frequently. **Endpoint**: `/vehicles/status/{device_id}` -**Method:** `POST` +**Method:** `GET` **Payload:** An array of [Vehicles](/data-types.md#vehicle-status) objects -Path Params: +_Path Parameters:_ -| Param | Type | Required/Optional | Description | +| Path Parameters | Type | Required/Optional | Description | | ------------ | ---- | ----------------- | ------------------------------------------- | | `device_id` | UUID | Optional | If provided, retrieve the specified vehicle | -200 Success Response: - If `device_id` is specified, `GET` will return an array with a vehicle status record, otherwise it will be a list of vehicle records with pagination details per the [JSON API](https://jsonapi.org/format/#fetching-pagination) spec: ```json { + "version": "2.0.0", "vehicles_status": [ ... ] "links": { "first": "https://...", @@ -134,56 +216,17 @@ If `device_id` is specified, `GET` will return an array with a vehicle status re } ``` -404 Failure Response: - -_No content returned on vehicle not found._ - -[Top][toc] - -### Vehicle - Register - -The `/vehicles` registration endpoint is used to register vehicles for use in the Agency's jurisdiction. +#### Responses -**Endpoint**: `/vehicles` -**Method:** `POST` -**Payload:** An array of [Vehicles](/data-types.md#vehicles) +_Possible HTTP Status Codes_: +200, +400 (with parameter), +401, +404, +406, +500 -200 Success Response: - -See [Bulk Responses][bulk-responses] - -[Top][toc] - -### Vehicle Register Error Codes: - -| `error` | `error_description` | `error_details`[] | -| -------------------- | ------------------------------------------------- | ------------------------------- | -| `bad_param` | A validation error occurred | Array of parameters with errors | -| `missing_param` | A required parameter is missing | Array of missing parameters | -| `already_registered` | A vehicle with `device_id` is already registered | | - -403 Unauthorized Response: - -**None** - -### Vehicle - Update - -The `/vehicles` update endpoint is used to change vehicle information, should some aspect of the vehicle change, such as the `vehicle_id`. Each vehicle must already be registered. - -**Endpoint**: `/vehicles` -**Method:** `PUT` -**Payload:** An array of [Vehicles](/data-types.md#vehicles) - -200 Success Response: - -See [Bulk Responses][bulk-responses] - -### Vehicle Update Error Codes: - -| `error` | `error_description` | `error_details`[] | -| -------------------- | ------------------------------------------------- | ------------------------------- | -| `bad_param` | A validation error occurred | Array of parameters with errors | -| `unregistered` | This `device_id` is unregistered | | +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. [Top][toc] @@ -198,9 +241,17 @@ The Trips endpoint serves two purposes: **Method:** `POST` **Payload:** Array of [Trips](/data-types.md#trips) -200 Success Response: +### Responses + +_Possible HTTP Status Codes_: +201, +400, +401, +404, +406, +500 -See [Bulk Responses][bulk-responses] +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. ### Trip Errors: @@ -220,9 +271,17 @@ The vehicle `/telemetry` endpoint allows a Provider to send vehicle telemetry da **Method**: `POST` **Payload**: An array of vehicle [Telemetry][vehicle-telemetry] -200 Success Response: +### Responses -See [Bulk Responses][bulk-responses] +_Possible HTTP Status Codes_: +201, +400, +401, +404, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. ### Telemetry Errors: @@ -242,9 +301,17 @@ The vehicle `/events` endpoint allows the Provider to submit events describing t **Method:** `POST` **Payload:** An array of vehicle [Events](/data-types.md#events) -200 Success Response: +### Responses + +_Possible HTTP Status Codes_: +201, +400, +401, +404, +406, +500 -See [Bulk Responses][bulk-responses] +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. ### Event Errors: @@ -266,9 +333,17 @@ The `/stops` endpoint allows an agency to register city-managed Stops, or a prov **Method:** `POST` **Payload**: An array of [Stops][stops] -200 Success Response: +### Responses -See [Bulk Responses][bulk-responses] +_Possible HTTP Status Codes_: +201, +400, +401, +406, +409, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. #### Stops Register Errors: @@ -290,15 +365,29 @@ See [Bulk Responses][bulk-responses] **Method:** `PUT` **Payload**: An array of of [Stop][stops] information, where the permitted changeable fields are defined as: -| Field | Required/Optional | Description | -|---------------------|-------------------|---------------------------------------------| -| stop_id | Required |See [Stops][stops] | -| status | Optional |See [Stops][stops] | -| num_spots_disabled | Optional |See [Stops][stops] | - -200 Success Response: - -See [Bulk Responses][bulk-responses] +| Field | Required/Optional | Description | +|------------------------|-------------------|-------------------| +| stop_id | Required |See [Stops][stops] | +| last_updated | Optional |See [Stops][stops] | +| status | Optional |See [Stops][stops] | +| rental_methods | Optional |See [Stops][stops] | +| num_vehicles_available | Optional |See [Stops][stops] | +| num_vehicles_disabled | Optional |See [Stops][stops] | +| num_places_available | Optional |See [Stops][stops] | +| num_places_disabled | Optional |See [Stops][stops] | +| devices | Optional |See [Stops][stops] | + +### Responses + +_Possible HTTP Status Codes_: +200, +400, +401, +404, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. #### Stops update Errors: @@ -306,26 +395,35 @@ See [Bulk Responses][bulk-responses] | -------------------- | ------------------------------------------------- | ------------------------------- | | `bad_param` | A validation error occurred | Array of parameters with errors | | `missing_param` | A required parameter is missing | Array of missing parameters | -| `unregistered` | No stop with `stop_id` is already registered | | +| `unregistered` | No stop with `stop_id` is already registered | | [Top][toc] ### Stops - Readback -**Endpoint:** `/stops/:stop_id` +**Endpoint:** `/stops/{stop_id}` **Method:** `GET` **Payload:** An array of [Stops][stops] -Path Params: +_Path Parameters:_ -| Param | Type | Required/Optional | Description | +| Path Parameters | Type | Required/Optional | Description | | ------------ | ---- | ----------------- | ------------------------------------------- | | `stop_id` | UUID | Optional | If provided, retrieve the specified stop | -200 Success Response: - If `stop_id` is specified, `GET` will return an array with a single stop record, otherwise it will be a list of all stop records. +### Responses + +_Possible HTTP Status Codes_: +200, +401, +404, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. + [Top][toc] ## Reports @@ -344,19 +442,24 @@ The `/reports` endpoint allows an agency to register aggregated report counts in **Method:** `POST` **Payload**: A CSV of [Reports][reports] -200 Success Response: +### Responses + +_Possible HTTP Status Codes_: +201, +400, +401, +406, +500 -See [Bulk Responses][bulk-responses] +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. #### Reports Register Errors: | `error` | `error_description` | `error_details`[] | | -------------------- | ------------------------------------------------- | ------------------------------- | | `bad_param` | A validation error occurred | Array of parameters with errors | -| `missing_param` | A required parameter is missing | Array of missing parameters | -| `already_registered` | A stop with `stop_id` is already registered | | -403 Unauthorized Response: +400 Unauthorized Response: **None** @@ -369,17 +472,19 @@ See [Bulk Responses][bulk-responses] [geography-driven-events]: /general-information.md#geography-driven-events [error-messages]: /general-information.md#error-messages [hdop]: https://en.wikipedia.org/wiki/Dilution_of_precision_(navigation) +[iana]: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml [modes]: /modes/README.md -[propulsion-types]: /data_types.md#propulsion-types -[reports]: /data_types.md#reports +[propulsion-types]: /data-types.md#propulsion-types +[reports]: /data-types.md#reports [responses]: /general-information.md#responses -[stops]: /data_types.md#stops -[telemetry-data]: /data_types.md#telemetry -[trip-data]: /data_types.md#trips +[schema]: /schema/ +[stops]: /data-types.md#stops +[telemetry-data]: /data-types.md#telemetry +[trip-data]: /data-types.md#trips [toc]: #table-of-contents [ts]: /general-information.md#timestamps [vehicle]: /data-types.md#vehicles -[vehicle-types]: /data_types.md#vehicle-types +[vehicle-types]: /data-types.md#vehicle-types [vehicle-states]: /modes/vehicle_states.md [vehicle-event-types]: /modes/event_types.md [vehicle-event]: /data-types.md#events diff --git a/agency/get_stops.json b/agency/get_stops.json deleted file mode 100644 index a966091c..00000000 --- a/agency/get_stops.json +++ /dev/null @@ -1,308 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/agency/get_stops.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Agency Schema, GET stops payload", - "type": "object", - "definitions": { - "stop": { - "$id": "#/definitions/stop", - "type": "object", - "description": "The common schema elements for a Stop in MDS", - "required": [ - "stop_id", - "name", - "last_reported", - "location", - "status", - "capacity", - "num_vehicles_available", - "num_vehicles_disabled" - ], - "properties": { - "stop_id": { - "$id": "#/definitions/stop/properties/stop_id", - "$ref": "#/definitions/uuid", - "description": "UUID for the Stop" - }, - "name": { - "$id": "#/definitions/stop/properties/name", - "$ref": "#/definitions/string", - "description": "Name of the Stop" - }, - "last_reported": { - "$id": "#/definitions/stop/properties/last_reported", - "$ref": "#/definitions/timestamp", - "description": "Date/Time of the last status update for this Stop" - }, - "location": { - "$id": "#/definitions/stop/properties/location", - "$ref": "#/definitions/MDS_Feature_Point", - "description": "Location of the stop" - }, - "status": { - "$id": "#/definitions/stop/properties/status", - "$ref": "#/definitions/stop_status", - "description": "The status of the Stop" - }, - "capacity": { - "$id": "#/definitions/stop/properties/capacity", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of total places per vehicle_type" - }, - "num_vehicles_available": { - "$id": "#/definitions/stop/properties/num_vehicles_available", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of available vehicles per vehicle_type" - }, - "num_vehicles_disabled": { - "$id": "#/definitions/stop/properties/num_vehicles_disabled", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of non_operational/reserved vehicles per vehicle_type" - }, - "provider_id": { - "$id": "#/definitions/stop/properties/provider_id", - "$ref": "#/definitions/uuid", - "description": "UUID for the Provider managing this Stop. Null/undefined if managed by an Agency." - }, - "geography_id": { - "$id": "#/definitions/stop/properties/geography_id", - "$ref": "#/definitions/uuid", - "description": "UUID for the Stop" - }, - "region_id": { - "$id": "#/definitions/stop/properties/region_id", - "$ref": "#/definitions/string", - "description": "ID of the region where the Stop is located. See GBFS Station Information." - }, - "short_name": { - "$id": "#/definitions/stop/properties/short_name", - "$ref": "#/definitions/string", - "description": "Abbreviated Stop name" - }, - "address": { - "$id": "#/definitions/stop/properties/address", - "$ref": "#/definitions/string", - "description": "Postal address (useful for directions)" - }, - "post_code": { - "$id": "#/definitions/stop/properties/post_code", - "$ref": "#/definitions/string", - "description": "Postal code (e.g. 10036)" - }, - "cross_street": { - "$id": "#/definitions/stop/properties/cross_street", - "$ref": "#/definitions/string", - "description": "Cross street of where Stop is located" - }, - "num_places_available": { - "$id": "#/definitions/stop/properties/num_places_available", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of places free to be populated per vehicle_type" - }, - "num_places_disabled": { - "$id": "#/definitions/stop/properties/num_places_disabled", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of places disabled an unable to accept vehicles per vehicle_type" - }, - "parent_stop": { - "$id": "#/definitions/stop/properties/parent_stop", - "$ref": "#/definitions/uuid", - "description": "Describe a basic hierarchy of Stops (e.g. a Stop inside a greater Stop)" - }, - "devices": { - "$id": "#/definitions/stop/properties/devices", - "$ref": "#/definitions/uuid_array", - "description": "List of device_id for vehicles currently at this Stop." - } - } - }, - "stop_status": { - "$id": "#/definitions/stop_status", - "type": "object", - "description": "Status object for a Stop in MDS", - "required": [ - "is_installed", - "is_renting", - "is_returning" - ], - "properties": { - "is_installed": { - "$id": "#/definitions/stop_status/properties/is_installed", - "type": "boolean" - }, - "is_renting": { - "$id": "#/definitions/stop_status/properties/is_renting", - "type": "boolean" - }, - "is_returning": { - "$id": "#/definitions/stop_status/properties/is_returning", - "type": "boolean" - } - } - }, - "string": { - "$id": "#/definitions/string", - "type": "string", - "description": "A length-limited string type", - "maxLength": 255, - "default": "", - "examples": [ - "ABC123" - ], - "pattern": "^(.*)$" - }, - "timestamp": { - "$id": "#/definitions/timestamp", - "type": "number", - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - }, - "uuid_array": { - "$id": "#/definitions/uuid_array", - "type": "array", - "description": "Array of UUID", - "items": { - "$id": "#/definitions/uuid_array/items", - "$ref": "#/definitions/uuid" - } - }, - "vehicle_type_counts": { - "$id": "#/definitions/vehicle_type_counts", - "type": "object", - "properties": { - "bicycle": { - "$id": "#/definitions/vehicle_type_counts/properties/bicycle", - "type": "integer", - "minimum": 0 - }, - "cargo_bicycle": { - "$id": "#/definitions/vehicle_type_counts/properties/cargo_bicycle", - "type": "integer", - "minimum": 0 - }, - "car": { - "$id": "#/definitions/vehicle_type_counts/properties/car", - "type": "integer", - "minimum": 0 - }, - "scooter": { - "$id": "#/definitions/vehicle_type_counts/properties/scooter", - "type": "integer", - "minimum": 0 - }, - "moped": { - "$id": "#/definitions/vehicle_type_counts/properties/moped", - "type": "integer", - "minimum": 0 - }, - "other": { - "$id": "#/definitions/vehicle_type_counts/properties/other", - "type": "integer", - "minimum": 0 - } - }, - "additionalProperties": false - }, - "MDS_Feature_Point": { - "$id": "#/definitions/MDS_Feature_Point", - "title": "MDS GeoJSON Feature Point", - "type": "object", - "required": [ - "type", - "properties", - "geometry" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Feature" - ] - }, - "id": { - "oneOf": [ - { - "type": "number" - }, - { - "type": "string" - } - ] - }, - "properties": { - "type": "object", - "required": [ - "timestamp" - ], - "properties": { - "timestamp": { - "$ref": "#/definitions/timestamp" - }, - "stop_id": { - "$ref": "#/definitions/uuid" - }, - "altitude": { - "type": "number", - "description": "Altitude above mean sea level in meters" - }, - "heading": { - "type": "number", - "description": "Degrees - clockwise starting at 0 degrees at true North" - }, - "speed": { - "type": "number", - "description": "Estimated speed in meters / sec as reported by the GPS chipset" - }, - "accuracy": { - "type": "number", - "description": "Horizontal accuracy, in meters" - }, - "hdop": { - "type": "number", - "description": "Horizontal GPS or GNSS accuracy value" - }, - "satellites": { - "type": "integer", - "description": "Number of GPS or GNSS satellites" - } - } - }, - "geometry": { - "$ref": "#/definitions/Point" - }, - "bbox": { - "type": "array", - "minItems": 4, - "items": { - "type": "number" - } - } - } - } - }, - "required": [ - "stops" - ], - "properties": { - "stops": { - "$id": "#/properties/stops", - "type": "array", - "description": "The array of stops", - "items": { - "$ref": "#/definitions/stop" - } - } - }, - "additionalProperties": false -} \ No newline at end of file diff --git a/agency/get_vehicle.json b/agency/get_vehicle.json deleted file mode 100644 index d03929f6..00000000 --- a/agency/get_vehicle.json +++ /dev/null @@ -1,332 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/agency/get_vehicle.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Agency Schema, GET vehicle payload", - "type": "object", - "definitions": { - "propulsion_types": { - "$id": "#/definitions/propulsion_types", - "type": "array", - "description": "Array of propulsion types, allowing multiple values", - "items": { - "$id": "#/definitions/propulsion_types/items", - "$ref": "#/definitions/propulsion_type" - }, - "uniqueItems": true - }, - "string": { - "$id": "#/definitions/string", - "type": "string", - "description": "A length-limited string type", - "maxLength": 255, - "default": "", - "examples": [ - "ABC123" - ], - "pattern": "^(.*)$" - }, - "timestamp": { - "$id": "#/definitions/timestamp", - "type": "number", - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "vehicle_type": { - "$id": "#/definitions/vehicle_type", - "type": "string", - "description": "The type of vehicle", - "enum": [ - "bicycle", - "cargo_bicycle", - "car", - "scooter", - "moped", - "other" - ] - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - }, - "vehicle_state": { - "$id": "#/definitions/vehicle_state", - "type": "string", - "description": "The state of a vehicle", - "enum": [ - "available", - "elsewhere", - "non_operational", - "on_trip", - "removed", - "reserved", - "unknown" - ] - }, - "vehicle_event": { - "$id": "#/definitions/vehicle_event", - "type": "string", - "description": "An event that changes a vehicle's state", - "enum": [ - "agency_drop_off", - "agency_pick_up", - "battery_charged", - "battery_low", - "comms_lost", - "comms_restored", - "compliance_pick_up", - "decommissioned", - "located", - "maintenance", - "maintenance_pick_up", - "missing", - "off_hours", - "on_hours", - "provider_drop_off", - "rebalance_pick_up", - "reservation_cancel", - "reservation_start", - "system_resume", - "system_suspend", - "trip_cancel", - "trip_end", - "trip_enter_jurisdiction", - "trip_leave_jurisdiction", - "trip_start", - "unspecified" - ] - }, - "vehicle_events": { - "$id": "#/definitions/vehicle_events", - "type": "array", - "description": "Array of events indicating a change to a vehicle's state", - "uniqueItems": true, - "minItems": 1, - "items": { - "$ref": "#/definitions/vehicle_event" - } - } - }, - "required": [ - "provider_id", - "device_id", - "vehicle_id", - "vehicle_type", - "propulsion_types", - "year", - "mfgr", - "model", - "state", - "prev_events", - "updated" - ], - "properties": { - "provider_id": { - "$id": "#/definitions/vehicle/properties/provider_id", - "$ref": "#/definitions/uuid", - "description": "The UUID for the Provider, unique within MDS" - }, - "device_id": { - "$id": "#/definitions/vehicle/properties/device_id", - "$ref": "#/definitions/uuid", - "description": "A unique device ID in UUID format" - }, - "vehicle_id": { - "$id": "#/definitions/vehicle/properties/vehicle_id", - "$ref": "#/definitions/string", - "description": "The Vehicle Identification Number visible on the vehicle itself" - }, - "vehicle_type": { - "$id": "#/definitions/vehicle/properties/vehicle_type", - "$ref": "#/definitions/vehicle_type", - "description": "The type of vehicle" - }, - "propulsion_types": { - "$id": "#/definitions/vehicle/properties/propulsion_types", - "$ref": "#/definitions/propulsion_types", - "description": "The type of propulsion; allows multiple values", - "minItems": 1 - }, - "year": { - "$id": "#/properties/year", - "type": "integer", - "description": "The year the vehicle was manufactured", - "default": 1970, - "examples": [ - 2018 - ] - }, - "mfgr": { - "$id": "#/properties/mfgr", - "$ref": "#/definitions/string", - "description": "The vehicle manufacturer" - }, - "model": { - "$id": "#/properties/model", - "$ref": "#/definitions/string", - "description": "The vehicle model" - }, - "state": { - "$id": "#/properties/state", - "$ref": "#/definitions/vehicle_state", - "description": "Current vehicle state" - }, - "prev_events": { - "$id": "#/properties/prev_events", - "$ref": "#/definitions/vehicle_events", - "description": "Last vehicle event" - }, - "updated": { - "$id": "#/properties/updated", - "$ref": "#/definitions/timestamp" - } - }, - "additionalProperties": false, - "allOf": [ - { - "description": "valid vehicle_state and vehicle_events combinations", - "oneOf": [ - { - "properties": { - "state": { - "const": "available" - }, - "prev_events": { - "contains": { - "enum": [ - "agency_drop_off", - "battery_charged", - "comms_restored", - "located", - "maintenance", - "on_hours", - "provider_drop_off", - "reservation_cancel", - "system_resume", - "trip_cancel", - "trip_end", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "state": { - "const": "elsewhere" - }, - "prev_events": { - "contains": { - "enum": [ - "comms_restored", - "located", - "trip_leave_jurisdiction", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "state": { - "const": "non_operational" - }, - "prev_events": { - "contains": { - "enum": [ - "battery_low", - "comms_restored", - "located", - "maintenance", - "off_hours", - "system_suspend", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "state": { - "const": "on_trip" - }, - "prev_events": { - "contains": { - "enum": [ - "comms_restored", - "located", - "trip_enter_jurisdiction", - "trip_start", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "state": { - "const": "removed" - }, - "prev_events": { - "contains": { - "enum": [ - "agency_pick_up", - "comms_restored", - "compliance_pick_up", - "decommissioned", - "located", - "maintenance_pick_up", - "rebalance_pick_up", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "state": { - "const": "reserved" - }, - "prev_events": { - "contains": { - "enum": [ - "comms_restored", - "located", - "reservation_start", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "state": { - "const": "unknown" - }, - "prev_events": { - "contains": { - "enum": [ - "comms_lost", - "missing", - "unspecified" - ] - } - } - } - } - ] - } - ] -} \ No newline at end of file diff --git a/agency/post_stops.json b/agency/post_stops.json deleted file mode 100644 index 570973b9..00000000 --- a/agency/post_stops.json +++ /dev/null @@ -1,308 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/agency/post_stops.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Agency Schema, register Stops", - "type": "object", - "definitions": { - "stop": { - "$id": "#/definitions/stop", - "type": "object", - "description": "The common schema elements for a Stop in MDS", - "required": [ - "stop_id", - "name", - "last_reported", - "location", - "status", - "capacity", - "num_vehicles_available", - "num_vehicles_disabled" - ], - "properties": { - "stop_id": { - "$id": "#/definitions/stop/properties/stop_id", - "$ref": "#/definitions/uuid", - "description": "UUID for the Stop" - }, - "name": { - "$id": "#/definitions/stop/properties/name", - "$ref": "#/definitions/string", - "description": "Name of the Stop" - }, - "last_reported": { - "$id": "#/definitions/stop/properties/last_reported", - "$ref": "#/definitions/timestamp", - "description": "Date/Time of the last status update for this Stop" - }, - "location": { - "$id": "#/definitions/stop/properties/location", - "$ref": "#/definitions/MDS_Feature_Point", - "description": "Location of the stop" - }, - "status": { - "$id": "#/definitions/stop/properties/status", - "$ref": "#/definitions/stop_status", - "description": "The status of the Stop" - }, - "capacity": { - "$id": "#/definitions/stop/properties/capacity", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of total places per vehicle_type" - }, - "num_vehicles_available": { - "$id": "#/definitions/stop/properties/num_vehicles_available", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of available vehicles per vehicle_type" - }, - "num_vehicles_disabled": { - "$id": "#/definitions/stop/properties/num_vehicles_disabled", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of non_operational/reserved vehicles per vehicle_type" - }, - "provider_id": { - "$id": "#/definitions/stop/properties/provider_id", - "$ref": "#/definitions/uuid", - "description": "UUID for the Provider managing this Stop. Null/undefined if managed by an Agency." - }, - "geography_id": { - "$id": "#/definitions/stop/properties/geography_id", - "$ref": "#/definitions/uuid", - "description": "UUID for the Stop" - }, - "region_id": { - "$id": "#/definitions/stop/properties/region_id", - "$ref": "#/definitions/string", - "description": "ID of the region where the Stop is located. See GBFS Station Information." - }, - "short_name": { - "$id": "#/definitions/stop/properties/short_name", - "$ref": "#/definitions/string", - "description": "Abbreviated Stop name" - }, - "address": { - "$id": "#/definitions/stop/properties/address", - "$ref": "#/definitions/string", - "description": "Postal address (useful for directions)" - }, - "post_code": { - "$id": "#/definitions/stop/properties/post_code", - "$ref": "#/definitions/string", - "description": "Postal code (e.g. 10036)" - }, - "cross_street": { - "$id": "#/definitions/stop/properties/cross_street", - "$ref": "#/definitions/string", - "description": "Cross street of where Stop is located" - }, - "num_places_available": { - "$id": "#/definitions/stop/properties/num_places_available", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of places free to be populated per vehicle_type" - }, - "num_places_disabled": { - "$id": "#/definitions/stop/properties/num_places_disabled", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of places disabled an unable to accept vehicles per vehicle_type" - }, - "parent_stop": { - "$id": "#/definitions/stop/properties/parent_stop", - "$ref": "#/definitions/uuid", - "description": "Describe a basic hierarchy of Stops (e.g. a Stop inside a greater Stop)" - }, - "devices": { - "$id": "#/definitions/stop/properties/devices", - "$ref": "#/definitions/uuid_array", - "description": "List of device_id for vehicles currently at this Stop." - } - } - }, - "stop_status": { - "$id": "#/definitions/stop_status", - "type": "object", - "description": "Status object for a Stop in MDS", - "required": [ - "is_installed", - "is_renting", - "is_returning" - ], - "properties": { - "is_installed": { - "$id": "#/definitions/stop_status/properties/is_installed", - "type": "boolean" - }, - "is_renting": { - "$id": "#/definitions/stop_status/properties/is_renting", - "type": "boolean" - }, - "is_returning": { - "$id": "#/definitions/stop_status/properties/is_returning", - "type": "boolean" - } - } - }, - "string": { - "$id": "#/definitions/string", - "type": "string", - "description": "A length-limited string type", - "maxLength": 255, - "default": "", - "examples": [ - "ABC123" - ], - "pattern": "^(.*)$" - }, - "timestamp": { - "$id": "#/definitions/timestamp", - "type": "number", - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - }, - "uuid_array": { - "$id": "#/definitions/uuid_array", - "type": "array", - "description": "Array of UUID", - "items": { - "$id": "#/definitions/uuid_array/items", - "$ref": "#/definitions/uuid" - } - }, - "vehicle_type_counts": { - "$id": "#/definitions/vehicle_type_counts", - "type": "object", - "properties": { - "bicycle": { - "$id": "#/definitions/vehicle_type_counts/properties/bicycle", - "type": "integer", - "minimum": 0 - }, - "cargo_bicycle": { - "$id": "#/definitions/vehicle_type_counts/properties/cargo_bicycle", - "type": "integer", - "minimum": 0 - }, - "car": { - "$id": "#/definitions/vehicle_type_counts/properties/car", - "type": "integer", - "minimum": 0 - }, - "scooter": { - "$id": "#/definitions/vehicle_type_counts/properties/scooter", - "type": "integer", - "minimum": 0 - }, - "moped": { - "$id": "#/definitions/vehicle_type_counts/properties/moped", - "type": "integer", - "minimum": 0 - }, - "other": { - "$id": "#/definitions/vehicle_type_counts/properties/other", - "type": "integer", - "minimum": 0 - } - }, - "additionalProperties": false - }, - "MDS_Feature_Point": { - "$id": "#/definitions/MDS_Feature_Point", - "title": "MDS GeoJSON Feature Point", - "type": "object", - "required": [ - "type", - "properties", - "geometry" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Feature" - ] - }, - "id": { - "oneOf": [ - { - "type": "number" - }, - { - "type": "string" - } - ] - }, - "properties": { - "type": "object", - "required": [ - "timestamp" - ], - "properties": { - "timestamp": { - "$ref": "#/definitions/timestamp" - }, - "stop_id": { - "$ref": "#/definitions/uuid" - }, - "altitude": { - "type": "number", - "description": "Altitude above mean sea level in meters" - }, - "heading": { - "type": "number", - "description": "Degrees - clockwise starting at 0 degrees at true North" - }, - "speed": { - "type": "number", - "description": "Estimated speed in meters / sec as reported by the GPS chipset" - }, - "accuracy": { - "type": "number", - "description": "Horizontal accuracy, in meters" - }, - "hdop": { - "type": "number", - "description": "Horizontal GPS or GNSS accuracy value" - }, - "satellites": { - "type": "integer", - "description": "Number of GPS or GNSS satellites" - } - } - }, - "geometry": { - "$ref": "#/definitions/Point" - }, - "bbox": { - "type": "array", - "minItems": 4, - "items": { - "type": "number" - } - } - } - } - }, - "required": [ - "stops" - ], - "properties": { - "stops": { - "$id": "#/properties/stops", - "type": "array", - "description": "The array of stops", - "items": { - "$ref": "#/definitions/stop" - } - } - }, - "additionalProperties": false -} \ No newline at end of file diff --git a/agency/post_vehicle.json b/agency/post_vehicle.json deleted file mode 100644 index 21d14ec2..00000000 --- a/agency/post_vehicle.json +++ /dev/null @@ -1,101 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/agency/post_vehicle.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Agency Schema, register vehicle body", - "type": "object", - "definitions": { - "propulsion_types": { - "$id": "#/definitions/propulsion_types", - "type": "array", - "description": "Array of propulsion types, allowing multiple values", - "items": { - "$id": "#/definitions/propulsion_types/items", - "$ref": "#/definitions/propulsion_type" - }, - "uniqueItems": true - }, - "string": { - "$id": "#/definitions/string", - "type": "string", - "description": "A length-limited string type", - "maxLength": 255, - "default": "", - "examples": [ - "ABC123" - ], - "pattern": "^(.*)$" - }, - "vehicle_type": { - "$id": "#/definitions/vehicle_type", - "type": "string", - "description": "The type of vehicle", - "enum": [ - "bicycle", - "cargo_bicycle", - "car", - "scooter", - "moped", - "other" - ] - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - } - }, - "required": [ - "device_id", - "vehicle_id", - "vehicle_type", - "propulsion_types" - ], - "properties": { - "device_id": { - "$id": "#/definitions/vehicle/properties/device_id", - "$ref": "#/definitions/uuid", - "description": "A unique device ID in UUID format" - }, - "vehicle_id": { - "$id": "#/definitions/vehicle/properties/vehicle_id", - "$ref": "#/definitions/string", - "description": "The Vehicle Identification Number visible on the vehicle itself" - }, - "vehicle_type": { - "$id": "#/definitions/vehicle/properties/vehicle_type", - "$ref": "#/definitions/vehicle_type", - "description": "The type of vehicle" - }, - "propulsion_types": { - "$id": "#/definitions/vehicle/properties/propulsion_types", - "$ref": "#/definitions/propulsion_types", - "description": "The type of propulsion; allows multiple values", - "minItems": 1 - }, - "year": { - "$id": "#/properties/year", - "type": "integer", - "description": "The year the vehicle was manufactured", - "default": 1970, - "examples": [ - 2018 - ] - }, - "mfgr": { - "$id": "#/properties/mfgr", - "$ref": "#/definitions/string", - "description": "The vehicle manufacturer" - }, - "model": { - "$id": "#/properties/model", - "$ref": "#/definitions/string", - "description": "The vehicle model" - } - }, - "additionalProperties": false -} \ No newline at end of file diff --git a/agency/post_vehicle_event.json b/agency/post_vehicle_event.json deleted file mode 100644 index 284bc222..00000000 --- a/agency/post_vehicle_event.json +++ /dev/null @@ -1,345 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/agency/post_vehicle_event.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Agency Schema, POST vehicle status body", - "type": "object", - "definitions": { - "timestamp": { - "$id": "#/definitions/timestamp", - "type": "number", - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - }, - "vehicle_telemetry": { - "$id": "#/definitions/vehicle_telemetry", - "type": "object", - "description": "A telemetry datum for a specific vehicle at a specific time", - "required": [ - "device_id", - "timestamp", - "gps" - ], - "additionalProperties": false, - "properties": { - "device_id": { - "$ref": "#/definitions/uuid" - }, - "timestamp": { - "$ref": "#/definitions/timestamp" - }, - "gps": { - "type": "object", - "required": [ - "lat", - "lng" - ], - "additionalProperties": false, - "properties": { - "lat": { - "type": "number", - "description": "Latitude of the location", - "minimum": -90, - "maximum": 90 - }, - "lng": { - "type": "number", - "description": "Longitude of the location", - "minimum": -180, - "maximum": 180 - }, - "altitude": { - "type": "number", - "description": "Altitude above mean sea level in meters" - }, - "heading": { - "type": "number", - "description": "Degrees - clockwise starting at 0 degrees at true North" - }, - "speed": { - "type": "number", - "description": "Estimated speed in meters / sec as reported by the GPS chipset" - }, - "accuracy": { - "type": "number", - "description": "Horizontal accuracy, in meters" - }, - "hdop": { - "type": "number", - "description": "Horizontal GPS or GNSS accuracy value" - }, - "satellites": { - "type": "integer", - "description": "Number of GPS or GNSS satellites" - } - } - }, - "charge": { - "type": "number", - "description": "Fraction of charge of the vehicle (required if applicable)", - "minimum": 0, - "maximum": 1 - } - } - }, - "vehicle_state": { - "$id": "#/definitions/vehicle_state", - "type": "string", - "description": "The state of a vehicle", - "enum": [ - "available", - "elsewhere", - "non_operational", - "on_trip", - "removed", - "reserved", - "unknown" - ] - }, - "vehicle_event": { - "$id": "#/definitions/vehicle_event", - "type": "string", - "description": "An event that changes a vehicle's state", - "enum": [ - "agency_drop_off", - "agency_pick_up", - "battery_charged", - "battery_low", - "comms_lost", - "comms_restored", - "compliance_pick_up", - "decommissioned", - "located", - "maintenance", - "maintenance_pick_up", - "missing", - "off_hours", - "on_hours", - "provider_drop_off", - "rebalance_pick_up", - "reservation_cancel", - "reservation_start", - "system_resume", - "system_suspend", - "trip_cancel", - "trip_end", - "trip_enter_jurisdiction", - "trip_leave_jurisdiction", - "trip_start", - "unspecified" - ] - }, - "vehicle_events": { - "$id": "#/definitions/vehicle_events", - "type": "array", - "description": "Array of events indicating a change to a vehicle's state", - "uniqueItems": true, - "minItems": 1, - "items": { - "$ref": "#/definitions/vehicle_event" - } - } - }, - "required": [ - "vehicle_state", - "event_types", - "timestamp", - "telemetry" - ], - "properties": { - "vehicle_state": { - "$ref": "#/definitions/vehicle_state" - }, - "event_types": { - "$ref": "#/definitions/vehicle_events" - }, - "timestamp": { - "$ref": "#/definitions/timestamp" - }, - "telemetry": { - "$ref": "#/definitions/vehicle_telemetry" - }, - "trip_id": { - "$ref": "#/definitions/uuid" - } - }, - "additionalProperties": false, - "allOf": [ - { - "description": "valid vehicle_state and vehicle_events combinations", - "oneOf": [ - { - "properties": { - "vehicle_state": { - "const": "available" - }, - "event_types": { - "contains": { - "enum": [ - "agency_drop_off", - "battery_charged", - "comms_restored", - "located", - "maintenance", - "on_hours", - "provider_drop_off", - "reservation_cancel", - "system_resume", - "trip_cancel", - "trip_end", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "elsewhere" - }, - "event_types": { - "contains": { - "enum": [ - "comms_restored", - "located", - "trip_leave_jurisdiction", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "non_operational" - }, - "event_types": { - "contains": { - "enum": [ - "battery_low", - "comms_restored", - "located", - "maintenance", - "off_hours", - "system_suspend", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "on_trip" - }, - "event_types": { - "contains": { - "enum": [ - "comms_restored", - "located", - "trip_enter_jurisdiction", - "trip_start", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "removed" - }, - "event_types": { - "contains": { - "enum": [ - "agency_pick_up", - "comms_restored", - "compliance_pick_up", - "decommissioned", - "located", - "maintenance_pick_up", - "rebalance_pick_up", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "reserved" - }, - "event_types": { - "contains": { - "enum": [ - "comms_restored", - "located", - "reservation_start", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "unknown" - }, - "event_types": { - "contains": { - "enum": [ - "comms_lost", - "missing", - "unspecified" - ] - } - } - } - } - ] - }, - { - "description": "Conditionally require a trip_id reference", - "anyOf": [ - { - "not": { - "properties": { - "event_types": { - "contains": { - "enum": [ - "trip_cancel", - "trip_end", - "trip_enter_jurisdiction", - "trip_leave_jurisdiction", - "trip_start" - ] - } - } - } - } - }, - { - "required": [ - "trip_id" - ] - } - ] - } - ] -} \ No newline at end of file diff --git a/agency/post_vehicle_telemetry.json b/agency/post_vehicle_telemetry.json deleted file mode 100644 index 021c9d8e..00000000 --- a/agency/post_vehicle_telemetry.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/agency/post_vehicle_telemetry.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Agency Schema, POST vehicle telemetry body", - "type": "object", - "definitions": { - "timestamp": { - "$id": "#/definitions/timestamp", - "type": "number", - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - }, - "vehicle_telemetry": { - "$id": "#/definitions/vehicle_telemetry", - "type": "object", - "description": "A telemetry datum for a specific vehicle at a specific time", - "required": [ - "device_id", - "timestamp", - "gps" - ], - "additionalProperties": false, - "properties": { - "device_id": { - "$ref": "#/definitions/uuid" - }, - "timestamp": { - "$ref": "#/definitions/timestamp" - }, - "gps": { - "type": "object", - "required": [ - "lat", - "lng" - ], - "additionalProperties": false, - "properties": { - "lat": { - "type": "number", - "description": "Latitude of the location", - "minimum": -90, - "maximum": 90 - }, - "lng": { - "type": "number", - "description": "Longitude of the location", - "minimum": -180, - "maximum": 180 - }, - "altitude": { - "type": "number", - "description": "Altitude above mean sea level in meters" - }, - "heading": { - "type": "number", - "description": "Degrees - clockwise starting at 0 degrees at true North" - }, - "speed": { - "type": "number", - "description": "Estimated speed in meters / sec as reported by the GPS chipset" - }, - "accuracy": { - "type": "number", - "description": "Horizontal accuracy, in meters" - }, - "hdop": { - "type": "number", - "description": "Horizontal GPS or GNSS accuracy value" - }, - "satellites": { - "type": "integer", - "description": "Number of GPS or GNSS satellites" - } - } - }, - "charge": { - "type": "number", - "description": "Fraction of charge of the vehicle (required if applicable)", - "minimum": 0, - "maximum": 1 - } - } - } - }, - "required": [ - "data" - ], - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/definitions/vehicle_telemetry" - } - } - }, - "additionalProperties": false -} \ No newline at end of file diff --git a/agency/put_stops.json b/agency/put_stops.json deleted file mode 100644 index 5f510cdb..00000000 --- a/agency/put_stops.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/agency/put_stops.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Agency Schema, update Stops", - "type": "object", - "definitions": { - "stop_status": { - "$id": "#/definitions/stop_status", - "type": "object", - "description": "Status object for a Stop in MDS", - "required": [ - "is_installed", - "is_renting", - "is_returning" - ], - "properties": { - "is_installed": { - "$id": "#/definitions/stop_status/properties/is_installed", - "type": "boolean" - }, - "is_renting": { - "$id": "#/definitions/stop_status/properties/is_renting", - "type": "boolean" - }, - "is_returning": { - "$id": "#/definitions/stop_status/properties/is_returning", - "type": "boolean" - } - } - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - }, - "vehicle_type_counts": { - "$id": "#/definitions/vehicle_type_counts", - "type": "object", - "properties": { - "bicycle": { - "$id": "#/definitions/vehicle_type_counts/properties/bicycle", - "type": "integer", - "minimum": 0 - }, - "cargo_bicycle": { - "$id": "#/definitions/vehicle_type_counts/properties/cargo_bicycle", - "type": "integer", - "minimum": 0 - }, - "car": { - "$id": "#/definitions/vehicle_type_counts/properties/car", - "type": "integer", - "minimum": 0 - }, - "scooter": { - "$id": "#/definitions/vehicle_type_counts/properties/scooter", - "type": "integer", - "minimum": 0 - }, - "moped": { - "$id": "#/definitions/vehicle_type_counts/properties/moped", - "type": "integer", - "minimum": 0 - }, - "other": { - "$id": "#/definitions/vehicle_type_counts/properties/other", - "type": "integer", - "minimum": 0 - } - }, - "additionalProperties": false - } - }, - "required": [ - "stops" - ], - "properties": { - "stops": { - "$id": "#/properties/stops", - "type": "array", - "description": "The array of stops", - "items": { - "type": "object", - "required": [ - "stop_id" - ], - "properties": { - "stop_id": { - "$ref": "#/definitions/uuid" - }, - "status": { - "$ref": "#/definitions/stop_status" - }, - "num_spots_disabled": { - "$ref": "#/definitions/vehicle_type_counts" - } - } - } - } - }, - "additionalProperties": false -} \ No newline at end of file diff --git a/data-types.md b/data-types.md index f963a754..304a43cf 100644 --- a/data-types.md +++ b/data-types.md @@ -24,13 +24,13 @@ A vehicle record is as follows: | Field | Type | Required/Optional | Comments | | -------------------- | -------- | --------------------- | -------- | | `device_id` | UUID | Required | A unique device ID in UUID format, should match this device in Provider | -| `provider_id` | UUID | Required | A UUID for the Provider, unique within MDS. See MDS [provider list](/providers.csv). | +| `provider_id` | UUID | Required | A UUID for the Provider, unique within MDS. See MDS [provider list](/providers.csv). | | `data_provider_id` | UUID | Optional | If different than `provider_id`, a UUID for the data solution provider managing the data feed in this endpoint. See MDS [provider list](/providers.csv) which includes both service operators and data solution providers. | | `vehicle_id` | String | Required | A unique vehicle identifier (visible code, license plate, etc), visible on the vehicle itself | | `vehicle_type` | Enum | Required | The [vehicle type][vehicle-types] | -| `vehicle_attributes` | Array | Optional | **[Mode](/modes#list-of-supported-modes) Specific**. [Vehicle attributes](/modes#vehicle-attributes) given as mode-specific unordered key-value pairs | +| `vehicle_attributes` | Map | Optional | **[Mode](/modes#list-of-supported-modes) Specific**. [Vehicle attributes](/modes#vehicle-attributes) given as mode-specific unordered key-value pairs | | `propulsion_types` | Enum[] | Required | Array of [propulsion types][propulsion-types]; allows multiple values | -| `accessibility_options` | Enum[] | Required | **[Mode](/modes#list-of-supported-modes) Specific**. [Accessibility options](/modes#accessibility-options) given as an array of enumerated values. List of any accessibility options **available on the vehicle**. | +| `accessibility_attributes` | Enum[] | Required if Available | **[Mode](/modes#list-of-supported-modes) Specific**. [Accessibility attributes](/modes#accessibility-attributes) given as an array of enumerated values. List of any accessibility attributes **available on the vehicle**. | | `battery_capacity` | Integer | Required if Available | Capacity of battery expressed as milliamp hours (mAh) | | `fuel_capacity` | Integer | Required if Available | Capacity of fuel tank (liquid, solid, gaseous) expressed in liters | | `maximum_speed` | Integer | Required if Available | Maximum speed (kph) possible with vehicle under normal, flat incline, smooth surface conditions. Applicable if the device has a built-in or intelligent speed limiter/governor. | @@ -39,7 +39,7 @@ A vehicle record is as follows: ### Vehicle Types -The list of allowed `vehicle_type` values in MDS. +The list of allowed `vehicle_type` values in MDS. | `vehicle_type` | Description | |--------------------| ----------- | @@ -61,7 +61,7 @@ Values based off of `form_factor` in [GBFS vehicle_types](https://github.com/Mob ### Propulsion Types -The list of allowed `propulsion_type` values in MDS. +The list of allowed `propulsion_type` values in MDS. | `propulsion` | Description | | -------------------- | ------------------------------------------------------ | @@ -80,7 +80,7 @@ Values based off of `propulsion_type` in [GBFS vehicle_types](https://github.com [Top][toc] -### Vehicle Status +### Vehicle Status A vehicle status record represents the current or last-known event and telemetry from a vehicle, defined as follows: @@ -112,8 +112,7 @@ Events represent changes in vehicle status. | `event_geographies` | UUID[] | Optional | **[Beta feature](/general-information.md#beta-features):** *Yes (as of 2.0.0)*. Array of Geography UUIDs consisting of every Geography that contains the location of the status change. See [Geography Driven Events][geography-driven-events]. Required if `location` is not present. | | `battery_percent` | Integer | Required if Applicable | Percent battery charge of vehicle, expressed between 0 and 100 | | `fuel_percent` | Integer | Required if Applicable | Percent fuel in vehicle, expressed between 0 and 100 | -| `trip_ids`[] | UUID[] | Required if Applicable | Trip UUIDs (foreign key to /trips endpoint), required if `event_types` contains `trip_start`, `trip_end`, `trip_cancel`, `trip_enter_jurisdiction`, or `trip_leave_jurisdiction` | -| `journey_id` | UUID | Optional | Journey UUID | TODO "see `journey_id`" or something | +| `trip_ids` | UUID[] | Required if Applicable | Trip UUIDs (foreign key to /trips endpoint), required if `event_types` contains `trip_start`, `trip_end`, `trip_cancel`, `trip_enter_jurisdiction`, or `trip_leave_jurisdiction` | | `associated_ticket` | String | Optional | Identifier for an associated ticket inside an Agency-maintained 311 or CRM system | ### Event Times @@ -133,8 +132,8 @@ A standard point of vehicle telemetry. References to latitude and longitude impl | `data_provider_id`| UUID | Optional | If different than `provider_id`, a UUID for the data solution provider managing the data feed in this endpoint. See MDS [provider list](/providers.csv) which includes both service operators and data solution providers. | | `telemetry_id` | UUID | Required | ID used for uniquely-identifying a Telemetry entry | | `timestamp` | [Timestamp][ts] | Required | Date/time that event occurred. Based on GPS or GNSS clock | -| `trip_ids` | UUID[] | Required | If telemetry occurred during a trip, the ID of the trip(s). If not in a trip, `null`. -| `journey_id` | UUID | Required | If telemetry occurred during a trip, the ID of the journey. If not in a trip, `null`. +| `trip_ids` | UUID[] | Required | If telemetry occurred during a trip, the ID of the trip(s). If not in a trip, `null`. +| `journey_id` | UUID | Required | If telemetry occurred during a trip and journeys are used for the mode, the ID of the journey. If not in a trip, `null`. | `stop_id` | UUID | Required if Applicable | Stop that the vehicle is currently located at. See [Stops][stops] | | `location` | [GPS][gps] | Required | Telemetry position data | | `location_type` | Enum | Required if Known | If detectable and known, what type of location the device is on or in. One of `street`, `sidewalk`, `crosswalk`, `garage`, `bike_lane`. | @@ -165,7 +164,7 @@ Stops describe vehicle trip start and end locations in a pre-designated physical | ----- | ---- |-------------------|-------------| | `stop_id` | UUID | Required | Unique ID for stop | | `name` | String | Required | Name of stop | -| `last_reported` | Timestamp | Required | Date/Time that the stop was last updated | +| `last_updated` | Timestamp | Required | Date/Time that the stop was last updated | | `location` | [GPS][gps] | Required | Simple centerpoint location of the Stop. The use of the optional `geography_id` is recommended to provide more detail. | | `status` | [Stop Status](#stop-status) | Required | Object representing the status of the Stop. See [Stop Status](#stop-status). | | `capacity` | {vehicle_type: number} | Required | Number of total places per vehicle_type | @@ -227,12 +226,12 @@ A Trip is defined by the following structure: | `fare_attributes` | Map | Optional | **[Mode](/modes#list-of-supported-modes) Specific**. [Fare attributes](/modes#fare-attributes) given as unordered key-value pairs | | `start_time` | [Timestamp][ts] | Required | Start of the passenger/driver trip | | `end_time` | [Timestamp][ts] | Required | End of the passenger/driver trip | -| `start_location` | [GPS](gps) | Required | Location of the start of the trip. | -| `end_location` | [GPS](gps) | Required | Location of the end of the trip. | +| `start_location` | [GPS][gps] | Required | Location of the start of the trip. | +| `end_location` | [GPS][gps] | Required | Location of the end of the trip. | | `duration` | Integer | Required | Time, in Seconds | | `distance` | Integer | Required | Trip Distance, in Meters | | `publication_time` | [Timestamp][ts] | Optional | Date/time that trip became available through the trips endpoint | -| `accessibility_options` | Enum[] | Required | **[Mode](/modes#list-of-supported-modes) Specific**. [Accessibility options](/modes#accessibility-options) given as an array of enumerated values. List of any accessibility options **used during the trip**. | +| `accessibility_attributes` | Enum[] | Required if Available | **[Mode](/modes#list-of-supported-modes) Specific**. [Accessibility attributes](/modes#accessibility-attributes) given as an array of enumerated values. List of any accessibility attributes **used during the trip**. | | `parking_verification_url` | URL | Optional | A URL to a photo (or other evidence) of proper vehicle parking at the end of a trip, provided by customer or operator. | | `parking_category` | Enum | Optional | The type of parking location detected or provided and the end of a trip. One of `corral`, `curb`, `rack`, `other_valid`, `invalid`. Note that `other_valid` covers any other allowed parking location beyond what is enumerated, and `invalid` is any improper parking based on agency parking rules. | `standard_cost` | Integer | Optional | The cost, in the currency defined in `currency`, to perform that trip in the standard operation of the System (see [Costs & Currencies][costs-and-currencies]) | @@ -260,11 +259,11 @@ A Report is defined by the following structure: ### Data Notes -Report contents include every combination of special group types, geography IDs, and vehicle types in operation for each month since the provider began operations in the jurisdiction. New files are added monthly in addition to the previous monthly historic files. +Report contents include every combination of special group types, geography IDs, and vehicle types in operation for each month since the provider began operations in the jurisdiction. New files are added monthly in addition to the previous monthly historic files. Counts are calculated based the agency's local time zone. Trips are counted based on their start time, i.e. if a trip starts in month A but ends in month B, it will be counted only as part of the report for month A. Similarly, trips are counted based on their start geography, i.e. if a trip starts in geography A and ends in geography B, it will appear in the counts for geography A and not for geography B. -All geography IDs included in the city published [Geography](/geography) API endpoint are included in the report results. In lieu of serving an API, this can alternately be a [flat file](/geography#file-format) created by the city and sent to the provider via link. If there is no `/geography` available, then counts are for the entire agency operating area, and `null` is returned for each Geography ID. +All geography IDs included in the city published [Geography](/geography) API endpoint are included in the report results. In lieu of serving an API, this can alternately be a [flat file](/geography#file-format) created by the city and sent to the provider via link. If there is no `/geography` available, then counts are for the entire agency operating area, and `null` is returned for each Geography ID. [Top][toc] @@ -272,52 +271,41 @@ All geography IDs included in the city published [Geography](/geography) API end Some combinations of parameters may return a small count of trips, which could increase a privacy risk of re-identification. To correct for that, Reports does not return data below a certain count of results. This data redaction is called k-anonymity, and the threshold is set at a k-value of 10. For more explanation of this methodology, see our [Data Redaction Guidance document](https://github.com/openmobilityfoundation/mobility-data-specification/wiki/MDS-Data-Redaction). -**If the query returns fewer than `10` trips in a count, then that row's count value is returned as "-1".** Note "0" values are also returned as "-1" since the goal is to group both low and no count values for privacy. +**If the query returns fewer than `10` trips in a count, then that row's count value is returned as "-1".** Note "0" values are also returned as "-1" since the goal is to group both low and no count values for privacy. This value may be adjusted in future releases and/or may become dynamic to account for specific categories of use cases and users. To improve the specification and to inform future guidance, users are encouraged to share their feedback and questions about k-values on this [discussion thread](https://github.com/openmobilityfoundation/mobility-data-specification/discussions/622). -Using k-anonymity will reduce, but not necessarily eliminate the risk that an individual could be re-identified in a dataset, and this data should still be treated as sensitive. This is just one part of good privacy protection practices, which you can read more about in our [MDS Privacy Guide for Cities](https://github.com/openmobilityfoundation/governance/blob/main/documents/OMF-MDS-Privacy-Guide-for-Cities.pdf). +Using k-anonymity will reduce, but not necessarily eliminate the risk that an individual could be re-identified in a dataset, and this data should still be treated as sensitive. This is just one part of good privacy protection practices, which you can read more about in our [MDS Privacy Guide for Cities](https://github.com/openmobilityfoundation/governance/blob/main/documents/OMF-MDS-Privacy-Guide-for-Cities.pdf). [Top][toc] -### Special Group Type +### Special Group Type -Here are the possible values for the `special_group_type` dimension field: +Here are the possible values for the `special_group_type` dimension field: -| Name | Description | -| ---------------- | --------------------------------------------------------------------------------------------------------------------- | -| low_income | Trips where a low income discount is applied by the provider, e.g., a discount from a qualified provider equity plan. | +| Name | Description | +| ---------------- | --------------------------------------------------------------------------------------------------------------------- | +| low_income | Trips where a low income discount is applied by the provider, e.g., a discount from a qualified provider equity plan. | | adaptive_scooter | Trips taken on a scooter with features to improve accessibility for people with disabilities, e.g., scooter with a seat or wider base | -| all_riders | All riders from any group | +| all_riders | All riders from any group | Other special group types may be added in future MDS releases as relevant agency and provider use cases are identified. When additional special group types or metrics are proposed, a thorough review of utility and relevance in program oversight, evaluation, and policy development should be done by OMF Working Groups, as well as any privacy implications by the OMF Privacy Committee. [Top][toc] -[agency]: /agency/README.md -[accessibility-options]: /modes/README.md#accessibility-options -[decimal-degrees]: https://en.wikipedia.org/wiki/Decimal_degrees [costs-and-currencies]: /general-information.md#costs-and-currencies [event-times]: /general-information.md#event-times -[hdop]: https://en.wikipedia.org/wiki/Dilution_of_precision_(navigation) [gbfs-station-info]: https://github.com/NABSA/gbfs/blob/master/gbfs.md#station_informationjson [gbfs-station-status]: https://github.com/NABSA/gbfs/blob/master/gbfs.md#station_statusjson -[general-stops]: /general-information.md#stops -[geo]: #geographic-data [geography-driven-events]: /general-information.md#geography-driven-events [gps]: #gps-data [iso4217]: https://en.wikipedia.org/wiki/ISO_4217#Active_codes [modes]: /modes/README.md -[policy]: /policy/README.md [propulsion-types]: /general-information.md#propulsion-types -[provider]: /provider/README.md -[point-geo]: #geographic-telemetry-data [stop-based-geo]: #stop-based-geographic-data [stops]: #stops -[st-intersects]: https://postgis.net/docs/ST_Intersects.html [toc]: #table-of-contents [ts]: /general-information.md#timestamps [vehicle-states]: /modes#vehicle-states [vehicle-events]: /modes#event-types [vehicle-types]: /general-information.md#vehicle-types -[wgs84]: https://en.wikipedia.org/wiki/World_Geodetic_System diff --git a/general-information.md b/general-information.md index 6a71cfcf..7b433028 100644 --- a/general-information.md +++ b/general-information.md @@ -29,13 +29,13 @@ This document contains specifications that are shared between the various MDS [A Outlines shared authorization details and methods across all MDS APIs. -### Endpoint Requirements +### Endpoint Requirements All MDS Provider, Agency, and Metrics APIs require authentication, as outlined. If implementing MDS Policy, Geography, and/or Jurisdiction APIs and endpoints, an agency must make them unauthenticated and public. This allows transparency for the public to see how the city is regulating, holds the city accountable for their policy decisions, and reduces the technical burden on providers to use these endpoints. A side benefit is that this allows third parties to ingest this information into their applications and services for public benefit. -As of MDS 0.3.0, `gbfs.json` is required. The required GBFS endpoints should be made available publicly. See Provider [#realtime-data](https://github.com/openmobilityfoundation/mobility-data-specification/tree/main/provider#realtime-data) for more information about how to implement GBFS for dockless systems. +As of MDS 0.3.0, `gbfs.json` is required. The required GBFS endpoints should be made available publicly. See Provider [#realtime-data](https://github.com/openmobilityfoundation/mobility-data-specification/tree/main/provider#realtime-data) for more information about how to implement GBFS for dockless systems. ### Header @@ -95,23 +95,25 @@ If the currency field is null, USD cents is implied. Shared data structures including [vehicles](/data-types.md#vehicles), [vehicle events](/data-types.md#vehicle-state-events), [vehicle telemetry](/data-types.md#telemetry-data), and [trips](/data-types.md#trips) can be found in the [Data Types](/data-types.md) page. +Standard [JSON data type definitions](https://en.wikipedia.org/wiki/JSON#Data_types) apply when feeds are in JSON format. The spec may also have more specific formatting requests, like enumeration (an enumerated set of approved values), object (an unordered key-value mapping of integer, strings, and symbols), map (an ordered mapping of any data types), integer (whole number), float (number with up to 8 decimal places), double (number with up 16 decimal places), etc. + [Top][toc] ## Definitions Defining terminology and abbreviations used throughout MDS. -* **API** - Application Programming Interface - A function or set of functions that allow one software application to access or communicate with features of a different software application or service. -* **API Endpoint** - A point at which an API connects with a software application or service. -* **DOT** - Department of Transportation, usually a city-run agency. -* **Jurisdiction** - An agency’s area of legal authority to manage and regulate a mobility program in the real world. Note there is also an MDS API called [Jurisdiction](/jurisdiction), which is a way to digitally represent this. -* **PROW** - Public Right of Way - the physical infrastructure reserved for transportation purposes, examples include sidewalks, curbs, bike lanes, transit lanes and stations, traffic lanes and signals, and public parking. +- **API** - Application Programming Interface - A function or set of functions that allow one software application to access or communicate with features of a different software application or service. +- **API Endpoint** - A point at which an API connects with a software application or service. +- **DOT** - Department of Transportation, usually a city-run agency. +- **Jurisdiction** - An agency’s area of legal authority to manage and regulate a mobility program in the real world. Note there is also an MDS API called [Jurisdiction](/jurisdiction), which is a way to digitally represent this. +- **PROW** - Public Right of Way - the physical infrastructure reserved for transportation purposes, examples include sidewalks, curbs, bike lanes, transit lanes and stations, traffic lanes and signals, and public parking. [Top][toc] ## Devices -MDS defines the *device* as the unit that transmits GPS or GNSS signals for a particular vehicle. A given device must have a UUID (`device_id` below) that is unique within the Provider's fleet. +MDS defines the _device_ as the unit that transmits GPS or GNSS signals for a particular vehicle. A given device must have a UUID (`device_id` below) that is unique within the Provider's fleet. Additionally, `device_id` must remain constant for the device's lifetime of service, regardless of the vehicle components that house the device. @@ -139,9 +141,9 @@ For the purposes of this specification, the intersection of two geographic datat ## Geography-Driven Events -**[Beta feature](/general-information.md#beta-features):** *Yes (as of 1.1.0)*. [Leave feedback](https://github.com/openmobilityfoundation/mobility-data-specification/issues/670) +**[Beta feature](/general-information.md#beta-features):** _Yes (as of 1.1.0)_. [Leave feedback](https://github.com/openmobilityfoundation/mobility-data-specification/issues/670) -Geography-Driven Events (GDE) is an MDS feature for Agencies to perform complete Policy compliance monitoring without precise location data. Geography-Driven Events describe individual vehicles in realtime – not just aggregate data. However, rather than receiving the exact location of a vehicle, Agencies receive information about the vehicle's current geographic region. The regions used for Geography-Driven Events correspond to the Geographies in an Agency's current Policy. In this way, the data-shared using Geography-Driven Events is matched to an Agency's particular regulatory needs. +Geography-Driven Events (GDE) is an MDS feature for Agencies to perform complete Policy compliance monitoring without precise location data. Geography-Driven Events describe individual vehicles in realtime – not just aggregate data. However, rather than receiving the exact location of a vehicle, Agencies receive information about the vehicle's current geographic region. The regions used for Geography-Driven Events correspond to the Geographies in an Agency's current Policy. In this way, the data-shared using Geography-Driven Events is matched to an Agency's particular regulatory needs. See [this example](/policy/examples/requirements.md#geography-driven-events) for how to implement GDE using [Policy Requirements](/policy#requirement). @@ -149,15 +151,15 @@ Here's how it works in practice: 1. The Agency creates a geographic Policy Area for a local regulatory need - *Scooters traveling within downtown during peak hours incur a $0.20 fee.* + _Scooters traveling within downtown during peak hours incur a $0.20 fee._ 2. Providers notify the Agency in real-time about events in the Policy Area. - *At 5:21pm scooter X7123 entered downtown.* + _At 5:21pm scooter X7123 entered downtown._ 3. The Agency can refine their data needs over time by revising their published Policy Areas. - *Agency adds rule disallowing parking on waterfront path, begins receiving data on events within area.* + _Agency adds rule disallowing parking on waterfront path, begins receiving data on events within area._ Agencies that wish to use Geography-Driven Events do so by requiring a new `event_geographies` field in status events. When an Agency is using Geography-Driven Events, Providers must emit a new `changed_geographies` status event whenever a vehicle in a trip enters or leaves a Geography managed by a Policy. @@ -167,35 +169,36 @@ During the Beta period for this feature, location and telemetry data remain requ ## Responses -* **200:** OK: operation successful. -* **201:** Created: `POST` operations, new object(s) created -* **400:** Bad request. -* **401:** Unauthorized: Invalid, expired, or insufficient scope of token. -* **404:** Not Found: Object does not exist, returned on `GET` or `POST` operations if the object does not exist. -* **409:** Conflict: `POST` operations when an object already exists and an update is not possible. -* **500:** Internal server error: In this case, the answer may contain a `text/plain` body with an error message for troubleshooting. +- **200:** OK: operation successful. +- **201:** Created: `POST` operations, new object(s) created +- **400:** Bad request. +- **401:** Unauthorized: Invalid, expired, or insufficient scope of token. +- **404:** Not Found: Object does not exist, returned on `GET` or `POST` operations if the object does not exist. +- **406:** MDS version in Accept header is unsupported or invalid. +- **409:** Conflict: `POST` operations when an object already exists and an update is not possible. +- **500:** Internal server error: In this case, the answer should contain an `application/json` body with an [error message](#error-messages) for troubleshooting. ### Error Messages -```json +```jsonc { - "error": "...", - "error_description": "...", - "error_details": [ "...", "..." ] + "error": "...", + "error_description": "...", + "error_details": ["...", "..."] } ``` -| Field | Type | Field Description | -| ------------------- | -------- | ---------------------- | -| `error` | String | Error message string | +| Field | Type | Field Description | +| ------------------- | -------- | --------------------------------------------------- | +| `error` | String | Error message string | | `error_description` | String | Human readable error description (can be localized) | -| `error_details` | String[] | Array of error details | +| `error_details` | String[] | Array of error details | ### Bulk Responses For multi-record POST and PUT calls, e.g. sending Events using the Agency API, the bulk-response structure describes a list of failures is as follows: -```json +```jsonc { "success": "...", "total": "...", @@ -203,27 +206,27 @@ For multi-record POST and PUT calls, e.g. sending Events using the Agency API, t "item": { ... }, // copy of the item with the problem "error": "...", "error_description": "...", - "error_details": [ "...", "..." ] + "error_details": [ "...", "..." ] }, { // additional failure records } ] } ``` -| Field | Type | Field Description | -| ---------- | ------------------------------ | ------------------------------------------------------------------------------------------------------- | -| `success` | Integer | Number of successfully written trip records points | -| `total` | Integer | Total number of provided points | -| `failures` | [Trip](#trip-data)[] | Array of failed trip records (empty if all successful) | +| Field | Type | Field Description | +| ---------- | ------------------------------------- | --------------------------------------------------------------- | +| `success` | Integer | Number of successfully written records | +| `total` | Integer | Total number of provided records | +| `failures` | [Failure Details](#failure-details)[] | Array of details about failed records (empty if all successful) | ### Failure Details -| Field | Type | Field Description | -| ----- | ---- | ----------------- | -| `item` | Vehicle, Event, etc. | Invalid submitted item | -| `error` | Enum | Error code | -| `error_description` | String | Human readable error description (can be localized) | -| `error_details` | String[] | Array of fields with errors, if applicable | +| Field | Type | Field Description | +| ------------------- | -------------------- | --------------------------------------------------- | +| `item` | Vehicle, Event, etc. | Invalid submitted item | +| `error` | Enum | Error code | +| `error_description` | String | Human readable error description (can be localized) | +| `error_details` | String[] | Array of fields with errors, if applicable | [Top][toc] @@ -292,7 +295,7 @@ See new location within [individual modes](/modes#list-of-supported-modes) in [m MDS APIs must handle requests for specific versions of the specification from clients. -Versioning must be implemented through the use of a custom media-type, `application/vnd.mds+json`, combined with a required `version` parameter. The one exception is the `/reports` endpoint, which returns CSV files instead of JSON, and so uses `text/vnd.mds+csv` as its media-type. +Versioning must be implemented through the use of a custom media-type, `application/vnd.mds+json`, combined with a required `version` parameter. The one exception is the `/reports` endpoint, which returns CSV files instead of JSON, and so uses `text/vnd.mds+csv` as its media-type. The version parameter specifies the dot-separated combination of major and minor versions from a published version of the specification. For example, the media-type for version `1.0.1` would be specified as `application/vnd.mds+json;version=1.0`. Only major and minor versions are allowed and required in the media-type version string (not [patch](https://github.com/openmobilityfoundation/governance/blob/main/technical/ReleaseGuidelines.md#versioning) releases). @@ -304,31 +307,15 @@ Accept: application/vnd.mds+json;version=2.0 Since versioning was not available from the start, the following APIs provide a fallback version if the `Accept` header is not set as specified above: -* The `provider` API must respond as if version `0.2` was requested. -* The `agency` API must respond as if version `0.3` was requested. -* The `policy` API must respond as if version `0.4` was requested. +- The `provider` API must respond as if version `0.2` was requested. +- The `agency` API must respond as if version `0.3` was requested. +- The `policy` API must respond as if version `0.4` was requested. If an unsupported or invalid version is requested, the API must respond with a status of `406 Not Acceptable`. [Top][toc] -[agency]: /agency/README.md [decimal-degrees]: https://en.wikipedia.org/wiki/Decimal_degrees -[hdop]: https://en.wikipedia.org/wiki/Dilution_of_precision_(navigation) -[gbfs-station-info]: https://github.com/NABSA/gbfs/blob/master/gbfs.md#station_informationjson -[gbfs-station-status]: https://github.com/NABSA/gbfs/blob/master/gbfs.md#station_statusjson -[general-stops]: /general-information.md#stops -[geo]: #geographic-data -[geojson-feature]: https://tools.ietf.org/html/rfc7946#section-3.2 -[geojson-point]: https://tools.ietf.org/html/rfc7946#section-3.1.2 -[modes]: /modes/README.md -[policy]: /policy/README.md -[provider]: /provider/README.md -[point-geo]: #geographic-telemetry-data -[stop-based-geo]: #stop-based-geographic-data [st-intersects]: https://postgis.net/docs/ST_Intersects.html [toc]: #table-of-contents -[ts]: /general-information.md#timestamps -[vehicle-states]: /modes#vehicle-states -[vehicle-events]: /modes#event-types [wgs84]: https://en.wikipedia.org/wiki/World_Geodetic_System diff --git a/geography/README.md b/geography/README.md index c38dce5e..cab295b6 100644 --- a/geography/README.md +++ b/geography/README.md @@ -4,27 +4,27 @@ This specification contains a collection of RESTful APIs used to read Geographies (descriptions of geographical information, e.g. multi-polygons, currently represented via GeoJSON). -Geographical data has many applications in the context of mobility, such as the description of municipal boundaries, locations for pick-up and drop-off zones, and areas of temporary closure for special events or emergencies. This API is intended to support a variety of other APIs, including the Policy API. +Geographical data has many applications in the context of mobility, such as the description of municipal boundaries, locations for pick-up and drop-off zones, and areas of temporary closure for special events or emergencies. This API is intended to support a variety of other APIs, including the Policy API. -Geographical data will be stored as GeoJSON and read from either `geographies.json` or the `/geographies` endpoint, referenced by UUID. Geography data once published through this API shall be treated as immutable, to ensure that any rules or regulations referring to the boundaries cannot be retroactively changed. A Geography may be deprecated and replaced by updated version with a new UUID. +Geographical data will be stored as GeoJSON and read from either `geographies.json` or the `/geographies` endpoint, referenced by UUID. Geography data once published through this API shall be treated as immutable, to ensure that any rules or regulations referring to the boundaries cannot be retroactively changed. A Geography may be deprecated and replaced by updated version with a new UUID. ## Table of Contents -* [General Information](#general-information) - * [Authorization](#authorization) - * [Versioning](#versioning) -* [Distribution](#distribution) - * [Flat Files](#flat-files) - * [Response Format](#response-format) -* [Schema](#schema) - * [Geography Fields](#geography-fields) - * [Previous Geographies](#previous-geographies) - * [Geography Type](#geography-type) -* [File Format](#file-format) -* [Endpoints](#endpoints) - * [Geography](#geography) - * [Geographies](#geographies) -* [Examples](#examples) +- [General Information](#general-information) + - [Authorization](#authorization) + - [Versioning](#versioning) +- [Distribution](#distribution) + - [Flat Files](#flat-files) + - [Response Format](#response-format) +- [Schema](#schema) + - [Geography Fields](#geography-fields) + - [Previous Geographies](#previous-geographies) + - [Geography Type](#geography-type) +- [File Format](#file-format) +- [Endpoints](#endpoints) + - [Geography](#geography) + - [Geographies](#geographies) +- [Examples](#examples) ## General Information @@ -48,11 +48,11 @@ Versioning must be implemented as specified in the [Versioning section][versioni ## Distribution -Geographies shall be published by regulatory agencies or their authorized delegates as JSON objects. These JSON objects shall be served by either [flat files](#flat-files) or via [REST API endpoints](#rest-endpoints). In either case, geography data shall follow the [schema](#schema) outlined below. +Geographies shall be published by regulatory agencies or their authorized delegates as JSON objects. These JSON objects shall be served by either [flat files](#flat-files) or via [REST API endpoints](#endpoints). In either case, geography data shall follow the [schema](#schema) outlined below. Published geographies, should be treated as immutable data. Obsoleting or otherwise changing a geography is accomplished by publishing a new geography with a field named `prev_geographies`, a list of UUID references to the geography or policies geographies by the new geography. -Geographical data shall be represented as GeoJSON `Feature` objects. Typically no part of the geographical data should be outside the [municipality boundary][muni-boundary] unless an agency has the authority to regulate there. +Geographical data shall be represented as GeoJSON `FeatureCollection` objects. Typically no part of the geographical data should be outside the [municipality boundary][muni-boundary] unless an agency has the authority to regulate there. Geographies should be re-fetched at an agreed upon interval between providers and agencies, or when either entity requests it. @@ -62,13 +62,13 @@ Geographies should be re-fetched at an agreed upon interval between providers an To use a flat file, geographies shall be represented in one (1) file equivalent to the /geographies endpoint: -* `geographies.json` in Geography API +- `geographies.json` in Geography API -The files shall be structured like the output of the [REST endpoints](#rest-endpoints) above. +The files shall be structured like the output of the [REST endpoints](#endpoints) above. The publishing Agency should establish and communicate to providers how frequently these files should be polled. -The `updated` field in the payload wrapper should be set to the time of publishing a revision, so that it is simple to identify a changed file. +The `last_updated` field in the payload wrapper should be set to the time of publishing a revision, so that it is simple to identify a changed file. [Top][toc] @@ -80,7 +80,7 @@ See the [Responses][responses] and [Error Messages][error-messages] sections. ## Schema -See the [Endpoints](#endpoints) below for links to their specific JSON Schema documents. +See the [Endpoints](#endpoints) below for links to specific data objects, and the [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for full details and interactive documentation. [Top][toc] @@ -102,15 +102,15 @@ See the [Endpoints](#endpoints) below for links to their specific JSON Schema do ### Previous Geographies -Obsoleting or otherwise changing a geography is accomplished by publishing a new geography with the `prev_geographies` field, which is a list of UUID references to the geography or geographies superseded by the new geography. The previous geographies are also published in the `/geographies` endpoint. Using it allows agencies to look back historically at previously published geographies, for analysis, historic reference, or an auditable change trail. +Obsoleting or otherwise changing a geography is accomplished by publishing a new geography with the `prev_geographies` field, which is a list of UUID references to the geography or geographies superseded by the new geography. The previous geographies are also published in the `/geographies` endpoint. Using it allows agencies to look back historically at previously published geographies, for analysis, historic reference, or an auditable change trail. -This field is optional can be omitted by the publishing Agency. +This field is optional can be omitted by the publishing Agency. [Top][toc] ### Geography Type -Type of geography. These specific types are recommendations based on ones commonly defined by agencies. Others may be created by the Agency as needed, or the optional `geography_type` field may be omitted. +Type of geography. These specific types are recommendations based on ones commonly defined by agencies. Others may be created by the Agency as needed, or the optional `geography_type` field may be omitted. `geography_type` does not imply policy or required actions by providers, but instead is for organizational and discovery purposes within the standalone Geography API. Geographies need to be referenced from other areas of MDS to be meaningfully applied. @@ -138,44 +138,54 @@ Type of geography. These specific types are recommendations based on ones common ## File format -Note: to use flat files rather than REST endpoints, Geography objects should be stored in `geographies.json`. The `geographies.json` file will look like the output of `GET /geographies`. +Note: to use flat files rather than REST endpoints, Geography objects should be stored in `geographies.json`. The `geographies.json` file will look like the output of `GET /geographies`. Example `geographies.json` ```jsonc { - "version": "1.2.0", - "updated": "1570035222868", - "geographies": [ - { - // Geography 1 - }, - { - // Geography 2 - } - ] + "version": "2.0.0", + "last_updated": "1682984274000", + "geographies": [ + { + // Geography 1 + }, + { + // Geography 2 + } + ] } ``` +#### Responses + +_Possible HTTP Status Codes_: +200, +404, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. + [Top][toc] ## Endpoints Responses must set the `Content-Type` header, as specified in the [Provider versioning](../provider/README.md#versioning) section. They must also specify the API version in the JSON-formatted response body, under the `version` key. -The Geography Author API consists of the following endpoints: +The Geography API consists of the following endpoints: ### Geography -**Endpoint**: `/geographies/{geography_id}` +**Endpoint**: `/geographies/{geography_id}` **Method**: `GET` -**Schema:** [`geography` schema](./geography.json) +**Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. -#### Query Parameters +#### Path Parameters -| Name | Type | Required/Optional | Description | -| ------------- | ---- | --- | --------------------------------------------------- | -| `geography_id` | UUID | Required | Unique identifier for a single specific Geography | +| Path Parameter | Type | Required/Optional | Description | +| -------------- | ---- | ----------------- | ------------------------------------------------- | +| `geography_id` | UUID | Required | Unique identifier for a single specific Geography | Returns: Details of a single Geography based on a UUID. @@ -183,7 +193,7 @@ Response body: ```js { - "version": '1.2.0', + "version": "2.0.0", "geography": { "geography_id": UUID, "geography_type": string, @@ -193,24 +203,28 @@ Response body: "effective_date": timestamp, "prev_geographies": UUID[], "geography_json": GeoJSON FeatureCollection - } + } } ``` -Response codes: +#### Responses -* 200 - success -* 401 - unauthorized -* 404 - no geography found -* 403 - user is attempting to read an unpublished geography, but only has the `geographies:read:published` scope. +_Possible HTTP Status Codes_: +200, +400 (with parameter), +404, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. [Top][toc] ### Geographies -**Endpoint**: `/geographies` +**Endpoint**: `/geographies` **Method**: `GET` -**Schema:** [`geographies` schema](./geographies.json) +**Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. Returns: All geography objects @@ -218,23 +232,28 @@ Response body: ```jsonc { - "version": "1.2.0", - "updated": "1570035222868", - "geographies": [ - { - // Geography 1 - }, - { - // Geography 2 - } - ] + "version": "2.0.0", + "last_updated": "1682984274000", + "geographies": [ + { + // Geography 1 + }, + { + // Geography 2 + } + ] } ``` -Response codes: +#### Responses + +_Possible HTTP Status Codes_: +200, +404, +406, +500 -* 200 - success -* 401 - unauthorized +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. [Top][toc] @@ -244,8 +263,10 @@ See the [Geography Examples](examples/README.md) for ways these can be implement [Top][toc] +[bulk-responses]: /general-information.md#bulk-responses [error-messages]: /general-information.md#error-messages [responses]: /general-information.md#responses +[schema]: /schema/ [ts]: /general-information.md#timestamps [versioning]: /general-information.md#versioning [muni-boundary]: ../provider/README.md#municipality-boundary diff --git a/geography/geographies.json b/geography/geographies.json deleted file mode 100644 index d1ebbc76..00000000 --- a/geography/geographies.json +++ /dev/null @@ -1,163 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/geography/geographies.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Geographies Schema", - "type": "object", - "definitions": { - "geography": { - "$id": "#/definitions/geography", - "type": "object", - "title": "The geography object schema", - "additionalProperties": false, - "required": [ - "name", - "geography_id", - "geography_json", - "published_date" - ], - "properties": { - "name": { - "$id": "#/definitions/geography/properties/name", - "$ref": "#/definitions/string", - "description": "Name of geography" - }, - "description": { - "$id": "#/definitions/geography/properties/description", - "$ref": "#/definitions/string", - "description": "Description of geography" - }, - "geography_type": { - "$id": "#/definitions/geography/properties/geography_type", - "type": "string", - "description": "The type of geography" - }, - "geography_id": { - "$id": "#/definitions/geography/properties/geography_id", - "$ref": "#/definitions/uuid", - "description": "Unique ID of geography" - }, - "geography_json": { - "$id": "#/definitions/geography/properties/geography_json", - "$ref": "https://geojson.org/schema/FeatureCollection.json", - "description": "The GeoJSON FeatureCollection that defines the geographical coordinates" - }, - "effective_date": { - "$id": "#/definitions/geography/properties/effective_date", - "$ref": "#/definitions/null_timestamp", - "description": "The date at which a Geography is considered 'live'. Must be at or after published_date." - }, - "published_date": { - "$id": "#/definitions/geography/properties/published_date", - "$ref": "#/definitions/timestamp", - "description": "Timestamp at which the geography was published i.e. made immutable" - }, - "retire_date": { - "$id": "#/definitions/geography/properties/end_date", - "$ref": "#/definitions/null_timestamp", - "description": "Time that the geography is slated to retire. Once the retire date is passed, new policies can no longer reference it and old policies referencing it should be updated. Retired geographies should continue to be returned in the geographies list. Must be after effective_date." - }, - "prev_geographies": { - "$id": "#/definitions/geography/properties/prev_geographies", - "$ref": "#/definitions/null_uuid_array", - "description": "Unique IDs of prior geographies replaced by this one", - "uniqueItems": true - } - } - }, - "string": { - "$id": "#/definitions/string", - "type": "string", - "description": "A length-limited string type", - "maxLength": 255, - "default": "", - "examples": [ - "ABC123" - ], - "pattern": "^(.*)$" - }, - "timestamp": { - "$id": "#/definitions/timestamp", - "type": "number", - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - }, - "version": { - "$id": "#/definitions/version", - "type": "string", - "description": "The version of MDS this data represents", - "examples": [ - "1.2.0" - ], - "pattern": "^1\\.2\\.[0-9]+$" - }, - "uuid_array": { - "$id": "#/definitions/uuid_array", - "type": "array", - "description": "Array of UUID", - "items": { - "$id": "#/definitions/uuid_array/items", - "$ref": "#/definitions/uuid" - } - }, - "null_timestamp": { - "$id": "#/definitions/null_timestamp", - "type": [ - "number", - "null" - ], - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "null_uuid_array": { - "$id": "#/definitions/null_uuid_array", - "type": [ - "array", - "null" - ], - "description": "Array of UUID", - "items": { - "$id": "#/definitions/uuid_array/items", - "$ref": "#/definitions/uuid" - } - } - }, - "required": [ - "geographies", - "updated", - "version" - ], - "properties": { - "geographies": { - "$id": "#/properties/geographies", - "type": "array", - "title": "The array of policy objects in this payload", - "items": { - "$id": "#/properties/geographies/items", - "$ref": "#/definitions/geography" - } - }, - "updated": { - "$id": "#/properties/updated", - "$ref": "#/definitions/timestamp", - "description": "The timestamp when geographies was last updated" - }, - "version": { - "$id": "#/properties/version", - "$ref": "#/definitions/version", - "description": "The version of MDS that the geographies represents" - } - }, - "additionalProperties": false -} \ No newline at end of file diff --git a/geography/geography.json b/geography/geography.json deleted file mode 100644 index 661263f8..00000000 --- a/geography/geography.json +++ /dev/null @@ -1,154 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/geography/geography.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Geography Schema", - "type": "object", - "definitions": { - "geography": { - "$id": "#/definitions/geography", - "type": "object", - "title": "The geography object schema", - "additionalProperties": false, - "required": [ - "name", - "geography_id", - "geography_json", - "published_date" - ], - "properties": { - "name": { - "$id": "#/definitions/geography/properties/name", - "$ref": "#/definitions/string", - "description": "Name of geography" - }, - "description": { - "$id": "#/definitions/geography/properties/description", - "$ref": "#/definitions/string", - "description": "Description of geography" - }, - "geography_type": { - "$id": "#/definitions/geography/properties/geography_type", - "type": "string", - "description": "The type of geography" - }, - "geography_id": { - "$id": "#/definitions/geography/properties/geography_id", - "$ref": "#/definitions/uuid", - "description": "Unique ID of geography" - }, - "geography_json": { - "$id": "#/definitions/geography/properties/geography_json", - "$ref": "https://geojson.org/schema/FeatureCollection.json", - "description": "The GeoJSON FeatureCollection that defines the geographical coordinates" - }, - "effective_date": { - "$id": "#/definitions/geography/properties/effective_date", - "$ref": "#/definitions/null_timestamp", - "description": "The date at which a Geography is considered 'live'. Must be at or after published_date." - }, - "published_date": { - "$id": "#/definitions/geography/properties/published_date", - "$ref": "#/definitions/timestamp", - "description": "Timestamp at which the geography was published i.e. made immutable" - }, - "retire_date": { - "$id": "#/definitions/geography/properties/end_date", - "$ref": "#/definitions/null_timestamp", - "description": "Time that the geography is slated to retire. Once the retire date is passed, new policies can no longer reference it and old policies referencing it should be updated. Retired geographies should continue to be returned in the geographies list. Must be after effective_date." - }, - "prev_geographies": { - "$id": "#/definitions/geography/properties/prev_geographies", - "$ref": "#/definitions/null_uuid_array", - "description": "Unique IDs of prior geographies replaced by this one", - "uniqueItems": true - } - } - }, - "string": { - "$id": "#/definitions/string", - "type": "string", - "description": "A length-limited string type", - "maxLength": 255, - "default": "", - "examples": [ - "ABC123" - ], - "pattern": "^(.*)$" - }, - "timestamp": { - "$id": "#/definitions/timestamp", - "type": "number", - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - }, - "version": { - "$id": "#/definitions/version", - "type": "string", - "description": "The version of MDS this data represents", - "examples": [ - "1.2.0" - ], - "pattern": "^1\\.2\\.[0-9]+$" - }, - "uuid_array": { - "$id": "#/definitions/uuid_array", - "type": "array", - "description": "Array of UUID", - "items": { - "$id": "#/definitions/uuid_array/items", - "$ref": "#/definitions/uuid" - } - }, - "null_timestamp": { - "$id": "#/definitions/null_timestamp", - "type": [ - "number", - "null" - ], - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "null_uuid_array": { - "$id": "#/definitions/null_uuid_array", - "type": [ - "array", - "null" - ], - "description": "Array of UUID", - "items": { - "$id": "#/definitions/uuid_array/items", - "$ref": "#/definitions/uuid" - } - } - }, - "required": [ - "geography", - "version" - ], - "properties": { - "geography": { - "$id": "#/properties/geography", - "$ref": "#/definitions/geography", - "description": "The geography in this payload", - "additionalProperties": false - }, - "version": { - "$id": "#/properties/version", - "$ref": "#/definitions/version", - "description": "The version of MDS that the geography represents" - } - }, - "additionalProperties": false -} \ No newline at end of file diff --git a/jurisdiction/README.md b/jurisdiction/README.md index dccc741d..1f32b8a5 100644 --- a/jurisdiction/README.md +++ b/jurisdiction/README.md @@ -13,6 +13,8 @@ This specification details the purpose, use cases, and schema for Jurisdictions. - [Distribution](#distribution) - [Schema](#schema) - [REST Endpoints](#rest-endpoints) + - [Get Jurisdictions](#get-jurisdictions) + - [Get Jurisdiction](#get-jurisdiction) - [Flat Files](#flat-files) - [Examples](#examples) @@ -84,7 +86,9 @@ Jurisdictions can be served by agencies through the following REST API, or via [ ## Schema -A Jurisdiction optionally contains a reference to a Geography object. This reference may change over time, e.g. if two +See the [Endpoints](#endpoints) below for information on their specific schema, and the [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for full details and interactive documentation. + +A Jurisdiction optionally contains a reference to a Geography object. When a Jurisdiction is updated, the old version should remain in the back-end for archival purposes. @@ -97,7 +101,7 @@ An individual `Jurisdiction` object is defined by the following fields: | `agency_name` | String | Optional | Human-readable agency name for display purposes. | | `description` | String | Required | Description of Jurisdiction. | | `geography_id` | UUID | Optional | The unique ID of the geography covered by this Jurisdiction. | -| `mobility_modes` | String[] | Required | Use this field to specify an array of what mobility [modes][modes] a jurisdiction applies to. | +| `mode_ids` | String[] | Required | Use this field to specify an array of what mobility [modes][modes] a jurisdiction applies to. | | `timestamp` | timestamp | Required | Creation or update time of a Jurisdiction. | Formatted in JSON, a Jurisdiction object should look like this: @@ -108,7 +112,7 @@ Formatted in JSON, a Jurisdiction object should look like this: "agency_key": string, "agency_name": string, "geography_id": UUID, - "mobility_modes": [ + "mode_ids": [ string ], "timestamp": Timestamp @@ -126,41 +130,75 @@ Responses must set the `Content-Type` header, as specified in the [Provider vers Response bodies must be a `UTF-8` encoded JSON object. +[Top][toc] + ### HTTP Response Codes The response to a client request must include a valid HTTP status code defined in the [IANA HTTP Status Code Registry](https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml) +[Top][toc] -### GET /Jurisdictions +### Get Jurisdictions Gets all of an agency's Jurisdictions. Served by agencies. -Parameters: -| Name | Type | R/O | Description | +**Endpoint:** `/jurisdictions/` +**Method:** `GET` +**[Beta feature][beta]:** _Yes (as of 1.1.0)_. [Leave feedback](https://github.com/openmobilityfoundation/mobility-data-specification/issues/673) +**Schema:** [`jurisdiction` schema](#schema) +**`data` Payload:** `{ "jurisdiction": [] }`, an array of [jurisdiction](#schema) objects + +_Query Parameters:_ + +| Query Parameters | Type | R/O | Description | | ------------ | --------- | --- | ---------------------------------------------- | | `effective` | Timestamp | O | See the state of all the Jurisdictions (i.e. which ones are effective) at that point in time. If not supplied, the default is to show only Jurisdictions that are currently in effect. | -Response codes: +#### Responses + +_Possible HTTP Status Codes_: +200, +400 (with parameter), +404, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. + +[Top][toc] + +### GET Jurisdiction + +Gets a single Jurisdictions. Served by agencies. -- 200 - success -- 403 - unauthorized -- 500 - server error +**Endpoint:** `/jurisdictions/{jurisdiction_id}` +**Method:** `GET` +**[Beta feature][beta]:** _Yes (as of 1.1.0)_. [Leave feedback](https://github.com/openmobilityfoundation/mobility-data-specification/issues/673) +**Schema:** [`jurisdiction` schema](#schema) +**`data` Payload:** `{ "jurisdiction": [] }`, an array of [jurisdiction](#schema) objects -### GET /Jurisdictions/:jurisdiction_id +_Path Parameters:_ + +| Path Parameters | Type | R/O | Description | +| ------------ | --------- | --- | ---------------------------------------------- | +| `jurisdiction_id` | UUID | R | Single jurisdiction to return | -Gets a single Jurisdictions. Served by agencies +_Query Parameters:_ -Parameters: -| Name | Type | R/O | Description | +| Query Parameters | Type | R/O | Description | | ------------ | --------- | --- | ---------------------------------------------- | | `effective` | Timestamp | O | See the version of the Jurisdiction that was in effect at that point in time. | -Response codes: +#### Responses -- 200 - Success -- 403 - Unauthorized -- 404 - not found -- 500 - Server error +_Possible HTTP Status Codes_: +200, +400 (with parameter), +404, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. [Top][toc] @@ -175,7 +213,17 @@ The format and content of `jurisdictions.json` should resemble the responses fro The publishing Agency should establish and communicate to interested parties how frequently these files should be polled. -The `updated` field in the payload wrapper should be set to the time of publishing a revision, so that it is simple to identify a changed file. +The `last_updated` field in the payload wrapper should be set to the time of publishing a revision, so that it is simple to identify a changed file. + +### Responses + +_Possible HTTP Status Codes_: +200, +404, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. [Top][toc] @@ -187,5 +235,8 @@ See the [Geography Examples](/geography/examples/README.md) for an example `geog [Top][toc] +[bulk-responses]: /general-information.md#bulk-responses [modes]: /modes#list-of-supported-modes -[toc]: #table-of-contents \ No newline at end of file +[responses]: /general-information.md#responses +[schema]: /schema/ +[toc]: #table-of-contents diff --git a/metrics/README.md b/metrics/README.md index 6d9e6dd4..1ae39775 100644 --- a/metrics/README.md +++ b/metrics/README.md @@ -14,6 +14,7 @@ The Metrics API endpoints are intended to be implemented by regulatory agencies, - [Data Requirements](#data-requirements) - [Beta Feature](#beta-feature) - [Date and Time Format](#date-and-time-format) +- [Data Schema](#data-schema) - [Data Redaction](#data-redaction) - [Metrics Discovery API](#metrics-discovery-api) - [Metrics Query API](#metrics-query-api) @@ -98,6 +99,12 @@ All interval durations (duration) are [ISO 8601](https://en.wikipedia.org/wiki/I [Top][toc] +## Data Schema + +See the [Endpoints](#endpoints) below for information on their specific schema, and the [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for full details and interactive documentation. + +[Top][toc] + ## Data Redaction Some combinations of dimensions, filters, time, and geography may return a small count of trips, which could increase a privacy risk of re-identification. To correct for that, Metrics does not return data below a certain count of results. This data redaction is called k-anonymity, and the threshold is set at a k-value of 10. For more explanation of this methodology, see our [Data Redaction Guidance document](https://github.com/openmobilityfoundation/mobility-data-specification/wiki/MDS-Data-Redaction). @@ -153,9 +160,14 @@ None. } ``` -See the [Metrics Examples](examples) for ways these can be implemented. +### Responses -[Top][toc] +_Possible HTTP Status Codes_: +200, +404, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. ## Metrics Query API @@ -167,7 +179,7 @@ Supports querying one or more metrics with the following parameters. ### Parameters -| Name | Type | Required | Comments | +| Query Parameters | Type | Required | Comments | | --------------- | -------- | -------- | ------------------------------------------------------------------------------- | | `measures` | string[] | Yes | list of measures to return. [See metric names](core_metrics.md) | | `interval` | duration | Yes | [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Durations) duration for metrics intervals. | @@ -241,6 +253,16 @@ All named fields are required to be returned in response. Non-relevant values ca } ``` +### Responses + +_Possible HTTP Status Codes_: +200, +400 (with parameter), +404, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. + [Top][toc] ## Examples @@ -249,4 +271,7 @@ See the [Metrics Examples](examples) for ways these can be implemented. [Top][toc] +[bulk-responses]: /general-information.md#bulk-responses +[responses]: /general-information.md#responses [toc]: #table-of-contents +[schema]: /schema/ diff --git a/modes/README.md b/modes/README.md index dff5c164..26187fc7 100644 --- a/modes/README.md +++ b/modes/README.md @@ -14,9 +14,14 @@ All MDS APIs should be mode-agnostic. ## Modes -The `mode` value is used to specify the applicable mobility category in MDS Policy, MDS Jurisdictions, and many other parts of MDS. +The `mode` value is used to specify the applicable mobility category in MDS Policy, Provider/Agency, and many other parts of MDS. -A `mode` is defined as: A distinct regulatory framework for a type of mobility service, as distinguished by a combination of a) the data needed by regulators, b) the operating rules under which the service functions, c) the legal authority under which it is regulated, and the d) design and operating model of the service itself. +A `mode` is defined as: A distinct regulatory framework for a type of mobility service or program, as distinguished by a combination of: + +1. the data needed by regulators, +1. the operating rules under which the service functions, +1. the legal authority under which it is regulated, and +1. the design and operating model of the service itself. There will be some gray areas and some differences from one jurisdiction to another (e.g. taxis and ridehail may be regulated under the same rules on one place, but different rules in another). MDS will not pre-define a complete taxonomy of modes, or identify every modal boundary upfront, but will instead add modes on an as-needed basis, maintaining as much consistency of naming as possible. @@ -59,7 +64,7 @@ The `journey_id` field allows multiple trip segments to be referentially linked ### Journey Attributes -The `journey_attributes` array allows additional mode-specific information about the nature of a journey to be described. See each [mode definition](#list-of-supported-modes) for details. +The `journey_attributes` object allows additional mode-specific information about the nature of a journey to be described. See each [mode definition](#list-of-supported-modes) for details. ### Trip Type @@ -67,25 +72,25 @@ The `trip_type` field allows the purpose of each trip segment to be described. S ### Trip Attributes -The `trip_attributes` array allows additional mode-specific information about the nature of a trip to be described. It can return a list of JSON-formatted key/value pairs which correspond to the allowed attributes and values for the operative mode. See each [mode definition](#list-of-supported-modes) for details. +The `trip_attributes` object allows additional mode-specific information about the nature of a trip to be described. It can return a list of JSON-formatted key/value pairs which correspond to the allowed attributes and values for the operative mode. See each [mode definition](#list-of-supported-modes) for details. _See more available trip attributes for any mode in the [trips object](/data-types.md#trips)._ ### Fare Attributes -The `fare_attributes` array allows additional mode-specific information about fare information associated with the trip. It can return a list of JSON-formatted key/value pairs which correspond to the allowed attributes and values for the operative mode. See each [mode definition](#list-of-supported-modes) for details. +The `fare_attributes` object allows additional mode-specific information about fare information associated with the trip. It can return a list of JSON-formatted key/value pairs which correspond to the allowed attributes and values for the operative mode. See each [mode definition](#list-of-supported-modes) for details. _See more available fare attributes for any mode in the [trips object](/data-types.md#trips)._ ### Vehicle Attributes -The `vehicle_attributes` array returns a list of JSON-formatted key/value pairs which correspond to the allowed attributes and values for the operative mode. For each mode, the allowed attributes and corresponding values are defined in the [mode definition](#list-of-supported-modes). +The `vehicle_attributes` object returns a list of JSON-formatted key/value pairs which correspond to the allowed attributes and values for the operative mode. For each mode, the allowed attributes and corresponding values are defined in the [mode definition](#list-of-supported-modes). _See more available vehicle attributes for any mode in the [vehicles object](/data-types.md#vehicles)._ -### Accessibility Options +### Accessibility Attributes -The `accessibility_options` array returns a list of JSON-formatted key/value pairs which correspond to the allowed accessibility attributes and values for the operative mode. For each mode, the allowed attributes and corresponding values are defined in the [mode definition](#list-of-supported-modes). +The `accessibility_attributes` object returns a list of JSON-formatted key/value pairs which correspond to the allowed accessibility attributes and values for the operative mode. For each mode, the allowed attributes and corresponding values are defined in the [mode definition](#list-of-supported-modes). [Top][toc] diff --git a/modes/car-share-state-machine-diagram.svg b/modes/car-share-state-machine-diagram.svg index 323c0109..365977f5 100644 --- a/modes/car-share-state-machine-diagram.svg +++ b/modes/car-share-state-machine-diagram.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/modes/car-share.md b/modes/car-share.md index 84f4289a..fb9e4b5a 100644 --- a/modes/car-share.md +++ b/modes/car-share.md @@ -19,7 +19,7 @@ See the [modes overview](/modes) for how the mode specific information below app - [Fare Attributes](#fare-attributes) - [Vehicle Properties](#vehicle-properties) - [Vehicle Attributes](#vehicle-attributes) - - [Accessibility Options](#accessibility-options) + - [Accessibility Attributes](#accessibility-attributes) - [State Machine](#state-machine) - [Vehicle States](#vehicle-states) - [Event Types](#event-types) @@ -52,7 +52,7 @@ The `journey_id` field shall have a consistent value in overlapping trips for a ### Journey Attributes -The `journey_attributes` array **may** have the following key value pairs: +The `journey_attributes` object **may** have the following key value pairs: - `reservation_id` (UUID, optional): unique identifier for an entire car share reservation, tied across multiple journeys and therefore trips. @@ -60,7 +60,7 @@ The `journey_attributes` array **may** have the following key value pairs: ### Trip ID Requirements -Events require a valid `trip_id` in events where `event_types` contains `reservation_start`, `reservation_stop`, `trip_start`, `trip_pause`, `trip_resume`, `trip_end`,`trip_cancel`, `customer_cancellation`, `provider_cancellation`, or `driver_cancellation`. +Events require a valid `trip_id` in events where `event_types` contains `reservation_start`, `reservation_stop`, `trip_start`, `trip_resume`, `trip_end`,`trip_cancel`, `customer_cancellation`, `provider_cancellation`, or `driver_cancellation`. Additionally, `trip_id` is required if `event_types` contains a `trip_enter_jurisdiction` or `trip_leave_jurisdiction` event pertaining to a trip. @@ -78,7 +78,7 @@ The `trip_type` field **must** have one of the following enumerated values: ### Trip Attributes -The `trip_attributes` array **may** have the following key value pairs: +The `trip_attributes` object **may** have the following key value pairs: - `reservation_type` (enumerated, required): how was the vehicle reserved, one of `phone_dispatch`, `phone`, `text`, `app` - `app_name` (text, optional): name of the app used to reserve the vehicle which could be provider's app or 3rd party app @@ -89,9 +89,9 @@ The `trip_attributes` array **may** have the following key value pairs: ### Fare Attributes -The `fare_attributes` array **may** have the following key value pairs: +The `fare_attributes` object **may** have the following key value pairs: -- `payment_type` (enumerated, required): `cash`, `credit_card`, `mobile`, `voucher`, `no payment`, `test` +- `payment_type` (enumerated, required): `account_number`, `cash`, `credit_card`, `mobile_app`, `no payment`, `phone`, `voucher`, `test` - `fare_type` (enumerated, required): `meter_fare`, `upfront_pricing`, `flat_rate`. Indicator of which rate was charged. - `tolls` (currency, optional) - Sum of any and all tolls charged for the trip, such as bridge tolls - `base_rate` (currency, optional) - Minimum fare to be charged as soon as the trip starts. @@ -110,7 +110,7 @@ _See more available vehicle attributes and accessibility options for any mode us ### Vehicle Attributes -The `vehicle_attributes` array **may** have the following key value pairs: +The `vehicle_attributes` object **may** have the following key value pairs: - `year` (integer, required) - `make` (string, required) @@ -140,13 +140,13 @@ Note many of these attributes come from fields in [GBFS vehicle_types](https://g [Top][toc] -### Accessibility Options +### Accessibility Attributes -This `accessibility_options` enum represents the accessibility options available on a given vehicle, or the accessibility options utilized for a given trip. +This `accessibility_attributes` enum represents the accessibility attributes available on a given vehicle, or the accessibility attributes utilized for a given trip. -| `accessibility_options` | Description | -|-------------------------|---------------------------------------| -| `wheelchair_accessible` | This vehicle is wheelchair accessible | +| `accessibility_attributes` | Description | +|----------------------------|---------------------------------------| +| `wheelchair_accessible` | This vehicle is wheelchair accessible | [Top][toc] @@ -177,13 +177,13 @@ Valid car share vehicle event types are - `charging_end` - `comms_lost` - `comms_restored` +- `customer_cancellation` - `driver_cancellation` - `fueling_start` - `fueling_end` - `maintenance` - `maintenance_pick_up` - `maintenance_end` -- `passenger_cancellation` - `provider_cancellation` - `remote_start` - `remote_end` @@ -237,13 +237,13 @@ This is the list of `vehicle_state` and `event_type` pairings that constitute th | `removed` | `non_operational` | N/A | `maintenance_end` | The vehicle maintenance work has ended | | `removed` | `non_operational` | N/A | `recommissioned` | The vehicle has been re-added to the Provider's fleet after being previously `decommissioned` | | `reserved` | `available` | N/A | `driver_cancellation` | The driver has canceled the reservation | -| `reserved` | `available` | N/A | `passenger_cancellation` | The passenger has canceled the reservation | +| `reserved` | `available` | N/A | `customer_cancellation` | The customer has canceled the reservation | | `reserved` | `available` | N/A | `provider_cancellation` | The provider has canceled the reservation | | `reserved` | `elsewhere` | N/A | `trip_leave_jurisdiction` | The vehicle has left the jurisdiction while in a reservation | | `reserved` | `non_contactable` | N/A | `comms_lost` | The vehicle went out of comms while being reserved by a passenger | | `reserved` | `stopped` | `stopped` | `reservation_stop` | The vehicle has stopped to pick up the passenger | | `stopped` | `available` | N/A | `driver_cancellation` | The driver has canceled the trip while either waiting for the passenger, or dropping them off | -| `stopped` | `available` | N/A | `passenger_cancellation` | The passenger has canceled the trip while the vehicle is waiting to pick them up, or they are being dropped off | +| `stopped` | `available` | N/A | `customer_cancellation` | The customer has canceled the trip while the vehicle is waiting to pick them up, or they are being dropped off | | `stopped` | `available` | N/A | `provider_cancellation` | The provider has canceled the trip while the vehicle is waiting for a passenger, or dropping them off | | `stopped` | `available` | N/A | `trip_end` | The trip has been successfully completed | | `stopped` | `non_contactable` | N/A | `comms_lost` | The vehicle has went out of comms while stopped | diff --git a/modes/delivery-robots.md b/modes/delivery-robots.md index bc0f91a0..b7908445 100644 --- a/modes/delivery-robots.md +++ b/modes/delivery-robots.md @@ -23,7 +23,7 @@ Autonomous and remotely piloted delivery robots do not require a driver, whereas - [Fare Attributes](#fare-attributes) - [Vehicle Properties](#vehicle-properties) - [Vehicle Attributes](#vehicle-attributes) - - [Accessibility Options](#accessibility-options) + - [Accessibility Attributes](#accessibility-attributes) - [State Machine](#state-machine) - [Vehicle States](#vehicle-states) - [Event Types](#event-types) @@ -55,7 +55,7 @@ The `journey_id` field shall have a consistent value in overlapping trips. Journ ### Journey Attributes -The `journey_attributes` array is not used in this mode. +The `journey_attributes` object is not used in this mode. [Top][toc] @@ -84,12 +84,12 @@ The `trip_type` field **must** have one of the following enumerated values: ### Trip Attributes -The `trip_attributes` array **may** have the following key value pairs: +The `trip_attributes` object **may** have the following key value pairs: -- `driver_type` (enum, required): type of driver operating the device: `human`, `semi-autonomous`, `autonomous` +- `driver_type` (enum, required): type of driver operating the device: `human`, `semi_autonomous`, `autonomous` - `driver_id` (UUID, optional): consistent unique identifier of the primary driver. Could be based on software version or an internal human driver id. - `app_name` (text, optional): name of the app used to reserve the trip which could be provider's app or 3rd party app -- `request_time` (timestamp, optional): when the customer requested the trip +- `requested_time` ([Timestamp][ts], optional): when the customer requested the trip - `has_payload` (boolean, optional): is there any payload for any delivery included in the device at trip start. 1 = loaded, 0 = empty - `range` (integer, optional): estimated range in meters based on energy levels in device at trip start - `identification_required` (boolean, optional): does the cargo require providing customer identification before trip start or upon delivery? @@ -98,20 +98,20 @@ The `trip_attributes` array **may** have the following key value pairs: ### Fare Attributes -The `fare_attributes` array **may** have the following key value pairs: +The `fare_attributes` object **may** have the following key value pairs: -- `payment_type` (enumerated, optional): `cash`, `mobile`, `voucher`, `paratransit`, `no payment`, `test` +- `payment_type` (enumerated, optional): `account_number`, `cash`, `credit_card`, `mobile_app`, `no payment`, `phone`, `voucher`, `test` - `price` (currency, optional): Total price of the order [Top][toc] ## Vehicle Properties -_See more available vehicle attributes and accessibility options for any mode used in the [vehicles object](/data-types.md#vehicles)._ +_See more available vehicle attributes and accessibility attributes for any mode used in the [vehicles object](/data-types.md#vehicles)._ ### Vehicle Attributes -The `vehicle_attributes` array **may** have the following key value pairs: +The `vehicle_attributes` object **may** have the following key value pairs: - `year` (integer, optional) - `make` (string, optional) @@ -130,9 +130,9 @@ The `vehicle_attributes` array **may** have the following key value pairs: [Top][toc] -### Accessibility Options +### Accessibility Attributes -The `accessibility_options` array **may** have the following key value pairs: +The `accessibility_attributes` object **may** have the following key value pairs: - `audio_cue` (boolean, optional): is the device equipped with audio cues upon delivery - `visual_cue` (boolean, optional): is the device equipped with visual cues upon delivery @@ -297,5 +297,6 @@ if t=[]: [home]: /README.md [modes]: /modes/README.md [toc]: #table-of-contents +[ts]: /general-information.md#timestamps [vehicle-states]: /modes/vehicle_states.md [vehicle-events]: /modes/event_types.md diff --git a/modes/event_types.md b/modes/event_types.md index 819404b2..54eb29df 100644 --- a/modes/event_types.md +++ b/modes/event_types.md @@ -4,54 +4,59 @@ This file defines all possible `event_type`s that can be used in state machines As with all MDS definitions, they should be described in a way that maximizes their relevance to multiple modes whenever possible. -| `event_type` | Description | -|---------------------- | ------------| -| `agency_drop_off` | Drop off by the agency | -| `agency_pick_up` | Pick up by the agency, e.g. impound | -| `battery_charged` | Battery charged (entering service) | -| `battery_low` | Battery low (exiting service) | -| `changed_geographies` | Geography change per [Geography Driven Events](/general-information.md#geography-driven-events) | -| `charging_start` | Battery start charging | -| `charging_end` | Battery end charging | -| `comms_lost` | Communications lost | -| `comms_restored` | Communications restored | -| `compliance_pick_up` | Pick up for compliance (rule violation) | -| `customer_cancellation` | Customer cancelled a trip | -| `decommissioned` | Decommissioned | -| `driver_cancellation` | Driver cancelled a trip | -| `fueling_start` | Fueling starts | -| `fueling_end` | Fueling ends | -| `located` | Location found (opposite of Missing) | -| `maintenance` | Start general maintenance in right of way | -| `maintenance_pick_up` | Start pick up for maintenance outside of right of way | -| `maintenance_end` | End of maintenance | -| `not_located` | Location unknown | -| `off_hours` | Off hours - end of service | -| `on_hours` | On hours - start of service | -| `order_drop_off` | Pick up of the order at business | -| `order_pick_up` | Delivery of the order at the customer location | -| `provider_cancellation` | Provider cancelled a trip | -| `provider_drop_off` | Drop off by the provider | -| `rebalance_pick_up` | Pick up for rebalancing | -| `remote_start` | Remotely start the engine | -| `remote_end` | Remotely stop the engine | -| `reservation_cancel` | Reservation cancelled before trip | -| `reservation_start` | Reservation started | -| `reservation_stop` | Reservation stopped temporarily | -| `system_resume` | Resume system operations, e.g. start of day | -| `system_suspend` | Suspend system operations, e.g. end of day | -| `trip_cancel` | Cancel trip | -| `trip_end` | End trip | -| `trip_enter_jurisdiction` | Trip enters a jurisdiction | -| `trip_leave_jurisdiction` | Trip leaves a jurisdiction | -| `trip_start` | Start trip | -| `trip_pause` | Pause trip temporarily but do not end trip | -| `trip_resume` | Resume trip | -| `unspecified` | Unspecified | +| `event_type` | Description | +| ------------------------- | ----------------------------------------------------------------------------------------------- | +| `agency_drop_off` | Drop off by the agency | +| `agency_pick_up` | Pick up by the agency, e.g. impound | +| `battery_charged` | Battery charged (entering service) | +| `battery_low` | Battery low (exiting service) | +| `changed_geographies` | Geography change per [Geography Driven Events](/general-information.md#geography-driven-events) | +| `charging_start` | Battery start charging | +| `charging_end` | Battery end charging | +| `comms_lost` | Communications lost | +| `comms_restored` | Communications restored | +| `compliance_pick_up` | Pick up for compliance (rule violation) | +| `customer_cancellation` | Customer cancelled a trip | +| `decommissioned` | Decommissioned | +| `driver_cancellation` | Driver cancelled a trip | +| `fueling_start` | Fueling starts | +| `fueling_end` | Fueling ends | +| `located` | Location found (opposite of Missing) | +| `maintenance` | Start general maintenance in right of way | +| `maintenance_pick_up` | Start pick up for maintenance outside of right of way | +| `maintenance_end` | End of maintenance | +| `not_located` | Location unknown | +| `off_hours` | Off hours - end of service | +| `on_hours` | On hours - start of service | +| `order_drop_off` | Pick up of the order at business | +| `order_pick_up` | Delivery of the order at the customer location | +| `passenger_cancellation` | Passenger cancelled a trip | +| `provider_cancellation` | Provider cancelled a trip | +| `provider_drop_off` | Drop off by the provider | +| `rebalance_pick_up` | Pick up for rebalancing | +| `recommission` | Recommissioned | +| `remote_start` | Remotely start the engine | +| `remote_end` | Remotely stop the engine | +| `reservation_cancel` | Reservation cancelled before trip | +| `reservation_start` | Reservation started | +| `reservation_stop` | Reservation stopped temporarily | +| `service_end` | End of service | +| `system_start` | Start of service | +| `system_resume` | Resume system operations, e.g. start of day | +| `system_suspend` | Suspend system operations, e.g. end of day | +| `trip_cancel` | Cancel trip | +| `trip_end` | End trip | +| `trip_enter_jurisdiction` | Trip enters a jurisdiction | +| `trip_leave_jurisdiction` | Trip leaves a jurisdiction | +| `trip_pause` | Pause trip temporarily but do not end trip | +| `trip_resume` | Resume trip | +| `trip_start` | Start trip | +| `trip_stop` | Stop trip | +| `unspecified` | Unspecified | ### Limitations on the Use of Certain Values -MDS is intended to communicate the provider's best available information to regulators. However there may be legitimate circumstances where providers do not have definitive or current information about devices on the ground. MDS incorporates some values to convey these situations. These vehicle state and event type values are to be used sparingly and temporarily, and are not meant for repeated or prolonged use. These values exist to create logical coherence within MDS about vehicles that are operating abnormally or are out of communication. When a more accurate value is known, the MDS API should be updated with the latest information. Cities may add language to their Service Level Agreements (SLAs) that minimize the use of these values by providers. +MDS is intended to communicate the provider's best available information to regulators. However there may be legitimate circumstances where providers do not have definitive or current information about devices on the ground. MDS incorporates some values to convey these situations. These vehicle state and event type values are to be used sparingly and temporarily, and are not meant for repeated or prolonged use. These values exist to create logical coherence within MDS about vehicles that are operating abnormally or are out of communication. When a more accurate value is known, the MDS API should be updated with the latest information. Cities may add language to their Service Level Agreements (SLAs) that minimize the use of these values by providers. #### Event Type: Unspecified diff --git a/modes/micromobility.md b/modes/micromobility.md index 052bab54..4f3d1ae9 100644 --- a/modes/micromobility.md +++ b/modes/micromobility.md @@ -19,7 +19,7 @@ See the [modes overview](/modes) for how the mode specific information below app - [Fare Attributes](#fare-attributes) - [Vehicle Properties](#vehicle-properties) - [Vehicle Attributes](#vehicle-attributes) - - [Accessibility Options](#accessibility-options) + - [Accessibility Attributes](#accessibility-attributes) - [State Machine](#state-machine) - [Vehicle States](#vehicle-states) - [Event Types](#event-types) @@ -46,7 +46,7 @@ The `journey_id` field is not used in this mode. Trips are point-to-point. ### Journey Attributes -The `journey_attributes` array is not used in this mode. +The `journey_attributes` object is not used in this mode. [Top][toc] @@ -68,23 +68,23 @@ The `trip_type` field **may** have one of the following values: ### Trip Attributes -The `trip_attributes` array is not used in this mode. +The `trip_attributes` object is not used in this mode. [Top][toc] ### Fare Attributes -The `fare_attributes` array is not used in this mode. +The `fare_attributes` object is not used in this mode. [Top][toc] ## Vehicle Properties -_See more available vehicle attributes and accessibility options for any mode used in the [vehicles object](/data-types.md#vehicles)._ +_See more available vehicle attributes and accessibility attributes for any mode used in the [vehicles object](/data-types.md#vehicles)._ ### Vehicle Attributes -The `vehicle_attributes` array **may** have the following key value pairs: +The `vehicle_attributes` object **may** have the following key value pairs: - `year` (integer, optional) - `make` (string, optional) @@ -92,13 +92,13 @@ The `vehicle_attributes` array **may** have the following key value pairs: [Top][toc] -### Accessibility Options +### Accessibility Attributes -This `accessibility_options` enum represents the accessibility options available on a given vehicle, or the accessibility options utilized for a given trip. +This `accessibility_attributes` enum represents the accessibility attributes available on a given vehicle, or the accessibility attributes utilized for a given trip. -| `accessibility_options` | Description | -|-------------------------|---------------------------------------| -| `adaptive` | This vehicle is accessible to people with various physical disabilities, and may include three wheels or be self balancing, a seat, or a basket or storage area | +| `accessibility_attributes` | Description | +|----------------------------|---------------------------------------| +| `adaptive` | This vehicle is accessible to people with various physical disabilities, and may include three wheels or be self balancing, a seat, or a basket or storage area | [Top][toc] diff --git a/modes/passenger-services.md b/modes/passenger-services.md index f4f85c93..a10aa394 100644 --- a/modes/passenger-services.md +++ b/modes/passenger-services.md @@ -23,7 +23,7 @@ Taxis typically require explicit tracking of maintenance while TNCs typically do - [Fare Attributes](#fare-attributes) - [Vehicle Properties](#vehicle-properties) - [Vehicle Attributes](#vehicle-attributes) - - [Accessibility Options](#accessibility-options) + - [Accessibility Attributes](#accessibility-attributes) - [State Machine](#state-machine) - [Vehicle States](#vehicle-states) - [Event Types](#event-types) @@ -55,7 +55,7 @@ The `journey_id` field shall have a consistent value in overlapping trips, e.g. ### Journey Attributes -The `journey_attributes` array **may** have the following key value pairs: +The `journey_attributes` object **may** have the following key value pairs: - `shift_id` (UUID, optional): unique identifier for an entire driver's work shift, tied across multiple journeys and therefore trips. @@ -82,12 +82,12 @@ The `trip_type` field **must** have one of the following enumerated values: ### Trip Attributes -The `trip_attributes` array **may** have the following key value pairs: +The `trip_attributes` object **may** have the following key value pairs: - `hail_type` (enumerated, required): `street_hail`, `phone_dispatch`, `phone`, `text`, `app` - `app_name` (text, optional): name of the app used to reserve the trip which could be provider's app or 3rd party app - `passenger_count` (integer, required): unique count of passengers transported during trip duration -- `requested_time` (timestamp, required): when the passenger requested the trip +- `requested_time` ([Timestamp][ts], required): when the passenger requested the trip - `requested_trip_start_location` ([GPS](gps), Conditionally Required): Location where the customer requested the trip to start (required if this is within jurisdictional boundaries) - `quoted_trip_start_time` ([Timestamp][ts], Required): Time the trip was estimated or scheduled to start, that was provided to the passenger - `dispatch_time` ([Timestamp][ts], Conditionally Required): Time the vehicle was dispatched to the customer (required if trip was dispatched) @@ -104,9 +104,9 @@ The `trip_attributes` array **may** have the following key value pairs: ### Fare Attributes -The `fare_attributes` array **may** have the following key value pairs: +The `fare_attributes` object **may** have the following key value pairs: -- `payment_type` (enumerated, required): `cash`, `credit_card`, `mobile`, `voucher`, `paratransit`, `no payment`, `test` +- `payment_type` (enumerated, required): `account_number`, `cash`, `credit_card`, `mobile_app`, `no_payment`, `paratransit`, `phone`, `voucher`, `test` - `fare_type` (enumerated, required): `meter_fare`, `upfront_pricing`, `flat_rate`. Indicator of which rate was charged. - `meter_fare_amount` (currency, conditionally required): if `upfront_pricing` is used as a `fare_type` include what the metered fare would have been if `meter_fare` would have been used. Allows cost comparison in evaluation of programs and pilots. - `tolls` (currency, optional) - Sum of any and all tolls charged for the trip, such as bridge tolls @@ -125,11 +125,11 @@ The `fare_attributes` array **may** have the following key value pairs: ## Vehicle Properties -_See more available vehicle attributes and accessibility options for any mode used in the [vehicles object](/data-types.md#vehicles)._ +_See more available vehicle attributes and accessibility attributes for any mode used in the [vehicles object](/data-types.md#vehicles)._ ### Vehicle Attributes -The `vehicle_attributes` array **may** have the following key value pairs: +The `vehicle_attributes` object **may** have the following key value pairs: - `year` (integer, optional) - `make` (string, optional) @@ -142,13 +142,13 @@ The `vehicle_attributes` array **may** have the following key value pairs: [Top][toc] -### Accessibility Options +### Accessibility Attributes -This `accessibility_options` enum represents the accessibility options available on a given vehicle, or the accessibility options utilized for a given trip. +This `accessibility_attributes` enum represents the accessibility attributes available on a given vehicle, or the accessibility attributes utilized for a given trip. -| `accessibility_options` | Description | -|-------------------------|---------------------------------------| -| `wheelchair_accessible` | This vehicle is wheelchair accessible | +| `accessibility_attributes` | Description | +|----------------------------|---------------------------------------| +| `wheelchair_accessible` | This vehicle is wheelchair accessible | [Top][toc] diff --git a/policy/README.md b/policy/README.md index 4b8bcb83..1c449030 100644 --- a/policy/README.md +++ b/policy/README.md @@ -10,6 +10,7 @@ This specification describes the digital relationship between _mobility as a ser - [General information](#general-information) - [Background](#background) + - [Policy Examples](#policy-examples) - [Authorization](#authorization) - [Update Frequency](#update-frequency) - [Updating or Ending Policies](#updating-or-ending-policies) @@ -18,14 +19,13 @@ This specification describes the digital relationship between _mobility as a ser - [REST Endpoints](#rest-endpoints) - [Responses and Error Messages](#responses-and-error-messages) - [Policies](#policies) - - [Query Parameters](#query-parameters) - [Geographies](#geographies) - [Requirements](#requirements) - [Flat Files](#flat-files) - [Example `policies.json`](#example-policiesjson) - [Example `geographies.json`](#example-geographiesjson) - [Schema](#schema) - - [JSON Schema](#json-schema) + - [Data Schema](#data-schema) - [Policy](#policy) - [Rules](#rules) - [Rule Types](#rule-types) @@ -38,6 +38,7 @@ This specification describes the digital relationship between _mobility as a ser - [Value URL](#value-url) - [Order of Operations](#order-of-operations) - [Requirement](#requirement) + - [Examples](#examples) - [Public Hosting](#public-hosting) - [Update Frequency](#requirement-update-frequency) - [Version Tracking](#version-tracking) @@ -67,13 +68,19 @@ The goal of the Policy API specification is to enable agencies to create, revise The machine-readable format allows Providers to obtain policies and compute compliance where it can be determined entirely by data obtained internally, and know what data is required from them and provided to them. -**See the [Policy Examples](./examples/README.md) for ways these can be implemented.** +[Top][toc] + +### Policy Examples + +See the [Policy Examples](./examples/README.md) for ways Policy can be implemented. [Top][toc] ### Authorization -This endpoint should be made public. Authorization is not required. +The Policy endpoints should be made public. Authorization is not required. + +[Top][toc] ### Update Frequency @@ -93,7 +100,7 @@ To revoke or end a policy, create a new policy with empty rules, and list the en ### Versioning -`policy` APIs must handle requests for specific versions of the specification from clients. +`Policy` APIs must handle requests for specific versions of the specification from clients. [Top][toc] @@ -107,8 +114,8 @@ Geographical data shall be represented as GeoJSON `Feature` objects. No part of Policies should be re-fetched whenever: -1) a policy expires (via its `end_date`), or -2) at an interval specified by the regulatory body, e.g. "daily at midnight". +1. a policy expires (via its `end_date`), or +2. at an interval specified by the regulatory body, e.g. "daily at midnight". Flat files have an optional `end_date` field that will apply to the file as a whole. @@ -118,10 +125,10 @@ Flat files have an optional `end_date` field that will apply to the file as a wh Among other use-cases, configuring a REST API allows an Agency to: -1) Dynamically adjust caps -2) Set Provider specific policies -3) Adjust other attributes in closer to real time -4) Enumerate when policies are set to change +1. Dynamically adjust caps +2. Set Provider specific policies +3. Adjust other attributes in closer to real time +4. Enumerate when policies are set to change Responses must set the `Content-Type` header, as specified in the [versioning][versioning] section. @@ -133,16 +140,23 @@ See the [Responses section][responses] for information on valid MDS response cod ### Policies -**Endpoint**: `/policies/{id}` +**Endpoint**: `/policies/{policy_id}` **Method**: `GET` -**Schema:** [`policy` schema][json-schema] +**Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. +**Authorization**: public **`data` Payload**: `{ "policies": [] }`, an array of objects with the structure [outlined below](#policy). -#### Query Parameters +_Path Parameters:_ + +| Path Parameter | Type | Required / Optional | Description | +| ------------ | --------- | --- | ---------------------------------------------- | +| `policy_id` | UUID | Optional | If provided, returns one policy object with the matching UUID; default is to return all policy objects. | + +_Query Parameters:_ -| Name | Type | Required / Optional | Description | +| Query Parameter | Type | Required / Optional | Description | | ------------ | --------- | --- | ---------------------------------------------- | -| `id` | UUID | Optional | If provided, returns one policy object with the matching UUID; default is to return all policy objects. | +| `policy_id` | UUID | Optional | If provided, returns one policy object with the matching UUID; default is to return all policy objects. | | `start_date` | [timestamp][ts] | Optional | Beginning date of the queried time range; the default value is the request time | | `end_date` | [timestamp][ts] | Optional | Ending date of the queried time range; the default value is null, which captures all policies that are effective in the future| @@ -152,6 +166,19 @@ Policies will be returned in order of effective date (see schema below), with pa `provider_id` is an implicit parameter and will be encoded in the authentication mechanism, or a complete list of policies should be produced. If the Agency decides that Provider-specific policy documents should not be shared with other Providers (e.g. punitive policy in response to violations), an Agency should filter policy objects before serving them via this endpoint. +### Responses + +_Possible HTTP Status Codes_: +200, +400 (with parameter), +404, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. + +[Top][toc] + ### Geographies **Deprecated:** see the [Geography API](/geography#transition-from-policy) for the current home of this endpoint. @@ -163,11 +190,22 @@ Policies will be returned in order of effective date (see schema below), with pa **Endpoint**: `/requirements/` **Method**: `GET` **[Beta feature](/general-information.md#beta-features)**: *No (as of 2.0.0)*. -**Schema:** TBD +**Authorization**: public +**Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. **`data` Payload**: `{ requirements: [] }`, JSON objects that follow the schema [outlined here](#requirement). See [Policy Requirements Examples](/policy/examples/requirements.md) for how this can be implemented. +#### Responses + +_Possible HTTP Status Codes_: +200, +404, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. + [Top][toc] ## Flat Files @@ -181,25 +219,35 @@ The files shall be structured like the output of the [REST endpoints](#rest-endp The publishing agency should establish and communicate to providers how frequently these files should be polled. -The `updated` field in the payload wrapper should be set to the time of publishing a revision, so that it is simple to identify a changed file. +The `last_updated` field in the payload wrapper should be set to the time of publishing a revision, so that it is simple to identify a changed file. + +### Responses + +_Possible HTTP Status Codes_: +200, +404, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. + +[Top][toc] ### Example `policies.json` ```jsonc { - "version": "0.4.0", - "updated": 1570035222868, - "end_date": 1570035222868, - "data": { - "policies": [ - { - // policy JSON 1 - }, - { - // policy JSON 2 - } - ] + "version": "2.0.0", + "last_updated": 1570035222868, + "end_date": 1570035222868, + "policies": [ + { + // policy JSON 1 + }, + { + // policy JSON 2 } + ] } ``` @@ -209,18 +257,16 @@ The optional `end_date` field applies to all policies represented in the file. ```jsonc { - "version": "0.4.0", - "updated": 1570035222868, - "data": { - "geographies": [ - { - // GeoJSON Feature 1 - }, - { - // GeoJSON Feature 2 - } - ] + "version": "2.0.0", + "last_updated": 1570035222868, + "geographies": [ + { + // GeoJSON Feature 1 + }, + { + // GeoJSON Feature 2 } + ] } ``` @@ -230,21 +276,19 @@ The optional `end_date` field applies to all policies represented in the file. All response fields must use `lower_case_with_underscores`. -Response bodies must be a `UTF-8` encoded JSON object and must minimally include the MDS `version`, a timestamp indicating the last time the data was `updated`, and a `data` payload: +Response bodies must be a `UTF-8` encoded JSON object and must minimally include the MDS `version`, a timestamp indicating the last time the data was `last_updated`, and a `data` payload: ```jsonc { - "version": "x.y.z", - "updated": 1570035222868, - "data": { - // endpoint/file specific payload - } + "version": "x.y.z", + "last_updated": 1570035222868, + // endpoint/file specific payload } ``` -### JSON Schema +### Data Schema -The JSON Schema file is available in this repository: [`policy.json`](./policy.json). +See the [Endpoints](#endpoints) below for information on their specific schema, and the [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for full details and interactive documentation. Before publishing a new Policy document, the document should be validated against the schema to ensure it has the correct format and fields. @@ -257,7 +301,7 @@ An individual `Policy` object is defined by the following fields: | Name | Type | Required / Optional | Description | | ---------------- | --------------- | ---------- | ----------------------------------------------------------------------------------- | | `name` | String | Required | Name of policy | -| `mode` | [Mode][modes] | Required | Mode this rule should apply, see MDS [mode list][modes] for options. Default `micromobility` for backwards compatibility (this default will likely be removed in a subsequent MDS release) | +| `mode_id` | [Mode][modes] | Required | Mode this rule should apply, see MDS [mode list][modes] for options. Default `micromobility` for backwards compatibility (this default will likely be removed in a subsequent MDS release) | | `policy_id` | UUID | Required | Unique ID of policy | | `provider_ids` | UUID[] | Optional | Providers for whom this policy is applicable; empty arrays and `null`/absent implies all Providers. See MDS [provider list](/providers.csv). | | `description` | String | Required | Description of policy | @@ -331,12 +375,14 @@ An individual `Rule` object is defined by the following fields: Rate-related properties can currently be specified on all rule types except `user`, i.e. any rule that can be measured. -**[Beta feature](/general-information.md#beta-features)**: *No (as of 2.0.0)*. [Leave feedback](https://github.com/openmobilityfoundation/mobility-data-specification/issues/674) +**[Beta feature](/general-information.md#beta-features)**: *No (as of 2.0.0)*. #### Rate Amounts The amount of a rate applied when this rule applies, if applicable (default zero). A positive integer rate amount represents a fee, while a negative integer represents a subsidy. Rate amounts are given in the `currency` defined in the [Policy](#policy). +[Top][toc] + #### Rate Recurrences Rate recurrences specify how a rate is applied – either once, or periodically according to a `time_unit` specified using [Rule Units](#rule-units). A `time_unit` refers to a unit of time as measured in local time for the jurisdiction – a day begins at midnight local time, an hour begins at the top of the hour, etc. @@ -363,6 +409,8 @@ The `rate_applies_when` field may take the following values: | `in_bounds` | Rate applies when an event or count is within the rule `minimum` and `maximum` | | `out_of_bounds` | Rate applies when an event or count is outside of the rule `minimum` and `maximum` | +[Top][toc] + ### Messages Some Policies as established by the Agency may benefit from rider communication. This optional field contains a map of languages to messages, to be shown to the user. @@ -416,22 +464,34 @@ A public agency's Policy program Requirements endpoint enumerates all of the par Requirements can also be used to define a scaled-down MDS implementation in situations where an agency has more limited regulatory goals, has legal limitations on the types of data they can collect, or wants to use a lightweight version of MDS for a pilot project or other experiment where aspects of a full MDS implementation would be irrelevant or unnecessary. +[Top][toc] + +#### Examples + See [Policy Requirements Examples](/policy/examples/requirements.md) for ideas on how this can be implemented. +[Top][toc] + #### Public Hosting This endpoint is not authenticated (ie. public), and allows the discovery of other public endpoints within Geography, Policy, and Jurisdiction. The agency can host this as a file or dynamic endpoint on their servers, on a third party server, or the OMF can host on behalf of an agency in the [agency program requirements repo](https://github.com/openmobilityfoundation/agency-program-requirements). See this [hosting guidance document](https://github.com/openmobilityfoundation/mobility-data-specification/wiki/Policy-Requirements-OMF-Hosting-Guidance) for more information. This requirements file can be [referenced directly](https://github.com/openmobilityfoundation/governance/blob/main/technical/OMF-MDS-Policy-Language-Guidance.md) in an agency's operating permit/policy document when discussing program data requirements, and [updated digitally as needed](#requirement-update-frequency). To be compliant with MDS you must obtain an `agency_id` and list your public URL in [agencies.csv](/agencies.csv), per our [guidance document](https://github.com/openmobilityfoundation/mobility-data-specification/wiki/Adding-an-MDS-Agency-ID). +[Top][toc] + #### Requirement Update Frequency The OMF recommends updating the Requirements feed no more than monthly, and you may specify your expected timeframe with the `max_update_interval` in the [metadata](#requirement-metadata) section so providers have some idea of how often to check the feed. More specifically the OMF recommends giving the following notice to providers: 1 month for optional field additions, 3 months for endpoint/API changes/additions, 3 months for new minor releases, and 4 months for major releases. You should also communicate these future changes ahead of time with the `start_date` field. Finally, the OMF recommends any changes need to be part of a discussion between agencies and affected providers. +[Top][toc] + #### Version Tracking If you are upgrading to a new MDS version, it is recommended to create a new requirements file at a new URL, since field names and available options may have changed. To make this more obvious, the MDS version number could be part of your URL, e.g. "https://mds.cityname.gov/requirements/1.2.0". When requirements are updated within the same MDS version, in the [metadata](#requirement-metadata) section, increment the `file_version` value by one and update the `last_updated` timestamp. Though not required, you may choose to use the `start_date` and `end_date` fields in the [programs](#requirement-programs) section to keep retired requirements accessible. We also recommend hosting your requirements file in a location that has a publicly-accessible version history, like GitHub or Bitbucket, or keeping previous versions accessible with a versioned URL, e.g. "https://mds.cityname.gov/requirements/1.2.0/v3". +[Top][toc] + #### Requirement Format An agency's program [Requirements](#requirements) endpoint contains a number of distinct parts, namely [metadata](#requirement-metadata), [program definitions](#requirement-programs), and [data specs](#requirement-data-specs) (with sub sections on relevant [required APIs](#requirement-apis)). @@ -577,7 +637,7 @@ For each combination of items in a program, you can specify the data specs, APIs { "data_spec_name": "[DATA SPEC NAME]", "version": "[VERSION NUMBER]", - "mode": "[MODE SHORTNAME]", + "mode_id": "[MODE SHORTNAME]", "required_apis": [ { // Required APIs array @@ -598,7 +658,7 @@ For each combination of items in a program, you can specify the data specs, APIs | -------------------- | ------ | -------- | ----------------------------------- | | `data_spec_name` | Enum | Required | Name of the data spec required. Supported values are: '[MDS](https://github.com/openmobilityfoundation/mobility-data-specification/tree/ms-requirements)', '[CDS](https://github.com/openmobilityfoundation/curb-data-specification)' '[GBFS](https://github.com/NABSA/gbfs/tree/v2.2)'. Others like GOFS, GTFS, TOMP-API, etc may also be referenced now by agencies and officially standardized here in the future -- leave your feedback on [this issue](https://github.com/openmobilityfoundation/mobility-data-specification/issues/682). | | `version` | Text | Required | Version number of the data spec required. E.g. '1.2.0' | -| `mode` | Text | Optional | The [mode list][modes] shortname for MDS. E.g. 'passenger-services' | +| `mode_id` | Text | Optional | The [mode list][modes] shortname for MDS. E.g. 'passenger-services' | | `required_apis` | Array | Conditionally Required | Name of the [Requirement APIs](#requirement-apis) that need to be served by providers. At least one API is required. APIs not listed will not be available to the agency. | | `available_apis` | Array | Conditionally Required | Name of the [Requirement APIs](#requirement-apis) that are being served by agencies. Not applicable to GBFS. APIs not listed will not be available to the provider. | @@ -668,6 +728,8 @@ You may also show which APIs, endpoints, and fields your agency is serving to pr | `endpoint_name` | Text | Required | Name of the required endpoint under the API. At least one endpoint is required. E.g. for MDS 'provider': 'trips' | | `use_cases` | Object with Array | Optional | The list of policy uses cases that this data standard's information covers for your program. Includes an `external_url` to a HTTP reference list or database (e.g. to the [OMF Use Case Database](https://airtable.com/shrPf4QvORkjZmHIs/tblzFfU6fxQm5Sdhm)), **and** an array of `ids` of each applicable use case (e.g. "OMF-MDS-31"). You may enumerate multiple external use case sources and ids. | +[Top][toc] + **Provider Endpoints** - Specific to the `required_apis` array | Name | Type | Required/Optional | Description | @@ -696,6 +758,7 @@ You may also show which APIs, endpoints, and fields your agency is serving to pr [accessibility-options]: /general-information.md#accessibility-options [beta]: /general-information.md#beta +[bulk-responses]: /general-information.md#bulk-responses [error-messages]: /general-information.md#error-messages [iana]: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml [json-schema]: #json-schema @@ -703,6 +766,7 @@ You may also show which APIs, endpoints, and fields your agency is serving to pr [muni-boundary]: /provider/README.md#municipality-boundary [propulsion-types]: /general-information.md#propulsion-types [responses]: /general-information.md#responses +[schema]: /schema/ [ts]: /general-information.md#timestamps [toc]: #table-of-contents [vehicle-events]: /modes#event-types diff --git a/policy/examples/README.md b/policy/examples/README.md index 45419194..64de23d6 100644 --- a/policy/examples/README.md +++ b/policy/examples/README.md @@ -20,12 +20,13 @@ This file presents a series of example [Policy documents](../README.md#policy) f ## Operating Area -The vehicle should stay within the areas of operation defined (Riding area). +The vehicle should stay within the areas of operation defined (riding area). ```json { "name": "Operating Area ", "policy_id": "dcc49f37-aafb-4306-b16c-49518d5a8038", + "mode_id": "micromobility", "provider_ids": null, "description": "E-scooter operation area of the city", "start_date": 1635750000000, diff --git a/policy/examples/requirements.md b/policy/examples/requirements.md index 7dedfb8f..23bf17b1 100644 --- a/policy/examples/requirements.md +++ b/policy/examples/requirements.md @@ -10,6 +10,7 @@ This file presents a series of example [Requirements](../README.md#requirement) - [Trips with No Routes, Vehicles IDs, or Dates](#trips-with-no-routes-vehicle-ids-or-dates) - [Provider and Other APIs](#provider-and-other-apis) - [Agency](#agency) +- [Use Cases](#use-cases) - [Geography Driven Events](#geography-driven-events) - [GBFS Only](#gbfs-only) @@ -135,6 +136,7 @@ Version 1.1.0 for one provider with scooters, and 1.0.0 for another provider for { "data_spec_name": "MDS", "version": "1.2.0", + "mode_id": "micromobility", "required_apis": [ { "api_name": "provider", @@ -595,6 +597,73 @@ Version 1.1.0 for 3 providers and serving Agency only linking to a defined MDS P [Top](#table-of-contents) +## Use Cases + +Version 2.0.0 for 2 providers requiring Provider `/vehicles` with external use cases for the program enumerated. + +```json +{ + "metadata": { + "mds_release": "2.0.0", + "file_version": "2", + "last_updated": "1611953923", + "max_update_interval": "P1M", + "agency_id": "46c9882d-1297-48fc-83e5-3067d4e9337f", + "agency_name": "Gemeente Amsterdam", + "agency_timezone": "Europe/Amsterdam", + "agency_language": "nl_NL", + "agency_currency": "EUR", + "agency_website_url": "https://www.cityname.gov/transportation/", + "url": "https://mds.cityname.gov/policy/requirements/2.0.0" + }, + "programs": [ + { + "description": "SMART MOBILITY Actieprogramma", + "program_website_url": "https://www.cityname.gov/transportation/shared-devices.html", + "program_document_url": "https://www.cityname.gov/mds_data_policy.pdf", + "provider_ids": [ + "70aa475d-1fcd-4504-b69c-2eeb2107f7be", + "2411d395-04f2-47c9-ab66-d09e9e3c3251" + ], + "start_date": 1611958740, + "end_date": 1611970539, + "required_data_specs": [ + { + "data_spec_name": "MDS", + "version": "2.0.0", + "required_apis": [ + { + "api_name": "provider", + "required_endpoints": [ + { + "endpoint_name": "vehicles" + } + ] + } + ] + }, + { + "data_spec_name": "GBFS", + "version": "2.2" + } + ], + "use_cases": [ + { + "external_url": "https://airtable.com/shr2cnPQvKjzONJpG", + "ids": ["OMF-MDS-4","OMF-MDS-12","OMF-MDS-34"] + }, + { + "external_url": "https://github.com/CDSM-WG/CDS-M/tree/main/use-cases", + "ids": ["reduced-speed-area","start-trips","end-trips","realtime-events"] + } + ] + } + ] +} +``` + +[Top](#table-of-contents) + ## Geography Driven Events Version 1.1.0 for 2 providers requiring Provider `/status_changes` with the minimum required for beta feature [Geography Driven Events](/general-information.md#geography-driven-events). diff --git a/policy/policy.json b/policy/policy.json deleted file mode 100644 index 8e173d5e..00000000 --- a/policy/policy.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/policy/policy.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Policy Schema", - "type": "object", - "definitions": { - "policy": { - "$id": "#/definitions/policy", - "type": "object", - "title": "The policy object schema", - "additionalProperties": false, - "required": [ - "name", - "policy_id", - "description", - "start_date", - "published_date", - "rules" - ], - "properties": { - "name": { - "$id": "#/definitions/policy/properties/name", - "$ref": "#/definitions/string", - "description": "Name of policy" - }, - "policy_id": { - "$id": "#/definitions/policy/properties/policy_id", - "$ref": "#/definitions/uuid", - "description": "Unique ID of policy" - }, - "provider_ids": { - "$id": "#/definitions/policy/properties/provider_ids", - "$ref": "#/definitions/null_uuid_array", - "description": "Providers for whom this policy is applicable; empty arrays and null/absent implies all Providers.", - "uniqueItems": true - }, - "description": { - "$id": "#/definitions/policy/properties/description", - "$ref": "#/definitions/string", - "description": "Description of policy" - }, - "currency": { - "$id": "#/definitions/policy/properties/currency", - "$ref": "#/definitions/currency" - }, - "start_date": { - "$id": "#/definitions/policy/properties/start_date", - "$ref": "#/definitions/timestamp", - "description": "Beginning date/time of policy enforcement" - }, - "end_date": { - "$id": "#/definitions/policy/properties/end_date", - "$ref": "#/definitions/null_timestamp", - "description": "End date/time of policy enforcement" - }, - "published_date": { - "$id": "#/definitions/policy/properties/published_date", - "$ref": "#/definitions/timestamp", - "description": "Timestamp at which the policy was published" - }, - "prev_policies": { - "$id": "#/definitions/policy/properties/prev_policies", - "$ref": "#/definitions/null_uuid_array", - "description": "Unique IDs of prior policies replaced by this one", - "uniqueItems": true - }, - "rules": { - "$id": "#/definitions/rules", - "type": "array", - "description": "Array of applicable Rule objects", - "items": { - "$id": "#/definitions/policy/properties/rules/items", - "$ref": "#/definitions/rule" - }, - "minItems": 1 - } - } - }, - "rule": { - "$id": "#/definitions/rule", - "type": "object", - "description": "An individual rule in a policy", - "additionalProperties": false, - "required": [ - "name", - "rule_id", - "rule_type", - "geographies", - "states" - ], - "properties": { - "name": { - "$id": "#/definitions/rule/properties/name", - "$ref": "#/definitions/string", - "description": "Name of rule" - }, - "rule_id": { - "$id": "#/definitions/rule/properties/rule_id", - "$ref": "#/definitions/uuid", - "description": "Unique ID of rule" - }, - "rule_type": { - "$id": "#/definitions/rule/properties/rule_type", - "type": "string", - "description": "The type of rule", - "enum": [ - "count", - "time", - "speed", - "user" - ] - }, - "geographies": { - "$id": "#/definitions/rule/properties/geographies", - "$ref": "#/definitions/uuid_array", - "description": "List of Geography UUIDs (non-overlapping) specifying the covered geography", - "minItems": 1, - "uniqueItems": true - }, - "states": { - "$id": "#/definitions/rule/properties/states", - "type": "object", - "description": "Vehicle state to which this rule applies. Optionally provide a list of specific vehicle events as a subset of a given state for the rule to apply to. An empty list or null/absent defaults to \"all\" for the state.", - "propertyNames": { - "$id": "#/definitions/rule/properties/states/propertyNames", - "$ref": "#/definitions/vehicle_state" - }, - "properties": {}, - "additionalProperties": { - "type": "array", - "uniqueItems": true, - "items": { - "$ref": "#/definitions/vehicle_event" - } - } - }, - "rule_units": { - "$id": "#/definitions/rule/properties/rule_units", - "type": "string", - "description": "Measured units of policy", - "enum": [ - "seconds", - "minutes", - "hours", - "days", - "mph", - "kph", - "devices", - "amount" - ] - }, - "vehicle_types": { - "$id": "#/definitions/rule/properties/vehicle_types", - "$ref": "#/definitions/null_vehicle_types", - "description": "Applicable vehicle types, default \"all\"" - }, - "propulsion_types": { - "$id": "#/definitions/rule/properties/propulsion_types", - "$ref": "#/definitions/null_propulsion_types", - "description": "Applicable vehicle propulsion types, default \"all\"" - }, - "minimum": { - "$id": "#/definitions/rule/properties/minimum", - "type": [ - "null", - "integer" - ], - "description": "Minimum value, if applicable (default 0)" - }, - "maximum": { - "$id": "#/definitions/rule/properties/maximum", - "type": [ - "null", - "integer" - ], - "description": "Maximum value, if applicable (default unlimited)" - }, - "inclusive_minimum": { - "$id": "#/definitions/rule/properties/inclusive_minimum", - "type": [ - "null", - "boolean" - ], - "description": "Whether the rule minimum is considered in-bounds (default true)" - }, - "inclusive_maximum": { - "$id": "#/definitions/rule/properties/inclusive_maximum", - "type": [ - "null", - "boolean" - ], - "description": "Whether the rule maximum is considered in-bounds (default true)" - }, - "rate_amount": { - "$id": "#/definitions/rule/properties/rate_amount", - "type": [ - "null", - "integer" - ], - "description": "The amount of a rate applied when this rule applies, if applicable (default zero). A positive integer rate amount represents a fee, while a negative integer represents a subsidy. Rate amounts are given in the currency defined in the Policy." - }, - "rate_recurrence": { - "$id": "#/definitions/rule/properties/rate_recurrence", - "type": [ - "string", - "null" - ], - "description": "Specify how a rate is applied \u00e2\u20ac\u201c either once, or periodically according to a time unit specified using rule_units", - "enum": [ - "once_on_match", - "once_on_unmatch", - "each_time_unit", - "per_complete_time_unit" - ] - }, - "rate_applies_when": { - "$id": "#/definitions/rule/properties/rate_applies_when", - "type": [ - "string", - "null" - ], - "description": "Specify when a rate is applicable to an event or count: when it's within rule bounds or when it is not", - "enum": [ - "in_bounds", - "out_of_bounds" - ] - }, - "start_time": { - "$id": "#/definitions/rule/properties/start_time", - "$ref": "#/definitions/null_iso_time", - "description": "Beginning time-of-day when the rule is in effect (default 00:00:00)" - }, - "end_time": { - "$id": "#/definitions/rule/properties/end_time", - "$ref": "#/definitions/null_iso_time", - "description": "Ending time-of-day when the rule is in effect (default 23:59:59)" - }, - "days": { - "$id": "#/definitions/rule/properties/days", - "$ref": "#/definitions/null_days", - "description": "Days when the rule is in effect (default all)" - }, - "messages": { - "$id": "#/definitions/rule/properties/messages", - "type": [ - "null", - "object" - ], - "description": "Message to rider user, if desired, in various languages, keyed by BCP 47 language tag", - "propertyNames": { - "pattern": "([A-Za-z]{2,3})([-][A-Za-z]{3}){0,3}([-]([A-Za-z]{4}))?([-]([A-Za-z]{2}|[0-9]{3}))?" - } - }, - "value_url": { - "$id": "#/definitions/rule/properties/value_url", - "type": [ - "null", - "string" - ], - "description": "URL to an API endpoint that can provide dynamic information for the measured value", - "format": "uri" - } - }, - "allOf": [ - { - "description": "Valid rule_type and rule_unit values for this rule", - "oneOf": [ - { - "properties": { - "rule_type": { - "const": "user" - } - } - }, - { - "allOf": [ - { - "required": [ - "rule_units" - ] - }, - { - "oneOf": [ - { - "properties": { - "rule_type": { - "const": "time" - }, - "rule_units": { - "enum": [ - "seconds", - "minutes", - "hours", - "days" - ] - } - } - }, - { - "properties": { - "rule_type": { - "const": "speed" - }, - "rule_units": { - "enum": [ - "mph", - "kph" - ] - } - } - }, - { - "properties": { - "rule_type": { - "const": "count" - }, - "rule_units": { - "enum": [ - "devices" - ] - } - } - }, - { - "required": [ - "rate_amount", - "rate_recurrence" - ], - "properties": { - "rule_units": { - "enum": [ - "amount", - "seconds", - "minutes", - "hours", - "days" - ] - } - } - } - ] - } - ] - } - ] - } - ] - }, - "currency": { - "$id": "#/definitions/currency", - "type": [ - "string", - "null" - ], - "pattern": "^[A-Z]{3}$", - "default": "USD", - "description": "An ISO 4217 Alphabetic Currency Code representing currency of the payee. If null, USD cents is implied.", - "examples": [ - "USD", - "EUR", - "GBP" - ] - }, - "day": { - "$id": "#/definitions/day", - "type": "string", - "description": "A day of the week", - "enum": [ - "sun", - "mon", - "tue", - "wed", - "thu", - "fri", - "sat" - ] - }, - "propulsion_type": { - "$id": "#/definitions/propulsion_type", - "type": "string", - "description": "The type of propulsion", - "enum": [ - "combustion", - "electric", - "electric_assist", - "human" - ] - }, - "string": { - "$id": "#/definitions/string", - "type": "string", - "description": "A length-limited string type", - "maxLength": 255, - "default": "", - "examples": [ - "ABC123" - ], - "pattern": "^(.*)$" - }, - "timestamp": { - "$id": "#/definitions/timestamp", - "type": "number", - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - }, - "uuid_array": { - "$id": "#/definitions/uuid_array", - "type": "array", - "description": "Array of UUID", - "items": { - "$id": "#/definitions/uuid_array/items", - "$ref": "#/definitions/uuid" - } - }, - "vehicle_event": { - "$id": "#/definitions/vehicle_event", - "type": "string", - "description": "An event that changes a vehicle's state", - "enum": [ - "agency_drop_off", - "agency_pick_up", - "battery_charged", - "battery_low", - "comms_lost", - "comms_restored", - "compliance_pick_up", - "decommissioned", - "located", - "maintenance", - "maintenance_pick_up", - "missing", - "off_hours", - "on_hours", - "provider_drop_off", - "rebalance_pick_up", - "reservation_cancel", - "reservation_start", - "system_resume", - "system_suspend", - "trip_cancel", - "trip_end", - "trip_enter_jurisdiction", - "trip_leave_jurisdiction", - "trip_start", - "unspecified" - ] - }, - "vehicle_state": { - "$id": "#/definitions/vehicle_state", - "type": "string", - "description": "The state of a vehicle", - "enum": [ - "available", - "elsewhere", - "non_operational", - "on_trip", - "removed", - "reserved", - "unknown" - ] - }, - "vehicle_type": { - "$id": "#/definitions/vehicle_type", - "type": "string", - "description": "The type of vehicle", - "enum": [ - "bicycle", - "cargo_bicycle", - "car", - "scooter", - "moped", - "other" - ] - }, - "version": { - "$id": "#/definitions/version", - "type": "string", - "description": "The version of MDS this data represents", - "examples": [ - "1.2.0" - ], - "pattern": "^1\\.2\\.[0-9]+$" - }, - "days": { - "$id": "#/definitions/days", - "type": "array", - "description": "Array of days of the week", - "items": { - "$id": "#/definitions/days/items", - "$ref": "#/definitions/day" - }, - "uniqueItems": true - }, - "iso_time": { - "$id": "#/definitions/iso_time", - "type": "string", - "description": "Time-of-day expressed as ISO 8601 hh:mm:ss", - "pattern": "([0-2][0-3]|[0-1][0-9]):[0-5][0-9]:[0-5][0-9]" - }, - "propulsion_types": { - "$id": "#/definitions/propulsion_types", - "type": "array", - "description": "Array of propulsion types, allowing multiple values", - "items": { - "$id": "#/definitions/propulsion_types/items", - "$ref": "#/definitions/propulsion_type" - }, - "uniqueItems": true - }, - "vehicle_types": { - "$id": "#/definitions/vehicle_types", - "type": "array", - "description": "Array of vehicle types", - "items": { - "$id": "#/definitions/vehicle_types/items", - "$ref": "#/definitions/vehicle_type" - }, - "uniqueItems": true - }, - "null_days": { - "$id": "#/definitions/null_days", - "type": [ - "array", - "null" - ], - "description": "Array of days of the week", - "items": { - "$id": "#/definitions/days/items", - "$ref": "#/definitions/day" - }, - "uniqueItems": true - }, - "null_iso_time": { - "$id": "#/definitions/null_iso_time", - "type": [ - "string", - "null" - ], - "description": "Time-of-day expressed as ISO 8601 hh:mm:ss", - "pattern": "([0-2][0-3]|[0-1][0-9]):[0-5][0-9]:[0-5][0-9]" - }, - "null_propulsion_types": { - "$id": "#/definitions/null_propulsion_types", - "type": [ - "array", - "null" - ], - "description": "Array of propulsion types, allowing multiple values", - "items": { - "$id": "#/definitions/propulsion_types/items", - "$ref": "#/definitions/propulsion_type" - }, - "uniqueItems": true - }, - "null_timestamp": { - "$id": "#/definitions/null_timestamp", - "type": [ - "number", - "null" - ], - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "null_uuid_array": { - "$id": "#/definitions/null_uuid_array", - "type": [ - "array", - "null" - ], - "description": "Array of UUID", - "items": { - "$id": "#/definitions/uuid_array/items", - "$ref": "#/definitions/uuid" - } - }, - "null_vehicle_types": { - "$id": "#/definitions/null_vehicle_types", - "type": [ - "array", - "null" - ], - "description": "Array of vehicle types", - "items": { - "$id": "#/definitions/vehicle_types/items", - "$ref": "#/definitions/vehicle_type" - }, - "uniqueItems": true - } - }, - "required": [ - "data", - "updated", - "version" - ], - "properties": { - "data": { - "$id": "#/properties/data", - "type": "object", - "description": "The data records in this payload", - "required": [ - "policies" - ], - "properties": { - "policies": { - "$id": "#/properties/data/properties/policies", - "type": "array", - "title": "The array of policy objects in this payload", - "items": { - "$id": "#/properties/data/properties/policies/items", - "$ref": "#/definitions/policy" - } - } - }, - "additionalProperties": false - }, - "end_date": { - "$id": "#/properties/end_date", - "$ref": "#/definitions/null_timestamp", - "description": "The timestamp after which the Policy is no longer effective" - }, - "updated": { - "$id": "#/properties/updated", - "$ref": "#/definitions/timestamp", - "description": "The timestamp when the Policy was last updated" - }, - "version": { - "$id": "#/properties/version", - "$ref": "#/definitions/version", - "description": "The version of MDS that the Policy represents" - } - }, - "additionalProperties": false -} \ No newline at end of file diff --git a/provider/README.md b/provider/README.md index f5b785bb..e4f7b09a 100644 --- a/provider/README.md +++ b/provider/README.md @@ -15,7 +15,7 @@ This specification contains a data standard for *mobility as a service* provider * [Responses and Error Messages](#responses-and-error-messages) * [GBFS](#GBFS) * [Data Latency Requirements][data-latency] - * [JSON Schema](#json-schema) + * [Data Schema](#data-schema) * [Pagination](#pagination) * [Municipality Boundary](#municipality-boundary) * [Other Data Types](#other-data-types) @@ -54,7 +54,7 @@ General authorization details are specified in the [Authorization section](/gene ### Versioning -`provider` APIs must handle requests for specific versions of the specification from clients. +`Provider` APIs must handle requests for specific versions of the specification from clients. Versioning must be implemented as specified in the [Versioning section][versioning]. @@ -70,21 +70,23 @@ MDS is intended to be used for multiple transportation modes, including its orig The response to a client request must include a valid HTTP status code defined in the [IANA HTTP Status Code Registry][iana]. -See [Responses][responses] for information on valid MDS response codes and [Error Messages][error-messages] for information on formatting error messages. - The response must set the `Content-Type` header as specified in the [Versioning section][versioning]. -Response bodies must be a `UTF-8` encoded JSON object and must minimally include the MDS `version` and a `data` payload: +Response bodies must be a `UTF-8` encoded JSON object + +See the [Responses][responses], [Error Messages][error-messages], and [Bulk Responses][bulk-responses] sections, and the [schema][schema] for more details. + +Response bodies must be a `UTF-8` encoded JSON object and must minimally include the MDS `version` and an object payload: ```json { "version": "x.y.z", - "data": { - "trips": [{ - "provider_id": "...", - "trip_id": "...", - }] - } + "trips": [ + { + "provider_id": "...", + "trip_id": "..." + } + ] } ``` @@ -109,11 +111,9 @@ ttl | Yes | Integer representing the number of millisecond [Top][toc] -### JSON Schema +### Data Schema -MDS defines [JSON Schema][json-schema] files for each endpoint. - -`provider` API responses must validate against their respective schema files. The schema files always take precedence over the language and examples in this and other supporting documentation meant for *human* consumption. +See the [Endpoints](#endpoints) below for information on their specific schema, and the [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for full details and interactive documentation. [Top][toc] @@ -135,12 +135,10 @@ At a minimum, paginated payloads must include a `next` key, which must be set to ```json { "version": "x.y.z", - "data": { - "trips": [{ - "provider_id": "...", - "trip_id": "...", - }] - }, + "trips": [{ + "provider_id": "...", + "trip_id": "...", + }], "links": { "first": "https://...", "last": "https://...", @@ -179,11 +177,9 @@ In addition to the standard [Provider payload wrapper](#response-format), respon ```json { "version": "x.y.z", - "data": { - "vehicles": [] - }, "last_updated": "12345", - "ttl": "12345" + "ttl": "12345", + "vehicles": [] } ``` @@ -192,21 +188,20 @@ The `/vehicles` endpoint returns the specified vehicle (if a device_id is provid **Endpoint:** `/vehicles/{device_id}` **Method:** `GET` **[Beta feature][beta]:** No (as of 1.2.0) -**Schema:** [`vehicles` schema][vehicles-schema] -**`data` Payload:** `{ "vehicles": [] }`, an array of [Vehicle](vehicle) objects +**Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. +**`data` Payload:** `{ "vehicles": [] }`, an array of [Vehicle][vehicles] objects -Path Params: +_Path Parameters:_ -| Param | Type | Required/Optional | Description | +| Path Parameters | Type | Required/Optional | Description | | ------------ | ---- | ----------------- | ------------------------------------------- | | `device_id` | UUID | Optional | If provided, retrieve the specified vehicle | -200 Success Response: - If `device_id` is specified, `GET` will return an array with a single vehicle record, otherwise it will be a list of vehicle records with pagination details per the [JSON API](https://jsonapi.org/format/#fetching-pagination) spec: ```json { + "version": "x.y.z", "vehicles": [ ... ] "links": { "first": "https://...", @@ -217,9 +212,17 @@ If `device_id` is specified, `GET` will return an array with a single vehicle re } ``` -404 Failure Response: +#### Responses + +_Possible HTTP Status Codes_: +200, +400 (with parameter), +401, +404, +406, +500 -_No content returned on vehicle not found._ +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. [Top][toc] @@ -230,21 +233,20 @@ The `/vehicles/status` endpoint returns the specified vehicle (if a device_id is **Endpoint:** `/vehicles/status/{device_id}` **Method:** `GET` **[Beta feature][beta]:** No (as of 1.2.0) -**Schema:** N/A +**Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. **`data` Payload:** `{ "vehicles_status": [] }`, an array of [Vehicle Status][vehicle-status] objects -Path Params: +_Path Parameters:_ -| Param | Type | Required/Optional | Description | +| Path Parameter | Type | Required/Optional | Description | | ------------ | ---- | ----------------- | ------------------------------------------- | | `device_id` | UUID | Optional | If provided, retrieve the specified vehicle | -200 Success Response: - If `device_id` is specified, `GET` will return an array with a vehicle status record, otherwise it will be a list of vehicle records with pagination details per the [JSON API](https://jsonapi.org/format/#fetching-pagination) spec: ```json { + "version": "x.y.z", "vehicles": [ ... ] "links": { "first": "https://...", @@ -255,9 +257,17 @@ If `device_id` is specified, `GET` will return an array with a vehicle status re } ``` -404 Failure Response: +#### Responses -_No content returned on vehicle not found._ +_Possible HTTP Status Codes_: +200, +400 (with parameter), +401, +404, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. [Top][toc] @@ -272,17 +282,16 @@ Unless stated otherwise by the municipality, the trips endpoint must return all **Endpoint:** `/trips` **Method:** `GET` **[Beta feature][beta]:** No -**Schema:** [`trips` schema][trips-schema] +**Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. **`data` Payload:** `{ "trips": [] }`, an array of [Trip][trips] objects ### Trips - Query Parameters The `/trips` API should allow querying trips with the following query parameters: -| Parameter | Format | Expected Output | +| Query Parameter | Format | Expected Output | | --------------- | ------ | --------------- | | `end_time` | `YYYY-MM-DDTHH`, an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) extended datetime representing an UTC hour between 00 and 23. | All trips with an end time occurring within the hour. For example, requesting `end_time=2019-10-01T07` returns all trips where `2019-10-01T07:00:00 <= trip.end_time < 2019-10-01T08:00:00` UTC. | -| `route` | Boolean | If false, do not return route data. | Without an `end_time` query parameter, `/trips` shall return a `400 Bad Request` error. @@ -298,7 +307,7 @@ processing for that hour: * For hours in which the provider was not operating the API shall return a `404 Not Found` response. * For hours that are in the past but for which data is not yet available - the API shall return a `102 Processing` response. + the API shall return a `202 Accepted` response. * For all other hours the API shall return a `200 OK` response with a fully populated body, even for hours that contain no trips to report. If the hour has no trips to report the response shall contain an empty @@ -307,14 +316,25 @@ processing for that hour: ```json { "version": "x.y.z", - "data": { - "trips": [] - } + "trips": [] } ``` For the near-ish real time use cases, please use the [events][events] endpoint. +#### Responses + +_Possible HTTP Status Codes_: +200, +202, +400 (with parameter), +401, +404, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. + [Top][toc] ## Telemetry @@ -327,19 +347,30 @@ Telemetry for a [trip](#trip) must include at least 2 points: the start point an **Endpoint:** `/telemetry` **Method:** `GET` -**Schema:** [`telemetry` schema][telemetry-schema] +**Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. **`data` Payload:** `{ "telemetry": [] }`, an array of [Vehicle Telemetry][vehicle-telemetry] objects [Top][toc] ### Telemetry - Query Parameters -| Parameter | Format | Expected Output | +| Query Parameter | Format | Expected Output | | --------- | ------ | --------------- | | `telemetry_time` | `YYYY-MM-DDTHH`, an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) extended datetime representing an UTC hour between 00 and 23. | All telemetry with timestamp occurring within the hour. For example, requesting `telemetry_time=2019-10-01T07` returns all telemetry where `2019-10-01T07:00:00 <= telemetry.timestamp < 2019-10-01T08:00:00` UTC. | Without a `telemetry_time` query parameter, `/telemetry` shall return a `400 Bad Request` error. +#### Responses + +_Possible HTTP Status Codes_: +200, +400 (with parameter), +401, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. + [Top][toc] ## Events @@ -353,8 +384,8 @@ Unless stated otherwise by the municipality, this endpoint must return only thos **Endpoint:** `/events/historical` **Method:** `GET` **[Beta feature][beta]:** No -**Schema:** [`events` schema][events-schema] -**`data` Payload:** `{ "data": [] }`, an array of [Events](/data-types.md#events) object +**Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. +**`data` Payload:** `{ "events": [] }`, an array of [Events](/data-types.md#events) object [Top][toc] @@ -362,7 +393,7 @@ Unless stated otherwise by the municipality, this endpoint must return only thos The `/events/historical` API uses the following query parameter: -| Parameter | Format | Expected Output | +| Query Parameter | Format | Expected Output | | --------- | ------ | --------------- | | `event_time` | `YYYY-MM-DDTHH`, an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) extended datetime representing an UTC hour between 00 and 23. | All status changes with an event time occurring within the hour. For example, requesting `event_time=2019-10-01T07` returns all status changes where `2019-10-01T07:00:00 <= status_change.event_time < 2019-10-01T08:00:00` UTC. | @@ -378,7 +409,7 @@ processing for that hour: * For hours in which the provider was not operating the API shall return a `404 Not Found` response. * For hours that are in the past but for which data is not yet available - the API shall return a `102 Processing` response. + the API shall return a `202 Accepted` response. * For all other hours the API shall return a `200 OK` response with a fully populated body, even for hours that contain no status changes to report. If the hour has no status changes to report the response shall contain an @@ -387,12 +418,23 @@ processing for that hour: ```json { "version": "x.y.z", - "data": { - "status_changes": [] - } + "status_changes": [] } ``` +#### Responses + +_Possible HTTP Status Codes_: +200, +202, +400 (with parameter), +401, +404, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. + [Top][toc] ### Recent Events @@ -404,14 +446,14 @@ See also [Stop-based Geographic Data][stop-based-geo]. **Endpoint:** `/events/recent` **Method:** `GET` **[Beta feature][beta]:** No (as of 1.0.0) -**Schema:** [`events` schema][events-schema] +**Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. **`data` Payload:** `{ "events": [] }`, an array of [Events](/data-types.md#events) object objects #### Recent Events - Query Parameters The Recent Events API requires two parameters: -| Parameter | Type | Expected Output | +| Query Parameter | Type | Expected Output | | ----- | ---- | -------- | | `start_time` | [timestamp][ts] | status changes where `start_time <= event.timestamp` | | `end_time` | [timestamp][ts] | status changes where `event.timestamp < end_time` | @@ -420,6 +462,17 @@ Should either side of the requested time range be missing, `/events/recent` shal Should either side of the requested time range be greater than 2 weeks before the time of the request, `/events/recent` shall return a `400 Bad Request` error. +#### Responses + +_Possible HTTP Status Codes_: +200, +400 (with parameter), +401, +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. + [Top][toc] ## Stops @@ -431,21 +484,31 @@ In addition to the standard [Provider payload wrapper](#response-format), respon ```json { "version": "x.y.z", - "data": { - "stops": [] - }, "last_updated": "12345", - "ttl": "12345" + "ttl": "12345", + "stops": [] } ``` -**Endpoint:** `/stops/:stop_id` +**Endpoint:** `/stops/{stop_id}` **Method:** `GET` **[Beta feature][beta]:** Yes (as of 1.0.0). [Leave feedback](https://github.com/openmobilityfoundation/mobility-data-specification/issues/638) -**Schema:** [`stops` schema][stops-schema] +**Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. **`data` Payload:** `{ "stops": [] }`, an array of [Stops][stops] -In the case that a `stop_id` query parameter is specified, the `stops` array returned will only have one entry. In the case that no `stop_id` query parameter is specified, all stops will be returned. +In the case that a `stop_id` path parameter is specified, the `stops` array returned will only have one entry. In the case that no `stop_id` query parameter is specified, all stops will be returned. + +#### Responses + +_Possible HTTP Status Codes_: +200, +400 (with parameter), +401, +404 (with parameter), +406, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. [Top][toc] @@ -463,10 +526,20 @@ The authenticated reports are monthly, historic flat files that may be pre-gener **Method:** `GET` **[Beta feature][beta]:** No (as of 2.0.0). [Leave feedback](https://github.com/openmobilityfoundation/mobility-data-specification/issues/672) **Usage note:** This endpoint uses media-type `text/vnd.mds+csv` instead of `application/vnd.mds+json`, see [Versioning][versioning]. -**Schema:** TBD +**Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. **`data` Filename:** monthly file named by year and month, e.g. `/reports/YYYY-MM.csv` **`data` Payload:** monthly CSV files of [Report](/data-types.md#Reports) objects +#### Responses + +_Possible HTTP Status Codes_: +200, +401, +404, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. + [Top][toc] ### Reports - Example @@ -477,13 +550,13 @@ See [Provider examples](examples.md#reports). [agps]: https://en.wikipedia.org/wiki/Assisted_GPS [beta]: /general-information.md#beta-features +[bulk-responses]: /general-information.md#bulk-responses [costs-and-currencies]: /general-information.md#costs-and-currencies [data-latency]: #data-latency-requirements [dgps]: https://en.wikipedia.org/wiki/Differential_GPS [error-messages]: /general-information.md#error-messages [events]: /data-types.md#events [events---query-parameters]: #events---query-parameters -[events-schema]: events.json [event-times]: #event-times [gbfs]: https://github.com/NABSA/gbfs [general-information]: /general-information.md @@ -499,24 +572,20 @@ See [Provider examples](examples.md#reports). [point-geo]: /data-types.md#gps-data [propulsion-types]: /general-information.md#propulsion-types [responses]: /general-information.md#responses +[schema]: /schema/ [stops]: /data-types.md#stops [stop-based-geo]: /general-information.md#stop-based-geographic-data -[stops-schema]: stops.json [telemetry]: /data-types.md#telemetry -[telemetry-schema]: telemetry.json [telemetry---query-parameters]: #telemetry-query-parameters [toc]: #table-of-contents [trips]: /data-types.md#trips [trips-general-info]: /general-information.md#stop-based-geographic-data -[trips-schema]: trips.json [ts]: /general-information.md#timestamps [vehicles]: /data-types.md#vehicles -[vehicle]: /data-types.md#vehicles [vehicle-types]: /data-types.md#vehicle-types -[vehicle-status]: /data-types.md#vehicle-states +[vehicle-status]: /data-types.md#vehicle-status [vehicle-states]: /modes#vehicle-states [vehicle-events]: /modes#event-types [vehicle-event-data]: /general-information.md#event-data -[vehicles-schema]: vehicles.json [vehicle-telemetry]: /data-types.md#telemetry [versioning]: /general-information.md#versioning diff --git a/provider/events.json b/provider/events.json deleted file mode 100644 index b97fe883..00000000 --- a/provider/events.json +++ /dev/null @@ -1,610 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/provider/events.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "Schema for MDS Provider events payloads", - "type": "object", - "definitions": { - "string": { - "$id": "#/definitions/string", - "type": "string", - "description": "A length-limited string type", - "maxLength": 255, - "default": "", - "examples": [ - "ABC123" - ], - "pattern": "^(.*)$" - }, - "timestamp": { - "$id": "#/definitions/timestamp", - "type": "number", - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - }, - "version": { - "$id": "#/definitions/version", - "type": "string", - "description": "The version of MDS this data represents", - "examples": [ - "1.2.0" - ], - "pattern": "^1\\.2\\.[0-9]+$" - }, - "MDS_Feature_Point": { - "$id": "#/definitions/MDS_Feature_Point", - "title": "MDS GeoJSON Feature Point", - "type": "object", - "required": [ - "type", - "properties", - "geometry" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Feature" - ] - }, - "id": { - "oneOf": [ - { - "type": "number" - }, - { - "type": "string" - } - ] - }, - "properties": { - "type": "object", - "required": [ - "timestamp" - ], - "properties": { - "timestamp": { - "$ref": "#/definitions/timestamp" - }, - "stop_id": { - "$ref": "#/definitions/uuid" - }, - "altitude": { - "type": "number", - "description": "Altitude above mean sea level in meters" - }, - "heading": { - "type": "number", - "description": "Degrees - clockwise starting at 0 degrees at true North" - }, - "speed": { - "type": "number", - "description": "Estimated speed in meters / sec as reported by the GPS chipset" - }, - "accuracy": { - "type": "number", - "description": "Horizontal accuracy, in meters" - }, - "hdop": { - "type": "number", - "description": "Horizontal GPS or GNSS accuracy value" - }, - "satellites": { - "type": "integer", - "description": "Number of GPS or GNSS satellites" - } - } - }, - "geometry": { - "$ref": "#/definitions/Point" - }, - "bbox": { - "type": "array", - "minItems": 4, - "items": { - "type": "number" - } - } - } - }, - "Point": { - "$id": "#/definitions/Point", - "title": "GeoJSON Point", - "type": "object", - "required": [ - "type", - "coordinates" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Point" - ] - }, - "coordinates": { - "type": "array", - "minItems": 2, - "items": [ - { - "type": "number", - "minimum": -180.0, - "maximum": 180.0 - }, - { - "type": "number", - "minimum": -90.0, - "maximum": 90.0 - } - ], - "maxItems": 2 - }, - "bbox": { - "type": "array", - "minItems": 4, - "items": { - "type": "number" - } - } - } - }, - "propulsion_type": { - "$id": "#/definitions/propulsion_type", - "type": "string", - "description": "The type of propulsion", - "enum": [ - "combustion", - "electric", - "electric_assist", - "human" - ] - }, - "propulsion_types": { - "$id": "#/definitions/propulsion_types", - "type": "array", - "description": "Array of propulsion types, allowing multiple values", - "items": { - "$id": "#/definitions/propulsion_types/items", - "$ref": "#/definitions/propulsion_type" - }, - "uniqueItems": true - }, - "vehicle_type": { - "$id": "#/definitions/vehicle_type", - "type": "string", - "description": "The type of vehicle", - "enum": [ - "bicycle", - "cargo_bicycle", - "car", - "scooter", - "moped", - "other" - ] - }, - "vehicle_state": { - "$id": "#/definitions/vehicle_state", - "type": "string", - "description": "The state of a vehicle", - "enum": [ - "available", - "elsewhere", - "non_operational", - "on_trip", - "removed", - "reserved", - "unknown" - ] - }, - "vehicle_event": { - "$id": "#/definitions/vehicle_event", - "type": "string", - "description": "An event that changes a vehicle's state", - "enum": [ - "agency_drop_off", - "agency_pick_up", - "battery_charged", - "battery_low", - "comms_lost", - "comms_restored", - "compliance_pick_up", - "decommissioned", - "located", - "maintenance", - "maintenance_pick_up", - "missing", - "off_hours", - "on_hours", - "provider_drop_off", - "rebalance_pick_up", - "reservation_cancel", - "reservation_start", - "system_resume", - "system_suspend", - "trip_cancel", - "trip_end", - "trip_enter_jurisdiction", - "trip_leave_jurisdiction", - "trip_start", - "unspecified" - ] - }, - "vehicle_events": { - "$id": "#/definitions/vehicle_events", - "type": "array", - "description": "Array of events indicating a change to a vehicle's state", - "uniqueItems": true, - "minItems": 1, - "items": { - "$ref": "#/definitions/vehicle_event" - } - }, - "links": { - "$id": "#/definitions/links", - "type": "object", - "required": [ - "next" - ], - "properties": { - "first": { - "$id": "#/definitions/links/first", - "type": [ - "null", - "string" - ], - "title": "The URL to the first page of data", - "examples": [ - "https://data.provider.co/trips/first" - ], - "format": "uri" - }, - "last": { - "$id": "#/definitions/links/last", - "type": [ - "null", - "string" - ], - "title": "The URL to the last page of data", - "examples": [ - "https://data.provider.co/trips/last" - ], - "format": "uri" - }, - "prev": { - "$id": "#/definitions/links/prev", - "type": [ - "null", - "string" - ], - "title": "The URL to the previous page of data", - "examples": [ - "https://data.provider.co/trips/prev" - ], - "format": "uri" - }, - "next": { - "$id": "#/definitions/links/next", - "type": [ - "null", - "string" - ], - "title": "The URL to the next page of data", - "examples": [ - "https://data.provider.co/trips/next" - ], - "format": "uri", - "pattern": "^(.*)$" - } - }, - "additionalProperties": false - } - }, - "required": [ - "data", - "version" - ], - "properties": { - "data": { - "$id": "#/properties/data", - "type": "object", - "description": "The data records in this payload", - "required": [ - "status_changes" - ], - "properties": { - "status_changes": { - "$id": "#/properties/data/properties/status_changes", - "type": "array", - "title": "The status_changes payload", - "items": { - "$id": "#/properties/data/properties/status_changes/items", - "type": "object", - "title": "The status_change item schema", - "additionalProperties": false, - "required": [ - "provider_name", - "provider_id", - "device_id", - "vehicle_id", - "vehicle_type", - "propulsion_types", - "vehicle_state", - "event_types", - "event_time", - "event_location" - ], - "properties": { - "provider_name": { - "$id": "#/definitions/vehicle/properties/provider_name", - "$ref": "#/definitions/string", - "description": "The public-facing name of the Provider" - }, - "provider_id": { - "$id": "#/definitions/vehicle/properties/provider_id", - "$ref": "#/definitions/uuid", - "description": "The UUID for the Provider, unique within MDS" - }, - "device_id": { - "$id": "#/definitions/vehicle/properties/device_id", - "$ref": "#/definitions/uuid", - "description": "A unique device ID in UUID format" - }, - "vehicle_id": { - "$id": "#/definitions/vehicle/properties/vehicle_id", - "$ref": "#/definitions/string", - "description": "The Vehicle Identification Number visible on the vehicle itself" - }, - "vehicle_type": { - "$id": "#/definitions/vehicle/properties/vehicle_type", - "$ref": "#/definitions/vehicle_type", - "description": "The type of vehicle" - }, - "propulsion_types": { - "$id": "#/definitions/vehicle/properties/propulsion_types", - "$ref": "#/definitions/propulsion_types", - "description": "The type of propulsion; allows multiple values", - "minItems": 1 - }, - "event_time": { - "$id": "#/properties/data/properties/status_changes/items/properties/event_time", - "$ref": "#/definitions/timestamp", - "description": "The time the event occurred, expressed as a Unix Timestamp" - }, - "publication_time": { - "$id": "#/properties/data/properties/status_changes/items/properties/publication_time", - "$ref": "#/definitions/timestamp", - "description": "The time the event became available through the status changes endpoint, expressed as a Unix Timestamp" - }, - "event_location": { - "$id": "#/properties/data/properties/status_changes/items/properties/event_location", - "$ref": "#/definitions/MDS_Feature_Point", - "description": "The GPS or GNSS coordinates of where the event occurred" - }, - "vehicle_state": { - "$id": "#/properties/data/properties/status_changes/items/properties/vehicle_state", - "$ref": "#/definitions/vehicle_state", - "description": "The state of the vehicle" - }, - "event_types": { - "$id": "#/properties/data/properties/status_changes/items/properties/event_types", - "$ref": "#/definitions/vehicle_events", - "description": "The event(s) that caused a change in the vehicle's state" - }, - "battery_pct": { - "$id": "#/properties/data/properties/status_changes/items/properties/battery_pct", - "type": [ - "number", - "null" - ], - "description": "Percent charge of device battery, expressed between 0 and 1", - "examples": [ - 0.89 - ], - "minimum": 0, - "maximum": 1 - }, - "trip_id": { - "$id": "#/properties/data/properties/status_changes/items/properties/trip_id", - "$ref": "#/definitions/uuid", - "description": "Trip UUID (foreign key to Trips API), required if event_types contains trip_start, trip_end, trip_cancel, trip_enter_jurisdiction, or trip_leave_jurisdiction" - }, - "associated_ticket": { - "$id": "#/properties/data/properties/status_changes/items/properties/associated_ticket", - "$ref": "#/definitions/string", - "description": "Identifier for an associated ticket inside an Agency-maintained 311 or CRM system." - } - }, - "allOf": [ - { - "description": "valid vehicle_state and vehicle_events combinations", - "oneOf": [ - { - "properties": { - "vehicle_state": { - "const": "available" - }, - "event_types": { - "contains": { - "enum": [ - "agency_drop_off", - "battery_charged", - "comms_restored", - "located", - "maintenance", - "on_hours", - "provider_drop_off", - "reservation_cancel", - "system_resume", - "trip_cancel", - "trip_end", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "elsewhere" - }, - "event_types": { - "contains": { - "enum": [ - "comms_restored", - "located", - "trip_leave_jurisdiction", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "non_operational" - }, - "event_types": { - "contains": { - "enum": [ - "battery_low", - "comms_restored", - "located", - "maintenance", - "off_hours", - "system_suspend", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "on_trip" - }, - "event_types": { - "contains": { - "enum": [ - "comms_restored", - "located", - "trip_enter_jurisdiction", - "trip_start", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "removed" - }, - "event_types": { - "contains": { - "enum": [ - "agency_pick_up", - "comms_restored", - "compliance_pick_up", - "decommissioned", - "located", - "maintenance_pick_up", - "rebalance_pick_up", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "reserved" - }, - "event_types": { - "contains": { - "enum": [ - "comms_restored", - "located", - "reservation_start", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "unknown" - }, - "event_types": { - "contains": { - "enum": [ - "comms_lost", - "missing", - "unspecified" - ] - } - } - } - } - ] - }, - { - "description": "Conditionally require a trip_id reference", - "anyOf": [ - { - "not": { - "properties": { - "event_types": { - "contains": { - "enum": [ - "trip_cancel", - "trip_end", - "trip_enter_jurisdiction", - "trip_leave_jurisdiction", - "trip_start" - ] - } - } - } - } - }, - { - "required": [ - "trip_id" - ] - } - ] - } - ] - } - } - }, - "additionalProperties": false - }, - "version": { - "$id": "#/properties/version", - "$ref": "#/definitions/version" - }, - "links": { - "$id": "#/properties/links", - "$ref": "#/definitions/links" - } - }, - "additionalProperties": false -} diff --git a/provider/status_changes.json b/provider/status_changes.json deleted file mode 100644 index 68faca22..00000000 --- a/provider/status_changes.json +++ /dev/null @@ -1,547 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/provider/status_changes.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "Schema for MDS Provider status_changes payloads", - "type": "object", - "definitions": { - "string": { - "$id": "#/definitions/string", - "type": "string", - "description": "A length-limited string type", - "maxLength": 255, - "default": "", - "examples": [ - "ABC123" - ], - "pattern": "^(.*)$" - }, - "timestamp": { - "$id": "#/definitions/timestamp", - "type": "number", - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - }, - "version": { - "$id": "#/definitions/version", - "type": "string", - "description": "The version of MDS this data represents", - "examples": [ - "1.2.0" - ], - "pattern": "^1\\.2\\.[0-9]+$" - }, - "MDS_Feature_Point": { - "$id": "#/definitions/MDS_Feature_Point", - "title": "MDS GeoJSON Feature Point", - "type": "object", - "required": [ - "type", - "properties", - "geometry" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Feature" - ] - }, - "id": { - "oneOf": [ - { - "type": "number" - }, - { - "type": "string" - } - ] - }, - "properties": { - "type": "object", - "required": [ - "timestamp" - ], - "properties": { - "timestamp": { - "$ref": "#/definitions/timestamp" - }, - "stop_id": { - "$ref": "#/definitions/uuid" - }, - "altitude": { - "type": "number", - "description": "Altitude above mean sea level in meters" - }, - "heading": { - "type": "number", - "description": "Degrees - clockwise starting at 0 degrees at true North" - }, - "speed": { - "type": "number", - "description": "Estimated speed in meters / sec as reported by the GPS chipset" - }, - "accuracy": { - "type": "number", - "description": "Horizontal accuracy, in meters" - }, - "hdop": { - "type": "number", - "description": "Horizontal GPS or GNSS accuracy value" - }, - "satellites": { - "type": "integer", - "description": "Number of GPS or GNSS satellites" - } - } - }, - "geometry": { - "$ref": "#/definitions/Point" - }, - "bbox": { - "type": "array", - "minItems": 4, - "items": { - "type": "number" - } - } - } - }, - "Point": { - "$id": "#/definitions/Point", - "title": "GeoJSON Point", - "type": "object", - "required": [ - "type", - "coordinates" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Point" - ] - }, - "coordinates": { - "type": "array", - "minItems": 2, - "items": [ - { - "type": "number", - "minimum": -180.0, - "maximum": 180.0 - }, - { - "type": "number", - "minimum": -90.0, - "maximum": 90.0 - } - ], - "maxItems": 2 - }, - "bbox": { - "type": "array", - "minItems": 4, - "items": { - "type": "number" - } - } - } - }, - "propulsion_type": { - "$id": "#/definitions/propulsion_type", - "type": "string", - "description": "The type of propulsion", - "enum": [ - "combustion", - "electric", - "electric_assist", - "human" - ] - }, - "propulsion_types": { - "$id": "#/definitions/propulsion_types", - "type": "array", - "description": "Array of propulsion types, allowing multiple values", - "items": { - "$id": "#/definitions/propulsion_types/items", - "$ref": "#/definitions/propulsion_type" - }, - "uniqueItems": true - }, - "vehicle_type": { - "$id": "#/definitions/vehicle_type", - "type": "string", - "description": "The type of vehicle", - "enum": [ - "bicycle", - "cargo_bicycle", - "car", - "scooter", - "moped", - "other" - ] - }, - "vehicle_state": { - "$id": "#/definitions/vehicle_state", - "type": "string", - "description": "The state of a vehicle", - "enum": [ - "available", - "elsewhere", - "non_operational", - "on_trip", - "removed", - "reserved", - "unknown" - ] - }, - "vehicle_event": { - "$id": "#/definitions/vehicle_event", - "type": "string", - "description": "An event that changes a vehicle's state", - "enum": [ - "agency_drop_off", - "agency_pick_up", - "battery_charged", - "battery_low", - "comms_lost", - "comms_restored", - "compliance_pick_up", - "decommissioned", - "located", - "maintenance", - "maintenance_pick_up", - "missing", - "off_hours", - "on_hours", - "provider_drop_off", - "rebalance_pick_up", - "reservation_cancel", - "reservation_start", - "system_resume", - "system_suspend", - "trip_cancel", - "trip_end", - "trip_enter_jurisdiction", - "trip_leave_jurisdiction", - "trip_start", - "unspecified" - ] - }, - "vehicle_events": { - "$id": "#/definitions/vehicle_events", - "type": "array", - "description": "Array of events indicating a change to a vehicle's state", - "uniqueItems": true, - "minItems": 1, - "items": { - "$ref": "#/definitions/vehicle_event" - } - } - }, - "required": [ - "data", - "version" - ], - "properties": { - "data": { - "$id": "#/properties/data", - "type": "object", - "description": "The data records in this payload", - "required": [ - "status_changes" - ], - "properties": { - "status_changes": { - "$id": "#/properties/data/properties/status_changes", - "type": "array", - "title": "The status_changes payload", - "items": { - "$id": "#/properties/data/properties/status_changes/items", - "type": "object", - "title": "The status_change item schema", - "additionalProperties": false, - "required": [ - "provider_name", - "provider_id", - "device_id", - "vehicle_id", - "vehicle_type", - "propulsion_types", - "vehicle_state", - "event_types", - "event_time", - "event_location" - ], - "properties": { - "provider_name": { - "$id": "#/definitions/vehicle/properties/provider_name", - "$ref": "#/definitions/string", - "description": "The public-facing name of the Provider" - }, - "provider_id": { - "$id": "#/definitions/vehicle/properties/provider_id", - "$ref": "#/definitions/uuid", - "description": "The UUID for the Provider, unique within MDS" - }, - "device_id": { - "$id": "#/definitions/vehicle/properties/device_id", - "$ref": "#/definitions/uuid", - "description": "A unique device ID in UUID format" - }, - "vehicle_id": { - "$id": "#/definitions/vehicle/properties/vehicle_id", - "$ref": "#/definitions/string", - "description": "The Vehicle Identification Number visible on the vehicle itself" - }, - "vehicle_type": { - "$id": "#/definitions/vehicle/properties/vehicle_type", - "$ref": "#/definitions/vehicle_type", - "description": "The type of vehicle" - }, - "propulsion_types": { - "$id": "#/definitions/vehicle/properties/propulsion_types", - "$ref": "#/definitions/propulsion_types", - "description": "The type of propulsion; allows multiple values", - "minItems": 1 - }, - "event_time": { - "$id": "#/properties/data/properties/status_changes/items/properties/event_time", - "$ref": "#/definitions/timestamp", - "description": "The time the event occurred, expressed as a Unix Timestamp" - }, - "publication_time": { - "$id": "#/properties/data/properties/status_changes/items/properties/publication_time", - "$ref": "#/definitions/timestamp", - "description": "The time the event became available through the status changes endpoint, expressed as a Unix Timestamp" - }, - "event_location": { - "$id": "#/properties/data/properties/status_changes/items/properties/event_location", - "$ref": "#/definitions/MDS_Feature_Point", - "description": "The GPS or GNSS coordinates of where the event occurred" - }, - "vehicle_state": { - "$id": "#/properties/data/properties/status_changes/items/properties/vehicle_state", - "$ref": "#/definitions/vehicle_state", - "description": "The state of the vehicle" - }, - "event_types": { - "$id": "#/properties/data/properties/status_changes/items/properties/event_types", - "$ref": "#/definitions/vehicle_events", - "description": "The event(s) that caused a change in the vehicle's state" - }, - "battery_pct": { - "$id": "#/properties/data/properties/status_changes/items/properties/battery_pct", - "type": [ - "number", - "null" - ], - "description": "Percent charge of device battery, expressed between 0 and 1", - "examples": [ - 0.89 - ], - "minimum": 0, - "maximum": 1 - }, - "trip_id": { - "$id": "#/properties/data/properties/status_changes/items/properties/trip_id", - "$ref": "#/definitions/uuid", - "description": "Trip UUID (foreign key to Trips API), required if event_types contains trip_start, trip_end, trip_cancel, trip_enter_jurisdiction, or trip_leave_jurisdiction" - }, - "associated_ticket": { - "$id": "#/properties/data/properties/status_changes/items/properties/associated_ticket", - "$ref": "#/definitions/string", - "description": "Identifier for an associated ticket inside an Agency-maintained 311 or CRM system." - } - }, - "allOf": [ - { - "description": "valid vehicle_state and vehicle_events combinations", - "oneOf": [ - { - "properties": { - "vehicle_state": { - "const": "available" - }, - "event_types": { - "contains": { - "enum": [ - "agency_drop_off", - "battery_charged", - "comms_restored", - "located", - "maintenance", - "on_hours", - "provider_drop_off", - "reservation_cancel", - "system_resume", - "trip_cancel", - "trip_end", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "elsewhere" - }, - "event_types": { - "contains": { - "enum": [ - "comms_restored", - "located", - "trip_leave_jurisdiction", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "non_operational" - }, - "event_types": { - "contains": { - "enum": [ - "battery_low", - "comms_restored", - "located", - "maintenance", - "off_hours", - "system_suspend", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "on_trip" - }, - "event_types": { - "contains": { - "enum": [ - "comms_restored", - "located", - "trip_enter_jurisdiction", - "trip_start", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "removed" - }, - "event_types": { - "contains": { - "enum": [ - "agency_pick_up", - "comms_restored", - "compliance_pick_up", - "decommissioned", - "located", - "maintenance_pick_up", - "rebalance_pick_up", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "reserved" - }, - "event_types": { - "contains": { - "enum": [ - "comms_restored", - "located", - "reservation_start", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "unknown" - }, - "event_types": { - "contains": { - "enum": [ - "comms_lost", - "missing", - "unspecified" - ] - } - } - } - } - ] - }, - { - "description": "Conditionally require a trip_id reference", - "anyOf": [ - { - "not": { - "properties": { - "event_types": { - "contains": { - "enum": [ - "trip_cancel", - "trip_end", - "trip_enter_jurisdiction", - "trip_leave_jurisdiction", - "trip_start" - ] - } - } - } - } - }, - { - "required": [ - "trip_id" - ] - } - ] - } - ] - } - } - }, - "additionalProperties": false - }, - "version": { - "$id": "#/properties/version", - "$ref": "#/definitions/version" - } - }, - "additionalProperties": false -} diff --git a/provider/stops.json b/provider/stops.json deleted file mode 100644 index 5f913970..00000000 --- a/provider/stops.json +++ /dev/null @@ -1,392 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/provider/stops.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "Schema for MDS Provider stops payloads", - "type": "object", - "definitions": { - "string": { - "$id": "#/definitions/string", - "type": "string", - "description": "A length-limited string type", - "maxLength": 255, - "default": "", - "examples": [ - "ABC123" - ], - "pattern": "^(.*)$" - }, - "timestamp": { - "$id": "#/definitions/timestamp", - "type": "number", - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - }, - "version": { - "$id": "#/definitions/version", - "type": "string", - "description": "The version of MDS this data represents", - "examples": [ - "1.2.0" - ], - "pattern": "^1\\.2\\.[0-9]+$" - }, - "MDS_Feature_Point": { - "$id": "#/definitions/MDS_Feature_Point", - "title": "MDS GeoJSON Feature Point", - "type": "object", - "required": [ - "type", - "properties", - "geometry" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Feature" - ] - }, - "id": { - "oneOf": [ - { - "type": "number" - }, - { - "type": "string" - } - ] - }, - "properties": { - "type": "object", - "required": [ - "timestamp" - ], - "properties": { - "timestamp": { - "$ref": "#/definitions/timestamp" - }, - "stop_id": { - "$ref": "#/definitions/uuid" - }, - "altitude": { - "type": "number", - "description": "Altitude above mean sea level in meters" - }, - "heading": { - "type": "number", - "description": "Degrees - clockwise starting at 0 degrees at true North" - }, - "speed": { - "type": "number", - "description": "Estimated speed in meters / sec as reported by the GPS chipset" - }, - "accuracy": { - "type": "number", - "description": "Horizontal accuracy, in meters" - }, - "hdop": { - "type": "number", - "description": "Horizontal GPS or GNSS accuracy value" - }, - "satellites": { - "type": "integer", - "description": "Number of GPS or GNSS satellites" - } - } - }, - "geometry": { - "$ref": "#/definitions/Point" - }, - "bbox": { - "type": "array", - "minItems": 4, - "items": { - "type": "number" - } - } - } - }, - "Point": { - "$id": "#/definitions/Point", - "title": "GeoJSON Point", - "type": "object", - "required": [ - "type", - "coordinates" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Point" - ] - }, - "coordinates": { - "type": "array", - "minItems": 2, - "items": [ - { - "type": "number", - "minimum": -180.0, - "maximum": 180.0 - }, - { - "type": "number", - "minimum": -90.0, - "maximum": 90.0 - } - ], - "maxItems": 2 - }, - "bbox": { - "type": "array", - "minItems": 4, - "items": { - "type": "number" - } - } - } - }, - "ttl": { - "$id": "#/definitions/ttl", - "type": "integer", - "description": "Integer milliseconds until next data update (0 if the data is always refreshed)", - "minimum": 0, - "maximum": 300000 - }, - "stop": { - "$id": "#/definitions/stop", - "type": "object", - "description": "The common schema elements for a Stop in MDS", - "required": [ - "stop_id", - "name", - "last_reported", - "location", - "status", - "capacity", - "num_vehicles_available", - "num_vehicles_disabled" - ], - "properties": { - "stop_id": { - "$id": "#/definitions/stop/properties/stop_id", - "$ref": "#/definitions/uuid", - "description": "UUID for the Stop" - }, - "name": { - "$id": "#/definitions/stop/properties/name", - "$ref": "#/definitions/string", - "description": "Name of the Stop" - }, - "last_reported": { - "$id": "#/definitions/stop/properties/last_reported", - "$ref": "#/definitions/timestamp", - "description": "Date/Time of the last status update for this Stop" - }, - "location": { - "$id": "#/definitions/stop/properties/location", - "$ref": "#/definitions/MDS_Feature_Point", - "description": "Location of the stop" - }, - "status": { - "$id": "#/definitions/stop/properties/status", - "$ref": "#/definitions/stop_status", - "description": "The status of the Stop" - }, - "capacity": { - "$id": "#/definitions/stop/properties/capacity", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of total places per vehicle_type" - }, - "num_vehicles_available": { - "$id": "#/definitions/stop/properties/num_vehicles_available", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of available vehicles per vehicle_type" - }, - "num_vehicles_disabled": { - "$id": "#/definitions/stop/properties/num_vehicles_disabled", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of non_operational/reserved vehicles per vehicle_type" - }, - "provider_id": { - "$id": "#/definitions/stop/properties/provider_id", - "$ref": "#/definitions/uuid", - "description": "UUID for the Provider managing this Stop. Null/undefined if managed by an Agency." - }, - "geography_id": { - "$id": "#/definitions/stop/properties/geography_id", - "$ref": "#/definitions/uuid", - "description": "UUID for the Stop" - }, - "region_id": { - "$id": "#/definitions/stop/properties/region_id", - "$ref": "#/definitions/string", - "description": "ID of the region where the Stop is located. See GBFS Station Information." - }, - "short_name": { - "$id": "#/definitions/stop/properties/short_name", - "$ref": "#/definitions/string", - "description": "Abbreviated Stop name" - }, - "address": { - "$id": "#/definitions/stop/properties/address", - "$ref": "#/definitions/string", - "description": "Postal address (useful for directions)" - }, - "post_code": { - "$id": "#/definitions/stop/properties/post_code", - "$ref": "#/definitions/string", - "description": "Postal code (e.g. 10036)" - }, - "cross_street": { - "$id": "#/definitions/stop/properties/cross_street", - "$ref": "#/definitions/string", - "description": "Cross street of where Stop is located" - }, - "num_places_available": { - "$id": "#/definitions/stop/properties/num_places_available", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of places free to be populated per vehicle_type" - }, - "num_places_disabled": { - "$id": "#/definitions/stop/properties/num_places_disabled", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of places disabled an unable to accept vehicles per vehicle_type" - }, - "parent_stop": { - "$id": "#/definitions/stop/properties/parent_stop", - "$ref": "#/definitions/uuid", - "description": "Describe a basic hierarchy of Stops (e.g. a Stop inside a greater Stop)" - }, - "devices": { - "$id": "#/definitions/stop/properties/devices", - "$ref": "#/definitions/uuid_array", - "description": "List of device_id for vehicles currently at this Stop." - } - } - }, - "stop_status": { - "$id": "#/definitions/stop_status", - "type": "object", - "description": "Status object for a Stop in MDS", - "required": [ - "is_installed", - "is_renting", - "is_returning" - ], - "properties": { - "is_installed": { - "$id": "#/definitions/stop_status/properties/is_installed", - "type": "boolean" - }, - "is_renting": { - "$id": "#/definitions/stop_status/properties/is_renting", - "type": "boolean" - }, - "is_returning": { - "$id": "#/definitions/stop_status/properties/is_returning", - "type": "boolean" - } - } - }, - "uuid_array": { - "$id": "#/definitions/uuid_array", - "type": "array", - "description": "Array of UUID", - "items": { - "$id": "#/definitions/uuid_array/items", - "$ref": "#/definitions/uuid" - } - }, - "vehicle_type_counts": { - "$id": "#/definitions/vehicle_type_counts", - "type": "object", - "properties": { - "bicycle": { - "$id": "#/definitions/vehicle_type_counts/properties/bicycle", - "type": "integer", - "minimum": 0 - }, - "cargo_bicycle": { - "$id": "#/definitions/vehicle_type_counts/properties/cargo_bicycle", - "type": "integer", - "minimum": 0 - }, - "car": { - "$id": "#/definitions/vehicle_type_counts/properties/car", - "type": "integer", - "minimum": 0 - }, - "scooter": { - "$id": "#/definitions/vehicle_type_counts/properties/scooter", - "type": "integer", - "minimum": 0 - }, - "moped": { - "$id": "#/definitions/vehicle_type_counts/properties/moped", - "type": "integer", - "minimum": 0 - }, - "other": { - "$id": "#/definitions/vehicle_type_counts/properties/other", - "type": "integer", - "minimum": 0 - } - }, - "additionalProperties": false - } - }, - "required": [ - "data", - "version", - "last_updated", - "ttl" - ], - "properties": { - "data": { - "$id": "#/properties/data", - "type": "object", - "description": "The data records in this payload", - "required": [ - "stops" - ], - "properties": { - "stops": { - "$id": "#/properties/data/properties/stops", - "type": "array", - "title": "The stops payload", - "items": { - "$id": "#/properties/data/properties/stops/items", - "$ref": "#/definitions/stop" - } - } - }, - "additionalProperties": false - }, - "version": { - "$id": "#/properties/version", - "$ref": "#/definitions/version" - }, - "last_updated": { - "$id": "#/properties/last_updated", - "$ref": "#/definitions/timestamp" - }, - "ttl": { - "$id": "#/properties/ttl", - "$ref": "#/definitions/ttl" - } - }, - "additionalProperties": false -} diff --git a/provider/trips.json b/provider/trips.json deleted file mode 100644 index f89c8748..00000000 --- a/provider/trips.json +++ /dev/null @@ -1,413 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/provider/trips.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "Schema for MDS Provider trips payloads", - "type": "object", - "definitions": { - "string": { - "$id": "#/definitions/string", - "type": "string", - "description": "A length-limited string type", - "maxLength": 255, - "default": "", - "examples": [ - "ABC123" - ], - "pattern": "^(.*)$" - }, - "timestamp": { - "$id": "#/definitions/timestamp", - "type": "number", - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - }, - "version": { - "$id": "#/definitions/version", - "type": "string", - "description": "The version of MDS this data represents", - "examples": [ - "1.2.0" - ], - "pattern": "^1\\.2\\.[0-9]+$" - }, - "MDS_Feature_Point": { - "$id": "#/definitions/MDS_Feature_Point", - "title": "MDS GeoJSON Feature Point", - "type": "object", - "required": [ - "type", - "properties", - "geometry" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Feature" - ] - }, - "id": { - "oneOf": [ - { - "type": "number" - }, - { - "type": "string" - } - ] - }, - "properties": { - "type": "object", - "required": [ - "timestamp" - ], - "properties": { - "timestamp": { - "$ref": "#/definitions/timestamp" - }, - "stop_id": { - "$ref": "#/definitions/uuid" - }, - "altitude": { - "type": "number", - "description": "Altitude above mean sea level in meters" - }, - "heading": { - "type": "number", - "description": "Degrees - clockwise starting at 0 degrees at true North" - }, - "speed": { - "type": "number", - "description": "Estimated speed in meters / sec as reported by the GPS chipset" - }, - "accuracy": { - "type": "number", - "description": "Horizontal accuracy, in meters" - }, - "hdop": { - "type": "number", - "description": "Horizontal GPS or GNSS accuracy value" - }, - "satellites": { - "type": "integer", - "description": "Number of GPS or GNSS satellites" - } - } - }, - "geometry": { - "$ref": "#/definitions/Point" - }, - "bbox": { - "type": "array", - "minItems": 4, - "items": { - "type": "number" - } - } - } - }, - "Point": { - "$id": "#/definitions/Point", - "title": "GeoJSON Point", - "type": "object", - "required": [ - "type", - "coordinates" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Point" - ] - }, - "coordinates": { - "type": "array", - "minItems": 2, - "items": [ - { - "type": "number", - "minimum": -180.0, - "maximum": 180.0 - }, - { - "type": "number", - "minimum": -90.0, - "maximum": 90.0 - } - ], - "maxItems": 2 - }, - "bbox": { - "type": "array", - "minItems": 4, - "items": { - "type": "number" - } - } - } - }, - "currency": { - "$id": "#/definitions/currency", - "type": [ - "string", - "null" - ], - "pattern": "^[A-Z]{3}$", - "default": "USD", - "description": "An ISO 4217 Alphabetic Currency Code representing currency of the payee. If null, USD cents is implied.", - "examples": [ - "USD", - "EUR", - "GBP" - ] - }, - "MDS_FeatureCollection_Route": { - "$id": "#/definitions/MDS_FeatureCollection_Route", - "title": "MDS GeoJSON FeatureCollection Route", - "type": "object", - "required": [ - "type", - "features" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "FeatureCollection" - ] - }, - "features": { - "type": "array", - "items": { - "$ref": "#/definitions/MDS_Feature_Point" - }, - "minItems": 2 - }, - "bbox": { - "type": "array", - "minItems": 4, - "items": { - "type": "number" - } - } - } - }, - "propulsion_type": { - "$id": "#/definitions/propulsion_type", - "type": "string", - "description": "The type of propulsion", - "enum": [ - "combustion", - "electric", - "electric_assist", - "human" - ] - }, - "propulsion_types": { - "$id": "#/definitions/propulsion_types", - "type": "array", - "description": "Array of propulsion types, allowing multiple values", - "items": { - "$id": "#/definitions/propulsion_types/items", - "$ref": "#/definitions/propulsion_type" - }, - "uniqueItems": true - }, - "vehicle_type": { - "$id": "#/definitions/vehicle_type", - "type": "string", - "description": "The type of vehicle", - "enum": [ - "bicycle", - "cargo_bicycle", - "car", - "scooter", - "moped", - "other" - ] - } - }, - "required": [ - "data", - "version" - ], - "properties": { - "data": { - "$id": "#/properties/data", - "type": "object", - "description": "The data records in this payload", - "required": [ - "trips" - ], - "properties": { - "trips": { - "$id": "#/properties/data/properties/trips", - "type": "array", - "title": "The trips payload", - "items": { - "$id": "#/properties/data/properties/trips/items", - "type": "object", - "title": "The trip item schema", - "additionalProperties": false, - "required": [ - "provider_name", - "provider_id", - "device_id", - "vehicle_id", - "vehicle_type", - "propulsion_types", - "trip_id", - "trip_duration", - "trip_distance", - "route", - "accuracy", - "start_time", - "end_time" - ], - "properties": { - "provider_name": { - "$id": "#/definitions/vehicle/properties/provider_name", - "$ref": "#/definitions/string", - "description": "The public-facing name of the Provider" - }, - "provider_id": { - "$id": "#/definitions/vehicle/properties/provider_id", - "$ref": "#/definitions/uuid", - "description": "The UUID for the Provider, unique within MDS" - }, - "device_id": { - "$id": "#/definitions/vehicle/properties/device_id", - "$ref": "#/definitions/uuid", - "description": "A unique device ID in UUID format" - }, - "vehicle_id": { - "$id": "#/definitions/vehicle/properties/vehicle_id", - "$ref": "#/definitions/string", - "description": "The Vehicle Identification Number visible on the vehicle itself" - }, - "vehicle_type": { - "$id": "#/definitions/vehicle/properties/vehicle_type", - "$ref": "#/definitions/vehicle_type", - "description": "The type of vehicle" - }, - "propulsion_types": { - "$id": "#/definitions/vehicle/properties/propulsion_types", - "$ref": "#/definitions/propulsion_types", - "description": "The type of propulsion; allows multiple values", - "minItems": 1 - }, - "trip_id": { - "$id": "#/properties/data/properties/trips/items/properties/trip_id", - "description": "A unique ID for each trip", - "$ref": "#/definitions/uuid" - }, - "trip_duration": { - "$id": "#/properties/data/properties/trips/items/properties/trip_duration", - "type": "integer", - "description": "The length of time, in seconds, that the trip lasted", - "default": 0, - "examples": [ - 600 - ] - }, - "trip_distance": { - "$id": "#/properties/data/properties/trips/items/properties/trip_distance", - "type": "integer", - "description": "The distance, in meters, that the trip covered", - "default": 0, - "examples": [ - 1000 - ] - }, - "route": { - "$id": "#/properties/data/properties/trips/items/properties/route", - "title": "The Route Schema", - "$ref": "#/definitions/MDS_FeatureCollection_Route" - }, - "accuracy": { - "$id": "#/properties/data/properties/trips/items/properties/accuracy", - "type": "integer", - "title": "The approximate level of accuracy, in meters, of Points within route", - "default": 0, - "examples": [ - 15 - ] - }, - "start_time": { - "$id": "#/properties/data/properties/trips/items/properties/start_time", - "description": "The time the trip began, expressed as a Unix Timestamp", - "$ref": "#/definitions/timestamp" - }, - "end_time": { - "$id": "#/properties/data/properties/trips/items/properties/end_time", - "description": "The time the trip ended, expressed as a Unix Timestamp", - "$ref": "#/definitions/timestamp" - }, - "publication_time": { - "$id": "#/properties/data/properties/trips/items/properties/publication_time", - "description": "The time the trip became available through the trips endpoint, expressed as a Unix Timestamp", - "$ref": "#/definitions/timestamp" - }, - "parking_verification_url": { - "$id": "#/properties/data/properties/trips/items/properties/parking_verification_url", - "type": [ - "string", - "null" - ], - "format": "uri", - "description": "A URL to a photo (or other evidence) of proper vehicle parking", - "examples": [ - "https://data.provider.co/parking_verify/1234.jpg" - ] - }, - "standard_cost": { - "$id": "#/properties/data/properties/trips/items/properties/standard_cost", - "type": [ - "integer", - "null" - ], - "description": "The cost, in the currency defined in `currency`, that it would cost to perform that trip in the standard operation of the System. If no currency is given, USD cents is implied.", - "examples": [ - 500 - ] - }, - "actual_cost": { - "$id": "#/properties/data/properties/trips/items/properties/actual_cost", - "type": [ - "integer", - "null" - ], - "description": "The actual cost, in the currency defined in `currency`, paid by the customer of the *mobility as a service* provider. If no currency is given, USD cents is implied.", - "examples": [ - 520 - ] - }, - "currency": { - "$id": "#/properties/data/properties/trips/items/properties/currency", - "$ref": "#/definitions/currency" - } - } - } - } - }, - "additionalProperties": false - }, - "version": { - "$id": "#/properties/version", - "$ref": "#/definitions/version" - } - }, - "additionalProperties": false -} diff --git a/provider/vehicles.json b/provider/vehicles.json deleted file mode 100644 index 6bda6bc3..00000000 --- a/provider/vehicles.json +++ /dev/null @@ -1,605 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/provider/vehicles.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "Schema for MDS Provider vehicles payloads", - "type": "object", - "definitions": { - "string": { - "$id": "#/definitions/string", - "type": "string", - "description": "A length-limited string type", - "maxLength": 255, - "default": "", - "examples": [ - "ABC123" - ], - "pattern": "^(.*)$" - }, - "timestamp": { - "$id": "#/definitions/timestamp", - "type": "number", - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - }, - "version": { - "$id": "#/definitions/version", - "type": "string", - "description": "The version of MDS this data represents", - "examples": [ - "1.2.0" - ], - "pattern": "^1\\.2\\.[0-9]+$" - }, - "MDS_Feature_Point": { - "$id": "#/definitions/MDS_Feature_Point", - "title": "MDS GeoJSON Feature Point", - "type": "object", - "required": [ - "type", - "properties", - "geometry" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Feature" - ] - }, - "id": { - "oneOf": [ - { - "type": "number" - }, - { - "type": "string" - } - ] - }, - "properties": { - "type": "object", - "required": [ - "timestamp" - ], - "properties": { - "timestamp": { - "$ref": "#/definitions/timestamp" - }, - "stop_id": { - "$ref": "#/definitions/uuid" - }, - "altitude": { - "type": "number", - "description": "Altitude above mean sea level in meters" - }, - "heading": { - "type": "number", - "description": "Degrees - clockwise starting at 0 degrees at true North" - }, - "speed": { - "type": "number", - "description": "Estimated speed in meters / sec as reported by the GPS chipset" - }, - "accuracy": { - "type": "number", - "description": "Horizontal accuracy, in meters" - }, - "hdop": { - "type": "number", - "description": "Horizontal GPS or GNSS accuracy value" - }, - "satellites": { - "type": "integer", - "description": "Number of GPS or GNSS satellites" - } - } - }, - "geometry": { - "$ref": "#/definitions/Point" - }, - "bbox": { - "type": "array", - "minItems": 4, - "items": { - "type": "number" - } - } - } - }, - "Point": { - "$id": "#/definitions/Point", - "title": "GeoJSON Point", - "type": "object", - "required": [ - "type", - "coordinates" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Point" - ] - }, - "coordinates": { - "type": "array", - "minItems": 2, - "items": [ - { - "type": "number", - "minimum": -180.0, - "maximum": 180.0 - }, - { - "type": "number", - "minimum": -90.0, - "maximum": 90.0 - } - ], - "maxItems": 2 - }, - "bbox": { - "type": "array", - "minItems": 4, - "items": { - "type": "number" - } - } - } - }, - "links": { - "$id": "#/definitions/links", - "type": "object", - "required": [ - "next" - ], - "properties": { - "first": { - "$id": "#/definitions/links/first", - "type": [ - "null", - "string" - ], - "title": "The URL to the first page of data", - "examples": [ - "https://data.provider.co/trips/first" - ], - "format": "uri" - }, - "last": { - "$id": "#/definitions/links/last", - "type": [ - "null", - "string" - ], - "title": "The URL to the last page of data", - "examples": [ - "https://data.provider.co/trips/last" - ], - "format": "uri" - }, - "prev": { - "$id": "#/definitions/links/prev", - "type": [ - "null", - "string" - ], - "title": "The URL to the previous page of data", - "examples": [ - "https://data.provider.co/trips/prev" - ], - "format": "uri" - }, - "next": { - "$id": "#/definitions/links/next", - "type": [ - "null", - "string" - ], - "title": "The URL to the next page of data", - "examples": [ - "https://data.provider.co/trips/next" - ], - "format": "uri", - "pattern": "^(.*)$" - } - }, - "additionalProperties": false - }, - "ttl": { - "$id": "#/definitions/ttl", - "type": "integer", - "description": "Integer milliseconds until next data update (0 if the data is always refreshed)", - "minimum": 0, - "maximum": 300000 - }, - "vehicle_state": { - "$id": "#/definitions/vehicle_state", - "type": "string", - "description": "The state of a vehicle", - "enum": [ - "available", - "elsewhere", - "non_operational", - "on_trip", - "removed", - "reserved", - "unknown" - ] - }, - "vehicle_event": { - "$id": "#/definitions/vehicle_event", - "type": "string", - "description": "An event that changes a vehicle's state", - "enum": [ - "agency_drop_off", - "agency_pick_up", - "battery_charged", - "battery_low", - "comms_lost", - "comms_restored", - "compliance_pick_up", - "decommissioned", - "located", - "maintenance", - "maintenance_pick_up", - "missing", - "off_hours", - "on_hours", - "provider_drop_off", - "rebalance_pick_up", - "reservation_cancel", - "reservation_start", - "system_resume", - "system_suspend", - "trip_cancel", - "trip_end", - "trip_enter_jurisdiction", - "trip_leave_jurisdiction", - "trip_start", - "unspecified" - ] - }, - "vehicle_events": { - "$id": "#/definitions/vehicle_events", - "type": "array", - "description": "Array of events indicating a change to a vehicle's state", - "uniqueItems": true, - "minItems": 1, - "items": { - "$ref": "#/definitions/vehicle_event" - } - }, - "propulsion_type": { - "$id": "#/definitions/propulsion_type", - "type": "string", - "description": "The type of propulsion", - "enum": [ - "combustion", - "electric", - "electric_assist", - "human" - ] - }, - "propulsion_types": { - "$id": "#/definitions/propulsion_types", - "type": "array", - "description": "Array of propulsion types, allowing multiple values", - "items": { - "$id": "#/definitions/propulsion_types/items", - "$ref": "#/definitions/propulsion_type" - }, - "uniqueItems": true - }, - "vehicle_type": { - "$id": "#/definitions/vehicle_type", - "type": "string", - "description": "The type of vehicle", - "enum": [ - "bicycle", - "cargo_bicycle", - "car", - "scooter", - "moped", - "other" - ] - } - }, - "required": [ - "data", - "version", - "last_updated", - "ttl" - ], - "properties": { - "data": { - "$id": "#/properties/data", - "type": "object", - "description": "The data records in this payload", - "required": [ - "vehicles" - ], - "properties": { - "vehicles": { - "$id": "#/properties/data/properties/vehicles", - "type": "array", - "title": "The vehicles payload", - "items": { - "$id": "#/properties/data/properties/vehicles/items", - "type": "object", - "title": "The vehicle item schema", - "required": [ - "provider_name", - "provider_id", - "device_id", - "vehicle_id", - "vehicle_type", - "propulsion_types", - "last_event_time", - "last_vehicle_state", - "last_event_types", - "last_event_location" - ], - "properties": { - "provider_name": { - "$id": "#/definitions/vehicle/properties/provider_name", - "$ref": "#/definitions/string", - "description": "The public-facing name of the Provider" - }, - "provider_id": { - "$id": "#/definitions/vehicle/properties/provider_id", - "$ref": "#/definitions/uuid", - "description": "The UUID for the Provider, unique within MDS" - }, - "device_id": { - "$id": "#/definitions/vehicle/properties/device_id", - "$ref": "#/definitions/uuid", - "description": "A unique device ID in UUID format" - }, - "vehicle_id": { - "$id": "#/definitions/vehicle/properties/vehicle_id", - "$ref": "#/definitions/string", - "description": "The Vehicle Identification Number visible on the vehicle itself" - }, - "vehicle_type": { - "$id": "#/definitions/vehicle/properties/vehicle_type", - "$ref": "#/definitions/vehicle_type", - "description": "The type of vehicle" - }, - "propulsion_types": { - "$id": "#/definitions/vehicle/properties/propulsion_types", - "$ref": "#/definitions/propulsion_types", - "description": "The type of propulsion; allows multiple values", - "minItems": 1 - }, - "last_event_time": { - "$id": "#/properties/data/properties/vehicles/items/properties/last_event_time", - "$ref": "#/definitions/timestamp", - "description": "The time the most recent status change event occurred, expressed as a Unix Timestamp" - }, - "last_vehicle_state": { - "$id": "#/properties/data/properties/vehicles/items/properties/last_vehicle_state", - "$ref": "#/definitions/vehicle_state", - "description": "The last known state of the vehicle" - }, - "last_event_types": { - "$id": "#/properties/data/properties/vehicles/items/properties/last_event_types", - "$ref": "#/definitions/vehicle_events", - "description": "The most recent event(s) that caused a change in the vehicle's state" - }, - "last_event_location": { - "$id": "#/properties/data/properties/vehicles/items/properties/last_event_location", - "$ref": "#/definitions/MDS_Feature_Point", - "description": "Location of the vehicle's last status change event" - }, - "current_location": { - "$id": "#/properties/data/properties/vehicles/items/properties/current_location", - "$ref": "#/definitions/MDS_Feature_Point", - "description": "Current location of vehicle if different from last event, and the vehicle is not currently on a trip" - }, - "battery_pct": { - "$id": "#/properties/data/properties/vehicles/items/properties/battery_pct", - "type": [ - "number", - "null" - ], - "description": "Percent charge of device battery, expressed between 0 and 1", - "examples": [ - 0.89 - ], - "minimum": 0, - "maximum": 1 - } - }, - "allOf": [ - { - "description": "Valid last_vehicle_state values for this endpoint", - "properties": { - "last_vehicle_state": { - "enum": [ - "available", - "elsewhere", - "non_operational", - "on_trip", - "removed", - "reserved", - "unknown" - ] - } - } - }, - { - "description": "valid vehicle_state and vehicle_events combinations", - "oneOf": [ - { - "properties": { - "last_vehicle_state": { - "const": "available" - }, - "last_event_types": { - "contains": { - "enum": [ - "agency_drop_off", - "battery_charged", - "comms_restored", - "located", - "maintenance", - "on_hours", - "provider_drop_off", - "reservation_cancel", - "system_resume", - "trip_cancel", - "trip_end", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "last_vehicle_state": { - "const": "elsewhere" - }, - "last_event_types": { - "contains": { - "enum": [ - "comms_restored", - "located", - "trip_leave_jurisdiction", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "last_vehicle_state": { - "const": "non_operational" - }, - "last_event_types": { - "contains": { - "enum": [ - "battery_low", - "comms_restored", - "located", - "maintenance", - "off_hours", - "system_suspend", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "last_vehicle_state": { - "const": "on_trip" - }, - "last_event_types": { - "contains": { - "enum": [ - "comms_restored", - "located", - "trip_enter_jurisdiction", - "trip_start", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "last_vehicle_state": { - "const": "removed" - }, - "last_event_types": { - "contains": { - "enum": [ - "agency_pick_up", - "comms_restored", - "compliance_pick_up", - "decommissioned", - "located", - "maintenance_pick_up", - "rebalance_pick_up", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "last_vehicle_state": { - "const": "reserved" - }, - "last_event_types": { - "contains": { - "enum": [ - "comms_restored", - "located", - "reservation_start", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "last_vehicle_state": { - "const": "unknown" - }, - "last_event_types": { - "contains": { - "enum": [ - "comms_lost", - "missing", - "unspecified" - ] - } - } - } - } - ] - } - ] - } - } - }, - "additionalProperties": false - }, - "version": { - "$id": "#/properties/version", - "$ref": "#/definitions/version" - }, - "links": { - "$id": "#/properties/links", - "$ref": "#/definitions/links" - }, - "last_updated": { - "$id": "#/properties/last_updated", - "$ref": "#/definitions/timestamp" - }, - "ttl": { - "$id": "#/properties/ttl", - "$ref": "#/definitions/ttl" - } - }, - "additionalProperties": false -} diff --git a/providers.csv b/providers.csv index 538108ce..b61e6dd1 100644 --- a/providers.csv +++ b/providers.csv @@ -48,3 +48,5 @@ Tembici,micromobility,46b28e68-8ecb-4875-b97e-836fd5e1930f,https://www.tembici.c POPPY Mobility,micromobility,5c869736-797f-4244-9132-fb50a22d1bfd,https://www.poppy.be/,https://poppy.red/mds, Whoosh,micromobility,3f8908a7-86fa-450d-8889-5d49077e06cd,https://whoosh.bike,https://mds.whoosh.bike, Telofun,micromobility,3dd253d3-557c-4fcb-98da-9af3edeaaae6,https://www.tel-o-fun.co.il/,https://mds.fsmctmobility.com/api/mds/v1/, +Gbike,micromobility,a50b796e-bca2-11ed-afa1-0242ac120002,https://gcoo.io/,https://mds.gcoo.io/,https://mds.gcoo.io/gbfs +SURF,micromobility,66c43ccb-f9f9-4f70-9707-37301b9f49a8,https://www.surfingscooters.com,https://api.app.surf/mds,https://api.app.surf/gbfs/en diff --git a/schema/README.md b/schema/README.md index 04200056..c3707631 100644 --- a/schema/README.md +++ b/schema/README.md @@ -1,34 +1,5 @@ # MDS Schema Definitions -This directory contains the templates and code that _generate_ the official JSON schemas for the Mobility Data Specification. However, the official schema documents live inside the `provider`, `agency` or appropriate folder. +See the external OMF GitHub repository [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) for more details and schema definitions, and browse the interactive API documentation on our [MDS Stoplight workspace](https://openmobilityfnd.stoplight.io/docs/mds-openapi/). -## Regenerating the Schemas - -At a command prompt within this `schema` directory run: - -```bash -python generate_schemas.py [--agency] [--geography] [--policy] [--provider] -``` - -The optional flags `--agency`, `--geography`, `--policy`, and `--provider` can be used to specify which -set of schemas to generate. The default is to generate all schemas. - -## Updating Schemas - -1. Edit the appropriate file(s) inside the the [`templates/`][templates] directory. - -1. Run the command to regenerate the schema(s). - -## Adding New Schemas - -1. Create a new template in the appropriate folder inside [`templates/`][templates]. See the existing templates for ideas. Remember to reference shared definitions from [`templates/common.json`][common-template]. - -1. Edit the appropriate `.py` file to add a function that creates the new schema as a `dict`. See the existing functions for ideas. The [`common` module][common-module] defines some shared functionality. - -1. Add your schema name and generator function to the collection in the `schema_generators()` function at the top of each `.py` file. - -1. Run the command to regenerate the schema(s). - -[common-module]: common.py -[common-template]: templates/common.json -[templates]: templates/ +Starting with MDS 2.0, [OpenAPI](https://www.openapis.org/) documents describe MDS endpoints and allow for schema validation, expanding on the prior JSON Schemas work. diff --git a/schema/__init__.py b/schema/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/schema/agency.py b/schema/agency.py deleted file mode 100644 index 9c7e41c0..00000000 --- a/schema/agency.py +++ /dev/null @@ -1,193 +0,0 @@ -""" -Schema generators for Agency endpoints. -""" - -import json - -import common - - -def vehicle_telemetry(): - telemetry = common.load_definitions("telemetry") - vehicle_telemetry = common.load_definitions("vehicle_telemetry") - - # merge the standard telemetry props into vehicle_telemetry.gps - vehicle_telemetry["properties"]["gps"]["properties"].update(telemetry["properties"]) - - return vehicle_telemetry - - -def get_stops_schema(): - """ - Create the schema for the Agency GET /stops endpoint. - """ - # load schema template and insert definitions - schema = common.load_json("./templates/agency/get_stops.json") - stops = common.stop_definitions() - schema["definitions"].update(stops) - - # verify and return - return common.check_schema(schema) - - -def post_stops_schema(): - """ - Create the schema for the Agency POST /stops endpoint. - """ - # load schema template and insert definitions - schema = common.load_json("./templates/agency/post_stops.json") - stops = common.stop_definitions() - schema["definitions"].update(stops) - - # verify and return - return common.check_schema(schema) - - -def put_stops_schema(): - """ - Create the schema for the Agency POST /stops endpoint. - """ - # load schema template and insert definitions - - # the PUT body allows a small subset of fields - schema = common.load_json("./templates/agency/put_stops.json") - - stops = common.stop_definitions() - needed_defs = ["stop_status", "uuid", "vehicle_type_counts"] - for key in [k for k in stops.keys() if k not in needed_defs]: - del stops[key] - - schema["definitions"].update(stops) - - # verify and return - return common.check_schema(schema) - - -def get_vehicle_schema(): - """ - Create the schema for the Agency GET /vehicles endpoint. - """ - # load schema template and insert definitions - schema = common.load_json("./templates/agency/get_vehicle.json") - definitions = common.load_definitions( - "propulsion_types", - "string", - "timestamp", - "vehicle_type", - "uuid" - ) - schema["definitions"].update(definitions) - - # merge the state machine definitions and transition combinations rule - state_machine_defs, transitions = common.vehicle_state_machine("state", "prev_events") - schema["definitions"].update(state_machine_defs) - schema["allOf"].append(transitions) - - # merge common vehicle information, with Agency tweaks - vehicle = common.vehicle_definition(provider_name=False) - schema["required"] = vehicle["required"] + schema["required"] - schema["properties"] = { **vehicle["properties"], **schema["properties"] } - - # verify and return - return common.check_schema(schema) - - -def post_vehicle_schema(): - """ - Create the schema for the Agency POST /vehicles endpoint. - """ - # load schema template and insert definitions - schema = common.load_json("./templates/agency/post_vehicle.json") - definitions = common.load_definitions( - "propulsion_types", - "string", - "vehicle_type", - "uuid" - ) - schema["definitions"].update(definitions) - - # merge common vehicle information, with Agency tweaks - vehicle = common.vehicle_definition(provider_name=False, provider_id=False) - - schema["required"] = vehicle["required"] + schema["required"] - schema["properties"] = { **vehicle["properties"], **schema["properties"] } - - # verify and return - return common.check_schema(schema) - - -def post_vehicle_event_schema(): - """ - Create the schema for the Agency POST /vehicles/:id/event endpoint. - """ - # load schema template and insert definitions - schema = common.load_json("./templates/agency/post_vehicle_event.json") - definitions = common.load_definitions( - "timestamp", - "uuid" - ) - definitions["vehicle_telemetry"] = vehicle_telemetry() - schema["definitions"].update(definitions) - - # merge the state machine definitions and transition combinations rule - state_machine_defs, transitions = common.vehicle_state_machine("vehicle_state", "event_types") - schema["definitions"].update(state_machine_defs) - schema["allOf"].append(transitions) - - # add the conditionally-required trip_id rule - trip_id_ref = common.load_definitions("trip_id_reference") - schema["allOf"].append(trip_id_ref) - - # verify and return - return common.check_schema(schema) - - -def post_vehicle_telemetry_schema(): - """ - Create the schema for the Agency POST /vehicles/telemetry endpoint. - """ - # load schema template and insert definitions - schema = common.load_json("./templates/agency/post_vehicle_telemetry.json") - definitions = common.load_definitions( - "timestamp", - "uuid" - ) - definitions["vehicle_telemetry"] = vehicle_telemetry() - schema["definitions"].update(definitions) - - # verify and return - return common.check_schema(schema) - - -def schema_generators(): - """ - The dict of schema generators for Agency. - - The key is the name of the schema file/template file. - The value is the generator function, taking a dict of common definitions as an argument. - The generator function should return the complete, validated schema document as a dict. - """ - return { - "get_vehicle": get_vehicle_schema, - "post_vehicle": post_vehicle_schema, - "post_vehicle_event": post_vehicle_event_schema, - "post_vehicle_telemetry": post_vehicle_telemetry_schema, - "post_stops": post_stops_schema, - "put_stops": put_stops_schema, - "get_stops": get_stops_schema - } - - -def write_schema_files(): - """ - Create each of the Agency endpoint schema files in the appropriate directory. - """ - print("\nStarting to generate Agency JSON Schemas...\n") - - for name, generator in schema_generators().items(): - schema = generator() - with open(f"../agency/{name}.json", "w") as schemafile: - schemafile.write(json.dumps(schema, indent=2)) - print(f"Wrote {name}.json") - - print("\nFinished generating Agency JSON Schemas") diff --git a/schema/common.py b/schema/common.py deleted file mode 100644 index cd0184fc..00000000 --- a/schema/common.py +++ /dev/null @@ -1,282 +0,0 @@ -""" -Shared functionality for schema generation. -""" - -import copy -import json -import jsonschema -import requests - - -COMMON_DEFINITIONS = {} - - -MDS_FEATURE_POINT = "MDS_Feature_Point" - - -def load_json(path): - """ - Load a JSON file from disk. - """ - with open(path) as f: - data = json.load(f) - return data - - -def definition_id(id): - """ - Generate a JSON Schema definition reference for the given id. - """ - return f"#/definitions/{id}" - - -def vehicle_definition(provider_name=True, provider_id=True): - """ - Extract a deep-copy of the common vehicle model definition to allow for customization. - """ - vehicle = copy.deepcopy(load_definitions("vehicle")) - - if not provider_name: - vehicle["required"].remove("provider_name") - del vehicle["properties"]["provider_name"] - - if not provider_id: - vehicle["required"].remove("provider_id") - del vehicle["properties"]["provider_id"] - - return vehicle - - -def vehicle_state_machine(vehicle_state=None, vehicle_events=None): - """ - Return a tuple (definitions, transitions) with the common vehicle state schema. - * defitions is the common definitions for vehicle state fields - * transitions is the rule for valid state/event combinations - - Optionally pass field names for the vehicle_state and vehicle_events schemas - to override those in transitions. - """ - state_machine_defs = load_definitions("vehicle_state", "vehicle_event", "vehicle_events") - transitions = copy.deepcopy(load_definitions("vehicle_state_transitions")) - - if vehicle_state: - for option in transitions["oneOf"]: - state = option["properties"]["vehicle_state"] - del option["properties"]["vehicle_state"] - option["properties"][vehicle_state] = state - - if vehicle_events: - for option in transitions["oneOf"]: - events = option["properties"]["vehicle_events"] - del option["properties"]["vehicle_events"] - option["properties"][vehicle_events] = events - - return (state_machine_defs, transitions) - - -def vehicle_type_counts_definition(definitions): - """ - Generate a definition for a dict of vehicle_type: int. - """ - vehicle_type_counts = {} - def_name = "vehicle_type_counts" - def_id = definition_id(def_name) - vehicle_types = definitions["vehicle_type"] - - for vehicle_type in vehicle_types["enum"]: - vehicle_type_counts[vehicle_type] = { - "$id": f"{def_id}/properties/{vehicle_type}", - "type": "integer", - "minimum": 0 - } - - return { - def_name: { - "$id": def_id, - "type": "object", - "properties": vehicle_type_counts, - "additionalProperties": False - } - } - - -def point_definition(): - """ - Get the canonical schema definition for a GeoJSON point. - """ - name = "Point" - point = requests.get("http://geojson.org/schema/Point.json").json() - - # Modify some metadata - point.pop("$schema") - point["$id"] = definition_id("Point") - - # enforce lat/lon bounds - point["properties"]["coordinates"]["maxItems"] = 2 - point["properties"]["coordinates"]["items"] = [ - { - "type": "number", - "minimum": -180.0, - "maximum": 180.0 - }, - { - "type": "number", - "minimum": -90.0, - "maximum": 90.0 - } - ] - - return { - name: point - } - - -def mds_feature_point_definition(definitions): - """ - Create a customized definition of the GeoJSON Feature schema for MDS Points. - """ - # Get the canonical Feature schema - feature = requests.get("http://geojson.org/schema/Feature.json").json() - - # Modify metadata - feature.pop("$schema") - feature["$id"] = definition_id(MDS_FEATURE_POINT) - feature["title"] = "MDS GeoJSON Feature Point" - - # Only allow GeoJSON Point feature geometry - feature["properties"]["geometry"] = { "$ref": definition_id("Point") } - - # Modfy properties definition/requirements - f_properties = feature["properties"]["properties"] - del f_properties["oneOf"] - f_properties["type"] = "object" - - # Point features must include the timestamp - f_properties["required"] = ["timestamp"] - - f_properties["properties"] = { - "timestamp": { - "$ref": definition_id("timestamp") - }, - # Locations corresponding to Stops must include a stop_id reference - "stop_id": { - "$ref": definition_id("uuid") - } - } - - # merge telemetry props - telemetry = definitions["telemetry"] - f_properties["properties"].update(telemetry["properties"]) - - return {MDS_FEATURE_POINT: feature} - - -def stop_definitions(): - """ - Return a dict of definitions needed for stops. - """ - definitions = load_definitions( - "stop", - "stop_status", - "string", - "timestamp", - "uuid", - "uuid_array", - "vehicle_type_counts", - MDS_FEATURE_POINT - ) - - return definitions - - -def property_definition(property_id, ref=""): - """ - Return a tuple (property, definition) of schema elements for the given id. - """ - # property ref definition - definition = { property_id: load_definitions(property_id) } - # the property - ref = ref or definition_id(property_id) - prop = { property_id: { "$id": f"#/properties/{property_id}", "$ref": ref } } - - return prop, definition - - -def load_definitions(*args, allow_null=False): - """ - Load the common.json definitions file, with some generated additions. - - If args are provided, filter to a dictionary of definitions using the args as keys. - - With only a single arg, return the definition with that key directly. - - If allow_null is True, override definition types to allow null. - """ - # store the definitions once globally after reading from the source file - global COMMON_DEFINITIONS - - if COMMON_DEFINITIONS == {}: - common = load_json("./templates/common.json") - common_definitions = common["definitions"] - - # MDS specific geography definition - mds_feature = mds_feature_point_definition(common_definitions) - common_definitions.update(mds_feature) - - # vehicle_type -> count definition - veh_type_counts = vehicle_type_counts_definition(common_definitions) - common_definitions.update(veh_type_counts) - - COMMON_DEFINITIONS = common_definitions - - # filter all definitions to those requested as args - if args and len(args) > 0: - _d = { key: COMMON_DEFINITIONS.get(key) for key in args } - else: - _d = COMMON_DEFINITIONS - - # create a deepcopy for possible modifications - definitions = copy.deepcopy(_d) - - # modify definitions to allow null - if allow_null: - # get all definitions with a type property - typekey = "type" - typedefs = { k: v for k, v in definitions.items() if typekey in v } - for key, defn in typedefs.items(): - nullkey = f"null_{key}" - - # for reference definitions, override the reference to the null version - if "$ref" in defn: - refid = defn["$ref"].split("/") - refid[-1] = f"null_{refid[-1]}" - - defn["$ref"] = "/".join(refid) - # for type definitions, create a new definition allowing null - else: - defnid = defn["$id"].split("/") - defnid[-1] = f"null_{defnid[-1]}" - - nulldefn = copy.deepcopy(defn) - nulldefn["$id"] = "/".join(defnid) - - if isinstance(nulldefn[typekey], str): - nulldefn[typekey] = [nulldefn[typekey]] - if "null" not in nulldefn[typekey]: - nulldefn[typekey].append("null") - # add the null definition to the definitions dict - definitions[nullkey] = nulldefn - - # if there was only one arg, return the definition directly - return definitions.get(args[0]) if len(args) == 1 else definitions - - -def check_schema(schema): - """ - Check the validity of the given schema document under Draft 7 of the JSON Schema spec. - - Returns the (valid) schema instance. - """ - jsonschema.Draft7Validator.check_schema(schema) - - return schema diff --git a/schema/generate_schemas.py b/schema/generate_schemas.py deleted file mode 100644 index 01454588..00000000 --- a/schema/generate_schemas.py +++ /dev/null @@ -1,36 +0,0 @@ -""" -Generate the JSON Schema documents for MDS endpoints. - -USAGE: - python generate_schemas.py [--agency] [--geography] [--policy] [--provider] -""" - -import sys - -import agency -import geography -import policy -import provider - - -if __name__ == "__main__": - if len(sys.argv) == 1: - agency.write_schema_files() - geography.write_schema_files() - policy.write_schema_files() - provider.write_schema_files() - else: - if "--agency" in sys.argv: - agency.write_schema_files() - sys.argv.remove("--agency") - if "--geography" in sys.argv: - geography.write_schema_files() - sys.argv.remove("--geography") - if "--policy" in sys.argv: - policy.write_schema_files() - sys.argv.remove("--policy") - if "--provider" in sys.argv: - provider.write_schema_files() - sys.argv.remove("--provider") - if len(sys.argv) > 1: - print(__doc__) diff --git a/schema/geography.py b/schema/geography.py deleted file mode 100644 index 125402fd..00000000 --- a/schema/geography.py +++ /dev/null @@ -1,71 +0,0 @@ -""" -Schema generators for Geography endpoints. -""" - -import json - -import common - - -def geography_schema(): - """ - Create the schema for the Geography endpoint. - """ - # load schema template and insert definitions - schema = common.load_json("./templates/geography/geography.json") - definitions = common.load_definitions( - "string", - "timestamp", - "uuid", - "version" - ) - definitions.update(common.load_definitions( - "timestamp", - "uuid_array", - allow_null=True - )) - schema["definitions"].update(definitions) - - # verify and return - return common.check_schema(schema) - - -def geographies_schema(): - """ - Create the schema for the Geographies endpoint. - """ - # load schema template and insert definitions from geography - geography = geography_schema() - schema = common.load_json("./templates/geography/geographies.json") - schema["definitions"].update(geography["definitions"]) - - return common.check_schema(schema) - - -def schema_generators(): - """ - The dict of schema generators for Geography. - - The key is the name of the schema file/template file. - The value is the generator function, taking a dict of common definitions as an argument. - The generator function should return the complete, validated schema document as a dict. - """ - return { - "geography": geography_schema, - "geographies": geographies_schema - } - - -def write_schema_files(): - """ - Create each of the Geography endpoint schema files in the appropriate directory. - """ - print("\nStarting to generate Geography JSON Schemas...\n") - - for name, generator in schema_generators().items(): - schema = generator() - with open(f"../geography/{name}.json", "w") as schemafile: - schemafile.write(json.dumps(schema, indent=2)) - print(f"Wrote {name}.json") - - print("\nFinished generating Geography JSON Schemas") diff --git a/schema/policy.py b/schema/policy.py deleted file mode 100644 index 5d2ae8b4..00000000 --- a/schema/policy.py +++ /dev/null @@ -1,69 +0,0 @@ -""" -Schema generators for Policy endpoints. -""" - -import json - -import common - - -def policy_schema(): - """ - Create the schema for the Policy endpoint. - """ - # load schema template and insert definitions - schema = common.load_json("./templates/policy/policy.json") - definitions = common.load_definitions( - "currency", - "day", - "propulsion_type", - "string", - "timestamp", - "uuid", - "uuid_array", - "vehicle_event", - "vehicle_state", - "vehicle_type", - "version" - ) - definitions.update(common.load_definitions( - "days", - "iso_time", - "propulsion_types", - "timestamp", - "uuid_array", - "vehicle_types", - allow_null=True - )) - schema["definitions"].update(definitions) - - # verify and return - return common.check_schema(schema) - - -def schema_generators(): - """ - The dict of schema generators for Policy. - - The key is the name of the schema file/template file. - The value is the generator function, taking a dict of common definitions as an argument. - The generator function should return the complete, validated schema document as a dict. - """ - return { - "policy": policy_schema - } - - -def write_schema_files(): - """ - Create each of the Policy endpoint schema files in the appropriate directory. - """ - print("\nStarting to generate Policy JSON Schemas...\n") - - for name, generator in schema_generators().items(): - schema = generator() - with open(f"../policy/{name}.json", "w") as schemafile: - schemafile.write(json.dumps(schema, indent=2)) - print(f"Wrote {name}.json") - - print("\nFinished generating Policy JSON Schemas") diff --git a/schema/provider.py b/schema/provider.py deleted file mode 100644 index cb8efad9..00000000 --- a/schema/provider.py +++ /dev/null @@ -1,226 +0,0 @@ -""" -Schema generators for Provider endpoints. -""" - -import json -import requests - -import common - - -def feature_collection_schema(id=None, title=None, features=None): - """ - Get the canonical schema for a GeoJSON Feature Collection, - and make any given modifications. - - :id: overrides the `$id` metadata - :title: overrides the `title` metadata - :features: overrides the allowed `features` for the FeatureCollection - """ - # Get the canonical FeatureCollection schema - feature_collection = requests.get("http://geojson.org/schema/FeatureCollection.json").json() - - # Modify some metadata - feature_collection.pop("$schema") - if id is not None: - feature_collection["$id"] = id - if title is not None: - feature_collection["title"] = title - - if features is not None: - fc_features = feature_collection["properties"]["features"] - feature_collection["properties"]["features"] = { **fc_features, **features } - - return feature_collection - - -def endpoint_schema(endpoint, extra_definitions={}): - """ - Generate the Provider payload schema for the given endpoint. - """ - # load common schema template and update metadata - schema = common.load_json("./templates/provider/endpoint.json") - schema["$id"] = schema["$id"].replace("endpoint.json", f"{endpoint}.json") - schema["title"] = schema["title"].replace("endpoint", endpoint) - - # merge custom definitions with relevant common definitions - definitions = common.load_definitions( - "string", - "timestamp", - "uuid", - "version", - common.MDS_FEATURE_POINT - ) - definitions.update(common.point_definition()) - definitions.update(extra_definitions) - - endpoint_schema = common.load_json(f"./templates/provider/{endpoint}.json") - - # for all but stops, merge standard vehicle info with items schema - if endpoint not in ["stops"]: - items = endpoint_schema[endpoint]["items"] - vehicle = common.vehicle_definition() - items["required"] = vehicle["required"] + items["required"] - items["properties"] = { **vehicle["properties"], **items["properties"] } - definitions.update(common.load_definitions("propulsion_type", "propulsion_types", "vehicle_type")) - - # merge endpoint schema into the endpoint template - data_schema = schema["properties"]["data"] - data_schema["required"] = [endpoint] - data_schema["properties"] = endpoint_schema - - # insert definitions - schema["definitions"].update(definitions) - - return schema - - -def trips_schema(): - """ - Create the schema for the /trips endpoint. - """ - # generate the route definition - mds_feature_collection_route = feature_collection_schema( - id = common.definition_id("MDS_FeatureCollection_Route"), - title = "MDS GeoJSON FeatureCollection Route", - # 1. Only allow MDS Feature Points - # 2. There must be *at least* two Features in the FeatureCollection. - features = { "items": { "$ref": common.definition_id("MDS_Feature_Point") }, "minItems": 2 } - ) - trips_definitions = { - "currency": common.load_definitions("currency"), - "MDS_FeatureCollection_Route": mds_feature_collection_route - } - - # create the trips schema - schema = endpoint_schema("trips", trips_definitions) - - # verify and return - return common.check_schema(schema) - - -def status_changes_schema(): - """ - Create the schema for the /status_changes endpoint. - """ - schema = endpoint_schema("status_changes") - items = schema["properties"]["data"]["properties"]["status_changes"]["items"] - - # merge the state machine definitions and transition combinations rule - state_machine_defs, transitions = common.vehicle_state_machine("vehicle_state", "event_types") - schema["definitions"].update(state_machine_defs) - items["allOf"].append(transitions) - - trip_id_ref = common.load_definitions("trip_id_reference") - items["allOf"].append(trip_id_ref) - - # verify and return - return common.check_schema(schema) - - -def events_schema(): - """ - Create the schema for the /events endpoint. - """ - links_prop, links_def = common.property_definition("links") - - # events is the same as status_changes, but allows paging - schema = status_changes_schema() - schema["$id"] = schema["$id"].replace("status_changes", "events") - schema["title"] = schema["title"].replace("status_changes", "events") - schema["definitions"].update(links_def) - schema["properties"].update(links_prop) - - # verify and return - return common.check_schema(schema) - - -def stops_schema(): - """ - Create the schema for the /stops endpoint. - """ - definitions, properties = {}, {} - - prop, _ = common.property_definition("last_updated", ref=common.definition_id("timestamp")) - properties.update(prop) - - prop, defn = common.property_definition("ttl") - definitions.update(defn) - properties.update(prop) - - stop_defs = common.stop_definitions() - definitions.update(stop_defs) - - schema = endpoint_schema("stops", definitions) - - # update list of required and properties object - schema["required"].extend(["last_updated", "ttl"]) - schema["properties"].update(properties) - - # verify and return - return common.check_schema(schema) - - -def vehicles_schema(): - """ - Create the schema for the /vehicles endpoint. - """ - definitions, properties = {}, {} - - prop, defn = common.property_definition("links") - definitions.update(defn) - properties.update(prop) - - prop, _ = common.property_definition("last_updated", ref=common.definition_id("timestamp")) - properties.update(prop) - - prop, defn = common.property_definition("ttl") - definitions.update(defn) - properties.update(prop) - - state_defs, transitions = common.vehicle_state_machine("last_vehicle_state", "last_event_types") - definitions.update(state_defs) - - schema = endpoint_schema("vehicles", definitions) - - # update list of required and properties object - schema["required"].extend(["last_updated", "ttl"]) - schema["properties"].update(properties) - - # add state machine transition rules - schema["properties"]["data"]["properties"]["vehicles"]["items"]["allOf"].append(transitions) - - # verify and return - return common.check_schema(schema) - - -def schema_generators(): - """ - The dict of schema generators for Provider. - - The key is the name of the schema file/template file. - The value is the generator function, taking a dict of common definitions as an argument. - The generator function should return the complete, validated schema document as a dict. - """ - return { - "trips": trips_schema, - "status_changes": status_changes_schema, - "events": events_schema, - "vehicles": vehicles_schema, - "stops": stops_schema - } - - -def write_schema_files(): - """ - Create each of the Provider endpoint schema files in the appropriate directory. - """ - print("\nStarting to generate Provider JSON Schemas...\n") - - for name, generator in schema_generators().items(): - schema = generator() - with open(f"../provider/{name}.json", "w") as schemafile: - schemafile.write(json.dumps(schema, indent=2)) - print(f"Wrote {name}.json") - - print("\nFinished generating Provider JSON Schemas") diff --git a/schema/requirements.txt b/schema/requirements.txt deleted file mode 100644 index fb758e7a..00000000 --- a/schema/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -jsonschema==3.0.1 -requests diff --git a/schema/templates/agency/get_stops.json b/schema/templates/agency/get_stops.json deleted file mode 100644 index 128930ae..00000000 --- a/schema/templates/agency/get_stops.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/agency/get_stops.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Agency Schema, GET stops payload", - "type": "object", - "definitions": {}, - "required": [ - "stops" - ], - "properties": { - "stops": { - "$id": "#/properties/stops", - "type": "array", - "description": "The array of stops", - "items": { - "$ref": "#/definitions/stop" - } - } - }, - "additionalProperties": false -} \ No newline at end of file diff --git a/schema/templates/agency/get_vehicle.json b/schema/templates/agency/get_vehicle.json deleted file mode 100644 index 048fff66..00000000 --- a/schema/templates/agency/get_vehicle.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/agency/get_vehicle.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Agency Schema, GET vehicle payload", - "type": "object", - "definitions": {}, - "required": [ - "year", - "mfgr", - "model", - "state", - "prev_events", - "updated" - ], - "properties": { - "year": { - "$id": "#/properties/year", - "type": "integer", - "description": "The year the vehicle was manufactured", - "default": 1970, - "examples": [ - 2018 - ] - }, - "mfgr": { - "$id": "#/properties/mfgr", - "$ref": "#/definitions/string", - "description": "The vehicle manufacturer" - }, - "model": { - "$id": "#/properties/model", - "$ref": "#/definitions/string", - "description": "The vehicle model" - }, - "state": { - "$id": "#/properties/state", - "$ref": "#/definitions/vehicle_state", - "description": "Current vehicle state" - }, - "prev_events": { - "$id": "#/properties/prev_events", - "$ref": "#/definitions/vehicle_events", - "description": "Last vehicle event" - }, - "updated": { - "$id": "#/properties/updated", - "$ref": "#/definitions/timestamp" - } - }, - "additionalProperties": false, - "allOf": [] -} diff --git a/schema/templates/agency/post_stops.json b/schema/templates/agency/post_stops.json deleted file mode 100644 index ba53da2d..00000000 --- a/schema/templates/agency/post_stops.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/agency/post_stops.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Agency Schema, register Stops", - "type": "object", - "definitions": {}, - "required": [ - "stops" - ], - "properties": { - "stops": { - "$id": "#/properties/stops", - "type": "array", - "description": "The array of stops", - "items": { - "$ref": "#/definitions/stop" - } - } - }, - "additionalProperties": false - } - \ No newline at end of file diff --git a/schema/templates/agency/post_vehicle.json b/schema/templates/agency/post_vehicle.json deleted file mode 100644 index ec58eba8..00000000 --- a/schema/templates/agency/post_vehicle.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/agency/post_vehicle.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Agency Schema, register vehicle body", - "type": "object", - "definitions": {}, - "required": [], - "properties": { - "year": { - "$id": "#/properties/year", - "type": "integer", - "description": "The year the vehicle was manufactured", - "default": 1970, - "examples": [ - 2018 - ] - }, - "mfgr": { - "$id": "#/properties/mfgr", - "$ref": "#/definitions/string", - "description": "The vehicle manufacturer" - }, - "model": { - "$id": "#/properties/model", - "$ref": "#/definitions/string", - "description": "The vehicle model" - } - }, - "additionalProperties": false -} diff --git a/schema/templates/agency/post_vehicle_event.json b/schema/templates/agency/post_vehicle_event.json deleted file mode 100644 index d7b4dfdc..00000000 --- a/schema/templates/agency/post_vehicle_event.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/agency/post_vehicle_event.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Agency Schema, POST vehicle status body", - "type": "object", - "definitions": {}, - "required": [ - "vehicle_state", - "event_types", - "timestamp", - "telemetry" - ], - "properties": { - "vehicle_state": { - "$ref": "#/definitions/vehicle_state" - }, - "event_types": { - "$ref": "#/definitions/vehicle_events" - }, - "timestamp": { - "$ref": "#/definitions/timestamp" - }, - "telemetry": { - "$ref": "#/definitions/vehicle_telemetry" - }, - "trip_id": { - "$ref": "#/definitions/uuid" - } - }, - "additionalProperties": false, - "allOf": [] -} diff --git a/schema/templates/agency/post_vehicle_telemetry.json b/schema/templates/agency/post_vehicle_telemetry.json deleted file mode 100644 index f7ad99f9..00000000 --- a/schema/templates/agency/post_vehicle_telemetry.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/agency/post_vehicle_telemetry.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Agency Schema, POST vehicle telemetry body", - "type": "object", - "definitions": {}, - "required": [ - "data" - ], - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/definitions/vehicle_telemetry" - } - } - }, - "additionalProperties": false -} diff --git a/schema/templates/agency/put_stops.json b/schema/templates/agency/put_stops.json deleted file mode 100644 index cf904d10..00000000 --- a/schema/templates/agency/put_stops.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/agency/put_stops.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Agency Schema, update Stops", - "type": "object", - "definitions": {}, - "required": [ - "stops" - ], - "properties": { - "stops": { - "$id": "#/properties/stops", - "type": "array", - "description": "The array of stops", - "items": { - "type": "object", - "required": [ - "stop_id" - ], - "properties": { - "stop_id": { - "$ref": "#/definitions/uuid" - }, - "status": { - "$ref": "#/definitions/stop_status" - }, - "num_spots_disabled": { - "$ref": "#/definitions/vehicle_type_counts" - } - } - } - } - }, - "additionalProperties": false - } - \ No newline at end of file diff --git a/schema/templates/common.json b/schema/templates/common.json deleted file mode 100644 index 08919fd1..00000000 --- a/schema/templates/common.json +++ /dev/null @@ -1,722 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/schema/templates/common.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "Common schema definitions for MDS", - "definitions": { - "area_type": { - "$id": "#/definitions/area_type", - "type": "string", - "description": "The type of a service area", - "enum": [ - "unrestricted", - "restricted", - "preferred_pick_up", - "preferred_drop_off" - ] - }, - "currency": { - "$id": "#/definitions/currency", - "type": [ - "string", - "null" - ], - "pattern": "^[A-Z]{3}$", - "default": "USD", - "description": "An ISO 4217 Alphabetic Currency Code representing currency of the payee. If null, USD cents is implied.", - "examples": [ - "USD", - "EUR", - "GBP" - ] - }, - "day": { - "$id": "#/definitions/day", - "type": "string", - "description": "A day of the week", - "enum": [ - "sun", - "mon", - "tue", - "wed", - "thu", - "fri", - "sat" - ] - }, - "days": { - "$id": "#/definitions/days", - "type": "array", - "description": "Array of days of the week", - "items": { - "$id": "#/definitions/days/items", - "$ref": "#/definitions/day" - }, - "uniqueItems": true - }, - "iso_time": { - "$id": "#/definitions/iso_time", - "type": "string", - "description": "Time-of-day expressed as ISO 8601 hh:mm:ss", - "pattern": "([0-2][0-3]|[0-1][0-9]):[0-5][0-9]:[0-5][0-9]" - }, - "links": { - "$id": "#/definitions/links", - "type": "object", - "required": [ - "next" - ], - "properties": { - "first": { - "$id": "#/definitions/links/first", - "type": [ - "null", - "string" - ], - "title": "The URL to the first page of data", - "examples": [ - "https://data.provider.co/trips/first" - ], - "format": "uri" - }, - "last": { - "$id": "#/definitions/links/last", - "type": [ - "null", - "string" - ], - "title": "The URL to the last page of data", - "examples": [ - "https://data.provider.co/trips/last" - ], - "format": "uri" - }, - "prev": { - "$id": "#/definitions/links/prev", - "type": [ - "null", - "string" - ], - "title": "The URL to the previous page of data", - "examples": [ - "https://data.provider.co/trips/prev" - ], - "format": "uri" - }, - "next": { - "$id": "#/definitions/links/next", - "type": [ - "null", - "string" - ], - "title": "The URL to the next page of data", - "examples": [ - "https://data.provider.co/trips/next" - ], - "format": "uri", - "pattern": "^(.*)$" - } - }, - "additionalProperties": false - }, - "propulsion_type": { - "$id": "#/definitions/propulsion_type", - "type": "string", - "description": "The type of propulsion", - "enum": [ - "combustion", - "electric", - "electric_assist", - "human" - ] - }, - "propulsion_types": { - "$id": "#/definitions/propulsion_types", - "type": "array", - "description": "Array of propulsion types, allowing multiple values", - "items": { - "$id": "#/definitions/propulsion_types/items", - "$ref": "#/definitions/propulsion_type" - }, - "uniqueItems": true - }, - "rental_methods": { - "$id": "#/definitions/rental_methods", - "type": "array", - "description": "Payment methods accepted at this Stop. From GBFS Station Information.", - "items": { - "enum": [ - "KEY", - "CREDITCARD", - "PAYPASS", - "APPLEPAY", - "ANDROIDPAY", - "TRANSITCARD", - "ACCOUNTNUMBER", - "PHONE" - ] - }, - "uniqueItems": true - }, - "stop": { - "$id": "#/definitions/stop", - "type": "object", - "description": "The common schema elements for a Stop in MDS", - "required": [ - "stop_id", - "name", - "last_reported", - "location", - "status", - "capacity", - "num_vehicles_available", - "num_vehicles_disabled" - ], - "properties": { - "stop_id": { - "$id": "#/definitions/stop/properties/stop_id", - "$ref": "#/definitions/uuid", - "description": "UUID for the Stop" - }, - "name": { - "$id": "#/definitions/stop/properties/name", - "$ref": "#/definitions/string", - "description": "Name of the Stop" - }, - "last_reported": { - "$id": "#/definitions/stop/properties/last_reported", - "$ref": "#/definitions/timestamp", - "description": "Date/Time of the last status update for this Stop" - }, - "location": { - "$id": "#/definitions/stop/properties/location", - "$ref": "#/definitions/MDS_Feature_Point", - "description": "Location of the stop" - }, - "status": { - "$id": "#/definitions/stop/properties/status", - "$ref": "#/definitions/stop_status", - "description": "The status of the Stop" - }, - "capacity": { - "$id": "#/definitions/stop/properties/capacity", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of total places per vehicle_type" - }, - "num_vehicles_available": { - "$id": "#/definitions/stop/properties/num_vehicles_available", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of available vehicles per vehicle_type" - }, - "num_vehicles_disabled": { - "$id": "#/definitions/stop/properties/num_vehicles_disabled", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of non_operational/reserved vehicles per vehicle_type" - }, - "provider_id": { - "$id": "#/definitions/stop/properties/provider_id", - "$ref": "#/definitions/uuid", - "description": "UUID for the Provider managing this Stop. Null/undefined if managed by an Agency." - }, - "geography_id": { - "$id": "#/definitions/stop/properties/geography_id", - "$ref": "#/definitions/uuid", - "description": "UUID for the Stop" - }, - "region_id": { - "$id": "#/definitions/stop/properties/region_id", - "$ref": "#/definitions/string", - "description": "ID of the region where the Stop is located. See GBFS Station Information." - }, - "short_name": { - "$id": "#/definitions/stop/properties/short_name", - "$ref": "#/definitions/string", - "description": "Abbreviated Stop name" - }, - "address": { - "$id": "#/definitions/stop/properties/address", - "$ref": "#/definitions/string", - "description": "Postal address (useful for directions)" - }, - "post_code": { - "$id": "#/definitions/stop/properties/post_code", - "$ref": "#/definitions/string", - "description": "Postal code (e.g. 10036)" - }, - "cross_street": { - "$id": "#/definitions/stop/properties/cross_street", - "$ref": "#/definitions/string", - "description": "Cross street of where Stop is located" - }, - "num_places_available": { - "$id": "#/definitions/stop/properties/num_places_available", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of places free to be populated per vehicle_type" - }, - "num_places_disabled": { - "$id": "#/definitions/stop/properties/num_places_disabled", - "$ref": "#/definitions/vehicle_type_counts", - "description": "Number of places disabled an unable to accept vehicles per vehicle_type" - }, - "parent_stop": { - "$id": "#/definitions/stop/properties/parent_stop", - "$ref": "#/definitions/uuid", - "description": "Describe a basic hierarchy of Stops (e.g. a Stop inside a greater Stop)" - }, - "devices": { - "$id": "#/definitions/stop/properties/devices", - "$ref": "#/definitions/uuid_array", - "description": "List of device_id for vehicles currently at this Stop." - } - } - }, - "stop_status": { - "$id": "#/definitions/stop_status", - "type": "object", - "description": "Status object for a Stop in MDS", - "required": [ - "is_installed", - "is_renting", - "is_returning" - ], - "properties": { - "is_installed": { - "$id": "#/definitions/stop_status/properties/is_installed", - "type": "boolean" - }, - "is_renting": { - "$id": "#/definitions/stop_status/properties/is_renting", - "type": "boolean" - }, - "is_returning": { - "$id": "#/definitions/stop_status/properties/is_returning", - "type": "boolean" - } - } - }, - "string": { - "$id": "#/definitions/string", - "type": "string", - "description": "A length-limited string type", - "maxLength": 255, - "default": "", - "examples": [ - "ABC123" - ], - "pattern": "^(.*)$" - }, - "telemetry": { - "$id": "#/definitions/telemetry", - "type": "object", - "description": "A telemetry datum", - "additionalProperties": false, - "properties": { - "altitude": { - "type": "number", - "description": "Altitude above mean sea level in meters" - }, - "heading": { - "type": "number", - "description": "Degrees - clockwise starting at 0 degrees at true North" - }, - "speed": { - "type": "number", - "description": "Estimated speed in meters / sec as reported by the GPS chipset" - }, - "accuracy": { - "type": "number", - "description": "Horizontal accuracy, in meters" - }, - "hdop": { - "type": "number", - "description": "Horizontal GPS or GNSS accuracy value" - }, - "satellites": { - "type": "integer", - "description": "Number of GPS or GNSS satellites" - } - } - }, - "timestamp": { - "$id": "#/definitions/timestamp", - "type": "number", - "description": "Integer milliseconds since Unix epoch", - "multipleOf": 1.0, - "minimum": 1514764800000 - }, - "trip_id_reference": { - "description": "Conditionally require a trip_id reference", - "anyOf": [ - { - "not": { - "properties": { - "event_types": { - "contains": { - "enum": [ - "trip_cancel", - "trip_end", - "trip_enter_jurisdiction", - "trip_leave_jurisdiction", - "trip_start" - ] - } - } - } - } - }, - { - "required": [ - "trip_id" - ] - } - ] - }, - "ttl": { - "$id": "#/definitions/ttl", - "type": "integer", - "description": "Integer milliseconds until next data update (0 if the data is always refreshed)", - "minimum": 0, - "maximum": 300000 - }, - "uuid": { - "$id": "#/definitions/uuid", - "type": "string", - "description": "A UUID used to uniquely identifty an object", - "default": "", - "examples": [ - "3c9604d6-b5ee-11e8-96f8-529269fb1459" - ], - "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" - }, - "uuid_array": { - "$id": "#/definitions/uuid_array", - "type": "array", - "description": "Array of UUID", - "items": { - "$id": "#/definitions/uuid_array/items", - "$ref": "#/definitions/uuid" - } - }, - "vehicle": { - "$id": "#/definitions/vehicle", - "type": "object", - "description": "The common schema elements for a Vehicle in MDS", - "required": [ - "provider_name", - "provider_id", - "device_id", - "vehicle_id", - "vehicle_type", - "propulsion_types" - ], - "properties": { - "provider_name": { - "$id": "#/definitions/vehicle/properties/provider_name", - "$ref": "#/definitions/string", - "description": "The public-facing name of the Provider" - }, - "provider_id": { - "$id": "#/definitions/vehicle/properties/provider_id", - "$ref": "#/definitions/uuid", - "description": "The UUID for the Provider, unique within MDS" - }, - "device_id": { - "$id": "#/definitions/vehicle/properties/device_id", - "$ref": "#/definitions/uuid", - "description": "A unique device ID in UUID format" - }, - "vehicle_id": { - "$id": "#/definitions/vehicle/properties/vehicle_id", - "$ref": "#/definitions/string", - "description": "The Vehicle Identification Number visible on the vehicle itself" - }, - "vehicle_type": { - "$id": "#/definitions/vehicle/properties/vehicle_type", - "$ref": "#/definitions/vehicle_type", - "description": "The type of vehicle" - }, - "propulsion_types": { - "$id": "#/definitions/vehicle/properties/propulsion_types", - "$ref": "#/definitions/propulsion_types", - "description": "The type of propulsion; allows multiple values", - "minItems": 1 - } - }, - "additionalProperties": false - }, - "vehicle_event": { - "$id": "#/definitions/vehicle_event", - "type": "string", - "description": "An event that changes a vehicle's state", - "enum": [ - "agency_drop_off", - "agency_pick_up", - "battery_charged", - "battery_low", - "comms_lost", - "comms_restored", - "compliance_pick_up", - "decommissioned", - "located", - "maintenance", - "maintenance_pick_up", - "missing", - "off_hours", - "on_hours", - "provider_drop_off", - "rebalance_pick_up", - "reservation_cancel", - "reservation_start", - "system_resume", - "system_suspend", - "trip_cancel", - "trip_end", - "trip_enter_jurisdiction", - "trip_leave_jurisdiction", - "trip_start", - "unspecified" - ] - }, - "vehicle_events": { - "$id": "#/definitions/vehicle_events", - "type": "array", - "description": "Array of events indicating a change to a vehicle's state", - "uniqueItems": true, - "minItems": 1, - "items": { - "$ref": "#/definitions/vehicle_event" - } - }, - "vehicle_state": { - "$id": "#/definitions/vehicle_state", - "type": "string", - "description": "The state of a vehicle", - "enum": [ - "available", - "elsewhere", - "non_operational", - "on_trip", - "removed", - "reserved", - "unknown" - ] - }, - "vehicle_state_transitions": { - "description": "valid vehicle_state and vehicle_events combinations", - "oneOf": [ - { - "properties": { - "vehicle_state": { - "const": "available" - }, - "vehicle_events": { - "contains": { - "enum": [ - "agency_drop_off", - "battery_charged", - "comms_restored", - "located", - "maintenance", - "on_hours", - "provider_drop_off", - "reservation_cancel", - "system_resume", - "trip_cancel", - "trip_end", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "elsewhere" - }, - "vehicle_events": { - "contains": { - "enum": [ - "comms_restored", - "located", - "trip_leave_jurisdiction", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "non_operational" - }, - "vehicle_events": { - "contains": { - "enum": [ - "battery_low", - "comms_restored", - "located", - "maintenance", - "off_hours", - "system_suspend", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "on_trip" - }, - "vehicle_events": { - "contains": { - "enum": [ - "comms_restored", - "located", - "trip_enter_jurisdiction", - "trip_start", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "removed" - }, - "vehicle_events": { - "contains": { - "enum": [ - "agency_pick_up", - "comms_restored", - "compliance_pick_up", - "decommissioned", - "located", - "maintenance_pick_up", - "rebalance_pick_up", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "reserved" - }, - "vehicle_events": { - "contains": { - "enum": [ - "comms_restored", - "located", - "reservation_start", - "unspecified" - ] - } - } - } - }, - { - "properties": { - "vehicle_state": { - "const": "unknown" - }, - "vehicle_events": { - "contains": { - "enum": [ - "comms_lost", - "missing", - "unspecified" - ] - } - } - } - } - ] - }, - "vehicle_telemetry": { - "$id": "#/definitions/vehicle_telemetry", - "type": "object", - "description": "A telemetry datum for a specific vehicle at a specific time", - "required": [ - "device_id", - "timestamp", - "gps" - ], - "additionalProperties": false, - "properties": { - "device_id": { - "$ref": "#/definitions/uuid" - }, - "timestamp": { - "$ref": "#/definitions/timestamp" - }, - "gps": { - "type": "object", - "required": [ - "lat", - "lng" - ], - "additionalProperties": false, - "properties": { - "lat": { - "type": "number", - "description": "Latitude of the location", - "minimum": -90, - "maximum": 90 - }, - "lng": { - "type": "number", - "description": "Longitude of the location", - "minimum": -180, - "maximum": 180 - } - } - }, - "charge": { - "type": "number", - "description": "Fraction of charge of the vehicle (required if applicable)", - "minimum": 0, - "maximum": 1 - } - } - }, - "vehicle_type": { - "$id": "#/definitions/vehicle_type", - "type": "string", - "description": "The type of vehicle", - "enum": [ - "bicycle", - "cargo_bicycle", - "car", - "scooter", - "moped", - "other" - ] - }, - "vehicle_types": { - "$id": "#/definitions/vehicle_types", - "type": "array", - "description": "Array of vehicle types", - "items": { - "$id": "#/definitions/vehicle_types/items", - "$ref": "#/definitions/vehicle_type" - }, - "uniqueItems": true - }, - "version": { - "$id": "#/definitions/version", - "type": "string", - "description": "The version of MDS this data represents", - "examples": [ - "1.2.0" - ], - "pattern": "^1\\.2\\.[0-9]+$" - } - } -} diff --git a/schema/templates/geography/geographies.json b/schema/templates/geography/geographies.json deleted file mode 100644 index 13380181..00000000 --- a/schema/templates/geography/geographies.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/geography/geographies.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Geographies Schema", - "type": "object", - "definitions": { - }, - "required": [ - "geographies", - "updated", - "version" - ], - "properties": { - "geographies": { - "$id": "#/properties/geographies", - "type": "array", - "title": "The array of policy objects in this payload", - "items": { - "$id": "#/properties/geographies/items", - "$ref": "#/definitions/geography" - } - }, - "updated": { - "$id": "#/properties/updated", - "$ref": "#/definitions/timestamp", - "description": "The timestamp when geographies was last updated" - }, - "version": { - "$id": "#/properties/version", - "$ref": "#/definitions/version", - "description": "The version of MDS that the geographies represents" - } - }, - "additionalProperties": false -} diff --git a/schema/templates/geography/geography.json b/schema/templates/geography/geography.json deleted file mode 100644 index e5987bcc..00000000 --- a/schema/templates/geography/geography.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/geography/geography.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Geography Schema", - "type": "object", - "definitions": { - "geography": { - "$id": "#/definitions/geography", - "type": "object", - "title": "The geography object schema", - "additionalProperties": false, - "required": [ - "name", - "geography_id", - "geography_json", - "published_date" - ], - "properties": { - "name": { - "$id": "#/definitions/geography/properties/name", - "$ref": "#/definitions/string", - "description": "Name of geography" - }, - "description": { - "$id": "#/definitions/geography/properties/description", - "$ref": "#/definitions/string", - "description": "Description of geography" - }, - "geography_type": { - "$id": "#/definitions/geography/properties/geography_type", - "type": "string", - "description": "The type of geography" - }, - "geography_id": { - "$id": "#/definitions/geography/properties/geography_id", - "$ref": "#/definitions/uuid", - "description": "Unique ID of geography" - }, - "geography_json": { - "$id": "#/definitions/geography/properties/geography_json", - "$ref": "https://geojson.org/schema/FeatureCollection.json", - "description": "The GeoJSON FeatureCollection that defines the geographical coordinates" - }, - "effective_date":{ - "$id": "#/definitions/geography/properties/effective_date", - "$ref": "#/definitions/null_timestamp", - "description": "The date at which a Geography is considered 'live'. Must be at or after published_date." - }, - "published_date": { - "$id": "#/definitions/geography/properties/published_date", - "$ref": "#/definitions/timestamp", - "description": "Timestamp at which the geography was published i.e. made immutable" - }, - "retire_date": { - "$id": "#/definitions/geography/properties/end_date", - "$ref": "#/definitions/null_timestamp", - "description": "Time that the geography is slated to retire. Once the retire date is passed, new policies can no longer reference it and old policies referencing it should be updated. Retired geographies should continue to be returned in the geographies list. Must be after effective_date." - }, - "prev_geographies": { - "$id": "#/definitions/geography/properties/prev_geographies", - "$ref": "#/definitions/null_uuid_array", - "description": "Unique IDs of prior geographies replaced by this one", - "uniqueItems": true - } - } - } - }, - "required": [ - "geography", - "version" - ], - "properties": { - "geography": { - "$id": "#/properties/geography", - "$ref": "#/definitions/geography", - "description": "The geography in this payload", - "additionalProperties": false - }, - "version": { - "$id": "#/properties/version", - "$ref": "#/definitions/version", - "description": "The version of MDS that the geography represents" - } - }, - "additionalProperties": false -} diff --git a/schema/templates/policy/policy.json b/schema/templates/policy/policy.json deleted file mode 100644 index 3f210955..00000000 --- a/schema/templates/policy/policy.json +++ /dev/null @@ -1,393 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/policy/policy.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "The MDS Policy Schema", - "type": "object", - "definitions": { - "policy": { - "$id": "#/definitions/policy", - "type": "object", - "title": "The policy object schema", - "additionalProperties": false, - "required": [ - "name", - "policy_id", - "description", - "start_date", - "published_date", - "rules" - ], - "properties": { - "name": { - "$id": "#/definitions/policy/properties/name", - "$ref": "#/definitions/string", - "description": "Name of policy" - }, - "policy_id": { - "$id": "#/definitions/policy/properties/policy_id", - "$ref": "#/definitions/uuid", - "description": "Unique ID of policy" - }, - "provider_ids": { - "$id": "#/definitions/policy/properties/provider_ids", - "$ref": "#/definitions/null_uuid_array", - "description": "Providers for whom this policy is applicable; empty arrays and null/absent implies all Providers.", - "uniqueItems": true - }, - "description": { - "$id": "#/definitions/policy/properties/description", - "$ref": "#/definitions/string", - "description": "Description of policy" - }, - "currency": { - "$id": "#/definitions/policy/properties/currency", - "$ref": "#/definitions/currency" - }, - "start_date": { - "$id": "#/definitions/policy/properties/start_date", - "$ref": "#/definitions/timestamp", - "description": "Beginning date/time of policy enforcement" - }, - "end_date": { - "$id": "#/definitions/policy/properties/end_date", - "$ref": "#/definitions/null_timestamp", - "description": "End date/time of policy enforcement" - }, - "published_date": { - "$id": "#/definitions/policy/properties/published_date", - "$ref": "#/definitions/timestamp", - "description": "Timestamp at which the policy was published" - }, - "prev_policies": { - "$id": "#/definitions/policy/properties/prev_policies", - "$ref": "#/definitions/null_uuid_array", - "description": "Unique IDs of prior policies replaced by this one", - "uniqueItems": true - }, - "rules": { - "$id": "#/definitions/rules", - "type": "array", - "description": "Array of applicable Rule objects", - "items": { - "$id": "#/definitions/policy/properties/rules/items", - "$ref": "#/definitions/rule" - }, - "minItems": 1 - } - } - }, - "rule": { - "$id": "#/definitions/rule", - "type": "object", - "description": "An individual rule in a policy", - "additionalProperties": false, - "required": [ - "name", - "rule_id", - "rule_type", - "geographies", - "states" - ], - "properties": { - "name": { - "$id": "#/definitions/rule/properties/name", - "$ref": "#/definitions/string", - "description": "Name of rule" - }, - "rule_id": { - "$id": "#/definitions/rule/properties/rule_id", - "$ref": "#/definitions/uuid", - "description": "Unique ID of rule" - }, - "rule_type": { - "$id": "#/definitions/rule/properties/rule_type", - "type": "string", - "description": "The type of rule", - "enum": [ - "count", - "time", - "speed", - "user" - ] - }, - "geographies": { - "$id": "#/definitions/rule/properties/geographies", - "$ref": "#/definitions/uuid_array", - "description": "List of Geography UUIDs (non-overlapping) specifying the covered geography", - "minItems": 1, - "uniqueItems": true - }, - "states": { - "$id": "#/definitions/rule/properties/states", - "type": "object", - "description": "Vehicle state to which this rule applies. Optionally provide a list of specific vehicle events as a subset of a given state for the rule to apply to. An empty list or null/absent defaults to \"all\" for the state.", - "propertyNames": { - "$id": "#/definitions/rule/properties/states/propertyNames", - "$ref": "#/definitions/vehicle_state" - }, - "properties": {}, - "additionalProperties": { - "type": "array", - "uniqueItems": true, - "items": { - "$ref": "#/definitions/vehicle_event" - } - } - }, - "rule_units": { - "$id": "#/definitions/rule/properties/rule_units", - "type": "string", - "description": "Measured units of policy", - "enum": [ - "seconds", - "minutes", - "hours", - "days", - "mph", - "kph", - "devices", - "amount" - ] - }, - "vehicle_types": { - "$id": "#/definitions/rule/properties/vehicle_types", - "$ref": "#/definitions/null_vehicle_types", - "description": "Applicable vehicle types, default \"all\"" - }, - "propulsion_types": { - "$id": "#/definitions/rule/properties/propulsion_types", - "$ref": "#/definitions/null_propulsion_types", - "description": "Applicable vehicle propulsion types, default \"all\"" - }, - "minimum": { - "$id": "#/definitions/rule/properties/minimum", - "type": [ - "null", - "integer" - ], - "description": "Minimum value, if applicable (default 0)" - }, - "maximum": { - "$id": "#/definitions/rule/properties/maximum", - "type": [ - "null", - "integer" - ], - "description": "Maximum value, if applicable (default unlimited)" - }, - "inclusive_minimum": { - "$id": "#/definitions/rule/properties/inclusive_minimum", - "type": [ - "null", - "boolean" - ], - "description": "Whether the rule minimum is considered in-bounds (default true)" - }, - "inclusive_maximum": { - "$id": "#/definitions/rule/properties/inclusive_maximum", - "type": [ - "null", - "boolean" - ], - "description": "Whether the rule maximum is considered in-bounds (default true)" - }, - "rate_amount": { - "$id": "#/definitions/rule/properties/rate_amount", - "type": [ - "null", - "integer" - ], - "description": "The amount of a rate applied when this rule applies, if applicable (default zero). A positive integer rate amount represents a fee, while a negative integer represents a subsidy. Rate amounts are given in the currency defined in the Policy." - }, - "rate_recurrence": { - "$id": "#/definitions/rule/properties/rate_recurrence", - "type": [ - "string", - "null" - ], - "description": "Specify how a rate is applied – either once, or periodically according to a time unit specified using rule_units", - "enum": [ - "once_on_match", - "once_on_unmatch", - "each_time_unit", - "per_complete_time_unit" - ] - }, - "rate_applies_when": { - "$id": "#/definitions/rule/properties/rate_applies_when", - "type": [ - "string", - "null" - ], - "description": "Specify when a rate is applicable to an event or count: when it's within rule bounds or when it is not", - "enum": [ - "in_bounds", - "out_of_bounds" - ] - }, - "start_time": { - "$id": "#/definitions/rule/properties/start_time", - "$ref": "#/definitions/null_iso_time", - "description": "Beginning time-of-day when the rule is in effect (default 00:00:00)" - }, - "end_time": { - "$id": "#/definitions/rule/properties/end_time", - "$ref": "#/definitions/null_iso_time", - "description": "Ending time-of-day when the rule is in effect (default 23:59:59)" - }, - "days": { - "$id": "#/definitions/rule/properties/days", - "$ref": "#/definitions/null_days", - "description": "Days when the rule is in effect (default all)" - }, - "messages": { - "$id": "#/definitions/rule/properties/messages", - "type": [ - "null", - "object" - ], - "description": "Message to rider user, if desired, in various languages, keyed by BCP 47 language tag", - "propertyNames": { - "pattern": "([A-Za-z]{2,3})([-][A-Za-z]{3}){0,3}([-]([A-Za-z]{4}))?([-]([A-Za-z]{2}|[0-9]{3}))?" - } - }, - "value_url": { - "$id": "#/definitions/rule/properties/value_url", - "type": [ - "null", - "string" - ], - "description": "URL to an API endpoint that can provide dynamic information for the measured value", - "format": "uri" - } - }, - "allOf": [ - { - "description": "Valid rule_type and rule_unit values for this rule", - "oneOf": [ - { - "properties": { - "rule_type": { - "const": "user" - } - } - }, - { - "allOf": [ - { - "required": [ - "rule_units" - ] - }, - { - "oneOf": [ - { - "properties": { - "rule_type": { - "const": "time" - }, - "rule_units": { - "enum": [ - "seconds", - "minutes", - "hours", - "days" - ] - } - } - }, - { - "properties": { - "rule_type": { - "const": "speed" - }, - "rule_units": { - "enum": [ - "mph", - "kph" - ] - } - } - }, - { - "properties": { - "rule_type": { - "const": "count" - }, - "rule_units": { - "enum": [ - "devices" - ] - } - } - }, - { - "required": [ - "rate_amount", - "rate_recurrence" - ], - "properties": { - "rule_units": { - "enum": [ - "amount", - "seconds", - "minutes", - "hours", - "days" - ] - } - } - } - ] - } - ] - } - ] - } - ] - } - }, - "required": [ - "data", - "updated", - "version" - ], - "properties": { - "data": { - "$id": "#/properties/data", - "type": "object", - "description": "The data records in this payload", - "required": [ - "policies" - ], - "properties": { - "policies": { - "$id": "#/properties/data/properties/policies", - "type": "array", - "title": "The array of policy objects in this payload", - "items": { - "$id": "#/properties/data/properties/policies/items", - "$ref": "#/definitions/policy" - } - } - }, - "additionalProperties": false - }, - "end_date": { - "$id": "#/properties/end_date", - "$ref": "#/definitions/null_timestamp", - "description": "The timestamp after which the Policy is no longer effective" - }, - "updated": { - "$id": "#/properties/updated", - "$ref": "#/definitions/timestamp", - "description": "The timestamp when the Policy was last updated" - }, - "version": { - "$id": "#/properties/version", - "$ref": "#/definitions/version", - "description": "The version of MDS that the Policy represents" - } - }, - "additionalProperties": false -} \ No newline at end of file diff --git a/schema/templates/provider/endpoint.json b/schema/templates/provider/endpoint.json deleted file mode 100644 index 1a2dc8f3..00000000 --- a/schema/templates/provider/endpoint.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/openmobilityfoundation/mobility-data-specification/main/provider/endpoint.json", - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "Schema for MDS Provider endpoint payloads", - "type": "object", - "definitions": {}, - "required": [ - "data", - "version" - ], - "properties": { - "data": { - "$id": "#/properties/data", - "type": "object", - "description": "The data records in this payload", - "required": [], - "properties": {}, - "additionalProperties": false - }, - "version": { - "$id": "#/properties/version", - "$ref": "#/definitions/version" - } - }, - "additionalProperties": false -} \ No newline at end of file diff --git a/schema/templates/provider/status_changes.json b/schema/templates/provider/status_changes.json deleted file mode 100644 index c289a7cb..00000000 --- a/schema/templates/provider/status_changes.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "status_changes": { - "$id": "#/properties/data/properties/status_changes", - "type": "array", - "title": "The status_changes payload", - "items": { - "$id": "#/properties/data/properties/status_changes/items", - "type": "object", - "title": "The status_change item schema", - "additionalProperties": false, - "required": [ - "vehicle_state", - "event_types", - "event_time", - "event_location" - ], - "properties": { - "event_time": { - "$id": "#/properties/data/properties/status_changes/items/properties/event_time", - "$ref": "#/definitions/timestamp", - "description": "The time the event occurred, expressed as a Unix Timestamp" - }, - "publication_time": { - "$id": "#/properties/data/properties/status_changes/items/properties/publication_time", - "$ref": "#/definitions/timestamp", - "description": "The time the event became available through the status changes endpoint, expressed as a Unix Timestamp" - }, - "event_location": { - "$id": "#/properties/data/properties/status_changes/items/properties/event_location", - "$ref": "#/definitions/MDS_Feature_Point", - "description": "The GPS or GNSS coordinates of where the event occurred" - }, - "vehicle_state": { - "$id": "#/properties/data/properties/status_changes/items/properties/vehicle_state", - "$ref": "#/definitions/vehicle_state", - "description": "The state of the vehicle" - }, - "event_types": { - "$id": "#/properties/data/properties/status_changes/items/properties/event_types", - "$ref": "#/definitions/vehicle_events", - "description": "The event(s) that caused a change in the vehicle's state" - }, - "battery_pct": { - "$id": "#/properties/data/properties/status_changes/items/properties/battery_pct", - "type": [ - "number", - "null" - ], - "description": "Percent charge of device battery, expressed between 0 and 1", - "examples": [ - 0.89 - ], - "minimum": 0, - "maximum": 1 - }, - "trip_id": { - "$id": "#/properties/data/properties/status_changes/items/properties/trip_id", - "$ref": "#/definitions/uuid", - "description": "Trip UUID (foreign key to Trips API), required if event_types contains trip_start, trip_end, trip_cancel, trip_enter_jurisdiction, or trip_leave_jurisdiction" - }, - "associated_ticket": { - "$id": "#/properties/data/properties/status_changes/items/properties/associated_ticket", - "$ref": "#/definitions/string", - "description": "Identifier for an associated ticket inside an Agency-maintained 311 or CRM system." - } - }, - "allOf": [] - } - } -} \ No newline at end of file diff --git a/schema/templates/provider/stops.json b/schema/templates/provider/stops.json deleted file mode 100644 index d2fcbb5f..00000000 --- a/schema/templates/provider/stops.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "stops": { - "$id": "#/properties/data/properties/stops", - "type": "array", - "title": "The stops payload", - "items": { - "$id": "#/properties/data/properties/stops/items", - "$ref": "#/definitions/stop" - } - } -} \ No newline at end of file diff --git a/schema/templates/provider/trips.json b/schema/templates/provider/trips.json deleted file mode 100644 index d271332a..00000000 --- a/schema/templates/provider/trips.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "trips": { - "$id": "#/properties/data/properties/trips", - "type": "array", - "title": "The trips payload", - "items": { - "$id": "#/properties/data/properties/trips/items", - "type": "object", - "title": "The trip item schema", - "additionalProperties": false, - "required": [ - "trip_id", - "trip_duration", - "trip_distance", - "route", - "accuracy", - "start_time", - "end_time" - ], - "properties": { - "trip_id": { - "$id": "#/properties/data/properties/trips/items/properties/trip_id", - "description": "A unique ID for each trip", - "$ref": "#/definitions/uuid" - }, - "trip_duration": { - "$id": "#/properties/data/properties/trips/items/properties/trip_duration", - "type": "integer", - "description": "The length of time, in seconds, that the trip lasted", - "default": 0, - "examples": [ - 600 - ] - }, - "trip_distance": { - "$id": "#/properties/data/properties/trips/items/properties/trip_distance", - "type": "integer", - "description": "The distance, in meters, that the trip covered", - "default": 0, - "examples": [ - 1000 - ] - }, - "route": { - "$id": "#/properties/data/properties/trips/items/properties/route", - "title": "The Route Schema", - "$ref": "#/definitions/MDS_FeatureCollection_Route" - }, - "accuracy": { - "$id": "#/properties/data/properties/trips/items/properties/accuracy", - "type": "integer", - "title": "The approximate level of accuracy, in meters, of Points within route", - "default": 0, - "examples": [ - 15 - ] - }, - "start_time": { - "$id": "#/properties/data/properties/trips/items/properties/start_time", - "description": "The time the trip began, expressed as a Unix Timestamp", - "$ref": "#/definitions/timestamp" - }, - "end_time": { - "$id": "#/properties/data/properties/trips/items/properties/end_time", - "description": "The time the trip ended, expressed as a Unix Timestamp", - "$ref": "#/definitions/timestamp" - }, - "publication_time": { - "$id": "#/properties/data/properties/trips/items/properties/publication_time", - "description": "The time the trip became available through the trips endpoint, expressed as a Unix Timestamp", - "$ref": "#/definitions/timestamp" - }, - "parking_verification_url": { - "$id": "#/properties/data/properties/trips/items/properties/parking_verification_url", - "type": [ - "string", - "null" - ], - "format": "uri", - "description": "A URL to a photo (or other evidence) of proper vehicle parking", - "examples": [ - "https://data.provider.co/parking_verify/1234.jpg" - ] - }, - "standard_cost": { - "$id": "#/properties/data/properties/trips/items/properties/standard_cost", - "type": [ - "integer", - "null" - ], - "description": "The cost, in the currency defined in `currency`, that it would cost to perform that trip in the standard operation of the System. If no currency is given, USD cents is implied.", - "examples": [ - 500 - ] - }, - "actual_cost": { - "$id": "#/properties/data/properties/trips/items/properties/actual_cost", - "type": [ - "integer", - "null" - ], - "description": "The actual cost, in the currency defined in `currency`, paid by the customer of the *mobility as a service* provider. If no currency is given, USD cents is implied.", - "examples": [ - 520 - ] - }, - "currency": { - "$id": "#/properties/data/properties/trips/items/properties/currency", - "$ref": "#/definitions/currency" - } - } - } - } -} \ No newline at end of file diff --git a/schema/templates/provider/vehicles.json b/schema/templates/provider/vehicles.json deleted file mode 100644 index e9117524..00000000 --- a/schema/templates/provider/vehicles.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "vehicles": { - "$id": "#/properties/data/properties/vehicles", - "type": "array", - "title": "The vehicles payload", - "items": { - "$id": "#/properties/data/properties/vehicles/items", - "type": "object", - "title": "The vehicle item schema", - "required": [ - "last_event_time", - "last_vehicle_state", - "last_event_types", - "last_event_location" - ], - "properties": { - "last_event_time": { - "$id": "#/properties/data/properties/vehicles/items/properties/last_event_time", - "$ref": "#/definitions/timestamp", - "description": "The time the most recent status change event occurred, expressed as a Unix Timestamp" - }, - "last_vehicle_state": { - "$id": "#/properties/data/properties/vehicles/items/properties/last_vehicle_state", - "$ref": "#/definitions/vehicle_state", - "description": "The last known state of the vehicle" - }, - "last_event_types": { - "$id": "#/properties/data/properties/vehicles/items/properties/last_event_types", - "$ref": "#/definitions/vehicle_events", - "description": "The most recent event(s) that caused a change in the vehicle's state" - }, - "last_event_location": { - "$id": "#/properties/data/properties/vehicles/items/properties/last_event_location", - "$ref": "#/definitions/MDS_Feature_Point", - "description": "Location of the vehicle's last status change event" - }, - "current_location": { - "$id": "#/properties/data/properties/vehicles/items/properties/current_location", - "$ref": "#/definitions/MDS_Feature_Point", - "description": "Current location of vehicle if different from last event, and the vehicle is not currently on a trip" - }, - "battery_pct": { - "$id": "#/properties/data/properties/vehicles/items/properties/battery_pct", - "type": [ - "number", - "null" - ], - "description": "Percent charge of device battery, expressed between 0 and 1", - "examples": [ - 0.89 - ], - "minimum": 0, - "maximum": 1 - } - }, - "allOf": [ - { - "description": "Valid last_vehicle_state values for this endpoint", - "properties": { - "last_vehicle_state": { - "enum": [ - "available", - "elsewhere", - "non_operational", - "on_trip", - "removed", - "reserved", - "unknown" - ] - } - } - } - ] - } - } -}