ゲーミングPCのLEDをC#で制御する

# 対応メーカー

軽く調べてみたところ下記メーカーがSDKを公開しているようです。
 - MSI
 - ASUS
 - GIGABYTE

# 実装してみる

## メーカー
残念ながら我が家にある光るPCは全てASUS製のマザボなので、この記事はASUSのみのお話になります。

## 言語
 - C++
 - C#
 - Python

で書けるみたいです。私はC#に魂を売っているので、この記事はC#での実装になります。

## 事前準備

### プロジェクト作成
とりあえずコンソールでもWPFでもいいのでプロジェクトを作成します。
試していませんがUWPでも大丈夫だと思います。

### 参照設定
公式SDKを参照に追加します。
![2022-12-11_20h46_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164419/b18d6b02-0c68-e988-d826-df25f0610d1a.png)

「COM」から「AuraServiceLib」を選択しましょう。
![2022-12-11_20h47_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164419/ca1b3d51-df5e-e09b-a8cb-9e597be5ebd5.png)
私の環境では最初からありましたが、AuraCreator(Asus公式のLED制御ツール)とかインストールしてない人はひょっとしたら存在しないかもです。
ちょろっと探してみた限りではこのDLL単体での配布は見つからなかったので、一覧に無い場合はAuraSyncやAuraCreatorをインストールする必要があると思います。たぶん。

### 検証コード
WPFでの検証コードです。ボタンを2つ置くだけの簡単な画面なのでXAMLは割愛します。
![2022-12-11_20h58_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164419/7ffa38d4-7d69-6cb9-ee5c-125de552d7a1.png)

```C#:MainWindow.xaml.cs
using AuraServiceLib;
using System.Windows;

namespace WpfApp1 {
    public partial class MainWindow : Window {

        /// <summary>
        /// 制御用のインスタンス
        /// </summary>
        IAuraSdk sdk = new AuraSdk();

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MainWindow() {
            InitializeComponent();

            //制御権を貰う
            sdk.SwitchMode();
        }

        #region ボタンクリック時の処理
        private void button_Click(object sender, RoutedEventArgs e) {
            //全部を赤に
            setColorAllLED(0x00FF0000);
        }

        private void button_Copy_Click(object sender, RoutedEventArgs e) {
            //全部を青に
            setColorAllLED(0x000000FF);
        }
        #endregion ボタンクリック時の処理

        /// <summary>
        /// 色設定用の共通処理
        /// </summary>
        /// <param name="colorCode"></param>
        private void setColorAllLED(uint colorCode) {
            IAuraSyncDeviceCollection devices = sdk.Enumerate(0);

            //全部のデバイス
            foreach (IAuraSyncDevice dev in devices) {
                //全部のLED
                foreach (IAuraRgbLight light in dev.Lights) {
                    //色を設定
                    light.Color = colorCode;
                }

                //反映
                dev.Apply();
            }
        }
    }
}

```

こんな感じで動いてくれます。
画面右下に置かれているPCのLEDを赤/青に変えています。


![unnamed.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164419/7b915e68-37ad-7905-74b2-aefa59e94ff1.gif)


#### 初回処理
`SwitchMode()`でLED制御を取得します。**一度呼んでおかないと制御できない**です。これ無しで色の設定を行っても例外が発生したりとかは無いので、忘れてるとなかなか気付けないかもしれません。

呼び出し以降は別のアプリケーションがこれを呼ぶまでは制御権を持ち続けます。
逆に言えば、別のアプリケーションに制御権を渡したくない場合は定期的に呼んであげる必要がありそうですね。

また、掴んだ制御権はプロセスが正常に終了すれば自動で解放してくれるみたいです。
強制終了も試してみましたが、しばらくしたらAuraCreatorが勝手に奪い返してくれました(終了せずに放置して奪い返されることは無かったので、何かしら裏で応答確認的なものが動いているのかもしれません。知らんけど)。

#### 色設定
`AuraSdk.Enumerate().IAuraSyncDevice.IAuraRgbLight.Color`にuint型で色情報をぶち込んで設定します。
0x `不使用(00)` `青(00～FF)` `緑(00～FF)` `赤(00～FF)`です。

#### 明るさ設定
**明るさは輝度を直接設定するわけではなく**、設定した色が黒に近くなるほど暗くなるようです。
こちらが`0x00FF0000`、
![DSC_0126 (400x300).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164419/53273e68-9893-5cf0-0df7-033f646cc917.jpeg)

そしてこちらが`0x00300000`です。
![DSC_0127 (400x300).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164419/27cf50df-4171-dca0-bd06-77b97d3a9da4.jpeg)

## おまけ
上記コードの`setColorAllLED()`呼び出し部分をこんな感じにすればフェードっぽい点灯もできます。
このままでは少しぎこちないですが、三角関数とか使ってあげると滑らかになるんじゃないでしょうか。

```
for (; ; ) {
    for (int i = 10; i < 250; i*=2) {
        setColorAllLED((uint)i);                       
    }
    await Task.Delay(1000);
}
```

## 参考
下記、公式リファレンスです。UnityやUE4用のあれこれもあるらしい。
https://www.asus.com/microsite/aurareadydevportal/namespace_aura_service_lib.html

## 続編
https://qiita.com/unasenohkoku/items/d079bfde5bf144c82e53