Skip to content

Commit 379230b

Browse files
committed
updates per feedback
1 parent 1e0e740 commit 379230b

6 files changed

Lines changed: 193 additions & 218 deletions

File tree

agency/README.md

Lines changed: 12 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,37 +17,21 @@ This specification contains a collection of RESTful APIs used to specify the dig
1717

1818
## General information
1919

20-
This specification uses data types including timestamps, UUIDs, and vehicle state definitions as described in the MDS [Shared Definitions](#../shared/README.md) document.
20+
This specification uses data types including timestamps, UUIDs, and vehicle state definitions as described in the MDS [General Information][general] document.
2121

2222
### Versioning
2323

2424
`agency` APIs must handle requests for specific versions of the specification from clients.
2525

26-
Versioning must be implemented as specified in the [`General information versioning section`][general-information/versioning].
27-
28-
### Authorization
29-
30-
The following information applies to all `agency` API endpoints.
31-
32-
Currently, the `agency` API is implemented for dockless scooter, bikeshare, and carshare. To implement another mode, add it to the `schema/generate_schema.py` file and this README and submit a pull request.
26+
Versioning must be implemented as specified in the [`General information versioning section`][versioning].
3327

3428
### Responses
3529

36-
* **200:** OK: operation successful.
37-
* **201:** Created: `POST` operations, new object created
38-
* **400:** Bad request.
39-
* **401:** Unauthorized: Invalid, expired, or insufficient scope of token.
40-
* **404:** Not Found: Object does not exist, returned on `GET` or `POST` operations if the object does not exist.
41-
* **409:** Conflict: `POST` operations when an object already exists and an update is not possible.
42-
* **500:** Internal server error: In this case, the answer may contain a `text/plain` body with an error message for troubleshooting.
30+
See [responses][responses]
4331

4432
### Error Message Format
4533

46-
| Field | Type | Field Description |
47-
| ------------------- | -------- | ---------------------- |
48-
| `error` | String | Error message string |
49-
| `error_description` | String | Human readable error description (can be localized) |
50-
| `error_details` | String[] | Array of error details |
34+
See [error message format][error-message-format]
5135

5236
### Authorization
5337

@@ -250,30 +234,15 @@ A standard point of vehicle telemetry. References to latitude and longitude impl
250234
| `gps.satellites` | Integer | Required if Available | Number of GPS or GNSS satellites
251235
| `charge` | Float | Required if Applicable | Percent battery charge of vehicle, expressed between 0 and 1 |
252236

253-
## Responses
254-
255-
* **200:** OK: operation successful.
256-
* **201:** Created: `POST` operations, new object created
257-
* **400:** Bad request.
258-
* **401:** Unauthorized: Invalid, expired, or insufficient scope of token.
259-
* **404:** Not Found: Object does not exist, returned on `GET` or `POST` operations if the object does not exist.
260-
* **409:** Conflict: `POST` operations when an object already exists and an update is not possible.
261-
* **500:** Internal server error: In this case, the answer may contain a `text/plain` body with an error message for troubleshooting.
262-
263-
### Error Message Format
264-
265-
| Field | Type | Field Description |
266-
| ------------------- | -------- | ---------------------- |
267-
| `error` | String | Error message string |
268-
| `error_description` | String | Human readable error description (can be localized) |
269-
| `error_details` | String[] | Array of error details |
270-
271237
[Top][toc]
272238

273239
[toc]: #table-of-contents
274-
[general-information/versioning]: /general-information.md#versioning
275-
[vehicle-types]: ../shared/README.md#vehicle-types
276-
[vehicle-states]: ../shared/README.md#vehicle-states
277-
[vehicle-events]: ../shared/README.md#vehicle-events
278-
[propulsion-types]: ../shared/README.md#propulsion-types
240+
[general]: /general-information.md
241+
[versioning]: /general-information.md#versioning
242+
[responses]: /general-information.md#responses
243+
[error-message-format]: /general-information.md#error-message-format
244+
[vehicle-types]: /general-information.md#vehicle-types
245+
[vehicle-states]: /general-information.md#vehicle-states
246+
[vehicle-events]: /general-information.md#vehicle-events
247+
[propulsion-types]: /general-information.md#propulsion-types
279248
[hdop]: https://support.esri.com/en/other-resources/gis-dictionary/term/358112bd-b61c-4081-9679-4fca9e3eb926

general-information.md

Lines changed: 143 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,30 @@ This document contains specifications that are shared between the various MDS AP
66

77
* [Versioning](#versioning)
88
* [Beta Features](#beta-features)
9+
* [Responses](#responses)
10+
* [Error Message Format](#error-message-format)
11+
* [Timestamps](#timestamps)
12+
* [Strings](#strings)
13+
* [UUIDs](#uuids)
14+
* [Costs and Currencies](#costs-and-currencies)
15+
* [Devices](#devices)
16+
* [Vehicle Types](#vehicle-types)
17+
* [Propulsion Types](#propulsion-types)
18+
* [Vehicle States](#vehicle-states)
19+
* [Vehicle Events](#vehicle-events)
920

1021
## Versioning
1122

1223
MDS APIs must handle requests for specific versions of the specification from clients.
1324

14-
Versioning must be implemented through the use of a custom media-type, `application/vnd.mds.provider+json`, combined with a required `version` parameter.
25+
Versioning must be implemented through the use of a custom media-type, `application/vnd.mds+json`, combined with a required `version` parameter.
1526

16-
The version parameter specifies the dot-separated combination of major and minor versions from a published version of the specification. For example, the media-type for version `0.2.1` would be specified as `application/vnd.mds.provider+json;version=0.2`
17-
18-
> Note: Normally breaking changes are covered by different major versions in semver notation. However, as this specification is still pre-1.0.0, changes in minor versions may include breaking changes, and therefore are included in the version string.
27+
The version parameter specifies the dot-separated combination of major and minor versions from a published version of the specification. For example, the media-type for version `1.0.1` would be specified as `application/vnd.mds+json;version=1.0`
1928

2029
Clients must specify the version they are targeting through the `Accept` header. For example:
2130

2231
```http
23-
Accept: application/vnd.mds.provider+json;version=0.3
32+
Accept: application/vnd.mds+json;version=0.3
2433
```
2534

2635
> Since versioning was not available from the start, the following APIs provide a fallback version if the `Accept` header is not set as specified above:
@@ -35,18 +44,37 @@ A client negotiates available versions using the `OPTIONS` method to an MDS endp
3544
```http
3645
OPTIONS /trips/ HTTP/1.1
3746
Host: provider.example.com
38-
Accept: application/vnd.mds.provider+json;version=0.2,application/vnd.mds.provider+json;version=0.3;q=0.9
47+
Accept: application/vnd.mds+json;version=0.2,application/vnd.mds+json;version=0.3;q=0.9
3948
```
4049

4150
The response will include the most preferred supported version in the `Content-Type` header. For example, if only `0.3` is supported:
4251

4352
```http
44-
Content-Type: application/vnd.mds.provider+json;version=0.3
53+
Content-Type: application/vnd.mds+json;version=0.3
4554
```
4655

4756
The client can use the returned value verbatim as a version request in the `Accept` header.
4857

58+
## Responses
59+
60+
* **200:** OK: operation successful.
61+
* **201:** Created: `POST` operations, new object created
62+
* **400:** Bad request.
63+
* **401:** Unauthorized: Invalid, expired, or insufficient scope of token.
64+
* **404:** Not Found: Object does not exist, returned on `GET` or `POST` operations if the object does not exist.
65+
* **409:** Conflict: `POST` operations when an object already exists and an update is not possible.
66+
* **500:** Internal server error: In this case, the answer may contain a `text/plain` body with an error message for troubleshooting.
67+
68+
## Error Message Format
69+
70+
| Field | Type | Field Description |
71+
| ------------------- | -------- | ---------------------- |
72+
| `error` | String | Error message string |
73+
| `error_description` | String | Human readable error description (can be localized) |
74+
| `error_details` | String[] | Array of error details |
75+
4976
## Beta Features
77+
5078
In some cases, features within MDS may be marked as "beta." These are typically recently added endpoints or fields. Because beta features are new, they may not yet be fully mature and proven in real-world operation. The design of beta features may have undiscovered gaps, ambiguities, or inconsistencies. Implementations of those features are typically also quite new and are more likely to contain bugs or other flaws. Beta features are likely to evolve more rapidly than other parts of the specification.
5179

5280
Despite this, MDS users are highly encouraged to use beta features. New features can only become proven and trusted through implementation, use, and the learning that comes with it. Users should be thoughtful about the role of beta features in their operations. Beta features may be suitable for enabling some new tools and analysis, but may not be appropriate for mission-critical applications or regulatory decisions where certainty and reliability are essential.
@@ -56,3 +84,111 @@ Users of beta features are strongly encouraged to share their experiences, learn
5684
Working Groups and their Steering Committees are expected to review beta designated features with each release cycle and determine whether the feature has reached the level of stability and maturity needed to remove the beta designation. In a case where a beta feature fails to reach substantial adoption after an extended time, Working Group Steering Committees should discuss whether or not the feature should remain in the specification.
5785

5886
[Top](#table-of-contents)
87+
88+
## Timestamps
89+
90+
A `timestamp` refers to integer milliseconds since Unix epoch.
91+
92+
## Strings
93+
94+
All String fields, such as `vehicle_id`, are limited to a maximum of 255 characters.
95+
96+
## UUIDs
97+
98+
Object identifiers are described via Universally Unique Identifiers [(UUIDs)](https://en.wikipedia.org/wiki/Universally_unique_identifier). For example, the `device_id` field used to uniquely identify a vehicle is a UUID.
99+
100+
MDS uses Version 1 UUIDs.
101+
102+
## Costs and currencies
103+
104+
Fields specifying a monetary cost use a currency as specified in [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217#Active_codes). All costs should be given as integers in the currency's smallest unit. As an example, to represent $1 USD, specify an amount of `100` (100 cents).
105+
106+
If the currency field is null, USD cents is implied.
107+
108+
## Devices
109+
110+
MDS defines the *device* as the unit that transmits GPS or GNSS signals for a particular vehicle. A given device must have a UUID (`device_id` below) that is unique within the Provider's fleet.
111+
112+
Additionally, `device_id` must remain constant for the device's lifetime of service, regardless of the vehicle components that house the device.
113+
114+
## Vehicle Types
115+
116+
The list of allowed `vehicle_type` values in MDS is:
117+
118+
| `vehicle_type` | Description |
119+
|--------------| --- |
120+
| bicycle | Anything with pedals, including recumbents; can include powered assist |
121+
| car | Any automobile |
122+
| scooter | Any motorized mobility device intended for one rider |
123+
| moped | A motorcycle/bicycle hybrid that can be powered or pedaled |
124+
125+
## Propulsion Types
126+
127+
| `propulsion` | Description |
128+
| ----------------- | ------------------------------------------------------ |
129+
| `human` | Pedal or foot propulsion |
130+
| `electric_assist` | Provides power only alongside human propulsion |
131+
| `electric` | Contains throttle mode with a battery-powered motor |
132+
| `combustion` | Contains throttle mode with a gas engine-powered motor |
133+
134+
A vehicle may have one or more values from the `propulsion`, depending on the number of modes of operation. For example, a scooter that can be powered by foot or by electric motor would have the `propulsion` represented by the array `['human', 'electric']`. A bicycle with pedal-assist would have the `propulsion` represented by the array `['human', 'electric_assist']` if it can also be operated as a traditional bicycle.
135+
136+
## Vehicle States
137+
138+
This table describes the list of vehicle conditions that may be used by regulators to assess the disposition of individual vehicles and fleets of vehicles. Some of these states describe vehicles in the Public Right-of-Way (PROW), and others represent vehicles that are not. One state (`unknown`) implies that PROW status is unknown.
139+
140+
In a multi-jurisdiction environment, the status of a vehicle is per-jurisdiction. For example, a vehicle may be in the `trip` status for a county that contains five cities, and also in the `trip` status for one of those cities, but `elsewhere` for the other four cities. In such a condition, generally a Provider would send the device data to the over-arching jurisdiction (the county) and the vehicle state with respect to each city would be determined by the Agency managing the jurisdictions.
141+
142+
| `vehicle_state` | In PROW? | Description |
143+
| --- | --- |
144+
| `removed` | no | Examples include: at the Provider's warehouse, in a Provider's truck, or destroyed and in a landfill. |
145+
| `available` | yes | Available for rental via the Provider's app. In PROW. |
146+
| `unavailable` | yes | Not available for rent. Examples include: vehicle has low battery, or currently outside legal operating hours. |
147+
| `reserved` | yes | Reserved via Provider's app, waiting to be picked up by a rider. |
148+
| `trip` | yes | In posession of renter. May or may not be in motion. |
149+
| `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. |
150+
| `unknown` | unknown | Provider has lost contact with the vehicle and its disposition is unknown. Examples include: taken into a private residence, thrown in river. |
151+
152+
## Vehicle Events
153+
154+
This is the list of `vehicle_state` and `event_type` pairings that constitute the valid transitions of the vehicle state machine.
155+
156+
Note that to handle out-of-order events, the validity of the prior-state is not enforced at the time of ingest via Provider or Agency. Events received out-of-order may result in transient incorrect vehicle states.
157+
158+
| Valid prior `vehicle_state` values | `vehicle_state` | `event_type` | Description |
159+
| --- | --- | --- | --- |
160+
| `unavailable` | `available` | `battery_charged` | The vehicle became available because its battery is now charged. |
161+
| `unavailable` | `available` | `on_hours` | The vehicle has entered operating hours (per the regulator or per the provider) |
162+
| `removed`, `elsewhere`, `unknown` | `available` | `provider_drop_off` | The vehicle was placed in the PROW by the provider |
163+
| `removed`, `elsewhere`, `unknown` | `available` | `agency_drop_off` | The vehicle was placed in the PROW by a city or county |
164+
| `unavailable` | `available` | `maintenance` | The vehicle was previously in need of maintenance |
165+
| `trip` | `available` | `trip_end` | A trip has ended, and the vehicle is again available for rent |
166+
| `reserved` | `available` | `reservation_cancel` | A reservation was canceled and the vehicle returned to service |
167+
| `trip` | `available` | `trip_cancel` | A trip was initiated, then canceled prior to moving any distance |
168+
| `unavailable`, `unknown`, `removed`, `reserved`, `elsewhere` | `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`. |
169+
| `available` | `reserved` | `reservation_start` | The vehicle was reserved for use by a customer |
170+
| `available`, `reserved` | `trip` | `trip_start` | A customer initiated a trip with this vehicle |
171+
| `elsewhere` | `trip` | `trip_enter_jurisdiction` | A vehicle on a trip entered the jurisdiction |
172+
| `trip` | `elsewhere` | `trip_leave_jurisdiction` | A vehicle on a trip left the jurisdiction |
173+
| `available` | `unavailable` | `low_battery` | The vehicle's battery is below some rentability threshold |
174+
| `available` | `unavailable` | `maintenance` | The vehicle requires some non-charge-related maintenance |
175+
| `available` | `unavailable` | `off_hours` | The vehicle has exited operating hours (per the regulator or per the Provider) |
176+
| `available` | `unavailable` | `unspecified` | The vehicle became unavailable, but he Provider cannot definitively (yet) specify the reason. |
177+
| `available`, `unavailable`, `elsewhere` | `removed` | `rebalance_pick_up` | The provider picked up the vehicle for rebalancing purposes |
178+
| `available`, `unavailable`, `elsewhere` | `removed` | `maintenance_pick_up` | The provider picked up the vehicle to service it |
179+
| any | `removed` | `agency_pick_up` | An agency picked up the vehicle for some reason, e.g. illegal placement |
180+
| `available`, `unavailable`, `elsewhere` | `removed` | `compliance_pick_up` | The provider picked up the vehicle because it was placed in a non-compliant location |
181+
| `available`, `unavailable`, `removed`, `elsewhere`, `unknown` | `removed` | `decommissioned` | The provider has removed the vehicle from its fleet |
182+
| `unknown`, `unavailable`, `available`, `elsewhere` | `removed` | `unspecified` | The vehicle was removed, but the provider cannot definitively (yet) specify the reason |
183+
| any | `unknown` | `missing` | The vehicle is not at its last reported GPS location, or that location is wildly in error |
184+
| any | `unknown` | `out_of_comms` | The vehicle is unable to transmit its GPS location |
185+
186+
NOTES:
187+
188+
`trip` vs. `in_trip` vs. `on_trip`?
189+
190+
`unavailable` vs `non_operational`?
191+
192+
Should we try to handle "unlicensed movements"?
193+
194+
What's the best way to return from `unknown`?

0 commit comments

Comments
 (0)