Skip to content

Commit

Permalink
resolve issue #1117
Browse files Browse the repository at this point in the history
  • Loading branch information
Sben65 committed Sep 6, 2022
1 parent 4f566cc commit cf4448c
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
@page "/edge/devices/{deviceId}"

@using AzureIoTHub.Portal.Models.v10
@using AzureIoTHub.Portal.Shared.Models.v10;

@attribute [Authorize]
@inject NavigationManager NavigationManager
Expand Down Expand Up @@ -145,9 +147,13 @@
<MudTd DataLabel="Module Name" Style="word-break: break-all;">@context.ModuleName</MudTd>
<MudTd DataLabel="Version" Style="text-align: center">@context.Version</MudTd>
<MudTd DataLabel="Status" Style="text-align: center">@context.Status</MudTd>
<MudTd DataLabel="Device" Style="text-align: center">
<MudTd DataLabel="Device" Style="text-align: center;display:flex">
<MudButton Variant="Variant.Filled" Class="btn showLogs" Color="Color.Dark" Disabled="btn_disable" OnClick="@(async () => await ShowEdgeDeviceLogs(context) )">logs</MudButton>
<MudButton Variant="Variant.Filled" Class="rebootModule" Color="Color.Primary" Disabled="btn_disable" OnClick="@(async () => await OnMethod(context,"RestartModule") )">reboot</MudButton>
@foreach (var command in context.Commands)
{
<MudButton Variant="Variant.Filled" Class="@(command.Name)" Disabled="btn_disable" Color="Color.Success" OnClick="@(async () => await ExecuteCommand(context.ModuleName, command) )">@command.Name</MudButton>
}
</MudTd>
</RowTemplate>
</MudTable>
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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<br>Status : {c2dResult.Status};<br>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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,14 @@ public async Task<List<IoTEdgeDeviceLog>> GetEdgeDeviceLogs(string deviceId, IoT

public async Task<C2Dresult> 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<C2Dresult>();
}

public async Task<C2Dresult> 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<C2Dresult>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,7 @@ public interface IEdgeDeviceClientService
Task<List<IoTEdgeDeviceLog>> GetEdgeDeviceLogs(string deviceId, IoTEdgeModule edgeModule);

Task<C2Dresult> ExecuteModuleMethod(string deviceId, IoTEdgeModule edgeModule, string methodName);

Task<C2Dresult> ExecuteModuleCommand(string deviceId, string moduleName, string commandName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,19 @@ public async Task<ActionResult<EnrollmentCredentials>> GetCredentials(string dev
/// <summary>
/// Executes the module method on the IoT Edge device.
/// </summary>
/// <param name="edgeModule">The edge module.</param>
/// <param name="moduleName">The edge module name.</param>
/// <param name="deviceId">The device identifier.</param>
/// <param name="methodName">Name of the method.</param>
[HttpPost("{deviceId}/{moduleId}/{methodName}", Name = "POST Execute module command")]
public async Task<C2Dresult> ExecuteModuleMethod(IoTEdgeModule edgeModule, string deviceId, string methodName)
[HttpGet("{deviceId}/{moduleName}/{methodName}", Name = "Get Execute module command")]
public async Task<C2Dresult> 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<C2Dresult> ExecuteCustomModuleMethod(string deviceId, string moduleName, string commandName)
{
return await this.edgeDevicesService.ExecuteModuleCommand(deviceId, moduleName, commandName);
}

/// <summary>
Expand Down
6 changes: 6 additions & 0 deletions src/AzureIoTHub.Portal/Server/Helpers/DeviceHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ public static IReadOnlyCollection<IoTEdgeModule> RetrieveModuleList(Twin twin)
ModuleName = property.Key
};

if (propertyObject.TryGetValue("settings", out var moduleSettings))
{
var setting = moduleSettings.ToObject<Dictionary<string, string>>();
module.ImageURI = setting["image"];
}

if (propertyObject.TryGetValue("status", out var status))
{
module.Status = status.Value<string>();
Expand Down
20 changes: 20 additions & 0 deletions src/AzureIoTHub.Portal/Server/Services/DeviceService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,26 @@ public async Task<CloudToDeviceMethodResult> ExecuteC2DMethod(string deviceId, C
}
}

/// <summary>
/// C2DMethod for custom command.
/// </summary>
/// <param name="deviceId">the deviceId.</param>
/// <param name="moduleName">the module name.</param>
/// <param name="method">the C2DMethod.</param>
/// <returns></returns>
/// <exception cref="InternalServerErrorException"></exception>
public async Task<CloudToDeviceMethodResult> 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);
}
}

/// <summary>
/// Get edge device logs
/// </summary>
Expand Down
39 changes: 33 additions & 6 deletions src/AzureIoTHub.Portal/Server/Services/EdgeDevicesService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,23 +170,23 @@ public async Task<Twin> UpdateEdgeDevice(IoTEdgeDevice edgeDevice)
/// <summary>
/// Executes the module method on the IoT Edge device.
/// </summary>
/// <param name="edgeModule"></param>
/// <param name="moduleName"></param>
/// <param name="deviceId"></param>
/// <param name="methodName"></param>
/// <returns></returns>
public async Task<C2Dresult> ExecuteModuleMethod(IoTEdgeModule edgeModule, string deviceId, string methodName)
public async Task<C2Dresult> 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"
});
}

Expand All @@ -201,6 +201,33 @@ public async Task<C2Dresult> ExecuteModuleMethod(IoTEdgeModule edgeModule, strin
};
}

/// <summary>
/// Execute the custom module command.
/// </summary>
/// <param name="deviceId">the device identifier.</param>
/// <param name="moduleName">the module name.</param>
/// <param name="commandName">the command name.</param>
/// <returns></returns>
public async Task<C2Dresult> 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
};
}

/// <summary>
/// Gets the IoT Edge device enrollement credentials.
/// </summary>
Expand Down
3 changes: 3 additions & 0 deletions src/AzureIoTHub.Portal/Server/Services/EdgeModelService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,13 @@ public async Task<IoTEdgeModel> GetEdgeModel(string modelId)
var query = await this.tableClientFactory
.GetEdgeDeviceTemplates()
.GetEntityAsync<TableEntity>(DefaultPartitionKey, modelId);

var modules = await this.configService.GetConfigModuleList(modelId);

var commands = this.tableClientFactory.GetEdgeModuleCommands()
.Query<EdgeModuleCommand>(c => c.PartitionKey == modelId)
.ToArray();

return this.edgeDeviceModelMapper.CreateEdgeDeviceModel(query.Value, modules, commands);
}
catch (RequestFailedException e)
Expand Down
2 changes: 2 additions & 0 deletions src/AzureIoTHub.Portal/Server/Services/IDeviceService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public interface IDeviceService

Task<CloudToDeviceMethodResult> ExecuteC2DMethod(string deviceId, CloudToDeviceMethod method);

Task<CloudToDeviceMethodResult> ExecuteCustomCommandC2DMethod(string deviceId, string moduleName, CloudToDeviceMethod method);

Task DeleteDevice(string deviceId);

Task<PaginationResult<Twin>> GetAllDevice(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ PaginationResult<IoTEdgeListItem> GetEdgeDevicesPage(PaginationResult<Twin> edge

Task<Twin> UpdateEdgeDevice(IoTEdgeDevice edgeDevice);

Task<C2Dresult> ExecuteModuleMethod(IoTEdgeModule edgeModule, string deviceId, string methodName);
Task<C2Dresult> ExecuteModuleMethod(string moduleName, string deviceId, string methodName);

Task<EnrollmentCredentials> GetEdgeDeviceCredentials(string edgeDeviceId);

Task<C2Dresult> ExecuteModuleCommand(string deviceId, string moduleName, string commandName);
}
}

0 comments on commit cf4448c

Please sign in to comment.