diff --git a/docs/_data/components/schemas/array-max-monitored-elements.yaml b/docs/_data/components/schemas/array-max-monitored-elements.yaml index f3a5c554..8fca3ee7 100644 --- a/docs/_data/components/schemas/array-max-monitored-elements.yaml +++ b/docs/_data/components/schemas/array-max-monitored-elements.yaml @@ -1,4 +1,4 @@ -forecast-limits-snapshot: +forecast-limits-snapshot: &forecast-limit-snapshot type: object description: A snapshot of the forecast for a monitoring set. properties: @@ -11,17 +11,27 @@ forecast-limits-snapshot: description: Set of forecast limits items: $ref: 'array-max-forecast-periods.yaml#/forecast-limit-item' + required: + - snapshot-header + - limits -forecast-limits-slim-snapshot: - type: object - description: A snapshot of the forecast for a monitoring set. - properties: +forecast-limits-snapshot-slim: + <<: *forecast-limit-snapshot + description: A slim snapshot of the forecast for a monitoring set. + properties: &forecast-limit-snapshot-slim-props snapshot-header: $ref: ./headers.yaml#/forecast-snapshot-slim-header limits: <<: *max items: $ref: 'array-max-forecast-periods.yaml#/resource-forecast-proposal-slim' +forecast-limits-snapshot-slim-inputs-used: + <<: *forecast-limit-snapshot + description: | + A slim snapshot of the forecast for a monitoring set, including the inputs + that were used to determine the continuous limits. + properties: + <<: *forecast-limit-snapshot-slim-props inputs-used: &inputs-used-slim description: | @@ -64,20 +74,24 @@ forecast-limits-slim-snapshot: - name - values - unit - required: - - snapshot-header - - limits -forecast-limits-detailed-snapshot: - type: object +forecast-limits-snapshot-elide-psr: + <<: *forecast-limit-snapshot + properties: + snapshot-header: + $ref: ./headers.yaml#/forecast-snapshot-header-elide-psr + limits: *max + +forecast-limits-detailed-snapshot-elide-psr: &forecast-limit-detailed + <<: *forecast-limit-snapshot description: | A detailed snapshot of the forecast for a monitoring set. These details are meant to support analysis, archival, and troubleshooting. - properties: + properties: &forecast-limit-detailed-props snapshot-header: - $ref: ./headers.yaml#/forecast-snapshot-header + $ref: ./headers.yaml#/forecast-snapshot-header-elide-psr limits: <<: *max description: Forecast including provenance information. @@ -87,6 +101,13 @@ forecast-limits-detailed-snapshot: - snapshot-header - limits +forecast-limits-detailed-snapshot: + <<: *forecast-limit-detailed + properties: + <<: *forecast-limit-detailed-props + snapshot-header: + $ref: ./headers.yaml#/forecast-snapshot-header + named-power-system-resources: &psr <<: *max description: Collection of power system resource names @@ -248,10 +269,10 @@ real-time-proposal-status: - invalid-proposal-count - proposal-validation-errors -realtime-limits-snapshot: +realtime-limits-snapshot: &realtime-limit-snapshot type: object description: A snapshot of the realtime limits for a monitoring set. - properties: + properties: &realtime-limit-snapshot-props snapshot-header: $ref: ./headers.yaml#/real-time-snapshot-header limits: @@ -259,30 +280,28 @@ realtime-limits-snapshot: description: Real-time limits items: $ref: './realtime-limit-item.yaml#/normal' - -realtime-limits-detailed-snapshot: - type: object - description: A snapshot of the realtime limits for a monitoring set. - properties: - snapshot-header: - $ref: ./headers.yaml#/real-time-snapshot-header - limits: - <<: *max - description: Real-time limits including provenance. - items: - $ref: './realtime-limit-item.yaml#/detailed' + required: + - snapshot-header + - limits realtime-limits-snapshot-slim: - type: object - description: A snapshot of the realtime limits for a monitoring set. - properties: - snapshot-header: - $ref: ./headers.yaml#/real-time-snapshot-header + <<: *realtime-limit-snapshot + description: A slim snapshot of the realtime limits for a monitoring set. + properties: &realtime-limit-snapshot-slim-props + <<: *realtime-limit-snapshot-props limits: <<: *max description: Real-time limits items: $ref: 'array-max-emergency-ratings.yaml#/slim' + +realtime-limits-snapshot-slim-inputs-used: + <<: *realtime-limit-snapshot + description: | + A slim snapshot of the realtime limits for a monitoring set, including the + inputs used to determine the continuous limits. + properties: + <<: *realtime-limit-snapshot-slim-props inputs-used: <<: *inputs-used-slim items: @@ -302,10 +321,37 @@ realtime-limits-snapshot-slim: type: number format: float nullable: true - required: - snapshot-header - limits + - inputs-used + +realtime-limits-snapshot-elide-psr: + <<: *realtime-limit-snapshot + properties: + <<: *realtime-limit-snapshot-props + snapshot-header: + $ref: ./headers.yaml#/real-time-snapshot-header-elide-psr + +realtime-limits-detailed-snapshot-elide-psr: + <<: *realtime-limit-snapshot + description: A snapshot of the realtime limits for a monitoring set. + properties: + snapshot-header: + $ref: ./headers.yaml#/real-time-snapshot-header-elide-psr + limits: + <<: *max + description: Real-time limits including provenance. + items: + $ref: './realtime-limit-item.yaml#/detailed' + +realtime-limits-detailed-snapshot: + <<: *realtime-limit-snapshot + description: A snapshot of the realtime limits for a monitoring set. + properties: + <<: *realtime-limit-snapshot-props + limits: + $ref: "#/realtime-limits-detailed-snapshot-elide-psr/properties/limits" realtime-proposal: type: object @@ -432,26 +478,41 @@ seasonal-ratings-proposal-status: - incomplete-obligation-count - invalid-proposal-count -seasonal-ratings-snapshot: +seasonal-ratings-snapshot: &seasonal-rating-snapshot type: object description: A snapshot of the seasonal ratings for a monitoring set. - properties: &seasonal-rating-snapshot-props + properties: snapshot-header: $ref: ./headers.yaml#/common-header ratings: <<: *max items: $ref: ./array-max-seasons.yaml#/seasonal-rating-snapshot-item + required: + - snapshot-header + - ratings + seasonal-ratings-snapshot-detailed: + <<: *seasonal-rating-snapshot description: A snapshot of the seasonal ratings for a monitoring set. properties: - <<: *seasonal-rating-snapshot-props + snapshot-header: + $ref: ./headers.yaml#/common-header ratings: <<: *max items: $ref: ./array-max-seasons.yaml#/seasonal-rating-snapshot-item-detailed +seasonal-ratings-snapshot-detailed-elide-psr: + <<: *seasonal-rating-snapshot + description: A snapshot of the seasonal ratings for a monitoring set. + properties: + snapshot-header: + $ref: ./headers.yaml#/base-header + ratings: + $ref: "#/seasonal-ratings-snapshot-detailed/properties/ratings" + temporary-aar-exception-set: type: array minItems: 0 diff --git a/docs/_data/components/schemas/headers.yaml b/docs/_data/components/schemas/headers.yaml index b3904ac6..193722d9 100644 --- a/docs/_data/components/schemas/headers.yaml +++ b/docs/_data/components/schemas/headers.yaml @@ -1,22 +1,27 @@ -common-header: &common-header +base-header: &base-header type: object - - properties: &common-header-props + properties: &base-header-props source: $ref: ./data-provenance.yaml - default-emergency-durations: $ref: ./array-max-emergency-durations.yaml#/emergency-durations - power-system-resources: - $ref: ./array-max-monitored-elements.yaml#/named-power-system-resources default-limiting-analysis: $ref: ./limiting-analysis.yaml + additionalProperties: false + required: + - source + - default-emergency-durations +common-header: &common-header + <<: *base-header + properties: &common-header-props + <<: *base-header-props + power-system-resources: + $ref: ./array-max-monitored-elements.yaml#/named-power-system-resources required: - source - default-emergency-durations - power-system-resources - additionalProperties: false real-time-proposal-header: &forecast-proposal-header <<: *common-header @@ -88,10 +93,12 @@ forecast-proposal-slim-header: - default-emergency-durations - power-system-resources -forecast-snapshot-header: &forecast-snapshot-header - description: Details about the snapshot provided by the Clearinghouse provider. - properties: &forecast-snapshot-header-props - <<: *common-header-props +forecast-snapshot-header-elide-psr: + description: | + Details about the snapshot provided by the Clearinghouse provider. The + `power-system-resources` property is omitted from this header. + properties: &forecast-snapshot-header-elide-psr-props + <<: *base-header-props begins: <<: *begins description: | @@ -99,6 +106,21 @@ forecast-snapshot-header: &forecast-snapshot-header RFC 3339 date-time string with *no fractional seconds component* that Nominates the operational window of this snapshot. + source: + $ref: ./data-provenance.yaml + default-emergency-durations: + $ref: ./array-max-emergency-durations.yaml#/emergency-durations + required: + - begins + - source + - default-emergency-durations + +forecast-snapshot-header: &forecast-snapshot-header + description: Details about the snapshot provided by the Clearinghouse provider. + properties: &forecast-snapshot-header-props + <<: *forecast-snapshot-header-elide-psr-props + power-system-resources: + $ref: ./array-max-monitored-elements.yaml#/named-power-system-resources required: - begins - source @@ -124,13 +146,13 @@ forecast-snapshot-slim-header: - power-system-resources - default-emergency-durations +real-time-snapshot-header-elide-psr: + <<: *base-header + description: Details about the snapshot provided by the Clearinghouse provider. + real-time-snapshot-header: + <<: *common-header description: Details about the snapshot provided by the Clearinghouse provider. - properties: - <<: *common-header-props - required: - - source - - power-system-resources seasonal-proposal-header: <<: *common-header @@ -155,9 +177,8 @@ seasonal-proposal-header-slim: Defines the seasonal schedule that is used in the proposal. Each season is defined in the `schedule` array and the `ends` property defines the - end of the last season. - - Each individual facility proposal must have + end of the last season. Each individual facility proposal must have + corresponding entry for each entry In the `schedule` array. properties: schedule: diff --git a/docs/_data/components/schemas/limit.yaml b/docs/_data/components/schemas/limit.yaml index e0c8be5a..6f144afd 100644 --- a/docs/_data/components/schemas/limit.yaml +++ b/docs/_data/components/schemas/limit.yaml @@ -10,6 +10,21 @@ description: | `application/problem+json` response if they receive a proposal in an unsupported but valid limit type as defined here. + When used as the media type parameter `limit-type`, these are nominated by + the following names. + + * `active-power` + * `active-power-with-power-factor` + * `apparent-power` + * `current` + * `current-with-kV` + * `reactive-power` + * `overvoltage-threshold-pu` + * `overvoltage-threshold` + * `undervoltage-threshold-pu` + * `undervoltage-threshold` + + oneOf: - $ref: './limit-types/active-power.yaml' - $ref: './limit-types/active-power-with-power-factor.yaml' diff --git a/docs/_data/paths/limits_forecast-snapshot.yaml b/docs/_data/paths/limits_forecast-snapshot.yaml index 382c38f9..61e73235 100644 --- a/docs/_data/paths/limits_forecast-snapshot.yaml +++ b/docs/_data/paths/limits_forecast-snapshot.yaml @@ -23,6 +23,29 @@ current: requested, which also references the source proposals used to generate the snapshot, as well as reporting data from the ratings clearing process. + The `application/vnd.trolie.forecast-limits-snapshot.v1+json` and + `application/vnd.trolie.forecast-limits-detailed-snapshot.v1+json` media + types support the `include-psr-header` parameter. This is a boolean + parameter that defaults to `true`. When set to `false`, the + `power-system-resource` header is omitted. This can result in smaller + payloads when the client already knows the resource ids in use by the + Clearinghouse Provider. + ```http + GET /limits/forecast-snapshot HTTP/1.1 + Accept: application/vnd.trolie.forecast-limits-detailed-snapshot.v1+json; include-psr-header=false + ``` + + Additionally, the `application/vnd.trolie.forecast-limits-snapshot-slim.v1+json` + media type may be used to request a more concise representation of the data. + The media type parameter `limit-type` is required to specify the type of limit + being requested. For example, + ```http + GET /limits/forecast-snapshot HTTP/1.1 + Accept: application/vnd.trolie.forecast-limits-snapshot-slim.v1+json; limit-type=apparent-power + ``` + Note this format is much more concise but requires significant care in processing. + See [Using Slim Media Types](../example-narratives/using-slim-media-types) for more details. + Clients SHOULD perform Conditional `GET` using the `If-None-Match` header and the `ETag` of a previous `GET` response to poll this endpoint. Rate limiting is done on a per Ratings Provider basis, so requests from @@ -33,20 +56,35 @@ current: description: The requested operating forecast snapshot is returned. content: application/vnd.trolie.forecast-limits-snapshot.v1+json: + schema: + $ref: "../components/schemas/array-max-monitored-elements.yaml#/forecast-limits-snapshot-elide-psr" + example: + $ref: '../../example-narratives/examples/forecast-limits-elide-psr.json' + application/vnd.trolie.forecast-limits-snapshot.v1+json; include-psr-header=false: schema: $ref: "../components/schemas/array-max-monitored-elements.yaml#/forecast-limits-snapshot" example: $ref: '../../example-narratives/examples/forecast-limits.json' - application/vnd.trolie.forecast-limits-slim-snapshot.v1+json: + application/vnd.trolie.forecast-limits-snapshot-slim.v1+json; limit-type=apparent-power: schema: - $ref: "../components/schemas/array-max-monitored-elements.yaml#/forecast-limits-slim-snapshot" + $ref: "../components/schemas/array-max-monitored-elements.yaml#/forecast-limits-snapshot-slim" example: $ref: '../../example-narratives/examples/forecast-limits-slim-active-power.json' + application/vnd.trolie.forecast-limits-snapshot-slim.v1+json; limit-type=apparent-power, inputs-used=true: + schema: + $ref: "../components/schemas/array-max-monitored-elements.yaml#/forecast-limits-snapshot-slim-inputs-used" + example: + $ref: '../../example-narratives/examples/forecast-limits-slim-active-power-dry-bulb.json' application/vnd.trolie.forecast-limits-detailed-snapshot.v1+json: schema: $ref: "../components/schemas/array-max-monitored-elements.yaml#/forecast-limits-detailed-snapshot" example: $ref: "../../example-narratives/examples/forecast-limits-detailed.json" + application/vnd.trolie.forecast-limits-detailed-snapshot.v1+json; include-psr-header=false: + schema: + $ref: "../components/schemas/array-max-monitored-elements.yaml#/forecast-limits-detailed-snapshot-elide-psr" + example: + $ref: "../../example-narratives/examples/forecast-limits-detailed-elide-names-header.json" headers: $ref: '../openapi-split.yaml#/components/responses/204/headers' '304': diff --git a/docs/_data/paths/limits_realtime-snapshot.yaml b/docs/_data/paths/limits_realtime-snapshot.yaml index cb80e8ec..12cfc8a1 100644 --- a/docs/_data/paths/limits_realtime-snapshot.yaml +++ b/docs/_data/paths/limits_realtime-snapshot.yaml @@ -25,16 +25,31 @@ global: $ref: "../components/schemas/array-max-monitored-elements.yaml#/realtime-limits-snapshot" example: $ref: '../../example-narratives/examples/realtime-limit-set.json' + application/vnd.trolie.realtime-limits-snapshot.v1+json; include-psr-header=false: + schema: + $ref: "../components/schemas/array-max-monitored-elements.yaml#/realtime-limits-snapshot-elide-psr" + example: + $ref: '../../example-narratives/examples/realtime-limit-set-elide-psr.json' application/vnd.trolie.realtime-limits-detailed-snapshot.v1+json: schema: $ref: "../components/schemas/array-max-monitored-elements.yaml#/realtime-limits-detailed-snapshot" example: $ref: '../../example-narratives/examples/realtime-limit-set-detailed.json' - application/vnd.trolie.realtime-limits-snapshot-slim.v1+json: + application/vnd.trolie.realtime-limits-detailed-snapshot.v1+json; include-psr-header=false: + schema: + $ref: "../components/schemas/array-max-monitored-elements.yaml#/realtime-limits-detailed-snapshot-elide-psr" + example: + $ref: '../../example-narratives/examples/realtime-limit-set-detailed-elide-psr.json' + application/vnd.trolie.realtime-limits-snapshot-slim.v1+json; limit-type=apparent-power: schema: $ref: "../components/schemas/array-max-monitored-elements.yaml#/realtime-limits-snapshot-slim" example: $ref: '../../example-narratives/examples/realtime-limit-set-slim.json' + application/vnd.trolie.realtime-limits-snapshot-slim.v1+json; limit-type=apparent-power; inputs-used=true: + schema: + $ref: "../components/schemas/array-max-monitored-elements.yaml#/realtime-limits-snapshot-slim-inputs-used" + example: + $ref: '../../example-narratives/examples/realtime-limit-set-slim-dry-bulb.json' headers: $ref: '../openapi-split.yaml#/components/responses/204/headers' '304': diff --git a/docs/_data/paths/rating-proposals_forecasts.yaml b/docs/_data/paths/rating-proposals_forecasts.yaml index dfde94ef..7bdde2a7 100644 --- a/docs/_data/paths/rating-proposals_forecasts.yaml +++ b/docs/_data/paths/rating-proposals_forecasts.yaml @@ -75,6 +75,24 @@ patch: leveraged to split a large proposal into one or more parts in cases where that is advantageous from a performance or reliable delivery perspective. + + There are two supported media types for a Real-Time Ratings proposals. + + `application/vnd.trolie.rating-forecast-proposal.v1+json` allows the + Ratings Provider to combine different limit types, such as + `apparent-power` (MVA) and `current` (MW), in a single proposal. + + `application/vnd.trolie.rating-forecast-proposal-slim.v1+json` for + proposals that only require a single limit type, e.g., `apparent-power`. + Clients *MUST* specify that [limit-type](#tag/limit-type) as a media type + parameter. For example, + ```http + PATCH /ratings-proposals/forecast HTTP/1.1 + Content-Type: application/vnd.trolie.rating-forecast-proposal-slim.v1+json; limit-type=apparent-power + ``` + Note that this format is much more concise but requires significant care + in serialization/deserialization. For details, see [Using Slim Media Types](../example-narratives/using-slim-media-types). + requestBody: required: true content: @@ -83,11 +101,18 @@ patch: $ref: ../components/schemas/array-max-monitored-elements.yaml#/forecast-proposal example: $ref: ../../example-narratives/examples/forecast-ratings-proposal-patch.json - application/vnd.trolie.rating-forecast-proposal-slim.v1+json: + application/vnd.trolie.rating-forecast-proposal-slim.v1+json; limit-type=apparent-power: schema: $ref: ../components/schemas/array-max-monitored-elements.yaml#/forecast-proposal-slim - example: - $ref: ../../example-narratives/examples/forecast-ratings-proposal-slim-patch.json + examples: + "No Inputs Provided": + summary: No Inputs Provided in the Forecast Proposal + value: + $ref: ../../example-narratives/examples/forecast-ratings-proposal-slim-patch.json + "Dry Bulb Temp Provided": + summary: Dry Bulb Temp Provided in the Forecast Proposal + value: + $ref: ../../example-narratives/examples/forecast-ratings-proposal-slim-patch-dry-bulb.json responses: '202': diff --git a/docs/_data/paths/rating-proposals_realtime.yaml b/docs/_data/paths/rating-proposals_realtime.yaml index 07c017c2..4724a9e8 100644 --- a/docs/_data/paths/rating-proposals_realtime.yaml +++ b/docs/_data/paths/rating-proposals_realtime.yaml @@ -82,6 +82,23 @@ post: data that is either completely missing, or is considered stale by the Clearinghouse Provider, likely due to simply not receiving a value within a reasonable period, such as an hour. + There are two supported media types for a Real-Time Ratings proposals. + + `application/vnd.trolie.rating-realtime-proposal.v1+json` allows the + Ratings Provider to combine different limit types, such as + `apparent-power` (MVA) and `current` (MW), in a single proposal. + + `application/vnd.trolie.rating-realtime-proposal-slim.v1+json` for + proposals that only require a single limit type, e.g., `apparent-power`. + Clients *MUST* specify that [limit-type](#tag/limit-type) as a media type + parameter. For example, + ```http + POST /ratings-proposals/realtime HTTP/1.1 + Content-Type: application/vnd.trolie.rating-realtime-proposal-slim.v1+json; limit-type=apparent-power + ``` + Note that this format is much more concise but requires significant care + in serialization/deserialization. For details, see [Using Slim Media Types](../example-narratives/using-slim-media-types). + tags: *tags requestBody: @@ -92,11 +109,14 @@ post: $ref: "../components/schemas/array-max-monitored-elements.yaml#/realtime-proposal" example: $ref: ../../example-narratives/examples/realtime-proposal.json - application/vnd.trolie.rating-realtime-proposal-slim.v1+json: + application/vnd.trolie.rating-realtime-proposal-slim.v1+json; limit-type=apparent-power: schema: $ref: "../components/schemas/array-max-monitored-elements.yaml#/realtime-proposal-slim" - example: - $ref: ../../example-narratives/examples/realtime-proposal-slim-patch.json + examples: + "No Inputs Provided": + summary: No Inputs Provided in the Real-Time Proposal + value: + $ref: ../../example-narratives/examples/realtime-proposal-slim-patch.json responses: '202': description: | diff --git a/docs/_data/paths/rating-proposals_seasonal.yaml b/docs/_data/paths/rating-proposals_seasonal.yaml index c7570ca2..bb6a1689 100644 --- a/docs/_data/paths/rating-proposals_seasonal.yaml +++ b/docs/_data/paths/rating-proposals_seasonal.yaml @@ -104,7 +104,7 @@ patch: $ref: "../components/schemas/array-max-monitored-elements.yaml#/seasonal-ratings-proposal" example: $ref: ../../example-narratives/examples/seasonal-ratings-proposals-patch.json - application/vnd.trolie.seasonal-ratings-proposal-slim.v1+json: + application/vnd.trolie.seasonal-ratings-proposal-slim.v1+json; limit-type=apparent-power: schema: $ref: "../components/schemas/array-max-monitored-elements.yaml#/seasonal-ratings-proposal-slim" example: diff --git a/docs/_data/paths/seasonal-ratings-snapshot.yaml b/docs/_data/paths/seasonal-ratings-snapshot.yaml index 5078aa3c..edefbe6d 100644 --- a/docs/_data/paths/seasonal-ratings-snapshot.yaml +++ b/docs/_data/paths/seasonal-ratings-snapshot.yaml @@ -21,6 +21,11 @@ get: $ref: ../components/schemas/array-max-monitored-elements.yaml#/seasonal-ratings-snapshot-detailed example: $ref: '../../example-narratives/examples/seasonal-ratings-snapshot-detailed.json' + application/vnd.trolie.seasonal-rating-snapshot-detailed.v1+json; include-psr-header=false: + schema: + $ref: ../components/schemas/array-max-monitored-elements.yaml#/seasonal-ratings-snapshot-detailed-elide-psr + example: + $ref: '../../example-narratives/examples/seasonal-ratings-snapshot-detailed-elide-psr.json' headers: $ref: '../openapi-split.yaml#/components/responses/204/headers' diff --git a/docs/articles/media-types.md b/docs/articles/media-types.md index b5ff324d..cd3074ad 100644 --- a/docs/articles/media-types.md +++ b/docs/articles/media-types.md @@ -114,12 +114,6 @@ details. #### Slim Media Types {: .no_toc } -{: .nb } -> At the time of this writing, -> `application/vnd.trolie.seasonal-ratings-proposal-slim.v1+json` is the only -> "slim" media type that has been implemented, but others are -> [planned](https://github.com/trolie/spec/issues/152). - The media types in the table above are verbose because they make intentional trade-offs between efficiency and other qualities. For more information please review the article [Performance Trade-offs in the TROLIE Schema Design](./tradeoffs). @@ -128,148 +122,10 @@ Because the TROLIE specification chose to [leverage media types to evolve the interface](../decision-log/media-type-versioning), the project was able to implement a "slim" media type use for seasonal ratings, `application/vnd.trolie.seasonal-ratings-proposal-slim.v1+json`, that -complements `application/vnd.trolie.seasonal-ratings-proposal.v1+json`. This -"slim" format is much more space-efficient but requires a few processing steps -and assumptions: - -1. The `limit-type` used in the proposal is specified by the Ratings Provider as -a parameter of the media type. The `limit-type` chosen determines the layout of -the ratings values. -2. The ratings are provided in order of decreasing duration, e.g., continuous -then emergency then load shed. -3. The facilities are required to be in the same order they appear in the -header. -4. The seasons are required to be in the same order they appear in the header. -5. Each forecast must have the number of hourly forecasts corresponding to the -new header field hours with the assumption that the begins header is the first -entry and each subsequent entry represents the subsequent hour's forecast. - -This is discussed in further detail in the -[spec](../spec#schema/seasonal-proposals-slim). Here we can breakdown a concrete -example. We'll start with a `curl` request, then discuss the HTTP request itself -in two parts, the headers then the JSON payload. - -##### `curl` Example -{: .no_toc } - -{% include_relative snippets/_accept-header-placeholder-warning.md %} -```sh -curl -X PATCH \ - -H "Content-Type: application/vnd.trolie.seasonal-ratings-proposal-slim.v1+json; limit-type=apparent-power" \ - -H "Accept: application/vnd.trolie.seasonal-ratings-proposal-status.v1+json, */*" \ - -d @seasonal-ratings.json \ - $TROLIE_SERVER_URL/ratings-proposals/seasonal -``` - -{: .important } -> The `limit-type` parameter in the `Content-Type` header (line 2 above) is -> required by the TROLIE specification for the -> `application/vnd.trolie.seasonal-ratings-proposal-slim.v1+json` media type, as -> no default `limit-type` can be assumed. See [Limit -> Types](../spec#tag/limit-type) for the other options defined in the spec. +complements `application/vnd.trolie.seasonal-ratings-proposal.v1+json`. {: .nb } -> The `Accept` header in this example specifies one of the -> [Status Responses](#status-responses). - -##### HTTP Headers -{: .no_toc } - -The previous `curl` request would result in an HTTP request like the following: - -```http -PATCH /ratings-proposals/seasonal HTTP/1.1 -Host: trolie.example.com -Accept: application/vnd.trolie.seasonal-ratings-proposal-status.v1+json, */* -Content-Type: application/vnd.trolie.seasonal-ratings-proposal-slim.v1+json; limit-type=apparent-power -``` - -##### Payload -{: .no_toc } - -{: .important } -> For illustrative purposes here, we present the JSON payload with inline -> comments. However, comments are **not** permitted in the TROLIE media types. - -```jsonc -{ - "proposal-header": { - "source": { /* ...details elided for clarity... */ }, - "default-emergency-durations": [ - { "name": "emergency", "duration-minutes": 240 }, - { "name": "load shed", "duration-minutes": 15 } - ], - "power-system-resources": [ - { "resource-id": "8badf00d", - "alternate-identifiers": [ { "name": "segmentX", "authority": "TO-NERC-ID" } ] - }, { - "resource-id": "f34d3d", - "alternate-identifiers": [ { "name": "segmentY", "authority": "TO-NERC-ID" } ] - } - ], - "default-seasonal-schedule": { - "schedule": [ - { "season-name": "WINTER", "begins": "2024-11-15T00:00:00-05:00" }, - { "season-name": "SPRING", "begins": "2025-03-01T00:00:00-05:00" }, - { "season-name": "SUMMER", "begins": "2025-06-15T00:00:00-05:00" }, - { "season-name": "FALL", "begins": "2025-09-01T00:00:00-05:00" } - ], - "ends": "2025-11-15T00:00:00-05:00" - } - }, - "ratings": [ - // note all values are assumed to be MVA because the header in this example - // Content-Type: application/vnd.trolie.seasonal-ratings-proposal-slim.v1+json; limit-type=apparent-power - // specifies the apparent-power limit type which has a single value of MVA - // see https://trolie.energy/spec#tag/limit-type - - [ // resource-id: 8badf00d - [ // season-name: WINTER - 160, //continuous MVA - 170, //emergency MVA - 200, //load shed MVA - ], - [ // season-name: SPRING - 155, //continuous MVA - 160, //emergency MVA - 200 //load shed MVA - ], - [ // season-name: SUMMER - 145, //continuous MVA - 150, //emergency MVA - 200 //load shed MVA - ], - [ // season-name: FALL - 155, //continuous MVA - 160, //emergency MVA - 200 //load shed MVA - ] - ], - [ // resource-id: f34d3d - [ // season-name: WINTER - 161, //continuous MVA - 171, //emergency MVA - 201 //load shed MVA - ], - [ // season-name: SPRING - 156, //continuous MVA - 161, //emergency MVA - 201 //load shed MVA - ], - [ // season-name: SUMMER - 146, //continuous MVA - 151, //emergency MVA - 201 //load shed MVA - ], - [ // season-name: FALL - 156, //continuous MVA - 161, //emergency MVA - 201 //load shed MVA - ] - ] - ] -} -``` +> For more information see [Using Slim Media Types](../example-narratives/using-slim-media-types) ### Status Responses diff --git a/docs/example-narratives/examples/forecast-limits-detailed-elide-names-header.json b/docs/example-narratives/examples/forecast-limits-detailed-elide-names-header.json new file mode 100644 index 00000000..ced448bd --- /dev/null +++ b/docs/example-narratives/examples/forecast-limits-detailed-elide-names-header.json @@ -0,0 +1,152 @@ +{ + "snapshot-header": { + "begins": "2023-07-12T16:00:00-07:00", + "source": { + "provider": "X-AMPL-RC", + "last-updated": "2024-07-12T16:00:00-07:00", + "origin-id": "//trolie.example.com/snapshots/2024-08-05T11%3a00%3a00-07%3a00" + }, + "default-emergency-durations": [ + { + "name": "lte", + "duration-minutes": 240 + }, + { + "name": "ste", + "duration-minutes": 30 + }, + { + "name": "dal", + "duration-minutes": 15 + } + ] + }, + "limits": [ + { + "resource-id": "8badf00d", + "periods": [ + { + "period-start": "2023-07-12T16:00:00-07:00", + "period-end": "2023-07-12T17:00:00-07:00", + "proposals-considered": [ + { + "resource-id": "8badf00d-UTILITY-A-SEG-id", + "source": { + "last-updated": "2023-07-12T16:00:00-07:00", + "provider": "UTILITY-A", + "origin-id": "8badf00d-UTILITY-A-correlation-id" + }, + "period-start": "2023-07-12T16:00:00-07:00", + "period-end": "2023-07-12T17:00:00-07:00", + "proposal-disposition": "Used", + "continuous-operating-limit": { + "mva": 150 + }, + "emergency-operating-limits": [ + { + "duration-name": "lte", + "limit": { + "mva": 160 + } + }, + { + "duration-name": "ste", + "limit": { + "mva": 165 + } + }, + { + "duration-name": "dal", + "limit": { + "mva": 170 + } + } + ] + } + ], + "temporary-aar-exceptions": [ + { + "id": "https://trolie.example.com/temporary-aar-exceptions/1234", + "source": { + "origin-id": "2d8c80e8-f533-4be9-85bf-f7f81eb73d67", + "provider": "UTILITY-A", + "last-updated": "2025-07-12T16:00:00-07:00" + }, + "resource": { + "resource-id": "8badf00d" + }, + "start-time": "2025-07-12T16:00:00-07:00", + "end-time": "2025-08-01T00:00:00-07:00", + "continuous-operating-limit": { + "mva": 160 + }, + "emergency-operating-limits": [ + { + "duration-name": "lte", + "limit": { + "mva": 165 + } + }, + { + "duration-name": "ste", + "limit": { + "mva": 170 + } + }, + { + "duration-name": "dal", + "limit": { + "mva": 180 + } + } + ] + } + ], + "overrides": [ + { + "continuous-operating-limit": { + "mva": 160 + }, + "emergency-operating-limits": [ + { + "duration-name": "lte", + "limit": { + "mva": 165 + } + } + ], + "override-reason": "TOI 20250701-01", + "start-time": "2025-07-01T00:00:00-07:00" + } + ], + "additional-data": { + "vendor-specific-data": {} + }, + "continuous-operating-limit": { + "mva": 160 + }, + "emergency-operating-limits": [ + { + "duration-name": "lte", + "limit": { + "mva": 165 + } + }, + { + "duration-name": "ste", + "limit": { + "mva": 170 + } + }, + { + "duration-name": "dal", + "limit": { + "mva": 180 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/example-narratives/examples/forecast-limits-elide-psr.json b/docs/example-narratives/examples/forecast-limits-elide-psr.json new file mode 100644 index 00000000..3dedde94 --- /dev/null +++ b/docs/example-narratives/examples/forecast-limits-elide-psr.json @@ -0,0 +1,62 @@ +{ + "snapshot-header": { + "begins": "2023-07-12T16:00:00-07:00", + "source": { + "provider":"X-AMPL", + "last-updated": "2023-07-12T16:00:00-07:00", + "origin-id": "//trolie.example.com/snapshots/2024-08-05T11%3a00%3a00-07%3a00" + }, + "default-emergency-durations": [ + { + "name": "lte", + "duration-minutes": 240 + }, + { + "name": "ste", + "duration-minutes": 30 + }, + { + "name": "dal", + "duration-minutes": 15 + } + ] + }, + "limits": [ + { + "resource-id": "8badf00d", + "periods": [ + { + "period-start": "2023-07-12T16:00:00-07:00", + "period-end": "2023-07-12T17:00:00-07:00", + "continuous-operating-limit": { + "mw": 160, + "pf": 1.0 + }, + "emergency-operating-limits": [ + { + "duration-name": "lte", + "limit": { + "mw": 170, + "pf": 1.0 + } + }, + { + "duration-name": "ste", + "limit": { + "mw": 180, + "pf": 1.0 + } + }, + { + "duration-name": "dal", + "limit": { + "mw": 190, + "pf": 1.0 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/example-narratives/examples/forecast-limits-slim-active-power-dry-bulb.json b/docs/example-narratives/examples/forecast-limits-slim-active-power-dry-bulb.json new file mode 100644 index 00000000..e305b9ce --- /dev/null +++ b/docs/example-narratives/examples/forecast-limits-slim-active-power-dry-bulb.json @@ -0,0 +1,59 @@ +{ + "snapshot-header": { + "begins": "2023-07-12T16:00:00-07:00", + "ends": "2023-07-12T18:00:00-07:00", + "source": { + "provider":"X-AMPL", + "last-updated": "2023-07-12T16:00:00-07:00", + "origin-id": "//trolie.example.com/snapshots/2024-08-05T11%3a00%3a00-07%3a00" + }, + "default-emergency-durations": [ + { + "name": "lte", + "duration-minutes": 240 + }, + { + "name": "ste", + "duration-minutes": 30 + }, + { + "name": "dal", + "duration-minutes": 15 + } + ], + "power-system-resources": [ + { "resource-id": "8badf00d", + "alternate-identifiers": [ + {"name": "segmentX", "authority": "TO-NERC-ID"}, + {"name": "LINE1 SEG-X", "authority": "RC-NERC-ID", "mrid": "8badf00d"} + ] + }, + { "resource-id": "f34d3d", + "alternate-identifiers": [ + {"name": "segmentY", "authority": "TO-NERC-ID"}, + {"name": "LINE2 SEG-Y", "authority": "RC-NERC-ID", "mrid": "8badf00d"} + ] + } + ] + }, + "limits": [ + [ + [160, 1.0, 170, 1.0, 180, 1.0, 190, 1.0], + [161, 1.0, 171, 1.0, 181, 1.0, 191, 1.0] + ], + [ + [140, 1.0, 150, 1.0, 160, 1.0, 170, 1.0], + [141, 1.0, 151, 1.0, 161, 1.0, 171, 1.0] + ] + ], + "inputs-used": [ + { + "name": "dry bulb temperature (Fahrenheit)", + "unit": "degF", + "values": [ + [ 50, 51, 52, 53 ], + [ 46.1, 46.5, 47.1, 48 ] + ] + } + ] +} \ No newline at end of file diff --git a/docs/example-narratives/examples/forecast-ratings-proposal-slim-patch-dry-bulb.json b/docs/example-narratives/examples/forecast-ratings-proposal-slim-patch-dry-bulb.json new file mode 100644 index 00000000..c8404971 --- /dev/null +++ b/docs/example-narratives/examples/forecast-ratings-proposal-slim-patch-dry-bulb.json @@ -0,0 +1,55 @@ +{ + "proposal-header" : { + "source": { + "last-updated": "2025-10-31T15:05:43.044267100-07:00", + "provider": "UTILITY-A", + "origin-id": "5aeacb25-9b65-4738-8a00-ac10afa63640" + }, + "begins": "2025-11-01T01:00:00-05:00", + "ends": "2025-11-01T05:00:00-05:00", + "default-emergency-durations": [ + { + "name": "emergency", + "duration-minutes": 240 + } + ], + "power-system-resources": [ + { "resource-id": "8badf00d", + "alternate-identifiers": [ + {"name": "segmentX", "authority": "TO-NERC-ID"}, + {"name": "LINE1 SEG-X", "authority": "RC-NERC-ID", "mrid": "8badf00d"} + ] + }, + { "resource-id": "f34d3d", + "alternate-identifiers": [ + {"name": "segmentY", "authority": "TO-NERC-ID"}, + {"name": "LINE2 SEG-Y", "authority": "RC-NERC-ID", "mrid": "8badf00d"} + ] + } + ] + }, + "ratings": [ + [ + [160, 170], + [155, 160], + [145, 150], + [140, 145] + ], + [ + [160, 170], + [155, 160], + [145, 150], + [140, 145] + ] + ], + "inputs-used": [ + { + "name": "dry bulb temperature (Fahrenheit)", + "unit": "degF", + "values": [ + [ 50, 51, 52, 53 ], + [ 46.1, 46.5, 47.1, 48 ] + ] + } + ] +} diff --git a/docs/example-narratives/examples/forecast-ratings-proposal-slim-patch.json b/docs/example-narratives/examples/forecast-ratings-proposal-slim-patch.json index 08815db2..305adeb5 100644 --- a/docs/example-narratives/examples/forecast-ratings-proposal-slim-patch.json +++ b/docs/example-narratives/examples/forecast-ratings-proposal-slim-patch.json @@ -41,15 +41,5 @@ [145, 150], [140, 145] ] - ], - "inputs-used": [ - { - "name": "dry bulb temperature (Fahrenheit)", - "unit": "degF", - "values": [ - [ 50, 51, 52, 53 ], - [ 46.1, 46.5, 47.1, 48 ] - ] - } ] -} \ No newline at end of file +} diff --git a/docs/example-narratives/examples/realtime-limit-set-detailed-elide-psr.json b/docs/example-narratives/examples/realtime-limit-set-detailed-elide-psr.json new file mode 100644 index 00000000..e1edbc99 --- /dev/null +++ b/docs/example-narratives/examples/realtime-limit-set-detailed-elide-psr.json @@ -0,0 +1,181 @@ +{ + "snapshot-header": { + "source": { + "provider": "X-AMPL-RC", + "last-updated": "2023-07-12T15:05:43.044267100-07:00", + "origin-id": "//trolie.example.com/snapshots/2024-08-05T11%3a00%3a00-07%3a00" + }, + "default-emergency-durations": [ + { + "name": "lte", + "duration-minutes": 240 + }, + { + "name": "ste", + "duration-minutes": 30 + }, + { + "name": "dal", + "duration-minutes": 5 + } + ] + }, + "limits": [ + { + "resource-id": "8badf00d", + "period-start": "2025-07-12T15:00:00-07:00", + "period-end": "2025-07-12T16:00:00-07:00", + "proposals-considered": [ + { + "resource-id": "8badf00d-UTILITY-A-SEG-id", + "source": { + "last-updated": "2025-07-12T14:10:12-07:00", + "provider": "UTILITY-A", + "origin-id": "8badf00d-UTILITY-A-correlation-id" + }, + "period-start": "2025-07-12T15:00:00-07:00", + "period-end": "2025-07-12T16:00:00-07:00", + "proposal-disposition": "Used", + "continuous-operating-limit": { + "mva": 150 + }, + "emergency-operating-limits": [ + { + "duration-name": "lte", + "limit": { + "mva": 165 + } + }, + { + "duration-name": "ste", + "limit": { + "mva": 170 + } + }, + { + "duration-name": "dal", + "limit": { + "mva": 180 + } + } + ] + }, + { + "resource-id": "8badf00d-UTILITY-B-SEG-id", + "source": { + "last-updated": "2025-07-12T14:10:12-07:00", + "provider": "UTILITY-B", + "origin-id": "8badf00d-UTILITY-B-correlation-id" + }, + "period-start": "2025-07-12T15:00:00-07:00", + "period-end": "2025-07-12T16:00:00-07:00", + "proposal-disposition": "Used", + "continuous-operating-limit": { + "mva": 150 + }, + "emergency-operating-limits": [ + { + "duration-name": "lte", + "limit": { + "mva": 166 + } + }, + { + "duration-name": "ste", + "limit": { + "mva": 171 + } + }, + { + "duration-name": "dal", + "limit": { + "mva": 175 + } + } + ] + } + ], + "temporary-aar-exceptions": [ + { + "id": "284928-2025-07-12T16:00:00-07:00", + "source": { + "origin-id": "2d8c80e8-f533-4be9-85bf-f7f81eb73d67", + "provider": "UTILITY-A", + "last-updated": "2025-07-12T16:00:00-07:00" + }, + "resource": { + "resource-id": "8badf00d" + }, + "start-time": "2025-07-12T16:00:00-07:00", + "end-time": "2025-08-01T00:00:00-07:00", + "continuous-operating-limit": { + "mva": 160 + }, + "emergency-operating-limits": [ + { + "duration-name": "lte", + "limit": { + "mva": 165 + } + }, + { + "duration-name": "ste", + "limit": { + "mva": 170 + } + }, + { + "duration-name": "dal", + "limit": { + "mva": 180 + } + } + ] + } + ], + "overrides": [ + { + "continuous-operating-limit": { + "mva": 160 + }, + "emergency-operating-limits": [ + { + "duration-name": "lte", + "limit": { + "mva": 165 + } + } + ], + "override-reason": "TOI 20250701-01", + "start-time": "2025-07-01T00:00:00-07:00" + } + ], + "additional-data": { + "vendor-specific-data": {} + }, + "continuous-operating-limit": { + "mva": 160 + }, + "emergency-operating-limits": [ + { + "duration-name": "lte", + "limit": { + "mva": 165 + } + }, + { + "duration-name": "ste", + "limit": { + "mva": 170 + } + }, + { + "duration-name": "dal", + "limit": { + "mva": 175 + } + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/example-narratives/examples/realtime-limit-set-elide-psr.json b/docs/example-narratives/examples/realtime-limit-set-elide-psr.json new file mode 100644 index 00000000..79e7b760 --- /dev/null +++ b/docs/example-narratives/examples/realtime-limit-set-elide-psr.json @@ -0,0 +1,51 @@ +{ + "snapshot-header": { + "source": { + "provider":"X-AMPL", + "last-updated": "2023-07-12T15:05:43.044267100-07:00", + "origin-id": "//trolie.example.com/snapshots/2024-08-05T11%3a00%3a00-07%3a00" + }, + "default-emergency-durations": [ + { + "name": "lte", + "duration-minutes": 240 + }, + { + "name": "ste", + "duration-minutes": 30 + }, + { + "name": "dal", + "duration-minutes": 15 + } + ] + }, + "limits": [ + { + "resource-id": "8badf00d", + "continuous-operating-limit": { + "mva": 160 + }, + "emergency-operating-limits": [ + { + "duration-name": "lte", + "limit": { + "mva": 165 + } + }, + { + "duration-name": "ste", + "limit": { + "mva": 170 + } + }, + { + "duration-name": "dal", + "limit": { + "mva": 180 + } + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/example-narratives/examples/realtime-limit-set-slim-dry-bulb.json b/docs/example-narratives/examples/realtime-limit-set-slim-dry-bulb.json new file mode 100644 index 00000000..50f71f93 --- /dev/null +++ b/docs/example-narratives/examples/realtime-limit-set-slim-dry-bulb.json @@ -0,0 +1,40 @@ +{ + "snapshot-header": { + "source": { + "provider": "X-AMPL", + "last-updated": "2023-07-12T15:05:43.044267100-07:00", + "origin-id": "//trolie.example.com/snapshots/2024-08-05T11%3a00%3a00-07%3a00" + }, + "default-emergency-durations": [ + { + "name": "emergency", + "duration-minutes": 240 + } + ], + "power-system-resources": [ + { "resource-id": "8badf00d", + "alternate-identifiers": [ + { "name": "segmentX", "authority": "TO-NERC-ID" }, + { "name": "LINE1 SEG-X", "authority": "RC-NERC-ID", "mrid": "8badf00d" } + ] + }, + { "resource-id": "f34d3d", + "alternate-identifiers": [ + { "name": "segmentY", "authority": "TO-NERC-ID" }, + { "name": "LINE2 SEG-Y", "authority": "RC-NERC-ID", "mrid": "8badf00d" } + ] + } + ] + }, + "limits": [ + [ 160, 170 ], + [ 155, 160 ] + ], + "inputs-used": [ + { + "name": "dry bulb temperature (Fahrenheit)", + "unit": "degF", + "values": [ 50, 51] + } + ] +} diff --git a/docs/example-narratives/examples/realtime-proposal-slim-patch-dry-bulb.json b/docs/example-narratives/examples/realtime-proposal-slim-patch-dry-bulb.json new file mode 100644 index 00000000..3e8cde88 --- /dev/null +++ b/docs/example-narratives/examples/realtime-proposal-slim-patch-dry-bulb.json @@ -0,0 +1,41 @@ +{ + "proposal-header" : { + "source": { + "last-updated": "2025-10-31T15:05:43.044267100-07:00", + "provider": "UTILITY-A", + "origin-id": "5aeacb25-9b65-4738-8a00-ac10afa63640" + }, + "default-emergency-durations": [ + { + "name": "emergency", + "duration-minutes": 240 + } + ], + "power-system-resources": [ + { "resource-id": "8badf00d", + "alternate-identifiers": [ + {"name": "segmentX", "authority": "TO-NERC-ID"}, + {"name": "LINE1 SEG-X", "authority": "RC-NERC-ID", "mrid": "8badf00d"} + ] + }, + { "resource-id": "f34d3d", + "alternate-identifiers": [ + {"name": "segmentY", "authority": "TO-NERC-ID"}, + {"name": "LINE2 SEG-Y", "authority": "RC-NERC-ID", "mrid": "8badf00d"} + ] + } + ] + }, + "ratings": [ + [160, 170], + [155, 160] + ], + "inputs-used": [ + { + "name": "dry bulb temperature (Fahrenheit)", + "unit": "degF", + "values": [ + [ 50, 51] + ] + } + ]} diff --git a/docs/example-narratives/examples/seasonal-ratings-snapshot-detailed-elide-psr.json b/docs/example-narratives/examples/seasonal-ratings-snapshot-detailed-elide-psr.json new file mode 100644 index 00000000..0719ce06 --- /dev/null +++ b/docs/example-narratives/examples/seasonal-ratings-snapshot-detailed-elide-psr.json @@ -0,0 +1,94 @@ +{ + "snapshot-header": { + "source": { + "provider": "X-AMPL", + "last-updated": "2023-07-12T16:00:00-07:00", + "origin-id": "//trolie.example.com/snapshots/2024-08-05T11%3a00%3a00-07%3a00" + }, + "default-emergency-durations": [ + { + "name": "lte", + "duration-minutes": 240 + }, + { + "name": "ste", + "duration-minutes": 30 + }, + { + "name": "dal", + "duration-minutes": 15 + } + ] + }, + "ratings": [ + { + "resource-id": "LINE1", + "periods": [ + { + "period-start": "2024-04-01T01:00:00Z", + "period-end": "2024-07-01T01:00:00Z", + "season-name": "spring", + "continuous-operating-limit": { + "mva": 160 + }, + "emergency-operating-limits": [ + { + "duration-name": "lte", + "limit": { + "mva": 165 + } + }, + { + "duration-name": "ste", + "limit": { + "mva": 170 + } + }, + { + "duration-name": "dal", + "limit": { + "mva": 180 + } + } + ], + "proposals-considered": [ + { + "resource-id": "8badf00d", + "period-start": "2024-04-01T01:00:00Z", + "period-end": "2024-07-01T01:00:00Z", + "source": { + "provider": "X-AMPL", + "last-updated": "2023-07-12T16:00:00-07:00", + "origin-id": "//trolie.example.com/snapshots/2024-08-05T11%3a00%3a00-07%3a00" + }, + "season-name": "spring", + "continuous-operating-limit": { + "mva": 160 + }, + "emergency-operating-limits": [ + { + "duration-name": "lte", + "limit": { + "mva": 165 + } + }, + { + "duration-name": "ste", + "limit": { + "mva": 170 + } + }, + { + "duration-name": "dal", + "limit": { + "mva": 180 + } + } + ] + } + ] + } + ] + } + ] +} diff --git a/docs/example-narratives/using-slim-media-types.md b/docs/example-narratives/using-slim-media-types.md new file mode 100644 index 00000000..9c26d8cb --- /dev/null +++ b/docs/example-narratives/using-slim-media-types.md @@ -0,0 +1,181 @@ +--- +title: Using Slim Media Types +parent: Usage Examples +nav_order: 8 +toc: true +--- + +The "slim" media types provided by TROLIE include: + +* `application/vnd.trolie.rating-realtime-proposal-slim.v1+json` +* `application/vnd.trolie.seasonal-ratings-proposal-slim.v1+json` +* `application/vnd.trolie.rating-forecast-proposal-slim.v1+json` +* `application/vnd.trolie.forecast-limits-snapshot-slim.v1+json` +* `application/vnd.trolie.realtime-limits-snapshot-slim.v1+json` + +These slim snapshots and proposals require the `limit-type` media type parameter +to be specified. The following names are valid values for the `limit-type` +parameter. + + * `active-power` + * `active-power-with-power-factor` + * `apparent-power` + * `current` + * `current-with-kV` + * `reactive-power` + * `overvoltage-threshold-pu` + * `overvoltage-threshold` + * `undervoltage-threshold-pu` + * `undervoltage-threshold` + +These correspond to the valid [Limit Types](../spec#tag/limit-type). + +Here's an example that requests a slim forecast limits snapshot +```http +GET /limits/forecast-snapshot HTTP/1.1 +Accept: application/vnd.trolie.forecast-limits-snapshot-slim.v1+json; limit-type=apparent-power +``` + + + + This +"slim" format is much more space-efficient but requires a few processing steps +and assumptions: + +1. The `limit-type` used in the proposal is specified by the Ratings Provider as +a parameter of the media type. The `limit-type` chosen determines the layout of +the ratings values. +2. The ratings are provided in order of decreasing duration, e.g., continuous +then emergency then load shed. +3. The facilities are required to be in the same order they appear in the +header. +4. The seasons are required to be in the same order they appear in the header. +5. Each forecast must have the number of hourly forecasts corresponding to the +new header field hours with the assumption that the begins header is the first +entry and each subsequent entry represents the subsequent hour's forecast. + +This is discussed in further detail in the +[spec](../spec#schema/seasonal-proposals-slim). Here we can breakdown a concrete +example. We'll start with a `curl` request, then discuss the HTTP request itself +in two parts, the headers then the JSON payload. + +##### `curl` Example +{: .no_toc } + +```sh +curl -X PATCH \ + -H "Content-Type: application/vnd.trolie.seasonal-ratings-proposal-slim.v1+json; limit-type=apparent-power" \ + -H "Accept: application/vnd.trolie.seasonal-ratings-proposal-status.v1+json, */*" \ + -d @seasonal-ratings.json \ + $TROLIE_SERVER_URL/ratings-proposals/seasonal +``` + +{: .important } +> The `limit-type` parameter in the `Content-Type` header (line 2 above) is +> required by the TROLIE specification for the +> `application/vnd.trolie.seasonal-ratings-proposal-slim.v1+json` media type, as +> no default `limit-type` can be assumed. See [Limit +> Types](../spec#tag/limit-type) for the other options defined in the spec. + +{: .nb } +> The `Accept` header in this example specifies one of the +> [Status Responses](#status-responses). + +##### HTTP Headers +{: .no_toc } + +The previous `curl` request would result in an HTTP request like the following: + +```http +PATCH /ratings-proposals/seasonal HTTP/1.1 +Host: trolie.example.com +Accept: application/vnd.trolie.seasonal-ratings-proposal-status.v1+json, */* +Content-Type: application/vnd.trolie.seasonal-ratings-proposal-slim.v1+json; limit-type=apparent-power +``` + +##### Payload +{: .no_toc } + +{: .important } +> For illustrative purposes here, we present the JSON payload with inline +> comments. However, comments are **not** permitted in the TROLIE media types. + +```jsonc +{ + "proposal-header": { + "source": { /* ...details elided for clarity... */ }, + "default-emergency-durations": [ + { "name": "emergency", "duration-minutes": 240 }, + { "name": "load shed", "duration-minutes": 15 } + ], + "power-system-resources": [ + { "resource-id": "8badf00d", + "alternate-identifiers": [ { "name": "segmentX", "authority": "TO-NERC-ID" } ] + }, { + "resource-id": "f34d3d", + "alternate-identifiers": [ { "name": "segmentY", "authority": "TO-NERC-ID" } ] + } + ], + "default-seasonal-schedule": { + "schedule": [ + { "season-name": "WINTER", "begins": "2024-11-15T00:00:00-05:00" }, + { "season-name": "SPRING", "begins": "2025-03-01T00:00:00-05:00" }, + { "season-name": "SUMMER", "begins": "2025-06-15T00:00:00-05:00" }, + { "season-name": "FALL", "begins": "2025-09-01T00:00:00-05:00" } + ], + "ends": "2025-11-15T00:00:00-05:00" + } + }, + "ratings": [ + // note all values are assumed to be MVA because the header in this example + // Content-Type: application/vnd.trolie.seasonal-ratings-proposal-slim.v1+json; limit-type=apparent-power + // specifies the apparent-power limit type which has a single value of MVA + // see https://trolie.energy/spec#tag/limit-type + + [ // resource-id: 8badf00d + [ // season-name: WINTER + 160, //continuous MVA + 170, //emergency MVA + 200, //load shed MVA + ], + [ // season-name: SPRING + 155, //continuous MVA + 160, //emergency MVA + 200 //load shed MVA + ], + [ // season-name: SUMMER + 145, //continuous MVA + 150, //emergency MVA + 200 //load shed MVA + ], + [ // season-name: FALL + 155, //continuous MVA + 160, //emergency MVA + 200 //load shed MVA + ] + ], + [ // resource-id: f34d3d + [ // season-name: WINTER + 161, //continuous MVA + 171, //emergency MVA + 201 //load shed MVA + ], + [ // season-name: SPRING + 156, //continuous MVA + 161, //emergency MVA + 201 //load shed MVA + ], + [ // season-name: SUMMER + 146, //continuous MVA + 151, //emergency MVA + 201 //load shed MVA + ], + [ // season-name: FALL + 156, //continuous MVA + 161, //emergency MVA + 201 //load shed MVA + ] + ] + ] +} +```