Skip to content

Commit

Permalink
All SME types into database (#327)
Browse files Browse the repository at this point in the history
* Initial commit on orphan branch

* file error fix

* start

* Database-schema, Clear, Load

* delete

* works

* works

* extrude to seperate files finished

* db name change

* image of db schema changed

* blazor changes

* blazor changes

* delete table config

* delete num to id

* Identifier changed

* outsource of code from page for db

* fremdschluessel einbau noch nicht fertig

* finish refactoring

* bug fix

* bug fix

* work on SearchSMEsResult

* Edit works now

* smal fix

* smal fix

* faster

* faster works

* faster works

* faster works

* Database, not required added

* Bug with searchSMEs and countSMEs fixed

* Auslagern von SM zu Json

* Change

* new db image

* API Work started

* change start parameters

* refactoring database

* refactoring database

* refactoring database

* refactoring database

* start working through comments

* Rework SubmodelRepositoryAPIApi

* API connection to db

* API connection to db

* API connection to db

* Timestamp added to EntityFW and some APIs

* launchSettings.json

* Query rework

* Query rework SME

* Query rework SMEResult

* Query clean up

* Query update

* Query update

* rework Query

* rework Query

* start of rework SearchSME to make SME faster

* update of rework SearchSME to make SME faster

* update of rework SearchSME to make SME faster

* befor cleaning of SearchSME

* befor cleaning of SearchSME

* refactoring graph ql

* refactoring graphql finish

* search on blazor pages AAS, SM and SME with timestamp

* search on blazor pages AAS, SM and SME with timestamp

* work through the comments

* merge with upstream

* delete old/unused methode

* merge with main

* merge with main

change email adress

* Query, added diff

* Query, diff bug fix

* Separate classes

* launchSettings.json

* merge with local repo

* merge with local repo

* merge with local repo

* Update Edit.cs

* finish timestamp

* Update Edit.cs

* Query D- or IValue with only diff fix

* Query fix dataformat

* change to string.IsNullOrEmpty

* change to string.IsNullOrEmpty

* launchSettings.json

* add timestamp to query result

* File for TimeStamp

* File for TimeStamp

* Bug fix Search on Page /db/sme?search=

* Bug fix Search on Page /db/sme?search=

* Query change

* Query change

* Add argument sm identifier

* Bug fix sm identifier

* finish

* merge with dev-timestamp

* PR prep

* PR prep

* Bug fix: url param search

* Merge main

* Merge main

* Start of load all aasx

* load all aasx in db to local

* Test .net 6.0

* Merge main

* Merge main

* VisitorAASX changes

* Fix Atex2 with DB

* ATEX change

* launchSettings.json

* Start rework sme value

* Merge main

* Rework SME Value finished

* entity finished

* merge main

* Start of ReferenceElement

* finish

* Beginn Range

* Add entity to db, rework sme, new parameter on gui

* Add entity to db, rework sme, new parameter on gui

* Add entity to db, rework sme, new parameter on gui

* Add entity to db, rework sme, new parameter on gui

* Implement comments

* Change launchSettings

* File, Blob

* File, Blob

* SME canges

* launchSettings

* befor Opr

* Opr change to SMEType

* start datatype

* DataTypeDef finish

* OValue with only changes in Visitor and Converter

* OValue

* OValue to NodeJSON

* finish oValue

* db schema image

* img db schema

* merge main

* launch Settings

---------

Co-authored-by: Oliver Fries <info@oliver-fries.de>
Co-authored-by: aorzelskiGH <aorzelski@phoenixcontact.com>
  • Loading branch information
3 people authored Jul 9, 2024
1 parent 847a3ed commit d638896
Show file tree
Hide file tree
Showing 24 changed files with 1,316 additions and 561 deletions.
370 changes: 264 additions & 106 deletions src/AasxServerBlazor/Pages/Db.razor

Large diffs are not rendered by default.

Binary file modified src/AasxServerBlazor/wwwroot/db-schema.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions src/AasxServerDB/AasxServerDB.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.002.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AasxServerDB", "AasxServerDB.csproj", "{C9DB3CB8-7B4E-4226-AEDD-793789CFD3F4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C9DB3CB8-7B4E-4226-AEDD-793789CFD3F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C9DB3CB8-7B4E-4226-AEDD-793789CFD3F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9DB3CB8-7B4E-4226-AEDD-793789CFD3F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9DB3CB8-7B4E-4226-AEDD-793789CFD3F4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B5AC5726-DC49-40E1-AA38-8ECC0D2A6523}
EndGlobalSection
EndGlobal
219 changes: 169 additions & 50 deletions src/AasxServerDB/Converter.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
using System.Text;
using AasCore.Aas3_0;
using AasxServerDB.Entities;
using AdminShellNS;
using Extensions;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using Nodes = System.Text.Json.Nodes;

namespace AasxServerDB
{
public class Converter
{
static public AdminShellPackageEnv? GetPackageEnv(string path, AASSet? aasDB)
public static AdminShellPackageEnv? GetPackageEnv(string path, AASSet? aasDB)
{
using (AasContext db = new AasContext())
{
Expand Down Expand Up @@ -42,7 +45,7 @@ public class Converter
}
}

static public Submodel? GetSubmodel(SMSet? smDB = null, string smIdentifier = "")
public static Submodel? GetSubmodel(SMSet? smDB = null, string smIdentifier = "")
{
using (AasContext db = new AasContext())
{
Expand All @@ -53,6 +56,7 @@ public class Converter
return null;
smDB = smList.First();
}

if (smDB == null)
return null;

Expand All @@ -61,115 +65,230 @@ public class Converter
.Where(sme => sme.SMId == smDB.Id)
.ToList();

Submodel submodel = new Submodel(smDB.Identifier);
var submodel = new Submodel(smDB.Identifier);
submodel.IdShort = smDB.IdShort;
submodel.SemanticId = new Reference(AasCore.Aas3_0.ReferenceTypes.ExternalReference,
new List<IKey>() { new Key(KeyTypes.GlobalReference, smDB.SemanticId) });
submodel.SubmodelElements = new List<ISubmodelElement>();

LoadSME(submodel, null, null, SMEList, null);
LoadSME(submodel, null, null, SMEList);

submodel.TimeStampCreate = smDB.TimeStampCreate;
submodel.TimeStamp = smDB.TimeStamp;
submodel.TimeStampTree = smDB.TimeStampTree;
submodel.SetAllParents();

return submodel;
}
}
}

static private void LoadSME(Submodel submodel, ISubmodelElement? sme, string? SMEType, List<SMESet> SMEList, int? smeId)
private static void LoadSME(Submodel submodel, ISubmodelElement? sme, SMESet? smeSet, List<SMESet> SMEList)
{
var smeLevel = SMEList.Where(s => s.ParentSMEId == smeId).OrderBy(s => s.IdShort).ToList();
var smeSets = SMEList.Where(s => s.ParentSMEId == (smeSet != null ? smeSet.Id : null)).OrderBy(s => s.IdShort).ToList();

foreach (var smel in smeLevel)
foreach (var smel in smeSets)
{
ISubmodelElement? nextSME = null;
var value = smel.getValue();
switch (smel.SMEType)
{
case "Prop":
nextSME = new Property(DataTypeDefXsd.String, value: value.First()[0]);
break;
case "SMC":
nextSME = new SubmodelElementCollection(value: new List<ISubmodelElement>());
break;
case "MLP":
nextSME = new MultiLanguageProperty(
value: value.ConvertAll<ILangStringTextType>(val => new LangStringTextType(val[1], val[0])));
break;
case "File":
nextSME = new AasCore.Aas3_0.File("text", value: value.First()[0]);
break;
case "Ent":
nextSME = new Entity(
value.First()[1].Equals("SelfManagedEntity") ? EntityType.SelfManagedEntity : EntityType.CoManagedEntity,
globalAssetId: value.First()[0],
statements: new List<ISubmodelElement>());
break;
}

if (nextSME == null)
continue;
// prefix of operation
var split = !smel.SMEType.IsNullOrEmpty() ? smel.SMEType.Split(VisitorAASX.OPERATION_SPLIT) : [ string.Empty ];
var oprPrefix = split.Length == 2 ? split[ 0 ] : string.Empty;
smel.SMEType = split.Length == 2 ? split[ 1 ] : split[ 0 ];

nextSME.IdShort = smel.IdShort;
if (!smel.SemanticId.IsNullOrEmpty())
{
nextSME.SemanticId = new Reference(AasCore.Aas3_0.ReferenceTypes.ExternalReference,
new List<IKey>() { new Key(KeyTypes.GlobalReference, smel.SemanticId) });
}
nextSME.TimeStamp = smel.TimeStamp;
nextSME.TimeStampCreate = smel.TimeStampCreate;
nextSME.TimeStampTree = smel.TimeStampTree;
// create SME from database
var nextSME = CreateSME(smel);

// add sme to sm or sme
if (sme == null)
{
submodel.Add(nextSME);
}
else
{
switch (SMEType)
switch (smeSet.SMEType)
{
case "RelA":
(sme as AnnotatedRelationshipElement).Annotations.Add((IDataElement) nextSME);
break;
case "SML":
(sme as SubmodelElementList).Value.Add(nextSME);
break;
case "SMC":
(sme as SubmodelElementCollection).Value.Add(nextSME);
break;
case "Ent":
(sme as Entity).Statements.Add(nextSME);
break;
case "Opr":
if (oprPrefix.Equals(VisitorAASX.OPERATION_INPUT))
(sme as Operation).InputVariables.Add(new OperationVariable(nextSME));
else if (oprPrefix.Equals(VisitorAASX.OPERATION_OUTPUT))
(sme as Operation).OutputVariables.Add(new OperationVariable(nextSME));
else if (oprPrefix.Equals(VisitorAASX.OPERATION_INOUTPUT))
(sme as Operation).InoutputVariables.Add(new OperationVariable(nextSME));
break;
}
}

if (smel.SMEType.Equals("SMC") || smel.SMEType.Equals("Ent"))
// recursiv, call for child sme's
switch (smel.SMEType)
{
LoadSME(submodel, nextSME, smel.SMEType, SMEList, smel.Id);
case "RelA":
case "SML":
case "SMC":
case "Ent":
case "Opr":
LoadSME(submodel, nextSME, smel, SMEList);
break;
}
}
}

static public string GetAASXPath(string aasId = "", string submodelId = "")
private static ISubmodelElement? CreateSME(SMESet smeSet)
{
using AasContext db = new AasContext();
ISubmodelElement? sme = null;
var value = smeSet.GetValue();
var oValue = smeSet.GetOValue();

switch (smeSet.SMEType)
{
case "Rel":
sme = new RelationshipElement(
first: oValue.ContainsKey("First") ? CreateReferenceFromObject(oValue["First"]) : new Reference(ReferenceTypes.ExternalReference, new List<IKey>()),
second: oValue.ContainsKey("Second") ? CreateReferenceFromObject(oValue["Second"]) : new Reference(ReferenceTypes.ExternalReference, new List<IKey>()));
break;
case "RelA":
sme = new AnnotatedRelationshipElement(
first: oValue.ContainsKey("First") ? CreateReferenceFromObject(oValue["First"]) : new Reference(ReferenceTypes.ExternalReference, new List<IKey>()),
second: oValue.ContainsKey("Second") ? CreateReferenceFromObject(oValue["Second"]) : new Reference(ReferenceTypes.ExternalReference, new List<IKey>()),
annotations: new List<IDataElement>());
break;
case "Prop":
sme = new Property(
valueType: Jsonization.Deserialize.DataTypeDefXsdFrom(value.First()[1]),
value: value.First()[0],
valueId: oValue.ContainsKey("ValueId") ? CreateReferenceFromObject(oValue["ValueId"]) : null);
break;
case "MLP":
sme = new MultiLanguageProperty(
value: value.ConvertAll<ILangStringTextType>(val => new LangStringTextType(val[1], val[0])),
valueId: oValue.ContainsKey("ValueId") ? CreateReferenceFromObject(oValue["ValueId"]) : null);
break;
case "Range":
var findMin = value.Find(val => val[1].Equals("Min"));
var findMax = value.Find(val => val[1].Equals("Max"));
sme = new AasCore.Aas3_0.Range(
valueType: Jsonization.Deserialize.DataTypeDefXsdFrom(oValue["ValueType"]),
min: findMin != null ? findMin[0] : string.Empty,
max: findMax != null ? findMax[0] : string.Empty);
break;
case "Blob":
sme = new Blob(
value: Encoding.ASCII.GetBytes(value.First()[0]),
contentType: value.First()[1]);
break;
case "File":
sme = new AasCore.Aas3_0.File(
value: value.First()[0],
contentType: value.First()[1]);
break;
case "Ref":
sme = new ReferenceElement(
value: oValue.ContainsKey("Value") ? CreateReferenceFromObject(oValue["Value"]) : null);
break;
case "Cap":
sme = new Capability();
break;
case "SML":
sme = new SubmodelElementList(
orderRelevant: oValue.ContainsKey("OrderRelevant") ? (bool?)oValue["OrderRelevant"] : true,
semanticIdListElement: oValue.ContainsKey("SemanticIdListElement") ? CreateReferenceFromObject(oValue["SemanticIdListElement"]) : null,
typeValueListElement: Jsonization.Deserialize.AasSubmodelElementsFrom(oValue["TypeValueListElement"]),
valueTypeListElement: oValue.ContainsKey("ValueTypeListElement") ? Jsonization.Deserialize.DataTypeDefXsdFrom(oValue["ValueTypeListElement"]) : null,
value: new List<ISubmodelElement>());
break;
case "SMC":
sme = new SubmodelElementCollection(
value: new List<ISubmodelElement>());
break;
case "Ent":
var spec = new List<ISpecificAssetId>();
if (oValue.ContainsKey("SpecificAssetIds"))
foreach (var item in (Nodes.JsonArray) oValue["SpecificAssetIds"])
spec.Add(Jsonization.Deserialize.SpecificAssetIdFrom(item));
sme = new Entity(
statements: new List<ISubmodelElement>(),
entityType: Jsonization.Deserialize.EntityTypeFrom(value.First()[1]),
globalAssetId: value.First()[0],
specificAssetIds: oValue.ContainsKey("SpecificAssetIds") ? spec : null);
break;
case "Evt":
sme = new BasicEventElement(
observed: oValue.ContainsKey("Observed") ? CreateReferenceFromObject(oValue["Observed"]) : new Reference(ReferenceTypes.ExternalReference, new List<IKey>()),
direction: Jsonization.Deserialize.DirectionFrom(oValue["Direction"]),
state: Jsonization.Deserialize.StateOfEventFrom(oValue["State"]),
messageTopic: oValue.ContainsKey("MessageTopic") ? oValue["MessageTopic"].ToString() : null,
messageBroker: oValue.ContainsKey("MessageBroker") ? CreateReferenceFromObject(oValue["MessageBroker"]) : null,
lastUpdate: oValue.ContainsKey("LastUpdate") ? oValue["LastUpdate"].ToString() : null,
minInterval: oValue.ContainsKey("MinInterval") ? oValue["MinInterval"].ToString() : null,
maxInterval: oValue.ContainsKey("MaxInterval") ? oValue["MaxInterval"].ToString() : null);
break;
case "Opr":
sme = new Operation(
inputVariables: new List<IOperationVariable>(),
outputVariables: new List<IOperationVariable>(),
inoutputVariables: new List<IOperationVariable>());
break;
}

if (sme == null)
return null;

sme.IdShort = smeSet.IdShort;
sme.TimeStamp = smeSet.TimeStamp;
sme.TimeStampCreate = smeSet.TimeStampCreate;
sme.TimeStampTree = smeSet.TimeStampTree;
if (!smeSet.SemanticId.IsNullOrEmpty())
sme.SemanticId = new Reference(ReferenceTypes.ExternalReference,
new List<IKey>() { new Key(KeyTypes.GlobalReference, smeSet.SemanticId) });

return sme;
}

private static Reference CreateReferenceFromObject(Nodes.JsonNode obj)
{
var result = Jsonization.Deserialize.ReferenceFrom(obj);
if (result != null)
return result;
else
return new Reference(ReferenceTypes.ExternalReference, new List<IKey>());
}

public static string GetAASXPath(string aasId = "", string submodelId = "")
{
using var db = new AasContext();
int? aasxId = null;
if (!submodelId.IsNullOrEmpty())
{
var submodelDBList = db.SMSets.Where(s => s.Identifier == submodelId);
if (submodelDBList.Count() > 0)
aasxId = submodelDBList.First().AASXId;
}

if (!aasId.IsNullOrEmpty())
{
var aasDBList = db.AASSets.Where(a => a.Identifier == aasId);
if (aasDBList.Any())
aasxId = aasDBList.First().AASXId;
}

if (aasxId == null)
return string.Empty;

var aasxDBList = db.AASXSets.Where(a => a.Id == aasxId);
if (!aasxDBList.Any())
return string.Empty;

var aasxDB = aasxDBList.First();
return aasxDB.AASX;

}
}
}
4 changes: 2 additions & 2 deletions src/AasxServerDB/Edit.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using AdminShellNS;
using AdminShellNS;
using Microsoft.EntityFrameworkCore;
using AasxServerDB.Entities;

Expand Down Expand Up @@ -34,5 +34,5 @@ static public void Update(AdminShellPackageEnv env)
}
env.setWrite(false);
}
}
}
}
19 changes: 10 additions & 9 deletions src/AasxServerDB/Entities/AASSet.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations.Schema;

namespace AasxServerDB.Entities
{
public class AASSet
{
public int Id { get; set; }

[ForeignKey("AASXSet")] public int AASXId { get; set; }
public virtual AASXSet? AASXSet { get; set; }
[ForeignKey("AASXSet")]
public int AASXId { get; set; }
public virtual AASXSet? AASXSet { get; set; }

public string? Identifier { get; set; }
public string? IdShort { get; set; }
public string? AssetKind { get; set; }
public string? GlobalAssetId { get; set; }
public string? Identifier { get; set; }
public string? IdShort { get; set; }
public string? AssetKind { get; set; }
public string? GlobalAssetId { get; set; }

public DateTime TimeStampCreate { get; set; }
public DateTime TimeStamp { get; set; }
public DateTime TimeStampTree { get; set; }
public DateTime TimeStamp { get; set; }
public DateTime TimeStampTree { get; set; }

public virtual ICollection<SMSet> SMSets { get; } = new List<SMSet>();
}
Expand Down
5 changes: 3 additions & 2 deletions src/AasxServerDB/Entities/AASXSet.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
namespace AasxServerDB.Entities
namespace AasxServerDB.Entities
{
public class AASXSet
{
public int Id { get; set; }
public int Id { get; set; }

public string? AASX { get; set; }

public virtual ICollection<AASSet> AASSets { get; } = new List<AASSet>();
Expand Down
Loading

0 comments on commit d638896

Please sign in to comment.