From f6142d485ef6dfd199629d1a0b1f882ecb5c986d Mon Sep 17 00:00:00 2001 From: Neil Goldader Date: Thu, 15 Jul 2021 08:11:25 -0400 Subject: [PATCH 1/4] rate_recurrences: rename 'once' to 'once_on_match', add 'once_on_unmatch'. Add example policies using rate properties with time rules. --- policy/README.md | 13 +++-- .../tiered-parking-fees-per-hour.json | 57 +++++++++++++++++++ .../examples/tiered-parking-fees-total.json | 57 +++++++++++++++++++ 3 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 policy/examples/tiered-parking-fees-per-hour.json create mode 100644 policy/examples/tiered-parking-fees-total.json diff --git a/policy/README.md b/policy/README.md index 7de2bae6..268a64d1 100644 --- a/policy/README.md +++ b/policy/README.md @@ -270,7 +270,7 @@ An individual `Rule` object is defined by the following fields: | Name | Description | | ------- | ------------------------------------------------------------------------------------------------------------- | | `count` | Fleet counts based on regions. Rule `minimum`/`maximum` refers to number of devices in [Rule Units](#rule-units). | -| `time` | Individual limitations on time spent in one or more vehicle-states. Rule `minimum`/`maximum` refers to increments of time 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). | | `speed` | Global or local speed limits. Rule `minimum`/`maximum` refers to speed in [Rule Units](#rule-units). | | `rate` | **[Beta feature](/general-information.md#beta-features):** *Yes (as of 1.0.0)*. Fees or subsidies based on regions and time spent in one or more vehicle-states. Rule `rate_amount` refers to the rate charged according to the [Rate Recurrences](#rate_recurrences) and the [currency requirements](/general-information.md#costs-and-currencies) in [Rule Units](#rule-units). *Prior to implementation agencies should consult with providers to discuss how the `rate` rule will be used. Most agencies do this as a matter of course, but it is particularly important to communicate in advance how frequently and in what ways rates might change over time.* | | `user` | Information for users, e.g. about helmet laws. Generally can't be enforced via events and telemetry. | @@ -312,11 +312,12 @@ An individual `Rule` object is defined by the following fields: Rate recurrences specify when a rate is applied – either once, or periodically according to a `time_unit` specified using [Rule Units](#rule-units). A `time_unit` refers to a unit of time as measured in local time for the juristiction – a day begins at midnight local time, an hour begins at the top of the hour, etc. -| Name | Description | -| --------- | ------------------- | -| `once` | Rate is applied once to vehicles entering a matching status from a non-matching status. | -| `each_time_unit` | During each `time_unit`, rate is applied once to vehicles entering or remaining in a matching status. Requires a `time_unit` to be specified using `rule_units`. | -| `per_complete_time_unit` | Rate is applied once per complete `time_unit` that vehicles remain in a matching status. Requires a `time_unit` to be specified using `rule_units`. | +| Name | Description | +| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `once_on_match` | Rate is applied once when a vehicle transitions **into** a matching status from a non-matching status. | +| `once_on_unmatch` | Rate is applied once a vehicle transitions **out of** a matching status to a non-matching status. | +| `each_time_unit` | During each `time_unit`, rate is applied once to vehicles entering or remaining in a matching status. Requires a `time_unit` to be specified using `rule_units`. | +| `per_complete_time_unit` | Rate is applied once per complete `time_unit` that vehicles remain in a matching status. Requires a `time_unit` to be specified using `rule_units`. | [Top][toc] diff --git a/policy/examples/tiered-parking-fees-per-hour.json b/policy/examples/tiered-parking-fees-per-hour.json new file mode 100644 index 00000000..99696102 --- /dev/null +++ b/policy/examples/tiered-parking-fees-per-hour.json @@ -0,0 +1,57 @@ +{ + "updated": 0, + "version": "1.2.0", + "data": { + "policy": [ + { + "name": "Tiered Dwell Time Example", + "description": "First hour $2, second hour $4, every hour onwards $10", + "policy_id": "2800cd0a-7827-4110-9713-b9e5bf29e9a1", + "start_date": 1558389669540, + "publish_date": 1558389669540, + "end_date": null, + "prev_policies": null, + "provider_ids": [], + "currency": "USD", + "rules": [ + { + "name": "> 2 hours", + "rule_id": "9cd1768c-ab9e-484c-93f8-72a7078aa7b9", + "rule_type": "time", + "rule_units": "hours", + "geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"], + "statuses": { "available": [], "non_operational": [] }, + "vehicle_types": ["bicycle", "scooter"], + "maximum": 2, + "rate_amount": 1000, + "rate_recurrence": "each_time_unit" + }, + { + "name": "1-2 Hours", + "rule_id": "edd6a195-bb30-4eb5-a2cc-44e5a18798a2", + "rule_type": "time", + "rule_units": "hours", + "geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"], + "statuses": { "available": [], "non_operational": [] }, + "vehicle_types": ["bicycle", "scooter"], + "maximum": 1, + "rate_amount": 400, + "rate_recurrence": "each_time_unit" + }, + { + "name": "0-1 Hour", + "rule_id": "6b6fe61b-dbe5-4367-8e35-84fb14d23c54", + "rule_type": "time", + "rule_units": "hours", + "geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"], + "statuses": { "available": [], "non_operational": [] }, + "vehicle_types": ["bicycle", "scooter"], + "maximum": 0, + "rate_amount": 200, + "rate_recurrence": "each_time_unit" + } + ] + } + ] + } +} diff --git a/policy/examples/tiered-parking-fees-total.json b/policy/examples/tiered-parking-fees-total.json new file mode 100644 index 00000000..86b8e1a3 --- /dev/null +++ b/policy/examples/tiered-parking-fees-total.json @@ -0,0 +1,57 @@ +{ + "updated": 0, + "version": "1.2.0", + "data": { + "policy": [ + { + "name": "Tiered Dwell Time Example", + "description": "If parked for <1hr $2 upon exit, if parked for 1-2 hours $4 upon exit, if parked for longer than 2 hours $10 upon exit", + "policy_id": "2800cd0a-7827-4110-9713-b9e5bf29e9a1", + "start_date": 1558389669540, + "publish_date": 1558389669540, + "end_date": null, + "prev_policies": null, + "provider_ids": [], + "currency": "USD", + "rules": [ + { + "name": "> 2 hours", + "rule_id": "9cd1768c-ab9e-484c-93f8-72a7078aa7b9", + "rule_type": "time", + "rule_units": "hours", + "geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"], + "statuses": { "available": [], "non_operational": [] }, + "vehicle_types": ["bicycle", "scooter"], + "maximum": 2, + "rate_amount": 1000, + "rate_recurrence": "once_on_unmatch" + }, + { + "name": "1-2 Hours", + "rule_id": "edd6a195-bb30-4eb5-a2cc-44e5a18798a2", + "rule_type": "time", + "rule_units": "hours", + "geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"], + "statuses": { "available": [], "non_operational": [] }, + "vehicle_types": ["bicycle", "scooter"], + "maximum": 1, + "rate_amount": 400, + "rate_recurrence": "once_on_unmatch" + }, + { + "name": "0-1 Hour", + "rule_id": "6b6fe61b-dbe5-4367-8e35-84fb14d23c54", + "rule_type": "time", + "rule_units": "hours", + "geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"], + "statuses": { "available": [], "non_operational": [] }, + "vehicle_types": ["bicycle", "scooter"], + "maximum": 0, + "rate_amount": 200, + "rate_recurrence": "once_on_unmatch" + } + ] + } + ] + } +} From 864bdc6d28b44982678676887e96ff2e41f8b5b3 Mon Sep 17 00:00:00 2001 From: Neil Goldader Date: Tue, 10 Aug 2021 15:01:41 -0400 Subject: [PATCH 2/4] Add examples to policy/examples/README.md --- policy/examples/README.md | 139 +++++++++++++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 8 deletions(-) diff --git a/policy/examples/README.md b/policy/examples/README.md index 9fb59f93..05373724 100644 --- a/policy/examples/README.md +++ b/policy/examples/README.md @@ -4,14 +4,18 @@ This file presents a series of example [Policy documents](../README.md#schema) f ## Table of Contents -- [Prohibited Zone](#prohibited-zone) -- [Provider Cap](#provider-cap) -- [Idle Time](#idle-time) -- [Speed Limits](#speed-limits) -- [Per Trip Fees](#per-trip-fees) -- [Vehicle Right of Way Fees](#vehicle-right-of-way-fees) -- [Metered Parking Fees](#metered-parking-fees) -- [Required Parking](#required-parking) +- [Policy Examples](#policy-examples) + - [Table of Contents](#table-of-contents) + - [Prohibited Zone](#prohibited-zone) + - [Provider Cap](#provider-cap) + - [Idle Time](#idle-time) + - [Speed Limits](#speed-limits) + - [Per Trip Fees](#per-trip-fees) + - [Vehicle Right of Way Fees](#vehicle-right-of-way-fees) + - [Metered Parking Fees](#metered-parking-fees) + - [Required Parking](#required-parking) + - [Tiered Parking Fees Per Hour](#tiered-parking-fees-per-hour) + - [Tiered Parking Fees Total](#tiered-parking-fees-total) ## Prohibited Zone @@ -445,5 +449,124 @@ File: [`required-parking.json`](required-parking.json) } ``` +## Tiered Parking Fees Per Hour +This policy states parking fees as such: +- Parking for the first hour costs $2 +- Parking for the second hour costs $4 +- Parking every hour onwards costs $10 + +For example, say a vehicle is parked for 6.5 hours. It will be charged `$2 (0-1hr) + $4 (1-2hr) + $10 (2-3hr) + $10 (3-4hr) + $10 (4-5hr) + $10 (5-6hr) + $10 (6-6.5hr) = $56` +File: [`tiered-parking-fees-per-hour.json`](tiered-parking-fees-per-hour.json) +``` +{ + "name": "Tiered Dwell Time Example", + "description": "First hour $2, second hour $4, every hour onwards $10", + "policy_id": "2800cd0a-7827-4110-9713-b9e5bf29e9a1", + "start_date": 1558389669540, + "publish_date": 1558389669540, + "end_date": null, + "prev_policies": null, + "provider_ids": [], + "currency": "USD", + "rules": [ + { + "name": "> 2 hours", + "rule_id": "9cd1768c-ab9e-484c-93f8-72a7078aa7b9", + "rule_type": "time", + "rule_units": "hours", + "geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"], + "statuses": { "available": [], "non_operational": [] }, + "vehicle_types": ["bicycle", "scooter"], + "maximum": 2, + "rate_amount": 1000, +"rate_recurrence": "each_time_unit" + }, + { + "name": "1-2 Hours", + "rule_id": "edd6a195-bb30-4eb5-a2cc-44e5a18798a2", + "rule_type": "time", + "rule_units": "hours", + "geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"], + "statuses": { "available": [], "non_operational": [] }, + "vehicle_types": ["bicycle", "scooter"], + "maximum": 1, + "rate_amount": 400, +"rate_recurrence": "each_time_unit" + }, + { + "name": "0-1 Hour", + "rule_id": "6b6fe61b-dbe5-4367-8e35-84fb14d23c54", + "rule_type": "time", + "rule_units": "hours", + "geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"], + "statuses": { "available": [], "non_operational": [] }, + "vehicle_types": ["bicycle", "scooter"], + "maximum": 0, + "rate_amount": 200, +"rate_recurrence": "each_time_unit" + } + ] +} +``` + +## Tiered Parking Fees Total +This policy states parking fees as such: +- If parked for less than an hour, $2 on exit +- If parked for less than 2 hours, $4 on exit +- If parked for any duration longer than 2 hours, $10 on exit + +For example, if a vehicle is parked for 6.5 hours, it will be charged $10 on exit. +File: [`tiered-parking-fees-total.json`](tiered-parking-fees-total.json) +``` +{ + "name": "Tiered Dwell Time Example", + "description": "If parked for <1hr $2 upon exit, if parked for 1-2 hours $4 upon exit, if parked for longer than 2 hours $10 upon exit", + "policy_id": "2800cd0a-7827-4110-9713-b9e5bf29e9a1", + "start_date": 1558389669540, + "publish_date": 1558389669540, + "end_date": null, + "prev_policies": null, + "provider_ids": [], + "currency": "USD", + "rules": [ + { + "name": "> 2 hours", + "rule_id": "9cd1768c-ab9e-484c-93f8-72a7078aa7b9", + "rule_type": "time", + "rule_units": "hours", + "geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"], + "statuses": { "available": [], "non_operational": [] }, + "vehicle_types": ["bicycle", "scooter"], + "maximum": 2, + "rate_amount": 1000, +"rate_recurrence": "once_on_unmatch" + }, + { + "name": "1-2 Hours", + "rule_id": "edd6a195-bb30-4eb5-a2cc-44e5a18798a2", + "rule_type": "time", + "rule_units": "hours", + "geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"], + "statuses": { "available": [], "non_operational": [] }, + "vehicle_types": ["bicycle", "scooter"], + "maximum": 1, + "rate_amount": 400, +"rate_recurrence": "once_on_unmatch" + }, + { + "name": "0-1 Hour", + "rule_id": "6b6fe61b-dbe5-4367-8e35-84fb14d23c54", + "rule_type": "time", + "rule_units": "hours", + "geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"], + "statuses": { "available": [], "non_operational": [] }, + "vehicle_types": ["bicycle", "scooter"], + "maximum": 0, + "rate_amount": 200, +"rate_recurrence": "once_on_unmatch" + } + ] +} +``` [Top](#table-of-contents) From f3b901748ccca647334b53c52dfa89688ad5d02b Mon Sep 17 00:00:00 2001 From: Neil Goldader Date: Tue, 10 Aug 2021 15:02:19 -0400 Subject: [PATCH 3/4] Fix some formatting issues --- policy/examples/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/policy/examples/README.md b/policy/examples/README.md index 05373724..3a6ac846 100644 --- a/policy/examples/README.md +++ b/policy/examples/README.md @@ -479,7 +479,7 @@ File: [`tiered-parking-fees-per-hour.json`](tiered-parking-fees-per-hour.json) "vehicle_types": ["bicycle", "scooter"], "maximum": 2, "rate_amount": 1000, -"rate_recurrence": "each_time_unit" + "rate_recurrence": "each_time_unit" }, { "name": "1-2 Hours", @@ -491,7 +491,7 @@ File: [`tiered-parking-fees-per-hour.json`](tiered-parking-fees-per-hour.json) "vehicle_types": ["bicycle", "scooter"], "maximum": 1, "rate_amount": 400, -"rate_recurrence": "each_time_unit" + "rate_recurrence": "each_time_unit" }, { "name": "0-1 Hour", @@ -503,7 +503,7 @@ File: [`tiered-parking-fees-per-hour.json`](tiered-parking-fees-per-hour.json) "vehicle_types": ["bicycle", "scooter"], "maximum": 0, "rate_amount": 200, -"rate_recurrence": "each_time_unit" + "rate_recurrence": "each_time_unit" } ] } @@ -539,7 +539,7 @@ File: [`tiered-parking-fees-total.json`](tiered-parking-fees-total.json) "vehicle_types": ["bicycle", "scooter"], "maximum": 2, "rate_amount": 1000, -"rate_recurrence": "once_on_unmatch" + "rate_recurrence": "once_on_unmatch" }, { "name": "1-2 Hours", @@ -551,7 +551,7 @@ File: [`tiered-parking-fees-total.json`](tiered-parking-fees-total.json) "vehicle_types": ["bicycle", "scooter"], "maximum": 1, "rate_amount": 400, -"rate_recurrence": "once_on_unmatch" + "rate_recurrence": "once_on_unmatch" }, { "name": "0-1 Hour", @@ -563,7 +563,7 @@ File: [`tiered-parking-fees-total.json`](tiered-parking-fees-total.json) "vehicle_types": ["bicycle", "scooter"], "maximum": 0, "rate_amount": 200, -"rate_recurrence": "once_on_unmatch" + "rate_recurrence": "once_on_unmatch" } ] } From c0d407fc26d5a8ea442c8f1e96ba0aed4f4aace6 Mon Sep 17 00:00:00 2001 From: Neil Goldader Date: Fri, 13 Aug 2021 11:59:38 -0400 Subject: [PATCH 4/4] Clarify when rate-related properties are allowed --- policy/README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/policy/README.md b/policy/README.md index 268a64d1..f838b5bc 100644 --- a/policy/README.md +++ b/policy/README.md @@ -255,7 +255,7 @@ An individual `Rule` object is defined by the following fields: | `propulsion_types` | `propulsion_type[]` | Optional | Applicable vehicle [propulsion types][propulsion-types], default "all". | | `minimum` | integer | Optional | Minimum value, if applicable (default 0) | | `maximum` | integer | Optional | Maximum value, if applicable (default unlimited) | -| `rate_amount` | integer | Optional | 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). | +| `rate_amount` | integer | Optional | Amount of the rate (see [Rate Amounts](#rate-amounts)) | | `rate_recurrence` | enum | Optional | Recurrence of the rate (see [Rate Recurrences](#rate-recurrences)) | | `start_time` | ISO 8601 time `hh:mm:ss` | Optional | Beginning time-of-day when the rule is in effect (default 00:00:00). | | `end_time` | ISO 8601 time `hh:mm:ss` | Optional | Ending time-of-day when the rule is in effect (default 23:59:59). | @@ -308,9 +308,15 @@ An individual `Rule` object is defined by the following fields: [Top][toc] -### Rate Recurrences +### Rates +Rate-related properties can currently be specified on `rate` and `time` Rules. Note: A future MDS version will likely support rates for `count` and `speed` rules, but their behavior is currently undefined. -Rate recurrences specify when a rate is applied – either once, or periodically according to a `time_unit` specified using [Rule Units](#rule-units). A `time_unit` refers to a unit of time as measured in local time for the juristiction – a day begins at midnight local time, an hour begins at the top of the hour, etc. +#### 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). + +#### Rate Recurrences + +Rate recurrences specify when a rate is applied – either once, or periodically according to a `time_unit` specified using [Rule Units](#rule-units). A `time_unit` refers to a unit of time as measured in local time for the jurisdiction – a day begins at midnight local time, an hour begins at the top of the hour, etc. | Name | Description | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |