定期的にスピードテストを実施して回線速度を記録する

- 我が家の回線が異様に遅かった。
    - NTT東フレッツ光(ファミリー・ハイスピードタイプ)+YahooBB
    - ベストエフォートは下り200Mbps
    - 21時～0時ごろでこんな感じ
    - ![変更前スピードテスト](https://qiita-image-store.s3.amazonaws.com/0/64415/56359a3e-3c1d-e179-e0a1-8e545bfa14a5.png)
    - まるで速度制限中のスマホ回線……
- 毎日ポチポチ手動でやるのがめんどくさい。
- 朝昼早いけど実際きちんと記録していないので本当に夜遅いのか確証がない。
- じゃぁ定期的にやるか！ってなった。

## やること

- 定期的にスピードテストを実施(PC起動しっぱなし)
- Googleスプレッドシートに記録
- グラフを見てニヤニヤする

## 注意事項

- 筆者はGASもPowerShellも普段使ってないのでググりながら書いている
- 理解が浅いのでいやいやこんな書き方しないでしょってこともあるのでコピペ非推奨
- 失敗しても実害ないので例外処理は書いてない

## 完成図

![データシート](https://qiita-image-store.s3.amazonaws.com/0/64415/0a2fcbc8-46b5-a363-ea9e-fcea479419e7.png)

![グラフシート](https://qiita-image-store.s3.amazonaws.com/0/64415/c836e9d8-77a0-ae3c-d205-96049bce1542.png)

## スプレッドシートの用意

- ヘッダは日付＋時
- スクリプトエディタを開いてこんな感じのスクリプトを書く

```speedtest.js
var prop = PropertiesService.getScriptProperties();
var verifyToken = prop.getProperty('VERIFY_TOKEN');
var sheetId = prop.getProperty('SHEET_ID');
var sheetName = prop.getProperty('SHEET_NAME');

function doPost(e) {
  if (verifyToken !== e.parameter.token) {
    throw new Error('invalid token.');
  }
  var json = JSON.parse(e.parameter.data);
  var ss = SpreadsheetApp.openById(sheetId);
  var sh = ss.getSheetByName(sheetName);
  var lastrow = sh.getLastRow();
  if (lastrow === 1) {
    sh.insertRowAfter(lastrow);
    lastrow++;
    sh.getRange(lastrow, 1).setValue(json.date);
  } else {
    var lastdate = Utilities.formatDate(sh.getRange(lastrow, 1).getValue(), 'Asia/Tokyo', 'yyyy-MM-dd');
    if (lastdate !== json.date) {
      sh.insertRowAfter(lastrow);
      lastrow++;
      sh.getRange(lastrow, 1).setValue(json.date);
    }
  }
  sh.getRange(lastrow, json.hour + 2).setNumberFormat('#,##0').setValue(json.speed);
  return ContentService.createTextOutput('OK');
}

//function test() {
//  var e = {};
//  e.parameter = {};
//  e.parameter.token = verifyToken;
//  e.parameter.data = '{"date":"2017-11-01","hour":0,"speed":105189}';
//  return doPost(e);
//}

```

- プロジェクトのプロパティ→スクリプトのプロパティを開いて以下を登録
    - `VERIFY_TOKEN`：認証用謎の文字列
    - `SHEET_ID`：スプレッドシートのID
    - `SHEET_NAME`：データ記録用のシート名

## スピードテストの定期実行

- スピードテスト自体は [zpeters/speedtest](https://github.com/zpeters/speedtest) を使わせてもらう
- 実行ディレクトリにlogフォルダを作っておく
    - なかったら多分ログ出力が失敗する
    - 失敗するけど処理は続行されたと思う
- タスクスケジューラで1時間ごとに以下を実施

```speedtest.ps1
# GASで公開したスクリプトのURL 
$URL = "https://script.google.com/macros/s/GASのID/exec"
# 認証用謎の文字列(GASのVERIFY_TOKENと合わせる)
$TOKEN = "XXXXXXXXXXXXXXXX"
# 実行回数(失敗したりたまに遅かったりするので3回ぐらい実施しておく)
$TRY_COUNT = 3

$now = Get-Date
$date = $now.ToString("yyyy-MM-dd")
$hour = [int]($now.ToString("HH"))

$path = Split-Path -Parent $MyInvocation.MyCommand.Path
$logfile = "$path\log\$date.log"

$result = @()
for ($i = 0; $i -lt $TRY_COUNT; $i++) {
    $spdTest = iex "$path\speedtest-64-speed-issues.exe -do -r"
    Write-Host $spdTest
    $spdTest | Add-Content $logfile -Encoding UTF8
    $result += [int]($spdTest.Split('|')[4])
}

# 降順ソートで最速値を取得
$result = $result | sort -Descending
$max = $result[0]

$json = "{""date"":""$date"",""hour"":$hour,""speed"":$max}"
Write-Host $json

wget -Uri $URL -Method POST -Body @{token=$TOKEN;data=$json}

```

## 感想

- 作った時にはNUROに乗り換え済みなので、いい感じの速度出ているが、乗り換え前から動かしておきたかった。
- NURO速いという噂は聞いていたけど、元の回線がベストエフォートの1000分の1も出ていなかったので、2Gbpsといっても実際は……という不安があったが、測ってみて1日中安定して速度でているようなで一安心。
- 今になってそれっぽい記事を見つけた。http://buzzap.jp/news/20171104-soumu-flets-ntt-isp/
- 思ってたほど時間による速度差がないので計測頻度減らしてもいいかも。
- 2017/11/04の23時が0になっているのは3回連続失敗したっぽい。
    - このあたりは同じサーバにつながらないようにしたほうが良かったかも。
    - とはいえ割といい結果が出ているので変更するモチベーションがない。