【VRChat】 OSCでPC使用率をチャットボックスに送信する 

## はじめに

皆さん、VRChatをご存じですか？
VRChatとは、VR空間内で他ユーザーとの交流やイベントを楽しめる、ソーシャルVRプラットフォームです。しかし、私はVRChatを「エンジニアが自身の技術を存分に活かせる絶好の場」だと考えています。3Dモデリングやスクリプト制作、さらにはワールドの作成など、デジタル空間に自分のアイデアやクリエイティブを世界中のユーザーと共有できる場としても活用できると思いました。

今回の記事では、システムのリソース使用率（CPU、メモリ、GPU）を取得し、VRChatのチャットボックスに表示する方法をご紹介します。

## システムの使用率を取得する

以下のPythonライブラリを使用します。

psutil：CPUとメモリの情報を取得

pynvml：GPU（NVIDIA）の情報を取得

python-osc：OSCを使ってVRChatにデータを送信

インストールが必要な場合は、以下のコマンドを実行してください。


```
pip install psutil pynvml python-osc
```

## コード

以下が実際のプログラムです。このコードは、システム使用率を取得し、それをOSCプロトコルでVRChatに送信します。

```python
from pythonosc.udp_client import SimpleUDPClient
import psutil
import time
from pynvml import nvmlInit, nvmlDeviceGetHandleByIndex, nvmlDeviceGetUtilizationRates, nvmlDeviceGetMemoryInfo

def get_system_usage():
    # CPU使用率
    cpu_usage = psutil.cpu_percent(interval=1)
    
    # メモリ使用率
    memory = psutil.virtual_memory()
    memory_usage = memory.percent  # メモリ使用率 (%)
    total_memory = memory.total / (1024**3)  # 総メモリ (GB)
    used_memory = memory.used / (1024**3)  # 使用中メモリ (GB)
    
    # GPU使用率 (NVIDIA)
    try:
        nvmlInit()
    
        # GPU0の情報を取得
        handle = nvmlDeviceGetHandleByIndex(0)
        utilization = nvmlDeviceGetUtilizationRates(handle)
        memory_info = nvmlDeviceGetMemoryInfo(handle)
        gpu_usages = {
            "gpu_usage": utilization.gpu,  # GPU使用率 (%)
            "memory_usage": utilization.memory,  # GPUメモリ使用率 (%)
            "total_memory": memory_info.total / (1024**3),  # 総GPUメモリ (GB)
            "used_memory": memory_info.used / (1024**3),  # 使用中GPUメモリ (GB)
        }
    except Exception as e:
        gpu_usages = f"Error retrieving GPU information: {e}"

    return {
        "cpu_usage": cpu_usage,
        "memory_usage": memory_usage,
        "total_memory": total_memory,
        "used_memory": used_memory,
        "gpu_usages": gpu_usages,
    }

if __name__ == "__main__":
    # OSC送信先（VRChatのデフォルトアドレスとポート）
    ip = "127.0.0.1"
    port = 9000
    client = SimpleUDPClient(ip, port)

    while True:
        usage = get_system_usage()
        
        usageFormat = (
            f"CPU Usage : {usage['cpu_usage']:.2f}%\n"
            f"Memory Usage : {usage['memory_usage']:.2f}%\n"
            f"Used Memory : {usage['used_memory']:.2f}/{usage['total_memory']:.2f}GB\n"
            f"GPU Usage : {usage['gpu_usages']['gpu_usage']}%\n"
            f"GPU Memory Usage : {usage['gpu_usages']['memory_usage']}%\n"
            f"Used Memory : {usage['gpu_usages']['used_memory']:.2f} / {usage['gpu_usages']['total_memory']:.2f}GB\n"
        )

        #チャットボックスに送信
        client.send_message("/chatbox/input", [usageFormat, 1])

        time.sleep(10)

```
## コード解説

### 1. システム使用率の取得

CPU使用率: psutil.cpu_percent(interval=1) を使用。

メモリ使用率: psutil.virtual_memory() から詳細情報を取得。

GPU使用率: pynvml を使用してNVIDIAのGPU情報を取得。

### 2. OSCプロトコルを使用してVRChatに送信

SimpleUDPClient を使い、VRChatのデフォルトアドレス (127.0.0.1) とポート (9000) にデータを送信。

/chatbox/input エンドポイントを指定して、フォーマットした使用率情報を送信します。

### 3. 実行ループ

10秒ごとにシステムの使用率を取得し、更新されたデータをVRChatに送信します。

### 動作確認

https://x.com/yato__zz/status/1873170738049585551

よく見るとGPU Memory UsageとGPU Used Memoryの比率が一致していないです...
もしメモリの使用率を正確に把握したい場合は、used_memory / total_memory * 100の比率を自前で計算するほうが良いかもしれないです。