/// <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); }
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); }
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); }
/// <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; }
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); }
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); } }