Skip to content

Common Information Model (CIM) Module

The GridLab.Gmss.Cim module provides a comprehensive .NET framework for working with CIM (Common Information Model) power system data according to IEC standards. It offers a complete solution for parsing, managing, and code-generating from CIM-XML documents and RDF schemas used in energy grid operations.

Overview

The CIM module serves as a bridge between the international standards for power system data exchange (IEC 61970 series) and practical .NET application development. It addresses the unique challenges of working with CIMXML data while providing modern, type-safe APIs for developers.

What Problem Does It Solve?

The energy sector relies on CIM for exchanging power system models between utilities, system operators, and market participants. However, working with CIM presents several challenges:

  1. Non-Standard RDF Syntax: CIMXML predates W3C RDF/XML standardization, using legacy formats that standard RDF libraries cannot parse
  2. Missing Datatype Information: CIMXML often omits rdf:datatype attributes, requiring schema-based inference
  3. Complex Multi-Version Support: Multiple CGMES versions (2.4.15, 3.0.0) and profiles must coexist
  4. Identity Management: Three different URI formats for resource identification (rdf:ID, rdf:about, urn:uuid)
  5. Code Generation Needs: Manual class creation from schemas is error-prone and time-consuming

See: CGMES/CIMXML Gaps Documentation for detailed technical challenges and solutions.

Solution Architecture

The module provides three integrated layers:

graph TB
    subgraph "1. RDF Framework Layer"
        A[Graph Context Lifecycle Management]
        B[Entity Repositories CRUD Operations]
        C[Entity Mappers RDF ↔ Domain]
    end

    subgraph "2. CIM Domain Models"
        D[CIM-XML Documents Full & Difference Models]
        E[RDF Schema Models Classes, Properties, Enums]
    end

    subgraph "3. Code Generation"
        F[Model Generator Tool C# / Java / Python]
    end

    subgraph "Applications"
        G[Power System Applications]
        H[Model Exchange Services]
        I[Validation Tools]
    end

    A --> D
    B --> D
    C --> D
    E --> F
    F --> G
    D --> H
    B --> I

Key Features

1. CIM-XML Document Processing

  • Full Model Support: Parse and create complete power system models (md:FullModel)
  • Difference Model Support: Handle incremental updates with forward/reverse/precondition changes (dm:DifferenceModel)
  • Document Metadata: Version tracking, dependencies, supersession chains, modeling authority sets
  • Property Types: Literal values, resource references, and compound structured values
  • URI Normalization: Automatic handling of fragment IDs, URN UUIDs, and absolute URIs

See: Simplified RDF Syntax Specification

2. RDF Schema Management

  • Type-Safe Schema Models: Strongly-typed .NET classes representing CIM RDF Schema elements
  • Multi-Version Support: CGMES 2.4.15 (cim16) and 3.0.0 (CIM100) schemas
  • Inheritance Resolution: Query class hierarchies and inherited properties
  • Stereotype Classification: Concrete classes, enumerations, primitives, CIM datatypes
  • Profile Queries: Search by package, type, multiplicity, and other criteria

See: CIM RDF Schema Domain Models

3. Entity Access Layer

The module provides a complete repository pattern for CRUD operations over RDF graphs:

  • Domain Entity Repositories: Type-safe CRUD operations with RdfGraphRepository<TEntity, TKey>
  • Graph Context Management: Multi-graph lifecycle with RdfGraphContextBase
  • Bidirectional Mapping: Transform between RDF triples and domain entities using IRdfEntityMapper
  • Batch Operations: Efficient InsertMany, UpdateMany, DeleteMany methods
  • Query Support: Find by ID, predicate-based filtering, pagination, and sorting

Architecture:

graph LR
    subgraph "Application Layer"
        App[Application Service]
    end

    subgraph "Repository Layer"
        Repo[RdfGraphRepository]
    end

    subgraph "Mapping Layer"
        Mapper[IRdfEntityMapper]
        Factory[MapperFactory]
    end

    subgraph "Infrastructure Layer"
        Context[RdfGraphContext]
        Reader[Definition Reader]
        Writer[Definition Writer]
    end

    subgraph "Data Layer"
        Graph[IGraph - VDS.RDF]
    end

    App --> Repo
    Repo --> Mapper
    Repo --> Context
    Repo --> Reader
    Repo --> Writer
    Factory --> Mapper
    Context --> Graph
    Reader --> Graph
    Writer --> Graph

See:

4. CIM Identifier Management

The module provides specialized parsing for CIM resource identifiers according to IEC 61970-552:

  • Format Support: URN UUID (urn:uuid:...), Hash format (#_...), rdf:ID format (_...)
  • Validation: Compliance checking for Full Model, Difference Model, and profile identifiers
  • Normalization: Convert between formats with preferred URN UUID output
  • Type Conversion: Parse to Guid or string representations
  • Generation: Create new compliant CIM identifiers

See: Object Identification Documentation

5. Code Generation

Transform CIM RDF schemas into strongly-typed programming language models:

  • Multi-Language: C# (full support), Java (experimental), Python (experimental)
  • Template-Based: Extensible Scriban template system
  • Profile Merging: Combine multiple schema profiles with conflict resolution strategies
  • Batch Processing: Process entire schema directories
  • Customizable Output: Control namespaces, file structure, and code style

Code Generation Pipeline:

graph LR
    A[RDF Schema Files] --> B[Graph Loading]
    B --> C[Schema Parsing]
    C --> D[Validation]
    D --> E[Type Mapping]
    E --> F[Template Rendering]
    F --> G[File Writing]
    G --> H[Generated Code<br/>C# / Java / Python]

User Interface

The module provides an MVC/Razor Pages UI for managing CIM documents and querying RDF graphs.

The module adds a Grid model menu item to the root menu:

Grid Model Menu

  • Document: CIM-XML model documents management page
  • GraphQL: Graph query page for RDF data exploration

The CimMenus class contains constants for menu item names.

Core Components

1. RDF Graph Context

Purpose: Central graph management system for RDF data lifecycle.

Key Capabilities:

  • Multi-graph container management (create, load, dispose)
  • Load from multiple sources (files, URIs, streams, strings)
  • Thread-safe concurrent access with ConcurrentDictionary and SemaphoreSlim
  • Format detection (RDF/XML, Turtle, JSON-LD, N-Triples)
  • Graph initializers for namespace prefixes and configuration
  • HTTP client configuration with timeouts and connection pooling

Configuration via RdfGraphContextOptions:

services.AddCimGraphContext<MyCimGraphContext>(options =>
{
    options.DefaultGraphName = "CIM-Model";
    options.AutoResetOnReload = true;
    options.HttpTimeout = TimeSpan.FromSeconds(60);
    options.GraphInitializers.Add(new CustomNamespaceInitializer());
});

See: Graph Context Documentation


2. Entity Repositories

Purpose: Domain-centric CRUD operations over RDF graphs.

Key Capabilities:

  • Full CRUD operations (Create, Read, Update, Delete)
  • Key-based lookups (O(1) performance)
  • Predicate-based filtering (LINQ expressions)
  • Batch operations for performance
  • Pagination and sorting support
  • Direct graph access for advanced scenarios

Usage Example:

var repository = serviceProvider.GetRequiredService<IRdfGraphRepository<Terminal, Guid>>();

// Read operations
var terminal = repository.Find(terminalId);
var terminals = repository.GetList(t => t.Name.StartsWith("T"));
var paged = repository.GetPagedList(0, 10, "Name ASC");

// Write operations
repository.Insert(newTerminal);
repository.Update(existingTerminal);
repository.Upsert(terminal);
repository.Delete(terminalId);

See: Repository Documentation


3. Entity Mappers

Purpose: Bidirectional transformation between RDF definitions and domain entities.

Key Capabilities:

  • Type-safe mapping with validation
  • Support for required and optional properties
  • Enum parsing with case-insensitive matching
  • Value parsing with invariant culture (floats, integers, booleans)
  • Identity extraction and normalization
  • Optional reverse mapping (Entity → RDF)

Mapping Flow:

sequenceDiagram
    participant Repo as Repository
    participant Mapper as Entity Mapper
    participant Parser as CIM Parsers
    participant Entity as Domain Entity

    Note over Repo,Entity: Read Operation (RDF → Entity)
    Repo->>Mapper: Map(rdfDefinition)
    Mapper->>Parser: ParseGuid(resourceId)
    Parser-->>Mapper: Guid
    Mapper->>Parser: ParseFloat(value)
    Parser-->>Mapper: float
    Mapper->>Entity: new Entity(id, name, value)
    Entity-->>Repo: Entity instance

    Note over Repo,Entity: Write Operation (Entity → RDF)
    Repo->>Mapper: Unmap(entity)
    Mapper->>Mapper: Create IRdfDefinition
    Mapper-->>Repo: RDF Definition

See: Mapper Documentation


4. CIM Identifier Parser

Purpose: Parse and validate CIM resource identifiers per IEC 61970-552.

Key Capabilities:

  • Parse multiple formats: urn:uuid:..., #_..., _...
  • Validate for different contexts (Full Model, Difference Model, Profiles)
  • Extract UUIDs as Guid or string
  • Normalize to preferred format (URN UUID)
  • Generate new compliant identifiers

Usage Example:

var parser = serviceProvider.GetRequiredService<ICimIdentifierParser>();

// Parse various formats
if (parser.TryParseGuid("urn:uuid:26cc8d71-3b7e-4cf8-8c93-8d9d557a4846", out var guid))
{
    // Use guid...
}

// Validate for Full Model (must be URN UUID)
var validForModel = parser.IsValidForModel("urn:uuid:26cc8d71-...");

// Normalize to preferred format
var normalized = parser.Normalize("#_26cc8d71-...");
// Result: "urn:uuid:26cc8d71-..."

// Generate new identifier
var newId = parser.GenerateNewId();

See: Object Identification Documentation


Model Generator Tool

A command-line tool for generating strongly-typed code from CIM RDF schema files.

Features

  • Multi-Language Output: C# (full support), Java (experimental), Python (experimental)
  • Profile Merging: Combine multiple CGMES profiles into unified output
  • Conflict Resolution: Configurable strategies for handling duplicate properties/classes
  • Template Customization: Use custom Scriban templates for code generation
  • Batch Processing: Process entire schema directories
  • Docker Support: Run in containerized environments

Command Line Usage

# Generate C# code from CGMES schemas
dotnet run --project tool/GridLab.Gmss.Cim.ModelGenerator -- \
  --target-language CSharp \
  --base-namespace GridLab.Gmss.Cgmes \
  --output ./Generated \
  --merge-profiles \
  --profile-name CGMES30

# Generate from single schema file
dotnet run --project tool/GridLab.Gmss.Cim.ModelGenerator -- \
  --input ./schemas/EquipmentProfile.rdf \
  --target-language CSharp \
  --output ./Generated

Key Options

Option Short Description
--target-language -t Target language: CSharp, Java, Python
--base-namespace -b Base namespace for generated code
--output -o Output directory path
--merge-profiles -m Merge all schemas into unified output
--profile-name -p Profile name (required when merging)
--merge-strategy Property conflict strategy: KeepAll, KeepFirst, KeepLast, ThrowOnConflict
--overwrite Overwrite existing files
--interfaces -i Generate interface definitions
--classes -c Generate class implementations
--enums -e Generate enum definitions

View all options:

GridLab.Gmss.Cim.ModelGenerator --help

Docker Usage

# Build the Docker image
docker build -t gridlab.gmss.cim.modelgenerator:latest -f Dockerfile.Local .

# Run with mounted volumes
docker run --rm \
  -v /path/to/schemas:/app/schemas:ro \
  -v /path/to/output:/home/app \
  gridlab.gmss.cim.modelgenerator:latest \
  --target-language CSharp \
  --base-namespace GridLab.Gmss.Cgmes \
  --output /home/app \
  --merge-profiles \
  --profile-name CGMES30

Or use Docker Compose:

# Run the included docker-compose setup
.\docker-run.ps1

Technical Highlights

Solving CIMXML Non-Standard RDF

The module includes specialized handling for CIMXML's legacy RDF syntax:

Challenge: CIMXML uses rdf:parseType="Statements" and non-standard URI formats that violate W3C RDF/XML specifications.

Solution:

  • Custom XML reconstruction for difference models
  • URI normalization for _uuid, #_uuid, and urn:uuid: formats
  • Schema-based datatype inference when rdf:datatype is missing

Example:

// Framework automatically handles all three identifier formats:
var id1 = "_26cc8d71-3b7e-4cf8-8c93-8d9d557a4846";       // rdf:ID format
var id2 = "#_26cc8d71-3b7e-4cf8-8c93-8d9d557a4846";     // Hash format
var id3 = "urn:uuid:26cc8d71-3b7e-4cf8-8c93-8d9d557a4846"; // URN UUID

// All resolve to the same resource

See: CGMES/CIMXML Gaps - Section on Non-Standard RDF/XML Serialization

Schema-Based Datatype Inference

Challenge: CIMXML often omits rdf:datatype attributes, making it impossible to distinguish between strings, numbers, dates, etc.

Solution: Two-layer type registry system:

// 1. Property name → CIM datatype (from schema)
// 2. CIM datatype → Primitive type → XSD datatype

// Example: ACLineSegment.bch property
Property Name: "ACLineSegment.bch"
     (Registry Lookup)
CIM Datatype: "Susceptance"
     (Type Chain Resolution)
Primitive: CimPrimitiveType.Float
     (XSD Mapping)
XSD Datatype: "http://www.w3.org/2001/XMLSchema#float"

See: CGMES/CIMXML Gaps - Section on Missing Datatype Information

Graph Metadata Extensions

Track custom metadata for graphs using typed extensions:

// Set model type extension
var metadata = graphContext.GetGraphMetadata("cim-graph");
metadata.SetExtension(new CimModelTypeExtension 
{ 
    ModelType = CimModelType.FullModel 
});

// Retrieve model type
var modelType = metadata.GetExtension<CimModelTypeExtension>()?.ModelType;

See: Graph Context Documentation - GraphMetadata section

Configuration

Graph Context Options

services.AddCimGraphContext<MyCimGraphContext>(options =>
{
    // Basic settings
    options.DefaultGraphName = "CIM-Model";
    options.AutoResetOnReload = true;

    // HTTP configuration
    options.HttpTimeout = TimeSpan.FromSeconds(60);
    options.MaxHttpConnections = 10;

    // Memory management
    options.MemoryStreamThreshold = 10 * 1024 * 1024; // 10MB
    options.StreamBufferSize = 8192; // 8KB

    // Graph initializers (namespace prefixes, defaults)
    options.GraphInitializers.Add(new CustomNamespaceInitializer());
});

CGMES-Aware Registration:

// Automatically configures CIM/CGMES defaults
services.AddCimGraphContext<MyCimGraphContext>();
// Includes: DefaultNamespaceInitializer, DefaultModelTypeInitializer, CgmesBaseUriResolver

Supported Standards

Standard Version Description
IEC 61970-301 2016 Common Information Model (CIM) base standard
IEC 61970-501 2006 CIM RDF Schema specification
IEC 61970-552 2016 CIMXML Model Exchange Specification
CGMES 2.4.15 Common Grid Model Exchange Standard
CGMES 3.0.0 Common Grid Model Exchange Standard

Supported CGMES Profiles

  • EQ - Equipment Profile
  • SSH - Steady State Hypothesis Profile
  • TP - Topology Profile
  • SV - State Variables Profile
  • DY - Dynamics Profile
  • GL - Geographical Location Profile
  • DL - Diagram Layout Profile

Framework Documentation

Topic Description
CGMES/CIMXML Gaps Technical challenges and solutions for non-standard CIMXML
Graph Context RDF graph lifecycle management and data loading
Repositories Entity access layer with CRUD operations
Mappers Bidirectional entity-to-RDF transformation
Object Identification CIM resource identifier parsing and validation
RDF Schema Models Domain models for CIM RDF schemas
Simplified Syntax CIMXML syntax specification per IEC 61970-552

External References