0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

.NETでSwitchBotプラグミニと温湿度計の値をSDK無しのBLE Advertisementパケットから取得する

Last updated at Posted at 2025-02-13

:star: はじめに

こちらの記事では、RS-WFWATTCH2を使って消費電力を測定する方法を記述しています。

room.png

上記記事中にもあるように、RS-WFWATTCH2は高いので、SwitchBotプラグミニも併用しており、こちらではSwitchBotから消費電力を取得する方法について記述します。

取得方法はSwitchBot APIを使用した方法ではなく、BLE Advertisementパケットを拾って値を取得する方法です。
BLE Advertisementパケットを使用する方法は測定タイミングの制御できませんが、APIのリクエスト上限・デバイス数を気にせず測定できるメリットがあります。

また、サンプルコードにはSwitchBotプラグミニから消費電力を取得する処理だけでなく、温湿度計の値(CO2センサーの値含む)を取得する方法も含めます。

:hammer_pick: コード

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0-windows10.0.22000.0</TargetFramework>
  </PropertyGroup>

</Project>
using System.Runtime.InteropServices.WindowsRuntime;

using Windows.Devices.Bluetooth.Advertisement;

var watcher = new BluetoothLEAdvertisementWatcher();
watcher.Received += OnWatcherReceived;
watcher.Start();

Console.ReadLine();

void OnWatcherReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{
    foreach (var md in args.Advertisement.ManufacturerData.Where(static x => x.CompanyId == 0x0969))
    {
        var buffer = md.Data.ToArray();
        Console.WriteLine($"address={args.BluetoothAddress:X12}, rssi={args.RawSignalStrengthInDBm}");

        // 温度計
        if (IsMeter(args.BluetoothAddress))
        {
            var temperature = (((double)(buffer[8] & 0x0f) / 10) + (buffer[9] & 0x7f)) * ((buffer[9] & 0x80) > 0 ? 1 : -1);
            var humidity = buffer[10] & 0x7f;
            // CO2センサーに対応している場合
            var co2 = buffer.Length >= 16 ? (buffer[13] << 8) + buffer[14] : 0;
            Console.WriteLine($"  temperature={temperature}C, humidity={humidity}%, co2={co2}ppm");
        }
        // プラグミニ
        if (IsPlugMini(args.BluetoothAddress))
        {
            var power = (double)(((buffer[10] & 0b00111111) << 8) + (buffer[11] & 0b01111111)) / 10;
            Console.WriteLine($"  power={power}W");
        }
    }
}

:pencil: 解説

WindowsランタイムのAPIを使用するため、TargetFrameworkをnet8.0-windows10.0.22000.0のような形に変更します。
詳細は以下を参照してください。

BLE Advertisementパケットの取得はBluetoothLEAdvertisementWatcher.Receivedイベントで行ないます。

CompanyIdが0x0969のものがSwitchBotの機器で、値はManufacturerDataから取得します。

各機器の測定値の取得方法は以下を参照してください。

ManufacturerData.Dataの値には先頭にアドレスが入っているので、その分はオフセットをずらして読むようにしてください。

送られてきたデータがプラグミニのものか温湿度計のものかはこの処理だけでは判断できないので、その部分の判定についてはアドレスに対する種別が別途登録済みの想定として省略しています。

:rabbit: うさコメ

SDKのリクエスト上限を気にせず、プラグや温湿度計の台数を好きなだけ増やして、測定値Prometheus+Grafana表示に使えるので満足( ˙ω˙)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?