Skip to content

Commit b8362b8

Browse files
authored
Merge pull request #658 from lacuna-tech/feature/neil/tiered-rate-policies
Tiered Dwell Time with Rates
2 parents 31a8be0 + c0d407f commit b8362b8

4 files changed

Lines changed: 261 additions & 17 deletions

File tree

policy/README.md

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ An individual `Rule` object is defined by the following fields:
277277
| `propulsion_types` | `propulsion_type[]` | Optional | Applicable vehicle [propulsion types][propulsion-types], default "all". |
278278
| `minimum` | integer | Optional | Minimum value, if applicable (default 0) |
279279
| `maximum` | integer | Optional | Maximum value, if applicable (default unlimited) |
280-
| `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). |
280+
| `rate_amount` | integer | Optional | Amount of the rate (see [Rate Amounts](#rate-amounts)) |
281281
| `rate_recurrence` | enum | Optional | Recurrence of the rate (see [Rate Recurrences](#rate-recurrences)) |
282282
| `start_time` | ISO 8601 time `hh:mm:ss` | Optional | Beginning time-of-day when the rule is in effect (default 00:00:00). |
283283
| `end_time` | ISO 8601 time `hh:mm:ss` | Optional | Ending time-of-day when the rule is in effect (default 23:59:59). |
@@ -292,7 +292,7 @@ An individual `Rule` object is defined by the following fields:
292292
| Name | Description |
293293
| ------- | ------------------------------------------------------------------------------------------------------------- |
294294
| `count` | Fleet counts based on regions. Rule `minimum`/`maximum` refers to number of devices in [Rule Units](#rule-units). |
295-
| `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). |
295+
| `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). |
296296
| `speed` | Global or local speed limits. Rule `minimum`/`maximum` refers to speed in [Rule Units](#rule-units). |
297297
| `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.* |
298298
| `user` | Information for users, e.g. about helmet laws. Generally can't be enforced via events and telemetry. |
@@ -332,15 +332,22 @@ An individual `Rule` object is defined by the following fields:
332332

333333
[Top][toc]
334334

335-
### Rate Recurrences
335+
### Rates
336+
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.
336337

337-
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.
338+
#### Rate Amounts
339+
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).
338340

339-
| Name | Description |
340-
| --------- | ------------------- |
341-
| `once` | Rate is applied once to vehicles entering a matching status from a non-matching status. |
342-
| `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`. |
343-
| `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`. |
341+
#### Rate Recurrences
342+
343+
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.
344+
345+
| Name | Description |
346+
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
347+
| `once_on_match` | Rate is applied once when a vehicle transitions **into** a matching status from a non-matching status. |
348+
| `once_on_unmatch` | Rate is applied once a vehicle transitions **out of** a matching status to a non-matching status. |
349+
| `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`. |
350+
| `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`. |
344351

345352
[Top][toc]
346353

policy/examples/README.md

Lines changed: 131 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@ This file presents a series of example [Policy documents](../README.md#policy) f
44

55
## Table of Contents
66

7-
- [Prohibited Zone](#prohibited-zone)
8-
- [Provider Cap](#provider-cap)
9-
- [Idle Time](#idle-time)
10-
- [Speed Limits](#speed-limits)
11-
- [Per Trip Fees](#per-trip-fees)
12-
- [Vehicle Right of Way Fees](#vehicle-right-of-way-fees)
13-
- [Metered Parking Fees](#metered-parking-fees)
14-
- [Required Parking](#required-parking)
7+
- [Policy Examples](#policy-examples)
8+
- [Table of Contents](#table-of-contents)
9+
- [Prohibited Zone](#prohibited-zone)
10+
- [Provider Cap](#provider-cap)
11+
- [Idle Time](#idle-time)
12+
- [Speed Limits](#speed-limits)
13+
- [Per Trip Fees](#per-trip-fees)
14+
- [Vehicle Right of Way Fees](#vehicle-right-of-way-fees)
15+
- [Metered Parking Fees](#metered-parking-fees)
16+
- [Required Parking](#required-parking)
17+
- [Tiered Parking Fees Per Hour](#tiered-parking-fees-per-hour)
18+
- [Tiered Parking Fees Total](#tiered-parking-fees-total)
1519

1620
## Prohibited Zone
1721

@@ -445,5 +449,124 @@ File: [`required-parking.json`](required-parking.json)
445449
}
446450
```
447451

452+
## Tiered Parking Fees Per Hour
453+
This policy states parking fees as such:
454+
- Parking for the first hour costs $2
455+
- Parking for the second hour costs $4
456+
- Parking every hour onwards costs $10
457+
458+
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`
459+
File: [`tiered-parking-fees-per-hour.json`](tiered-parking-fees-per-hour.json)
460+
```
461+
{
462+
"name": "Tiered Dwell Time Example",
463+
"description": "First hour $2, second hour $4, every hour onwards $10",
464+
"policy_id": "2800cd0a-7827-4110-9713-b9e5bf29e9a1",
465+
"start_date": 1558389669540,
466+
"publish_date": 1558389669540,
467+
"end_date": null,
468+
"prev_policies": null,
469+
"provider_ids": [],
470+
"currency": "USD",
471+
"rules": [
472+
{
473+
"name": "> 2 hours",
474+
"rule_id": "9cd1768c-ab9e-484c-93f8-72a7078aa7b9",
475+
"rule_type": "time",
476+
"rule_units": "hours",
477+
"geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"],
478+
"statuses": { "available": [], "non_operational": [] },
479+
"vehicle_types": ["bicycle", "scooter"],
480+
"maximum": 2,
481+
"rate_amount": 1000,
482+
"rate_recurrence": "each_time_unit"
483+
},
484+
{
485+
"name": "1-2 Hours",
486+
"rule_id": "edd6a195-bb30-4eb5-a2cc-44e5a18798a2",
487+
"rule_type": "time",
488+
"rule_units": "hours",
489+
"geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"],
490+
"statuses": { "available": [], "non_operational": [] },
491+
"vehicle_types": ["bicycle", "scooter"],
492+
"maximum": 1,
493+
"rate_amount": 400,
494+
"rate_recurrence": "each_time_unit"
495+
},
496+
{
497+
"name": "0-1 Hour",
498+
"rule_id": "6b6fe61b-dbe5-4367-8e35-84fb14d23c54",
499+
"rule_type": "time",
500+
"rule_units": "hours",
501+
"geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"],
502+
"statuses": { "available": [], "non_operational": [] },
503+
"vehicle_types": ["bicycle", "scooter"],
504+
"maximum": 0,
505+
"rate_amount": 200,
506+
"rate_recurrence": "each_time_unit"
507+
}
508+
]
509+
}
510+
```
511+
512+
## Tiered Parking Fees Total
513+
This policy states parking fees as such:
514+
- If parked for less than an hour, $2 on exit
515+
- If parked for less than 2 hours, $4 on exit
516+
- If parked for any duration longer than 2 hours, $10 on exit
517+
518+
For example, if a vehicle is parked for 6.5 hours, it will be charged $10 on exit.
519+
File: [`tiered-parking-fees-total.json`](tiered-parking-fees-total.json)
520+
```
521+
{
522+
"name": "Tiered Dwell Time Example",
523+
"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",
524+
"policy_id": "2800cd0a-7827-4110-9713-b9e5bf29e9a1",
525+
"start_date": 1558389669540,
526+
"publish_date": 1558389669540,
527+
"end_date": null,
528+
"prev_policies": null,
529+
"provider_ids": [],
530+
"currency": "USD",
531+
"rules": [
532+
{
533+
"name": "> 2 hours",
534+
"rule_id": "9cd1768c-ab9e-484c-93f8-72a7078aa7b9",
535+
"rule_type": "time",
536+
"rule_units": "hours",
537+
"geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"],
538+
"statuses": { "available": [], "non_operational": [] },
539+
"vehicle_types": ["bicycle", "scooter"],
540+
"maximum": 2,
541+
"rate_amount": 1000,
542+
"rate_recurrence": "once_on_unmatch"
543+
},
544+
{
545+
"name": "1-2 Hours",
546+
"rule_id": "edd6a195-bb30-4eb5-a2cc-44e5a18798a2",
547+
"rule_type": "time",
548+
"rule_units": "hours",
549+
"geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"],
550+
"statuses": { "available": [], "non_operational": [] },
551+
"vehicle_types": ["bicycle", "scooter"],
552+
"maximum": 1,
553+
"rate_amount": 400,
554+
"rate_recurrence": "once_on_unmatch"
555+
},
556+
{
557+
"name": "0-1 Hour",
558+
"rule_id": "6b6fe61b-dbe5-4367-8e35-84fb14d23c54",
559+
"rule_type": "time",
560+
"rule_units": "hours",
561+
"geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"],
562+
"statuses": { "available": [], "non_operational": [] },
563+
"vehicle_types": ["bicycle", "scooter"],
564+
"maximum": 0,
565+
"rate_amount": 200,
566+
"rate_recurrence": "once_on_unmatch"
567+
}
568+
]
569+
}
570+
```
448571
[Top](#table-of-contents)
449572

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"updated": 0,
3+
"version": "1.2.0",
4+
"data": {
5+
"policy": [
6+
{
7+
"name": "Tiered Dwell Time Example",
8+
"description": "First hour $2, second hour $4, every hour onwards $10",
9+
"policy_id": "2800cd0a-7827-4110-9713-b9e5bf29e9a1",
10+
"start_date": 1558389669540,
11+
"publish_date": 1558389669540,
12+
"end_date": null,
13+
"prev_policies": null,
14+
"provider_ids": [],
15+
"currency": "USD",
16+
"rules": [
17+
{
18+
"name": "> 2 hours",
19+
"rule_id": "9cd1768c-ab9e-484c-93f8-72a7078aa7b9",
20+
"rule_type": "time",
21+
"rule_units": "hours",
22+
"geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"],
23+
"statuses": { "available": [], "non_operational": [] },
24+
"vehicle_types": ["bicycle", "scooter"],
25+
"maximum": 2,
26+
"rate_amount": 1000,
27+
"rate_recurrence": "each_time_unit"
28+
},
29+
{
30+
"name": "1-2 Hours",
31+
"rule_id": "edd6a195-bb30-4eb5-a2cc-44e5a18798a2",
32+
"rule_type": "time",
33+
"rule_units": "hours",
34+
"geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"],
35+
"statuses": { "available": [], "non_operational": [] },
36+
"vehicle_types": ["bicycle", "scooter"],
37+
"maximum": 1,
38+
"rate_amount": 400,
39+
"rate_recurrence": "each_time_unit"
40+
},
41+
{
42+
"name": "0-1 Hour",
43+
"rule_id": "6b6fe61b-dbe5-4367-8e35-84fb14d23c54",
44+
"rule_type": "time",
45+
"rule_units": "hours",
46+
"geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"],
47+
"statuses": { "available": [], "non_operational": [] },
48+
"vehicle_types": ["bicycle", "scooter"],
49+
"maximum": 0,
50+
"rate_amount": 200,
51+
"rate_recurrence": "each_time_unit"
52+
}
53+
]
54+
}
55+
]
56+
}
57+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"updated": 0,
3+
"version": "1.2.0",
4+
"data": {
5+
"policy": [
6+
{
7+
"name": "Tiered Dwell Time Example",
8+
"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",
9+
"policy_id": "2800cd0a-7827-4110-9713-b9e5bf29e9a1",
10+
"start_date": 1558389669540,
11+
"publish_date": 1558389669540,
12+
"end_date": null,
13+
"prev_policies": null,
14+
"provider_ids": [],
15+
"currency": "USD",
16+
"rules": [
17+
{
18+
"name": "> 2 hours",
19+
"rule_id": "9cd1768c-ab9e-484c-93f8-72a7078aa7b9",
20+
"rule_type": "time",
21+
"rule_units": "hours",
22+
"geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"],
23+
"statuses": { "available": [], "non_operational": [] },
24+
"vehicle_types": ["bicycle", "scooter"],
25+
"maximum": 2,
26+
"rate_amount": 1000,
27+
"rate_recurrence": "once_on_unmatch"
28+
},
29+
{
30+
"name": "1-2 Hours",
31+
"rule_id": "edd6a195-bb30-4eb5-a2cc-44e5a18798a2",
32+
"rule_type": "time",
33+
"rule_units": "hours",
34+
"geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"],
35+
"statuses": { "available": [], "non_operational": [] },
36+
"vehicle_types": ["bicycle", "scooter"],
37+
"maximum": 1,
38+
"rate_amount": 400,
39+
"rate_recurrence": "once_on_unmatch"
40+
},
41+
{
42+
"name": "0-1 Hour",
43+
"rule_id": "6b6fe61b-dbe5-4367-8e35-84fb14d23c54",
44+
"rule_type": "time",
45+
"rule_units": "hours",
46+
"geographies": ["0c77c813-bece-4e8a-84fd-f99af777d198"],
47+
"statuses": { "available": [], "non_operational": [] },
48+
"vehicle_types": ["bicycle", "scooter"],
49+
"maximum": 0,
50+
"rate_amount": 200,
51+
"rate_recurrence": "once_on_unmatch"
52+
}
53+
]
54+
}
55+
]
56+
}
57+
}

0 commit comments

Comments
 (0)