Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend system_pricing_plans.json #252

Merged
merged 12 commits into from
Oct 14, 2020
Merged

Extend system_pricing_plans.json #252

merged 12 commits into from
Oct 14, 2020

Conversation

josee-sabourin
Copy link
Contributor

Context
In October 2019 during the GBFS Developers' workshop, before the NABSA annual conference, Kristian (@kanagy) shared a proposal for enhancing pricing information in GBFS. Participants agreed that it was a promising "minimum viable proposal" (MVP), and Kristian (@kanagy) opened PR #194. The proposal was discussed again at MobilityData's Shared Mobility Workshop in Paris in December 2019, and participants agreed it was a good place to start. However, we have received very little producer input on the proposal, and we will need at least one producer to vote on the proposal and to implement it. Starting in 2020, the scope of GBFS has been expanding to be able to support carsharing, which ultimately complicated the needs of a minimum viable proposal for extending system_pricing_plans.

Pull Request
MobilityData drafted up a proposal to cover most existing use cases along with future carsharing use cases. We heard during initial conversations with stakeholders that it was overly complex and would be difficult to implement all at once. We've scaled it back to a minimum viable proposal, while still being able to support a handful of carsharing pricing schemes. This specific PR is representative of our MVP, the full proposal can be found here.

The specific changes in the MVP are:

  • Add scheduled pricing properties (day, month, start_time, and end_time of pricing plans) to allow for future trip planning.
  • Add vehicle_type_id to reflect the various pricing schemes that are available to certain vehicle types.
  • Add rates to reflect a majority of systems that charge per kilometre or per minute for example.
  • Add price increases that take effect after a certain period of time.
  • Add surge_pricing to support demand-driven pricing.

Some of our open questions are:

  • Should we limit the unit enums to just minute and kilometers? Keeping in mind some carsharing plans are charged per week.
  • Should all units be abbreviated, if so, to which standard?

Please let us know what you think of these open questions as well as general comments/questions/concerns!

josee-sabourin and others added 6 commits July 21, 2020 13:03
Addition of Core Pricing for new PR in response to Kristian's original proposal.
Co-authored-by: Sean Barbeau <sjbarbeau@gmail.com>
Co-authored-by: Sean Barbeau <sjbarbeau@gmail.com>
gbfs.md Outdated Show resolved Hide resolved
@jiffyclub
Copy link

jiffyclub commented Sep 10, 2020

Something that I don't think could be reflected in this model is Gig's scheme where they have several different pricing schemes and charge you whichever one would result in the lowest total at the end of your rental: https://gigcarshare.com/rates/

@josee-sabourin
Copy link
Contributor Author

josee-sabourin commented Sep 15, 2020

Hi all! After the developers workshop and some individual stakeholder feedback - we now have a Pricing v2.1!.

Some notable changes:

  • removal of units in exchange for per_km_pricing and per_min_pricing
  • removal of variable_price and flat_price in exchange for defining interval every time, as suggested by @jiffyclub above
  • addition of end to the Core MVP to account for rates that are replaced by the following rate.

To note:

  • currently vehicle_type_id is added in this file, pending the vote results of Aggregate available vehicle_types at a station #261, this may be altered to have pricing_plan_id in free_bike_status.json for every vehicle, which would allow for easier dynamic pricing based on location.

@jiffyclub to model Gig would require the use of GBFS-CapPricing which is in the Google Doc proposal but not this MVP, I've added Gig as an example in Section 7 of the document!

@sfaubert1
Copy link
Contributor

Hi @josee-sabourin! This looks really good and it's clear, but I just realized that in our case we can have different per_min_pricing per vehicle_type for the same plan, and I don't see how we could clearly include this information currently without duplicating the same plan in the feed to include details for each vehicle type...

For example, a plan could have a single price to have access to different vehicle types, but then trip fees would be depending on the vehicle type used with this plan, such as:

  • 0.50 per half hour if the vehicle type used is a regular bike (human propulsion_type)
  • 1.00 per half hour if the vehicle type used is an eBike (electric_assist propulsion_type)

I don't know if it's only applicable to us or if other systems would have plans that are eligible for multiple vehicle types and where the trip fees (pricing per km or min) would be different based on the vehicle type used within a given plan.

In this case, could we add the specific vehicle_type_id as an optional field within each section for per_km_pricing / per_min_pricing (if not present, would apply to all vehicle types eligible for this plan) or should we define it somewhere else? (note that if we add it, maybe rename one of the vehicle_type_id fields since there would be 2 fields with the same name that means different things: one at the plan level and another at the additional pricing level)

Or maybe I just missed something and there's an easier way to do this?

@josee-sabourin
Copy link
Contributor Author

Hi @sfaubert1 , you are correct you would need have separate plans for each vehicle type, this was chosen to avoid parsing errors of having multiple vehicle type ID's scattered in the same plan. I'm wondering what implications your suggestion would have on the consumer side, @kanagy, what are your thoughts on this?

@kanagy
Copy link

kanagy commented Sep 28, 2020

Hi @sfaubert1, in this case I think the clearest and easiest thing to do is to treat these as two separate plans in the feed (i.e. duplicate the plan, first plan charges 0.5 per hour, second plan charges 1 per hour). I also personally think of these as two different pricing schemes, each applying to different vehicle type.

I would be against the suggestion of complicating the feed to reduce minor duplication (is that the goal?). The feed should be kept simple and a common denominator of different schemes (as long different schemes can be represented, we're good).

Copy link

@kanagy kanagy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks pretty good, left some comments.

gbfs.md Outdated Show resolved Hide resolved
gbfs.md Outdated Show resolved Hide resolved
gbfs.md Outdated
\-&nbsp;`plan_id` | Yes | ID | Identifier for a pricing plan in the system.
\-&nbsp;`vehicle_type_id` | Optional | Array | `vehicle_type_id` of the vehicle eligible for this pricing plan as described in [vehicle_types.json](#vehicle_typesjson-added-in-v21-rc).<br /><br />If this field is empty, the plan applies to all vehicle types defined in the dataset.<br /><br />In the case of a vehicle type being attributed to different plans, all plans associated with the vehicle type are valid.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would love to hear community's opinion on two approaches here:

  1. The one defined here where a pricing plan references vehicle type feed via vehicle_type_id.
  2. One where vehicle type feed references pricing plan via plan_id (i.e. the opposite of 1). I personally slightly prefer this one (because existing plan_id in the spec can be reused for referencing).

gbfs.md Outdated Show resolved Hide resolved
gbfs.md Outdated Show resolved Hide resolved
gbfs.md Outdated Show resolved Hide resolved
gbfs.md Outdated Show resolved Hide resolved
gbfs.md Outdated Show resolved Hide resolved
@josee-sabourin
Copy link
Contributor Author

josee-sabourin commented Sep 28, 2020

As mentioned in a previous comment, now that #261 has passed, this proposal has been updated to reflect those changes. Now that each vehicle can be represented in free_bike_status.json regardless of being docked or dockless, pricing_plan_id has been added to free_bike_status.json and vehicle_type_id has been removed from system_pricing_plans.json.

Additionally, #216 discussed revising price type to string to accommodate feeds that use a comma in their prices rather than a period. The fields price and rate have been changed to string. While it will be voted on in this vote, the change to price will not be implemented until v3.0.

With that, I am hoping we can move to a vote for this proposal.

I hereby call a vote on this proposal. Voting will be open for 7 full calendar days until 11:59PM UTC on October 6th, 2020.
Please vote for or against the proposal, and include the organization for which you are voting in your comment.
Please note if you can commit to implementing the proposal.

gbfs.md Outdated Show resolved Hide resolved
gbfs.md Outdated Show resolved Hide resolved
@kanagy
Copy link

kanagy commented Sep 30, 2020

+1 from Google Maps. We don't have cycles to implement it in Q4, but we do already use a very similar and compatible format with Lime.

@MuteQ
Copy link

MuteQ commented Oct 2, 2020

+1 from Transit

@jiffyclub
Copy link

+1 from Populus, looks like it can cover many cases. Populus, though, does not have any current plans to integrate with this endpoint.

@evansiroky
Copy link
Contributor

+1 from IBI Group

gbfs.md Outdated
@@ -576,10 +578,83 @@ Field Name | Required | Type | Defines
\-&nbsp;`url` | Optional | URL | URL where the customer can learn more about this pricing plan.
\-&nbsp;`name` | Yes | String | Name of this pricing plan.
\-&nbsp;`currency` | Yes | String | Currency used to pay the fare. <br /><br /> This pricing is in ISO 4217 code: http://en.wikipedia.org/wiki/ISO_4217 <br />(e.g. `CAD` for Canadian dollars, `EUR` for euros, or `JPY` for Japanese yen.)
\-&nbsp;`price` | Yes | Non-negative float OR String | Fare price, in the unit specified by currency. If String, must be in decimal monetary value.
\-&nbsp;`price` | Yes | Non-Negative float OR String | Fare price, in the unit specified by currency. If string must be in decimal monetary value. Note: v3.0 will only allow non-negative float, therefore future implementations must be non-negative float.<br /><br />In case of non-rate price, this field is the total price. In case of rate price, this field is the base price that is charged only once per trip (e.g., price for unlocking) in addition to `per_km_pricing` and/or `per_min_pricing`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the description of price, it could also be the base price that is charged to access the vehicles for a certain period of time (instead of being per trip). For example, a flat fee to have access to bikes for 24 hours, which is not charged per trip but once at the start of the 24h period, and then each trip can be charged per min or per km within these 24 hours.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, this MVP is designed for modelling one-way trips, so passes are not easily modelled this way, however it can be done using two concurrent rates (one with an interval of 1440 minutes). We can add more specific language about price acting as an unlock fee, and once this is in the spec we will be sure to add a handful of examples to show how it can be used in these various ways. Hope that helps!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I see, thanks!

gbfs.md Outdated
@@ -468,6 +469,7 @@ Field Name | Required | Type | Defines
\- `vehicle_type_id` <br/>*(added in v2.1-RC)* | Conditionally Required | ID | The vehicle_type_id of this vehicle as described in [vehicle_types.json](#vehicle_typesjson-added-in-v21-rc). This field is required if the [vehicle_types.json](#vehicle_typesjson-added-in-v21-rc) is defined.
\- `last_reported` <br/>*(added in v2.1-RC)* | Optional | Timestamp | The last time this vehicle reported its status to the operator's backend.
\- `current_range_meters` <br/>*(added in v2.1-RC)* | Conditionally Required | Non-negative float | If the corresponding vehicle_type definition for this vehicle has a motor, then this field is required. This value represents the furthest distance in meters that the vehicle can travel without recharging or refueling with the vehicle's current charge or fuel.
\- `pricing_plan_id` | Optional | ID | The `plan_id` of the pricing plan this vehicle is eligible for as described in [system_pricing_plans.json](#system_pricing_plans.json).
Copy link
Contributor

@sfaubert1 sfaubert1 Oct 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that the pricing_plan_id is at the vehicle type level (instead of the vehicle type at the pricing level) to allow for easier dynamic pricing based on location, but based on my comment from September 15th (about the same plan having different pricing based on the vehicle type), this would be confusing.

For example, if vehicle ABC is eligible for plan 123 with a certain per_min_princing and vehicle XYZ is also eligible for plan 123 but with another per_min_princing. Both ABC and XYZ vehicles would be linked to the same pricing_plan_id=123, but there would actually be 2 objects with plan_id=123 in system_pricing_plans including different per_min_princing based on the vehicle type and no way to know which vehicle is linked to which of the plan_id=123 objects in this case (without data manipulation).

I'm curious to know if we are the only ones with this particular case?

(FYI the "vehicle_type_id" is still in the system_pricing_plans.json example)

Copy link
Contributor Author

@josee-sabourin josee-sabourin Oct 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would effectively be two different pricing plans, and therefore would have two separate plan IDs, for example plan ID 123-ABC and plan ID 123-XYZ, the public name for these can be the same, but in the back end they are different. As a general rule of thumb, even if the public plan name is the same (ex: one-way), if the prices are different, they should be treated as separate plans with separate plan IDs.

Thanks for catching the example error! I'll make sure to fix that!

@sfaubert1
Copy link
Contributor

+1 from PBSC

@jayjonsson
Copy link

+1 from Lime

@heidiguenin
Copy link
Contributor

The vote on this is now closed, and it passes!

Votes in favor:
Google Maps (consumer)
Transit (consumer)
Populus (consumer)
IBI (consumer)
PBSC (producer)
Lime (producer)

No votes against.

We'll be merging, creating v2.1RC2, and then we'll follow up with those of you who said you'd be implementing. v2.1RC2 will include the recently passed #261 in addition to #269 if it passes - the vote's open, so please chime in there, too!

gbfs.md Outdated Show resolved Hide resolved
@barbeau barbeau changed the title Extending system_pricing_plans.json Extend system_pricing_plans.json Oct 14, 2020
@barbeau barbeau merged commit 9227fe5 into MobilityData:master Oct 14, 2020
@kanagy
Copy link

kanagy commented Feb 18, 2021

Hey folks, this PR is marked in README and other places as being in v2.1-RC2 (https://github.com/NABSA/gbfs/blob/master/README.md#read-the-spec--version-history), but it is not actually merged into that branch. https://github.com/NABSA/gbfs/blob/v2.1-RC/gbfs.md#system_pricing_plansjson doesn't contain the fields added in this PR. Should it be merged to v2.1-RC2 too?

@josee-sabourin
Copy link
Contributor Author

Hi Kristian, I believe you may be looking at the wrong tag (your link is to v2.1-RC), take a look here at v2.1-RC2: https://github.com/NABSA/gbfs/blob/v2.1-RC2/gbfs.md, let me know if that clarifies things!

@kanagy
Copy link

kanagy commented Feb 21, 2021

Wooops, my bad, thanks!

mplsmitch pushed a commit that referenced this pull request Mar 18, 2021
Prepare for v2.1 release
Updates README version history for v2.1 release
Changes labels from v2.1-RC and v2.1-RC2 to v2.1
Moves #252 Extend system_pricing_plans to v2.2-RC
@mplsmitch mplsmitch mentioned this pull request Mar 18, 2021
mplsmitch pushed a commit that referenced this pull request Mar 18, 2021
Prepare for v2.1 release
Updates README version history for v2.1 release
Changes labels from v2.1-RC and v2.1-RC2 to v2.1
Moves #252 Extend system_pricing_plans to v2.2-RC
@josee-sabourin josee-sabourin deleted the gbfs-corepricing branch October 21, 2021 18:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants