Unify energy VCs into Electricity Credentials#208
Unify energy VCs into Electricity Credentials#208Anusree-J wants to merge 25 commits intobeckn:mainfrom
Conversation
Combines the 4 separate credentials (utility-customer, consumption-profile, generation-profile, storage-profile) into a single W3C VC using the credentialSubject array pattern. The 5 equal-level subjects are: - ConsumerProfile (meterNumber, consumerNumber, maskedIdNumber) - ConsumerDetails (fullName, installationAddress, serviceConnectionDate) - ConsumptionProfile (premisesType, connectionType, sanctionedLoadKW, tariffCategoryCode) - GenerationProfile (generationType, capacityKW, commissioningDate, manufacturer, modelNumber) - StorageProfile (storageCapacityKWh, powerRatingKW, commissioningDate, storageType) https://claude.ai/code/session_01Uu922mXdheZs3VSroAkdqt
Remove redundant id repetition across all 5 subjects. Now uses a single credentialSubject object with the consumer DID declared once at the top, and 5 equal-level sibling properties: consumerProfile, consumerDetails, consumptionProfile, generationProfile, storageProfile. https://claude.ai/code/session_01Uu922mXdheZs3VSroAkdqt
1. credentialSubject.id now optional (per W3C VC Data Model) 2. serviceConnectionDate moved to customerProfile 3. Renamed to ElectricityCredential 4. Added validFrom/validUntil (VC Data Model 2.0 validity period) 5. Added maskedIdType alongside maskedIdNumber 6. Issuer id is now a URL (per W3C VC 2.0 issuer spec) 7. Added meterType (Smart, Conventional, Prepaid) to customerProfile 8. Renamed consumer → customer throughout https://claude.ai/code/session_01Uu922mXdheZs3VSroAkdqt
Documents all classes, properties, ranges, and external vocabulary mappings used by the ElectricityCredential specification. https://claude.ai/code/session_01Uu922mXdheZs3VSroAkdqt
Renames the folder and updates all internal URIs (context.jsonld, schema.json, example.json) and the parent readme. https://claude.ai/code/session_01Uu922mXdheZs3VSroAkdqt
- Delete utility-customer-vc, consumption-profile-vc, generation-profile-vc, storage-profile-vc - Restructure program-enrollment-vc to use shared customerProfile and customerDetails objects (both optional), matching the electricity credential structure - Upgrade program enrollment to W3C VC Data Model 2.0 (validFrom/validUntil instead of issuanceDate/expirationDate) - Rename validUntil field to enrollmentValidUntil to avoid collision with the VC-level validUntil - Update parent readme https://claude.ai/code/session_01Uu922mXdheZs3VSroAkdqt
Use correct URL format: example-utility.com/vc-revocation-registry https://claude.ai/code/session_01Uu922mXdheZs3VSroAkdqt
Only customerProfile is required in credentialSubject. customerDetails, consumptionProfile, generationProfile, and storageProfile are all optional. https://claude.ai/code/session_01Uu922mXdheZs3VSroAkdqt
licenseNumber is no longer a required field on the issuer object. https://claude.ai/code/session_01Uu922mXdheZs3VSroAkdqt
Updated all references across both electricity-credential and program-enrollment-vc specs. https://claude.ai/code/session_01Uu922mXdheZs3VSroAkdqt
…e, add geo/plusCode, fix meterType, remove UtilityIssuer - Rename ElectricityCredential to CustomerCredential (deg:CustomerCredential) - Change namespace prefix from energy: to deg: across all context files - Remove enum constraint from meterType (no standard list exists) - Add geo coordinates (latitude/longitude) and plusCode to installationAddress - Remove UtilityIssuer custom type, use standard W3C issuer property - Make licenseNumber optional in program-enrollment issuer - Update all readmes to reflect changes https://claude.ai/code/session_01Uu922mXdheZs3VSroAkdqt
Change all schema $id and context URLs from nfh-trust-labs.github.io/vc-schemas to anusree-j.github.io/DEG/specification to point to the DEG repo itself. https://claude.ai/code/session_01Uu922mXdheZs3VSroAkdqt
specification/energy-credentials/electricity-credential/example.json
Outdated
Show resolved
Hide resolved
| "customerNumber": "UTIL-2025-001234567", | ||
| "meterNumber": "MET2025789456123", | ||
| "meterType": "Smart", | ||
| "maskedIdType": "SSN", |
There was a problem hiding this comment.
great to have maskedIdType!
| "issuer": { | ||
| "id": "https://example-utility.com/issuers/energy-dept", | ||
| "name": "Example Energy Utility", | ||
| "licenseNumber": "REG-2025-00001" |
| "validUntil": "2026-01-13T10:30:00Z", | ||
| "credentialStatus": { | ||
| "id": "https://dedi.global/dedi/query/example-utility.com/vc-revocation-registry", | ||
| "type": "dediregistry" |
There was a problem hiding this comment.
add statuspurpose = revocation
type = dedi
give both URLs
There was a problem hiding this comment.
…um, datetime offsets - Replace licenseNumber and maskedIdType/maskedIdNumber with reusable idRef pattern (issuedBy DID + authority-domain:id-value subjectId) - Update credentialStatus to full dedi structure with statusPurpose and statusListCredential - Add meterType enum from Green Button/ESPI: AMR, AMI, Electromechanical, Forward, Reverse, Bidirectional, Prepaid, NetMeter, Other - Convert all date fields to date-time with explicit timezone offset (non-GMT) - Update @context URLs to schema.beckn.io (no /energy/, no .jsonld extension) - Move old per-profile schemas and examples into eos-schemas/ archive - Rewrite all three readmes to reflect the new structures
Align the installationAddress object with the beckn protocol Location schema (https://schema.beckn.io/Location/2.0). All beckn Location fields included (id, descriptor, map_url, gps, address, city, district, state, country, area_code, circle, polygon, 3dspace, rating) plus openLocationCode as a DEG extension. Required fields: address, area_code, country. Context uses beckn: namespace for Location terms.
Add beckn Location context and update all DEG context URLs to use proper .jsonld paths (e.g., https://schema.beckn.io/deg/CustomerProfile/context.jsonld).
|
Hi @Anusree-J could you add a PR description? |
| "https://schema.beckn.io/deg/CustomerDetails/context.jsonld", | ||
| "https://schema.beckn.io/deg/ConsumptionProfile/context.jsonld", | ||
| "https://schema.beckn.io/deg/GenerationProfile/context.jsonld", | ||
| "https://schema.beckn.io/deg/StorageProfile/context.jsonld" |
There was a problem hiding this comment.
will check with @ravi-prakash-v on whether he prefers flat class hierarchy vs. nested under deg. I presume, we will need to upload these, and in a follow-up, use $ref: url within schema.json to invoke them by reference.
| "https://www.w3.org/ns/credentials/v2", | ||
| "https://schema.org/", | ||
| "https://schema.beckn.io/Location/2.0/context.jsonld", | ||
| "https://schema.beckn.io/deg/CustomerCredential/context.jsonld", |
There was a problem hiding this comment.
For future: We may want to add version names in folders, create those in specification/schema and publish them on schema.beckn.io under flat structure
| | `meterType` | enum | Yes | Type of meter — see [meterType enum](#metertype-enum) | | ||
| | `idRef` | object | No | External identity reference (e.g., government ID) — see [idRef](#idref) | | ||
|
|
||
| #### meterType enum |
There was a problem hiding this comment.
Potential usability issue here by defining this as an enum. This seems to be mixing a set of orthogonal concepts.
Meter technology : AMR/AMI/Electromechanical
Direction : Forward/Reverse/Bidirectional
Payment settlement terms : Prepaid
Billing / settlement : NetMeter
Once can have a AMI, bidirectional, prepaid, netmetering meter.
The terms are also not obvious - e.g. Forward/Reverse. Would terms like Import/Export be easier?
|
|
||
| | Field | Type | Required | Description | | ||
| |-------|------|----------|-------------| | ||
| | `premisesType` | enum | Yes | `Residential`, `Commercial`, `Industrial`, or `Agricultural` | |
There was a problem hiding this comment.
Shouldn't premiseType be part of customer profile
|
|
||
| | Field | Type | Required | Description | | ||
| |-------|------|----------|-------------| | ||
| | `assetId` | string | No | Unique identifier for the generation asset | |
There was a problem hiding this comment.
This is a customer profile - should it be limited to 1 asset. What if I have solar and wind both installed?
| | `generationType` | enum | Yes | `Solar`, `Wind`, `MicroHydro`, or `Other` | | ||
| | `capacityKW` | number | Yes | Installed generation capacity in kW | | ||
| | `commissioningDate` | date-time | Yes | Date and time when the system was activated | | ||
| | `manufacturer` | string | No | Equipment manufacturer | |
There was a problem hiding this comment.
Is this manufacturer of inverter / grid connection / ...?
Restructure the schemas repo around a stable, versioned URL pattern
(`schemas/<name>/v<version>/schema.json`) and replace placeholder content
with real JSON Schemas.
Cleanup:
- Drop space-in-name `energy credentials/` directory
- Move `schemas/salary-slip/{schema.json,README.md}` -> `schemas/salary-slip/v1/`
- Rename the existing `schema.json` (which was a sample instance, not a
schema) to `example.json` and add a real JSON Schema alongside it
- Fix typo in root README, list available schemas, document URL pattern
and immutability/versioning policy
- Add CONTRIBUTING.md describing add/revise workflow
Real schemas added under `schemas/<name>/v1/` with `$id` matching their
raw GitHub URL:
- education, employment, identity, health, business
(sourced from OpenCred's bundled built-in templates)
- electricity (Customer Credential, sourced from beckn/DEG#208 with
upstream attribution)
All schemas validated with ajv (draft-07 and 2020-12). Both examples
(electricity, salary-slip) validate against their schemas.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Restructure the schemas repo around a stable, versioned URL pattern
(`schemas/<name>/v<version>/schema.json`) and replace placeholder content
with real JSON Schemas.
Cleanup:
- Drop space-in-name `energy credentials/` directory
- Move `schemas/salary-slip/{schema.json,README.md}` -> `schemas/salary-slip/v1/`
- Rename the existing `schema.json` (which was a sample instance, not a
schema) to `example.json` and add a real JSON Schema alongside it
- Fix typo in root README, list available schemas, document URL pattern
and immutability/versioning policy
- Add CONTRIBUTING.md describing add/revise workflow
Real schemas added under `schemas/<name>/v1/` with `$id` matching their
raw GitHub URL:
- education, employment, identity, health, business
(sourced from OpenCred's bundled built-in templates)
- electricity (Customer Credential, sourced from beckn/DEG#208 with
upstream attribution)
All schemas validated with ajv (draft-07 and 2020-12). Both examples
(electricity, salary-slip) validate against their schemas.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
Consolidates four separate energy Verifiable Credentials (utility-customer, consumption-profile, generation-profile, storage-profile) into a single Customer Credential (
electricity-credential/) and restructures the Program Enrollment Credential to share data objects with it.What changed
Unified credential: A single
CustomerCredential(W3C VC 2.0) issued per meter, with five sections undercredentialSubject:customerProfile(required) — customer number, meter number, meterType enum (from Green Button/ESPI), identity referencecustomerDetails(required) — name, installation address (aligned with beckn Location schema +openLocationCode), service connection dateconsumptionProfile(optional) — premises type, connection type, sanctioned load, tariffgenerationProfile(optional) — DER type, capacity, commissioning date, manufacturerstorageProfile(optional) — battery capacity, power rating, storage typeW3C VC Data Model 2.0 upgrade: Both credentials now use
validFrom/validUntil(replacesissuanceDate/expirationDate), credentials/v2 context, and all date-time values carry explicit timezone offsets.Reusable patterns introduced:
idRef(issuedByDID +subjectId) — replaceslicenseNumberon issuers andmaskedIdNumber/maskedIdTypeon customerscredentialStatus— structured DeDi revocation withstatusPurposeandstatusListCredentialProgram Enrollment restructured:
credentialSubjectnow uses optionalcustomerProfileandcustomerDetailsobjects (same shape as the Customer Credential) instead of flatconsumerNumber/fullNamefields.enrollmentValidUntilreplacesvalidUntilto avoid collision with the VC-level field.Namespace migration:
utility:→deg:prefix; all context/schema URLs moved fromnfh-trust-labs.github.iotoschema.beckn.io.Old schemas archived: The four individual profile VCs moved to
eos-schemas/for reference.Files added/changed
electricity-credential/program-enrollment-vc/eos-schemas/readme.md(top-level)examples/program-enrollment-vc.jsonTest plan
electricity-credential/example.jsonagainstelectricity-credential/schema.jsonusing a JSON Schema draft 2020-12 validatorprogram-enrollment-vc/example.jsonagainstprogram-enrollment-vc/schema.json@contextURLs in both examples resolve or are consistent withschema.beckn.ioconventionseos-schemas/contains all original files (no data loss from the archive move)🤖 Generated with Claude Code