RS-WFWATTCH2を使ってPCの消費電力(実測値)をモニタリングしてみよう

# :star: はじめに

CPU/GPUの高性能化に伴いその消費電力が増加している昨今、みなさんは消費電力を気にする方ですか？
自分は単純な性能だけではなく、PCの消費電力や静音性なんかも気にする方です。

しかし、巷のPC系の記事等では、TDPが記述されているだけだったりと、その方面では物足りないものが多い状況です。[^1]
自分が本当に知りたいのは、アイドル時は負荷時含め、PC全体での実測値なのです。

そんな中、去年Wi-Fi接続で消費電力を計測できるワットモニターRS-WFWATTCH2が発売されました。

https://www.ratocsystems.com/products/sensor/watt/rswfwattch2/

https://www.amazon.co.jp/dp/B0D6YV85V2/

この製品の前にBluetoothベースのRS-BTWATTCH2という製品もありましたが、Bluetoothのペアリングが成功しにくかったり、Windowsでペアリングをした時には使用できなかったりと、ちょっと難のある製品でした。
しかし、Wi-Fi接続であればペアリング周りの問題に悩まされることなく、TCP接続で単純に消費電力を測定できるのではないかと考え、実際にコードでの値の取得を行なってみました。

また、この手の製品はスマホアプリで値を参照するものが多く、RS-WFWATTCH2にはWindows用のアプリもついてきますが、本当にやりたいのは対話的な参照ではなく、モニタリングツールを使っての継続的な監視です。
後は、モニタリングツールはWindows上だけではなく、Linux(Raspberry Pi)上等からでも動作させたいですし。
そこで、値の取得部分をライブラリとして作成し、監視ツールで使用する事で以下の様にGrafanaを使ってのモニタリングも可能になったので、その事についての記事となります。[^2][^3]

![power.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9645/e4e71657-8fe8-f397-f017-0f0eddb612b0.png)

# :hammer_pick: コード

RS-WFWATTCH2から計測値を取得するための最小限のコードと実行結果を以下に示します。

## サンプル

```csharp
using System.Net;
using System.Net.Sockets;

using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

await socket.ConnectAsync(new IPEndPoint(IPAddress.Parse("192.168.1.101"), 60121));

// コマンド送信
var command = new byte[] { 0xAA, 0x00, 0x02, 0x18, 0x00, 0x65 };
await socket.SendAsync(command.AsMemory(), SocketFlags.None);

// レスポンス受信
var response = new byte[30];
var read = await socket.ReceiveAsync(response.AsMemory());
if (read < response.Length)
{
    return;
}

// レスポンス解析
var voltage = (double)ReadValue(response[5..11]) / (1L << 24);
var current = (double)ReadValue(response[11..17]) / (1L << 30);
var power = (double)ReadValue(response[17..23]) / (1L << 24);
var dateTime = ReadDateTime(response[23..29]);

Console.WriteLine($"{dateTime:HH:mm:ss}: Power=[{power:F2}], Voltage=[{voltage:F2}], Current=[{current:F3}]");


static long ReadValue(ReadOnlySpan<byte> buffer) =>
    ((long)buffer[5] << 40) +
    ((long)buffer[4] << 32) +
    ((long)buffer[3] << 24) +
    ((long)buffer[2] << 16) +
    ((long)buffer[1] << 8) +
    buffer[0];

static DateTime ReadDateTime(ReadOnlySpan<byte> buffer) =>
    new(buffer[5] + 2000, buffer[4], buffer[3], buffer[2], buffer[1], buffer[0]);
```

## 実行結果

```
20:02:05: Power=[179.28], Voltage=[100.88], Current=[1.799]
```

## 補足

- RS-WFWATTCH2のIPアドレス、ポート60121にTCPで接続してコマンドを送信すると、レスポンスが返ってきます
- 基本的な電文構造はRS-BTWATTCH2のものとほぼ同じです
- ここでは最低限のサンプルなのでエラー処理等は省略しています、ライブラリ化した完全なコードは以下を参照してくだささい[^4]

https://github.com/usausa/devicelib-wfwattch2

# :pencil: 解説

電文の詳細は以下になります。

## リクエスト

|値|概要|
|:----|:----|
|AA|プレフィックス|
|0002|データ長|
|1800|コマンド|
|65|CRC8|

## レスポンス(例)

|値|概要|
|:----|:----|
|AA|プレフィックス|
|001A|データ長|
|1800|コマンド|
|3473E2640000|電圧|
|8E091C730000|電流|
|E17348B30000|電力|
|050214010119|時刻|
|1A|CRC8|

# :rabbit: うさコメ

RS-WFWATTCH2から取得しているのは消費電力だけですが、他にも各種ライブラリを使って自前のPrometheus expoterを作成し、こんなモニタリングもできるようにしています( ˙ω˙)

![windows.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9645/91c2bcf3-52f1-34f7-15b2-e16b582dcd4e.png)

自前のPrometheus expoterのソース全体はこちらです。

https://github.com/usausa/prometheus-exporter-alternative

PC全体の消費電力と比較して表示するためのCPU/GPUの消費電力や温度はLibreHardwareMonitorを使用して取得しています。

温度の取得に関しては、室温の取得はOMRONの2JCIE-BL及びSitchBotの各種温度計に対応しています。

https://www.fa.omron.co.jp/products/family/3723/

https://www.switchbot.jp/products/switchbot-meter

https://www.switchbot.jp/products/switchbot-co2-meter

SitchBotについてはAPIを使用するのではなく、BLEアドバタイズパケットの値を拾っています。
ちなみにOMRONのセンサーから値を取得する部分もライブラリ化しており、こんなモニタリングもしています。

![environment.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9645/e616dd46-c21f-4f42-4ca5-3ab4b38c80e5.png)

https://github.com/usausa/devicelib-sensor-omron

他にもS.M.A.R.T情報の取得とかもしていますが、それについてはこちらの記事で。

https://qiita.com/yamaokunousausa/items/ae6c28e56fa1338098c1

また、消費電力の取得については、RS-WFWATTCH2だけではなく、SwitchBotのプラグミニににも対応しています。

https://www.switchbot.jp/products/switchbot-plug-mini

なにせSwitchBotと比較してRS-WFWATTCH2はお高いので(; ˙ω˙)
RS-WFWATTCH2は雷サージ保護をうたっていたり、SwitchBotは機器としては信用はしていないので、運用としては、主要なPCにはRS-WFWATTCH2を使用し、ノートPC等バッテリーで駆動できるようなものにはSwitchBotの方を使う等と使い分けをしています。

![room.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9645/978740cd-7955-0b77-439f-cc978d44bfe3.png)


[^1]: 海外の記事なんかだともう少し突っ込んだものもありますが。
[^2]: 本当は微妙なアプリを用意するだけではなく、オフィシャルで仕様を公開してくれれば簡単に自前での工夫も出来て便利なんですけどね。
[^3]: PowerのTotal部分がこの記事で扱っている値となります。
[^4]: ライブラリが対応しているのは計測値の取得だけですが、RS-WFWATTCH2自体にはリモートからの電源オンオフをはじめ、他にもいくつかのコマンドがあります。