public static void Update(this UXRNodeContext context, NodeIdInfo info) { context.ThrowIfNull(nameof(context)); context.NodeId = info.Id; // context.NodeName = info.Name; context.IsConnected = true; }
private bool PublishOneNode(NodeIdInfo nodeIdInfo) { string logPrefix = $"{_logClassPrefix}:PublishOneNode:"; try { int retryCount = 0; int maxRetries = 3; while (retryCount < maxRetries) { VariantCollection inputArguments = new VariantCollection() { nodeIdInfo.Id, TestserverUrl }; CallMethodRequestCollection requests = new CallMethodRequestCollection(); CallMethodResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; CallMethodRequest request = new CallMethodRequest(); request.ObjectId = new NodeId("Methods", 2); request.MethodId = new NodeId("PublishNode", 2); request.InputArguments = inputArguments; requests.Add(request); ResponseHeader responseHeader = _session.Call(null, requests, out results, out diagnosticInfos); if (results[0].StatusCode == StatusCodes.BadSessionNotActivated) { retryCount++; Logger.Warning($"{logPrefix} need to retry to publish node, since session is not yet activated (nodeId: '{nodeIdInfo.Id}', retry: '{retryCount}')"); Task.Delay(MaxShortWaitSec * 1000).Wait(); continue; } if (!nodeIdInfo.Published && StatusCode.IsBad(results[0].StatusCode)) { Logger.Warning($"{logPrefix} failed (nodeId: '{nodeIdInfo.Id}', published: '{nodeIdInfo.Published}')"); return(false); } else { nodeIdInfo.Published = true; Logger.Verbose($"{logPrefix} succeeded (nodeId: '{nodeIdInfo.Id}', error: '{results[0].StatusCode}'"); return(true); } } } catch (Exception e) { Logger.Fatal(e, $"{logPrefix} Exception"); } Logger.Warning($"{logPrefix} failed (nodeId: '{nodeIdInfo.Id}', published: '{nodeIdInfo.Published}')"); return(false); }
private bool UnpublishOneNode(NodeIdInfo nodeIdInfo, string endpointUrl = null) { string logPrefix = $"{_logClassPrefix}:UnpublishOneNode:"; try { VariantCollection inputArguments = new VariantCollection() { nodeIdInfo.Id, endpointUrl ?? TestserverUrl }; CallMethodRequestCollection requests = new CallMethodRequestCollection(); CallMethodResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; CallMethodRequest request = new CallMethodRequest(); request.ObjectId = new NodeId("Methods", 2); request.MethodId = new NodeId("UnpublishNode", 2); request.InputArguments = inputArguments; requests.Add(request); ResponseHeader responseHeader = _session.Call(null, requests, out results, out diagnosticInfos); if (nodeIdInfo.Published && StatusCode.IsBad(results[0].StatusCode)) { Logger.Warning($"{logPrefix} failed (nodeId: '{nodeIdInfo.Id}', published: '{nodeIdInfo.Published}')"); return(false); } else { nodeIdInfo.Published = false; Logger.Verbose($"{logPrefix} succeeded (nodeId: '{nodeIdInfo.Id}', error: '{results[0].StatusCode}'"); return(true); } } catch (Exception e) { Logger.Fatal(e, $"{logPrefix} Exception"); } return(false); }
/// <summary> /// Asynchronous part of the main method of the app. /// </summary> public async static Task MainAsync(string[] args) { Logger = new LoggerConfiguration() .WriteTo.Console() .MinimumLevel.Debug() .CreateLogger(); Logger.Information($"OPC Publisher node configuration tool"); // command line options bool showHelp = false; string iotHubConnectionString = string.Empty; string iotHubPublisherDeviceName = string.Empty; string iotHubPublisherModuleName = string.Empty; Mono.Options.OptionSet options = new Mono.Options.OptionSet { { "h|help", "show this message and exit", h => showHelp = h != null }, { "ic|iotHubConnectionString=", "IoTHub owner or service connectionstring", (string s) => iotHubConnectionString = s }, { "id|iothubdevicename=", "IoTHub device name of the OPC Publisher", (string s) => iotHubPublisherDeviceName = s }, { "im|iothubmodulename=", "IoT Edge module name of the OPC Publisher which runs in the IoT Edge device specified by id/iothubdevicename", (string s) => iotHubPublisherModuleName = s }, { "pc|purgeconfig", "remove all configured nodes before pushing new ones", b => _purgeConfig = b != null }, { "bf|backupfile=", $"the filename to store the existing node configuration of OPC Publisher\nDefault: './{_backupFileName}'", (string l) => _backupFileName = l }, { "nc|nodeconfigfile=", $"the filename of the new node configuration to be set", (string l) => _nodeConfigFileName = l }, { "lf|logfile=", $"the filename of the logfile to use\nDefault: './{_logFileName}'", (string l) => _logFileName = l }, { "ll|loglevel=", $"the loglevel to use (allowed: fatal, error, warn, info, debug, verbose).\nDefault: info", (string l) => { List <string> logLevels = new List <string> { "fatal", "error", "warn", "info", "debug", "verbose" }; if (logLevels.Contains(l.ToLowerInvariant())) { _logLevel = l.ToLowerInvariant(); } else { throw new OptionException("The loglevel must be one of: fatal, error, warn, info, debug, verbose", "loglevel"); } } } }; IList <string> extraArgs = null; try { extraArgs = options.Parse(args); } catch (OptionException e) { // initialize logging InitLogging(); // show message Logger.Fatal(e, "Error in command line options"); // show usage Usage(options, args); return; } // initialize logging InitLogging(); // show usage if requested if (showHelp) { Usage(options); return; } // no extra options if (extraArgs.Count > 0) { for (int i = 1; i < extraArgs.Count; i++) { Logger.Error("Error: Unknown option: {0}", extraArgs[i]); } Usage(options, args); return; } // sanity check parameters if (string.IsNullOrEmpty(iotHubConnectionString) || string.IsNullOrEmpty(iotHubPublisherDeviceName)) { Logger.Fatal("For IoTHub communication an IoTHub connection string and the publisher devicename (and modulename) must be specified."); return; } Logger.Information($"IoTHub connectionstring: {iotHubConnectionString}"); if (string.IsNullOrEmpty(iotHubPublisherModuleName)) { Logger.Information($"OPC Publisher not running in IoT Edge."); Logger.Information($"IoTHub OPC Publisher device name: {iotHubPublisherDeviceName}"); } else { Logger.Information($"OPC Publisher running as IoT Edge module."); Logger.Information($"IoT Edge device name: {iotHubPublisherDeviceName}"); Logger.Information($"OPC Publisher module name: {iotHubPublisherModuleName}"); } CancellationTokenSource cts = new CancellationTokenSource(); CancellationToken ct = cts.Token; // read new configuration if (!string.IsNullOrEmpty(_nodeConfigFileName)) { try { _configurationFileEntries = JsonConvert.DeserializeObject <List <PublisherConfigurationFileEntryLegacyModel> >(File.ReadAllText(_nodeConfigFileName)); } catch (Exception e) { Logger.Fatal(e, $"Error reading configuration file. Exiting..."); return; } Logger.Information($"The configuration file '{_nodeConfigFileName}' to be applied contains {_configurationFileEntries.Count} entries."); } // instantiate OPC Publisher interface Publisher publisher = new Publisher(iotHubConnectionString, iotHubPublisherDeviceName, iotHubPublisherModuleName, MAX_SHORT_WAIT_SEC, MAX_LONG_WAIT_SEC, ct); // read existing configuration List <PublisherConfigurationFileEntryModel> currentConfiguration = new List <PublisherConfigurationFileEntryModel>(); List <string> configuredEndpoints = publisher.GetConfiguredEndpoints(ct); if (configuredEndpoints.Count > 0) { Logger.Information($"OPC Publisher has the following node configuration:"); } else { Logger.Information($"OPC Publisher is not publishing any data."); } foreach (var configuredEndpoint in configuredEndpoints) { List <NodeModel> configuredNodesOnEndpoint = publisher.GetConfiguredNodesOnEndpoint(configuredEndpoint, ct); PublisherConfigurationFileEntryModel configEntry = new PublisherConfigurationFileEntryModel(); configEntry.EndpointUrl = new Uri(configuredEndpoint); List <OpcNodeOnEndpointModel> nodesOnEndpoint = new List <OpcNodeOnEndpointModel>(); Logger.Information($"For endpoint '{configuredEndpoint}' there are {configuredNodesOnEndpoint.Count} nodes configured."); foreach (var configuredNode in configuredNodesOnEndpoint) { Logger.Debug($"Id '{configuredNode.Id}', " + $"OpcPublishingInterval: {(configuredNode.OpcPublishingInterval == null ? "default" : configuredNode.OpcPublishingInterval.ToString())}, " + $"OpcSamplingInterval: {(configuredNode.OpcSamplingInterval == null ? "default" : configuredNode.OpcSamplingInterval.ToString())}"); OpcNodeOnEndpointModel opcNodeOnEndpoint = new OpcNodeOnEndpointModel(); opcNodeOnEndpoint.Id = configuredNode.Id; opcNodeOnEndpoint.OpcSamplingInterval = configuredNode.OpcSamplingInterval; opcNodeOnEndpoint.OpcPublishingInterval = configuredNode.OpcPublishingInterval; nodesOnEndpoint.Add(opcNodeOnEndpoint); } configEntry.OpcNodes = nodesOnEndpoint; currentConfiguration.Add(configEntry); } // save it on request if (!string.IsNullOrEmpty(_backupFileName) && currentConfiguration.Count > 0) { await File.WriteAllTextAsync(_backupFileName, JsonConvert.SerializeObject(currentConfiguration, Formatting.Indented)); Logger.Information($"The existing OPC Publisher node configuration was saved in '{_backupFileName}'"); } // remove existing configuration on request if (_purgeConfig) { publisher.UnpublishAllConfiguredNodes(ct); Logger.Information($"The existing node configuration was purged. OPC Publisher should no longer publish any data."); } // push new configuration, if required if (_configurationFileEntries != null) { var uniqueEndpoints = _configurationFileEntries.Select(e => e.EndpointUrl).Distinct(); Logger.Information($"The new node configuration will now be set in OPC Publisher."); foreach (var uniqueEndpoint in uniqueEndpoints) { var endpointConfigurationfileEntries = _configurationFileEntries.Where(e => e.EndpointUrl == uniqueEndpoint); List <NodeIdInfo> configurationNodeIdInfos = new List <NodeIdInfo>(); foreach (var endpointConfigurationFileEntry in endpointConfigurationfileEntries) { foreach (var opcNode in endpointConfigurationFileEntry.OpcNodes) { Logger.Debug($"Id '{opcNode.Id}', " + $"OpcPublishingInterval: {(opcNode.OpcPublishingInterval == null ? "default" : opcNode.OpcPublishingInterval.ToString())}, " + $"OpcSamplingInterval: {(opcNode.OpcSamplingInterval == null ? "default" : opcNode.OpcSamplingInterval.ToString())}"); NodeIdInfo nodeIdInfo = new NodeIdInfo(opcNode.Id); configurationNodeIdInfos.Add(nodeIdInfo); } } if (!publisher.PublishNodes(configurationNodeIdInfos, ct, uniqueEndpoint.AbsoluteUri)) { Logger.Error($"Not able to send the new node configuration to OPC Publisher."); } } } // done Logger.Information($"Done. Exiting...."); return; }