diff --git a/src/AasxCsharpLibrary/AdminShellUtil.cs b/src/AasxCsharpLibrary/AdminShellUtil.cs index 244844e6..e85bfb8b 100644 --- a/src/AasxCsharpLibrary/AdminShellUtil.cs +++ b/src/AasxCsharpLibrary/AdminShellUtil.cs @@ -413,6 +413,7 @@ public static ISubmodelElement CreateSubmodelElementFromEnum(AasSubmodelElements } #endregion + public static string EvalToNonNullString(string fmt, object o, string elseString = "") { if (o == null) @@ -427,6 +428,17 @@ public static string EvalToNonEmptyString(string fmt, string o, string elseStrin return string.Format(fmt, o); } + /// + /// Some syntactic sugar to easily take the first string which has content. + /// + public static string TakeFirstContent(params string[] choices) + { + foreach (var c in choices) + if (c != null && c.Trim().Length > 0) + return c; + return ""; + } + /// /// If len of exceeds then /// string is shortened and returned with an ellipsis(…) at the end. @@ -789,18 +801,40 @@ public static string WrapLinesAtColumn(string text, int columnLimit) // Reflection // + /// + /// Returns type or the underlying type, if is a Nullable + /// + public static Type GetTypeOrUnderlyingType(Type type) + { + var nut = Nullable.GetUnderlyingType(type); + if (nut != null) + type = nut; + return type; + } + + /// + /// Tries parsing the value, supposedly a string, to a field value + /// for reflection of type specific data. + /// Works for most scalars, dateTime, string. + /// public static void SetFieldLazyValue(FieldInfo f, object obj, object value) { // access if (f == null || obj == null) return; - switch (Type.GetTypeCode(f.FieldType)) + // 2024-01-04: make function more suitable for + switch (Type.GetTypeCode(GetTypeOrUnderlyingType(f.FieldType))) { case TypeCode.String: f.SetValue(obj, "" + value); break; + case TypeCode.DateTime: + if (DateTime.TryParse("" + value, out var dt)) + f.SetValue(obj, dt); + break; + case TypeCode.Byte: if (Byte.TryParse("" + value, out var ui8)) f.SetValue(obj, ui8); @@ -842,12 +876,24 @@ public static void SetFieldLazyValue(FieldInfo f, object obj, object value) break; case TypeCode.Single: + if (value is double vd) + f.SetValue(obj, vd); + else + if (value is float vf) + f.SetValue(obj, vf); + else if (Single.TryParse("" + value, NumberStyles.Float, CultureInfo.InvariantCulture, out var sgl)) f.SetValue(obj, sgl); break; case TypeCode.Double: + if (value is double vd2) + f.SetValue(obj, vd2); + else + if (value is float vf2) + f.SetValue(obj, vf2); + else if (Double.TryParse("" + value, NumberStyles.Float, CultureInfo.InvariantCulture, out var dbl)) f.SetValue(obj, dbl); @@ -863,6 +909,102 @@ public static void SetFieldLazyValue(FieldInfo f, object obj, object value) } } + /// + /// Rathhe sepcialised: adding a type-specific value to a list + /// of type-specific values. + /// Works for most scalars, dateTime, string. + /// + public static void AddToListLazyValue(object obj, object value) + { + // access + if (obj == null) + return; + + switch (obj) + { + case List lstr: + lstr.Add("" + value); + break; + + case List ldt: + if (DateTime.TryParse("" + value, out var dt)) + ldt.Add(dt); + break; + + case List lbyte: + if (Byte.TryParse("" + value, out var ui8)) + lbyte.Add(ui8); + break; + + case List lsbyte: + if (SByte.TryParse("" + value, out var i8)) + lsbyte.Add(i8); + break; + + case List li16: + if (Int16.TryParse("" + value, out var i16)) + li16.Add(i16); + break; + + case List li32: + if (Int32.TryParse("" + value, out var i32)) + li32.Add(i32); + break; + + case List li64: + if (Int64.TryParse("" + value, out var i64)) + li64.Add(i64); + break; + + case List lui16: + if (UInt16.TryParse("" + value, out var ui16)) + lui16.Add(ui16); + break; + + case List lui32: + if (UInt32.TryParse("" + value, out var ui32)) + lui32.Add(ui32); + break; + + case List lui64: + if (UInt64.TryParse("" + value, out var ui64)) + lui64.Add(ui64); + break; + + case List lfloat: + if (value is double vd) + lfloat.Add((float) vd); + else + if (value is float vf) + lfloat.Add(vf); + else + if (Single.TryParse("" + value, NumberStyles.Float, + CultureInfo.InvariantCulture, out var sgl)) + lfloat.Add(sgl); + break; + + case List ldouble: + if (value is double vd2) + ldouble.Add(vd2); + else + if (value is float vf2) + ldouble.Add(vf2); + else + if (Double.TryParse("" + value, NumberStyles.Float, + CultureInfo.InvariantCulture, out var dbl)) + ldouble.Add(dbl); + break; + + case List lbool: + var isFalse = value == null + || (value is int vi && vi == 0) + || (value is string vs && (vs == "" || vs == "false")) + || (value is bool vb && !vb); + lbool.Add(!isFalse); + break; + } + } + // // temp file utilities // diff --git a/src/AasxCsharpLibrary/Extensions/ExtendReference.cs b/src/AasxCsharpLibrary/Extensions/ExtendReference.cs index 10a459f6..4026e6cb 100644 --- a/src/AasxCsharpLibrary/Extensions/ExtendReference.cs +++ b/src/AasxCsharpLibrary/Extensions/ExtendReference.cs @@ -186,6 +186,9 @@ public static bool Matches(this IReference reference, IReference otherReference, return match; } + /// + /// Useful, if the searched reference will have only on key (e.g. ECLASS properties) + /// public static bool MatchesExactlyOneKey(this IReference reference, IKey key, MatchMode matchMode = MatchMode.Strict) { if (key == null || reference.Keys == null || reference.Keys.Count != 1) diff --git a/src/AasxCsharpLibrary/Extensions/ExtendReferenceList.cs b/src/AasxCsharpLibrary/Extensions/ExtendReferenceList.cs new file mode 100644 index 00000000..8708236c --- /dev/null +++ b/src/AasxCsharpLibrary/Extensions/ExtendReferenceList.cs @@ -0,0 +1,35 @@ +/* +Copyright (c) 2018-2023 Festo SE & Co. KG +Author: Michael Hoffmeister + +This source code is licensed under the Apache License 2.0 (see LICENSE.txt). + +This source code may use other Open Source software components (see LICENSE.txt). +*/ +using AdminShellNS.Exceptions; +using System.Collections.Generic; +using System.Linq; + +namespace Extensions +{ + public static class ExtendReferenceList + { + /// + /// Useful, if the searched reference will have only on key (e.g. ECLASS properties) + /// + public static bool MatchesAnyWithExactlyOneKey(this List reflist, IKey key, MatchMode matchMode = MatchMode.Strict) + { + if (key == null || reflist == null || reflist.Count < 1) + { + return false; + } + + var found = false; + foreach (var r in reflist) + found = found || r.MatchesExactlyOneKey(key, matchMode); + + return found; + } + } + +} diff --git a/src/AasxPackageExplorer.sln b/src/AasxPackageExplorer.sln index b9c9e43a..e4732969 100644 --- a/src/AasxPackageExplorer.sln +++ b/src/AasxPackageExplorer.sln @@ -162,6 +162,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AasxPluginContactInformatio EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AasxCore.Samm2_2_0", "AasxCore.Samm2_2_0\AasxCore.Samm2_2_0.csproj", "{DCFD6C2F-A7C5-4AA2-82F3-0D3856E7EA99}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AasxPluginAssetInterfaceDesc", "AasxPluginAssetInterfaceDesc\AasxPluginAssetInterfaceDesc.csproj", "{92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -419,8 +421,8 @@ Global {6D1A03B2-EBA7-4CE2-9237-DF9AD7128947}.ReleaseWithoutCEF|x64.Build.0 = Release|Any CPU {6D1A03B2-EBA7-4CE2-9237-DF9AD7128947}.ReleaseWithoutCEF|x86.ActiveCfg = Release|Any CPU {6D1A03B2-EBA7-4CE2-9237-DF9AD7128947}.ReleaseWithoutCEF|x86.Build.0 = Release|Any CPU - {042305D7-DB68-4D02-B08F-ED47BBCD705E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {042305D7-DB68-4D02-B08F-ED47BBCD705E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {042305D7-DB68-4D02-B08F-ED47BBCD705E}.Debug|Any CPU.ActiveCfg = Debug|x64 + {042305D7-DB68-4D02-B08F-ED47BBCD705E}.Debug|Any CPU.Build.0 = Debug|x64 {042305D7-DB68-4D02-B08F-ED47BBCD705E}.Debug|x64.ActiveCfg = Debug|Any CPU {042305D7-DB68-4D02-B08F-ED47BBCD705E}.Debug|x64.Build.0 = Debug|Any CPU {042305D7-DB68-4D02-B08F-ED47BBCD705E}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -1971,6 +1973,36 @@ Global {DCFD6C2F-A7C5-4AA2-82F3-0D3856E7EA99}.ReleaseWithoutCEF|x64.Build.0 = Release|Any CPU {DCFD6C2F-A7C5-4AA2-82F3-0D3856E7EA99}.ReleaseWithoutCEF|x86.ActiveCfg = Release|Any CPU {DCFD6C2F-A7C5-4AA2-82F3-0D3856E7EA99}.ReleaseWithoutCEF|x86.Build.0 = Release|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.Debug|x64.ActiveCfg = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.Debug|x64.Build.0 = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.Debug|x86.ActiveCfg = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.Debug|x86.Build.0 = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.DebugSlow|Any CPU.ActiveCfg = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.DebugSlow|Any CPU.Build.0 = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.DebugSlow|x64.ActiveCfg = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.DebugSlow|x64.Build.0 = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.DebugSlow|x86.ActiveCfg = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.DebugSlow|x86.Build.0 = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.DebugWithoutCEF|Any CPU.ActiveCfg = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.DebugWithoutCEF|Any CPU.Build.0 = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.DebugWithoutCEF|x64.ActiveCfg = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.DebugWithoutCEF|x64.Build.0 = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.DebugWithoutCEF|x86.ActiveCfg = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.DebugWithoutCEF|x86.Build.0 = Debug|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.Release|Any CPU.Build.0 = Release|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.Release|x64.ActiveCfg = Release|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.Release|x64.Build.0 = Release|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.Release|x86.ActiveCfg = Release|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.Release|x86.Build.0 = Release|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.ReleaseWithoutCEF|Any CPU.ActiveCfg = Release|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.ReleaseWithoutCEF|Any CPU.Build.0 = Release|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.ReleaseWithoutCEF|x64.ActiveCfg = Release|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.ReleaseWithoutCEF|x64.Build.0 = Release|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.ReleaseWithoutCEF|x86.ActiveCfg = Release|Any CPU + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8}.ReleaseWithoutCEF|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2035,6 +2067,7 @@ Global {DA75828B-E5AC-4E9D-AE1F-398F8FF5AE25} = {66D730EB-B9D7-4C3A-8954-0F86240AD612} {938BB137-DC45-4A84-B0C9-AC46DA321FDB} = {66D730EB-B9D7-4C3A-8954-0F86240AD612} {DCFD6C2F-A7C5-4AA2-82F3-0D3856E7EA99} = {DDA9C372-F8ED-4099-A53C-01B9333FD985} + {92AC5ECF-6DB4-4ABD-8DD4-6EFA0BE65BA8} = {66D730EB-B9D7-4C3A-8954-0F86240AD612} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1AE21162-9541-4B98-A49C-A63B6AD03998} diff --git a/src/AasxPackageExplorer/debug.MIHO.script b/src/AasxPackageExplorer/debug.MIHO.script index 2997bd86..27dfc24c 100644 --- a/src/AasxPackageExplorer/debug.MIHO.script +++ b/src/AasxPackageExplorer/debug.MIHO.script @@ -11,7 +11,7 @@ Tool("editkey"); Select("Submodel", "First"); // Tool("sammaspectimport", "File", "C:\\HOMI\\Develop\\Aasx\\repo\\samm-test\\Aspect_Example_SML_MLP.ttl"); -Tool("exportpredefineconcepts", "File", "C:\HOMI\Develop\Aasx\repo\aid\new.txt"); +// Tool("exportpredefineconcepts", "File", "C:\HOMI\Develop\Aasx\repo\aid\new.txt"); // Tool("submodelinstancefromsmtconcepts"); // Select("ConceptDescription", "First"); // Select("ConceptDescription", "Next"); diff --git a/src/AasxPackageExplorer/options-debug.MIHO.json b/src/AasxPackageExplorer/options-debug.MIHO.json index 57406223..7fff4025 100644 --- a/src/AasxPackageExplorer/options-debug.MIHO.json +++ b/src/AasxPackageExplorer/options-debug.MIHO.json @@ -33,7 +33,8 @@ // "AasxToLoad": "C:\\HOMI\\Develop\\Aasx\\repo\\samm-test\\SMT_and_SAMM_Showcase_v02.aasx", // "AasxToLoad": "C:\\HOMI\\Develop\\Aasx\\repo\\samm-test\\Aspect_Example_SML_MLP.ttl", // "AasxToLoad": "C:\\HOMI\\Develop\\Aasx\\repo\\8001203_SPAU-P10R-T-R18M-L-PNLK-PNVBA-M8D_060ff64f-9fd2-422d-81ce-b17e49f007c5_work.aasx", - "AasxToLoad": "C:\\HOMI\\Develop\\Aasx\\repo\\aid\\2023_AID1.0_Template_Rework_MIHO.aasx", + // "AasxToLoad": "C:\\HOMI\\Develop\\Aasx\\repo\\aid\\2023_AID1.0_Template_Rework_MIHO.aasx", + "AasxToLoad": "C:\\HOMI\\Develop\\Aasx\\repo\\aid\\aid-test-2.aasx", // "AasxRepositoryFn": "C:\\HOMI\\Develop\\Aasx\\repo_Festo_demo_case_V3\\Festo-DemoCase-repo-V3-local.json", "WindowLeft": 200, "WindowTop": -1, @@ -120,6 +121,10 @@ "Args": [] }, */ + { + "Path": "..\\..\\..\\..\\..\\..\\AasxPluginAssetInterfaceDesc\\bin\\Debug\\net6.0-windows\\AasxPluginAssetInterfaceDesc.dll", + "Args": [] + }, { "Path": "..\\..\\..\\..\\..\\..\\AasxPluginKnownSubmodels\\bin\\Debug\\net6.0-windows\\AasxPluginKnownSubmodels.dll", "Args": [] diff --git a/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.csproj b/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.csproj new file mode 100644 index 00000000..1041bb6d --- /dev/null +++ b/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.csproj @@ -0,0 +1,51 @@ + + + net6.0-windows + library + false + true + + + + true + false + + + + + + + + + PreserveNewest + + + PreserveNewest + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + + + + diff --git a/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.options.json b/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.options.json new file mode 100644 index 00000000..5cba3995 --- /dev/null +++ b/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.options.json @@ -0,0 +1,46 @@ +{ + "Records": [ + { + "RecordType": 0, + "AllowSubmodelSemanticId": [ + { + "type": "Submodel", + "local": false, + "value": "http://www.admin-shell.io/mtp/v1/submodel", + "index": 0, + "idType": "IRI" + } + ] + }, + { + "RecordType": 1, + "AllowSubmodelSemanticId": [ + { + "type": "Submodel", + "local": false, + "value": "http://www.admin-shell.io/mtp/v1/mtp-instance-submodel", + "index": 0, + "idType": "IRI" + } + ] + } + ], + "SymbolMappings": [ + { + "EClassVersions": null, + "EClassClasses": "37010201", + "EClassIRDIs": null, + "SymbolDefault": "PNID_Festo.manual_valve_active-u-nozzled", + "SymbolActive": null, + "SymbolIntermediate": null, + "Comment": "V003,45fd1be7-d9fe-426a-aec7-ca16a09cb64b" + } + ], + "VisuOptions": { + "Background": "#707070", + "StateColorActive": "#2020ff", + "StateColorNonActive": "#202020", + "StateColorForward": "#2020ff", + "StateColorReverse": "#20ff20" + } +} \ No newline at end of file diff --git a/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.plugin b/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.plugin new file mode 100644 index 00000000..3beebdf2 --- /dev/null +++ b/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.plugin @@ -0,0 +1 @@ +This file tags the according .ddl to be a plug-in for AasxPackageExplorer. \ No newline at end of file diff --git a/src/AasxPluginAssetInterfaceDesc/AidInterfaceStatus.cs b/src/AasxPluginAssetInterfaceDesc/AidInterfaceStatus.cs new file mode 100644 index 00000000..cd804d39 --- /dev/null +++ b/src/AasxPluginAssetInterfaceDesc/AidInterfaceStatus.cs @@ -0,0 +1,337 @@ +/* +Copyright (c) 2018-2023 Festo SE & Co. KG +Author: Michael Hoffmeister + +This source code is licensed under the Apache License 2.0 (see LICENSE.txt). + +This source code may use other Open Source software components (see LICENSE.txt). +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AasxPredefinedConcepts; +using Aas = AasCore.Aas3_0; +using AdminShellNS; +using Extensions; +using WpfMtpControl; +using AasxIntegrationBase; +using AasxPredefinedConcepts.AssetInterfacesDescription; +using FluentModbus; +using System.Net; +using System.Text.RegularExpressions; +using System.Globalization; + +namespace AasxPluginAssetInterfaceDescription +{ + public enum AidIfxItemKind { Unknown, Property, Action, Event }; + + public class AidIfxItemStatus + { + /// + /// Which kind of information: Property, Action, Event. + /// + public AidIfxItemKind Kind = AidIfxItemKind.Unknown; + + /// + /// Contains the hierarchy information, where the item is stored in hierarchy + /// of the given interface (end-point). + /// + public string Location = ""; + + /// + /// Display name of the item. Could be from IdShort, key, title. + /// + public string DisplayName = ""; + + /// + /// Contains the forms information with all detailed information for the + /// technology. + /// + public CD_Forms FormData = null; + + /// + /// String data for value incl. unit information. + /// + public string Value = ""; + + /// + /// Link to entity (property, action, event). + /// + public object Tag = null; + } + + public enum AidInterfaceTechnology { HTTP, Modbus, MQTT } + + public class AidInterfaceStatus + { + /// + /// Technology being used .. + /// + public AidInterfaceTechnology Technology = AidInterfaceTechnology.HTTP; + + /// + /// Display name. Could be from SMC IdShort or title. + /// Will be printed in bold. + /// + public string DisplayName = ""; + + /// + /// Further infornation. Printed in light appearence. + /// + public string Info = ""; + + /// + /// The information items (properties, actions, events) + /// + public List Items = new List(); + + /// + /// Base connect information. + /// + public string EndpointBase = ""; + + /// + /// Link to entity (interface). + /// + public object Tag = null; + + /// + /// Holds the technology connection currently used. + /// + public AidModbusConnection Connection = null; + } + + public class AidModbusConnection + { + public Uri TargetUri; + + public ModbusTcpClient Client; + + public DateTime LastActive = default(DateTime); + + public bool Open() + { + try + { + Client = new ModbusTcpClient(); + Client.Connect(new IPEndPoint(IPAddress.Parse(TargetUri.Host), TargetUri.Port)); + LastActive = DateTime.Now; + return true; + } catch (Exception ex) + { + Client = null; + return false; + } + } + + public bool IsConnected() + { + return Client != null && Client.IsConnected; + } + + public void Close() + { + if (IsConnected()) + { + Client.Disconnect(); + Client = null; + } + else + { + Client = null; + } + } + + public void UpdateItemValue(AidModbusConnection conn, AidIfxItemStatus item) + { + // access + if (item?.FormData?.Href?.HasContent() != true + || item.FormData.Modbus_function?.HasContent() != true) + return; + + // decode address + quantity + // (assumption: 1 quantity = 2 bytes) + var match = Regex.Match(item.FormData.Href, @"^(\d{1,5})(\?quantity=(\d+))?$"); + if (!match.Success) + return; + + if (!int.TryParse(match.Groups[1].ToString(), out var address)) + return; + if (!int.TryParse(match.Groups[3].ToString(), out var quantity)) + quantity = 1; + quantity = Math.Max(0, Math.Min(0xffff, quantity)); + + // perform function (id = in data) + byte[] id = null; + if (item.FormData.Modbus_function.Trim().ToLower() == "readholdingregisters") + { + // readHoldingRegisters + id = conn.Client.ReadHoldingRegisters(99, address, quantity).ToArray(); + // time + conn.LastActive = DateTime.Now; + } + + // success with reading? + if (id == null || id.Length < 1) + return; + + // swapping (od = out data) + // https://doc.iobroker.net/#de/adapters/adapterref/iobroker.modbus/README.md?wp + var mbtp = item.FormData.Modbus_type?.ToLower().Trim(); + byte[] od = id.ToArray(); + if (quantity == 2) + { + // 32bit operation on AABBCCDD + if (mbtp.EndsWith("be")) + { + // big endian AABBCCDD => AABBCCDD + od[3] = id[3]; od[2] = id[2]; od[1] = id[1]; od[0] = id[0]; + } + else + if (mbtp.EndsWith("le")) + { + // little endian AABBCCDD => DDCCBBAA + od[3] = id[0]; od[2] = id[1]; od[1] = id[2]; od[0] = id[3]; + } + else + if (mbtp.EndsWith("sw")) + { + // Big Endian Word Swap AABBCCDD => CCDDAABB + od[3] = id[2]; od[2] = id[3]; od[1] = id[0]; od[0] = id[1]; + } + else + if (mbtp.EndsWith("sb")) + { + // Big Endian Byte Swap AABBCCDD => DDCCBBAA + od[3] = id[0]; od[2] = id[1]; od[1] = id[2]; od[0] = id[3]; + } + } + else + if (quantity == 1) + { + // 16bit operation on AABB + if (mbtp.EndsWith("le")) + { + // little endian AABB => BBAA + od[1] = id[0]; od[0] = id[1]; + } + } + + // conversion to value + // idea: (1) convert to binary type, (2) convert to adequate string representation + var strval = ""; + if (mbtp.StartsWith("uint32") && quantity >= 2) + { + strval = BitConverter.ToUInt32(od).ToString(); + } + else + if (mbtp.StartsWith("int32") && quantity >= 2) + { + strval = BitConverter.ToInt32(od).ToString(); + } + else + if (mbtp.StartsWith("uint16") && quantity >= 1) + { + strval = BitConverter.ToUInt16(od).ToString(); + } + else + if (mbtp.StartsWith("int16") && quantity >= 1) + { + strval = BitConverter.ToInt16(od).ToString(); + } + else + if (mbtp.StartsWith("uint8") && quantity >= 1) + { + strval = Convert.ToByte(od[0]).ToString(); + } + else + if (mbtp.StartsWith("int8") && quantity >= 1) + { + strval = Convert.ToSByte(od[0]).ToString(); + } + else + if (mbtp.StartsWith("float") && quantity >= 2) + { + strval = BitConverter.ToSingle(od).ToString("R", CultureInfo.InvariantCulture); + } + else + if (mbtp.StartsWith("double") && quantity >= 4) + { + strval = BitConverter.ToDouble(od).ToString("R", CultureInfo.InvariantCulture); + } + else + if (mbtp.StartsWith("string") && quantity >= 1) + { + strval = BitConverter.ToString(od); + } + + // save in item + item.Value = strval; + } + } + + public class AidModbusConnections : Dictionary + { + public AidModbusConnection GetOrCreate(string target) + { + if (!Uri.TryCreate(target, UriKind.Absolute, out var uri)) + return null; + if (this.ContainsKey(uri)) + return this[uri]; + + var conn = new AidModbusConnection() { TargetUri = uri }; + return conn; + } + } + + /// + /// Holds track of all current Aid interface status information. + /// Idea: well be preset and updated by plug-in events. + /// Will then allow technical connect to asset interfaces. + /// Will exist **longer** than the invocation of just the plugin UI. + /// + public class AidAllInterfaceStatus + { + public List InterfaceStatus = new List(); + + public AidModbusConnections ModbusConnections = new AidModbusConnections(); + + /// + /// Will connect to each target once, get values and will disconnect again. + /// + public void UpdateValuesSingleShot() + { + // Modbus + // Open, connect and read all connections + foreach (var ifc in InterfaceStatus.Where((i) => i.Technology == AidInterfaceTechnology.Modbus)) + { + // get a connection + if (ifc.EndpointBase?.HasContent() != true) + continue; + var conn = ModbusConnections.GetOrCreate(ifc.EndpointBase); + if (conn == null) + continue; + + // open it + if (!conn.Open()) + continue; + ifc.Connection = conn; + + // go thru all items + foreach (var item in ifc.Items) + conn.UpdateItemValue(conn, item); + } + + // close all connections + foreach (var ifc in InterfaceStatus.Where((i) => i.Technology == AidInterfaceTechnology.Modbus)) + { + if (ifc.Connection?.IsConnected() == true) + ifc.Connection.Close(); + } + } + } + +} diff --git a/src/AasxPluginAssetInterfaceDesc/AssetInterfaceAnyUiControl.cs b/src/AasxPluginAssetInterfaceDesc/AssetInterfaceAnyUiControl.cs new file mode 100644 index 00000000..aa2ddcf2 --- /dev/null +++ b/src/AasxPluginAssetInterfaceDesc/AssetInterfaceAnyUiControl.cs @@ -0,0 +1,437 @@ +/* +Copyright (c) 2018-2023 Festo SE & Co. KG +Author: Michael Hoffmeister + +This source code is licensed under the Apache License 2.0 (see LICENSE.txt). + +This source code may use other Open Source software components (see LICENSE.txt). +*/ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using AasxIntegrationBase; +using Aas = AasCore.Aas3_0; +using AdminShellNS; +using Extensions; +using AnyUi; +using Newtonsoft.Json; +using AasxPredefinedConcepts; +using AasxPredefinedConcepts.AssetInterfacesDescription; +using System.Windows.Shapes; +using AasxIntegrationBaseGdi; +using FluentModbus; +using System.Net; + +namespace AasxPluginAssetInterfaceDescription +{ + public class AssetInterfaceAnyUiControl + { + #region Members + //============= + + private LogInstance _log = new LogInstance(); + private AdminShellPackageEnv _package = null; + private Aas.Submodel _submodel = null; + private AssetInterfaceOptions _options = null; + private PluginEventStack _eventStack = null; + private AnyUiStackPanel _panel = null; + + private AidAllInterfaceStatus _allInterfaceStatus = null; + + protected AnyUiSmallWidgetToolkit _uitk = new AnyUiSmallWidgetToolkit(); + + protected Dictionary _dictTechnologyToBitmap = + new Dictionary(); + + #endregion + + #region Members to be kept for state/ update + //============= + + protected double _lastScrollPosition = 0.0; + + protected int _selectedLangIndex = 0; + protected string _selectedLangStr = null; + + #endregion + + #region Constructors + //============= + + // ReSharper disable EmptyConstructor + public AssetInterfaceAnyUiControl() + { + } + // ReSharper enable EmptyConstructor + + public void Start( + LogInstance log, + AdminShellPackageEnv thePackage, + Aas.Submodel theSubmodel, + AssetInterfaceOptions theOptions, + PluginEventStack eventStack, + AnyUiStackPanel panel, + AidAllInterfaceStatus ifxStatus) + { + // internal members + _log = log; + _package = thePackage; + _submodel = theSubmodel; + _options = theOptions; + _eventStack = eventStack; + _panel = panel; + _allInterfaceStatus = ifxStatus; + + // some required logos + _dictTechnologyToBitmap = new Dictionary(); + if (OperatingSystem.IsWindowsVersionAtLeast(7)) + { + _dictTechnologyToBitmap.Add(AidInterfaceTechnology.HTTP, + AnyUiGdiHelper.CreateAnyUiBitmapFromResource( + "AasxPluginAssetInterfaceDesc.Resources.logo-http.png", + assembly: Assembly.GetExecutingAssembly())); + _dictTechnologyToBitmap.Add(AidInterfaceTechnology.Modbus, + AnyUiGdiHelper.CreateAnyUiBitmapFromResource( + "AasxPluginAssetInterfaceDesc.Resources.logo-modbus.png", + assembly: Assembly.GetExecutingAssembly())); + _dictTechnologyToBitmap.Add(AidInterfaceTechnology.MQTT, + AnyUiGdiHelper.CreateAnyUiBitmapFromResource( + "AasxPluginAssetInterfaceDesc.Resources.logo-mqqt.png", + assembly: Assembly.GetExecutingAssembly())); + } + + // fill given panel + RenderFullView(_panel, _uitk, _package, _submodel); + } + + public static AssetInterfaceAnyUiControl FillWithAnyUiControls( + LogInstance log, + object opackage, object osm, + AssetInterfaceOptions options, + PluginEventStack eventStack, + object opanel, + AidAllInterfaceStatus ifxStatus) + { + // access + var package = opackage as AdminShellPackageEnv; + var sm = osm as Aas.Submodel; + var panel = opanel as AnyUiStackPanel; + if (package == null || sm == null || panel == null) + return null; + + // the Submodel elements need to have parents + sm.SetAllParents(); + + // factory this object + var aidCntl = new AssetInterfaceAnyUiControl(); + aidCntl.Start(log, package, sm, options, eventStack, panel, ifxStatus); + + // return shelf + return aidCntl; + } + + #endregion + + #region Display Submodel + //============= + + private void RenderFullView( + AnyUiStackPanel view, AnyUiSmallWidgetToolkit uitk, + AdminShellPackageEnv package, + Aas.Submodel sm) + { + // test trivial access + if (_options == null || _submodel?.SemanticId == null) + return; + + // make sure for the right Submodel + var foundRecs = new List(); + foreach (var rec in _options.LookupAllIndexKey( + _submodel?.SemanticId?.GetAsExactlyOneKey())) + foundRecs.Add(rec); + + // render + RenderPanelOutside(view, uitk, foundRecs, package, sm); + } + + protected void RenderPanelOutside( + AnyUiStackPanel view, AnyUiSmallWidgetToolkit uitk, + IEnumerable foundRecs, + AdminShellPackageEnv package, + Aas.Submodel sm) + { + // make an outer grid, very simple grid of two rows: header & body + var outer = view.Add(uitk.AddSmallGrid(rows: 7, cols: 1, colWidths: new[] { "*" })); + + // + // Bluebar + // + + var bluebar = uitk.AddSmallGridTo(outer, 0, 0, 1, cols: 5, colWidths: new[] { "*", "#", "#", "#", "#" }); + + bluebar.Margin = new AnyUiThickness(0); + bluebar.Background = AnyUiBrushes.LightBlue; + + uitk.AddSmallBasicLabelTo(bluebar, 0, 0, margin: new AnyUiThickness(8, 6, 0, 6), + foreground: AnyUiBrushes.DarkBlue, + fontSize: 1.5f, + setBold: true, + content: $"Asset Interfaces Descriptions"); + + // + // Scroll area + // + + // small spacer + outer.RowDefinitions[1] = new AnyUiRowDefinition(2.0, AnyUiGridUnitType.Pixel); + uitk.AddSmallBasicLabelTo(outer, 1, 0, + fontSize: 0.3f, + verticalAlignment: AnyUiVerticalAlignment.Top, + content: "", background: AnyUiBrushes.White); + + // add the body, a scroll viewer + outer.RowDefinitions[2] = new AnyUiRowDefinition(1.0, AnyUiGridUnitType.Star); + var scroll = AnyUiUIElement.RegisterControl( + uitk.AddSmallScrollViewerTo(outer, 2, 0, + horizontalScrollBarVisibility: AnyUiScrollBarVisibility.Disabled, + verticalScrollBarVisibility: AnyUiScrollBarVisibility.Visible, + flattenForTarget: AnyUiTargetPlatform.Browser, initialScrollPosition: _lastScrollPosition), + (o) => + { + if (o is Tuple positions) + { + _lastScrollPosition = positions.Item2; + } + return new AnyUiLambdaActionNone(); + }); + + // content of the scroll viewer + // need a stack panel to add inside + var inner = new AnyUiStackPanel() + { + Orientation = AnyUiOrientation.Vertical, + Margin = new AnyUiThickness(2) + }; + scroll.Content = inner; + + if (foundRecs != null) + foreach (var rec in foundRecs) + RenderPanelInner(inner, uitk, rec, package, sm); + } + + #endregion + + #region Inner + //============= + + protected void RenderPanelInner( + AnyUiStackPanel view, AnyUiSmallWidgetToolkit uitk, + AssetInterfaceOptionsRecord rec, + AdminShellPackageEnv package, + Aas.Submodel sm) + { + // access + if (view == null || uitk == null || sm == null || rec == null) + return; + + var grid = view.Add(uitk.AddSmallGrid(rows: 3, cols: 2, colWidths: new[] { "110:", "*" })); + + uitk.AddSmallLabelTo(grid, 0, 0, content: "Debug:"); + AnyUiUIElement.RegisterControl( + uitk.AddSmallButtonTo(grid, 0, 1, + margin: new AnyUiThickness(2), setHeight: 21, + padding: new AnyUiThickness(2, 0, 2, 0), + content: "Test .."), + (o) => + { + try + { + //var client = new ModbusTcpClient(); + //client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5020)); + //var byteData = client.ReadHoldingRegisters(99, 1, 8); + + _allInterfaceStatus?.UpdateValuesSingleShot(); + } + catch (Exception ex) + { + ; + } + return new AnyUiLambdaActionNone(); + }); + + // get SM data and + _allInterfaceStatus.InterfaceStatus = PrepareAidInformation(sm); + RenderTripleRowData(view, uitk, _allInterfaceStatus.InterfaceStatus); + } + + #endregion + + #region Update + //============= + + public void Update(params object[] args) + { + // check args + if (args == null || args.Length < 1 + || !(args[0] is AnyUiStackPanel newPanel)) + return; + + // ok, re-assign panel and re-display + _panel = newPanel; + _panel.Children.Clear(); + + // the default: the full shelf + RenderFullView(_panel, _uitk, _package, _submodel); + } + + #endregion + + #region Interface items + //===================== + + protected List PrepareAidInformation(Aas.Submodel sm) + { + // access + var res = new List(); + if (sm == null) + return res; + + // get data + var data = new AasxPredefinedConcepts.AssetInterfacesDescription.CD_AssetInterfacesDescription(); + PredefinedConceptsClassMapper.ParseAasElemsToObject(_submodel, data); + + // prepare + foreach (var tech in AdminShellUtil.GetEnumValues()) + { + var ifxs = data?.InterfaceHTTP; + if (tech == AidInterfaceTechnology.Modbus) ifxs = data?.InterfaceMODBUS; + if (tech == AidInterfaceTechnology.MQTT) ifxs = data?.InterfaceMQTT; + if (ifxs == null || ifxs.Count < 1) + continue; + foreach (var ifx in ifxs) + { + // new interface + var dn = AdminShellUtil.TakeFirstContent(ifx.Title, ifx.__Info__?.Referable?.IdShort); + var aidIfx = new AidInterfaceStatus() + { + Technology = tech, + DisplayName = $"{dn}", + Info = $"{ifx.EndpointMetadata?.Base}", + EndpointBase = "" + ifx.EndpointMetadata?.Base, + Tag = ifx + }; + res.Add(aidIfx); + + // Properties .. lambda recursion + Action recurseProp = null; + recurseProp = (location, propName) => + { + // add item + var ifcItem = new AidIfxItemStatus() { + Kind = AidIfxItemKind.Property, + Location = location, + DisplayName = AdminShellUtil.TakeFirstContent( + propName.Title, propName.Key, propName.__Info__?.Referable?.IdShort), + FormData = propName.Forms, + Value = "???" + }; + aidIfx.Items.Add(ifcItem); + + // directly recurse? + if (propName?.Properties?.Property != null) + foreach (var child in propName.Properties.Property) + recurseProp(location + " . " + ifcItem.DisplayName, child); + }; + + if (ifx.InterfaceMetadata?.Properties?.Property == null) + continue; + foreach (var propName in ifx.InterfaceMetadata?.Properties?.Property) + recurseProp("\u2302", propName); + } + } + + return res; + } + + protected void RenderTripleRowData( + AnyUiStackPanel view, AnyUiSmallWidgetToolkit uitk, + List interfaces) + { + // access + if (interfaces == null) + return; + + // ok + var grid = view.Add(uitk.AddSmallGrid(rows: interfaces.Count, cols: 5, colWidths: new[] { "40:", "1*", "1*", "1*", "100:" })); + int rowIndex = 0; + foreach (var ifx in interfaces) + { + // heading + grid.RowDefinitions.Add(new AnyUiRowDefinition()); + + var headGrid = uitk.Set( + uitk.AddSmallGridTo(grid, rowIndex++, 0, + rows: 1, cols: 3, colWidths: new[] { "#", "#", "#" }, + margin: new AnyUiThickness(0, 8, 0, 4)), + colSpan: 5); + + if (_dictTechnologyToBitmap.ContainsKey(ifx.Technology)) + uitk.AddSmallImageTo(headGrid, 0, 0, + margin: new AnyUiThickness(0, 0, 10, 0), + bitmap: _dictTechnologyToBitmap[ifx.Technology]); + + uitk.AddSmallBasicLabelTo(headGrid, 0, 1, fontSize: 1.2f, setBold: true, + verticalAlignment: AnyUiVerticalAlignment.Center, + verticalContentAlignment: AnyUiVerticalAlignment.Center, + content: ifx.DisplayName); + + uitk.AddSmallBasicLabelTo(headGrid, 0, 2, fontSize: 1.2f, + margin: new AnyUiThickness(10, 0, 0, 0), + verticalAlignment: AnyUiVerticalAlignment.Center, + verticalContentAlignment: AnyUiVerticalAlignment.Center, + content: ifx.Info); + + // items? + if (ifx.Items != null) + foreach (var item in ifx.Items) + { + // normal row, 3 bordered cells + grid.RowDefinitions.Add(new AnyUiRowDefinition()); + var cols = new[] { + "Prop.", item.Location, item.DisplayName, "" + item.FormData?.Href, item.Value }; + for (int ci = 0; ci < 5; ci++) + { + var brd = uitk.AddSmallBorderTo(grid, rowIndex, ci, + margin: (ci == 0) ? new AnyUiThickness(0, -1, 0, 0) + : new AnyUiThickness(-1, -1, 0, 0), + borderThickness: new AnyUiThickness(1.0), borderBrush: AnyUiBrushes.DarkGray); + brd.Child = new AnyUiSelectableTextBlock() + { + Text = cols[ci], + Padding = new AnyUiThickness(3, 1, 3, 1), + FontSize = 1.0f, + FontWeight = AnyUiFontWeight.Normal + }; + } + rowIndex++; + } + } + } + + #endregion + + #region Callbacks + //=============== + + + #endregion + + #region Utilities + //=============== + + + #endregion + } +} diff --git a/src/AasxPluginAssetInterfaceDesc/AssetInterfaceOptions.cs b/src/AasxPluginAssetInterfaceDesc/AssetInterfaceOptions.cs new file mode 100644 index 00000000..71a7a8be --- /dev/null +++ b/src/AasxPluginAssetInterfaceDesc/AssetInterfaceOptions.cs @@ -0,0 +1,50 @@ +/* +Copyright (c) 2018-2023 Festo SE & Co. KG +Author: Michael Hoffmeister + +This source code is licensed under the Apache License 2.0 (see LICENSE.txt). + +This source code may use other Open Source software components (see LICENSE.txt). +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AasxPredefinedConcepts; +using Aas = AasCore.Aas3_0; +using AdminShellNS; +using Extensions; +using WpfMtpControl; +using AasxIntegrationBase; + +namespace AasxPluginAssetInterfaceDescription +{ + public class AssetInterfaceOptionsRecord : AasxPluginOptionsLookupRecordBase + { + } + + public class AssetInterfaceOptions : AasxPluginLookupOptionsBase + { + public List Records = new List(); + + /// + /// Create a set of minimal options + /// + public static AssetInterfaceOptions CreateDefault() + { + var defs = new DefinitionsMTP.ModuleTypePackage(); + + var rec1 = new AssetInterfaceOptionsRecord(); + rec1.AllowSubmodelSemanticId = new[] { + new Aas.Key(Aas.KeyTypes.Submodel, + "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Submodel") }.ToList(); + + var opt = new AssetInterfaceOptions(); + opt.Records.Add(rec1); + + return opt; + } + } +} diff --git a/src/AasxPluginAssetInterfaceDesc/LICENSE.TXT b/src/AasxPluginAssetInterfaceDesc/LICENSE.TXT new file mode 100644 index 00000000..21bf04b1 --- /dev/null +++ b/src/AasxPluginAssetInterfaceDesc/LICENSE.TXT @@ -0,0 +1,244 @@ +Copyright (c) 2018-2023 Festo SE & Co. KG +, +author: Michael Hoffmeister + +This software is licensed under the Apache Public License 2.0 (APL-2.0) +(see below). +The AutomationML.Engine is licensed under the MIT license (MIT) +(see below). + +This application is a sample application for demonstration of the features +of the Administration Shell. +It is not allowed for productive use. The implementation uses the concepts +of the document "Details of the Asset +Administration Shell" published on www.plattform-i40.de which is licensed +under Creative Commons CC BY-ND 3.0 DE. + +The MIT License (MIT) + +Copyright (c) 2007 James Newton-King + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT 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. + +(http://www.apache.org/licenses/LICENSE-2.0) + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + +With respect to AutomationML.Engine +=================================== + +(https://raw.githubusercontent.com/AutomationML/AMLEngine2.1/master/license.txt) + +The MIT License (MIT) + +Copyright 2017 AutomationML e.V. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT 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. + diff --git a/src/AasxPluginAssetInterfaceDesc/Opc.Ua.SampleClient.Config.xml b/src/AasxPluginAssetInterfaceDesc/Opc.Ua.SampleClient.Config.xml new file mode 100644 index 00000000..8c8ea824 --- /dev/null +++ b/src/AasxPluginAssetInterfaceDesc/Opc.Ua.SampleClient.Config.xml @@ -0,0 +1,99 @@ + + + UA Core Sample Client + urn:localhost:OPCFoundation:CoreSampleClient + http://opcfoundation.org/UA/CoreSampleClient + Client_1 + + + + + + X509Store + CurrentUser\My + CN=UA Core Sample Client, C=US, S=Arizona, O=OPC Foundation, DC=localhost + + + + + Directory + %LocalApplicationData%/OPC Foundation/pki/issuer + + + + + Directory + %LocalApplicationData%/OPC Foundation/pki/trusted + + + + + Directory + %LocalApplicationData%/OPC Foundation/pki/rejected + + + + false + + + + + + + 600000 + 1048576 + 4194304 + 65535 + 4194304 + 65535 + 300000 + 3600000 + + + + + + + 600000 + + + + opc.tcp://{0}:4840/UADiscovery + + + + + + + 10000 + + + + %LocalApplicationData%/Logs/Opc.Ua.CoreSampleClient.log.txt + true + + + + + + + + + + + + + + + + true + + \ No newline at end of file diff --git a/src/AasxPluginAssetInterfaceDesc/Plugin.cs b/src/AasxPluginAssetInterfaceDesc/Plugin.cs new file mode 100644 index 00000000..89fd37de --- /dev/null +++ b/src/AasxPluginAssetInterfaceDesc/Plugin.cs @@ -0,0 +1,177 @@ +/* +Copyright (c) 2018-2023 Festo SE & Co. KG +Author: Michael Hoffmeister + +This source code is licensed under the Apache License 2.0 (see LICENSE.txt). + +This source code may use other Open Source software components (see LICENSE.txt). +*/ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Aas = AasCore.Aas3_0; +using AdminShellNS; +using Extensions; +using JetBrains.Annotations; +using Newtonsoft.Json; +using AasxPluginAssetInterfaceDescription; + +namespace AasxIntegrationBase // the namespace has to be: AasxIntegrationBase +{ + [UsedImplicitlyAttribute] + // the class names has to be: AasxPlugin and subclassing IAasxPluginInterface + public class AasxPlugin : AasxPluginBase + { + private AasxPluginAssetInterfaceDescription.AssetInterfaceOptions _options + = new AasxPluginAssetInterfaceDescription.AssetInterfaceOptions(); + + // TODO: make this multi-session!! + private AidAllInterfaceStatus _allInterfaceStatus = new AidAllInterfaceStatus(); + + public class Session : PluginSessionBase + { + public AasxPluginAssetInterfaceDescription.AssetInterfaceAnyUiControl AnyUiControl = null; + } + + public new void InitPlugin(string[] args) + { + // start .. + PluginName = "AasxPluginAssetInterfaceDescription"; + + // .. with built-in options + _options = AasxPluginAssetInterfaceDescription.AssetInterfaceOptions.CreateDefault(); + + // try load defaults options from assy directory + try + { + var newOpt = + AasxPluginOptionsBase + .LoadDefaultOptionsFromAssemblyDir( + this.GetPluginName(), Assembly.GetExecutingAssembly()); + if (newOpt != null) + _options = newOpt; + } + catch (Exception ex) + { + _log.Error(ex, "Exception when reading default options {1}"); + } + + // index them! + _options.IndexListOfRecords(_options.Records); + } + + public new object CheckForLogMessage() + { + return _log.PopLastShortTermPrint(); + } + + public new AasxPluginActionDescriptionBase[] ListActions() + { + var res = ListActionsBasicHelper( + enableCheckVisualExt: true, + enableOptions: true, + enableLicenses: true, + enablePanelAnyUi: true); + return res.ToArray(); + } + + public new AasxPluginResultBase ActivateAction(string action, params object[] args) + { + // for speed reasons, have the most often used at top! + if (action == "call-check-visual-extension") + { + // arguments + if (args.Length < 1) + return null; + + // looking only for Submodels + var sm = args[0] as Aas.Submodel; + if (sm == null) + return null; + + // check for a record in options, that matches Submodel + bool found = _options?.ContainsIndexKey(sm?.SemanticId?.GetAsExactlyOneKey()) ?? false; + if (!found) + return null; + + // success prepare record + var cve = new AasxPluginResultVisualExtension("AID", "Asset Interfaces Description"); + + // ok + return cve; + } + + // can basic helper help to reduce lines of code? + var help = ActivateActionBasicHelper(action, ref _options, args, + enableGetCheckVisuExt: true); + if (help != null) + return help; + + // rest follows + + if (action == "fill-anyui-visual-extension") + { + // arguments (package, submodel, panel, display-context, session-id) + if (args == null || args.Length < 5) + return null; + + // create session and call + var session = _sessions.CreateNewSession(args[4]); + session.AnyUiControl = AasxPluginAssetInterfaceDescription.AssetInterfaceAnyUiControl.FillWithAnyUiControls( + _log, args[0], args[1], _options, _eventStack, args[2], _allInterfaceStatus); + + // give object back + var res = new AasxPluginResultBaseObject(); + res.obj = session.AnyUiControl; + return res; + } + + if (action == "update-anyui-visual-extension" + && _sessions != null) + { + // arguments (panel, display-context, session-id) + if (args == null || args.Length < 3) + return null; + + if (_sessions.AccessSession(args[2], out Session session)) + { + // call + session.AnyUiControl.Update(args); + + // give object back + var res = new AasxPluginResultBaseObject(); + res.obj = 42; + return res; + } + } + + if (action == "dispose-anyui-visual-extension" + && _sessions != null) + { + // arguments (session-id) + if (args == null || args.Length < 1) + return null; + + // ReSharper disable UnusedVariable + if (_sessions.AccessSession(args[0], out Session session)) + { + // dispose all ressources + ; + + // remove + _sessions.Remove(args[0]); + } + // ReSharper enable UnusedVariable + } + + // default + return null; + } + + } +} diff --git a/src/AasxPluginAssetInterfaceDesc/Resources/LICENSE.TXT b/src/AasxPluginAssetInterfaceDesc/Resources/LICENSE.TXT new file mode 100644 index 00000000..fc70527e --- /dev/null +++ b/src/AasxPluginAssetInterfaceDesc/Resources/LICENSE.TXT @@ -0,0 +1,651 @@ +Copyright (c) 2018-2023 Festo SE & Co. KG , author: Michael Hoffmeister +Copyright (c) 2019 PHOENIX CONTACT GmbH & Co. KG , author: Andreas Orzelski +This software is licensed under the Eclipse Public License 2.0 (EPL-2.0) (see below) +The browser functionality is licensed under the cefSharp license (see below) +The Newtonsoft.JSON serialization is licensed under the MIT License (MIT) (see below) +The QR code generation is licensed under the MIT license (MIT) (see below) +The Zxing.Net Dot Matrix Code (DMC) generation is licensed under the Apache License 2.0 (Apache-2.0) (see below) +The Grapevine REST server framework is licensed under Apache License 2.0 (Apache-2.0) (see below) +The AutomationML.Engine is licensed under the MIT license (MIT) (see below) +The MQTT server and client is licensed under the MIT license (MIT) (see below) + +This application is a sample application for demonstration of the features of the Administration Shell. +It is not allowed for productive use. The implementation uses the concepts of the document "Details of the Asset +Administration Shell" published on www.plattform-i40.de which is licensed under Creative Commons CC BY-ND 3.0 DE. + +Eclipse Public License 2.0 (EPL-2.0) +==================================== + +(https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt) + + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE + PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION + OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial content + Distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; + where such changes and/or additions to the Program originate from + and are Distributed by that particular Contributor. A Contribution + "originates" from a Contributor if it was added to the Program by + such Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include changes or additions to the Program that + are not Modified Works. + +"Contributor" means any person or entity that Distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which +are necessarily infringed by the use or sale of its Contribution alone +or when combined with the Program. + +"Program" means the Contributions Distributed in accordance with this +Agreement. + +"Recipient" means anyone who receives the Program under this Agreement +or any Secondary License (as applicable), including Contributors. + +"Derivative Works" shall mean any work, whether in Source Code or other +form, that is based on (or derived from) the Program and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. + +"Modified Works" shall mean any work in Source Code or other form that +results from an addition to, deletion from, or modification of the +contents of the Program, including, for purposes of clarity any new file +in Source Code form that contains any contents of the Program. Modified +Works shall not include works that contain only declarations, +interfaces, types, classes, structures, or files of the Program solely +in each case in order to link to, bind by name, or subclass the Program +or Modified Works thereof. + +"Distribute" means the acts of a) distributing or b) making available +in any manner that enables the transfer of a copy. + +"Source Code" means the form of a Program preferred for making +modifications, including but not limited to software source code, +documentation source, and configuration files. + +"Secondary License" means either the GNU General Public License, +Version 2.0, or any later versions of that license, including any +exceptions or additional permissions as identified by the initial +Contributor. + +2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, Distribute and sublicense the Contribution of such + Contributor, if any, and such Derivative Works. + + b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in Source Code or other form. This patent license shall + apply to the combination of the Contribution and the Program if, at + the time the Contribution is added by the Contributor, such addition + of the Contribution causes such combination to be covered by the + Licensed Patents. The patent license shall not apply to any other + combinations which include the Contribution. No hardware per se is + licensed hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the + rights and licenses granted hereunder, each Recipient hereby + assumes sole responsibility to secure any other intellectual + property rights needed, if any. For example, if a third party + patent license is required to allow Recipient to Distribute the + Program, it is Recipient's responsibility to acquire that license + before distributing the Program. + + d) Each Contributor represents that to its knowledge it has + sufficient copyright rights in its Contribution, if any, to grant + the copyright license set forth in this Agreement. + + e) Notwithstanding the terms of any Secondary License, no + Contributor makes additional grants to any Recipient (other than + those set forth in this Agreement) as a result of such Recipient's + receipt of the Program under the terms of a Secondary License + (if permitted under the terms of Section 3). + +3. REQUIREMENTS + +3.1 If a Contributor Distributes the Program in any form, then: + + a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and + + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: + i) effectively disclaims on behalf of all other Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and + implied warranties or conditions of merchantability and fitness + for a particular purpose; + + ii) effectively excludes on behalf of all other Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) does not attempt to limit or alter the recipients' rights + in the Source Code under section 3.2; and + + iv) requires any subsequent distribution of the Program by any + party to be under a license that satisfies the requirements + of this section 3. + +3.2 When the Program is Distributed as Source Code: + + a) it must be made available under this Agreement, or if the + Program (i) is combined with other material in a separate file or + files made available under a Secondary License, and (ii) the initial + Contributor attached to the Source Code the notice described in + Exhibit A of this Agreement, then the Program may be made available + under the terms of such Secondary Licenses, and + + b) a copy of this Agreement must be included with each copy of + the Program. + +3.3 Contributors may not remove or alter any copyright, patent, +trademark, attribution notices, disclaimers of warranty, or limitations +of liability ("notices") contained within the Program from any copy of +the Program which they Distribute, provided that Contributors may add +their own appropriate notices. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities +with respect to end users, business partners and the like. While this +license is intended to facilitate the commercial use of the Program, +the Contributor who includes the Program in a commercial product +offering should do so in a manner which does not create potential +liability for other Contributors. Therefore, if a Contributor includes +the Program in a commercial product offering, such Contributor +("Commercial Contributor") hereby agrees to defend and indemnify every +other Contributor ("Indemnified Contributor") against any losses, +damages and costs (collectively "Losses") arising from claims, lawsuits +and other legal actions brought by a third party against the Indemnified +Contributor to the extent caused by the acts or omissions of such +Commercial Contributor in connection with its distribution of the Program +in a commercial product offering. The obligations in this section do not +apply to any claims or Losses relating to any actual or alleged +intellectual property infringement. In order to qualify, an Indemnified +Contributor must: a) promptly notify the Commercial Contributor in +writing of such claim, and b) allow the Commercial Contributor to control, +and cooperate with the Commercial Contributor in, the defense and any +related settlement negotiations. The Indemnified Contributor may +participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have to +defend claims against the other Contributors related to those performance +claims and warranties, and if a court requires any other Contributor to +pay any damages as a result, the Commercial Contributor must pay +those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" +BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF +TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR +PURPOSE. Each Recipient is solely responsible for determining the +appropriateness of using and distributing the Program and assumes all +risks associated with its exercise of rights under this Agreement, +including but not limited to the risks and costs of program errors, +compliance with applicable laws, damage to or loss of data, programs +or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS +SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE +EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability of +the remainder of the terms of this Agreement, and without further +action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the +Program itself (excluding combinations of the Program with other software +or hardware) infringes such Recipient's patent(s), then such Recipient's +rights granted under Section 2(b) shall terminate as of the date such +litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of +time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use +and distribution of the Program as soon as reasonably practicable. +However, Recipient's obligations under this Agreement and any licenses +granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, +but in order to avoid inconsistency the Agreement is copyrighted and +may only be modified in the following manner. The Agreement Steward +reserves the right to publish new versions (including revisions) of +this Agreement from time to time. No one other than the Agreement +Steward has the right to modify this Agreement. The Eclipse Foundation +is the initial Agreement Steward. The Eclipse Foundation may assign the +responsibility to serve as the Agreement Steward to a suitable separate +entity. Each new version of the Agreement will be given a distinguishing +version number. The Program (including Contributions) may always be +Distributed subject to the version of the Agreement under which it was +received. In addition, after a new version of the Agreement is published, +Contributor may elect to Distribute the Program (including its +Contributions) under the new version. + +Except as expressly stated in Sections 2(a) and 2(b) above, Recipient +receives no rights or licenses to the intellectual property of any +Contributor under this Agreement, whether expressly, by implication, +estoppel or otherwise. All rights in the Program not expressly granted +under this Agreement are reserved. Nothing in this Agreement is intended +to be enforceable by any entity that is not a Contributor or Recipient. +No third-party beneficiary rights are created under this Agreement. + +Exhibit A - Form of Secondary Licenses Notice + +"This Source Code may also be made available under the following +Secondary Licenses when the conditions for such availability set forth +in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), +version(s), and exceptions or additional permissions here}." + + Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. + + If it is not possible or desirable to put the notice in a particular + file, then You may include the notice in a location (such as a LICENSE + file in a relevant directory) where a recipient would be likely to + look for such a notice. + + You may add additional accurate notices of copyright ownership. + +With respect to cefSharp +======================== + +(https://raw.githubusercontent.com/cefsharp/CefSharp/master/LICENSE) + +// Copyright © The CefSharp Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the name CefSharp nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +With respect to Newtonsoft.Json +=============================== + +(https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md) + +The MIT License (MIT) + +Copyright (c) 2007 James Newton-King + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT 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. + +With respect to QRcoder +======================= + +(https://github.com/codebude/QRCoder/blob/master/LICENSE.txt) + +The MIT License (MIT) + +Copyright (c) 2013-2018 Raffael Herrmann + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT 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. + +With respect to ZXing.Net +========================= +With respect to Grapevine +========================= + +(http://www.apache.org/licenses/LICENSE-2.0) + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + +With respect to AutomationML.Engine +=================================== + +(https://raw.githubusercontent.com/AutomationML/AMLEngine2.1/master/license.txt) + +The MIT License (MIT) + +Copyright 2017 AutomationML e.V. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 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. + +With respect to MQTTnet +======================= + +(https://github.com/chkr1011/MQTTnet/blob/master/LICENSE) + +MIT License + +MQTTnet Copyright (c) 2016-2019 Christian Kratky + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT 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. + +With respect to MSAGL (Microsoft Automatic Graph Layout) +======================================================== +(see: https://github.com/microsoft/automatic-graph-layout/blob/master/LICENSE) + +Microsoft Automatic Graph Layout, MSAGL + +Copyright (c) Microsoft Corporation + +All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +""Software""), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 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. + diff --git a/src/AasxPluginAssetInterfaceDesc/Resources/logo-http.png b/src/AasxPluginAssetInterfaceDesc/Resources/logo-http.png new file mode 100644 index 00000000..0424ef88 Binary files /dev/null and b/src/AasxPluginAssetInterfaceDesc/Resources/logo-http.png differ diff --git a/src/AasxPluginAssetInterfaceDesc/Resources/logo-modbus.png b/src/AasxPluginAssetInterfaceDesc/Resources/logo-modbus.png new file mode 100644 index 00000000..007f4acf Binary files /dev/null and b/src/AasxPluginAssetInterfaceDesc/Resources/logo-modbus.png differ diff --git a/src/AasxPluginAssetInterfaceDesc/Resources/logo-mqtt.png b/src/AasxPluginAssetInterfaceDesc/Resources/logo-mqtt.png new file mode 100644 index 00000000..158d239a Binary files /dev/null and b/src/AasxPluginAssetInterfaceDesc/Resources/logo-mqtt.png differ diff --git a/src/AasxPredefinedConcepts/DefinitionsAssetInterfacesDescription.cs b/src/AasxPredefinedConcepts/DefinitionsAssetInterfacesDescription.cs index cf30ee53..a318cc88 100644 --- a/src/AasxPredefinedConcepts/DefinitionsAssetInterfacesDescription.cs +++ b/src/AasxPredefinedConcepts/DefinitionsAssetInterfacesDescription.cs @@ -24,434 +24,500 @@ namespace AasxPredefinedConcepts.AssetInterfacesDescription public class CD_GenericInterface { [AasConcept(Cd = "https://www.w3.org/2019/wot/td#title", Card = AasxPredefinedCardinality.One)] - string Title; + public string Title; [AasConcept(Cd = "https://www.w3.org/2019/wot/td#created", Card = AasxPredefinedCardinality.ZeroToOne)] - DateTime? Created; + public DateTime? Created; [AasConcept(Cd = "https://www.w3.org/2019/wot/td#modified", Card = AasxPredefinedCardinality.ZeroToOne)] - DateTime? Modified; + public DateTime? Modified; [AasConcept(Cd = "https://www.w3.org/2019/wot/td#support", Card = AasxPredefinedCardinality.ZeroToOne)] - string Support; + public string Support; [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/EndpointMetadata", Card = AasxPredefinedCardinality.One)] - CD_EndpointMetadata EndpointMetadata = new CD_EndpointMetadata(); + public CD_EndpointMetadata EndpointMetadata = new CD_EndpointMetadata(); [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/InterfaceMetadata", Card = AasxPredefinedCardinality.One)] - CD_InterfaceMetadata InterfaceMetadata = new CD_InterfaceMetadata(); + public CD_InterfaceMetadata InterfaceMetadata = new CD_InterfaceMetadata(); [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/ExternalDescriptor", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_ExternalDescriptor ExternalDescriptor = null; + public CD_ExternalDescriptor ExternalDescriptor = null; + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/EndpointMetadata")] public class CD_EndpointMetadata { [AasConcept(Cd = "https://www.w3.org/2019/wot/td#base", Card = AasxPredefinedCardinality.One)] - string Base; + public string Base; [AasConcept(Cd = "https://www.w3.org/2019/wot/hypermedia#forContentType", Card = AasxPredefinedCardinality.One)] - string ContentType; + public string ContentType; [AasConcept(Cd = "https://www.w3.org/2019/wot/td#hasSecurityConfiguration", Card = AasxPredefinedCardinality.One)] - CD_Security Security = new CD_Security(); + public CD_Security Security = new CD_Security(); [AasConcept(Cd = "https://www.w3.org/2019/wot/td#definesSecurityScheme", Card = AasxPredefinedCardinality.One)] - CD_SecurityDefinitions SecurityDefinitions = new CD_SecurityDefinitions(); + public CD_SecurityDefinitions SecurityDefinitions = new CD_SecurityDefinitions(); + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/td#hasSecurityConfiguration")] public class CD_Security { + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/td#definesSecurityScheme")] public class CD_SecurityDefinitions { [AasConcept(Cd = "https://www.w3.org/2019/wot/security#NoSecurityScheme", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_Nosec_sc Nosec_sc = null; + public CD_Nosec_sc Nosec_sc = null; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#AutoSecurityScheme", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_Auto_sc Auto_sc = null; + public CD_Auto_sc Auto_sc = null; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#BasicSecurityScheme", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_Basic_sc Basic_sc = null; + public CD_Basic_sc Basic_sc = null; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#ComboSecurityScheme", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_Combo_sc Combo_sc = null; + public CD_Combo_sc Combo_sc = null; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#APIKeySecurityScheme", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_Apikey_sc Apikey_sc = null; + public CD_Apikey_sc Apikey_sc = null; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#PSKSecurityScheme", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_Psk_sc Psk_sc = null; + public CD_Psk_sc Psk_sc = null; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#DigestSecurityScheme", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_Digest_sc Digest_sc = null; + public CD_Digest_sc Digest_sc = null; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#BearerSecurityScheme", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_Bearer_sc Bearer_sc = null; + public CD_Bearer_sc Bearer_sc = null; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#OAuth2SecurityScheme", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_Oauth2_sc Oauth2_sc = null; + public CD_Oauth2_sc Oauth2_sc = null; + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/security#NoSecurityScheme")] public class CD_Nosec_sc { [AasConcept(Cd = "https://www.w3.org/2019/wot/td#definesSecurityScheme", Card = AasxPredefinedCardinality.One)] - string Scheme; + public string Scheme; + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/security#AutoSecurityScheme")] public class CD_Auto_sc { [AasConcept(Cd = "https://www.w3.org/2019/wot/td#definesSecurityScheme", Card = AasxPredefinedCardinality.One)] - string Scheme; + public string Scheme; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#proxy", Card = AasxPredefinedCardinality.ZeroToOne)] - string Proxy; + public string Proxy; + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/security#BasicSecurityScheme")] public class CD_Basic_sc { [AasConcept(Cd = "https://www.w3.org/2019/wot/td#definesSecurityScheme", Card = AasxPredefinedCardinality.One)] - string Scheme; + public string Scheme; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#name", Card = AasxPredefinedCardinality.ZeroToOne)] - string Name; + public string Name; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#in", Card = AasxPredefinedCardinality.ZeroToOne)] - string In; + public string In; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#proxy", Card = AasxPredefinedCardinality.ZeroToOne)] - string Proxy; + public string Proxy; + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/security#ComboSecurityScheme")] public class CD_Combo_sc { [AasConcept(Cd = "https://www.w3.org/2019/wot/td#definesSecurityScheme", Card = AasxPredefinedCardinality.One)] - string Scheme; + public string Scheme; [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#oneOf", Card = AasxPredefinedCardinality.One)] - CD_OneOf OneOf = new CD_OneOf(); + public CD_OneOf OneOf = new CD_OneOf(); [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#allOf", Card = AasxPredefinedCardinality.One)] - CD_AllOf AllOf = new CD_AllOf(); + public CD_AllOf AllOf = new CD_AllOf(); [AasConcept(Cd = "https://www.w3.org/2019/wot/security#proxy", Card = AasxPredefinedCardinality.ZeroToOne)] - string Proxy; + public string Proxy; + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#oneOf")] public class CD_OneOf { + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#allOf")] public class CD_AllOf { + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/security#APIKeySecurityScheme")] public class CD_Apikey_sc { [AasConcept(Cd = "https://www.w3.org/2019/wot/td#definesSecurityScheme", Card = AasxPredefinedCardinality.One)] - string Scheme; + public string Scheme; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#name", Card = AasxPredefinedCardinality.ZeroToOne)] - string Name; + public string Name; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#in", Card = AasxPredefinedCardinality.ZeroToOne)] - string In; + public string In; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#proxy", Card = AasxPredefinedCardinality.ZeroToOne)] - string Proxy; + public string Proxy; + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/security#PSKSecurityScheme")] public class CD_Psk_sc { [AasConcept(Cd = "https://www.w3.org/2019/wot/td#definesSecurityScheme", Card = AasxPredefinedCardinality.One)] - string Scheme; + public string Scheme; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#identity", Card = AasxPredefinedCardinality.ZeroToOne)] - string Identity; + public string Identity; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#proxy", Card = AasxPredefinedCardinality.ZeroToOne)] - string Proxy; + public string Proxy; + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/security#DigestSecurityScheme")] public class CD_Digest_sc { [AasConcept(Cd = "https://www.w3.org/2019/wot/td#definesSecurityScheme", Card = AasxPredefinedCardinality.One)] - string Scheme; + public string Scheme; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#name", Card = AasxPredefinedCardinality.ZeroToOne)] - string Name; + public string Name; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#in", Card = AasxPredefinedCardinality.ZeroToOne)] - string In; + public string In; - string Qop; + public string Qop; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#proxy", Card = AasxPredefinedCardinality.ZeroToOne)] - string Proxy; + public string Proxy; + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/security#BearerSecurityScheme")] public class CD_Bearer_sc { [AasConcept(Cd = "https://www.w3.org/2019/wot/td#definesSecurityScheme", Card = AasxPredefinedCardinality.One)] - string Scheme; + public string Scheme; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#name", Card = AasxPredefinedCardinality.ZeroToOne)] - string Name; + public string Name; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#in", Card = AasxPredefinedCardinality.ZeroToOne)] - string In; + public string In; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#authorization", Card = AasxPredefinedCardinality.ZeroToOne)] - string Authorization; + public string Authorization; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#alg", Card = AasxPredefinedCardinality.ZeroToOne)] - string Alg; + public string Alg; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#format", Card = AasxPredefinedCardinality.ZeroToOne)] - string Format; + public string Format; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#proxy", Card = AasxPredefinedCardinality.ZeroToOne)] - string Proxy; + public string Proxy; + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/security#OAuth2SecurityScheme")] public class CD_Oauth2_sc { [AasConcept(Cd = "https://www.w3.org/2019/wot/td#definesSecurityScheme", Card = AasxPredefinedCardinality.One)] - string Scheme; + public string Scheme; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#token", Card = AasxPredefinedCardinality.ZeroToOne)] - string Token; + public string Token; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#refresh", Card = AasxPredefinedCardinality.ZeroToOne)] - string Refresh; + public string Refresh; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#authorization", Card = AasxPredefinedCardinality.ZeroToOne)] - string Authorization; + public string Authorization; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#scopes", Card = AasxPredefinedCardinality.ZeroToOne)] - string Scopes; + public string Scopes; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#flow", Card = AasxPredefinedCardinality.ZeroToOne)] - string Flow; + public string Flow; [AasConcept(Cd = "https://www.w3.org/2019/wot/security#proxy", Card = AasxPredefinedCardinality.ZeroToOne)] - string Proxy; + public string Proxy; + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/InterfaceMetadata")] public class CD_InterfaceMetadata { [AasConcept(Cd = "https://www.w3.org/2019/wot/td#PropertyAffordance", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_PropertiesAffordance Properties = null; + public CD_PropertiesAffordance Properties = null; + // public CD_Properties Properties = null; [AasConcept(Cd = "https://www.w3.org/2019/wot/td#ActionAffordance", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_Actions Actions = null; + public CD_Actions Actions = null; [AasConcept(Cd = "https://www.w3.org/2019/wot/td#EventAffordance", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_Events Events = null; + public CD_Events Events = null; + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/td#PropertyAffordance")] public class CD_PropertiesAffordance { [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfaceDescription/1/0/PropertyDefinition", Card = AasxPredefinedCardinality.ZeroToMany)] - List PropertyName = new List(); + public List Property = new List(); + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfaceDescription/1/0/PropertyDefinition")] public class CD_PropertyName { [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/key", Card = AasxPredefinedCardinality.ZeroToOne)] - string Key; + public string Key; [AasConcept(Cd = "https://www.w3.org/1999/02/22-rdf-syntax-ns#type", Card = AasxPredefinedCardinality.ZeroToOne)] - string Type; + public string Type; [AasConcept(Cd = "https://www.w3.org/2019/wot/td#title", Card = AasxPredefinedCardinality.ZeroToOne)] - string Title; + public string Title; [AasConcept(Cd = "https://www.w3.org/2019/wot/td#isObservable", Card = AasxPredefinedCardinality.ZeroToOne)] - bool? Observable; + public bool? Observable; [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#const", Card = AasxPredefinedCardinality.ZeroToOne)] - int? Const; + public int? Const; [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#default", Card = AasxPredefinedCardinality.ZeroToOne)] - string Default; + public string Default; [AasConcept(Cd = "https://schema.org/unitCode", Card = AasxPredefinedCardinality.ZeroToOne)] - string Unit; + public string Unit; + + [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/minMaxRange", Card = AasxPredefinedCardinality.ZeroToOne)] + public AasClassMapperRange Min_max = null; + + [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/lengthRange", Card = AasxPredefinedCardinality.ZeroToOne)] + public AasClassMapperRange LengthRange = null; [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#items", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_Items Items = null; + public CD_Items Items = null; + + [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/itemsRange", Card = AasxPredefinedCardinality.ZeroToOne)] + public AasClassMapperRange ItemsRange = null; [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#properties", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_Properties Properties = null; + public CD_Properties Properties = null; [AasConcept(Cd = "https://www.w3.org/2019/wot/td#hasForm", Card = AasxPredefinedCardinality.One)] - CD_Forms Forms = new CD_Forms(); + public CD_Forms Forms = new CD_Forms(); + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#items")] public class CD_Items { [AasConcept(Cd = "https://www.w3.org/1999/02/22-rdf-syntax-ns#type", Card = AasxPredefinedCardinality.ZeroToOne)] - string Type; + public string Type; [AasConcept(Cd = "https://schema.org/unitCode", Card = AasxPredefinedCardinality.ZeroToOne)] - string Unit; + public string Unit; [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#default", Card = AasxPredefinedCardinality.ZeroToOne)] - string Default; + public string Default; [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#const", Card = AasxPredefinedCardinality.ZeroToOne)] - int? Const; + public int? Const; [AasConcept(Cd = "https://www.w3.org/2019/wot/td#isObservable", Card = AasxPredefinedCardinality.ZeroToOne)] - bool? Observable; + public bool? Observable; [AasConcept(Cd = "https://www.w3.org/2019/wot/td#title", Card = AasxPredefinedCardinality.ZeroToOne)] - string Title; + public string Title; + + [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/minMaxRange", Card = AasxPredefinedCardinality.ZeroToOne)] + public AasClassMapperRange Min_max = null; + + [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/lengthRange", Card = AasxPredefinedCardinality.ZeroToOne)] + public AasClassMapperRange LengthRange = null; + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#properties")] public class CD_Properties { [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#propertyName", Card = AasxPredefinedCardinality.ZeroToMany)] - List _propertyName_ = new List(); + public List Property = new List(); - [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#propertyName", Card = AasxPredefinedCardinality.ZeroToMany)] - List PropertyName = new List(); - } - - [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#propertyName")] - public class CD__propertyName_ - { - [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/key", Card = AasxPredefinedCardinality.ZeroToOne)] - string Key; - - [AasConcept(Cd = "https://www.w3.org/1999/02/22-rdf-syntax-ns#type", Card = AasxPredefinedCardinality.ZeroToOne)] - string Type; - - [AasConcept(Cd = "https://www.w3.org/2019/wot/td#title", Card = AasxPredefinedCardinality.ZeroToOne)] - string Title; - - [AasConcept(Cd = "https://www.w3.org/2019/wot/td#isObservable", Card = AasxPredefinedCardinality.ZeroToOne)] - bool? Observable; - - [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#const", Card = AasxPredefinedCardinality.ZeroToOne)] - int? Const; - - [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#default", Card = AasxPredefinedCardinality.ZeroToOne)] - string Default; - - [AasConcept(Cd = "https://schema.org/unitCode", Card = AasxPredefinedCardinality.ZeroToOne)] - string Unit; - - [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#items", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_Items Items = null; + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/td#hasForm")] public class CD_Forms { [AasConcept(Cd = "https://www.w3.org/2019/wot/hypermedia#hasTarget", Card = AasxPredefinedCardinality.One)] - string Href; + public string Href; [AasConcept(Cd = "https://www.w3.org/2019/wot/hypermedia#forContentType", Card = AasxPredefinedCardinality.ZeroToOne)] - string ContentType; + public string ContentType; [AasConcept(Cd = "https://www.w3.org/2019/wot/td#hasSecurityConfiguration", Card = AasxPredefinedCardinality.One)] - CD_Security Security = new CD_Security(); + public CD_Security Security = new CD_Security(); [AasConcept(Cd = "https://www.w3.org/2011/http#methodName", Card = AasxPredefinedCardinality.ZeroToOne)] - string Htv_methodName; + public string Htv_methodName; [AasConcept(Cd = "https://www.w3.org/2011/http#headers", Card = AasxPredefinedCardinality.ZeroToOne)] - CD_Htv_headers Htv_headers = null; + public CD_Htv_headers Htv_headers = null; [AasConcept(Cd = "https://www.w3.org/2019/wot/modbus#Function", Card = AasxPredefinedCardinality.ZeroToOne)] - string Modbus_function; + public string Modbus_function; [AasConcept(Cd = "https://www.w3.org/2019/wot/modbus#Entity", Card = AasxPredefinedCardinality.ZeroToOne)] - string Modbus_entity; + public string Modbus_entity; [AasConcept(Cd = "https://www.w3.org/2019/wot/modbus#hasZeroBasedAddressingFlag", Card = AasxPredefinedCardinality.ZeroToOne)] - string Modbus_zeroBasedAddressing; + public string Modbus_zeroBasedAddressing; [AasConcept(Cd = "https://www.w3.org/2019/wot/modbus#pollingTime", Card = AasxPredefinedCardinality.ZeroToOne)] - string Modbus_pollingTime; + public string Modbus_pollingTime; [AasConcept(Cd = "https://www.w3.org/2019/wot/mqtt#hasQoSFlag", Card = AasxPredefinedCardinality.ZeroToOne)] - string Modbus_timeout; + public string Modbus_timeout; [AasConcept(Cd = "https://www.w3.org/2019/wot/modbus#type", Card = AasxPredefinedCardinality.ZeroToOne)] - string Modbus_type; + public string Modbus_type; [AasConcept(Cd = "https://www.w3.org/2019/wot/mqtt#hasRetainFlag", Card = AasxPredefinedCardinality.ZeroToOne)] - string Mqv_retain; + public string Mqv_retain; [AasConcept(Cd = "https://www.w3.org/2019/wot/mqtt#ControlPacket", Card = AasxPredefinedCardinality.ZeroToOne)] - string Mqv_controlPacket; + public string Mqv_controlPacket; [AasConcept(Cd = "https://www.w3.org/2019/wot/mqtt#hasQoSFlag", Card = AasxPredefinedCardinality.ZeroToOne)] - string Mqv_qos; + public string Mqv_qos; + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2011/http#headers")] public class CD_Htv_headers { [AasConcept(Cd = "https://www.w3.org/2011/http#headers", Card = AasxPredefinedCardinality.OneToMany)] - List Htv_headers = new List(); + public List Htv_headers = new List(); [AasConcept(Cd = "https://www.w3.org/2011/http#fieldName", Card = AasxPredefinedCardinality.One)] - string Htv_fieldName; + public string Htv_fieldName; [AasConcept(Cd = "https://www.w3.org/2011/http#fieldValue", Card = AasxPredefinedCardinality.One)] - string Htv_fieldValue; + public string Htv_fieldValue; + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/td#ActionAffordance")] public class CD_Actions { + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://www.w3.org/2019/wot/td#EventAffordance")] public class CD_Events { + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/ExternalDescriptor")] public class CD_ExternalDescriptor { + + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Submodel")] public class CD_AssetInterfacesDescription { - [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Interface", Card = AasxPredefinedCardinality.ZeroToMany)] - List InterfaceHTTP = new List(); + [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Interface", Card = AasxPredefinedCardinality.ZeroToMany, + SupplSemId = "http://www.w3.org/2011/http")] + public List InterfaceHTTP = new List(); + + [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Interface", Card = AasxPredefinedCardinality.ZeroToMany, + SupplSemId = "http://www.w3.org/2011/modbus")] + public List InterfaceMODBUS = new List(); - [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Interface", Card = AasxPredefinedCardinality.ZeroToMany)] - List InterfaceMODBUS = new List(); + [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Interface", Card = AasxPredefinedCardinality.ZeroToMany, + SupplSemId = "http://www.w3.org/2011/mqtt")] + public List InterfaceMQTT = new List(); - [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Interface", Card = AasxPredefinedCardinality.ZeroToMany)] - List InterfaceMQTT = new List(); + // auto-generated informations + public AasClassMapperInfo __Info__ = null; } } diff --git a/src/AasxPredefinedConcepts/PredefinedConceptsClassMapper.cs b/src/AasxPredefinedConcepts/PredefinedConceptsClassMapper.cs index a737fc86..a8b8daef 100644 --- a/src/AasxPredefinedConcepts/PredefinedConceptsClassMapper.cs +++ b/src/AasxPredefinedConcepts/PredefinedConceptsClassMapper.cs @@ -7,15 +7,18 @@ This source code is licensed under the Apache License 2.0 (see LICENSE.txt). This source code may use other Open Source software components (see LICENSE.txt). */ +using AasCore.Aas3_0; using AasxIntegrationBase; using AasxIntegrationBase.AasForms; using AdminShellNS; using Extensions; +using Namotion.Reflection; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Runtime.Intrinsics.X86; using Aas = AasCore.Aas3_0; namespace AasxPredefinedConcepts @@ -29,6 +32,8 @@ public enum AasxPredefinedCardinality { ZeroToOne = 0, One, ZeroToMany, OneToMan public class AasConceptAttribute : Attribute { public string Cd { get; set; } + public string SupplSemId { get; set; } + public AasxPredefinedCardinality Card { get; set; } public AasConceptAttribute() @@ -37,7 +42,25 @@ public AasConceptAttribute() } /// - /// This class provides methods to derive a set of C# class definitions from a SMZT definition and + /// This class is used in auto-generated files by AasxPredefinedConcepts.PredefinedConceptsClassMapper + /// + public class AasClassMapperRange + { + public T Min; + public T Max; + } + + /// + /// If this class is present in an mapped class, then (source) information will be added to the + /// data objects. + /// + public class AasClassMapperInfo + { + public Aas.IReferable Referable; + } + + /// + /// This class provides methods to derive a set of C# class definitions from a SMT definition and /// to create runtime instances from it based on a concrete SM. /// public class PredefinedConceptsClassMapper @@ -46,6 +69,61 @@ public class PredefinedConceptsClassMapper // Export C# classes // + private static string CSharpTypeFrom(Aas.DataTypeDefXsd valueType) + { + switch (valueType) + { + case Aas.DataTypeDefXsd.Boolean: + return "bool"; + + case Aas.DataTypeDefXsd.Byte: + return "byte"; + + case Aas.DataTypeDefXsd.Date: + case Aas.DataTypeDefXsd.DateTime: + case Aas.DataTypeDefXsd.Time: + return "DateTime"; + + case Aas.DataTypeDefXsd.Float: + return "float"; + + case Aas.DataTypeDefXsd.Double: + return "double"; + + case Aas.DataTypeDefXsd.Int: + case Aas.DataTypeDefXsd.Integer: + return "int"; + + case Aas.DataTypeDefXsd.Long: + return "long"; + + case Aas.DataTypeDefXsd.NegativeInteger: + case Aas.DataTypeDefXsd.NonPositiveInteger: + return "int"; + + case Aas.DataTypeDefXsd.NonNegativeInteger: + case Aas.DataTypeDefXsd.PositiveInteger: + return "unsigned int"; + + case Aas.DataTypeDefXsd.Short: + return "short"; + + case Aas.DataTypeDefXsd.UnsignedByte: + return "unsigned byte"; + + case Aas.DataTypeDefXsd.UnsignedInt: + return "unsigned int"; + + case Aas.DataTypeDefXsd.UnsignedLong: + return "usingned long"; + + case Aas.DataTypeDefXsd.UnsignedShort: + return "unsigned short"; + } + + return "string"; + } + private static void ExportCSharpMapperSingleItems( string indent, Aas.Environment env, Aas.IReferable rf, System.IO.StreamWriter snippets, bool noEmptyLineFirst = false) @@ -109,22 +187,22 @@ private static void ExportCSharpMapperSingleItems( var nullOp = (dt == "string") ? "" : "?"; if (card == FormMultiplicity.ZeroToOne) - snippets.WriteLine($"{indent}{dt}{nullOp} {instance};"); + snippets.WriteLine($"{indent}public {dt}{nullOp} {instance};"); else if (card == FormMultiplicity.One) - snippets.WriteLine($"{indent}{dt} {instance};"); + snippets.WriteLine($"{indent}public {dt} {instance};"); else - snippets.WriteLine($"{indent}List<{dt}> {instance} = new List<{dt}>();"); + snippets.WriteLine($"{indent}public List<{dt}> {instance} = new List<{dt}>();"); } else { if (card == FormMultiplicity.ZeroToOne) - snippets.WriteLine($"{indent}{dt} {instance} = null;"); + snippets.WriteLine($"{indent}public {dt} {instance} = null;"); else if (card == FormMultiplicity.One) - snippets.WriteLine($"{indent}{dt} {instance} = new {dt}();"); + snippets.WriteLine($"{indent}public {dt} {instance} = new {dt}();"); else - snippets.WriteLine($"{indent}List<{dt}> {instance} = new List<{dt}>();"); + snippets.WriteLine($"{indent}public List<{dt}> {instance} = new List<{dt}>();"); } }; @@ -134,74 +212,33 @@ private static void ExportCSharpMapperSingleItems( if (rf is Aas.Property prop) { - var dt = "string"; - switch (prop.ValueType) - { - case Aas.DataTypeDefXsd.Boolean: - dt = "bool"; - break; - - case Aas.DataTypeDefXsd.Byte: - dt = "byte"; - break; - - case Aas.DataTypeDefXsd.Date: - case Aas.DataTypeDefXsd.DateTime: - case Aas.DataTypeDefXsd.Time: - dt = "DateTime"; - break; - - case Aas.DataTypeDefXsd.Float: - dt = "float"; - break; - - case Aas.DataTypeDefXsd.Double: - dt = "double"; - break; - - case Aas.DataTypeDefXsd.Int: - case Aas.DataTypeDefXsd.Integer: - dt = "int"; - break; - - case Aas.DataTypeDefXsd.Long: - dt = "long"; - break; - - case Aas.DataTypeDefXsd.NegativeInteger: - case Aas.DataTypeDefXsd.NonPositiveInteger: - dt = "int"; - break; - - case Aas.DataTypeDefXsd.NonNegativeInteger: - case Aas.DataTypeDefXsd.PositiveInteger: - dt = "unsigned int"; - break; - - case Aas.DataTypeDefXsd.Short: - dt = "short"; - break; - - case Aas.DataTypeDefXsd.UnsignedByte: - dt = "unsigned byte"; - break; - - case Aas.DataTypeDefXsd.UnsignedInt: - dt = "unsigned int"; - break; - - case Aas.DataTypeDefXsd.UnsignedLong: - dt = "usingned long"; - break; - - case Aas.DataTypeDefXsd.UnsignedShort: - dt = "unsigned short"; - break; - } - + var dt = CSharpTypeFrom(prop.ValueType); declareLambda(dt, true, idsff); } + // + // Range + // + + if (rf is Aas.Range rng) + { + var dt = CSharpTypeFrom(rng.ValueType); + declareLambda($"AasClassMapperRange<{dt}>", false, idsff); + } + + // + // MultiLanguageProperty + // + + if (rf is MultiLanguageProperty mlp) + { + declareLambda("List", false, idsff); + } + + // + // SMC, SML .. + // + if (( rf is Aas.Submodel || rf is Aas.SubmodelElementCollection || rf is Aas.SubmodelElementList) @@ -283,16 +320,12 @@ public void EnrichMembersFrom(ExportCSharpClassDef cld) } private static void ExportCSharpMapperOnlyClasses( - string indent, Aas.Environment env, Aas.ISubmodel sm, System.IO.StreamWriter snippets) + string indent, Aas.Environment env, Aas.ISubmodel sm, System.IO.StreamWriter snippets, + bool addInfoObj = false) { - // which is a structual element? - Func isStructRf = (rf) => - (rf is Aas.SubmodelElementCollection - || rf is Aas.SubmodelElementList); - // list of class definitions (not merged, yet) var elems = new List(); - foreach (var sme in sm.SubmodelElements?.FindDeep((sme) => isStructRf(sme))) + foreach (var sme in sm.SubmodelElements?.FindDeep((sme) => sme.IsStructured())) elems.Add(new ExportCSharpClassDef(env, sme)); // list of merged class defs @@ -346,8 +379,14 @@ private static void ExportCSharpMapperOnlyClasses( } } + if (addInfoObj) + { + snippets.WriteLine($""); + snippets.WriteLine($"{indent} // auto-generated informations"); + snippets.WriteLine($"{indent} public AasClassMapperInfo __Info__ = null;"); + } - snippets.WriteLine($"{indent}}}"); + snippets.WriteLine($"{indent}}}"); } } @@ -382,7 +421,8 @@ This source code was auto-generated by the AASX Package Explorer. snippets.WriteLine($"namespace AasxPredefinedConcepts.{AdminShellUtil.FilterFriendlyName(sm?.IdShort)} {{"); - ExportCSharpMapperOnlyClasses(" ", env, sm, snippets); + ExportCSharpMapperOnlyClasses(" ", env, sm, snippets, + addInfoObj: true); // ExportCSharpMapperSingleItems(" ", env, sm, snippets); @@ -395,18 +435,167 @@ This source code was auto-generated by the AASX Package Explorer. private class ElemAttrInfo { + public object Obj; public FieldInfo Fi; public AasConceptAttribute Attr; } - private void ParseAasElemFillData(ElemAttrInfo eai, Aas.ISubmodelElement sme) + private static object CreateRangeObjectSpecific(Type genericType0, Aas.ISubmodelElement sme) { // access - if (eai?.Fi == null || sme == null) + if (genericType0 == null || sme == null || !(sme is Aas.IRange rng)) + return null; + + // create generic instance + // see: https://stackoverflow.com/questions/4194033/adding-items-to-listt-using-reflection + var objTyp = genericType0; + var IListRef = typeof(AasClassMapperRange<>); + Type[] IListParam = { objTyp }; + object rngObj = Activator.CreateInstance(IListRef.MakeGenericType(IListParam)); + + // set + var rngType = rngObj.GetType(); + AdminShellUtil.SetFieldLazyValue(rngType.GetField("Min"), rngObj, "" + rng.Min); + AdminShellUtil.SetFieldLazyValue(rngType.GetField("Max"), rngObj, "" + rng.Max); + + // ok + return rngObj; + } + + // TODO (MIHO, 2024-01-04): Move to AdminShellUtil .. + private static void SetFieldLazyFromSme(FieldInfo f, object obj, Aas.ISubmodelElement sme) + { + // access + if (f == null || obj == null || sme == null) return; + // identify type + var t = AdminShellUtil.GetTypeOrUnderlyingType(f.FieldType); + + if (t.IsGenericType + && t.GetGenericTypeDefinition() == typeof(AasClassMapperRange<>) + && t.GenericTypeArguments.Length >= 1 + && sme is Aas.IRange rng) + { + // create generic instance + var rngObj = CreateRangeObjectSpecific(t.GenericTypeArguments[0], sme); + + // set it + f.SetValue(obj, rngObj); + } + else + { + AdminShellUtil.SetFieldLazyValue(f, obj, sme.ValueAsText()); + } + } + + public static void AddToListLazySme(FieldInfo f, object obj, Aas.ISubmodelElement sme) + { + // access + if (f == null || obj == null || sme == null) + return; + + // identify type + var t = AdminShellUtil.GetTypeOrUnderlyingType(f.FieldType); + + if (t.IsGenericType + && t.GetGenericTypeDefinition() == typeof(AasClassMapperRange<>) + && sme is Aas.IRange rng) + { + // create generic instance + var rngObj = CreateRangeObjectSpecific(t.GenericTypeArguments[0], sme); + + // add it + var listObj = f.GetValue(obj); + listObj.GetType().GetMethod("Add").Invoke(listObj, new[] { rngObj }); + } + else + { + AdminShellUtil.AddToListLazyValue(obj, sme.ValueAsText()); + } + } + + private static void ParseAasElemFillData(ElemAttrInfo eai, Aas.ISubmodelElement sme) + { + // access + if (eai?.Fi == null || eai.Attr == null || sme == null) + return; + + if (sme?.IdShort == "Voltage_L1_N") + { ; } + // straight? + if (!sme.IsStructured()) + { + if (eai.Attr.Card == AasxPredefinedCardinality.One) + { + // scalar value + SetFieldLazyFromSme(eai.Fi, eai.Obj, sme); + } + else + if (eai.Attr.Card == AasxPredefinedCardinality.ZeroToOne) + { + // sure to have a nullable type + SetFieldLazyFromSme(eai.Fi, eai.Obj, sme); + } + else + if ((eai.Attr.Card == AasxPredefinedCardinality.ZeroToMany + || eai.Attr.Card == AasxPredefinedCardinality.OneToMany) + && eai.Obj.GetType().IsGenericType + && eai.Obj.GetType().GetGenericTypeDefinition() == typeof(List<>)) + { + // sure to have a (instantiated) List + AddToListLazySme(eai.Fi, eai.Obj, sme); + } + } + else + { + if (eai.Attr.Card == AasxPredefinedCardinality.One) + { + // assume a already existing object + var childObj = eai.Fi.GetValue(eai.Obj); + + // recurse to fill in + ParseAasElemsToObject(sme, childObj); + } + else + if (eai.Attr.Card == AasxPredefinedCardinality.ZeroToOne) + { + // get value first, shall not be present + var childObj = eai.Fi.GetValue(eai.Obj); + if (childObj != null) + throw new Exception( + $"ParseAasElemFillData: [0..1] instance for {eai.Fi.FieldType.Name}> already present!"); + + // ok, make new, add + childObj = Activator.CreateInstance(eai.Fi.FieldType); + eai.Fi.SetValue(eai.Obj, childObj); + + // recurse to fill in + ParseAasElemsToObject(sme, childObj); + } + else + if ((eai.Attr.Card == AasxPredefinedCardinality.ZeroToMany + || eai.Attr.Card == AasxPredefinedCardinality.OneToMany) + && eai.Fi.FieldType.IsGenericType + && eai.Fi.FieldType.GetGenericTypeDefinition() == typeof(List<>) + && eai.Fi.FieldType.GenericTypeArguments.Length > 0 + && eai.Fi.FieldType.GenericTypeArguments[0] != null) + { + // create a new object instance + var childObj = Activator.CreateInstance(eai.Fi.FieldType.GenericTypeArguments[0]); + + // add to list + var listObj = eai.Fi.GetValue(eai.Obj); + listObj.GetType().GetMethod("Add").Invoke(listObj, new [] { childObj }); + // recurse to fill in + ParseAasElemsToObject(sme, childObj); + } + + // recurse + + } } /// @@ -425,13 +614,22 @@ public static void ParseAasElemsToObject(Aas.IReferable root, object obj) // find fields for this object var t = obj.GetType(); - var l = t.GetFields(BindingFlags.Instance | BindingFlags.Public); + var l = t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (var f in l) { + // special case + if (f.FieldType == typeof(AasClassMapperInfo)) + { + var info = new AasClassMapperInfo() { Referable = root }; + f.SetValue(obj, info); + continue; + } + + // store for a bit later processing var a = f.GetCustomAttribute(); if (a != null) { - eais.Add(new ElemAttrInfo() { Fi = f, Attr = a }); + eais.Add(new ElemAttrInfo() { Obj = obj, Fi = f, Attr = a }); } } @@ -441,8 +639,20 @@ public static void ParseAasElemsToObject(Aas.IReferable root, object obj) // try find sme in Rf foreach (var x in root.DescendOnce()) if (x is Aas.ISubmodelElement sme) - if (sme?.SemanticId?.MatchesExactlyOneKey(new Aas.Key(Aas.KeyTypes.GlobalReference, eai?.Attr?.Cd)) == true) - ; + { + var hit = sme?.SemanticId?.MatchesExactlyOneKey( + new Aas.Key(Aas.KeyTypes.GlobalReference, eai?.Attr?.Cd), + matchMode: MatchMode.Relaxed) == true; + + if (hit && eai?.Attr?.SupplSemId?.HasContent() == true) + hit = hit && sme?.SupplementalSemanticIds?.MatchesAnyWithExactlyOneKey( + new Aas.Key(Aas.KeyTypes.GlobalReference, eai?.Attr?.SupplSemId), + matchMode: MatchMode.Relaxed) == true; + + if (hit) + ParseAasElemFillData(eai, sme); + } + } } }