From c4d3bcd5f64a46922edbcfab558778241a33ac2a Mon Sep 17 00:00:00 2001 From: iioter <535915157@qq.com> Date: Sat, 11 Jan 2025 23:23:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8C=97=E5=90=91=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E5=B7=A5=E5=8E=82=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BasicData/DeviceVMs/AttributeVM.cs | 4 +- .../BasicData/DeviceVMs/DeviceVM.cs | 8 +- .../BasicData/ImportExcelVM.cs | 4 +- .../Config/SystemConfigVMs/SystemConfigVM.cs | 4 +- IoTGateway/Startup.cs | 3 +- Plugins/Plugin/DeviceService.cs | 9 +- Plugins/Plugin/DeviceThread.cs | 34 +- Plugins/Plugin/MessageService.cs | 294 ++ Plugins/Plugin/MyMqttClient.cs | 774 ---- .../PlatformHandler/IPlatformHandler.cs | 27 + .../Plugin/PlatformHandler/IoTSharpHandler.cs | 150 + .../PlatformHandler/PlatformHandlerFactory.cs | 24 + .../PlatformHandler/ThingsBoardHandler.cs | 134 + .../PlatformHandler/ThingsCloudHandler.cs | 111 + Plugins/Plugin/UA.Server/ConsoleUtils.cs | 275 -- Plugins/Plugin/UA.Server/Namespaces.cs | 42 - .../Plugin/UA.Server/ReferenceNodeManager.cs | 3696 ----------------- Plugins/Plugin/UA.Server/ReferenceServer.cs | 381 -- .../UA.Server/ReferenceServerConfiguration.cs | 82 - Plugins/Plugin/UA.Server/UAServer.cs | 267 -- Plugins/Plugin/UAService.cs | 31 - 21 files changed, 772 insertions(+), 5582 deletions(-) create mode 100644 Plugins/Plugin/MessageService.cs delete mode 100644 Plugins/Plugin/MyMqttClient.cs create mode 100644 Plugins/Plugin/PlatformHandler/IPlatformHandler.cs create mode 100644 Plugins/Plugin/PlatformHandler/IoTSharpHandler.cs create mode 100644 Plugins/Plugin/PlatformHandler/PlatformHandlerFactory.cs create mode 100644 Plugins/Plugin/PlatformHandler/ThingsBoardHandler.cs create mode 100644 Plugins/Plugin/PlatformHandler/ThingsCloudHandler.cs delete mode 100644 Plugins/Plugin/UA.Server/ConsoleUtils.cs delete mode 100644 Plugins/Plugin/UA.Server/Namespaces.cs delete mode 100644 Plugins/Plugin/UA.Server/ReferenceNodeManager.cs delete mode 100644 Plugins/Plugin/UA.Server/ReferenceServer.cs delete mode 100644 Plugins/Plugin/UA.Server/ReferenceServerConfiguration.cs delete mode 100644 Plugins/Plugin/UA.Server/UAServer.cs delete mode 100644 Plugins/Plugin/UAService.cs diff --git a/IoTGateway.ViewModel/BasicData/DeviceVMs/AttributeVM.cs b/IoTGateway.ViewModel/BasicData/DeviceVMs/AttributeVM.cs index dafc60c..b72ecf5 100644 --- a/IoTGateway.ViewModel/BasicData/DeviceVMs/AttributeVM.cs +++ b/IoTGateway.ViewModel/BasicData/DeviceVMs/AttributeVM.cs @@ -26,8 +26,8 @@ namespace IoTGateway.ViewModel.BasicData.DeviceVMs 请求结果 = "复制失败,找不到设备"; else { - var myMqttClient = Wtm.ServiceProvider.GetService(typeof(MyMqttClient)) as MyMqttClient; - myMqttClient.RequestAttributes(device.DeviceName, true, device.DeviceConfigs.Where(x => x.DataSide == DataSide.AnySide).Select(x => x.DeviceConfigName).ToArray()); + var messageService = Wtm.ServiceProvider.GetService(typeof(MessageService)) as MessageService; + messageService.RequestAttributes(device.DeviceName, true, device.DeviceConfigs.Where(x => x.DataSide == DataSide.AnySide).Select(x => x.DeviceConfigName).ToArray()); } DC.SaveChanges(); transaction.Commit(); diff --git a/IoTGateway.ViewModel/BasicData/DeviceVMs/DeviceVM.cs b/IoTGateway.ViewModel/BasicData/DeviceVMs/DeviceVM.cs index 96f977b..acbf90c 100644 --- a/IoTGateway.ViewModel/BasicData/DeviceVMs/DeviceVM.cs +++ b/IoTGateway.ViewModel/BasicData/DeviceVMs/DeviceVM.cs @@ -39,8 +39,8 @@ namespace IoTGateway.ViewModel.BasicData.DeviceVMs var device = DC.Set().Where(x => x.ID == Entity.ID).Include(x => x.Parent).Include(x => x.Driver).Include(x => x.DeviceVariables).SingleOrDefault(); deviceService.CreateDeviceThread(device); - var myMqttClient = Wtm.ServiceProvider.GetService(typeof(MyMqttClient)) as MyMqttClient; - myMqttClient.DeviceAdded(device); + var messageService = Wtm.ServiceProvider.GetService(typeof(MessageService)) as MessageService; + messageService.DeviceAdded(device); } } catch (Exception ex) @@ -62,8 +62,8 @@ namespace IoTGateway.ViewModel.BasicData.DeviceVMs List Ids = new List() { Guid.Parse(FC["id"].ToString()) }; var pluginManager = Wtm.ServiceProvider.GetService(typeof(DeviceService)) as DeviceService; - var myMqttClient = Wtm.ServiceProvider.GetService(typeof(MyMqttClient)) as MyMqttClient; - myMqttClient.DeviceDeleted(Entity); + var messageService = Wtm.ServiceProvider.GetService(typeof(MessageService)) as MessageService; + messageService.DeviceDeleted(Entity); var ret = DeleteDevices.doDelete(pluginManager, DC, Ids); if (!ret.IsSuccess) { diff --git a/IoTGateway.ViewModel/BasicData/ImportExcelVM.cs b/IoTGateway.ViewModel/BasicData/ImportExcelVM.cs index 2ebaf98..974433d 100644 --- a/IoTGateway.ViewModel/BasicData/ImportExcelVM.cs +++ b/IoTGateway.ViewModel/BasicData/ImportExcelVM.cs @@ -97,8 +97,8 @@ namespace IoTGateway.ViewModel.BasicData transaction.Commit(); - var myMqttClient = Wtm.ServiceProvider.GetService(typeof(MyMqttClient)) as MyMqttClient; - myMqttClient.StartClientAsync().Wait(); + var messageService = Wtm.ServiceProvider.GetService(typeof(MessageService)) as MessageService; + messageService.StartClientAsync().Wait(); //重新启动采集 deviceService.CreateDeviceThreads(); diff --git a/IoTGateway.ViewModel/Config/SystemConfigVMs/SystemConfigVM.cs b/IoTGateway.ViewModel/Config/SystemConfigVMs/SystemConfigVM.cs index 10295c7..cde14dc 100644 --- a/IoTGateway.ViewModel/Config/SystemConfigVMs/SystemConfigVM.cs +++ b/IoTGateway.ViewModel/Config/SystemConfigVMs/SystemConfigVM.cs @@ -29,8 +29,8 @@ namespace IoTGateway.ViewModel.Config.SystemConfigVMs public override void DoEdit(bool updateAllFields = false) { base.DoEdit(updateAllFields); - var myMqttClient = Wtm.ServiceProvider.GetService(typeof(MyMqttClient)) as MyMqttClient; - myMqttClient.StartClientAsync().Wait(); + var messageService = Wtm.ServiceProvider.GetService(typeof(MessageService)) as MessageService; + messageService.StartClientAsync().Wait(); } public override void DoDelete() diff --git a/IoTGateway/Startup.cs b/IoTGateway/Startup.cs index e107696..dd4fe54 100644 --- a/IoTGateway/Startup.cs +++ b/IoTGateway/Startup.cs @@ -74,8 +74,7 @@ namespace IoTGateway services.AddHostedService(); services.AddSingleton(); services.AddSingleton(); - //services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); } diff --git a/Plugins/Plugin/DeviceService.cs b/Plugins/Plugin/DeviceService.cs index b38a376..79ae94f 100644 --- a/Plugins/Plugin/DeviceService.cs +++ b/Plugins/Plugin/DeviceService.cs @@ -17,19 +17,18 @@ namespace Plugin public DriverService DrvierManager; public List DeviceThreads = new List(); - private readonly MyMqttClient _myMqttClient; - private readonly UAService _uAService; + private readonly MessageService _messageService; private readonly MqttServer _mqttServer; private readonly string _connnectSetting = IoTBackgroundService.connnectSetting; private readonly DBTypeEnum _dbType = IoTBackgroundService.DbType; //UAService? uAService, - public DeviceService(IConfiguration configRoot, DriverService drvierManager, MyMqttClient myMqttClient, + public DeviceService(IConfiguration configRoot, DriverService drvierManager, MessageService messageService, MqttServer mqttServer, ILogger logger) { _logger = logger; DrvierManager = drvierManager; - _myMqttClient = myMqttClient; + _messageService = messageService; //_uAService = uAService; _mqttServer = mqttServer ?? throw new ArgumentNullException(nameof(mqttServer)); @@ -152,7 +151,7 @@ namespace Plugin if (deviceObj != null && systemManage != null) { var deviceThread = new DeviceThread(device, deviceObj, systemManage.GatewayName, - _myMqttClient, + _messageService, _mqttServer, _logger); DeviceThreads.Add(deviceThread); } diff --git a/Plugins/Plugin/DeviceThread.cs b/Plugins/Plugin/DeviceThread.cs index 9e2b2a1..4bd178c 100644 --- a/Plugins/Plugin/DeviceThread.cs +++ b/Plugins/Plugin/DeviceThread.cs @@ -18,7 +18,7 @@ namespace Plugin public readonly Device Device; public readonly IDriver Driver; private readonly string _projectId; - private readonly MyMqttClient? _myMqttClient; + private readonly MessageService _messageService; private Interpreter? _interpreter; internal List? Methods { get; set; } private Task? _task; @@ -26,11 +26,11 @@ namespace Plugin private readonly CancellationTokenSource _tokenSource = new CancellationTokenSource(); private ManualResetEvent resetEvent = new(true); - public DeviceThread(Device device, IDriver driver, string projectId, MyMqttClient myMqttClient, + public DeviceThread(Device device, IDriver driver, string projectId, MessageService messageService, MqttServer mqttServer, ILogger logger) { - _myMqttClient = myMqttClient; - _myMqttClient.OnExcRpc += MyMqttClient_OnExcRpc; + _messageService = messageService; + _messageService.OnExcRpc += MyMqttClient_OnExcRpc; Device = device; Driver = driver; _projectId = projectId; @@ -64,7 +64,7 @@ namespace Plugin //上传客户端属性 foreach (var deviceVariables in Device.DeviceVariables!.GroupBy(x => x.Alias)) { - _myMqttClient.UploadAttributeAsync(string.IsNullOrWhiteSpace(deviceVariables.Key) + _messageService.UploadAttributeAsync(string.IsNullOrWhiteSpace(deviceVariables.Key) ? Device.DeviceName : deviceVariables.Key, Device.DeviceConfigs.Where(x => x.DataSide == DataSide.ClientSide || x.DataSide == DataSide.AnySide) @@ -101,7 +101,7 @@ namespace Plugin var triggerVariables = deviceVariables.Where(x => x.IsTrigger).ToList(); ReadVariables(ref triggerVariables, ref payLoadTrigger, _mqttServer); - var triggerValues = triggerVariables.ToDictionary(x=>x.Name,x=>x.CookedValue); + var triggerValues = triggerVariables.ToDictionary(x => x.Name, x => x.CookedValue); var payLoadUnTrigger = new PayLoad() { Values = new() }; @@ -126,13 +126,13 @@ namespace Plugin payLoad.TS = (long)(DateTime.UtcNow - _tsStartDt).TotalMilliseconds; payLoad.DeviceStatus = DeviceStatusTypeEnum.Good; sendModel[deviceName] = new List { payLoad }; - _myMqttClient + _messageService .PublishTelemetryAsync(deviceName, Device, sendModel).Wait(); } - + if (deviceVariables.Any(x => x.StatusType == VaribaleStatusTypeEnum.Bad)) - _myMqttClient?.DeviceDisconnected(deviceName, Device); + _messageService?.DeviceDisconnected(deviceName, Device); } } @@ -153,7 +153,7 @@ namespace Plugin ? Device.DeviceName : deviceVariables.Key; - _myMqttClient?.DeviceDisconnected(deviceName, Device); + _messageService?.DeviceDisconnected(deviceName, Device); } if (Driver.Connect()) @@ -164,7 +164,7 @@ namespace Plugin ? Device.DeviceName : deviceVariables.Key; - _myMqttClient?.DeviceConnected(deviceName, Device); + _messageService?.DeviceConnected(deviceName, Device); } } } @@ -246,7 +246,7 @@ namespace Plugin item.Message = ret.Message; //变化了才推送到mqttserver,用于前端展示 - if (JsonConvert.SerializeObject(item.Values[1]) != JsonConvert.SerializeObject(item.Values[0])|| JsonConvert.SerializeObject(item.CookedValues[1]) != JsonConvert.SerializeObject(item.CookedValues[0])) + if (JsonConvert.SerializeObject(item.Values[1]) != JsonConvert.SerializeObject(item.Values[0]) || JsonConvert.SerializeObject(item.CookedValues[1]) != JsonConvert.SerializeObject(item.CookedValues[0])) { var msgInternal = new InjectedMqttApplicationMessage( new MqttApplicationMessage() @@ -258,7 +258,7 @@ namespace Plugin }); mqttServer.InjectApplicationMessage(msgInternal); } - + Thread.Sleep((int)Device.CmdPeriod); } } @@ -301,7 +301,7 @@ namespace Plugin DeviceVariable? deviceVariable; if (e.DeviceName == Device.DeviceName) deviceVariable = Device.DeviceVariables.FirstOrDefault(x => - x.Name == para.Key ); + x.Name == para.Key); else deviceVariable = Device.DeviceVariables.FirstOrDefault(x => x.Name == para.Key && x.Alias == e.DeviceName); @@ -348,7 +348,7 @@ namespace Plugin } //反馈RPC - _myMqttClient.ResponseRpcAsync(rpcResponse).Wait(); + _messageService.ResponseRpcAsync(rpcResponse).Wait(); //纪录入库 rpcLog.IsSuccess = rpcResponse.IsSuccess; rpcLog.Description = rpcResponse.Description; @@ -371,12 +371,12 @@ namespace Plugin string deviceName = string.IsNullOrWhiteSpace(deviceVariables.Key) ? Device.DeviceName : deviceVariables.Key; - _myMqttClient?.DeviceDisconnected(deviceName, Device); + _messageService?.DeviceDisconnected(deviceName, Device); } } if (_task == null) return; - if (_myMqttClient != null) _myMqttClient.OnExcRpc -= MyMqttClient_OnExcRpc; + if (_messageService != null) _messageService.OnExcRpc -= MyMqttClient_OnExcRpc; _tokenSource.Cancel(); Driver.Close(); } diff --git a/Plugins/Plugin/MessageService.cs b/Plugins/Plugin/MessageService.cs new file mode 100644 index 0000000..6ea99fa --- /dev/null +++ b/Plugins/Plugin/MessageService.cs @@ -0,0 +1,294 @@ +using IoTGateway.Model; +using Microsoft.Extensions.Logging; +using MQTTnet.Extensions.ManagedClient; +using PluginInterface.IoTSharp; +using PluginInterface; +using IoTGateway.DataAccess; +using MQTTnet.Client; +using MQTTnet.Formatter; +using MQTTnet; +using MQTTnet.Protocol; +using Plugin.PlatformHandler; +using Newtonsoft.Json; +using Quartz.Logging; + +namespace Plugin +{ + public class MessageService + { + private readonly ILogger _logger; + private IPlatformHandler _platformHandler; + + private SystemConfig _systemConfig; + private ManagedMqttClientOptions _options; + public bool IsConnected => (Client.IsConnected); + private IManagedMqttClient? Client { get; set; } + public event EventHandler OnExcRpc; + public event EventHandler OnReceiveAttributes; + private readonly string _tbRpcTopic = "v1/gateway/rpc"; + public MessageService(ILogger logger) + { + _logger = logger; + + StartClientAsync().Wait(); + + } + + public async Task StartClientAsync() + { + try + { + if (Client != null) + { + Client.Dispose(); + } + Client = new MqttFactory().CreateManagedMqttClient(); + await using var dc = new DataContext(IoTBackgroundService.connnectSetting, IoTBackgroundService.DbType); + _systemConfig = dc.Set().First(); + + #region ClientOptions + + _options = new ManagedMqttClientOptionsBuilder() + .WithAutoReconnectDelay(TimeSpan.FromSeconds(5)) + .WithMaxPendingMessages(100000) + .WithClientOptions(new MqttClientOptionsBuilder() + .WithClientId(string.IsNullOrEmpty(_systemConfig.ClientId) + ? Guid.NewGuid().ToString() + : _systemConfig.ClientId) + .WithTcpServer(_systemConfig.MqttIp, _systemConfig.MqttPort) + .WithCredentials(_systemConfig.MqttUName, _systemConfig.MqttUPwd) + .WithTimeout(TimeSpan.FromSeconds(30)) + .WithKeepAlivePeriod(TimeSpan.FromSeconds(60)) + .WithProtocolVersion(MqttProtocolVersion.V311) + .WithCleanSession(true) + .Build()) + .Build(); + #endregion + + Client.ConnectedAsync += Client_ConnectedAsync; + Client.DisconnectedAsync += Client_DisconnectedAsync; + Client.ApplicationMessageReceivedAsync += Client_ApplicationMessageReceivedAsync; + + await Client.StartAsync(_options); + + // 使用工厂模式创建对应平台的处理器 + _platformHandler = PlatformHandlerFactory.CreateHandler(_systemConfig.IoTPlatformType, Client, _logger, OnExcRpc); + + _logger.LogInformation("MQTT WAITING FOR APPLICATION MESSAGES"); + + } + catch (Exception ex) + { + _logger.LogError(ex, $"StartManagedClientAsync FAILED "); + } + } + + public async Task Client_ConnectedAsync(MqttClientConnectedEventArgs arg) + { + _logger.LogInformation($"MQTT CONNECTED WITH SERVER "); + #region Topics + try + { + switch (_systemConfig.IoTPlatformType) + { + case IoTPlatformType.ThingsBoard: + //{"device": "Device A", "data": {"id": $request_id, "method": "toggle_gpio", "params": {"pin":1}}} + await Client.SubscribeAsync(_tbRpcTopic, MqttQualityOfServiceLevel.ExactlyOnce); + //Message: {"id": $request_id, "device": "Device A", "value": "value1"} + await Client.SubscribeAsync("v1/gateway/attributes/response", MqttQualityOfServiceLevel.ExactlyOnce); + //Message: {"device": "Device A", "data": {"attribute1": "value1", "attribute2": 42}} + await Client.SubscribeAsync("v1/gateway/attributes", MqttQualityOfServiceLevel.ExactlyOnce); + break; + case IoTPlatformType.IoTSharp: + case IoTPlatformType.IoTGateway: + await Client.SubscribeAsync("devices/+/rpc/request/+/+", MqttQualityOfServiceLevel.ExactlyOnce); + await Client.SubscribeAsync("devices/+/attributes/update", MqttQualityOfServiceLevel.ExactlyOnce); + //Message: {"device": "Device A", "data": {"attribute1": "value1", "attribute2": 42}} + await Client.SubscribeAsync("devices/+/attributes/response/+", MqttQualityOfServiceLevel.ExactlyOnce); + break; + case IoTPlatformType.ThingsCloud: + await Client.SubscribeAsync("gateway/attributes/response", MqttQualityOfServiceLevel.ExactlyOnce); + await Client.SubscribeAsync("gateway/attributes/get/response", MqttQualityOfServiceLevel.ExactlyOnce); + await Client.SubscribeAsync("gateway/attributes/push", MqttQualityOfServiceLevel.ExactlyOnce); + await Client.SubscribeAsync("gateway/event/response", MqttQualityOfServiceLevel.ExactlyOnce); + await Client.SubscribeAsync("gateway/command/send", MqttQualityOfServiceLevel.ExactlyOnce); + break; + case IoTPlatformType.AliCloudIoT: + break; + case IoTPlatformType.TencentIoTHub: + break; + case IoTPlatformType.BaiduIoTCore: + break; + case IoTPlatformType.OneNET: + break; + } + } + catch (Exception ex) + { + _logger.LogError(ex, "MQTT Subscribe FAILED"); + } + #endregion + } + + public async Task Client_DisconnectedAsync(MqttClientDisconnectedEventArgs arg) + { + try + { + _logger.LogError($"MQTT DISCONNECTED WITH SERVER "); + await Task.CompletedTask; + } + catch (Exception ex) + { + _logger.LogError(ex, "MQTT CONNECTING FAILED"); + } + } + + public Task Client_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs e) + { + _logger.LogDebug( + $"ApplicationMessageReceived Topic {e.ApplicationMessage.Topic} QualityOfServiceLevel:{e.ApplicationMessage.QualityOfServiceLevel} Retain:{e.ApplicationMessage.Retain} "); + try + { + _platformHandler.ReceiveRpc(e); + } + catch (Exception ex) + { + _logger.LogError( + ex, $"ClientId:{e.ClientId} Topic:{e.ApplicationMessage.Topic},Payload:{e.ApplicationMessage.ConvertPayloadToString()}"); + } + + return Task.CompletedTask; + } + + public async Task PublishTelemetryAsync(string deviceName, Device device, + Dictionary> sendModel) + { + if (CanPubTelemetry(deviceName, device, sendModel)) + { + await _platformHandler.PublishTelemetryAsync(deviceName, device, sendModel); + } + } + + public async Task UploadAttributeAsync(string deviceName, object obj) + { + await _platformHandler.UploadAttributeAsync(deviceName, obj); + } + + public async Task DeviceConnected(string deviceName, Device device) + { + try + { + await _platformHandler.DeviceConnected(deviceName, device); + } + catch (Exception ex) + { + _logger.LogError(ex, $"DeviceConnected:{deviceName}"); + } + } + + public async Task DeviceDisconnected(string deviceName, Device device) + { + try + { + await _platformHandler.DeviceDisconnected(deviceName, device); + } + catch (Exception ex) + { + _logger.LogError(ex, $"DeviceDisconnected:{deviceName}"); + } + } + + public async Task ResponseRpcAsync(RpcResponse rpcResponse) + { + try + { + await _platformHandler.ResponseRpcAsync(rpcResponse); + } + catch (Exception ex) + { + _logger.LogError(ex, $"ResponseRpc Error,{rpcResponse}"); + } + } + + public async Task RequestAttributes(string deviceName, bool anySide, params string[] args) + { + + await _platformHandler.RequestAttributes(deviceName, anySide, args); + } + + + public async Task DeviceAdded(Device device) + { + try + { + await _platformHandler.DeviceAdded(device); + } + catch (Exception ex) + { + _logger.LogError(ex, $"DeviceAdded:{device.DeviceName}"); + } + } + + public async Task DeviceDeleted(Device device) + { + try + { + await _platformHandler.DeviceDeleted(device); + } + catch (Exception ex) + { + _logger.LogError(ex, $"DeviceAdded:{device.DeviceName}"); + } + } + + + private Dictionary> _lastTelemetrys = new(0); + + /// + /// 判断是否推送遥测数据 + /// + /// + /// 设备 + /// 遥测 + /// + private bool CanPubTelemetry(string deviceName, Device device, Dictionary> sendModel) + { + bool canPub = false; + try + {//第一次上传 + if (!_lastTelemetrys.ContainsKey(deviceName)) + canPub = true; + else + { + //变化上传 + if (device.CgUpload) + { + //是否超过归档周期 + if (sendModel[deviceName][0].TS - _lastTelemetrys[deviceName][0].TS > + device.EnforcePeriod) + canPub = true; + //是否变化 这里不好先用 + else + { + if (JsonConvert.SerializeObject(sendModel[deviceName][0].Values) != + JsonConvert.SerializeObject(_lastTelemetrys[deviceName][0].Values)) + canPub = true; + } + } + //非变化上传 + else + canPub = true; + } + } + catch (Exception e) + { + canPub = true; + Console.WriteLine(e); + } + + if (canPub) + _lastTelemetrys[deviceName] = sendModel[deviceName]; + return canPub; + } + } +} diff --git a/Plugins/Plugin/MyMqttClient.cs b/Plugins/Plugin/MyMqttClient.cs deleted file mode 100644 index 93348e2..0000000 --- a/Plugins/Plugin/MyMqttClient.cs +++ /dev/null @@ -1,774 +0,0 @@ -using MQTTnet; -using MQTTnet.Client; -using Newtonsoft.Json; -using PluginInterface; -using IoTGateway.Model; -using MQTTnet.Protocol; -using MQTTnet.Formatter; -using IoTGateway.DataAccess; -using PluginInterface.IoTSharp; -using PluginInterface.HuaWeiRoma; -using PluginInterface.ThingsBoard; -using Microsoft.Extensions.Logging; -using MQTTnet.Extensions.ManagedClient; - -namespace Plugin -{ - public class MyMqttClient - { - private readonly ILogger _logger; - //private readonly ReferenceNodeManager? _uaNodeManager; - - private SystemConfig _systemConfig; - private ManagedMqttClientOptions _options; - public bool IsConnected => (Client.IsConnected); - private IManagedMqttClient? Client { get; set; } - public event EventHandler OnExcRpc; - public event EventHandler OnReceiveAttributes; - private readonly string _tbRpcTopic = "v1/gateway/rpc"; - - //UAService uaService, - public MyMqttClient(ILogger logger) - { - _logger = logger; - //_uaNodeManager = uaService.server.m_server.nodeManagers[0] as ReferenceNodeManager; - - StartClientAsync().Wait(); - } - - public async Task StartClientAsync() - { - try - { - if (Client != null) - { - Client.Dispose(); - } - Client = new MqttFactory().CreateManagedMqttClient(); - await using var dc = new DataContext(IoTBackgroundService.connnectSetting, IoTBackgroundService.DbType); - _systemConfig = dc.Set().First(); - - #region ClientOptions - - _options = new ManagedMqttClientOptionsBuilder() - .WithAutoReconnectDelay(TimeSpan.FromSeconds(5)) - .WithMaxPendingMessages(100000) - .WithClientOptions(new MqttClientOptionsBuilder() - .WithClientId(string.IsNullOrEmpty(_systemConfig.ClientId) - ? Guid.NewGuid().ToString() - : _systemConfig.ClientId) - .WithTcpServer(_systemConfig.MqttIp, _systemConfig.MqttPort) - .WithCredentials(_systemConfig.MqttUName, _systemConfig.MqttUPwd) - .WithTimeout(TimeSpan.FromSeconds(30)) - .WithKeepAlivePeriod(TimeSpan.FromSeconds(60)) - .WithProtocolVersion(MqttProtocolVersion.V311) - .WithCleanSession(true) - .Build()) - .Build(); - #endregion - - Client.ConnectedAsync += Client_ConnectedAsync; - Client.DisconnectedAsync += Client_DisconnectedAsync; - Client.ApplicationMessageReceivedAsync += Client_ApplicationMessageReceivedAsync; - - await Client.StartAsync(_options); - - _logger.LogInformation("MQTT WAITING FOR APPLICATION MESSAGES"); - - } - catch (Exception ex) - { - _logger.LogError(ex, $"StartManagedClientAsync FAILED "); - } - } - - private async Task Client_ConnectedAsync(MqttClientConnectedEventArgs arg) - { - _logger.LogInformation($"MQTT CONNECTED WITH SERVER "); - #region Topics - try - { - switch (_systemConfig.IoTPlatformType) - { - case IoTPlatformType.ThingsBoard: - //{"device": "Device A", "data": {"id": $request_id, "method": "toggle_gpio", "params": {"pin":1}}} - await Client.SubscribeAsync(_tbRpcTopic, MqttQualityOfServiceLevel.ExactlyOnce); - //Message: {"id": $request_id, "device": "Device A", "value": "value1"} - await Client.SubscribeAsync("v1/gateway/attributes/response", MqttQualityOfServiceLevel.ExactlyOnce); - //Message: {"device": "Device A", "data": {"attribute1": "value1", "attribute2": 42}} - await Client.SubscribeAsync("v1/gateway/attributes", MqttQualityOfServiceLevel.ExactlyOnce); - break; - case IoTPlatformType.IoTSharp: - case IoTPlatformType.IoTGateway: - await Client.SubscribeAsync("devices/+/rpc/request/+/+", MqttQualityOfServiceLevel.ExactlyOnce); - await Client.SubscribeAsync("devices/+/attributes/update", MqttQualityOfServiceLevel.ExactlyOnce); - //Message: {"device": "Device A", "data": {"attribute1": "value1", "attribute2": 42}} - await Client.SubscribeAsync("devices/+/attributes/response/+", MqttQualityOfServiceLevel.ExactlyOnce); - break; - case IoTPlatformType.ThingsCloud: - await Client.SubscribeAsync("gateway/attributes/response", MqttQualityOfServiceLevel.ExactlyOnce); - await Client.SubscribeAsync("gateway/attributes/get/response", MqttQualityOfServiceLevel.ExactlyOnce); - await Client.SubscribeAsync("gateway/attributes/push", MqttQualityOfServiceLevel.ExactlyOnce); - await Client.SubscribeAsync("gateway/event/response", MqttQualityOfServiceLevel.ExactlyOnce); - await Client.SubscribeAsync("gateway/command/send", MqttQualityOfServiceLevel.ExactlyOnce); - break; - case IoTPlatformType.AliCloudIoT: - break; - case IoTPlatformType.TencentIoTHub: - break; - case IoTPlatformType.BaiduIoTCore: - break; - case IoTPlatformType.OneNET: - break; - } - } - catch (Exception ex) - { - _logger.LogError(ex, "MQTT Subscribe FAILED"); - } - #endregion - } - - private async Task Client_DisconnectedAsync(MqttClientDisconnectedEventArgs arg) - { - try - { - _logger.LogError($"MQTT DISCONNECTED WITH SERVER "); - //await Client.ConnectAsync(_options); - } - catch (Exception ex) - { - _logger.LogError(ex, "MQTT CONNECTING FAILED"); - } - } - - private Task Client_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs e) - { - _logger.LogDebug( - $"ApplicationMessageReceived Topic {e.ApplicationMessage.Topic} QualityOfServiceLevel:{e.ApplicationMessage.QualityOfServiceLevel} Retain:{e.ApplicationMessage.Retain} "); - try - { - if (e.ApplicationMessage.Topic == _tbRpcTopic) - ReceiveTbRpc(e); - else if (e.ApplicationMessage.Topic.StartsWith($"devices/") && - e.ApplicationMessage.Topic.Contains("/response/")) - { - ReceiveAttributes(e); - } - else if (e.ApplicationMessage.Topic.StartsWith($"devices/") && - e.ApplicationMessage.Topic.Contains("/rpc/request/")) - { - ReceiveIsRpc(e); - } - else if (e.ApplicationMessage.Topic == "gateway/command/send") - { - ReceiveTcRpc(e); - } - } - catch (Exception ex) - { - _logger.LogError( - ex, $"ClientId:{e.ClientId} Topic:{e.ApplicationMessage.Topic},Payload:{e.ApplicationMessage.ConvertPayloadToString()}"); - } - - return Task.CompletedTask; - } - - /// - /// thingsboard rpc - /// - /// - private void ReceiveTbRpc(MqttApplicationMessageReceivedEventArgs e) - { - try - { - var tBRpcRequest = - JsonConvert.DeserializeObject(e.ApplicationMessage.ConvertPayloadToString()); - if (tBRpcRequest != null && !string.IsNullOrWhiteSpace(tBRpcRequest.RequestData.Method)) - { - OnExcRpc(Client, new RpcRequest() - { - Method = tBRpcRequest.RequestData.Method, - DeviceName = tBRpcRequest.DeviceName, - RequestId = tBRpcRequest.RequestData.RequestId, - Params = tBRpcRequest.RequestData.Params - }); - } - } - catch (Exception ex) - { - _logger.LogError(ex, - $"ReceiveTbRpc:Topic:{e.ApplicationMessage.Topic},Payload:{e.ApplicationMessage.ConvertPayloadToString()}"); - } - } - - /// - /// thingscloud rpc - /// - /// - private void ReceiveTcRpc(MqttApplicationMessageReceivedEventArgs e) - { - try - { - var tCRpcRequest = - JsonConvert.DeserializeObject(e.ApplicationMessage.ConvertPayloadToString()); - if (tCRpcRequest != null) - OnExcRpc.Invoke(Client, new RpcRequest() - { - Method = tCRpcRequest.RequestData.Method, - DeviceName = tCRpcRequest.DeviceName, - RequestId = tCRpcRequest.RequestData.RequestId, - Params = tCRpcRequest.RequestData.Params - }); - } - catch (Exception ex) - { - _logger.LogError(ex, - $"ReceiveTbRpc:Topic:{e.ApplicationMessage.Topic},Payload:{e.ApplicationMessage.ConvertPayloadToString()}"); - } - } - - private void ReceiveIsRpc(MqttApplicationMessageReceivedEventArgs e) - { - try - { - var tps = e.ApplicationMessage.Topic.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); - var rpcMethodName = tps[4]; - var rpcDeviceName = tps[1]; - var rpcRequestId = tps[5]; - _logger.LogInformation($"rpcMethodName={rpcMethodName} "); - _logger.LogInformation($"rpcDeviceName={rpcDeviceName} "); - _logger.LogInformation($"rpcRequestId={rpcRequestId} "); - if (!string.IsNullOrEmpty(rpcMethodName) && !string.IsNullOrEmpty(rpcDeviceName) && - !string.IsNullOrEmpty(rpcRequestId)) - { - Task.Run(() => - { - OnExcRpc(Client, new RpcRequest() - { - Method = rpcMethodName, - DeviceName = rpcDeviceName, - RequestId = rpcRequestId, - Params = JsonConvert.DeserializeObject>(e.ApplicationMessage - .ConvertPayloadToString()) - }); - }); - } - } - catch (Exception ex) - { - _logger.LogError(ex, - $"ReceiveIsRpc:Topic:{e.ApplicationMessage.Topic},Payload:{e.ApplicationMessage.ConvertPayloadToString()}"); - } - } - - private async Task ResponseTbRpcAsync(TBRpcResponse tBRpcResponse) - { - await Client.EnqueueAsync(new MqttApplicationMessageBuilder() - .WithTopic(_tbRpcTopic) - .WithPayload(JsonConvert.SerializeObject(tBRpcResponse)) - .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce).Build()); - } - - private async Task ResponseTcRpcAsync(TCRpcRequest tCRpcResponse) - { - var topic = $"command/reply/{tCRpcResponse.RequestData.RequestId}"; - await Client.EnqueueAsync(new MqttApplicationMessageBuilder() - .WithTopic(topic) - .WithPayload(JsonConvert.SerializeObject(tCRpcResponse)) - .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); - } - - private async Task ResponseIsRpcAsync(ISRpcResponse rpcResult) - { - //var responseTopic = $"/devices/{deviceid}/rpc/response/{methodName}/{rpcid}"; - var topic = $"devices/{rpcResult.DeviceId}/rpc/response/{rpcResult.Method}/{rpcResult.ResponseId}"; - await Client.EnqueueAsync(new MqttApplicationMessageBuilder() - .WithTopic(topic) - .WithPayload(JsonConvert.SerializeObject(rpcResult)) - .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); - } - - private void ReceiveAttributes(MqttApplicationMessageReceivedEventArgs e) - { - var tps = e.ApplicationMessage.Topic.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); - var rpcMethodName = tps[2]; - var rpcDeviceName = tps[1]; - var rpcRequestId = tps[4]; - _logger.LogInformation($"rpcMethodName={rpcMethodName}"); - _logger.LogInformation($"rpcDeviceName={rpcDeviceName}"); - _logger.LogInformation($"rpcRequestId={rpcRequestId}"); - - if (!string.IsNullOrEmpty(rpcMethodName) && !string.IsNullOrEmpty(rpcDeviceName) && - !string.IsNullOrEmpty(rpcRequestId)) - { - if (e.ApplicationMessage.Topic.Contains("/attributes/")) - { - OnReceiveAttributes.Invoke(Client, new ISAttributeResponse() - { - KeyName = rpcMethodName, - DeviceName = rpcDeviceName, - Id = rpcRequestId, - Data = e.ApplicationMessage.ConvertPayloadToString() - }); - } - } - } - - public Task UploadAttributeAsync(string deviceName, object obj) - { - //Topic: v1/gateway/attributes - //Message: {"Device A":{"attribute1":"value1", "attribute2": 42}, "Device B":{"attribute1":"value1", "attribute2": 42} - try - { - return Client.EnqueueAsync(new MqttApplicationMessageBuilder() - .WithTopic($"devices/{deviceName}/attributes").WithPayload(JsonConvert.SerializeObject(obj)) - .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce) - .Build()); - } - catch (Exception ex) - { - _logger.LogError(ex, $"Device:{deviceName} UploadAttributeAsync Failed"); - } - - return Task.CompletedTask; - } - - public async Task UploadIsTelemetryDataAsync(string deviceName, object obj) - { - await Client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic($"devices/{deviceName}/telemetry") - .WithPayload(JsonConvert.SerializeObject(obj)).Build()); - } - - public async Task UploadTcTelemetryDataAsync(string deviceName, object obj) - { - var toSend = new Dictionary { { deviceName, obj } }; - await Client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic($"gateway/attributes") - .WithPayload(JsonConvert.SerializeObject(toSend)).WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); - } - - public async Task UploadHwTelemetryDataAsync(Device device, object obj) - { - var hwTelemetry = new List() - { - new HwTelemetry() - { - DeviceId = device.DeviceConfigs.FirstOrDefault(x => x.DeviceConfigName == "DeviceId")?.Value, - Services = new() - { - new Service() - { - ServiceId = "serviceId", - EventTime = DateTime.Now.ToString("yyyyMMddTHHmmssZ"), - Data = obj - } - } - } - }; - var hwTelemetrys = new HwTelemetrys() - { - Devices = hwTelemetry - }; - - await Client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic($"/v1/devices/{_systemConfig.GatewayName}/datas") - .WithPayload(JsonConvert.SerializeObject(hwTelemetrys)).WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); - } - - public async Task ResponseRpcAsync(RpcResponse rpcResponse) - { - try - { - switch (_systemConfig.IoTPlatformType) - { - case IoTPlatformType.ThingsBoard: - var tRpcResponse = new TBRpcResponse - { - DeviceName = rpcResponse.DeviceName, - RequestId = rpcResponse.RequestId, - ResponseData = new Dictionary - { { "success", rpcResponse.IsSuccess }, { "description", rpcResponse.Description } } - }; - await ResponseTbRpcAsync(tRpcResponse); - break; - case IoTPlatformType.IoTSharp: - case IoTPlatformType.IoTGateway: - await ResponseIsRpcAsync(new ISRpcResponse - { - DeviceId = rpcResponse.DeviceName, - Method = rpcResponse.Method, - ResponseId = rpcResponse.RequestId, - Data = JsonConvert.SerializeObject(new Dictionary - { - { "success", rpcResponse.IsSuccess }, { "description", rpcResponse.Description } - }) - }); - break; - case IoTPlatformType.ThingsCloud: - //官网API不需要回复的 - break; - case IoTPlatformType.AliCloudIoT: - break; - case IoTPlatformType.TencentIoTHub: - break; - case IoTPlatformType.BaiduIoTCore: - break; - case IoTPlatformType.OneNET: - break; - } - } - catch (Exception ex) - { - _logger.LogError(ex, $"ResponseRpc Error,{rpcResponse}"); - } - } - - public async Task RequestAttributes(string deviceName, bool anySide, params string[] args) - { - try - { - string id = Guid.NewGuid().ToString(); - switch (_systemConfig.IoTPlatformType) - { - case IoTPlatformType.ThingsBoard: - //{"id": $request_id, "device": "Device A", "client": true, "key": "attribute1"} - Dictionary tbRequestData = new Dictionary - { - { "id", id }, - { "device", deviceName }, - { "client", true }, - { "key", args[0] } - }; - await Client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic($"v1/gateway/attributes/request") - .WithPayload(JsonConvert.SerializeObject(tbRequestData)).WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); - break; - case IoTPlatformType.IoTSharp: - case IoTPlatformType.IoTGateway: - string topic = $"devices/{deviceName}/attributes/request/{id}"; - Dictionary keys = new Dictionary(); - keys.Add(anySide ? "anySide" : "server", string.Join(",", args)); - await Client.SubscribeAsync($"devices/{deviceName}/attributes/response/{id}", - MqttQualityOfServiceLevel.ExactlyOnce); - await Client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic(topic) - .WithPayload(JsonConvert.SerializeObject(keys)) - .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); - break; - case IoTPlatformType.AliCloudIoT: - break; - case IoTPlatformType.TencentIoTHub: - break; - case IoTPlatformType.BaiduIoTCore: - break; - case IoTPlatformType.OneNET: - break; - } - } - catch (Exception ex) - { - _logger.LogError(ex, $"RequestAttributes:{deviceName}"); - } - } - - private Dictionary> _lastTelemetrys = new(0); - - /// - /// 判断是否推送遥测数据 - /// - /// 设备 - /// 遥测 - /// - private bool CanPubTelemetry(string DeviceName, Device device, Dictionary> sendModel) - { - bool canPub = false; - try - {//第一次上传 - if (!_lastTelemetrys.ContainsKey(DeviceName)) - canPub = true; - else - { - //变化上传 - if (device.CgUpload) - { - //是否超过归档周期 - if (sendModel[DeviceName][0].TS - _lastTelemetrys[DeviceName][0].TS > - device.EnforcePeriod) - canPub = true; - //是否变化 这里不好先用 - else - { - if (JsonConvert.SerializeObject(sendModel[DeviceName][0].Values) != - JsonConvert.SerializeObject(_lastTelemetrys[DeviceName][0].Values)) - canPub = true; - } - } - //非变化上传 - else - canPub = true; - } - } - catch (Exception e) - { - canPub = true; - Console.WriteLine(e); - } - - if (canPub) - _lastTelemetrys[DeviceName] = sendModel[DeviceName]; - return canPub; - } - - public async Task PublishTelemetryAsync(string deviceName, Device device, Dictionary> sendModel) - { - try - { - if (CanPubTelemetry(deviceName, device, sendModel)) - { - switch (_systemConfig.IoTPlatformType) - { - case IoTPlatformType.ThingsBoard: - await Client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic("v1/gateway/telemetry") - .WithPayload(JsonConvert.SerializeObject(sendModel)) - .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce).Build()); - break; - case IoTPlatformType.IoTSharp: - case IoTPlatformType.IoTGateway: - foreach (var payload in sendModel[deviceName]) - { - if (payload.Values != null) - { - if (_systemConfig.IoTPlatformType == IoTPlatformType.IoTGateway) - payload.Values["_ts_"] = (long)(DateTime.UtcNow - _tsStartDt).TotalMilliseconds; - await UploadIsTelemetryDataAsync(deviceName, payload.Values); - } - } - - break; - case IoTPlatformType.ThingsCloud: - foreach (var payload in sendModel[deviceName]) - { - if (payload.Values != null) - await UploadTcTelemetryDataAsync(deviceName, payload.Values); - } - - break; - case IoTPlatformType.HuaWei: - foreach (var payload in sendModel[deviceName]) - { - if (payload.Values != null) - await UploadHwTelemetryDataAsync(device, payload.Values); - } - - break; - - case IoTPlatformType.AliCloudIoT: - case IoTPlatformType.TencentIoTHub: - case IoTPlatformType.BaiduIoTCore: - case IoTPlatformType.OneNET: - default: - break; - } - } - - //foreach (var payload in sendModel[deviceName]) - //{ - // if (payload.Values != null) - // foreach (var kv in payload.Values) - // { - // //更新到UAService - // _uaNodeManager?.UpdateNode($"{device.Parent.DeviceName}.{deviceName}.{kv.Key}", - // kv.Value); - // } - //} - } - catch (Exception ex) - { - _logger.LogError(ex, $"PublishTelemetryAsync Error"); - } - } - - private readonly DateTime _tsStartDt = new(1970, 1, 1); - - public async Task DeviceConnected(string DeviceName, Device device) - { - try - { - switch (_systemConfig.IoTPlatformType) - { - case IoTPlatformType.ThingsBoard: - case IoTPlatformType.IoTSharp: - case IoTPlatformType.IoTGateway: - await Client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic("v1/gateway/connect") - .WithPayload(JsonConvert.SerializeObject(new Dictionary - { { "device", DeviceName } })) - .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce).Build()); - break; - case IoTPlatformType.AliCloudIoT: - break; - case IoTPlatformType.TencentIoTHub: - break; - case IoTPlatformType.BaiduIoTCore: - break; - case IoTPlatformType.OneNET: - break; - case IoTPlatformType.ThingsCloud: - await Client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic("gateway/connect") - .WithPayload(JsonConvert.SerializeObject(new Dictionary - { { "device", DeviceName } })) - .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); - break; - case IoTPlatformType.HuaWei: - var deviceOnLine = new HwDeviceOnOffLine() - { - MId = new Random().Next(0, 1024), //命令ID - DeviceStatuses = new List() - { - new DeviceStatus() - { - DeviceId = device.DeviceConfigs - .FirstOrDefault(x => x.DeviceConfigName == "DeviceId") - ?.Value, - Status = "ONLINE" - } - } - }; - await Client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic($"/v1/devices/{_systemConfig.GatewayName}/topo/update") - .WithPayload(JsonConvert.SerializeObject(deviceOnLine)) - .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); - break; - } - } - catch (Exception ex) - { - _logger.LogError(ex, $"DeviceConnected:{DeviceName}"); - } - } - - public async Task DeviceDisconnected(string DeviceName, Device device) - { - try - { - switch (_systemConfig.IoTPlatformType) - { - case IoTPlatformType.ThingsBoard: - case IoTPlatformType.IoTSharp: - case IoTPlatformType.IoTGateway: - await Client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic($"v1/gateway/disconnect") - .WithPayload(JsonConvert.SerializeObject(new Dictionary - { { "device", DeviceName } })) - .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce).Build()); - break; - case IoTPlatformType.AliCloudIoT: - break; - case IoTPlatformType.TencentIoTHub: - break; - case IoTPlatformType.BaiduIoTCore: - break; - case IoTPlatformType.OneNET: - break; - case IoTPlatformType.ThingsCloud: - await Client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic($"gateway/disconnect") - .WithPayload(JsonConvert.SerializeObject(new Dictionary - { { "device", DeviceName } })) - .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); - break; - case IoTPlatformType.HuaWei: - var deviceOnLine = new HwDeviceOnOffLine() - { - MId = new Random().Next(0, 1024), //命令ID - DeviceStatuses = new List() - { - new DeviceStatus() - { - DeviceId = device.DeviceConfigs - .FirstOrDefault(x => x.DeviceConfigName == "DeviceId") - ?.Value, - Status = "OFFLINE" - } - } - }; - await Client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic($"/v1/devices/{_systemConfig.GatewayName}/topo/update") - .WithPayload(JsonConvert.SerializeObject(deviceOnLine)) - .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); - break; - } - } - catch (Exception ex) - { - _logger.LogError(ex, $"DeviceDisconnected:{DeviceName}"); - } - } - - public async Task DeviceAdded(Device device) - { - try - { - switch (_systemConfig.IoTPlatformType) - { - case IoTPlatformType.HuaWei: - var topic = $"/v1/devices/{_systemConfig.GatewayName}/topo/add"; - - var addDeviceDto = new HwAddDeviceDto - { - MId = new Random().Next(0, 1024), //命令ID - }; - addDeviceDto.DeviceInfos.Add( - new DeviceInfo - { - NodeId = device.DeviceName, - Name = device.DeviceName, - Description = device.Description, - ManufacturerId = "Test_n", - ProductType = "A_n" - } - ); - await Client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic(topic) - .WithPayload(JsonConvert.SerializeObject(addDeviceDto)) - .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); - break; - } - } - catch (Exception ex) - { - _logger.LogError(ex, $"DeviceAdded:{device.DeviceName}"); - } - } - - public async Task DeviceDeleted(Device device) - { - try - { - switch (_systemConfig.IoTPlatformType) - { - case IoTPlatformType.HuaWei: - var topic = $"/v1/devices/{_systemConfig.GatewayName}/topo/delete"; - - await using (var dc = new DataContext(IoTBackgroundService.connnectSetting, IoTBackgroundService.DbType)) - { - var deviceId = dc.Set().FirstOrDefault(x => - x.DeviceId == device.ID && x.DeviceConfigName == "DeviceId")?.Value; - - var deleteDeviceDto = new HwDeleteDeviceDto - { - Id = new Random().Next(0, 1024), //命令ID - DeviceId = deviceId, - RequestTime = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds, - Request = new() - { - ManufacturerId = "Test_n", - ManufacturerName = "Test_n", - ProductType = "A_n" - } - }; - await Client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic(topic) - .WithPayload(JsonConvert.SerializeObject(deleteDeviceDto)) - .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); - } - break; - } - } - catch (Exception ex) - { - _logger.LogError(ex, $"DeviceAdded:{device.DeviceName}"); - } - } - } -} \ No newline at end of file diff --git a/Plugins/Plugin/PlatformHandler/IPlatformHandler.cs b/Plugins/Plugin/PlatformHandler/IPlatformHandler.cs new file mode 100644 index 0000000..1e5d573 --- /dev/null +++ b/Plugins/Plugin/PlatformHandler/IPlatformHandler.cs @@ -0,0 +1,27 @@ +using MQTTnet.Client; +using Microsoft.Extensions.Logging; +using MQTTnet.Extensions.ManagedClient; +using PluginInterface; +using IoTGateway.Model; + +namespace Plugin.PlatformHandler +{ + public interface IPlatformHandler + { + IManagedMqttClient MqttClient { get; } + ILogger Logger { get; } + + public event EventHandler OnExcRpc; + + Task ClientConnected(); + void ReceiveRpc(MqttApplicationMessageReceivedEventArgs e); + Task ResponseRpcAsync(RpcResponse rpcResponse); + Task PublishTelemetryAsync(string deviceName, Device device, Dictionary> sendModel); + Task UploadAttributeAsync(string deviceName, object obj); + Task RequestAttributes(string deviceName, bool anySide, params string[] args); + Task DeviceConnected(string deviceName, Device device); + Task DeviceDisconnected(string deviceName, Device device); + Task DeviceAdded(Device device); + Task DeviceDeleted(Device device); + } +} diff --git a/Plugins/Plugin/PlatformHandler/IoTSharpHandler.cs b/Plugins/Plugin/PlatformHandler/IoTSharpHandler.cs new file mode 100644 index 0000000..b83d853 --- /dev/null +++ b/Plugins/Plugin/PlatformHandler/IoTSharpHandler.cs @@ -0,0 +1,150 @@ +using IoTGateway.Model; +using Microsoft.Extensions.Logging; +using MQTTnet; +using MQTTnet.Client; +using MQTTnet.Extensions.ManagedClient; +using MQTTnet.Protocol; +using Newtonsoft.Json; +using PluginInterface; +using PluginInterface.IoTSharp; + +namespace Plugin.PlatformHandler +{ + public class IoTSharpHandler : IPlatformHandler + { + public IManagedMqttClient MqttClient { get; } + public ILogger Logger { get; } + + public event EventHandler OnExcRpc; + private readonly DateTime _tsStartDt = new(1970, 1, 1); + + public IoTSharpHandler(IManagedMqttClient mqttClient, ILogger logger, EventHandler onExcRpc) + { + MqttClient = mqttClient; + Logger = logger; + OnExcRpc = onExcRpc; + } + + + public async Task ClientConnected() + { + await MqttClient.SubscribeAsync("devices/+/rpc/request/+/+", MqttQualityOfServiceLevel.ExactlyOnce); + await MqttClient.SubscribeAsync("devices/+/attributes/update", MqttQualityOfServiceLevel.ExactlyOnce); + //Message: {"device": "Device A", "data": {"attribute1": "value1", "attribute2": 42}} + await MqttClient.SubscribeAsync("devices/+/attributes/response/+", MqttQualityOfServiceLevel.ExactlyOnce); + } + public void ReceiveRpc(MqttApplicationMessageReceivedEventArgs e) + { + try + { + var tps = e.ApplicationMessage.Topic.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + var rpcMethodName = tps[4]; + var rpcDeviceName = tps[1]; + var rpcRequestId = tps[5]; + Logger.LogInformation($"rpcMethodName={rpcMethodName} "); + Logger.LogInformation($"rpcDeviceName={rpcDeviceName} "); + Logger.LogInformation($"rpcRequestId={rpcRequestId} "); + if (!string.IsNullOrEmpty(rpcMethodName) && !string.IsNullOrEmpty(rpcDeviceName) && + !string.IsNullOrEmpty(rpcRequestId)) + { + Task.Run(() => + { + OnExcRpc(MqttClient, new RpcRequest() + { + Method = rpcMethodName, + DeviceName = rpcDeviceName, + RequestId = rpcRequestId, + Params = JsonConvert.DeserializeObject>(e.ApplicationMessage + .ConvertPayloadToString()) + }); + }); + } + } + catch (Exception ex) + { + Logger.LogError(ex, + $"ReceiveIsRpc:Topic:{e.ApplicationMessage.Topic},Payload:{e.ApplicationMessage.ConvertPayloadToString()}"); + } + } + + public async Task ResponseRpcAsync(RpcResponse rpcResponse) + { + var rpcResult = new ISRpcResponse + { + DeviceId = rpcResponse.DeviceName, + Method = rpcResponse.Method, + ResponseId = rpcResponse.RequestId, + Data = JsonConvert.SerializeObject(new Dictionary + { + { "success", rpcResponse.IsSuccess }, { "description", rpcResponse.Description } + }) + }; + + //var responseTopic = $"/devices/{deviceid}/rpc/response/{methodName}/{rpcid}"; + var topic = $"devices/{rpcResult.DeviceId}/rpc/response/{rpcResult.Method}/{rpcResult.ResponseId}"; + + await MqttClient.EnqueueAsync(new MqttApplicationMessageBuilder() + .WithTopic(topic) + .WithPayload(JsonConvert.SerializeObject(rpcResult)) + .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); + } + + public async Task PublishTelemetryAsync(string deviceName, Device device, Dictionary> sendModel) + { + foreach (var payload in sendModel[deviceName]) + { + if (payload.Values != null) + { + payload.Values["_ts_"] = (long)(DateTime.UtcNow - _tsStartDt).TotalMilliseconds; + await MqttClient.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic($"devices/{deviceName}/telemetry") + .WithPayload(JsonConvert.SerializeObject(payload.Values)).Build()); + } + } + } + + public Task UploadAttributeAsync(string deviceName, object obj) + { + return Task.CompletedTask; + } + + public async Task RequestAttributes(string deviceName, bool anySide, params string[] args) + { + string id = Guid.NewGuid().ToString(); + string topic = $"devices/{deviceName}/attributes/request/{id}"; + Dictionary keys = new Dictionary(); + keys.Add(anySide ? "anySide" : "server", string.Join(",", args)); + await MqttClient.SubscribeAsync($"devices/{deviceName}/attributes/response/{id}", + MqttQualityOfServiceLevel.ExactlyOnce); + await MqttClient.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic(topic) + .WithPayload(JsonConvert.SerializeObject(keys)) + .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); + } + + public async Task DeviceConnected(string deviceName, Device device) + { + await MqttClient.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic("v1/gateway/connect") + .WithPayload(JsonConvert.SerializeObject(new Dictionary + { { "device", deviceName } })) + .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce).Build()); + } + + public async Task DeviceDisconnected(string deviceName, Device device) + { + await MqttClient.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic($"v1/gateway/disconnect") + .WithPayload(JsonConvert.SerializeObject(new Dictionary + { { "device", deviceName } })) + .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce).Build()); + } + + public Task DeviceAdded(Device device) + { + return Task.CompletedTask; + } + + public Task DeviceDeleted(Device device) + { + return Task.CompletedTask; + } + + } +} diff --git a/Plugins/Plugin/PlatformHandler/PlatformHandlerFactory.cs b/Plugins/Plugin/PlatformHandler/PlatformHandlerFactory.cs new file mode 100644 index 0000000..72faecf --- /dev/null +++ b/Plugins/Plugin/PlatformHandler/PlatformHandlerFactory.cs @@ -0,0 +1,24 @@ +using IoTGateway.Model; +using Microsoft.Extensions.Logging; +using MQTTnet.Extensions.ManagedClient; +using PluginInterface; + +namespace Plugin.PlatformHandler +{ + public static class PlatformHandlerFactory + { + public static IPlatformHandler CreateHandler(IoTPlatformType platform, IManagedMqttClient mqttClient, ILogger logger, EventHandler onExcRpc) + { + switch (platform) + { + case IoTPlatformType.ThingsBoard: + return new ThingsBoardHandler(mqttClient, logger, onExcRpc); + case IoTPlatformType.ThingsCloud: + return new ThingsCloudHandler(mqttClient, logger, onExcRpc); + case IoTPlatformType.IoTSharp: + default: + return new IoTSharpHandler(mqttClient, logger, onExcRpc); + } + } + } +} diff --git a/Plugins/Plugin/PlatformHandler/ThingsBoardHandler.cs b/Plugins/Plugin/PlatformHandler/ThingsBoardHandler.cs new file mode 100644 index 0000000..28456f7 --- /dev/null +++ b/Plugins/Plugin/PlatformHandler/ThingsBoardHandler.cs @@ -0,0 +1,134 @@ +using MQTTnet.Extensions.ManagedClient; +using IoTGateway.Model; +using PluginInterface; +using MQTTnet.Protocol; +using MQTTnet.Client; +using Microsoft.Extensions.Logging; +using MQTTnet; +using Newtonsoft.Json; +using PluginInterface.ThingsBoard; + +namespace Plugin.PlatformHandler +{ + public class ThingsBoardHandler : IPlatformHandler + { + private readonly string _tbRpcTopic = "v1/gateway/rpc"; + + public IManagedMqttClient MqttClient { get; } + public ILogger Logger { get; } + public event EventHandler OnExcRpc; + + public ThingsBoardHandler(IManagedMqttClient mqttClient, ILogger logger, EventHandler onExcRpc) + { + MqttClient = mqttClient; + Logger = logger; + OnExcRpc = onExcRpc; + } + + public async Task ClientConnected() + { + //{"device": "Device A", "data": {"id": $request_id, "method": "toggle_gpio", "params": {"pin":1}}} + await MqttClient.SubscribeAsync(_tbRpcTopic, MqttQualityOfServiceLevel.ExactlyOnce); + //Message: {"id": $request_id, "device": "Device A", "value": "value1"} + await MqttClient.SubscribeAsync("v1/gateway/attributes/response", MqttQualityOfServiceLevel.ExactlyOnce); + //Message: {"device": "Device A", "data": {"attribute1": "value1", "attribute2": 42}} + await MqttClient.SubscribeAsync("v1/gateway/attributes", MqttQualityOfServiceLevel.ExactlyOnce); + } + + public void ReceiveRpc(MqttApplicationMessageReceivedEventArgs e) + { + try + { + var tBRpcRequest = + JsonConvert.DeserializeObject(e.ApplicationMessage.ConvertPayloadToString()); + if (tBRpcRequest != null && !string.IsNullOrWhiteSpace(tBRpcRequest.RequestData.Method)) + { + OnExcRpc(MqttClient, new RpcRequest() + { + Method = tBRpcRequest.RequestData.Method, + DeviceName = tBRpcRequest.DeviceName, + RequestId = tBRpcRequest.RequestData.RequestId, + Params = tBRpcRequest.RequestData.Params + }); + } + } + catch (Exception ex) + { + Logger.LogError(ex, + $"ReceiveTbRpc:Topic:{e.ApplicationMessage.Topic},Payload:{e.ApplicationMessage.ConvertPayloadToString()}"); + } + } + + public async Task ResponseRpcAsync(RpcResponse rpcResponse) + { + var tBRpcResponse = new TBRpcResponse + { + DeviceName = rpcResponse.DeviceName, + RequestId = rpcResponse.RequestId, + ResponseData = new Dictionary + { { "success", rpcResponse.IsSuccess }, { "description", rpcResponse.Description } } + }; + + await MqttClient.EnqueueAsync(new MqttApplicationMessageBuilder() + .WithTopic(_tbRpcTopic) + .WithPayload(JsonConvert.SerializeObject(tBRpcResponse)) + .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce).Build()); + } + + public async Task PublishTelemetryAsync(string deviceName, Device device, Dictionary> sendModel) + { + await MqttClient.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic("v1/gateway/telemetry") + .WithPayload(JsonConvert.SerializeObject(sendModel)) + .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce).Build()); + } + + public Task UploadAttributeAsync(string deviceName, object obj) + { + return MqttClient.EnqueueAsync(new MqttApplicationMessageBuilder() + .WithTopic($"devices/{deviceName}/attributes").WithPayload(JsonConvert.SerializeObject(obj)) + .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce) + .Build()); + } + + public async Task RequestAttributes(string deviceName, bool anySide, params string[] args) + { + string id = Guid.NewGuid().ToString(); + //{"id": $request_id, "device": "Device A", "client": true, "key": "attribute1"} + Dictionary tbRequestData = new Dictionary + { + { "id", id }, + { "device", deviceName }, + { "client", true }, + { "key", args[0] } + }; + await MqttClient.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic($"v1/gateway/attributes/request") + .WithPayload(JsonConvert.SerializeObject(tbRequestData)).WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); + } + + public async Task DeviceConnected(string deviceName, Device device) + { + await MqttClient.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic("v1/gateway/connect") + .WithPayload(JsonConvert.SerializeObject(new Dictionary + { { "device", deviceName } })) + .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce).Build()); + } + + public async Task DeviceDisconnected(string deviceName, Device device) + { + await MqttClient.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic($"v1/gateway/disconnect") + .WithPayload(JsonConvert.SerializeObject(new Dictionary + { { "device", deviceName } })) + .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce).Build()); + } + + public Task DeviceAdded(Device device) + { + return Task.CompletedTask; + } + + public Task DeviceDeleted(Device device) + { + return Task.CompletedTask; + } + } +} diff --git a/Plugins/Plugin/PlatformHandler/ThingsCloudHandler.cs b/Plugins/Plugin/PlatformHandler/ThingsCloudHandler.cs new file mode 100644 index 0000000..b3596a2 --- /dev/null +++ b/Plugins/Plugin/PlatformHandler/ThingsCloudHandler.cs @@ -0,0 +1,111 @@ +using MQTTnet.Client; +using MQTTnet.Extensions.ManagedClient; +using MQTTnet.Protocol; +using PluginInterface; +using IoTGateway.Model; +using Microsoft.Extensions.Logging; +using MQTTnet; +using Newtonsoft.Json; +using PluginInterface.ThingsBoard; + +namespace Plugin.PlatformHandler +{ + public class ThingsCloudHandler : IPlatformHandler + { + public IManagedMqttClient MqttClient { get; } + public ILogger Logger { get; } + public event EventHandler OnExcRpc; + + public ThingsCloudHandler(IManagedMqttClient mqttClient, ILogger logger, EventHandler onExcRpc) + { + MqttClient = mqttClient; + Logger = logger; + OnExcRpc = onExcRpc; + } + + + public async Task ClientConnected() + { + await MqttClient.SubscribeAsync("gateway/attributes/response", MqttQualityOfServiceLevel.ExactlyOnce); + await MqttClient.SubscribeAsync("gateway/attributes/get/response", MqttQualityOfServiceLevel.ExactlyOnce); + await MqttClient.SubscribeAsync("gateway/attributes/push", MqttQualityOfServiceLevel.ExactlyOnce); + await MqttClient.SubscribeAsync("gateway/event/response", MqttQualityOfServiceLevel.ExactlyOnce); + await MqttClient.SubscribeAsync("gateway/command/send", MqttQualityOfServiceLevel.ExactlyOnce); + } + public void ReceiveRpc(MqttApplicationMessageReceivedEventArgs e) + { + try + { + var tCRpcRequest = + JsonConvert.DeserializeObject(e.ApplicationMessage.ConvertPayloadToString()); + if (tCRpcRequest != null) + OnExcRpc.Invoke(MqttClient, new RpcRequest() + { + Method = tCRpcRequest.RequestData.Method, + DeviceName = tCRpcRequest.DeviceName, + RequestId = tCRpcRequest.RequestData.RequestId, + Params = tCRpcRequest.RequestData.Params + }); + } + catch (Exception ex) + { + Logger.LogError(ex, + $"ReceiveTbRpc:Topic:{e.ApplicationMessage.Topic},Payload:{e.ApplicationMessage.ConvertPayloadToString()}"); + } + } + + public Task ResponseRpcAsync(RpcResponse rpcResponse) + { + return Task.CompletedTask; + } + + public async Task PublishTelemetryAsync(string deviceName, Device device, Dictionary> sendModel) + { + foreach (var payload in sendModel[deviceName]) + { + if (payload.Values != null) + { + var toSend = new Dictionary { { deviceName, payload.Values } }; + await MqttClient.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic($"gateway/attributes") + .WithPayload(JsonConvert.SerializeObject(toSend)).WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); + } + } + } + + public Task UploadAttributeAsync(string deviceName, object obj) + { + return Task.CompletedTask; + } + + public Task RequestAttributes(string deviceName, bool anySide, params string[] args) + { + return Task.CompletedTask; + } + + public async Task DeviceConnected(string deviceName, Device device) + { + await MqttClient.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic("gateway/connect") + .WithPayload(JsonConvert.SerializeObject(new Dictionary + { { "device", deviceName } })) + .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); + } + + public async Task DeviceDisconnected(string deviceName, Device device) + { + await MqttClient.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic($"gateway/disconnect") + .WithPayload(JsonConvert.SerializeObject(new Dictionary + { { "device", deviceName } })) + .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce).Build()); + } + + public Task DeviceAdded(Device device) + { + return Task.CompletedTask; + } + + public Task DeviceDeleted(Device device) + { + return Task.CompletedTask; + } + } +} diff --git a/Plugins/Plugin/UA.Server/ConsoleUtils.cs b/Plugins/Plugin/UA.Server/ConsoleUtils.cs deleted file mode 100644 index b810268..0000000 --- a/Plugins/Plugin/UA.Server/ConsoleUtils.cs +++ /dev/null @@ -1,275 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2021 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * 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. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; -using Mono.Options; -using Opc.Ua; -using Opc.Ua.Configuration; -using static Opc.Ua.Utils; - -namespace Quickstarts -{ - /// - /// The log output implementation of a TextWriter. - /// - public class LogWriter : TextWriter - { - private StringBuilder m_builder = new StringBuilder(); - - public override void Write(char value) - { - m_builder.Append(value); - } - - public override void WriteLine(char value) - { - m_builder.Append(value); - //LogInfo("{0}", m_builder.ToString()); - m_builder.Clear(); - } - - public override void WriteLine() - { - //LogInfo("{0}", m_builder.ToString()); - m_builder.Clear(); - } - - public override void WriteLine(string format, object arg0) - { - m_builder.Append(format); - //LogInfo(m_builder.ToString(), arg0); - m_builder.Clear(); - } - - public override void WriteLine(string format, object arg0, object arg1) - { - m_builder.Append(format); - //LogInfo(m_builder.ToString(), arg0, arg1); - m_builder.Clear(); - } - - public override void WriteLine(string format, params object[] arg) - { - m_builder.Append(format); - //LogInfo(m_builder.ToString(), arg); - m_builder.Clear(); - } - - public override void Write(string value) - { - m_builder.Append(value); - } - - public override void WriteLine(string value) - { - m_builder.Append(value); - //LogInfo("{0}", m_builder.ToString()); - m_builder.Clear(); - } - - public override Encoding Encoding - { - get { return Encoding.Default; } - } - } - - /// - /// The error code why the application exit. - /// - public enum ExitCode : int - { - Ok = 0, - ErrorNotStarted = 0x80, - ErrorRunning = 0x81, - ErrorException = 0x82, - ErrorStopping = 0x83, - ErrorCertificate = 0x84, - ErrorInvalidCommandLine = 0x100 - }; - - /// - /// An exception that occured and caused an exit of the application. - /// - public class ErrorExitException : Exception - { - public ExitCode ExitCode { get; } - - public ErrorExitException(ExitCode exitCode) - { - ExitCode = exitCode; - } - - public ErrorExitException() - { - ExitCode = ExitCode.Ok; - } - - public ErrorExitException(string message) : base(message) - { - ExitCode = ExitCode.Ok; - } - - public ErrorExitException(string message, ExitCode exitCode) : base(message) - { - ExitCode = exitCode; - } - - public ErrorExitException(string message, Exception innerException) : base(message, innerException) - { - ExitCode = ExitCode.Ok; - } - - public ErrorExitException(string message, Exception innerException, ExitCode exitCode) : base(message, innerException) - { - ExitCode = exitCode; - } - } - - /// - /// A dialog which asks for user input. - /// - public class ApplicationMessageDlg : IApplicationMessageDlg - { - private TextWriter m_output; - private string m_message = string.Empty; - private bool m_ask; - - public ApplicationMessageDlg(TextWriter output) - { - m_output = output; - } - - public override void Message(string text, bool ask) - { - m_message = text; - m_ask = ask; - } - - public override async Task ShowAsync() - { - if (m_ask) - { - var message = new StringBuilder(m_message); - message.Append(" (y/n, default y): "); - //m_output.Write(message.ToString()); - - try - { - ConsoleKeyInfo result = Console.ReadKey(); - //m_output.WriteLine(); - return await Task.FromResult((result.KeyChar == 'y') || - (result.KeyChar == 'Y') || (result.KeyChar == '\r')).ConfigureAwait(false); - } - catch - { - // intentionally fall through - } - } - else - { - //m_output.WriteLine(m_message); - } - - return await Task.FromResult(true).ConfigureAwait(false); - } - } - - /// - /// Helper functions shared in various console applications. - /// - public static class ConsoleUtils - { - /// - /// Process a command line of the console sample application. - /// - public static string ProcessCommandLine( - TextWriter output, - string[] args, - Mono.Options.OptionSet options, - ref bool showHelp, - bool noExtraArgs = true) - { - IList extraArgs = null; - try - { - extraArgs = options.Parse(args); - if (noExtraArgs) - { - foreach (string extraArg in extraArgs) - { - output.WriteLine("Error: Unknown option: {0}", extraArg); - showHelp = true; - } - } - } - catch (OptionException e) - { - output.WriteLine(e.Message); - showHelp = true; - } - - if (showHelp) - { - options.WriteOptionDescriptions(output); - throw new ErrorExitException("Invalid Commandline or help requested.", ExitCode.ErrorInvalidCommandLine); - } - - return extraArgs.FirstOrDefault(); - } - - /// - /// Create an event which is set if a user - /// enters the Ctrl-C key combination. - /// - public static ManualResetEvent CtrlCHandler() - { - var quitEvent = new ManualResetEvent(false); - try - { - Console.CancelKeyPress += (_, eArgs) => { - quitEvent.Set(); - eArgs.Cancel = true; - }; - } - catch - { - // intentionally left blank - } - return quitEvent; - } - } -} - diff --git a/Plugins/Plugin/UA.Server/Namespaces.cs b/Plugins/Plugin/UA.Server/Namespaces.cs deleted file mode 100644 index 4dbe0c5..0000000 --- a/Plugins/Plugin/UA.Server/Namespaces.cs +++ /dev/null @@ -1,42 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * 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. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - -namespace Quickstarts.ReferenceServer -{ - /// - /// Defines constants for namespaces used by the servers. - /// - public static partial class Namespaces - { - /// - /// The namespace for the nodes provided by the reference server. - /// - public const string ReferenceServer = "http://opcfoundation.org/Quickstarts/ReferenceServer"; - } -} diff --git a/Plugins/Plugin/UA.Server/ReferenceNodeManager.cs b/Plugins/Plugin/UA.Server/ReferenceNodeManager.cs deleted file mode 100644 index 35e0524..0000000 --- a/Plugins/Plugin/UA.Server/ReferenceNodeManager.cs +++ /dev/null @@ -1,3696 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * 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. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - -using System; -using System.Collections.Generic; -using System.Xml; -using System.Threading; -using System.Numerics; -using Opc.Ua; -using Opc.Ua.Server; -using Range = Opc.Ua.Range; -using IoTGateway.DataAccess; -using Plugin; -using IoTGateway.Model; -using System.Linq; -using Microsoft.EntityFrameworkCore; - -namespace Quickstarts.ReferenceServer -{ - /// - /// A node manager for a server that exposes several variables. - /// - public class ReferenceNodeManager : CustomNodeManager2 - { - #region Constructors - - /// - /// Initializes the node manager. - /// - public ReferenceNodeManager(IServerInternal server, ApplicationConfiguration configuration) - : base(server, configuration, Namespaces.ReferenceServer) - { - SystemContext.NodeIdFactory = this; - - // get the configuration for the node manager. - m_configuration = configuration.ParseExtension(); - - // use suitable defaults if no configuration exists. - if (m_configuration == null) - { - m_configuration = new ReferenceServerConfiguration(); - } - - m_dynamicNodes = new List(); - m_iotgatewayNodes = new List(); - } - - #endregion - - #region IDisposable Members - - /// - /// An overrideable version of the Dispose. - /// - protected override void Dispose(bool disposing) - { - if (disposing) - { - // TBD - } - } - - #endregion - - #region INodeIdFactory Members - - /// - /// Creates the NodeId for the specified node. - /// - public override NodeId New(ISystemContext context, NodeState node) - { - BaseInstanceState instance = node as BaseInstanceState; - - if (instance != null && instance.Parent != null) - { - string id = instance.Parent.NodeId.Identifier as string; - - if (id != null) - { - return new NodeId(id + "_" + instance.SymbolicName, instance.Parent.NodeId.NamespaceIndex); - } - } - - return node.NodeId; - } - - #endregion - - #region Private Helper Functions - - private static bool IsUnsignedAnalogType(BuiltInType builtInType) - { - if (builtInType == BuiltInType.Byte || - builtInType == BuiltInType.UInt16 || - builtInType == BuiltInType.UInt32 || - builtInType == BuiltInType.UInt64) - { - return true; - } - - return false; - } - - private static bool IsAnalogType(BuiltInType builtInType) - { - switch (builtInType) - { - case BuiltInType.Byte: - case BuiltInType.UInt16: - case BuiltInType.UInt32: - case BuiltInType.UInt64: - case BuiltInType.SByte: - case BuiltInType.Int16: - case BuiltInType.Int32: - case BuiltInType.Int64: - case BuiltInType.Float: - case BuiltInType.Double: - return true; - } - - return false; - } - - private static Opc.Ua.Range GetAnalogRange(BuiltInType builtInType) - { - switch (builtInType) - { - case BuiltInType.UInt16: - return new Range(System.UInt16.MaxValue, System.UInt16.MinValue); - case BuiltInType.UInt32: - return new Range(System.UInt32.MaxValue, System.UInt32.MinValue); - case BuiltInType.UInt64: - return new Range(System.UInt64.MaxValue, System.UInt64.MinValue); - case BuiltInType.SByte: - return new Range(System.SByte.MaxValue, System.SByte.MinValue); - case BuiltInType.Int16: - return new Range(System.Int16.MaxValue, System.Int16.MinValue); - case BuiltInType.Int32: - return new Range(System.Int32.MaxValue, System.Int32.MinValue); - case BuiltInType.Int64: - return new Range(System.Int64.MaxValue, System.Int64.MinValue); - case BuiltInType.Float: - return new Range(System.Single.MaxValue, System.Single.MinValue); - case BuiltInType.Double: - return new Range(System.Double.MaxValue, System.Double.MinValue); - case BuiltInType.Byte: - return new Range(System.Byte.MaxValue, System.Byte.MinValue); - default: - return new Range(System.SByte.MaxValue, System.SByte.MinValue); - } - } - - #endregion - - #region INodeManager Members - - /// - /// Does any initialization required before the address space can be used. - /// - /// - /// The externalReferences is an out parameter that allows the node manager to link to nodes - /// in other node managers. For example, the 'Objects' node is managed by the CoreNodeManager and - /// should have a reference to the root folder node(s) exposed by this node manager. - /// - public void CreateAddressSpaceFoundation(IDictionary> externalReferences) - { - lock (Lock) - { - IList references = null; - - if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references)) - { - externalReferences[ObjectIds.ObjectsFolder] = references = new List(); - } - - FolderState root = CreateFolder(null, "CTT", "CTT"); - root.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); - references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, root.NodeId)); - root.EventNotifier = EventNotifiers.SubscribeToEvents; - AddRootNotifier(root); - - List variables = new List(); - - try - { - #region Scalar_Static - - FolderState scalarFolder = CreateFolder(root, "Scalar", "Scalar"); - BaseDataVariableState scalarInstructions = CreateVariable(scalarFolder, "Scalar_Instructions", - "Scalar_Instructions", DataTypeIds.String, ValueRanks.Scalar); - scalarInstructions.Value = "A library of Read/Write Variables of all supported data-types."; - variables.Add(scalarInstructions); - - FolderState staticFolder = CreateFolder(scalarFolder, "Scalar_Static", "Scalar_Static"); - const string scalarStatic = "Scalar_Static_"; - variables.Add(CreateVariable(staticFolder, scalarStatic + "Boolean", "Boolean", DataTypeIds.Boolean, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "Byte", "Byte", DataTypeIds.Byte, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "ByteString", "ByteString", - DataTypeIds.ByteString, ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "DateTime", "DateTime", - DataTypeIds.DateTime, ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "Double", "Double", DataTypeIds.Double, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "Duration", "Duration", - DataTypeIds.Duration, ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "Float", "Float", DataTypeIds.Float, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "Guid", "Guid", DataTypeIds.Guid, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "Int16", "Int16", DataTypeIds.Int16, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "Int32", "Int32", DataTypeIds.Int32, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "Int64", "Int64", DataTypeIds.Int64, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "Integer", "Integer", DataTypeIds.Integer, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "LocaleId", "LocaleId", - DataTypeIds.LocaleId, ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "LocalizedText", "LocalizedText", - DataTypeIds.LocalizedText, ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "NodeId", "NodeId", DataTypeIds.NodeId, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "Number", "Number", DataTypeIds.Number, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "QualifiedName", "QualifiedName", - DataTypeIds.QualifiedName, ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "SByte", "SByte", DataTypeIds.SByte, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "String", "String", DataTypeIds.String, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "UInt16", "UInt16", DataTypeIds.UInt16, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "UInt32", "UInt32", DataTypeIds.UInt32, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "UInt64", "UInt64", DataTypeIds.UInt64, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "UInteger", "UInteger", - DataTypeIds.UInteger, ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "UtcTime", "UtcTime", DataTypeIds.UtcTime, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "Variant", "Variant", BuiltInType.Variant, - ValueRanks.Scalar)); - variables.Add(CreateVariable(staticFolder, scalarStatic + "XmlElement", "XmlElement", - DataTypeIds.XmlElement, ValueRanks.Scalar)); - - BaseDataVariableState decimalVariable = CreateVariable(staticFolder, scalarStatic + "Decimal", - "Decimal", DataTypeIds.DecimalDataType, ValueRanks.Scalar); - // Set an arbitrary precision decimal value. - BigInteger largeInteger = - BigInteger.Parse("1234567890123546789012345678901234567890123456789012345"); - DecimalDataType decimalValue = new DecimalDataType(); - decimalValue.Scale = 100; - decimalValue.Value = largeInteger.ToByteArray(); - decimalVariable.Value = decimalValue; - variables.Add(decimalVariable); - - #endregion - - #region Scalar_Static_Arrays - - FolderState arraysFolder = CreateFolder(staticFolder, "Scalar_Static_Arrays", "Arrays"); - const string staticArrays = "Scalar_Static_Arrays_"; - - variables.Add(CreateVariable(arraysFolder, staticArrays + "Boolean", "Boolean", DataTypeIds.Boolean, - ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "Byte", "Byte", DataTypeIds.Byte, - ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "ByteString", "ByteString", - DataTypeIds.ByteString, ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "DateTime", "DateTime", - DataTypeIds.DateTime, ValueRanks.OneDimension)); - - BaseDataVariableState doubleArrayVar = CreateVariable(arraysFolder, staticArrays + "Double", - "Double", DataTypeIds.Double, ValueRanks.OneDimension); - // Set the first elements of the array to a smaller value. - double[] doubleArrayVal = doubleArrayVar.Value as double[]; - doubleArrayVal[0] %= 10E+10; - doubleArrayVal[1] %= 10E+10; - doubleArrayVal[2] %= 10E+10; - doubleArrayVal[3] %= 10E+10; - variables.Add(doubleArrayVar); - - variables.Add(CreateVariable(arraysFolder, staticArrays + "Duration", "Duration", - DataTypeIds.Duration, ValueRanks.OneDimension)); - - BaseDataVariableState floatArrayVar = CreateVariable(arraysFolder, staticArrays + "Float", "Float", - DataTypeIds.Float, ValueRanks.OneDimension); - // Set the first elements of the array to a smaller value. - float[] floatArrayVal = floatArrayVar.Value as float[]; - floatArrayVal[0] %= 0xf10E + 4; - floatArrayVal[1] %= 0xf10E + 4; - floatArrayVal[2] %= 0xf10E + 4; - floatArrayVal[3] %= 0xf10E + 4; - variables.Add(floatArrayVar); - - variables.Add(CreateVariable(arraysFolder, staticArrays + "Guid", "Guid", DataTypeIds.Guid, - ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "Int16", "Int16", DataTypeIds.Int16, - ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "Int32", "Int32", DataTypeIds.Int32, - ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "Int64", "Int64", DataTypeIds.Int64, - ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "Integer", "Integer", DataTypeIds.Integer, - ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "LocaleId", "LocaleId", - DataTypeIds.LocaleId, ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "LocalizedText", "LocalizedText", - DataTypeIds.LocalizedText, ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "NodeId", "NodeId", DataTypeIds.NodeId, - ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "Number", "Number", DataTypeIds.Number, - ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "QualifiedName", "QualifiedName", - DataTypeIds.QualifiedName, ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "SByte", "SByte", DataTypeIds.SByte, - ValueRanks.OneDimension)); - - BaseDataVariableState stringArrayVar = CreateVariable(arraysFolder, staticArrays + "String", - "String", DataTypeIds.String, ValueRanks.OneDimension); - stringArrayVar.Value = new string[] - { - "Лошадь_ Пурпурово( Змейка( Слон", - "猪 绿色 绵羊 大象~ 狗 菠萝 猪鼠", - "Лошадь Овцы Голубика Овцы Змейка", - "Чернота` Дракон Бело Дракон", - "Horse# Black Lemon Lemon Grape", - "猫< パイナップル; ドラゴン 犬 モモ", - "레몬} 빨간% 자주색 쥐 백색; 들", - "Yellow Sheep Peach Elephant Cow", - "Крыса Корова Свинья Собака Кот", - "龙_ 绵羊 大象 芒果; 猫'" - }; - variables.Add(stringArrayVar); - - variables.Add(CreateVariable(arraysFolder, staticArrays + "UInt16", "UInt16", DataTypeIds.UInt16, - ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "UInt32", "UInt32", DataTypeIds.UInt32, - ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "UInt64", "UInt64", DataTypeIds.UInt64, - ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "UInteger", "UInteger", - DataTypeIds.UInteger, ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "UtcTime", "UtcTime", DataTypeIds.UtcTime, - ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "Variant", "Variant", BuiltInType.Variant, - ValueRanks.OneDimension)); - variables.Add(CreateVariable(arraysFolder, staticArrays + "XmlElement", "XmlElement", - DataTypeIds.XmlElement, ValueRanks.OneDimension)); - - #endregion - - #region Scalar_Static_Arrays2D - - FolderState arrays2DFolder = CreateFolder(staticFolder, "Scalar_Static_Arrays2D", "Arrays2D"); - const string staticArrays2D = "Scalar_Static_Arrays2D_"; - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "Boolean", "Boolean", - DataTypeIds.Boolean, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "Byte", "Byte", DataTypeIds.Byte, - ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "ByteString", "ByteString", - DataTypeIds.ByteString, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "DateTime", "DateTime", - DataTypeIds.DateTime, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "Double", "Double", - DataTypeIds.Double, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "Duration", "Duration", - DataTypeIds.Duration, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "Float", "Float", DataTypeIds.Float, - ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "Guid", "Guid", DataTypeIds.Guid, - ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "Int16", "Int16", DataTypeIds.Int16, - ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "Int32", "Int32", DataTypeIds.Int32, - ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "Int64", "Int64", DataTypeIds.Int64, - ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "Integer", "Integer", - DataTypeIds.Integer, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "LocaleId", "LocaleId", - DataTypeIds.LocaleId, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "LocalizedText", "LocalizedText", - DataTypeIds.LocalizedText, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "NodeId", "NodeId", - DataTypeIds.NodeId, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "Number", "Number", - DataTypeIds.Number, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "QualifiedName", "QualifiedName", - DataTypeIds.QualifiedName, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "SByte", "SByte", DataTypeIds.SByte, - ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "String", "String", - DataTypeIds.String, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "UInt16", "UInt16", - DataTypeIds.UInt16, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "UInt32", "UInt32", - DataTypeIds.UInt32, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "UInt64", "UInt64", - DataTypeIds.UInt64, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "UInteger", "UInteger", - DataTypeIds.UInteger, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "UtcTime", "UtcTime", - DataTypeIds.UtcTime, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "Variant", "Variant", - BuiltInType.Variant, ValueRanks.TwoDimensions)); - variables.Add(CreateVariable(arrays2DFolder, staticArrays2D + "XmlElement", "XmlElement", - DataTypeIds.XmlElement, ValueRanks.TwoDimensions)); - - #endregion - - #region Scalar_Static_ArrayDynamic - - FolderState arrayDymnamicFolder = - CreateFolder(staticFolder, "Scalar_Static_ArrayDymamic", "ArrayDymamic"); - const string staticArraysDynamic = "Scalar_Static_ArrayDynamic_"; - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "Boolean", "Boolean", - DataTypeIds.Boolean, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "Byte", "Byte", - DataTypeIds.Byte, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "ByteString", "ByteString", - DataTypeIds.ByteString, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "DateTime", "DateTime", - DataTypeIds.DateTime, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "Double", "Double", - DataTypeIds.Double, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "Duration", "Duration", - DataTypeIds.Duration, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "Float", "Float", - DataTypeIds.Float, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "Guid", "Guid", - DataTypeIds.Guid, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "Int16", "Int16", - DataTypeIds.Int16, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "Int32", "Int32", - DataTypeIds.Int32, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "Int64", "Int64", - DataTypeIds.Int64, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "Integer", "Integer", - DataTypeIds.Integer, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "LocaleId", "LocaleId", - DataTypeIds.LocaleId, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "LocalizedText", - "LocalizedText", DataTypeIds.LocalizedText, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "NodeId", "NodeId", - DataTypeIds.NodeId, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "Number", "Number", - DataTypeIds.Number, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "QualifiedName", - "QualifiedName", DataTypeIds.QualifiedName, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "SByte", "SByte", - DataTypeIds.SByte, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "String", "String", - DataTypeIds.String, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "UInt16", "UInt16", - DataTypeIds.UInt16, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "UInt32", "UInt32", - DataTypeIds.UInt32, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "UInt64", "UInt64", - DataTypeIds.UInt64, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "UInteger", "UInteger", - DataTypeIds.UInteger, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "UtcTime", "UtcTime", - DataTypeIds.UtcTime, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "Variant", "Variant", - BuiltInType.Variant, ValueRanks.OneOrMoreDimensions)); - variables.Add(CreateVariable(arrayDymnamicFolder, staticArraysDynamic + "XmlElement", "XmlElement", - DataTypeIds.XmlElement, ValueRanks.OneOrMoreDimensions)); - - #endregion - - #region Scalar_Static_Mass - - // create 100 instances of each static scalar type - FolderState massFolder = CreateFolder(staticFolder, "Scalar_Static_Mass", "Mass"); - const string staticMass = "Scalar_Static_Mass_"; - variables.AddRange(CreateVariables(massFolder, staticMass + "Boolean", "Boolean", - DataTypeIds.Boolean, ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "Byte", "Byte", DataTypeIds.Byte, - ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "ByteString", "ByteString", - DataTypeIds.ByteString, ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "DateTime", "DateTime", - DataTypeIds.DateTime, ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "Double", "Double", DataTypeIds.Double, - ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "Duration", "Duration", - DataTypeIds.Duration, ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "Float", "Float", DataTypeIds.Float, - ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "Guid", "Guid", DataTypeIds.Guid, - ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "Int16", "Int16", DataTypeIds.Int16, - ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "Int32", "Int32", DataTypeIds.Int32, - ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "Int64", "Int64", DataTypeIds.Int64, - ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "Integer", "Integer", - DataTypeIds.Integer, ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "LocalizedText", "LocalizedText", - DataTypeIds.LocalizedText, ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "NodeId", "NodeId", DataTypeIds.NodeId, - ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "Number", "Number", DataTypeIds.Number, - ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "SByte", "SByte", DataTypeIds.SByte, - ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "String", "String", DataTypeIds.String, - ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "UInt16", "UInt16", DataTypeIds.UInt16, - ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "UInt32", "UInt32", DataTypeIds.UInt32, - ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "UInt64", "UInt64", DataTypeIds.UInt64, - ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "UInteger", "UInteger", - DataTypeIds.UInteger, ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "UtcTime", "UtcTime", - DataTypeIds.UtcTime, ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "Variant", "Variant", - BuiltInType.Variant, ValueRanks.Scalar, 100)); - variables.AddRange(CreateVariables(massFolder, staticMass + "XmlElement", "XmlElement", - DataTypeIds.XmlElement, ValueRanks.Scalar, 100)); - - #endregion - - #region Scalar_Simulation - - FolderState simulationFolder = CreateFolder(scalarFolder, "Scalar_Simulation", "Simulation"); - const string scalarSimulation = "Scalar_Simulation_"; - CreateDynamicVariable(simulationFolder, scalarSimulation + "Boolean", "Boolean", - DataTypeIds.Boolean, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Byte", "Byte", DataTypeIds.Byte, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "ByteString", "ByteString", - DataTypeIds.ByteString, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "DateTime", "DateTime", - DataTypeIds.DateTime, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Double", "Double", DataTypeIds.Double, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Duration", "Duration", - DataTypeIds.Duration, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Float", "Float", DataTypeIds.Float, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Guid", "Guid", DataTypeIds.Guid, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Int16", "Int16", DataTypeIds.Int16, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Int32", "Int32", DataTypeIds.Int32, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Int64", "Int64", DataTypeIds.Int64, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Integer", "Integer", - DataTypeIds.Integer, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "LocaleId", "LocaleId", - DataTypeIds.LocaleId, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "LocalizedText", "LocalizedText", - DataTypeIds.LocalizedText, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "NodeId", "NodeId", DataTypeIds.NodeId, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Number", "Number", DataTypeIds.Number, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "QualifiedName", "QualifiedName", - DataTypeIds.QualifiedName, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "SByte", "SByte", DataTypeIds.SByte, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "String", "String", DataTypeIds.String, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "UInt16", "UInt16", DataTypeIds.UInt16, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "UInt32", "UInt32", DataTypeIds.UInt32, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "UInt64", "UInt64", DataTypeIds.UInt64, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "UInteger", "UInteger", - DataTypeIds.UInteger, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "UtcTime", "UtcTime", - DataTypeIds.UtcTime, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Variant", "Variant", - BuiltInType.Variant, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "XmlElement", "XmlElement", - DataTypeIds.XmlElement, ValueRanks.Scalar); - - BaseDataVariableState intervalVariable = CreateVariable(simulationFolder, - scalarSimulation + "Interval", "Interval", DataTypeIds.UInt16, ValueRanks.Scalar); - intervalVariable.Value = m_simulationInterval; - intervalVariable.OnSimpleWriteValue = OnWriteInterval; - - BaseDataVariableState enabledVariable = CreateVariable(simulationFolder, - scalarSimulation + "Enabled", "Enabled", DataTypeIds.Boolean, ValueRanks.Scalar); - enabledVariable.Value = m_simulationEnabled; - enabledVariable.OnSimpleWriteValue = OnWriteEnabled; - - #endregion - - #region Scalar_Simulation_Arrays - - FolderState arraysSimulationFolder = - CreateFolder(simulationFolder, "Scalar_Simulation_Arrays", "Arrays"); - const string simulationArrays = "Scalar_Simulation_Arrays_"; - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "Boolean", "Boolean", - DataTypeIds.Boolean, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "Byte", "Byte", DataTypeIds.Byte, - ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "ByteString", "ByteString", - DataTypeIds.ByteString, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "DateTime", "DateTime", - DataTypeIds.DateTime, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "Double", "Double", - DataTypeIds.Double, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "Duration", "Duration", - DataTypeIds.Duration, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "Float", "Float", - DataTypeIds.Float, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "Guid", "Guid", DataTypeIds.Guid, - ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "Int16", "Int16", - DataTypeIds.Int16, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "Int32", "Int32", - DataTypeIds.Int32, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "Int64", "Int64", - DataTypeIds.Int64, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "Integer", "Integer", - DataTypeIds.Integer, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "LocaleId", "LocaleId", - DataTypeIds.LocaleId, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "LocalizedText", "LocalizedText", - DataTypeIds.LocalizedText, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "NodeId", "NodeId", - DataTypeIds.NodeId, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "Number", "Number", - DataTypeIds.Number, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "QualifiedName", "QualifiedName", - DataTypeIds.QualifiedName, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "SByte", "SByte", - DataTypeIds.SByte, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "String", "String", - DataTypeIds.String, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "UInt16", "UInt16", - DataTypeIds.UInt16, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "UInt32", "UInt32", - DataTypeIds.UInt32, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "UInt64", "UInt64", - DataTypeIds.UInt64, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "UInteger", "UInteger", - DataTypeIds.UInteger, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "UtcTime", "UtcTime", - DataTypeIds.UtcTime, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "Variant", "Variant", - BuiltInType.Variant, ValueRanks.OneDimension); - CreateDynamicVariable(arraysSimulationFolder, simulationArrays + "XmlElement", "XmlElement", - DataTypeIds.XmlElement, ValueRanks.OneDimension); - - #endregion - - #region Scalar_Simulation_Mass - - FolderState massSimulationFolder = CreateFolder(simulationFolder, "Scalar_Simulation_Mass", "Mass"); - const string massSimulation = "Scalar_Simulation_Mass_"; - CreateDynamicVariables(massSimulationFolder, massSimulation + "Boolean", "Boolean", - DataTypeIds.Boolean, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "Byte", "Byte", DataTypeIds.Byte, - ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "ByteString", "ByteString", - DataTypeIds.ByteString, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "DateTime", "DateTime", - DataTypeIds.DateTime, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "Double", "Double", - DataTypeIds.Double, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "Duration", "Duration", - DataTypeIds.Duration, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "Float", "Float", DataTypeIds.Float, - ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "Guid", "Guid", DataTypeIds.Guid, - ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "Int16", "Int16", DataTypeIds.Int16, - ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "Int32", "Int32", DataTypeIds.Int32, - ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "Int64", "Int64", DataTypeIds.Int64, - ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "Integer", "Integer", - DataTypeIds.Integer, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "LocaleId", "LocaleId", - DataTypeIds.LocaleId, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "LocalizedText", "LocalizedText", - DataTypeIds.LocalizedText, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "NodeId", "NodeId", - DataTypeIds.NodeId, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "Number", "Number", - DataTypeIds.Number, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "QualifiedName", "QualifiedName", - DataTypeIds.QualifiedName, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "SByte", "SByte", DataTypeIds.SByte, - ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "String", "String", - DataTypeIds.String, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "UInt16", "UInt16", - DataTypeIds.UInt16, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "UInt32", "UInt32", - DataTypeIds.UInt32, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "UInt64", "UInt64", - DataTypeIds.UInt64, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "UInteger", "UInteger", - DataTypeIds.UInteger, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "UtcTime", "UtcTime", - DataTypeIds.UtcTime, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "Variant", "Variant", - BuiltInType.Variant, ValueRanks.Scalar, 100); - CreateDynamicVariables(massSimulationFolder, massSimulation + "XmlElement", "XmlElement", - DataTypeIds.XmlElement, ValueRanks.Scalar, 100); - - #endregion - - #region DataAccess_DataItem - - FolderState daFolder = CreateFolder(root, "DataAccess", "DataAccess"); - BaseDataVariableState daInstructions = CreateVariable(daFolder, "DataAccess_Instructions", - "Instructions", DataTypeIds.String, ValueRanks.Scalar); - daInstructions.Value = "A library of Read/Write Variables of all supported data-types."; - variables.Add(daInstructions); - - FolderState dataItemFolder = CreateFolder(daFolder, "DataAccess_DataItem", "DataItem"); - const string daDataItem = "DataAccess_DataItem_"; - - foreach (string name in Enum.GetNames(typeof(BuiltInType))) - { - DataItemState item = CreateDataItemVariable(dataItemFolder, daDataItem + name, name, - (BuiltInType)Enum.Parse(typeof(BuiltInType), name), ValueRanks.Scalar); - - // set initial value to String.Empty for String node. - if (name == BuiltInType.String.ToString()) - { - item.Value = String.Empty; - } - } - - #endregion - - #region DataAccess_AnalogType - - FolderState analogItemFolder = CreateFolder(daFolder, "DataAccess_AnalogType", "AnalogType"); - const string daAnalogItem = "DataAccess_AnalogType_"; - - foreach (string name in Enum.GetNames(typeof(BuiltInType))) - { - BuiltInType builtInType = (BuiltInType)Enum.Parse(typeof(BuiltInType), name); - if (IsAnalogType(builtInType)) - { - AnalogItemState item = CreateAnalogItemVariable(analogItemFolder, daAnalogItem + name, name, - builtInType, ValueRanks.Scalar); - - if (builtInType == BuiltInType.Int64 || - builtInType == BuiltInType.UInt64) - { - // make test case without optional ranges - item.EngineeringUnits = null; - item.InstrumentRange = null; - } - else if (builtInType == BuiltInType.Float) - { - item.EURange.Value.High = 0; - item.EURange.Value.Low = 0; - } - - //set default value for Definition property - if (item.Definition != null) - { - item.Definition.Value = String.Empty; - } - } - } - - #endregion - - #region DataAccess_AnalogType_Array - - FolderState analogArrayFolder = - CreateFolder(analogItemFolder, "DataAccess_AnalogType_Array", "Array"); - const string daAnalogArray = "DataAccess_AnalogType_Array_"; - - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "Boolean", "Boolean", - BuiltInType.Boolean, ValueRanks.OneDimension, - new Boolean[] { true, false, true, false, true, false, true, false, true }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "Byte", "Byte", BuiltInType.Byte, - ValueRanks.OneDimension, new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "ByteString", "ByteString", - BuiltInType.ByteString, ValueRanks.OneDimension, - new Byte[][] - { - new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, - new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, - new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, - new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, - new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } - }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "DateTime", "DateTime", - BuiltInType.DateTime, ValueRanks.OneDimension, - new DateTime[] - { - DateTime.MinValue, DateTime.MaxValue, DateTime.MinValue, DateTime.MaxValue, - DateTime.MinValue, DateTime.MaxValue, DateTime.MinValue, DateTime.MaxValue, - DateTime.MinValue - }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "Double", "Double", BuiltInType.Double, - ValueRanks.OneDimension, - new double[] { 9.00001d, 9.0002d, 9.003d, 9.04d, 9.5d, 9.06d, 9.007d, 9.008d, 9.0009d }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "Duration", "Duration", - DataTypeIds.Duration, ValueRanks.OneDimension, - new double[] { 9.00001d, 9.0002d, 9.003d, 9.04d, 9.5d, 9.06d, 9.007d, 9.008d, 9.0009d }, null); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "Float", "Float", BuiltInType.Float, - ValueRanks.OneDimension, - new float[] { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 1.1f, 2.2f, 3.3f, 4.4f, 5.5f }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "Guid", "Guid", BuiltInType.Guid, - ValueRanks.OneDimension, - new Guid[] - { - Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid(), - Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() - }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "Int16", "Int16", BuiltInType.Int16, - ValueRanks.OneDimension, new Int16[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "Int32", "Int32", BuiltInType.Int32, - ValueRanks.OneDimension, new Int32[] { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "Int64", "Int64", BuiltInType.Int64, - ValueRanks.OneDimension, new Int64[] { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "Integer", "Integer", - BuiltInType.Integer, ValueRanks.OneDimension, - new Int64[] { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "LocaleId", "LocaleId", - DataTypeIds.LocaleId, ValueRanks.OneDimension, - new String[] { "en", "fr", "de", "en", "fr", "de", "en", "fr", "de", "en" }, null); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "LocalizedText", "LocalizedText", - BuiltInType.LocalizedText, ValueRanks.OneDimension, - new LocalizedText[] - { - new LocalizedText("en", "Hello World1"), new LocalizedText("en", "Hello World2"), - new LocalizedText("en", "Hello World3"), new LocalizedText("en", "Hello World4"), - new LocalizedText("en", "Hello World5"), new LocalizedText("en", "Hello World6"), - new LocalizedText("en", "Hello World7"), new LocalizedText("en", "Hello World8"), - new LocalizedText("en", "Hello World9"), new LocalizedText("en", "Hello World10") - }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "NodeId", "NodeId", BuiltInType.NodeId, - ValueRanks.OneDimension, - new NodeId[] - { - new NodeId(Guid.NewGuid()), new NodeId(Guid.NewGuid()), new NodeId(Guid.NewGuid()), - new NodeId(Guid.NewGuid()), new NodeId(Guid.NewGuid()), new NodeId(Guid.NewGuid()), - new NodeId(Guid.NewGuid()), new NodeId(Guid.NewGuid()), new NodeId(Guid.NewGuid()), - new NodeId(Guid.NewGuid()) - }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "Number", "Number", BuiltInType.Number, - ValueRanks.OneDimension, new Int16[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "QualifiedName", "QualifiedName", - BuiltInType.QualifiedName, ValueRanks.OneDimension, - new QualifiedName[] { "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9" }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "SByte", "SByte", BuiltInType.SByte, - ValueRanks.OneDimension, new SByte[] { 10, 20, 30, 40, 50, 60, 70, 80, 90 }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "String", "String", BuiltInType.String, - ValueRanks.OneDimension, - new String[] { "a00", "b10", "c20", "d30", "e40", "f50", "g60", "h70", "i80", "j90" }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "UInt16", "UInt16", BuiltInType.UInt16, - ValueRanks.OneDimension, new UInt16[] { 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "UInt32", "UInt32", BuiltInType.UInt32, - ValueRanks.OneDimension, new UInt32[] { 30, 31, 32, 33, 34, 35, 36, 37, 38, 39 }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "UInt64", "UInt64", BuiltInType.UInt64, - ValueRanks.OneDimension, new UInt64[] { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "UInteger", "UInteger", - BuiltInType.UInteger, ValueRanks.OneDimension, - new UInt64[] { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "UtcTime", "UtcTime", - DataTypeIds.UtcTime, ValueRanks.OneDimension, - new DateTime[] - { - DateTime.MinValue.ToUniversalTime(), DateTime.MaxValue.ToUniversalTime(), - DateTime.MinValue.ToUniversalTime(), DateTime.MaxValue.ToUniversalTime(), - DateTime.MinValue.ToUniversalTime(), DateTime.MaxValue.ToUniversalTime(), - DateTime.MinValue.ToUniversalTime(), DateTime.MaxValue.ToUniversalTime(), - DateTime.MinValue.ToUniversalTime() - }, null); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "Variant", "Variant", - BuiltInType.Variant, ValueRanks.OneDimension, - new Variant[] { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }); - XmlDocument doc1 = new XmlDocument(); - CreateAnalogItemVariable(analogArrayFolder, daAnalogArray + "XmlElement", "XmlElement", - BuiltInType.XmlElement, ValueRanks.OneDimension, - new XmlElement[] - { - doc1.CreateElement("tag1"), doc1.CreateElement("tag2"), doc1.CreateElement("tag3"), - doc1.CreateElement("tag4"), doc1.CreateElement("tag5"), doc1.CreateElement("tag6"), - doc1.CreateElement("tag7"), doc1.CreateElement("tag8"), doc1.CreateElement("tag9"), - doc1.CreateElement("tag10") - }); - - #endregion - - #region DataAccess_DiscreteType - - FolderState discreteTypeFolder = CreateFolder(daFolder, "DataAccess_DiscreteType", "DiscreteType"); - FolderState twoStateDiscreteFolder = CreateFolder(discreteTypeFolder, - "DataAccess_TwoStateDiscreteType", "TwoStateDiscreteType"); - const string daTwoStateDiscrete = "DataAccess_TwoStateDiscreteType_"; - - // Add our Nodes to the folder, and specify their customized discrete enumerations - CreateTwoStateDiscreteItemVariable(twoStateDiscreteFolder, daTwoStateDiscrete + "001", "001", "red", - "blue"); - CreateTwoStateDiscreteItemVariable(twoStateDiscreteFolder, daTwoStateDiscrete + "002", "002", - "open", "close"); - CreateTwoStateDiscreteItemVariable(twoStateDiscreteFolder, daTwoStateDiscrete + "003", "003", "up", - "down"); - CreateTwoStateDiscreteItemVariable(twoStateDiscreteFolder, daTwoStateDiscrete + "004", "004", - "left", "right"); - CreateTwoStateDiscreteItemVariable(twoStateDiscreteFolder, daTwoStateDiscrete + "005", "005", - "circle", "cross"); - - FolderState multiStateDiscreteFolder = CreateFolder(discreteTypeFolder, - "DataAccess_MultiStateDiscreteType", "MultiStateDiscreteType"); - const string daMultiStateDiscrete = "DataAccess_MultiStateDiscreteType_"; - - // Add our Nodes to the folder, and specify their customized discrete enumerations - CreateMultiStateDiscreteItemVariable(multiStateDiscreteFolder, daMultiStateDiscrete + "001", "001", - "open", "closed", "jammed"); - CreateMultiStateDiscreteItemVariable(multiStateDiscreteFolder, daMultiStateDiscrete + "002", "002", - "red", "green", "blue", "cyan"); - CreateMultiStateDiscreteItemVariable(multiStateDiscreteFolder, daMultiStateDiscrete + "003", "003", - "lolo", "lo", "normal", "hi", "hihi"); - CreateMultiStateDiscreteItemVariable(multiStateDiscreteFolder, daMultiStateDiscrete + "004", "004", - "left", "right", "center"); - CreateMultiStateDiscreteItemVariable(multiStateDiscreteFolder, daMultiStateDiscrete + "005", "005", - "circle", "cross", "triangle"); - - #endregion - - #region DataAccess_MultiStateValueDiscreteType - - FolderState multiStateValueDiscreteFolder = CreateFolder(discreteTypeFolder, - "DataAccess_MultiStateValueDiscreteType", "MultiStateValueDiscreteType"); - const string daMultiStateValueDiscrete = "DataAccess_MultiStateValueDiscreteType_"; - - // Add our Nodes to the folder, and specify their customized discrete enumerations - CreateMultiStateValueDiscreteItemVariable(multiStateValueDiscreteFolder, - daMultiStateValueDiscrete + "001", "001", new string[] { "open", "closed", "jammed" }); - CreateMultiStateValueDiscreteItemVariable(multiStateValueDiscreteFolder, - daMultiStateValueDiscrete + "002", "002", new string[] { "red", "green", "blue", "cyan" }); - CreateMultiStateValueDiscreteItemVariable(multiStateValueDiscreteFolder, - daMultiStateValueDiscrete + "003", "003", - new string[] { "lolo", "lo", "normal", "hi", "hihi" }); - CreateMultiStateValueDiscreteItemVariable(multiStateValueDiscreteFolder, - daMultiStateValueDiscrete + "004", "004", new string[] { "left", "right", "center" }); - CreateMultiStateValueDiscreteItemVariable(multiStateValueDiscreteFolder, - daMultiStateValueDiscrete + "005", "005", new string[] { "circle", "cross", "triangle" }); - - // Add our Nodes to the folder and specify varying data types - CreateMultiStateValueDiscreteItemVariable(multiStateValueDiscreteFolder, - daMultiStateValueDiscrete + "Byte", "Byte", DataTypeIds.Byte, - new string[] { "open", "closed", "jammed" }); - CreateMultiStateValueDiscreteItemVariable(multiStateValueDiscreteFolder, - daMultiStateValueDiscrete + "Int16", "Int16", DataTypeIds.Int16, - new string[] { "red", "green", "blue", "cyan" }); - CreateMultiStateValueDiscreteItemVariable(multiStateValueDiscreteFolder, - daMultiStateValueDiscrete + "Int32", "Int32", DataTypeIds.Int32, - new string[] { "lolo", "lo", "normal", "hi", "hihi" }); - CreateMultiStateValueDiscreteItemVariable(multiStateValueDiscreteFolder, - daMultiStateValueDiscrete + "Int64", "Int64", DataTypeIds.Int64, - new string[] { "left", "right", "center" }); - CreateMultiStateValueDiscreteItemVariable(multiStateValueDiscreteFolder, - daMultiStateValueDiscrete + "SByte", "SByte", DataTypeIds.SByte, - new string[] { "open", "closed", "jammed" }); - CreateMultiStateValueDiscreteItemVariable(multiStateValueDiscreteFolder, - daMultiStateValueDiscrete + "UInt16", "UInt16", DataTypeIds.UInt16, - new string[] { "red", "green", "blue", "cyan" }); - CreateMultiStateValueDiscreteItemVariable(multiStateValueDiscreteFolder, - daMultiStateValueDiscrete + "UInt32", "UInt32", DataTypeIds.UInt32, - new string[] { "lolo", "lo", "normal", "hi", "hihi" }); - CreateMultiStateValueDiscreteItemVariable(multiStateValueDiscreteFolder, - daMultiStateValueDiscrete + "UInt64", "UInt64", DataTypeIds.UInt64, - new string[] { "left", "right", "center" }); - - #endregion - - #region References - - FolderState referencesFolder = CreateFolder(root, "References", "References"); - const string referencesPrefix = "References_"; - - BaseDataVariableState referencesInstructions = CreateVariable(referencesFolder, - "References_Instructions", "Instructions", DataTypeIds.String, ValueRanks.Scalar); - referencesInstructions.Value = - "This folder will contain nodes that have specific Reference configurations."; - variables.Add(referencesInstructions); - - // create variable nodes with specific references - BaseDataVariableState hasForwardReference = CreateMeshVariable(referencesFolder, - referencesPrefix + "HasForwardReference", "HasForwardReference"); - hasForwardReference.AddReference(ReferenceTypes.HasCause, false, variables[0].NodeId); - variables.Add(hasForwardReference); - - BaseDataVariableState hasInverseReference = CreateMeshVariable(referencesFolder, - referencesPrefix + "HasInverseReference", "HasInverseReference"); - hasInverseReference.AddReference(ReferenceTypes.HasCause, true, variables[0].NodeId); - variables.Add(hasInverseReference); - - BaseDataVariableState has3InverseReference = null; - for (int i = 1; i <= 5; i++) - { - string referenceString = "Has3ForwardReferences"; - if (i > 1) - { - referenceString += i.ToString(); - } - - BaseDataVariableState has3ForwardReferences = CreateMeshVariable(referencesFolder, - referencesPrefix + referenceString, referenceString); - has3ForwardReferences.AddReference(ReferenceTypes.HasCause, false, variables[0].NodeId); - has3ForwardReferences.AddReference(ReferenceTypes.HasCause, false, variables[1].NodeId); - has3ForwardReferences.AddReference(ReferenceTypes.HasCause, false, variables[2].NodeId); - if (i == 1) - { - has3InverseReference = has3ForwardReferences; - } - - variables.Add(has3ForwardReferences); - } - - BaseDataVariableState has3InverseReferences = CreateMeshVariable(referencesFolder, - referencesPrefix + "Has3InverseReferences", "Has3InverseReferences"); - has3InverseReferences.AddReference(ReferenceTypes.HasEffect, true, variables[0].NodeId); - has3InverseReferences.AddReference(ReferenceTypes.HasEffect, true, variables[1].NodeId); - has3InverseReferences.AddReference(ReferenceTypes.HasEffect, true, variables[2].NodeId); - variables.Add(has3InverseReferences); - - BaseDataVariableState hasForwardAndInverseReferences = CreateMeshVariable(referencesFolder, - referencesPrefix + "HasForwardAndInverseReference", "HasForwardAndInverseReference", - hasForwardReference, hasInverseReference, has3InverseReference, has3InverseReferences, - variables[0]); - variables.Add(hasForwardAndInverseReferences); - - #endregion - - #region AccessRights - - FolderState folderAccessRights = CreateFolder(root, "AccessRights", "AccessRights"); - const string accessRights = "AccessRights_"; - - BaseDataVariableState accessRightsInstructions = CreateVariable(folderAccessRights, - accessRights + "Instructions", "Instructions", DataTypeIds.String, ValueRanks.Scalar); - accessRightsInstructions.Value = - "This folder will be accessible to all who enter, but contents therein will be secured."; - variables.Add(accessRightsInstructions); - - // sub-folder for "AccessAll" - FolderState folderAccessRightsAccessAll = - CreateFolder(folderAccessRights, "AccessRights_AccessAll", "AccessAll"); - const string accessRightsAccessAll = "AccessRights_AccessAll_"; - - BaseDataVariableState arAllRO = CreateVariable(folderAccessRightsAccessAll, - accessRightsAccessAll + "RO", "RO", BuiltInType.Int16, ValueRanks.Scalar); - arAllRO.AccessLevel = AccessLevels.CurrentRead; - arAllRO.UserAccessLevel = AccessLevels.CurrentRead; - variables.Add(arAllRO); - BaseDataVariableState arAllWO = CreateVariable(folderAccessRightsAccessAll, - accessRightsAccessAll + "WO", "WO", BuiltInType.Int16, ValueRanks.Scalar); - arAllWO.AccessLevel = AccessLevels.CurrentWrite; - arAllWO.UserAccessLevel = AccessLevels.CurrentWrite; - variables.Add(arAllWO); - BaseDataVariableState arAllRW = CreateVariable(folderAccessRightsAccessAll, - accessRightsAccessAll + "RW", "RW", BuiltInType.Int16, ValueRanks.Scalar); - arAllRW.AccessLevel = AccessLevels.CurrentReadOrWrite; - arAllRW.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - variables.Add(arAllRW); - BaseDataVariableState arAllRONotUser = CreateVariable(folderAccessRightsAccessAll, - accessRightsAccessAll + "RO_NotUser", "RO_NotUser", BuiltInType.Int16, ValueRanks.Scalar); - arAllRONotUser.AccessLevel = AccessLevels.CurrentRead; - arAllRONotUser.UserAccessLevel = AccessLevels.None; - variables.Add(arAllRONotUser); - BaseDataVariableState arAllWONotUser = CreateVariable(folderAccessRightsAccessAll, - accessRightsAccessAll + "WO_NotUser", "WO_NotUser", BuiltInType.Int16, ValueRanks.Scalar); - arAllWONotUser.AccessLevel = AccessLevels.CurrentWrite; - arAllWONotUser.UserAccessLevel = AccessLevels.None; - variables.Add(arAllWONotUser); - BaseDataVariableState arAllRWNotUser = CreateVariable(folderAccessRightsAccessAll, - accessRightsAccessAll + "RW_NotUser", "RW_NotUser", BuiltInType.Int16, ValueRanks.Scalar); - arAllRWNotUser.AccessLevel = AccessLevels.CurrentReadOrWrite; - arAllRWNotUser.UserAccessLevel = AccessLevels.CurrentRead; - variables.Add(arAllRWNotUser); - BaseDataVariableState arAllROUserRW = CreateVariable(folderAccessRightsAccessAll, - accessRightsAccessAll + "RO_User1_RW", "RO_User1_RW", BuiltInType.Int16, ValueRanks.Scalar); - arAllROUserRW.AccessLevel = AccessLevels.CurrentRead; - arAllROUserRW.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - variables.Add(arAllROUserRW); - BaseDataVariableState arAllROGroupRW = CreateVariable(folderAccessRightsAccessAll, - accessRightsAccessAll + "RO_Group1_RW", "RO_Group1_RW", BuiltInType.Int16, ValueRanks.Scalar); - arAllROGroupRW.AccessLevel = AccessLevels.CurrentRead; - arAllROGroupRW.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - variables.Add(arAllROGroupRW); - - // sub-folder for "AccessUser1" - FolderState folderAccessRightsAccessUser1 = - CreateFolder(folderAccessRights, "AccessRights_AccessUser1", "AccessUser1"); - const string accessRightsAccessUser1 = "AccessRights_AccessUser1_"; - - BaseDataVariableState arUserRO = CreateVariable(folderAccessRightsAccessUser1, - accessRightsAccessUser1 + "RO", "RO", BuiltInType.Int16, ValueRanks.Scalar); - arUserRO.AccessLevel = AccessLevels.CurrentRead; - arUserRO.UserAccessLevel = AccessLevels.CurrentRead; - variables.Add(arUserRO); - BaseDataVariableState arUserWO = CreateVariable(folderAccessRightsAccessUser1, - accessRightsAccessUser1 + "WO", "WO", BuiltInType.Int16, ValueRanks.Scalar); - arUserWO.AccessLevel = AccessLevels.CurrentWrite; - arUserWO.UserAccessLevel = AccessLevels.CurrentWrite; - variables.Add(arUserWO); - BaseDataVariableState arUserRW = CreateVariable(folderAccessRightsAccessUser1, - accessRightsAccessUser1 + "RW", "RW", BuiltInType.Int16, ValueRanks.Scalar); - arUserRW.AccessLevel = AccessLevels.CurrentReadOrWrite; - arUserRW.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - variables.Add(arUserRW); - - // sub-folder for "AccessGroup1" - FolderState folderAccessRightsAccessGroup1 = - CreateFolder(folderAccessRights, "AccessRights_AccessGroup1", "AccessGroup1"); - const string accessRightsAccessGroup1 = "AccessRights_AccessGroup1_"; - - BaseDataVariableState arGroupRO = CreateVariable(folderAccessRightsAccessGroup1, - accessRightsAccessGroup1 + "RO", "RO", BuiltInType.Int16, ValueRanks.Scalar); - arGroupRO.AccessLevel = AccessLevels.CurrentRead; - arGroupRO.UserAccessLevel = AccessLevels.CurrentRead; - variables.Add(arGroupRO); - BaseDataVariableState arGroupWO = CreateVariable(folderAccessRightsAccessGroup1, - accessRightsAccessGroup1 + "WO", "WO", BuiltInType.Int16, ValueRanks.Scalar); - arGroupWO.AccessLevel = AccessLevels.CurrentWrite; - arGroupWO.UserAccessLevel = AccessLevels.CurrentWrite; - variables.Add(arGroupWO); - BaseDataVariableState arGroupRW = CreateVariable(folderAccessRightsAccessGroup1, - accessRightsAccessGroup1 + "RW", "RW", BuiltInType.Int16, ValueRanks.Scalar); - arGroupRW.AccessLevel = AccessLevels.CurrentReadOrWrite; - arGroupRW.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - variables.Add(arGroupRW); - - // sub folder for "RolePermissions" - FolderState folderRolePermissions = CreateFolder(folderAccessRights, "AccessRights_RolePermissions", - "RolePermissions"); - const string rolePermissions = "AccessRights_RolePermissions_"; - - BaseDataVariableState rpAnonymous = CreateVariable(folderRolePermissions, - rolePermissions + "AnonymousAccess", "AnonymousAccess", BuiltInType.Int16, ValueRanks.Scalar); - rpAnonymous.Description = "This node can be accessed by users that have Anonymous Role"; - rpAnonymous.RolePermissions = new RolePermissionTypeCollection() - { - // allow access to users with Anonymous role - new RolePermissionType() - { - RoleId = ObjectIds.WellKnownRole_Anonymous, - Permissions = (uint)(PermissionType.Browse | PermissionType.Read | - PermissionType.ReadRolePermissions | PermissionType.Write) - }, - }; - variables.Add(rpAnonymous); - - BaseDataVariableState rpAuthenticatedUser = CreateVariable(folderRolePermissions, - rolePermissions + "AuthenticatedUser", "AuthenticatedUser", BuiltInType.Int16, - ValueRanks.Scalar); - rpAuthenticatedUser.Description = - "This node can be accessed by users that have AuthenticatedUser Role"; - rpAuthenticatedUser.RolePermissions = new RolePermissionTypeCollection() - { - // allow access to users with AuthenticatedUser role - new RolePermissionType() - { - RoleId = ObjectIds.WellKnownRole_AuthenticatedUser, - Permissions = (uint)(PermissionType.Browse | PermissionType.Read | - PermissionType.ReadRolePermissions | PermissionType.Write) - }, - }; - variables.Add(rpAuthenticatedUser); - - BaseDataVariableState rpAdminUser = CreateVariable(folderRolePermissions, - rolePermissions + "AdminUser", "AdminUser", BuiltInType.Int16, ValueRanks.Scalar); - rpAdminUser.Description = - "This node can be accessed by users that have SecurityAdmin Role over an encrypted connection"; - rpAdminUser.AccessRestrictions = AccessRestrictionType.EncryptionRequired; - rpAdminUser.RolePermissions = new RolePermissionTypeCollection() - { - // allow access to users with SecurityAdmin role - new RolePermissionType() - { - RoleId = ObjectIds.WellKnownRole_SecurityAdmin, - Permissions = (uint)(PermissionType.Browse | PermissionType.Read | - PermissionType.ReadRolePermissions | PermissionType.Write) - }, - }; - variables.Add(rpAdminUser); - - // sub-folder for "AccessRestrictions" - FolderState folderAccessRestrictions = CreateFolder(folderAccessRights, - "AccessRights_AccessRestrictions", "AccessRestrictions"); - const string accessRestrictions = "AccessRights_AccessRestrictions_"; - - BaseDataVariableState arNone = CreateVariable(folderAccessRestrictions, accessRestrictions + "None", - "None", BuiltInType.Int16, ValueRanks.Scalar); - arNone.AccessLevel = AccessLevels.CurrentRead; - arNone.UserAccessLevel = AccessLevels.CurrentRead; - arNone.AccessRestrictions = AccessRestrictionType.None; - variables.Add(arNone); - - BaseDataVariableState arSigningRequired = CreateVariable(folderAccessRestrictions, - accessRestrictions + "SigningRequired", "SigningRequired", BuiltInType.Int16, - ValueRanks.Scalar); - arSigningRequired.AccessLevel = AccessLevels.CurrentRead; - arSigningRequired.UserAccessLevel = AccessLevels.CurrentRead; - arSigningRequired.AccessRestrictions = AccessRestrictionType.SigningRequired; - variables.Add(arSigningRequired); - - BaseDataVariableState arEncryptionRequired = CreateVariable(folderAccessRestrictions, - accessRestrictions + "EncryptionRequired", "EncryptionRequired", BuiltInType.Int16, - ValueRanks.Scalar); - arEncryptionRequired.AccessLevel = AccessLevels.CurrentRead; - arEncryptionRequired.UserAccessLevel = AccessLevels.CurrentRead; - arEncryptionRequired.AccessRestrictions = AccessRestrictionType.EncryptionRequired; - variables.Add(arEncryptionRequired); - - BaseDataVariableState arSessionRequired = CreateVariable(folderAccessRestrictions, - accessRestrictions + "SessionRequired", "SessionRequired", BuiltInType.Int16, - ValueRanks.Scalar); - arSessionRequired.AccessLevel = AccessLevels.CurrentRead; - arSessionRequired.UserAccessLevel = AccessLevels.CurrentRead; - arSessionRequired.AccessRestrictions = AccessRestrictionType.SessionRequired; - variables.Add(arSessionRequired); - - #endregion - - #region NodeIds - - FolderState nodeIdsFolder = CreateFolder(root, "NodeIds", "NodeIds"); - const string nodeIds = "NodeIds_"; - - BaseDataVariableState nodeIdsInstructions = CreateVariable(nodeIdsFolder, nodeIds + "Instructions", - "Instructions", DataTypeIds.String, ValueRanks.Scalar); - nodeIdsInstructions.Value = - "All supported Node types are available except whichever is in use for the other nodes."; - variables.Add(nodeIdsInstructions); - - BaseDataVariableState integerNodeId = CreateVariable(nodeIdsFolder, nodeIds + "Int16Integer", - "Int16Integer", DataTypeIds.Int16, ValueRanks.Scalar); - integerNodeId.NodeId = new NodeId((uint)9202, NamespaceIndex); - variables.Add(integerNodeId); - - variables.Add(CreateVariable(nodeIdsFolder, nodeIds + "Int16String", "Int16String", - DataTypeIds.Int16, ValueRanks.Scalar)); - - BaseDataVariableState guidNodeId = CreateVariable(nodeIdsFolder, nodeIds + "Int16GUID", "Int16GUID", - DataTypeIds.Int16, ValueRanks.Scalar); - guidNodeId.NodeId = new NodeId(new Guid("00000000-0000-0000-0000-000000009204"), NamespaceIndex); - variables.Add(guidNodeId); - - BaseDataVariableState opaqueNodeId = CreateVariable(nodeIdsFolder, nodeIds + "Int16Opaque", - "Int16Opaque", DataTypeIds.Int16, ValueRanks.Scalar); - opaqueNodeId.NodeId = new NodeId(new byte[] { 9, 2, 0, 5 }, NamespaceIndex); - variables.Add(opaqueNodeId); - - #endregion - - #region Methods - - FolderState methodsFolder = CreateFolder(root, "Methods", "Methods"); - const string methods = "Methods_"; - - BaseDataVariableState methodsInstructions = CreateVariable(methodsFolder, methods + "Instructions", - "Instructions", DataTypeIds.String, ValueRanks.Scalar); - methodsInstructions.Value = "Contains methods with varying parameter definitions."; - variables.Add(methodsInstructions); - - MethodState voidMethod = CreateMethod(methodsFolder, methods + "Void", "Void"); - voidMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnVoidCall); - - #region Add Method - - MethodState addMethod = CreateMethod(methodsFolder, methods + "Add", "Add"); - // set input arguments - addMethod.InputArguments = new PropertyState(addMethod); - addMethod.InputArguments.NodeId = new NodeId(addMethod.BrowseName.Name + "InArgs", NamespaceIndex); - addMethod.InputArguments.BrowseName = BrowseNames.InputArguments; - addMethod.InputArguments.DisplayName = addMethod.InputArguments.BrowseName.Name; - addMethod.InputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; - addMethod.InputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; - addMethod.InputArguments.DataType = DataTypeIds.Argument; - addMethod.InputArguments.ValueRank = ValueRanks.OneDimension; - - addMethod.InputArguments.Value = new Argument[] - { - new Argument() - { - Name = "Float value", Description = "Float value", DataType = DataTypeIds.Float, - ValueRank = ValueRanks.Scalar - }, - new Argument() - { - Name = "UInt32 value", Description = "UInt32 value", DataType = DataTypeIds.UInt32, - ValueRank = ValueRanks.Scalar - } - }; - - // set output arguments - addMethod.OutputArguments = new PropertyState(addMethod); - addMethod.OutputArguments.NodeId = - new NodeId(addMethod.BrowseName.Name + "OutArgs", NamespaceIndex); - addMethod.OutputArguments.BrowseName = BrowseNames.OutputArguments; - addMethod.OutputArguments.DisplayName = addMethod.OutputArguments.BrowseName.Name; - addMethod.OutputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; - addMethod.OutputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; - addMethod.OutputArguments.DataType = DataTypeIds.Argument; - addMethod.OutputArguments.ValueRank = ValueRanks.OneDimension; - - addMethod.OutputArguments.Value = new Argument[] - { - new Argument() - { - Name = "Add Result", Description = "Add Result", DataType = DataTypeIds.Float, - ValueRank = ValueRanks.Scalar - } - }; - - addMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnAddCall); - - #endregion - - #region Multiply Method - - MethodState multiplyMethod = CreateMethod(methodsFolder, methods + "Multiply", "Multiply"); - // set input arguments - multiplyMethod.InputArguments = new PropertyState(multiplyMethod); - multiplyMethod.InputArguments.NodeId = - new NodeId(multiplyMethod.BrowseName.Name + "InArgs", NamespaceIndex); - multiplyMethod.InputArguments.BrowseName = BrowseNames.InputArguments; - multiplyMethod.InputArguments.DisplayName = multiplyMethod.InputArguments.BrowseName.Name; - multiplyMethod.InputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; - multiplyMethod.InputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; - multiplyMethod.InputArguments.DataType = DataTypeIds.Argument; - multiplyMethod.InputArguments.ValueRank = ValueRanks.OneDimension; - - multiplyMethod.InputArguments.Value = new Argument[] - { - new Argument() - { - Name = "Int16 value", Description = "Int16 value", DataType = DataTypeIds.Int16, - ValueRank = ValueRanks.Scalar - }, - new Argument() - { - Name = "UInt16 value", Description = "UInt16 value", DataType = DataTypeIds.UInt16, - ValueRank = ValueRanks.Scalar - } - }; - - // set output arguments - multiplyMethod.OutputArguments = new PropertyState(multiplyMethod); - multiplyMethod.OutputArguments.NodeId = - new NodeId(multiplyMethod.BrowseName.Name + "OutArgs", NamespaceIndex); - multiplyMethod.OutputArguments.BrowseName = BrowseNames.OutputArguments; - multiplyMethod.OutputArguments.DisplayName = multiplyMethod.OutputArguments.BrowseName.Name; - multiplyMethod.OutputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; - multiplyMethod.OutputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; - multiplyMethod.OutputArguments.DataType = DataTypeIds.Argument; - multiplyMethod.OutputArguments.ValueRank = ValueRanks.OneDimension; - - multiplyMethod.OutputArguments.Value = new Argument[] - { - new Argument() - { - Name = "Multiply Result", Description = "Multiply Result", DataType = DataTypeIds.Int32, - ValueRank = ValueRanks.Scalar - } - }; - - multiplyMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnMultiplyCall); - - #endregion - - #region Divide Method - - MethodState divideMethod = CreateMethod(methodsFolder, methods + "Divide", "Divide"); - // set input arguments - divideMethod.InputArguments = new PropertyState(divideMethod); - divideMethod.InputArguments.NodeId = - new NodeId(divideMethod.BrowseName.Name + "InArgs", NamespaceIndex); - divideMethod.InputArguments.BrowseName = BrowseNames.InputArguments; - divideMethod.InputArguments.DisplayName = divideMethod.InputArguments.BrowseName.Name; - divideMethod.InputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; - divideMethod.InputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; - divideMethod.InputArguments.DataType = DataTypeIds.Argument; - divideMethod.InputArguments.ValueRank = ValueRanks.OneDimension; - - divideMethod.InputArguments.Value = new Argument[] - { - new Argument() - { - Name = "Int32 value", Description = "Int32 value", DataType = DataTypeIds.Int32, - ValueRank = ValueRanks.Scalar - }, - new Argument() - { - Name = "UInt16 value", Description = "UInt16 value", DataType = DataTypeIds.UInt16, - ValueRank = ValueRanks.Scalar - } - }; - - // set output arguments - divideMethod.OutputArguments = new PropertyState(divideMethod); - divideMethod.OutputArguments.NodeId = - new NodeId(divideMethod.BrowseName.Name + "OutArgs", NamespaceIndex); - divideMethod.OutputArguments.BrowseName = BrowseNames.OutputArguments; - divideMethod.OutputArguments.DisplayName = divideMethod.OutputArguments.BrowseName.Name; - divideMethod.OutputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; - divideMethod.OutputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; - divideMethod.OutputArguments.DataType = DataTypeIds.Argument; - divideMethod.OutputArguments.ValueRank = ValueRanks.OneDimension; - - divideMethod.OutputArguments.Value = new Argument[] - { - new Argument() - { - Name = "Divide Result", Description = "Divide Result", DataType = DataTypeIds.Float, - ValueRank = ValueRanks.Scalar - } - }; - - divideMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnDivideCall); - - #endregion - - #region Substract Method - - MethodState substractMethod = CreateMethod(methodsFolder, methods + "Substract", "Substract"); - // set input arguments - substractMethod.InputArguments = new PropertyState(substractMethod); - substractMethod.InputArguments.NodeId = - new NodeId(substractMethod.BrowseName.Name + "InArgs", NamespaceIndex); - substractMethod.InputArguments.BrowseName = BrowseNames.InputArguments; - substractMethod.InputArguments.DisplayName = substractMethod.InputArguments.BrowseName.Name; - substractMethod.InputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; - substractMethod.InputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; - substractMethod.InputArguments.DataType = DataTypeIds.Argument; - substractMethod.InputArguments.ValueRank = ValueRanks.OneDimension; - - substractMethod.InputArguments.Value = new Argument[] - { - new Argument() - { - Name = "Int16 value", Description = "Int16 value", DataType = DataTypeIds.Int16, - ValueRank = ValueRanks.Scalar - }, - new Argument() - { - Name = "Byte value", Description = "Byte value", DataType = DataTypeIds.Byte, - ValueRank = ValueRanks.Scalar - } - }; - - // set output arguments - substractMethod.OutputArguments = new PropertyState(substractMethod); - substractMethod.OutputArguments.NodeId = - new NodeId(substractMethod.BrowseName.Name + "OutArgs", NamespaceIndex); - substractMethod.OutputArguments.BrowseName = BrowseNames.OutputArguments; - substractMethod.OutputArguments.DisplayName = substractMethod.OutputArguments.BrowseName.Name; - substractMethod.OutputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; - substractMethod.OutputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; - substractMethod.OutputArguments.DataType = DataTypeIds.Argument; - substractMethod.OutputArguments.ValueRank = ValueRanks.OneDimension; - - substractMethod.OutputArguments.Value = new Argument[] - { - new Argument() - { - Name = "Substract Result", Description = "Substract Result", DataType = DataTypeIds.Int16, - ValueRank = ValueRanks.Scalar - } - }; - - substractMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnSubstractCall); - - #endregion - - #region Hello Method - - MethodState helloMethod = CreateMethod(methodsFolder, methods + "Hello", "Hello"); - // set input arguments - helloMethod.InputArguments = new PropertyState(helloMethod); - helloMethod.InputArguments.NodeId = - new NodeId(helloMethod.BrowseName.Name + "InArgs", NamespaceIndex); - helloMethod.InputArguments.BrowseName = BrowseNames.InputArguments; - helloMethod.InputArguments.DisplayName = helloMethod.InputArguments.BrowseName.Name; - helloMethod.InputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; - helloMethod.InputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; - helloMethod.InputArguments.DataType = DataTypeIds.Argument; - helloMethod.InputArguments.ValueRank = ValueRanks.OneDimension; - - helloMethod.InputArguments.Value = new Argument[] - { - new Argument() - { - Name = "String value", Description = "String value", DataType = DataTypeIds.String, - ValueRank = ValueRanks.Scalar - } - }; - - // set output arguments - helloMethod.OutputArguments = new PropertyState(helloMethod); - helloMethod.OutputArguments.NodeId = - new NodeId(helloMethod.BrowseName.Name + "OutArgs", NamespaceIndex); - helloMethod.OutputArguments.BrowseName = BrowseNames.OutputArguments; - helloMethod.OutputArguments.DisplayName = helloMethod.OutputArguments.BrowseName.Name; - helloMethod.OutputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; - helloMethod.OutputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; - helloMethod.OutputArguments.DataType = DataTypeIds.Argument; - helloMethod.OutputArguments.ValueRank = ValueRanks.OneDimension; - - helloMethod.OutputArguments.Value = new Argument[] - { - new Argument() - { - Name = "Hello Result", Description = "Hello Result", DataType = DataTypeIds.String, - ValueRank = ValueRanks.Scalar - } - }; - - helloMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnHelloCall); - - #endregion - - #region Input Method - - MethodState inputMethod = CreateMethod(methodsFolder, methods + "Input", "Input"); - // set input arguments - inputMethod.InputArguments = new PropertyState(inputMethod); - inputMethod.InputArguments.NodeId = - new NodeId(inputMethod.BrowseName.Name + "InArgs", NamespaceIndex); - inputMethod.InputArguments.BrowseName = BrowseNames.InputArguments; - inputMethod.InputArguments.DisplayName = inputMethod.InputArguments.BrowseName.Name; - inputMethod.InputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; - inputMethod.InputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; - inputMethod.InputArguments.DataType = DataTypeIds.Argument; - inputMethod.InputArguments.ValueRank = ValueRanks.OneDimension; - - inputMethod.InputArguments.Value = new Argument[] - { - new Argument() - { - Name = "String value", Description = "String value", DataType = DataTypeIds.String, - ValueRank = ValueRanks.Scalar - } - }; - - inputMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnInputCall); - - #endregion - - #region Output Method - - MethodState outputMethod = CreateMethod(methodsFolder, methods + "Output", "Output"); - - // set output arguments - outputMethod.OutputArguments = new PropertyState(helloMethod); - outputMethod.OutputArguments.NodeId = - new NodeId(helloMethod.BrowseName.Name + "OutArgs", NamespaceIndex); - outputMethod.OutputArguments.BrowseName = BrowseNames.OutputArguments; - outputMethod.OutputArguments.DisplayName = helloMethod.OutputArguments.BrowseName.Name; - outputMethod.OutputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; - outputMethod.OutputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; - outputMethod.OutputArguments.DataType = DataTypeIds.Argument; - outputMethod.OutputArguments.ValueRank = ValueRanks.OneDimension; - - outputMethod.OutputArguments.Value = new Argument[] - { - new Argument() - { - Name = "Output Result", Description = "Output Result", DataType = DataTypeIds.String, - ValueRank = ValueRanks.Scalar - } - }; - - outputMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnOutputCall); - - #endregion - - #endregion - - #region Views - - FolderState viewsFolder = CreateFolder(root, "Views", "Views"); - const string views = "Views_"; - - ViewState viewStateOperations = - CreateView(viewsFolder, externalReferences, views + "Operations", "Operations"); - ViewState viewStateEngineering = CreateView(viewsFolder, externalReferences, views + "Engineering", - "Engineering"); - - #endregion - - #region Locales - - FolderState localesFolder = CreateFolder(root, "Locales", "Locales"); - const string locales = "Locales_"; - - BaseDataVariableState qnEnglishVariable = CreateVariable(localesFolder, locales + "QNEnglish", - "QNEnglish", DataTypeIds.QualifiedName, ValueRanks.Scalar); - qnEnglishVariable.Description = new LocalizedText("en", "English"); - qnEnglishVariable.Value = new QualifiedName("Hello World", NamespaceIndex); - variables.Add(qnEnglishVariable); - BaseDataVariableState ltEnglishVariable = CreateVariable(localesFolder, locales + "LTEnglish", - "LTEnglish", DataTypeIds.LocalizedText, ValueRanks.Scalar); - ltEnglishVariable.Description = new LocalizedText("en", "English"); - ltEnglishVariable.Value = new LocalizedText("en", "Hello World"); - variables.Add(ltEnglishVariable); - - BaseDataVariableState qnFrancaisVariable = CreateVariable(localesFolder, locales + "QNFrancais", - "QNFrancais", DataTypeIds.QualifiedName, ValueRanks.Scalar); - qnFrancaisVariable.Description = new LocalizedText("en", "Francais"); - qnFrancaisVariable.Value = new QualifiedName("Salut tout le monde", NamespaceIndex); - variables.Add(qnFrancaisVariable); - BaseDataVariableState ltFrancaisVariable = CreateVariable(localesFolder, locales + "LTFrancais", - "LTFrancais", DataTypeIds.LocalizedText, ValueRanks.Scalar); - ltFrancaisVariable.Description = new LocalizedText("en", "Francais"); - ltFrancaisVariable.Value = new LocalizedText("fr", "Salut tout le monde"); - variables.Add(ltFrancaisVariable); - - BaseDataVariableState qnDeutschVariable = CreateVariable(localesFolder, locales + "QNDeutsch", - "QNDeutsch", DataTypeIds.QualifiedName, ValueRanks.Scalar); - qnDeutschVariable.Description = new LocalizedText("en", "Deutsch"); - qnDeutschVariable.Value = new QualifiedName("Hallo Welt", NamespaceIndex); - variables.Add(qnDeutschVariable); - BaseDataVariableState ltDeutschVariable = CreateVariable(localesFolder, locales + "LTDeutsch", - "LTDeutsch", DataTypeIds.LocalizedText, ValueRanks.Scalar); - ltDeutschVariable.Description = new LocalizedText("en", "Deutsch"); - ltDeutschVariable.Value = new LocalizedText("de", "Hallo Welt"); - variables.Add(ltDeutschVariable); - - BaseDataVariableState qnEspanolVariable = CreateVariable(localesFolder, locales + "QNEspanol", - "QNEspanol", DataTypeIds.QualifiedName, ValueRanks.Scalar); - qnEspanolVariable.Description = new LocalizedText("en", "Espanol"); - qnEspanolVariable.Value = new QualifiedName("Hola mundo", NamespaceIndex); - variables.Add(qnEspanolVariable); - BaseDataVariableState ltEspanolVariable = CreateVariable(localesFolder, locales + "LTEspanol", - "LTEspanol", DataTypeIds.LocalizedText, ValueRanks.Scalar); - ltEspanolVariable.Description = new LocalizedText("en", "Espanol"); - ltEspanolVariable.Value = new LocalizedText("es", "Hola mundo"); - variables.Add(ltEspanolVariable); - - BaseDataVariableState qnJapaneseVariable = CreateVariable(localesFolder, locales + "QN日本の", "QN日本の", - DataTypeIds.QualifiedName, ValueRanks.Scalar); - qnJapaneseVariable.Description = new LocalizedText("en", "Japanese"); - qnJapaneseVariable.Value = new QualifiedName("ハローワールド", NamespaceIndex); - variables.Add(qnJapaneseVariable); - BaseDataVariableState ltJapaneseVariable = CreateVariable(localesFolder, locales + "LT日本の", "LT日本の", - DataTypeIds.LocalizedText, ValueRanks.Scalar); - ltJapaneseVariable.Description = new LocalizedText("en", "Japanese"); - ltJapaneseVariable.Value = new LocalizedText("jp", "ハローワールド"); - variables.Add(ltJapaneseVariable); - - BaseDataVariableState qnChineseVariable = CreateVariable(localesFolder, locales + "QN中國的", "QN中國的", - DataTypeIds.QualifiedName, ValueRanks.Scalar); - qnChineseVariable.Description = new LocalizedText("en", "Chinese"); - qnChineseVariable.Value = new QualifiedName("世界您好", NamespaceIndex); - variables.Add(qnChineseVariable); - BaseDataVariableState ltChineseVariable = CreateVariable(localesFolder, locales + "LT中國的", "LT中國的", - DataTypeIds.LocalizedText, ValueRanks.Scalar); - ltChineseVariable.Description = new LocalizedText("en", "Chinese"); - ltChineseVariable.Value = new LocalizedText("ch", "世界您好"); - variables.Add(ltChineseVariable); - - BaseDataVariableState qnRussianVariable = CreateVariable(localesFolder, locales + "QNрусский", - "QNрусский", DataTypeIds.QualifiedName, ValueRanks.Scalar); - qnRussianVariable.Description = new LocalizedText("en", "Russian"); - qnRussianVariable.Value = new QualifiedName("LTрусский", NamespaceIndex); - variables.Add(qnRussianVariable); - BaseDataVariableState ltRussianVariable = CreateVariable(localesFolder, locales + "LTрусский", - "LTрусский", DataTypeIds.LocalizedText, ValueRanks.Scalar); - ltRussianVariable.Description = new LocalizedText("en", "Russian"); - ltRussianVariable.Value = new LocalizedText("ru", "LTрусский"); - variables.Add(ltRussianVariable); - - BaseDataVariableState qnArabicVariable = CreateVariable(localesFolder, locales + "QNالعربية", - "QNالعربية", DataTypeIds.QualifiedName, ValueRanks.Scalar); - qnArabicVariable.Description = new LocalizedText("en", "Arabic"); - qnArabicVariable.Value = new QualifiedName("مرحبا بالعال", NamespaceIndex); - variables.Add(qnArabicVariable); - BaseDataVariableState ltArabicVariable = CreateVariable(localesFolder, locales + "LTالعربية", - "LTالعربية", DataTypeIds.LocalizedText, ValueRanks.Scalar); - ltArabicVariable.Description = new LocalizedText("en", "Arabic"); - ltArabicVariable.Value = new LocalizedText("ae", "مرحبا بالعال"); - variables.Add(ltArabicVariable); - - BaseDataVariableState qnKlingonVariable = CreateVariable(localesFolder, locales + "QNtlhIngan", - "QNtlhIngan", DataTypeIds.QualifiedName, ValueRanks.Scalar); - qnKlingonVariable.Description = new LocalizedText("en", "Klingon"); - qnKlingonVariable.Value = new QualifiedName("qo' vIvan", NamespaceIndex); - variables.Add(qnKlingonVariable); - BaseDataVariableState ltKlingonVariable = CreateVariable(localesFolder, locales + "LTtlhIngan", - "LTtlhIngan", DataTypeIds.LocalizedText, ValueRanks.Scalar); - ltKlingonVariable.Description = new LocalizedText("en", "Klingon"); - ltKlingonVariable.Value = new LocalizedText("ko", "qo' vIvan"); - variables.Add(ltKlingonVariable); - - #endregion - - #region Attributes - - FolderState folderAttributes = CreateFolder(root, "Attributes", "Attributes"); - - #region AccessAll - - FolderState folderAttributesAccessAll = - CreateFolder(folderAttributes, "Attributes_AccessAll", "AccessAll"); - const string attributesAccessAll = "Attributes_AccessAll_"; - - BaseDataVariableState accessLevelAccessAll = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "AccessLevel", "AccessLevel", DataTypeIds.Double, ValueRanks.Scalar); - accessLevelAccessAll.WriteMask = AttributeWriteMask.AccessLevel; - accessLevelAccessAll.UserWriteMask = AttributeWriteMask.AccessLevel; - variables.Add(accessLevelAccessAll); - - BaseDataVariableState arrayDimensionsAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "ArrayDimensions", "ArrayDimensions", DataTypeIds.Double, - ValueRanks.Scalar); - arrayDimensionsAccessLevel.WriteMask = AttributeWriteMask.ArrayDimensions; - arrayDimensionsAccessLevel.UserWriteMask = AttributeWriteMask.ArrayDimensions; - variables.Add(arrayDimensionsAccessLevel); - - BaseDataVariableState browseNameAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "BrowseName", "BrowseName", DataTypeIds.Double, ValueRanks.Scalar); - browseNameAccessLevel.WriteMask = AttributeWriteMask.BrowseName; - browseNameAccessLevel.UserWriteMask = AttributeWriteMask.BrowseName; - variables.Add(browseNameAccessLevel); - - BaseDataVariableState containsNoLoopsAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "ContainsNoLoops", "ContainsNoLoops", DataTypeIds.Double, - ValueRanks.Scalar); - containsNoLoopsAccessLevel.WriteMask = AttributeWriteMask.ContainsNoLoops; - containsNoLoopsAccessLevel.UserWriteMask = AttributeWriteMask.ContainsNoLoops; - variables.Add(containsNoLoopsAccessLevel); - - BaseDataVariableState dataTypeAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "DataType", "DataType", DataTypeIds.Double, ValueRanks.Scalar); - dataTypeAccessLevel.WriteMask = AttributeWriteMask.DataType; - dataTypeAccessLevel.UserWriteMask = AttributeWriteMask.DataType; - variables.Add(dataTypeAccessLevel); - - BaseDataVariableState descriptionAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "Description", "Description", DataTypeIds.Double, ValueRanks.Scalar); - descriptionAccessLevel.WriteMask = AttributeWriteMask.Description; - descriptionAccessLevel.UserWriteMask = AttributeWriteMask.Description; - variables.Add(descriptionAccessLevel); - - BaseDataVariableState eventNotifierAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "EventNotifier", "EventNotifier", DataTypeIds.Double, ValueRanks.Scalar); - eventNotifierAccessLevel.WriteMask = AttributeWriteMask.EventNotifier; - eventNotifierAccessLevel.UserWriteMask = AttributeWriteMask.EventNotifier; - variables.Add(eventNotifierAccessLevel); - - BaseDataVariableState executableAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "Executable", "Executable", DataTypeIds.Double, ValueRanks.Scalar); - executableAccessLevel.WriteMask = AttributeWriteMask.Executable; - executableAccessLevel.UserWriteMask = AttributeWriteMask.Executable; - variables.Add(executableAccessLevel); - - BaseDataVariableState historizingAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "Historizing", "Historizing", DataTypeIds.Double, ValueRanks.Scalar); - historizingAccessLevel.WriteMask = AttributeWriteMask.Historizing; - historizingAccessLevel.UserWriteMask = AttributeWriteMask.Historizing; - variables.Add(historizingAccessLevel); - - BaseDataVariableState inverseNameAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "InverseName", "InverseName", DataTypeIds.Double, ValueRanks.Scalar); - inverseNameAccessLevel.WriteMask = AttributeWriteMask.InverseName; - inverseNameAccessLevel.UserWriteMask = AttributeWriteMask.InverseName; - variables.Add(inverseNameAccessLevel); - - BaseDataVariableState isAbstractAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "IsAbstract", "IsAbstract", DataTypeIds.Double, ValueRanks.Scalar); - isAbstractAccessLevel.WriteMask = AttributeWriteMask.IsAbstract; - isAbstractAccessLevel.UserWriteMask = AttributeWriteMask.IsAbstract; - variables.Add(isAbstractAccessLevel); - - BaseDataVariableState minimumSamplingIntervalAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "MinimumSamplingInterval", "MinimumSamplingInterval", DataTypeIds.Double, - ValueRanks.Scalar); - minimumSamplingIntervalAccessLevel.WriteMask = AttributeWriteMask.MinimumSamplingInterval; - minimumSamplingIntervalAccessLevel.UserWriteMask = AttributeWriteMask.MinimumSamplingInterval; - variables.Add(minimumSamplingIntervalAccessLevel); - - BaseDataVariableState nodeClassIntervalAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "NodeClass", "NodeClass", DataTypeIds.Double, ValueRanks.Scalar); - nodeClassIntervalAccessLevel.WriteMask = AttributeWriteMask.NodeClass; - nodeClassIntervalAccessLevel.UserWriteMask = AttributeWriteMask.NodeClass; - variables.Add(nodeClassIntervalAccessLevel); - - BaseDataVariableState nodeIdAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "NodeId", "NodeId", DataTypeIds.Double, ValueRanks.Scalar); - nodeIdAccessLevel.WriteMask = AttributeWriteMask.NodeId; - nodeIdAccessLevel.UserWriteMask = AttributeWriteMask.NodeId; - variables.Add(nodeIdAccessLevel); - - BaseDataVariableState symmetricAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "Symmetric", "Symmetric", DataTypeIds.Double, ValueRanks.Scalar); - symmetricAccessLevel.WriteMask = AttributeWriteMask.Symmetric; - symmetricAccessLevel.UserWriteMask = AttributeWriteMask.Symmetric; - variables.Add(symmetricAccessLevel); - - BaseDataVariableState userAccessLevelAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "UserAccessLevel", "UserAccessLevel", DataTypeIds.Double, - ValueRanks.Scalar); - userAccessLevelAccessLevel.WriteMask = AttributeWriteMask.UserAccessLevel; - userAccessLevelAccessLevel.UserWriteMask = AttributeWriteMask.UserAccessLevel; - variables.Add(userAccessLevelAccessLevel); - - BaseDataVariableState userExecutableAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "UserExecutable", "UserExecutable", DataTypeIds.Double, - ValueRanks.Scalar); - userExecutableAccessLevel.WriteMask = AttributeWriteMask.UserExecutable; - userExecutableAccessLevel.UserWriteMask = AttributeWriteMask.UserExecutable; - variables.Add(userExecutableAccessLevel); - - BaseDataVariableState valueRankAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "ValueRank", "ValueRank", DataTypeIds.Double, ValueRanks.Scalar); - valueRankAccessLevel.WriteMask = AttributeWriteMask.ValueRank; - valueRankAccessLevel.UserWriteMask = AttributeWriteMask.ValueRank; - variables.Add(valueRankAccessLevel); - - BaseDataVariableState writeMaskAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "WriteMask", "WriteMask", DataTypeIds.Double, ValueRanks.Scalar); - writeMaskAccessLevel.WriteMask = AttributeWriteMask.WriteMask; - writeMaskAccessLevel.UserWriteMask = AttributeWriteMask.WriteMask; - variables.Add(writeMaskAccessLevel); - - BaseDataVariableState valueForVariableTypeAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "ValueForVariableType", "ValueForVariableType", DataTypeIds.Double, - ValueRanks.Scalar); - valueForVariableTypeAccessLevel.WriteMask = AttributeWriteMask.ValueForVariableType; - valueForVariableTypeAccessLevel.UserWriteMask = AttributeWriteMask.ValueForVariableType; - variables.Add(valueForVariableTypeAccessLevel); - - BaseDataVariableState allAccessLevel = CreateVariable(folderAttributesAccessAll, - attributesAccessAll + "All", "All", DataTypeIds.Double, ValueRanks.Scalar); - allAccessLevel.WriteMask = AttributeWriteMask.AccessLevel | AttributeWriteMask.ArrayDimensions | - AttributeWriteMask.BrowseName | AttributeWriteMask.ContainsNoLoops | - AttributeWriteMask.DataType | - AttributeWriteMask.Description | AttributeWriteMask.DisplayName | - AttributeWriteMask.EventNotifier | AttributeWriteMask.Executable | - AttributeWriteMask.Historizing | AttributeWriteMask.InverseName | - AttributeWriteMask.IsAbstract | - AttributeWriteMask.MinimumSamplingInterval | - AttributeWriteMask.NodeClass | AttributeWriteMask.NodeId | - AttributeWriteMask.Symmetric | AttributeWriteMask.UserAccessLevel | - AttributeWriteMask.UserExecutable | - AttributeWriteMask.UserWriteMask | - AttributeWriteMask.ValueForVariableType | AttributeWriteMask.ValueRank | - AttributeWriteMask.WriteMask; - allAccessLevel.UserWriteMask = - AttributeWriteMask.AccessLevel | AttributeWriteMask.ArrayDimensions | - AttributeWriteMask.BrowseName | AttributeWriteMask.ContainsNoLoops | - AttributeWriteMask.DataType | - AttributeWriteMask.Description | AttributeWriteMask.DisplayName | - AttributeWriteMask.EventNotifier | AttributeWriteMask.Executable | - AttributeWriteMask.Historizing | AttributeWriteMask.InverseName | - AttributeWriteMask.IsAbstract | - AttributeWriteMask.MinimumSamplingInterval | AttributeWriteMask.NodeClass | - AttributeWriteMask.NodeId | AttributeWriteMask.Symmetric | AttributeWriteMask.UserAccessLevel | - AttributeWriteMask.UserExecutable | - AttributeWriteMask.UserWriteMask | AttributeWriteMask.ValueForVariableType | - AttributeWriteMask.ValueRank | AttributeWriteMask.WriteMask; - variables.Add(allAccessLevel); - - #endregion - - #region AccessUser1 - - FolderState folderAttributesAccessUser1 = - CreateFolder(folderAttributes, "Attributes_AccessUser1", "AccessUser1"); - const string attributesAccessUser1 = "Attributes_AccessUser1_"; - - BaseDataVariableState accessLevelAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "AccessLevel", "AccessLevel", DataTypeIds.Double, ValueRanks.Scalar); - accessLevelAccessAll.WriteMask = AttributeWriteMask.AccessLevel; - accessLevelAccessAll.UserWriteMask = AttributeWriteMask.AccessLevel; - variables.Add(accessLevelAccessAll); - - BaseDataVariableState arrayDimensionsAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "ArrayDimensions", "ArrayDimensions", DataTypeIds.Double, - ValueRanks.Scalar); - arrayDimensionsAccessUser1.WriteMask = AttributeWriteMask.ArrayDimensions; - arrayDimensionsAccessUser1.UserWriteMask = AttributeWriteMask.ArrayDimensions; - variables.Add(arrayDimensionsAccessUser1); - - BaseDataVariableState browseNameAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "BrowseName", "BrowseName", DataTypeIds.Double, ValueRanks.Scalar); - browseNameAccessUser1.WriteMask = AttributeWriteMask.BrowseName; - browseNameAccessUser1.UserWriteMask = AttributeWriteMask.BrowseName; - variables.Add(browseNameAccessUser1); - - BaseDataVariableState containsNoLoopsAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "ContainsNoLoops", "ContainsNoLoops", DataTypeIds.Double, - ValueRanks.Scalar); - containsNoLoopsAccessUser1.WriteMask = AttributeWriteMask.ContainsNoLoops; - containsNoLoopsAccessUser1.UserWriteMask = AttributeWriteMask.ContainsNoLoops; - variables.Add(containsNoLoopsAccessUser1); - - BaseDataVariableState dataTypeAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "DataType", "DataType", DataTypeIds.Double, ValueRanks.Scalar); - dataTypeAccessUser1.WriteMask = AttributeWriteMask.DataType; - dataTypeAccessUser1.UserWriteMask = AttributeWriteMask.DataType; - variables.Add(dataTypeAccessUser1); - - BaseDataVariableState descriptionAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "Description", "Description", DataTypeIds.Double, ValueRanks.Scalar); - descriptionAccessUser1.WriteMask = AttributeWriteMask.Description; - descriptionAccessUser1.UserWriteMask = AttributeWriteMask.Description; - variables.Add(descriptionAccessUser1); - - BaseDataVariableState eventNotifierAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "EventNotifier", "EventNotifier", DataTypeIds.Double, - ValueRanks.Scalar); - eventNotifierAccessUser1.WriteMask = AttributeWriteMask.EventNotifier; - eventNotifierAccessUser1.UserWriteMask = AttributeWriteMask.EventNotifier; - variables.Add(eventNotifierAccessUser1); - - BaseDataVariableState executableAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "Executable", "Executable", DataTypeIds.Double, ValueRanks.Scalar); - executableAccessUser1.WriteMask = AttributeWriteMask.Executable; - executableAccessUser1.UserWriteMask = AttributeWriteMask.Executable; - variables.Add(executableAccessUser1); - - BaseDataVariableState historizingAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "Historizing", "Historizing", DataTypeIds.Double, ValueRanks.Scalar); - historizingAccessUser1.WriteMask = AttributeWriteMask.Historizing; - historizingAccessUser1.UserWriteMask = AttributeWriteMask.Historizing; - variables.Add(historizingAccessUser1); - - BaseDataVariableState inverseNameAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "InverseName", "InverseName", DataTypeIds.Double, ValueRanks.Scalar); - inverseNameAccessUser1.WriteMask = AttributeWriteMask.InverseName; - inverseNameAccessUser1.UserWriteMask = AttributeWriteMask.InverseName; - variables.Add(inverseNameAccessUser1); - - BaseDataVariableState isAbstractAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "IsAbstract", "IsAbstract", DataTypeIds.Double, ValueRanks.Scalar); - isAbstractAccessUser1.WriteMask = AttributeWriteMask.IsAbstract; - isAbstractAccessUser1.UserWriteMask = AttributeWriteMask.IsAbstract; - variables.Add(isAbstractAccessUser1); - - BaseDataVariableState minimumSamplingIntervalAccessUser1 = - CreateVariable(folderAttributesAccessUser1, attributesAccessUser1 + "MinimumSamplingInterval", - "MinimumSamplingInterval", DataTypeIds.Double, ValueRanks.Scalar); - minimumSamplingIntervalAccessUser1.WriteMask = AttributeWriteMask.MinimumSamplingInterval; - minimumSamplingIntervalAccessUser1.UserWriteMask = AttributeWriteMask.MinimumSamplingInterval; - variables.Add(minimumSamplingIntervalAccessUser1); - - BaseDataVariableState nodeClassIntervalAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "NodeClass", "NodeClass", DataTypeIds.Double, ValueRanks.Scalar); - nodeClassIntervalAccessUser1.WriteMask = AttributeWriteMask.NodeClass; - nodeClassIntervalAccessUser1.UserWriteMask = AttributeWriteMask.NodeClass; - variables.Add(nodeClassIntervalAccessUser1); - - BaseDataVariableState nodeIdAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "NodeId", "NodeId", DataTypeIds.Double, ValueRanks.Scalar); - nodeIdAccessUser1.WriteMask = AttributeWriteMask.NodeId; - nodeIdAccessUser1.UserWriteMask = AttributeWriteMask.NodeId; - variables.Add(nodeIdAccessUser1); - - BaseDataVariableState symmetricAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "Symmetric", "Symmetric", DataTypeIds.Double, ValueRanks.Scalar); - symmetricAccessUser1.WriteMask = AttributeWriteMask.Symmetric; - symmetricAccessUser1.UserWriteMask = AttributeWriteMask.Symmetric; - variables.Add(symmetricAccessUser1); - - BaseDataVariableState userAccessUser1AccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "UserAccessUser1", "UserAccessUser1", DataTypeIds.Double, - ValueRanks.Scalar); - userAccessUser1AccessUser1.WriteMask = AttributeWriteMask.UserAccessLevel; - userAccessUser1AccessUser1.UserWriteMask = AttributeWriteMask.UserAccessLevel; - variables.Add(userAccessUser1AccessUser1); - - BaseDataVariableState userExecutableAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "UserExecutable", "UserExecutable", DataTypeIds.Double, - ValueRanks.Scalar); - userExecutableAccessUser1.WriteMask = AttributeWriteMask.UserExecutable; - userExecutableAccessUser1.UserWriteMask = AttributeWriteMask.UserExecutable; - variables.Add(userExecutableAccessUser1); - - BaseDataVariableState valueRankAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "ValueRank", "ValueRank", DataTypeIds.Double, ValueRanks.Scalar); - valueRankAccessUser1.WriteMask = AttributeWriteMask.ValueRank; - valueRankAccessUser1.UserWriteMask = AttributeWriteMask.ValueRank; - variables.Add(valueRankAccessUser1); - - BaseDataVariableState writeMaskAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "WriteMask", "WriteMask", DataTypeIds.Double, ValueRanks.Scalar); - writeMaskAccessUser1.WriteMask = AttributeWriteMask.WriteMask; - writeMaskAccessUser1.UserWriteMask = AttributeWriteMask.WriteMask; - variables.Add(writeMaskAccessUser1); - - BaseDataVariableState valueForVariableTypeAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "ValueForVariableType", "ValueForVariableType", DataTypeIds.Double, - ValueRanks.Scalar); - valueForVariableTypeAccessUser1.WriteMask = AttributeWriteMask.ValueForVariableType; - valueForVariableTypeAccessUser1.UserWriteMask = AttributeWriteMask.ValueForVariableType; - variables.Add(valueForVariableTypeAccessUser1); - - BaseDataVariableState allAccessUser1 = CreateVariable(folderAttributesAccessUser1, - attributesAccessUser1 + "All", "All", DataTypeIds.Double, ValueRanks.Scalar); - allAccessUser1.WriteMask = AttributeWriteMask.AccessLevel | AttributeWriteMask.ArrayDimensions | - AttributeWriteMask.BrowseName | AttributeWriteMask.ContainsNoLoops | - AttributeWriteMask.DataType | - AttributeWriteMask.Description | AttributeWriteMask.DisplayName | - AttributeWriteMask.EventNotifier | AttributeWriteMask.Executable | - AttributeWriteMask.Historizing | AttributeWriteMask.InverseName | - AttributeWriteMask.IsAbstract | - AttributeWriteMask.MinimumSamplingInterval | - AttributeWriteMask.NodeClass | AttributeWriteMask.NodeId | - AttributeWriteMask.Symmetric | AttributeWriteMask.UserAccessLevel | - AttributeWriteMask.UserExecutable | - AttributeWriteMask.UserWriteMask | - AttributeWriteMask.ValueForVariableType | AttributeWriteMask.ValueRank | - AttributeWriteMask.WriteMask; - allAccessUser1.UserWriteMask = - AttributeWriteMask.AccessLevel | AttributeWriteMask.ArrayDimensions | - AttributeWriteMask.BrowseName | AttributeWriteMask.ContainsNoLoops | - AttributeWriteMask.DataType | - AttributeWriteMask.Description | AttributeWriteMask.DisplayName | - AttributeWriteMask.EventNotifier | AttributeWriteMask.Executable | - AttributeWriteMask.Historizing | AttributeWriteMask.InverseName | - AttributeWriteMask.IsAbstract | - AttributeWriteMask.MinimumSamplingInterval | AttributeWriteMask.NodeClass | - AttributeWriteMask.NodeId | AttributeWriteMask.Symmetric | AttributeWriteMask.UserAccessLevel | - AttributeWriteMask.UserExecutable | - AttributeWriteMask.UserWriteMask | AttributeWriteMask.ValueForVariableType | - AttributeWriteMask.ValueRank | AttributeWriteMask.WriteMask; - variables.Add(allAccessUser1); - - #endregion - - #endregion - - #region MyCompany - - FolderState myCompanyFolder = CreateFolder(root, "MyCompany", "MyCompany"); - const string myCompany = "MyCompany_"; - - BaseDataVariableState myCompanyInstructions = CreateVariable(myCompanyFolder, - myCompany + "Instructions", "Instructions", DataTypeIds.String, ValueRanks.Scalar); - myCompanyInstructions.Value = "A place for the vendor to describe their address-space."; - variables.Add(myCompanyInstructions); - - #endregion - } - catch (Exception e) - { - } - - AddPredefinedNode(SystemContext, root); - m_simulationTimer = new Timer(DoSimulation, null, 1000, 1000); - } - } - - private ServiceResult OnWriteInterval(ISystemContext context, NodeState node, ref object value) - { - try - { - m_simulationInterval = (UInt16)value; - - if (m_simulationEnabled) - { - m_simulationTimer.Change(100, (int)m_simulationInterval); - } - - return ServiceResult.Good; - } - catch (Exception e) - { - return ServiceResult.Create(e, StatusCodes.Bad, "Error writing Interval variable."); - } - } - - private ServiceResult OnWriteEnabled(ISystemContext context, NodeState node, ref object value) - { - try - { - m_simulationEnabled = (bool)value; - - if (m_simulationEnabled) - { - m_simulationTimer.Change(100, (int)m_simulationInterval); - } - else - { - m_simulationTimer.Change(100, 0); - } - - return ServiceResult.Good; - } - catch (Exception e) - { - return ServiceResult.Create(e, StatusCodes.Bad, "Error writing Enabled variable."); - } - } - - /// - /// Creates a new folder. - /// - private FolderState CreateFolder(NodeState parent, string path, string name) - { - FolderState folder = new FolderState(parent); - - folder.SymbolicName = name; - folder.ReferenceTypeId = ReferenceTypes.Organizes; - folder.TypeDefinitionId = ObjectTypeIds.FolderType; - folder.NodeId = new NodeId(path, NamespaceIndex); - folder.BrowseName = new QualifiedName(path, NamespaceIndex); - folder.DisplayName = new LocalizedText("en", name); - folder.WriteMask = AttributeWriteMask.None; - folder.UserWriteMask = AttributeWriteMask.None; - folder.EventNotifier = EventNotifiers.None; - - if (parent != null) - { - parent.AddChild(folder); - } - - return folder; - } - - /// - /// Creates a new object. - /// - private BaseObjectState CreateObject(NodeState parent, string path, string name) - { - BaseObjectState folder = new BaseObjectState(parent); - - folder.SymbolicName = name; - folder.ReferenceTypeId = ReferenceTypes.Organizes; - folder.TypeDefinitionId = ObjectTypeIds.BaseObjectType; - folder.NodeId = new NodeId(path, NamespaceIndex); - folder.BrowseName = new QualifiedName(name, NamespaceIndex); - folder.DisplayName = folder.BrowseName.Name; - folder.WriteMask = AttributeWriteMask.None; - folder.UserWriteMask = AttributeWriteMask.None; - folder.EventNotifier = EventNotifiers.None; - - if (parent != null) - { - parent.AddChild(folder); - } - - return folder; - } - - /// - /// Creates a new object type. - /// - private BaseObjectTypeState CreateObjectType(NodeState parent, - IDictionary> externalReferences, string path, string name) - { - BaseObjectTypeState type = new BaseObjectTypeState(); - - type.SymbolicName = name; - type.SuperTypeId = ObjectTypeIds.BaseObjectType; - type.NodeId = new NodeId(path, NamespaceIndex); - type.BrowseName = new QualifiedName(name, NamespaceIndex); - type.DisplayName = type.BrowseName.Name; - type.WriteMask = AttributeWriteMask.None; - type.UserWriteMask = AttributeWriteMask.None; - type.IsAbstract = false; - - IList references = null; - - if (!externalReferences.TryGetValue(ObjectTypeIds.BaseObjectType, out references)) - { - externalReferences[ObjectTypeIds.BaseObjectType] = references = new List(); - } - - references.Add(new NodeStateReference(ReferenceTypes.HasSubtype, false, type.NodeId)); - - if (parent != null) - { - parent.AddReference(ReferenceTypes.Organizes, false, type.NodeId); - type.AddReference(ReferenceTypes.Organizes, true, parent.NodeId); - } - - AddPredefinedNode(SystemContext, type); - return type; - } - - /// - /// Creates a new variable. - /// - private BaseDataVariableState CreateMeshVariable(NodeState parent, string path, string name, - params NodeState[] peers) - { - BaseDataVariableState variable = CreateVariable(parent, path, name, BuiltInType.Double, ValueRanks.Scalar); - - if (peers != null) - { - foreach (NodeState peer in peers) - { - peer.AddReference(ReferenceTypes.HasCause, false, variable.NodeId); - variable.AddReference(ReferenceTypes.HasCause, true, peer.NodeId); - peer.AddReference(ReferenceTypes.HasEffect, true, variable.NodeId); - variable.AddReference(ReferenceTypes.HasEffect, false, peer.NodeId); - } - } - - return variable; - } - - /// - /// Creates a new variable. - /// - private DataItemState CreateDataItemVariable(NodeState parent, string path, string name, BuiltInType dataType, - int valueRank) - { - DataItemState variable = new DataItemState(parent); - variable.ValuePrecision = new PropertyState(variable); - variable.Definition = new PropertyState(variable); - - variable.Create( - SystemContext, - null, - variable.BrowseName, - null, - true); - - variable.SymbolicName = name; - variable.ReferenceTypeId = ReferenceTypes.Organizes; - variable.NodeId = new NodeId(path, NamespaceIndex); - variable.BrowseName = new QualifiedName(path, NamespaceIndex); - variable.DisplayName = new LocalizedText("en", name); - variable.WriteMask = AttributeWriteMask.None; - variable.UserWriteMask = AttributeWriteMask.None; - variable.DataType = (uint)dataType; - variable.ValueRank = valueRank; - variable.AccessLevel = AccessLevels.CurrentReadOrWrite; - variable.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - variable.Historizing = false; - variable.Value = Opc.Ua.TypeInfo.GetDefaultValue((uint)dataType, valueRank, Server.TypeTree); - variable.StatusCode = StatusCodes.Good; - variable.Timestamp = DateTime.UtcNow; - - if (valueRank == ValueRanks.OneDimension) - { - variable.ArrayDimensions = new ReadOnlyList(new List { 0 }); - } - else if (valueRank == ValueRanks.TwoDimensions) - { - variable.ArrayDimensions = new ReadOnlyList(new List { 0, 0 }); - } - - variable.ValuePrecision.Value = 2; - variable.ValuePrecision.AccessLevel = AccessLevels.CurrentReadOrWrite; - variable.ValuePrecision.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - variable.Definition.Value = String.Empty; - variable.Definition.AccessLevel = AccessLevels.CurrentReadOrWrite; - variable.Definition.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - - if (parent != null) - { - parent.AddChild(variable); - } - - return variable; - } - - private DataItemState[] CreateDataItemVariables(NodeState parent, string path, string name, - BuiltInType dataType, int valueRank, UInt16 numVariables) - { - List itemsCreated = new List(); - // create the default name first: - itemsCreated.Add(CreateDataItemVariable(parent, path, name, dataType, valueRank)); - // now to create the remaining NUMBERED items - for (uint i = 0; i < numVariables; i++) - { - string newName = string.Format("{0}{1}", name, i.ToString("000")); - string newPath = string.Format("{0}/Mass/{1}", path, newName); - itemsCreated.Add(CreateDataItemVariable(parent, newPath, newName, dataType, valueRank)); - } //for i - - return (itemsCreated.ToArray()); - } - - private ServiceResult OnWriteDataItem( - ISystemContext context, - NodeState node, - NumericRange indexRange, - QualifiedName dataEncoding, - ref object value, - ref StatusCode statusCode, - ref DateTime timestamp) - { - DataItemState variable = node as DataItemState; - - // verify data type. - Opc.Ua.TypeInfo typeInfo = Opc.Ua.TypeInfo.IsInstanceOfDataType( - value, - variable.DataType, - variable.ValueRank, - context.NamespaceUris, - context.TypeTable); - - if (typeInfo == null || typeInfo == Opc.Ua.TypeInfo.Unknown) - { - return StatusCodes.BadTypeMismatch; - } - - if (typeInfo.BuiltInType != BuiltInType.DateTime) - { - double number = Convert.ToDouble(value); - number = Math.Round(number, (int)variable.ValuePrecision.Value); - value = Opc.Ua.TypeInfo.Cast(number, typeInfo.BuiltInType); - } - - return ServiceResult.Good; - } - - /// - /// Creates a new variable. - /// - private AnalogItemState CreateAnalogItemVariable(NodeState parent, string path, string name, - BuiltInType dataType, int valueRank) - { - return (CreateAnalogItemVariable(parent, path, name, dataType, valueRank, null)); - } - - private AnalogItemState CreateAnalogItemVariable(NodeState parent, string path, string name, - BuiltInType dataType, int valueRank, object initialValues) - { - return (CreateAnalogItemVariable(parent, path, name, dataType, valueRank, initialValues, null)); - } - - private AnalogItemState CreateAnalogItemVariable(NodeState parent, string path, string name, - BuiltInType dataType, int valueRank, object initialValues, Opc.Ua.Range customRange) - { - return CreateAnalogItemVariable(parent, path, name, (uint)dataType, valueRank, initialValues, customRange); - } - - private AnalogItemState CreateAnalogItemVariable(NodeState parent, string path, string name, NodeId dataType, - int valueRank, object initialValues, Opc.Ua.Range customRange) - { - AnalogItemState variable = new AnalogItemState(parent); - variable.BrowseName = new QualifiedName(path, NamespaceIndex); - variable.EngineeringUnits = new PropertyState(variable); - variable.InstrumentRange = new PropertyState(variable); - - variable.Create( - SystemContext, - new NodeId(path, NamespaceIndex), - variable.BrowseName, - null, - true); - - variable.NodeId = new NodeId(path, NamespaceIndex); - variable.SymbolicName = name; - variable.DisplayName = new LocalizedText("en", name); - variable.WriteMask = AttributeWriteMask.None; - variable.UserWriteMask = AttributeWriteMask.None; - variable.ReferenceTypeId = ReferenceTypes.Organizes; - variable.DataType = dataType; - variable.ValueRank = valueRank; - variable.AccessLevel = AccessLevels.CurrentReadOrWrite; - variable.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - variable.Historizing = false; - - if (valueRank == ValueRanks.OneDimension) - { - variable.ArrayDimensions = new ReadOnlyList(new List { 0 }); - } - else if (valueRank == ValueRanks.TwoDimensions) - { - variable.ArrayDimensions = new ReadOnlyList(new List { 0, 0 }); - } - - BuiltInType builtInType = Opc.Ua.TypeInfo.GetBuiltInType(dataType, Server.TypeTree); - - // Simulate a mV Voltmeter - Range newRange = GetAnalogRange(builtInType); - // Using anything but 120,-10 fails a few tests - newRange.High = Math.Min(newRange.High, 120); - newRange.Low = Math.Max(newRange.Low, -10); - variable.InstrumentRange.Value = newRange; - - if (customRange != null) - { - variable.EURange.Value = customRange; - } - else - { - variable.EURange.Value = new Range(100, 0); - } - - if (initialValues == null) - { - variable.Value = Opc.Ua.TypeInfo.GetDefaultValue(dataType, valueRank, Server.TypeTree); - } - else - { - variable.Value = initialValues; - } - - variable.StatusCode = StatusCodes.Good; - variable.Timestamp = DateTime.UtcNow; - // The latest UNECE version (Rev 11, published in 2015) is available here: - // http://www.opcfoundation.org/UA/EngineeringUnits/UNECE/rec20_latest_08052015.zip - variable.EngineeringUnits.Value = - new EUInformation("mV", "millivolt", "http://www.opcfoundation.org/UA/units/un/cefact"); - // The mapping of the UNECE codes to OPC UA(EUInformation.unitId) is available here: - // http://www.opcfoundation.org/UA/EngineeringUnits/UNECE/UNECE_to_OPCUA.csv - variable.EngineeringUnits.Value.UnitId = 12890; // "2Z" - variable.OnWriteValue = OnWriteAnalog; - variable.EURange.OnWriteValue = OnWriteAnalogRange; - variable.EURange.AccessLevel = AccessLevels.CurrentReadOrWrite; - variable.EURange.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - variable.EngineeringUnits.AccessLevel = AccessLevels.CurrentReadOrWrite; - variable.EngineeringUnits.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - variable.InstrumentRange.OnWriteValue = OnWriteAnalogRange; - variable.InstrumentRange.AccessLevel = AccessLevels.CurrentReadOrWrite; - variable.InstrumentRange.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - - if (parent != null) - { - parent.AddChild(variable); - } - - return variable; - } - - /// - /// Creates a new variable. - /// - private DataItemState CreateTwoStateDiscreteItemVariable(NodeState parent, string path, string name, - string trueState, string falseState) - { - TwoStateDiscreteState variable = new TwoStateDiscreteState(parent); - - variable.NodeId = new NodeId(path, NamespaceIndex); - variable.BrowseName = new QualifiedName(path, NamespaceIndex); - variable.DisplayName = new LocalizedText("en", name); - variable.WriteMask = AttributeWriteMask.None; - variable.UserWriteMask = AttributeWriteMask.None; - - variable.Create( - SystemContext, - null, - variable.BrowseName, - null, - true); - - variable.SymbolicName = name; - variable.ReferenceTypeId = ReferenceTypes.Organizes; - variable.DataType = DataTypeIds.Boolean; - variable.ValueRank = ValueRanks.Scalar; - variable.AccessLevel = AccessLevels.CurrentReadOrWrite; - variable.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - variable.Historizing = false; - variable.Value = (bool)GetNewValue(variable); - variable.StatusCode = StatusCodes.Good; - variable.Timestamp = DateTime.UtcNow; - - variable.TrueState.Value = trueState; - variable.TrueState.AccessLevel = AccessLevels.CurrentReadOrWrite; - variable.TrueState.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - - variable.FalseState.Value = falseState; - variable.FalseState.AccessLevel = AccessLevels.CurrentReadOrWrite; - variable.FalseState.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - - if (parent != null) - { - parent.AddChild(variable); - } - - return variable; - } - - /// - /// Creates a new variable. - /// - private DataItemState CreateMultiStateDiscreteItemVariable(NodeState parent, string path, string name, - params string[] values) - { - MultiStateDiscreteState variable = new MultiStateDiscreteState(parent); - - variable.NodeId = new NodeId(path, NamespaceIndex); - variable.BrowseName = new QualifiedName(path, NamespaceIndex); - variable.DisplayName = new LocalizedText("en", name); - variable.WriteMask = AttributeWriteMask.None; - variable.UserWriteMask = AttributeWriteMask.None; - - variable.Create( - SystemContext, - null, - variable.BrowseName, - null, - true); - - variable.SymbolicName = name; - variable.ReferenceTypeId = ReferenceTypes.Organizes; - variable.DataType = DataTypeIds.UInt32; - variable.ValueRank = ValueRanks.Scalar; - variable.AccessLevel = AccessLevels.CurrentReadOrWrite; - variable.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - variable.Historizing = false; - variable.Value = (uint)0; - variable.StatusCode = StatusCodes.Good; - variable.Timestamp = DateTime.UtcNow; - variable.OnWriteValue = OnWriteDiscrete; - - LocalizedText[] strings = new LocalizedText[values.Length]; - - for (int ii = 0; ii < strings.Length; ii++) - { - strings[ii] = values[ii]; - } - - variable.EnumStrings.Value = strings; - variable.EnumStrings.AccessLevel = AccessLevels.CurrentReadOrWrite; - variable.EnumStrings.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - - if (parent != null) - { - parent.AddChild(variable); - } - - return variable; - } - - /// - /// Creates a new UInt32 variable. - /// - private DataItemState CreateMultiStateValueDiscreteItemVariable(NodeState parent, string path, string name, - params string[] enumNames) - { - return CreateMultiStateValueDiscreteItemVariable(parent, path, name, null, enumNames); - } - - /// - /// Creates a new variable. - /// - private DataItemState CreateMultiStateValueDiscreteItemVariable(NodeState parent, string path, string name, - NodeId nodeId, params string[] enumNames) - { - MultiStateValueDiscreteState variable = new MultiStateValueDiscreteState(parent); - - variable.NodeId = new NodeId(path, NamespaceIndex); - variable.BrowseName = new QualifiedName(path, NamespaceIndex); - variable.DisplayName = new LocalizedText("en", name); - variable.WriteMask = AttributeWriteMask.None; - variable.UserWriteMask = AttributeWriteMask.None; - - variable.Create( - SystemContext, - null, - variable.BrowseName, - null, - true); - - variable.SymbolicName = name; - variable.ReferenceTypeId = ReferenceTypes.Organizes; - variable.DataType = (nodeId == null) ? DataTypeIds.UInt32 : nodeId; - variable.ValueRank = ValueRanks.Scalar; - variable.AccessLevel = AccessLevels.CurrentReadOrWrite; - variable.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - variable.Historizing = false; - variable.Value = (uint)0; - variable.StatusCode = StatusCodes.Good; - variable.Timestamp = DateTime.UtcNow; - variable.OnWriteValue = OnWriteValueDiscrete; - - // there are two enumerations for this type: - // EnumStrings = the string representations for enumerated values - // ValueAsText = the actual enumerated value - - // set the enumerated strings - LocalizedText[] strings = new LocalizedText[enumNames.Length]; - for (int ii = 0; ii < strings.Length; ii++) - { - strings[ii] = enumNames[ii]; - } - - // set the enumerated values - EnumValueType[] values = new EnumValueType[enumNames.Length]; - for (int ii = 0; ii < values.Length; ii++) - { - values[ii] = new EnumValueType(); - values[ii].Value = ii; - values[ii].Description = strings[ii]; - values[ii].DisplayName = strings[ii]; - } - - variable.EnumValues.Value = values; - variable.EnumValues.AccessLevel = AccessLevels.CurrentReadOrWrite; - variable.EnumValues.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - variable.ValueAsText.Value = variable.EnumValues.Value[0].DisplayName; - - if (parent != null) - { - parent.AddChild(variable); - } - - return variable; - } - - private ServiceResult OnWriteDiscrete( - ISystemContext context, - NodeState node, - NumericRange indexRange, - QualifiedName dataEncoding, - ref object value, - ref StatusCode statusCode, - ref DateTime timestamp) - { - MultiStateDiscreteState variable = node as MultiStateDiscreteState; - - // verify data type. - Opc.Ua.TypeInfo typeInfo = Opc.Ua.TypeInfo.IsInstanceOfDataType( - value, - variable.DataType, - variable.ValueRank, - context.NamespaceUris, - context.TypeTable); - - if (typeInfo == null || typeInfo == Opc.Ua.TypeInfo.Unknown) - { - return StatusCodes.BadTypeMismatch; - } - - if (indexRange != NumericRange.Empty) - { - return StatusCodes.BadIndexRangeInvalid; - } - - double number = Convert.ToDouble(value); - - if (number >= variable.EnumStrings.Value.Length || number < 0) - { - return StatusCodes.BadOutOfRange; - } - - return ServiceResult.Good; - } - - private ServiceResult OnWriteValueDiscrete( - ISystemContext context, - NodeState node, - NumericRange indexRange, - QualifiedName dataEncoding, - ref object value, - ref StatusCode statusCode, - ref DateTime timestamp) - { - MultiStateValueDiscreteState variable = node as MultiStateValueDiscreteState; - - TypeInfo typeInfo = TypeInfo.Construct(value); - - if (variable == null || - typeInfo == null || - typeInfo == Opc.Ua.TypeInfo.Unknown || - !TypeInfo.IsNumericType(typeInfo.BuiltInType)) - { - return StatusCodes.BadTypeMismatch; - } - - if (indexRange != NumericRange.Empty) - { - return StatusCodes.BadIndexRangeInvalid; - } - - Int32 number = Convert.ToInt32(value); - if (number >= variable.EnumValues.Value.Length || number < 0) - { - return StatusCodes.BadOutOfRange; - } - - if (!node.SetChildValue(context, BrowseNames.ValueAsText, variable.EnumValues.Value[number].DisplayName, - true)) - { - return StatusCodes.BadOutOfRange; - } - - node.ClearChangeMasks(context, true); - - return ServiceResult.Good; - } - - private ServiceResult OnWriteAnalog( - ISystemContext context, - NodeState node, - NumericRange indexRange, - QualifiedName dataEncoding, - ref object value, - ref StatusCode statusCode, - ref DateTime timestamp) - { - AnalogItemState variable = node as AnalogItemState; - - // verify data type. - Opc.Ua.TypeInfo typeInfo = Opc.Ua.TypeInfo.IsInstanceOfDataType( - value, - variable.DataType, - variable.ValueRank, - context.NamespaceUris, - context.TypeTable); - - if (typeInfo == null || typeInfo == Opc.Ua.TypeInfo.Unknown) - { - return StatusCodes.BadTypeMismatch; - } - - // check index range. - if (variable.ValueRank >= 0) - { - if (indexRange != NumericRange.Empty) - { - object target = variable.Value; - ServiceResult result = indexRange.UpdateRange(ref target, value); - - if (ServiceResult.IsBad(result)) - { - return result; - } - - value = target; - } - } - - // check instrument range. - else - { - if (indexRange != NumericRange.Empty) - { - return StatusCodes.BadIndexRangeInvalid; - } - - double number = Convert.ToDouble(value); - - if (variable.InstrumentRange != null && (number < variable.InstrumentRange.Value.Low || - number > variable.InstrumentRange.Value.High)) - { - return StatusCodes.BadOutOfRange; - } - } - - return ServiceResult.Good; - } - - private ServiceResult OnWriteAnalogRange( - ISystemContext context, - NodeState node, - NumericRange indexRange, - QualifiedName dataEncoding, - ref object value, - ref StatusCode statusCode, - ref DateTime timestamp) - { - PropertyState variable = node as PropertyState; - ExtensionObject extensionObject = value as ExtensionObject; - TypeInfo typeInfo = TypeInfo.Construct(value); - - if (variable == null || - extensionObject == null || - typeInfo == null || - typeInfo == Opc.Ua.TypeInfo.Unknown) - { - return StatusCodes.BadTypeMismatch; - } - - Range newRange = extensionObject.Body as Range; - AnalogItemState parent = variable.Parent as AnalogItemState; - if (newRange == null || - parent == null) - { - return StatusCodes.BadTypeMismatch; - } - - if (indexRange != NumericRange.Empty) - { - return StatusCodes.BadIndexRangeInvalid; - } - - TypeInfo parentTypeInfo = TypeInfo.Construct(parent.Value); - Range parentRange = GetAnalogRange(parentTypeInfo.BuiltInType); - if (parentRange.High < newRange.High || - parentRange.Low > newRange.Low) - { - return StatusCodes.BadOutOfRange; - } - - value = newRange; - - return ServiceResult.Good; - } - - /// - /// Creates a new variable. - /// - private BaseDataVariableState CreateVariable(NodeState parent, string path, string name, BuiltInType dataType, - int valueRank) - { - return CreateVariable(parent, path, name, (uint)dataType, valueRank); - } - - /// - /// Creates a new variable. - /// - private BaseDataVariableState CreateVariable(NodeState parent, string path, string name, NodeId dataType, - int valueRank, bool ini = true) - { - BaseDataVariableState variable = new BaseDataVariableState(parent); - - variable.SymbolicName = name; - variable.ReferenceTypeId = ReferenceTypes.Organizes; - variable.TypeDefinitionId = VariableTypeIds.BaseDataVariableType; - variable.NodeId = new NodeId(path, NamespaceIndex); - variable.BrowseName = new QualifiedName(path, NamespaceIndex); - variable.DisplayName = new LocalizedText("en", name); - variable.WriteMask = AttributeWriteMask.DisplayName | AttributeWriteMask.Description; - variable.UserWriteMask = AttributeWriteMask.DisplayName | AttributeWriteMask.Description; - variable.DataType = dataType; - variable.ValueRank = valueRank; - variable.AccessLevel = AccessLevels.CurrentReadOrWrite; - variable.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - variable.Historizing = false; - variable.Value = ini ? GetNewValue(variable) : null; - variable.StatusCode = ini ? StatusCodes.Good : StatusCodes.Bad; - variable.Timestamp = DateTime.UtcNow; - - if (valueRank == ValueRanks.OneDimension) - { - variable.ArrayDimensions = new ReadOnlyList(new List { 0 }); - } - else if (valueRank == ValueRanks.TwoDimensions) - { - variable.ArrayDimensions = new ReadOnlyList(new List { 0, 0 }); - } - - if (parent != null) - { - parent.AddChild(variable); - } - - return variable; - } - - private BaseDataVariableState[] CreateVariables(NodeState parent, string path, string name, - BuiltInType dataType, int valueRank, UInt16 numVariables) - { - return CreateVariables(parent, path, name, (uint)dataType, valueRank, numVariables); - } - - private BaseDataVariableState[] CreateVariables(NodeState parent, string path, string name, NodeId dataType, - int valueRank, UInt16 numVariables) - { - // first, create a new Parent folder for this data-type - FolderState newParentFolder = CreateFolder(parent, path, name); - - List itemsCreated = new List(); - // now to create the remaining NUMBERED items - for (uint i = 0; i < numVariables; i++) - { - string newName = string.Format("{0}_{1}", name, i.ToString("00")); - string newPath = string.Format("{0}_{1}", path, newName); - itemsCreated.Add(CreateVariable(newParentFolder, newPath, newName, dataType, valueRank)); - } - - return (itemsCreated.ToArray()); - } - - /// - /// Creates a new variable. - /// - private BaseDataVariableState CreateDynamicVariable(NodeState parent, string path, string name, - BuiltInType dataType, int valueRank) - { - return CreateDynamicVariable(parent, path, name, (uint)dataType, valueRank); - } - - /// - /// Creates a new variable. - /// - private BaseDataVariableState CreateDynamicVariable(NodeState parent, string path, string name, NodeId dataType, - int valueRank) - { - BaseDataVariableState variable = CreateVariable(parent, path, name, dataType, valueRank); - m_dynamicNodes.Add(variable); - return variable; - } - - /// - /// Creates a new variable. - /// - private void CreateIoTGatewayVariable(NodeState parent, string path, string name, NodeId dataType, - int valueRank) - { - try - { - BaseDataVariableState variable = CreateVariable(parent, path, name, dataType, valueRank, false); - m_iotgatewayNodes.Add(variable); - } - catch (Exception ex) - { - Console.WriteLine($"节点创建失败,{name},{ex}"); - } - } - - - private BaseDataVariableState[] CreateDynamicVariables(NodeState parent, string path, string name, - BuiltInType dataType, int valueRank, uint numVariables) - { - return CreateDynamicVariables(parent, path, name, (uint)dataType, valueRank, numVariables); - } - - private BaseDataVariableState[] CreateDynamicVariables(NodeState parent, string path, string name, - NodeId dataType, int valueRank, uint numVariables) - { - // first, create a new Parent folder for this data-type - FolderState newParentFolder = CreateFolder(parent, path, name); - - List itemsCreated = new List(); - // now to create the remaining NUMBERED items - for (uint i = 0; i < numVariables; i++) - { - string newName = string.Format("{0}_{1}", name, i.ToString("00")); - string newPath = string.Format("{0}_{1}", path, newName); - itemsCreated.Add(CreateDynamicVariable(newParentFolder, newPath, newName, dataType, valueRank)); - } //for i - - return (itemsCreated.ToArray()); - } - - /// - /// Creates a new variable type. - /// - private BaseVariableTypeState CreateVariableType(NodeState parent, - IDictionary> externalReferences, string path, string name, BuiltInType dataType, - int valueRank) - { - BaseDataVariableTypeState type = new BaseDataVariableTypeState(); - - type.SymbolicName = name; - type.SuperTypeId = VariableTypeIds.BaseDataVariableType; - type.NodeId = new NodeId(path, NamespaceIndex); - type.BrowseName = new QualifiedName(name, NamespaceIndex); - type.DisplayName = type.BrowseName.Name; - type.WriteMask = AttributeWriteMask.None; - type.UserWriteMask = AttributeWriteMask.None; - type.IsAbstract = false; - type.DataType = (uint)dataType; - type.ValueRank = valueRank; - type.Value = null; - - IList references = null; - - if (!externalReferences.TryGetValue(VariableTypeIds.BaseDataVariableType, out references)) - { - externalReferences[VariableTypeIds.BaseDataVariableType] = references = new List(); - } - - references.Add(new NodeStateReference(ReferenceTypes.HasSubtype, false, type.NodeId)); - - if (parent != null) - { - parent.AddReference(ReferenceTypes.Organizes, false, type.NodeId); - type.AddReference(ReferenceTypes.Organizes, true, parent.NodeId); - } - - AddPredefinedNode(SystemContext, type); - return type; - } - - /// - /// Creates a new data type. - /// - private DataTypeState CreateDataType(NodeState parent, - IDictionary> externalReferences, string path, string name) - { - DataTypeState type = new DataTypeState(); - - type.SymbolicName = name; - type.SuperTypeId = DataTypeIds.Structure; - type.NodeId = new NodeId(path, NamespaceIndex); - type.BrowseName = new QualifiedName(name, NamespaceIndex); - type.DisplayName = type.BrowseName.Name; - type.WriteMask = AttributeWriteMask.None; - type.UserWriteMask = AttributeWriteMask.None; - type.IsAbstract = false; - - IList references = null; - - if (!externalReferences.TryGetValue(DataTypeIds.Structure, out references)) - { - externalReferences[DataTypeIds.Structure] = references = new List(); - } - - references.Add(new NodeStateReference(ReferenceTypeIds.HasSubtype, false, type.NodeId)); - - if (parent != null) - { - parent.AddReference(ReferenceTypes.Organizes, false, type.NodeId); - type.AddReference(ReferenceTypes.Organizes, true, parent.NodeId); - } - - AddPredefinedNode(SystemContext, type); - return type; - } - - /// - /// Creates a new reference type. - /// - private ReferenceTypeState CreateReferenceType(NodeState parent, - IDictionary> externalReferences, string path, string name) - { - ReferenceTypeState type = new ReferenceTypeState(); - - type.SymbolicName = name; - type.SuperTypeId = ReferenceTypeIds.NonHierarchicalReferences; - type.NodeId = new NodeId(path, NamespaceIndex); - type.BrowseName = new QualifiedName(name, NamespaceIndex); - type.DisplayName = type.BrowseName.Name; - type.WriteMask = AttributeWriteMask.None; - type.UserWriteMask = AttributeWriteMask.None; - type.IsAbstract = false; - type.Symmetric = true; - type.InverseName = name; - - IList references = null; - - if (!externalReferences.TryGetValue(ReferenceTypeIds.NonHierarchicalReferences, out references)) - { - externalReferences[ReferenceTypeIds.NonHierarchicalReferences] = references = new List(); - } - - references.Add(new NodeStateReference(ReferenceTypeIds.HasSubtype, false, type.NodeId)); - - if (parent != null) - { - parent.AddReference(ReferenceTypes.Organizes, false, type.NodeId); - type.AddReference(ReferenceTypes.Organizes, true, parent.NodeId); - } - - AddPredefinedNode(SystemContext, type); - return type; - } - - /// - /// Creates a new view. - /// - private ViewState CreateView(NodeState parent, IDictionary> externalReferences, - string path, string name) - { - ViewState type = new ViewState(); - - type.SymbolicName = name; - type.NodeId = new NodeId(path, NamespaceIndex); - type.BrowseName = new QualifiedName(name, NamespaceIndex); - type.DisplayName = type.BrowseName.Name; - type.WriteMask = AttributeWriteMask.None; - type.UserWriteMask = AttributeWriteMask.None; - type.ContainsNoLoops = true; - - IList references = null; - - if (!externalReferences.TryGetValue(ObjectIds.ViewsFolder, out references)) - { - externalReferences[ObjectIds.ViewsFolder] = references = new List(); - } - - type.AddReference(ReferenceTypeIds.Organizes, true, ObjectIds.ViewsFolder); - references.Add(new NodeStateReference(ReferenceTypeIds.Organizes, false, type.NodeId)); - - if (parent != null) - { - parent.AddReference(ReferenceTypes.Organizes, false, type.NodeId); - type.AddReference(ReferenceTypes.Organizes, true, parent.NodeId); - } - - AddPredefinedNode(SystemContext, type); - return type; - } - - /// - /// Creates a new method. - /// - private MethodState CreateMethod(NodeState parent, string path, string name) - { - MethodState method = new MethodState(parent); - - method.SymbolicName = name; - method.ReferenceTypeId = ReferenceTypeIds.HasComponent; - method.NodeId = new NodeId(path, NamespaceIndex); - method.BrowseName = new QualifiedName(path, NamespaceIndex); - method.DisplayName = new LocalizedText("en", name); - method.WriteMask = AttributeWriteMask.None; - method.UserWriteMask = AttributeWriteMask.None; - method.Executable = true; - method.UserExecutable = true; - - if (parent != null) - { - parent.AddChild(method); - } - - return method; - } - - private ServiceResult OnVoidCall( - ISystemContext context, - MethodState method, - IList inputArguments, - IList outputArguments) - { - return ServiceResult.Good; - } - - private ServiceResult OnAddCall( - ISystemContext context, - MethodState method, - IList inputArguments, - IList outputArguments) - { - // all arguments must be provided. - if (inputArguments.Count < 2) - { - return StatusCodes.BadArgumentsMissing; - } - - try - { - float floatValue = (float)inputArguments[0]; - UInt32 uintValue = (UInt32)inputArguments[1]; - - // set output parameter - outputArguments[0] = (float)(floatValue + uintValue); - return ServiceResult.Good; - } - catch - { - return new ServiceResult(StatusCodes.BadInvalidArgument); - } - } - - private ServiceResult OnMultiplyCall( - ISystemContext context, - MethodState method, - IList inputArguments, - IList outputArguments) - { - // all arguments must be provided. - if (inputArguments.Count < 2) - { - return StatusCodes.BadArgumentsMissing; - } - - try - { - Int16 op1 = (Int16)inputArguments[0]; - UInt16 op2 = (UInt16)inputArguments[1]; - - // set output parameter - outputArguments[0] = (Int32)(op1 * op2); - return ServiceResult.Good; - } - catch - { - return new ServiceResult(StatusCodes.BadInvalidArgument); - } - } - - private ServiceResult OnDivideCall( - ISystemContext context, - MethodState method, - IList inputArguments, - IList outputArguments) - { - // all arguments must be provided. - if (inputArguments.Count < 2) - { - return StatusCodes.BadArgumentsMissing; - } - - try - { - Int32 op1 = (Int32)inputArguments[0]; - UInt16 op2 = (UInt16)inputArguments[1]; - - // set output parameter - outputArguments[0] = (float)((float)op1 / (float)op2); - return ServiceResult.Good; - } - catch - { - return new ServiceResult(StatusCodes.BadInvalidArgument); - } - } - - private ServiceResult OnSubstractCall( - ISystemContext context, - MethodState method, - IList inputArguments, - IList outputArguments) - { - // all arguments must be provided. - if (inputArguments.Count < 2) - { - return StatusCodes.BadArgumentsMissing; - } - - try - { - Int16 op1 = (Int16)inputArguments[0]; - Byte op2 = (Byte)inputArguments[1]; - - // set output parameter - outputArguments[0] = (Int16)(op1 - op2); - return ServiceResult.Good; - } - catch - { - return new ServiceResult(StatusCodes.BadInvalidArgument); - } - } - - private ServiceResult OnHelloCall( - ISystemContext context, - MethodState method, - IList inputArguments, - IList outputArguments) - { - // all arguments must be provided. - if (inputArguments.Count < 1) - { - return StatusCodes.BadArgumentsMissing; - } - - try - { - string op1 = (string)inputArguments[0]; - - // set output parameter - outputArguments[0] = (string)("hello " + op1); - return ServiceResult.Good; - } - catch - { - return new ServiceResult(StatusCodes.BadInvalidArgument); - } - } - - private ServiceResult OnInputCall( - ISystemContext context, - MethodState method, - IList inputArguments, - IList outputArguments) - { - // all arguments must be provided. - if (inputArguments.Count < 1) - { - return StatusCodes.BadArgumentsMissing; - } - - return ServiceResult.Good; - } - - private ServiceResult OnOutputCall( - ISystemContext context, - MethodState method, - IList inputArguments, - IList outputArguments) - { - // all arguments must be provided. - try - { - // set output parameter - outputArguments[0] = (string)("Output"); - return ServiceResult.Good; - } - catch - { - return new ServiceResult(StatusCodes.BadInvalidArgument); - } - } - - private object GetNewValue(BaseVariableState variable) - { - if (m_generator == null) - { - m_generator = new Opc.Ua.Test.DataGenerator(null); - m_generator.BoundaryValueFrequency = 0; - } - - object value = null; - int retryCount = 0; - - while (value == null && retryCount < 10) - { - value = m_generator.GetRandom(variable.DataType, variable.ValueRank, new uint[] { 10 }, - Server.TypeTree); - retryCount++; - } - - return value; - } - - private void DoSimulation(object state) - { - try - { - lock (Lock) - { - foreach (BaseDataVariableState variable in m_dynamicNodes) - { - variable.Value = GetNewValue(variable); - variable.Timestamp = DateTime.UtcNow; - variable.ClearChangeMasks(SystemContext, false); - } - } - } - catch (Exception e) - { - } - } - - /// - /// Frees any resources allocated for the address space. - /// - public override void DeleteAddressSpace() - { - lock (Lock) - { - // TBD - } - } - - /// - /// Returns a unique handle for the node. - /// - protected override NodeHandle GetManagerHandle(ServerSystemContext context, NodeId nodeId, - IDictionary cache) - { - lock (Lock) - { - // quickly exclude nodes that are not in the namespace. - if (!IsNodeIdInNamespace(nodeId)) - { - return null; - } - - NodeState node = null; - - if (!PredefinedNodes.TryGetValue(nodeId, out node)) - { - return null; - } - - NodeHandle handle = new NodeHandle(); - - handle.NodeId = nodeId; - handle.Node = node; - handle.Validated = true; - - return handle; - } - } - - /// - /// Verifies that the specified node exists. - /// - protected override NodeState ValidateNode( - ServerSystemContext context, - NodeHandle handle, - IDictionary cache) - { - // not valid if no root. - if (handle == null) - { - return null; - } - - // check if previously validated. - if (handle.Validated) - { - return handle.Node; - } - - // TBD - - return null; - } - - #endregion - - #region Overrides - - #endregion - - #region Private Fields - - private ReferenceServerConfiguration m_configuration; - private Opc.Ua.Test.DataGenerator m_generator; - private Timer m_simulationTimer; - private UInt16 m_simulationInterval = 1000; - private bool m_simulationEnabled = true; - private List m_dynamicNodes; - public List m_iotgatewayNodes; - - #endregion - - - public override void CreateAddressSpace(IDictionary> externalReferences) - { - lock (Lock) - { - IList references = null; - - if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references)) - { - externalReferences[ObjectIds.ObjectsFolder] = references = new List(); - } - - FolderState root = CreateFolder(null, "IoTGateway", "IoTGateway"); - root.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); - references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, root.NodeId)); - root.EventNotifier = EventNotifiers.SubscribeToEvents; - AddRootNotifier(root); - - List variables = new List(); - - try - { - #region IoTGatewayDevice - - using (var DC = new DataContext(IoTBackgroundService.connnectSetting, IoTBackgroundService.DbType)) - { - foreach (var group in DC.Set().AsNoTracking() - .Where(x => x.DeviceTypeEnum == DeviceTypeEnum.Group).OrderBy(x => x.Index) - .ToList()) - { - FolderState deviceGroupFolder = CreateFolder(root, group.DeviceName, group.DeviceName); - - foreach (var device in DC.Set().AsNoTracking().Where(x => x.ParentId == group.ID) - .Include(x => x.DeviceVariables).Include(x => x.DeviceConfigs) - .OrderBy(x => x.Index).ToList()) - { - FolderState staticFolder = CreateFolder(deviceGroupFolder, device.DeviceName, - device.DeviceName); - foreach (var variable in device.DeviceVariables) - { - //先把变量加进去,都用float有瑕疵,属性先不做, - - CreateIoTGatewayVariable(staticFolder, - $"{group.DeviceName}.{device.DeviceName}.{variable.Name}", $"{variable.Name}", - DataTypeIds.Float, ValueRanks.Scalar); - } - } - } - } - - #endregion - - #region Scalar_Simulation - - FolderState scalarFolder = CreateFolder(root, "常量", "常量"); - FolderState simulationFolder = CreateFolder(scalarFolder, "实时模拟", "实时模拟"); - const string scalarSimulation = "Scalar_Simulation_"; - CreateDynamicVariable(simulationFolder, scalarSimulation + "Boolean", "Boolean", - DataTypeIds.Boolean, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Byte", "Byte", DataTypeIds.Byte, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "ByteString", "ByteString", - DataTypeIds.ByteString, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "DateTime", "DateTime", - DataTypeIds.DateTime, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Double", "Double", DataTypeIds.Double, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Duration", "Duration", - DataTypeIds.Duration, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Float", "Float", DataTypeIds.Float, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Guid", "Guid", DataTypeIds.Guid, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Int16", "Int16", DataTypeIds.Int16, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Int32", "Int32", DataTypeIds.Int32, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Int64", "Int64", DataTypeIds.Int64, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Integer", "Integer", - DataTypeIds.Integer, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "LocaleId", "LocaleId", - DataTypeIds.LocaleId, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "LocalizedText", "LocalizedText", - DataTypeIds.LocalizedText, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "NodeId", "NodeId", DataTypeIds.NodeId, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Number", "Number", DataTypeIds.Number, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "QualifiedName", "QualifiedName", - DataTypeIds.QualifiedName, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "SByte", "SByte", DataTypeIds.SByte, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "String", "String", DataTypeIds.String, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "UInt16", "UInt16", DataTypeIds.UInt16, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "UInt32", "UInt32", DataTypeIds.UInt32, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "UInt64", "UInt64", DataTypeIds.UInt64, - ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "UInteger", "UInteger", - DataTypeIds.UInteger, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "UtcTime", "UtcTime", - DataTypeIds.UtcTime, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "Variant", "Variant", - BuiltInType.Variant, ValueRanks.Scalar); - CreateDynamicVariable(simulationFolder, scalarSimulation + "XmlElement", "XmlElement", - DataTypeIds.XmlElement, ValueRanks.Scalar); - - BaseDataVariableState intervalVariable = CreateVariable(simulationFolder, - scalarSimulation + "Interval", "Interval", DataTypeIds.UInt16, ValueRanks.Scalar); - intervalVariable.Value = m_simulationInterval; - intervalVariable.OnSimpleWriteValue = OnWriteInterval; - - BaseDataVariableState enabledVariable = CreateVariable(simulationFolder, - scalarSimulation + "Enabled", "Enabled", DataTypeIds.Boolean, ValueRanks.Scalar); - enabledVariable.Value = m_simulationEnabled; - enabledVariable.OnSimpleWriteValue = OnWriteEnabled; - - #endregion - - #region Methods - - FolderState methodsFolder = CreateFolder(root, "方法", "方法"); - const string methods = "Methods_"; - - BaseDataVariableState methodsInstructions = CreateVariable(methodsFolder, methods + "Instructions", - "Instructions", DataTypeIds.String, ValueRanks.Scalar); - methodsInstructions.Value = "Contains methods with varying parameter definitions."; - variables.Add(methodsInstructions); - - MethodState voidMethod = CreateMethod(methodsFolder, methods + "Void", "Void"); - voidMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnVoidCall); - - #region Add Method - - MethodState addMethod = CreateMethod(methodsFolder, methods + "Add", "Add"); - // set input arguments - addMethod.InputArguments = new PropertyState(addMethod); - addMethod.InputArguments.NodeId = new NodeId(addMethod.BrowseName.Name + "InArgs", NamespaceIndex); - addMethod.InputArguments.BrowseName = BrowseNames.InputArguments; - addMethod.InputArguments.DisplayName = addMethod.InputArguments.BrowseName.Name; - addMethod.InputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; - addMethod.InputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; - addMethod.InputArguments.DataType = DataTypeIds.Argument; - addMethod.InputArguments.ValueRank = ValueRanks.OneDimension; - - addMethod.InputArguments.Value = new Argument[] - { - new Argument() - { - Name = "Float value", Description = "Float value", DataType = DataTypeIds.Float, - ValueRank = ValueRanks.Scalar - }, - new Argument() - { - Name = "UInt32 value", Description = "UInt32 value", DataType = DataTypeIds.UInt32, - ValueRank = ValueRanks.Scalar - } - }; - - // set output arguments - addMethod.OutputArguments = new PropertyState(addMethod); - addMethod.OutputArguments.NodeId = - new NodeId(addMethod.BrowseName.Name + "OutArgs", NamespaceIndex); - addMethod.OutputArguments.BrowseName = BrowseNames.OutputArguments; - addMethod.OutputArguments.DisplayName = addMethod.OutputArguments.BrowseName.Name; - addMethod.OutputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; - addMethod.OutputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; - addMethod.OutputArguments.DataType = DataTypeIds.Argument; - addMethod.OutputArguments.ValueRank = ValueRanks.OneDimension; - - addMethod.OutputArguments.Value = new Argument[] - { - new Argument() - { - Name = "Add Result", Description = "Add Result", DataType = DataTypeIds.Float, - ValueRank = ValueRanks.Scalar - } - }; - - addMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnAddCall); - - #endregion - - #region Input Method - - MethodState inputMethod = CreateMethod(methodsFolder, methods + "Input", "Input"); - // set input arguments - inputMethod.InputArguments = new PropertyState(inputMethod); - inputMethod.InputArguments.NodeId = - new NodeId(inputMethod.BrowseName.Name + "InArgs", NamespaceIndex); - inputMethod.InputArguments.BrowseName = BrowseNames.InputArguments; - inputMethod.InputArguments.DisplayName = inputMethod.InputArguments.BrowseName.Name; - inputMethod.InputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; - inputMethod.InputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; - inputMethod.InputArguments.DataType = DataTypeIds.Argument; - inputMethod.InputArguments.ValueRank = ValueRanks.OneDimension; - - inputMethod.InputArguments.Value = new Argument[] - { - new Argument() - { - Name = "String value", Description = "String value", DataType = DataTypeIds.String, - ValueRank = ValueRanks.Scalar - } - }; - - inputMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnInputCall); - - #endregion - - #endregion - - #region Contact - - FolderState myCompanyFolder = CreateFolder(root, "联系", "联系"); - const string myCompany = "Contact_"; - - BaseDataVariableState myContactInstructions = CreateVariable(myCompanyFolder, myCompany + "联系方式", - "联系方式", DataTypeIds.String, ValueRanks.Scalar); - myContactInstructions.Value = "https://github.com/iioter/iotgateway."; - variables.Add(myContactInstructions); - - #endregion - } - catch (Exception e) - { - } - - AddPredefinedNode(SystemContext, root); - m_simulationTimer = new Timer(DoSimulation, null, 1000, 1000); - } - } - - public void UpdateNode(string nodeName, object value) - { - try - { - var variable = m_iotgatewayNodes.Where(x => x.NodeId.Identifier.ToString() == nodeName) - .FirstOrDefault(); - if (variable != null) - { - variable.Value = value; - variable.Timestamp = DateTime.UtcNow; - variable.StatusCode = StatusCodes.Good; - variable.ClearChangeMasks(SystemContext, false); - } - } - catch (Exception ex) - { - } - } - } -} \ No newline at end of file diff --git a/Plugins/Plugin/UA.Server/ReferenceServer.cs b/Plugins/Plugin/UA.Server/ReferenceServer.cs deleted file mode 100644 index b87d111..0000000 --- a/Plugins/Plugin/UA.Server/ReferenceServer.cs +++ /dev/null @@ -1,381 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * 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. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Security.Cryptography.X509Certificates; -using Opc.Ua; -using Opc.Ua.Server; - -namespace Quickstarts.ReferenceServer -{ - /// - /// Implements the Quickstart Reference Server. - /// - /// - /// Each server instance must have one instance of a StandardServer object which is - /// responsible for reading the configuration file, creating the endpoints and dispatching - /// incoming requests to the appropriate handler. - /// - /// This sub-class specifies non-configurable metadata such as Product Name and initializes - /// the EmptyNodeManager which provides access to the data exposed by the Server. - /// - public partial class ReferenceServer : ReverseConnectServer - { - #region Overridden Methods - /// - /// Creates the node managers for the server. - /// - /// - /// This method allows the sub-class create any additional node managers which it uses. The SDK - /// always creates a CoreNodeManager which handles the built-in nodes defined by the specification. - /// Any additional NodeManagers are expected to handle application specific nodes. - /// - protected override MasterNodeManager CreateMasterNodeManager(IServerInternal server, ApplicationConfiguration configuration) - { - - - // create the custom node managers. - nodeManagers.Add(new ReferenceNodeManager(server, configuration)); - - if (m_nodeManagerFactory == null || m_nodeManagerFactory.Count == 0) - { - AddDefaultFactories(); - } - - foreach (var nodeManagerFactory in m_nodeManagerFactory) - { - nodeManagers.Add(nodeManagerFactory.Create(server, configuration)); - } - - // create master node manager. - return new MasterNodeManager(server, configuration, null, nodeManagers.ToArray()); - } - - /// - /// Loads the non-configurable properties for the application. - /// - /// - /// These properties are exposed by the server but cannot be changed by administrators. - /// - protected override ServerProperties LoadServerProperties() - { - ServerProperties properties = new ServerProperties(); - - properties.ManufacturerName = "OPC Foundation"; - properties.ProductName = "Quickstart Reference Server"; - properties.ProductUri = "http://opcfoundation.org/Quickstart/ReferenceServer/v1.04"; - properties.SoftwareVersion = Utils.GetAssemblySoftwareVersion(); - properties.BuildNumber = Utils.GetAssemblyBuildNumber(); - properties.BuildDate = Utils.GetAssemblyTimestamp(); - - return properties; - } - - /// - /// Creates the resource manager for the server. - /// - protected override ResourceManager CreateResourceManager(IServerInternal server, ApplicationConfiguration configuration) - { - ResourceManager resourceManager = new ResourceManager(server, configuration); - - System.Reflection.FieldInfo[] fields = typeof(StatusCodes).GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); - - foreach (System.Reflection.FieldInfo field in fields) - { - uint? id = field.GetValue(typeof(StatusCodes)) as uint?; - - if (id != null) - { - resourceManager.Add(id.Value, "en-US", field.Name); - } - } - - return resourceManager; - } - - /// - /// Initializes the server before it starts up. - /// - /// - /// This method is called before any startup processing occurs. The sub-class may update the - /// configuration object or do any other application specific startup tasks. - /// - protected override void OnServerStarting(ApplicationConfiguration configuration) - { - - base.OnServerStarting(configuration); - - // it is up to the application to decide how to validate user identity tokens. - // this function creates validator for X509 identity tokens. - CreateUserIdentityValidators(configuration); - } - - /// - /// Called after the server has been started. - /// - protected override void OnServerStarted(IServerInternal server) - { - base.OnServerStarted(server); - - // request notifications when the user identity is changed. all valid users are accepted by default. - server.SessionManager.ImpersonateUser += new ImpersonateEventHandler(SessionManager_ImpersonateUser); - - try - { - lock (ServerInternal.Status.Lock) - { - // allow a faster sampling interval for CurrentTime node. - ServerInternal.Status.Variable.CurrentTime.MinimumSamplingInterval = 250; - } - } - catch - { } - - } - #endregion - - #region User Validation Functions - /// - /// Creates the objects used to validate the user identity tokens supported by the server. - /// - private void CreateUserIdentityValidators(ApplicationConfiguration configuration) - { - for (int ii = 0; ii < configuration.ServerConfiguration.UserTokenPolicies.Count; ii++) - { - UserTokenPolicy policy = configuration.ServerConfiguration.UserTokenPolicies[ii]; - - // create a validator for a certificate token policy. - if (policy.TokenType == UserTokenType.Certificate) - { - // check if user certificate trust lists are specified in configuration. - if (configuration.SecurityConfiguration.TrustedUserCertificates != null && - configuration.SecurityConfiguration.UserIssuerCertificates != null) - { - CertificateValidator certificateValidator = new CertificateValidator(); - certificateValidator.Update(configuration.SecurityConfiguration).Wait(); - certificateValidator.Update(configuration.SecurityConfiguration.UserIssuerCertificates, - configuration.SecurityConfiguration.TrustedUserCertificates, - configuration.SecurityConfiguration.RejectedCertificateStore); - - // set custom validator for user certificates. - m_userCertificateValidator = certificateValidator.GetChannelValidator(); - } - } - } - } - - /// - /// Called when a client tries to change its user identity. - /// - private void SessionManager_ImpersonateUser(Session session, ImpersonateEventArgs args) - { - // check for a user name token. - UserNameIdentityToken userNameToken = args.NewIdentity as UserNameIdentityToken; - - if (userNameToken != null) - { - args.Identity = VerifyPassword(userNameToken); - - // set AuthenticatedUser role for accepted user/password authentication - args.Identity.GrantedRoleIds.Add(ObjectIds.WellKnownRole_AuthenticatedUser); - - if (args.Identity is SystemConfigurationIdentity) - { - // set ConfigureAdmin role for user with permission to configure server - args.Identity.GrantedRoleIds.Add(ObjectIds.WellKnownRole_ConfigureAdmin); - args.Identity.GrantedRoleIds.Add(ObjectIds.WellKnownRole_SecurityAdmin); - } - - return; - } - - // check for x509 user token. - X509IdentityToken x509Token = args.NewIdentity as X509IdentityToken; - - if (x509Token != null) - { - VerifyUserTokenCertificate(x509Token.Certificate); - args.Identity = new UserIdentity(x509Token); - - // set AuthenticatedUser role for accepted certificate authentication - args.Identity.GrantedRoleIds.Add(ObjectIds.WellKnownRole_AuthenticatedUser); - - return; - } - - // check for anonymous token. - if (args.NewIdentity is AnonymousIdentityToken || args.NewIdentity == null) - { - // allow anonymous authentication and set Anonymous role for this authentication - args.Identity = new UserIdentity(); - args.Identity.GrantedRoleIds.Add(ObjectIds.WellKnownRole_Anonymous); - - return; - } - - // unsuported identity token type. - throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid, - "Not supported user token type: {0}.", args.NewIdentity); - } - - /// - /// Validates the password for a username token. - /// - private IUserIdentity VerifyPassword(UserNameIdentityToken userNameToken) - { - var userName = userNameToken.UserName; - var password = userNameToken.DecryptedPassword; - if (String.IsNullOrEmpty(userName)) - { - // an empty username is not accepted. - throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid, - "Security token is not a valid username token. An empty username is not accepted."); - } - - if (String.IsNullOrEmpty(password)) - { - // an empty password is not accepted. - throw ServiceResultException.Create(StatusCodes.BadIdentityTokenRejected, - "Security token is not a valid username token. An empty password is not accepted."); - } - - // User with permission to configure server - if (userName == "sysadmin" && password == "demo") - { - return new SystemConfigurationIdentity(new UserIdentity(userNameToken)); - } - - // standard users for CTT verification - if (!((userName == "user1" && password == "password") || - (userName == "user2" && password == "password1"))) - { - // construct translation object with default text. - TranslationInfo info = new TranslationInfo( - "InvalidPassword", - "en-US", - "Invalid username or password.", - userName); - - // create an exception with a vendor defined sub-code. - throw new ServiceResultException(new ServiceResult( - StatusCodes.BadUserAccessDenied, - "InvalidPassword", - LoadServerProperties().ProductUri, - new LocalizedText(info))); - } - - return new UserIdentity(userNameToken); - } - - /// - /// Verifies that a certificate user token is trusted. - /// - private void VerifyUserTokenCertificate(X509Certificate2 certificate) - { - try - { - if (m_userCertificateValidator != null) - { - m_userCertificateValidator.Validate(certificate); - } - else - { - CertificateValidator.Validate(certificate); - } - } - catch (Exception e) - { - TranslationInfo info; - StatusCode result = StatusCodes.BadIdentityTokenRejected; - ServiceResultException se = e as ServiceResultException; - if (se != null && se.StatusCode == StatusCodes.BadCertificateUseNotAllowed) - { - info = new TranslationInfo( - "InvalidCertificate", - "en-US", - "'{0}' is an invalid user certificate.", - certificate.Subject); - - result = StatusCodes.BadIdentityTokenInvalid; - } - else - { - // construct translation object with default text. - info = new TranslationInfo( - "UntrustedCertificate", - "en-US", - "'{0}' is not a trusted user certificate.", - certificate.Subject); - } - - // create an exception with a vendor defined sub-code. - throw new ServiceResultException(new ServiceResult( - result, - info.Key, - LoadServerProperties().ProductUri, - new LocalizedText(info))); - } - } - - private static INodeManagerFactory IsINodeManagerFactoryType(Type type) - { - var nodeManagerTypeInfo = type.GetTypeInfo(); - if (nodeManagerTypeInfo.IsAbstract || - !typeof(INodeManagerFactory).IsAssignableFrom(type)) - { - return null; - } - - return Activator.CreateInstance(type) as INodeManagerFactory; - } - - private void AddDefaultFactories() - { - var assembly = GetType().Assembly; - var factories = assembly.GetExportedTypes().Select(type => IsINodeManagerFactoryType(type)).Where(type => type != null); - m_nodeManagerFactory = new List(); - foreach (var nodeManagerFactory in factories) - { - m_nodeManagerFactory.Add(nodeManagerFactory); - } - } - #endregion - - #region Private Fields - private IList m_nodeManagerFactory; - private ICertificateValidator m_userCertificateValidator; - #endregion - - - public List nodeManagers = new List(); - } -} diff --git a/Plugins/Plugin/UA.Server/ReferenceServerConfiguration.cs b/Plugins/Plugin/UA.Server/ReferenceServerConfiguration.cs deleted file mode 100644 index 7628154..0000000 --- a/Plugins/Plugin/UA.Server/ReferenceServerConfiguration.cs +++ /dev/null @@ -1,82 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * 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. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - -using System.Runtime.Serialization; - -namespace Quickstarts.ReferenceServer -{ - /// - /// Stores the configuration the data access node manager. - /// - [DataContract(Namespace = Namespaces.ReferenceServer)] - public class ReferenceServerConfiguration - { - #region Constructors - /// - /// The default constructor. - /// - public ReferenceServerConfiguration() - { - Initialize(); - } - - /// - /// Initializes the object during deserialization. - /// - [OnDeserializing()] - private void Initialize(StreamingContext context) - { - Initialize(); - } - - /// - /// Sets private members to default values. - /// - private static void Initialize() - { - } - #endregion - - #region Public Properties - /// - /// Whether the user dialog for accepting invalid certificates should be displayed. - /// - [DataMember(Order = 1)] - public bool ShowCertificateValidationDialog - { - get { return m_showCertificateValidationDialog; } - set { m_showCertificateValidationDialog = value; } - } - #endregion - - #region Private Members - private bool m_showCertificateValidationDialog; - #endregion - } -} diff --git a/Plugins/Plugin/UA.Server/UAServer.cs b/Plugins/Plugin/UA.Server/UAServer.cs deleted file mode 100644 index b1cbb7a..0000000 --- a/Plugins/Plugin/UA.Server/UAServer.cs +++ /dev/null @@ -1,267 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * 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. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Opc.Ua; -using Opc.Ua.Configuration; -using Opc.Ua.Server; - -namespace Quickstarts -{ - public class UAServer where T : StandardServer, new() - { - public ApplicationInstance Application => m_application; - public ApplicationConfiguration Configuration => m_application.ApplicationConfiguration; - - public bool AutoAccept { get; set; } - public string Password { get; set; } - - public ExitCode ExitCode { get; private set; } - - /// - /// Ctor of the server. - /// - /// The text output. - public UAServer(TextWriter writer) - { - m_output = writer; - } - - /// - /// Load the application configuration. - /// - public async Task LoadAsync(string applicationName, string configSectionName) - { - try - { - ExitCode = ExitCode.ErrorNotStarted; - - ApplicationInstance.MessageDlg = new ApplicationMessageDlg(m_output); - CertificatePasswordProvider PasswordProvider = new CertificatePasswordProvider(Password); - m_application = new ApplicationInstance { - ApplicationName = applicationName, - ApplicationType = ApplicationType.Server, - ConfigSectionName = configSectionName, - CertificatePasswordProvider = PasswordProvider - }; - - // load the application configuration. - await m_application.LoadApplicationConfiguration(false).ConfigureAwait(false); - - } - catch (Exception ex) - { - throw new ErrorExitException(ex.Message, ExitCode); - } - } - - /// - /// Load the application configuration. - /// - public async Task CheckCertificateAsync(bool renewCertificate) - { - try - { - var config = m_application.ApplicationConfiguration; - if (renewCertificate) - { - //await m_application.DeleteApplicationInstanceCertificate().ConfigureAwait(false); - } - - // check the application certificate. - bool haveAppCertificate = await m_application.CheckApplicationInstanceCertificate(false, minimumKeySize: 0).ConfigureAwait(false); - if (!haveAppCertificate) - { - throw new Exception("Application instance certificate invalid!"); - } - - if (!config.SecurityConfiguration.AutoAcceptUntrustedCertificates) - { - config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation); - } - } - catch (Exception ex) - { - throw new ErrorExitException(ex.Message, ExitCode); - } - } - - /// - /// Start the server. - /// - public async Task StartAsync() - { - try - { - // create the server. - m_server = new T(); - - // start the server - await m_application.Start(m_server).ConfigureAwait(false); - - // save state - ExitCode = ExitCode.ErrorRunning; - - // print endpoint info - var endpoints = m_application.Server.GetEndpoints().Select(e => e.EndpointUrl).Distinct(); - foreach (var endpoint in endpoints) - { - Console.WriteLine(endpoint); - } - - // start the status thread - m_status = Task.Run(StatusThreadAsync); - - // print notification on session events - m_server.CurrentInstance.SessionManager.SessionActivated += EventStatus; - m_server.CurrentInstance.SessionManager.SessionClosing += EventStatus; - m_server.CurrentInstance.SessionManager.SessionCreated += EventStatus; - } - catch (Exception ex) - { - throw new ErrorExitException(ex.Message, ExitCode); - } - } - - /// - /// Stops the server. - /// - public async Task StopAsync() - { - try - { - if (m_server != null) - { - using (T server = m_server) - { - // Stop status thread - m_server = null; - await m_status.ConfigureAwait(false); - - // Stop server and dispose - server.Stop(); - } - } - - ExitCode = ExitCode.Ok; - } - catch (Exception ex) - { - throw new ErrorExitException(ex.Message, ExitCode.ErrorStopping); - } - } - - /// - /// The certificate validator is used - /// if auto accept is not selected in the configuration. - /// - private void CertificateValidator_CertificateValidation(CertificateValidator validator, CertificateValidationEventArgs e) - { - if (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted) - { - if (AutoAccept) - { - Console.WriteLine("Accepted Certificate: [{0}] [{1}]", e.Certificate.Subject, e.Certificate.Thumbprint); - e.Accept = true; - return; - } - } - Console.WriteLine("Rejected Certificate: {0} [{1}] [{2}]", e.Error, e.Certificate.Subject, e.Certificate.Thumbprint); - } - - /// - /// Update the session status. - /// - private void EventStatus(Session session, SessionEventReason reason) - { - m_lastEventTime = DateTime.UtcNow; - PrintSessionStatus(session, reason.ToString()); - } - - /// - /// Output the status of a connected session. - /// - private void PrintSessionStatus(Session session, string reason, bool lastContact = false) - { - lock (session.DiagnosticsLock) - { - StringBuilder item = new StringBuilder(); - item.AppendFormat("{0,9}:{1,20}:", reason, session.SessionDiagnostics.SessionName); - if (lastContact) - { - item.AppendFormat("Last Event:{0:HH:mm:ss}", session.SessionDiagnostics.ClientLastContactTime.ToLocalTime()); - } - else - { - if (session.Identity != null) - { - item.AppendFormat(":{0,20}", session.Identity.DisplayName); - } - item.AppendFormat(":{0}", session.Id); - } - //Console.WriteLine(item.ToString()); - } - } - - /// - /// Status thread, prints connection status every 10 seconds. - /// - private async Task StatusThreadAsync() - { - while (m_server != null) - { - if (DateTime.UtcNow - m_lastEventTime > TimeSpan.FromMilliseconds(10000)) - { - IList sessions = m_server.CurrentInstance.SessionManager.GetSessions(); - for (int ii = 0; ii < sessions.Count; ii++) - { - Session session = sessions[ii]; - PrintSessionStatus(session, "-Status-", true); - } - m_lastEventTime = DateTime.UtcNow; - } - await Task.Delay(1000).ConfigureAwait(false); - } - } - - #region Private Members - private readonly TextWriter m_output; - private ApplicationInstance m_application; - public T m_server; - private Task m_status; - private DateTime m_lastEventTime; - #endregion - } -} - diff --git a/Plugins/Plugin/UAService.cs b/Plugins/Plugin/UAService.cs deleted file mode 100644 index 1e03698..0000000 --- a/Plugins/Plugin/UAService.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Quickstarts; -using Quickstarts.ReferenceServer; - -namespace Plugin -{ - public class UAService :IDisposable - { - string applicationName = "ConsoleReferenceServer"; - string configSectionName = "Quickstarts.ReferenceServer"; - - public UAServer server = null; - - public UAService() - { - server = new UAServer(null) - { - AutoAccept = false, - Password = null - }; - - server.LoadAsync(applicationName, configSectionName).ConfigureAwait(false); - server.CheckCertificateAsync(false).ConfigureAwait(false); - server.StartAsync().ConfigureAwait(false); - } - - public void Dispose() - { - server.StopAsync().ConfigureAwait(false); - } - } -}