diff --git a/src/AasxOpcUa2Client/AasOpcUaClient2.cs b/src/AasxOpcUa2Client/AasOpcUaClient2.cs
index 00d85657..49bfa821 100644
--- a/src/AasxOpcUa2Client/AasOpcUaClient2.cs
+++ b/src/AasxOpcUa2Client/AasOpcUaClient2.cs
@@ -19,6 +19,7 @@ This source code may use other Open Source software components (see LICENSE.txt)
using System.Threading.Tasks;
using AasxIntegrationBase;
using AdminShellNS;
+using AnyUi;
using Workstation.ServiceModel.Ua;
using Workstation.ServiceModel.Ua.Channels;
@@ -58,12 +59,22 @@ public class AasOpcUaClient2
protected string _password;
protected uint _timeOutMs = 2000;
+ //Optional parameters for secured OPC UA interface in AID
+ protected MessageSecurityMode _securityMode;
+ protected string _securityPolicy;
+ protected static bool _autoConnect = false;
+
protected ClientSessionChannel _channel = null;
- public AasOpcUaClient2(string endpointURL, bool autoAccept,
+ public AasOpcUaClient2(
+ string endpointURL,
+ bool autoAccept,
string userName, string password,
uint timeOutMs = 2000,
- LogInstance log = null)
+ LogInstance log = null,
+ MessageSecurityMode? securityMode = MessageSecurityMode.None,
+ string? securityPolicy = SecurityPolicyUris.None,
+ bool? autoConnect = false)
{
_endpointURL = endpointURL;
_autoAccept = autoAccept;
@@ -71,6 +82,9 @@ public AasOpcUaClient2(string endpointURL, bool autoAccept,
_password = password;
_timeOutMs = timeOutMs;
_log = log;
+ _securityMode = (MessageSecurityMode)securityMode;
+ _securityPolicy = securityPolicy;
+ _autoConnect = (bool)autoConnect;
}
public async Task DirectConnect()
@@ -98,19 +112,97 @@ public async Task StartClientAsync()
ApplicationType = ApplicationType.Client
};
- // create a 'ClientSessionChannel', a client-side channel that opens a 'session' with the server.
- _channel = new ClientSessionChannel(
- clientDescription,
- null, // no x509 certificates
- new AnonymousIdentity(), // no user identity
- "" + _endpointURL,
- SecurityPolicyUris.None); // no encryption
+ // Create Endpoint
+ var Endpoint = new EndpointDescription
+ {
+ EndpointUrl = _endpointURL,
+ SecurityPolicyUri = _securityPolicy,
+ SecurityMode = _securityMode,
+ };
+
+ ///
+ ///Set up auto connection by getting all endpoints from server and using one of these endpoints
+ ///Used by AID Submodel
+ ///
+ if (_autoConnect)
+ {
+
+ var endpointRequest = new GetEndpointsRequest()
+ {
+ EndpointUrl = _endpointURL,
+ };
+ GetEndpointsResponse endpoints = await DiscoveryService.GetEndpointsAsync(endpointRequest);
+ if (endpoints.Endpoints != null)
+ {
+ foreach (var endpoint in endpoints.Endpoints)
+ {
+ if (endpoint.SecurityMode.ToString().ToLower() == "none" &&
+ endpoint.SecurityPolicyUri.Split("#").Last().ToLower() == "none")
+ {
+ _log?.Info("Using auto connect option...");
+ _log?.Info($"Creating channel from one of {endpoints.Endpoints.Length} Endpoints");
+ _log?.Info($"Using Endpoint : Security Mode = {endpoint.SecurityMode} and Security Policy: {endpoint.SecurityPolicyUri.Split("#").Last()}");
+ Endpoint.EndpointUrl = endpoint.EndpointUrl;
+ Endpoint.SecurityMode = endpoint.SecurityMode;
+ Endpoint.SecurityPolicyUri = endpoint.SecurityPolicyUri;
+ _channel = new ClientSessionChannel(
+ clientDescription,
+ null, // no x509 certificates
+ new AnonymousIdentity(), // no user identity
+ Endpoint);
+
+ }
+ break;
+ }
+ }
+
+ }
+
+ ///
+ ///Set up Secure Session. Used by AID Submodel
+ ///
+
+ else if (_securityMode != MessageSecurityMode.None && _securityPolicy != SecurityPolicyUris.None)
+ {
+ ///
+ ///create directory for client certificate.
+ ///certificate will be created if none is existing.
+ ///If the server does not auto accept certificates, it is mandatory to copy this client's public key
+ ///in ./pki/own/certs folder and add it to the server's trusted folders
+ ///
+ _log?.Info($"....Creating Secure channel with security mode: {_securityMode} and security policy: {_securityPolicy}");
+ var certificatestore = new DirectoryStore("./pki");
+ // create a 'ClientSessionChannel', a client-side channel that opens a 'session' with the server.
+ _channel = new ClientSessionChannel(
+ clientDescription,
+ certificatestore,
+ new AnonymousIdentity(), // no user identity
+ Endpoint // endpoint built for opc ua security
+ );
+
+ }
+ ///
+ /// Set up Unsecure Session. Used by AID, MTP and UaClient plugins
+ ///
+
+ else if (_securityMode == MessageSecurityMode.None)
+ {
+ // create a 'ClientSessionChannel', a client-side channel that opens a 'session' with the server.
+ _log?.Info($"....Creating Unsecure channel with security mode: {_securityMode} and security policy: {_securityPolicy}");
+ _channel = new ClientSessionChannel(
+ clientDescription,
+ null, // no x509 certificates
+ new AnonymousIdentity(), // no user identity
+
+ Endpoint);
+ }
// try opening a session and reading a few nodes.
try
{
await _channel.OpenAsync();
- } catch (Exception ex)
+ }
+ catch (Exception ex)
{
ClientStatus = AasOpcUaClientStatus.ErrorCreateSession;
_log?.Error(ex, "open async");
diff --git a/src/AasxPackageExplorer.sln b/src/AasxPackageExplorer.sln
index c1906122..15961177 100644
--- a/src/AasxPackageExplorer.sln
+++ b/src/AasxPackageExplorer.sln
@@ -264,7 +264,6 @@ Global
{EBAE658A-3ECE-4C98-89BC-F79809AB4A5E}.ReleaseWithoutCEF|x86.ActiveCfg = Release|Any CPU
{EBAE658A-3ECE-4C98-89BC-F79809AB4A5E}.ReleaseWithoutCEF|x86.Build.0 = Release|Any CPU
{967E60E3-D668-42A3-AA0B-1A031C20D871}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {967E60E3-D668-42A3-AA0B-1A031C20D871}.Debug|Any CPU.Build.0 = Debug|Any CPU
{967E60E3-D668-42A3-AA0B-1A031C20D871}.Debug|x64.ActiveCfg = Debug|Any CPU
{967E60E3-D668-42A3-AA0B-1A031C20D871}.Debug|x64.Build.0 = Debug|Any CPU
{967E60E3-D668-42A3-AA0B-1A031C20D871}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -802,7 +801,6 @@ Global
{7788AC2B-7F97-4755-B343-C4196FA90198}.ReleaseWithoutCEF|x86.ActiveCfg = Release|Any CPU
{7788AC2B-7F97-4755-B343-C4196FA90198}.ReleaseWithoutCEF|x86.Build.0 = Release|Any CPU
{2F21FEFF-F0EF-40B5-BA05-09FC9F499AE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2F21FEFF-F0EF-40B5-BA05-09FC9F499AE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F21FEFF-F0EF-40B5-BA05-09FC9F499AE9}.Debug|x64.ActiveCfg = Debug|Any CPU
{2F21FEFF-F0EF-40B5-BA05-09FC9F499AE9}.Debug|x64.Build.0 = Debug|Any CPU
{2F21FEFF-F0EF-40B5-BA05-09FC9F499AE9}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -1552,7 +1550,6 @@ Global
{4EB64F40-1A01-46BB-BEED-D1A75313C7F8}.ReleaseWithoutCEF|x86.ActiveCfg = Release|Any CPU
{4EB64F40-1A01-46BB-BEED-D1A75313C7F8}.ReleaseWithoutCEF|x86.Build.0 = Release|Any CPU
{BE68E42C-28CB-4298-9F34-A18AF92FC4DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BE68E42C-28CB-4298-9F34-A18AF92FC4DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BE68E42C-28CB-4298-9F34-A18AF92FC4DE}.Debug|x64.ActiveCfg = Debug|Any CPU
{BE68E42C-28CB-4298-9F34-A18AF92FC4DE}.Debug|x64.Build.0 = Debug|Any CPU
{BE68E42C-28CB-4298-9F34-A18AF92FC4DE}.Debug|x86.ActiveCfg = Debug|Any CPU
diff --git a/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.csproj b/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.csproj
index 6166ed62..02599e40 100644
--- a/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.csproj
+++ b/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.csproj
@@ -15,6 +15,7 @@
+
@@ -33,6 +34,7 @@
+
@@ -42,6 +44,7 @@
+
diff --git a/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.options.json b/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.options.json
index 15734b7b..6a29021c 100644
--- a/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.options.json
+++ b/src/AasxPluginAssetInterfaceDesc/AasxPluginAssetInterfaceDesc.options.json
@@ -1,7 +1,8 @@
{
"Records": [
{
- "IsDescription": true,
+ "IsDescription1_0": true,
+ "IsDescription1_1": false,
"IsMapping": false,
"AllowSubmodelSemanticId": [
{
@@ -9,13 +10,31 @@
"value": "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Submodel"
}
],
- "UseHttp": false,
+ "UseHttp": true,
"UseModbus": false,
"UseMqtt": false,
- "UseOpcUa": true
+ "UseOpcUa": false,
+ "UseBacnet": false
},
{
- "IsDescription": false,
+ "IsDescription1_0": false,
+ "IsDescription1_1": true,
+ "IsMapping": false,
+ "AllowSubmodelSemanticId": [
+ {
+ "type": "Submodel",
+ "value": "https://admin-shell.io/idta/AssetInterfacesDescription/1/1/Submodel"
+ }
+ ],
+ "UseHttp": true,
+ "UseModbus": false,
+ "UseMqtt": false,
+ "UseOpcUa": false,
+ "UseBacnet": false
+ },
+ {
+ "IsDescription1_0": false,
+ "IsDescription1_1": false,
"IsMapping": true,
"AllowSubmodelSemanticId": [
{
diff --git a/src/AasxPluginAssetInterfaceDesc/AidBacnetConnection.cs b/src/AasxPluginAssetInterfaceDesc/AidBacnetConnection.cs
new file mode 100644
index 00000000..bf7aa5ea
--- /dev/null
+++ b/src/AasxPluginAssetInterfaceDesc/AidBacnetConnection.cs
@@ -0,0 +1,125 @@
+using AdminShellNS;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO.BACnet;
+using System.Threading.Tasks;
+using Aas = AasCore.Aas3_0;
+
+namespace AasxPluginAssetInterfaceDescription
+{
+ public class AidBacnetConnection : AidBaseConnection
+ {
+ public BacnetClient Client;
+ private Dictionary DeviceAddresses = new Dictionary();
+ public BacnetAddress deviceAddress;
+
+ override public async Task Open()
+ {
+ try
+ {
+ Client = new BacnetClient();
+ Client.OnIam += OnIamHandler;
+
+ if (TimeOutMs >= 10)
+ {
+ Client.Timeout = (int)TimeOutMs;
+ }
+
+ Client.Start();
+
+ // Extract device ID from the URI
+ uint deviceId = uint.Parse(TargetUri.Host);
+ if (!DeviceAddresses.ContainsKey(deviceId))
+ {
+ Client.WhoIs((int)deviceId, (int)deviceId);
+ await Task.Delay(1000);
+ }
+ if (!DeviceAddresses.TryGetValue(deviceId, out deviceAddress))
+ {
+ return false;
+ }
+
+ await Task.Yield();
+ return true;
+ }
+ catch (Exception)
+ {
+ Client = null;
+ return false;
+ }
+ }
+
+ private void OnIamHandler(BacnetClient sender, BacnetAddress adr, uint deviceId, uint maxAPDU, BacnetSegmentations segmentation, ushort vendorId)
+ {
+ // Store the device address from I-Am response
+ DeviceAddresses[deviceId] = adr;
+ }
+
+ override public bool IsConnected()
+ {
+ return Client != null;
+ }
+
+ override public void Close()
+ {
+ // Dispose client
+ if (Client != null)
+ {
+ Client.Dispose();
+ Client = null;
+ }
+ }
+
+ override public int UpdateItemValue(AidIfxItemStatus item)
+ {
+ int res = 0;
+ if (item?.FormData?.Href?.HasContent() != true ||
+ item.FormData.Bacv_useService?.HasContent() != true ||
+ !IsConnected() ||
+ Client == null)
+ {
+ return res;
+ }
+ try
+ {
+
+ var href = item.FormData.Href.TrimStart('/');
+ string[] mainParts = href.Split('/');
+ string[] objectParts = mainParts[0].Split(',');
+
+ var objectType = (BacnetObjectTypes)int.Parse(objectParts[0]);
+ uint instance = uint.Parse(objectParts[1]);
+ BacnetObjectId objectId = new BacnetObjectId(objectType, instance);
+
+ var propertyId = (BacnetPropertyIds)int.Parse(mainParts[1]);
+
+ // READ operation
+ if (item.FormData.Bacv_useService.Trim().ToLower() == "readproperty")
+ {
+ try
+ {
+ IList values_r1 = new List();
+ bool result_r1 = Client.ReadPropertyRequest(deviceAddress, objectId, propertyId, out values_r1);
+ if (result_r1 && values_r1.Count > 0 && values_r1[0].Value != null)
+ {
+ float val_r1 = (float)values_r1[0].Value;
+ item.Value = val_r1.ToString("R", CultureInfo.InvariantCulture);
+ NotifyOutputItems(item, item.Value);
+ res = 1;
+ }
+ }
+ catch (Exception)
+ {
+ return res;
+ }
+ }
+ }
+ catch (Exception)
+ {
+ return res;
+ }
+ return res;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/AasxPluginAssetInterfaceDesc/AidInterfaceStatus.cs b/src/AasxPluginAssetInterfaceDesc/AidInterfaceStatus.cs
index 6ae8d03f..5b416085 100644
--- a/src/AasxPluginAssetInterfaceDesc/AidInterfaceStatus.cs
+++ b/src/AasxPluginAssetInterfaceDesc/AidInterfaceStatus.cs
@@ -7,28 +7,31 @@ 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 AasCore.Aas3_1;
+using AasxIntegrationBase;
+using AasxIntegrationBase.AdminShellEvents;
using AasxPredefinedConcepts;
-using Aas = AasCore.Aas3_1;
+using AasxPredefinedConcepts.AssetInterfacesDescription;
using AdminShellNS;
using AdminShellNS.DiaryData;
+using AnyUi;
using Extensions;
-using AasxIntegrationBase;
-using AasxPredefinedConcepts.AssetInterfacesDescription;
using FluentModbus;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
using System.Net;
+using System.Text;
using System.Text.RegularExpressions;
-using System.Globalization;
-using AnyUi;
+using System.Threading.Tasks;
+using System.Windows.Controls;
using System.Windows.Media.Animation;
-using AasxIntegrationBase.AdminShellEvents;
-using System.IO;
-using Newtonsoft.Json.Linq;
-using Newtonsoft.Json;
+using static System.Net.WebRequestMethods;
+using Aas = AasCore.Aas3_1;
namespace AasxPluginAssetInterfaceDescription
{
@@ -97,7 +100,7 @@ public class AidIfxItemStatus
public AnyUiUIElement RenderedUiElement = null;
}
- public enum AidInterfaceTechnology { HTTP, Modbus, MQTT, OPCUA }
+ public enum AidInterfaceTechnology { HTTP, Modbus, MQTT, OPCUA, BACNET }
public class AidInterfaceStatus
{
@@ -120,7 +123,7 @@ public class AidInterfaceStatus
///
/// The information items (properties, actions, events)
///
- public MultiValueDictionary Items =
+ public MultiValueDictionary Items =
new MultiValueDictionary();
///
@@ -128,6 +131,27 @@ public class AidInterfaceStatus
///
public string EndpointBase = "";
+ ///
+ /// For creating OPC UA secured channel. it can be either None, Sign, SignAndEncrypt
+ ///
+
+ public int SecurityMode = 1;
+
+ ///
+ /// For creating OPC UA security channel. For this version, only
+ /// None, Basic256Sha256, Aes128_Sha256_RsaOaep, Aes256_Sha256_RsaPss,
+ /// Outdated(not recommended policies):Basic256, Basic128Rsa15
+ ///
+
+ public string SecurityPolicy = "http://opcfoundation.org/UA/SecurityPolicy#None";
+
+ ///
+ /// For creating OPC UA security channel.
+ /// when AutoConnection is true, the client gets endpoints from server
+ /// and pick one from the list of endpoints to set up the session.
+ ///
+
+ public bool OPCAutoConnection = false;
///
/// Used by byteStream payload for decoding, presently, mainly used by Modbus but other protocols will also be using it
@@ -201,7 +225,7 @@ protected string ComputeKey(string key)
return key;
}
- public void SetLogLine (StoredPrint.Color color, string line)
+ public void SetLogLine(StoredPrint.Color color, string line)
{
LogColor = color;
LogLine = line;
@@ -219,7 +243,7 @@ public void AddItem(AidIfxItemStatus item)
// compute key
var key = ComputeKey(item?.FormData?.Href);
-
+
// now add
Items.Add(key, item);
}
@@ -257,6 +281,28 @@ public class AidBaseConnection
///
public string Password = null;
+ ///
+ /// For creating OPC UA secured channel. it can be either None, Sign, SignAndEncrypt
+ ///
+
+ public int SecurityMode = 1;
+
+ ///
+ /// For creating OPC UA security channel. For this version, only
+ /// None, Basic256Sha256, Aes128_Sha256_RsaOaep, Aes256_Sha256_RsaPss,
+ /// Outdated(not recommended policies):Basic256, Basic128Rsa15
+ ///
+
+ public string SecurityPolicy = null;
+
+ ///
+ /// For creating OPC UA security channel.
+ /// when AutoConnection is true, the client gets endpoints from server
+ /// and pick one from the list of endpoints to set up the session.
+ ///
+
+ public bool OPCAutoConnection = false;
+
///
/// Used by byteStream payload for decoding, presently, mainly used by Modbus but other protocols will also be using it
///
@@ -401,7 +447,7 @@ public void NotifyOutputItems(AidIfxItemStatus item, string strval)
}
}
-
+
}
}
}
@@ -428,6 +474,13 @@ public T GetOrCreate(string target, LogInstance log = null)
///
public class AidAllInterfaceStatus
{
+ ///
+ /// Flag to enable or disable protocols in the UI based on AID version.
+ /// Version 1.0 will enable HTTP, MODBUS and MQTT.
+ /// version 1.1 will enable HTTP, MODBUS, MQTT, OPCUA and BACNET.
+ ///
+ public bool AidVersion1_1 = false;
+
///
/// Set to logger, if logging is desired.
///
@@ -451,7 +504,7 @@ public class AidAllInterfaceStatus
///
/// Current setting, which technologies shall be used.
///
- public bool[] UseTech = { false, false, false, true };
+ public bool[] UseTech = { true, false, false, false, false };
///
/// Will hold connections steady and continously update values, either by
@@ -464,7 +517,7 @@ public class AidAllInterfaceStatus
public AidGenericConnections HttpConnections =
new AidGenericConnections();
- public AidGenericConnections ModbusConnections =
+ public AidGenericConnections ModbusConnections =
new AidGenericConnections();
public AidGenericConnections MqttConnections =
@@ -473,6 +526,9 @@ public class AidAllInterfaceStatus
public AidGenericConnections OpcUaConnections =
new AidGenericConnections();
+ public AidGenericConnections BacnetConnections =
+ new AidGenericConnections();
+
public AidAllInterfaceStatus(LogInstance log = null)
{
_log = log;
@@ -494,7 +550,7 @@ public void RememberAidSubmodel(Aas.ISubmodel sm, AssetInterfaceOptionsRecord op
if (sm == null || optRec == null)
return;
- if (optRec.IsDescription)
+ if (optRec.IsDescription1_0 || optRec.IsDescription1_1)
SmAidDescription = sm;
if (adoptUseFlags)
@@ -503,6 +559,7 @@ public void RememberAidSubmodel(Aas.ISubmodel sm, AssetInterfaceOptionsRecord op
UseTech[(int)AidInterfaceTechnology.Modbus] = optRec.UseModbus;
UseTech[(int)AidInterfaceTechnology.MQTT] = optRec.UseMqtt;
UseTech[(int)AidInterfaceTechnology.OPCUA] = optRec.UseOpcUa;
+ UseTech[(int)AidInterfaceTechnology.BACNET] = optRec.UseBacnet;
}
}
@@ -538,7 +595,15 @@ protected AidBaseConnection GetOrCreate(
case AidInterfaceTechnology.OPCUA:
conn = OpcUaConnections.GetOrCreate(endpointBase, log);
+ conn.OPCAutoConnection = ifcStatus.OPCAutoConnection;
+ conn.SecurityMode = ifcStatus.SecurityMode;
+ conn.SecurityPolicy = ifcStatus.SecurityPolicy;
+ break;
+
+ case AidInterfaceTechnology.BACNET:
+ conn = BacnetConnections.GetOrCreate(endpointBase, log);
break;
+
}
conn.UpdateFreqMs = ifcStatus.UpdateFreqMs;
@@ -762,17 +827,17 @@ public async Task UpdateValuesContinousByTickAsyc()
// go thru all items (sync)
foreach (var item in ifc.Items.Values)
- ifc.ValueChanges += (UInt64) ifc.Connection.UpdateItemValue(item);
+ ifc.ValueChanges += (UInt64)ifc.Connection.UpdateItemValue(item);
// go thru all items (async)
// see: https://www.hanselman.com/blog/parallelforeachasync-in-net-6
await Parallel.ForEachAsync(
- ifc.Items.Values,
- new ParallelOptions() { MaxDegreeOfParallelism = 10 },
+ ifc.Items.Values,
+ new ParallelOptions() { MaxDegreeOfParallelism = 10 },
async (item, token) =>
- {
- ifc.ValueChanges += (UInt64) (await ifc.Connection.UpdateItemValueAsync(item));
- });
+ {
+ ifc.ValueChanges += (UInt64)(await ifc.Connection.UpdateItemValueAsync(item));
+ });
}
}
}
@@ -810,17 +875,20 @@ public void PrepareAidInformation(Aas.ISubmodel smAid, Aas.ISubmodel smMapping =
// get data MC
var dataMc = (smMapping != null) ?
- new AasxPredefinedConcepts.AssetInterfacesMappingConfiguration.
- CD_AssetInterfacesMappingConfiguration() : null;
+ new AasxPredefinedConcepts.AssetInterfacesMappingConfiguration.
+ CD_AssetInterfacesMappingConfiguration() : null;
PredefinedConceptsClassMapper.ParseAasElemsToObject(smMapping, dataMc, lambdaLookupReference);
// prepare
foreach (var tech in AdminShellUtil.GetEnumValues())
{
var ifxs = dataAid?.InterfaceHTTP;
+ ifxs = null;
+ if (tech == AidInterfaceTechnology.HTTP) ifxs = dataAid?.InterfaceHTTP;
if (tech == AidInterfaceTechnology.Modbus) ifxs = dataAid?.InterfaceMODBUS;
if (tech == AidInterfaceTechnology.MQTT) ifxs = dataAid?.InterfaceMQTT;
- if (tech == AidInterfaceTechnology.OPCUA) ifxs = dataAid?.InterfaceOPCUA;
+ if (tech == AidInterfaceTechnology.OPCUA && AidVersion1_1) ifxs = dataAid?.InterfaceOPCUA;
+ if (tech == AidInterfaceTechnology.BACNET && AidVersion1_1) ifxs = dataAid?.InterfaceBACNET;
if (ifxs == null || ifxs.Count < 1)
continue;
foreach (var ifx in ifxs)
@@ -829,6 +897,7 @@ public void PrepareAidInformation(Aas.ISubmodel smAid, Aas.ISubmodel smMapping =
var dn = AdminShellUtil.TakeFirstContent(ifx.Title, ifx.__Info__?.Referable?.IdShort);
var aidIfx = new AidInterfaceStatus()
{
+
Technology = tech,
DisplayName = $"{dn}",
Info = $"{ifx.EndpointMetadata?.Base}",
@@ -853,7 +922,7 @@ public void PrepareAidInformation(Aas.ISubmodel smAid, Aas.ISubmodel smMapping =
FormData = propName.Forms,
Value = "???"
};
-
+
// does (some) mapping have a source with this property name?
var lst = new List();
@@ -874,7 +943,7 @@ public void PrepareAidInformation(Aas.ISubmodel smAid, Aas.ISubmodel smMapping =
aidIfx.AddItem(ifcItem);
ifcItem.MapOutputItems = lst;
}
-
+
// directly recurse?
if (propName?.Properties?.Property != null)
@@ -884,17 +953,113 @@ public void PrepareAidInformation(Aas.ISubmodel smAid, Aas.ISubmodel smMapping =
child.Forms = propName.Forms;
recurseProp(location + " . " + ifcItem.DisplayName, child);
}
-
+
};
if (ifx.InteractionMetadata?.Properties?.Property == null)
continue;
foreach (var propName in ifx.InteractionMetadata?.Properties?.Property)
recurseProp("\u2302", propName);
+
+ //Handling of opc ua security
+ if (aidIfx.Technology == AidInterfaceTechnology.OPCUA)
+ {
+ ExtractSecurityData(ifx, aidIfx);
+
+ }
+
}
}
}
+ protected void ExtractSecurityData(CD_GenericInterface ifx, AidInterfaceStatus aidIfx)
+ {
+ if (ifx.EndpointMetadata.Security.SecurityRef.Count > 0 &&
+ ifx.EndpointMetadata.Security.SecurityRef[0].ValueHint != null &&
+ ifx.EndpointMetadata.Security.SecurityRef[0].ValueHint is SubmodelElementCollection securityRef)
+ {
+
+ if (securityRef.SemanticId?.GetAsExactlyOneKey().Value == "https://www.w3.org/2019/wot/security#NoSecurityScheme")
+ {
+ aidIfx.SecurityMode = 1;
+ aidIfx.SecurityPolicy = "http://opcfoundation.org/UA/SecurityPolicy#None";
+ return;
+ }
+ else if (securityRef.SemanticId?.GetAsExactlyOneKey().Value == "https://www.w3.org/2019/wot/security#AutoSecurityScheme")
+ {
+ aidIfx.OPCAutoConnection = true;
+ return;
+
+ }
+ else if(securityRef.SemanticId?.GetAsExactlyOneKey().Value == "https://www.w3.org/2019/wot/security#ComboSecurityScheme")
+ {
+ //Combo Security implementation here
+ // Handling allOf
+ foreach(var opcuaSecurityRef in ifx.EndpointMetadata.SecurityDefinitions.Combo_sc.AllOf.SecurityRef)
+ {
+ if(opcuaSecurityRef != null && opcuaSecurityRef.ValueHint is SubmodelElementCollection opcuasec)
+ {
+ if(opcuasec.SemanticId.GetAsExactlyOneKey().Value == "http://opcfoundation.org/UA/WoT-Binding/OPCUASecurityChannelScheme")
+ {
+ switch(ifx.EndpointMetadata.SecurityDefinitions.Opcua_channel_sc.Uav_securityMode.ToLower())
+ {
+ case "none":
+ aidIfx.SecurityMode = 1;
+ break;
+ case "sign":
+ aidIfx.SecurityMode = 2;
+ break;
+ case "signandencrypt":
+ aidIfx.SecurityMode = 3;
+ break;
+ default:
+ aidIfx.SecurityMode = 1;
+ break;
+
+
+ }
+ switch (ifx.EndpointMetadata.SecurityDefinitions.Opcua_channel_sc.Uav_securityPolicy.ToLower())
+ {
+ case "basic256sha256":
+ aidIfx.SecurityPolicy = "http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256";
+ break;
+ case "aes128_sha256_rsaoaep":
+ aidIfx.SecurityPolicy = "http://opcfoundation.org/UA/SecurityPolicy#Aes128_Sha256_RsaOaep";
+ break;
+ case "aes256_sha256_rsapss":
+ aidIfx.SecurityPolicy = "http://opcfoundation.org/UA/SecurityPolicy#Aes256_Sha256_RsaPss";
+ break;
+ case "basic256":
+ aidIfx.SecurityPolicy = "http://opcfoundation.org/UA/SecurityPolicy#Basic256";
+ break;
+ case "basic128rsa15":
+ aidIfx.SecurityPolicy = "http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15";
+ break;
+ default:
+ aidIfx.SecurityPolicy = "http://opcfoundation.org/UA/SecurityPolicy#None";
+ break;
+ }
+ }
+
+ }
+
+ }
+ return;
+ }
+ else
+ {
+ aidIfx.SecurityMode = 1;
+ aidIfx.SecurityPolicy = "http://opcfoundation.org/UA/SecurityPolicy#None";
+ return;
+ }
+ }
+ else
+ {
+ aidIfx.SecurityMode = 1;
+ aidIfx.SecurityPolicy = "http://opcfoundation.org/UA/SecurityPolicy#None";
+ return;
+ }
+ }
protected List SelectValuesToIntList- (
IEnumerable
- items,
Func
- selectStringValue) where ITEM : class
@@ -956,20 +1121,6 @@ public void SetAidInformationForUpdateAndTimeout(
ref ifc.TimeOutMs, 10.0, defaultTimeOutMs,
SelectValuesToIntList(ifc?.Items?.Values, (it) => it.FormData?.Modv_timeout));
}
-
- // for OPC UA, analyze update frequency and timeout
- foreach (var ifc in InterfaceStatus.Where((i) => i.Technology == AidInterfaceTechnology.OPCUA))
- {
- // polltimes
- SetDoubleOnDefaultOrAvgOfIntList(
- ref ifc.UpdateFreqMs, 10.0, defaultUpdateFreqMs,
- SelectValuesToIntList(ifc?.Items?.Values, (it) => it.FormData?.OpcUa_pollingTime));
-
- // time out
- SetDoubleOnDefaultOrAvgOfIntList(
- ref ifc.TimeOutMs, 10.0, defaultTimeOutMs,
- SelectValuesToIntList(ifc?.Items?.Values, (it) => it.FormData?.OpcUa_timeout));
- }
}
}
diff --git a/src/AasxPluginAssetInterfaceDesc/AidOpcUaConnection.cs b/src/AasxPluginAssetInterfaceDesc/AidOpcUaConnection.cs
index 0778dd59..f0cd3e51 100644
--- a/src/AasxPluginAssetInterfaceDesc/AidOpcUaConnection.cs
+++ b/src/AasxPluginAssetInterfaceDesc/AidOpcUaConnection.cs
@@ -29,6 +29,8 @@ This source code may use other Open Source software components (see LICENSE.txt)
using MQTTnet.Client;
using System.Web.Services.Description;
using AasxOpcUa2Client;
+using System.IO;
+
#if OPCUA2
@@ -75,13 +77,18 @@ override public async Task Open()
// make client
// use the full target uri as endpoint (first)
#if OPCUA2
+
Client = new AasOpcUaClient2(
TargetUri.ToString(),
autoAccept: true,
userName: this.User,
password: this.Password,
timeOutMs: (TimeOutMs >= 10) ? (uint)TimeOutMs : 2000,
- log: Log);
+ log: Log,
+ securityMode: (MessageSecurityMode?)this.SecurityMode,
+ securityPolicy: this.SecurityPolicy,
+ autoConnect: this.OPCAutoConnection);
+
#else
Client = new AasOpcUaClient(
TargetUri.ToString(),
@@ -138,12 +145,17 @@ override public async Task UpdateItemValueAsync(AidIfxItemStatus item)
// careful
try
{
+ var nodePath = "" + item.FormData?.Href;
+ nodePath = nodePath.Replace("/?id =", "").Trim();
// get an node id?
- var nid = Client.ParseAndCreateNodeId(item?.FormData?.Href);
+ var nid = Client.ParseAndCreateNodeId(nodePath);
// direct read possible?
var dv = await Client.ReadNodeIdAsync(nid);
item.Value = AdminShellUtil.ToStringInvariant(dv?.Value);
+
+ // notify
+ NotifyOutputItems(item, item.Value);
LastActive = DateTime.Now;
// success
@@ -198,11 +210,14 @@ override public async Task PrepareContinousRunAsync(IEnumerable _dictTechnologyToBitmap =
+ protected Dictionary _dictTechnologyToBitmap =
new Dictionary();
private System.Timers.Timer _dispatcherTimer = null;
@@ -109,6 +110,10 @@ public void Start(
_dictTechnologyToBitmap = new Dictionary();
if (OperatingSystem.IsWindowsVersionAtLeast(7))
{
+ _dictTechnologyToBitmap.Add(AidInterfaceTechnology.BACNET,
+ AnyUiGdiHelper.CreateAnyUiBitmapFromResource(
+ "AasxPluginAssetInterfaceDesc.Resources.logo-bacnet.png",
+ assembly: Assembly.GetExecutingAssembly()));
_dictTechnologyToBitmap.Add(AidInterfaceTechnology.HTTP,
AnyUiGdiHelper.CreateAnyUiBitmapFromResource(
"AasxPluginAssetInterfaceDesc.Resources.logo-http.png",
@@ -283,13 +288,13 @@ protected void RenderPanelInner(
uitk.AddSmallLabelTo(grid, 0, 0, content: "Technologies:");
- var gridTech = uitk.AddSmallGridTo(grid, 0, 1, rows: 1, cols: 6,
+ var gridTech = uitk.AddSmallGridTo(grid, 0, 1, rows: 1, cols: 6,
colWidths: new[] { "#", "#", "#", "#", "#", "#" });
foreach (var tech in AdminShellUtil.GetEnumValues())
{
AnyUiUIElement.SetBoolFromControl(
- uitk.AddSmallCheckBoxTo(gridTech, 0, 0 + ((int) tech),
+ uitk.AddSmallCheckBoxTo(gridTech, 0, 0 + ((int)tech),
margin: new AnyUiThickness(0, 0, 10, 0),
content: "" + tech.ToString(),
isChecked: _allInterfaceStatus.UseTech[(int)tech],
@@ -302,7 +307,7 @@ protected void RenderPanelInner(
//
uitk.AddSmallLabelTo(grid, 1, 0, content: "Startup:");
-
+
AnyUiUIElement.RegisterControl(
uitk.AddSmallButtonTo(grid, 1, 1,
margin: new AnyUiThickness(2), setHeight: 21,
@@ -319,11 +324,18 @@ protected void RenderPanelInner(
return new AnyUiLambdaActionNone();
}
+ // Check if at least one technology is selected
+ if (!_allInterfaceStatus.UseTech.Any(tech => tech))
+ {
+ _log.Info(StoredPrint.Color.Blue, "Please select at least one technology.");
+ return new AnyUiLambdaActionNone();
+ }
+
// build up data structures
_allInterfaceStatus.PrepareAidInformation(
_allInterfaceStatus.SmAidDescription,
_allInterfaceStatus.SmAidMapping,
- lambdaLookupReference: (rf) => package?.AasEnv?.FindReferableByReference(rf) );
+ lambdaLookupReference: (rf) => package?.AasEnv?.FindReferableByReference(rf));
_allInterfaceStatus.SetAidInformationForUpdateAndTimeout();
// trigger a complete redraw, as the regions might emit
@@ -345,7 +357,7 @@ protected void RenderPanelInner(
setValueAsync: async (o) =>
{
try
- {
+ {
// locked?
if (_allInterfaceStatus?.ContinousRun == true)
{
@@ -451,7 +463,7 @@ public void Update(params object[] args)
#region Interface items
//=====================
-
+
protected void RenderTripleRowData(
AnyUiStackPanel view, AnyUiSmallWidgetToolkit uitk,
List interfaces)
@@ -460,11 +472,16 @@ protected void RenderTripleRowData(
if (interfaces == null)
return;
+ // Filter interfaces based on selected technologies
+ var filteredInterfaces = interfaces.Where(ifx =>
+ _allInterfaceStatus.UseTech[(int)ifx.Technology]).ToList();
+
// ok
- var grid = view.Add(uitk.AddSmallGrid(rows: interfaces.Count, cols: 5,
+ var grid = view.Add(uitk.AddSmallGrid(rows: interfaces.Count, cols: 5,
colWidths: new[] { "40:", "1*", "1*", "1*", "180:" }));
int rowIndex = 0;
- foreach (var ifx in interfaces)
+
+ foreach (var ifx in filteredInterfaces)
{
//
// heading
@@ -479,7 +496,7 @@ protected void RenderTripleRowData(
colSpan: 5);
if (_dictTechnologyToBitmap.ContainsKey(ifx.Technology))
- uitk.AddSmallImageTo(headGrid, 0, 0,
+ uitk.AddSmallImageTo(headGrid, 0, 0,
margin: new AnyUiThickness(0, 4, 10, 4),
bitmap: _dictTechnologyToBitmap[ifx.Technology]);
@@ -503,13 +520,13 @@ protected void RenderTripleRowData(
{
// normal row, 5 bordered cells
grid.RowDefinitions.Add(new AnyUiRowDefinition());
- var cols = new[] {
+ 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),
+ 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()
{
@@ -534,7 +551,7 @@ protected void RenderTripleRowData(
var innerGrid = uitk.Set(
uitk.AddSmallGridTo(grid, rowIndex++, 1,
- rows: item.MapOutputItems.Count,
+ rows: item.MapOutputItems.Count,
cols: 3, colWidths: new[] { "#", "*", "#" },
margin: new AnyUiThickness(2, 0, 0, 6)),
colSpan: 4);
@@ -656,4 +673,4 @@ private void DispatcherTimer_Tick(object sender, EventArgs e)
#endregion
}
-}
+}
\ No newline at end of file
diff --git a/src/AasxPluginAssetInterfaceDesc/AssetInterfaceOptions.cs b/src/AasxPluginAssetInterfaceDesc/AssetInterfaceOptions.cs
index 708c464b..9a6cc528 100644
--- a/src/AasxPluginAssetInterfaceDesc/AssetInterfaceOptions.cs
+++ b/src/AasxPluginAssetInterfaceDesc/AssetInterfaceOptions.cs
@@ -22,13 +22,15 @@ namespace AasxPluginAssetInterfaceDescription
{
public class AssetInterfaceOptionsRecord : AasxPluginOptionsLookupRecordBase
{
- public bool IsDescription = false;
+ public bool IsDescription1_0 = false;
+ public bool IsDescription1_1 = false;
public bool IsMapping = false;
public bool UseHttp = true;
public bool UseModbus = true;
public bool UseMqtt = true;
public bool UseOpcUa = true;
+ public bool UseBacnet = true;
}
public class AssetInterfaceOptions : AasxPluginLookupOptionsBase
@@ -43,13 +45,19 @@ public static AssetInterfaceOptions CreateDefault()
var defs = new DefinitionsMTP.ModuleTypePackage();
var rec1 = new AssetInterfaceOptionsRecord();
- rec1.IsDescription = true;
- rec1.AllowSubmodelSemanticId = new[] {
- new Aas.Key(Aas.KeyTypes.Submodel,
+ rec1.IsDescription1_0 = true;
+ rec1.AllowSubmodelSemanticId = new[] {
+ new Aas.Key(Aas.KeyTypes.Submodel,
"https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Submodel") }.ToList();
var rec2 = new AssetInterfaceOptionsRecord();
- rec2.IsMapping = true;
+ rec2.IsDescription1_1 = true;
+ rec1.AllowSubmodelSemanticId = new[] {
+ new Aas.Key(Aas.KeyTypes.Submodel,
+ "https://admin-shell.io/idta/AssetInterfacesDescription/1/1/Submodel") }.ToList();
+
+ var rec3 = new AssetInterfaceOptionsRecord();
+ rec3.IsMapping = true;
rec1.AllowSubmodelSemanticId = new[] {
new Aas.Key(Aas.KeyTypes.Submodel,
"https://admin-shell.io/idta/AssetInterfacesMappingConfiguration/1/0/Submodel") }.ToList();
diff --git a/src/AasxPluginAssetInterfaceDesc/Plugin.cs b/src/AasxPluginAssetInterfaceDesc/Plugin.cs
index 374490ad..b7a07f08 100644
--- a/src/AasxPluginAssetInterfaceDesc/Plugin.cs
+++ b/src/AasxPluginAssetInterfaceDesc/Plugin.cs
@@ -118,9 +118,22 @@ public class Session : PluginSessionBase
return null;
// remember for later / background
- if (foundOptRec.IsDescription)
+ if (foundOptRec.IsDescription1_0)
+ {
+ _allInterfaceStatus.RememberAidSubmodel(sm, foundOptRec,
+ adoptUseFlags: true);
+ _allInterfaceStatus.AidVersion1_1 = false;
+ }
+
+
+ // remember for later / background
+ if (foundOptRec.IsDescription1_1)
+ {
_allInterfaceStatus.RememberAidSubmodel(sm, foundOptRec,
adoptUseFlags: true);
+ _allInterfaceStatus.AidVersion1_1 = true;
+ }
+
if (foundOptRec.IsMapping)
_allInterfaceStatus.RememberMappingSubmodel(sm);
@@ -273,7 +286,7 @@ public class Session : PluginSessionBase
if (foundOptRec == null)
continue;
- if (foundOptRec.IsDescription)
+ if (foundOptRec.IsDescription1_0)
_allInterfaceStatus.RememberAidSubmodel(sm, foundOptRec,
adoptUseFlags: true);
if (foundOptRec.IsMapping)
diff --git a/src/AasxPluginAssetInterfaceDesc/Resources/logo-bacnet.png b/src/AasxPluginAssetInterfaceDesc/Resources/logo-bacnet.png
new file mode 100644
index 00000000..cefb4d60
Binary files /dev/null and b/src/AasxPluginAssetInterfaceDesc/Resources/logo-bacnet.png differ
diff --git a/src/AasxPredefinedConcepts/Mappings/MappingsAssetInterfacesDescription.cs b/src/AasxPredefinedConcepts/Mappings/MappingsAssetInterfacesDescription.cs
index 28e3f272..2c012f6e 100644
--- a/src/AasxPredefinedConcepts/Mappings/MappingsAssetInterfacesDescription.cs
+++ b/src/AasxPredefinedConcepts/Mappings/MappingsAssetInterfacesDescription.cs
@@ -12,6 +12,7 @@ This source code may use other Open Source software components (see LICENSE.txt)
using Extensions;
using System;
using System.Collections.Generic;
+using static AasxPredefinedConcepts.ConceptModel.ConceptModelZveiTechnicalData;
using Aas = AasCore.Aas3_1;
// These classes were serialized by "export predefined concepts"
@@ -20,7 +21,7 @@ This source code may use other Open Source software components (see LICENSE.txt)
namespace AasxPredefinedConcepts.AssetInterfacesDescription
{
-
+
[AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Interface")]
public class CD_GenericInterface
{
@@ -40,7 +41,7 @@ public class CD_GenericInterface
public CD_EndpointMetadata EndpointMetadata = new CD_EndpointMetadata();
[AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/InteractionMetadata", Card = AasxPredefinedCardinality.One)]
- public CD_InterfaceMetadata InteractionMetadata = new CD_InterfaceMetadata();
+ public CD_InteractionMetadata InteractionMetadata = new CD_InteractionMetadata();
[AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/ExternalDescriptor", Card = AasxPredefinedCardinality.ZeroToOne)]
public CD_ExternalDescriptor ExternalDescriptor = null;
@@ -77,7 +78,9 @@ public class CD_EndpointMetadata
[AasConcept(Cd = "https://www.w3.org/2019/wot/td#hasSecurityConfiguration")]
public class CD_Security
{
-
+ [AasConcept(Cd = "https://www.w3.org/2019/wot/td#definesSecurityScheme", Card = AasxPredefinedCardinality.ZeroToMany)]
+ public List SecurityRef = new List();
+
// auto-generated informations
public AasClassMapperInfo __Info__ = null;
}
@@ -112,6 +115,12 @@ public class CD_SecurityDefinitions
[AasConcept(Cd = "https://www.w3.org/2019/wot/security#OAuth2SecurityScheme", Card = AasxPredefinedCardinality.ZeroToOne)]
public CD_Oauth2_sc Oauth2_sc = null;
+ [AasConcept(Cd = "http://opcfoundation.org/UA/WoT-Binding/OPCUASecurityChannelScheme", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public CD_Opcua_channel_sc Opcua_channel_sc = null;
+
+ [AasConcept(Cd = "http://opcfoundation.org/UA/WoT-Binding/OPCUASecurityAuthenticationScheme ", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public CD_Opcua_authentication_sc Opcua_authentication_sc = null;
+
// auto-generated informations
public AasClassMapperInfo __Info__ = null;
}
@@ -164,10 +173,10 @@ public class CD_Combo_sc
[AasConcept(Cd = "https://www.w3.org/2019/wot/security#SecurityScheme", Card = AasxPredefinedCardinality.One)]
public string Scheme;
- [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#oneOf", Card = AasxPredefinedCardinality.One)]
+ [AasConcept(Cd = "https://www.w3.org/2019/wot/security#oneOf", Card = AasxPredefinedCardinality.One)]
public CD_OneOf OneOf = new CD_OneOf();
- [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#allOf", Card = AasxPredefinedCardinality.One)]
+ [AasConcept(Cd = "https://www.w3.org/2019/wot/security#allOf", Card = AasxPredefinedCardinality.One)]
public CD_AllOf AllOf = new CD_AllOf();
[AasConcept(Cd = "https://www.w3.org/2019/wot/security#proxy", Card = AasxPredefinedCardinality.ZeroToOne)]
@@ -177,18 +186,20 @@ public class CD_Combo_sc
public AasClassMapperInfo __Info__ = null;
}
- [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#oneOf")]
+ [AasConcept(Cd = "https://www.w3.org/2019/wot/security#oneOf")]
public class CD_OneOf
{
-
+ [AasConcept(Cd = "https://www.w3.org/2019/wot/td#definesSecurityScheme", Card = AasxPredefinedCardinality.ZeroToMany)]
+ public List SecurityRef = new List();
// auto-generated informations
public AasClassMapperInfo __Info__ = null;
}
- [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#allOf")]
+ [AasConcept(Cd = "https://www.w3.org/2019/wot/security#allOf")]
public class CD_AllOf
{
-
+ [AasConcept(Cd = "https://www.w3.org/2019/wot/td#definesSecurityScheme", Card = AasxPredefinedCardinality.ZeroToMany)]
+ public List SecurityRef = new List();
// auto-generated informations
public AasClassMapperInfo __Info__ = null;
}
@@ -305,8 +316,46 @@ public class CD_Oauth2_sc
public AasClassMapperInfo __Info__ = null;
}
- [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/InterfaceMetadata")]
- public class CD_InterfaceMetadata
+ [AasConcept(Cd = "http://opcfoundation.org/UA/WoT-Binding/OPCUASecurityChannelScheme")]
+ public class CD_Opcua_channel_sc
+ {
+ [AasConcept(Cd = "https://www.w3.org/2019/wot/security#SecurityScheme", Card = AasxPredefinedCardinality.One)]
+ public string Scheme;
+
+ [AasConcept(Cd = "http://opcfoundation.org/UA/WoT-Binding/securityMode ", Card = AasxPredefinedCardinality.One)]
+ public string Uav_securityMode;
+
+ [AasConcept(Cd = "http://opcfoundation.org/UA/WoT-Binding/securityPolicy", Card = AasxPredefinedCardinality.One)]
+ public string Uav_securityPolicy;
+
+ [AasConcept(Cd = "https://www.w3.org/2019/wot/security#proxy", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public string Proxy;
+
+ // auto-generated informations
+ public AasClassMapperInfo __Info__ = null;
+ }
+
+ [AasConcept(Cd = "http://opcfoundation.org/UA/WoT-Binding/OPCUASecurityAuthenticationScheme")]
+ public class CD_Opcua_authentication_sc
+ {
+ [AasConcept(Cd = "https://www.w3.org/2019/wot/security#SecurityScheme", Card = AasxPredefinedCardinality.One)]
+ public string Scheme;
+
+ [AasConcept(Cd = "http://opcfoundation.org/UA/WoT-Binding/userIdentityToken", Card = AasxPredefinedCardinality.One)]
+ public string Uav_userIdentityToken;
+
+ [AasConcept(Cd = "http://opcfoundation.org/UA/WoT-Binding/issueToken", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public AasClassMapperHintedReference Uav_issueToken = new AasClassMapperHintedReference();
+
+ [AasConcept(Cd = "https://www.w3.org/2019/wot/security#proxy", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public string Proxy;
+
+ // auto-generated informations
+ public AasClassMapperInfo __Info__ = null;
+ }
+
+ [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/InteractionMetadata")]
+ public class CD_InteractionMetadata
{
[AasConcept(Cd = "https://www.w3.org/2019/wot/td#PropertyAffordance", Card = AasxPredefinedCardinality.ZeroToOne)]
public CD_PropertiesAffordance Properties = null;
@@ -350,6 +399,9 @@ public class CD_PropertyName
[AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#const", Card = AasxPredefinedCardinality.ZeroToOne)]
public int? Const;
+ [AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#enum", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public CD_Enum Enum = new CD_Enum();
+
[AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#default", Card = AasxPredefinedCardinality.ZeroToOne)]
public string Default;
@@ -371,6 +423,12 @@ public class CD_PropertyName
[AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#properties", Card = AasxPredefinedCardinality.ZeroToOne)]
public CD_Properties Properties = null;
+ [AasConcept(Cd = "https://www.w3.org/2019/wot/td#hasUriTemplateSchema", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public CD_Properties UriVariables = null;
+
+ [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/valueSemantics", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public AasClassMapperHintedReference ValueSemanticas = new AasClassMapperHintedReference();
+
[AasConcept(Cd = "https://www.w3.org/2019/wot/td#hasForm", Card = AasxPredefinedCardinality.One)]
public CD_Forms Forms = new CD_Forms();
@@ -378,6 +436,13 @@ public class CD_PropertyName
public AasClassMapperInfo __Info__ = null;
}
+ public class CD_Enum
+ {
+
+ // auto-generated informations
+ public AasClassMapperInfo __Info__ = null;
+ }
+
[AasConcept(Cd = "https://www.w3.org/2019/wot/json-schema#items")]
public class CD_Items
{
@@ -405,6 +470,9 @@ public class CD_Items
[AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/lengthRange", Card = AasxPredefinedCardinality.ZeroToOne)]
public AasClassMapperRange LengthRange = null;
+ [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/valueSemantics", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public AasClassMapperHintedReference ValueSemanticas = new AasClassMapperHintedReference();
+
// auto-generated informations
public AasClassMapperInfo __Info__ = null;
}
@@ -476,11 +544,14 @@ public class CD_Forms
[AasConcept(Cd = "https://www.w3.org/2019/wot/mqtt#hasQoSFlag", Card = AasxPredefinedCardinality.ZeroToOne)]
public string Mqv_qos;
- [AasConcept(Cd = "https://www.w3.org/2019/wot/opc-ua#pollingTime", Card = AasxPredefinedCardinality.ZeroToOne)]
- public string OpcUa_pollingTime;
+ [AasConcept(Cd = "http://opcfoundation.org/UA/WoT-Binding#browsePath", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public string Uav_browsePath;
- [AasConcept(Cd = "https://www.w3.org/2019/wot/opc-ua#timeout", Card = AasxPredefinedCardinality.ZeroToOne)]
- public string OpcUa_timeout;
+ [AasConcept(Cd = "http://www.w3.org/2022/bacnet#usesService", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public string Bacv_useService;
+
+ [AasConcept(Cd = "http://www.w3.org/2022/bacnet#hasDataType", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public CD_Bacv_hasDataType Bacv_hasDataType = null;
// auto-generated informations
public AasClassMapperInfo __Info__ = null;
@@ -502,6 +573,58 @@ public class CD_Htv_headers
public AasClassMapperInfo __Info__ = null;
}
+ [AasConcept(Cd = "http://www.w3.org/2022/bacnet#hasDataType")]
+ public class CD_Bacv_hasDataType
+ {
+ [AasConcept(Cd = "http://www.w3.org/2022/bacnet#isIso8601", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public bool? bacv_isISO8601;
+
+ [AasConcept(Cd = "http://www.w3.org/2022/bacnet#hasBinaryRepresentation", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public string bacv_hasBinaryRepresentation;
+
+ [AasConcept(Cd = "http://www.w3.org/2022/bacnet#hasMember", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public CD_Bacv_hasDataType bacv_hasMember = null;
+
+ [AasConcept(Cd = "http://www.w3.org/2022/bacnet#hasNamedMember", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public List bacv_hasNamedMember = null;
+
+ [AasConcept(Cd = "http://www.w3.org/2022/bacnet#hasValueMap", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public List bacv_hasValueMap = null;
+
+ // auto-generated informations
+ public AasClassMapperInfo __Info__ = null;
+ }
+
+ [AasConcept(Cd = "http://www.w3.org/2022/bacnet#NamedMember")]
+ public class CD_Bacv_hasNamedMember
+ {
+ [AasConcept(Cd = "http://www.w3.org/2022/bacnet#hasfieldName", Card = AasxPredefinedCardinality.One)]
+ public string bacv_hasFieldName;
+
+ [AasConcept(Cd = "http://www.w3.org/2022/bacnet#hasContextTag", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public bool? bacv_hasContextTag;
+
+ [AasConcept(Cd = "http://www.w3.org/2022/bacnet#hasDataType", Card = AasxPredefinedCardinality.ZeroToOne)]
+ public CD_Bacv_hasDataType bacv_hasDataType = null;
+
+ // auto-generated informations
+ public AasClassMapperInfo __Info__ = null;
+ }
+
+ [AasConcept(Cd = "http://www.w3.org/2022/bacnet#hasMapEntry")]
+ public class CD_Bacv_hasValueMap
+ {
+
+ [AasConcept(Cd = "http://www.w3.org/2022/bacnet#hasLogicalVal", Card = AasxPredefinedCardinality.One)]
+ public string bacv_hasLogicalVal;
+
+ [AasConcept(Cd = "http://www.w3.org/2022/bacnet#hasProtocolVal", Card = AasxPredefinedCardinality.One)]
+ public int bacv_hasProtocolVal;
+
+ // auto-generated informations
+ public AasClassMapperInfo __Info__ = null;
+ }
+
[AasConcept(Cd = "https://www.w3.org/2019/wot/td#ActionAffordance")]
public class CD_Actions
{
@@ -525,9 +648,9 @@ 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
+ public class CD_AssetInterfacesDescription
{
[AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Interface", Card = AasxPredefinedCardinality.ZeroToMany,
SupplSemId = "http://www.w3.org/2011/http")]
@@ -542,11 +665,14 @@ public class CD_AssetInterfacesDescription
public List InterfaceMQTT = new List();
[AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Interface", Card = AasxPredefinedCardinality.ZeroToMany,
- SupplSemId = "http://www.w3.org/2011/opc-ua")]
+ SupplSemId = "http://opcfoundation.org/UA/WoT-Binding")]
public List InterfaceOPCUA = new List();
+ [AasConcept(Cd = "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Interface", Card = AasxPredefinedCardinality.ZeroToMany,
+ SupplSemId = "http://www.w3.org/2022/bacnet")]
+ public List InterfaceBACNET = new List();
+
// auto-generated informations
public AasClassMapperInfo __Info__ = null;
}
-}
-
+}
\ No newline at end of file