# OCPPゲートウェイ

[OCPP](https://www.openchargealliance.org/)（Open Charge Point Protocol）は、充電ステーションと中央管理システムを接続するオープンな通信プロトコルであり、電気自動車充電インフラの統一された通信標準を提供することを目的としています。OCPPゲートウェイはプロトコル変換機能を持ち、OCPPとMQTTプロトコル間の橋渡しを行い、これらのプロトコルを使用するクライアント同士の通信を可能にします。

EMQX Cloudは、[OCPP 1.6-J](https://www.openchargealliance.org/protocols/ocpp-16/)向けのプロトコルゲートウェイを追加しました。これはOCPP仕様に準拠したさまざまなブランドの充電ステーション機器と接続可能です。ルールエンジン、データ統合、REST APIなどを通じて管理システム（Central System）と連携し、ユーザーが迅速に電気自動車充電インフラを構築できるよう支援します。

本ページでは、EMQX CloudにおけるOCPPゲートウェイの設定および利用方法を紹介します。

## 基本設定

OCPPゲートウェイの基本設定を行うには、**Actions**列の**Settings**ボタンをクリックしてください。

- **MountPoint**：パブリッシュおよびサブスクライブするすべてのMQTTトピックに付加されるプレフィックスです。これによりプロトコル間のメッセージルーティングの分離が可能となります。デフォルトは`ocpp/`です。
- **Default Heartbeat Interval**：チャージポイントから送信されるハートビートメッセージのデフォルト間隔（秒）、デフォルトは`60s`です。
- **Heartbeat Checking Times Backoff**：ハートビートタイムアウトチェックのバックオフに使用される乗数、デフォルトは`1`です。
- **Message Format Checking**：メッセージフォーマットの妥当性チェックを有効にするかどうか。EMQXはアップロードストリームおよびダウンロードストリームのメッセージフォーマットをJSONスキーマで定義された形式と照合します。チェックに失敗した場合、EMQXは対応する応答メッセージを返します。選択肢は以下の通りです：
  - `all`：すべてのメッセージをチェックします。
  - `upstream_only`：アップロードストリームメッセージのみチェックします。
  - `dnstream_only`：ダウンロードストリームメッセージのみチェックします。
  - `disable`：メッセージチェックを行いません。
- **JSON Schema ID Prefix**：OCPP JSONスキーマドキュメントを識別するためのプレフィックス、デフォルトは`urn:OCPP:1.6:2019:12:`です。
- **Idle Timeout**：非アクティブ状態が続いた場合にOCPPフレームの受信を待つ最大時間（秒）を設定し、その時間を超えると接続を切断します。
- **Upstream**：アップロードストリームの設定グループ（チャージポイント -> EMQX）。
  - **Topic**：アップロードストリームのCall Requestメッセージ用トピック、デフォルトは`cp/${cid}`です。
  - **Reply Topic**：アップロードストリームのReplyメッセージ用トピック、デフォルトは`cp/${cid}/Reply`です。
  - **Error Topic**：アップロードストリームのErrorメッセージ用トピック、デフォルトは`cp/${cid}/Reply`です。
  - **Topic Override Mapping**：メッセージ名によるアップロードストリームのトピック上書きマッピング。
- **Downstream**：ダウンロードストリームの設定グループ（EMQX -> チャージポイント）。
  - **Topic**：EMQXからのリクエスト／制御メッセージを受信するためのダウンロードストリームトピック。この値はすべての接続されたチャージポイントがサブスクライブするワイルドカードトピック名です。デフォルトは`cs/${cid}`です。
  - **Max Message Queue Length**：ダウンロードストリームのメッセージ配信における最大メッセージキュー長。デフォルトは`100`です。

## 認証

OCPP 1.6-J自体には組み込みの認証機構は定義されていませんが、WebSocketハンドシェイク時にHTTP Basic認証を用いてクライアント認証を行うのが一般的な方法です。OCPPゲートウェイはこの方法を採用し、チャージポイント接続時にクライアント認証情報を取得します。

ゲートウェイは接続リクエストから以下の情報を使用します：

- **Client ID**：固定パスプレフィックスの後のWebSocket接続URLから抽出されます（例：`/ocpp/chargePointSim` -> `chargePointSim`）。
- **Username**および**Password**：HTTP Basic認証の`Authorization`ヘッダーからデコードされます。

これらの認証情報は、EMQX Cloudコンソールの**OCPP** -> **Authentication**に登録された情報と照合されます。クライアントの接続を許可するには、あらかじめ該当するユーザー名とパスワードをこのページで追加しておく必要があります。

## OCPPクライアントツールを使ったOCPPゲートウェイのテスト

OCPPゲートウェイが起動したら、OCPPクライアントを接続してセットアップを検証できます。本節では、オープンソースツール[ocpp-js](https://github.com/0721Betty/ocpp-js)を使用してチャージポイントをシミュレートし、接続テストを行う方法を説明します。

1. [MQTTX](https://mqttx.app/downloads)などのMQTTクライアントを用意し、OCPPゲートウェイを通じて交換されるメッセージを監視します。

   - MQTTXをEMQXデプロイメントに接続します。
   - ワイルドカードトピック`ocpp/#`をサブスクライブします。

   これにより、すべてのOCPP関連メッセージを観察できます。

   <img src="./_assets/ocpp-mqttx-create-conn.png" alt="ocpp-mqttx-create-conn" style="zoom:67%;" />

2. `ocpp-js`クライアントをクローンしてセットアップします：

   ```shell
   git clone https://github.com/0721Betty/ocpp-js.git
   cd ocpp-js
   npm install
   ```

3. 環境変数を設定します。環境テンプレートをコピーし、実際の設定に合わせて編集してください：

   ```shell
   cp env.template .env.local
   ```

   `.env.local`を開き、デプロイメント固有の情報を入力します：

   ```bash
   OCPP_USERNAME=your_username
   OCPP_PASSWORD=your_password
   OCPP_CLIENT_ID=chargePointSim
   EMQX_CLOUD_DEPLOYMENT_ADDRESS=your_deployment_address
   ```

   ::: tip 補足

   - デプロイメントアドレスはEMQX Cloudコンソールの**Overview**ページで確認できます。
   - ユーザー名とパスワードは**OCPP** -> **Authentication**で設定した認証情報と一致させてください。

   :::

4. OCPPクライアントを起動してEMQX OCPPゲートウェイに接続します：

   ```shell
   npm start
   ```

   またはNode.jsで直接実行します：

   ```shell
   node client.js
   ```

   成功すると、以下のようなログが表示されます：

   ```bash
   Connected to Central System
   Client ID: chargePointSim
   Username: your_username
   Sending: ......
   ```

5. MQTTXでは、トピック`ocpp/cp/chargePointSim`に以下のようなメッセージが届きます：

   ```json
   Topic: ocpp/cp/chargePointSim
   {
     "UniqueId": "1200012677",
     "Payload": {
       "chargePointVendor": "vendor1",
       "chargePointModel": "model1"
     },
     "Action": "BootNotification"
   }
   ```

   これはシミュレートされたチャージポイントが接続し、`BootNotification`リクエストを送信したことを示しています。

6. MQTTXでトピック`ocpp/cs/chargePointSim`に対して返信を送信します。`UniqueId`は前のメッセージで受信したものに置き換えてください：

   ::: tip

   `UniqueId`は元の`BootNotification`と一致させる必要があります。

   :::

   ```json
   {
     "MessageTypeId": 3,
     "UniqueId": "***",
     "Payload": {
       "currentTime": "2023-12-01T14:20:39+00:00",
       "interval": 300,
       "status": "Accepted"
     },
     "Action": "BootNotification"
   }
   ```

7. `BootNotification`への応答後、MQTTXで`StatusNotification`メッセージが届きます：

   ```json
   Topic: ocpp/cp/chargePointSim
   Payload:
   {
     "UniqueId": "3062609974",
     "Payload": {
       "status": "Available",
       "errorCode": "NoError",
       "connectorId": 0
     },
     "MessageTypeId": 2,
     "Action": "StatusNotification"
   }
   ```

これはOCPPクライアントがゲートウェイとの通信を確立し、現在のステータスを報告したことを示しています。

## クライアント

OCPPページの**Clients**タブでは、現在接続中のすべてのOCPPクライアントの基本情報を確認できます。**Actions**列からはクライアントの強制切断が可能です。

![ocpp_client](./_assets/ocpp_client.png)
