KLab若手エンジニアの これなぁに?

KLab株式会社の若手エンジニアによる技術ブログです。phpやRubyなどの汎用LLやJavaScript/actionScript等のクライアントサイドの内容、MySQL等のデータベース、その他フレームワークまで幅広く面白い情報を発信します。

2010年06月

高層ビルオフィスで使う電波時計

特に若くもないuchikawa-yです。はじめまして。 KLabの「自由に研究していい」どぶろく制度でやったことを紹介します。 発端 電波時計はJJY(日本の標準電波)等の時刻情報の放送を受信して時刻合わせを行います。この放送は鉄筋コンクリートの建物内ではかなり弱くなるので電波時計はマンションやオフィスビル内では使えない場合が多いです(このことを知らない人が多いのも事実です)。 日本標準時プロジェクト Q&A 日本標準時プロジェクト 標準電波(電波時計)の運用状況 弊社におきましても以下のようなことが起きたことがあります
  1. 会議室などに設置する時計に電波時計を購入した
  2. 初期状態で手動などで正確な時刻を設定したのでしばらくは正常に使える
  3. JJYが受信できないのでそのうちに時刻がずれる 異常動作で大きくずれた時刻を表示したものもあった
  4. 「故障した」と判断されて何台かは廃棄された
悲しい事件ですね。この後、私の雑な調査によれば本社オフィスでは電波時計が正常に動作するのは窓から2~3m程度の範囲に限られることがわかりました。 展開 鉄筋コンクリートの建物内で電波時計を使うための中継装置というものがあります。 Webで調べたところリズム時計工業という会社がJJYの中継装置を製造、CITIZENブランドで販売しているようです。通販などでは入手もできるよう です。 これは2万円程度するようなのでもっと安くなんとかする方法はないか考えました。 思いついたのは外部アンテナを使う方法です。外部アンテナをJJYの電波を受信可能な場所に設置し、同軸ケーブルなどの有線で電波時計の場所 まで送ります。電波時計とケーブルの間は数ターンのコイルで結合させます(具体的には電波時計に内蔵されているアンテナのありそうな部分に導線を巻きつけ ます)。 空中線(アンテナ) JJYの放送局は日本に2ヶ所あります。福島県から40kHz、福岡県から60kHzで放送されています。東京の場合福島県の40kHzを主に利用しま す。これは長波と呼ばれる帯域で、通常は中波ラジオで使われるようなバーアンテナやループアンテナを使用します。今回は無調整で使用できて、バーアンテナ よりも性能の良いものが作れるマグネチックループアンテナを作ってみました。 これは以下のページに詳しい内容があります。 作成したアンテナは不平衡型です。 受信専用マグネチック・ループアンテナ 配線用のダクトをフレームにしました。サイズは(62cm×48cm)です。これに同軸ケーブル(1.5D-2V)を5回巻いたものをアンテナにして います。 電波時計との間のケーブルも1.5D-2Vです。 ケーブルの特性についてはたとえば 古川電工 メタルケーブルの「同軸ケーブル・高周波同軸ケーブル」のページにある詳細PDFが参考になります。 1.5D-2Vの減衰量は周波数が低くなるほど少なくなり、1MHzで24dB/kmです。つまり100m引き回した場合、減衰は50%以下です。JJYはさらに1桁周波数が低いので室内での使用に限れば気にするほどの減衰はないと思います。 マグネチックループアンテナは通常のループアンテナとは異なりループ面と平行方向に最大感度の指向性を持ちます。 社内のいくつかの場所で試したところ西側や北側に窓のある場所でもアンテナの最大感度方向を窓に向けた場合に高い受信感度が得られることがわかりました。
[caption id="" align="alignnone" width="506" caption="アンテナ"]
アンテナ
[/caption]


実験 市販のクロックタイプの電波時計を使って実験してみました。
[caption id="" align="alignnone" width="512" caption="市販の電波時計(アンテナなし)"]
市販の電波時計(アンテナなし)
[/caption]


窓からほんの4mほどのところにあるテーブルの上においた電波時計です。電池を一度抜いて完全にリセットかけています。1月1日木曜日だそうで調べてみると2009年のようです。1時間ほど置いてありますがこのように現在の時刻を表示してくれません。 次に先ほどのアンテナを窓際に設置(「実験中」の張り紙をして窓際にあるテーブルの下に立てました。ケーブルは他の社員が足を引っ掛けないようテープで床に固定です)して電波時計に接続します。 接続といってもアンテナのケーブルに細めの導線をつないで輪にして数回時計に巻きつけてあるだけです。
[caption id="" align="alignnone" width="512" caption="市販の電波時計(アンテナ接続)"]
市販の電波時計(アンテナ接続)
[/caption]


ごらんの通りに正常に現在時刻が表示されています。なお時計の液晶面右上にある「~~」のような波型表示は受信インジケータらしいです。 外部アンテナを使う方法の有用性が証明できました。 裏側 実は市販の時計を使って確認するのはやりにくいです。設置してしばらく待たないと正常に受信できているかどうかわかりませんし、受信インジケータの表示もアンテナの設置方向を決めるには粒度が荒すぎてあまり役には立ちません。 なので試行錯誤している段階では自作のJJY受信機とトライステート社の 電波時計キット を併用しています。 JJY受信機については以下のページで紹介されているもののコピーです。 長波JJY受信機の製作 こちらでは「手持ちの部品に合わせて作った」というようなことが書かれています。私もOPアンプの入手しやすさや手持ちの部品に合わせて多少アレンジしています。
[caption id="" align="alignnone" width="512" caption="キットの電波時計をアンテナにつないで時刻データを取得"]
キットの電波時計
[/caption]


[caption id="" align="alignnone" width="365" caption="自作のJJY受信機"]
自作のJJY受信機
[/caption]


とあるOAuthのtwitterクライアント

umjammer です、 今月末で Twitter API は BASIC 認証を廃止して OAuth オンリーに移行するみたいですね。以前ソーシャルアプリ関連で OAuth を調べていたときに Twitter も試していたのでその時の成果物を公開します。ずいぶん前のことなので忘れていました。危うく旬を逃すところでした。 では、順を追って OAuth を使用した Twitter デスクトップクライアントの作り方を説明します。 Twitter クライアント用のコンシューマーキー、シークレットの取得
  1. この URL で Twitter クライアントアプリ申請を行う
  2. 今回はデスクトップアプリなのでブラウザではない方のチェックボックスをチェックしておく
    twi1


  3. 設定を保存すると画面が変わり、コンシューマーキー、シークレットを取得できる
  4. 同時にアクセストークンリクエストや認可画面URLも取得
    twi2


アクセストークンリクエストや認可画面URLは後述の TwitterOAuthProvider.java で使用しています。 Twitter クライアント用のアクセストークン、シークレットの取得 さきほど取得したコンシューマーキー、シークレットを使用してアクセストークンとシークレットを取得します。Twitter の OAuth のアクセストークンとシークレットは期限が設けられていないみたいですので一回取得すれば今のところずっと使用可能です。 流れとしては、
  1. コンシューマーキー、シークレットを引数にして認可画面をリクエスト
  2. 認可画面のURLが帰ってくる
    tw3


  3. URLの画面をブラウザ上で表示し認可を行なう
  4. ブラウザ画面上にベリファイアが表示される
    tw4


  5. ベリファイアを引数にアクセストークン、シークレットをリクエスト
  6. アクセストークン、シークレットを取得
な感じになります。コードにすると以下になります。

        String consumerKey = "xxxxxxxxxxxxxxxxxxxx";
        String consumerSecret = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";
        
        // コンシューマーを生成
        OAuthUtil oauth = new OAuthUtil(new OAuthConsumer("oob", consumerKey, consumerSecret, new TwitterOAuthProvider()));
        // リクエストトークンを取得
        oauth.doGettingRequestToken();

        // 認可のURLを取得
        System.out.println("以下のURLをブラウザで開いてください。");
        System.out.println(oauth.getAuthorizationURL());

        // アクセストークンを取得
        System.out.print("ベリファイアを入力: ");
        oauth.doGettingAccessToken(oauth.readLineFromStdin());

        // 
        System.out.println("accessToken: " + oauth.getAccessToken());
        System.out.println("tokenSecret: " + oauth.getAccessTokenSecret());

Twitter クライアントの作成 アクセストークン、シークレットを取得したところでようやくクライアント作成にかかれます。今回は便利なライブラリ twitter4j を使用しました。今まで取得したキーを引数に API を呼んでやるとサクっと投稿アプリが作れます。あとは GUI 頑張るだけです。


        String consumerKey = "xxxxxxxxxxxxxxxxxxxxx";
        String consumerSecret = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";

        String accessTokenString = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
        String tokenSecretString = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";

        TwitterFactory factory = new TwitterFactory();
        Twitter twitter = factory.getInstance();
        twitter.setOAuthConsumer(consumerKey, consumerSecret);
        AccessToken accessToken = new AccessToken(accessTokenString, tokenSecretString);
        twitter.setOAuthAccessToken(accessToken);

        Status status = twitter.updateStatus(statusString);
        System.out.println("Successfully updated the status to [" + status.getText() + "].");

結果です、クライアント名が今回作成したアプリケーション名になっているでしょう?
tw5


今回使用したその他のコードとライブラリ OAuthUtil.java
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URISyntaxException; import java.util.HashMap; import java.util.Map; import net.oauth.OAuth; import net.oauth.OAuthAccessor; import net.oauth.OAuthConsumer; import net.oauth.OAuthException; import net.oauth.OAuthMessage; import net.oauth.client.OAuthClient; import net.oauth.client.httpclient4.HttpClient4; /** * OAuthUtil. */ public class OAuthUtil { /** */ protected OAuthConsumer consumer; /** */ protected OAuthClient client; /** */ public OAuthUtil(OAuthConsumer consumer) { this.consumer = consumer; this.client = new OAuthClient(new HttpClient4()); } /** * リクエストトークンを取得する。 */ public void doGettingRequestToken() throws IOException, OAuthException, URISyntaxException { doGettingRequestToken(null); } /** * @before {@link #doGettingRequestToken(Map)} */ private OAuthAccessor requestAccessor; /** * リクエストトークンを取得する。 * * http://.../oauth/request_token */ public void doGettingRequestToken(Map
TwitterOAuthProvider.java
import net.oauth.OAuthServiceProvider; /** * TwitterOAuthProvider. */ public class TwitterOAuthProvider extends OAuthServiceProvider { public TwitterOAuthProvider() { super("http://twitter.com/oauth/request_token", "http://twitter.com/oauth/authorize", "http://twitter.com/oauth/access_token"); } }
その他のライブラリ
  • net.oauth.core/oauth-20090617
  • net.oauth.core/oauth-consumer-20090617
  • net.oauth.core/oauth-httpclient4-20090617
  • net.homeip.yusuke/twitter4j-core-2.1.*
まとめ OAuth や Twitter API にはライブラリが揃っていますので簡単に OAuth アプリが作れました。 ただ OAuth を使用したデスクトップクライアントソフトにはここに書かれているような問題があります。悪用すればクライアントなりすましも可能でしょう。 以前紹介した OpenFeint API も OAuth を使用しています。iPhone や iPad のアプリは .ipa ファイルとして iTunes ライブラリに保存されていますが、単なる .zip ファイルなので解凍して中を覗くことができます。皆さん暗号化とかされてるみたいですのでまだシークレットキーを発見したことはないのですが、リバースエンジニアリングされればもしかすると発見できるかもしれません。そうなるとハイスコア改ざんやトロフィーコンプリートなども簡単にできちゃいます。 私もいろいろ考えたのですがいい回避策が思いつきません。皆さんなにか良い知恵があればお教えください。あとは OAuth WRAP に期待ですか。 訂正 2010-06-18 一枚目の画像が説明と異なっていたので差し替えました。
 KLab若手エンジニアブログのフッター