Sending Files using the API

This topic describes how to send files using Octave's REST API.

File Transfer API Overview

When using your Cloud, a file transfer campaign consists of three interactions using three distinct endpoints in Octave’s REST API:

  1. File API to download (POST) a new file object in Octave Cloud and manage files in the repository (GET, PUT, DELETE).
  2. Send API to send a file from Octave Cloud to a list of targeted devices from Octave Edge.
  3. Operation API to read the file-sending operation’s status from the different steps.

For a file service, a new Octave domain object has been created with following definition:

File : {
  "id" : "f1234567890",
  "version" : 1,
  "creatorId" : ...
  "creationDate" : ...
  "companyId" : "c1234567890",
  "description" : "",
  "filename" : "file_name.png",
  "path" : "/my_company/files"
  "type" : "image/png", // Mime Type
  "size" : 12345678,
  "avFileId" : "028747efade",
  "hash" : "abcdef",
  "closed" : false,
  "source" : "cloud" / "device",
 }

The File object is bound to an Octave Company and can be created, updated, and read using standard endpoints:

📘

Note:

  • Files will be versioned in a similar way to Blueprints and Edge Actions.
  • Updating fields which describe the object (e.g., the description) will NOT create a new version (the current description will be modified).
  • Updating the file contents (by uploading a new file) will cause a new version to be created.
  • A file cannot be deleted if it’s associated with a Blueprint.
  • Furthermore, multiple files with the same filename cannot persist on a single device! If a new file arrives with same filename (but different hash), it will be overwritten.
  • The operation ID of a file-sending request will not be passed to the Octave Edge device and won’t be available through its Resource to reconciliate acknowledgement with initial operation.
  • You can refer to the API examples here.

File-Sending API Sequence

The following steps describe how to send a file to your Remote Asset:

  1. Your Cloud uploads a file to Octave Cloud using POST /v5.0/company-name/file:
    a. You must submit both JSON data and the file to upload. Octave will handle this as a multipart-mixed message.
    b. This endpoint will return a File object synchronously, ready to be used.
    c. The path and description fields are optional.
    d. The filename will be populated using the attribute in the Content-Disposition header of the POST data.
    e. The maximum size of the file is 80MB and the repository size per company is limited to 5GB.

Customer Cloud to Octave Cloud – Download a File

Request

POST /v5.0/company-name/file

Content-type: multipart/mixed; boundary="ABCD"
--ABCD
Content-Disposition: form-data; name="file"; filename="file.csv"
Content-Type: image.gif
// GIF attached
...
--ABCD
// JSON attached
Content-Disposition: form-data; name="params"; filename="object.json"
Content-Type: application/json
{
"path" : "/company-name/",
"description" : "beep boop"
}
--ABCD--

Response

{
  "head": {
    "status": 201,
    "ok": true,
    "messages": [
      "Your request has been processed successfully. A new resource has been created."
    ],
    "errors": [],
    "references": {}
  },
  "body": {
    "id": "<id>",
    "avFileId": "<id>",
    "companyId": "<id>",
    "creationDate": <date>,
    "creatorId": "<id>",
    "description": "a description",
    "filename": "yoshi.png",
    "filetype": "image/png",
    "hash": "<hash>",
    "lastEditDate": <date>,
    "lastEditorId": "<id>",
    "path": "/farm",
    "size": 642729,
    "source": "CLOUD",
    "version": 1
  }
}
  1. Your Cloud sends a request to Octave Cloud to send a file to a list of devices (or a Tag) using PUT /v5.0/company-name/device/file/send:
    a. This API will return an Operation object. Steps will be created for all devices, for all files, regardless of whether the file is already present on the device.
    b. If the file is already present on a device, it will not be sent again. Octave will report success.
    c. There is currently no means to pass instructions to the Octave Edge and the Remote Asset in the request as to what should be done with the file – the File Service is responsible for deciding how the file is consumed.
    d. Only files available in a company can be sent to Octave devices belonging to that company.

Customer Cloud to Octave Cloud – Send a File to a List of Devices

Request

PUT /v5.0/company-name/device/file/send
{
  // One of:
  deviceIds : ["d1", "d2"]
  tag : "@foo=bar",
  filter : "hardware.model==\"FX30\"",
  //
 
  fileIds : {"f000001" : {"version" : 1}}
}

Response

{
  "head": {
    "status": 200,
    "ok": true,
    "messages": [],
    "errors": [],
    "references": 
  },
  "body": {
    "id": "<id>",
    "action": "SEND_FILE",
    "companyId": "<id>",
    "complete": false,
    "creationDate": <date>,
    "creatorId": "<id>",
    "details": {},
    "deviceIds": [],
    "input": {
      "deviceIds": [
        "d1",
        "d2"
      ]
    },
    "lastEditDate": <date>,
    "lastEditorId": "<id>",
    "state": "STARTED",
    "status": {},
    "stepCount": 2,
    "timeout": 86400
  }
}
  1. (Optional) Your Cloud requests to Octave Cloud the status of the file-sending operation using GET /v5.0/company-name/operation/{id}:

Customer Cloud to Octave Cloud – Get File-Sending Operation’s Status

Request

GET /v5.0/company-name/operation/{id}

Response

{
  "head": {
    "status": 200,
    "ok": true,
    "messages": [],
    "errors": []
  },
  "body": {
    "companyId": "string",
    "creationDate": 1553558878392,
    "lastEditDate": 1553558878392,
    "id": "o5c37879220721249d5c8ffa3",
    "action": "TRANSFER_DEVICE",
    "complete": true,
    "state": "UNKOWN",
    "status": {
      "d5b73101dc4eaa254868f2e7b": {
        "PUSH_CONFIGURATION": {
          "state": "STARTED",
          "ts": 1553560620870
        }
      }
    }
  }
}
  1. (Optional) Your Cloud requests to Octave Cloud the status of the file-sending operation for given device (a.k.a. step) using GET /v5.0/company-name/step/{operation-id}/{id}:

Customer Cloud to Octave Cloud – Get File-Sending Status for a given device

Request

GET /v5.0/{company}/step/{operation-id}/{id}

Response

{
  "head": {
    "status": 200,
    "ok": true,
    "messages": [],
    "errors": [],
    "references": {}
  },
  "body": [
    {
      "id": "u6086e139c7106c5a75e4c660",
      "action": "SEND_FILE",
      "companyId": "c5bae617e90f45d7d11710087",
      "complete": false,
      "creationDate": 1619452217139,
      "creatorId": "i5adf463709159f4dde43a86f",
      "currentStep": 0,
      "details": {
        "avSystemId": "122c1b2f4e1740d0926670c51b4f6c1b",
        "avCompanyId": "5b57c7e3fe0b43d6a7c25de6e17e3ad1"
      },
      "lastEditDate": 1619452222929,
      "lastEditorId": "i000000000000000000000001",
      "operationId": "o6086e139c7106c5a75e4c65f",
      "state": "STARTED",
      "steps": [
        {
          "action": "SEND_FILE",
          "state": "STARTED",
          "complete": false,
          "percentComplete": 0,
          "details": {
            "path": "/iot_solutions",
            "avFileId": "2fb2312e-5a78-4c31-8206-0390e14ab34e",
            "filename": "file_01.txt",
            "size": 2000,
            "fileVersion": 1,
            "fileId": "f6079517a1aa919de914f93f1"
          },
          "output": {},
          "error": null
        }
      ],
      "targetId": "d60794d111aa919de914f9311"
    }
  ]
}

The following diagram depicts this process:

750

📘

Note:

You can use the Operation endpoint to determine when the file is successfully sent to Octave Edge but if you want to have complete acknowledgment of the operation up to the usage of the file by your asset, you should consider using Resources and Cloud Actions to receive aggregated acknowledgments in a time-sensitive manner as described in Acknowledgment Orchestration.

File Transfer Support in Blueprints

Along with an Octave Edge configuration, a Blueprint can also support file transfers. This means you can include a file-sending request in a Blueprint so that when the Blueprint is applied, Octave also sends the file to the device. You can add a specific file so that it will be transferred automatically when the Blueprint is applied.

This enables you to automatically provision your new devices with the following, in this order:

  1. Octave Firmware updates.
  2. Edge configuration (Resources, Edge Actions, Observations, services).
  3. File for Asset software updates.

The following example shows how your Cloud adds a file to a Blueprint using PUT /v5.0/company-name/blueprint/{id}:

Customer Cloud to Octave Cloud – Update blueprint with a file

Request

curl -X "PUT" "https://api.flowthings.io/v5.0/my_company/blueprint/{id}" \
     -H 'X-Auth-Token: <token>' \
     -H 'X-Auth-User: <user>' \
     -d $'{
	"files" : {
       "f6062114711980e223248d74c" : {"version": 1},
       "f6053d2ba6313cc5d2dd0a3ad" : {"version": 1},
    } 
}'

Response

{
  "head": {
    "status": 201,
    "ok": true,
    "messages": [
      "Your request has been processed successfully. A new resource has been created."
    ],
    "errors": [],
    "references": {}
  },
  "body": {
    "id": "<id>",
    "companyId": "<id>",
    "creationDate": <date>,
    "creatorId": "<id>",
    "files": {
      "f6053d2ba6313cc5d2dd0a3ad": {
        "version": 1
      },
      "f6062114711980e223248d74c": {
        "version": 1
      }
    },
    "lastEditDate": <date>,
    "lastEditorId": "<id>",
    "version": 1
  }
}