/// <summary>
        /// Get the configuration for the module (in this case the OPC-UA Connection String for the Device).
        /// </summary>
        private async Task <ModuleConfig> GetConfiguration(DeviceClient deviceClient)
        {
            // First try to get the config from the Module twin
            var twin = await deviceClient.GetTwinAsync();

            if (twin.Properties.Desired.Contains(OpcUAConnectionStringKey))
            {
                opcUAConnectionString = (string)twin.Properties.Desired[OpcUAConnectionStringKey];
            }

            var moduleConfig = new ModuleConfig(opcUAConnectionString);

            await UpdateDesiredProperties(twin.Properties.Desired, deviceClient, moduleConfig);

            Console.WriteLine(moduleConfig);
            return(moduleConfig);
        }
 private async Task <Session> OpcBoot(ModuleConfig moduleConfig)
 {
     Console.WriteLine($"EdgeOpcUAClient - Message received at {DateTime.Now.ToLongTimeString()}");
     while (true)
     {
         try
         {
             return(await ConnectToServer(moduleConfig.OpcUAConnectionString));
         }
         catch (Exception ex)
         {
             Console.WriteLine($"Message: {ex.Message}");
             Console.WriteLine($"Error on connection to OPC UA endpoint. Retry in {retryInterval.TotalSeconds} seconds");
             await Task.Delay(retryInterval);
         }
     }
 }
        /// <summary>
        /// Initializes the DeviceClient and sets up the callback to receive messages
        /// </summary>
        private async Task <IDisposable> Init(string connectionString)
        {
            await Task.Delay(TimeSpan.FromSeconds(10));

            // Use Mqtt transport settings.
            // The RemoteCertificateValidationCallback needs to be set
            // since the Edge Hub currently uses a self signed SSL certificate.
            ITransportSettings[] settings =
            {
                new MqttTransportSettings(TransportType.Mqtt_Tcp_Only)
                {
                    RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true
                }
            };

            // Open a connection to the Edge runtime
            DeviceClient deviceClient =
                DeviceClient.CreateFromConnectionString(connectionString, settings);
            await deviceClient.OpenAsync();

            Console.WriteLine("EdgeOpcUAClient - Opened module client connection");

            ModuleConfig moduleConfig = await GetConfiguration(deviceClient);

            await deviceClient.SetDesiredPropertyUpdateCallbackAsync((props, context) => UpdateDesiredProperties(props, context, moduleConfig), deviceClient);

            var session = await OpcBoot(moduleConfig);

            await deviceClient.SetInputMessageHandlerAsync(
                "input1",
                (message, context) => SendDataToDevice(deviceClient, session, message, moduleConfig),
                null);

            Console.WriteLine("EdgeOpcUAClient - callback for route \"input1\" registered");

            return(Disposable.Create(() =>
            {
                session.Close();
                session.Dispose();
            }));
        }
        // here you have to implement the message conversion for the OPC device.
        private async Task <MessageResponse> SendDataToDevice(DeviceClient deviceClient, Session session, Message message, ModuleConfig moduleConfig)
        {
            return(await Task.Run(() => {
                byte[] messageBytes = message.GetBytes();
                string messageString = Encoding.UTF8.GetString(messageBytes);
                Console.WriteLine($"Message received: {messageString}");

                // send it to the OPC-UA device using the session.
                // session.Write(null, somevalcol, out _, out _);

                return MessageResponse.Completed;
            }));
        }
        // check for module twin updates. Below is a sample value check
        private async Task UpdateDesiredProperties(TwinCollection desiredproperties, object usercontext, ModuleConfig moduleConfig)
        {
            if (desiredproperties.Contains(OpcUASampleValueKey))
            {
                string value = desiredproperties[OpcUASampleValueKey].ToString();
                if (!string.IsNullOrEmpty(value))
                {
                    moduleConfig.OpcUASampleValue = value;
                }
                Console.WriteLine($"{nameof(ModuleConfig.OpcUASampleValue)}: { moduleConfig.OpcUASampleValue}");
            }

            if (usercontext is DeviceClient deviceClient)
            {
                await deviceClient.UpdateReportedPropertiesAsync(CreateTwinCollectionFromModuleConfig(moduleConfig));
            }
        }
 private TwinCollection CreateTwinCollectionFromModuleConfig(ModuleConfig moduleConfig)
 {
     return(new TwinCollection(JsonConvert.SerializeObject(moduleConfig)));
 }