示例#1
0
        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);
        }
示例#4
0
        /// <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;
        }