インターネット回線の安定性を計測

投稿日:

更新日:

カテゴリ:

最近自宅のインターネット回線が非常に不安定です。どのぐらいかというと、Teams会議の音声が途切れ途切れになるぐらいです。

ちなみに、私今使っている回線はa◯ひかりのホーム5ギガです。

モデムの5Gbpsの口からCAT7(10Gbps)のLANケーブル使って部屋すぐ外にある無線ルーターとつなぎ、無線ルーターはWiFi 6E対応ですが、2.5GbpsのWANですので、理論最大2.5Gbpsになります。

ところで実測値は、高い時500~600Mbps、低い時100Mbps未満の時だってあります。

問い合わせしてモデムを変えてもらい、無線ルーターも自分で買い替え、パソコンで試したり、スマホで試したりしましたが、やっぱり早かったり遅かったりです。

そういうわけで、どんな時が遅いのか、規則性ないのかを確認するため、簡易な計測スクリプト作って溜まったデータをグラフ化にしてみました。

※2024/02/20追記:プロバイダ変更後の続編があり、スクリプトの一部問題も発覚しましたので、合わせてご確認ください。

測定計測ツール

SPEEDTEST® CLIを使います。

公式にはインストール手順が書かれてますので、ここでは割愛します。

実行コマンドはspeedtestだけでも行けますが、整形したJSON形式で出すには以下のコマンドになります。

speedtest -f json-pretty

実行結果はこんな感じです。

{
    "type": "result",
    "timestamp": "2024-02-01T16:10:13Z",
    "ping": {
        "jitter": 51.665,
        "latency": 9.638,
        "low": 5.676,
        "high": 212.335
    },
    "download": {
        "bandwidth": 75583800,
        "bytes": 912997499,
        "elapsed": 12712,
        "latency": {
            "iqm": 19.684,
            "low": 7.491,
            "high": 233.161,
            "jitter": 7.163
        }
    },
    "upload": {
        "bandwidth": 60794931,
        "bytes": 773419127,
        "elapsed": 15000,
        "latency": {
            "iqm": 8.508,
            "low": 4.243,
            "high": 387.352,
            "jitter": 6.013
        }
    },
    "packetLoss": 13.75,
    "isp": "au one net",
    "interface": {
        "internalIp": "240f:103:cc85:1:dda4:245b:723c:dd77",
        "name": "en1",
        "macAddr": "5C:1B:F4:8D:5F:07",
        "isVpn": false,
        "externalIp": "240f:103:cc85:1:dda4:245b:723c:dd77"
    },
    "server": {
        "id": 21569,
        "host": "jp.as.speedtest.i3d.net",
        "port": 8080,
        "name": "i3D.net",
        "location": "Tokyo",
        "country": "Japan",
        "ip": "2a00:1633:3400::213"
    },
    "result": {
        "id": "be525837-729b-4fb7-b435-3e6dc47137ad",
        "url": "https://www.speedtest.net/result/c/be525837-729b-4fb7-b435-3e6dc47137ad",
        "persisted": true
    }
}

参考2を頼りに、速度はbandwidthのところの数値であり、単位はBytes/sだと分かりました。

速度計測スクリプト

上のツールを呼び出すだけなので、シェルだけでも作れるはずですが、JSON解析の便宜上、参考1をもとに次のPythonスクリプトを作成しました。

import json
import logging
import subprocess
import time

logging.basicConfig(filename="speed.log", encoding="utf-8", level=logging.DEBUG)

server_id = "21569" # `speedtest -L`の実行結果にあるIDを適当に選んでます


def get_speedtest_result():
    try:
        process = subprocess.run(
            ["speedtest", "-s", server_id, "-f", "json"],
            capture_output=True,
        )
        return json.loads(process.stdout)
    except Exception as e:
        logging.error(e)
        return None


def bytes2mega_bits(bytes):
    return bytes / 1024 / 1024 * 8


while 1:
    result = get_speedtest_result()
    # print(result)
    logging.debug(result)
    if result:
        timestamp = result.get("timestamp")
        download = result.get("download")
        upload = result.get("upload")
        if timestamp and download and upload:
            logging.info(
                "%s,%s,%s",
                timestamp,
                bytes2mega_bits(download.get("bandwidth")),
                bytes2mega_bits(upload.get("bandwidth")),
            )
        else:
            logging.error("Speed test result missing download or upload bytes")
    else:
        logging.error("no result")

    time.sleep(240)

参考1では、resultで返ってくるものの想定が現時点とは異なり、その修正が必要でした。

また、サイズの計算をMbpsに合わせることにして、記録をログに出すようにしてます。

実行すると、4分おきに測定します。

最初は1分にしてましたが、エラーになり、度々中断することになったので、処理時間をあわせて大体5分間隔になるように4分にしています。

この間隔は各自の環境に合わせて調整してみてください。

実行してしばらくするログが溜まりますので、grep "INFO:root:" speed.logとかでCSVっぽい形式で結果が取れます。

 

結果グラフ

私の環境で計測した結果グラフはこちらです。

2日分ぐらい取ってますが、途中エラーで止まりソースを直したり、パソコンがスリープして止まったりして、X軸の時間を見ていただければ分かる通り、断続的であることをご了承ください。

感覚ではこれほどいい数字出てない気がしますが、まあ、不安定さは伝わるでしょう。

また、記事の趣旨としては私の環境がどうというよりも、皆さんもこの方法で自分の環境の安定さを可視化できることですので、一旦やり方は書けたかなと思います。

ということで、私はインターネットのプロバイダーを乗り換えますが、この記事がお役に立てたら嬉しいです。

参考

  1. PythonでWiFiの速度計測をする
  2. Understand ookla speedtest json values

投稿日

カテゴリー:

投稿者:

タグ:

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です