twitterから自宅の蛍光灯を制御してみました
やるに至った背景は,
部屋の模様替えをした際に,配置上壁にある蛍光灯のスイッチにアクセスできなくなってしまいました.
蛍光灯はリモコン制御のLED照明なので,部屋中どこからでもリモコンで制御可能ですが,
その辺に転がって紛失しそうであったため,入口に常設することにしました.
しかし,これだとベッドに寝ころびながら電気を消せない!!
ということで思い切ってtwitterから制御してみることにしました
システム構成はこんな感じ
ソフトウェアはProcessingとTwitter APIであるTwitter 4jを利用.
IRLED制御のための制御基盤にはArduino Uno互換で安価なSainSmart Unoを利用しました.
ソースコードはこちら
Processing
Arduino
実行結果はこんな感じ
Twitterから蛍光灯制御出来た!! pic.twitter.com/kJN06aEMia
— Ryla (@utautattaro) March 27, 2016
点灯もいける pic.twitter.com/jMl7pZBwUl
— Ryla (@utautattaro) March 27, 2016
リモコンの主ボタンが
全灯→常夜灯→消灯 を繰り返す使用になっていたので
twitterでのつぶやきをそのボタンに割り当てました.
開発の際にいろいろ起きた問題をまとめます.
1.キーワードをツイートして○○する的なTIPSが見つからない
Processingからつぶやく類のTIPSは多くの方が先にやられていて
ノウハウも残されているのに対し,Twitterをトリガーに使う例はなかなか見つかりませんでした…
タイムラインを取得するプログラムは発見したので,それを応用してごちゃごちゃやってみました.
Twitter.getUserTimeline();メソッドで自分自身(consumerKeyの取得元)アカウントのタイムラインを取得します.
get(N)で上からNつめのツイート情報を取得.
日時やリンクといった情報も格納されているので,さらにgetText()でストリング型でツイート本体をString型で取得できます.
それをstring.equals(string)で比較すると,トリガーとして利用可能!
コードに起こすとこんな感じ
statusesはListになっています.
2.Twitterは連投できない仕様になっている
Twitterは同一ツイートの連投はできない仕様になっています.
これは,手入力の場合も,システムからつぶやく場合も同じ
完全一致の場合のみはじかれるようです.
数十分待つか,
別のツイートを10回挟むかしなければならないようです.
この仕様は,ツイートをトリガーとする場合とても面倒!
トリガーとなるキーワードを数個用意するとか,indexOf()メソッドを使用して
キーワードを部分一致にするとかいろいろ方法はありますが,スマートではありません.
そこで今回は,トリガーを検出したら対象のツイートをシステムから削除する方法で解決しました.
ツイートの削除にはTwitter.destroyStatus()メソッドを利用します.
引数にはツイートのIDが入ります.ツイートのリンクURLを取得した際に
最後のほうにある長い数字の羅列です.
ツイートIDの取得は簡単で,get(N)で目的のツイートを取得,それにgetId()で取得することができます.
こんな感じ.これをキーワード認識の次の処理に加えることで,認識した瞬間消去する仕様となり,同一ツイートの連投が可能となります.
連続投稿不可の仕様だけど
Processingによりツイートを即時削除しているので連投可能
削除のスピードにTwitterアプリが追いついていない
ちなみにキーワードは#Lightness0326 にした。0326はコード書いた日 pic.twitter.com/3MV3x9X8ii— Ryla (@utautattaro) March 26, 2016
3.TwitterのAPI制限に引っかかる(Error Code:429)
ツイートを検出したら,と処理をするのが理想ですが,
TwitterAPIの仕様上,タイムラインを取得→処理という仕様ですので,
システムからアクセスしに行く設計となります.
その際に気になるのがインターバル.リアルタイムである必要はありませんが,
比較的即時性が求められると思うので,その辺を調査してみました.
インターバルを短めに設定すると,こんなエラーが
エラーコード429 案の定API制限系のエラーっぽいです.
429は更新間隔が短すぎてAPI使い切った場合に出るメッセージです。更新間隔を長くするか、できるだけUserStreamをご利用ください QT @naporinokani 一度TLタブを閉じて再び作成してもリクエストエラー(429)が出て更新しない
— もふったー (@mofooter) June 3, 2013
なるほどなるほど.じゃあその制限ぎりぎりを突いてみましょう.
TwitterAPI Reference-API Rate Limits-によると
15 Minute Windows
Rate limits are divided into 15 minute intervals. Additionally, all endpoints require authentication, so there is no concept of unauthenticated calls and rate limits.
There are two initial buckets available for GET requests: 15 calls every 15 minutes, and 180 calls every 15 minutes.
だそうです.
15分で180回ということは,1分に12回,5秒に1回が天井ということだそうです.
ということでインターバルを5秒に設定することで解決できました~.
4.いちいちツイートするのもめんどくさい
キーワードは普段使わなそうな長めのものにしたため,いちいち打ち込むのがめんどくさい….
そのためツイートするだけのWebページを作りました.
当初の目標はGUIでリモコンライクな画面があって,押すとその通りにうごいて…みたいな感じでしたが
とりあえずα版ということで本家のツイートボタン作成ページで作成.1分くらいでできました.
面倒くさかったのでTwitterが提供してるシェアボタンでα版は実装
— Ryla (@utautattaro) March 27, 2016
確認画面煩わしいなー pic.twitter.com/1GVxNPYaQv
— Ryla (@utautattaro) March 27, 2016
5.Processing-シリアル通信用パッケージを使用したプロジェクトは64bit版exeがうごかない
そのまんま.
ProcessingにはExPort機能があるのでexeは当然吐けるのですが,
Arduinoと通信の処理を加えた瞬間64bit版exeが実行不能に.
おそらくProcessing付属のSerial Libraryが64bit版不対応みたいです.32bit版で動いたからよかった
6.いちいち常夜灯になるのが煩わしい
リモコンが全灯→常夜灯→消灯となっている仕様上,
常夜灯を毎回挟み,2回送らねばならなかったのが煩わしかったので,
SainSmartにcdsセルをつけて,照度を取得,現在の蛍光灯のステータスによって,
赤外線信号を1回送るか,delay(100)を挟んで2回送るかを切り替え解決.
全灯時は2回送信して 消灯に
消灯時は1回送信して 全灯に
cdsセルを買いにきた (@ 秋月電子通商 秋葉原店 in 千代田区, 東京都) t.co/sqYxPIYdnO
— Ryla (@utautattaro) March 27, 2016
はまったところはこのあたりです.
シリアル通信や学習リモコン等は先駆者の方々がわかりやすいエントリを残してくださったので
サクサクっとできました.ありがとうございます.
参考サイト
最後に,ソースコードはすべて下のGitにあげておきます.
github.com/TsudaRyotaro/public/tree/master/ControlRoomLight
よきライフハックを!
20160815追記
ノーメンテだったがまだ生きていた
Twitterから蛍光灯制御、まだ生きていた pic.twitter.com/mas4evVo18
— Ryla (@utautattaro) August 14, 2016