Liking cljdoc? Tell your friends :D

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 was in early development (0.x), breaking changes appeared between minor versions when needed to fix correctness issues or align with the MIDAS API. The 1.0.0 release tracks the California Energy Commission's MIDAS v2.0 API.

1.0.1 — 2026-06-24

A patch release fixing a v2.0 data-loss bug found while regenerating the spec's examples against the live API. All changes are additive or corrective; the public API is unchanged.

Fixed

  • Integer day-types are no longer silently dropped for MOER/ALRT. Live v2.0 SGIP GHG (MOER) and Flex Alert (ALRT) responses encode DayStart/DayEnd as the integer upload code (1=Monday through 7=Sunday, 8=Holiday), where v1.0 sent the weekday string. day-type-kw mapped only the strings, so the integer missed the map and :midas.value/day-start / :midas.value/day-end came back nil for every MOER/Flex interval. day-type-kw now keys on both the integer codes (1-8) and the legacy strings; the electricity-rate wire form (still string, pending utility migration) is unaffected.

Added

  • :midas.rate/signal-type and :midas.rate/description on coerced rate entities. Live v2.0 rate-values responses carry top-level SignalType and Description fields (matching the RIN-list labels); entities/->rate-info now surfaces them (SignalType coerced via signal-type-kw). Both are nil when the wire omits them.
  • Raw-response validation in the integration tests. The integration suite now validates the raw wire body (pre-coercion) against the raw Malli schema in midas.entities.schema.raw, in addition to the coerced-entity assertions. Coercion previously normalised the live integer DayStart to nil before the only schema check ran, masking the wire drift: this is the gap that let the integer-day-type bug ship. An offline unit regression (integer-day-type-coercion) covers the same shape without the live API.

Changed

  • Raw schema relaxed to faithfully model the v2.0 wire. ValueData DayStart/DayEnd accept int | string | null; Value accepts any JSON number (Flex Alert sends an integer 0/1); RateInfo RateID/RateName are nullable and the new top-level SignalType/Description are modelled.
  • Bundled example fixtures refreshed to v2.0 (resources/midas-spec/examples/): regenerated flex-alert, tou-rate, and rin-list samples, plus new moer-realtime (integer day-types) and keyed lookup-table-unit samples. These are documentation only; nothing in the library loads them.

1.0.0 — 2026-06-22

The California Energy Commission released MIDAS v2.0 on 2026-06-22, a breaking change to the live API; v1.0 was removed from the live service that day. clj-midas 1.0.0 is a v2-only release — v1.0 compatibility is intentionally dropped — and was verified end-to-end against the live v2.0 production API on release day (per signal type, via the unauthenticated GET surface). See doc/v2-migration.md for the v1.0→v2.0 upgrade guide.

Read-only consumer posture. clj-midas consumes MIDAS data via the v2.0 unauthenticated GET endpoints (create-anonymous-client) — no credentials required. The authenticated constructors (create-client / create-auto-client) remain for utilities that upload rate data to the CEC; that path requires CEC-issued utility credentials and is not exercised by this project.

Changed

  • Breaking: RIN-list SignalType labels are now v2.0 long-form. signal-type-kw maps "Electricity Rates", "Greenhouse Gas Emissions", and "California Independent System Operator Flex Alert" (v2.0 always populates this field; v1.0 returned null for GHG/Flex Alert entries). The old v1.0 labels ("Rates"/"GHG"/"Flex Alert") are no longer recognised.
  • Breaking: the per-interval value field is read from Value (capital V) instead of v1.0's lowercase value. The CEC standardised the casing in v2.0; the raw Malli schema and entities/->value-data follow suit.
  • Breaking: RateType coercion handles both v2.0 wire forms. The live API is inconsistent: electricity rates return the Ratetype lookup UploadCode short code (e.g. "TOU"), while GHG and Flex Alert return the long-form Description (e.g. "Greenhouse Gas emissions", "Flex Alert"). rate-type-kw now keys on both, and adds the v2.0 rate types (DSR, VPP, and the -D demand-charge variants).
  • Breaking: ValueData interval boundaries are zone-aware ZonedDateTime only. The zone-naive :midas.value/date-start, :date-end, :time-start, and :time-end (LocalDate/LocalTime) fields are removed; each boundary is exposed solely as :tick/beginning / :tick/end (ZonedDateTime in the client zone). A bare wall-clock time with no zone is ambiguous — and in v2.0 the wire delivers DateStart/TimeStart/DateEnd/TimeEnd in UTC for every signal type (v1.0 delivered SGIP GHG and Flex Alert in Pacific Time — an upstream-provider passthrough bug the CEC fixed in v2.0). Boundaries are composed in UTC and re-expressed in the client zone via withZoneSameInstant, so the moment is correct across DST. Consumers needing a wall-clock date/time derive it from the tick (.toLocalTime / .toLocalDate, optionally after .withZoneSameInstant). See doc/datetime-and-timezone.md.
  • Breaking: entities/rin-list peels the v2.0 keyed-object response. v2.0 wraps the RIN list in a single-keyed object rather than v1.0's bare array; rin-list peels the single key and returns a uniform vector (a bare vector is still accepted as a fallback). Verified live: the wrapper key is always Rates, regardless of the requested SignalType (the spec's predicted per-signal keys GHGEmissions/FlexAlerts/All do not appear on the wire — see midas-api-specs#2).
  • Breaking: entities/lookup-table peels the v2.0 keyed-object response. v2.0 wraps lookup tables in {table_name, data:[...]} rather than v1.0's bare array; lookup-table peels :data (a bare vector is still accepted as a fallback). See midas-api-specs#3.
  • Breaking: get-historical-data uses the path-param endpoint /HistoricalData/{rate_id} (was the ?id= query param) and documents the v2.0 6-month max range per call. The Clojure signature is unchanged: (get-historical-data client rin startdate enddate).
  • Bundled OpenAPI spec swapped to MIDAS v2.0 (resources/midas-spec/openapi.yaml, combined from the v2 branch of grid-coordination/midas-api-specs); GET operations are no longer marked as requiring auth.

Added

  • create-anonymous-client — an unauthenticated client constructor for the v2.0 GET endpoints (no token acquired, no Authorization header sent). This is all a data consumer needs; create-client / create-auto-client remain for utility uploaders.
  • g/kWh CO2 unit (:midas.unit/g-co2-per-kwh) for v2.0 GHG emissions, which report in grams rather than v1.0's kilograms — values are 1000× larger for the same physical reading. kg/kWh CO2 (:midas.unit/kg-co2-per-kwh) is retained (the live Unit lookup table still lists it). entities/ghg? recognises both units.
  • doc/v2-migration.md — a v1.0→v2.0 upgrade guide for consumers (what changed on the wire and what, if anything, you need to do).

Removed

  • The standalone /Holiday endpoint and all holiday code. The CEC retired /Holiday in v2.0 (absent from its published /openapi.json; the live route 401s). Removed client/get-holidays, entities/->holiday/holidays, the Holiday/HolidayEntry schemas, and the /Holiday path from the bundled spec. The 8=Holiday day-type value in rate schedules is a separate concept and is unaffected.
  • get-historical-list and entities/historical-list. v2.0 retires the /HistoricalList endpoint; use (entities/rin-list (get-rin-list client 0)) for the full active RIN list.

Fixed

  • RIN-list LastUpdated parsing for the v2.0 basic-format UTC offset. The field now arrives as e.g. "2021-07-14T14:31:55+0000" (offset with no colon), which DateTimeFormatter/ISO_OFFSET_DATE_TIME rejects — it previously threw DateTimeParseException and broke rin-list for every signal type. Parsing now uses a lenient formatter accepting +0000, +00:00, and Z. See midas-api-specs#4.

0.5.1 — 2026-05-05

Changed

  • Pinned jackson-core / jackson-databind on the build classpath to avoid a streamReadConstraints error from older transitive versions during deploy.

Added

  • CONTRIBUTING.md workflow doc.

0.5.0 — 2026-05-05

Changed

  • Breaking: datetime coercion is java.time.ZonedDateTime end-to-end. Every coerced timestamp is a ZonedDateTime in the client's configured zone (default America/Los_Angeles, MIDAS's native zone), DST-aware by construction. The zone is configurable per-instance via :zone and flows through each get-* fn onto the response as :midas/zone, where the coercion layer reads it. Replaces the earlier mixed LocalDateTime / Instant handling that mis-parsed MIDAS's bare wall-clock fields.

0.4.0 — 2026-04-27

Added

  • Build provenance embedded in the JAR. Each release writes META-INF/<group>/<artifact>/build-provenance.{edn,json} via com.dcj/build-provenance 0.2.0, so a downstream consumer can identify exactly which build is running.
  • README badges for the md-docs and build-provenance conventions; bumped com.dcj/codox-md to 0.2.0.

0.3.0 — 2026-04-16

Added

  • :tick/beginning and :tick/end on ValueData entities (when both date and time are present for a boundary), making a coerced interval directly usable as a tick interval.

0.2.0 — 2026-04-16

Initial published release to Clojars. Two-layer raw/coerced data model with namespaced keywords, java.time types, and BigDecimal prices; Martian-based Hato HTTP client with HTTP Basic → bearer-token auth and transparent token auto-refresh; spec-driven endpoints from a bundled OpenAPI spec; RIN parsing and lookup-table annotation; signal-type helpers (flex-alert?, flex-alert-active?, ghg?); Malli schemas for both raw and coerced layers; Codox-generated API docs embedded in the JAR via com.dcj/codox-md; clj-kondo lint config and GitHub Actions CI.

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close