Example #1
0
        /// <summary>
        /// Adds the disconnected handler and the reconnect functionality to the client.
        /// </summary>
        /// <param name="options">The configuration option.</param>
        private void AddDisconnectedHandler(SparkplugNodeOptions options)
        {
            this.Client.UseDisconnectedHandler(
                async e =>
            {
                // Todo: Use the metrics correctly.
                //// Set all states to unknown as we are disconnected
                //foreach (var nodeState in this.DeviceStatesPayloadA)
                //{
                //    var value = this.DeviceStatesPayloadA[nodeState.Key];
                //    value.ConnectionStatus = SparkplugConnectionStatus.Unknown;
                //    this.DeviceStatesPayloadA[nodeState.Key] = value;
                //}

                //// Set all states to unknown as we are disconnected
                //foreach (var nodeState in this.DeviceStatesPayloadB)
                //{
                //    var value = this.DeviceStatesPayloadB[nodeState.Key];
                //    value.ConnectionStatus = SparkplugConnectionStatus.Unknown;
                //    this.DeviceStatesPayloadB[nodeState.Key] = value;
                //}

                // Wait until the disconnect interval is reached
                await Task.Delay(options.ReconnectInterval);

                // Connect, subscribe to incoming messages and send a state message
                await this.ConnectInternal(options);
                await this.SubscribeInternal(options);
                await this.PublishInternal(options);
            });
        }
Example #2
0
        /// <summary>
        /// Subscribes the client to the node subscribe topics.
        /// </summary>
        /// <param name="options">The configuration option.</param>
        /// <returns>A <see cref="Task"/> representing any asynchronous operation.</returns>
        private async Task SubscribeInternal(SparkplugNodeOptions options)
        {
            var nodeCommandSubscribeTopic = this.TopicGenerator.GetNodeCommandSubscribeTopic(this.NameSpace, options.GroupIdentifier, options.EdgeNodeIdentifier);

            await this.Client.SubscribeAsync(nodeCommandSubscribeTopic, MqttQualityOfServiceLevel.AtLeastOnce);

            var deviceCommandSubscribeTopic = this.TopicGenerator.GetWildcardDeviceCommandSubscribeTopic(this.NameSpace, options.GroupIdentifier, options.EdgeNodeIdentifier);

            await this.Client.SubscribeAsync(deviceCommandSubscribeTopic, MqttQualityOfServiceLevel.AtLeastOnce);

            var stateSubscribeTopic = this.TopicGenerator.GetStateSubscribeTopic(options.ScadaHostIdentifier);

            await this.Client.SubscribeAsync(stateSubscribeTopic, MqttQualityOfServiceLevel.AtLeastOnce);
        }
Example #3
0
        /// <summary>
        /// Loads the messages used by the the Sparkplug application.
        /// </summary>
        /// <param name="options">The configuration option.</param>
        private void LoadMessages(SparkplugNodeOptions options)
        {
            this.willMessage = this.MessageGenerator.CreateSparkplugMessage(
                this.NameSpace,
                options.GroupIdentifier,
                SparkplugMessageType.NodeDeath,
                options.EdgeNodeIdentifier,
                null);

            this.nodeOnlineMessage = this.MessageGenerator.CreateSparkplugMessage(
                this.NameSpace,
                options.GroupIdentifier,
                SparkplugMessageType.NodeBirth,
                options.EdgeNodeIdentifier,
                null);
        }
Example #4
0
        /// <summary>
        /// Connects the Sparkplug node to the MQTT broker.
        /// </summary>
        /// <param name="options">The configuration option.</param>
        /// <returns>A <see cref="Task"/> representing any asynchronous operation.</returns>
        private async Task ConnectInternal(SparkplugNodeOptions options)
        {
            options.CancellationToken ??= CancellationToken.None;

            var builder = new MqttClientOptionsBuilder()
                          .WithClientId(options.ClientId)
                          .WithCredentials(options.UserName, options.Password)
                          .WithCleanSession(false)
                          .WithProtocolVersion(MqttProtocolVersion.V311);

            if (options.UseTls)
            {
                builder.WithTls();
            }

            if (options.WebSocketParameters is null)
            {
                builder.WithTcpServer(options.BrokerAddress, options.Port);
            }
            else
            {
                builder.WithWebSocketServer(options.BrokerAddress, options.WebSocketParameters);
            }

            if (options.ProxyOptions != null)
            {
                builder.WithProxy(
                    options.ProxyOptions.Address,
                    options.ProxyOptions.Username,
                    options.ProxyOptions.Password,
                    options.ProxyOptions.Domain,
                    options.ProxyOptions.BypassOnLocal);
            }

            if (this.willMessage != null)
            {
                builder.WithWillMessage(this.willMessage);
            }

            this.ClientOptions = builder.Build();

            await this.Client.ConnectAsync(this.ClientOptions, options.CancellationToken.Value);
        }
Example #5
0
        /// <summary>
        /// Starts the Sparkplug node.
        /// </summary>
        /// <param name="options">The configuration option.</param>
        /// <returns>A <see cref="Task"/> representing any asynchronous operation.</returns>
        public async Task Start(SparkplugNodeOptions options)
        {
            // Clear states
            this.DeviceStatesPayloadA.Clear();
            this.DeviceStatesPayloadB.Clear();

            // Load messages
            this.LoadMessages(options);

            // Add handlers
            this.AddDisconnectedHandler(options);
            this.AddMessageReceivedHandler();

            // Connect, subscribe to incoming messages and send a state message
            await this.ConnectInternal(options);

            await this.SubscribeInternal(options);

            await this.PublishInternal(options);
        }
Example #6
0
 /// <summary>
 /// Publishes data to the MQTT broker.
 /// </summary>
 /// <param name="options">The configuration option.</param>
 /// <returns>A <see cref="Task"/> representing any asynchronous operation.</returns>
 private async Task PublishInternal(SparkplugNodeOptions options)
 {
     options.CancellationToken ??= CancellationToken.None;
     await this.Client.PublishAsync(this.nodeOnlineMessage, options.CancellationToken.Value);
 }