Open Water Rate Specification
This repository documents the Open Water Rate Specification (OWRS), a machine-readable format for specifying and sharing water rate information.
OWRS is designed for analysts, economists, and software developers interested in analyzing water rates. OWRS attempts to fully encode a water utility's rate structure and pricing schedules in a form that is easy to store, share, modify and apply programmatically.
Table of Contents
- Why a Standard for Sharing Water Rates?
- Getting Started
- Full Utility Examples
Please see the CONTRIBUTING file for details.
Anyone familiar with water rates is likely familiar with the PDF documents, HTML tables and images generally used to present water pricing information to the public. These formats are useful because they provide a concise representation that is easy for people to understand. However, these formats are often not ideal for analysts, consultants, economists or others interested in analyzing water prices for several reasons:
HTML tables may be easy for customers to understand but they are difficult for computer code to understand and usually must be manually translated into code before a rate analysis can be performed.
Sometimes the exact formulas used to calculate a water bill are not explicitly defined.
PDF and HTML formats are more difficult to store, transmit and interpret than plain text.
OWRS attempts to overcome these downsides by specifying a plain text format to fully specify a water rate structure. Specifically:
OWRS is based on YAML, and as such it is designed to be easy to store, transmit, and parse in any programming language while also being easy for humans to read.
All the details stating how to calculate a customer bill, including formulas and conditional charges are specified in a single flat file.
Machine-readability sounds nice on paper, but the real benefit of this standard is in all of the tools that it enables.
RateParser is an R package that has the ability to interpret OWRS files and calculate water bills. The package is designed to simplify the work of analysts and economists interested in calculating water bills under a variety of rate structures.
In the future, this standard will form the foundation for a comprehensive database of water price information, similar in nature to the Utility Rate Database in the energy sector. When combined with customer billing data (like that centralized through the CaDC), this will enable a detailed, inter-utility analysis of revenue stability and water price equity.
Perhaps the best way to demonstrate how OWRS specifies a water rate is through an example. Let's consider the simplest possible OWRS file, representing a simple flat rate structure.
--- metadata: effective_date: 2016-01-01 utility_name: "Example Water District" bill_frequency: monthly rate_structure: RESIDENTIAL_SINGLE: flat_rate: 2.1 commodity_charge: flat_rate*usage_ccf bill: commodity_charge
yaml file format works by specifying a series of keys and values. In the example above,
bill_frequency is a key and
monthly is the value corresponding to that key. This key-value pair is itself a value of the
metadata is used to specify information about the rate structure that is not actualy used to calculate bills, such as the name of the utility and the date the rate structure went into effect.
rate_structure specifies information that is actually used for calculating water bills. The values of the
rate_structure key are the customer classes used to define rates. In our examples we use the standard classes defined by the CaDC:
In Example 1 above, we see a rate structure defined only for single-family residential customers, where the commodity charge is calculated as
flat_rate is 2.1, so the whole expression represents $2.1 per CCF of water used. In this case
usage_ccf is the data column name used to represent water usage. The total bill (
bill) for each customer is then equal to just the commodity charge.
--- metadata: ... rate_structure: RESIDENTIAL_SINGLE: service_charge: 14.65 flat_rate: 2.1 commodity_charge: flat_rate*usage_ccf bill: commodity_charge+service_charge
This second example extends Example 1 by adding a fixed service charge. Note that
bill is now calculated as the sum of
--- metadata: ... rate_structure: RESIDENTIAL_SINGLE: service_charge: depends_on: meter_size values: 3/4": 14.65 1" : 16.77 2" : 25.83 flat_rate: 2.1 commodity_charge: flat_rate*usage_ccf bill: commodity_charge+service_charge
Examples 1 & 2 above are composed entirely of simple parts, referred to in this context as Fields (e.g.
flat_rate: 2.1) or Formulas (e.g.
bill: commodity_charge+service_charge). However, often in real settings is it useful to have rate components that change for each customer. The canonical example is of a fixed service charge that depends on the size of the water meter used by each account (often referred to as a "meter charge").
Example 3 is almost the same as Example 2, but the fixed service charge now changes depending on the size of the meter. It is important to ensure that when the OWRS file is used to calculate water bills (e.g. with the RateParser package), that the values specified in
values ('3/4"', '1"', etc) are exactly the same as those that appear in the billing data set under the
--- metadata: ... rate_structure: RESIDENTIAL_SINGLE: service_charge: depends_on: meter_size values: 3/4": 14.65 1" : 16.77 2" : 25.83 tier_starts: - 0 - 15 - 41 - 149 tier_prices: - 2.87 - 4.29 - 6.44 - 10.07 commodity_charge: Tiered bill: commodity_charge+service_charge
Example 4 replaces the flat rate structure of earlier examples with an Increasing Block Rate, or "Tiered" rate structure. This pricing scheme is encoded using two new fields.
tier_startsrepresents the lower end of each block. It is the first unit of water billed at a specified price.
tier_pricesspecifies the price of water within each tier, in dollars per billing unit.
In Exampe 4, we can see that the first through the 14th units of water are billed at $2.87 per unit. The 15th through the 40th unit are billed at $4.29. The 41st through the 148th at $6.44. Finally all water use from the 149th unit and up is billed at $10.07 per unit.
In this case, the
commodity_charge field must be set as "Tiered" in order to specify how the tier starts are interpreted.
OWRS also accomodates budget/allocation based rates, although the complexity of the file must rise to match the complexity of the rate structure.
--- metadata: ... rate_structure: RESIDENTIAL_SINGLE: service_charge: depends_on: meter_size values: 3/4": 14.65 1" : 16.77 2" : 25.83 gpcd: 60 landscape_factor: 0.7 days_in_period: 30.4 indoor: "gpcd*hhsize*days_in_period*(1/748)" outdoor: "landscape_factor*et_amount*irr_area*0.62*(1/748)" budget: "indoor+outdoor" tier_starts: - 0 - indoor - 100% - 133% tier_prices: - 2.87 - 4.29 - 6.44 - 10.07 commodity_charge: Budget bill: commodity_charge+service_charge
Example 5 shows how to specify single-family rates under a budget based rate structure. There a several new fields and formulas in this example:
days_in_periodare all simple fields that are the same across all SFR customers. - Note that if
days_in_periodwere not defined here as 30.4 (average number of days in a month) then it would be expected that the user defines this as a data column and this value could change to reflect the actual number of days in each customer's billing period.
et_amountare expected to be provided as data columns.
budgetrepresent the calculated indoor allocation, outdoor allocation, and total water budget, respectively.
commodity_charge is specified as "Budget", OWRS parsers interpret
tier_starts differently. As is visible in this example, tier starts may be specified either as flat values in terms of billing units (as in Example 4) or they can be specified as a percentage of the
budget field. This allows OWRS to accomodate different tier widths for each account based on data specific to that account.
The examples above cover the vast majority of use cases, but there are still a few that have not yet been discussed. Fortunately the OWRS framework is extremely flexible. For example:
Tiers that depend on other values
--- tier_starts: depends_on: meter_size values: 5/8": - 0 - 211 1_1/2": - 0 - 466 2": - 0 - 871
Tiers that depend on multiple other values
For example, LADWP's tiers depend on season, lot size, and temperature zone
--- tier_starts: depends_on: - season - lot_size_group - temperature_zone values: Winter|1|Low: - 0 - 17 - 23 - 35 Summer|1|Low: - 0 - 17 - 29 - 53 Summer|1|Medium: - 0 - 17 - 31 - 59 Summer|1|High: ...
In this case each combination is enumerated as "value1|value2|...|valueN", where the values appear in the order they are given in the
depends_on field. This format is not quite as visually appealing as a table, but it provides easy processing for OWRS parsers.
One somewhat common use case is for utilities with budget based rates to set their CII allocations as a rolling average of historical water use for a given month. Unfortunatley this functionality is not supported by current OWRS parsers, but there is a work-around. Instead of being computed in the parser, allocations for CII customers can be precomputed and saved as a data column (e.g.
cii_allocation). This column could then be referenced in the OWRS file as
--- budget: cii_allocation tier_starts: ... tier_prices: ... commmodity_charge: Budget ...
See the examples from California in this repository for examples of full utility rate structures in OWRS format.