示例#1
0
        /// <summary>
        /// This sample performs root-level operations on a plug and play compatible device.
        /// </summary>
        /// <param name="args">
        /// Run with `--help` to see a list of required and optional parameters.
        /// </param>
        public static async Task Main(string[] args)
        {
            // Parse application parameters
            Parameters parameters            = null;
            ParserResult <Parameters> result = Parser.Default.ParseArguments <Parameters>(args)
                                               .WithParsed(parsedParams =>
            {
                parameters = parsedParams;
            })
                                               .WithNotParsed(errors =>
            {
                Environment.Exit(1);
            });

            s_logger = InitializeConsoleDebugLogger();
            if (!parameters.Validate())
            {
                throw new ArgumentException("Required parameters are not set. Please recheck required variables by using \"--help\"");
            }

            s_logger.LogDebug("Set up the digital twin client.");
            using DigitalTwinClient digitalTwinClient = DigitalTwinClient.CreateFromConnectionString(parameters.HubConnectionString);

            s_logger.LogDebug("Set up and start the Thermostat service sample.");
            var thermostatSample = new ThermostatSample(digitalTwinClient, parameters.DeviceId, s_logger);
            await thermostatSample.RunSampleAsync().ConfigureAwait(false);
        }
示例#2
0
        public static int Main(string[] args)
        {
            if (string.IsNullOrEmpty(deviceConnectionString) && args.Length > 0)
            {
                deviceConnectionString = args[0];
            }

            if (string.IsNullOrEmpty(deviceConnectionString))
            {
                Console.WriteLine("Please set a value for the environment variable \"DIGITAL_TWIN_DEVICE_CONNECTION_STRING\" or pass it in as an argument");
                Console.WriteLine("Press any key to exit");
                Console.ReadLine();
                return(0);
            }

            using (var deviceClient = DeviceClient.CreateFromConnectionString(deviceConnectionString, transportType))
            {
                DigitalTwinClient digitalTwinClient = new DigitalTwinClient(deviceClient);

                if (digitalTwinClient == null)
                {
                    Console.WriteLine("Failed to create DeviceClient!");
                    return(1);
                }

                var sample = new DigitalTwinClientSample(digitalTwinClient);
                sample.RunSampleAsync().GetAwaiter().GetResult();

                Console.WriteLine("Waiting to receive updates from cloud...");
                Console.WriteLine("Press any key to exit");
                Console.ReadLine();
            }

            return(0);
        }
        public async Task DigitalTwinClient_Http_TokenCredentialAuth_Success()
        {
            // arrange
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);

            string thermostatModelId = "dtmi:com:example:TemperatureController;1";

            // Create a device client instance initializing it with the "Thermostat" model.
            var options = new ClientOptions
            {
                ModelId = thermostatModelId,
            };

            using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Mqtt, options);

            // Call openAsync() to open the device's connection, so that the ModelId is sent over Mqtt CONNECT packet.
            await deviceClient.OpenAsync().ConfigureAwait(false);

            using var digitalTwinClient = DigitalTwinClient.Create(
                      Configuration.IoTHub.GetIotHubHostName(),
                      Configuration.IoTHub.GetClientSecretCredential());

            // act
            HttpOperationResponse <ThermostatTwin, DigitalTwinGetHeaders> response = await digitalTwinClient
                                                                                     .GetDigitalTwinAsync <ThermostatTwin>(testDevice.Id)
                                                                                     .ConfigureAwait(false);

            ThermostatTwin twin = response.Body;

            // assert
            twin.Metadata.ModelId.Should().Be(thermostatModelId);

            // cleanup
            await testDevice.RemoveDeviceAsync().ConfigureAwait(false);
        }
示例#4
0
        private async Task <DigitalTwinClient> CreateDigitalTwinsClientAsync()
        {
            var deviceClient = await DeviceClientFactory.CreateDeviceClientAsync(connectionString, logger);

            deviceClient.SetConnectionStatusChangesHandler((ConnectionStatus status, ConnectionStatusChangeReason reason) => logger.LogWarning($"Connection status changed: {status} {reason}"));
            var digitalTwinClient = new DigitalTwinClient(deviceClient);

            return(digitalTwinClient);
        }
示例#5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DigitalTwinClientSample"/> class.
        /// </summary>
        /// <param name="digitalTwinClient">digital twin client.</param>
        public DigitalTwinClientSample(DigitalTwinClient digitalTwinClient)
        {
            this.digitalTwinClient = digitalTwinClient;

            // create environmental sensor interface
            environmentalSensorInterface = new EnvironmentalSensorInterface(environmentalSensorInterfaceName);

            // create device information interface
            deviceInformationInterface = new DeviceInformationInterface();

            modelDefinitionInterface = new ModelDefinitionInterface(ModelDefinitionInterfaceName);
        }
 public IoTHubHelper(IOptions <AppSettings> config, ILogger <IoTHubHelper> logger)
 {
     _logger                    = logger;
     _appSettings               = config.Value;
     _registryManager           = RegistryManager.CreateFromConnectionString(_appSettings.IoTHub.ConnectionString);
     _serviceClient             = ServiceClient.CreateFromConnectionString(_appSettings.IoTHub.ConnectionString);
     _digitalTwinClient         = DigitalTwinClient.CreateFromConnectionString(_appSettings.IoTHub.ConnectionString);
     _provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(_appSettings.Dps.ConnectionString);
     _dps_webhookUrl            = _appSettings.Dps.WebHookUrl;
     _deviceClient              = null;
     _isConnected               = false;
     _privateModelRepoUrl       = _appSettings.ModelRepository.repoUrl;
     _privateModelToken         = _appSettings.GitHub.token;
 }
示例#7
0
        public async Task RunDeviceAsync()
        {
            var deviceInformationInterface = new DeviceInformationInterface("Device_information_S1_Sensor");
            var s1Sensor = new S1Sensor("S1_Sensor");

            DigitalTwinClient digitalTwinClient = await CreateDigitalTwinsClientAsync();

            Console.WriteLine("Registering digital twin intefaces.");
            await digitalTwinClient
            .RegisterInterfacesAsync(
                CapabilityModelId,
                new DigitalTwinInterfaceClient[]
            {
                s1Sensor,
                deviceInformationInterface
            },
                quitSignal)
            .ConfigureAwait(false);

            await deviceInformationInterface.SendDeviceInfoPropertiesAsync(DeviceInfoProperties).ConfigureAwait(false);

            await s1Sensor.EnterTelemetryLoopAsync(quitSignal).ConfigureAwait(false);
        }
示例#8
0
        public static async Task <int> Main(string[] args)
        {
            if (args.Length < 3)
            {
                Console.WriteLine("ProvisioningDeviceClientSymmetricKey <IDScope> <Secret> <registration>");
                return(1);
            }

            s_idScope = args[0];
            string primaryKey   = args[1];
            string secondaryKey = args[1];

            registrationId = args[2];

            SecurityProvider _security;

            using (var security = new SecurityProviderSymmetricKey(registrationId, primaryKey, secondaryKey))
                // Select one of the available transports:
                // To optimize for size, reference only the protocols used by your application.
                using (var transport = new ProvisioningTransportHandlerAmqp(TransportFallbackType.TcpOnly))
                // using (var transport = new ProvisioningTransportHandlerHttp())
                // using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly))
                // using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.WebSocketOnly))
                {
                    _security = security;
                    ProvisioningDeviceClient _provClient =
                        ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, s_idScope, _security, transport);


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

                    Console.Write("ProvisioningClient RegisterAsync . . . ");
                    DeviceRegistrationResult result = await _provClient.RegisterAsync().ConfigureAwait(false);

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

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

                    IAuthenticationMethod auth;
                    if (_security is SecurityProviderTpm)
                    {
                        Console.WriteLine("Creating TPM DeviceClient authentication.");
                        auth = new DeviceAuthenticationWithTpm(result.DeviceId, (_security as SecurityProviderTpm));
                    }
                    else if (_security is SecurityProviderX509)
                    {
                        Console.WriteLine("Creating X509 DeviceClient authentication.");
                        auth = new DeviceAuthenticationWithX509Certificate(result.DeviceId, (_security as SecurityProviderX509).GetAuthenticationCertificate());
                    }
                    else if (_security is SecurityProviderSymmetricKey)
                    {
                        Console.WriteLine("Creating Symmetric Key DeviceClient authenication");
                        auth = new DeviceAuthenticationWithRegistrySymmetricKey(result.DeviceId, (_security as SecurityProviderSymmetricKey).GetPrimaryKey());
                    }
                    else
                    {
                        throw new NotSupportedException("Unknown authentication type.");
                    }

                    // using (var deviceClient = DeviceClient.CreateFromConnectionString(deviceConnectionString, transportType))
                    using (DeviceClient deviceClient = DeviceClient.Create(result.AssignedHub, auth, TransportType.Amqp))
                    {
                        //
                        DigitalTwinClient digitalTwinClient = new DigitalTwinClient(deviceClient);

                        if (digitalTwinClient == null)
                        {
                            Console.WriteLine("Failed to create DeviceClient!");
                            return(1);
                        }

                        var sample = new DigitalTwinClientSample(digitalTwinClient);
                        await sample.RunSampleAsync();

                        Console.WriteLine("Waiting to receive updates from cloud...");
                        Console.WriteLine("Press any key to exit");
                        Console.ReadLine();
                    }
                }
            return(0);
        }
 public TemperatureControllerSample(DigitalTwinClient client, string digitalTwinId, ILogger logger)
 {
     _digitalTwinClient = client ?? throw new ArgumentNullException(nameof(client));
     _digitalTwinId     = digitalTwinId ?? throw new ArgumentNullException(nameof(digitalTwinId));
     _logger            = logger ?? LoggerFactory.Create(builder => builder.AddConsole()).CreateLogger <TemperatureControllerSample>();
 }
        public async Task DigitalTwinWithOnlyRootComponentOperationsAsync()
        {
            // Create a new test device instance.
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);

            string deviceId = testDevice.Id;

            try
            {
                // Create a device client instance over Mqtt, initializing it with the "Thermostat" model which has only a root component.
                var options = new ClientOptions
                {
                    ModelId = ThermostatModelId,
                };
                using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Mqtt, options);

                // Call openAsync() to open the device's connection, so that the ModelId is sent over Mqtt CONNECT packet.
                await deviceClient.OpenAsync().ConfigureAwait(false);

                // Perform operations on the digital twin.
                using var digitalTwinClient = DigitalTwinClient.CreateFromConnectionString(s_connectionString);

                // Retrieve the digital twin.
                HttpOperationResponse <ThermostatTwin, DigitalTwinGetHeaders> response =
                    await digitalTwinClient.GetDigitalTwinAsync <ThermostatTwin>(deviceId).ConfigureAwait(false);

                ThermostatTwin twin = response.Body;
                twin.Metadata.ModelId.Should().Be(ThermostatModelId);

                // Set callback handler for receiving root-level twin property updates.
                await deviceClient.SetDesiredPropertyUpdateCallbackAsync((patch, context) =>
                {
                    Logger.Trace($"{nameof(DigitalTwinWithComponentOperationsAsync)}: DesiredProperty update received: {patch}, {context}");
                    return(Task.FromResult(true));
                }, deviceClient);

                // Update the root-level property "targetTemperature".
                string propertyName  = "targetTemperature";
                double propertyValue = new Random().Next(0, 100);
                var    ops           = new UpdateOperationsUtility();
                ops.AppendAddPropertyOp($"/{propertyName}", propertyValue);
                string patch = ops.Serialize();
                HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> updateResponse =
                    await digitalTwinClient.UpdateDigitalTwinAsync(deviceId, patch);

                updateResponse.Response.StatusCode.Should().Be(HttpStatusCode.Accepted);

                // Set callback to handle root-level command invocation request.
                int    expectedCommandStatus = 200;
                string commandName           = "getMaxMinReport";
                await deviceClient.SetMethodHandlerAsync(commandName,
                                                         (request, context) =>
                {
                    Logger.Trace($"{nameof(DigitalTwinWithOnlyRootComponentOperationsAsync)}: Digital twin command received: {request.Name}.");
                    string payload = JsonConvert.SerializeObject(request.Name);
                    return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(payload), expectedCommandStatus)));
                },
                                                         null);

                // Invoke the root-level command "getMaxMinReport" on the digital twin.
                DateTimeOffset since   = DateTimeOffset.Now.Subtract(TimeSpan.FromMinutes(1));
                string         payload = JsonConvert.SerializeObject(since);
                HttpOperationResponse <DigitalTwinCommandResponse, DigitalTwinInvokeCommandHeaders> commandResponse =
                    await digitalTwinClient.InvokeCommandAsync(deviceId, commandName, payload).ConfigureAwait(false);

                commandResponse.Body.Status.Should().Be(expectedCommandStatus);
                commandResponse.Body.Payload.Should().Be(JsonConvert.SerializeObject(commandName));
            }
            finally
            {
                // Delete the device.
                await testDevice.RemoveDeviceAsync().ConfigureAwait(false);
            }
        }
        public async Task DigitalTwinWithComponentOperationsAsync()
        {
            // Create a new test device instance.
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);

            string deviceId = testDevice.Id;

            try
            {
                // Create a device client instance over Mqtt, initializing it with the "TemperatureController" model which has "Thermostat" components.
                var options = new ClientOptions
                {
                    ModelId = TemperatureControllerModelId,
                };
                using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Mqtt, options);

                // Call openAsync() to open the device's connection, so that the ModelId is sent over Mqtt CONNECT packet.
                await deviceClient.OpenAsync().ConfigureAwait(false);

                // Perform operations on the digital twin.
                using var digitalTwinClient = DigitalTwinClient.CreateFromConnectionString(s_connectionString);

                // Retrieve the digital twin.
                HttpOperationResponse <TemperatureControllerTwin, DigitalTwinGetHeaders> response =
                    await digitalTwinClient.GetDigitalTwinAsync <TemperatureControllerTwin>(deviceId).ConfigureAwait(false);

                TemperatureControllerTwin twin = response.Body;
                twin.Metadata.ModelId.Should().Be(TemperatureControllerModelId);

                string componentName = "thermostat1";

                // Set callback handler for receiving twin property updates.
                await deviceClient.SetDesiredPropertyUpdateCallbackAsync((patch, context) =>
                {
                    Logger.Trace($"{nameof(DigitalTwinWithComponentOperationsAsync)}: DesiredProperty update received: {patch}, {context}");
                    return(Task.FromResult(true));
                }, deviceClient);

                // Update the property "targetTemperature" under component "thermostat1" on the digital twin.
                // NOTE: since this is the first operation on the digital twin, the component "thermostat1" doesn't exist on it yet.
                // So we will create a property patch that "adds" a component, and updates the property in it.
                string propertyName   = "targetTemperature";
                double propertyValue  = new Random().Next(0, 100);
                var    propertyValues = new Dictionary <string, object> {
                    { propertyName, propertyValue }
                };

                var ops = new UpdateOperationsUtility();
                ops.AppendAddComponentOp($"/{componentName}", propertyValues);
                string patch = ops.Serialize();
                HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> updateResponse =
                    await digitalTwinClient.UpdateDigitalTwinAsync(deviceId, patch);

                updateResponse.Response.StatusCode.Should().Be(HttpStatusCode.Accepted);

                // Set callbacks to handle command requests.
                int expectedCommandStatus = 200;

                // Set callback to handle root-level command invocation request.
                string rootCommandName = "reboot";
                await deviceClient.SetMethodHandlerAsync(rootCommandName,
                                                         (request, context) =>
                {
                    Logger.Trace($"{nameof(DigitalTwinWithComponentOperationsAsync)}: Digital twin command {request.Name} received.");
                    string payload = JsonConvert.SerializeObject(request.Name);
                    return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(payload), expectedCommandStatus)));
                },
                                                         null);

                // Invoke the root-level command "reboot" on the digital twin.
                int    delay = 1;
                string rootCommandPayload = JsonConvert.SerializeObject(delay);
                HttpOperationResponse <DigitalTwinCommandResponse, DigitalTwinInvokeCommandHeaders> rootCommandResponse =
                    await digitalTwinClient.InvokeCommandAsync(deviceId, rootCommandName, rootCommandPayload).ConfigureAwait(false);

                rootCommandResponse.Body.Status.Should().Be(expectedCommandStatus);
                rootCommandResponse.Body.Payload.Should().Be(JsonConvert.SerializeObject(rootCommandName));

                // Set callback to handle component-level command invocation request.
                // For a component-level command, the command name is in the format "<component-name>*<command-name>".
                string componentCommandName    = "getMaxMinReport";
                string componentCommandNamePnp = $"{componentName}*{componentCommandName}";
                await deviceClient.SetMethodHandlerAsync(componentCommandNamePnp,
                                                         (request, context) =>
                {
                    Logger.Trace($"{nameof(DigitalTwinWithComponentOperationsAsync)}: Digital twin command {request.Name} received.");
                    string payload = JsonConvert.SerializeObject(request.Name);
                    return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(payload), expectedCommandStatus)));
                },
                                                         null);

                // Invoke the command "getMaxMinReport" under component "thermostat1" on the digital twin.
                DateTimeOffset since = DateTimeOffset.Now.Subtract(TimeSpan.FromMinutes(1));
                string         componentCommandPayload = JsonConvert.SerializeObject(since);
                HttpOperationResponse <DigitalTwinCommandResponse, DigitalTwinInvokeCommandHeaders> componentCommandResponse =
                    await digitalTwinClient.InvokeComponentCommandAsync(deviceId, componentName, componentCommandName, componentCommandPayload).ConfigureAwait(false);

                componentCommandResponse.Body.Status.Should().Be(expectedCommandStatus);
                componentCommandResponse.Body.Payload.Should().Be(JsonConvert.SerializeObject(componentCommandNamePnp));
            }
            finally
            {
                // Delete the device.
                await testDevice.RemoveDeviceAsync().ConfigureAwait(false);
            }
        }