【MATLAB】ThingSpeakでコンマ秒の精度で指定時間に自動ツイート

ThingSpeakを用いて,コンマ秒の精度で指定時間に自動ツイートするMATLABのコードを作成しました

なぜ投稿時刻にこだわるのか

決まった文字列をいかにミリ秒単位で時刻ぴったしに投稿できるかというTwitter上の競技に自動投稿で参戦したいと思ったからです

確認できる限りでは,「301」,「334」,「448」という3つの競技が毎日開催され,その競技の名前の時刻で競技名をツイートし,その時刻(334なら午前3時34分00.000秒)の近さで競います

その時刻より前にツイートするとフライングとなり順位は付きません

334

334の集計結果のツイートは下のような感じです

ミリ秒単位の激しい争いです

開始0.000秒から約30ミリ秒までがランクインし,特別に334位と0.334秒がいれば順位に表示されますが,ここではそれは狙いません

適当な文字列のリプを送ると結果を知ることが出来ます

301

334はかなり激しい闘いですが,301と448は比較的緩いです

301では1秒遅れても30位程度でランクインします

448

448では参加者が15人程度で,時には10秒以上遅れてもランクインします

334と301の集計結果ではTwitterクライアントも表示されていますが,ほとんどがiPhoneやiPadから手動のようです

筆者は何回かTweetDeckの予約ツイート機能を使って参戦していましたが,決まって0.21~0.30秒遅れ,分単位までしか設定できないため,334ではランクインから程遠い結果になっていました

301,448では同じような位置にしかランクインしないため,面白みがありません

そんな訳で,この競技のプロはほとんどの人が手動でツイートしています(上の集計結果でTweetDeckの方も表示されていますが,それはTweetDeckから手動で投稿していると思われます)

 

そこで,今回はThingSpeakを用いて自動投稿することにしました

ThingSpeakのThingTweetというアプリでは,自分のPCからPOSTすると自動で連携したTwitterアカウントで投稿します

PCの方のプログラムではミリ秒くらいの細かさで指定できます

(下にも書きましたが,POSTの時刻がミリ秒の精度でもツイートされるまでの時間差に0.1秒程度の幅があります)

ThingSpeak公式HP: IoT Analytics - ThingSpeak Internet of Things

実行結果

先に結果から書くと

  • POSTしてからツイートされるまでの時間差を1.1秒〜1.3秒に収めるのが限界

本番3競技×7日分の時間差の分布は下のような分布になっていました

(2.079 s, 1.795 s遅れたものは外れ値として除外しました)

正規分布にフィットさせたときのその平均値は1.168 sで,標準偏差は0.087 sでした

(まだデータ数が少なく感じるのでまたしばらくしたら更新します)

f:id:monhime:20200312072409p:plain:w500

なので実行するときには,ある程度確率が高くフライングを少なめにしたあたりで設定し,あとは運に任せます

POSTする時刻はミリ秒程度の精度を持っていて,TweetDeckよりはるかに細かく設定できるようになりましたが,この時間差の幅のため,必ずしも手動ツイートより上位を狙えるというわけではありません

しかし,TweetDeckよりかは大抵上位に入りますし,感覚ではなく数字でタイミングを調整するのでかなりやりやすいです

精度を高くする工夫

  • 本番の投稿前に予め2回(約20秒前と約5秒前)ツイートをしておく

POSTしてからツイートされるまでの時間差は,直近のPOSTしなかった時間に大きく依存していることが分かりました

1時間以上間隔を空けてからPOSTすると4.1〜4.4秒遅れ,3分空けると約2.0~2.4秒遅れ,間隔を10秒以内にすると殆どが1.1~1.3秒以内に収まりました

そのため,本番の投稿前の約5秒前に予めツイートし,その事前のツイートが大幅に遅れて本番の投稿に影響が出ないよう,さらにその約15秒前にも事前にツイートしておくことにしました

具体的な方法は,20秒前の投稿まで1秒毎に時刻を取得し,その時刻になったら投稿,さらに14秒待って約5秒前の投稿という感じです

この時点で最大1秒の誤差があります

 

  • 本番の投稿のタイミングの調整には,指定した時刻までの時間差を用いる

下が5秒前の投稿の後に本番の投稿まで待機し,タイミングを調整する部分のコードです

pause(etime(t(i,:),clock)-margin);

etime(t(i,:),clock)が指定した時刻までの時間差(単位は秒)です

tは指定時刻のタイムベクトル(行ベクトル)を4つ格納した行列です

公式のドキュメンテーションには明記されていませんが,コマンドウィンドウで実行すると5秒差程度であれば0.1ミリ秒の位まで表示されるので,かなり精度が良いはずです

参考:日付ベクトル間の経過時間 - MATLAB etime - MathWorks 日本

これによりプログラム実行開始時の最大1秒の誤差を吸収し,指定した時刻とPOSTの時間差は変数marginの値のみに依存します

あとはmarginを微調整すればOK

準備

ThingSpeakでチャネルを作成

こちらの記事で詳しく説明されています

データを簡単に保存&グラフ化できるThingSpeakが便利! - iwathiの/var/log

上の記事中では「Make Public」という項目がチャネルを作成する画面であったそうですが,今は変更してあり,デフォルトでは非公開になっています(チャネルを作成後,「Sharing」から公開設定が出来ます)

Tweet機能のみを今回は使うので,Fieldは作成しなくても大丈夫です

API keyの取得

画面上のメニューのApps>Thins Tweet を選んで,連携したいTwitterアカウントで認証すると,簡単にAPI keyを取得できます

f:id:monhime:20200305110139p:plain:w200

f:id:monhime:20200305110322p:plain:w500

ソースコード(自動ツイート)

MATLABのコードです

ご自由にお使い下さい

コードを見る(クリックして下さい)

コンマ秒の精度でThingSpeak経由で自動ツイート

 

ツイートを投稿する部分のコードは下のQiitaの記事からお借りしました

【ThingSpeak x MATLAB】 MATLAB Answers の新着質問をお知らせするTwitter bot 実装 - Qiita

実行する際の注意点

  • セクション「接続設定」の「api_key」には上で取得したapi_keyを入力して下さい

  • 301,334,448の他,テストツイートとして実行開始日の22時10分に"test"という投稿をします.それまでに実行を開始するか,テストツイートの時刻を遅くして下さい.

  • テストツイートは実行開始日,301,334,448は次の日付になっていることに注意して下さい

  • 実行開始後はPCが自動でスリープしないようにして下さい(Mac PCの場合は,省エネ設定で「可能な場合はハードディスクをスリープさせる」のチェックを外し,「ディスプレイがオフの時にコンピュータを自動でスリープさせない」をチェック,「ディスプレイをオフにするまでの時間」を「しない」の位置に合わせ,実行開始後は画面の明るさを1にします)

  • ルータやPCの電源ケーブルをつないだ状態にして下さい

  • 既に設定してあるmarginの値は,筆者のネット環境の場合なので,自分の環境に合わせて設定し直してください

競技に参加しなくても,msec_botという指定したツイートの投稿時刻をミリ秒単位で教えてくれるbotがあるのでそれを使うのがおすすめです

twitter.com

ソースコード(時間差の分析)

POSTからツイートまでの時間差を正規分布にフィッティングします

上の大見出し「実行結果」に載せたグラフを描写します

また,フィッティングした確率分布において,指定した時間差の値におけるcdf値と,指定したcdf値となる時間差の値を求めることができます

実行すると下のようにコマンドウィンドウに表示されます

>> rank334_hist
  NormalDistribution

  正規 分布
       mu =   1.15544   [1.10422, 1.20666]
    sigma = 0.0666354   [0.0450094, 0.127658]

t=1.138sでのcdf値p=0.39674
cdf値p=0.1となるt=1.07

コードを見る(クリックして下さい)

POSTからツイートまでの時間差の分析