Razer ChromaとNZXT CAMを繋げてクロスプラットフォームゲーミングPCを実現した話（ちょっとCorsairも）

## はじめに
ゲーミングPCのライティングを統一化したいと思ってWebを漁ったけど思ったようにいかなかったので自分で作ったという話です。
コードは公開するレベルではないと思いますが誰かの参考になればと:point_up_tone1:

![ChromaLinks Demo Video](https://github.com/q0v0p/ChromaLinks/assets/18714906/38e4bc23-9743-4af7-a21c-8107c821fdaa)
[フル動画はこちら](https://www.youtube.com/watch?v=QBApBbkQu3M)

## 自己紹介
自動化/LEDウィザードを自称している

[テックニンジャ（TechNinja）](https://twitter.com/ZxlTechNinja)

と申します。
仕事や身の回りのことを自動化して楽しいこと創造的なことを生み出すことを目指して活動しております。
最近の悩みはハッカーあるある[^1]で自動化を頑張り過ぎて実装の方が大変なこともよくあります😅

## なにを作った？
ゲーミングPC（LEDがギラギラする系）を自作したことない人にはなんのこっちゃな話だと思いますが、自作PCをやってるとRazerやNZXT、コルセアといったメーカーが各々独自規格でLEDライトを制御するソフトウェアを出しており、それらは統一の規格がなくそれぞれのソフトウェアで動いているので同期することが出来ません。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3731353938362f30653666663838302d393739622d353837382d663232622d3366303236386162343966392e6a706567.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359903/58d7c2fa-99ec-a8cf-0f0b-5dd69ce02ad1.jpeg)


そこで今回C#を使って各ソフトウェアをコントロールしてライティングを同期する仕組みを作ってみました。
私がGitHubやRedditなんかを徘徊してもニーズがあるけどまだ解決策が出てないかなと思い実装しました。

現在のバージョンでは人気ケースNZXT H510Elite(Smart Device V2)で動作するものを作りました。
ー海外の開発者の方がNZXT Kraken Xシリーズに対応するものを開発されていたので

さっそくこんな感じになります。
　　
<iframe width="560" height="315" src="https://www.youtube.com/embed/QBApBbkQu3M" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
（Chroma Studioの反応が悪いのと配線が汚いのはご愛嬌ということでｗ）


あとその他の機能として、なぜかNZXT CAMは画面ロックするとLEDが消えるオプションが無いのでせっかくなのでその機能も実装しました。これで寝るときに眩しくならずに寝れるようになります笑

## 実装について
今回はC#/.Net6を使って実装しました。
使用したライブラリは主に
* NzxtRGB
* CUESDK
* ChromaControl
です。

```csharp:ColorChanged
private void _api_ColorChanged(object sender, RzChromaBroadcastColorChangedEventArgs e)
{
    if (_isLinkNZXT)
    {
        Color[] channel1Colors = Enumerable.Repeat(e.Colors[0], 16).ToArray();
        Color[] channel2Colors = Enumerable.Repeat(e.Colors[0], 16).ToArray();
        _smartDeviceV2.SendRGB(1, channel1Colors);
        _smartDeviceV2.SendRGB(2, channel2Colors);
    }
    if (_isLinkCorsair)
    {
        Color[] colors = e.Colors;
        for (int i = 0; i < _corsairDeviceCount; i++)
        {
            CorsairLedPositions deviceLeds = CorsairLightingSDK.GetLedPositionsByDeviceIndex(i);
            CorsairLedColor[] buffer = new CorsairLedColor[deviceLeds.NumberOfLeds];
            CorsairLedColor corsairLedColor = default(CorsairLedColor);
            corsairLedColor.R = colors[0].R;
            corsairLedColor.G = colors[0].G;
            corsairLedColor.B = colors[0].B;
            CorsairLedColor currentColor = corsairLedColor;
            for (int j = 0; j < deviceLeds.NumberOfLeds; j++)
            {
                buffer[j] = currentColor;
                buffer[j].LedId = deviceLeds.LedPosition[j].LedId;
            }
            CorsairLightingSDK.SetLedsColorsBufferByDeviceIndex(i, buffer);
            CorsairLightingSDK.SetLedsColorsFlushBuffer();
        }
    }
}
```

こんな感じでRazer Chromaから飛んでくるLEDのカラー情報を各デバイス用に変換して同期している形です。

コードはGitHubに公開しましたので興味ある方は参考にしてみてください。まだ不完全なところが多いので使用するより参考がいいと思います。（特にCorsair系のデバイスは怪しい…）

https://github.com/q0v0p/ChromaLinks

## まとめ
バラバラに光っていたLEDたちが強調して光るようになって個人的にはとてもすっきりしました。Razer Chroma Addressable RGB Controllerというライティングを拡張するデバイスを購入したので部屋全体を1台のPCでライティングをコントロールする仕組みを構築したいと思います！

## 最後に
とりあえずシェアしようの気持ちでコードを公開しているのでバグやご要望があれば[Twitter](https://twitter.com/ZxlTechNinja)までお気軽ご連絡してください。DMやフォローお待ちしております:clap_tone1:

[テックニンジャ🥷🏼](https://twitter.com/TechNinja_z)

## 参考

https://github.com/Sajyd/NZXTConnect

https://github.com/ChromaControl/ChromaControl

[^1]: _ハッカーこそ、怠惰であれ、短気であれ、傲慢であれ by Larry Wall_