diff --git a/src/AzureIoTHub.Portal/Client/Pages/EdgeDevices/EdgeDeviceDetailPage.razor b/src/AzureIoTHub.Portal/Client/Pages/EdgeDevices/EdgeDeviceDetailPage.razor index ee7c18db8..7a9c15412 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/EdgeDevices/EdgeDeviceDetailPage.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/EdgeDevices/EdgeDeviceDetailPage.razor @@ -1,5 +1,7 @@ @page "/edge/devices/{deviceId}" + @using AzureIoTHub.Portal.Models.v10 +@using AzureIoTHub.Portal.Shared.Models.v10; @attribute [Authorize] @inject NavigationManager NavigationManager @@ -145,9 +147,13 @@ @context.ModuleName @context.Version @context.Status - + logs reboot + @foreach (var command in context.Commands) + { + @command.Name + } @@ -226,6 +232,17 @@ await LoadModel(edgeDevice.ModelId); + foreach (var edgeModelModule in edgeModel.EdgeModules) + { + foreach (var item in edgeDevice.Modules) + { + if (item.ModuleName.Equals(edgeModelModule.ModuleName, StringComparison.Ordinal)) + { + item.Commands = edgeModelModule.Commands; + } + } + } + TagList = await DeviceTagSettingsClientService.GetDeviceTags(); } catch (ProblemDetailsException exception) @@ -289,8 +306,6 @@ try { - //var result = await Http.PostAsJsonAsync($"api/edge/devices/{edgeDevice.DeviceId}/{module.ModuleName}/{methodName}", module); - var c2dResult = await EdgeDeviceClientService.ExecuteModuleMethod(edgeDevice.DeviceId, module, methodName); if (c2dResult.Status == 200) @@ -316,6 +331,37 @@ } } + public async Task ExecuteCommand(string moduleName, IoTEdgeModuleCommand command) + { + isProcessing = true; + + try + { + var c2dResult = await EdgeDeviceClientService.ExecuteModuleCommand(edgeDevice.DeviceId, moduleName, command.Name); + + if (c2dResult.Status == 200) + { + Snackbar.Add("Command successfully executed.", Severity.Success); + } + else + { + Snackbar.Add($"Error
Status : {c2dResult.Status};
Payload : {c2dResult.Payload};", Severity.Error, + (option) => + { + option.VisibleStateDuration = 10000; + }); + } + } + catch (ProblemDetailsException exception) + { + Error?.ProcessProblemDetails(exception); + } + finally + { + isProcessing = false; + } + } + public async Task ShowEdgeDeviceLogs(IoTEdgeModule module) { var parameter = new DialogParameters diff --git a/src/AzureIoTHub.Portal/Client/Services/EdgeDeviceClientService.cs b/src/AzureIoTHub.Portal/Client/Services/EdgeDeviceClientService.cs index 0827c35a8..22d237c7c 100644 --- a/src/AzureIoTHub.Portal/Client/Services/EdgeDeviceClientService.cs +++ b/src/AzureIoTHub.Portal/Client/Services/EdgeDeviceClientService.cs @@ -57,7 +57,14 @@ public async Task> GetEdgeDeviceLogs(string deviceId, IoT public async Task ExecuteModuleMethod(string deviceId, IoTEdgeModule edgeModule, string methodName) { - var response = await this.http.PostAsJsonAsync($"api/edge/devices/{deviceId}/{edgeModule.ModuleName}/{methodName}", edgeModule); + var response = await this.http.GetAsync($"api/edge/devices/{deviceId}/{edgeModule.ModuleName}/{methodName}"); + + return await response.Content.ReadFromJsonAsync(); + } + + public async Task ExecuteModuleCommand(string deviceId, string moduleName, string commandName) + { + var response = await this.http.GetAsync($"api/edge/devices/{deviceId}/{moduleName}/custom/{commandName}"); return await response.Content.ReadFromJsonAsync(); } diff --git a/src/AzureIoTHub.Portal/Client/Services/IEdgeDeviceClientService.cs b/src/AzureIoTHub.Portal/Client/Services/IEdgeDeviceClientService.cs index ca070d0ef..a096d94cf 100644 --- a/src/AzureIoTHub.Portal/Client/Services/IEdgeDeviceClientService.cs +++ b/src/AzureIoTHub.Portal/Client/Services/IEdgeDeviceClientService.cs @@ -24,5 +24,7 @@ public interface IEdgeDeviceClientService Task> GetEdgeDeviceLogs(string deviceId, IoTEdgeModule edgeModule); Task ExecuteModuleMethod(string deviceId, IoTEdgeModule edgeModule, string methodName); + + Task ExecuteModuleCommand(string deviceId, string moduleName, string commandName); } } diff --git a/src/AzureIoTHub.Portal/Server/Controllers/v1.0/EdgeDevicesController.cs b/src/AzureIoTHub.Portal/Server/Controllers/v1.0/EdgeDevicesController.cs index 4c6588c3c..c7e418f88 100644 --- a/src/AzureIoTHub.Portal/Server/Controllers/v1.0/EdgeDevicesController.cs +++ b/src/AzureIoTHub.Portal/Server/Controllers/v1.0/EdgeDevicesController.cs @@ -157,13 +157,19 @@ public async Task> GetCredentials(string dev /// /// Executes the module method on the IoT Edge device. /// - /// The edge module. + /// The edge module name. /// The device identifier. /// Name of the method. - [HttpPost("{deviceId}/{moduleId}/{methodName}", Name = "POST Execute module command")] - public async Task ExecuteModuleMethod(IoTEdgeModule edgeModule, string deviceId, string methodName) + [HttpGet("{deviceId}/{moduleName}/{methodName}", Name = "Get Execute module command")] + public async Task ExecuteModuleMethod(string moduleName, string deviceId, string methodName) { - return await this.edgeDevicesService.ExecuteModuleMethod(edgeModule, deviceId, methodName); + return await this.edgeDevicesService.ExecuteModuleMethod(moduleName, deviceId, methodName); + } + + [HttpGet("{deviceId}/{moduleName}/custom/{commandName}", Name = "GET Execute custom module command")] + public async Task ExecuteCustomModuleMethod(string deviceId, string moduleName, string commandName) + { + return await this.edgeDevicesService.ExecuteModuleCommand(deviceId, moduleName, commandName); } /// diff --git a/src/AzureIoTHub.Portal/Server/Helpers/DeviceHelper.cs b/src/AzureIoTHub.Portal/Server/Helpers/DeviceHelper.cs index d76cf9b89..b6bc05b6c 100644 --- a/src/AzureIoTHub.Portal/Server/Helpers/DeviceHelper.cs +++ b/src/AzureIoTHub.Portal/Server/Helpers/DeviceHelper.cs @@ -190,6 +190,12 @@ public static IReadOnlyCollection RetrieveModuleList(Twin twin) ModuleName = property.Key }; + if (propertyObject.TryGetValue("settings", out var moduleSettings)) + { + var setting = moduleSettings.ToObject>(); + module.ImageURI = setting["image"]; + } + if (propertyObject.TryGetValue("status", out var status)) { module.Status = status.Value(); diff --git a/src/AzureIoTHub.Portal/Server/Services/DeviceService.cs b/src/AzureIoTHub.Portal/Server/Services/DeviceService.cs index b145d8d4b..88cf262b4 100644 --- a/src/AzureIoTHub.Portal/Server/Services/DeviceService.cs +++ b/src/AzureIoTHub.Portal/Server/Services/DeviceService.cs @@ -403,6 +403,26 @@ public async Task ExecuteC2DMethod(string deviceId, C } } + /// + /// C2DMethod for custom command. + /// + /// the deviceId. + /// the module name. + /// the C2DMethod. + /// + /// + public async Task ExecuteCustomCommandC2DMethod(string deviceId, string moduleName, CloudToDeviceMethod method) + { + try + { + return await this.serviceClient.InvokeDeviceMethodAsync(deviceId, moduleName, method); + } + catch (Exception e) + { + throw new InternalServerErrorException($"Unable to execute the cloud to device method {method.MethodName} on the device with id {deviceId}", e); + } + } + /// /// Get edge device logs /// diff --git a/src/AzureIoTHub.Portal/Server/Services/EdgeDevicesService.cs b/src/AzureIoTHub.Portal/Server/Services/EdgeDevicesService.cs index c1bd98583..04bd0ddc2 100644 --- a/src/AzureIoTHub.Portal/Server/Services/EdgeDevicesService.cs +++ b/src/AzureIoTHub.Portal/Server/Services/EdgeDevicesService.cs @@ -170,23 +170,23 @@ public async Task UpdateEdgeDevice(IoTEdgeDevice edgeDevice) /// /// Executes the module method on the IoT Edge device. /// - /// + /// /// /// /// - public async Task ExecuteModuleMethod(IoTEdgeModule edgeModule, string deviceId, string methodName) + public async Task ExecuteModuleMethod(string moduleName, string deviceId, string methodName) { - ArgumentNullException.ThrowIfNull(edgeModule, nameof(edgeModule)); + ArgumentNullException.ThrowIfNull(moduleName, nameof(moduleName)); var method = new CloudToDeviceMethod(methodName); - var payload = string.Empty; + var payload = "{}"; if (methodName == "RestartModule") { payload = JsonConvert.SerializeObject(new { - id = edgeModule.ModuleName, - schemaVersion = edgeModule.Version + id = moduleName, + schemaVersion = "1.0" }); } @@ -201,6 +201,33 @@ public async Task ExecuteModuleMethod(IoTEdgeModule edgeModule, strin }; } + /// + /// Execute the custom module command. + /// + /// the device identifier. + /// the module name. + /// the command name. + /// + public async Task ExecuteModuleCommand(string deviceId, string moduleName, string commandName) + { + ArgumentNullException.ThrowIfNull(deviceId, nameof(deviceId)); + ArgumentNullException.ThrowIfNull(moduleName, nameof(moduleName)); + ArgumentNullException.ThrowIfNull(commandName, nameof(commandName)); + + var method = new CloudToDeviceMethod(commandName); + var payload = "{}"; + + _ = method.SetPayloadJson(payload); + + var result = await this.devicesService.ExecuteCustomCommandC2DMethod(deviceId,moduleName, method); + + return new C2Dresult() + { + Payload = result.GetPayloadAsJson(), + Status = result.Status + }; + } + /// /// Gets the IoT Edge device enrollement credentials. /// diff --git a/src/AzureIoTHub.Portal/Server/Services/EdgeModelService.cs b/src/AzureIoTHub.Portal/Server/Services/EdgeModelService.cs index 480e1e635..9f5904683 100644 --- a/src/AzureIoTHub.Portal/Server/Services/EdgeModelService.cs +++ b/src/AzureIoTHub.Portal/Server/Services/EdgeModelService.cs @@ -89,10 +89,13 @@ public async Task GetEdgeModel(string modelId) var query = await this.tableClientFactory .GetEdgeDeviceTemplates() .GetEntityAsync(DefaultPartitionKey, modelId); + var modules = await this.configService.GetConfigModuleList(modelId); + var commands = this.tableClientFactory.GetEdgeModuleCommands() .Query(c => c.PartitionKey == modelId) .ToArray(); + return this.edgeDeviceModelMapper.CreateEdgeDeviceModel(query.Value, modules, commands); } catch (RequestFailedException e) diff --git a/src/AzureIoTHub.Portal/Server/Services/IDeviceService.cs b/src/AzureIoTHub.Portal/Server/Services/IDeviceService.cs index 2d748613a..45969d89e 100644 --- a/src/AzureIoTHub.Portal/Server/Services/IDeviceService.cs +++ b/src/AzureIoTHub.Portal/Server/Services/IDeviceService.cs @@ -25,6 +25,8 @@ public interface IDeviceService Task ExecuteC2DMethod(string deviceId, CloudToDeviceMethod method); + Task ExecuteCustomCommandC2DMethod(string deviceId, string moduleName, CloudToDeviceMethod method); + Task DeleteDevice(string deviceId); Task> GetAllDevice( diff --git a/src/AzureIoTHub.Portal/Server/Services/IEdgeDevicesService.cs b/src/AzureIoTHub.Portal/Server/Services/IEdgeDevicesService.cs index 16222e921..a7af647bf 100644 --- a/src/AzureIoTHub.Portal/Server/Services/IEdgeDevicesService.cs +++ b/src/AzureIoTHub.Portal/Server/Services/IEdgeDevicesService.cs @@ -24,8 +24,10 @@ PaginationResult GetEdgeDevicesPage(PaginationResult edge Task UpdateEdgeDevice(IoTEdgeDevice edgeDevice); - Task ExecuteModuleMethod(IoTEdgeModule edgeModule, string deviceId, string methodName); + Task ExecuteModuleMethod(string moduleName, string deviceId, string methodName); Task GetEdgeDeviceCredentials(string edgeDeviceId); + + Task ExecuteModuleCommand(string deviceId, string moduleName, string commandName); } }