/// <summary> /// Method to get the list of published nodes. /// </summary> private ServiceResult OnGetListOfPublishedNodesCall(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments) { try { PublishDataSemaphore.Wait(); outputArguments[0] = JsonConvert.SerializeObject(PublisherConfigFileEntries); } finally { PublishDataSemaphore.Release(); } Trace("GetListOfPublishedNodes: Success!"); return(ServiceResult.Good); }
/// <summary> /// Method to remove the node from the subscription and stop publishing telemetry to IoTHub. /// </summary> private ServiceResult OnUnpublishNodeCall(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments) { if (inputArguments[0] == null || inputArguments[1] == null) { Trace("UnpublishNode: Invalid arguments!"); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments!")); } NodeId nodeId = null; Uri endpointUri = null; try { if (string.IsNullOrEmpty(inputArguments[0] as string) || string.IsNullOrEmpty(inputArguments[1] as string)) { Trace($"UnpublishNode: Arguments (0 (nodeId), 1 (endpointUrl)) are not valid strings!"); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments as strings!")); } nodeId = inputArguments[0] as string; endpointUri = new Uri(inputArguments[1] as string); } catch (UriFormatException) { Trace($"UnpublishNode: The endpointUrl is invalid '{inputArguments[1] as string}'!"); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA endpoint URL as second argument!")); } // find the session and stop monitoring the node. try { if (PublisherShutdownInProgress) { return(ServiceResult.Create(StatusCodes.BadUnexpectedError, $"Publisher shutdown in progress.")); } // find the session we need to monitor the node OpcSession opcSession = null; try { OpcSessionsSemaphore.Wait(); opcSession = OpcSessions.FirstOrDefault(s => s.EndpointUri == endpointUri); } catch { opcSession = null; } finally { OpcSessionsSemaphore.Release(); } if (opcSession == null) { // do nothing if there is no session for this endpoint. Trace($"UnpublishNode: Session for endpoint '{endpointUri.OriginalString}' not found."); return(ServiceResult.Create(StatusCodes.BadSessionIdInvalid, "Session for endpoint of published node not found!")); } else { Trace($"UnpublishNode: Session found for endpoint '{endpointUri.OriginalString}'"); } // remove the node from the sessions monitored items list. opcSession.TagNodeForMonitoringStop(nodeId); Trace("UnpublishNode: Requested to stop monitoring of node."); // remove node from persisted config file try { PublishDataSemaphore.Wait(); var entryToRemove = PublisherConfigFileEntries.Find(l => l.NodeId == nodeId && l.EndpointUri == endpointUri); PublisherConfigFileEntries.Remove(entryToRemove); File.WriteAllText(NodesToPublishAbsFilename, JsonConvert.SerializeObject(PublisherConfigFileEntries)); } finally { PublishDataSemaphore.Release(); } } catch (Exception e) { Trace(e, $"UnpublishNode: Exception while trying to configure publishing node '{nodeId.ToString()}'"); return(ServiceResult.Create(e, StatusCodes.BadUnexpectedError, $"Unexpected error publishing node: {e.Message}")); } return(ServiceResult.Good); }
/// <summary> /// Method to start monitoring a node and publish the data to IoTHub. /// </summary> private ServiceResult OnPublishNodeCall(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments) { if (inputArguments[0] == null || inputArguments[1] == null) { Trace("PublishNode: Invalid Arguments when trying to publish a node."); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments!")); } NodeToPublishConfig nodeToPublish; NodeId nodeId = null; Uri endpointUri = null; try { if (string.IsNullOrEmpty(inputArguments[0] as string) || string.IsNullOrEmpty(inputArguments[1] as string)) { Trace($"PublishNode: Arguments (0 (nodeId), 1 (endpointUrl)) are not valid strings!"); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments as strings!")); } nodeId = NodeId.Parse(inputArguments[0] as string); endpointUri = new Uri(inputArguments[1] as string); nodeToPublish = new NodeToPublishConfig(nodeId, endpointUri, OpcSamplingInterval, OpcPublishingInterval); } catch (UriFormatException) { Trace($"PublishNode: The EndpointUri has an invalid format '{inputArguments[1] as string}'!"); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA endpoint URL as second argument!")); } catch (Exception e) { Trace(e, $"PublishNode: The NodeId has an invalid format '{inputArguments[0] as string}'!"); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA NodeId in 'ns=' syntax as first argument!")); } // find/create a session to the endpoint URL and start monitoring the node. try { if (PublisherShutdownInProgress) { return(ServiceResult.Create(StatusCodes.BadUnexpectedError, $"Publisher shutdown in progress.")); } // find the session we need to monitor the node OpcSession opcSession = null; try { OpcSessionsSemaphore.Wait(); opcSession = OpcSessions.FirstOrDefault(s => s.EndpointUri == nodeToPublish.EndpointUri); // add a new session. if (opcSession == null) { // create new session info. opcSession = new OpcSession(nodeToPublish.EndpointUri, OpcSessionCreationTimeout); OpcSessions.Add(opcSession); Trace($"PublishNode: No matching session found for endpoint '{nodeToPublish.EndpointUri.OriginalString}'. Requested to create a new one."); } else { Trace($"PublishNode: Session found for endpoint '{nodeToPublish.EndpointUri.OriginalString}'"); } // add the node info to the subscription with the default publishing interval opcSession.AddNodeForMonitoring(OpcPublishingInterval, OpcSamplingInterval, nodeToPublish.NodeId); Trace($"PublishNode: Requested to monitor item with NodeId '{nodeToPublish.NodeId.ToString()}' (PublishingInterval: {OpcPublishingInterval}, SamplingInterval: {OpcSamplingInterval})"); } finally { OpcSessionsSemaphore.Release(); } // update our data try { PublishDataSemaphore.Wait(); PublishConfig.Add(nodeToPublish); // add it also to the publish file var publisherConfigFileEntry = new PublisherConfigFileEntry() { EndpointUri = endpointUri, NodeId = nodeId }; PublisherConfigFileEntries.Add(publisherConfigFileEntry); File.WriteAllText(NodesToPublishAbsFilename, JsonConvert.SerializeObject(PublisherConfigFileEntries)); } finally { PublishDataSemaphore.Release(); } return(ServiceResult.Good); } catch (Exception e) { Trace(e, $"PublishNode: Exception while trying to configure publishing node '{nodeToPublish.NodeId.ToString()}'"); return(ServiceResult.Create(e, StatusCodes.BadUnexpectedError, $"Unexpected error publishing node: {e.Message}")); } }