Raspberry Pi

Raspberry Pi で Nintendo Switch を自動化!単純作業を効率化しちゃおう

2022年4月16日

Raspberry Pi で Nintendo Switch を自動化!単純作業を効率化しちゃおう

こんにちは。ポン吉です。

妻が女神転生5に超ハマっているようで、深夜に永遠と香集めマラソン(ひたすらアイテムを拾い集める苦行)を実施して寝不足とのこと。

心を無にして不毛な時間を費やしているご様子。こりゃいかん。ゲーマー生産性向上?を図るべく自動化しようと思います。

ポン吉

うちは家族全員ゲーム大好き一家です!

調べたところ、ArduinoによるNintendo Switch自動化が主流のようです。

ラズパイでも「joycontrol-pluginloader」を使えば追加機器は一切不要で自動化が可能です。joycontrol 用プラグインローダの開発者Almtrさんありがとうございます!


ラズパイ & Nintendo Switchを持っているそこのアナタ!既に必要なものはすべて揃っています。

こちらの記事を読めば誰でもNintendo Switchの操作を自動化できるようになります。

今回のテーマはこちら!

  • Raspberry PiだけでNintendo Switchの操作を自動化してみる
  • 「レベル上げ、レアアイテム集め」といった不毛な単純作業を人類から解放する!
  • どこまで自動化できるのか?実用性を評価! ※【次回記事にて詳細化】

ラズパイに導入する上でうまく動かずかなり悩んだポイントが多かったです。誰でも動かせる手順をまとめて公開したいと思います。

それではやってみましょう~♪

Nintendo Switch自動化に必要なもの

Nintendo Switch本体とラズパイがあればOK!

ラズパイ自体も品薄で購入が難しい状況が続いています。ラズパイの在庫と価格をリアルタイム確認できるページを作りました。ラズパイを購入しようとしている方は是非参考にしてみてください。

Raspberry Pi OS への joycontrol-pluginloader インストール

インストール セットアップ 初期設定

ラズパイ自体も品薄で購入が難しい状況が続いています。ラズパイの在庫と価格をリアルタイム確認できるページを作りました。ラズパイを購入しようとしている方は是非参考にしてみてください。


 

必要パッケージをインストール

sudo apt update
sudo apt install -y python3-pip
sudo apt install -y git
sudo apt install -y python3-dbus
sudo apt install -y libhidapi-hidraw0
sudo apt install -y libbluetooth-dev
sudo apt install -y bluez 

Rasbperry Pi OSの初期インストール状態から、上記コマンド実行で必要パッケージはすべてインストールできると思います。

joycontrol / joycontrol-pluginloaderをインストール

cd ~/
git clone https://github.com/mart1nro/joycontrol.git
sudo pip install joycontrol/
git clone --recursive https://github.com/Almtr/joycontrol-pluginloader.git
sudo pip install joycontrol-pluginloader/

git cloneで持ってきてpipでインストール。必要なpythonパッケージも一緒にインストールされます。

sudo で pip install しているのは joycontrolがroot権限で実行する必要があるためです

 

Raspberry Pi 内蔵BluetoothのMACアドレスを変更

以下、GitHubのissues情報によるとNintendo Switchコントローラ関連機器は「94:58:CB:」から始まるMACアドレスにする必要があるようです。また、相性問題があり動かないBluetooth機器もある模様。ちなみにラズパイ3,4の内蔵Bluetoothは動作OK。

外付けUSBのBluetoothだと記事にあるようなbccmdコマンド等で変更できるのですが、ラズパイの内蔵Bluetoothの場合はエラーになります。試行錯誤した結果、以下のhcitoolコマンドで無事変更することができました。

# 事前にBluetoothのMACアドレスをチェックしておく(デバイス名 hciX を確認)
hciconfig

# BluetoothのMACアドレスをNintendo Switchが認識するアドレス帯に変更
sudo hcitool -i hci0 cmd 0x04 0x009
sudo hcitool -i hci0 cmd 0x3f 0x001 0x56 0x34 0x12 0xCB 0x58 0x94
sudo systemctl restart bluetooth.service

# BluetoothのMACアドレスが変わったかチェック(UP RUNNINGになるのに少し待つかも)
hciconfig

hciconfigコマンドの実行結果が hci0 とデバイス1つだった場合、 hcitoolコマンドの -i hci0 オプションは省略可能です

注意

BluetoothのMACアドレス変更についてはラズパイを再起動すると元に戻ってしまうので注意。再起動時にシェル等で再度実行するようにした方がよいと思います。

 

Bluetooth設定を変更

# ファイル編集できればどんなコマンドでもOK
sudo vi /lib/systemd/system/bluetooth.service

/lib/systemd/system/bluetooth.serviceのファイルで、ExecStart=の行について赤字部分のオプションを指定するように変更。更新後にBuletoothサービス再起動します。

 : 中略 
[Service]
Type=dbus
BusName=org.bluez
ExecStart=/usr/libexec/bluetooth/bluetoothd -C -P sap,input,avrcp
 : 中略

# bluetoothサービスの設定変更を再読み込みさせて再起動
sudo systemctl daemon-reload
sudo systemctl restart bluetooth.service

サービス再起動後bluetooth.serviceがエラーメッセージが出力していますが、動作に支障はないので先に進みます。

Nintendo Switchとのペアリング

ここがタイミング依存が絡む?のか難関なポイントとなります。以下の順番に従いペアリングを実行してみましょう。

ペアリング実行順番

  • joycontrol-pluginloaderでペアリング用のpythonプログラムを実行
  • Nintendo Switch側で [設定] ⇒ [コントローラとセンサー] ⇒ [コントローラの持ち方/順番を変える] を選択
  • しばらくするとペアリング成功 ※ここで無応答になる事が多い

それでは順番にやっていきましょう。

cd joycontrol-pluginloader/
sudo joycontrol-pluginloader plugins/tests/PairingController.py

[21:52:34] joycontrol.device set_name::69 INFO - setting device name to Pro Controller…
[21:52:34] joycontrol.server create_hid_server::83 INFO - Advertising the Bluetooth SDP record…
[21:52:34] joycontrol.device set_class::61 INFO - setting device class to 0x002508…
[21:52:34] joycontrol.server create_hid_server::96 INFO - Waiting for Switch to connect… Please open the "Change Grip/Order" menu.

上記、コマンド実行後に Waiting for Switch to connect… と接続待ち状態になります。次にNinotendo Switch側の操作に移ります。

[設定] ⇒ [コントローラとセンサー] ⇒ [コントローラの持ち方/順番を変える]
この画面になったらペアリングされることを祈る(笑)

 
しばらくするとプログラムの標準出力が動き出しペアリングを実行。ペアリング成功後は自動的に切断されます。1分ほど待っても動きがない場合は下記をお試しください。

うまくいかない場合の手順

  • pythonプログラムをCTRL+Cで終了させる
  • Nintendo Switch側もコントローラ接続して待ち画面を終了させる
  • Raspberry Piで bluetoothctlコマンドを実行してペアリング情報を確認
  • 何故か登録済となっているNintendo Switchペアリング情報を削除
  • 再度、ペアリング処理を実行して成功するまで繰り返す

python側ではペアリングできていないのに何故かペアリング済となってしまっているので削除してリトライします

bluetoothのペアリング情報の確認と削除については、下記実行例を参考にしてください。赤字部分はお持ちのNintendo Switch側のMACアドレスになりますので、remove時には適切置き換えて実行してください。

>_ command

bluetoothctl
[bluetooth]# paired-devices
Device XX:XX:XX:XX:XX:XX Nintendo Switch
[Nintendo Switch]# remove XX:XX:XX:XX:XX:XX
Device has been removed
[bluetooth]#   (CTRL+Cで終了)

ペアリング済みのステータスにはなっているのですが、接続と切断を繰り返している挙動になっていることがありました。

なーんか上手くいかないなぁ!イライラ

読者
ポン吉

焦らずリトライすればペアリングできるので頑張って!

 

joycontrol-pluginloader の動かし方

コーディング・チューニング

Bluetoothのペアリングが出来ればあとは動かすだけ!ボタン入力テストを実施しサンプルプログラムを動かします。 

Nintendo Switch のボタン入力テスト

Nintendo Switch側で [設定] ⇒ [コントローラとセンサー] ⇒ [入力デバイスの動作チェック] [ボタンの動作チェック] を選択

[設定] ⇒ [コントローラとセンサー] ⇒ [入力デバイスの動作チェック] 
[ボタンの動作チェック] を選択
ボタン入力の確認画面になったら使用していたコントローラを切断

ここで使っていたNintendo Switchのコントローラの電源をOFFにする必要があります。OFFにしないと各種自動化のプログラムは動かないので注意

nintendo switch controller

コントローラの内側側面に「押しにくい小さな黒いボタン」があります。このボタンを押すとコントローラの電源ON/OFFができます。LEDの点灯/無点灯でON/OFFを確認しましょう。

>_ command

cd ~/joycontrol-pluginloader/
sudo joycontrol-pluginloader -r XX:XX:XX:XX:XX:XX plugins/tests/TestControllerButtons.py

赤字部分のNintendo SwitchのMACアドレスは機器ごとに異なります。bluetoothctlコマンドのpaired-devicesにて確認した値で置き換えてください。

無事にコマンドが入力されれば、ラズパイからNintendo Switchの制御が可能な状態となりました!

サンプルプログラムの実行方法

サンプルプログラムは「~/joycontrol-pluginloader/plugins/samples」ディレクトリに入っています。左コントローラの「a」を押して「下▼」を押すだけのサンプルです。

>_ command

cd ~/joycontrol-pluginloader/
sudo joycontrol-pluginloader -r XX:XX:XX:XX:XX:XX plugins/samples/SamplePlugin.py

赤字部分のNintendo SwitchのMACアドレスは機器ごとに異なります。bluetoothctlコマンドのpaired-devicesにて確認した値で置き換えてください。

プログラム実行前に、コントローラの電源が切れていることを確認しましょう(よく忘れがち

import logging
from JoycontrolPlugin import JoycontrolPlugin

logger = logging.getLogger(__name__)

class SamplePlugin(JoycontrolPlugin):
    async def run(self):
        logger.info('This is sample joycontrol plugin!')

        logger.info(f'Plugin Options: {self.options}')

        logger.info('Push the A Button')
        await self.button_push('a')
        await self.wait(0.3)

        logger.info('Tilt the left stick down')
        await self.left_stick('down')
        await self.wait(0.3)

このpythonソースをベースにしてコマンド入力やスリープを組み合わせて処理を作ることになります。

SamplePlugin.pyをpenguin.pyという名前でコピーして・・
あれ動かないぞ!ムキー!!

読者
ポン吉

pythonのクラス名をコピー後のファイル名
変更する必要があるので注意。(サンプルの6行目)

 

コマンドリスト

ボタンを押す動作については以下のようにプログラムを記載します。

await self.button_push('a')      # Aボタンを押す(押してすぐ離す操作)
await self.wait(0.3)                  # 0.3秒待つ

await self.button_press('up')     # 上ボタンを押しっぱなしにする
await self.wait(5.0)                  # 5.0秒待つ(5秒上ボタンを押しっぱなし)
await self.button_release('up')    # 押しっぱなしにしていた上ボタンを離す
await self.wait(0.3)                  # 0.3秒待つ

await self.button_push('a', 'b')      # AボタンとBボタンを同時に押す(複数のボタンを指定可能)
await self.wait(0.3)                  # 0.3秒待つ

Nintendo Switchのボタンとプログラムで指定するキーを一覧にしてみました。

左コントローラ

Nintendo Switch コントローラボタン名 Pythonプログラムで指定するボタン名
上ボタン up
下ボタン down
右ボタン right
左ボタン left
Lボタン l
ZLボタン zl
◎(左アナログスティックを押し込んだ時) l_stick
ー(マイナス) minus

 

右コントローラ

Nintendo Switch コントローラボタン名 Pythonプログラムで指定するボタン名
Aボタン a
Bボタン b
Xボタン x
Yボタン y
Rボタン r
ZRボタン zr
◎(左アナログスティックを押し込んだ時) r_stick
ー(マイナス) plus

 

左右のアナログスティックは次のように使います。

# 方向を直接指定(up, down, right, left, centerから指定)
await self.right_stick('up')

# 角度を指定
angle=90
self.right_stick(angle=angle)

# 角度とパワーを指定
angle=90
power = self.max_stick_power / 2    # 最大値の半分のパワー
self.right_stick(angle=angle, power=power)

# 左アナログスティックはrightをleftに変えたものを指定
await self.left_stick('up')

どこまでNintendo Switchを自動化できるのか?実用性を検証

まとめ

長くなったので細かい検証は別ページにて記載予定。大まかな評価だけ記載します。

コマンドが遅延したり抜け落ちたりする場合あり

いろいろと動かしてテストしていくとわかるのですが遅延や抜け等がまれに発生します。あまりシビアな操作を必要としない、RPG等が自動化対象になるかなと思います。

まとめ

  • 特別なハードも不要でNintendo Switchの制御が可能
  • Bluetooth通信にやや不安定な部分があり、コントロール操作に遅延が出る点はマイナス
  • 家族の無駄ゲーム時間の削減は大いに期待できる!!(スクリプト作るのも大いに時間かかるけどね)
ポン吉

ペアリング部分は何度かリトライする前提でがんばろう~

おまけ

真女神転生5で香集めマラソンを完全自動化し、寝ている間にがっつりドーピングしたアモンさんを紹介。全ステータス999!メギドフレイムですべて焼き尽くせます(笑)宝石交換もクイーンメイブさんの場所まで移動し、全ての宝石交換まで完全自動化済みです。

女神転生5アモン

Switch自動化はこれから

今回はサンプルプログラム実行までになりますが、将来的にNintendo Switchのあらゆるゲームに適用可能な自動化スクリプトとして整備していきましょう。自動化スクリプト実装ではBluetooth故の不安定挙動があるため、ややコツがいるのですが別記事で投稿予定です。

-Raspberry Pi