How can I view a hierarchical folder structure in Azure IoT Central device Files list?

105 views Asked by At

Our devices upload daily files and we need them organised in a YYYY/YYYY-MM/YYYY-MM-DD folder structure but the devices Files page list in IoT Central only seems to display files and does not display folders.

The folder structure is created in BlobStorage but it seems the Files page just doesn't display folders at all.

Is it possible to customise the IoT Central apps Files page (or create a new one) to allow display of a hierarchical folder structure as well as files.

Link to reference for uploading files that show in IoTCentral https://learn.microsoft.com/en-us/azure/iot-hub/file-upload-dotnet#upload-file-from-a-device-app

2

There are 2 answers

1
Matthijs van der Veer On BEST ANSWER

The files view will always show all the blobs for that device, recursively. There's no folder display support in IoT Central.

The closest thing to it is being able to filter, once you put the view in list mode. In my example, I have a device that has some images on the root folder, and an image in a YYYY/MM/DD folder. You can switch the view to List: enable list view

Then you get a filter option: select filter

You can filter on the path of a file: filter on path

So yeah, no folder display support, but you can filter on a path.

0
Sampath On
  • Using reference MSDOC I am able the Upload files from devices to Azure IoT central with YYYY/YYYY-MM/YYYY-MM-DD folder structure.

  • AFAIK, There's no folder Structure in IoT Central but while checking the sample files in the blob they are uploaded with the folder Structure. The IoT Central Files page does not display folders but files only. However, you can create a folder structure in Blob Storage and upload files to the directory with Iot Central.

Code:

class IoTCentralDevice : IDisposable
{
    private string scopeId;
    private string deviceId;
    private string deviceKey;
    private string modelId;
    public DeviceClient DeviceClient { get; private set; }

    public IoTCentralDevice(string scopeId, string deviceId, string deviceKey, string modelId)
    {
        this.scopeId = scopeId;
        this.deviceId = deviceId;
        this.deviceKey = deviceKey;
        this.modelId = modelId;
    }

    public async Task<string> ProvisionDeviceClient()
    {
        string connectionString = string.Empty;

        try
        {
            var security = new SecurityProviderSymmetricKey(this.deviceId, this.deviceKey, null);
            var provisioningClient = ProvisioningDeviceClient.Create(
                "global.azure-devices-provisioning.net",
                this.scopeId,
                security,
                new ProvisioningTransportHandlerMqtt());

            var provisioningPayload = new ProvisioningRegistrationAdditionalData
            {
                JsonData = $"{{\"iotcModelId\": \"{this.modelId}\"}}"
            };

            DeviceRegistrationResult result = await provisioningClient.RegisterAsync(provisioningPayload);
            if (result.Status != ProvisioningRegistrationStatusType.Assigned)
            {
                throw new Exception($"Device registration failed with status: {result.Status}");
            }

            Console.WriteLine("DPS registration succeeded");

            connectionString = $"HostName={result.AssignedHub};DeviceId={result.DeviceId};SharedAccessKey={this.deviceKey}";
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Failed to instantiate client interface from configuration: {ex.Message}");
        }

        return connectionString;
    }

    public async Task ConnectDeviceClient(string connectionString)
    {
        try
        {
            DeviceClient = DeviceClient.CreateFromConnectionString(connectionString, Microsoft.Azure.Devices.Client.TransportType.Mqtt);
            if (DeviceClient == null)
            {
                Console.WriteLine($"Failed to connect device client interface from connection string - device: {this.deviceId}");
                return;
            }

            await DeviceClient.OpenAsync();

            Console.WriteLine($"IoT Central successfully connected device: {this.deviceId}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"IoT Central connection error: {ex.Message}");
        }
    }

    public async Task UploadFileToBlob(string filePath)
    {
        try
        {
            if (DeviceClient == null)
            {
                Console.WriteLine("DeviceClient is not initialized. Connect to IoT Central first.");
                return;
            }
            DateTime currentTime = DateTime.UtcNow;
            string year = currentTime.ToString("yyyy");
            string yearMonth = currentTime.ToString("yyyy-MM");
            string yearMonthDay = currentTime.ToString("yyyy-MM-dd");
            string fileName = "hello.pdf";
            string blobName = $"{year}/{yearMonth}/{yearMonthDay}{fileName}"; // This is the blob name for file upload

            using var fileStreamSource = new FileStream(filePath, FileMode.Open);

            // Get SAS URI for file upload
            var fileUploadSasUriRequest = new FileUploadSasUriRequest
            {
                BlobName = blobName
            };

            FileUploadSasUriResponse sasUri = await DeviceClient.GetFileUploadSasUriAsync(fileUploadSasUriRequest);
            Uri uploadUri = sasUri.GetBlobUri();

            // Upload the file to Azure Storage using SAS URI
            var blockBlobClient = new BlockBlobClient(uploadUri);
            await blockBlobClient.UploadAsync(fileStreamSource, new BlobUploadOptions());

            // Complete file upload and notify IoT Hub
            var successfulFileUploadCompletionNotification = new FileUploadCompletionNotification
            {
                CorrelationId = sasUri.CorrelationId,
                IsSuccess = true,
                StatusCode = 200,
                StatusDescription = "Success"
            };

            await DeviceClient.CompleteFileUploadAsync(successfulFileUploadCompletionNotification);

            Console.WriteLine("File uploaded.");
            Console.WriteLine($"Uploaded file name: {blobName}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error uploading file: {ex.Message}");
        }
    }

    public void Dispose()
    {
        DeviceClient?.Dispose();
    }
}

class Program
{
    static async Task Main(string[] args)
    {
        try
        {
            Console.WriteLine(" Starting IoT Central device...");

            string scopeId = "";
            string deviceId = "";
            string deviceKey = "";
            string modelId = "dtmi:IoTCentral:IotCentralFileUploadDevice;1";

            using var iotDevice = new IoTCentralDevice(scopeId, deviceId, deviceKey, modelId);

            Console.WriteLine("Starting device registration...");
            string connectionString = await iotDevice.ProvisionDeviceClient();

            if (!string.IsNullOrEmpty(connectionString))
            {
                Console.WriteLine("Connecting the device...");
                await iotDevice.ConnectDeviceClient(connectionString);

                string filePath = "C:\\Users\\hello.pdf";
                await iotDevice.UploadFileToBlob(filePath);
            }
            else
            {
                Console.WriteLine("Failed to obtain connection string for device.");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($" Error starting process: {ex.Message}");
        }
    }
}

Output:

enter image description here

In IOT Central:

enter image description here

In Blob storage : enter image description here