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.
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.
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.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.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).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.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).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.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).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.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./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.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.jackson-core / jackson-databind on the build classpath to avoid a streamReadConstraints error from older transitive versions during deploy.CONTRIBUTING.md workflow doc.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.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.md-docs and build-provenance conventions; bumped com.dcj/codox-md to 0.2.0.: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.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
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |