ルーター設定をPythonで自動化する

はじめに

理由あって、インターネットの接続方法をPPPoEモードで接続する必要がある状況になりました。しかし、PPPoE接続を利用したインターネット接続サービスは、通信速度が遅いため特殊な状況以外はIPv6接続で利用をしたいです。
毎回手動で設定を変えるのは億劫なため、python使って自動化しようと思った次第です。
※通信方式や、詳しいことについて詳しくないのでこの対処法がベストかどうかがわからないかは不明です。
初期設定↔︎PPPoEモード切り替えるものとなります

PPPoEモードで接続する必要がある状況とは

結論から言うと「スプラトゥーン3」が原因です。

同じ回線に接続したSwitch 2台でオープンマッチをするとき、同じ部屋で遊ぼうとするとエラーコード「2318-0522」が表示され、ほとんど遊べません

任天堂からは
「本エラーは、ネットワークの混雑などが原因でIPアドレスの処理が正しくできなかったときに表示されます。しばらく時間をあけてから、あらためてお試しください。」
https://support-jp.nintendo.com/app/answers/detail/a_id/37926/~/【switch】エラーコード「2318-0522」が表示されました。どうしたらいいですか?

ということなのですが、時間をおいてもどうも解決しませんでした。
調べてみるとどうやら、WiFiの通信方式とSwitchはPPPoEにしか対応していないことなど、かみ合いが悪さをしているようでした。
(間違ってたらすみません)

Pythonのseleniumを使用して切り替えを楽に

オープンマッチはやりたい。けど普段使いで遅い回線は嫌だ、でも毎回切り替えるのはめんどくさい。
そんな自分のために設定の切り替えを自動化しました。

自分の回線は以下の通りです。
回線:ドコモ光
プロバイダ:GMOとくとくBB
ルーター:Aterm WX3600HP

NECのルーター設定は「http://192.168.10.1」に接続することでブラウザ上で変更することができます。
そのため、今回はseleniumで自動でログインし、設定を行います。

Pythonの環境構築とChromeのインストールができている前提で話を進めます。

特に深い意味はありませんが、パブリックの環境をいじるのがあまり好きじゃないので、仮想環境を作成し、有効化します。

python -m venv venv
venv\Scripts\activate

必要なライブラリをインストール

pip install selenium webdriver-manager

※Chromeのバージョンを気にするほどマメではないのでwebdriver-managerもいれます
実際のコードは下記通り

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import Select, WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
import time


def get_user_mode():
    # 設定するモードを聞く
    print("設定するモードを選択してください:")
    print("1:オープンモード (PPPoEルータ)")
    print("2:Xマッチモード (v6プラス)")
    while True:
        try:
            mode = int(input("モードを選択 (1または2): "))
            if mode == 1 or mode == 2:
                return mode
            else:
                print("無効な選択です。1または2を入力してください。")
        except ValueError:
            print("無効な入力です。数字で入力してください。")


def login_to_SettingWifi(driver):
    print("ログイン")
    driver.get("http://192.168.10.1/page/login_main.html?return=index_contents.html")
    # ユーザー名を入力
    user_input = driver.find_element(By.ID, "USER_ID")
    user_input.clear()
    user_input.send_keys("ここにはログインIDを")

    # パスワードを入力
    password_input = driver.find_element(By.ID, "PASSWORD")
    password_input.clear()
    password_input.send_keys("ここにはパスワードを")

    # ログインボタンをクリック
    login_button = driver.find_element(By.CSS_SELECTOR, "a.btn.blue")
    login_button.click()

    # 少し待機(必要に応じて)
    time.sleep(3)
    print("ログインできました。")


def navigate_and_set_mode(driver, mode):
    print("基本設定ページへ移動")
    # 基本設定リンクをクリック
    basic_settings_link = driver.find_element(By.CSS_SELECTOR, "a.linkMark")
    basic_settings_link.click()

    # ページが移動するので少し待機
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "SYS_MODE")))

    print("動作モードを選択")
    # モードに応じてセレクトボックスの値を選択
    select_element = Select(driver.find_element(By.ID, "SYS_MODE"))
    if mode == 1:
        select_element.select_by_value("pppoe")  # PPPoEルータ
        print("PPPoEルータを選択しました。")
    elif mode == 2:
        select_element.select_by_value("mapeJpne")  # v6プラス
        print("v6プラスを選択しました。")

    # 「設定」ボタンをクリック
    submit_button = driver.find_element(By.CSS_SELECTOR, "a.btn.blue")
    submit_button.click()

    # 設定反映の待機(必要なら)
    time.sleep(3)
    print("設定を適用しました。")

    # 「OK」ボタンをクリック
    ok_button = driver.find_element(By.CSS_SELECTOR, "a.btn.blue.small")
    ok_button.click()

    print("リダイレクトを待機中...")
    # リダイレクトを確認
    target_url = driver.current_url
    # タイムアウト時間を設定
    timeout = 45
    elapsed_time = 0

    while elapsed_time < timeout:
        # 現在のURLをチェック
        if driver.current_url != target_url:
            print("設定が完了し、目的の画面に遷移しました。スクリプトを終了します。")
            return
        time.sleep(1)
        elapsed_time += 1

    print("タイムアウト: URLが変更されませんでした。手動で確認してください。")


# メイン処理
if __name__ == "__main__":
    # ユーザーにモードを選択させる
    selected_mode = get_user_mode()

    # ChromeDriverのパスを取得
    driver_service = Service(ChromeDriverManager().install())
    # WebDriverを初期化
    driver = webdriver.Chrome(service=driver_service)

    # 設定サイトへのログイン
    login_to_SettingWifi(driver)

    # 基本設定を実行する関数を呼び出し
    navigate_and_set_mode(driver, selected_mode)

    driver.quit()

毎回実行するために仮想環境を起動したり実行するコマンドを打ち込むのも面倒なためバッチファイルを作成して、実行します。
先ほどのスクリプトを「Src」フォルダを作成し、「AutoSetting.py」という名前を付けて保存しました。

@echo off
REM 仮想環境を有効化
cd 仮想環境のパス
call venv\Scripts\activate

REM スクリプトを実行
python src\AutoSetting.py

REM 仮想環境を無効化
deactivate
pause

使い方

作成したBatファイルをダブルクリックして、
最初に変更したい接続モードが聞かれます。
1はオープンで遊びたい時
2はXマッチで遊びたい時に選択します。

しばらくまてば選択した接続モードに切り替えてくれます。
進捗状況は随時、出力するように心がけていますが、逆にわかりずらいかもしれません。
(切り替え時にネットの接続が切れるかもしれません。)

おわり

今回は僕自身が通信方式や、各種設定に明るくないため、ネットで同様の症例の方が行っていた、接続モードを切り替えることで問題を回避しました。しかし、PPPoE接続モードでは、混雑時に極端に回線が遅いこと(プレイ中にラグが出ること)の問題を解決できたわけではないので別の対策も講じたいところです。
ネット対戦のため、自分だけでなく相手にも味方にも迷惑をかけることになるので、できれば回線はしっかりしたかったのが本音。
居住地の問題もあり仕方がないとは思いつつ、回線の乗り換えも視野に入れて改善を試みたいところあります。

スクリプトも、終了の仕方があまりに拙いため、リダイレクト処理を綺麗に待ちたいところでもあります。
(実際の運用で困ったことがないのでそのまま放置していますが…)

今回は「自分はこうしたよ」という備忘録として残しておきます。

いいなと思ったら応援しよう!