aptpod Tech Blog

株式会社アプトポッドのテクノロジーブログです

Agent 1とAgent 2の設定手順を比べてみた

2022年12月に intdash Edge Agent 2 デベロッパーガイド が公開されました。 これまでの intdash Edge Agent(以降、Agent 1)と設定手順を比較してみましょう。

はじめまして。ソリューションアーキテクトの伊勢です。

普段はお客様への提案を担当していて開発作業は行わないので、intdash Edge Agent 2(以降、Agent 2)にまだ直接触れられていません。どうやら、Agent 1の課題だった機能群の関係性のわかりやすさが改善されたことにより、設定方法が変わっているようです。

今回はAgent 2のご紹介がてら、具体的に設定作業がどう変わったのか確認していきたいと思います。

docs.intdash.jp

目次

その前に

おことわり

これはあくまで"やってみた"記事です。

正式な手順は各デベロッパーガイドをご参照ください。

Agent 2とは

デベロッパーガイド によれば、以下のとおりです。

intdash Edge Agent 2は、intdashサーバーとの間で時系列データの送受信を行うエージェントソフトウェアです。 エッジデバイス(Linux PC)にインストールして使用します。

intdash Edge Agent 2

エッジデバイスは、カメラやセンサから取得したデータをデバイスコネクター経由でAgentプロセスに流し込みます。 AgentはサーバーのAPIとストリームを張って、データをサーバーにUpstreamします。 また、エッジデバイスへの制御信号をサーバーからDownstreamしてデバイスコネクターに渡します。

Agent 1と何が変わったのか

デバイスコネクターとのインタフェースはこれまでの通り、名前付きパイプであるFIFOファイルです。 また、サーバーとの通信はiSCP v1の後継であるiSCP v2を採用していますが、Agentで隠蔽されるため、利用者が違いを意識することはあまりありません。 なお、実装は開発効率のためにRustとGoを採用しています。

利用者目線で変わった点は機能の再編(分割・追加・名称変更)です。 intdash提供開始から増え続けてきた各種機能の位置付けをゼロベースで見直し、定義しなおしています。

intdash Edge Agent

顕著な変更点はこのようなところです。

  • 設定管理はデーモンが行うようになった
  • 設定情報の形式がJSONからYAMLに変わった(オプションでJSONも指定可能)
  • 設定情報の項目立てが一新した
  • デバイスコネクターをパイプラインとして定義するようになった
  • UpstreamとDownstreamの区別が明確になった

設定周りが多いですね。Agent 1の設定ファイルはAgent 2ではそのまま使えません。

では、どのような設定手順になったのか、Agent 1とAgent 2で比較しながら見ていきましょう。

確認ポイント

典型的な利用ケース、またAgent 1→Agent 2の過渡期にあり得そうなパターンを想定して段階的にセットアップしていきます。

  • Upstreamのセットアップ
    • Agent導入とデバイスコネクター設定
    • フィルタリング設定
  • Downstreamのセットアップ
    • 遠隔指示:Agent 1 → Agent 1
    • 遠隔指示:Agent 2 → Agent 2
    • 遠隔指示:Agent 2 → Agent 1
    • 遠隔指示:Agent 1 → Agent 2

確認用の構成

今回はAgent 1/2とUpstream/Downstreamそれぞれの手順を確認したいため、1台のホストコンピュータに4つのDockerコンテナを立てています。

エッジを4つ用意

比較

Upstream:Agent導入とデバイスコネクター設定

外部デバイスのわかりやすい例としてUSBカメラのUpstreamを設定します。

USBカメラはLogicoolのC920s

Upstream:Agent導入とデバイスコネクター設定 - Agent 1

まずはAgent 1での設定方法のおさらいです。 構成はこのようになります。

Agent 1で映像をUpstream

Dockerコンテナを作成します。

コンテナでデバイスを利用するため --privileged を指定

intdash Edge Agent デベロッパーガイドの2.1 インストールを参考にインストールしていきます。

rootユーザーなのでsudoなしで
エディタとカメラデバイスユーティリティもインストール

Admin Consoleでエッジを作成します。

UUIDとクライアントシークレットをコピー

intdash-edge-managerを起動するときの環境変数が多いので起動用シェルスクリプトを作っておきます。

FQDN・UUID・クライアントシークレットを設定

デフォルト設定で起動するとEdge FinderでUpstreamを確認できます。

Status情報がUpstreamされている

一旦Agentを停止し、カメラ映像のUpstream設定を追加していきます。

ユーティリティでカメラデバイスの設定を確認します。

15FPS・640x480になっている

対応しているカメラなら、プリインストールされたデバイスコネクター(intdash-edge-logger)でAgentへのデータ連携が可能です。 デベロッパーガイドの3.2.1 マネージャーの設定ファイル例(manager.conf)を参考にmanager.confとmjpeg設定ファイルを編集します。

mjpeg設定ファイルパス・チャンネル・解像度を設定

再度、起動用シェルスクリプトで起動。

引数の設定ファイルパスを変更
Edge FinderでJPEGのUpsteramが確認できました。
1秒に15枚受信

このあと別のコンテナでカメラデバイスを使うため、Agentを停止しておきます。

Upstream:Agent導入とデバイスコネクター設定 - Agent 2

では、いよいよAgent 2を導入してみます。 構成はこのようになります。

Agent 2で映像をUpstream

Dockerコンテナを作成し、intdash Edge Agent 2 デベロッパーガイドを参考に進めていきます。

Agent 1と同じよう流れ

Agent 1と違ってデフォルトの設定ファイルがあるわけではありません。 実際にやって覚えるにはデベロッパーガイドのチュートリアルを進めるのがいいのですが、ここは比較のために映像のアップストリームを設定してみましょう。

なお、Dockerではsystemdでデーモンが自動起動しないため、デーモンを手動で起動します。

デーモン(intdash-agentd)を起動

Upstreamを設定します。カメラデバイスは設定レシピ集の7.2. カメラからV4L2経由で取得したJPEGデータを送信するにそのままの手順があります。これを参考にします。

アップストリームデバイスコネクターを設定します。 Agent 1のmanager.confloggers(mjpeg設定ファイルパス・チャンネル・解像度を設定したセクション)にあたる部分ですね。

iSCP v2にはチャンネルchannelという概念はありません。しかしここでは、互換ルールに沿ってiSCP v2のデータをiSCP v1のチャンネル1として扱えるようにするため、データ名称プリフィックスdata_name_prefixv1/1/を指定します。また、Agent 1と同じくカメラデバイスにあわせて解像度・FPSを設定します。

解像度・FPSは環境変数でデバイスコネクターに渡る

続いてデバイスコネクターのパイプラインを設定します。Agent 1のmjpeg設定ファイルの部分にあたります。 Agent1では/opt/vm2m/sbin/intdash-edge-loggerの中に隠蔽されていた、デバイス入力〜フォーマット変換〜FIFO出力の流れを定義します。Agent 2の付属デバイスコネクターの特長としてこのパイプラインの仕組みによりタスクの柔軟な定義が可能になっています。

入力→中間処理→出力

環境変数から解像度・FPSを取得

接続設定を行います。Agent 1ではintdash-edge-manager起動時に環境変数で指定した部分です。このコンテナ用のUUIDとクライアントシークレットをAdmin Consoleで払い出し、設定します。

FQDN・UUID・クライアントシークレットを設定

最後にストリーマーを起動します。 パイプラインに含まれるprint-log-filterのログが出力されます。 ログレベルは起動時に設定することができます。

デバイスコネクターへの入力データ量がわかる
こちらもEdge Finderで確認

Agent 2のintdash-agentctlコマンドだと設定時にフォーマットエラーに気づくことができるため、セットアップ作業の効率が上がりそうです。

Upstream:フィルタリング設定

送信データ量を間引くフィルタリングの代表例として、一定時間に1データポイントに絞るサンプリングの違いを見てみます。 Agent 1/2ともにデバイスコネクターの出力に対して定義します。

Upstream:フィルタリング設定 - Agent 1

Agent 1ではsampling フィルターで設定します。

サンプリング間隔の最初のデータポイントをパス

manager.confmanager.filtersセクションを編集します。

1000ミリ秒間に1データポイントに絞る

起動用シェルスクリプトを実行すると間引きされているのを確認できます。

1秒に1枚受信

Upstream:フィルタリング設定 - Agent 2

Agent 2ではsamplingタイプのフィルターを設定します。

考え方は同じ

はじめに、デバイスコネクターからのデータの行先を、recoverableではなくsrc_jpegに変更します。ただしsrc_jpegというストリームは存在しせんので、このあとサンプリングフィルターを経ても行先がsrc_jpegのままになっているデータは破棄されることになります。

デバイスコネクターの入力元IDを変更

フィルターを定義します。src_jpegに対してサンプリングした結果をrecoverableに出力します。

targetがフィルターの入力・change_toが出力

ストリーマーを起動すると間引きされているのを確認できます。

1秒に1枚受信

Agent 2のサンプリングはH.264形式に対応しています。確認してみましょう。

H.264は前フレームとの差分データによる動画圧縮規格のため、サンプリングするとリアルタイム再生はできません。JPEG以外にもサンプリングが効くことを確認するために実施しています。(遅延アップロードにより、全データポイントが回収されたあとは動画として再生が可能です。)

まずはカメラデバイスの設定を変更します。FPSは15のままです。

解像度・フォーマットを変更

デバイスコネクターの設定を新たに設定します。

カメラデバイス設定を反映

H.264用のパイプライン設定ファイルを作成します。

MJPEGのときに5つだったエレメントが4つになっています。 id: 2h264-split-filterの出力はiscp-v2-compat-msgなので、iscp-v2-compat-filterが不要なためです。

前処理の出力形式により必要なエレメントは異なる

デバイスコネクターにあわせて、フィルターの入力元IDとデータ型名も変更します。

jpegをh264に変更

ストリーマーを起動するとEdge Finderで1秒間に1回の受信を確認できます。

H.264は画面下部がバイト表示

Downstreamのセットアップ

ダウンストリームの典型例として、別のエッジの送信データをサーバー経由で受信します。 Agent 2同士のほか、Agent 1/2間での送受信の設定方法も確認してみたいと思います。

遠隔指示:Agent 1 → Agent 1

では、まずこれもAgent 1同士の手順を確認しておきます。

構成はこのようになります。

Agent 1からAgent 1にStringを送信

送信側の設定として先ほど作成したコンテナagent1upにチャンネルを追加します。 デベロッパーガイド 4.1 独自のデバイスコネクターを使用するための設定 を参考に進めます。

デバイスコネクター起動なし

起動用シェルスクリプトでAgentを起動します。

手っ取り早く送信するため、別ターミナルで同コンテナに入り、FIFOファイルにpython3のstruct.packの結果をリダイレクトします。

python3 -c "import struct, sys, time; s, n = divmod(time.clock_gettime(time.CLOCK_MONOTONIC_RAW), 1); sys.stdout.buffer.write(struct.pack('<BBBBLLBBB7s8s', 1, 26, 0, 0, int(s), int(n * 1_000_000_000), 0x1d, 0, 7, b'command', b'message1'))" > /var/run/intdash/logger_002.tx

フォーマットは6.5 Agent とデバイスコネクターの間で使われる FIFO のデータフォーマット、の6.5.1 共通ヘッダー、6.5.2 データタイプごとの固有部分に従っています。

タイムスタンプ(Time Sec、Time nano)は基準時刻以前だとAgentで受け付けないため、time.clock_gettime(time.CLOCK_MONOTONIC_RAW)で現在時刻を取得・計算しています。 Time Sec以降のデータサイズであるLength(第3引数26)の計算が結構面倒ですね。

任意のメッセージをFIFOにリダイレクト

Edge Finderでサーバーでの受信を確認します。

リダイレクトのたびに受信

次に受信側のエッジを構築します。Dockerでコンテナを作成して、送信側と同様にAgentをインストールします。

受信側では --privileged 不要

エディタもインストール

4.3 FIFO からの読み出しを参考にしてmanager.confにDownstream設定を追加します。"clients""type": "control"でこれがDownstreamであることを定義しています。 Downstreamの場合、送信元 EdgeのUUIDの設定が必要です。複数のエッジ(2つまで)を設定できるctlr_idsが利用できます。

clientsとloggersに設定を追加

Admin Consoleで受信側エッジのUUIDを新たに払い出し、起動用シェルスクリプトを作成しておきます。

FQDN・UUID・クライアントシークレットを設定

送信側・受信側それぞれで起動用シェルスクリプトを起動し、別ターミナルで受信側に入り、FIFOファイルをcatコマンドで監視しておきます。送信側でさきほどのリダイレクトを再度実行します。

catコマンドの結果で、送信側でリダイレクトしたアスキー文字項目(データID、データ)を確認できます。 odコマンドなどでバイトデータとして確認してもいいでしょう。

送信側のリダイレクトとほぼ同時に出力される

遠隔指示:Agent 2 → Agent 2

では、続いてAgent 2で同様の構成を設定してみます。

構成はこうです。

Agent 2からAgent 2にStringを送信

送信側の設定をコンテナagent2upに追加します。 デベロッパーガイド 4.1. アップストリームの設定を作成/変更する を参考に進めます。

フィルタリングが適用されているカメラ映像とは別にストリームを新規作成します。また、デバイスコネクター設定も作成しますが、Agent 1と同様にリダイレクトでFIFOファイルに書き込むため、パイプラインは作成しません。

新ストリームとデバイスコネクター設定を作成

Agent 1では送信・受信のFIFO(logger_XXX.txlogger_XXX.rx)をセットで定義していましたが、Agent 2では必要なデバイスコネクター設定に対して1つずつFIFOファイルを設定しています。

intdash-agentctl runでストリーマーを起動します。

別ターミナルでコンテナagent2upに入り、FIFOファイルにpython3のstruct.packの結果をリダイレクトします。

python3 -c "import struct, sys, time; s, n = divmod(time.clock_gettime(time.CLOCK_MONOTONIC_RAW), 1); sys.stdout.buffer.write(struct.pack('<LLHHL6s7s8s', int(s), int(n * 1_000_000_000), 6, 7, 8, b'string', b'command', b'message1'))" > /var/run/intdash/uplink-command.fifo

Agent 2ではフォーマットがAgent 1とは異なります。

5. intdash Edge Agent 2とデバイスコネクターの間で使われるFIFO用データフォーマットを参考にしています。複数項目のデータ長の合計項目がなくなったため、Agent 1よりバイト数指定が楽になりました。

リダイレクトのたびに受信

では、Agent 2でも受信側のエッジを構築します。Dockerでコンテナを作成して、送信側と同様にAgentをインストールします。

このくだりはもう慣れたもの

Downstreamとデバイスコネクターを設定していきます。

Downstreamとデバイスコネクター設定

受信側エッジagent2downをAdmin Consoleで払い出し、接続を設定します。

こちらも慣れたもの

/etc/init.d/intdash-agentd startでストリーマーを起動します。

起動直後

送信側でもストリーマーを起動します。別ターミナルで受信側に入り、FIFOファイルをcatコマンドで監視しておきます。 送信側でさきほどのリダイレクトを再度実行します。

送信側のリダイレクトとほぼ同時に出力される

Agent 2用のフォーマットで出力されているのがわかります。

遠隔指示:Agent 2 → Agent 1

次はAgent 1/2併用を想定した遠隔指示の設定を確認してみます。 Agent 1/2双方のデータを受け取れるように受信側に設定を追加します。まずはAgent 1から。

どこからどこに送信しているのかこんがらがってきますが構成はこちらです。

Agent 2からAgent 1にStringを送信

Agent 2には4.3. iSCP v1と互換性を持たせるためのデータ名称が用意されています。実は本記事はこれに則り、データ名称をv1/<チャンネル>で始めていますので、設定は最低限で済みます。

コンテナagent1downmanager.confctlr_idsに、コンテナagent2upのUUIDを追加します。チャンネル/データ名称接頭辞、データID、データタイプは今回あわせてあるため、修正不要です。

送信側のUUIDを追加

コンテナagent2upのストリーマー、コンテナagent1downの起動用シェルスクリプトを起動し、agent1downのFIFOをcatしておきます。 agent2upでFIFOにメッセージをリダイレクトします。

Agent 2から送られたデータが、Agent 1→Agent 1のときと同じく、Agent 1形式で出力されているのがわかります。

Agent 2のメッセージをAgent 1形式で出力

遠隔指示:Agent 1 → Agent 2

最後は、Agent 2の受信側にAgent 1の設定を追加します。

構成はこちらです。

Agent 1からAgent 2にStringを送信

コンテナagent2downにDownstream設定を追加します。

Downstreamのsrc_edge_uuidとしてagent1upのUUIDを追加しています。

filters 配下に複数の送信側エッジを設定可能

コンテナagent1upの起動用シェルスクリプト、コンテナagent2downのストリーマーを起動し、agent2downのFIFOをcatしておきます。 agent1upでFIFOにメッセージをリダイレクトします。

Agent 1のメッセージをAgent 2形式で出力

このように、Agent 2はフォーマットが違うAgent 1とも送受信ができるよう、互換性を備えています。

まとめ

長々とお付き合いありがとうございました。

Agent 1では、Agent起動とストリーム開始、UpstreamとDownstream、それにデバイスコネクター内の各処理が、一緒くたになっていて構築・運用しづらい面がありました。

Agent 2では、これらがきちんと意味合いごとに整理・分離され、個別の管理項目として再定義されたことで構造が理解しやすく、取り回ししやすくなりました。

今回はご紹介しきれませんでしたが、Agent 2には遅延アップロード(Agent 1の再送)などの機能があります。ぜひ実際にお使いいただき、intdashの低遅延性・操作性を体感いただければと思います。

また、Agent以外にもaptpodのプロダクトはブラッシュアップしていきますので、今後もお伝えしていきたいと思っています。

Appendix:設定情報

参考までに最終的な設定情報を掲載します。

Agent 2設定はデベロッパーガイド12. 設定を書き出す/読み込むの出力結果です。

全体像を再掲

コンテナ agent1up

/root/manager.conf
{
  "manager": {
    "meas_root": "$APPDIR/intdash/meas",
    "meas_root_volatile": "$RUNDIR/intdash/meas",
    "rawdir": "$APPDIR/intdash/raw",
    "basetime": "$RUNDIR/intdash/basetime",
    "stat": "$RUNDIR/intdash/manager.stat",
    "logger_stat": "$RUNDIR/intdash/logger_%03hhu.stat",
    "process_stat": "$RUNDIR/intdash/process.stat",
    "intdash_stat": "$RUNDIR/intdash/intdash.stat",
    "network_stat": "$RUNDIR/intdash/network.stat",
    "system_stat": "$RUNDIR/intdash/system.stat",
    "wwan_stat": "$RUNDIR/intdash/wwan.stat",
    "workdirs": [
      "$APPDIR/intdash/meas",
      "$RUNDIR/intdash"
    ],
    "filters": [
      {
        "name": "sampling",
        "channel": "1",
        "target": "realtime",
        "setting": [
          {
            "key": "rate",
            "value": "1000"
          }
        ]
      }
    ]
  },
  "clients": [
    {
      "protocol": "mod_websocket.v2",
      "type": "realtime",
      "my_token": "$TOKEN",
      "my_id": "$UUID",
      "my_secret": "$SECRET",
      "auth_path": "$APPDIR/intdash/.auth",
      "project_uuid": "",
      "connection": {
        "host": "$SERVER",
        "path": "/api/v1/ws/measurements"
      },
      "fifo_rx": "$RUNDIR/intdash/client_%s.rx",
      "fifo_tx": "$RUNDIR/intdash/client_%s.tx",
      "path": "$SBINDIR/intdash-edge-client",
      "stat": "$RUNDIR/intdash/client_%s.stat",
      "fast_net_check_cmd":"$BINDIR/intdash-edge-networkd.sh -q -t"
    },
    {
      "protocol": "mod_http",
      "type": "resend",
      "my_token": "$TOKEN",
      "my_id": "$UUID",
      "my_secret": "$SECRET",
      "project_uuid": "",
      "auth_path": "$APPDIR/intdash/.auth",
      "connection": {
        "host": "$SERVER",
        "path": "/api/v1/measurements"
      },
      "fifo_rx": "$RUNDIR/intdash/client_%s.rx",
      "fifo_tx": "$RUNDIR/intdash/client_%s.tx",
      "path": "$SBINDIR/intdash-edge-client",
      "stat": "$RUNDIR/intdash/client_%s.stat",
      "fast_net_check_cmd":"$BINDIR/intdash-edge-networkd.sh -q -t"
    }
  ],
  "loggers": [
    {
      "path": "",
      "connections": [
        {
          "channel": 255,
          "fifo_rx": "$RUNDIR/intdash/logger_XXX.rx",
          "fifo_tx": "$RUNDIR/intdash/logger_XXX.tx"
        }
      ],
      "details": {
        "plugin": "status",
        "plugin_dir": "$LIBDIR/plugins",
        "plugin_arg": {
          "stintd": {
            "meas_root": "$RUNDIR/intdash/meas"
          },
          "stsys": {
            "storage_dir": "/"
          }
        }
      }
    },
    {
      "path": "/opt/vm2m/sbin/intdash-edge-logger",
      "conf": "/root/logger.conf.mjpeg",
      "connections": [
        {
          "channel": 1,
          "fifo_rx": "$RUNDIR/intdash/logger_001.rx",
          "fifo_tx": "$RUNDIR/intdash/logger_001.tx"
        }
      ]
    },
    {
      "connections": [
        {
          "channel": 2,
          "fifo_rx": "$RUNDIR/intdash/logger_002.rx",
          "fifo_tx": "$RUNDIR/intdash/logger_002.tx"
        }
      ],
      "details": {
        "plugin": "fifo"
      }
    }
  ]
}
/root/logger.conf.mjpeg
{
  "type": "mjpeg",
  "data_handler": {
    "path": "/dev/video0",
    "baudrate": 15,
    "camera_width": 640,
    "camera_height": 480,
    "camera_hwencodedelay_msec": 100
  },
  "manager_client": {
    "tx_path": "/var/run/intdash/logger_001.tx",
    "rx_path": "/var/run/intdash/logger_001.rx"
  },
  "status": "/var/run/intdash/logger_001.stat",
  "basetime": "/var/run/intdash/basetime"
}

コンテナ agent2up

intdash-agentd config show
connection:
  server_url: https://xxx.intdash.jp
  project_uuid: 00000000-0000-0000-0000-000000000000
  edge_uuid: 84db287d-d763-4b40-a9a2-2d2824a8b803
  client_secret: xxx
transport:
  protocol: websocket
upstream:
- id: recoverable
  enabled: true
  recover: true
  persist: true
  qos: unreliable
  flush_policy: interval
  flush_interval: 5
- id: recoverable2
  enabled: true
  recover: true
  persist: true
  qos: unreliable
  flush_policy: interval
  flush_interval: 5
downstream: []
device_connectors_upstream:
- id: h264
  data_name_prefix: v1/1/
  dest_ids:
  - src_h264
  enabled: true
  format: iscp-v2-compat
  ipc:
    type: fifo
    path: /var/run/intdash/h264.fifo
  launch:
    cmd: device-connector-intdash
    args:
    - --config
    - /etc/dc_conf/h264-up.yml
    environment:
    - DC_V4L2_SRC_CONF_PATH=/dev/video0
    - DC_V4L2_SRC_WIDTH=1920
    - DC_V4L2_SRC_HEIGHT=1080
    - DC_V4L2_SRC_FPS=15
    - DC_PRINT_LOG_FILTER_CONF_TAG=h264
    - DC_FILE_SINK_CONF_PATH=/var/run/intdash/h264.fifo
- id: command
  data_name_prefix: v1/2
  dest_ids:
  - recoverable2
  enabled: true
  format: iscp-v2-compat
  ipc:
    type: fifo
    path: /var/run/intdash/uplink-command.fifo
device_connectors_downstream: []
filters_upstream:
- id: sampling
  enabled: true
  type: sampling
  target:
    dest_ids:
    - src_h264
    interval_ms: 1000
    name: ""
    src_id: ""
    type: h264
  change_to:
    dest_id: recoverable
filters_downstream: []
deferred_upload:
  priority: same_as_realtime
  limit_data_storage: true
  data_storage_capacity: 102400
/etc/dc_conf/jpeg-up.yml
tasks:
  - id: 1
    element: v4l2-src
    conf:
      path: $(DC_V4L2_SRC_CONF_PATH)
      type: jpeg
      width: $(DC_V4L2_SRC_WIDTH)
      height: $(DC_V4L2_SRC_HEIGHT)
      fps: $(DC_V4L2_SRC_FPS)

  - id: 2
    element: jpeg-split-filter
    from: [ [1] ]

  - id: 3
    element: iscp-v2-compat-filter
    from: [ [2] ]
    conf:
      timestamp:
        stamp:
          clock_id: CLOCK_MONOTONIC
      convert_rule: jpeg

  - id: 4
    element: print-log-filter
    from: [ [3] ]
    conf:
      interval_ms: 10000
      tag: $(DC_PRINT_LOG_FILTER_CONF_TAG)
      output: stderr

  - id: 5
    element: file-sink
    from: [ [4] ]
    conf:
      flush_size: 100
      path: $(DC_FILE_SINK_CONF_PATH)
/etc/dc_conf/h264-up.yml
tasks:
  - id: 1
    element: v4l2-src
    conf:
      path: $(DC_V4L2_SRC_CONF_PATH)
      type: h264
      width: $(DC_V4L2_SRC_WIDTH)
      height: $(DC_V4L2_SRC_HEIGHT)
      fps: $(DC_V4L2_SRC_FPS)

  - id: 2
    element: h264-split-filter
    from: [ [1] ]
    conf:
      clock_id: CLOCK_MONOTONIC

  - id: 3
    element: print-log-filter
    from: [ [2] ]
    conf:
      interval_ms: 10000
      tag: $(DC_PRINT_LOG_FILTER_CONF_TAG)
      output: stderr

  - id: 4
    element: file-sink
    from: [ [3] ]
    conf:
      flush_size: 100
      path: $(DC_FILE_SINK_CONF_PATH)

コンテナ agent1down

/root/manager.conf
{
  "manager": {
    "meas_root": "$APPDIR/intdash/meas",
    "meas_root_volatile": "$RUNDIR/intdash/meas",
    "rawdir": "$APPDIR/intdash/raw",
    "basetime": "$RUNDIR/intdash/basetime",
    "stat": "$RUNDIR/intdash/manager.stat",
    "logger_stat": "$RUNDIR/intdash/logger_%03hhu.stat",
    "process_stat": "$RUNDIR/intdash/process.stat",
    "intdash_stat": "$RUNDIR/intdash/intdash.stat",
    "network_stat": "$RUNDIR/intdash/network.stat",
    "system_stat": "$RUNDIR/intdash/system.stat",
    "wwan_stat": "$RUNDIR/intdash/wwan.stat",
    "workdirs": [
      "$APPDIR/intdash/meas",
      "$RUNDIR/intdash"
    ],
    "filters": []
  },
  "clients": [
    {
      "protocol": "mod_websocket.v2",
      "type": "realtime",
      "my_token": "$TOKEN",
      "my_id": "$UUID",
      "my_secret": "$SECRET",
      "auth_path": "$APPDIR/intdash/.auth",
      "project_uuid": "",
      "connection": {
        "host": "$SERVER",
        "path": "/api/v1/ws/measurements"
      },
      "fifo_rx": "$RUNDIR/intdash/client_%s.rx",
      "fifo_tx": "$RUNDIR/intdash/client_%s.tx",
      "path": "$SBINDIR/intdash-edge-client",
      "stat": "$RUNDIR/intdash/client_%s.stat",
      "fast_net_check_cmd":"$BINDIR/intdash-edge-networkd.sh -q -t"
    },
    {
      "protocol": "mod_http",
      "type": "resend",
      "my_token": "$TOKEN",
      "my_id": "$UUID",
      "my_secret": "$SECRET",
      "project_uuid": "",
      "auth_path": "$APPDIR/intdash/.auth",
      "connection": {
        "host": "$SERVER",
        "path": "/api/v1/measurements"
      },
      "fifo_rx": "$RUNDIR/intdash/client_%s.rx",
      "fifo_tx": "$RUNDIR/intdash/client_%s.tx",
      "path": "$SBINDIR/intdash-edge-client",
      "stat": "$RUNDIR/intdash/client_%s.stat",
      "fast_net_check_cmd":"$BINDIR/intdash-edge-networkd.sh -q -t"
    },
    {
      "protocol": "mod_websocket.v2",
      "type": "control",
      "my_id": "$UUID",
      "my_secret": "$SECRET",
      "project_uuid": "",
      "auth_path": "$APPDIR/intdash/.auth",
      "connection": {
        "host": "$SERVER",
        "path": "/api/v1/ws/measurements"
      },
      "fifo_rx": "$RUNDIR/intdash/client_%s.rx",
      "fifo_tx": "$RUNDIR/intdash/client_%s.tx",
      "path": "$SBINDIR/intdash-edge-client",
      "stat": "$RUNDIR/intdash/client_%s.stat",
      "down_dst_id": "00000000-0000-0000-0000-000000000000",
      "ctlr_ids": [
        "e5e156b5-35f3-40ec-9993-8d6d812428c9",
        "84db287d-d763-4b40-a9a2-2d2824a8b803"
      ],
      "ctlr_flts":[
        {
          "channel": 2,
          "dtype": 10,
          "ids": ["command"]
        }
      ]
    }
  ],
  "loggers": [
    {
      "path": "",
      "connections": [
        {
          "channel": 255,
          "fifo_rx": "$RUNDIR/intdash/logger_XXX.rx",
          "fifo_tx": "$RUNDIR/intdash/logger_XXX.tx"
        }
      ],
      "details": {
        "plugin": "status",
        "plugin_dir": "$LIBDIR/plugins",
        "plugin_arg": {
          "stintd": {
            "meas_root": "$RUNDIR/intdash/meas"
          },
          "stsys": {
            "storage_dir": "/"
          }
        }
      }
    },
    {
      "path": "",
      "connections": [
        {
          "channel": 2,
          "channel_rx": -1,
          "receive_basetime": true,
          "fifo_rx": "$RUNDIR/intdash/logger_002.rx",
          "fifo_tx": "$RUNDIR/intdash/logger_002.tx"
        }
      ],
      "details": {
        "plugin": "fifo"
      }
    }
  ]
}

コンテナ agent2down

intdash-agentd config show
connection:
  server_url: https://xxx.intdash.jp
  project_uuid: 00000000-0000-0000-0000-000000000000
  edge_uuid: 7e340e6a-ad9f-49d7-8e20-0694d906bbd8
  client_secret: xxx
transport:
  protocol: websocket
upstream: []
downstream:
- id: down
  enabled: true
  dest_ids:
  - src_command
  filters:
  - src_edge_uuid: 84db287d-d763-4b40-a9a2-2d2824a8b803
    data_filters:
    - type: string
      name: v1/2/command
  - src_edge_uuid: e5e156b5-35f3-40ec-9993-8d6d812428c9
    data_filters:
    - type: string
      name: v1/2/command
device_connectors_upstream: []
device_connectors_downstream:
- id: src_command
  enabled: true
  format: iscp-v2-compat
  ipc:
    type: fifo
    path: /var/run/intdash/downlink-command.fifo
filters_upstream: []
filters_downstream: []
deferred_upload:
  priority: same_as_realtime
  limit_data_storage: true
  data_storage_capacity: 102400