アプリケーションの各種スキーマ

ここでは、Actcast アプリケーションを開発する際に記述するスキーマファイルについて詳しく説明します。

アプリケーションスキーマは次の 3 つです。

  • Setting Schema: 動作環境の設定の雛形 (setting_schema.json)
  • Data Schema: アプリケーションから送信されるデータの雛形 (data_schema.json)
  • Manifesto: アプリケーションの実行時に必要となるリソース情報を記述

また、act_settings.jsonを用意することで Data Schema をテストできます。

setting_schema.json

Setting Schema はアプリケーションと共に利用される設定の形式を定義します。

アプリケーションは、スキーマに従った設定ファイルを環境変数ACT_SETTINGS_PATHを経由して利用します。 アプリケーション起動時に ACT_SETTINGS_PATH に JSON ファイルのパスがバインドされ、通常の JSON ファイルを利用するのと同様に利用できます。

Setting Schema は上記の JSON を記述するものです。setting_schema.json という名前のファイルに JSON Schema[^json schema] で記述します。 例えば以下のような記述をします。

{
  "$schema": "https://actcast.io/schema/v8/setting_schema_schema.json",
  "type": "object",
  "properties": {
    "display": {
      "title": "display",
      "description": "output video to HDMI display",
      "type": "boolean",
      "default": false
    },
    "threshold": {
      "title": "probability threshold",
      "description": "notify when over this threshold",
      "type": "number",
      "default": 0.9,
      "minimum": 0.0,
      "maximum": 1.0
    }
  },
  "required": [],
  "propertyOrder": ["display", "threshold"]
}

この記述には例えば以下のような JSON が適合します。

{
  "display": true,
  "threshold": 0.7
}

この JSON がアプリケーションへと渡されます。

Setting Schema に書ける項目

Setting Schema に書ける各フィールドは以下のようになっています。

フィールド名 型 必須 内容
$schema string Yes JSON Schema の記述形式を指定する
type string Yes "object" のみ
properties object Yes 設定の各プロパティを指定する
required array Yes 必須プロパティを指定する
propertyOrder array No プロパティを Web UI に表示する際の順番を指定する

$schema には "https://actcast.io/schema/v8/setting_schema_schema.json" を、 type には "object" を書きます。

propertyOrder が省略された場合は Actcast へアップロードする際に properties に書かれた順となるように propertyOrder が挿入されます。

properties

properties には以下の項目が書けます。

フィールド名 型 必須 内容
description string Yes フィールドの説明
descriptions object No フィールドの英語以外の言語での説明
type string Yes フィールドの型
title string No フィールドの名前
default No フィールドに値がない場合のデフォルト値
minimum number No ( type が number の場合のみ)フィールドの最小値
maximum number No ( type が number の場合のみ)フィールドの最大値
minLength number No ( type が string の場合のみ)フィールドの最小長
maxLength number No ( type が string の場合のみ)フィールドの最大長
pattern string No ( type が string の場合のみ)フィールドが一致すべき正規表現
enum array No ( type が string の場合のみ)フィールドの可能な値の列挙
x-ui-type string No Web UI で表示する方法

title と default については必須ではありませんが可能な限り付与することを推奨します。

危険

一度アプリケーションをアップロードした後は property の キーを維持したまま type だけを変更しないでください。
デバイスが正常に動作しなくなり、 再セットアップが必要になります。

  "properties": {
    "display": {
      "title": "display",
      "description": "output video to HDMI display",
      "type": "boolean", -> boolean 以外に変更するとデバイスが正常に動作しなくなります
      "default": false
    },
  }
descriptions

descriptions には英語以外の言語での説明を書きます。オブジェクトのプロパティ名にはISO 639-1 で指定された言語コードを、値にその言語での説明を書きます。

例えば以下のような記述をします。

{
  "ja": "これはフィールドの説明です",
  "eo": "Ĉi tiu estas la ekspliko de la areno"
}
pattern

pattern には、文字列の値が一致する必要のある正規表現を書きます。 例えば、大文字の英数字 8 文字のみを許可する場合は以下のように書きます。

{
  "title": "device ID",
  "description": "device ID",
  "type": "string",
  "pattern": "^[A-Z0-9]{8}$"
}
type

type には以下の項目が書けます。

値 説明
"boolean" 真偽値
"integer" 整数値
"number" 数値
"string" 文字列
x-ui-type

x-ui-type には以下の項目が書けます。

値 説明
"textarea" テキストエリア
"password" パスワード

data_schema.json

Data Schema ではアプリケーションの出力の形式を定義します。

Data Schema は Cast で利用され、例えば「信頼度スコアが 90%を超えたときに所定の場所にデータを POST する」という振る舞いを記述するために用いられます。 Actcast アプリケーションの標準出力は、各行が Data Schema に従う必要があります。 標準出力にプリントされた文字列は Act Log として Actcast に転送されます。

Data Schema は data_schema.json という名前のファイルに JSON Schema で記述します。

例えば以下のような記述をします。

{
  "$schema": "https://actcast.io/schema/v8/data_schema_schema.json",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "prob": {
        "title": "probability",
        "description": "matching score",
        "type": "number",
        "minimum": 0.0,
        "maximum": 1.0
      },
      "label": {
        "title": "label",
        "description": "the most matching class name",
        "type": "string"
      }
    },
    "required": ["prob", "label"]
  }
}

これには以下のような JSON が適合します。

[
  {
    "prob": 0.3,
    "label": "cat"
  },
  {
    "prob": 0.7,
    "label": "dog"
  }
]

アプリケーションはこのような JSON を出力することになります。

Data Schema に書ける項目

Data Schema に書ける各フィールドは以下のようになっています。

フィールド名 型 必須 内容
$schema string Yes JSON Schema の記述形式を指定する
type string Yes "array" のみ
items object Yes 配列の中身を指定する

items

items には以下の項目が書けます。

フィールド名 型 必須 内容
type string Yes "object" のみ
properties object Yes データの各プロパティを指定する
required array Yes 必須プロパティを指定する
properties

properties には以下の項目が書けます。

フィールド名 型 必須 内容
description string Yes プロパティの説明
descriptions object No プロパティの英語以外の言語での説明
type string Yes プロパティの型
title string No プロパティの名前
enum array No (type が string の場合のみ)可能な値の列挙
items object No (type が array の場合のみ)配列の要素のスキーマ
properties object No (type が object の場合のみ)オブジェクトのスキーマ

items と properties にはそれぞれ items と properties の内容が再帰的に書けます。 descriptions は Setting Schema のものと同じものが書けます。

type

type には以下の項目が書けます。

値 説明
"boolean" 真偽値
"integer" 整数値
"number" 数値
"string" 文字列
"array" 配列
"object" オブジェクト

act_settings.json

作業用ディレクトリに存在するact_settings.jsonは自動的に転送されアプリから利用されます。 この JSON ファイルはsetting_schema.jsonに従った形式である必要があります。

下記コマンドを実行すると、act_settings.json、setting_schema.jsonおよびdata_schema.jsonの検査を行います。

$ actdk validate-json

このコマンドと同等の検査は、actdk runコマンドを実行すると自動で行われます。

manifesto/*.json (Manifesto V2)

メモ

Actcast Agent のバージョン 1.6.0 以降で利用可能です。

Manifesto にはアプリケーションの実行時に必要となるリソースを記述します。 Manifesto はデバイスごとに異なる設定を記述することができます。 その際は別々のファイルに設定を記述することになります。

actdk は初期化時にいくつかの Manifesto を生成します。 例えば以下に示すマニフェストファイルは Raspberry Pi 4 に適用され、 カメラと VideoCore のアクセスを許可し、 特別なネットワークアクセスを許可しない標準的な設定です。

{
  "version": 2,
  "target_type": "raspberrypi-bookworm",
  "boards": [
    "RSPi4B"
  ],
  "devices": [
    {"type": "camera"},
    {"type": "videocore"}
  ]
}

version

"version" にはバージョンを表わす数値を入れます。このプロパティは将来の拡張性のために存在し、Manifesto V2 では 2 です。

target_type

"target_type" にはそのマニフェストを適用するターゲットタイプを記述します。現時点では "raspberrypi-bullseye" または "raspberrypi-bookworm" を指定できます。

boards

"boards" にはそのマニフェストを適用するボードのリストを記述します。

アプリを起動する際、Actcast デバイスエージェントは manifesto/*.json の "boards" と "target_type" を見てどの manifesto を適用するべきかを決定します。そのため、ある "target_type" に対して "boards" の指定が重複してはいけません。例えば manifesto/a.json と manifesto/b.json の両方に "target_type" として raspberrypi-bookworm が指定されている場合、その両方の "boards" に RSPi4B を含んではいけません。

"boards" には以下のボードを指定できます。

notation description
RSPi1A Raspberry Pi 1 Model A
RSPi1B Raspberry Pi 1 Model B
RSPi1APlus Raspberry Pi 1 Model A+
RSPi1BPlus Raspberry Pi 1 Model B+
RSPi2B Raspberry Pi 2 Model B
RSPiAlpha Raspberry Pi Alpha (early prototype)
RSPiCM1 Raspberry Pi Compute Module 1 (CM1)
RSPi3B Raspberry Pi 3 Model B
RSPiZero Raspberry Pi Zero
RSPiCM3 Raspberry Pi Compute Module 3 (CM3)
RSPiZeroW Raspberry Pi Zero W
RSPi3BPlus Raspberry Pi 3 Model B+
RSPi3APlus Raspberry Pi 3 Model A+
RSPiCM3Plus Raspberry Pi Compute Module 3+ (CM3+)
RSPi4B Raspberry Pi 4
RSPiCM4 Raspberry Pi Compute Module 4
RSPiZero2W Raspberry Pi Zero 2 W

devices

"devices" にはアプリケーションが要求するデバイスのリストを指定することができます。リストの要素は以下のようなフィールドを持ったオブジェクトとして記述します。

フィールド名 型 必須 デフォルト 内容
type string Yes N/A 要求するデバイス種
device array No N/A 対応するデバイスファイルのリスト
required bool No true デバイスの存在が必須かどうか
mode string No legacy デバイスのマウント方法

"type" に指定可能なデバイスの種類は以下の通りです。

タイプ名 ファイルの省略可否 説明
"camera" Yes カメラデバイス
"videocore" Yes VideoCore
"display" Yes ディスプレイ
"hid-input" Yes キーボード・マウス(ActcastOS のバージョン 4.20.0 以降で利用可能)
"framebuffer" No フレームバッファ
"gpio" No GPIO ピンを用いるデバイス
"sound" No マイク・スピーカ
"other" No 上記にあてはまらないデバイス

"device" を指定しなかった場合、Agent が "type" を元に自動でデバイスファイルをマウントします。その際にマウントされたファイルは アプリケーション内でのデバイスの扱い によってアプリケーションに通知されます。

"mode"に指定可能なモードは以下の通りです。

モード名 説明
legacy 個別のデバイスを--deviceオプションでマウントします
hotplug 機器の再接続が可能になるようにマウントします

hotplugモードは"camera"と"sound"のデバイスタイプでのみ指定可能です。hotplugモードのデバイスが存在する場合、ホストマシンの/dev全体がマウントされます。

required が true であることは、そのデバイスがアプリケーションの動作に必須であることを表します。あるデバイスが必須と指定された場合、そのアプリケーションを使用する Act の起動時に、デバイスファイルが存在することがチェックされます。 もし対応するデバイスファイルが存在しない場合、Act のインストールはエラーとなり、起動に失敗します。

以下に例を挙げます。

"devices": [
  {
    "type": "camera",
    "required": true
  }
]

この設定ではカメラが"required":trueと指定されているため、Act の起動時にカメラに関連するデバイスファイルの存在がチェックされます。

network_mode

メモ

以下のファームウェアバージョンで利用可能です。

  • Actcast OS 1: 1.83.0 以上
  • Actcast OS 2: 2.22.0 以上
  • Actcast OS 3: 3.11.0 以上

アプリが使うネットワークのモードを指定することができます。以下の値から指定することができます。

  • bridge: 外部との通信に制限がないブリッジネットワークを利用します
    • ポートを公開する場合はpublished_portsによる指定が必要となります
    • UDP multicast を利用する場合、networksに別途記述が必要になります
  • host: ホストシステムのネットワークをそのまま使います。ポートの公開も制限なく行えますが、アプリの脆弱性がホストシステムに影響がある可能性があります
    • networksやpublished_portsによる記述は無視されます
  • socks: SOCKS プロキシを経由することで外部との通信をnetworksで指定したもののみに限定します
    • published_portsは利用できません
  • filtered: 外向き通信は SOCKS プロキシ経由に限定しつつ、外部からのアクセスはfilter_rulesで指定した条件のみに制限します
    • ActcastOS 3.76.1, 4.28.1 以降で利用できます
    • egress の接続先はfilter_rules.egressに記述します
    • ingress を許可するにはfilter_rules.ingressとpublished_portsの両方を記述します
    • networksは利用しません

networks

network_modeが指定されていない、もしくはsocksが指定されている場合、アプリと外部と通信させたい接続先をネットワークマニフェストとして記述することで弊社が提供する SOCKS プロキシ経由で外部と通信できるようになります。 また、UDP multicast をbridgeモードで利用する場合もこちらの記述が必要になります。 network_modeがfilteredの場合はnetworksではなくfilter_rulesを利用してください。

詳細は ネットワークマニフェスト をご覧下さい。

filter_rules

network_modeがfilteredの場合、filter_rulesでアプリの入出力を制御できます。

  • egressではアプリから外部への接続先を指定します
    • 接続は SOCKS プロキシ経由で行われます。SOCKS プロキシへのアクセス方法(ACTCAST_SOCKS_SERVER 環境変数の使い方)は ネットワークマニフェスト と同じです
    • dst_domainまたはdst_ipのどちらかを指定します
    • dst_domain指定時のワイルドカードの扱いはnetworksと同じです
    • dst_ipには送信先の IPv4 アドレスを指定します
    • dst_portは省略可能です。省略した場合はポート番号を限定しません
    • protocolは現時点では"tcp"のみ指定できます
  • ingressでは外部からアプリへのアクセス元とコンテナ内ポートを指定します
    • src_ipには送信元の IPv4 アドレスを指定します。プレフィックス長を指定することもできます
    • container_portにはアプリが待ち受けるコンテナ内ポートを指定します
    • protocolは現時点では"tcp"のみ指定できます
  • filter_rulesを省略するか、egressとingressを空配列にした場合、filteredモードでは外部との通信は許可されません

以下は、actcast.io:443 と 192.168.1.0:80 への外向き通信と、192.168.1.0/24からのtcp:3000 -> tcp:8080の通信を許可する例です。

{
  "version": 2,
  "target_type": "raspberrypi-bookworm",
  "boards": ["RSPi4B"],
  "devices": [],
  "network_mode": "filtered",
  "filter_rules": {
    "egress": [
      {
        "dst_domain": "actcast.io",
        "dst_port": 443,
        "protocol": "tcp"
      },
      {
        "dst_ip": "192.168.1.0",
        "dst_port": 80,
        "protocol": "tcp"
      }
    ],
    "ingress": [
      {
        "src_ip": "192.168.1.0/24",
        "container_port": 8080,
        "protocol": "tcp"
      }
    ]
  },
  "published_ports": [
    {
      "container_port": 8080,
      "host_port": 3000,
      "protocol": "tcp"
    }
  ]
}

この例では、アプリは SOCKS プロキシ経由で actcast.io:443 に接続できます。 また、デバイスの 3000/tcp に届いた通信のうち、送信元が 192.168.1.0/24 に含まれるものだけがアプリの 8080/tcp に到達できます。

allow_all_networks

アプリを外部と無制限に通信させたい場合に指定します。network_modeがbridgeである状態と同じです。 network_modeが指定されている場合、このフィールドは使うことができません。

SOCKS プロキシを経由せずに外部と通信できるようになります。

  • この設定が有効な場合 networks の設定は無視されます。
  • TCP/UDP どちらも許可されます。
{
  "version": 2,
  "target_type": "raspberrypi-bookworm",
  "boards": ["RSPi4B"],
  "devices": [],
  "allow_all_networks": true
}

published_ports

アプリケーションが外部からアクセス可能なポートを指定します。 アプリ内でサーバを立てて外部ネットワークからアクセスできるようになる機能です。 ポートの指定はコンテナ内のポート番号(container_port)、ホスト側で実際に使われるポート番号(host_port)、使用するプロトコル(protocol)の3つのフィールドを含むオブジェクトの配列によって行われます。

  • network_modeがbridgeまたはfiltered、もしくはallow_all_networks が true の場合に使えます
  • host_portとして有効なポートは 1024-65535 の範囲です
    • ただし 8000 は actdk で利用しているため利用できません
  • プロトコルには “tcp”, “udp” または “sctp” が指定できます

> network_modeがfilteredの場合

  • 外部からの通信を許可するには同じcontainer_portをfilter_rules.ingressにも記述する必要があります
  • filter_rules.ingressは現時点でtcpのみに対応しています
{
  "version": 2,
  "target_type": "raspberrypi-bookworm",
  "boards": ["RSPi4B"],
  "devices": [],
  "allow_all_networks": true,
  "published_ports": [
    {
      "container_port": 80,
      "host_port": 8080,
      "protocol": "tcp"
    }
  ]
}

hailort_version

アプリケーションが利用する HailoRT のバージョンを指定します。 現時点では以下の制約があります。

  • actdk のバージョン 1.30.0 以降で利用できます
  • target_type が raspberrypi-bullseye または raspberrypi-bookworm の場合に利用できます
  • raspberrypi-bullseye では 4.10.0、4.14.0 または 4.21.0 を指定できます
  • raspberrypi-bookworm では 4.21.0 のみ指定できます
  • hailort_version が 4.14.0 の場合は actcastos 3.3.0 以降のデバイスでのみ動作します
  • hailort_version が 4.21.0 の場合は actcastos 3.22.0 以降のデバイスでのみ動作します
    • 4.21.0 は libatomic1 に依存しているため .actdk/dependencies.json に追加してください
{
  "version": 2,
  "target_type": "raspberrypi-bookworm",
  "boards": ["RSPiCM4"],
  "devices": [
    {
      "type": "other",
      "device": ["/dev/hailo0"]
    }
  ],
  "hailort_version": "4.21.0"
}

cache_volume

ActcastOS のバージョン 3.18.0 以降で利用可能です

通常、アプリケーションが保存するデータはデバイスの再起動とともに消滅してしまいます。 このオプションを指定すると、デバイス再起動時にもデータを永続的に保存できるボリュームを作成することができます。ボリュームは/mnt/cache_volumeにマウントされます。 act を切り替えてしまうとデータは消失します。

sizeは MB 単位で指定する必要があります。

{
  "version": 2,
  "target_type": "raspberrypi-bookworm",
  "boards": ["RSPi4B"],
  "devices": [],
  "cache_volume": {
    "size": 256
  }
}

保存されたデータはシステムと同じストレージ内に保存されます。頻繁な書き込みはストレージの寿命を短くし、システムのパフォーマンスに影響を与える可能性があります。

syscalls

ActcastOS のバージョン 4.20.0 以降で利用可能です

docker のseccompで default で許可されていない syscall が必要な場合はこの field に追加することで許可されます。

{
  "version": 2,
  "target_type": "raspberrypi-bookworm",
  "boards": ["RSPi4B"],
  "devices": [],
  "syscalls": ["clone","unshare"]
}

Act に対する追加フィルタールール

ActcastOS のバージョン 3.76.1、 4.28.1 以降で利用可能です

manifesto で filtered network mode が指定されている場合、manifesto の filter_rules に加え Act にフィルタールールを追加できます。 この追加フィルタールールは WebUI の Act 設定、もしくは actdk run 時の additional_filter_rules.json ファイルにより設定できます。 egress には許可のルールを追加で設定できます。これは filter_rules.egress とあわせて許可されます。 ingress には拒否のルールを追加で設定できます。これによって filter_rules.ingress によって許可されたものをさらに制限することができます。

以下は actcast.io:443 と 192.168.1.0 への外向き通信の追加許可と、 192.168.2.0/24 から tcp:8080 への通信を拒否する additional_filter_rules.json の例です。

{
  "egress": [
    {
      "dst_domain": "actcast.io",
      "dst_port": 443,
      "protocol": "tcp"
    },
    {
      "dst_ip": "192.168.1.0",
      "protocol": "tcp"
    }
  ],
  "ingress": [
    {
      "src_ip": "192.168.2.0/24",
      "container_port": 8080,
      "protocol": "tcp"
    }
  ]
}
最終更新日