diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md deleted file mode 100644 index 6a41ea19c..000000000 --- a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: Default -about: Suggest changes to MDS -title: - ---- - -# MDS Pull Request - -Thank you for your contribution! Please review our OMF [contributing page](https://github.com/openmobilityfoundation/governance/blob/main/CONTRIBUTING.md) to understand guidelines and policies for participation, and our [Code of Conduct page](https://github.com/openmobilityfoundation/governance/blob/main/CODE_OF_CONDUCT.md). - -To avoid complications and help make the Review process as smooth as possible, make sure to: - -1. Target [**`dev`**](https://github.com/openmobilityfoundation/mobility-data-specification/tree/dev) branch. Please ensure you are targeting **`dev`**, not **`main`**. -1. Keep the *"Allow edits from maintainers"* button checked to help us resolve some issues for you. -1. Be ready to resolve any merge conflicts before we approve your Pull Request. -1. Have an up to date profile, per our Github [community profile](https://github.com/openmobilityfoundation/governance/blob/main/CONTRIBUTING.md#community-profile) guildance. - -## Explain pull request - -Please provide a clear and concise reason for this pull request and the impact of the change - -## Is this a breaking change - -A breaking change would require consumers or implementors of the API to modify their code for it to continue to function (ex: renaming of a required field or the change in data type of an existing field). A non-breaking change would allow existing code to continue to function (ex: addition of an optional field or the creation of a new optional endpoint). - -* Yes, breaking -* No, not breaking -* I'm not sure - -## Impacted Spec - -Which spec(s) will this pull request impact? - -* `agency` -* `policy` -* `provider` - -## Additional context - -Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE/release-candidate.md b/.github/PULL_REQUEST_TEMPLATE/release-candidate.md deleted file mode 100644 index cc6205b32..000000000 --- a/.github/PULL_REQUEST_TEMPLATE/release-candidate.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -name: Release Candidate -about: Initiate discussion to obtain OMF approval for new release -title: Release Candidate [X.Y.Z] -labels: admin -assignees: jfh01 - ---- - -### Summary - -The Release Candidate for MDS `X.Y.Z` has been submitted: - -Please use this pull request to track Technology Council and OMF Board feedback and/or requested changes. - -### Action Item - -This pull request will be merged by an OMF maintainer after OMF Board Approval following the [Release Guidelines](https://github.com/openmobilityfoundation/governance/blob/main/technical/ReleaseGuidelines.md#making-a-release). diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 6a41ea19c..249210882 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,10 +1,3 @@ ---- -name: Default -about: Suggest changes to MDS -title: - ---- - # MDS Pull Request Thank you for your contribution! Please review our OMF [contributing page](https://github.com/openmobilityfoundation/governance/blob/main/CONTRIBUTING.md) to understand guidelines and policies for participation, and our [Code of Conduct page](https://github.com/openmobilityfoundation/governance/blob/main/CODE_OF_CONDUCT.md). @@ -28,14 +21,22 @@ A breaking change would require consumers or implementors of the API to modify t * No, not breaking * I'm not sure -## Impacted Spec +## Impacted APIs -Which spec(s) will this pull request impact? +Which API(s) will this pull request impact? * `agency` -* `policy` * `provider` +* `policy` +* `geography` +* `jurisdiction` +* `metrics` ## Additional context Add any other context or screenshots about the feature request here. + +## Licensing Agreement + +By submitting this pull request, you are signing the OMF's [Individual Contributor License Agreement](https://github.com/openmobilityfoundation/governance/raw/main/documents/OMF-Individual-CLA.pdf) (ICLA), and agree to the OMF's [contributing requirements](https://github.com/openmobilityfoundation/governance/blob/main/CONTRIBUTING.md), [participation policies](https://github.com/openmobilityfoundation/governance/raw/main/documents/OMFParticipationPolicies.pdf), and [code of conduct](https://github.com/openmobilityfoundation/governance/blob/main/CODE_OF_CONDUCT.md). + diff --git a/LIABILITY b/LIABILITY new file mode 100644 index 000000000..8804ce537 --- /dev/null +++ b/LIABILITY @@ -0,0 +1,25 @@ +Liability for Deliverables + +All Open Mobility Foundation deliverables are provided "AS IS", without warranty of any +kind, express or implied, and OMF, as well as all of its Members and Contributors, +expressly disclaim any warranty of merchantability, fitness for a particular or intended +purpose, accuracy, completeness, non-infringement of third party rights, or any other +warranty. + +In no event shall OMF or any of its officers, directors, agents or Members be liable to +any other person or entity for any loss of profits, loss of use, direct, indirect, incidental, +consequential, punitive, or special damages, whether under contract, tort, warranty, or +otherwise, arising in any way out of this Policy, whether or not such party had advance +notice of the possibility of such damages. Limitations to the liability of OMF +Contributors as Contributors are set forth in their Contributor License Agreements. + +In addition, except for grossly negligent or intentionally fraudulent acts, OMF and its +officers, directors, agents, Members and Contributors (and their respective +representatives) shall not be liable to any other person or entity for any loss of profits, +loss of use, direct, indirect, incidental, consequential, punitive, or special damages, +whether under contract, tort, warranty, or otherwise, arising in any way out of this +Policy, whether or not such party had advance notice of the possibility of such damages. + +OMF assumes no responsibility to compile, confirm, update or make public any +assertions of intellectual property rights or claims that might be infringed by an +implementation of an OMF Deliverable. diff --git a/README.md b/README.md index b7c6fccfd..dc14799b1 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ - [Modularity](#modularity) - [GBFS Requirement](#gbfs-requirement) - [Modes](#modes) + - [Future Modes](#future-modes) - [Versions](#versions) - [Technical Information](#technical-information) - [Data Validation](#data-validation) @@ -21,13 +22,19 @@ # About -The Mobility Data Specification (**MDS**), a project of the [Open Mobility Foundation](http://www.openmobilityfoundation.org) (**OMF**), is a set of Application Programming Interfaces (APIs) that helps cities better manage transportation in the public right of way, standardizing communication and data-sharing between cities and mobility providers, allowing cities to share and validate policy digitally, and enabling vehicle management and better outcomes for residents. Inspired in part by projects like [GTFS](https://developers.google.com/transit/gtfs/reference/) and [GBFS](https://github.com/MobilityData/gbfs), MDS is focused on managing mobility services such as dockless scooters, bicycles, mopeds, car share, delivery robots, fixed route services and shuttles, fleets, and passenger services. +The Mobility Data Specification (**MDS**), a project of the [Open Mobility Foundation](http://www.openmobilityfoundation.org) (**OMF**), is a set of Application Programming Interfaces (APIs) that helps cities better manage transportation in the public right of way, standardizing communication and data-sharing between cities and mobility providers, allowing cities to share and validate policy digitally, and enabling vehicle management and better outcomes for residents. Inspired in part by projects like [GTFS](https://developers.google.com/transit/gtfs/reference/) and [GBFS](https://github.com/MobilityData/gbfs), MDS is focused on managing mobility services such as dockless scooters, bicycles, mopeds, car share, food and goods delivery, sidewalk robots, fixed route services and shuttles, fleets, busses, and passenger services. + +![MDS Main Logo](https://i.imgur.com/AiUedl3.png) **MDS** is a key piece of digital infrastructure that supports the effective implementation of mobility policies in cities around the world. For a high level overview and visuals, see the [About MDS](https://www.openmobilityfoundation.org/about-mds/) page on the OMF website. -![MDS Main Logo](https://i.imgur.com/AiUedl3.png) +![MDS Overview Diagram](https://i.imgur.com/YsrCHPX.png) + +### History -**MDS** is an open-source project originally created by the [Los Angeles Department of Transportation](http://ladot.io) (LADOT). In November 2019, stewardship of MDS and the ownership of this repository were transferred to the [Open Mobility Foundation](http://www.openmobilityfoundation.org). GitHub automatically redirects any links to this repository from the `CityOfLosAngeles` organization to the `openmobilityfoundation` instead. MDS continues to be used by LADOT and [many other municipalities](#cities-using-mds) and companies. +**MDS** is an open-source project originally created by the [Los Angeles Department of Transportation](http://ladot.io) (LADOT). In November 2019, stewardship of MDS and the ownership of this repository were transferred to the [Open Mobility Foundation](http://www.openmobilityfoundation.org). GitHub automatically redirects any links to this repository from the `CityOfLosAngeles` organization to the `openmobilityfoundation` instead. MDS continues to be used by LADOT and [many other municipalities](#cities-using-mds) and companies (confirmed over 200 mobility operators, operating in over 1,200 cities globally, and 2 billion trips sent) as a global standard. + +![MDS Global Map](https://i.imgur.com/Mx8qHwz.png) [Top][toc] @@ -79,11 +86,11 @@ Many parts of the MDS definitions and APIs align across each other. In these cas You can read more in our **[Understanding the different MDS APIs](https://github.com/openmobilityfoundation/governance/blob/main/technical/Understanding-MDS-APIs.md)** guide. -![MDS APIs and Endpoints](https://i.imgur.com/i27Mmfw.png) +![MDS APIs and Endpoints](https://i.imgur.com/4xVWwbj.png) ## GBFS Requirement -All MDS compatible Provider and/or Agency feeds must also expose a public [GBFS](https://github.com/MobilityData/gbfs) feed for the micromobility and car share [modes](/modes) (passenger services and delivery robots may be optionally supported at the discretion of the agency running the program). Compatibility with [GBFS 3.0](https://github.com/MobilityData/gbfs/blob/v3.0/gbfs.md) or greater is advised, or the version recommended per MobilityData's [supported releases](https://github.com/MobilityData/gbfs?tab=readme-ov-file#current-version-recommended) guidance. Read MobilityData's RFP recommendations and required files list in their [GBFS and Shared Mobility Data Policy guide](https://gbfs.org/learn/data-policy/). +All MDS compatible Provider and/or Agency feeds must also expose a public [GBFS](https://github.com/MobilityData/gbfs) feed for the micromobility and car share [modes](/modes) (passenger services and delivery may be optionally supported at the discretion of the agency running the program). Compatibility with [GBFS 3.0](https://github.com/MobilityData/gbfs/blob/v3.0/gbfs.md) or greater is advised, or the version recommended per MobilityData's [supported releases](https://github.com/MobilityData/gbfs?tab=readme-ov-file#current-version-recommended) guidance. Read MobilityData's RFP recommendations and required files list in their [GBFS and Shared Mobility Data Policy guide](https://gbfs.org/learn/data-policy/). See our [MDS Vehicles Guide](https://github.com/openmobilityfoundation/mobility-data-specification/wiki/MDS-Vehicles) for how MDS Provider/Agency `/vehicles` can be used by regulators instead of the public GBFS `/vehicle_status` (formerly `/free_bike_status`). Additional information on MDS and GBFS can be found in this [guidance document](https://github.com/openmobilityfoundation/governance/blob/main/technical/GBFS_and_MDS.md). @@ -93,24 +100,28 @@ See our [MDS Vehicles Guide](https://github.com/openmobilityfoundation/mobility- MDS supports multiple "modes", defined as a distinct regulatory framework for a type of mobility service. See the [modes overview](/modes) or get started with a specific mode: -- **[Micromobility](/modes/micromobility.md)** - dockless or docked small devices such as e-scooters and bikes. -- **[Passenger services](/modes/passenger-services.md)** - transporting individuals with a vehicle driven by another entity, including taxis, TNCs, and microtransit -- **[Car share](/modes/car-share.md)** - shared point-to-point and station-based multi-passenger vehicles. -- **[Delivery robots](/modes/delivery-robots.md)** - autonomous and remotely driven goods delivery devices +- **[Micromobility](/modes/micromobility.md)** - customer operated dockless or docked small devices moving customers and goods, such as scooters, bikeshare, cargo bikes, adaptive scooters, docked bikes, mopeds, trikes, and quadracycles. +- **[Passenger](/modes/passenger-services.md)** - employees and contractors, autonomous, and remotely operated transporting individuals or goods with a vehicle driven by another entity, including taxis, for-hire AVs, robotaxis, busses, transportation network companies (TNCs), commercial transport apps (CTAs), and private hire vehicles (PHVs), shuttles, paratransit, on demand vehicles, limosines, and microtransit. +- **[Fleet](/modes/car-share.md)** - customer, employees and contractors, autonomous, and remotely operated shared point-to-point, station-based, or free-floating multi-passenger or cargo vehicles like consumer car share, sanitation vehicles (garbage, recycling), city fleets, vehicle rentals, street sweepers, snow plows, utility services, construction, emergency response (police, fire, ambulance), tree maintenance, inspection and permitting vehicles, mobile health clinics, and heavy maintenance vehicles. +- **[Delivery](/modes/delivery-robots.md)** - employees and contractors, autonomous, and remotely operated sidewalk robots, app delivery, packages, freight, goods, food, private hire vehicles, electric cargo bikes and trikes, mopeds and motorcycles, box trucks, bike and scooter couriers, cargo vans, semi-trucks and tractor-trailers, postal service, medicine, and other delivery services.

-MDS Mode - Micromobility       -MDS Mode - Passenger Services       -MDS Mode - Car Share       -MDS Mode - Delivery Robots +MDS Mode - Micromobility       +MDS Mode - Passenger       +MDS Mode - Fleet       +MDS Mode - Delivery


+## Future Modes + +Support for other shared modes, services, programs, and vehicles has been discussed for MDS, and could be created by public agencies and company requests in the future with non-breaking modifications in new MDS versions, for drone delivery, EVTOL air taxis, ferries, gondolas, subway, trolleys, trains, water taxis, helicopters, and planes. If interested, browse our [current conversations](https://github.com/openmobilityfoundation/mobility-data-specification/issues) or [start your own](https://github.com/openmobilityfoundation/mobility-data-specification/issues/new?template=feature-request---proposal.md). + [Top][toc] # Versions -MDS has a **current release** (version 2.0.0), **previous releases** (both recommended and longer recommended for use), and **upcoming releases** in development. For a full list of releases, their status, recommended versions, and timelines, see the [Official MDS Releases](https://github.com/openmobilityfoundation/governance/wiki/Releases) page. +MDS has a **current release** (version 2.1.0), **previous releases** (both recommended and longer recommended for use), and **upcoming releases** in development. For a full list of releases, their status, recommended versions, and timelines, see the [Official MDS Releases](https://github.com/openmobilityfoundation/governance/wiki/Releases) page. The OMF provides guidance on upgrading for cities, providers, and software companies, and sample permit language for cities. See our [MDS Version Guidance](https://github.com/openmobilityfoundation/governance/blob/main/technical/OMF-MDS-Version-Guidance.md) for best practices on how and when to upgrade MDS as new versions become available. Our complimentary [MDS Policy Language Guidance](https://github.com/openmobilityfoundation/governance/blob/main/technical/OMF-MDS-Policy-Language-Guidance.md) document is for cities writing MDS into their operating policy and includes sample policy language. @@ -163,7 +174,7 @@ Read about [how to become an OMF member](https://www.openmobilityfoundation.org/ # Cities Using MDS -More than 200 cities and public agencies across 21 countries around the world are known to use MDS, and it has been implemented by most major [mobility service providers](#providers-using-mds). +More than 1,200 cities and public agencies across 21 countries around the world are known to use MDS, and it has been implemented by over 200 major [mobility service providers](#providers-using-mds). - See our **[list of cities using MDS](https://www.openmobilityfoundation.org/mds-users/#cities-using-mds)** with links to public mobility websites and policy/permit documents. Please let us know [via our website](https://www.openmobilityfoundation.org/get-in-touch/) or in the [public discussion area](https://github.com/openmobilityfoundation/mobility-data-specification/discussions) if you are an agency using MDS so we can add you to the city resource list, especially if you have published your policies or documents publicly. @@ -174,7 +185,7 @@ To add yourself to the [agency list](/agencies.csv) and add your [Policy Require # Providers Using MDS -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. +Over 200 mobility service providers (MSPs) around the world use MDS, allowing them to create tools around a single data standard for multiple cities globally. - 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. @@ -185,7 +196,7 @@ To add yourself to the provider list, please let us know [via our website](https # Software Companies Using MDS -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. +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 and vendors 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. @@ -223,7 +234,7 @@ How cities use MDS depends on a variety of factors: their transportation goals, - **Resident Complaints:** Investigate and validate complaints from residents about operations, parking, riding, speed, etc, usually reported through 311 - **Infrastructure Planning:** Determine where to place new bike/scooter lanes and drop zones based on usage and demand, start and end points, and trips taken -A list of use cases is useful to show what's possible with MDS, to list what other cities are accomplishing with the data, to see many use cases up front for privacy considerations, and to use for policy discussions and policy language. More details and examples can be seen on the [OMF website](https://www.openmobilityfoundation.org/whats-possible-with-mds/) and our [Wiki Database](https://github.com/openmobilityfoundation/governance/wiki/MDS-Use-Cases). An agency may align their program to specific use cases by publishing [Policy Requirement use cases](/policy#requirement-apis). +A list of more than 60 use cases is useful to show what's possible with MDS, to list what other cities are accomplishing with the data, to see many use cases up front for privacy considerations, and to use for policy discussions and policy language. More details and examples can be seen on the [OMF website](https://www.openmobilityfoundation.org/whats-possible-with-mds/) and our [Wiki Database](https://github.com/openmobilityfoundation/governance/wiki/MDS-Use-Cases). An agency may align their program to specific use cases by publishing [Policy Requirement use cases](/policy#requirement-apis). Please [let us know](https://docs.google.com/forms/d/e/1FAIpQLScrMPgeb1TKMYCjjKsJh3y1TPTJO8HR_y1NByrf1rDmTEJS7Q/viewform) if you have recommended updates or use cases to add. diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 5a2cb7499..271ccb982 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,3 +1,15 @@ +## 2.1.0 + +> Released: xxxx + +The 2.1 release is a minor release. + +### CHANGES + +See the [Milestone 2.1.0](https://github.com/openmobilityfoundation/mobility-data-specification/milestone/17) and [Issues](https://github.com/openmobilityfoundation/mobility-data-specification/milestone/17?closed=1) for a full list of changes. + +**Full [Release Notes](https://github.com/openmobilityfoundation/mobility-data-specification/releases/tag/2.1.0)** for details. + ## 2.0.2 > Release 2025.06.04 diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..c80200120 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,11 @@ +# Security Policy + +## Supported Versions + +The most recent version and/or any version 2 years old or newer is supported. Other versions are not recommended and not supported. + +See our [MDS Releases](https://github.com/openmobilityfoundation/governance/wiki/Releases) page for full details and list of supported releases by version number. + +## Reporting a Vulnerability or Issue + +If you find a vulnerability or issue with a supported version of the specification, open an [Issue](https://github.com/openmobilityfoundation/mobility-data-specification/issues) to let us know and start a discussion on how to fix it in a future release. diff --git a/agency/README.md b/agency/README.md index 338823048..a56e4cb59 100644 --- a/agency/README.md +++ b/agency/README.md @@ -26,6 +26,9 @@ This specification contains a collection of RESTful APIs used to specify the dig * [Stops - Register](#stops---register) * [Stops - Update](#stops---update) * [Stops - Readback](#stops---readback) +* [Incidents](#incidents) + * [Incident - Create](#incident---create) + * [Incident - Update](#incident---update) * [Reports](#reports) * [Reports - Register](#reports---register) @@ -426,6 +429,69 @@ See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schem [Top][toc] +## Incidents + +The `/incidents` endpoints allow providers to create and update the details of incidents. + +### Incident - Create + +The `/incidents` create endpoint is used to create incident reports that occur with provider devices. + +**Endpoint**: `/incidents` +**Method:** `POST` +**Payload:** An array of [Incidents](/data-types.md#incidents) + +#### 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_created` | An incident with `incident_id` is already careated | | + +### Incident - Update + +The `/incidents` update endpoint is used to change incident information, should some aspect of the incident change. Each incident must already be created. + +**Endpoint**: `/incidents` +**Method:** `PUT` +**Payload:** An array of [Incidents](/data-types.md#incidents) + +#### 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 `incident_id` is unregistered | | + +[Top][toc] + ## Reports Reports are information that providers can send back to agencies containing aggregated data that is not contained within other MDS endpoints, like counts of special groups of riders. These supplemental reports are not a substitute for other MDS Provider endpoints. diff --git a/data-types.md b/data-types.md index 2a5299b57..1db883eb0 100644 --- a/data-types.md +++ b/data-types.md @@ -15,8 +15,12 @@ This MDS data types page catalogs the objects (fields, types, requirements, desc - [Stops](#stops) - [Stop Status](#stop-status) - [Trips](#trips) +- [Incidents](#incidents) - [Reports](#reports) - +- [Enforcement](#enforcement) + - [Violations](#violations) +- [External Reference](#external-reference) + ## Vehicles A vehicle record is as follows: @@ -34,6 +38,9 @@ A vehicle record is as follows: | `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. | +| `hardware_model` | String | Required if Available | Number, identifier, or description of the main device hardware model. Can apply to any mode. | +| `commissioned` | [Timestamp][ts] | Conditionally Required | Date/time the vehicle first starts providing service in the jurisdiction. Required if asked for by public agency. | +| `decommissioned` | [Timestamp][ts] | Conditionally Required | Date/time the vehicle stops providing service in the jurisdiction and is decommissioned. Required when the vehicle is retired from operations. | [Top][toc] @@ -50,12 +57,15 @@ The list of allowed `vehicle_type` values in MDS. | `delivery_robot` | A robot or remote-operated device intended for transporting goods | | `moped` | A seated fully-motorized mobility device capable of travel at moderate or high speeds and suited for operation in general urban traffic | | `motorcycle` | A seated fully-motorized mobility device capable of travel at high speeds and suited for operation in general urban traffic and highways | +| `scooter` | A standing _or_ seated fully-motorized mobility device intended for one rider, capable of travel at low or moderate speeds, and suited for operation in infrastructure shared with motorized bicycles | | `scooter_standing` | A standing fully-motorized mobility device without a seat intended for one rider, capable of travel at low or moderate speeds, and suited for operation in infrastructure shared with motorized bicycles | | `scooter_seated` | A fully-motorized mobility device with a seat intended for one rider, capable of travel at low or moderate speeds, and suited for operation in infrastructure shared with motorized bicycles | | `truck` | A truck or vehicle larger than a car or similar heavy-duty vehicle | +| `van` | A van with significant interior cargo space | +| `freight` | A large delivery truck with attached cab | | `other` | A device that does not fit in the other categories | -Values based off of `form_factor` in [GBFS vehicle_types](https://github.com/MobilityData/gbfs/blob/master/gbfs.md#vehicle_typesjson), with some additional to support MDS modes. +Values based off of `form_factor` in [GBFS vehicle_types](https://github.com/MobilityData/gbfs/blob/master/gbfs.md#vehicle_typesjson) and [CDS vehicle types](https://github.com/openmobilityfoundation/curb-data-specification/blob/main/events/README.md#vehicle-type), with some modifications to support MDS modes. [Top][toc] @@ -109,12 +119,17 @@ Events represent changes in vehicle status. | `timestamp` | [Timestamp][ts] | Required | Date/time that event occurred at. See [Event Times][event-times] | | `publication_time` | [Timestamp][ts] | [Optional](./general-information.md#optional-fields) | Date/time that event became available through the status changes endpoint | | `location` | [GPS][gps] | Required | See also [Telemetry][telemetry]. | -| `event_geographies` | UUID[] | [Optional](./general-information.md#optional-fields) | **[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. | +| `software_version` | String | [Optional](./general-information.md#optional-fields) | Software version the main device is running on. Can be provided only when there is an update. | +| `description` | String | [Optional](./general-information.md#optional-fields) | Description of the reason for the event, e.g. the type and reason for maintenance performed, note a software version upgrade, reason for system suspension, comms lost details, provider pickup reason, inspection details, etc. | +| `event_geographies` | UUID[] | [Optional](./general-information.md#optional-fields) | 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` and `statistical_area_ids` are not present. | +| `statistical_areas` | Strings[] | [Optional](./general-information.md#optional-fields) | Array of statistical area identifier(s) where the event occurred. e.g. US census area IDs (tract, block group, block, etc), Canadian dissemination blocks or areas, UK output areas, etc, or any other pre-defined standard district, area, sector, neighborhood, etc. Details of the type and meaning of these identifiers are communicated between the public agency and operator outside of MDS. Note that instead of these pre-defined areas, custom geographic areas can be defined using `event_geographies`. Required if `location` and `event_geographies` are not present. | | `battery_percent` | Integer | [Required if Applicable](./general-information.md#required-if-applicable-fields) | Percent battery charge of vehicle, expressed between 0 and 100 | | `fuel_percent` | Integer | [Required if Applicable](./general-information.md#required-if-applicable-fields) | Percent fuel in vehicle, expressed between 0 and 100 | | `trip_ids` | UUID[] | [Required if Applicable](./general-information.md#required-if-applicable-fields) | 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` | | `stop_id` | UUID | [Required if Applicable](./general-information.md#required-if-applicable-fields) | Stop that the vehicle is currently located at. See [Stops][stops] | | `associated_ticket` | String | [Optional](./general-information.md#optional-fields) | Identifier for an associated ticket inside an Agency-maintained 311 or CRM system | +| `gtfs_stop_id` | String | [Optional](./general-information.md#optional-fields) | A unique stop ID to be recorded when a vehicle makes a stop event at a location. Matches [GTFS](https://gtfs.org/documentation/schedule/reference/) `stop_id` | +| `external_references` | Array of [External Reference][external-reference] objects | [Optional](./general-information.md#optional-fields) | One or more references impacting or related to this Event. | ### Event Times @@ -133,6 +148,7 @@ A standard point of vehicle telemetry. References to latitude and longitude impl | `data_provider_id`| UUID | [Optional](./general-information.md#optional-fields) | 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 | +| `publication_time`| [Timestamp][ts] | [Optional](./general-information.md#optional-fields) | Date/time that telemetry data became available through the telemetry endpoint | | `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](./general-information.md#required-if-applicable-fields) | Stop that the vehicle is currently located at. See [Stops][stops] | @@ -141,9 +157,13 @@ A standard point of vehicle telemetry. References to latitude and longitude impl | `battery_percent` | Integer | [Required if Applicable](./general-information.md#required-if-applicable-fields) | Percent battery charge of vehicle, expressed between 0 and 100 | | `fuel_percent` | Integer | [Required if Applicable](./general-information.md#required-if-applicable-fields) | Percent fuel in vehicle, expressed between 0 and 100 | | `tipped_over` | Boolean | Required if Known | If detectable and known, is the device tipped over or not? Default is 'false'. | +| `gtfs_stop_id` | String | [Optional](./general-information.md#optional-fields) | A unique stop ID to be recorded when a vehicle makes a stop event at a location. Matches [GTFS](https://gtfs.org/documentation/schedule/reference/) `stop_id` | +| `incident_ids` | UUID[] | Optional | Array of one or more [Incident](#incidents) IDs that are connected to this telemetry data point. | ### GPS Data +Includes GPS device data and data from other relevant sensors. + | Field | Type | Required/Optional | Field Description | | ---------- | -------------- | --------------------- | ------------------------------------------------------------ | | `lat` | Double | Required | Latitude of the location | @@ -151,9 +171,12 @@ A standard point of vehicle telemetry. References to latitude and longitude impl | `altitude` | Double | Required if Available | Altitude above mean sea level in meters | | `heading` | Double | Required if Available | Degrees - clockwise starting at 0 degrees at true North | | `speed` | Float | Required if Available | Estimated speed in meters / sec as reported by the GPS chipset | -| `horizontal_accuracy` | Float | Required if Available | Horizontal accuracy, in meters | -| `vertical_accuracy` | Float | Required if Available | Vertical accuracy, in meters | +| `horizontal_accuracy` | Float | Required if Available | Horizontal accuracy, in meters | +| `vertical_accuracy` | Float | Required if Available | Vertical accuracy, in meters | | `satellites` | Integer | Required if Available | Number of GPS or GNSS satellites | +| `accelerometer_x` | Float | Required if Available | The x-axis acceleration in G's (gravitational force). | +| `accelerometer_y` | Float | Required if Available | The y-axis acceleration in G's (gravitational force). | +| `accelerometer_z` | Float | Required if Available | The z-axis acceleration in G's (gravitational force). | [Top][toc] @@ -185,6 +208,7 @@ Stops describe vehicle trip start and end locations in a pre-designated physical | `parent_stop` | UUID | [Optional](./general-information.md#optional-fields) | Describe a basic hierarchy of stops (e.g.a stop inside of a greater stop) | | `devices` | UUID[] | [Conditionally Required](./general-information.md#conditionally-required-fields) | List of device_ids for vehicles which are currently at this stop. Required if the program has station based availability requirements or service level agreements pertaining to stations. | | `image_url` | URL | [Optional](./general-information.md#optional-fields) | Link to an image, photo, or diagram of the stop. Could be used by providers to help riders find or use the stop. | +| `external_references` | Array of [External Reference][external-reference] objects | [Optional](./general-information.md#optional-fields) | One or more references impacting or related to this Stop. | [Top][toc] @@ -222,7 +246,7 @@ A Trip is defined by the following structure: | `journey_id` | UUID | [Optional](./general-information.md#optional-fields) | A unique [journey ID](/modes#journey-id) for associating collections of trips for its [mode][modes] | | `journey_attributes` | Map | [Optional](./general-information.md#optional-fields) | **[Mode](/modes#list-of-supported-modes) Specific**. [Journey attributes](/modes#journey-attributes) given as unordered key-value pairs | | `trip_id` | UUID | Required | A unique ID for each trip | -| `trip_type` | Enum | [Optional](./general-information.md#optional-fields) | **[Mode](/modes#list-of-supported-modes) Specific**. The [trip type](/modes#trip-type) describing the purpose of a trip segment | +| `trip_type` | Enum | [Optional](./general-information.md#optional-fields) | **[Mode](/modes#list-of-supported-modes) Specific**. The [trip type](/modes#trip-type) describing the purpose of a trip segment. _Note: if not provided, only send trips of the **default** `trip_type`, as marked for each mode._ | | `trip_attributes` | Map | [Optional](./general-information.md#optional-fields) | **[Mode](/modes#list-of-supported-modes) Specific**. [Trip attributes](/modes#trip-attributes) given as unordered key-value pairs | | `fare_attributes` | Map | [Optional](./general-information.md#optional-fields) | **[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 | @@ -234,10 +258,38 @@ A Trip is defined by the following structure: | `publication_time` | [Timestamp][ts] | [Optional](./general-information.md#optional-fields) | Date/time that trip became available through the trips endpoint | | `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](./general-information.md#optional-fields) | 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](./general-information.md#optional-fields) | 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. +| `parking_category` | Enum | [Optional](./general-information.md#optional-fields) | The type of parking location detected or provided and the end of a trip. One of `corral`, `curb`, `rack`, `space`, `dock`, `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. Use `external_references` to specify more details, like a link to CDS Curb Zones. | | `standard_cost` | Integer | [Optional](./general-information.md#optional-fields) | 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]) | | `actual_cost` | Integer | [Optional](./general-information.md#optional-fields) | The actual cost, in the currency defined in `currency`, paid by the customer of the *mobility as a service* provider (see [Costs & Currencies][costs-and-currencies]) | | `currency` | String | [Optional](./general-information.md#optional-fields), USD cents is implied if null.| An [ISO 4217 Alphabetic Currency Code][iso4217] representing the currency of the payee (see [Costs & Currencies][costs-and-currencies]) | +| `gtfs_trip_id` | String | Required if Applicable | A unique trip ID for the associated scheduled GTFS route-trip. Matches [GTFS](https://gtfs.org/documentation/schedule/reference/) `trip_id` in the trips.txt and other files.| +| `gtfs_api_url` | URL | Required if Applicable | Full URL to the location where the associated [GTFS](https://gtfs.org/documentation/schedule/reference/) dataset zip files are located. | +| `external_references` | Array of [External Reference][external-reference] objects | [Optional](./general-information.md#optional-fields) | One or more references impacting or related to this Trip. | + +[Top][toc] + +## Incidents + + Incidents are used in both [Provider](/provider#incidents) and [Agency](/agency#incidents) telemetry data, whether on or off a Trip. + +| Field | Type | Required/Optional | Comments | +| ---- | ---- | ---- | ---- | +| `incident_id` | UUID | Required | ID used for uniquely identifying an Incident. | +| `incident_type` | Enum | Required | The type of incident. One of `unplanned_stop`, `remote_takeover`, `ads_engaged` (Automated Driving System), `ads_disengaged`, `tip_over`, `harsh_stopping` (e.g. braking), `harsh_starting` (e.g. acceleration), `near_miss`, `vandalism`, `theft`, `violation`, `crash`. Exact definitions, and when and if which incident types are sent, come from the public agency. | +| `incident_time` | [Timestamp][ts] | Required | Date/time that incident first occurred. Note that this timestamp of the incident first occurance is independent of one or more Telemetry timestamps referenced via `incident_id`. Note that more frequent telemetry data points may be required when an incident is first discovered and occuring. | +| `discovery_time` | [Timestamp][ts] | Required | Date/time that incident was first discovered by the operator. This may be at the same moment of the `incident_time`, or may have been discovered later. | +| `publication_time` | [Timestamp][ts] | Required | Date/time that incident became first available to an agency through an Incident endpoint. | +| `last_updated` | [Timestamp][ts] | Required | Date/time that incident was last updated in the Incident endpoint. | +| `description` | String | Optional | Text description of the incident. | +| `severity` | String | Optional | Text description of the severity of the incident. | +| `medical_dispatch` | Boolean | Optional | If `true`, a medical dispatch occured connected to the incident. | +| `medical_transport` | Boolean | Optional | If `true`, one or more individuals was transported via an ambulance or emergency response vehicle because of the incident. | +| `report_id` | String | Optional | Identifier of an external report, from a police report, citation, internal system, service request, etc. The report source is communicated by the operator to the agency outside of MDS. | +| `report_type` | String | Optional | Description of the type of report referenced by the `report_id`, eg. police, customer, remote operator, 311 call, etc. | +| `enforcement` | [Enforcement](#enforcement) | Optional | Enforcement and violation information related to this incident. Can be used for any `incident_type`. | +| `external_references` | Array of [External Reference][external-reference] objects | Optional | One or more references to external data feeds, links, reports, or documents impacting or related to this Incident, as they become available. | +| `contact_info` | String | Optional | Description of any relevant contact information about the incident the operator can provide. | +| `preliminary` | Boolean | Optional | If `true`, then this information in this Incident is only preliminary, with more details and/or validation coming at a later date. If `false`, the information provided here is deemed valed with no more updates expected. | [Top][toc] @@ -294,8 +346,58 @@ Other special group types may be added in future MDS releases as relevant agency [Top][toc] +## Enforcement + +The Enforcement object describes a specific set of features relevant to an enforcement [Incident](#incidents). + +Where a citation could represent multiple violations, an enforcement object contains an array that enumerates the violations for a single citation. Where a citation can only represent a single violation, multiple Incidents may be published, each with a single violation in the array. + +The `enforcement` object is a JSON *object* with the following fields: + +| Name | Type | Required/Optional | Description | +| ---------------- | ------- | ----------------- | ------------- | +| `enforcement_id` | UUID | Required | An identifier unique to the enforcement incident, generated the first time an enforcement event is recorded, and referenced in future related enforcement events. Multiple Incidents (ex: `crash`, `violation`, or `vandalism`) that relate to the same enforcement activity can share the same `enforcement_id`. | +| `citation_id` | String | Optional | A unique id which represents a single citation. | +| `is_warning` | Boolean | Optional | A boolean value to indicate if the enforcement action is being processed as a warning. | +| `action_taken` | String | Optional | Indicates how the violation was enforced. Typical well-known values are `citation_registered`, `citation_posted`, `citation_served`, or `citation_emailed`. | +| `citation_cost` | String | Optional | The total cost of all violations associated to this enforcement action. | +| `violations` | Array of [Violations](#violations) | Optional | An array of Violation objects that indicate the one-to-many violations associated to this enforcement event. | + +[Top][toc] + +### Violations + +The Violations object describes the violations associated to an enforcement action that can occur as part of a [Enforcement](#enforcement) on an [Incident](#incidents). + +The `violations` object is a JSON *object* with the following fields: + +| Name | Type | Required/Optional | Description | +| ---------------- | ------ | ----------------- | ------------- | +| `violation_code` | String | Optional | The unique code created by the municipality, city, county, state, federal, or enforcement agency to identify the type of rule being enforced. | +| `violation_name` | String | Optional | The city/municipal, county, state, provincial, or federal code that was violated. | +| `violation_cost` | String | Optional | The original cost associated with the violation. | + +[Top][toc] + +## External Reference + +An External Reference object describes a specific feature from an external data source that is relevant to a part of MDS data. This allows MDS users to reference other data sources that impact or provide information about an MDS object, and see more details at an external URL. Data sources can be anything available via a URL, including an existing data standard (CDS, WZDx, CWZ, GTFS, GBFS, MDS, etc), a custom feed, API, document, web page, report, etc. + +An `external_reference` is a JSON *array* with the following fields within objects: + +| Name | Type | Required/Optional | Description | +| ------ | ------ | ------------------- | ------------- | +| `reference_url` | URL | Required | A web-accessible identifier URL for the source of the publicly or privately accessible data feed, document, website, etc. This MUST be a full HTTPS URL pointing to a location which contains more information impacting or explaining the location, event, or policy, etc. | +| `name` | String | [Optional](./general-information.md#optional-fields) | Name of the data source for reference. E.g. "WZDx", "CWZ", "GBFS", "GTFS", "Waze CIF", "TOMP", "OCPI", "NEVI", "DATEX", "TODS", "TIDES", even across to "CDS", and back to "MDS". | +| `public` | Boolean | [Optional](./general-information.md#optional-fields) | Is this data source able to be viewed with out any sort of authentication? If `true`, the `reference_url` is public. If `false`, the `reference_url` requires some sort of authentication, authorization, or API key to access. This is an informational field to set access expectations for the data source user, and does not provide any credentials directly unless explicitly contained in the `reference_url`. | +| `identifier_name` | String | [Optional](./general-information.md#optional-fields) | The name of the data field identifier or object that is referenced by the unique `ids`. E.g. "id", "report_id", "trip_id", "vehicle_id", "RoadEventFeature", etc, if relevant and available in `reference_url`. | +| `ids` | Array of Strings | [Optional](./general-information.md#optional-fields) | An array of one or more **ids** from the data sources that impacts the use of or relationship to part of MDS, e.g. Trips, Events, Stops, etc. The **ids** and their details are be found in the referenced `reference_url`. | + +[Top][toc] + [costs-and-currencies]: /general-information.md#costs-and-currencies [event-times]: #event-times +[external-reference]: #external-reference [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 [geography-driven-events]: /general-information.md#geography-driven-events @@ -308,5 +410,5 @@ Other special group types may be added in future MDS releases as relevant agency [toc]: #table-of-contents [ts]: /general-information.md#timestamps [vehicle-states]: /general-information.md#vehicle-states -[vehicle-events]: /general-information.md#event-types +[vehicle-events]: /modes/event_types.md [vehicle-types]: #vehicle-types diff --git a/general-information.md b/general-information.md index 21a37cbb8..88b0d1211 100644 --- a/general-information.md +++ b/general-information.md @@ -165,8 +165,6 @@ 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) - 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). @@ -187,8 +185,6 @@ Here's how it works in practice: 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. -During the Beta period for this feature, location and telemetry data remain required fields. This allows Agencies to test Geography-Driven Events, measuring its accuracy and efficacy against regulatory systems based on precise location data. After the beta period, if Geography-Driven Events is deemed by the OMF to be accurate and effective, the specification will evolve to allow cities to use Geography-Driven Events in lieu of location or telemetry data. - [Top][toc] ## Responses @@ -245,6 +241,8 @@ For multi-record POST and PUT calls, e.g. sending Events using the Agency API, t ### Failure Details +When there is a failure, stop processing the batch request, and return an error code relevant to the first error found. + | Field | Type | Field Description | | ------------------- | -------------------- | --------------------------------------------------- | | `item` | Vehicle, Event, etc. | Invalid submitted item | diff --git a/geography/README.md b/geography/README.md index 968d2c7af..5b1fec79f 100644 --- a/geography/README.md +++ b/geography/README.md @@ -24,6 +24,7 @@ Geographical data will be stored as GeoJSON and read from either `geographies.js - [Endpoints](#endpoints) - [Geography](#geography) - [Geographies](#geographies) + - [Geographies - Create](#geographies---create) - [Examples](#examples) ## General Information @@ -180,6 +181,7 @@ The Geography API consists of the following endpoints: **Endpoint**: `/geographies/{geography_id}` **Method**: `GET` **Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. +**Authorization**: public #### Path Parameters @@ -225,6 +227,7 @@ See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schem **Endpoint**: `/geographies` **Method**: `GET` **Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. +**Authorization**: public Returns: All geography objects @@ -257,6 +260,48 @@ See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schem [Top][toc] +### Geographies - Create + +Allows agencies to push a newly created policies to geographies, similar to the Agency API. This push method creates the opportunity for near real-time communication of geography changes. + +Note that when an update is communicated via a geography push, the agency should pull or push from the relevant [Policy API](../policy) endpoint to see if there are new or changed policies related to this geographic area. + +Endpoint producers **SHALL** provide authorization for API endpoints via a bearer token based auth system specified in the MDS [Authorization section](/general-information.md#authorization), to allow handshake communication and response confirmation. + +**Endpoint**: `/geographies/` +**Method:** `POST` +**Authorization**: required +**Payload:** An array of [Geography](#schema) objects + +_Optional endpoint, as required by public agencies; if not implemented, the server should reply with `501 Not Implemented` if possible._ + +#### Responses + +_Possible HTTP Status Codes_: +201, +400, +401, +406, +409, +500, +501 + +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_created` | A geography with `geography_id` is already created | | + +Note that you may only create a new MDS Geography. Retired geographies are simply referenced in `prev_geographies`. See [Distribution](#distribution) for details. + +[Top][toc] + ## Examples See the [Geography Examples](examples/README.md) for ways these can be implemented and geometry previews. diff --git a/jurisdiction/README.md b/jurisdiction/README.md index 64c64d4d9..471925cdf 100644 --- a/jurisdiction/README.md +++ b/jurisdiction/README.md @@ -7,7 +7,6 @@ This specification details the purpose, use cases, and schema for Jurisdictions. ## Table of Contents - [Background](#background) -- [Beta Feature](#beta-feature) - [Authorization](#authorization) - [Use Cases](#use-cases) - [Distribution](#distribution) @@ -37,14 +36,6 @@ A jurisdiction is: [Top][toc] -## Beta Feature - -The Jurisdictions API and all of its endpoints are marked as a [beta feature](https://github.com/openmobilityfoundation/mobility-data-specification/blob/feature-metrics/general-information.md#beta-features) starting in the 1.1.0 release. It has not been tested in real world scenarios, and may be adjusted in future releases. - -**[Beta feature](https://github.com/openmobilityfoundation/mobility-data-specification/blob/feature-metrics/general-information.md#beta-features)**: _Yes (as of 1.1.0)_. [Leave feedback](https://github.com/openmobilityfoundation/mobility-data-specification/issues/673) - -[Top][toc] - ### Authorization This endpoint should be made public. Authorization is not required. @@ -144,7 +135,6 @@ Gets all of an agency's Jurisdictions. Served by agencies. **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 @@ -173,7 +163,6 @@ Gets a single Jurisdictions. Served by agencies. **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 diff --git a/metrics/README.md b/metrics/README.md index 1ae397750..7d1cc7a0c 100644 --- a/metrics/README.md +++ b/metrics/README.md @@ -12,7 +12,6 @@ The Metrics API endpoints are intended to be implemented by regulatory agencies, - [Implementation](#implementation) - [Authorization](#authorization) - [Data Requirements](#data-requirements) -- [Beta Feature](#beta-feature) - [Date and Time Format](#date-and-time-format) - [Data Schema](#data-schema) - [Data Redaction](#data-redaction) @@ -83,14 +82,6 @@ Metrics may be a supplement for other more granular MDS data, and may be used to [Top][toc] -## Beta Feature - -**[Beta feature](https://github.com/openmobilityfoundation/mobility-data-specification/blob/feature-metrics/general-information.md#beta-features)**: _Yes (as of 1.0.0)_. [Leave feedback](https://github.com/openmobilityfoundation/mobility-data-specification/issues/671) - -The Metrics API and all of its endpoints are marked as a [beta feature](https://github.com/openmobilityfoundation/mobility-data-specification/blob/feature-metrics/general-information.md#beta-features). It has not been tested in real world scenarios, and may be adjusted in future releases. - -[Top][toc] - ## Date and Time Format All dates and times (datetime) are [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) formatted strings (YYYY-MM-DDTHHMM), with minute granularity supported and time zone (default UTC) or included offset. Dates and times may also be specified using a numeric *Unix epoch/timestamp* @@ -111,7 +102,7 @@ Some combinations of dimensions, filters, time, and geography may return a small **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 together for privacy. -The OMF suggests a k-value of 10 is an appropriate starting point for safe anonymization, absent analysis and a further decision from the agency. As Metrics is in [beta](#beta-feature), 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, beta 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). +The OMF suggests a k-value of 10 is an appropriate starting point for safe anonymization, absent analysis and a further decision from the agency. 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). The k-value being used is always returned in the Metrics Query API [response](/metrics#response-1) to provide important context for the data consumer on the data redaction that is occurring. diff --git a/modes/README.md b/modes/README.md index 26187fc7d..ff42001dc 100644 --- a/modes/README.md +++ b/modes/README.md @@ -39,18 +39,12 @@ MDS is intended to be used for multiple transportation modes, including its orig ## List of Supported Modes -- **[Micromobility](/modes/micromobility.md)** (`micromobility`) - dockless or docked small devices such as e-scooters and bikes. -- **[Passenger services](/modes/passenger-services.md)** (`passenger-services`) - transporting individuals with a vehicle driven by another entity, including taxis, TNCs, and microtransit -- **[Car share](/modes/car-share.md)** (`car-share`) - shared point-to-point and station-based multi-passenger vehicles. -- **[Delivery robots](/modes/delivery-robots.md)** (`delivery-robots`) - autonomous and remotely driven goods delivery devices - -

-MDS Mode - Micromobility       -MDS Mode - Passenger Services       -MDS Mode - Car Share       -MDS Mode - Delivery Robots -

-
+- **[Micromobility](/modes/micromobility.md)** (`micromobility`) - customer operated dockless or docked small devices moving customers and goods, such as scooters, bikeshare, cargo bikes, adaptive scooters, docked bikes, mopeds, trikes, and quadracycles. +- **[Passenger](/modes/passenger-services.md)** (`passenger-services`) - employees and contractors, autonomous, and remotely operated transporting individuals or goods with a vehicle driven by another entity, including taxis, for-hire AVs, robotaxis, transportation network companies (TNCs), commercial transport apps (CTAs), and private hire vehicles (PHVs), shuttles, paratransit, on demand vehicles, limosines, and microtransit. _Note: this will use the `passenger` short name in the next breaking release._ +- **[Fleet](/modes/car-share.md)** (`car-share`) - customer, employees and contractors, autonomous, and remotely operated shared point-to-point, station-based, or free-floating multi-passenger or cargo vehicles like consumer car share, sanitation vehicles (garbage, recycling), city fleets, vehicle rentals, street sweepers, snow plows, utility services, construction, emergency response (police, fire, ambulance), tree maintenance, inspection and permitting vehicles, mobile health clinics, and heavy maintenance vehicles. _Note: this will use the `fleet` short name in the next breaking release._ +- **[Delivery](/modes/delivery-robots.md)** (`delivery-robots`) - employees and contractors, autonomous, and remotely operated sidewalk robots, app delivery, packages, freight, goods, food, private hire vehicles, postal service, medicine, and other delivery services. _Note: this will use the `delivery` short name in the next breaking release._ + +MDS Modes: Micromobility, Passenger, Fleet, Delivery [Top][toc] diff --git a/modes/car-share-state-machine-diagram.svg b/modes/car-share-state-machine-diagram.svg index 365977f55..ba4770280 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 9cea3484e..8d609024c 100644 --- a/modes/car-share.md +++ b/modes/car-share.md @@ -1,11 +1,13 @@ -# Mobility Data Specification: **Car Share** +# Mobility Data Specification: **Fleet** -MDS Modes - Car Share +MDS Modes - Fleet -**Car Share** refers to shared point-to-point and station-based mutli-passenger vehicles. Car Share typically has a driver who is the customer, and possibly one or more passengers or cargo. +**Fleet** refers to shared customer, employees and contractors, autonomous, and remotely operated shared point-to-point, station-based, or free-floating multi-passenger or cargo vehicles like consumer car share, sanitation vehicles (garbage, recycling), city fleets, vehicle rentals, street sweepers, snow plows, utility services, construction, emergency response (police, fire, ambulance), tree maintenance, inspection and permitting vehicles, mobile health clinics, and heavy maintenance vehicles. See the [modes overview](/modes) for how the mode specific information below applies across MDS. +_Note: Formerly called "Car Share". Any references in the specification code or links to only "Car Share" will be updated to the broader "Fleet" scope in the next MDS 3.0 release._ + ## Table of Contents - [Mode Attributes](#mode-attributes) @@ -23,14 +25,14 @@ See the [modes overview](/modes) for how the mode specific information below app - [State Machine](#state-machine) - [Vehicle States](#vehicle-states) - [Event Types](#event-types) - - [Vehicle State Events](#vehicle-states-events) + - [Vehicle States Events](#vehicle-states-events) - [State Machine Diagram](#state-machine-diagram) ## Mode Attributes ### Mode ID -The short name identifier for Car Share used across MDS is `car-share`. +The short name identifier for Fleet used across MDS is `car-share`. In a future release this will be updated to `fleet`. [Top][toc] @@ -42,11 +44,129 @@ _See more available trip and fare attributes for any mode used in the [trips obj The `journey_id` field shall have a consistent value in overlapping trips for a single reservation period, e.g. trips taken by a customer between ignition states over the duration of their reservation. A reservation is the duration the customer has continuous exclusive access to the vehicle whether parked or in motion. Journeys may be point-to-point or multi-segment. -- **Example 1**: customer makes a reservation and company delivers vehicle to customer, then one trip point-to-point by customer, ending reservation at destination -- **Example 2**: customer reservation for multiple days with trips for errands, gas, entertainment, etc -- **Example 3**: one trip point-to-point with an employee moving the vehicle to a new location for maintenance +```mermaid +--- +config: + theme: 'base' + themeVariables: + 'activeTaskBkgColor': '#155654' + 'activeTaskBorderColor': '#2AF1BE' + 'critBorderColor': '#2AF1BE' + 'doneTaskBkgColor': '#299c90' + 'doneTaskBorderColor': '#373737' + 'taskBkgColor': '#2AF1BE' + 'taskBorderColor': '#373737' + 'taskTextColor': '#373737' + 'taskTextDarkColor': 'white' + 'taskTextLightColor': '#373737' + 'vertLineColor': '#155654' + 'sectionBkgColor': '#ddd' + 'altSectionBkgColor': '#aaa' + 'sectionBkgColor2': '#777' +--- +gantt + title Example 1: car share single journey, company delivers vehicle to customer, one trip point-to-point by customer + dateFormat HH:mm + axisFormat %H:%M + + section Journey + Journey Start : vert, v1, 17:00, 2m + + Journey : active, a, 17:00, 55m + + Trip - reservation : b, 17:00, 10m + Trip - private : b, 17:10, 45m + + Journey End : vert, v1, 17:55, 5m + +``` + +```mermaid +--- +config: + theme: 'base' + themeVariables: + 'activeTaskBkgColor': '#155654' + 'activeTaskBorderColor': '#2AF1BE' + 'critBorderColor': '#2AF1BE' + 'doneTaskBkgColor': '#299c90' + 'doneTaskBorderColor': '#373737' + 'taskBkgColor': '#2AF1BE' + 'taskBorderColor': '#373737' + 'taskTextColor': '#373737' + 'taskTextDarkColor': 'white' + 'taskTextLightColor': '#373737' + 'vertLineColor': '#155654' + 'sectionBkgColor': '#ddd' + 'altSectionBkgColor': '#aaa' + 'sectionBkgColor2': '#777' +--- +gantt + title Example 2: customer car share reservation for 4 days with a trip daily for errands, gas, entertainment, etc + dateFormat MM-DD + + section Reservation + Reservation Start : vert, v1, 03-20, 2m + + Reservation : done, a, 03-20, 4d + + Trip - private : b, 03-20, 1d + Trip - private : b, 03-21, 1d + Trip - private : b, 03-22, 1d + Trip - private : b, 03-23, 1d + + Reservation End : vert, v1, 03-24, 12h +``` + +```mermaid +--- +config: + theme: 'base' + themeVariables: + 'activeTaskBkgColor': '#155654' + 'activeTaskBorderColor': '#2AF1BE' + 'critBorderColor': '#2AF1BE' + 'doneTaskBkgColor': '#299c90' + 'doneTaskBorderColor': '#373737' + 'taskBkgColor': '#2AF1BE' + 'taskBorderColor': '#373737' + 'taskTextColor': '#373737' + 'taskTextDarkColor': 'white' + 'taskTextLightColor': '#373737' + 'vertLineColor': '#155654' + 'sectionBkgColor': '#ddd' + 'altSectionBkgColor': '#aaa' + 'sectionBkgColor2': '#777' +--- +gantt + title Example 3: a shift of a city snow plow driver, showing journeys from a central location, and trips inside the journeys + dateFormat HH:mm + axisFormat %H:%M + + section Shift + Shift Start : vert, v1, 17:00, 2m + Shift : done, a, 17:00, 90m + + section Journey 1 + Journey 1 : active, a, 17:00, 50m + Trip - private : b, 17:00, 10m + Trip - private : b, 17:10, 10m + Trip - private : b, 17:20, 20m + Trip - empty : b, 17:40, 10m + + section Journey 2 + Journey 2 : active, a, 17:50, 20m + Trip - private : b, 17:50, 10m + Trip - empty : b, 18:00, 10m + + section Journey 3 + Journey 3 : active, a, 18:10, 20m + Trip - private : b, 18:10, 12m + Trip - empty : b, 18:22, 8m + + Shift End : vert, v1, 18:30, 10m +``` -![Journey Diagram](https://i.imgur.com/FHxQLps.png) [Top][toc] @@ -54,7 +174,8 @@ The `journey_id` field shall have a consistent value in overlapping trips for a The `journey_attributes` object **may** have the following key value pairs: -- `reservation_id` (UUID, [Optional](../general-information.md#optional-fields)): unique identifier for an entire car share reservation, tied across multiple journeys and therefore trips. +- `reservation_id` (UUID, [Optional](../general-information.md#optional-fields)): unique identifier for an entire vehicle reservation, tied across multiple journeys and therefore trips. +- `shift_id` (UUID, [Optional](../general-information.md#optional-fields)): unique identifier for a driver or operator's working shift, tied across multiple journeys and therefore trips. [Top][toc] @@ -70,9 +191,10 @@ Additionally, `trip_id` is required if `event_types` contains a `trip_enter_juri The `trip_type` field **must** have one of the following enumerated values: -- `private`: a private trip made by one paying customer with one or more guests -- `reservation`: en route to pickup a customer who has made a reservation, with no passengers in the vehicle -- `empty`: vehicle movement with no customer (outside of other `trip_type` values) that may need to be reported, e.g. for maintenance +- `private` (_default_): a private trip made by one paying customer with one or more guests, or a driver using the vehicle +- `reservation`: en route to pickup a customer who has made a reservation, or movement before starting an official task +- `mapping`: primarily mapping the environment +- `empty`: vehicle movement with no customer or work (outside of other `trip_type` values) that may need to be reported, e.g. for maintenance, returning, etc [Top][toc] @@ -127,14 +249,21 @@ The `vehicle_attributes` object **may** have the following key value pairs: - `phone_charger` (boolean, [Optional](../general-information.md#optional-fields)) - a place to charge your phone - `sunshade` (boolean, [Optional](../general-information.md#optional-fields)) - sunshade available (i.e. for windshield) - `cargo_volume_capacity` (integer, [Optional](../general-information.md#optional-fields)) - Cargo volume available in the vehicle, expressed in liters. For cars, it corresponds to the space between the boot floor, including the storage under the hatch, to the rear shelf in the trunk. -- `cargo_load_capacity` (integer, [Optional](../general-information.md#optional-fields)) - The capacity of the vehicle cargo space (excluding passengers), expressed in kilograms. +- `cargo_load_capacity` (integer, [Optional](../general-information.md#optional-fields)) - The capacity of the vehicle cargo space (excluding passengers), expressed in kilograms - `door_count` (integer, [Optional](../general-information.md#optional-fields)) - number of doors this vehicle type has - `wheel_count` (integer, [Optional](../general-information.md#optional-fields)) - number of wheels this vehicle type has - `air_conditioning` (boolean, [Optional](../general-information.md#optional-fields)) - vehicle has air conditioning -- `gear_switch` (enum, [Optional](../general-information.md#optional-fields)) - one of `automatic`, `manual` +- `gear_switch` (enum, [Optional](../general-information.md#optional-fields)) - one of `automatic` (automatic and semi-automatic), `manual` (single or dual clutch, intelligent manual), `variable` (Continuously Variable Transmission (CVT)) - `convertible` (boolean, [Optional](../general-information.md#optional-fields)) - vehicle has a retractable roof - `cruise_control` (boolean, [Optional](../general-information.md#optional-fields)) - vehicle has a cruise control system - `navigation` (boolean, [Optional](../general-information.md#optional-fields)) - vehicle has a built-in navigation system +- `wheel_drive` (string, [Optional](../general-information.md#optional-fields)) - type of wheel drive of the vehicle (e.g., 4WD, AWD, front wheel drive, back wheel drive) +- `child_seat` (boolean, [Optional](../general-information.md#optional-fields)) - the vehicle is equipped with a children's seat +- `pets_allowed` (boolean, [Optional](../general-information.md#optional-fields)) - pets are allowed in the vehicle +- `rooftop_cargo_box` (boolean, [Optional](../general-information.md#optional-fields)) - the vehicle is equipped with a rooftop cargo box +- `roof_rails` (boolean, [Optional](../general-information.md#optional-fields)) - the vehicle is equipped with roof rails +- `ski_hatch` (boolean, [Optional](../general-information.md#optional-fields)) - the vehicle has a ski hatch in the rear seat row +- `winter_tires` (boolean, [Optional](../general-information.md#optional-fields)) - the vehicle is equipped with winter tires Note many of these attributes come from fields in [GBFS vehicle_types](https://github.com/MobilityData/gbfs/blob/v2.3/gbfs.md#vehicle_typesjson). @@ -154,7 +283,7 @@ This `accessibility_attributes` enum represents the accessibility attributes ava ### Vehicle States -Valid car share vehicle states are +Valid fleet vehicle states are - `removed` - `available` @@ -171,7 +300,7 @@ See [Vehicle States][vehicle-states] for descriptions. ### Event Types -Valid car share vehicle event types are +Valid fleet vehicle event types are - `charging_start` - `charging_end` @@ -206,63 +335,84 @@ See vehicle [Event Types][vehicle-events] for descriptions. This is the list of `vehicle_state` and `event_type` pairings that constitute the valid transitions of the vehicle state machine. -| **From** `vehicle_state` | **To** `vehicle_state` | `trip_state` | `event_type` | Description | -| ------------------------ | ---------------------- | ------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------- | -| `available` | `elsewhere` | N/A | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while available for-hire | -| `available` | `non_contactable` | N/A | `comms_lost` | The vehicle has went out of comms while available for-use | -| `available` | `non_operational` | N/A | `service_end` | The vehicle has went out of service (is unavailable for-hire) | -| `available` | `reserved` | `reserved` | `reservation_start` | The vehicle was reserved by a passenger | -| `elsewhere` | `available` | N/A | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while available for-hire | -| `elsewhere` | `non_contactable` | N/A | `comms_lost` | The vehicle has went out of comms while outside of jurisdictional boundaries | -| `elsewhere` | `non_operational` | N/A | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while not operating commercially | -| `elsewhere` | `on_trip` | `on_trip` | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while on a trip | -| `elsewhere` | `reserved` | N/A | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while reserved by a customer | -| `non_contactable` | `available` | N/A | `comms_restored` | The vehicle has come back into comms while available for-hire | -| `non_contactable` | `elsewhere` | N/A | `comms_restored` | The vehicle has come back into comms while outside of jurisdictional boundaries | -| `non_contactable` | `non_operational` | N/A | `comms_restored` | The vehicle has come back into comms while not operating commercially | -| `non_contactable` | `on_trip` | `on_trip` | `comms_restored` | The vehicle has come back into comms while on a trip | -| `non_contactable` | `removed` | N/A | `comms_restored` | The vehicle has come back into comms while removed | -| `non_contactable` | `reserved` | `reserved` | `comms_restored` | The vehicle has come back into comms while reserved by a passenger | -| `non_contactable` | `stopped` | `stopped` | `comms_restored` | The vehicle has come back into comms while stopped | -| `non_operational` | `available` | N/A | `service_start` | The vehicle has went into service (is available for-hire) | -| `non_operational` | `elsewhere` | N/A | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while not operating commercially | -| `non_operational` | `non_contactable` | N/A | `comms_lost` | The vehicle has went out of comms while not operating commercially | -| `non_operational` | `removed` | N/A | `decommissioned` | The vehicle has been removed from the Provider's fleet | -| `non_operational` | `removed` | N/A | `maintenance_pick_up` | The vehicle has entered the depot for maintenance | -| `non_operational` | `removed` | N/A | `maintenance` | The vehicle is undergoing maintenance on site | -| `on_trip` | `elsewhere` | N/A | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while on a trip | -| `on_trip` | `non_contactable` | N/A | `comms_lost` | The vehicle has gone out of comms while on a trip | -| `on_trip` | `stopped` | `stopped` | `trip_stop` | The vehicle has stopped while on a trip | -| `removed` | `non_contactable` | N/A | `comms_lost` | The vehicle has gone out of comms while removed | -| `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 | `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 customer has activated the vehicle | -| `stopped` | `available` | N/A | `driver_cancellation` | The driver has canceled the trip | -| `stopped` | `available` | N/A | `customer_cancellation` | The customer has canceled the trip | -| `stopped` | `available` | N/A | `provider_cancellation` | The provider has canceled the trip | -| `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 | -| `stopped` | `on_trip` | `on_trip` | `trip_resume` | Resume a trip that was previously stopped (e.g. picking up a friend to go to the airport with) | -| `stopped` | `on_trip` | `on_trip` | `trip_start` | Start a trip | -| `stopped` | `stopped` | `stopped` | `charging_end` | End charging the device battery | -| `stopped` | `stopped` | `stopped` | `charging_start` | Start charging the device battery | -| `stopped` | `stopped` | `stopped` | `fueling_end` | End fueling the device with physical fuel | -| `stopped` | `stopped` | `stopped` | `fueling_start` | Start fueling the device with physical fuel | -| `stopped` | `stopped` | `stopped` | `remote_end` | Remotely stop the engine while vehicle is already stopped | -| `stopped` | `stopped` | `stopped` | `remote_start` | Remotely start the engine while vehicle is stopped, usually to charge battery or warm up | +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|------------------------------------------------------------------------------------------------| +| `available` | `elsewhere` | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while available for-hire | +| `available` | `non_contactable` | `comms_lost` | The vehicle has went out of comms while available for-use | +| `available` | `non_operational` | `service_end` | The vehicle has went out of service (is unavailable for-hire) | +| `available` | `reserved` | `reservation_start` | The vehicle was reserved by a passenger | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|------------------------------------------------------------------------------------------------| +| `elsewhere` | `available` | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while available for-hire | +| `elsewhere` | `non_contactable` | `comms_lost` | The vehicle has went out of comms while outside of jurisdictional boundaries | +| `elsewhere` | `non_operational` | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while not operating commercially | +| `elsewhere` | `on_trip` | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while on a trip | +| `elsewhere` | `reserved` | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while reserved by a customer | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|------------------------------------------------------------------------------------------------| +| `non_contactable` | `available` | `comms_restored` | The vehicle has come back into comms while available for-hire | +| `non_contactable` | `elsewhere` | `comms_restored` | The vehicle has come back into comms while outside of jurisdictional boundaries | +| `non_contactable` | `non_operational` | `comms_restored` | The vehicle has come back into comms while not operating commercially | +| `non_contactable` | `on_trip` | `comms_restored` | The vehicle has come back into comms while on a trip | +| `non_contactable` | `removed` | `comms_restored` | The vehicle has come back into comms while removed | +| `non_contactable` | `reserved` | `comms_restored` | The vehicle has come back into comms while reserved by a passenger | +| `non_contactable` | `stopped` | `comms_restored` | The vehicle has come back into comms while stopped | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|------------------------------------------------------------------------------------------------| +| `non_operational` | `available` | `service_start` | The vehicle has went into service (is available for-hire) | +| `non_operational` | `elsewhere` | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while not operating commercially | +| `non_operational` | `non_contactable` | `comms_lost` | The vehicle has went out of comms while not operating commercially | +| `non_operational` | `removed` | `decommissioned` | The vehicle has been removed from the Provider's fleet | +| `non_operational` | `removed` | `maintenance_pick_up` | The vehicle has entered the depot for maintenance | +| `non_operational` | `removed` | `maintenance` | The vehicle is undergoing maintenance on site | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|------------------------------------------------------------------------------------------------| +| `on_trip` | `elsewhere` | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while on a trip | +| `on_trip` | `non_contactable` | `comms_lost` | The vehicle has gone out of comms while on a trip | +| `on_trip` | `stopped` | `trip_stop` | The vehicle has stopped while on a trip | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|------------------------------------------------------------------------------------------------| +| `removed` | `non_contactable` | `comms_lost` | The vehicle has gone out of comms while removed | +| `removed` | `non_operational` | `maintenance_end` | The vehicle maintenance work has ended | +| `removed` | `non_operational` | `recommissioned` | The vehicle has been re-added to the Provider's fleet after being previously `decommissioned` | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|------------------------------------------------------------------------------------------------| +| `reserved` | `available` | `driver_cancellation` | The driver has canceled the reservation | +| `reserved` | `available` | `customer_cancellation` | The customer has canceled the reservation | +| `reserved` | `available` | `provider_cancellation` | The provider has canceled the reservation | +| `reserved` | `elsewhere` | `trip_leave_jurisdiction` | The vehicle has left the jurisdiction while in a reservation | +| `reserved` | `non_contactable` | `comms_lost` | The vehicle went out of comms while being reserved by a passenger | +| `reserved` | `stopped` | `reservation_stop` | The customer has activated the vehicle | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|------------------------------------------------------------------------------------------------| +| `stopped` | `available` | `driver_cancellation` | The driver has canceled the trip | +| `stopped` | `available` | `customer_cancellation` | The customer has canceled the trip | +| `stopped` | `available` | `provider_cancellation` | The provider has canceled the trip | +| `stopped` | `available` | `trip_end` | The trip has been successfully completed | +| `stopped` | `non_contactable` | `comms_lost` | The vehicle has went out of comms while stopped | +| `stopped` | `on_trip` | `trip_resume` | Resume a trip that was previously stopped (e.g. picking up a friend to go to the airport with) | +| `stopped` | `on_trip` | `trip_start` | Start a trip | +| `stopped` | `stopped` | `charging_end` | End charging the device battery | +| `stopped` | `stopped` | `charging_start` | Start charging the device battery | +| `stopped` | `stopped` | `fueling_end` | End fueling the device with physical fuel | +| `stopped` | `stopped` | `fueling_start` | Start fueling the device with physical fuel | +| `stopped` | `stopped` | `remote_end` | Remotely stop the engine while vehicle is already stopped | +| `stopped` | `stopped` | `remote_start` | Remotely start the engine while vehicle is stopped, usually to charge battery or warm up | [Top][toc] ### State Machine Diagram -This *State Machine Diagram* shows how `vehicle_state` and `event_type` relate to each other and how vehicles can transition between states. See [Google Slides](https://docs.google.com/presentation/d/1fHdq1efbN5GSFDLF4en-oA_BYPXQKbbIbHff6iROJKA/edit#slide=id.g2072486e468_1_300) for the source file. +This *State Machine Diagram* shows how `vehicle_state` and `event_type` relate to each other and how vehicles can transition between states. See [Google Slides](https://docs.google.com/presentation/d/1FCrBCtNQyoIcchaGx6zw4BpLCquQaWmBHsEU6fUdUoo/edit?slide=id.g2072486e468_1_300#slide=id.g2072486e468_1_300) for the source file. -![Car Share State Machine Diagram](car-share-state-machine-diagram.svg) +![Fleet State Machine Diagram](car-share-state-machine-diagram.svg) [Top][toc] diff --git a/modes/delivery-robots-state-machine-diagram.svg b/modes/delivery-robots-state-machine-diagram.svg index 9e2dfa7c6..ab3bc5515 100644 --- a/modes/delivery-robots-state-machine-diagram.svg +++ b/modes/delivery-robots-state-machine-diagram.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/modes/delivery-robots.md b/modes/delivery-robots.md index d170a91c3..9477e41b0 100644 --- a/modes/delivery-robots.md +++ b/modes/delivery-robots.md @@ -1,14 +1,14 @@ -# Mobility Data Specification: **Delivery Robots** +# Mobility Data Specification: **Delivery** -MDS Modes - Delivery Robots +MDS Modes - Delivery Robots -**Delivery Robots** refers to autonomous and remotely driven goods delivery devices. There can be one or multiple orders on different trips at the same time. The state machine tracks the trip states of the orders separately from the vehicle state. +**Delivery** refers to employees and contractors, autonomous, and remotely operated sidewalk robots, app delivery, packages, freight, goods, food, private hire vehicles, electric cargo bikes and trikes, mopeds and motorcycles, box trucks, bike and scooter couriers, cargo vans, semi-trucks and tractor-trailers, postal service, medicine, and other delivery services. -See the [modes overview](/modes) for how the mode specific information below applies across MDS. +There can be one or multiple orders on different trips at the same time, connected via the journey identifier. The state machine tracks the trip states of the orders separately from the vehicle state. -## Robots Vs Other Delivery Types +See the [modes overview](/modes) for how the mode specific information below applies across MDS. -Autonomous and remotely piloted delivery robots do not require a driver, whereas other forms of deliveries may, e.g. in a commercial or private car, truck, bike, etc. For this MDS release, this mode is limited to deliveries where a human driver is not on board the vehicle doing the delivery, and human passengers are not being transported. +_Note: Formerly called "Delivery Robots". Any references in the specification code or links to only "Delivery Robots" will be updated to the broader "Delivery" scope in the next MDS 3.0 release._ ## Table of Contents @@ -27,14 +27,14 @@ Autonomous and remotely piloted delivery robots do not require a driver, whereas - [State Machine](#state-machine) - [Vehicle States](#vehicle-states) - [Event Types](#event-types) - - [Vehicle State Events](#vehicle-states-events) + - [Vehicle States Events](#vehicle-states-events) - [State Machine Diagram](#state-machine-diagram) ## Mode Attributes ### Mode ID -The short name identifier for deliveries used across MDS is `delivery-robots`. +The short name identifier for deliveries used across MDS is `delivery-robots`. _To be `delivery` in the next breaking release._ [Top][toc] @@ -44,19 +44,150 @@ _See more available trip and fare attributes for any mode used in the [trips obj ### Journey ID -The `journey_id` field shall have a consistent value in overlapping trips. Journeys may be point-to-point, multi-segment, or multi-segment overlapping. +The `journey_id` field shall have a consistent value in overlapping trips. Journeys may be point-to-point, multi-segment, or multi-segment overlapping. Note that multiple journeys can be tied together with `shift_id` or `route_id` in [Journey Attributes](#journey-attributes). + +```mermaid +--- +config: + theme: 'base' + themeVariables: + 'activeTaskBkgColor': '#155654' + 'activeTaskBorderColor': '#2AF1BE' + 'critBorderColor': '#2AF1BE' + 'doneTaskBkgColor': '#299c90' + 'doneTaskBorderColor': '#373737' + 'taskBkgColor': '#2AF1BE' + 'taskBorderColor': '#373737' + 'taskTextColor': '#373737' + 'taskTextDarkColor': 'white' + 'taskTextLightColor': '#373737' + 'vertLineColor': '#155654' + 'sectionBkgColor': '#ddd' + 'altSectionBkgColor': '#aaa' + 'sectionBkgColor2': '#777' +--- +gantt + title Example 1: delivery to a single location, then return + dateFormat HH:mm + axisFormat %H:%M + + Start : vert, v1, 17:00, 2m -- **Example 1**: delivery to a single location, then return -- **Example 2**: three overlapping delivery trips in the same journey + Trip - delivery : b, 17:00, 20m + Trip - return : b, 17:20, 20m -![Journey Diagram](https://i.imgur.com/Mx8jVQq.png) + End : vert, v1, 17:40, 5m +``` + +```mermaid +--- + +config: + theme: 'base' + themeVariables: + 'activeTaskBkgColor': '#155654' + 'activeTaskBorderColor': '#2AF1BE' + 'critBorderColor': '#2AF1BE' + 'doneTaskBkgColor': '#299c90' + 'doneTaskBorderColor': '#373737' + 'taskBkgColor': '#2AF1BE' + 'taskBorderColor': '#373737' + 'taskTextColor': '#373737' + 'taskTextDarkColor': 'white' + 'taskTextLightColor': '#373737' + 'vertLineColor': '#155654' + 'sectionBkgColor': '#ddd' + 'altSectionBkgColor': '#aaa' + 'sectionBkgColor2': '#777' +--- +gantt + title Example 2: four overlapping delivery trips in the same journey + dateFormat HH:mm + axisFormat %H:%M + + section Journey + Journey Start : vert, v1, 17:00, 2m + + Journey : active, a, 17:00, 50m + Trip - delivery : b, 17:00, 10m + Stop 1 : vert, v1, 17:10, 2m + Trip - roaming : b, 17:10, 10m + Stop 2 : vert, v1, 17:20, 2m + Trip - delivery : b, 17:20, 15m + Trip - delivery : b, 17:20, 20m + Trip - delivery : b, 17:20, 25m + Stop 3 : vert, v1, 17:35, 2m + Stop 4 : vert, v1, 17:40, 2m + Stop 5 : vert, v1, 17:45, 2m + Trip - return : b, 17:45, 5m + + Journey End : vert, v1, 17:50, 5m +``` + +```mermaid +--- +config: + theme: 'base' + themeVariables: + 'activeTaskBkgColor': '#155654' + 'activeTaskBorderColor': '#2AF1BE' + 'critBorderColor': '#2AF1BE' + 'doneTaskBkgColor': '#299c90' + 'doneTaskBorderColor': '#373737' + 'taskBkgColor': '#2AF1BE' + 'taskBorderColor': '#373737' + 'taskTextColor': '#373737' + 'taskTextDarkColor': 'white' + 'taskTextLightColor': '#373737' + 'vertLineColor': '#155654' + 'sectionBkgColor': '#ddd' + 'altSectionBkgColor': '#aaa' + 'sectionBkgColor2': '#777' +--- +gantt + title Example 3: delivery trips (w/ multiple orders) and journeys in 2 routes and 1 driver shift + dateFormat HH:mm + axisFormat %H:%M + + section Routes + Shift Start : vert, v1, 17:00, 2m + Shift : active, crit, a, 17:00, 90m + Route 1: done, a, 17:00, 70m + Route 2: done, a, 18:10, 20m + + section Journey 1 + Journey : active, a, 17:00, 50m + Trip - delivery : b, 17:00, 10m + Trip - delivery : b, 17:10, 10m + Trip - delivery : b, 17:20, 20m + Order 1: crit, done, c, 17:25, 5m + Order 2: crit, done, c, 17:30, 5m + Order 3: crit, done, c, 17:30, 10m + Trip - return : b, 17:40, 10m + + section Journey 2 + Journey : active, a, 17:50, 20m + Trip - delivery : b, 17:50, 10m + Trip - return : b, 18:00, 10m + + section Journey 3 + Journey : active, a, 18:10, 20m + Trip - delivery : b, 18:10, 12m + Trip - return : b, 18:22, 8m + + Shift End : vert, v1, 18:30, 10m +``` [Top][toc] ### Journey Attributes -The `journey_attributes` object is not used in this mode. +The `journey_attributes` object **may** have the following key value pairs: + +- `shift_id` (UUID, [Optional](../general-information.md#optional-fields)): unique identifier for a driver or operator's working shift, tied across multiple journeys and therefore trips. +- `route_id` (UUID, [Optional](../general-information.md#optional-fields)): unique identifier for a planned delivery or passenger route, tied across multiple journeys and therefore trips. +Shifts and routes are made up of journeys, and journeys are made up of trips, so these can be connected in various ways as needed. [Top][toc] @@ -64,8 +195,6 @@ The `journey_attributes` object is not used in this mode. 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`. -For the robots, the notion of driver does not exist, even when remotely operated. - Additionally, `trip_id` is required if `event_types` contains a `trip_enter_jurisdiction` or `trip_leave_jurisdiction` event pertaining to a trip. ### Trip Type @@ -74,11 +203,12 @@ The `trip_type` field is used to describe the trip itself. The `trip_type` field **must** have one of the following enumerated values: -- `delivery`: making a delivery -- `return`: returning to home location or next trip start +- `delivery` (_default_): making a delivery +- `return`: returning to home location or pickup point - `advertising`: displaying advertising and not making a delivery - `mapping`: mapping the environment and not making a delivery -- `roaming`: moving in right of way but not in another trip_type +- `roaming`: moving in right of way but not in another `trip_type` +- `testing`: vehicle is making a test trip [Top][toc] @@ -86,13 +216,28 @@ The `trip_type` field **must** have one of the following enumerated values: 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_id` (UUID, [Optional](../general-information.md#optional-fields)): consistent unique identifier of the primary driver. Could be based on software version or an internal human driver id. -- `app_name` (text, [Optional](../general-information.md#optional-fields)): name of the app used to reserve the trip which could be provider's app or 3rd party app -- `requested_time` ([Timestamp][ts], [Optional](../general-information.md#optional-fields)): when the customer requested the trip +- `driver_type` (enum, required): type of driver operating the device: `human`, `semi_autonomous`, `autonomous`, `remote` +- `driver_id` (UUID, [Optional](../general-information.md#optional-fields)): consistent unique identifier of the primary driver. Universal identifier of a specific driver, static across operators, like a driver's license number. Could also be used as a lookup in an agency's internal driver system. For autonomous or remote operations, could be based on software version, or an internal remote human driver id. +- `permit_number` (string, [Optional](../general-information.md#optional-fields)) - The permit number of the individual or organization that is operating the vehicle - `has_payload` (boolean, [Optional](../general-information.md#optional-fields)): is there any payload for any delivery included in the device at trip start. 1 = loaded, 0 = empty +- `parcel_count` (integer, [Optional](../general-information.md#optional-fields)) - count of individial parcels in the vehicle during this trip - `range` (integer, [Optional](../general-information.md#optional-fields)): estimated range in meters based on energy levels in device at trip start -- `identification_required` (boolean, [Optional](../general-information.md#optional-fields)): does the cargo require providing customer identification before trip start or upon delivery? +- `order` (Array, [Optional](../general-information.md#optional-fields)): Array of one or more orders with details for this trip: + - `order_id` (string, [Optional](../general-information.md#optional-fields)): identifier for this order, which could be used to cross reference in external system + - `app_name` (string, [Optional](../general-information.md#optional-fields)): name of the app used to reserve the trip which could be provider's app or 3rd party app + - `requested_time` ([Timestamp][ts], [Optional](../general-information.md#optional-fields)): when the customer requested the order + - `order_acceptance_time` ([Timestamp][ts], [Optional](../general-information.md#optional-fields)): when the driver has accepted the order, either in person or virtually + - `order_pickup_time` ([Timestamp][ts], [Optional](../general-information.md#optional-fields)): when the driver has physicaly picked up the order + - `unload_time` ([Timestamp][ts], [Optional](../general-information.md#optional-fields)): when the order was unloaded from the vehicle to finish delivery + - `delivery_time` ([Timestamp][ts], [Optional](../general-information.md#optional-fields)): when the order was delivered (e.g. customer received their order, package was left, etc). + - `pickup_location_name` (string, [Optional](../general-information.md#optional-fields)): name of the location where the order originated from + - `pickup_address` (string, [Optional](../general-information.md#optional-fields)): street address where the order originated from + - `origin_type` (string, [Optional](../general-information.md#optional-fields)): the name of the origin type for this delivery, e.g. ghost kitchen, individual restaurant, retail store, private delivery-courier, etc. + - `dropoff_address` (string, [Optional](../general-information.md#optional-fields)): street address where the trip ended + - `payload_type` (string, [Optional](../general-information.md#optional-fields)): the primary type or cargo or payload for this delivery, e.g. prepared food, parcel, medical, alcohol, grocery, etc. Could affect `fees`. + - `parcel_count` (integer, [Optional](../general-information.md#optional-fields)) - count of parcels in this order + - `identification_required` (boolean, [Optional](../general-information.md#optional-fields)): does the cargo require providing customer identification before trip start or upon delivery? + - `destination_type` (string, [Optional](../general-information.md#optional-fields)): the name of the destination type for this delivery, e.g. restaurant, residential, commerical, etc. [Top][toc] @@ -100,8 +245,12 @@ The `trip_attributes` object **may** have the following key value pairs: The `fare_attributes` object **may** have the following key value pairs: -- `payment_type` (enumerated, [Optional](../general-information.md#optional-fields)): `account_number`, `cash`, `credit_card`, `mobile_app`, `no payment`, `phone`, `voucher`, `test` -- `price` (currency, [Optional](../general-information.md#optional-fields)): Total price of the order +- `fare_order` (Array, [Optional](../general-information.md#optional-fields)): Array of one or more orders with details for this trip: + - `payment_type` (enumerated, [Optional](../general-information.md#optional-fields)): `account_number`, `cash`, `credit_card`, `mobile_app`, `no payment`, `phone`, `voucher`, `test` + - `price` (currency, [Optional](../general-information.md#optional-fields)): Total price of the order + - `tip` (currency, [Optional](../general-information.md#optional-fields)) - amount of tip paid by customer + - `taxes` (currency, [Optional](../general-information.md#optional-fields)) - amount of taxes paid for the trip + - `fees` (currency, [Optional](../general-information.md#optional-fields)): any additional fees (positive) or incentives/discounts (negative) for this trip [Top][toc] @@ -118,8 +267,9 @@ The `vehicle_attributes` object **may** have the following key value pairs: - `model` (string, [Optional](../general-information.md#optional-fields)) - `color` (string, [Optional](../general-information.md#optional-fields)) - `inspection_date` (date YYYY-MM-DD, [Optional](../general-information.md#optional-fields)): the date of the last inspection of the vehicle +- `software_version` (string, [Optional](../general-information.md#optional-fields)): the version of the software being used on this trip - `equipped_cameras` (integer, [Optional](../general-information.md#optional-fields)): number of cameras equipped on device -- `equipped_lighting` (integer, [Optional](../general-information.md#optional-fields)): number of lights used to illuminate the environment on the the device +- `equipped_lighting` (integer, [Optional](../general-information.md#optional-fields)): number of lights used to illuminate the environment on the device - `wheel_count` (integer, [Optional](../general-information.md#optional-fields)): number of wheels on the device - `width` (integer, [Optional](../general-information.md#optional-fields)): width in meters of the device - `length` (integer, [Optional](../general-information.md#optional-fields)): length in meters of the device @@ -132,11 +282,14 @@ The `vehicle_attributes` object **may** have the following key value pairs: ### Accessibility Attributes -The `accessibility_attributes` object **may** have the following key value pairs: +The `accessibility_attributes` enum represents the accessibility attributes available on a given vehicle, or the accessibility attributes utilized for a given trip. + +| `accessibility_attributes` | | Description | +|----------------------------|---|--------------------------------------| +| `audio_cue` | [Optional](../general-information.md#optional-fields) | is the device equipped with audio cues upon delivery | +| `visual_cue` | [Optional](../general-information.md#optional-fields) | is the device equipped with visual cues upon delivery | +| `remote_open` | [Optional](../general-information.md#optional-fields) | can the device door be remotely opened to retrieve cargo upon delivery | -- `audio_cue` (boolean, [Optional](../general-information.md#optional-fields)): is the device equipped with audio cues upon delivery -- `visual_cue` (boolean, [Optional](../general-information.md#optional-fields)): is the device equipped with visual cues upon delivery -- `remote_open` (boolean, [Optional](../general-information.md#optional-fields)): can the device door be remotely opened to retrieve cargo upon delivery [Top][toc] @@ -198,70 +351,94 @@ See vehicle [Event Types][vehicle-events] for descriptions. This is the list of `vehicle_state` and `event_type` pairings that constitute the valid transitions of the vehicle state machine. -| **From** `vehicle_state` | **To** `vehicle_state` | `trip_state` | `event_type` | Description | -| ------------------------ | ---------------------- | ------------ | ----------------------- | --------------------------------------------------------------------------------------------- | -| `available` | `elsewhere` | N/A | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while available for-hire | -| `available` | `non_contactable` | N/A | `comms_lost` | The vehicle has gone out of comms while available for-use | -| `available` | `non_operational` | N/A | `service_end` | The vehicle has gone out of service (is unavailable for-hire) | -| `available` | `reserved` | `reserved` | `reservation_start` | The vehicle was reserved by a customer | -| `elsewhere` | `available` | N/A | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while available for-hire | -| `elsewhere` | `non_contactable` | N/A | `comms_lost` | The vehicle has gone out of comms while outside of jurisdictional boundaries | -| `elsewhere` | `non_operational` | N/A | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while not operating commercially | -| `elsewhere` | `on_trip` | `on_trip` | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while on a trip | -| `elsewhere` | `reserved` | N/A | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while reserved by a customer | -| `missing` | `available` | N/A | `located` | The vehicle has been located while available for-hire | -| `missing` | `elsewhere` | N/A | `located` | The vehicle has been located while outside of jurisdictional boundaries | -| `missing` | `non_operational` | N/A | `located` | The vehicle has been located while not operating commercially | -| `missing` | `on_trip` | `on_trip` | `located` | The vehicle has been located while on a trip | -| `missing` | `removed` | N/A | `located` | The vehicle has been located while removed | -| `missing` | `reserved` | `reserved` | `located` | The vehicle has been located while reserved by a customer | -| `missing` | `stopped` | `stopped` | `located` | The vehicle has been located while stopped | -| `non_contactable` | `available` | N/A | `comms_restored` | The vehicle has come back into comms while available for-hire | -| `non_contactable` | `elsewhere` | N/A | `comms_restored` | The vehicle has come back into comms while outside of jurisdictional boundaries | -| `non_contactable` | `missing` | N/A | `not_located` | The vehicle has gone missing after a period of lost comms | -| `non_contactable` | `non_operational` | N/A | `comms_restored` | The vehicle has come back into comms while not operating commercially | -| `non_contactable` | `on_trip` | `on_trip` | `comms_restored` | The vehicle has come back into comms while on a trip | -| `non_contactable` | `removed` | N/A | `comms_restored` | The vehicle has come back into comms while removed | -| `non_contactable` | `reserved` | `reserved` | `comms_restored` | The vehicle has come back into comms while reserved by a customer | -| `non_contactable` | `stopped` | `stopped` | `comms_restored` | The vehicle has come back into comms while stopped | -| `non_operational` | `available` | N/A | `service_start` | The vehicle has gone into service (is available for-hire) | -| `non_operational` | `elsewhere` | N/A | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while not operating commercially | -| `non_operational` | `non_contactable` | N/A | `comms_lost` | The vehicle has gone out of comms while not operating commercially | -| `non_operational` | `non_operational` | N/A | `maintenance` | The vehicle has maintenance performed on site | -| `non_operational` | `non_operational` | N/A | `maintenance_end` | Maintenance is complete | -| `non_operational` | `removed` | N/A | `maintenance_pick_up` | The vehicle has entered the depot for maintenance | -| `non_operational` | `removed` | N/A | `decommissioned` | The vehicle has been removed from the Provider's fleet | -| `on_trip` | `elsewhere` | N/A | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while on a trip | -| `on_trip` | `non_contactable` | N/A | `comms_lost` | The vehicle has gone out of comms while on a trip to pick up the order | -| `on_trip` | `stopped` | N/A | `order_drop_off` | The vehicle is at the customer's place and is waiting for them | -| `on_trip` | `stopped` | `stopped` | `order_pick_up` | The vehicle has come to pick up the order at the restaurant | -| `on_trip` | `stopped` | `stopped` | `trip_pause` | The vehicle has paused while on a trip | -| `removed` | `non_contactable` | N/A | `comms_lost` | The vehicle has gone out of comms while removed | -| `removed` | `non_operational` | N/A | `maintenance_end` | The vehicle has left the depot | -| `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 | `customer_cancellation` | The customer has canceled the reservation | -| `reserved` | `available` | N/A | `driver_cancellation` | The driver 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 has gone of comms while being reserved by a customer | -| `reserved` | `stopped` | `stopped` | `reservation_stop` | The vehicle has stopped to pickup reservation | -| `stopped` | `available` | N/A | `customer_cancellation` | The customer has canceled the trip while the vehicle is waiting | -| `stopped` | `available` | N/A | `driver_cancellation` | The driver has canceled the trip while waiting | -| `stopped` | `available` | N/A | `provider_cancellation` | The provider has canceled the trip while the vehicle is waiting | -| `stopped` | `available` | N/A | `trip_end` | The trip has been successfully completed | -| `stopped` | `non_contactable` | N/A | `comms_lost` | The vehicle has gone out of comms while stopped | -| `stopped` | `on_trip` | `on_trip` | `trip_resume` | Resume a trip that was previously paused (e.g. picking up an order) | -| `stopped` | `on_trip` | `on_trip` | `trip_start` | Start a trip | +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------| +| `available` | `elsewhere` | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while available for-hire | +| `available` | `non_contactable` | `comms_lost` | The vehicle has gone out of comms while available for-use | +| `available` | `non_operational` | `service_end` | The vehicle has gone out of service (is unavailable for-hire) | +| `available` | `reserved` | `reservation_start` | The vehicle was reserved by a customer | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------| +| `elsewhere` | `available` | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while available for-hire | +| `elsewhere` | `non_contactable` | `comms_lost` | The vehicle has gone out of comms while outside of jurisdictional boundaries | +| `elsewhere` | `non_operational` | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while not operating commercially | +| `elsewhere` | `on_trip` | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while on a trip | +| `elsewhere` | `reserved` | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while reserved by a customer | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------| +| `missing` | `available` | `located` | The vehicle has been located while available for-hire | +| `missing` | `elsewhere` | `located` | The vehicle has been located while outside of jurisdictional boundaries | +| `missing` | `non_operational` | `located` | The vehicle has been located while not operating commercially | +| `missing` | `on_trip` | `located` | The vehicle has been located while on a trip | +| `missing` | `removed` | `located` | The vehicle has been located while removed | +| `missing` | `reserved` | `located` | The vehicle has been located while reserved by a customer | +| `missing` | `stopped` | `located` | The vehicle has been located while stopped | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------| +| `non_contactable` | `available` | `comms_restored` | The vehicle has come back into comms while available for-hire | +| `non_contactable` | `elsewhere` | `comms_restored` | The vehicle has come back into comms while outside of jurisdictional boundaries | +| `non_contactable` | `missing` | `not_located` | The vehicle has gone missing after a period of lost comms | +| `non_contactable` | `non_operational` | `comms_restored` | The vehicle has come back into comms while not operating commercially | +| `non_contactable` | `on_trip` | `comms_restored` | The vehicle has come back into comms while on a trip | +| `non_contactable` | `removed` | `comms_restored` | The vehicle has come back into comms while removed | +| `non_contactable` | `reserved` | `comms_restored` | The vehicle has come back into comms while reserved by a customer | +| `non_contactable` | `stopped` | `comms_restored` | The vehicle has come back into comms while stopped | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------| +| `non_operational` | `available` | `service_start` | The vehicle has gone into service (is available for-hire) | +| `non_operational` | `elsewhere` | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while not operating commercially | +| `non_operational` | `non_contactable` | `comms_lost` | The vehicle has gone out of comms while not operating commercially | +| `non_operational` | `non_operational` | `maintenance` | The vehicle has maintenance performed on site | +| `non_operational` | `non_operational` | `maintenance_end` | Maintenance is complete | +| `non_operational` | `removed` | `maintenance_pick_up` | The vehicle has entered the depot for maintenance | +| `non_operational` | `removed` | `decommissioned` | The vehicle has been removed from the Provider's fleet | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------| +| `on_trip` | `elsewhere` | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while on a trip | +| `on_trip` | `non_contactable` | `comms_lost` | The vehicle has gone out of comms while on a trip to pick up the order | +| `on_trip` | `stopped` | `order_drop_off` | The vehicle is at the customer's place | +| `on_trip` | `stopped` | `order_pick_up` | The vehicle has come to pick up the order from the origin point | +| `on_trip` | `stopped` | `trip_pause` | The vehicle has paused while on a trip | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------| +| `removed` | `non_contactable` | `comms_lost` | The vehicle has gone out of comms while removed | +| `removed` | `non_operational` | `maintenance_end` | The vehicle has left the depot | +| `removed` | `non_operational` | `recommissioned` | The vehicle has been re-added to the Provider's fleet after being previously `decommissioned` | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------| +| `reserved` | `available` | `customer_cancellation` | The customer has canceled the reservation | +| `reserved` | `available` | `driver_cancellation` | The driver has canceled the reservation | +| `reserved` | `available` | `provider_cancellation` | The provider has canceled the reservation | +| `reserved` | `elsewhere` | `trip_leave_jurisdiction` | The vehicle has left the jurisdiction while in a reservation | +| `reserved` | `non_contactable` | `comms_lost` | The vehicle has gone out of comms while being reserved by a customer | +| `reserved` | `stopped` | `reservation_stop` | The vehicle has stopped to pickup reservation | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------| +| `stopped` | `available` | `customer_cancellation` | The customer has canceled the trip while the vehicle is waiting | +| `stopped` | `available` | `driver_cancellation` | The driver has canceled the trip while waiting | +| `stopped` | `available` | `provider_cancellation` | The provider has canceled the trip while the vehicle is waiting | +| `stopped` | `available` | `trip_end` | The trip has been successfully completed | +| `stopped` | `non_contactable` | `comms_lost` | The vehicle has gone out of comms while stopped | +| `stopped` | `on_trip` | `trip_resume` | Resume a trip that was previously paused (e.g. picking up an order) | +| `stopped` | `on_trip` | `trip_start` | Start a trip | [Top][toc] ### State Machine Diagram -This *State Machine Diagram* shows how `vehicle_state` and `event_type` relate to each other and how vehicles can transition between states. See [Google Slides](https://docs.google.com/presentation/d/1fHdq1efbN5GSFDLF4en-oA_BYPXQKbbIbHff6iROJKA/edit#slide=id.g207ec9d0152_0_0) for the source file. +This *State Machine Diagram* shows how `vehicle_state` and `event_type` relate to each other and how vehicles can transition between states. See [Google Slides](https://docs.google.com/presentation/d/1FCrBCtNQyoIcchaGx6zw4BpLCquQaWmBHsEU6fUdUoo/edit?slide=id.g207ec9d0152_0_0#slide=id.g207ec9d0152_0_0) for the source file. -![Delivery Robots State Machine Diagram](delivery-robots-state-machine-diagram.svg) +![Delivery State Machine Diagram](delivery-robots-state-machine-diagram.svg) -#### Delivery Robots State Notes +#### Delivery State Notes When there is only one trip ongoing, `trip_state == vehicle_state` diff --git a/modes/event_types.md b/modes/event_types.md index 54eb29df7..b71e73e6b 100644 --- a/modes/event_types.md +++ b/modes/event_types.md @@ -18,7 +18,7 @@ As with all MDS definitions, they should be described in a way that maximizes th | `compliance_pick_up` | Pick up for compliance (rule violation) | | `customer_cancellation` | Customer cancelled a trip | | `decommissioned` | Decommissioned | -| `driver_cancellation` | Driver cancelled a trip | +| `driver_cancellation` | Driver cancelled a trip (if known, and more specific than `trip_cancel`) | | `fueling_start` | Fueling starts | | `fueling_end` | Fueling ends | | `located` | Location found (opposite of Missing) | @@ -28,30 +28,30 @@ As with all MDS definitions, they should be described in a way that maximizes th | `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 | +| `order_drop_off` | Delivery of the order at the customer location | +| `order_pick_up` | Pick up of the order at business | +| `passenger_cancellation` | Passenger cancelled a trip (if known, and more specific than `trip_cancel`) | +| `provider_cancellation` | Provider cancelled a trip (if known, and more specific than `trip_cancel`) | | `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_cancel` | Reservation cancelled before trip (different than `trip_cancel` since the transaction hadn't started yet, and the reservation hold is let go) | | `reservation_start` | Reservation started | -| `reservation_stop` | Reservation stopped temporarily | +| `reservation_stop` | Reservation stopped temporarily. If at the end of a trip, the time between `reserved` and `stopped` States is the customer wait time. | | `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_cancel` | Cancel trip - trip is ended by anyone for some reason, either before or after motion starts (note: use more specific cancellation event types when possible) | +| `trip_end` | End trip - end of the trip and transaction | | `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 | +| `trip_pause` | Pause trip temporarily but do not end trip - trip intends to continue, but is paused in motion or transaction | +| `trip_resume` | Resume trip - trip resumes after a `trip_pause` (a pause is required before a resume can happen) | +| `trip_start` | Start trip - first start of a trip and transaction (required for any trip) | +| `trip_stop` | Stop trip - last movement in the trip, intending to end it (customer may be idling or interacting with devices to end trip) | | `unspecified` | Unspecified | ### Limitations on the Use of Certain Values @@ -62,6 +62,16 @@ MDS is intended to communicate the provider's best available information to regu The `unspecified` event type state transition means that the vehicle has moved from one state to another for an unspecified or unknown reason. It is used when there are multiple possible event types between states, but the reason for the transition is not clear. It is expected that `unspecified` will not be used frequently, and only for short periods of time. Cities may put in place specific limitations via an SLA. When more accurate information becomes available to the provider, it should be updated in the MDS data by sending a new event type state transition with the current timestamp. +Generally, regulator Service-Level Agreements will limit the amount of time a vehicle's last event type may be `unspecified`. + +#### Multi State Transitions + +See the mode specific state-transition tables which descibe how the `vehicle_state` changes in response to each `event_type`. Most events will have a single `event_type`. However, if a single event has more than one ordered `event_type` entry, the intermediate `vehicle_state` value(s) are discarded. For example, if an event contains `[trip_end, battery_low]` then the vehicle transitions from `on_trip` through `available` to `non_operational` per the state machine, but the vehicle is never "in" the `available` state. + +#### Out of Order Events + +Note that to handle out-of-order events, the validity of the prior-state shall not be enforced at the time of ingest via Provider or Agency. Events received out-of-order may result in transient incorrect vehicle states. + --- [Modes Overview][modes] diff --git a/modes/micromobility-state-machine-diagram.svg b/modes/micromobility-state-machine-diagram.svg index e870daab0..3d7efa5c5 100644 --- a/modes/micromobility-state-machine-diagram.svg +++ b/modes/micromobility-state-machine-diagram.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/modes/micromobility.md b/modes/micromobility.md index d1adb14e5..78d7e3f7f 100644 --- a/modes/micromobility.md +++ b/modes/micromobility.md @@ -1,11 +1,13 @@ # Mobility Data Specification: **Micromobility** -MDS Modes - Micromobility +MDS Modes - Micromobility -"**Micromobility**" refers to single-occupancy modes of docked or dockless transportation such as e-scooters, e-bikes, and human-powered bikes. +"**Micromobility**" refers to customer operated dockless or docked small devices moving customers and goods, such as scooters, bikeshare, cargo bikes, adaptive scooters, docked bikes, mopeds, trikes, and quadracycles. See the [modes overview](/modes) for how the mode specific information below applies across MDS. +  + ## Table of Contents - [Mode Attributes](#mode-attributes) @@ -23,7 +25,7 @@ See the [modes overview](/modes) for how the mode specific information below app - [State Machine](#state-machine) - [Vehicle States](#vehicle-states) - [Event Types](#event-types) - - [Vehicle State Events](#vehicle-states-events) + - [Vehicle States Events](#vehicle-states-events) - [State Machine Diagram](#state-machine-diagram) ## Mode Attributes @@ -60,7 +62,7 @@ Required in events if `event_types` contains `trip_start`, `trip_end`, `trip_can The `trip_type` field **may** have one of the following values: -- `rider`: a single rider is taking a trip +- `rider` (_default_): a single rider is taking a trip - `rebalance`: vehicle ridden by operator to rebalance - `maintenance`: vehicles ridden by operator to perform maintenance or check operation @@ -74,7 +76,8 @@ The `trip_attributes` object is not used in this mode. ### Fare Attributes -The `fare_attributes` object is not used in this mode. +The `fare_attributes` object may have the following key value pairs: +- `rate_code_id` (enumerated, Optional) - one of `standard`, `access`, `member` [Top][toc] @@ -159,71 +162,124 @@ See vehicle [Event Types][vehicle-events] for descriptions. [Top][toc] -### Vehicle State Events +### Vehicle States Events This is the list of `vehicle_state` and `event_type` pairings that constitute the valid transitions of the vehicle state machine. -The state-transition table below describes how the `vehicle_state` changes in response to each `event_type`. Most events will have a single `event_type`. However, if a single event has more than one ordered `event_type` entry, the intermediate `vehicle_state` value(s) are discarded. For example, if an event contains [`trip_end`, `battery_low`] then the vehicle transitions from `on_trip` through `available` to `non_operational` per the state machine, but the vehicle is never "in" the `available` state. - -Note that to handle out-of-order events, the validity of the prior-state shall not be enforced at the time of ingest via Provider or Agency. Events received out-of-order may result in transient incorrect vehicle states. - -Vehicles can enter the `non_contactable` state to and from any other state with the following event types: any state can go to `non_contactable` with event type `comms_lost` or `unspecified`, and `non_contactable` can go to any state with event type `comms_restored` of `unspecified`. - -Vehicles can exit the `missing` state to any other state with the following event types: `missing` can go to any state with event type `located` or `unspecified`. -| **From** `vehicle_state` | **To** `vehicle_state` | `event_type` | Description | -|-------------------------------------------------------------------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `available` | `non_operational` | `battery_low` | The vehicle's battery is below some rentability threshold | -| `available` | `non_operational` | `maintenance` | The vehicle requires some non-charge-related maintenance | -| `available` | `non_operational` | `off_hours` | The vehicle has exited operating hours (per the regulator or per the Provider) | -| `available` | `reserved` | `reservation_start` | The vehicle was reserved for use by a customer | -| `available` | `non_operational` | `system_suspend` | The vehicle is not available because of e.g. weather or temporary regulations | -| `available`, `elsewhere`, `non_operational`, `on_trip`, `removed`, `reserved` | `non_contactable` | `comms_lost` | The vehicle is unable to transmit its GPS location or other status information | -| `available`, `elsewhere`, `non_operational`, `on_trip`, `removed`, `reserved` | `non_contactable` | `unspecified` | The provider cannot definitively (yet) specify the reason for the non_contactable state | -| `available`, `non_contactable`, `missing` | `non_operational` | `unspecified` | The vehicle became unavailable, but the Provider cannot definitively (yet) specify the reason. | -| `available`, `non_operational`, `elsewhere` | `removed` | `compliance_pick_up` | The provider picked up the vehicle because it was placed in a non-compliant location | -| `available`, `non_operational`, `elsewhere` | `removed` | `maintenance_pick_up` | The provider picked up the vehicle to service it | -| `available`, `non_operational`, `elsewhere` | `removed` | `rebalance_pick_up` | The provider picked up the vehicle for rebalancing purposes | -| `available`, `non_operational`, `elsewhere`, `non_contactable`, `missing` | `removed` | `agency_pick_up` | An agency picked up the vehicle for some reason, e.g. illegal placement | -| `available`, `non_operational`, `elsewhere`, `non_contactable`, `missing` | `removed` | `decommissioned` | The provider has removed the vehicle from its fleet | -| `available`, `reserved` | `on_trip` | `trip_start` | A customer initiated a trip with this vehicle | -| `elsewhere` | `on_trip` | `trip_enter_jurisdiction` | A vehicle on a trip entered the jurisdiction | -| `missing` | `available` | `located` | The vehicle has been located by the provider | -| `missing` | `elsewhere` | `located` | The vehicle has been located by the provider | -| `missing` | `non_operational` | `located` | The vehicle has been located by the provider | -| `missing` | `on_trip` | `located` | The vehicle has been located by the provider | -| `missing` | `removed` | `located` | The vehicle has been located by the provider | -| `missing` | `reserved` | `located` | The vehicle has been located by the provider | -| `non_contactable` | `available` | `comms_restored` | The vehicle transmitted status information after a period of being out of communication. | -| `non_contactable` | `elsewhere` | `comms_restored` | The vehicle transmitted status information after a period of being out of communication. | -| `non_contactable` | `non_operational` | `comms_restored` | The vehicle transmitted status information after a period of being out of communication | -| `non_contactable` | `on_trip` | `comms_restored` | The vehicle transmitted status information after a period of being out of communication. | -| `non_contactable` | `removed` | `comms_restored` | The vehicle transmitted status information after a period of being in an non_contactable state | -| `non_contactable` | `reserved` | `comms_restored` | The vehicle transmitted status information after a period of being out of communication. | -| `non_contactable` | `missing` | `not_located` | The vehicle is not at its last reported GPS location, or that location is wildly in error | -| `non_contactable` | `missing` | `unspecified` | The provider cannot definitively (yet) specify the reason for the missing state | -| `non_contactable`, `missing` | `elsewhere` | `unspecified` | The provider cannot definitively state how a vehicle went `elsewhere`. | -| `non_contactable`, `missing` | `on_trip` | `unspecified` | The provider cannot definitively state how a vehicle started a trip. | -| `non_contactable`, `missing` | `reserved` | `unspecified` | The provider cannot definitively state how a vehicle became reserved. | -| `non_contactable`, `missing`, `non_operational`, `available`, `elsewhere` | `removed` | `unspecified` | The vehicle was removed, but the provider cannot definitively (yet) specify the reason | -| `non_operational` | `available` | `battery_charged` | The vehicle became available because its battery is now charged. | -| `non_operational` | `available` | `maintenance` | The vehicle was previously in need of maintenance | -| `non_operational` | `available` | `on_hours` | The vehicle has entered operating hours (per the regulator or per the provider) | -| `non_operational` | `available` | `system_resume` | The vehicle is available because e.g. weather suspension or temporary regulations ended | -| `non_operational`, `non_contactable`, `missing` | `available` | `unspecified` | The vehicle became available, but the provider cannot definitively (yet) specify the reason. Generally, regulator Service-Level Agreements will limit the amount of time a vehicle's last event type may be `unspecified`. | -| `on_trip` | `on_trip ` | `changed_geographies` | **[Beta feature](/general-information.md#beta-features):** *Yes (as of 1.1.0)*. The vehicle has entered or left one or more Geographies managed by a Policy. See [Geography Driven Events](#geography-driven-events). | -| `on_trip` | `available` | `trip_cancel` | A trip was initiated, then canceled prior to moving any distance | -| `on_trip` | `available` | `trip_end` | A trip has ended, and the vehicle is again available for rent | -| `on_trip` | `elsewhere` | `trip_leave_jurisdiction` | A vehicle on a trip left the jurisdiction | -| `removed`, `non_contactable`, `missing` | `available` | `agency_drop_off` | The vehicle was placed in the PROW by a city or county | -| `removed`, `non_contactable`, `missing` | `available` | `provider_drop_off` | The vehicle was placed in the PROW by the provider | -| `reserved` | `available` | `reservation_cancel` | A reservation was canceled and the vehicle returned to service | - +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|-----------------------|-----------------------------------------------------------------------------------------------| +| `available` | `non_contactable` | `comms_lost` | The vehicle is unable to transmit its GPS location or other status information | +| `available` | `non_contactable` | `unspecified` | The provider cannot definitively (yet) specify the reason for the non_contactable state | +| `available` | `non_operational` | `battery_low` | The vehicle's battery is below some rentability threshold | +| `available` | `non_operational` | `maintenance` | The vehicle requires some non-charge-related maintenance | +| `available` | `non_operational` | `off_hours` | The vehicle has exited operating hours (per the regulator or per the Provider) | +| `available` | `non_operational` | `system_suspend` | The vehicle is not available because of e.g. weather or temporary regulations | +| `available` | `non_operational` | `unspecified` | The vehicle became unavailable, but the Provider cannot definitively (yet) specify the reason | +| `available` | `on_trip` | `trip_start` | A customer initiated a trip with this vehicle | +| `available` | `removed` | `agency_pick_up` | An agency picked up the vehicle for some reason, e.g. illegal placement | +| `available` | `removed` | `compliance_pick_up` | The provider picked up the vehicle because it was placed in a non-compliant location | +| `available` | `removed` | `decommissioned` | The provider has removed the vehicle from its fleet | +| `available` | `removed` | `maintenance_pick_up` | The provider picked up the vehicle to service it | +| `available` | `removed` | `rebalance_pick_up` | The provider picked up the vehicle for rebalancing purposes | +| `available` | `removed` | `unspecified` | The vehicle was removed, but the provider cannot definitively (yet) specify the reason | +| `available` | `reserved` | `reservation_start` | The vehicle was reserved for use by a customer | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------| +| `elsewhere` | `non_contactable` | `comms_lost` | The vehicle is unable to transmit its GPS location or other status information | +| `elsewhere` | `non_contactable` | `unspecified` | The provider cannot definitively (yet) specify the reason for the non_contactable state | +| `elsewhere` | `on_trip` | `trip_enter_jurisdiction` | A vehicle on a trip entered the jurisdiction | +| `elsewhere` | `removed` | `agency_pick_up` | An agency picked up the vehicle for some reason, e.g. illegal placement | +| `elsewhere` | `removed` | `compliance_pick_up` | The provider picked up the vehicle because it was placed in a non-compliant location | +| `elsewhere` | `removed` | `decommissioned` | The provider has removed the vehicle from its fleet | +| `elsewhere` | `removed` | `maintenance_pick_up` | The provider picked up the vehicle to service it | +| `elsewhere` | `removed` | `rebalance_pick_up` | The provider picked up the vehicle for rebalancing purposes | +| `elsewhere` | `removed` | `unspecified` | The vehicle was removed, but the provider cannot definitively (yet) specify the reason | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------|-----------------------------------------------------------------------------------------------| +| `missing` | `available` | `agency_drop_off` | The vehicle was placed in the PROW by a city or county | +| `missing` | `available` | `located` | The vehicle has been located by the provider | +| `missing` | `available` | `provider_drop_off` | The vehicle was placed in the PROW by the provider | +| `missing` | `available` | `unspecified` | The vehicle became available, but the provider cannot definitively (yet) specify the reason. Generally, regulator Service-Level Agreements will limit the amount of time a vehicle's last event type may be `unspecified`. | +| `missing` | `elsewhere` | `located` | The vehicle has been located by the provider | +| `missing` | `elsewhere` | `unspecified` | The provider cannot definitively state how a vehicle went elsewhere | +| `missing` | `non_operational` | `located` | The vehicle has been located by the provider | +| `missing` | `non_operational` | `unspecified` | The vehicle became unavailable, but the Provider cannot definitively (yet) specify the reason | +| `missing` | `on_trip` | `located` | The vehicle has been located by the provider | +| `missing` | `on_trip` | `unspecified` | The provider cannot definitively state how a vehicle started a trip | +| `missing` | `removed` | `agency_pick_up` | An agency picked up the vehicle for some reason, e.g. illegal placement | +| `missing` | `removed` | `decommissioned` | The provider has removed the vehicle from its fleet | +| `missing` | `removed` | `located` | The vehicle has been located by the provider | +| `missing` | `removed` | `unspecified` | The vehicle was removed, but the provider cannot definitively (yet) specify the reason | +| `missing` | `reserved` | `located` | The vehicle has been located by the provider | +| `missing` | `reserved` | `unspecified` | The provider cannot definitively state how a vehicle became reserved | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------|-----------------------------------------------------------------------------------------------| +| `non_contactable` | `available` | `agency_drop_off` | The vehicle was placed in the PROW by a city or county | +| `non_contactable` | `available` | `comms_restored` | The vehicle transmitted status information after a period of being out of communication | +| `non_contactable` | `available` | `provider_drop_off` | The vehicle was placed in the PROW by the provider | +| `non_contactable` | `available` | `unspecified` | The vehicle became available, but the provider cannot definitively (yet) specify the reason. Generally, regulator Service-Level Agreements will limit the amount of time a vehicle's last event type may be `unspecified`. | +| `non_contactable` | `elsewhere` | `comms_restored` | The vehicle transmitted status information after a period of being out of communication | +| `non_contactable` | `elsewhere` | `unspecified` | The provider cannot definitively state how a vehicle went `elsewhere` | +| `non_contactable` | `missing` | `not_located` | The vehicle is not at its last reported GPS location, or that location is wildly in error | +| `non_contactable` | `missing` | `unspecified` | The provider cannot definitively (yet) specify the reason for the missing state | +| `non_contactable` | `non_operational` | `comms_restored` | The vehicle transmitted status information after a period of being out of communication | +| `non_contactable` | `non_operational` | `unspecified` | The vehicle became unavailable, but the Provider cannot definitively (yet) specify the reason | +| `non_contactable` | `on_trip` | `comms_restored` | The vehicle transmitted status information after a period of being out of communication | +| `non_contactable` | `on_trip` | `unspecified` | The provider cannot definitively state how a vehicle started a trip | +| `non_contactable` | `removed` | `agency_pick_up` | An agency picked up the vehicle for some reason, e.g. illegal placement | +| `non_contactable` | `removed` | `comms_restored` | The vehicle transmitted status information after a period of being out of communication | +| `non_contactable` | `removed` | `decommissioned` | The provider has removed the vehicle from its fleet | +| `non_contactable` | `removed` | `unspecified` | The vehicle was removed, but the provider cannot definitively (yet) specify the reason | +| `non_contactable` | `reserved` | `comms_restored` | The vehicle transmitted status information after a period of being out of communication | +| `non_contactable` | `reserved` | `unspecified` | The provider cannot definitively state how a vehicle became reserved | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|-----------------------|----------------------------------------------------------------------------------------------| +| `non_operational` | `available` | `battery_charged` | The vehicle became available because its battery is now charged | +| `non_operational` | `available` | `maintenance` | The vehicle was previously in need of maintenance | +| `non_operational` | `available` | `on_hours` | The vehicle has entered operating hours (per the regulator or per the provider) | +| `non_operational` | `available` | `system_resume` | The vehicle is available because e.g. weather suspension or temporary regulations ended | +| `non_operational` | `available` | `unspecified` | The vehicle became available, but the provider cannot definitively (yet) specify the reason. Generally, regulator Service-Level Agreements will limit the amount of time a vehicle's last event type may be `unspecified`. | +| `non_operational` | `non_contactable` | `comms_lost` | The vehicle is unable to transmit its GPS location or other status information | +| `non_operational` | `non_contactable` | `unspecified` | The provider cannot definitively (yet) specify the reason for the non_contactable state | +| `non_operational` | `removed` | `agency_pick_up` | An agency picked up the vehicle for some reason, e.g. illegal placement | +| `non_operational` | `removed` | `compliance_pick_up` | The provider picked up the vehicle because it was placed in a non-compliant location | +| `non_operational` | `removed` | `decommissioned` | The provider has removed the vehicle from its fleet | +| `non_operational` | `removed` | `maintenance_pick_up` | The provider picked up the vehicle to service it | +| `non_operational` | `removed` | `rebalance_pick_up` | The provider picked up the vehicle for rebalancing purposes | +| `non_operational` | `removed` | `unspecified` | The vehicle was removed, but the provider cannot definitively (yet) specify the reason | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------| +| `on_trip` | `available` | `trip_cancel` | A trip was initiated, then canceled prior to moving any distance | +| `on_trip` | `available` | `trip_end` | A trip has ended, and the vehicle is again available for rent | +| `on_trip` | `elsewhere` | `trip_leave_jurisdiction` | A vehicle on a trip left the jurisdiction | +| `on_trip` | `non_contactable` | `comms_lost` | The vehicle is unable to transmit its GPS location or other status information | +| `on_trip` | `non_contactable` | `unspecified` | The provider cannot definitively (yet) specify the reason for the non_contactable state | +| `on_trip` | `on_trip ` | `changed_geographies` | The vehicle has entered or left one or more Geographies managed by a Policy. See [Geography Driven Events](#geography-driven-events). | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------|-----------------------------------------------------------------------------------------| +| `removed` | `available` | `agency_drop_off` | The vehicle was placed in the PROW by a city or county | +| `removed` | `available` | `provider_drop_off` | The vehicle was placed in the PROW by the provider | +| `removed` | `non_contactable` | `comms_lost` | The vehicle is unable to transmit its GPS location or other status information | +| `removed` | `non_contactable` | `unspecified` | The provider cannot definitively (yet) specify the reason for the non_contactable state | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|----------------------|-----------------------------------------------------------------------------------------| +| `reserved` | `available` | `reservation_cancel` | A reservation was canceled and the vehicle returned to service | +| `reserved` | `non_contactable` | `comms_lost` | The vehicle is unable to transmit its GPS location or other status information | +| `reserved` | `non_contactable` | `unspecified` | The provider cannot definitively (yet) specify the reason for the non_contactable state | +| `reserved` | `on_trip` | `trip_start` | A customer initiated a trip with this vehicle | [Top][toc] ### State Machine Diagram -This *State Machine Diagram* shows how `vehicle_state` and `event_type` relate to each other and how vehicles can transition between states. See [Google Slides](https://docs.google.com/presentation/d/1fHdq1efbN5GSFDLF4en-oA_BYPXQKbbIbHff6iROJKA/edit#slide=id.g206f7c6e12e_0_0) for the source file. +This *State Machine Diagram* shows how `vehicle_state` and `event_type` relate to each other and how vehicles can transition between states. See [Google Slides](https://docs.google.com/presentation/d/1FCrBCtNQyoIcchaGx6zw4BpLCquQaWmBHsEU6fUdUoo/edit?slide=id.g206f7c6e12e_0_0#slide=id.g206f7c6e12e_0_0) for the source file. ![micromobility-state-machine-diagram](/modes/micromobility-state-machine-diagram.svg) diff --git a/modes/passenger-services-state-machine-diagram.svg b/modes/passenger-services-state-machine-diagram.svg index b5c27f1e7..082826f86 100644 --- a/modes/passenger-services-state-machine-diagram.svg +++ b/modes/passenger-services-state-machine-diagram.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/modes/passenger-services.md b/modes/passenger-services.md index 180c552a5..010448a8f 100644 --- a/modes/passenger-services.md +++ b/modes/passenger-services.md @@ -1,14 +1,16 @@ -# Mobility Data Specification: **Passenger Services** +# Mobility Data Specification: **Passenger** -MDS Modes - Passenger Services +MDS Modes - Passenger -**Passenger Services** refers to taxis, transportation network companies (TNCs), commercial transport apps (CTAs), and private hire vehicles (PHVs). Passenger Services typically have a driver, one or more passengers, and multiple passengers may be on different trips. The state machine tracks the trip states of the passengers separately from the vehicle state. +**Passenger** refers to employees and contractors, autonomous, and remotely operated transporting individuals or goods with a vehicle driven by another entity, including taxis, for-hire AVs, robotaxis, busses, transportation network companies (TNCs), commercial transport apps (CTAs), and private hire vehicles (PHVs), shuttles, paratransit, on demand vehicles, limousines, and microtransit. See the [modes overview](/modes) for how the mode specific information below applies across MDS. -## Taxi vs. TNC implementation differences +_Note: Formerly called "Passenger Services". Any references in the specification code or links to "Passenger Services" will be updated to the shorter "Passenger" scope in the next MDS 3.0 release._ -Taxis typically require explicit tracking of maintenance while TNCs typically do not. Public agency regulations, legal authority, differ based on local, state, and federal laws and jurisdictions between taxis, TNCs, CTAs, PHV, etc. +## Implementation differences + +Taxis and similar traditionally regulated services typically require explicit tracking of maintenance and labor, while TNCs or other contract driver services may not. Public agency regulations, legal authority, differ based on local, state, and federal laws and jurisdictions between taxis, TNCs, CTAs, PHV, AVs, etc. ## Table of Contents @@ -27,14 +29,14 @@ Taxis typically require explicit tracking of maintenance while TNCs typically do - [State Machine](#state-machine) - [Vehicle States](#vehicle-states) - [Event Types](#event-types) - - [Vehicle State Events](#vehicle-states-events) + - [Vehicle States Events](#vehicle-states-events) - [State Machine Diagram](#state-machine-diagram) ## Mode Attributes ### Mode ID -The short name identifier for Passenger Services used across MDS is `passenger-services`. +The short name identifier for Passenger mode used across MDS is `passenger-services`. In a future release this will be updated to `passenger`. [Top][toc] @@ -46,10 +48,90 @@ _See more available trip and fare attributes for any mode used in the [trips obj The `journey_id` field shall have a consistent value in overlapping trips, e.g. "pooled" or "shared" rides with different start and/or end locations. Journeys may be point-to-point, multi-segment, or multi-segment overlapping. -- **Example 1**: one private trip with reservation, then return to depot -- **Example 2**: three shared trips, some overlapping +```mermaid +--- +config: + theme: 'base' + themeVariables: + 'activeTaskBkgColor': '#155654' + 'activeTaskBorderColor': '#2AF1BE' + 'critBorderColor': '#2AF1BE' + 'doneTaskBkgColor': '#299c90' + 'doneTaskBorderColor': '#373737' + 'taskBkgColor': '#2AF1BE' + 'taskBorderColor': '#373737' + 'taskTextColor': '#373737' + 'taskTextDarkColor': 'white' + 'taskTextLightColor': '#373737' + 'vertLineColor': '#155654' + 'sectionBkgColor': '#ddd' + 'altSectionBkgColor': '#aaa' + 'sectionBkgColor2': '#777' +--- +gantt + title Example 1: one private trip with reservation, then return to depot + dateFormat HH:mm + axisFormat %H:%M + + section Journey + Journey Start : vert, v1, 17:00, 2m + + Journey : active, a, 17:00, 55m + + Trip - reservation : b, 17:00, 10m + Trip - private : b, 17:10, 30m + Trip - empty : b, 17:40, 15m + + Journey End : vert, v1, 17:55, 5m +``` + + +```mermaid +--- +config: + theme: 'base' + themeVariables: + 'activeTaskBkgColor': '#155654' + 'activeTaskBorderColor': '#2AF1BE' + 'critBorderColor': '#2AF1BE' + 'doneTaskBkgColor': '#299c90' + 'doneTaskBorderColor': '#373737' + 'taskBkgColor': '#2AF1BE' + 'taskBorderColor': '#373737' + 'taskTextColor': '#373737' + 'taskTextDarkColor': 'white' + 'taskTextLightColor': '#373737' + 'vertLineColor': '#155654' + 'sectionBkgColor': '#ddd' + 'altSectionBkgColor': '#aaa' + 'sectionBkgColor2': '#777' +--- +gantt + title Example 2: three shared trips, some overlapping, from airport to hotels + dateFormat HH:mm + axisFormat %H:%M + + section Journey + + Journey - airport to hotels : active, a, 17:00, 80m + Trip 1 - reservation : b, 17:00, 10m + Reserve Trip 1 : vert, v1, 17:00, 2m + Trip 1 - shared : b, 17:10, 30m + Pickup Trip 1 : vert, v1, 17:10, 1m + Trip 2 - reservation : b, 17:20, 10m + Reserve Trip 2 : vert, v1, 17:20, 2m + Trip 2 - shared : b, 17:30, 30m + Pickup Trip 2: vert, v1, 17:30, 2m + Dropoff Trip 1 : vert, v1, 17:40, 2m + Trip 3 - reservation : b, 17:50, 20m + Reserve Trip 3 : vert, v1, 17:50, 2m + Dropoff Trip 2 : vert, v1, 18:00, 2m + Trip 3 - private : b, 18:10, 10m + Pickup Trip 3 : vert, v1, 18:10, 2m + Dropoff Trip 3 : vert, v1, 18:20, 5m + +``` -![Journey Diagram](https://i.imgur.com/ciNnDKC.png) [Top][toc] @@ -57,7 +139,7 @@ The `journey_id` field shall have a consistent value in overlapping trips, e.g. 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. +- `shift_id` (UUID, [Optional](../general-information.md#optional-fields)): unique identifier for an entire driver's work shift, tied across multiple journeys and therefore trips. [Top][toc] @@ -73,9 +155,10 @@ Additionally, `trip_id` is required if `event_types` contains a `trip_enter_juri The `trip_type` field **must** have one of the following enumerated values: -- `private`: a private trip made by one paying customer with one or more guests +- `private` (_default_): a private trip made by one paying customer with one or more guests - `shared`: a shared or pooled trip with more than one paying customer - `reservation`: en route to pickup a customer who has made a reservation, with no passengers in the vehicle +- `mapping`: mapping the environment - `empty`: vehicle movement with no passengers (outside of other `trip_type` values) that may need to be reported, e.g. for deadheading [Top][toc] @@ -85,7 +168,7 @@ The `trip_type` field **must** have one of the following enumerated values: 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 +- `app_name` (text, [Optional](../general-information.md#optional-fields)): 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][ts], required): when the passenger requested the trip - `requested_trip_start_location` ([GPS](gps), [Conditionally Required](../general-information.md#conditionally-required-fields)): Location where the customer requested the trip to start (required if this is within jurisdictional boundaries) @@ -95,6 +178,8 @@ The `trip_attributes` object **may** have the following key value pairs: - `trip_fare_time` (milliseconds, [Optional](../general-information.md#optional-fields)): part of the passenger trip where the vehicle was moving more quickly (e.g. >12mph), which is a different fare rate in some jurisdictions - `pickup_address` (text, [Optional](../general-information.md#optional-fields)): street address where the trip originated from - `dropoff_address` (text, [Optional](../general-information.md#optional-fields)): street address where the trip ended +- `passenger_pickup` (boolean, [Optional](../general-information.md#optional-fields)): One or more passengers were picked up at the start of this trip. If you need to record other pickups, do so in a different Trip. +- `passenger_drop_off` (boolean, [Optional](../general-information.md#optional-fields)): One or more passengers were sropped off at the end of this trip. If you need to record other drop offs, do so in a different Trip. - `permit_license_number` (string, [Optional](../general-information.md#optional-fields)) - The permit license number of the organization that dispatched the vehicle - `driver_id` (string, [Optional](../general-information.md#optional-fields)): Universal identifier of a specific driver, static across operators, like a driver's license number. Could also be used as a lookup in an agency's internal driver system. - `wheelchair_transported` (boolean, [Optional](../general-information.md#optional-fields)) - was a wheelchair transported as part of this trip? @@ -156,7 +241,7 @@ This `accessibility_attributes` enum represents the accessibility attributes ava ### Vehicle States -Valid passenger services vehicle states are +Valid passenger vehicle states are - `removed` - `available` @@ -173,7 +258,7 @@ See [Vehicle States][vehicle-states] for descriptions. ### Event Types -Valid passenger services vehicle event types are +Valid passenger vehicle event types are - `comms_lost` - `comms_restored` @@ -204,62 +289,83 @@ See vehicle [Event Types][vehicle-events] for descriptions. This is the list of `vehicle_state` and `event_type` pairings that constitute the valid transitions of the vehicle state machine. -| **From** `vehicle_state` | **To** `vehicle_state` | `trip_state` | `event_type` | Description | -| ------------------------ | ---------------------- | ------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------- | -| `available` | `elsewhere` | N/A | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while available for-hire | -| `available` | `non_contactable` | N/A | `comms_lost` | The vehicle has went out of comms while available for-use | -| `available` | `non_operational` | N/A | `service_end` | The vehicle has went out of service (is unavailable for-hire) | -| `available` | `reserved` | `reserved` | `reservation_start` | The vehicle was reserved by a passenger | -| `elsewhere` | `available` | N/A | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while available for-hire | -| `elsewhere` | `non_contactable` | N/A | `comms_lost` | The vehicle has went out of comms while outside of jurisdictional boundaries | -| `elsewhere` | `non_operational` | N/A | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while not operating commercially | -| `elsewhere` | `on_trip` | `on_trip` | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while on a trip | -| `elsewhere` | `reserved` | N/A | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while reserved by a customer | -| `non_contactable` | `available` | N/A | `comms_restored` | The vehicle has come back into comms while available for-hire | -| `non_contactable` | `elsewhere` | N/A | `comms_restored` | The vehicle has come back into comms while outside of jurisdictional boundaries | -| `non_contactable` | `non_operational` | N/A | `comms_restored` | The vehicle has come back into comms while not operating commercially | -| `non_contactable` | `on_trip` | `on_trip` | `comms_restored` | The vehicle has come back into comms while on a trip | -| `non_contactable` | `removed` | N/A | `comms_restored` | The vehicle has come back into comms while removed | -| `non_contactable` | `reserved` | `reserved` | `comms_restored` | The vehicle has come back into comms while reserved by a passenger | -| `non_contactable` | `stopped` | `stopped` | `comms_restored` | The vehicle has come back into comms while stopped | -| `non_operational` | `available` | N/A | `service_start` | The vehicle has went into service (is available for-hire) | -| `non_operational` | `elsewhere` | N/A | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while not operating commercially | -| `non_operational` | `non_contactable` | N/A | `comms_lost` | The vehicle has went out of comms while not operating commercially | -| `non_operational` | `non_operational` | N/A | `maintenance` | The vehicle has maintenance performed on site | -| `non_operational` | `non_operational` | N/A | `maintenance_end` | Maintenance is complete | -| `non_operational` | `removed` | N/A | `maintenance_pick_up` | The vehicle has entered the depot for maintenance | -| `non_operational` | `removed` | N/A | `decommissioned` | The vehicle has been removed from the Provider's fleet | -| `on_trip` | `elsewhere` | N/A | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while on a trip | -| `on_trip` | `non_contactable` | N/A | `comms_lost` | The vehicle has gone out of comms while on a trip | -| `on_trip` | `stopped` | `stopped` | `trip_stop` | The vehicle has stopped while on a trip | -| `removed` | `non_contactable` | N/A | `comms_lost` | The vehicle has gone out of comms while removed | -| `removed` | `non_operational` | N/A | `maintenance_end` | The vehicle has left the depot | -| `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 | `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 | `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 | -| `stopped` | `on_trip` | `on_trip` | `trip_resume` | Resume a trip that was previously stopped (e.g. picking up a friend to go to the airport with) | -| `stopped` | `on_trip` | `on_trip` | `trip_start` | Start a trip | +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------------------------| +| `available` | `elsewhere` | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while available for-hire | +| `available` | `non_contactable` | `comms_lost` | The vehicle has went out of comms while available for-use | +| `available` | `non_operational` | `service_end` | The vehicle has went out of service (is unavailable for-hire) | +| `available` | `reserved` | `reservation_start` | The vehicle was reserved by a passenger | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------------------------| +| `elsewhere` | `available` | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while available for-hire | +| `elsewhere` | `non_contactable` | `comms_lost` | The vehicle has went out of comms while outside of jurisdictional boundaries | +| `elsewhere` | `non_operational` | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while not operating commercially | +| `elsewhere` | `on_trip` | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while on a trip | +| `elsewhere` | `reserved` | `trip_enter_jurisdiction` | The vehicle has entered jurisdictional boundaries while reserved by a customer | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------------------------| +| `non_contactable` | `available` | `comms_restored` | The vehicle has come back into comms while available for-hire | +| `non_contactable` | `elsewhere` | `comms_restored` | The vehicle has come back into comms while outside of jurisdictional boundaries | +| `non_contactable` | `non_operational` | `comms_restored` | The vehicle has come back into comms while not operating commercially | +| `non_contactable` | `on_trip` | `comms_restored` | The vehicle has come back into comms while on a trip | +| `non_contactable` | `removed` | `comms_restored` | The vehicle has come back into comms while removed | +| `non_contactable` | `reserved` | `comms_restored` | The vehicle has come back into comms while reserved by a passenger | +| `non_contactable` | `stopped` | `comms_restored` | The vehicle has come back into comms while stopped | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------------------------| +| `non_operational` | `available` | `service_start` | The vehicle has went into service (is available for-hire) | +| `non_operational` | `elsewhere` | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while not operating commercially | +| `non_operational` | `non_contactable` | `comms_lost` | The vehicle has went out of comms while not operating commercially | +| `non_operational` | `non_operational` | `maintenance` | The vehicle has maintenance performed on site | +| `non_operational` | `non_operational` | `maintenance_end` | Maintenance is complete | +| `non_operational` | `removed` | `maintenance_pick_up` | The vehicle has entered the depot for maintenance | +| `non_operational` | `removed` | `decommissioned` | The vehicle has been removed from the Provider's fleet | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------------------------| +| `on_trip` | `elsewhere` | `trip_leave_jurisdiction` | The vehicle has left jurisdictional boundaries while on a trip | +| `on_trip` | `non_contactable` | `comms_lost` | The vehicle has gone out of comms while on a trip | +| `on_trip` | `stopped` | `trip_stop` | The vehicle has stopped while on a trip | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------------------------| +| `removed` | `non_contactable` | `comms_lost` | The vehicle has gone out of comms while removed | +| `removed` | `non_operational` | `maintenance_end` | The vehicle has left the depot | +| `removed` | `non_operational` | `recommissioned` | The vehicle has been re-added to the Provider's fleet after being previously `decommissioned` | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------------------------| +| `reserved` | `available` | `driver_cancellation` | The driver has canceled the reservation | +| `reserved` | `available` | `passenger_cancellation` | The passenger has canceled the reservation | +| `reserved` | `available` | `provider_cancellation` | The provider has canceled the reservation | +| `reserved` | `elsewhere` | `trip_leave_jurisdiction` | The vehicle has left the jurisdiction while in a reservation | +| `reserved` | `non_contactable` | `comms_lost` | The vehicle went out of comms while being reserved by a passenger | +| `reserved` | `stopped` | `reservation_stop` | The vehicle has stopped to pick up the passenger | + +| From `vehicle_state` | To `vehicle_state` | `event_type` | Description | +|----------------------|--------------------|---------------------------|-----------------------------------------------------------------------------------------------------------------| +| `stopped` | `available` | `driver_cancellation` | The driver has canceled the trip while either waiting for the passenger, or dropping them off | +| `stopped` | `available` | `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` | `provider_cancellation` | The provider has canceled the trip while the vehicle is waiting for a passenger, or dropping them off | +| `stopped` | `available` | `trip_end` | The trip has been successfully completed | +| `stopped` | `non_contactable` | `comms_lost` | The vehicle has went out of comms while stopped | +| `stopped` | `on_trip` | `trip_resume` | Resume a trip that was previously stopped (e.g. picking up a friend to go to the airport with) | +| `stopped` | `on_trip` | `trip_start` | Start a trip | [Top][toc] ### State Machine Diagram -This *State Machine Diagram* shows how `vehicle_state` and `event_type` relate to each other and how vehicles can transition between states. See [Google Slides](https://docs.google.com/presentation/d/1fHdq1efbN5GSFDLF4en-oA_BYPXQKbbIbHff6iROJKA/edit#slide=id.g2072486e468_1_19) for the source file. +This *State Machine Diagram* shows how `vehicle_state` and `event_type` relate to each other and how vehicles can transition between states. See [Google Slides](https://docs.google.com/presentation/d/1FCrBCtNQyoIcchaGx6zw4BpLCquQaWmBHsEU6fUdUoo/edit?slide=id.g2072486e468_1_19#slide=id.g2072486e468_1_19) for the source file. -![Passenger Services State Machine Diagram](passenger-services-state-machine-diagram.svg) +![Passenger State Machine Diagram](passenger-services-state-machine-diagram.svg) [Top][toc] -#### Passenger Services State Notes +#### Passenger State Notes When there is only one trip ongoing, `trip_state == vehicle_state` diff --git a/modes/vehicle_states.md b/modes/vehicle_states.md index 0969852c8..1385c6fc5 100644 --- a/modes/vehicle_states.md +++ b/modes/vehicle_states.md @@ -7,9 +7,9 @@ This file defines all possible `vehicle_state`s that can be used in state machin | `removed` | no | Examples include: at the Provider's warehouse, in a Provider's truck, or destroyed and in a landfill. | | `available` | yes | Available for rental via the Provider's app. | | `non_operational` | yes | Not available for hire. Examples include: vehicle has low battery, or currently outside legal operating hours. | -| `reserved` | yes | Reserved via Provider's app. A scooter waiting to be picked up by a rider, a taxi en route to a pickup. | +| `reserved` | yes | Reserved via Provider's app. A scooter waiting to be picked up by a rider, a taxi en route to a pickup. Time between `reserved` and `stopped` at pickup location is the customer's wait time for vehicle arrival. | | `on_trip` | yes | In a trip. For micromobility, in possession of renter. May or may not be in motion. | -| `stopped` | yes | In a trip, but stopped temporarily for some purpose, e.g. to pick up or drop off passengers or packages, or if a driver is on break. | +| `stopped` | yes | In a trip, but stopped temporarily for some purpose, e.g. to pick up or drop off passengers or packages, or if a driver is on break. Time between `stopped` and returning to `on_trip` is the vehicle wait time for customer. | | `non_contactable` | yes | Provider has temporarily lost contact with the vehicle and its disposition is unknown. Examples include: connectivity loss, GPS issues. | | `missing` | no | Provider has lost contact with the vehicle and its disposition is unknown with no immediate resolution. Examples include: scooter taken into a private residence, bike thrown in river. | | `elsewhere` | no | Outside of regulator's jurisdiction, and thus not subject to cap-counts or other regulations. Example: a vehicle that started a trip in L.A. has transitioned to Santa Monica. | @@ -22,6 +22,14 @@ MDS is intended to communicate the provider's best available information to regu It is expected that `non-contactable` will be used only for short periods of time and cities may put in place specific limitations via an SLA. As vehicles regain connectivity they should return to their prior state, and then send additional events to reflect any subsequent changes to that state. If vehicles remain `non-contactable` for over a specific limit as stated in the City SLA, then vehicles should be moved to `missing`. +#### Multi State Transitions + +See the mode specific state-transition tables which descibe how the `vehicle_state` changes in response to each `event_type`. Most events will have a single `event_type`. However, if a single event has more than one ordered `event_type` entry, the intermediate `vehicle_state` value(s) are discarded. For example, if an event contains `[trip_end, battery_low]` then the vehicle transitions from `on_trip` through `available` to `non_operational` per the state machine, but the vehicle is never "in" the `available` state. + +#### Out of Order Events + +Note that to handle out-of-order events, the validity of the prior-state shall not be enforced at the time of ingest via Provider or Agency. Events received out-of-order may result in transient incorrect vehicle states. + --- [Modes Overview][modes] diff --git a/policy/README.md b/policy/README.md index 82892835a..b1ff89833 100644 --- a/policy/README.md +++ b/policy/README.md @@ -19,6 +19,8 @@ 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) + - [Policies - Get](#policies---get) + - [Policies - Create](#policies---create) - [Geographies](#geographies) - [Requirements](#requirements) - [Flat Files](#flat-files) @@ -80,7 +82,11 @@ See the [MDS Policy Examples](https://github.com/openmobilityfoundation/mobility ### Authorization -The Policy endpoints should be made public. Authorization is not required. Agencies may make reasonable accommodations to manage their endpoints, for example, using an API key that has a clear, public way to obtain - this can be useful for rate limiting requests, ensure proper use, tracking access per requestor, and/or customization of the Policy tailored to the requestor. +In most cases, the Policy endpoints should be made public. Authorization is not required in such cases, as this information should be made public and easily accessible. + +Agencies may make reasonable accommodations to manage their endpoints by, for example, using a free to acquire API key that has a clear, public way to obtain. This can be useful for rate limiting requests, prevent abuse, ensure proper use, tracking access per requestor, for certain mobility programs or pilots, and/or customization of the Policy tailored to the requestor. + +In some cases though, it can be justified to use Authorization for the Policy API (some agencies may decide to make it authenticated for privacy programs or functional purposes). Authorization may then be used for the Policy API. It should then rely on the standard [Authorization](../general-information.md#authorization) methods used in other MDS APIs. [Top][toc] @@ -147,11 +153,15 @@ See the [Responses section][responses] for information on valid MDS response cod ### Policies +#### Policies - Get + +Allows operators to pull a list of active policies from agencies, similar to the Provider API. + **Endpoint**: `/policies/{policy_id}` **Method**: `GET` -**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). +**Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. +**Authorization**: public _or_ authenticated (see [Authorization](#authorization)) +**`data` Payload**: `{ "policies": [] }`, an array of objects with the structure [outlined below](#policy). _Path Parameters:_ @@ -175,7 +185,7 @@ 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 +**Responses** _Possible HTTP Status Codes_: 200, @@ -188,6 +198,48 @@ See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schem [Top][toc] +#### Policies - Create + +Allows agencies to push a newly created policies to operators, similar to the Agency API. This push method creates the opportunity for near real-time communication of policy changes. + +Note that once an update is communicated via a policy push, the agency should push or pull from the relevant [Geography API](../geography) endpoint to get the latest information on new or changed geographic areas. + +Endpoint producers **SHALL** provide authorization for API endpoints via a bearer token based auth system specified in the MDS [Authorization section](/general-information.md#authorization), to allow handshake communication and response confirmation. + +**Endpoint**: `/policies/` +**Method:** `POST` +**Authorization**: required +**Payload:** An array of [Policy](#policy) objects + +_Optional endpoint, as required by public agencies; if not implemented, the server should reply with `501 Not Implemented` if possible._ + +**Responses** + +_Possible HTTP Status Codes_: +201, +400, +401, +406, +409, +500, +501 + +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_created` | A policy with `policy_id` is already created | | + +Note that you may only create a new MDS Policy. Retired policies are simply referenced in `prev_policies`. See [Updating or Ending Policies](#updating-or-ending-policies) for details. + +[Top][toc] + ### Geographies **Deprecated:** see the [Geography API](/geography#transition-from-policy) for the current home of this endpoint. @@ -198,7 +250,6 @@ See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schem **Endpoint**: `/requirements/` **Method**: `GET` -**[Beta feature](/general-information.md#beta-features)**: *No (as of 2.0.0)*. **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). @@ -322,6 +373,7 @@ An individual `Policy` object is defined by the following fields: | `published_date` | [timestamp][ts] | Required | Timestamp that the policy was published | | `prev_policies` | UUID[] | [Optional](../general-information.md#optional-fields) | Unique IDs of prior policies replaced by this one | | `rules` | Rule[] | Required | List of applicable [Rule](#rules) objects | +| `external_references` | Array of [External Reference][external-reference] objects | Optional | One or more references impacting or related to this Policy. | [Top][toc] @@ -357,10 +409,11 @@ An individual `Rule` object is defined by the following fields: ### Rule Types -| Name | Description | +| Name | Description | | ------- | ------------------------------------------------------------------------------------------------------------- | | `count` | Fleet counts based on regions. Rule `minimum`/`maximum` refers to number of devices in [Rule Units](#rule-units). | | `time` | Individual limitations or fees based upon time spent in one or more vehicle states. Rule `minimum`/`maximum` refers to increments of time in [Rule Units](#rule-units). | +| `distance` | Individual limitations or fees based upon distance travelled during one or more trips. Rule `minimum`/`maximum` refers to increments of distance in [Rule Units](#rule-units). | | `speed` | Global or local speed limits. Rule `minimum`/`maximum` refers to speed in [Rule Units](#rule-units). | | `user` | Information for users, e.g. about helmet laws. Generally can't be enforced via events and telemetry. | @@ -374,6 +427,8 @@ An individual `Rule` object is defined by the following fields: | `minutes` | `time` | Minutes | | `hours` | `time` | Hours | | `days` | `time` | Days | +| `km` | `distance` | Kilometers | +| `miles` | `distance` | Miles | | `mph` | `speed` | Miles per hour | | `kph` | `speed` | Kilometers per hour | | `devices` | `count` | Devices | @@ -386,8 +441,6 @@ 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)*. - #### 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). @@ -648,7 +701,7 @@ Contains metadata applicable to the agency and at the top of its [Requirement](# Contains information about an agency's programs, with links to policy documents, and a list of providers and data specs/APIs/endpoints/fields that the program applies to over a certain time frame in its [Requirement](#requirement) data feed in the `required_data_specs` section. -Unique combinations for data specs, specific providers, vehicle types, policies, and dates (past, current, or future) can be defined. For example an agency can define MDS version 1.2.0 and GBFS 2.2 for Provider #1 in a pilot with beta endpoints and optional fields, MDS version 1.2.0 for other providers without beta features starting a month from now, and MDS version 1.1.0 for Provider #2 with docked bikeshare. +Unique combinations for data specs, specific providers, vehicle types, policies, and dates (past, current, or future) can be defined. For example an agency can define MDS version 1.2.0 and GBFS 2.2 for Provider #1 in a pilot with testing endpoints and optional fields, MDS version 1.2.0 for other providers without testing features starting a month from now, and MDS version 1.1.0 for Provider #2 with docked bikeshare. ```jsonc // ... @@ -790,6 +843,7 @@ You may also show which APIs, endpoints, and fields your agency is serving to pr | -------------------- | ----- | -------- | ----------------------------------- | | `api_name` | Text | Required | Name of the applicable API required. At least one API is required. APIs not listed will not be available to the agency. E.g. for MDS: 'provider', or 'agency'. For GBFS, this field is omitted since GBFS starts at the `endpoint` level. | | `endpoint_name` | Text | Required | Name of the required endpoint under the API. At least one endpoint is required. E.g. for MDS 'provider': 'trips' | +| `update_interval` | duration | [Optional](../general-information.md#optional-fields) | The expected minimum frequency with which this endpoint should could be updated. [ISO 8601 duration](https://en.wikipedia.org/wiki/ISO_8601#Durations). E.g. "T1M" | | `use_cases` | Object with Array | [Optional](../general-information.md#optional-fields) | 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] diff --git a/provider/README.md b/provider/README.md index 805638600..6adba70d4 100644 --- a/provider/README.md +++ b/provider/README.md @@ -20,6 +20,8 @@ This specification contains a data standard for *mobility as a service* provider * [Municipality Boundary](#municipality-boundary) * [Other Data Types](#other-data-types) * [Vehicles](#vehicles) + * [Vehicles - Get](#vehicles---get) + * [Vehicles - Post](#vehicles---post) * [Vehicle Status](#vehicle-status) * [Trips](#trips) * [Trips - Query Parameters](#trips---query-parameters) @@ -32,6 +34,8 @@ This specification contains a data standard for *mobility as a service* provider * [Recent Events](#recent-events) * [Recent Events - Query Parameters](#recent-events---query-parameters) * [Stops](#stops) +* [Incidents](#incidents) + * [Incidents - Query Parameters](#incidents---query-parameters) * [Reports](#reports) * [Reports - Response](#reports---response) * [Reports - Example](#reports---example) @@ -179,15 +183,19 @@ As with other MDS APIs, the vehicles endpoints are intended for use by regulator The `/vehicles` endpoint returns the specified vehicle (if a `device_id` is provided) or a list of vehicles. It contains vehicle properties that do not change often. -When `/vehicles` is called without specifying a device ID it should return every vehicle that has +When `/vehicles` is called without specifying a device ID it must return every vehicle that has been deployed in an agency's [Jurisdiction](/general-information.md#definitions) and/or area of agency responsibility -in the last 30 days. +in the last 30 days and it must include every vehicle included when calling the `/vehicles/status` +endpoint at the same time without specifying a specific vehicle. (In other words, if someone +retrieves `/vehicles/status` and `/vehicles` at the same time, they must be able to find every +vehicle in the `/vehicles/status` response in the `/vehicles` response.) Vehicle information about all device IDs present in other MDS endpoints must be acessible via the `/vehicles/{device_id}` style call regardless of when they were deployed. +#### Vehicles - Get + **Endpoint:** `/vehicles/{device_id}` **Method:** `GET` -**[Beta feature][beta]:** No (as of 1.2.0) **Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. **Payload:** `{ "vehicles": [] }`, an array of [Vehicle][vehicles] objects @@ -212,7 +220,7 @@ If `device_id` is specified, `GET` will return an array with a single vehicle re } ``` -#### Responses +**Responses** _Possible HTTP Status Codes_: 200, @@ -226,6 +234,50 @@ See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schem [Top][toc] +#### Vehicles - Post + +The `/vehicles` POST endpoint takes a JSON body of `device_ids` UUIDs, and returns only information for those device ids. This may be useful to obtain a targetted list of vehicles deployed more than 30 days into the past, retrieving info on many vehicles that are not in the base `/vehicles` GET response. + +**POST Body** + +```json +{"device_ids": ["a", "b", "c"]} +``` + +**Endpoint**: `/vehicles` +**Method:** `POST` +**Payload:** An array of [Vehicles](/data-types.md#vehicles) + +Returned will be a list of vehicle records with pagination details per the [JSON API](https://jsonapi.org/format/#fetching-pagination) spec (recommmend 1,000 devices or less per page): + +```json +{ + "version": "x.y.z", + "vehicles": [ ... ] + "links": { + "first": "https://...", + "last": "https://...", + "prev": "https://...", + "next": "https://..." + } +} +``` + +**Responses** + +_Possible HTTP Status Codes_: +200, +201, +400, +401, +406, +409, +500 + +See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schema] for details. + +[Top][toc] + ### Vehicle Status The `/vehicles/status` endpoint is a near-realtime endpoint and returns the current status of vehicles in an agency's [Jurisdiction](/general-information.md#definitions) and/or area of agency responsibility. All vehicles that are currently in any [PROW](/general-information.md#definitions) state [`vehicle_state`][vehicle-states] should be returned in this payload. Since all states are returned, care should be taken to filter out states not in the [PROW](/general-information.md#definitions) if doing vehicle counts. For the states `elsewhere`, `removed`, and `missing`, which include vehicles not in the [PROW](/general-information.md#definitions) but provide some operational clarity for agencies, these vehicles must only persist in the feed for 90 minutes before being removed (and should persist in the feed for at least 90 minutes). @@ -246,7 +298,6 @@ In addition to the standard [Provider payload wrapper](#response-format), respon **Endpoint:** `/vehicles/status/{device_id}` **Method:** `GET` -**[Beta feature][beta]:** No (as of 1.2.0) **Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. **Payload:** `{ "vehicles_status": [] }`, an array of [Vehicle Status][vehicle-status] objects @@ -295,7 +346,6 @@ Unless stated otherwise by the municipality, the trips endpoint must return all **Endpoint:** `/trips` **Method:** `GET` -**[Beta feature][beta]:** No **Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. **Payload:** `{ "trips": [] }`, an array of [Trip][trips] objects @@ -353,7 +403,7 @@ See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schem ## Telemetry -The `/telemetry` endpoint is a feed of vehicle telemetry data for publishing all available location data. For privacy reasons, in-trip telemetry may be delayed at the discretion of the regulating body. +The `/telemetry` endpoint is a feed of vehicle telemetry data for publishing all available location data. Telemetry data occurs whether a vehicle is on a trip or not. The frequency of the telemetry data points is determined by the agency for the specific mobility program and the technical abilities of the vehicles, operator, connectivity, etc. This frequency may be clearly specified with the [Policy Requirements](../policy/README.md#requirement-apis) `update_interval` field. For privacy reasons, in-trip telemetry may be delayed at the discretion of the regulating agency. To represent [trip](#trip) telemetry, the data should include every [observed point][point-geo] in the trip, even those which occur outside the [municipality boundary][muni-boundary], as long as any part of the trip [intersects][intersection] with the [municipality boundary][muni-boundary]. @@ -397,7 +447,6 @@ Unless stated otherwise by the municipality, this endpoint must return only thos **Endpoint:** `/events/historical` **Method:** `GET` -**[Beta feature][beta]:** No **Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. **Payload:** `{ "events": [] }`, an array of [Events](/data-types.md#events) object @@ -459,7 +508,6 @@ See also [Telemetry][telemetry]. **Endpoint:** `/events/recent` **Method:** `GET` -**[Beta feature][beta]:** No (as of 1.0.0) **Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. **Payload:** `{ "events": [] }`, an array of [Events](/data-types.md#events) object objects @@ -506,7 +554,6 @@ In addition to the standard [Provider payload wrapper](#response-format), respon **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:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. **Payload:** `{ "stops": [] }`, an array of [Stops][stops] @@ -526,6 +573,44 @@ See [Responses][responses], [Bulk Responses][bulk-responses], and [schema][schem [Top][toc] +## Incidents + +The `/incidents` endpoint is a feed of various incident data from vehicles and devices that are the public agency's jurisdition, and are connected to the [Telemetry](#telemetry) endpoint which includes geolocation with timestamp, and other information. Included if part of a [Trip](#trips), as long as any part of the trip [intersects][intersection] with the [municipality boundary][muni-boundary]. + +Incidents should be created as close to real-time as possible, and then updated when new information or changes happen. + +**Endpoint:** `/incidents` +**Method:** `GET` +**Schema:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. +**Payload:** `{ "incidents": [] }`, an array of [Incidents][incidents] objects + +[Top][toc] + +### Incidents - Query Parameters + +| Query Parameter | Type | Expected Output | +| ----- | ---- | -------- | +| `incident_id` | UUID | Return details only about a specific incident. | +| `incident_type` | String | Return details only about a specific incident type. | +| `publication_start_time` | [timestamp][ts] | Incidents where `publication_start_time <= incident.publication_time` | +| `publication_end_time` | [timestamp][ts] | Incidents where `incident.publication_time < publication_end_time` | +| `last_updated_start` | [timestamp][ts] | Incidents where `last_updated_start <= incident.last_updated` | +| `last_updated_end` | [timestamp][ts] | Incidents where `incident.last_updated < last_updated_end` | + +#### 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] + + ## Reports Reports are information that providers can send back to agencies containing aggregated data that is not contained within other MDS endpoints, like counts of special groups of riders. These supplemental reports are not a substitute for other MDS Provider endpoints. @@ -538,7 +623,6 @@ The authenticated reports are monthly, historic flat files that may be pre-gener **Endpoint:** `/reports` **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:** See [`mds-openapi`](https://github.com/openmobilityfoundation/mds-openapi) repository for schema. **Filename:** monthly file named by year and month, e.g. `/reports/YYYY-MM.csv` @@ -577,6 +661,7 @@ See [Provider examples](examples.md#reports). [geography-driven-events]: /general-information.md#geography-driven-events [geojson-feature-collection]: https://tools.ietf.org/html/rfc7946#section-3.3 [iana]: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml +[incidents]: /data-types.md#incidents [intersection]: /general-information.md#intersection-operation [iso4217]: https://en.wikipedia.org/wiki/ISO_4217#Active_codes [json-api-pagination]: http://jsonapi.org/format/#fetching-pagination diff --git a/providers.csv b/providers.csv index 642cc0e5a..c525d4437 100644 --- a/providers.csv +++ b/providers.csv @@ -50,7 +50,7 @@ Whoosh,micromobility,3f8908a7-86fa-450d-8889-5d49077e06cd,https://whoosh.bike,ht 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 -Nextbike,micromobility,31e54f5a-66c4-4a4c-bb6e-236351c90312,https://www.nextbike.de,https://platform-services.tier-services.io/data-sharing/mds/,https://api.nextbike.net/maps/gbfs/ +Nextbike,micromobility,31e54f5a-66c4-4a4c-bb6e-236351c90312,https://www.nextbike.de,https://mds-provider-api.nextbike.net,https://api.nextbike.net/maps/gbfs/ Scooty,micromobility,f4ac8ed2-d6c3-4e6f-b000-f69050e8a616,https://www.otoride.co/,https://oto-api.otoride.co/api/v2/mds/, Starship Technologies,delivery-robots,4a1524f3-8182-4b55-90c2-023c0cac84b9,https://www.starship.xyz/,https://mds-provider.starship.xyz/api/v1/mds/, Deutsche Bahn Connect,micromobility,dcd47d65-b290-4bd6-adf2-24578fbd9110,https://www.deutschebahnconnect.com/,https://bike-prod.msp.dbrent.net/mds/,https://apis.deutschebahn.com/db-api-marketplace/apis/shared-mobility-gbfs/2-2/de/CallABike/gbfs/ @@ -75,4 +75,13 @@ Tripshot,passenger-services,e154cf80-df89-4d7e-b5e7-2ee8050a6e9c,https://www.tri Trakk,passenger-services,6a907d9d-1e3c-4cb6-991c-f9738d30337b,https://gettrakk.com/,, Swoop,passenger-services,08ad2b21-8115-4d18-874f-48082e8e50fb,https://www.swoopapp.com/,, GoSharing,micromobility,1f859479-4427-4f52-8220-05c786436314,https://www.binbin.tech/,https://complianceapi.binbinapp.com/api/mds/,https://complianceapi.binbinapp.com/api/gbfs/ - +Mosaic Global,passenger-services,74ba2b64-c44f-474a-afbd-c2030fe162a6,https://mosaicglobaltransportation.com/,, +Code3,passenger-services,b49a32d7-a418-4a6a-9f81-b5227d6c7ef8,https://code3transportation.com/,, +Track My Shuttle,passenger-services,dd7db795-09c0-402f-9441-360235da3025,https://trackmyshuttle.com/,, +Greenwheels,car-share,5f88cd9e-2c7e-477a-a531-f68143121876,https://www.greenwheels.nl,, +Sixt,car-share,df72d104-372f-4d98-a4c3-9b001967990e,https://sixt.com/,https://api.orange.sixt.com/v1/share-third-party-sources/mds,https://api.orange.sixt.com/v1/share-third-party-sources/gbfs +Getaround,car-share,ede4d096-1641-4077-b986-37c602e881ae,https:getaround.com/,,https://api-eu.getaround.com/gbfs/manifest?country_code=FR +Transwest,passenger-services,8cf2ebbb-f2d4-46a7-98d2-e10e229cf718,https://www.transwestco.com/,, +Drop Mobility,micromobility,f219d244-5f62-45f1-8e79-fb0274ac58fe,https://dropmobility.com/,https://mds.dropmobility.com,https://gbfs.dropmobility.com +DoorDash,delivery-robots,6728346d-5ad1-4ddb-81d6-161c915a3d35,https://www.doordash.com/,, +Peak Transit,passenger-services,b0a0cc68-6248-4d5c-b514-bc44fbfb5d96,https://www.peaktransit.com/,,