M5StickC でスマートメーターから計測値を取得して Amazon Timestream に保存する

## 概要

M5StickC を使って各家庭に設置されたスマートメーター(電力計)から計測値を取得し、MQTT で AWS IoT に送信、Amazon Timestream に連携して保存します。保存したデータは Grafana などで可視化できます。

![概要](https://hirose-public.s3-ap-northeast-1.amazonaws.com/qiita/2024/05/12/78861858-8049-4a08-b04c-fb9e6f9b9745.png)

## 必要なもの

- 低圧スマートメーター
- [M5StickC](https://shop.m5stack.com/products/stick-c) or [M5StickC Plus](https://shop.m5stack.com/products/m5stickc-plus-esp32-pico-mini-iot-development-kit)
- [M5StickC 用 Wi-SUN HAT キット](https://booth.pm/ja/items/1650727)
- Wi-SUN モジュール (以下のいずれか)
  - [BP35A1 - Wi-SUN Compatible Wireless Module](https://www.rohm.com/products/wireless-communication/specified-low-power-radio-modules/bp35a1-product)
  - BP35C1-J11-T01
- AWS アカウント

## ランニングコスト

[Amazon Timesteam](https://aws.amazon.com/jp/timestream/pricing/) の料金として約 4 USD/月ほどかかります。

- 書き込み: 0.625 USD/100 万書き込み
- ストレージ(マグネティックストア): 0.0375 USD/GB･月

書き込みは 15 秒に 1 回送信した場合で 5,760 回/日、約 18 万回/月なので、月に数十円程度。
ストレージの単価は 0.0375 USD/GB･月 ですが、最低料金として 100 GB ぶん(3.75 GB/月)の料金がかかります。

また可視化のために [Amazon Managed Grafana](https://aws.amazon.com/jp/grafana/pricing/) を使用する場合は、別途 9.0 USD/月の固定料金がかかります。

## 手順

### 1. B ルートを有効化

参考) [M5StickCで家庭用スマートメーターをハックする！](https://kitto-yakudatsu.com/archives/7206)

スマートメーターから直接計測値を取得するためには、まずお使いの電力会社に「電力メーター情報発信サービス(B ルートサービス)」に申し込んで B ルートを有効化する必要があります。手続き完了までに数日かかるため、まずは先にやっておきましょう。

認証用の ID とパスワードが発行されます。

### 2. M5StickC に Wi-SUN モジュールを接続する

参考) [M5StickCで家庭用スマートメーターをハックする！](https://kitto-yakudatsu.com/archives/7206)

M5StickC にスマートメーターと通信するためのモジュールを装着します。

### 3. AWS IoT にデバイスを登録

M5StickC から送信されたデータを受信するために、以下の手順でデバイスの設定を作成します。AWS IoT ではこの接続するデバイスのことを「モノ (Thing)」と呼びます。

 1. AWS 管理コンソール > [AWS IoT](https://ap-northeast-1.console.aws.amazon.com/iot/home) > モノ
 1. 「モノを作成」
 1. 「1 つのモノを作成」
 1. モノのプロパティを指定して「次へ」
    - モノの名前: (例: `SmartMeterHub`)
 1. 「新しい証明書を自動生成 (推奨)」を選択して「次へ」
 1. ポリシーをアタッチして「モノを作成」
    - ポリシーを作成してアタッチします。(後述)
 1. 以下のファイルをダウンロードする (のちほどデバイスに組み込んで使用します。)
    - デバイス証明書
    - パブリックキーファイル
    - プライベートキーファイル
    - Amazon 信頼サービスエンドポイント

証明書にアタッチするポリシーは、例として以下のように設定します。

- モノ `SmartMeterHub` の接続のみ許可
- トピック `SmartMeterHub/measured` へのパブリッシュを許可

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:(リージョン):(アカウントID):client/SmartMeterHub"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": "arn:aws:iot:(リージョン):(アカウントID):topic/SmartMeterHub/*"
    }
  ]
}
```

### 4. スマートメーターから計測値を取得して MQTT に送信するファームウェアを作成する

[yh1224/M5SmartMeterHub - GitHub](https://github.com/yh1224/M5SmartMeterHub) からソースをダウンロードし、手順に従ってインストールします。

 1. src/config.h.template を参考に、src/config.h を作成します。

    - `WIFI_SSID` : 接続する Wi-Fi アクセスポイントの SSID を指定
    - `WIFI_PASS` : 接続する Wi-Fi アクセスポイントのパスワードを指定
    - `WISUN_MODULE` : 使用する Wi-SUN モジュールを指定 (BP35A または BP35C)
    - `BROUTE_ID` : 電力会社から発行された B ルート ID を指定
    - `BROUTE_PASSWORD` : 電力会社から発行された B ルートパスワードを指定
    - `MQTT_HOST` : MQTT ブローカーのホスト名として、AWS IoT の「デバイスデータエンドポイント」を指定 (AWS アカウントごとに異なり、[AWS IoT](https://ap-northeast-1.console.aws.amazon.com/iot/home) の「設定」から確認します。)
    - `MQTT_CLIENT_ID` : AWS IoT に登録した「モノの名前」を指定
    - `MQTT_TOPIC` : 計測値の送信先トピックを指定 (例: `SmartMeterHub/measured`)

    その他の設定は、必要に応じて変更します。

 1. data/ ディレクトリ配下に以下のファイルを配置し、

    - ca.pem.crt : AWS IoT からダウンロードした「Amazon 信頼サービスエンドポイントの証明書」
    - certificate.pem.crt : AWS IoT からダウンロードした「デバイス証明書」
    - private.pem.key : AWS IoT からダウンロードした「プライベートキーファイル」

    デバイスのファイルシステム (SPIFFS) にアップロードします。

    ```shell
    pio run -t uploadfs
    ```

 1. ファームウェアをビルドして、デバイスにアップロードします。

    ```shell
    pio run -t upload
    ```

### 5. Amazon Timestream データベースを作成 

AWS 管理コンソール > [Amazon Timestream](https://ap-northeast-1.console.aws.amazon.com/timestream/home) から、データベースおよびテーブルを作成します。

- データベース
  - 名前: (例: `SmartMeter`)
- テーブル
  - データベース名: 作成したデータベースを選択 (例: `SmartMeter`)
  - テーブル名: (例: `measured`)
  - パーティションキー設定: デフォルトパーティショニング

### 6. AWS IoT から Timestream に連携

AWS 管理コンソール > [AWS IoT](https://ap-northeast-1.console.aws.amazon.com/iot/home) > メッセージのルーティング > ルール から、ルールを作成します。

- ルール名: (例: `smartMeter`)
- SQL ステートメント: `SELECT * FROM 'SmartMeterHub/measured'`
- アクション: Timesteam table
  - データベース名: (例: `SmartMeter`)
  - テーブル名: (例: `measured`)
  - ディメンション
    - ディメンション名: `deviceId`
    - ディメンション値: `${topic(1)}`
  - タイムスタンプ値: `${timestamp}`
  - タイムスタンプの単位: `SECONDS`
  - IAM ロール: 作成して選択する
    - データベースへの書き込みパーミッションが自動的に設定されます。
      例)

      ```json
      {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Effect": "Allow",
            "Action": ["timestream:WriteRecords"],
            "Resource": "arn:aws:timestream:(リージョン):(アカウントID):database/SmartMeter/table/measured"
          },
          {
            "Effect": "Allow",
            "Action": ["timestream:DescribeEndpoints"],
            "Resource": "*"
          }
        ]
      }
      ```

### 7. Grafana で可視化

Grafana 自体のセットアップについて詳細は割愛しますが、IAM Identity Center を使用している場合は Amazon Managed Grafana を使用して以下の手順で簡単に連携することができます。

 1. AWS 管理コンソール > [Amazon Managed Grafana](https://ap-northeast-1.console.aws.amazon.com/grafana/home)
 1. 「ワークスペースを作成」
 1. ワークスペース名を入力して「次へ」
 1. 認証アクセス情報に「AWS IAM ID センター」を選択して「次へ」
 1. データソースに「Amazon TimeStream」を選択して「次へ」
 1. 「ワークスペースを作成」
 1. AWS IAM ID センターの「新しいユーザーまたはグループの割り当て」
 1. アクセスするユーザーを選択して「ユーザーとグループを割り当て」
 1. 割り当てたユーザーを選択して「アクション」→「管理者を作成する」
 1. 「Grafana ワークスペース URL」にアクセスして管理者でログイン
 1. Administration > Data sources から「Add data source」→「Amazon Timestream」をクリック

#### ダッシュボードへの表示例

![表示例](https://hirose-public.s3-ap-northeast-1.amazonaws.com/qiita/2023/07/22/fc3b2a8e-b5d0-443c-b2b8-8c212579438d.png)

#### 設定

例) 瞬時電力計測値をグラフ化する

```sql
SELECT measure_value::bigint, time
FROM SmartMeter.measured
WHERE measure_name = 'instantaneous'
```

例) 30 分ごとの電力使用量をグラフ化する

```sql
SELECT (MAX(measure_value::double) - MIN(measure_value::double)) AS value, MIN(time)
FROM SmartMeter.measured
WHERE measure_name = 'cumulative'
GROUP BY bin(time, 30m)
```

## 処理詳細

### Wi-SUN モジュールによるスマートメーターとの通信

Wi-SUN モジュールとのシリアル通信により、スマートメーターとの認証・接続・通信をおこないます。Wi-SUN モジュールのインタフェース仕様は以下からダウンロードできます。

- [BP35A1 - Wi-SUN Compatible Wireless Module](https://www.rohm.com/products/wireless-communication/specified-low-power-radio-modules/bp35a1-product)
- [BP35C0-J11 - Wi-SUN Enhanced HAN Compatible Wireless Module](https://www.rohm.com/products/wireless-communication/specified-low-power-radio-modules/bp35c0-j11-product) ([日本語](https://www.rohm.co.jp/products/wireless-communication/specified-low-power-radio-modules/bp35c0-j11-product))
  ※BP35C1-J11-T01 はアンテナ・コネクタ付きの評価用アダプターボードであり、I/F 仕様は上記と同一です。

#### 接続シーケンス (BP35A1 の場合)

![](https://hirose-public.s3-ap-northeast-1.amazonaws.com/qiita/2024/11/04/323a7755-a322-4de5-b85a-ecb65c45738e.png)

#### 接続シーケンス (BP35C1-J11-T01 の場合)

![](https://hirose-public.s3-ap-northeast-1.amazonaws.com/qiita/2024/11/04/86365ea5-4f67-44cc-a830-5742cd65349b.png)

### スマートメーターからのデータ取得

スマートメーターのインタフェース仕様は、[エコーネットコンソーシアム](https://echonet.jp/) により ECHONET Lite として規定されています。「低圧スマート電力量メータ・HEMSコントローラ間 アプリケーション通信 インタフェース仕様書」を参照します。

#### 瞬時電力および積算電力量を取得する

以下のプロパティを使用して、現時点の瞬時電力および積算電力量を取得します。

|プロパティ名|EPC|Get/Set|サイズ|備考|
|:--|:--|:--|--:|:--|
|積算電力量計測値 (正方向計測値)|0xE0|Get|4|計測開始からの現在の累積の電力量 (単位は「積算電力量単位」による)|
|積算電力量単位|0xE1|Get|1|積算電力量の単位|
|瞬時電力計測値|0xE7|Get|4|取得した瞬間の電力量 (単位:W)|

![](https://hirose-public.s3-ap-northeast-1.amazonaws.com/qiita/2024/11/04/e2e82d33-0e93-4013-8fad-b7bbb438c6fd.png)

「積算電力量単位」は以下の値を取り、「積算電力量計測値」の単位を示します。例えば積算電力量計測値が 9999 で積算電力量単位が 0x01 の場合、9999 × 0.1 kWh = 999.9 kWh となります。

- 0x00: 1 kWh
- 0x01: 0.1 kWh
- 0x02: 0.01 kWh
- 0x03: 0.001 kWh
- 0x04: 0.0001 kWh
- 0x0A: 10 kWh
- 0x0B: 100 kWh
- 0x0C: 1,000 kWh
- 0x0D: 10,000 kWh

#### 積算電力量の履歴を取得する

スマートメーター内には 30 分ごとの積算電力量が記録されており、以下のプロパティを使用して、その履歴を取得することができます。

|プロパティ名|EPC|Get/Set|サイズ|備考|
|:--|:--|:--|--:|:--|
|積算電力量単位|0xE1|Get|1|積算電力量の単位|
|積算電力量計測値履歴1 (正方向計測値)|0xE2|Get|194|30 分ごとの積算電力量計 (単位は「積算電力量単位」による)|
|積算履歴収集日1|0xE5|Get/Set|1|積算履歴を取得する対象の日付を指定|

「積算履歴収集日1」に何日前を取得するか指定(当日の場合は 0)してから、「積算電力量計測値履歴1」を取得します。

![](https://hirose-public.s3-ap-northeast-1.amazonaws.com/qiita/2024/11/04/0c4ffb6e-e994-4013-acef-25e4fd6de72b.png)

「積算電力量計測値履歴」のデータは先頭 2 バイトがサイズで 0x00C0 (192) 固定、その後 00:00 から 30 分ごとの積算電力量計測値が 4 バイトずつ 48 コマ続きます。