Skip to content

Commit

Permalink
Finalize first version of serializer
Browse files Browse the repository at this point in the history
  • Loading branch information
mhrimaz committed Dec 6, 2023
1 parent edfd6e6 commit b34fdfb
Show file tree
Hide file tree
Showing 10 changed files with 551 additions and 36 deletions.
147 changes: 143 additions & 4 deletions app/models/basic_event_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import rdflib
from pydantic import BaseModel
from rdflib import RDF

from app.models.aas_namespace import AASNameSpace
from app.models.event_element import EventElement
from app.models.model_type import ModelType
from app.models.reference import Reference
Expand All @@ -37,16 +40,17 @@
from app.models.range import Range
from app.models.reference_element import ReferenceElement
from app.models.relationship_element import RelationshipElement
from app.models.submodel_element import SubmodelElement


class Direction(Enum):
input = "input"
output = "output"
Input = "input"
Output = "output"


class StateOfEvent(Enum):
off = "off"
on = "on"
Off = "off"
On = "on"


class BasicEventElement(EventElement):
Expand All @@ -64,3 +68,138 @@ class BasicEventElement(EventElement):
minInterval: Optional[constr()] = None
maxInterval: Optional[constr()] = None
modelType: Literal["BasicEventElement"] = ModelType.BasicEventElement.value

def to_rdf(
self,
graph: rdflib.Graph = None,
parent_node: rdflib.IdentifiedNode = None,
prefix_uri: str = "",
base_uri: str = "",
) -> (rdflib.Graph, rdflib.IdentifiedNode):
created_graph, created_node = super().to_rdf(graph, parent_node, prefix_uri, base_uri)
created_graph.add((created_node, RDF.type, AASNameSpace.AAS["BasicEventElement"]))

_, created_observed_node = self.observed.to_rdf(created_graph, created_node)
created_graph.add((created_node, AASNameSpace.AAS["BasicEventElement/observed"], created_observed_node))
created_graph.add(
(
created_node,
AASNameSpace.AAS["BasicEventElement/direction"],
AASNameSpace.AAS[f"Direction/{self.direction.name}"],
)
)
created_graph.add(
(
created_node,
AASNameSpace.AAS["BasicEventElement/state"],
AASNameSpace.AAS[f"StateOfEvent/{self.state.name}"],
)
)
if self.messageTopic:
_, created_message_broker_node = self.messageBroker.to_rdf(created_graph, created_node)
created_graph.add(
(created_node, AASNameSpace.AAS["BasicEventElement/messageBroker"], created_message_broker_node)
)
if self.messageBroker:
created_graph.add(
(created_node, AASNameSpace.AAS["BasicEventElement/messageTopic"], rdflib.Literal(self.messageTopic))
)
if self.lastUpdate:
created_graph.add(
(created_node, AASNameSpace.AAS["BasicEventElement/lastUpdate"], rdflib.Literal(self.lastUpdate))
)
if self.minInterval:
created_graph.add(
(created_node, AASNameSpace.AAS["BasicEventElement/minInterval"], rdflib.Literal(self.minInterval))
)
if self.maxInterval:
created_graph.add(
(created_node, AASNameSpace.AAS["BasicEventElement/maxInterval"], rdflib.Literal(self.maxInterval))
)
return created_graph, created_node

@staticmethod
def from_rdf(graph: rdflib.Graph, subject: rdflib.IdentifiedNode) -> "BasicEventElement":
observed_value = None
observed_ref: rdflib.URIRef = next(
graph.objects(subject=subject, predicate=AASNameSpace.AAS["BasicEventElement/observed"]),
None,
)
if observed_ref:
observed_value = Reference.from_rdf(graph, observed_ref)

direction_value = None
direction_ref: rdflib.URIRef = next(
graph.objects(subject=subject, predicate=AASNameSpace.AAS["BasicEventElement/direction"]),
None,
)
if direction_ref:
direction_value = Direction[direction_ref[direction_ref.rfind("/") + 1 :]]

state_value = None
state_ref: rdflib.URIRef = next(
graph.objects(subject=subject, predicate=AASNameSpace.AAS["BasicEventElement/state"]),
None,
)
if state_ref:
state_value = StateOfEvent[state_ref[state_ref.rfind("/") + 1 :]]

message_topic_value = None
message_topic_ref: rdflib.Literal = next(
graph.objects(subject=subject, predicate=AASNameSpace.AAS["BasicEventElement/messageTopic"]),
None,
)
if message_topic_ref:
message_topic_value = message_topic_ref.value

message_broker_value = None
message_broker_ref: rdflib.URIRef = next(
graph.objects(subject=subject, predicate=AASNameSpace.AAS["BasicEventElement/messageBroker"]),
None,
)
if message_broker_ref:
message_broker_value = Reference.from_rdf(graph, message_broker_ref)

last_update_value = None
last_update_ref: rdflib.Literal = next(
graph.objects(subject=subject, predicate=AASNameSpace.AAS["BasicEventElement/lastUpdate"]),
None,
)
if last_update_ref:
last_update_value = last_update_ref.value
min_interval_value = None
min_interval_ref: rdflib.Literal = next(
graph.objects(subject=subject, predicate=AASNameSpace.AAS["BasicEventElement/minInterval"]),
None,
)
if min_interval_ref:
min_interval_value = min_interval_ref.value

max_interval_value = None
max_interval_ref: rdflib.Literal = next(
graph.objects(subject=subject, predicate=AASNameSpace.AAS["BasicEventElement/maxInterval"]),
None,
)
if max_interval_ref:
max_interval_value = max_interval_ref.value

submodel_element = SubmodelElement.from_rdf(graph, subject)
return BasicEventElement(
observed=observed_value,
direction=direction_value,
state=state_value,
messageTopic=message_topic_value,
messageBroker=message_broker_value,
lastUpdate=last_update_value,
minInterval=min_interval_value,
maxInterval=max_interval_value,
qualifiers=submodel_element.qualifiers,
category=submodel_element.category,
idShort=submodel_element.idShort,
displayName=submodel_element.displayName,
description=submodel_element.description,
extensions=submodel_element.extensions,
semanticId=submodel_element.semanticId,
supplementalSemanticIds=submodel_element.supplementalSemanticIds,
embeddedDataSpecifications=submodel_element.embeddedDataSpecifications,
)
103 changes: 100 additions & 3 deletions app/models/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import rdflib
from rdflib import RDF

from app.models.aas_namespace import AASNameSpace
from app.models.model_type import ModelType
from app.models.specific_asset_id import SpecificAssetId
from app.models.submodel_element import SubmodelElement
Expand All @@ -35,14 +39,107 @@ class EntityType(Enum):


class Entity(SubmodelElement):
# TODO: recheck
statements: List["SubmodelElementChoice"] = Field(None, min_length=0, discriminator="modelType")
statements: Optional[List["SubmodelElementChoice"]] = Field(None, min_length=0)
entityType: EntityType
globalAssetId: Optional[
constr(
min_length=1,
max_length=2000,
)
] = None
specificAssetIds: Optional[List[SpecificAssetId]] = Field(None, min_length=1)
specificAssetIds: Optional[List[SpecificAssetId]] = Field(None, min_length=0)
modelType: Literal["Entity"] = ModelType.Entity.value

def to_rdf(
self,
graph: rdflib.Graph = None,
parent_node: rdflib.IdentifiedNode = None,
prefix_uri: str = "",
base_uri: str = "",
) -> (rdflib.Graph, rdflib.IdentifiedNode):
created_graph, created_node = super().to_rdf(graph, parent_node, prefix_uri, base_uri)
created_graph.add((created_node, RDF.type, AASNameSpace.AAS["Entity"]))

created_graph.add(
(
created_node,
AASNameSpace.AAS["Entity/entityType"],
AASNameSpace.AAS[f"EntityType/{self.entityType.name}"],
)
)
if self.statements:
for idx, statement in enumerate(self.statements):
_, created_sub_node = statement.to_rdf(
graph, created_node, prefix_uri=prefix_uri + str(created_node) + "."
)
graph.add((created_sub_node, AASNameSpace.AAS["index"], rdflib.Literal(idx)))
graph.add((created_node, AASNameSpace.AAS["Entity/statements"], created_sub_node))
if self.globalAssetId:
created_graph.add(
(
created_node,
AASNameSpace.AAS["Entity/globalAssetId"],
rdflib.Literal(self.globalAssetId),
)
)

if self.specificAssetIds:
for idx, specific_asset_id in enumerate(self.specificAssetIds):
_, created_sub_node = specific_asset_id.to_rdf(
graph, created_node, prefix_uri=prefix_uri + str(created_node) + "."
)
graph.add((created_sub_node, AASNameSpace.AAS["index"], rdflib.Literal(idx)))
graph.add((created_node, AASNameSpace.AAS["Entity/specificAssetIds"], created_sub_node))
return created_graph, created_node

@staticmethod
def from_rdf(graph: rdflib.Graph, subject: rdflib.IdentifiedNode) -> "Entity":
statements_value = []
from app.models.util import from_unknown_rdf

for statement_uriref in graph.objects(subject=subject, predicate=AASNameSpace.AAS["Entity/statements"]):
element = from_unknown_rdf(graph, statement_uriref)
statements_value.append(element)

if len(statements_value) == 0:
statements_value = None

entity_type_value = None
entity_type_ref: rdflib.URIRef = next(
graph.objects(subject=subject, predicate=AASNameSpace.AAS["Entity/entityType"]),
None,
)
if entity_type_ref:
entity_type_value = EntityType[entity_type_ref[entity_type_ref.rfind("/") + 1 :]]

global_asset_id_value = None
global_asset_id_ref: rdflib.Literal = next(
graph.objects(subject=subject, predicate=AASNameSpace.AAS["Entity/globalAssetId"]),
None,
)
if global_asset_id_ref:
global_asset_id_value = global_asset_id_ref.value

specificAssetIds_value = []
for statement_uriref in graph.objects(subject=subject, predicate=AASNameSpace.AAS["Entity/specificAssetIds"]):
element = SpecificAssetId.from_rdf(graph, statement_uriref)
specificAssetIds_value.append(element)
if len(specificAssetIds_value) == 0:
specificAssetIds_value = None
submodel_element = SubmodelElement.from_rdf(graph, subject)

return Entity(
statements=statements_value,
entityType=entity_type_value,
globalAssetId=global_asset_id_value,
specificAssetIds=specificAssetIds_value,
qualifiers=submodel_element.qualifiers,
category=submodel_element.category,
idShort=submodel_element.idShort,
displayName=submodel_element.displayName,
description=submodel_element.description,
extensions=submodel_element.extensions,
semanticId=submodel_element.semanticId,
supplementalSemanticIds=submodel_element.supplementalSemanticIds,
embeddedDataSpecifications=submodel_element.embeddedDataSpecifications,
)
Loading

0 comments on commit b34fdfb

Please sign in to comment.