cognite-neat 0.92.2__py3-none-any.whl → 0.93.0__py3-none-any.whl
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.
Potentially problematic release.
This version of cognite-neat might be problematic. Click here for more details.
- cognite/neat/__init__.py +3 -2
- cognite/neat/{app → _app}/api/configuration.py +9 -7
- cognite/neat/_app/api/context_manager/__init__.py +3 -0
- cognite/neat/{app → _app}/api/context_manager/manager.py +1 -1
- cognite/neat/{app → _app}/api/explorer.py +5 -5
- cognite/neat/{app → _app}/api/routers/configuration.py +2 -2
- cognite/neat/{app → _app}/api/routers/crud.py +4 -4
- cognite/neat/{app → _app}/api/routers/workflows.py +7 -7
- cognite/neat/{app → _app}/main.py +1 -1
- cognite/neat/_app/ui/neat-app/package-lock.json +18306 -0
- cognite/neat/_app/ui/neat-app/package.json +62 -0
- cognite/neat/_app/ui/neat-app/public/favicon.ico +0 -0
- cognite/neat/_app/ui/neat-app/public/img/architect-icon.svg +116 -0
- cognite/neat/_app/ui/neat-app/public/img/developer-icon.svg +112 -0
- cognite/neat/_app/ui/neat-app/public/img/sme-icon.svg +34 -0
- cognite/neat/_app/ui/neat-app/public/index.html +43 -0
- cognite/neat/_app/ui/neat-app/public/logo192.png +0 -0
- cognite/neat/_app/ui/neat-app/public/manifest.json +25 -0
- cognite/neat/_app/ui/neat-app/public/robots.txt +3 -0
- cognite/neat/_app/ui/neat-app/src/App.css +38 -0
- cognite/neat/_app/ui/neat-app/src/App.js +17 -0
- cognite/neat/_app/ui/neat-app/src/App.test.js +8 -0
- cognite/neat/_app/ui/neat-app/src/MainContainer.tsx +70 -0
- cognite/neat/_app/ui/neat-app/src/components/JsonViewer.tsx +43 -0
- cognite/neat/_app/ui/neat-app/src/components/LocalUploader.tsx +124 -0
- cognite/neat/_app/ui/neat-app/src/components/OverviewComponentEditorDialog.tsx +63 -0
- cognite/neat/_app/ui/neat-app/src/components/StepEditorDialog.tsx +511 -0
- cognite/neat/_app/ui/neat-app/src/components/TabPanel.tsx +36 -0
- cognite/neat/_app/ui/neat-app/src/components/Utils.tsx +56 -0
- cognite/neat/_app/ui/neat-app/src/components/WorkflowDeleteDialog.tsx +60 -0
- cognite/neat/_app/ui/neat-app/src/components/WorkflowExecutionReport.tsx +112 -0
- cognite/neat/_app/ui/neat-app/src/components/WorkflowImportExportDialog.tsx +67 -0
- cognite/neat/_app/ui/neat-app/src/components/WorkflowMetadataDialog.tsx +79 -0
- cognite/neat/_app/ui/neat-app/src/index.css +13 -0
- cognite/neat/_app/ui/neat-app/src/index.js +13 -0
- cognite/neat/_app/ui/neat-app/src/logo.svg +1 -0
- cognite/neat/_app/ui/neat-app/src/reportWebVitals.js +13 -0
- cognite/neat/_app/ui/neat-app/src/setupTests.js +5 -0
- cognite/neat/_app/ui/neat-app/src/types/WorkflowTypes.ts +388 -0
- cognite/neat/_app/ui/neat-app/src/views/AboutView.tsx +61 -0
- cognite/neat/_app/ui/neat-app/src/views/ConfigView.tsx +184 -0
- cognite/neat/_app/ui/neat-app/src/views/GlobalConfigView.tsx +180 -0
- cognite/neat/_app/ui/neat-app/src/views/WorkflowView.tsx +570 -0
- cognite/neat/_app/ui/neat-app/tsconfig.json +27 -0
- cognite/neat/{config.py → _config.py} +3 -3
- cognite/neat/{constants.py → _constants.py} +13 -5
- cognite/neat/_graph/_shared.py +34 -0
- cognite/neat/{graph → _graph}/_tracking/base.py +1 -1
- cognite/neat/{graph → _graph}/_tracking/log.py +1 -1
- cognite/neat/{graph → _graph}/extractors/__init__.py +5 -0
- cognite/neat/{graph → _graph}/extractors/_base.py +2 -2
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_assets.py +1 -1
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_base.py +4 -4
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_classic.py +5 -5
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_data_sets.py +1 -1
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_events.py +1 -1
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_files.py +1 -1
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_labels.py +1 -1
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_relationships.py +2 -2
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_sequences.py +1 -1
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_timeseries.py +1 -1
- cognite/neat/{graph → _graph}/extractors/_dexpi.py +5 -5
- cognite/neat/{graph → _graph}/extractors/_dms.py +3 -3
- cognite/neat/_graph/extractors/_iodd.py +402 -0
- cognite/neat/{graph → _graph}/extractors/_mock_graph_generator.py +9 -8
- cognite/neat/_graph/extractors/_rdf_file.py +49 -0
- cognite/neat/{graph → _graph}/loaders/_base.py +5 -5
- cognite/neat/{graph → _graph}/loaders/_rdf2asset.py +11 -10
- cognite/neat/{graph → _graph}/loaders/_rdf2dms.py +10 -10
- cognite/neat/{graph → _graph}/queries/_base.py +91 -19
- cognite/neat/{graph → _graph}/queries/_construct.py +5 -5
- cognite/neat/{graph → _graph}/queries/_shared.py +3 -3
- cognite/neat/{graph → _graph}/transformers/__init__.py +6 -0
- cognite/neat/{graph → _graph}/transformers/_classic_cdf.py +135 -3
- cognite/neat/_graph/transformers/_iodd.py +25 -0
- cognite/neat/_graph/transformers/_prune_graph.py +126 -0
- cognite/neat/{graph → _graph}/transformers/_rdfpath.py +3 -3
- cognite/neat/_graph/transformers/_value_type.py +66 -0
- cognite/neat/{issues → _issues}/_base.py +32 -17
- cognite/neat/{issues → _issues}/errors/__init__.py +1 -1
- cognite/neat/{issues → _issues}/errors/_external.py +8 -8
- cognite/neat/{issues → _issues}/errors/_general.py +5 -5
- cognite/neat/{issues → _issues}/errors/_properties.py +7 -7
- cognite/neat/{issues → _issues}/errors/_resources.py +11 -11
- cognite/neat/{issues → _issues}/errors/_workflow.py +5 -5
- cognite/neat/{issues → _issues}/warnings/__init__.py +1 -1
- cognite/neat/{issues → _issues}/warnings/_external.py +5 -5
- cognite/neat/{issues → _issues}/warnings/_general.py +4 -4
- cognite/neat/{issues → _issues}/warnings/_models.py +10 -10
- cognite/neat/{issues → _issues}/warnings/_properties.py +6 -6
- cognite/neat/{issues → _issues}/warnings/_resources.py +5 -5
- cognite/neat/{issues → _issues}/warnings/user_modeling.py +9 -9
- cognite/neat/_rules/_constants.py +190 -0
- cognite/neat/{rules → _rules}/_shared.py +5 -5
- cognite/neat/_rules/analysis/__init__.py +5 -0
- cognite/neat/{rules → _rules}/analysis/_asset.py +5 -5
- cognite/neat/{rules → _rules}/analysis/_base.py +5 -5
- cognite/neat/_rules/analysis/_dms.py +43 -0
- cognite/neat/{rules → _rules}/analysis/_information.py +12 -6
- cognite/neat/_rules/catalog/__init__.py +6 -0
- cognite/neat/_rules/catalog/info-rules-imf.xlsx +0 -0
- cognite/neat/{rules → _rules}/exporters/__init__.py +2 -0
- cognite/neat/{rules → _rules}/exporters/_base.py +3 -3
- cognite/neat/{rules → _rules}/exporters/_rules2dms.py +5 -5
- cognite/neat/{rules → _rules}/exporters/_rules2excel.py +26 -7
- cognite/neat/_rules/exporters/_rules2instance_template.py +152 -0
- cognite/neat/{rules → _rules}/exporters/_rules2ontology.py +10 -9
- cognite/neat/{rules → _rules}/exporters/_rules2yaml.py +1 -3
- cognite/neat/{rules → _rules}/exporters/_validation.py +2 -2
- cognite/neat/{rules → _rules}/importers/_base.py +3 -3
- cognite/neat/{rules → _rules}/importers/_dms2rules.py +9 -9
- cognite/neat/{rules → _rules}/importers/_dtdl2rules/dtdl_converter.py +7 -7
- cognite/neat/{rules → _rules}/importers/_dtdl2rules/dtdl_importer.py +9 -9
- cognite/neat/{rules → _rules}/importers/_dtdl2rules/spec.py +1 -1
- cognite/neat/_rules/importers/_rdf/_base.py +144 -0
- cognite/neat/{rules → _rules}/importers/_rdf/_imf2rules/_imf2classes.py +1 -1
- cognite/neat/{rules → _rules}/importers/_rdf/_imf2rules/_imf2metadata.py +4 -4
- cognite/neat/{rules → _rules}/importers/_rdf/_imf2rules/_imf2properties.py +2 -1
- cognite/neat/{rules → _rules}/importers/_rdf/_imf2rules/_imf2rules.py +8 -39
- cognite/neat/{rules → _rules}/importers/_rdf/_inference2rules.py +33 -106
- cognite/neat/{rules → _rules}/importers/_rdf/_owl2rules/_owl2classes.py +1 -1
- cognite/neat/{rules → _rules}/importers/_rdf/_owl2rules/_owl2metadata.py +5 -5
- cognite/neat/{rules → _rules}/importers/_rdf/_owl2rules/_owl2properties.py +1 -1
- cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2rules.py +39 -0
- cognite/neat/{rules → _rules}/importers/_rdf/_shared.py +4 -4
- cognite/neat/{rules → _rules}/importers/_spreadsheet2rules.py +40 -6
- cognite/neat/{rules → _rules}/importers/_yaml2rules.py +5 -5
- cognite/neat/{rules → _rules}/models/__init__.py +5 -5
- cognite/neat/{rules → _rules}/models/_base_input.py +30 -11
- cognite/neat/{rules → _rules}/models/_base_rules.py +22 -8
- cognite/neat/{rules → _rules}/models/_rdfpath.py +1 -1
- cognite/neat/_rules/models/_types.py +151 -0
- cognite/neat/{rules → _rules}/models/asset/_rules.py +4 -4
- cognite/neat/{rules → _rules}/models/asset/_rules_input.py +4 -4
- cognite/neat/{rules → _rules}/models/asset/_validation.py +7 -7
- cognite/neat/{rules → _rules}/models/data_types.py +15 -12
- cognite/neat/{rules → _rules}/models/dms/_exporter.py +60 -12
- cognite/neat/{rules → _rules}/models/dms/_rules.py +29 -26
- cognite/neat/{rules → _rules}/models/dms/_rules_input.py +4 -4
- cognite/neat/{rules → _rules}/models/dms/_schema.py +15 -14
- cognite/neat/{rules → _rules}/models/dms/_validation.py +8 -8
- cognite/neat/{rules → _rules}/models/domain.py +6 -6
- cognite/neat/{rules → _rules}/models/entities/__init__.py +1 -2
- cognite/neat/_rules/models/entities/_constants.py +15 -0
- cognite/neat/{rules → _rules}/models/entities/_loaders.py +2 -2
- cognite/neat/{rules → _rules}/models/entities/_multi_value.py +15 -2
- cognite/neat/{rules → _rules}/models/entities/_single_value.py +16 -4
- cognite/neat/{rules → _rules}/models/information/_rules.py +37 -25
- cognite/neat/{rules → _rules}/models/information/_rules_input.py +3 -3
- cognite/neat/{rules → _rules}/models/information/_validation.py +6 -5
- cognite/neat/_rules/models/mapping/__init__.py +4 -0
- cognite/neat/_rules/models/mapping/_base.py +131 -0
- cognite/neat/_rules/models/mapping/_classic2core.py +150 -0
- cognite/neat/{rules → _rules}/transformers/__init__.py +15 -2
- cognite/neat/{rules → _rules}/transformers/_base.py +3 -3
- cognite/neat/{rules → _rules}/transformers/_converters.py +289 -20
- cognite/neat/{rules/transformers/_map_onto.py → _rules/transformers/_mapping.py} +46 -4
- cognite/neat/{rules → _rules}/transformers/_pipelines.py +4 -4
- cognite/neat/{rules → _rules}/transformers/_verification.py +10 -4
- cognite/neat/_session/__init__.py +3 -0
- cognite/neat/_session/_base.py +86 -0
- cognite/neat/_session/_prepare.py +61 -0
- cognite/neat/_session/_read.py +118 -0
- cognite/neat/_session/_show.py +96 -0
- cognite/neat/_session/_state.py +69 -0
- cognite/neat/_session/_to.py +70 -0
- cognite/neat/_session/_wizard.py +39 -0
- cognite/neat/_session/exceptions.py +42 -0
- cognite/neat/{store → _store}/_base.py +63 -32
- cognite/neat/{store → _store}/_provenance.py +11 -1
- cognite/neat/{utils → _utils}/auth.py +14 -3
- cognite/neat/{utils → _utils}/auxiliary.py +1 -1
- cognite/neat/{utils → _utils}/cdf/loaders/_data_modeling.py +8 -2
- cognite/neat/{utils → _utils}/cdf/loaders/_ingestion.py +1 -1
- cognite/neat/{utils → _utils}/upload.py +1 -1
- cognite/neat/_version.py +1 -1
- cognite/neat/_workflows/__init__.py +17 -0
- cognite/neat/{workflows → _workflows}/base.py +10 -10
- cognite/neat/{workflows → _workflows}/cdf_store.py +3 -3
- cognite/neat/{workflows → _workflows}/examples/Export_DMS/workflow.yaml +89 -89
- cognite/neat/{workflows → _workflows}/manager.py +6 -6
- cognite/neat/{workflows → _workflows}/steps/data_contracts.py +3 -3
- cognite/neat/{workflows → _workflows}/steps/lib/current/graph_extractor.py +8 -31
- cognite/neat/{workflows → _workflows}/steps/lib/current/graph_loader.py +4 -4
- cognite/neat/{workflows → _workflows}/steps/lib/current/graph_store.py +4 -4
- cognite/neat/{workflows → _workflows}/steps/lib/current/rules_exporter.py +8 -8
- cognite/neat/{workflows → _workflows}/steps/lib/current/rules_importer.py +13 -13
- cognite/neat/{workflows → _workflows}/steps/lib/current/rules_validator.py +8 -8
- cognite/neat/{workflows → _workflows}/steps/lib/io/io_steps.py +3 -3
- cognite/neat/{workflows → _workflows}/steps/step_model.py +3 -3
- cognite/neat/{workflows → _workflows}/steps_registry.py +9 -9
- cognite/neat/{workflows → _workflows}/tasks.py +1 -1
- cognite/neat/{workflows → _workflows}/triggers.py +2 -2
- {cognite_neat-0.92.2.dist-info → cognite_neat-0.93.0.dist-info}/METADATA +6 -2
- cognite_neat-0.93.0.dist-info/RECORD +276 -0
- {cognite_neat-0.92.2.dist-info → cognite_neat-0.93.0.dist-info}/WHEEL +1 -1
- cognite_neat-0.93.0.dist-info/entry_points.txt +3 -0
- cognite/neat/app/api/context_manager/__init__.py +0 -3
- cognite/neat/graph/_shared.py +0 -5
- cognite/neat/graph/extractors/_iodd.py +0 -160
- cognite/neat/graph/extractors/_rdf_file.py +0 -26
- cognite/neat/rules/analysis/__init__.py +0 -6
- cognite/neat/rules/examples/__init__.py +0 -10
- cognite/neat/rules/examples/info-rules-imf.xlsx +0 -0
- cognite/neat/rules/examples/wind-energy.owl +0 -1511
- cognite/neat/rules/importers/_rdf/_owl2rules/_owl2rules.py +0 -65
- cognite/neat/rules/models/_types.py +0 -96
- cognite/neat/rules/models/entities/_constants.py +0 -73
- cognite/neat/utils/regex_patterns.py +0 -58
- cognite/neat/workflows/__init__.py +0 -12
- cognite_neat-0.92.2.dist-info/RECORD +0 -224
- cognite_neat-0.92.2.dist-info/entry_points.txt +0 -3
- /cognite/neat/{app → _app}/api/__init__.py +0 -0
- /cognite/neat/{app → _app}/api/asgi/metrics.py +0 -0
- /cognite/neat/{app → _app}/api/data_classes/__init__.py +0 -0
- /cognite/neat/{app → _app}/api/data_classes/rest.py +0 -0
- /cognite/neat/{app → _app}/api/routers/metrics.py +0 -0
- /cognite/neat/{app → _app}/api/utils/__init__.py +0 -0
- /cognite/neat/{app → _app}/api/utils/data_mapping.py +0 -0
- /cognite/neat/{app → _app}/api/utils/logging.py +0 -0
- /cognite/neat/{app → _app}/api/utils/query_templates.py +0 -0
- /cognite/neat/{app → _app}/monitoring/__init__.py +0 -0
- /cognite/neat/{app → _app}/monitoring/metrics.py +0 -0
- /cognite/neat/{app → _app}/ui/index.html +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/.gitignore +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/README.md +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/asset-manifest.json +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/favicon.ico +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/img/architect-icon.svg +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/img/developer-icon.svg +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/img/sme-icon.svg +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/index.html +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/logo192.png +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/manifest.json +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/robots.txt +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/static/css/main.72e3d92e.css +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/static/css/main.72e3d92e.css.map +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/static/js/main.5a52cf09.js +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/static/js/main.5a52cf09.js.LICENSE.txt +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/static/js/main.5a52cf09.js.map +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/static/media/logo.8093b84df9ed36a174c629d6fe0b730d.svg +0 -0
- /cognite/neat/{graph → _graph}/__init__.py +0 -0
- /cognite/neat/{graph → _graph}/_tracking/__init__.py +0 -0
- /cognite/neat/{graph → _graph}/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
- /cognite/neat/{graph → _graph}/examples/Knowledge-Graph-Nordic44.xml +0 -0
- /cognite/neat/{graph → _graph}/examples/__init__.py +0 -0
- /cognite/neat/{graph → _graph}/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
- /cognite/neat/{graph → _graph}/extractors/_classic_cdf/__init__.py +0 -0
- /cognite/neat/{graph → _graph}/loaders/__init__.py +0 -0
- /cognite/neat/{graph → _graph}/models.py +0 -0
- /cognite/neat/{graph → _graph}/queries/__init__.py +0 -0
- /cognite/neat/{graph → _graph}/transformers/_base.py +0 -0
- /cognite/neat/{issues → _issues}/__init__.py +0 -0
- /cognite/neat/{issues → _issues}/formatters.py +0 -0
- /cognite/neat/{rules → _rules}/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/importers/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/importers/_dtdl2rules/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/importers/_dtdl2rules/_unit_lookup.py +0 -0
- /cognite/neat/{rules → _rules}/importers/_rdf/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/importers/_rdf/_imf2rules/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/importers/_rdf/_owl2rules/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/models/asset/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/models/dms/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/models/entities/_types.py +0 -0
- /cognite/neat/{rules → _rules}/models/entities/_wrapped.py +0 -0
- /cognite/neat/{rules → _rules}/models/information/__init__.py +0 -0
- /cognite/neat/{store → _store}/__init__.py +0 -0
- /cognite/neat/{utils → _utils}/__init__.py +0 -0
- /cognite/neat/{utils → _utils}/cdf/__init__.py +0 -0
- /cognite/neat/{utils → _utils}/cdf/data_classes.py +0 -0
- /cognite/neat/{utils → _utils}/cdf/loaders/__init__.py +0 -0
- /cognite/neat/{utils → _utils}/cdf/loaders/_base.py +0 -0
- /cognite/neat/{utils → _utils}/collection_.py +0 -0
- /cognite/neat/{utils → _utils}/rdf_.py +0 -0
- /cognite/neat/{utils → _utils}/spreadsheet.py +0 -0
- /cognite/neat/{utils → _utils}/text.py +0 -0
- /cognite/neat/{utils → _utils}/time_.py +0 -0
- /cognite/neat/{utils → _utils}/xml_.py +0 -0
- /cognite/neat/{workflows → _workflows}/examples/Export_Semantic_Data_Model/workflow.yaml +0 -0
- /cognite/neat/{workflows → _workflows}/examples/Import_DMS/workflow.yaml +0 -0
- /cognite/neat/{workflows → _workflows}/examples/Validate_Rules/workflow.yaml +0 -0
- /cognite/neat/{workflows → _workflows}/examples/Validate_Solution_Model/workflow.yaml +0 -0
- /cognite/neat/{workflows → _workflows}/model.py +0 -0
- /cognite/neat/{workflows → _workflows}/steps/__init__.py +0 -0
- /cognite/neat/{workflows → _workflows}/steps/lib/__init__.py +0 -0
- /cognite/neat/{workflows → _workflows}/steps/lib/current/__init__.py +0 -0
- /cognite/neat/{workflows → _workflows}/steps/lib/io/__init__.py +0 -0
- /cognite/neat/{workflows → _workflows}/utils.py +0 -0
- {cognite_neat-0.92.2.dist-info → cognite_neat-0.93.0.dist-info}/LICENSE +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from ._base import BaseExtractor
|
|
2
2
|
from ._classic_cdf._assets import AssetsExtractor
|
|
3
3
|
from ._classic_cdf._classic import ClassicGraphExtractor
|
|
4
|
+
from ._classic_cdf._data_sets import DataSetExtractor
|
|
4
5
|
from ._classic_cdf._events import EventsExtractor
|
|
5
6
|
from ._classic_cdf._files import FilesExtractor
|
|
6
7
|
from ._classic_cdf._labels import LabelsExtractor
|
|
@@ -17,6 +18,7 @@ __all__ = [
|
|
|
17
18
|
"BaseExtractor",
|
|
18
19
|
"AssetsExtractor",
|
|
19
20
|
"ClassicGraphExtractor",
|
|
21
|
+
"DataSetExtractor",
|
|
20
22
|
"MockGraphGenerator",
|
|
21
23
|
"RelationshipsExtractor",
|
|
22
24
|
"TimeSeriesExtractor",
|
|
@@ -43,6 +45,9 @@ TripleExtractors = (
|
|
|
43
45
|
| RdfFileExtractor
|
|
44
46
|
| DexpiExtractor
|
|
45
47
|
| IODDExtractor
|
|
48
|
+
| DMSExtractor
|
|
49
|
+
| ClassicGraphExtractor
|
|
50
|
+
| DataSetExtractor
|
|
46
51
|
)
|
|
47
52
|
|
|
48
53
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
from collections.abc import Iterable
|
|
3
3
|
|
|
4
|
-
from cognite.neat.
|
|
5
|
-
from cognite.neat.
|
|
4
|
+
from cognite.neat._graph.models import Triple
|
|
5
|
+
from cognite.neat._utils.auxiliary import class_html_doc
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class BaseExtractor:
|
|
@@ -7,7 +7,7 @@ from cognite.client import CogniteClient
|
|
|
7
7
|
from cognite.client.data_classes import Asset, AssetFilter, AssetList
|
|
8
8
|
from rdflib import RDF, Literal, Namespace
|
|
9
9
|
|
|
10
|
-
from cognite.neat.
|
|
10
|
+
from cognite.neat._graph.models import Triple
|
|
11
11
|
|
|
12
12
|
from ._base import DEFAULT_SKIP_METADATA_VALUES, ClassicCDFBaseExtractor, InstanceIdPrefix
|
|
13
13
|
from ._labels import LabelsExtractor
|
|
@@ -8,10 +8,10 @@ from typing import Generic, TypeVar
|
|
|
8
8
|
from cognite.client.data_classes._base import CogniteResource
|
|
9
9
|
from rdflib import XSD, Literal, Namespace, URIRef
|
|
10
10
|
|
|
11
|
-
from cognite.neat.
|
|
12
|
-
from cognite.neat.
|
|
13
|
-
from cognite.neat.
|
|
14
|
-
from cognite.neat.
|
|
11
|
+
from cognite.neat._constants import DEFAULT_NAMESPACE
|
|
12
|
+
from cognite.neat._graph.extractors._base import BaseExtractor
|
|
13
|
+
from cognite.neat._graph.models import Triple
|
|
14
|
+
from cognite.neat._utils.auxiliary import string_to_ideal_type
|
|
15
15
|
|
|
16
16
|
T_CogniteResource = TypeVar("T_CogniteResource", bound=CogniteResource)
|
|
17
17
|
|
|
@@ -5,11 +5,11 @@ from typing import ClassVar, NamedTuple
|
|
|
5
5
|
from cognite.client import CogniteClient
|
|
6
6
|
from rdflib import Namespace
|
|
7
7
|
|
|
8
|
-
from cognite.neat.
|
|
9
|
-
from cognite.neat.
|
|
10
|
-
from cognite.neat.
|
|
11
|
-
from cognite.neat.
|
|
12
|
-
from cognite.neat.
|
|
8
|
+
from cognite.neat._constants import DEFAULT_NAMESPACE
|
|
9
|
+
from cognite.neat._graph.extractors._base import BaseExtractor
|
|
10
|
+
from cognite.neat._graph.models import Triple
|
|
11
|
+
from cognite.neat._utils.collection_ import chunker
|
|
12
|
+
from cognite.neat._utils.rdf_ import remove_namespace_from_uri
|
|
13
13
|
|
|
14
14
|
from ._assets import AssetsExtractor
|
|
15
15
|
from ._base import ClassicCDFBaseExtractor, InstanceIdPrefix
|
|
@@ -7,7 +7,7 @@ from cognite.client.data_classes import DataSet, DataSetList
|
|
|
7
7
|
from cognite.client.utils.useful_types import SequenceNotStr
|
|
8
8
|
from rdflib import RDF, Literal, Namespace
|
|
9
9
|
|
|
10
|
-
from cognite.neat.
|
|
10
|
+
from cognite.neat._graph.models import Triple
|
|
11
11
|
|
|
12
12
|
from ._base import DEFAULT_SKIP_METADATA_VALUES, ClassicCDFBaseExtractor, InstanceIdPrefix
|
|
13
13
|
|
|
@@ -6,7 +6,7 @@ from cognite.client import CogniteClient
|
|
|
6
6
|
from cognite.client.data_classes import Event, EventFilter, EventList
|
|
7
7
|
from rdflib import RDF, Literal, Namespace
|
|
8
8
|
|
|
9
|
-
from cognite.neat.
|
|
9
|
+
from cognite.neat._graph.models import Triple
|
|
10
10
|
|
|
11
11
|
from ._base import DEFAULT_SKIP_METADATA_VALUES, ClassicCDFBaseExtractor, InstanceIdPrefix
|
|
12
12
|
|
|
@@ -6,7 +6,7 @@ from cognite.client import CogniteClient
|
|
|
6
6
|
from cognite.client.data_classes import FileMetadata, FileMetadataFilter, FileMetadataList
|
|
7
7
|
from rdflib import RDF, Literal, Namespace
|
|
8
8
|
|
|
9
|
-
from cognite.neat.
|
|
9
|
+
from cognite.neat._graph.models import Triple
|
|
10
10
|
|
|
11
11
|
from ._base import DEFAULT_SKIP_METADATA_VALUES, ClassicCDFBaseExtractor, InstanceIdPrefix
|
|
12
12
|
from ._labels import LabelsExtractor
|
|
@@ -7,7 +7,7 @@ from cognite.client import CogniteClient
|
|
|
7
7
|
from cognite.client.data_classes import Label, LabelDefinition, LabelDefinitionList
|
|
8
8
|
from rdflib import RDF, Literal, Namespace
|
|
9
9
|
|
|
10
|
-
from cognite.neat.
|
|
10
|
+
from cognite.neat._graph.models import Triple
|
|
11
11
|
|
|
12
12
|
from ._base import DEFAULT_SKIP_METADATA_VALUES, ClassicCDFBaseExtractor, InstanceIdPrefix
|
|
13
13
|
|
|
@@ -7,8 +7,8 @@ from cognite.client import CogniteClient
|
|
|
7
7
|
from cognite.client.data_classes import Relationship, RelationshipList
|
|
8
8
|
from rdflib import RDF, Literal, Namespace
|
|
9
9
|
|
|
10
|
-
from cognite.neat.
|
|
11
|
-
from cognite.neat.
|
|
10
|
+
from cognite.neat._graph.models import Triple
|
|
11
|
+
from cognite.neat._utils.auxiliary import create_sha256_hash
|
|
12
12
|
|
|
13
13
|
from ._base import DEFAULT_SKIP_METADATA_VALUES, ClassicCDFBaseExtractor, InstanceIdPrefix
|
|
14
14
|
from ._labels import LabelsExtractor
|
|
@@ -6,7 +6,7 @@ from cognite.client import CogniteClient
|
|
|
6
6
|
from cognite.client.data_classes import Sequence, SequenceFilter, SequenceList
|
|
7
7
|
from rdflib import RDF, Literal, Namespace
|
|
8
8
|
|
|
9
|
-
from cognite.neat.
|
|
9
|
+
from cognite.neat._graph.models import Triple
|
|
10
10
|
|
|
11
11
|
from ._base import DEFAULT_SKIP_METADATA_VALUES, ClassicCDFBaseExtractor, InstanceIdPrefix
|
|
12
12
|
|
|
@@ -7,7 +7,7 @@ from cognite.client.data_classes import TimeSeries, TimeSeriesFilter, TimeSeries
|
|
|
7
7
|
from pydantic import AnyHttpUrl, ValidationError
|
|
8
8
|
from rdflib import RDF, Literal, Namespace, URIRef
|
|
9
9
|
|
|
10
|
-
from cognite.neat.
|
|
10
|
+
from cognite.neat._graph.models import Triple
|
|
11
11
|
|
|
12
12
|
from ._base import DEFAULT_SKIP_METADATA_VALUES, ClassicCDFBaseExtractor, InstanceIdPrefix
|
|
13
13
|
|
|
@@ -6,11 +6,11 @@ from xml.etree.ElementTree import Element
|
|
|
6
6
|
|
|
7
7
|
from rdflib import RDF, RDFS, XSD, Literal, Namespace, URIRef
|
|
8
8
|
|
|
9
|
-
from cognite.neat.
|
|
10
|
-
from cognite.neat.
|
|
11
|
-
from cognite.neat.
|
|
12
|
-
from cognite.neat.
|
|
13
|
-
from cognite.neat.
|
|
9
|
+
from cognite.neat._constants import DEFAULT_NAMESPACE
|
|
10
|
+
from cognite.neat._graph.extractors._base import BaseExtractor
|
|
11
|
+
from cognite.neat._graph.models import Triple
|
|
12
|
+
from cognite.neat._utils.rdf_ import as_neat_compliant_uri
|
|
13
|
+
from cognite.neat._utils.xml_ import get_children, iterate_tree
|
|
14
14
|
|
|
15
15
|
DEXPI = Namespace("http://sandbox.dexpi.org/rdl/")
|
|
16
16
|
QUDT = Namespace("https://qudt.org/vocab/unit/")
|
|
@@ -7,9 +7,9 @@ from cognite.client.data_classes.data_modeling import DataModelIdentifier
|
|
|
7
7
|
from cognite.client.data_classes.data_modeling.instances import Instance, PropertyValue
|
|
8
8
|
from rdflib import RDF, XSD, Literal, Namespace, URIRef
|
|
9
9
|
|
|
10
|
-
from cognite.neat.
|
|
11
|
-
from cognite.neat.
|
|
12
|
-
from cognite.neat.
|
|
10
|
+
from cognite.neat._constants import DEFAULT_SPACE_URI
|
|
11
|
+
from cognite.neat._graph.models import Triple
|
|
12
|
+
from cognite.neat._issues.errors import ResourceRetrievalError
|
|
13
13
|
|
|
14
14
|
from ._base import BaseExtractor
|
|
15
15
|
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import uuid
|
|
3
|
+
import xml.etree.ElementTree as ET
|
|
4
|
+
from functools import cached_property
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import ClassVar
|
|
7
|
+
from typing import Literal as LiteralType
|
|
8
|
+
from xml.etree.ElementTree import Element
|
|
9
|
+
|
|
10
|
+
from rdflib import RDF, XSD, Literal, Namespace, URIRef
|
|
11
|
+
|
|
12
|
+
from cognite.neat._constants import DEFAULT_NAMESPACE
|
|
13
|
+
from cognite.neat._graph.extractors._base import BaseExtractor
|
|
14
|
+
from cognite.neat._graph.models import Triple
|
|
15
|
+
from cognite.neat._issues.errors import FileReadError, NeatValueError
|
|
16
|
+
from cognite.neat._utils.rdf_ import remove_namespace_from_uri
|
|
17
|
+
from cognite.neat._utils.text import to_camel
|
|
18
|
+
from cognite.neat._utils.xml_ import get_children
|
|
19
|
+
|
|
20
|
+
IODD = Namespace("http://www.io-link.com/IODD/2010/10/")
|
|
21
|
+
XSI = Namespace("http://www.w3.org/2001/XMLSchema-instance/")
|
|
22
|
+
|
|
23
|
+
XSI_XML_PREFIX = "{http://www.w3.org/2001/XMLSchema-instance}"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class IODDExtractor(BaseExtractor):
|
|
27
|
+
"""
|
|
28
|
+
IODD-XML extractor of RDF triples
|
|
29
|
+
|
|
30
|
+
Each IODD sheet describes an IODD device. This extractor extracts rdf triples that describes the device, and the
|
|
31
|
+
sensors connected to the device.
|
|
32
|
+
This data is described under the elements "DeviceIdentity" and "ProcessDataCollection".
|
|
33
|
+
In addition, triples extacted from "DeviceIdentity" and
|
|
34
|
+
"ProcessDataCollection" may reference "Text" elements which are found under "ExternalTextCollection". Edges to
|
|
35
|
+
these Text element nodes are also extracted.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
root: XML root element of IODD XML file.
|
|
39
|
+
namespace: Optional custom namespace to use for extracted triples that define data
|
|
40
|
+
model instances. Defaults to DEFAULT_NAMESPACE.
|
|
41
|
+
device_id: Optional user specified unique id/tag for actual equipment instance. If not provided, a randomly
|
|
42
|
+
generated UUID will be used. The device_id must be WEB compliant,
|
|
43
|
+
meaning that the characters /&?=: % are not allowed
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
device_elements_with_text_nodes: ClassVar[list[str]] = ["VendorText", "VendorUrl", "DeviceName", "DeviceFamily"]
|
|
47
|
+
std_variable_elements_to_extract: ClassVar[list[str]] = ["V_SerialNumber", "V_ApplicationSpecificTag"]
|
|
48
|
+
text_elements_language: LiteralType["en", "de"] = "en"
|
|
49
|
+
|
|
50
|
+
def __init__(
|
|
51
|
+
self,
|
|
52
|
+
root: Element,
|
|
53
|
+
namespace: Namespace | None = None,
|
|
54
|
+
device_id: str | None = None,
|
|
55
|
+
):
|
|
56
|
+
self.root = root
|
|
57
|
+
self.namespace = namespace or DEFAULT_NAMESPACE
|
|
58
|
+
|
|
59
|
+
if device_id and device_id != re.sub(r"[^a-zA-Z0-9-_.]", "", device_id):
|
|
60
|
+
raise NeatValueError("Specified device_id is not web compliant. Please exclude characters: /&?=: %")
|
|
61
|
+
|
|
62
|
+
self.device_id = (
|
|
63
|
+
self.namespace[device_id] if device_id else self.namespace[f"Device_{str(uuid.uuid4()).replace('-', '_')}"]
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
@cached_property
|
|
67
|
+
def _text_id_2value_mapping(self) -> dict[str, str]:
|
|
68
|
+
"""
|
|
69
|
+
!!! note used for "Prototype Solution" !!!
|
|
70
|
+
A mapping for text_id references to Text elements under ExternalTextCollection.
|
|
71
|
+
The mapping can be used to find the Text element with matching id, and returns
|
|
72
|
+
the value associated with the Text element.
|
|
73
|
+
"""
|
|
74
|
+
mapping = {}
|
|
75
|
+
if et_root := get_children(
|
|
76
|
+
self.root, "ExternalTextCollection", ignore_namespace=True, include_nested_children=True, no_children=1
|
|
77
|
+
):
|
|
78
|
+
if language_element := get_children(et_root[0], "PrimaryLanguage", ignore_namespace=True, no_children=1):
|
|
79
|
+
if (
|
|
80
|
+
language_element[0].attrib.get("{http://www.w3.org/XML/1998/namespace}lang")
|
|
81
|
+
== self.text_elements_language
|
|
82
|
+
):
|
|
83
|
+
if text_elements := get_children(
|
|
84
|
+
language_element[0], child_tag="Text", ignore_namespace=True, include_nested_children=True
|
|
85
|
+
):
|
|
86
|
+
for element in text_elements:
|
|
87
|
+
if id := element.attrib.get("id"):
|
|
88
|
+
if value := element.attrib.get("value"):
|
|
89
|
+
mapping[id] = value
|
|
90
|
+
return mapping
|
|
91
|
+
|
|
92
|
+
@classmethod
|
|
93
|
+
def from_file(cls, filepath: Path, namespace: Namespace | None = None, device_id: str | None = None):
|
|
94
|
+
if filepath.suffix != ".xml":
|
|
95
|
+
raise FileReadError(filepath, "File is not XML.")
|
|
96
|
+
return cls(ET.parse(filepath).getroot(), namespace, device_id)
|
|
97
|
+
|
|
98
|
+
@classmethod
|
|
99
|
+
def _from_root2triples(cls, root: Element, namespace: Namespace, device_id: URIRef) -> list[Triple]:
|
|
100
|
+
"""Loops through the relevant elements of the IODD XML sheet to create rdf triples that describes the IODD
|
|
101
|
+
device by starting at the root element.
|
|
102
|
+
"""
|
|
103
|
+
triples: list[Triple] = []
|
|
104
|
+
|
|
105
|
+
# Extract DeviceIdentity triples
|
|
106
|
+
if di_root := get_children(
|
|
107
|
+
root, "DeviceIdentity", ignore_namespace=True, include_nested_children=True, no_children=1
|
|
108
|
+
):
|
|
109
|
+
triples.extend(cls._iodd_device_identity2triples(di_root[0], namespace, device_id))
|
|
110
|
+
|
|
111
|
+
# Extract VariableCollection triples -
|
|
112
|
+
# this element holds the information about the sensors connected to the device that collects data such as
|
|
113
|
+
# temperature, voltage, leakage etc.
|
|
114
|
+
if vc_root := get_children(
|
|
115
|
+
root, "VariableCollection", ignore_namespace=True, include_nested_children=True, no_children=1
|
|
116
|
+
):
|
|
117
|
+
triples.extend(cls._variables_data_collection2triples(vc_root[0], namespace, device_id))
|
|
118
|
+
|
|
119
|
+
if pc_root := get_children(
|
|
120
|
+
root, "ProcessDataCollection", ignore_namespace=True, include_nested_children=True, no_children=1
|
|
121
|
+
):
|
|
122
|
+
triples.extend(cls._process_data_collection2triples(pc_root[0], namespace, device_id))
|
|
123
|
+
|
|
124
|
+
if et_root := get_children(
|
|
125
|
+
root, "ExternalTextCollection", ignore_namespace=True, include_nested_children=True, no_children=1
|
|
126
|
+
):
|
|
127
|
+
triples.extend(cls._text_elements2triples(et_root[0], namespace))
|
|
128
|
+
|
|
129
|
+
return triples
|
|
130
|
+
|
|
131
|
+
@classmethod
|
|
132
|
+
def _process_data_collection2triples(
|
|
133
|
+
cls, pc_root: Element, namespace: Namespace, device_id: URIRef
|
|
134
|
+
) -> list[Triple]:
|
|
135
|
+
"""
|
|
136
|
+
Will only collect ProcessDataIn elements at this point. The data from the IO-master is transmitted as an
|
|
137
|
+
array related to a ProcessDataIn item.
|
|
138
|
+
"""
|
|
139
|
+
triples: list[Triple] = []
|
|
140
|
+
|
|
141
|
+
if process_data_in := get_children(
|
|
142
|
+
pc_root, "ProcessDataIn", ignore_namespace=True, include_nested_children=True
|
|
143
|
+
):
|
|
144
|
+
for process_data_element in process_data_in:
|
|
145
|
+
if p_id := process_data_element.attrib.get("id"):
|
|
146
|
+
device_id_str = remove_namespace_from_uri(device_id)
|
|
147
|
+
process_data_in_id = namespace[f"{device_id_str}.{p_id}"]
|
|
148
|
+
|
|
149
|
+
# Create ProcessDataIn node
|
|
150
|
+
triples.append((process_data_in_id, RDF.type, IODD.ProcessDataIn))
|
|
151
|
+
|
|
152
|
+
# Create connection from device to node
|
|
153
|
+
triples.append((device_id, IODD.processDataIn, process_data_in_id))
|
|
154
|
+
|
|
155
|
+
# Connect record items (essentially an array of indexed variables) to the ProcessDataIn node
|
|
156
|
+
triples.extend(cls._process_data_in_records2triples(process_data_element, process_data_in_id))
|
|
157
|
+
|
|
158
|
+
return triples
|
|
159
|
+
|
|
160
|
+
@classmethod
|
|
161
|
+
def _device_2text_elements_edges(cls, di_root: Element, id: URIRef, namespace: Namespace) -> list[Triple]:
|
|
162
|
+
"""
|
|
163
|
+
Create edges from the device node to text nodes.
|
|
164
|
+
"""
|
|
165
|
+
triples: list[Triple] = []
|
|
166
|
+
|
|
167
|
+
for element_tag in cls.device_elements_with_text_nodes:
|
|
168
|
+
if child := get_children(
|
|
169
|
+
di_root, child_tag=element_tag, ignore_namespace=True, include_nested_children=True, no_children=1
|
|
170
|
+
):
|
|
171
|
+
if text_id := child[0].attrib.get("textId"):
|
|
172
|
+
# Create connection from device to textId node
|
|
173
|
+
element_tag = to_camel(element_tag)
|
|
174
|
+
triples.append((id, IODD[element_tag], namespace[text_id]))
|
|
175
|
+
|
|
176
|
+
return triples
|
|
177
|
+
|
|
178
|
+
@classmethod
|
|
179
|
+
def _text_elements2triples(cls, et_root: Element, namespace: Namespace) -> list[Triple]:
|
|
180
|
+
"""
|
|
181
|
+
This method extracts all text item triples under the ExternalTextCollection element. This will create a node
|
|
182
|
+
for each text item, and add the text value as a property to the node.
|
|
183
|
+
"""
|
|
184
|
+
triples: list[Triple] = []
|
|
185
|
+
|
|
186
|
+
if language_element := get_children(et_root, "PrimaryLanguage", ignore_namespace=True, no_children=1):
|
|
187
|
+
if (
|
|
188
|
+
language_element[0].attrib.get("{http://www.w3.org/XML/1998/namespace}lang")
|
|
189
|
+
== cls.text_elements_language
|
|
190
|
+
):
|
|
191
|
+
if text_elements := get_children(
|
|
192
|
+
language_element[0], child_tag="Text", ignore_namespace=True, include_nested_children=True
|
|
193
|
+
):
|
|
194
|
+
for element in text_elements:
|
|
195
|
+
if id := element.attrib.get("id"):
|
|
196
|
+
text_id = namespace[id]
|
|
197
|
+
|
|
198
|
+
# Create Text node
|
|
199
|
+
triples.append((text_id, RDF.type, IODD.TextObject))
|
|
200
|
+
|
|
201
|
+
# Resolve text value related to the text item
|
|
202
|
+
if value := element.attrib.get("value"):
|
|
203
|
+
triples.append((text_id, IODD.value, Literal(value)))
|
|
204
|
+
return triples
|
|
205
|
+
|
|
206
|
+
@classmethod
|
|
207
|
+
def _std_variables2triples(cls, vc_root: Element, namespace: Namespace, device_id: URIRef) -> list[Triple]:
|
|
208
|
+
"""
|
|
209
|
+
For simplicity, only extract the two items we want for this use case - V_ApplicationSpecificTag and
|
|
210
|
+
V_SerialNumber
|
|
211
|
+
"""
|
|
212
|
+
triples: list[Triple] = []
|
|
213
|
+
|
|
214
|
+
if std_variable_elements := get_children(vc_root, child_tag="StdVariableRef", ignore_namespace=True):
|
|
215
|
+
for element in std_variable_elements:
|
|
216
|
+
if id := element.attrib.get("id"):
|
|
217
|
+
if id in cls.std_variable_elements_to_extract:
|
|
218
|
+
if object := element.attrib.get("defaultValue"):
|
|
219
|
+
predicate = to_camel(id.replace("V_", ""))
|
|
220
|
+
triples.append((device_id, IODD[predicate], Literal(object)))
|
|
221
|
+
return triples
|
|
222
|
+
|
|
223
|
+
@classmethod
|
|
224
|
+
def _variables_data_collection2triples(
|
|
225
|
+
cls, vc_root: Element, namespace: Namespace, device_id: URIRef
|
|
226
|
+
) -> list[Triple]:
|
|
227
|
+
"""
|
|
228
|
+
VariableCollection contains elements that references Variables and StdVariables. The StdVariables
|
|
229
|
+
can be resolved by looking up the ID in the IODD-StandardDefinitions1.1.xml sheet.
|
|
230
|
+
|
|
231
|
+
The Variable elements are descriptions of the sensors collecting data for the device.
|
|
232
|
+
"""
|
|
233
|
+
triples: list[Triple] = []
|
|
234
|
+
|
|
235
|
+
# StdVariableRef elements of interest
|
|
236
|
+
triples.extend(cls._std_variables2triples(vc_root, namespace, device_id))
|
|
237
|
+
|
|
238
|
+
# Variable elements (these are the descriptions of the sensors)
|
|
239
|
+
if variable_elements := get_children(vc_root, child_tag="Variable", ignore_namespace=True):
|
|
240
|
+
for element in variable_elements:
|
|
241
|
+
if id := element.attrib.get("id"):
|
|
242
|
+
device_id_str = remove_namespace_from_uri(device_id)
|
|
243
|
+
variable_id = f"{device_id_str}.{id}"
|
|
244
|
+
|
|
245
|
+
# Create connection from device node to time series
|
|
246
|
+
triples.append((device_id, IODD.variable, Literal(variable_id, datatype=XSD["timeseries"])))
|
|
247
|
+
|
|
248
|
+
return triples
|
|
249
|
+
|
|
250
|
+
@classmethod
|
|
251
|
+
def _iodd_device_identity2triples(cls, di_root: Element, namespace: Namespace, device_id: URIRef) -> list[Triple]:
|
|
252
|
+
"""
|
|
253
|
+
Properties and metadata related to the IO Device are described under the 'DeviceIdentity' element in the XML.
|
|
254
|
+
This method extracts the triples that describe the device's identity which is found under the
|
|
255
|
+
DeviceIdentity element and its child elements.
|
|
256
|
+
|
|
257
|
+
"""
|
|
258
|
+
triples: list[Triple] = []
|
|
259
|
+
|
|
260
|
+
# Create rdf type triple for IODD
|
|
261
|
+
triples.append(
|
|
262
|
+
(
|
|
263
|
+
device_id,
|
|
264
|
+
RDF.type,
|
|
265
|
+
IODD.IoddDevice,
|
|
266
|
+
)
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
for attribute_name, attribute_value in di_root.attrib.items():
|
|
270
|
+
triples.append((device_id, IODD[attribute_name], Literal(attribute_value)))
|
|
271
|
+
|
|
272
|
+
triples.extend(cls._device_2text_elements_edges(di_root, device_id, namespace))
|
|
273
|
+
return triples
|
|
274
|
+
|
|
275
|
+
@classmethod
|
|
276
|
+
def _process_data_in_records2triples(cls, pc_in_root: Element, process_data_in_id: URIRef):
|
|
277
|
+
"""
|
|
278
|
+
Extract RecordItems related to a ProcessDataIn element. Each record item is indexed. Will use this index
|
|
279
|
+
as the identifier for the time series in CDF.
|
|
280
|
+
"""
|
|
281
|
+
triples: list[Triple] = []
|
|
282
|
+
|
|
283
|
+
if record_items := get_children(pc_in_root, "RecordItem", ignore_namespace=True, include_nested_children=True):
|
|
284
|
+
for record in record_items:
|
|
285
|
+
if index := record.attrib.get("subindex"):
|
|
286
|
+
process_id_str = remove_namespace_from_uri(process_data_in_id)
|
|
287
|
+
record_id = f"{process_id_str}.{index}"
|
|
288
|
+
# Create connection from device node to time series
|
|
289
|
+
triples.append((process_data_in_id, IODD.variable, Literal(record_id, datatype=XSD["timeseries"])))
|
|
290
|
+
|
|
291
|
+
return triples
|
|
292
|
+
|
|
293
|
+
def extract(self) -> list[Triple]:
|
|
294
|
+
"""
|
|
295
|
+
Extract RDF triples from IODD XML
|
|
296
|
+
"""
|
|
297
|
+
return self._from_root2triples(self.root, self.namespace, self.device_id)
|
|
298
|
+
|
|
299
|
+
def _variable2info(self, variable_element: Element) -> dict:
|
|
300
|
+
"""
|
|
301
|
+
!!! note used for "Prototype Solution" !!!
|
|
302
|
+
Extracts information relevant to a CDF time series type from a Variable element
|
|
303
|
+
"""
|
|
304
|
+
|
|
305
|
+
variable_dict = {}
|
|
306
|
+
|
|
307
|
+
if name := get_children(
|
|
308
|
+
variable_element, child_tag="Name", ignore_namespace=True, include_nested_children=False, no_children=1
|
|
309
|
+
):
|
|
310
|
+
if text_id := name[0].get("textId"):
|
|
311
|
+
variable_dict["name"] = self._text_id_2value_mapping[text_id]
|
|
312
|
+
if description := get_children(
|
|
313
|
+
variable_element,
|
|
314
|
+
child_tag="Description",
|
|
315
|
+
ignore_namespace=True,
|
|
316
|
+
include_nested_children=False,
|
|
317
|
+
no_children=1,
|
|
318
|
+
):
|
|
319
|
+
if text_id := description[0].get("textId"):
|
|
320
|
+
variable_dict["description"] = self._text_id_2value_mapping[text_id]
|
|
321
|
+
if data_type := get_children(
|
|
322
|
+
variable_element, child_tag="Datatype", ignore_namespace=True, include_nested_children=False, no_children=1
|
|
323
|
+
):
|
|
324
|
+
variable_dict["data_type"] = data_type[0].attrib[f"{XSI_XML_PREFIX}type"]
|
|
325
|
+
|
|
326
|
+
return variable_dict
|
|
327
|
+
|
|
328
|
+
def _process_record2info(self, record_element: Element) -> dict:
|
|
329
|
+
"""
|
|
330
|
+
!!! note used for "Prototype Solution" !!!
|
|
331
|
+
Extracts information relevant to a CDF time series type from a Record element
|
|
332
|
+
"""
|
|
333
|
+
record_dict = {}
|
|
334
|
+
|
|
335
|
+
if name := get_children(
|
|
336
|
+
record_element, child_tag="Name", ignore_namespace=True, include_nested_children=False, no_children=1
|
|
337
|
+
):
|
|
338
|
+
if text_id := name[0].get("textId"):
|
|
339
|
+
record_dict["name"] = self._text_id_2value_mapping[text_id]
|
|
340
|
+
if description := get_children(
|
|
341
|
+
record_element, child_tag="Description", ignore_namespace=True, include_nested_children=False, no_children=1
|
|
342
|
+
):
|
|
343
|
+
if text_id := description[0].get("textId"):
|
|
344
|
+
record_dict["description"] = self._text_id_2value_mapping[text_id]
|
|
345
|
+
if data_type := get_children(
|
|
346
|
+
record_element,
|
|
347
|
+
child_tag="SimpleDatatype",
|
|
348
|
+
ignore_namespace=True,
|
|
349
|
+
include_nested_children=False,
|
|
350
|
+
no_children=1,
|
|
351
|
+
):
|
|
352
|
+
record_dict["data_type"] = data_type[0].attrib[f"{XSI_XML_PREFIX}type"]
|
|
353
|
+
if index := record_element.attrib.get("subindex"):
|
|
354
|
+
record_dict["index"] = index
|
|
355
|
+
|
|
356
|
+
return record_dict
|
|
357
|
+
|
|
358
|
+
def _extract_enhanced_ts_information(self, json_file_path: Path):
|
|
359
|
+
"""
|
|
360
|
+
Extract additional information like name, description and data type for Variables and ProcessDataIn
|
|
361
|
+
record elements in the IODD. The purpose is for the result gile to be used for enhancing time series with more
|
|
362
|
+
information when they are created in CDF.
|
|
363
|
+
|
|
364
|
+
Args:
|
|
365
|
+
json_file_path: file path for where to write the extracted information about all time series
|
|
366
|
+
in the IODD
|
|
367
|
+
|
|
368
|
+
!!! note "Prototype Solution" !!!
|
|
369
|
+
This is an intermediate solution while better support for adding this information directly
|
|
370
|
+
into the knowledge graph for the timeseries node type is under development.
|
|
371
|
+
"""
|
|
372
|
+
import json
|
|
373
|
+
|
|
374
|
+
ts_ext_id2_info_map = {}
|
|
375
|
+
|
|
376
|
+
# Variable elements (these are the descriptions of the sensors)
|
|
377
|
+
if variable_elements := get_children(
|
|
378
|
+
self.root, child_tag="Variable", ignore_namespace=True, include_nested_children=True
|
|
379
|
+
):
|
|
380
|
+
for element in variable_elements:
|
|
381
|
+
if id := element.attrib.get("id"):
|
|
382
|
+
device_id_str = remove_namespace_from_uri(self.device_id)
|
|
383
|
+
variable_id = f"{device_id_str}.{id}"
|
|
384
|
+
ts_ext_id2_info_map[variable_id] = self._variable2info(element)
|
|
385
|
+
|
|
386
|
+
if process_data_in := get_children(
|
|
387
|
+
self.root, "ProcessDataIn", ignore_namespace=True, include_nested_children=True
|
|
388
|
+
):
|
|
389
|
+
for process_data_element in process_data_in:
|
|
390
|
+
if p_id := process_data_element.attrib.get("id"):
|
|
391
|
+
device_id_str = remove_namespace_from_uri(self.device_id)
|
|
392
|
+
process_data_in_id = f"{device_id_str}.{p_id}"
|
|
393
|
+
if record_items := get_children(
|
|
394
|
+
process_data_element, "RecordItem", ignore_namespace=True, include_nested_children=True
|
|
395
|
+
):
|
|
396
|
+
for record in record_items:
|
|
397
|
+
if index := record.attrib.get("subindex"):
|
|
398
|
+
process_record_id = f"{process_data_in_id}.{index}"
|
|
399
|
+
ts_ext_id2_info_map[process_record_id] = self._process_record2info(record)
|
|
400
|
+
|
|
401
|
+
with Path.open(json_file_path, "w") as fp:
|
|
402
|
+
json.dump(ts_ext_id2_info_map, fp, indent=2)
|
|
@@ -11,13 +11,14 @@ import numpy
|
|
|
11
11
|
import pandas as pd
|
|
12
12
|
from rdflib import RDF, Literal, Namespace, URIRef
|
|
13
13
|
|
|
14
|
-
from cognite.neat.
|
|
15
|
-
from cognite.neat.
|
|
16
|
-
from cognite.neat.
|
|
17
|
-
from cognite.neat.
|
|
18
|
-
from cognite.neat.
|
|
19
|
-
from cognite.neat.
|
|
20
|
-
from cognite.neat.
|
|
14
|
+
from cognite.neat._graph.models import Triple
|
|
15
|
+
from cognite.neat._rules._constants import EntityTypes
|
|
16
|
+
from cognite.neat._rules.analysis import InformationAnalysis
|
|
17
|
+
from cognite.neat._rules.models import DMSRules, InformationRules
|
|
18
|
+
from cognite.neat._rules.models.data_types import DataType
|
|
19
|
+
from cognite.neat._rules.models.entities import ClassEntity
|
|
20
|
+
from cognite.neat._rules.models.information import InformationProperty
|
|
21
|
+
from cognite.neat._utils.rdf_ import remove_namespace_from_uri
|
|
21
22
|
|
|
22
23
|
from ._base import BaseExtractor
|
|
23
24
|
|
|
@@ -43,7 +44,7 @@ class MockGraphGenerator(BaseExtractor):
|
|
|
43
44
|
):
|
|
44
45
|
if isinstance(rules, DMSRules):
|
|
45
46
|
# fixes potential issues with circular dependencies
|
|
46
|
-
from cognite.neat.
|
|
47
|
+
from cognite.neat._rules.transformers import DMSToInformation
|
|
47
48
|
|
|
48
49
|
self.rules = DMSToInformation().transform(rules).rules
|
|
49
50
|
elif isinstance(rules, InformationRules):
|