10.5.1 Overview
The Pricing function set provides the tariff structures communicated by the server and is designed to support a variety of tariff types, including:
Flat-rate pricing
Time-of-use tiers
Consumption blocks
Hourly day-ahead pricing
Real-time pricing
Combinations of the above
The Pricing function set supports application-specific tariffs for devices (e.g., PEV, DER), and special event-based prices like critical peak price (note, as per the supplemental material of IEEE Std 2030.5, critical peak pricing (CPP) is treated as just another TOU tier).
The Pricing function set is designed to stand on its own but can be paired with the Metering, Billing, and Prepayment function sets to provide additional benefit to users. The Pricing function set is not intended to provide all the information necessary to represent a premises’s bill.
10.5.2 List ordering
Table 42 —Pricing list ordering
Resource name | Primary key | Secondary key | Tertiary key |
TariffProfile | mRID (descending) | N/A | N/A |
RateComponent | mRID (descending) | N/A | N/A |
TimeTariffInterval and ActiveTimeTariffInterval | interval.start (ascending) | creationTime (descending) | mRID (descending) |
ConsumptionTariffInterval | startValue (ascending) | N/A | N/A |
10.5.3 Application guidelines/behavior
10.5.3.1 TariffProfile
Pricing servers SHALL be capable of internally storing and supporting at least one TariffProfile instance. Pricing clients SHALL be capable of internally storing and supporting at least one TariffProfile instance.
Pricing servers SHOULD be capable of internally storing and supporting at least three TariffProfile instances (e.g., multiple commodities, multiple service provider tariff options).
Pricing clients SHOULD be capable of internally storing and supporting at least three TariffProfile instances (e.g., multiple commodities, multiple service provider tariff options).
10.5.3.2 Rate component
Pricing servers SHALL support at least two RateComponent instances for each TariffProfile.
Pricing clients SHALL support at least one RateComponent instance for each TariffProfile. Pricing clients supporting the use of this resource SHOULD support at least two instances of RateComponent (e.g., to convey prices for forward energy [consumed by premises] and reverse energy [supplied by premises]).
10.5.3.3 TimeTariffInterval
Rates that do not contain time-differentiated characteristics SHALL create one TimeTariffInterval instance with a DateTimeInterval of sufficient duration to cover at least the next 24 hours or use the maximum time value for duration to minimize data transmission.
Pricing servers SHALL support at least two TimeTariffInterval instances per RateComponent instance (e.g., the active and subsequent TimeTariffInterval instance for a RateComponent).
Pricing servers SHOULD support at least 48 TimeTariffInterval instances for at least one RateComponent instance.
Pricing servers SHALL provide at most one active TimeTariffInterval per rate component. TimeTariffIntervals are to be scheduled for each occurrence of a TOU. A given day would have a flow of TimeTariffIntervals for the TOU rates for that day. A particular TimeTariffInterval instance specifies the touTier that is in effect during that event’s effective time period.
Pricing clients, upon detecting multiple active TimeTariffIntervals, SHALL ignore all but the TimeTariffInterval with the highest creation time. If this is insufficient to determine a unique active TimeTariffInterval (e.g., two active instances exist with the same creation time), clients SHALL operate as if there is no TimeTariffInterval defined for the given time period.
Pricing clients SHALL be capable of internally storing and supporting at least two TimeTariffInterval instances per RateComponent instance.
Pricing clients SHOULD be capable of internally storing and supporting at least five TimeTariffInterval instances per RateComponent instance.
The series of TimeTariffInterval instances on a server may contain gaps or breaks where pricing information is not defined for some time period. This may occur for various reasons, such as when private information is cleared from the server (e.g., during move-out) or potentially when superseding TimeTariffIntervals are created by the service provider (however, service providers should take care to ensure that gaps are not created, by creating additional TimeTariffInterval instances if necessary). The below guidelines promote common pricing client behavior and reduce the chances of different implementations displaying different cost information to a user in the event pricing information is unavailable during a particular period. This could cause users to question the reliability of the data. Rules for handling these gaps are as follows:
If a pricing client displays the active or scheduled price or calculated instantaneous cost data to the user, the client SHALL indicate the presence of an unexpected issue with the price data.
If a pricing client displays calculated running or averaged cost data to the user, the client MAY continue to display values by excluding the time periods where no price is defined. However, the
client SHALL also indicate the presence of an unexpected issue with the price data for as long as there are price gaps during the time period the client uses to calculate these values.
Pricing clients SHALL NOT default to any hardcoded price attribute (e.g., $0) or use a price attribute from another (past/future) TimeTariffInterval for display or calculation. If a pricing client displays human-readable pricing information, then they SHALL display a non-numerical indicator (e.g., “XX,” dashes, “NA”).
If the pricing server later makes TimeTariffInterval instances available to fill pricing gaps, pricing clients that display calculated cost information MAY recalculate past cost data based on the new information.
Pricing clients that are price responsive SHOULD return to normal operational mode (that is, the default behavior of the device without any price responsiveness) during time periods where no TimeTariffInterval instance is defined. These clients SHOULD provide some Notification to the user that the active TimeTariffInterval instance price information is unknown.
The ActiveTimeTariffIntervalList only filters out inactive TimeTariffInterval instances; this SHALL NOT filter out ConsumptionTariffInterval instances. That is, if a client GETs a TimeTariffInterval from a server’s ActiveTimeTariffIntervalList, the ConsumptionTariffIntervalList pointed to by that TimeTariffInterval’s ConsumptionTariffIntervalListLink SHALL contain all ConsumptionTariffInterval instances (equal to the number of consumption blocks defined in the ReadingType), not just the one active ConsumptionTariffInterval instance.
10.5.3.4 Interval
While strongly RECOMMENDED, Pricing clients are NOT REQUIRED to follow the sign of randomization for Pricing function set messages. However, Pricing clients SHALL observe the absolute value of the randomizeDuration or randomizeStart value for the randomization range when calculating the randomization value. This allows more capable price clients to look ahead at scheduled prices (if available) and, using knowledge of the client’s operating characteristics, determine if it is in the customer’s best interest to react to the event earlier or later.
If, while a price-responsive client is acting upon a TimeTariffInterval, that TimeTariffInterval is cancelled, the client SHALL observe the randomizeDuration value when ceasing action.
10.5.3.5 ConsumptionTariffInterval | |||||
Pricing servers SHALL be capable of internally storing ConsumptionTariffInterval element per TimeTariffInterval instance. | and | supporting | at | least | one |
Pricing servers SHOULD be capable of internally storing ConsumptionTariffInterval elements per TimeTariffInterval instance. | and | supporting | at | least | five |
Pricing clients SHOULD be capable of internally storing ConsumptionTariffInterval elements per TimeTariffInterval instance. | and | supporting | at | least | five |
A particular TimeTariffInterval instance MAY NOT include a ConsumptionTariffIntervalListLink, meaning that ConsumptionTariffIntervals (and therefore the actual price) are not available for that TimeTariffInterval. In such a case, price-responsive clients would be unable to act upon price; however, they MAY be price responsive to the touTier value (if present) in the TimeTariffInterval.
10.5.3.6 Sleepy devices/polling clients
It is RECOMMENDED that sleepy pricing client devices send requests to the pricing server on a periodic basis. The RECOMMENDED time period for the periodic poll (for sleepy devices or other clients that do not, or are unable to, make use of Subscriptions) is no more than once per hour, but at least once per 24- hour period. This ensures the client a high likelihood of receiving the pricing information needed to manage its operations in a timely fashion while respecting limited network resources.
It is RECOMMENDED that polling pricing client devices request updated information for pending TimeTariffInterval instances just prior to those TimeTariffInterval instances becoming active (e.g., 5 minutes to 10 minutes prior, including any negative randomizeStart). This ensures the TimeTariffInterval instance previously retrieved is still valid and accurate with the latest instance on the server.
10.5.3.7 Deployments with multiple pricing servers
For the purposes of price responsiveness, clients SHOULD only follow one pricing server in the HAN per commodity. Pricing clients MAY follow multiple Pricing servers for informational display purposes (e.g., to compare different providers) or price-seeking behavior. More sophisticated devices (e.g., premises energy management systems) MAY follow multiple Pricing servers and make policy-based decisions to dispatch local resources (e.g., distributed energy resources) and/or provide a single Pricing server for clients it controls based on user preferences.
Registered pricing devices SHALL determine their primary Pricing server via Function Set Assignments and follow it for the purposes of price responsiveness. It is incumbent upon the user to choose the Pricing server with which to register the device. Pricing devices SHALL periodically perform service discovery to find new pricing servers with which it is registered and begin following them for the purposes of price responsiveness. Pricing clients SHALL unsubscribe or discontinue following the previous Pricing server for the purposes of price responsiveness. In addition to periodic discovery of new Pricing servers, it is RECOMMENDED that devices allow a means of de-registration (or return to defaults) so the device can be manually de-registered and not require the periodic polling time. If a client is not registered to any Pricing server, the client SHALL use the Primacy value of any discovered public Pricing servers for the commodity or commodities of interest.
When devices are registered to a Pricing server, they SHALL not act upon any “public” pricing servers that are present in the HAN or become available.
10.5.3.8 Relative pricing between tiers and blocks
Pricing servers using multiple TOU tiers SHALL associate higher prices with higher touTier values. That is, the price of any (TOU Tier N, Consumption Block M) SHALL be less than or equal to the price of (TOU Tier N + 1, Consumption Block M). Note that this is only valid for comparing the same consumptionBlock between two TOU tiers. Servers MAY be configured such that one or more consumptionBlock prices from TOU tier N are greater than one or more consumptionBlock prices from TOU tier N + 1.
Similarly, there is no restriction regarding the relative prices between consumptionBlock prices within the same TOU tier. That is, within one TOU tier, the price of consumptionBlock N MAY be greater than the price of consumptionBlock N + 1.
10.5.3.9 Price responsiveness
Servers that also support EndDevice instances MAY include price-response thresholds for a particular end device. This provides a standard mechanism for end devices without user interfaces to receive configuration data concerning customer preferences for price responsiveness. Servers MAY provide a unique PriceResponseCfg resource for each RateComponent resource that server hosts.
Pricing clients that are registered to a particular Pricing program and are acting upon a particular RateComponent SHOULD check their PriceResponseCfgList for a PriceResponseCfg resource corresponding to the RateComponent. If a matching PriceResponseCfg is present, pricing clients SHOULD consume the associated commodity when the price is less than the consumeThreshold value (typically used for scenarios such as negative pricing, pre-heating/cooling, and battery charging), and SHOULD reduce consumption to the maximum extent possible when the price is above the maxReductionThreshold value.
PriceResponseCfg servers SHALL NOT specify a consumeThreshold that is greater than or equal to the maxReductionThreshold. If a pricing client reads a PriceResponseCfg instance where the consumeThreshold is greater than or equal to the maxReductionThreshold, the client SHALL ignore the erroneous PriceResponseCfg instance.
10.5.4 LogEvents
Table 43 —Pricing LogEvents
LogEvent name | LogEvent code | LogEvent description |
TP_NO_TTI | 0x00 | SHOULD be generated by a Pricing client when there is a gap between two TimeTariffInterval instances or if a TimeTariffInterval instance completes and is not followed by another. |