Skip to content

Latest commit

 

History

History
41 lines (23 loc) · 4.58 KB

File metadata and controls

41 lines (23 loc) · 4.58 KB

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project follows Semantic Versioning. While the library is in early development (0.x), breaking changes may appear between minor versions when needed to fix correctness issues or align with the OpenADR 3.1.0 specification.

0.5.0 — 2026-05-28

Added

  • Event.resolved_intervals() (POA3-9p7). Applies the OpenADR 3.1.0 intervalPeriod inheritance rules and returns a new list of Interval objects with the resolved values. Per the spec, event.intervalPeriod "sets default start time and duration of intervals" and a per-interval intervalPeriod "may set temporal aspects of interval or override event.intervalPeriod" — but Event.intervals[].interval_period is exposed as a raw passthrough, so without this helper every downstream consumer had to reimplement the inheritance and risked getting it wrong. The gap was first observed in the openadr3-ven-hass integration, where missing per-interval intervalPeriod was silently filled with a hardcoded 60-minute default instead of falling back to event-level. Rules: per-interval duration falls back to event.interval_period.duration; per-interval start falls back to event.interval_period.start advanced by the sum of all prior intervals' resolved durations; randomize_start is per-interval only (no event-level fallback). Original Event.intervals is never mutated.

0.4.0 — 2026-05-25

Fixed

  • Payload type case is now preserved from the wire (POA3-bp6). coerce_payload previously lowercased every payload.type (hardcoded "price" / "usage" for PRICE / USAGE, and raw["type"].lower() for all other types), while the descriptor side (EventPayloadDescriptor.payload_type, ReportPayloadDescriptor.payload_type) passed the wire value through unchanged. The result was a within-event mismatch: event.payload_descriptors[0].payload_type == "PRICE" but event.intervals[0].payloads[0].type == "price". Consumers joining per-interval payload rows against descriptor metadata by string-keying on the type field saw silent dict-lookup failures. The fix preserves the wire case throughout, so descriptor and payload-side type fields now agree. The OpenADR 3.1.0 spec uses UPPER_SNAKE_CASE for payload types (PRICE, EXPORT_PRICE, GHG, USAGE, etc.), so spec-compliant VTNs will see uppercase strings everywhere. Surfaced by the openadr3-ven-hass 0.4.0 → 0.4.1 incident; that integration's .upper() workaround at the row-construction site becomes a harmless no-op against openadr3>=0.4.0.

Changed

  • Breaking (observable): payload.type and attributes[].type strings now preserve the wire case (typically UPPER_SNAKE_CASE per OA3 spec) instead of being lowercased. Any consumer comparing these strings to lowercase literals ("price", "usage") must update to the wire case, or normalize at the comparison site. The _raw dict on every coerced entity was already wire-case and is unchanged.

0.3.0 — 2026-05-25

Added

  • user_agent parameter on OpenADRClient and factory functions for VTN server-side log identification (commit).
  • Round-trip wire-offset preservation tests covering Z, +00:00, and non-UTC offsets for datetimes and durations (commit).
  • CONTRIBUTING.md and README contributing section (commit).

Changed

  • Time-handling contract pinned via README guarantees: parse_datetime and parse_duration preserve the wire offset string; to_zoned is the only operation that intentionally changes the wire offset.

[0.2.0] — earlier

Initial published versions. Two-layer raw/coerced Pydantic data model, pendulum-based time types, httpx client with bearer auth, payload-type dispatch for PRICE / USAGE → Decimal, OpenAPI spec validation, notification coercion for both spec-compliant camelCase and VTN-RI snake_case shapes.