Custom Command

Custom Command

This page was machine-translated. The Japanese page is the official version.

Custom Command lets you send an arbitrary command to an Act on a device through the Actcast API and retrieve its result. Requests to the Actcast API are forwarded through the Actcast Agent on the device to a handler in the application.

Custom Command is available on ActcastOS 3.80.0 and later, or ActcastOS 4.32.0 and later.

APIs

For general information about using the Actcast API, see Actcast API. Custom Command primarily uses these APIs:

Both APIs require authentication with the Authorization: token <API token> header.

Workflow

  1. Implement a custom command handler in the Act application and register it with CommandServer.
  2. Call the Send a Custom Command API to send a payload to the target device.
  3. Save the id returned in the API response.
  4. The handler runs on the Act and returns a result string.
  5. Call the Get a Custom Command result API with the id from step 3 to retrieve status and data.

How API values map to the handler

API or sample value Corresponding value Description
Request body of POST /jobs/custom_command request['payload'] The request body is an arbitrary payload string and is passed to the handler unchanged.
Response id from POST /jobs/custom_command request['id'] A new ID is returned for each command and is used to retrieve its result.
Handler return value Response data from GET /custom_command/{id} When status is finished, the handler’s return string is returned as data.
Response status from GET /custom_command/{id} None Actcast sets this value to indicate the execution state; the handler does not return it.

The Actcast Agent passes JSON data like the following to the application handler:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "payload": "ping"
}

For details about communication between the Actcast Agent and an application, see Communication between an application and the Actcast Agent.

Example: Send a Custom Command and retrieve its result

This example uses curl to send a command through the Custom Command API and retrieve its result.

1. Send a Custom Command

Replace <your_api_token>, <group_id>, and <device_id> with your API token, group ID, and device ID.

API_TOKEN="<your_api_token>"
GROUP_ID="<group_id>"
DEVICE_ID="<device_id>"
PAYLOAD='ping'

curl -sS \
  -H "Authorization: token ${API_TOKEN}" \
  -H "Content-Type: text/plain" \
  --data-raw "${PAYLOAD}" \
  -X POST "https://api.actcast.io/v0/groups/${GROUP_ID}/devices/${DEVICE_ID}/jobs/custom_command"

Example response:

{"id":"550e8400-e29b-41d4-a716-446655440000"}

Save the returned id for the result request. The request body is the payload itself. For example, if you send PAYLOAD='ping', the handler receives request['payload'] == 'ping'.

2. Get the result

Set COMMAND_ID to the id returned when you sent the command:

COMMAND_ID="550e8400-e29b-41d4-a716-446655440000"

curl -sS \
  -H "Authorization: token ${API_TOKEN}" \
  "https://api.actcast.io/v0/groups/${GROUP_ID}/devices/${DEVICE_ID}/custom_command/${COMMAND_ID}"

Example response:

{
  "status": "finished",
  "data": "ping"
}

If status is processing, the result is not ready yet. Call the same API again after an interval.

data contains the string returned by the handler. For example, if the handler returns request['payload'], sending ping results in data being ping.

Possible status values:

  • processing: The command is still running.
  • finished: The command completed successfully. data contains the handler’s return value.
  • lost: No result was received within 5 minutes of sending the command.
  • app_error: An error occurred in the handler.
  • command_server_error: An error occurred in CommandServer.

Results are available for 14 days after the command is sent. After that, the result API returns HTTP 404.

Develop an application that supports Custom Command

Use CommandServer from actfw-core 2.17.0 or later.

Provide a handler for Custom Command and pass it to the CommandServer constructor. The handler parses the request string, performs the requested operation, and returns a result string.

The payload and response must each be 64 KiB or less.

The handler may be called more than once with the same request. If repeated execution is not safe, store the request UUID in the handler and check whether the operation needs to run.

Handlers may run concurrently without waiting for other handler calls to finish. If an operation cannot run concurrently, use a lock or another mechanism to ensure that it is not already running.

This handler example returns a string containing the ID and payload:

import actfw_core
from actfw_core.command_server import CustomCommandRequest


def custom_command_handler(request: CustomCommandRequest) -> str:
    custom_command_id = request["id"]
    payload = request["payload"]
    return f"Payload received: {payload} (id: {custom_command_id})"


def main():
    app = actfw_core.application.Application()
    command_server = actfw_core.CommandServer(
        custom_command_handler=custom_command_handler
    )
    app.register_task(command_server)
    app.run()


if __name__ == "__main__":
    main()

Notes

Do not send Custom Command requests to devices running Acts that do not support Custom Command (for example, Acts using an older version of actfw-core). A request may cause CommandServer to exit, preventing the Act from responding to Take Photo requests until it is restarted.

To avoid this, update the application to use actfw-core 2.17.0 or later, which supports Custom Command.

Last updated on