La version 4 (V4) du AWS SDK pour .NET est sortie !
Pour plus d'informations sur les modifications majeures et la migration de vos applications, consultez la rubrique relative à la migration.
Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
AWS IoT exemples utilisant SDK pour .NET (v4)
Les exemples de code suivants vous montrent comment effectuer des actions et implémenter des scénarios courants en utilisant le AWS SDK pour .NET (v4) avec AWS IoT.
Les principes de base sont des exemples de code qui vous montrent comment effectuer les opérations essentielles au sein d’un service.
Les actions sont des extraits de code de programmes plus larges et doivent être exécutées dans leur contexte. Alors que les actions vous indiquent comment appeler des fonctions de service individuelles, vous pouvez les voir en contexte dans leurs scénarios associés.
Chaque exemple inclut un lien vers le code source complet, où vous trouverez des instructions sur la configuration et l’exécution du code en contexte.
Mise en route
Les exemples de code suivants montrent comment démarrer avec AWS IoT.
- SDK pour .NET (v4)
-
Note
Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS
. /// <summary> /// Hello AWS IoT example. /// </summary> public class HelloIoT { /// <summary> /// Main method to run the Hello IoT example. /// </summary> /// <param name="args">Command line arguments.</param> /// <returns>A Task object.</returns> public static async Task Main(string[] args) { var iotClient = new AmazonIoTClient(); try { Console.WriteLine("Hello AWS IoT! Let's list your IoT Things:"); Console.WriteLine(new string('-', 80)); // Use pages of 10. var request = new ListThingsRequest() { MaxResults = 10 }; var response = await iotClient.ListThingsAsync(request); // Since there is not a built-in paginator, use the NextMarker to paginate. bool hasMoreResults = true; var things = new List<ThingAttribute>(); while (hasMoreResults) { things.AddRange(response.Things); // If NextMarker is not null, there are more results. Get the next page of results. if (!String.IsNullOrEmpty(response.NextMarker)) { request.Marker = response.NextMarker; response = await iotClient.ListThingsAsync(request); } else hasMoreResults = false; } if (things is { Count: > 0 }) { Console.WriteLine($"Found {things.Count} IoT Things:"); foreach (var thing in things) { Console.WriteLine($"- Thing Name: {thing.ThingName}"); Console.WriteLine($" Thing ARN: {thing.ThingArn}"); Console.WriteLine($" Thing Type: {thing.ThingTypeName ?? "No type specified"}"); Console.WriteLine($" Version: {thing.Version}"); if (thing.Attributes?.Count > 0) { Console.WriteLine(" Attributes:"); foreach (var attr in thing.Attributes) { Console.WriteLine($" {attr.Key}: {attr.Value}"); } } Console.WriteLine(); } } else { Console.WriteLine("No IoT Things found in your account."); Console.WriteLine("You can create IoT Things using the IoT Basics scenario example."); } Console.WriteLine("Hello IoT completed successfully."); } catch (Amazon.IoT.Model.ThrottlingException ex) { Console.WriteLine($"Request throttled, please try again later: {ex.Message}"); } catch (Exception ex) { Console.WriteLine($"Couldn't list Things. Here's why: {ex.Message}"); } } }-
Pour plus de détails sur l’API, consultez listThings dans la Référence des API du kit AWS SDK pour .NET .
-
Rubriques
Principes de base
L’exemple de code suivant illustre comment :
Créez un AWS IoT objet.
générer un certificat d’appareil ;
Mettez à jour un AWS IoT objet avec des attributs.
renvoyer un point de terminaison unique ;
Répertoriez vos AWS IoT certificats.
Mettez à jour une AWS IoT ombre.
rédiger les informations d’état ;
créer une règle ;
répertorier vos règles ;
rechercher des objets en utilisant le nom de l’objet ;
Supprimer un AWS IoT objet.
- SDK pour .NET (v4)
-
Note
Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS
. Exécutez un scénario interactif illustrant AWS IoT les fonctionnalités.
/// <summary> /// Scenario class for AWS IoT basics. /// </summary> public class IoTBasics { public static bool IsInteractive = true; public static IoTWrapper? Wrapper = null; public static IAmazonCloudFormation? CloudFormationClient = null; public static ILogger<IoTBasics> logger = null!; private static IoTWrapper _iotWrapper = null!; private static IAmazonCloudFormation _amazonCloudFormation = null!; private static ILogger<IoTBasics> _logger = null!; private static string _stackName = "IoTBasicsStack"; private static string _stackResourcePath = "../../../../../../scenarios/basics/iot/iot_usecase/resources/cfn_template.yaml"; /// <summary> /// Main method for the IoT Basics scenario. /// </summary> /// <param name="args">Command line arguments.</param> /// <returns>A Task object.</returns> public static async Task Main(string[] args) { // Set up dependency injection for the Amazon service. using var host = Host.CreateDefaultBuilder(args) .ConfigureServices((_, services) => services.AddAWSService<IAmazonIoT>(new AWSOptions() { Region = RegionEndpoint.USEast1 }) .AddAWSService<IAmazonCloudFormation>() .AddTransient<IoTWrapper>() .AddLogging(builder => builder.AddConsole()) .AddSingleton<IAmazonIotData>(sp => { var iotService = sp.GetRequiredService<IAmazonIoT>(); var request = new DescribeEndpointRequest { EndpointType = "iot:Data-ATS" }; var response = iotService.DescribeEndpointAsync(request).Result; return new AmazonIotDataClient($"https://{response.EndpointAddress}/"); }) ) .Build(); logger = LoggerFactory.Create(builder => builder.AddConsole()) .CreateLogger<IoTBasics>(); Wrapper = host.Services.GetRequiredService<IoTWrapper>(); CloudFormationClient = host.Services.GetRequiredService<IAmazonCloudFormation>(); // Set the private fields for backwards compatibility _logger = logger; _iotWrapper = Wrapper; _amazonCloudFormation = CloudFormationClient; Console.WriteLine(new string('-', 80)); Console.WriteLine("Welcome to the AWS IoT example scenario."); Console.WriteLine("This example program demonstrates various interactions with the AWS Internet of Things (IoT) Core service."); Console.WriteLine(); if (IsInteractive) { Console.WriteLine("Press Enter to continue..."); Console.ReadLine(); } Console.WriteLine(new string('-', 80)); try { await RunScenarioAsync(); } catch (Exception ex) { _logger.LogError(ex, "There was a problem running the scenario."); Console.WriteLine($"\nAn error occurred: {ex.Message}"); } Console.WriteLine(new string('-', 80)); Console.WriteLine("The AWS IoT scenario has successfully completed."); Console.WriteLine(new string('-', 80)); } /// <summary> /// Run the IoT Basics scenario. /// </summary> /// <returns>A Task object.</returns> public static async Task RunScenarioAsync() { // Use static properties if available, otherwise use private fields var iotWrapper = Wrapper ?? _iotWrapper; var cloudFormationClient = CloudFormationClient ?? _amazonCloudFormation; var scenarioLogger = logger ?? _logger; await RunScenarioInternalAsync(iotWrapper, cloudFormationClient, scenarioLogger); } /// <summary> /// Internal method to run the IoT Basics scenario with injected dependencies. /// </summary> /// <param name="iotWrapper">The IoT wrapper instance.</param> /// <param name="cloudFormationClient">The CloudFormation client instance.</param> /// <param name="scenarioLogger">The logger instance.</param> /// <returns>A Task object.</returns> private static async Task RunScenarioInternalAsync(IoTWrapper iotWrapper, IAmazonCloudFormation cloudFormationClient, ILogger<IoTBasics> scenarioLogger) { string thingName = $"iot-thing-{Guid.NewGuid():N}"; string certificateArn = ""; string certificateId = ""; string ruleName = $"iotruledefault"; string snsTopicArn = ""; try { // Step 1: Create an AWS IoT Thing Console.WriteLine(new string('-', 80)); Console.WriteLine("1. Create an AWS IoT Thing."); Console.WriteLine("An AWS IoT Thing represents a virtual entity in the AWS IoT service that can be associated with a physical device."); Console.WriteLine(); if (IsInteractive) { Console.Write("Enter Thing name: "); var userInput = Console.ReadLine(); if (!string.IsNullOrEmpty(userInput)) thingName = userInput; } else { Console.WriteLine($"Using default Thing name: {thingName}"); } var thingArn = await iotWrapper.CreateThingAsync(thingName); Console.WriteLine($"{thingName} was successfully created. The ARN value is {thingArn}"); Console.WriteLine(new string('-', 80)); // Step 1.1: List AWS IoT Things Console.WriteLine(new string('-', 80)); Console.WriteLine("2. List AWS IoT Things."); Console.WriteLine("Now let's list the IoT Things to see the Thing we just created."); Console.WriteLine(); if (IsInteractive) { Console.WriteLine("Press Enter to continue..."); Console.ReadLine(); } var things = await iotWrapper.ListThingsAsync(); Console.WriteLine($"Found {things.Count} IoT Things:"); foreach (var thing in things.Take(10)) // Show first 10 things { Console.WriteLine($"Thing Name: {thing.ThingName}"); Console.WriteLine($"Thing ARN: {thing.ThingArn}"); if (thing.Attributes != null && thing.Attributes.Any()) { Console.WriteLine("Attributes:"); foreach (var attr in thing.Attributes) { Console.WriteLine($" {attr.Key}: {attr.Value}"); } } Console.WriteLine("--------------"); } Console.WriteLine(); Console.WriteLine(new string('-', 80)); // Step 2: Generate a Device Certificate Console.WriteLine(new string('-', 80)); Console.WriteLine("3. Generate a device certificate."); Console.WriteLine("A device certificate performs a role in securing the communication between devices (Things) and the AWS IoT platform."); Console.WriteLine(); var createCert = "y"; if (IsInteractive) { Console.Write($"Do you want to create a certificate for {thingName}? (y/n)"); createCert = Console.ReadLine(); } else { Console.WriteLine($"Creating certificate for {thingName}..."); } if (createCert?.ToLower() == "y") { var certificateResult = await iotWrapper.CreateKeysAndCertificateAsync(); if (certificateResult.HasValue) { var (certArn, certPem, certId) = certificateResult.Value; certificateArn = certArn; certificateId = certId; Console.WriteLine($"\nCertificate:"); // Show only first few lines of certificate for brevity var lines = certPem.Split('\n'); for (int i = 0; i < Math.Min(lines.Length, 5); i++) { Console.WriteLine(lines[i]); } if (lines.Length > 5) { Console.WriteLine("..."); } Console.WriteLine($"\nCertificate ARN:"); Console.WriteLine(certificateArn); // Step 3: Attach the Certificate to the AWS IoT Thing Console.WriteLine("Attach the certificate to the AWS IoT Thing."); var attachResult = await iotWrapper.AttachThingPrincipalAsync(thingName, certificateArn); if (attachResult) { Console.WriteLine("Certificate attached to Thing successfully."); } else { Console.WriteLine("Failed to attach certificate to Thing."); } Console.WriteLine("Thing Details:"); Console.WriteLine($"Thing Name: {thingName}"); Console.WriteLine($"Thing ARN: {thingArn}"); } else { Console.WriteLine("Failed to create certificate."); } } Console.WriteLine(new string('-', 80)); // Step 4: Update an AWS IoT Thing with Attributes Console.WriteLine(new string('-', 80)); Console.WriteLine("4. Update an AWS IoT Thing with Attributes."); Console.WriteLine("IoT Thing attributes, represented as key-value pairs, offer a pivotal advantage in facilitating efficient data"); Console.WriteLine("management and retrieval within the AWS IoT ecosystem."); Console.WriteLine(); if (IsInteractive) { Console.WriteLine("Press Enter to continue..."); Console.ReadLine(); } var attributes = new Dictionary<string, string> { { "Location", "Seattle" }, { "DeviceType", "Sensor" }, { "Firmware", "1.2.3" } }; await iotWrapper.UpdateThingAsync(thingName, attributes); Console.WriteLine("Thing attributes updated successfully."); Console.WriteLine(new string('-', 80)); // Step 5: Return a unique endpoint specific to the Amazon Web Services account Console.WriteLine(new string('-', 80)); Console.WriteLine("5. Return a unique endpoint specific to the Amazon Web Services account."); Console.WriteLine(); if (IsInteractive) { Console.WriteLine("Press Enter to continue..."); Console.ReadLine(); } var endpoint = await iotWrapper.DescribeEndpointAsync(); if (endpoint != null) { var subdomain = endpoint.Split('.')[0]; Console.WriteLine($"Extracted subdomain: {subdomain}"); Console.WriteLine($"Full Endpoint URL: https://{endpoint}"); } else { Console.WriteLine("Failed to retrieve endpoint."); } Console.WriteLine(new string('-', 80)); // Step 6: List your AWS IoT certificates Console.WriteLine(new string('-', 80)); Console.WriteLine("6. List your AWS IoT certificates"); if (IsInteractive) { Console.WriteLine("Press Enter to continue..."); Console.ReadLine(); } var certificates = await iotWrapper.ListCertificatesAsync(); foreach (var cert in certificates.Take(5)) // Show first 5 certificates { Console.WriteLine($"Cert id: {cert.CertificateId}"); Console.WriteLine($"Cert Arn: {cert.CertificateArn}"); } Console.WriteLine(); Console.WriteLine(new string('-', 80)); // Step 7: Create an IoT shadow Console.WriteLine(new string('-', 80)); Console.WriteLine("7. Update an IoT shadow that refers to a digital representation or virtual twin of a physical IoT device"); Console.WriteLine(); if (IsInteractive) { Console.WriteLine("Press Enter to continue..."); Console.ReadLine(); } var shadowPayload = JsonSerializer.Serialize(new { state = new { desired = new { temperature = 25, humidity = 50 } } }); await iotWrapper.UpdateThingShadowAsync(thingName, shadowPayload); Console.WriteLine("Thing Shadow updated successfully."); Console.WriteLine(new string('-', 80)); // Step 8: Write out the state information, in JSON format Console.WriteLine(new string('-', 80)); Console.WriteLine("8. Write out the state information, in JSON format."); if (IsInteractive) { Console.WriteLine("Press Enter to continue..."); Console.ReadLine(); } var shadowData = await iotWrapper.GetThingShadowAsync(thingName); Console.WriteLine($"Received Shadow Data: {shadowData}"); Console.WriteLine(new string('-', 80)); // Step 9: Set up resources (SNS topic and IAM role) and create a rule Console.WriteLine(new string('-', 80)); Console.WriteLine("9. Set up resources and create a rule"); Console.WriteLine(); // Deploy CloudFormation stack to create SNS topic and IAM role Console.WriteLine("Deploying CloudFormation stack to create SNS topic and IAM role..."); var deployStack = !IsInteractive || GetYesNoResponse("Would you like to deploy the CloudFormation stack? (y/n) "); if (deployStack) { if (IsInteractive) { Console.Write( $"Enter stack resource file path (or press Enter for default '{_stackResourcePath}'): "); var userResourcePath = Console.ReadLine(); if (!string.IsNullOrEmpty(userResourcePath)) _stackResourcePath = userResourcePath; } _stackName = PromptUserForStackName(); var deploySuccess = await DeployCloudFormationStack(_stackName, cloudFormationClient, scenarioLogger); if (deploySuccess) { // Get stack outputs var stackOutputs = await GetStackOutputs(_stackName, cloudFormationClient, scenarioLogger); if (stackOutputs != null) { snsTopicArn = stackOutputs["SNSTopicArn"]; string roleArn = stackOutputs["RoleArn"]; Console.WriteLine($"Successfully deployed stack. SNS topic: {snsTopicArn}"); Console.WriteLine($"Successfully deployed stack. IAM role: {roleArn}"); if (IsInteractive) { Console.Write($"Enter Rule name (press Enter for default '{ruleName}'): "); var userRuleName = Console.ReadLine(); if (!string.IsNullOrEmpty(userRuleName)) ruleName = userRuleName; } else { Console.WriteLine($"Using default rule name: {ruleName}"); } // Now create the IoT rule with the CloudFormation outputs var ruleResult = await iotWrapper.CreateTopicRuleAsync(ruleName, snsTopicArn, roleArn); if (ruleResult) { Console.WriteLine("IoT Rule created successfully."); } else { Console.WriteLine("Failed to create IoT rule."); } } else { Console.WriteLine("Failed to get stack outputs. Skipping rule creation."); } } else { Console.WriteLine("Failed to deploy CloudFormation stack. Skipping rule creation."); } } else { Console.WriteLine("Skipping CloudFormation stack deployment and rule creation."); } Console.WriteLine(new string('-', 80)); // Step 10: List your rules Console.WriteLine(new string('-', 80)); Console.WriteLine("10. List your rules."); if (IsInteractive) { Console.WriteLine("Press Enter to continue..."); Console.ReadLine(); } var rules = await iotWrapper.ListTopicRulesAsync(); Console.WriteLine("List of IoT Rules:"); foreach (var rule in rules.Take(5)) // Show first 5 rules { Console.WriteLine($"Rule Name: {rule.RuleName}"); Console.WriteLine($"Rule ARN: {rule.RuleArn}"); Console.WriteLine("--------------"); } Console.WriteLine(); Console.WriteLine(new string('-', 80)); // Step 11: Search things using the Thing name Console.WriteLine(new string('-', 80)); Console.WriteLine("11. Search things using the Thing name."); if (IsInteractive) { Console.WriteLine("Press Enter to continue..."); Console.ReadLine(); } var searchResults = await iotWrapper.SearchIndexAsync($"thingName:{thingName}"); if (searchResults.Any()) { Console.WriteLine($"Thing id found using search is {searchResults.First().ThingId}"); } else { Console.WriteLine($"No search results found for Thing: {thingName}"); } Console.WriteLine(new string('-', 80)); // Step 12: Cleanup - Detach and delete certificate if (!string.IsNullOrEmpty(certificateArn)) { Console.WriteLine(new string('-', 80)); var deleteCert = "y"; if (IsInteractive) { Console.Write($"Do you want to detach and delete the certificate for {thingName}? (y/n)"); deleteCert = Console.ReadLine(); } else { Console.WriteLine($"Detaching and deleting certificate for {thingName}..."); } if (deleteCert?.ToLower() == "y") { Console.WriteLine("12. You selected to detach and delete the certificate."); if (IsInteractive) { Console.WriteLine("Press Enter to continue..."); Console.ReadLine(); } await iotWrapper.DetachThingPrincipalAsync(thingName, certificateArn); Console.WriteLine($"{certificateArn} was successfully removed from {thingName}"); await iotWrapper.DeleteCertificateAsync(certificateId); Console.WriteLine($"{certificateArn} was successfully deleted."); } Console.WriteLine(new string('-', 80)); } // Step 13: Delete the AWS IoT Thing Console.WriteLine(new string('-', 80)); Console.WriteLine("13. Delete the AWS IoT Thing."); var deleteThing = "y"; if (IsInteractive) { Console.Write($"Do you want to delete the IoT Thing? (y/n)"); deleteThing = Console.ReadLine(); } else { Console.WriteLine($"Deleting IoT Thing {thingName}..."); } if (deleteThing?.ToLower() == "y") { await iotWrapper.DeleteThingAsync(thingName); Console.WriteLine($"Deleted Thing {thingName}"); } Console.WriteLine(new string('-', 80)); // Step 14: Clean up CloudFormation stack if (!string.IsNullOrEmpty(snsTopicArn)) { Console.WriteLine(new string('-', 80)); Console.WriteLine("14. Clean up CloudFormation stack."); Console.WriteLine("Deleting the CloudFormation stack and all resources..."); var cleanup = !IsInteractive || GetYesNoResponse("Do you want to delete the CloudFormation stack and all resources? (y/n) "); if (cleanup) { var ruleCleanupSuccess = await iotWrapper.DeleteTopicRuleAsync(ruleName); var stackCleanupSuccess = await DeleteCloudFormationStack(_stackName, cloudFormationClient, scenarioLogger); if (ruleCleanupSuccess && stackCleanupSuccess) { Console.WriteLine("Successfully cleaned up CloudFormation stack and all resources."); } else { Console.WriteLine("Some cleanup operations failed. Check the logs for details."); } } else { Console.WriteLine($"Resources will remain. Stack name: {_stackName}"); } Console.WriteLine(new string('-', 80)); } } catch (Exception ex) { scenarioLogger.LogError(ex, "Error occurred during scenario execution."); // Cleanup on error if (!string.IsNullOrEmpty(certificateArn) && !string.IsNullOrEmpty(thingName)) { try { await iotWrapper.DetachThingPrincipalAsync(thingName, certificateArn); await iotWrapper.DeleteCertificateAsync(certificateId); } catch (Exception cleanupEx) { scenarioLogger.LogError(cleanupEx, "Error during cleanup."); } } if (!string.IsNullOrEmpty(thingName)) { try { await iotWrapper.DeleteThingAsync(thingName); } catch (Exception cleanupEx) { scenarioLogger.LogError(cleanupEx, "Error during Thing cleanup."); } } // Clean up CloudFormation stack on error if (!string.IsNullOrEmpty(snsTopicArn)) { try { await _iotWrapper.DeleteTopicRuleAsync(ruleName); await DeleteCloudFormationStack(_stackName, cloudFormationClient, scenarioLogger); } catch (Exception cleanupEx) { scenarioLogger.LogError(cleanupEx, "Error during CloudFormation stack cleanup."); } } throw; } } /// <summary> /// Deploys the CloudFormation stack with the necessary resources. /// </summary> /// <param name="stackName">The name of the CloudFormation stack.</param> /// <param name="cloudFormationClient">The CloudFormation client.</param> /// <param name="scenarioLogger">The logger.</param> /// <returns>True if the stack was deployed successfully.</returns> private static async Task<bool> DeployCloudFormationStack(string stackName, IAmazonCloudFormation cloudFormationClient, ILogger<IoTBasics> scenarioLogger) { Console.WriteLine($"\nDeploying CloudFormation stack: {stackName}"); try { var request = new CreateStackRequest { StackName = stackName, TemplateBody = await File.ReadAllTextAsync(_stackResourcePath), Capabilities = new List<string> { Capability.CAPABILITY_NAMED_IAM } }; var response = await cloudFormationClient.CreateStackAsync(request); if (response.HttpStatusCode == System.Net.HttpStatusCode.OK) { Console.WriteLine($"CloudFormation stack creation started: {stackName}"); bool stackCreated = await WaitForStackCompletion(response.StackId, cloudFormationClient, scenarioLogger); if (stackCreated) { Console.WriteLine("CloudFormation stack created successfully."); return true; } else { scenarioLogger.LogError($"CloudFormation stack creation failed: {stackName}"); return false; } } else { scenarioLogger.LogError($"Failed to create CloudFormation stack: {stackName}"); return false; } } catch (AlreadyExistsException) { scenarioLogger.LogWarning($"CloudFormation stack '{stackName}' already exists. Please provide a unique name."); var newStackName = PromptUserForStackName(); return await DeployCloudFormationStack(newStackName, cloudFormationClient, scenarioLogger); } catch (Exception ex) { scenarioLogger.LogError(ex, $"An error occurred while deploying the CloudFormation stack: {stackName}"); return false; } } /// <summary> /// Waits for the CloudFormation stack to be in the CREATE_COMPLETE state. /// </summary> /// <param name="stackId">The ID of the CloudFormation stack.</param> /// <param name="cloudFormationClient">The CloudFormation client.</param> /// <param name="scenarioLogger">The logger.</param> /// <returns>True if the stack was created successfully.</returns> private static async Task<bool> WaitForStackCompletion(string stackId, IAmazonCloudFormation cloudFormationClient, ILogger<IoTBasics> scenarioLogger) { int retryCount = 0; const int maxRetries = 30; const int retryDelay = 10000; while (retryCount < maxRetries) { var describeStacksRequest = new DescribeStacksRequest { StackName = stackId }; var describeStacksResponse = await cloudFormationClient.DescribeStacksAsync(describeStacksRequest); if (describeStacksResponse.Stacks.Count > 0) { if (describeStacksResponse.Stacks[0].StackStatus == StackStatus.CREATE_COMPLETE) { return true; } if (describeStacksResponse.Stacks[0].StackStatus == StackStatus.CREATE_FAILED || describeStacksResponse.Stacks[0].StackStatus == StackStatus.ROLLBACK_COMPLETE) { return false; } } Console.WriteLine("Waiting for CloudFormation stack creation to complete..."); await Task.Delay(retryDelay); retryCount++; } scenarioLogger.LogError("Timed out waiting for CloudFormation stack creation to complete."); return false; } /// <summary> /// Gets the outputs from the CloudFormation stack. /// </summary> /// <param name="stackName">The name of the CloudFormation stack.</param> /// <param name="cloudFormationClient">The CloudFormation client.</param> /// <param name="scenarioLogger">The logger.</param> /// <returns>A dictionary of stack outputs.</returns> private static async Task<Dictionary<string, string>?> GetStackOutputs(string stackName, IAmazonCloudFormation cloudFormationClient, ILogger<IoTBasics> scenarioLogger) { try { var describeStacksRequest = new DescribeStacksRequest { StackName = stackName }; var response = await cloudFormationClient.DescribeStacksAsync(describeStacksRequest); if (response.Stacks.Count > 0) { var outputs = new Dictionary<string, string>(); foreach (var output in response.Stacks[0].Outputs) { outputs[output.OutputKey] = output.OutputValue; } return outputs; } return null; } catch (Exception ex) { scenarioLogger.LogError(ex, $"Failed to get stack outputs for {stackName}"); return null; } } /// <summary> /// Deletes the CloudFormation stack and waits for confirmation. /// </summary> /// <param name="stackName">The name of the CloudFormation stack.</param> /// <param name="cloudFormationClient">The CloudFormation client.</param> /// <param name="scenarioLogger">The logger.</param> /// <returns>True if the stack was deleted successfully.</returns> private static async Task<bool> DeleteCloudFormationStack(string stackName, IAmazonCloudFormation cloudFormationClient, ILogger<IoTBasics> scenarioLogger) { try { var request = new DeleteStackRequest { StackName = stackName }; await cloudFormationClient.DeleteStackAsync(request); Console.WriteLine($"CloudFormation stack '{stackName}' is being deleted. This may take a few minutes."); bool stackDeleted = await WaitForStackDeletion(stackName, cloudFormationClient, scenarioLogger); if (stackDeleted) { Console.WriteLine($"CloudFormation stack '{stackName}' has been deleted."); return true; } else { scenarioLogger.LogError($"Failed to delete CloudFormation stack '{stackName}'."); return false; } } catch (Exception ex) { scenarioLogger.LogError(ex, $"An error occurred while deleting the CloudFormation stack: {stackName}"); return false; } } /// <summary> /// Waits for the stack to be deleted. /// </summary> /// <param name="stackName">The name of the CloudFormation stack.</param> /// <param name="cloudFormationClient">The CloudFormation client.</param> /// <param name="scenarioLogger">The logger.</param> /// <returns>True if the stack was deleted successfully.</returns> private static async Task<bool> WaitForStackDeletion(string stackName, IAmazonCloudFormation cloudFormationClient, ILogger<IoTBasics> scenarioLogger) { int retryCount = 0; const int maxRetries = 30; const int retryDelay = 10000; while (retryCount < maxRetries) { var describeStacksRequest = new DescribeStacksRequest { StackName = stackName }; try { var describeStacksResponse = await cloudFormationClient.DescribeStacksAsync(describeStacksRequest); if (describeStacksResponse.Stacks.Count == 0 || describeStacksResponse.Stacks[0].StackStatus == StackStatus.DELETE_COMPLETE) { return true; } } catch (AmazonCloudFormationException ex) when (ex.ErrorCode == "ValidationError") { return true; } Console.WriteLine($"Waiting for CloudFormation stack '{stackName}' to be deleted..."); await Task.Delay(retryDelay); retryCount++; } scenarioLogger.LogError($"Timed out waiting for CloudFormation stack '{stackName}' to be deleted."); return false; } /// <summary> /// Helper method to get a yes or no response from the user. /// </summary> private static bool GetYesNoResponse(string question) { Console.WriteLine(question); var ynResponse = Console.ReadLine(); var response = ynResponse != null && ynResponse.Equals("y", StringComparison.InvariantCultureIgnoreCase); return response; } /// <summary> /// Prompts the user for a stack name. /// </summary> private static string PromptUserForStackName() { if (IsInteractive) { Console.Write($"Enter a name for the CloudFormation stack (press Enter for default '{_stackName}'): "); string? input = Console.ReadLine(); if (!string.IsNullOrWhiteSpace(input)) { var regex = new System.Text.RegularExpressions.Regex("[a-zA-Z][-a-zA-Z0-9]*"); if (!regex.IsMatch(input)) { Console.WriteLine($"Invalid stack name. Using default: {_stackName}"); return _stackName; } return input; } } return _stackName; } }Une classe wrapper pour les méthodes du AWS IoT SDK.
/// <summary> /// Wrapper methods to use Amazon IoT Core with .NET. /// </summary> public class IoTWrapper { private readonly IAmazonIoT _amazonIoT; private readonly IAmazonIotData _amazonIotData; private readonly ILogger<IoTWrapper> _logger; /// <summary> /// Constructor for the IoT wrapper. /// </summary> /// <param name="amazonIoT">The injected IoT client.</param> /// <param name="amazonIotData">The injected IoT Data client.</param> /// <param name="logger">The injected logger.</param> public IoTWrapper(IAmazonIoT amazonIoT, IAmazonIotData amazonIotData, ILogger<IoTWrapper> logger) { _amazonIoT = amazonIoT; _amazonIotData = amazonIotData; _logger = logger; } /// <summary> /// Creates an AWS IoT Thing. /// </summary> /// <param name="thingName">The name of the Thing to create.</param> /// <returns>The ARN of the Thing created, or null if creation failed.</returns> public async Task<string?> CreateThingAsync(string thingName) { try { var request = new CreateThingRequest { ThingName = thingName }; var response = await _amazonIoT.CreateThingAsync(request); _logger.LogInformation($"Created Thing {thingName} with ARN {response.ThingArn}"); return response.ThingArn; } catch (Amazon.IoT.Model.ResourceAlreadyExistsException ex) { _logger.LogWarning($"Thing {thingName} already exists: {ex.Message}"); return null; } catch (Exception ex) { _logger.LogError($"Couldn't create Thing {thingName}. Here's why: {ex.Message}"); return null; } } /// <summary> /// Creates a device certificate for AWS IoT. /// </summary> /// <returns>The certificate details including ARN and certificate PEM, or null if creation failed.</returns> public async Task<(string CertificateArn, string CertificatePem, string CertificateId)?> CreateKeysAndCertificateAsync() { try { var request = new CreateKeysAndCertificateRequest { SetAsActive = true }; var response = await _amazonIoT.CreateKeysAndCertificateAsync(request); _logger.LogInformation($"Created certificate with ARN {response.CertificateArn}"); return (response.CertificateArn, response.CertificatePem, response.CertificateId); } catch (Amazon.IoT.Model.ThrottlingException ex) { _logger.LogWarning($"Request throttled, please try again later: {ex.Message}"); return null; } catch (Exception ex) { _logger.LogError($"Couldn't create certificate. Here's why: {ex.Message}"); return null; } } /// <summary> /// Attaches a certificate to an IoT Thing. /// </summary> /// <param name="thingName">The name of the Thing.</param> /// <param name="certificateArn">The ARN of the certificate to attach.</param> /// <returns>True if successful, false otherwise.</returns> public async Task<bool> AttachThingPrincipalAsync(string thingName, string certificateArn) { try { var request = new AttachThingPrincipalRequest { ThingName = thingName, Principal = certificateArn }; await _amazonIoT.AttachThingPrincipalAsync(request); _logger.LogInformation($"Attached certificate {certificateArn} to Thing {thingName}"); return true; } catch (Amazon.IoT.Model.ResourceNotFoundException ex) { _logger.LogError($"Cannot attach certificate - resource not found: {ex.Message}"); return false; } catch (Exception ex) { _logger.LogError($"Couldn't attach certificate to Thing. Here's why: {ex.Message}"); return false; } } /// <summary> /// Updates an IoT Thing with attributes. /// </summary> /// <param name="thingName">The name of the Thing to update.</param> /// <param name="attributes">Dictionary of attributes to add.</param> /// <returns>True if successful, false otherwise.</returns> public async Task<bool> UpdateThingAsync(string thingName, Dictionary<string, string> attributes) { try { var request = new UpdateThingRequest { ThingName = thingName, AttributePayload = new AttributePayload { Attributes = attributes, Merge = true } }; await _amazonIoT.UpdateThingAsync(request); _logger.LogInformation($"Updated Thing {thingName} with attributes"); return true; } catch (Amazon.IoT.Model.ResourceNotFoundException ex) { _logger.LogError($"Cannot update Thing - resource not found: {ex.Message}"); return false; } catch (Exception ex) { _logger.LogError($"Couldn't update Thing attributes. Here's why: {ex.Message}"); return false; } } /// <summary> /// Gets the AWS IoT endpoint URL. /// </summary> /// <returns>The endpoint URL, or null if retrieval failed.</returns> public async Task<string?> DescribeEndpointAsync() { try { var request = new DescribeEndpointRequest { EndpointType = "iot:Data-ATS" }; var response = await _amazonIoT.DescribeEndpointAsync(request); _logger.LogInformation($"Retrieved endpoint: {response.EndpointAddress}"); return response.EndpointAddress; } catch (Amazon.IoT.Model.ThrottlingException ex) { _logger.LogWarning($"Request throttled, please try again later: {ex.Message}"); return null; } catch (Exception ex) { _logger.LogError($"Couldn't describe endpoint. Here's why: {ex.Message}"); return null; } } /// <summary> /// Lists all certificates associated with the account. /// </summary> /// <returns>List of certificate information, or empty list if listing failed.</returns> public async Task<List<Certificate>> ListCertificatesAsync() { try { var request = new ListCertificatesRequest(); var response = await _amazonIoT.ListCertificatesAsync(request); _logger.LogInformation($"Retrieved {response.Certificates.Count} certificates"); return response.Certificates; } catch (Amazon.IoT.Model.ThrottlingException ex) { _logger.LogWarning($"Request throttled, please try again later: {ex.Message}"); return new List<Certificate>(); } catch (Exception ex) { _logger.LogError($"Couldn't list certificates. Here's why: {ex.Message}"); return new List<Certificate>(); } } /// <summary> /// Updates the Thing's shadow with new state information. /// </summary> /// <param name="thingName">The name of the Thing.</param> /// <param name="shadowPayload">The shadow payload in JSON format.</param> /// <returns>True if successful, false otherwise.</returns> public async Task<bool> UpdateThingShadowAsync(string thingName, string shadowPayload) { try { var request = new UpdateThingShadowRequest { ThingName = thingName, Payload = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(shadowPayload)) }; await _amazonIotData.UpdateThingShadowAsync(request); _logger.LogInformation($"Updated shadow for Thing {thingName}"); return true; } catch (Amazon.IotData.Model.ResourceNotFoundException ex) { _logger.LogError($"Cannot update Thing shadow - resource not found: {ex.Message}"); return false; } catch (Exception ex) { _logger.LogError($"Couldn't update Thing shadow. Here's why: {ex.Message}"); return false; } } /// <summary> /// Gets the Thing's shadow information. /// </summary> /// <param name="thingName">The name of the Thing.</param> /// <returns>The shadow data as a string, or null if retrieval failed.</returns> public async Task<string?> GetThingShadowAsync(string thingName) { try { var request = new GetThingShadowRequest { ThingName = thingName }; var response = await _amazonIotData.GetThingShadowAsync(request); using var reader = new StreamReader(response.Payload); var shadowData = await reader.ReadToEndAsync(); _logger.LogInformation($"Retrieved shadow for Thing {thingName}"); return shadowData; } catch (Amazon.IotData.Model.ResourceNotFoundException ex) { _logger.LogError($"Cannot get Thing shadow - resource not found: {ex.Message}"); return null; } catch (Exception ex) { _logger.LogError($"Couldn't get Thing shadow. Here's why: {ex.Message}"); return null; } } /// <summary> /// Creates an IoT topic rule. /// </summary> /// <param name="ruleName">The name of the rule.</param> /// <param name="snsTopicArn">The ARN of the SNS topic for the action.</param> /// <param name="roleArn">The ARN of the IAM role.</param> /// <returns>True if successful, false otherwise.</returns> public async Task<bool> CreateTopicRuleAsync(string ruleName, string snsTopicArn, string roleArn) { try { var request = new CreateTopicRuleRequest { RuleName = ruleName, TopicRulePayload = new TopicRulePayload { Sql = "SELECT * FROM 'topic/subtopic'", Description = $"Rule created by .NET example: {ruleName}", Actions = new List<Amazon.IoT.Model.Action> { new Amazon.IoT.Model.Action { Sns = new SnsAction { TargetArn = snsTopicArn, RoleArn = roleArn } } }, RuleDisabled = false } }; await _amazonIoT.CreateTopicRuleAsync(request); _logger.LogInformation($"Created IoT rule {ruleName}"); return true; } catch (Amazon.IoT.Model.ResourceAlreadyExistsException ex) { _logger.LogWarning($"Rule {ruleName} already exists: {ex.Message}"); return false; } catch (Exception ex) { _logger.LogError($"Couldn't create topic rule. Here's why: {ex.Message}"); return false; } } /// <summary> /// Deletes an IoT topic rule. /// </summary> /// <param name="ruleName">The name of the rule.</param> /// <returns>True if successful, false otherwise.</returns> public async Task<bool> DeleteTopicRuleAsync(string ruleName) { try { var request = new DeleteTopicRuleRequest { RuleName = ruleName, }; await _amazonIoT.DeleteTopicRuleAsync(request); _logger.LogInformation($"Deleted IoT rule {ruleName}"); return true; } catch (Amazon.IoT.Model.ResourceNotFoundException ex) { _logger.LogWarning($"Rule {ruleName} not found: {ex.Message}"); return false; } catch (Exception ex) { _logger.LogError($"Couldn't delete topic rule. Here's why: {ex.Message}"); return false; } } /// <summary> /// Lists all IoT topic rules. /// </summary> /// <returns>List of topic rules, or empty list if listing failed.</returns> public async Task<List<TopicRuleListItem>> ListTopicRulesAsync() { try { var request = new ListTopicRulesRequest(); var response = await _amazonIoT.ListTopicRulesAsync(request); _logger.LogInformation($"Retrieved {response.Rules.Count} IoT rules"); return response.Rules; } catch (Amazon.IoT.Model.ThrottlingException ex) { _logger.LogWarning($"Request throttled, please try again later: {ex.Message}"); return new List<TopicRuleListItem>(); } catch (Exception ex) { _logger.LogError($"Couldn't list topic rules. Here's why: {ex.Message}"); return new List<TopicRuleListItem>(); } } /// <summary> /// Searches for IoT Things using the search index. /// </summary> /// <param name="queryString">The search query string.</param> /// <returns>List of Things that match the search criteria, or empty list if search failed.</returns> public async Task<List<ThingDocument>> SearchIndexAsync(string queryString) { try { // First, try to perform the search var request = new SearchIndexRequest { QueryString = queryString }; var response = await _amazonIoT.SearchIndexAsync(request); _logger.LogInformation($"Search found {response.Things.Count} Things"); return response.Things; } catch (Amazon.IoT.Model.IndexNotReadyException ex) { _logger.LogWarning($"Search index not ready, setting up indexing configuration: {ex.Message}"); return await SetupIndexAndRetrySearchAsync(queryString); } catch (Amazon.IoT.Model.ResourceNotFoundException ex) when (ex.Message.Contains("index") || ex.Message.Contains("Index")) { _logger.LogWarning($"Search index not configured, setting up indexing configuration: {ex.Message}"); return await SetupIndexAndRetrySearchAsync(queryString); } catch (Amazon.IoT.Model.ThrottlingException ex) { _logger.LogWarning($"Request throttled, please try again later: {ex.Message}"); return new List<ThingDocument>(); } catch (Exception ex) { _logger.LogError($"Couldn't search index. Here's why: {ex.Message}"); return new List<ThingDocument>(); } } /// <summary> /// Sets up the indexing configuration and retries the search after waiting for the index to be ready. /// </summary> /// <param name="queryString">The search query string.</param> /// <returns>List of Things that match the search criteria, or empty list if setup/search failed.</returns> private async Task<List<ThingDocument>> SetupIndexAndRetrySearchAsync(string queryString) { try { // Update indexing configuration to REGISTRY mode _logger.LogInformation("Setting up IoT search indexing configuration..."); await _amazonIoT.UpdateIndexingConfigurationAsync( new UpdateIndexingConfigurationRequest() { ThingIndexingConfiguration = new ThingIndexingConfiguration() { ThingIndexingMode = ThingIndexingMode.REGISTRY } }); _logger.LogInformation("Indexing configuration updated. Waiting for index to be ready..."); // Wait for the index to be set up - this can take some time const int maxRetries = 10; const int retryDelaySeconds = 10; for (int attempt = 1; attempt <= maxRetries; attempt++) { try { _logger.LogInformation($"Waiting for index to be ready (attempt {attempt}/{maxRetries})..."); await Task.Delay(TimeSpan.FromSeconds(retryDelaySeconds)); // Try to get the current indexing configuration to see if it's ready var configResponse = await _amazonIoT.GetIndexingConfigurationAsync(new GetIndexingConfigurationRequest()); if (configResponse.ThingIndexingConfiguration?.ThingIndexingMode == ThingIndexingMode.REGISTRY) { // Try the search again var request = new SearchIndexRequest { QueryString = queryString }; var response = await _amazonIoT.SearchIndexAsync(request); _logger.LogInformation($"Search found {response.Things.Count} Things after index setup"); return response.Things; } } catch (Amazon.IoT.Model.IndexNotReadyException) { // Index still not ready, continue waiting _logger.LogInformation("Index still not ready, continuing to wait..."); continue; } catch (Amazon.IoT.Model.InvalidRequestException ex) when (ex.Message.Contains("index") || ex.Message.Contains("Index")) { // Index still not ready, continue waiting _logger.LogInformation("Index still not ready, continuing to wait..."); continue; } } _logger.LogWarning("Timeout waiting for search index to be ready after configuration update"); return new List<ThingDocument>(); } catch (Exception ex) { _logger.LogError($"Couldn't set up search index configuration. Here's why: {ex.Message}"); return new List<ThingDocument>(); } } /// <summary> /// Detaches a certificate from an IoT Thing. /// </summary> /// <param name="thingName">The name of the Thing.</param> /// <param name="certificateArn">The ARN of the certificate to detach.</param> /// <returns>True if successful, false otherwise.</returns> public async Task<bool> DetachThingPrincipalAsync(string thingName, string certificateArn) { try { var request = new DetachThingPrincipalRequest { ThingName = thingName, Principal = certificateArn }; await _amazonIoT.DetachThingPrincipalAsync(request); _logger.LogInformation($"Detached certificate {certificateArn} from Thing {thingName}"); return true; } catch (Amazon.IoT.Model.ResourceNotFoundException ex) { _logger.LogError($"Cannot detach certificate - resource not found: {ex.Message}"); return false; } catch (Exception ex) { _logger.LogError($"Couldn't detach certificate from Thing. Here's why: {ex.Message}"); return false; } } /// <summary> /// Deletes an IoT certificate. /// </summary> /// <param name="certificateId">The ID of the certificate to delete.</param> /// <returns>True if successful, false otherwise.</returns> public async Task<bool> DeleteCertificateAsync(string certificateId) { try { // First, update the certificate to inactive state var updateRequest = new UpdateCertificateRequest { CertificateId = certificateId, NewStatus = CertificateStatus.INACTIVE }; await _amazonIoT.UpdateCertificateAsync(updateRequest); // Then delete the certificate var deleteRequest = new DeleteCertificateRequest { CertificateId = certificateId }; await _amazonIoT.DeleteCertificateAsync(deleteRequest); _logger.LogInformation($"Deleted certificate {certificateId}"); return true; } catch (Amazon.IoT.Model.ResourceNotFoundException ex) { _logger.LogError($"Cannot delete certificate - resource not found: {ex.Message}"); return false; } catch (Exception ex) { _logger.LogError($"Couldn't delete certificate. Here's why: {ex.Message}"); return false; } } /// <summary> /// Deletes an IoT Thing. /// </summary> /// <param name="thingName">The name of the Thing to delete.</param> /// <returns>True if successful, false otherwise.</returns> public async Task<bool> DeleteThingAsync(string thingName) { try { var request = new DeleteThingRequest { ThingName = thingName }; await _amazonIoT.DeleteThingAsync(request); _logger.LogInformation($"Deleted Thing {thingName}"); return true; } catch (Amazon.IoT.Model.ResourceNotFoundException ex) { _logger.LogError($"Cannot delete Thing - resource not found: {ex.Message}"); return false; } catch (Exception ex) { _logger.LogError($"Couldn't delete Thing. Here's why: {ex.Message}"); return false; } } /// <summary> /// Lists IoT Things with pagination support. /// </summary> /// <returns>List of Things, or empty list if listing failed.</returns> public async Task<List<ThingAttribute>> ListThingsAsync() { try { // Use pages of 10. var request = new ListThingsRequest() { MaxResults = 10 }; var response = await _amazonIoT.ListThingsAsync(request); // Since there is not a built-in paginator, use the NextMarker to paginate. bool hasMoreResults = true; var things = new List<ThingAttribute>(); while (hasMoreResults) { things.AddRange(response.Things); // If NextMarker is not null, there are more results. Get the next page of results. if (!String.IsNullOrEmpty(response.NextMarker)) { request.Marker = response.NextMarker; response = await _amazonIoT.ListThingsAsync(request); } else hasMoreResults = false; } _logger.LogInformation($"Retrieved {things.Count} Things"); return things; } catch (Amazon.IoT.Model.ThrottlingException ex) { _logger.LogWarning($"Request throttled, please try again later: {ex.Message}"); return new List<ThingAttribute>(); } catch (Exception ex) { _logger.LogError($"Couldn't list Things. Here's why: {ex.Message}"); return new List<ThingAttribute>(); } } }
Actions
L'exemple de code suivant montre comment utiliserAttachThingPrincipal.
- SDK pour .NET (v4)
-
Note
Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS
. /// <summary> /// Attaches a certificate to an IoT Thing. /// </summary> /// <param name="thingName">The name of the Thing.</param> /// <param name="certificateArn">The ARN of the certificate to attach.</param> /// <returns>True if successful, false otherwise.</returns> public async Task<bool> AttachThingPrincipalAsync(string thingName, string certificateArn) { try { var request = new AttachThingPrincipalRequest { ThingName = thingName, Principal = certificateArn }; await _amazonIoT.AttachThingPrincipalAsync(request); _logger.LogInformation($"Attached certificate {certificateArn} to Thing {thingName}"); return true; } catch (Amazon.IoT.Model.ResourceNotFoundException ex) { _logger.LogError($"Cannot attach certificate - resource not found: {ex.Message}"); return false; } catch (Exception ex) { _logger.LogError($"Couldn't attach certificate to Thing. Here's why: {ex.Message}"); return false; } }-
Pour plus de détails sur l'API, reportez-vous AttachThingPrincipalà la section Référence des AWS SDK pour .NET API.
-
L'exemple de code suivant montre comment utiliserCreateKeysAndCertificate.
- SDK pour .NET (v4)
-
Note
Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS
. /// <summary> /// Creates a device certificate for AWS IoT. /// </summary> /// <returns>The certificate details including ARN and certificate PEM, or null if creation failed.</returns> public async Task<(string CertificateArn, string CertificatePem, string CertificateId)?> CreateKeysAndCertificateAsync() { try { var request = new CreateKeysAndCertificateRequest { SetAsActive = true }; var response = await _amazonIoT.CreateKeysAndCertificateAsync(request); _logger.LogInformation($"Created certificate with ARN {response.CertificateArn}"); return (response.CertificateArn, response.CertificatePem, response.CertificateId); } catch (Amazon.IoT.Model.ThrottlingException ex) { _logger.LogWarning($"Request throttled, please try again later: {ex.Message}"); return null; } catch (Exception ex) { _logger.LogError($"Couldn't create certificate. Here's why: {ex.Message}"); return null; } }-
Pour plus de détails sur l'API, reportez-vous CreateKeysAndCertificateà la section Référence des AWS SDK pour .NET API.
-
L'exemple de code suivant montre comment utiliserCreateThing.
- SDK pour .NET (v4)
-
Note
Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS
. /// <summary> /// Creates an AWS IoT Thing. /// </summary> /// <param name="thingName">The name of the Thing to create.</param> /// <returns>The ARN of the Thing created, or null if creation failed.</returns> public async Task<string?> CreateThingAsync(string thingName) { try { var request = new CreateThingRequest { ThingName = thingName }; var response = await _amazonIoT.CreateThingAsync(request); _logger.LogInformation($"Created Thing {thingName} with ARN {response.ThingArn}"); return response.ThingArn; } catch (Amazon.IoT.Model.ResourceAlreadyExistsException ex) { _logger.LogWarning($"Thing {thingName} already exists: {ex.Message}"); return null; } catch (Exception ex) { _logger.LogError($"Couldn't create Thing {thingName}. Here's why: {ex.Message}"); return null; } }-
Pour plus de détails sur l'API, reportez-vous CreateThingà la section Référence des AWS SDK pour .NET API.
-
L'exemple de code suivant montre comment utiliserCreateTopicRule.
- SDK pour .NET (v4)
-
Note
Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS
. /// <summary> /// Creates an IoT topic rule. /// </summary> /// <param name="ruleName">The name of the rule.</param> /// <param name="snsTopicArn">The ARN of the SNS topic for the action.</param> /// <param name="roleArn">The ARN of the IAM role.</param> /// <returns>True if successful, false otherwise.</returns> public async Task<bool> CreateTopicRuleAsync(string ruleName, string snsTopicArn, string roleArn) { try { var request = new CreateTopicRuleRequest { RuleName = ruleName, TopicRulePayload = new TopicRulePayload { Sql = "SELECT * FROM 'topic/subtopic'", Description = $"Rule created by .NET example: {ruleName}", Actions = new List<Amazon.IoT.Model.Action> { new Amazon.IoT.Model.Action { Sns = new SnsAction { TargetArn = snsTopicArn, RoleArn = roleArn } } }, RuleDisabled = false } }; await _amazonIoT.CreateTopicRuleAsync(request); _logger.LogInformation($"Created IoT rule {ruleName}"); return true; } catch (Amazon.IoT.Model.ResourceAlreadyExistsException ex) { _logger.LogWarning($"Rule {ruleName} already exists: {ex.Message}"); return false; } catch (Exception ex) { _logger.LogError($"Couldn't create topic rule. Here's why: {ex.Message}"); return false; } }-
Pour plus de détails sur l'API, reportez-vous CreateTopicRuleà la section Référence des AWS SDK pour .NET API.
-
L'exemple de code suivant montre comment utiliserDeleteCertificate.
- SDK pour .NET (v4)
-
Note
Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS
. /// <summary> /// Deletes an IoT certificate. /// </summary> /// <param name="certificateId">The ID of the certificate to delete.</param> /// <returns>True if successful, false otherwise.</returns> public async Task<bool> DeleteCertificateAsync(string certificateId) { try { // First, update the certificate to inactive state var updateRequest = new UpdateCertificateRequest { CertificateId = certificateId, NewStatus = CertificateStatus.INACTIVE }; await _amazonIoT.UpdateCertificateAsync(updateRequest); // Then delete the certificate var deleteRequest = new DeleteCertificateRequest { CertificateId = certificateId }; await _amazonIoT.DeleteCertificateAsync(deleteRequest); _logger.LogInformation($"Deleted certificate {certificateId}"); return true; } catch (Amazon.IoT.Model.ResourceNotFoundException ex) { _logger.LogError($"Cannot delete certificate - resource not found: {ex.Message}"); return false; } catch (Exception ex) { _logger.LogError($"Couldn't delete certificate. Here's why: {ex.Message}"); return false; } }-
Pour plus de détails sur l'API, reportez-vous DeleteCertificateà la section Référence des AWS SDK pour .NET API.
-
L'exemple de code suivant montre comment utiliserDeleteThing.
- SDK pour .NET (v4)
-
Note
Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS
. /// <summary> /// Deletes an IoT Thing. /// </summary> /// <param name="thingName">The name of the Thing to delete.</param> /// <returns>True if successful, false otherwise.</returns> public async Task<bool> DeleteThingAsync(string thingName) { try { var request = new DeleteThingRequest { ThingName = thingName }; await _amazonIoT.DeleteThingAsync(request); _logger.LogInformation($"Deleted Thing {thingName}"); return true; } catch (Amazon.IoT.Model.ResourceNotFoundException ex) { _logger.LogError($"Cannot delete Thing - resource not found: {ex.Message}"); return false; } catch (Exception ex) { _logger.LogError($"Couldn't delete Thing. Here's why: {ex.Message}"); return false; } }-
Pour plus de détails sur l'API, reportez-vous DeleteThingà la section Référence des AWS SDK pour .NET API.
-
L'exemple de code suivant montre comment utiliserDescribeEndpoint.
- SDK pour .NET (v4)
-
Note
Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS
. /// <summary> /// Gets the AWS IoT endpoint URL. /// </summary> /// <returns>The endpoint URL, or null if retrieval failed.</returns> public async Task<string?> DescribeEndpointAsync() { try { var request = new DescribeEndpointRequest { EndpointType = "iot:Data-ATS" }; var response = await _amazonIoT.DescribeEndpointAsync(request); _logger.LogInformation($"Retrieved endpoint: {response.EndpointAddress}"); return response.EndpointAddress; } catch (Amazon.IoT.Model.ThrottlingException ex) { _logger.LogWarning($"Request throttled, please try again later: {ex.Message}"); return null; } catch (Exception ex) { _logger.LogError($"Couldn't describe endpoint. Here's why: {ex.Message}"); return null; } }-
Pour plus de détails sur l'API, reportez-vous DescribeEndpointà la section Référence des AWS SDK pour .NET API.
-
L'exemple de code suivant montre comment utiliserDetachThingPrincipal.
- SDK pour .NET (v4)
-
Note
Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS
. /// <summary> /// Detaches a certificate from an IoT Thing. /// </summary> /// <param name="thingName">The name of the Thing.</param> /// <param name="certificateArn">The ARN of the certificate to detach.</param> /// <returns>True if successful, false otherwise.</returns> public async Task<bool> DetachThingPrincipalAsync(string thingName, string certificateArn) { try { var request = new DetachThingPrincipalRequest { ThingName = thingName, Principal = certificateArn }; await _amazonIoT.DetachThingPrincipalAsync(request); _logger.LogInformation($"Detached certificate {certificateArn} from Thing {thingName}"); return true; } catch (Amazon.IoT.Model.ResourceNotFoundException ex) { _logger.LogError($"Cannot detach certificate - resource not found: {ex.Message}"); return false; } catch (Exception ex) { _logger.LogError($"Couldn't detach certificate from Thing. Here's why: {ex.Message}"); return false; } }-
Pour plus de détails sur l'API, reportez-vous DetachThingPrincipalà la section Référence des AWS SDK pour .NET API.
-
L'exemple de code suivant montre comment utiliserListCertificates.
- SDK pour .NET (v4)
-
Note
Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS
. /// <summary> /// Lists all certificates associated with the account. /// </summary> /// <returns>List of certificate information, or empty list if listing failed.</returns> public async Task<List<Certificate>> ListCertificatesAsync() { try { var request = new ListCertificatesRequest(); var response = await _amazonIoT.ListCertificatesAsync(request); _logger.LogInformation($"Retrieved {response.Certificates.Count} certificates"); return response.Certificates; } catch (Amazon.IoT.Model.ThrottlingException ex) { _logger.LogWarning($"Request throttled, please try again later: {ex.Message}"); return new List<Certificate>(); } catch (Exception ex) { _logger.LogError($"Couldn't list certificates. Here's why: {ex.Message}"); return new List<Certificate>(); } }-
Pour plus de détails sur l'API, reportez-vous ListCertificatesà la section Référence des AWS SDK pour .NET API.
-
L'exemple de code suivant montre comment utiliserListThings.
- SDK pour .NET (v4)
-
Note
Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS
. /// <summary> /// Lists IoT Things with pagination support. /// </summary> /// <returns>List of Things, or empty list if listing failed.</returns> public async Task<List<ThingAttribute>> ListThingsAsync() { try { // Use pages of 10. var request = new ListThingsRequest() { MaxResults = 10 }; var response = await _amazonIoT.ListThingsAsync(request); // Since there is not a built-in paginator, use the NextMarker to paginate. bool hasMoreResults = true; var things = new List<ThingAttribute>(); while (hasMoreResults) { things.AddRange(response.Things); // If NextMarker is not null, there are more results. Get the next page of results. if (!String.IsNullOrEmpty(response.NextMarker)) { request.Marker = response.NextMarker; response = await _amazonIoT.ListThingsAsync(request); } else hasMoreResults = false; } _logger.LogInformation($"Retrieved {things.Count} Things"); return things; } catch (Amazon.IoT.Model.ThrottlingException ex) { _logger.LogWarning($"Request throttled, please try again later: {ex.Message}"); return new List<ThingAttribute>(); } catch (Exception ex) { _logger.LogError($"Couldn't list Things. Here's why: {ex.Message}"); return new List<ThingAttribute>(); } }-
Pour plus de détails sur l'API, reportez-vous ListThingsà la section Référence des AWS SDK pour .NET API.
-
L'exemple de code suivant montre comment utiliserSearchIndex.
- SDK pour .NET (v4)
-
Note
Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS
. /// <summary> /// Searches for IoT Things using the search index. /// </summary> /// <param name="queryString">The search query string.</param> /// <returns>List of Things that match the search criteria, or empty list if search failed.</returns> public async Task<List<ThingDocument>> SearchIndexAsync(string queryString) { try { // First, try to perform the search var request = new SearchIndexRequest { QueryString = queryString }; var response = await _amazonIoT.SearchIndexAsync(request); _logger.LogInformation($"Search found {response.Things.Count} Things"); return response.Things; } catch (Amazon.IoT.Model.IndexNotReadyException ex) { _logger.LogWarning($"Search index not ready, setting up indexing configuration: {ex.Message}"); return await SetupIndexAndRetrySearchAsync(queryString); } catch (Amazon.IoT.Model.ResourceNotFoundException ex) when (ex.Message.Contains("index") || ex.Message.Contains("Index")) { _logger.LogWarning($"Search index not configured, setting up indexing configuration: {ex.Message}"); return await SetupIndexAndRetrySearchAsync(queryString); } catch (Amazon.IoT.Model.ThrottlingException ex) { _logger.LogWarning($"Request throttled, please try again later: {ex.Message}"); return new List<ThingDocument>(); } catch (Exception ex) { _logger.LogError($"Couldn't search index. Here's why: {ex.Message}"); return new List<ThingDocument>(); } } /// <summary> /// Sets up the indexing configuration and retries the search after waiting for the index to be ready. /// </summary> /// <param name="queryString">The search query string.</param> /// <returns>List of Things that match the search criteria, or empty list if setup/search failed.</returns> private async Task<List<ThingDocument>> SetupIndexAndRetrySearchAsync(string queryString) { try { // Update indexing configuration to REGISTRY mode _logger.LogInformation("Setting up IoT search indexing configuration..."); await _amazonIoT.UpdateIndexingConfigurationAsync( new UpdateIndexingConfigurationRequest() { ThingIndexingConfiguration = new ThingIndexingConfiguration() { ThingIndexingMode = ThingIndexingMode.REGISTRY } }); _logger.LogInformation("Indexing configuration updated. Waiting for index to be ready..."); // Wait for the index to be set up - this can take some time const int maxRetries = 10; const int retryDelaySeconds = 10; for (int attempt = 1; attempt <= maxRetries; attempt++) { try { _logger.LogInformation($"Waiting for index to be ready (attempt {attempt}/{maxRetries})..."); await Task.Delay(TimeSpan.FromSeconds(retryDelaySeconds)); // Try to get the current indexing configuration to see if it's ready var configResponse = await _amazonIoT.GetIndexingConfigurationAsync(new GetIndexingConfigurationRequest()); if (configResponse.ThingIndexingConfiguration?.ThingIndexingMode == ThingIndexingMode.REGISTRY) { // Try the search again var request = new SearchIndexRequest { QueryString = queryString }; var response = await _amazonIoT.SearchIndexAsync(request); _logger.LogInformation($"Search found {response.Things.Count} Things after index setup"); return response.Things; } } catch (Amazon.IoT.Model.IndexNotReadyException) { // Index still not ready, continue waiting _logger.LogInformation("Index still not ready, continuing to wait..."); continue; } catch (Amazon.IoT.Model.InvalidRequestException ex) when (ex.Message.Contains("index") || ex.Message.Contains("Index")) { // Index still not ready, continue waiting _logger.LogInformation("Index still not ready, continuing to wait..."); continue; } } _logger.LogWarning("Timeout waiting for search index to be ready after configuration update"); return new List<ThingDocument>(); } catch (Exception ex) { _logger.LogError($"Couldn't set up search index configuration. Here's why: {ex.Message}"); return new List<ThingDocument>(); } }-
Pour plus de détails sur l'API, reportez-vous SearchIndexà la section Référence des AWS SDK pour .NET API.
-
L'exemple de code suivant montre comment utiliserUpdateThing.
- SDK pour .NET (v4)
-
Note
Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS
. /// <summary> /// Updates an IoT Thing with attributes. /// </summary> /// <param name="thingName">The name of the Thing to update.</param> /// <param name="attributes">Dictionary of attributes to add.</param> /// <returns>True if successful, false otherwise.</returns> public async Task<bool> UpdateThingAsync(string thingName, Dictionary<string, string> attributes) { try { var request = new UpdateThingRequest { ThingName = thingName, AttributePayload = new AttributePayload { Attributes = attributes, Merge = true } }; await _amazonIoT.UpdateThingAsync(request); _logger.LogInformation($"Updated Thing {thingName} with attributes"); return true; } catch (Amazon.IoT.Model.ResourceNotFoundException ex) { _logger.LogError($"Cannot update Thing - resource not found: {ex.Message}"); return false; } catch (Exception ex) { _logger.LogError($"Couldn't update Thing attributes. Here's why: {ex.Message}"); return false; } }-
Pour plus de détails sur l'API, reportez-vous UpdateThingà la section Référence des AWS SDK pour .NET API.
-