cimprofiles 0.1.0a2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cimprofiles-0.1.0a2/.gitignore +69 -0
- cimprofiles-0.1.0a2/CIMTool_plugin/LICENSE +29 -0
- cimprofiles-0.1.0a2/LICENSE +29 -0
- cimprofiles-0.1.0a2/PKG-INFO +128 -0
- cimprofiles-0.1.0a2/README.md +105 -0
- cimprofiles-0.1.0a2/pyproject.toml +57 -0
- cimprofiles-0.1.0a2/src/cimprofiles/README.md +291 -0
- cimprofiles-0.1.0a2/src/cimprofiles/__init__.py +36 -0
- cimprofiles-0.1.0a2/src/cimprofiles/build_merged_profiles.py +261 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim16/cim16v33/__init__.py +789 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim16/cim16v33/cim16v33.py +39396 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim16/cim16v33/cim16v33.rdfs-t2b.md +26221 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/__init__.py +2696 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/core_equipment/__init__.py +250 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/core_equipment/core_equipment.py +12615 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/diagram/__init__.py +29 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/diagram/diagram_layout.py +815 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/dynamics/__init__.py +9 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/dynamics/dynamics.py +18 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/equipment_boundary/__init__.py +34 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/equipment_boundary/equipment_boundary.py +1088 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/geographical_location/__init__.py +22 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/geographical_location/geographical_location.py +824 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/operation/__init__.py +67 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/operation/operation.py +2447 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/short_circuit/__init__.py +65 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/short_circuit/short_circuit.py +3769 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/state_variables/__init__.py +42 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/state_variables/state_variables.py +2286 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/steady_state_hypothesis/__init__.py +111 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/steady_state_hypothesis/steady_state_hypothesis.py +4112 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/topology/__init__.py +32 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cgmes_3_0_0/topology/topology.py +712 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cim17v40/__init__.py +1719 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cim17v40/cim17v40.py +177479 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cimhub_2023/__init__.py +621 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cimhub_2023/cimhub_2023.py +28616 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/cimhub_2023/cimhub_2023.rdfs-t2b.md +18888 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/gridappsd_rc4_2021/__init__.py +831 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim17/gridappsd_rc4_2021/rc4_2021.py +49017 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gad/__init__.py +2054 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gad/cim18v15.py +198592 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/__init__.py +1133 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/asset/Asset.rdfs-t2b.md +781 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/asset/__init__.py +41 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/asset/asset.py +1427 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/canonical/__init__.py +928 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/canonical/canonical.py +65313 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/connectivity/UnbalancedConnectivity.rdfs-t2b.md +2541 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/connectivity/__init__.py +76 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/connectivity/connectivity.py +2791 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/diagram/__init__.py +26 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/diagram/diagram.py +758 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/electrical/UnbalancedElectrical.rdfs-t2b.md +3044 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/electrical/__init__.py +140 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/electrical/electrical.py +4107 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/location/GeographicalLocation.rdfs-t2b.md +969 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/location/__init__.py +69 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/location/location.py +1103 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/marketnode/__init__.py +15 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cim18gmdm/marketnode/marketnode.py +180 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cimhub_2026/__init__.py +550 -0
- cimprofiles-0.1.0a2/src/cimprofiles/cim18/cimhub_2026/cimhub_2026.py +33382 -0
- cimprofiles-0.1.0a2/src/cimprofiles/dedupe_profile_fields.py +150 -0
- cimprofiles-0.1.0a2/src/cimprofiles/env_vars.py +48 -0
- cimprofiles-0.1.0a2/src/cimprofiles/identity.py +453 -0
- cimprofiles-0.1.0a2/src/cimprofiles/merge.py +472 -0
- cimprofiles-0.1.0a2/src/cimprofiles/merge_releases.yaml +33 -0
- cimprofiles-0.1.0a2/src/cimprofiles/units/__init__.py +2 -0
- cimprofiles-0.1.0a2/src/cimprofiles/units/cim_units/__init__.py +2 -0
- cimprofiles-0.1.0a2/src/cimprofiles/units/cim_units/unit_multiplier.py +113 -0
- cimprofiles-0.1.0a2/src/cimprofiles/units/cim_units/unit_symbol.py +660 -0
- cimprofiles-0.1.0a2/src/cimprofiles/units/cim_units/units.txt +95 -0
- cimprofiles-0.1.0a2/src/cimprofiles/units/units.py +67 -0
- cimprofiles-0.1.0a2/tests/test_cim_profile.py +30 -0
- cimprofiles-0.1.0a2/tests/test_merge_profiles.py +281 -0
- cimprofiles-0.1.0a2/tests/test_profile_fields.py +32 -0
- cimprofiles-0.1.0a2/tests/test_uuid.py +345 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
.vscode/*
|
|
2
|
+
.metadata/*
|
|
3
|
+
# Compiled class file
|
|
4
|
+
*.class
|
|
5
|
+
|
|
6
|
+
# Log file
|
|
7
|
+
*.log
|
|
8
|
+
|
|
9
|
+
# BlueJ files
|
|
10
|
+
*.ctxt
|
|
11
|
+
|
|
12
|
+
# Mobile Tools for Java (J2ME)
|
|
13
|
+
.mtj.tmp/
|
|
14
|
+
|
|
15
|
+
# Package Files #
|
|
16
|
+
*.jar
|
|
17
|
+
*.war
|
|
18
|
+
*.nar
|
|
19
|
+
*.ear
|
|
20
|
+
*.zip
|
|
21
|
+
*.tar.gz
|
|
22
|
+
*.rar
|
|
23
|
+
|
|
24
|
+
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
|
25
|
+
hs_err_pid*
|
|
26
|
+
replay_pid*
|
|
27
|
+
|
|
28
|
+
# Python bytecode and extensions
|
|
29
|
+
__pycache__/
|
|
30
|
+
*.py[cod]
|
|
31
|
+
*$py.class
|
|
32
|
+
*.so
|
|
33
|
+
|
|
34
|
+
# Python packaging and build output
|
|
35
|
+
build/
|
|
36
|
+
dist/
|
|
37
|
+
*.egg-info/
|
|
38
|
+
*.egg
|
|
39
|
+
.eggs/
|
|
40
|
+
wheels/
|
|
41
|
+
sdist/
|
|
42
|
+
|
|
43
|
+
# Virtual environments
|
|
44
|
+
.venv/
|
|
45
|
+
venv/
|
|
46
|
+
env/
|
|
47
|
+
.python-version
|
|
48
|
+
|
|
49
|
+
# Test, coverage and type-checker caches
|
|
50
|
+
.pytest_cache/
|
|
51
|
+
.coverage
|
|
52
|
+
.coverage.*
|
|
53
|
+
htmlcov/
|
|
54
|
+
coverage.xml
|
|
55
|
+
.tox/
|
|
56
|
+
.nox/
|
|
57
|
+
.mypy_cache/
|
|
58
|
+
.ruff_cache/
|
|
59
|
+
.pyright/
|
|
60
|
+
.hypothesis/
|
|
61
|
+
|
|
62
|
+
# Jupyter
|
|
63
|
+
.ipynb_checkpoints/
|
|
64
|
+
|
|
65
|
+
# Documentation site build (mkdocs)
|
|
66
|
+
site/
|
|
67
|
+
|
|
68
|
+
# Local environment files
|
|
69
|
+
.env
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024, Battelle Memorial Institute; All rights reserved.
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
9
|
+
this list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its contributors
|
|
16
|
+
may be used to endorse or promote products derived from this software without
|
|
17
|
+
specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
22
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
23
|
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
24
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
25
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
26
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
27
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
28
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
29
|
+
THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024, Battelle Memorial Institute; All rights reserved.
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
9
|
+
this list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its contributors
|
|
16
|
+
may be used to endorse or promote products derived from this software without
|
|
17
|
+
specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
22
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
23
|
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
24
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
25
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
26
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
27
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
28
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
29
|
+
THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: cimprofiles
|
|
3
|
+
Version: 0.1.0a2
|
|
4
|
+
Summary: CIM data profiles (Python dataclasses) and the Identity/units object model used by CIMantic Graphs
|
|
5
|
+
Project-URL: Homepage, https://github.com/PNNL-CIM-Tools/CIM-Profiles
|
|
6
|
+
Project-URL: Repository, https://github.com/PNNL-CIM-Tools/CIM-Profiles
|
|
7
|
+
Project-URL: Issues, https://github.com/PNNL-CIM-Tools/CIM-Profiles/issues
|
|
8
|
+
Author-email: "A. Anderson" <19935503+AAndersn@users.noreply.github.com>, "C. Allwardt" <3979063+craig8@users.noreply.github.com>
|
|
9
|
+
License-Expression: BSD-3-Clause
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: cgmes,cim,iec-61968,iec-61970,power-systems
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Requires-Python: <4.0,>=3.10
|
|
21
|
+
Requires-Dist: pint>=0.24.4
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# CIM-Profiles
|
|
25
|
+
|
|
26
|
+
CIMTool workspaces for the CIM 16–18 profiles, and the `cimprofiles` Python package built from
|
|
27
|
+
them. These files originally shipped as part of cim-graph 0.1.x through 0.5.x.
|
|
28
|
+
|
|
29
|
+
`cimprofiles` ships the CIM profiles as Python dataclasses, together with the object model they
|
|
30
|
+
are built on (`Identity`, `CIMUnit`, profile merging). It depends only on `pint`, and it is
|
|
31
|
+
released separately from [cim-graph](https://github.com/PNNL-CIM-Tools/CIM-Graph). Profile updates
|
|
32
|
+
(new classes from EA tickets, new profiles) therefore don't wait for a cim-graph release.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install cimprofiles
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
import cimprofiles.cim18.cimhub_2026 as cim
|
|
40
|
+
|
|
41
|
+
line = cim.ACLineSegment(name='line_1')
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
cim-graph 0.6 and later depend on `cimprofiles`. The old `cimgraph.data_profile.*` import paths
|
|
45
|
+
still work there, with a `DeprecationWarning`.
|
|
46
|
+
|
|
47
|
+
## Repository layout
|
|
48
|
+
|
|
49
|
+
| Path | Contents |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `cim17v40/`, `cim18v15/` | CIMTool workspaces. The Sparx EA `.eap` models are stored with Git LFS. |
|
|
52
|
+
| `CIMTool_plugin/` | The cimantic-graphs XSLT builders and their documentation |
|
|
53
|
+
| `src/cimprofiles/` | The Python package, with profiles grouped by CIM version (`cim16/`, `cim17/`, `cim18/`). See [`src/cimprofiles/README.md`](src/cimprofiles/README.md) for the available profiles and how merging works. |
|
|
54
|
+
| `scripts/import_cimtool_output.sh` | Copies a profile generated by CIMTool into `src/cimprofiles/` and rewrites its imports |
|
|
55
|
+
| `tests/` | Tests for `Identity`, UUIDs, merging and the generated profiles |
|
|
56
|
+
|
|
57
|
+
## Seeded UUIDs
|
|
58
|
+
|
|
59
|
+
Deterministic identifiers are what downstream converters (ArcGIS, OpenDSS, ...) rely on to give
|
|
60
|
+
the same equipment the same RDF ID on every run. `Identity.identifier` is a UUID (CIM 18):
|
|
61
|
+
either the one given, or a deterministic construct. There are two cases.
|
|
62
|
+
|
|
63
|
+
**Read from a file:** the `rdf:ID`/`rdf:about` *is* the UUID, in any serialization
|
|
64
|
+
(`urn:uuid:…`, `#_…`, `_…`, any case). The name is not used. An identifier that is not a UUID is
|
|
65
|
+
replaced, with a warning, by the UUID seeded from it (below), so reading the same file again
|
|
66
|
+
gives the same UUIDs. The original string is kept as the mRID, unless the file has an mRID.
|
|
67
|
+
Readers key their graphs with `cimprofiles.identity.read_identifier`, which gives the same UUID.
|
|
68
|
+
|
|
69
|
+
**Built** (converters, notebooks): a new object, deterministic only for the same model
|
|
70
|
+
authority, model, class, mRID and name. A renamed object (bus 300 to bus 301) is a different
|
|
71
|
+
object and gets a different UUID. A UUID given as the mRID is used directly.
|
|
72
|
+
|
|
73
|
+
The seeded UUID is version 5 (RFC 9562 §5.5):
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
namespace = uuid5(NAMESPACE_URL, model_authority)
|
|
77
|
+
uuid = uuid5(namespace, f'{model_name}+{ClassName}+{mRID}+{name}+{seed}')
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
- `model_authority` is a URI (`CIMG_MODEL_AUTHORITY`, default
|
|
81
|
+
`https://github.com/PNNL-CIM-Tools/CIM-Graph`), as in `md:Model.modelingAuthoritySet`. The
|
|
82
|
+
namespace is also the identifier of the `cim:ModelAuthority` object cim-graph writes in file
|
|
83
|
+
headers, so each authority's UUIDs live in its own namespace.
|
|
84
|
+
- `model_name` comes from `CIMG_MODEL_NAME` (default empty).
|
|
85
|
+
- `mRID` is the object's mRID, or the non-UUID `rdf:ID`/`rdf:about` of an object read from a
|
|
86
|
+
file. It is normalized so every serialization of one object agrees: surrounding whitespace, a
|
|
87
|
+
`urn:uuid:` prefix, everything up to the last `#` and one leading `_` are removed.
|
|
88
|
+
`rdf:ID="_LINE1"`, `rdf:about="#_LINE1"` and `mRID="LINE1"` give the same UUID. Case is kept.
|
|
89
|
+
- `name` (whitespace-trimmed) and `seed` (passed to `obj.uuid(seed=...)`) are optional.
|
|
90
|
+
- Every component keeps its position even when empty, and `%` and `+` inside a component are
|
|
91
|
+
escaped as `%25` and `%2B`, so two different inputs never produce the same string.
|
|
92
|
+
- No identifying input at all (or only empty/blank values) gives a random version 4 UUID.
|
|
93
|
+
|
|
94
|
+
`obj.uri()` returns the bare UUID: lowercase, or uppercase if it was read uppercase (CIMHub and
|
|
95
|
+
GridAPPS-D data), so writing a file back reproduces its identifiers. Underscores and
|
|
96
|
+
`urn:uuid:` prefixes belong to the serialization style and are added by cim-graph's writers
|
|
97
|
+
and queries (`CIMG_IEC61970_552`: `552-NEW`, `552-LEGACY` or `CGMES`).
|
|
98
|
+
|
|
99
|
+
`cimprofiles.identity.seeded_uuid` and `model_authority_namespace` implement the seeded UUID, and any
|
|
100
|
+
language with a UUID library can reproduce it from this description.
|
|
101
|
+
|
|
102
|
+
## Updating a profile
|
|
103
|
+
|
|
104
|
+
1. Regenerate it in CIMTool with the cimantic-graphs builders (`CIMTool_plugin/builder.md`).
|
|
105
|
+
2. Import it. This rewrites the `cimgraph.data_profile` imports emitted by CIMTool before 2.3.1:
|
|
106
|
+
```bash
|
|
107
|
+
scripts/import_cimtool_output.sh cim17 <Profiles/name.py> <Profiles/name.__init__.py>
|
|
108
|
+
```
|
|
109
|
+
The first argument is the CIM version directory. A fourth argument names the package
|
|
110
|
+
directory when it differs from the envelope name (`gridappsd_rc4_2021` for `rc4_2021`).
|
|
111
|
+
3. Check for duplicate field definitions, and rebuild the pre-baked merged profiles if it is one
|
|
112
|
+
of their parts:
|
|
113
|
+
```bash
|
|
114
|
+
uv run python -m cimprofiles.dedupe_profile_fields --check
|
|
115
|
+
uv run python -m cimprofiles.build_merged_profiles
|
|
116
|
+
```
|
|
117
|
+
4. Run the tests: `uv run pytest`.
|
|
118
|
+
|
|
119
|
+
## Development
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
uv sync
|
|
123
|
+
uv run pytest
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## License
|
|
127
|
+
|
|
128
|
+
BSD 3-Clause. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# CIM-Profiles
|
|
2
|
+
|
|
3
|
+
CIMTool workspaces for the CIM 16–18 profiles, and the `cimprofiles` Python package built from
|
|
4
|
+
them. These files originally shipped as part of cim-graph 0.1.x through 0.5.x.
|
|
5
|
+
|
|
6
|
+
`cimprofiles` ships the CIM profiles as Python dataclasses, together with the object model they
|
|
7
|
+
are built on (`Identity`, `CIMUnit`, profile merging). It depends only on `pint`, and it is
|
|
8
|
+
released separately from [cim-graph](https://github.com/PNNL-CIM-Tools/CIM-Graph). Profile updates
|
|
9
|
+
(new classes from EA tickets, new profiles) therefore don't wait for a cim-graph release.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install cimprofiles
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
import cimprofiles.cim18.cimhub_2026 as cim
|
|
17
|
+
|
|
18
|
+
line = cim.ACLineSegment(name='line_1')
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
cim-graph 0.6 and later depend on `cimprofiles`. The old `cimgraph.data_profile.*` import paths
|
|
22
|
+
still work there, with a `DeprecationWarning`.
|
|
23
|
+
|
|
24
|
+
## Repository layout
|
|
25
|
+
|
|
26
|
+
| Path | Contents |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `cim17v40/`, `cim18v15/` | CIMTool workspaces. The Sparx EA `.eap` models are stored with Git LFS. |
|
|
29
|
+
| `CIMTool_plugin/` | The cimantic-graphs XSLT builders and their documentation |
|
|
30
|
+
| `src/cimprofiles/` | The Python package, with profiles grouped by CIM version (`cim16/`, `cim17/`, `cim18/`). See [`src/cimprofiles/README.md`](src/cimprofiles/README.md) for the available profiles and how merging works. |
|
|
31
|
+
| `scripts/import_cimtool_output.sh` | Copies a profile generated by CIMTool into `src/cimprofiles/` and rewrites its imports |
|
|
32
|
+
| `tests/` | Tests for `Identity`, UUIDs, merging and the generated profiles |
|
|
33
|
+
|
|
34
|
+
## Seeded UUIDs
|
|
35
|
+
|
|
36
|
+
Deterministic identifiers are what downstream converters (ArcGIS, OpenDSS, ...) rely on to give
|
|
37
|
+
the same equipment the same RDF ID on every run. `Identity.identifier` is a UUID (CIM 18):
|
|
38
|
+
either the one given, or a deterministic construct. There are two cases.
|
|
39
|
+
|
|
40
|
+
**Read from a file:** the `rdf:ID`/`rdf:about` *is* the UUID, in any serialization
|
|
41
|
+
(`urn:uuid:…`, `#_…`, `_…`, any case). The name is not used. An identifier that is not a UUID is
|
|
42
|
+
replaced, with a warning, by the UUID seeded from it (below), so reading the same file again
|
|
43
|
+
gives the same UUIDs. The original string is kept as the mRID, unless the file has an mRID.
|
|
44
|
+
Readers key their graphs with `cimprofiles.identity.read_identifier`, which gives the same UUID.
|
|
45
|
+
|
|
46
|
+
**Built** (converters, notebooks): a new object, deterministic only for the same model
|
|
47
|
+
authority, model, class, mRID and name. A renamed object (bus 300 to bus 301) is a different
|
|
48
|
+
object and gets a different UUID. A UUID given as the mRID is used directly.
|
|
49
|
+
|
|
50
|
+
The seeded UUID is version 5 (RFC 9562 §5.5):
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
namespace = uuid5(NAMESPACE_URL, model_authority)
|
|
54
|
+
uuid = uuid5(namespace, f'{model_name}+{ClassName}+{mRID}+{name}+{seed}')
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- `model_authority` is a URI (`CIMG_MODEL_AUTHORITY`, default
|
|
58
|
+
`https://github.com/PNNL-CIM-Tools/CIM-Graph`), as in `md:Model.modelingAuthoritySet`. The
|
|
59
|
+
namespace is also the identifier of the `cim:ModelAuthority` object cim-graph writes in file
|
|
60
|
+
headers, so each authority's UUIDs live in its own namespace.
|
|
61
|
+
- `model_name` comes from `CIMG_MODEL_NAME` (default empty).
|
|
62
|
+
- `mRID` is the object's mRID, or the non-UUID `rdf:ID`/`rdf:about` of an object read from a
|
|
63
|
+
file. It is normalized so every serialization of one object agrees: surrounding whitespace, a
|
|
64
|
+
`urn:uuid:` prefix, everything up to the last `#` and one leading `_` are removed.
|
|
65
|
+
`rdf:ID="_LINE1"`, `rdf:about="#_LINE1"` and `mRID="LINE1"` give the same UUID. Case is kept.
|
|
66
|
+
- `name` (whitespace-trimmed) and `seed` (passed to `obj.uuid(seed=...)`) are optional.
|
|
67
|
+
- Every component keeps its position even when empty, and `%` and `+` inside a component are
|
|
68
|
+
escaped as `%25` and `%2B`, so two different inputs never produce the same string.
|
|
69
|
+
- No identifying input at all (or only empty/blank values) gives a random version 4 UUID.
|
|
70
|
+
|
|
71
|
+
`obj.uri()` returns the bare UUID: lowercase, or uppercase if it was read uppercase (CIMHub and
|
|
72
|
+
GridAPPS-D data), so writing a file back reproduces its identifiers. Underscores and
|
|
73
|
+
`urn:uuid:` prefixes belong to the serialization style and are added by cim-graph's writers
|
|
74
|
+
and queries (`CIMG_IEC61970_552`: `552-NEW`, `552-LEGACY` or `CGMES`).
|
|
75
|
+
|
|
76
|
+
`cimprofiles.identity.seeded_uuid` and `model_authority_namespace` implement the seeded UUID, and any
|
|
77
|
+
language with a UUID library can reproduce it from this description.
|
|
78
|
+
|
|
79
|
+
## Updating a profile
|
|
80
|
+
|
|
81
|
+
1. Regenerate it in CIMTool with the cimantic-graphs builders (`CIMTool_plugin/builder.md`).
|
|
82
|
+
2. Import it. This rewrites the `cimgraph.data_profile` imports emitted by CIMTool before 2.3.1:
|
|
83
|
+
```bash
|
|
84
|
+
scripts/import_cimtool_output.sh cim17 <Profiles/name.py> <Profiles/name.__init__.py>
|
|
85
|
+
```
|
|
86
|
+
The first argument is the CIM version directory. A fourth argument names the package
|
|
87
|
+
directory when it differs from the envelope name (`gridappsd_rc4_2021` for `rc4_2021`).
|
|
88
|
+
3. Check for duplicate field definitions, and rebuild the pre-baked merged profiles if it is one
|
|
89
|
+
of their parts:
|
|
90
|
+
```bash
|
|
91
|
+
uv run python -m cimprofiles.dedupe_profile_fields --check
|
|
92
|
+
uv run python -m cimprofiles.build_merged_profiles
|
|
93
|
+
```
|
|
94
|
+
4. Run the tests: `uv run pytest`.
|
|
95
|
+
|
|
96
|
+
## Development
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
uv sync
|
|
100
|
+
uv run pytest
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
BSD 3-Clause. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "cimprofiles"
|
|
3
|
+
version = "0.1.0a2"
|
|
4
|
+
description = "CIM data profiles (Python dataclasses) and the Identity/units object model used by CIMantic Graphs"
|
|
5
|
+
authors = [
|
|
6
|
+
{name = "A. Anderson", email = "19935503+AAndersn@users.noreply.github.com"},
|
|
7
|
+
{name = "C. Allwardt", email = "3979063+craig8@users.noreply.github.com"}
|
|
8
|
+
]
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10,<4.0"
|
|
11
|
+
license = "BSD-3-Clause"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
keywords = ["cim", "power-systems", "iec-61970", "iec-61968", "cgmes"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Intended Audience :: Science/Research",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.10",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Programming Language :: Python :: 3.13",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
dependencies = [
|
|
26
|
+
"pint>=0.24.4",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[dependency-groups]
|
|
30
|
+
dev = [
|
|
31
|
+
"pytest>=8.3.5",
|
|
32
|
+
# build_merged_profiles reads merge_releases.yaml
|
|
33
|
+
"pyyaml>=6.0",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[project.urls]
|
|
37
|
+
Homepage = "https://github.com/PNNL-CIM-Tools/CIM-Profiles"
|
|
38
|
+
Repository = "https://github.com/PNNL-CIM-Tools/CIM-Profiles"
|
|
39
|
+
Issues = "https://github.com/PNNL-CIM-Tools/CIM-Profiles/issues"
|
|
40
|
+
|
|
41
|
+
[build-system]
|
|
42
|
+
requires = ["hatchling>=1.27"]
|
|
43
|
+
build-backend = "hatchling.build"
|
|
44
|
+
|
|
45
|
+
[tool.hatch.build.targets.wheel]
|
|
46
|
+
packages = ["src/cimprofiles"]
|
|
47
|
+
|
|
48
|
+
[tool.hatch.build.targets.sdist]
|
|
49
|
+
include = [
|
|
50
|
+
"/src/cimprofiles",
|
|
51
|
+
"/tests",
|
|
52
|
+
"README.md",
|
|
53
|
+
"LICENSE",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
[tool.pytest.ini_options]
|
|
57
|
+
testpaths = ["tests"]
|