こんにちは。CData Software Japan リードエンジニアの杉本です。
今回の記事ではAI ネットワークカメラi-PRO とCData Arc・Tableau を組み合わせたデータ分析の方法を紹介します。
AI ネットワークカメラi-PRO とは?
パナソニック コネクト株式会社が販売するAIプロセッサーを搭載したネットワークカメラです。
https://connect.panasonic.com/jp-ja/products-services_security_networkcamera_ai

入退室の人数カウントや混雑検知、動体検知の機能が備わっており、監視・防犯システム的な使い方はもちろん、以下の事例のような来店客数カウントを駆使したマーケティング分析での活用も行われています。
https://cdn.shopify.com/s/files/1/0614/7332/5238/files/e__fin.pdf

また、i-PRO は他のシステム・サービスと連携するための、API・Webhook の機能が充実しているため、検知したデータを他のサービスと組み合わせて利活用することが可能です。
とはいえ、実際の連携のためにはある程度プログラミングやネットワークの知識が欠かせません。
そこで本記事では、ローコードでデータ処理の自動化を実現することが可能なCData Arc とデータ分析・BI ツールのTableau と組み合わせてノンプログラミングで検知データの可視化を行う方法を解説します。
https://jp.cdata.com/arc/

シナリオ
最初に今回のシナリオ、構成について解説しておきます。
前述の通り、i-PRO には「一定のラインを通り過ぎた人数などのカウントデータ」などをHTTP(Webhook)で他システムに通知することができる機能があります。

この通知データをCData Arc で受け取り、適切なフォーマットに変換して、MySQLに格納します。
CData Arc にはデフォルトでWebhook を受信するためのコネクタが含まれており、今回のような自動化を行う場合には使いやすいツールとなっています。
なお、CData Arcとネットワークカメラは同一ネットワーク上で、HTTP通信が相互に実施できる環境にある前提としています。
ネットワークカメラは 192.168.1.100、CData Arc は192.168.1.4 に配置、MySQL・Tableau はCData Arc と同じマシンにインストールしています。

その後、その格納されたデータを対象としてBI ツールのTableau で可視化します。

なお、今回はデータの格納先として入手しやすいRDB であるMySQL を採用しましたが、これは例えばkintone やSalesforce などのクラウドサービスなどでも構いません。
https://jp.cdata.com/drivers/

対象製品
今回は以下のAI カメラを利用しました。
https://cwc.i-pro.com/collections/all/products/wv-s4176ux

また、予め「i-PRO設定ツール」をCData Arc のマシンにインストールしておきましょう。
事前準備:CData Arc 製品のインストールとナレッジ
ネットワークカメラと併せて、事前にCData Arc を任意の環境にインストールしておきます。
以下のリンクから30日間のトライアルが取得できます。
https://arc.cdata.com/jp/trial/
CData Arc のインストールはこちらを参考にしてください。
https://jp.cdata.com/blog/arcesb-install-windows
CData Arc を使い始めるときは、こちらも参考にしてください。
https://arc.cdata.com/jp/start/
CData Arc に関するナレッジは、こちらにまとめています。あわせて参考にしてください。 https://arc.cdata.com/jp/kb/
事前準備:MySQLのテーブル構成
データの格納先となるMySQL には以下のようなテーブルを予め構成しておきました。取り込むデータの内容に応じて随時調整してください。
CREATE TABLE `cameralog` (
`Id` int NOT NULL AUTO_INCREMENT,
`CameraIPaddress` varchar(45) DEFAULT NULL,
`CameraMACaddress` varchar(45) DEFAULT NULL,
`Time` datetime DEFAULT NULL,
`In` int DEFAULT NULL,
`Out` int DEFAULT NULL,
PRIMARY KEY (`Id`),
UNIQUE KEY `Id_UNIQUE` (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

連携フローの作成
それでは実際に連携フローを作成していきます。 このシナリオで作成する連携フローは以下のような流れになっています。
|
コネクタ
|
内容
|
設定内容
|
|
1
|
Webhook
|
ネットワークカメラからのHTTP通知を受信するためのコネクタです。
|
|
2
|
Script
|
受信したJSONの結果をCData Arc が処理しやすいXMLのフォーマットに変換します。
|
|
3
|
XML Map
|
前処理のXMLデータをMySQLのテーブル構造にマッピングします。
|
|
4
|
MySQL
|
MySQL にデータを書き込む処理を行います。
|

今回作成したCData Arc のフローはサンプルテンプレートとして、以下のURL にアップしています。ぜひ皆さんの環境にインポートして、カスタマイズしながら使ってみてください。
https://cdatajwrk.s3.ap-northeast-1.amazonaws.com/arcflow_template/i-PRO_MySQL.arcflow
Webhook の構成およびi-PRO との連携設定
さて、まず最初に一番重要となるWebhook コネクタとi-PROの設定を進めます。
i-PROからはHTTPリクエストが飛んでくるので、そのデータを受信するために、CData Arc のWebhook コネクタを利用します。

Webhook コネクタを配置すると、以下のようにエンドポイントが構成されます。併せてリクエストのサンプルもJSONフォーマットとして入力しておきましょう。(これは一度テストで受信した後に設定しても構いません。)

Webhook のエンドポイントはBasic 認証がかかっているため、予め認証を行うユーザーを作成しておく必要があります。
「ユーザー」タブに移動して「+追加」をクリックし

POSTの権限を持つ、任意のユーザーを作成しておきます。ここで生成される認証トークンは後ほど利用するので控えておきましょう。

続いて、i-PROのネットワークカメラからの通信を許可するために、信頼されたIPアドレスにネットワークカメラのIPアドレスを追加しておきます。

合わせてFirewallの設定としても、8001ポートの受信を許可する設定を追加しておきましょう。
i-PRO設定ツールでHTTP通知設定の追加
Webhook のエンドポイントが構成できたら、i-PRO 設定ツールでHTTP通知の設定を追加します。
「i-PRO 設定ツール」を立ち上げて、対象のネットワークカメラの設定画面に移動します。

共通設定(AI-VMD・AI人数カウント)で「カウントデータHTTP追加通知先」の設定を追加します。
|
プロパティ名
|
設定値例
|
備考
|
|
通知先アドレス
|
192.168.1.4
|
CData Arc がインストールされたマシンのIPアドレスを指定します。
|
|
通知先パス名
|
/connector/PanasonicConnect/Webhook1/webhook.rsb
|
Webhook のエンドポイントのIPアドレス以降を指定します。
|
|
SSL
|
OFF
|
CData Arc でSSL を有効にしている場合は必要になります。
|
|
通知先ポート番号
|
8001
|
|
|
ユーザー名
|
admin
|
Webhook コネクタの設定で追加したユーザーのIDを指定します。
|
|
パスワード
|
Webhookの認証トークン
|
Webhook コネクタの設定で追加したユーザーの認証トークンを指定します。
|
|
通知間隔
|
5min
|
|
入力後、設定を保存しましょう。

これで正常に疎通ができていると、以下のようにWebhook コネクタの「アウトプット」タブでネットワークカメラのデータが受信されてきます。

Script コネクタの設定
Webhook で受信したデータはそのままではCData Arc では扱いづらいフォーマットのため、一度Script コネクタを介して、データを扱いやすいフォーマットに変換します。

このScript コネクタを解することで
左のようなJSON データのフォーマットから、階層構造がわかりやすい右のXMLフォーマットに変換できます。

Script コネクタはArc Script と呼ばれる独自のスクリプト言語を利用することで利用できます。
こちらで利用しているArc Script について詳しく知りたい方は、ぜひ以下の記事も参考にしてください。
https://arc.cdata.com/jp/kb/articles/arcscript-quickstart.rst
今回は以下のサンプルスクリプトを利用して、接続してみてください。
<!-- NOTE: Do not edit arc:info -->
<arc:info title="Custom Script" desc="This script will be executed when a file is processed.">
<input name="ConnectorId" desc="The id of this connector." type="text" />
<input name="WorkspaceId" desc="The workspace of this connector." type="text" />
<input name="MessageId" desc="The message id." type="text" />
<input name="FilePath" desc="The path of the file being processed." type="text" />
<input name="FileName" desc="The name of the file being processed." type="text" />
<input name="Attachment#" desc="The path of the attachment being processed." type="text" />
<input name="Header:*" desc="The message headers of the file being processed." type="text" />
<output name="Data" desc="The data that will be written to the file in the Receive folder."></output>
<output name="Encoding" desc="The encoding that will be used to write the file in the Receive folder."></output>
<output name="FileName" desc="The name of the output file in Receive folder."></output>
<output name="FilePath" desc="The path of file that will be written to Receive folder."></output>
<output name="Header:*" desc="The message headers of the file being written."></output>
</arc:info>
<!-- Code goes here -->
<arc:set attr="output.FileName" value="[FileName | replace('.json','.xml')]"></arc:set>
<arc:set attr="output.encoding" value="UTF-8"></arc:set>
<arc:set attr="json.uri" value="[FilePath]"></arc:set>
<arc:set attr="json.map:CameraIPaddress" value="/json/CameraIPaddress">
<arc:set attr="json.map:CameraMACaddress" value="/json/CameraMACaddress">
<arc:set attr="json.map:Time" value="/json/Time">
<arc:set attr="json.map:TimeZone" value="/json/TimeZone">
<arc:set attr="json.map:SummerTime" value="/json/SummerTime">
<arc:set attr="json.map:time_1" value="/json/ALL/\[1\]/list/\[1\]/\[1\]">
<arc:set attr="json.map:in_1" value="/json/ALL/\[1\]/list/\[1\]/\[2\]">
<arc:set attr="json.map:out_1" value="/json/ALL/\[1\]/list/\[1\]/\[3\]">
<arc:set attr="json.map:time_2" value="/json/ALL/\[1\]/list/\[2\]/\[1\]">
<arc:set attr="json.map:in_2" value="/json/ALL/\[1\]/list/\[2\]/\[2\]">
<arc:set attr="json.map:out_2" value="/json/ALL/\[1\]/list/\[2\]/\[3\]">
<arc:set attr="json.map:time_3" value="/json/ALL/\[1\]/list/\[3\]/\[1\]">
<arc:set attr="json.map:in_3" value="/json/ALL/\[1\]/list/\[3\]/\[2\]">
<arc:set attr="json.map:out_3" value="/json/ALL/\[1\]/list/\[3\]/\[3\]">
<arc:set attr="json.map:time_4" value="/json/ALL/\[1\]/list/\[4\]/\[1\]">
<arc:set attr="json.map:in_4" value="/json/ALL/\[1\]/list/\[4\]/\[2\]">
<arc:set attr="json.map:out_4" value="/json/ALL/\[1\]/list/\[4\]/\[3\]">
<arc:set attr="json.map:time_5" value="/json/ALL/\[1\]/list/\[5\]/\[1\]">
<arc:set attr="json.map:in_5" value="/json/ALL/\[1\]/list/\[5\]/\[2\]">
<arc:set attr="json.map:out_5" value="/json/ALL/\[1\]/list/\[5\]/\[3\]">
<arc:call op="jsonDOMGet" in="json" out="result">
<arc:set attr="output.Data">
<!--?xml version="1.0" encoding="UTF-8"?-->
<items>
<item>
<cameraipaddress>[result.CameraIPaddress]</cameraipaddress>
<cameramacaddress>[result.CameraMACaddress]</cameramacaddress>
<time>[result.time_1]</time>
<in>[result.in_1]</in>
<out>[result.out_1]</out>
</item>
<item>
<cameraipaddress>[result.CameraIPaddress]</cameraipaddress>
<cameramacaddress>[result.CameraMACaddress]</cameramacaddress>
<time>[result.time_2]</time>
<in>[result.in_2]</in>
<out>[result.out_2]</out>
</item>
<item>
<cameraipaddress>[result.CameraIPaddress]</cameraipaddress>
<cameramacaddress>[result.CameraMACaddress]</cameramacaddress>
<time>[result.time_3]</time>
<in>[result.in_3]</in>
<out>[result.out_3]</out>
</item>
<item>
<cameraipaddress>[result.CameraIPaddress]</cameraipaddress>
<cameramacaddress>[result.CameraMACaddress]</cameramacaddress>
<time>[result.time_4]</time>
<in>[result.in_4]</in>
<out>[result.out_4]</out>
</item>
<item>
<cameraipaddress>[result.CameraIPaddress]</cameraipaddress>
<cameramacaddress>[result.CameraMACaddress]</cameramacaddress>
<time>[result.time_5]</time>
<in>[result.in_5]</in>
<out>[result.out_5]</out>
</item>
</items>
</arc:set>
</arc:call>
<arc:push item="output"></arc:push>
</arc:set></arc:set></arc:set></arc:set></arc:set></arc:set></arc:set></arc:set></arc:set></arc:set></arc:set></arc:set></arc:set></arc:set></arc:set></arc:set></arc:set></arc:set></arc:set></arc:set>
XML Map コネクタの構成
続いて、変換したデータを今度はMySQL のテーブル構造にマッピングさせます。
ソースファイルには先程のScript コネクタで変換したファイルを設定します。ディスティネーションファイルはMySQL への接続を構成すると自動的に設定されます。
以下のように各項目をドラッグ・アンド・ドロップでマッピングさせることができます。

MySQL コネクタの構成
最後にMySQL への書き込み処理を担うコネクタを構成します。
コネクタを配置したら、接続情報を最初に構成します。

以下のように対象とするMySQL のサーバーアドレスやポート番号、データベース名、ユーザーID・PWを指定して、コネクションを確立します。

アクションはデータの書き込み処理を行う「Upsert」を指定し、対象テーブルとして事前に作成しておいたcameralog のテーブルを指定すればOKです。

これで以下のようにデータが取り込まれてくればOKです。

Tableau での可視化
MySQL にデータが取り込めれば、あとはお好みのBIツールでデータの可視化ができます。今回は一例としてTableau Desktop で可視化してみました。
Tableau Desktop を立ち上げて、MySQL へ接続します。

先程のデータが格納されている、MySQL に接続し

Cameralog のテーブルを選択して、データを取り込みましょう。

例えば日別の入室者数を可視化した場合ですと、以下のように折れ線グラフで表現することができます。

これにより日毎や時間帯別の来客者数などを可視化することができますね。
また、BIツールは様々なデータソースのデータを掛け合わせて分析できるのが特徴ですので、スマレジといったPOSレジのデータと組み合わせて、来場者数と売上の相関関係を分析してみるのも良いかもしれません。
おわりに
このようにCData Arc を利用することで、ネットワークカメラと他のサービス・BIツールなどの連携を簡単に実現することができます。
CData Arc はシンプルで拡張性の高いコアフレームワークに、豊富なMFT・EDI・エンタープライズコネクタを備えたパワフルな製品です。
CData Drivers との組み合わせで250を超えるアプリケーションへの連携を実現できます。必要な連携を低価格からはじめられる事も大きな特長です。 皆さんのつなぎたいシナリオでぜひ CData Arc を試してみてください。
https://jp.cdata.com/arc/
お試しいただく中で何かご不明な点があれば、テクニカルサポートへお気軽にお問い合わせください。
https://jp.cdata.com/support/