Ejemplo n.º 1
0
        public static async Task RunSample(X509Certificate2 certificate)
        {
            using (var security = new SecurityProviderX509Certificate(certificate))
                // using (var transport = new ProvisioningTransportHandlerHttp())
                //using (var transport = new ProvisioningTransportHandlerAmqp(TransportFallbackType.TcpOnly))
                using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly))
                {
                    ProvisioningDeviceClient provClient =
                        ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, s_idScope, security, transport);

                    Console.WriteLine($"RegistrationID = {security.GetRegistrationID()}");
                    Console.Write("ProvisioningClient RegisterAsync . . . ");
                    DeviceRegistrationResult result = await provClient.RegisterAsync();

                    Console.WriteLine($"{result.Status}");
                    Console.WriteLine($"ProvisioningClient AssignedHub: {result.AssignedHub}; DeviceID: {result.DeviceId}");

                    if (result.Status != ProvisioningRegistrationStatusType.Assigned)
                    {
                        return;
                    }

                    IAuthenticationMethod auth = new DeviceAuthenticationWithX509Certificate(result.DeviceId, certificate);
                    iotClient = DeviceClient.Create(result.AssignedHub, auth);

                    Console.WriteLine($"Now {deviceID} can start sending messages to assigned IoT Hub: {result.AssignedHub}");

                    await iotClient.OpenAsync();

                    SendDeviceToCloudMessagesAsync();


                    Console.ReadLine();
                }
        }
Ejemplo n.º 2
0
        protected virtual async Task <DeviceRegistrationResult> RegisterDeviceAsync(
            string dpsGlobalDeviceEndpoint,
            string dpsIdScope)
        {
            DeviceRegistrationResult result = null;

            using (var security =
                       new SecurityProviderX509Certificate(
                           this.HardwareSecurityModel.DeviceLeafCert))
                using (var transport =
                           new ProvisioningTransportHandlerMqtt(
                               TransportFallbackType.TcpOnly))
                {
                    ProvisioningDeviceClient provClient =
                        ProvisioningDeviceClient.Create(
                            dpsGlobalDeviceEndpoint,
                            dpsIdScope,
                            security,
                            transport);

                    result = await provClient.RegisterAsync().ConfigureAwait(false);
                }

            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Register a single device with the device provisioning service.
        /// </summary>
        /// <param name="enrollmentKey">Group Enrollment Key</param>
        /// <param name="idScope">DPS Service ID Scope</param>
        /// <param name="deviceId">Device Id of the device being registered</param>
        /// <returns></returns>
        public async static Task <SmartMeterDevice> RegisterDeviceAsync(string enrollmentKey, string idScope, string deviceId)
        {
            var globalEndpoint      = "global.azure-devices-provisioning.net";
            SmartMeterDevice device = null;

            //TODO: 1. Derive a device key from a combination of the group enrollment key and the device id
            //var primaryKey = ...

            //TODO: 2. Create symmetric key with the generated primary key
            //using (var security = ...
            using (var transportHandler = new ProvisioningTransportHandlerMqtt())
            {
                //TODO: 3. Create a Provisioning Device Client
                //var client = ...

                //TODO: 4. Register the device using the symmetric key and MQTT
                //DeviceRegistrationResult result = ...

                //TODO: 5. Populate the device provisioning details
                //device = new SmartMeterDevice()...
            }

            //return the device
            return(device);
        }
Ejemplo n.º 4
0
        public async Task ProvisioningDeviceClient_RegisterAsyncInvalidServiceCertificateMqttWs_Fails()
        {
            using var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.WebSocketOnly);
            ProvisioningTransportException exception = await Assert.ThrowsExceptionAsync <ProvisioningTransportException>(
                () => TestInvalidServiceCertificate(transport)).ConfigureAwait(false);

            Assert.IsInstanceOfType(exception.InnerException.InnerException.InnerException, typeof(AuthenticationException));
        }
Ejemplo n.º 5
0
        private static string ProvisionDevice(string scope, string deviceId, string primaryKey)
        {
            Console.Write("Provisioning device...");

            using var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly);
            var security   = new SecurityProviderSymmetricKey(deviceId, primaryKey, null);
            var provClient = ProvisioningDeviceClient.Create(GlobalProvisionEndPoint, scope, security, transport);
            var result     = provClient.RegisterAsync().GetAwaiter().GetResult();

            Console.WriteLine(" successfully provisioned");
            return(result.AssignedHub);
        }
Ejemplo n.º 6
0
        public static async Task <DeviceRegistrationResult> RegisterDeviceAsync(SecurityProviderSymmetricKey security, Device dev)
        {
            // Console.WriteLine("Register device...");
            using var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly);
            var provClient =
                ProvisioningDeviceClient.Create(dev.IoTGlobalDeviceEndpoint, dev.IoTDeviceScopeId, security, transport);
            // Console.WriteLine($"RegistrationID = {security.GetRegistrationID()}");
            // Console.Write("ProvisioningClient RegisterAsync...");
            var result = await provClient.RegisterAsync();

            // Console.WriteLine($"ProvisioningClient Stauts: {result.Status}, AssignedHub: {result.AssignedHub}; DeviceID: {result.DeviceId}");
            return(result);
        }
Ejemplo n.º 7
0
        // Provision a device via DPS, by sending the PnP model Id as DPS payload.
        private static async Task <DeviceRegistrationResult> ProvisionDeviceAsync(Parameters parameters, CancellationToken cancellationToken)
        {
            SecurityProvider             symmetricKeyProvider = new SecurityProviderSymmetricKey(parameters.DeviceId, parameters.DeviceSymmetricKey, null);
            ProvisioningTransportHandler mqttTransportHandler = new ProvisioningTransportHandlerMqtt();
            var pdc = ProvisioningDeviceClient.Create(parameters.DpsEndpoint, parameters.DpsIdScope, symmetricKeyProvider, mqttTransportHandler);

            var pnpPayload = new ProvisioningRegistrationAdditionalData
            {
                JsonData = $"{{ \"modelId\": \"{ModelId}\" }}",
            };

            return(await pdc.RegisterAsync(pnpPayload, cancellationToken));
        }
        static async Task Main(string[] args)
        {
            using (var security = new SecurityProviderSymmetricKey(registrationId, primaryKey, secondaryKey))
                using (var transport = new ProvisioningTransportHandlerMqtt())
                {
                    ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, idScope, security, transport);
                    var pnpPayload = new ProvisioningRegistrationAdditionalData
                    {
                        JsonData = $"{{ \"modelId\": \"{ModelId}\" }}",
                    };

                    DeviceRegistrationResult result = await provClient.RegisterAsync(pnpPayload);

                    IAuthenticationMethod auth = new DeviceAuthenticationWithRegistrySymmetricKey(result.DeviceId, (security as SecurityProviderSymmetricKey).GetPrimaryKey());

                    using (iotClient = DeviceClient.Create(result.AssignedHub, auth, TransportType.Mqtt))
                    {
                        await iotClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChangedAsync, null).ConfigureAwait(false); // callback for Device Twin updates
                        await DeviceTwinGetInitialState(iotClient);                                                                       // Get current cloud state of the device twin

                        while (true)
                        {
                            if (_temperature.IsAvailable)
                            {
                                try
                                {
                                    temperature = Math.Round(_temperature.Temperature.DegreesCelsius, 2);

                                    Console.WriteLine($"The CPU temperature is {temperature}");

                                    await SendMsgIotHub(iotClient, temperature);

                                    roomState = (int)temperature > targetTemperature ? RoomAction.Cooling : (int)temperature < targetTemperature ? RoomAction.Heating : RoomAction.Green;
                                    await UpdateRoomAction(roomState);

                                    if (temperature > maxTemperature)
                                    {
                                        maxTemperature = temperature;
                                        await UpdateDeviceTwin("maxTempSinceLastReboot", maxTemperature);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine("exception msg: " + ex.Message);
                                }
                            }
                            Thread.Sleep(2000); // sleep for 2 seconds
                        }
                    }
                }
        }
Ejemplo n.º 9
0
        internal static async Task <DeviceClient> ProvisionDeviceWithCertAsync(string scopeId, string X509LocatorString, string modelId, ILogger log)
        {
            using (var transport = new ProvisioningTransportHandlerMqtt())
            {
                var cert = X509Loader.GetCertFromConnectionString(X509LocatorString, log);
                using (var security = new SecurityProviderX509Certificate(cert))
                {
                    DeviceRegistrationResult provResult;
                    var provClient = ProvisioningDeviceClient.Create("global.azure-devices-provisioning.net", scopeId, security, transport);
                    if (!String.IsNullOrEmpty(modelId))
                    {
                        provResult = await provClient.RegisterWithModelAsync(modelId, log);
                    }
                    else
                    {
                        provResult = await provClient.RegisterAsync().ConfigureAwait(false);
                    }

                    log.LogInformation($"Provioning Result. Status [{provResult.Status}] SubStatus [{provResult.Substatus}]");

                    if (provResult.Status == ProvisioningRegistrationStatusType.Assigned)
                    {
                        log.LogWarning($"Device {provResult.DeviceId} in Hub {provResult.AssignedHub}");
                        log.LogInformation($"LastRefresh {provResult.LastUpdatedDateTimeUtc} RegistrationId {provResult.RegistrationId}");
                        Rido.DeviceClientFactory.Instance.HostName = provResult.AssignedHub;
                        var    csBuilder        = IotHubConnectionStringBuilder.Create(provResult.AssignedHub, new DeviceAuthenticationWithX509Certificate(provResult.DeviceId, security.GetAuthenticationCertificate()));
                        string connectionString = csBuilder.ToString();

                        DeviceClient client;
                        if (string.IsNullOrEmpty(modelId))
                        {
                            client = DeviceClient.Create(provResult.AssignedHub, new DeviceAuthenticationWithX509Certificate(provResult.DeviceId, security.GetAuthenticationCertificate()), TransportType.Mqtt);
                        }
                        else
                        {
                            client = DeviceClient.Create(provResult.AssignedHub, new DeviceAuthenticationWithX509Certificate(provResult.DeviceId, security.GetAuthenticationCertificate()), TransportType.Mqtt, new ClientOptions {
                                ModelId = modelId
                            });
                        }
                        return(client);
                    }
                    else
                    {
                        string errorMessage = $"Device not provisioned. Message: {provResult.ErrorMessage}";
                        log.LogError(errorMessage);
                        throw new IotHubException(errorMessage);
                    }
                }
            }
        }
Ejemplo n.º 10
0
        private async Task <DeviceRegistrationResult> RegisterAsync(SecurityProvider security, CancellationToken token)
        {
            _Logger.EnteringMethodAzure(nameof(CommunicationContext));
            ProvisioningTransportHandler transport = null;

            try
            {
                switch (_azureDeviceParameters.TransportType)
                {
                case TransportType.Amqp:
                    transport = new ProvisioningTransportHandlerAmqp();
                    break;

                case TransportType.Http1:
                    transport = new ProvisioningTransportHandlerHttp();
                    break;

                case TransportType.Amqp_WebSocket_Only:
                    transport = new ProvisioningTransportHandlerAmqp(TransportFallbackType.WebSocketOnly);
                    break;

                case TransportType.Amqp_Tcp_Only:
                    transport = new ProvisioningTransportHandlerAmqp(TransportFallbackType.TcpOnly);
                    break;

                case TransportType.Mqtt:
                    transport = new ProvisioningTransportHandlerMqtt();
                    break;

                case TransportType.Mqtt_WebSocket_Only:
                    transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.WebSocketOnly);
                    break;

                case TransportType.Mqtt_Tcp_Only:
                    transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                ProvisioningDeviceClient provisioningClient = ProvisioningDeviceClient.Create(_globalDeviceEndpoint, _azureDeviceParameters.AzureScopeId, security, transport);
                _Logger.EnteringMethodAzure(nameof(ProvisioningDeviceClient), nameof(ProvisioningDeviceClient.RegisterAsync));
                return(await provisioningClient.RegisterAsync(token));
            }
            finally
            {
                _Logger.EnteringMethodAzure(nameof(ProvisioningTransportHandler), nameof(ProvisioningTransportHandler.Dispose));
                transport.Dispose();
            }
        }
Ejemplo n.º 11
0
        private static async Task <DeviceRegistrationResult> RegisterDeviceAsync(Configuration configuration, SecurityProviderX509Certificate security)
        {
            using var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly);
            var provClient = ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, configuration.DpsIdScope, security, transport);
            DeviceRegistrationResult registrationResult = await provClient.RegisterAsync();

            Console.WriteLine($"Registration {registrationResult.Status}");
            Console.WriteLine($"ProvisioningClient AssignedHub: {registrationResult.AssignedHub}; DeviceID: {registrationResult.DeviceId}");

            if (registrationResult.Status != ProvisioningRegistrationStatusType.Assigned)
            {
                throw new Exception("IoT Hub not assigned!");
            }
            return(registrationResult);
        }
Ejemplo n.º 12
0
        public async Task ProvisioningDeviceClient_RegisterAsyncInvalidServiceCertificateMqttTcp_Fails()
        {
            using var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly);
            ProvisioningTransportException exception = await Assert.ThrowsExceptionAsync <ProvisioningTransportException>(
                () => TestInvalidServiceCertificate(transport)).ConfigureAwait(false);

            if (exception.InnerException == null)
            {
                Assert.AreEqual("MQTT Protocol Exception: Channel closed.", exception.Message);
            }
            else
            {
                Assert.IsInstanceOfType(exception.InnerException, typeof(AuthenticationException));
            }
        }
Ejemplo n.º 13
0
        private void ConnectViaDPSX509(SecureString password, TransportType transportType)
        {
            string certPath = Environment.GetEnvironmentVariable("DEVICE_CERTIFICATE");

            if (certPath == null)
            {
                certPath = ConfigurationManager.AppSettings["DEVICE_CERTIFICATE"];
            }

            string scopeId = Environment.GetEnvironmentVariable("DPS_IDSCOPE");

            if (scopeId == null)
            {
                scopeId = ConfigurationManager.AppSettings["DPS_IDSCOPE"];
            }

            System.Security.Cryptography.X509Certificates.X509Certificate2 myCert =
                new System.Security.Cryptography.X509Certificates.X509Certificate2(certPath, password);

            using (var security = new SecurityProviderX509Certificate(myCert)) {
                using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly))
                // using (var transport = new ProvisioningTransportHandlerHttp())
                // using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly))
                // using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.WebSocketOnly))
                {
                    ProvisioningDeviceClient provClient =
                        ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, scopeId, security, transport);

                    Console.WriteLine($"RegistrationID = {security.GetRegistrationID()}");
                    VerifyRegistrationIdFormat(security.GetRegistrationID());

                    Console.Write("ProvisioningClient RegisterAsync . . . ");
                    DeviceRegistrationResult result = provClient.RegisterAsync().Result;
                    deviceId = result.DeviceId;
                    Console.WriteLine($"{result.Status}");
                    Console.WriteLine($"ProvisioningClient AssignedHub: {result.AssignedHub}; DeviceID: {result.DeviceId}");

                    if (result.Status != ProvisioningRegistrationStatusType.Assigned)
                    {
                        return;
                    }

                    var auth = new DeviceAuthenticationWithX509Certificate(result.DeviceId, (security as SecurityProviderX509).GetAuthenticationCertificate());

                    deviceClient = DeviceClient.Create(result.AssignedHub, auth, transportType);
                }
            }
        }
Ejemplo n.º 14
0
        private async Task <DeviceRegistrationResult> RegisterDeviceAsync(SecurityProviderSymmetricKey security)
        {
            _logger.LogInformation("{time} - Register device...", DateTimeOffset.Now);

            using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly))
            {
                ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create(_globalDeviceEndpoint, _scopeID, security, transport);
                _logger.LogInformation($"{DateTimeOffset.Now} - RegistrationID = {security.GetRegistrationID()}");

                DeviceRegistrationResult result = await provClient.RegisterAsync();

                _logger.LogInformation($"{DateTimeOffset.Now} - ProvisioningClient AssignedHub: {result.AssignedHub}; DeviceID: {result.DeviceId}");

                return(result);
            }
        }
Ejemplo n.º 15
0
        public async Task <IoTHubDeviceClient> ProvisionDeviceAsync()
        {
            string             connectionKey;
            IoTHubDeviceClient iotHubClient = null;

            Console.WriteLine("Provisioning...");

            if (!String.IsNullOrEmpty(_deviceId) && !String.IsNullOrEmpty(s_sasKey) && !String.IsNullOrEmpty(s_idScope))
            {
                connectionKey = GenerateSymmetricKey();
                Console.WriteLine($"Connection Key : {connectionKey}");

                using (var securityProvider = new SecurityProviderSymmetricKey(_deviceId, connectionKey, null))
                    using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly))
                    {
                        _provClient = ProvisioningDeviceClient.Create(s_global_endpoint, s_idScope, securityProvider, transport);

                        // Sanity check
                        Console.WriteLine($"Device ID      : {securityProvider.GetRegistrationID()}");

                        DeviceRegistrationResult result = await _provClient.RegisterAsync().ConfigureAwait(false);

                        if (result.Status == ProvisioningRegistrationStatusType.Assigned)
                        {
                            Console.WriteLine($"Provisioned    : {result.Status}");
                            Console.WriteLine($"  Device ID    : {result.DeviceId}");
                            Console.WriteLine($"  IoT Hub      : {result.AssignedHub}");

                            IAuthenticationMethod authenticationMethod = new DeviceAuthenticationWithRegistrySymmetricKey(result.DeviceId, securityProvider.GetPrimaryKey());

                            iotHubClient = new IoTHubDeviceClient(result.AssignedHub, authenticationMethod);
                        }
                        else
                        {
                            Console.WriteLine($"Err : Provisioning Failed {result.Status}");
                        }
                    }
            }
            else
            {
                Console.WriteLine("Please set following Environment Variables");
                Console.WriteLine("DPS_IDSCOPE : ID Scope");
                Console.WriteLine("SAS_KEY     : SAS Key");
            }

            return(iotHubClient);
        }
Ejemplo n.º 16
0
        private static async Task Main(string[] args)
        {
            Console.WriteLine("DPS auto provisioned device");

            if (args.Length == 0)
            {
                Console.WriteLine("Please pass ID Scope as first command line argument");
                return;
            }

            var idScope = args[0];

            var certificate = LoadCertificate();
            DeviceAuthenticationWithX509Certificate auth;
            string iotHub;

            using (var security = new SecurityProviderX509Certificate(certificate))
            {
                using (var transport = new ProvisioningTransportHandlerMqtt())
                {
                    var provisioningClient = ProvisioningDeviceClient.Create("global.azure-devices-provisioning.net",
                                                                             idScope, security, transport);

                    var provisioningResult = await provisioningClient.RegisterAsync();

                    Console.WriteLine(
                        $"Provisioning done - Assigned Hub: {provisioningResult.AssignedHub} - DeviceID {provisioningResult.DeviceId}");

                    auth = new DeviceAuthenticationWithX509Certificate(provisioningResult.DeviceId,
                                                                       security.GetAuthenticationCertificate());
                    iotHub = provisioningResult.AssignedHub;
                }
            }

            using (var deviceClient = DeviceClient.Create(iotHub, auth, TransportType.Mqtt))
            {
                await deviceClient.OpenAsync();

                await deviceClient.SendEventAsync(
                    new Message(Encoding.UTF8.GetBytes("Auto provisioned device was here")));

                await deviceClient.CloseAsync();

                Console.WriteLine("Sent message");
            }
        }
        private static async Task <DeviceRegistrationResult> RegisterDevice()
        {
            try
            {
                ConsoleWriteLine($"Will register device {deviceId}...", ConsoleColor.White);

                // using symmetric keys
                using var securityProvider = new SecurityProviderSymmetricKey(
                          registrationId: deviceId,
                          primaryKey: devicePrimaryKey,
                          secondaryKey: null);

                using var transportHandler = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly);

                // set up provisioning client for given device
                var provisioningDeviceClient = ProvisioningDeviceClient.Create(
                    globalDeviceEndpoint: provisioningGlobalDeviceEndpoint,
                    idScope: provisioningIdScope,
                    securityProvider: securityProvider,
                    transport: transportHandler);

                // register device
                var deviceRegistrationResult = await provisioningDeviceClient.RegisterAsync();

                ConsoleWriteLine($"Device {deviceId} registration result: {deviceRegistrationResult.Status}", ConsoleColor.White);

                if (deviceRegistrationResult.Status != ProvisioningRegistrationStatusType.Assigned)
                {
                    throw new Exception($"Failed to register device {deviceId}");
                }

                ConsoleWriteLine($"Device {deviceId} was assigned to hub '{deviceRegistrationResult.AssignedHub}'", ConsoleColor.White);
                ConsoleWriteLine();

                return(deviceRegistrationResult);
            }
            catch (Exception ex)
            {
                ConsoleWriteLine($"* ERROR * {ex.Message}", ConsoleColor.Red);
            }

            return(null);
        }
Ejemplo n.º 18
0
        internal static async Task <DeviceClient> ProvisionDeviceWithSasKeyAsync(string scopeId, string deviceId, string deviceKey, string modelId, ILogger log)
        {
            using (var transport = new ProvisioningTransportHandlerMqtt())
            {
                using (var security = new SecurityProviderSymmetricKey(deviceId, deviceKey, null))
                {
                    DeviceRegistrationResult provResult;
                    var provClient = ProvisioningDeviceClient.Create("global.azure-devices-provisioning.net", scopeId, security, transport);

                    if (!string.IsNullOrEmpty(modelId))
                    {
                        provResult = await provClient.RegisterAsync(GetProvisionPayload(modelId)).ConfigureAwait(false);
                    }
                    else
                    {
                        provResult = await provClient.RegisterAsync().ConfigureAwait(false);
                    }

                    log.LogInformation($"Provioning Result. Status [{provResult.Status}] SubStatus [{provResult.Substatus}]");

                    if (provResult.Status == ProvisioningRegistrationStatusType.Assigned)
                    {
                        log.LogWarning($"Device {provResult.DeviceId} in Hub {provResult.AssignedHub}");
                        log.LogInformation($"LastRefresh {provResult.LastUpdatedDateTimeUtc} RegistrationId {provResult.RegistrationId}");
                        var    csBuilder        = IotHubConnectionStringBuilder.Create(provResult.AssignedHub, new DeviceAuthenticationWithRegistrySymmetricKey(provResult.DeviceId, security.GetPrimaryKey()));
                        string connectionString = csBuilder.ToString();
                        return(await Task.FromResult(
                                   DeviceClient.CreateFromConnectionString(
                                       connectionString, TransportType.Mqtt,
                                       new ClientOptions()
                        {
                            ModelId = modelId
                        })));
                    }
                    else
                    {
                        string errorMessage = $"Device not provisioned. Message: {provResult.ErrorMessage}";
                        log.LogError(errorMessage);
                        throw new IotHubException(errorMessage);
                    }
                }
            }
        }
Ejemplo n.º 19
0
        public static async Task <DeviceRegistrationResult> RegisterDeviceAsync(SecurityProviderSymmetricKey security)
        {
            Console.WriteLine("Register device...");

            using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly))
            {
                ProvisioningDeviceClient provClient =
                    ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, ScopeID, security, transport);

                Console.WriteLine($"RegistrationID = {security.GetRegistrationID()}");

                Console.Write("ProvisioningClient RegisterAsync...");
                DeviceRegistrationResult result = await provClient.RegisterAsync();

                Console.WriteLine($"{result.Status}");

                return(result);
            }
        }
        // Registers a device with the Device Provisioning Service using X509 Certificate Authentication
        public async Task RegisterAsync()
        {
            ProvisioningTransportHandler transport;

            switch (_deviceRegistrationOptions.TransportMethod)
            {
            case TransportCommunicationMethods.Http:
                transport = new ProvisioningTransportHandlerHttp();
                break;

            case TransportCommunicationMethods.Mqtt:
                transport = new ProvisioningTransportHandlerMqtt();
                break;

            case TransportCommunicationMethods.Amqp:
                transport = new ProvisioningTransportHandlerAmqp();
                break;

            default:
                throw new Exception("Unknown DPS Transport Method");
            }

            // Set up a proxy for DPS if specified
            if (!String.IsNullOrEmpty(_proxyOptions?.ProxyUri))
            {
                transport.Proxy = new WebProxy(_proxyOptions.ProxyUri);
            }

            // Create the provisioning client
            var dpsClient = ProvisioningDeviceClient.Create(
                _deviceRegistrationOptions.GlobalDeviceEndpoint,
                _deviceRegistrationOptions.IdScope,
                _securityProvider,
                transport
                );

            // Register the device
            _registrationResult = await dpsClient.RegisterAsync();
        }
Ejemplo n.º 21
0
        public async Task ProvisioningDeviceClient_RegisterAsyncInvalidServiceCertificateMqttWs_Fails()
        {
            using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.WebSocketOnly))
            {
                var exception = await Assert.ThrowsExceptionAsync <ProvisioningTransportException>(
                    () => TestInvalidServiceCertificate(transport)).ConfigureAwait(false);

#if !NETCOREAPP2_0
                Assert.IsInstanceOfType(exception.InnerException.InnerException.InnerException, typeof(AuthenticationException));
#else
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    // WinHttpException (0x80072F8F): A security error occurred
                    Assert.AreEqual(unchecked ((int)0x80072F8F), exception.InnerException.InnerException.InnerException.HResult);
                }
                else
                {
                    Assert.IsInstanceOfType(exception.InnerException.InnerException, typeof(AuthenticationException));
                }
#endif
            }
        }
        public async Task <DeviceRegistrationResult> RegisterDeviceAsync(SecurityProviderSymmetricKey security)
        {
            Console.WriteLine("Register device...");
            billingloginS = _BillingData.GetSubscriber_IDlogin(User.Identity.Name);
            if (billingloginS == null)
            {
                return(null);
            }
            int Subscriber_ID = 0;


            Subscriber_ID = billingloginS.Subscriber_ID;


            if (Subscriber_ID > 0)
            {
                IOTDEviceDetail = _DeviceData.GetIOTDEviceDetailsBySubscriberId(Subscriber_ID);
            }
            if (IOTDEviceDetail == null)
            {
                return(null);
            }


            using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.WebSocketOnly))
            {
                ProvisioningDeviceClient provClient =
                    ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, IOTDEviceDetail.ScopeID, security, transport);

                Console.WriteLine($"RegistrationID = {security.GetRegistrationID()}");

                Console.Write("ProvisioningClient RegisterAsync...");
                DeviceRegistrationResult result = await provClient.RegisterAsync();

                Console.WriteLine($"{result.Status}");

                return(result);
            }
        }
        static async Task Main(string[] args)
        {
            double temperature;

            using (var security = new SecurityProviderSymmetricKey(registrationId, primaryKey, secondaryKey))
                using (var transport = new ProvisioningTransportHandlerMqtt())
                {
                    ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, idScope, security, transport);
                    DeviceRegistrationResult result     = await provClient.RegisterAsync();

                    IAuthenticationMethod auth = new DeviceAuthenticationWithRegistrySymmetricKey(result.DeviceId, (security as SecurityProviderSymmetricKey).GetPrimaryKey());

                    using (DeviceClient iotClient = DeviceClient.Create(result.AssignedHub, auth, TransportType.Mqtt))
                    {
                        while (true)
                        {
                            if (_temperature.IsAvailable)
                            {
                                try
                                {
                                    temperature = Math.Round(_temperature.Temperature.Celsius, 2);

                                    Console.WriteLine($"The CPU temperature is {temperature}");

                                    await SendMsgIotHub(iotClient, temperature);
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine("exception msg: " + ex.Message);
                                }
                            }
                            Thread.Sleep(4000); // sleep for 10 seconds
                        }
                    }
                }
        }
Ejemplo n.º 24
0
        public async Task <IDevice> RegisterDevicesAsync(string deviceId)
        {
            var devicePrimaryKey   = Utilities.ComputeDerivedSymmetricKey(Convert.FromBase64String(_dpsContext.PrimaryKey), deviceId);
            var deviceSecondaryKey = Utilities.ComputeDerivedSymmetricKey(Convert.FromBase64String(_dpsContext.SecondaryKey), deviceId);

            using (var security = new SecurityProviderSymmetricKey(deviceId, devicePrimaryKey, deviceSecondaryKey))
            {
                using (var transport = new ProvisioningTransportHandlerMqtt())
                {
                    Console.WriteLine($"Resgistering {deviceId}....");
                    var provisioningDeviceClient = ProvisioningDeviceClient.Create(_dpsContext.GlobalDeviceEndpoint, _dpsContext.ScopeId, security, transport);
                    var result = await provisioningDeviceClient.RegisterAsync();

                    var device = new Device
                    {
                        Key         = security.GetPrimaryKey(),
                        DeviceId    = result.DeviceId,
                        AssignedHub = result.AssignedHub,
                        Status      = result.Status
                    };
                    return(device);
                }
            }
        }
Ejemplo n.º 25
0
        static async Task Main(string[] args)
        {
#if DEBUG
            // Attach remote debugger
            while (true)
            {
                Console.WriteLine("Waiting for remote debugger to attach...");

                if (Debugger.IsAttached)
                {
                    break;
                }

                System.Threading.Thread.Sleep(1000);
            }
#endif
            // print a list of all available serial ports for convenience
            string[] ports = SerialPort.GetPortNames();
            foreach (string port in ports)
            {
                Console.WriteLine("Serial port available: " + port);
            }

            // start processing smart meter messages
            SmartMeterLanguage sml = new SmartMeterLanguage(LinuxUSBSerialPort);
            sml.ProcessStream();

            DeviceClient deviceClient = null;
            try
            {
                // register the device
                string scopeId      = "0ne0010B637";
                string deviceId     = "RasPi2B";
                string primaryKey   = "";
                string secondaryKey = "";

                var security  = new SecurityProviderSymmetricKey(deviceId, primaryKey, secondaryKey);
                var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpWithWebSocketFallback);

                var provisioningClient = ProvisioningDeviceClient.Create("global.azure-devices-provisioning.net", scopeId, security, transport);
                var result             = await provisioningClient.RegisterAsync();

                var connectionString = "HostName=" + result.AssignedHub + ";DeviceId=" + result.DeviceId + ";SharedAccessKey=" + primaryKey;
                deviceClient = DeviceClient.CreateFromConnectionString(connectionString, TransportType.Mqtt);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }

            while (true)
            {
                TelemetryData telemetryData = new TelemetryData();

                try
                {
                    // read the current weather data from web service
                    using WebClient webClient = new WebClient
                          {
                              BaseAddress = "https://api.openweathermap.org/"
                          };
                    var         json    = webClient.DownloadString("data/2.5/weather?q=Munich,de&units=metric&appid=2898258e654f7f321ef3589c4fa58a9b");
                    WeatherInfo weather = JsonConvert.DeserializeObject <WeatherInfo>(json);
                    if (weather != null)
                    {
                        telemetryData.Temperature = weather.main.temp;
                        telemetryData.WindSpeed   = weather.wind.speed;
                        telemetryData.CloudCover  = weather.weather[0].description;
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }

                try
                {
                    // read the current converter data from web service
                    using WebClient webClient = new WebClient
                          {
                              BaseAddress = "http://192.168.178.31/"
                          };
                    var           json      = webClient.DownloadString("solar_api/v1/GetInverterRealtimeData.cgi?Scope=Device&DeviceID=1&DataCollection=CommonInverterData");
                    DCACConverter converter = JsonConvert.DeserializeObject <DCACConverter>(json);
                    if (converter != null)
                    {
                        if (converter.Body.Data.PAC != null)
                        {
                            telemetryData.PVOutputPower = ((double)converter.Body.Data.PAC.Value) / 1000.0;
                        }
                        if (converter.Body.Data.DAY_ENERGY != null)
                        {
                            telemetryData.PVOutputEnergyDay = ((double)converter.Body.Data.DAY_ENERGY.Value) / 1000.0;
                        }
                        if (converter.Body.Data.YEAR_ENERGY != null)
                        {
                            telemetryData.PVOutputEnergyYear = ((double)converter.Body.Data.YEAR_ENERGY.Value) / 1000.0;
                        }
                        if (converter.Body.Data.TOTAL_ENERGY != null)
                        {
                            telemetryData.PVOutputEnergyTotal = ((double)converter.Body.Data.TOTAL_ENERGY.Value) / 1000.0;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }

                try
                {
                    // read the current smart meter data
                    if (sml != null)
                    {
                        telemetryData.MeterEnergyPurchased = sml.Meter.EnergyPurchased;
                        telemetryData.MeterEnergySold      = sml.Meter.EnergySold;
                        telemetryData.MeterEnergyConsumed  = 0.0;

                        // calculate energy consumed from the other telemetry, if available
                        if ((telemetryData.MeterEnergyPurchased != 0.0) &&
                            (telemetryData.MeterEnergySold != 0.0) &&
                            (telemetryData.PVOutputEnergyTotal != 0.0))
                        {
                            telemetryData.MeterEnergyConsumed = telemetryData.PVOutputEnergyTotal + sml.Meter.EnergyPurchased - sml.Meter.EnergySold;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }


                try
                {
                    string  messageString = JsonConvert.SerializeObject(telemetryData);
                    Message cloudMessage  = new Message(Encoding.UTF8.GetBytes(messageString));

                    await deviceClient.SendEventAsync(cloudMessage);

                    Debug.WriteLine("{0}: {1}", DateTime.Now, messageString);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }

                await Task.Delay(5000);
            }
        }
Ejemplo n.º 26
0
        /// <summary>
        /// In order to provision the device and establish secure connection to IoT Edge
        /// certificates need to be installed in the Certificate Store(root, intermediate, leaf).
        /// Next phase is to use DPS to get necessary informations about IoT Hub.
        /// Last phase is to connect to the Edge device and send it MESSAGE_COUNT
        /// number of telemetry data messages.
        ///
        /// Note: Either set the MESSAGE_COUNT environment variable with the number of
        /// messages to be sent to the IoT Edge runtime or set it in the launchSettings.json.
        /// </summary>
        static void Main()
        {
            try
            {
                string messageCountEnv = Environment.GetEnvironmentVariable("MESSAGE_COUNT");
                if (!string.IsNullOrWhiteSpace(messageCountEnv))
                {
                    MESSAGE_COUNT = Int32.Parse(messageCountEnv, NumberStyles.None, new CultureInfo("en-US"));
                }
            }
            catch (Exception)
            {
                Console.WriteLine("Invalid number of messages in env variable DEVICE_MESSAGE_COUNT. MESSAGE_COUNT set to {0}\n", MESSAGE_COUNT);
            }

            Console.WriteLine("Creating device client from certificates\n");

            var rootCertificatePath         = Environment.GetEnvironmentVariable("CA_CERTIFICATE_PATH");
            var intermediateCertificatePath = Environment.GetEnvironmentVariable("CA_INTERMEDIATE_CERTIFICATE_PATH");
            var leafCertificatePath         = Environment.GetEnvironmentVariable("CA_LEAF_CERTIFICATE_PATH");
            var leafCertificatePassword     = Environment.GetEnvironmentVariable("CA_LEAF_CERTIFICATE_PASSWORD");
            var hostName = Environment.GetEnvironmentVariable("HOST_NAME");
            var dpsScope = Environment.GetEnvironmentVariable("DPS_IDSCOPE");

            // Add Root Certificate
            InstallCACert(certificatePath: rootCertificatePath);
            // Add Intermediate Certificate
            InstallCACert(certificatePath: intermediateCertificatePath);
            // Add Leaf Device Certificate
            InstallCACert(certificatePath: leafCertificatePath,
                          certificatePassword: leafCertificatePassword);

            var certificate = new X509Certificate2(leafCertificatePath, leafCertificatePassword);

            using (var security = new SecurityProviderX509Certificate(certificate))
                using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly))
                {
                    ProvisioningDeviceClient provClient =
                        ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, dpsScope, security, transport);

                    var deviceAuthentication = GetDeviceRegistrationResultAsync(provClient, security).Result;

                    var auth = new DeviceAuthenticationWithX509Certificate(deviceAuthentication.DeviceId, security.GetAuthenticationCertificate());

                    var deviceClient = DeviceClient.Create(hostname: deviceAuthentication.AssignedHub,
                                                           authenticationMethod: auth,
                                                           transportType: TransportType.Mqtt);


                    if (deviceClient == null)
                    {
                        Console.WriteLine("Failed to create DeviceClient!");
                    }
                    else
                    {
                        SendEvents(deviceClient, MESSAGE_COUNT).Wait();
                    }
                }
            Console.WriteLine("Exiting!\n");
            Console.ReadLine();
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Provision device using DPS and send telemetry to IoT Hub.
        /// </summary>
        /// <returns></returns>
        public static async Task RunSampleAsync()
        {
            try
            {
                using var security = new SecurityProviderX509Certificate(certificate);

                Console.WriteLine($"Initializing the device provisioning client...");

                // Use HTTP, AMQP or MQTT to communicate with DPS
                //var transportHandler = new ProvisioningTransportHandlerHttp();
                //var transportHandler = new ProvisioningTransportHandlerAmqp();
                var transportHandler = new ProvisioningTransportHandlerMqtt();

                // Standard DPS provisioning flow using x.509
                ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create(
                    dpsEndpoint,
                    idScope,
                    security,
                    transportHandler);

                Console.WriteLine($"Initialized for registration Id {security.GetRegistrationID()}.");

                Console.WriteLine("Registering with the device provisioning service... ");
                DeviceRegistrationResult result = await provClient.RegisterAsync();

                Console.WriteLine($"Registration status: {result.Status}.");
                if (result.Status != ProvisioningRegistrationStatusType.Assigned)
                {
                    Console.WriteLine($"Registration status did not assign a hub, so exiting this sample.");
                    return;
                }

                Console.WriteLine($"Device {result.DeviceId} registered to {result.AssignedHub}.");

                // Standard IoT Hub authentication and connection flow using x.509
                Console.WriteLine("Creating X509 authentication for IoT Hub...");
                IAuthenticationMethod auth = new DeviceAuthenticationWithX509Certificate(
                    result.DeviceId,
                    certificate);

                Console.WriteLine($"Connecting to IoT Hub...");
                iotClient = DeviceClient.Create(result.AssignedHub, auth, TransportType.Mqtt);

                Console.WriteLine("Sending telemetry messages...");
                var message = new Message(Encoding.UTF8.GetBytes("TestMessage"));

                for (int count = 0; count < MESSAGE_COUNT; count++)
                {
                    await iotClient.SendEventAsync(message);

                    Console.WriteLine($"Sent message {count}");

                    await Task.Delay(DELAY_BETWEEN_SENDS);
                }

                await iotClient.CloseAsync();

                iotClient.Dispose();

                Console.WriteLine("Finished.");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
Ejemplo n.º 28
0
        static async Task Main(string[] args)
        {
            double temperature;
            var    rand = new Random();

            using (var security = new SecurityProviderSymmetricKey(registrationId, primaryKey, secondaryKey))
                using (var transport = new ProvisioningTransportHandlerMqtt())
                {
                    ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, idScope, security, transport);
                    DeviceRegistrationResult result     = await provClient.RegisterAsync();

                    IAuthenticationMethod auth = new DeviceAuthenticationWithRegistrySymmetricKey(result.DeviceId, (security as SecurityProviderSymmetricKey).GetPrimaryKey());

                    using (DeviceClient iotClient = DeviceClient.Create(result.AssignedHub, auth, TransportType.Mqtt))
                    {
                        while (true)
                        {
                            if (_temperature.IsAvailable)
                            {
                                temperature = Math.Round(_temperature.Temperature.Celsius, 2);
                            }
                            else
                            {
                                temperature = rand.Next(15, 35);
                            }

                            try
                            {
                                msgId++;

                                Console.WriteLine($"The CPU temperature is {temperature}");

                                Image img = Image.FromFile(filename); // simulate camera captured image

                                using (MemoryStream ms = new MemoryStream())
                                {
                                    img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);

                                    TelemetryProtobuf tpb = new TelemetryProtobuf()
                                    {
                                        Temperature = temperature,
                                        Humidity    = 50,
                                        Pressure    = 1100,
                                        MsgId       = msgId,
                                        Label       = "Orange",
                                        Probability = 1.0,
                                        Image       = ByteString.CopyFrom(ms.ToArray()),
                                        DeviceId    = string.Empty // this is set in the azure function when writing to cosmosdb
                                    };

                                    using (MemoryStream memStream = new MemoryStream())
                                    {
                                        tpb.WriteTo(memStream);
                                        await SendMsgIotHub(iotClient, memStream.ToArray());

                                        // Deserialise Protobuf
                                        // var newTpb = TelemetryProtobuf.Parser.ParseFrom(memStream.ToArray());
                                    }

                                    await SendMsgIotHub(iotClient, temperature);
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("exception msg: " + ex.Message);
                            }
                            Thread.Sleep(4000); // sleep for 10 seconds
                        }
                    }
                }
        }
Ejemplo n.º 29
0
        static async Task Main(string[] args)
        {
#if DEBUG
            // Attach remote debugger
            while (true)
            {
                Console.WriteLine("Waiting for remote debugger to attach...");

                if (Debugger.IsAttached)
                {
                    break;
                }

                System.Threading.Thread.Sleep(1000);
            }
#endif
            // init log file
            Log.Logger = new LoggerConfiguration()
                         .WriteTo.Console()
                         .WriteTo.File(
                "logfile.txt",
                fileSizeLimitBytes: 1024 * 1024,
                flushToDiskInterval: TimeSpan.FromSeconds(30),
                rollOnFileSizeLimit: true,
                retainedFileCountLimit: 2)
                         .MinimumLevel.Debug()
                         .CreateLogger();
            Log.Information($"{Assembly.GetExecutingAssembly()} V{FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion}");

            // init Modbus TCP client for wallbox
            ModbusTCPClient wallbox = new ModbusTCPClient();
            wallbox.Connect(WallbeWallboxBaseAddress, WallbeWallboxModbusTCPPort);

            // init Modbus TCP client for inverter
            ModbusTCPClient inverter = new ModbusTCPClient();
            inverter.Connect(FroniusInverterBaseAddress, FroniusInverterModbusTCPPort);

            // read current inverter power limit (percentage)
            byte[] WMaxLimit = inverter.Read(
                FroniusInverterModbusUnitID,
                ModbusTCPClient.FunctionCode.ReadHoldingRegisters,
                SunSpecInverterModbusRegisterMapFloat.InverterBaseAddress + SunSpecInverterModbusRegisterMapFloat.WMaxLimPctOffset,
                SunSpecInverterModbusRegisterMapFloat.WMaxLimPctLength);

            int existingLimitPercent = Utils.ByteSwap(BitConverter.ToUInt16(WMaxLimit)) / 100;

            // go to the maximum grid export power limit with immediate effect without timeout
            ushort InverterPowerOutputPercent = (ushort)((GridExportPowerLimit / FroniusSymoMaxPower) * 100);
            inverter.WriteHoldingRegisters(
                FroniusInverterModbusUnitID,
                SunSpecInverterModbusRegisterMapFloat.InverterBaseAddress + SunSpecInverterModbusRegisterMapFloat.WMaxLimPctOffset,
                new ushort[] { (ushort)(InverterPowerOutputPercent * 100), 0, 0, 0, 1 });

            // check new setting
            WMaxLimit = inverter.Read(
                FroniusInverterModbusUnitID,
                ModbusTCPClient.FunctionCode.ReadHoldingRegisters,
                SunSpecInverterModbusRegisterMapFloat.InverterBaseAddress + SunSpecInverterModbusRegisterMapFloat.WMaxLimPctOffset,
                SunSpecInverterModbusRegisterMapFloat.WMaxLimPctLength);

            int newLimitPercent = Utils.ByteSwap(BitConverter.ToUInt16(WMaxLimit)) / 100;

            // print a list of all available serial ports for convenience
            string[] ports = SerialPort.GetPortNames();
            foreach (string port in ports)
            {
                Log.Information("Serial port available: " + port);
            }

            // start processing smart meter messages
            SmartMessageLanguage sml = new SmartMessageLanguage(LinuxUSBSerialPort);
            sml.ProcessStream();

            DeviceClient deviceClient = null;
            try
            {
                // register the device
                string scopeId      = "0ne0010B637";
                string deviceId     = "RasPi2B";
                string primaryKey   = "";
                string secondaryKey = "";

                var security  = new SecurityProviderSymmetricKey(deviceId, primaryKey, secondaryKey);
                var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpWithWebSocketFallback);

                var provisioningClient = ProvisioningDeviceClient.Create("global.azure-devices-provisioning.net", scopeId, security, transport);
                var result             = await provisioningClient.RegisterAsync();

                var connectionString = "HostName=" + result.AssignedHub + ";DeviceId=" + result.DeviceId + ";SharedAccessKey=" + primaryKey;
                deviceClient = DeviceClient.CreateFromConnectionString(connectionString, TransportType.Mqtt);

                // register our methods
                await deviceClient.SetMethodHandlerAsync("ChargeNowToggle", ChargeNowHandler, null);

                await deviceClient.SetMethodHandlerAsync("ChargingPhases", ChargingPhasesHandler, null);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Registering device failed!");
            }

            TelemetryData telemetryData = new TelemetryData();
            while (true)
            {
                telemetryData.ChargeNow         = _chargeNow;
                telemetryData.NumChargingPhases = _chargingPhases;

                try
                {
                    // read the current weather data from web service
                    WebClient webClient = new WebClient
                    {
                        BaseAddress = "https://api.openweathermap.org/"
                    };

                    string      json    = webClient.DownloadString("data/2.5/weather?q=Munich,de&units=metric&appid=2898258e654f7f321ef3589c4fa58a9b");
                    WeatherInfo weather = JsonConvert.DeserializeObject <WeatherInfo>(json);
                    if (weather != null)
                    {
                        telemetryData.Temperature = weather.main.temp;
                        telemetryData.WindSpeed   = weather.wind.speed;
                        telemetryData.CloudCover  = weather.weather[0].description;
                    }

                    webClient.Dispose();
                }
                catch (Exception ex)
                {
                    Log.Error(ex, "Getting weather data failed!");
                }

                try
                {
                    // read the current forecast data from web service
                    WebClient webClient = new WebClient
                    {
                        BaseAddress = "https://api.openweathermap.org/"
                    };

                    string   json     = webClient.DownloadString("data/2.5/forecast?q=Munich,de&units=metric&appid=2898258e654f7f321ef3589c4fa58a9b");
                    Forecast forecast = JsonConvert.DeserializeObject <Forecast>(json);
                    if (forecast != null && forecast.list != null && forecast.list.Count == 40)
                    {
                        telemetryData.CloudinessForecast = string.Empty;
                        for (int i = 0; i < 40; i++)
                        {
                            telemetryData.CloudinessForecast += "Cloudiness on " + forecast.list[i].dt_txt + ": " + forecast.list[i].clouds.all + "%\r\n";
                        }
                    }

                    webClient.Dispose();
                }
                catch (Exception ex)
                {
                    Log.Error(ex, "Getting weather forecast failed!");
                }

                try
                {
                    // read the current converter data from web service
                    WebClient webClient = new WebClient
                    {
                        BaseAddress = "http://" + FroniusInverterBaseAddress
                    };

                    string        json      = webClient.DownloadString("solar_api/v1/GetInverterRealtimeData.cgi?Scope=Device&DeviceID=1&DataCollection=CommonInverterData");
                    DCACConverter converter = JsonConvert.DeserializeObject <DCACConverter>(json);
                    if (converter != null)
                    {
                        if (converter.Body.Data.PAC != null)
                        {
                            telemetryData.PVOutputPower = converter.Body.Data.PAC.Value;
                        }
                        if (converter.Body.Data.DAY_ENERGY != null)
                        {
                            telemetryData.PVOutputEnergyDay = ((double)converter.Body.Data.DAY_ENERGY.Value) / 1000.0;
                        }
                        if (converter.Body.Data.YEAR_ENERGY != null)
                        {
                            telemetryData.PVOutputEnergyYear = ((double)converter.Body.Data.YEAR_ENERGY.Value) / 1000.0;
                        }
                        if (converter.Body.Data.TOTAL_ENERGY != null)
                        {
                            telemetryData.PVOutputEnergyTotal = ((double)converter.Body.Data.TOTAL_ENERGY.Value) / 1000.0;
                        }
                    }

                    webClient.Dispose();
                }
                catch (Exception ex)
                {
                    Log.Error(ex, "Getting converter data failed!");
                }

                try
                {
                    // read the current smart meter data
                    telemetryData.MeterEnergyPurchased = sml.Meter.EnergyPurchased;
                    telemetryData.MeterEnergySold      = sml.Meter.EnergySold;
                    telemetryData.CurrentPower         = sml.Meter.CurrentPower;

                    telemetryData.EnergyCost   = telemetryData.MeterEnergyPurchased * KWhCost;
                    telemetryData.EnergyProfit = telemetryData.MeterEnergySold * KWhProfit;

                    // calculate energy consumed from the other telemetry, if available
                    telemetryData.MeterEnergyConsumed = 0.0;
                    if ((telemetryData.MeterEnergyPurchased != 0.0) &&
                        (telemetryData.MeterEnergySold != 0.0) &&
                        (telemetryData.PVOutputEnergyTotal != 0.0))
                    {
                        telemetryData.MeterEnergyConsumed  = telemetryData.PVOutputEnergyTotal + sml.Meter.EnergyPurchased - sml.Meter.EnergySold;
                        telemetryData.CurrentPowerConsumed = telemetryData.PVOutputPower + sml.Meter.CurrentPower;
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(ex, "Getting smart meter data failed!");
                }

                try
                {
                    // ramp up or down EV charging, based on surplus
                    bool chargingInProgress = IsEVChargingInProgress(wallbox);
                    telemetryData.EVChargingInProgress = chargingInProgress? 1 : 0;
                    if (chargingInProgress)
                    {
                        // read current current (in Amps)
                        ushort wallbeWallboxCurrentCurrentSetting = Utils.ByteSwap(BitConverter.ToUInt16(wallbox.Read(
                                                                                                             WallbeWallboxModbusUnitID,
                                                                                                             ModbusTCPClient.FunctionCode.ReadHoldingRegisters,
                                                                                                             WallbeWallboxCurrentCurrentSettingAddress,
                                                                                                             1)));
                        telemetryData.WallboxCurrent = wallbeWallboxCurrentCurrentSetting;

                        OptimizeEVCharging(wallbox, sml.Meter.CurrentPower);
                    }
                    else
                    {
                        telemetryData.WallboxCurrent = 0;

                        // check if we should start charging our EV with the surplus power, but we need at least 6A of current per charing phase
                        // or the user set the "charge now" flag via direct method
                        if (((sml.Meter.CurrentPower / 230) < (_chargingPhases * -6.0f)) || _chargeNow)
                        {
                            StartEVCharging(wallbox);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(ex, "EV charing control failed!");
                }

                try
                {
                    string  messageString = JsonConvert.SerializeObject(telemetryData);
                    Message cloudMessage  = new Message(Encoding.UTF8.GetBytes(messageString));

                    await deviceClient.SendEventAsync(cloudMessage);

                    Debug.WriteLine("{0}: {1}", DateTime.Now, messageString);
                }
                catch (Exception ex)
                {
                    Log.Error(ex, "Sending telemetry failed!");
                }

                // wait 5 seconds and go again
                await Task.Delay(5000).ConfigureAwait(false);
            }
        }