jQuery コードリーディング その1
jQuery のソースコードを読んで、
jQueryとjavascriptを勉強する連載(予定)。
jQueryを使ったjavascriptプログラミングの勉強ではないです。
モチベーションはこれ
- ちょっとしたWebアプリを書けるようになりたい
- 美しいコードに触れたとき、涙があふれ、アメリカに行かなければと思った ──中島聡流プログラミングの原点 #OpenGL|CodeIQ MAGAZINE
最近はオープンソースにもいいものがあります。例えば、jQueryは僕がMicrosoftの外に出てから、一番美しいと思ったコードですね。
ブログ主のプログラム関連スペックはこんな
- Cはだいたいわかる
- Railsはさわったことがある。Herokuで自分用に動かしている簡単なアプリがある。
- javascriptは見よう見まねでコードを書いたことがある。生涯コード記述量は300行くらい。
jQueryのバージョンは現時点で最新の2.1.1を使う。
いつ終わるかわからないが、終わらせるまでやりたいと思う。
Pebble でWorldCupを楽しむ
2014 FIFA World Cup Brazil の試合スコアをライブ表示するPebble Appをつくってみた。
スコアが動くとブルッとします。多分動くと思う。
PCな方はこちら
Android/iOSな方はこちら
このあたりを使って作っています。感謝。
- Simply.js
- kimono : Turn websites into structured APIs from your browser in seconds
- LiveScore.com : Live World Cup Soccer / Football Scores
基本的にはこれと同じです。
Pebbleでサッカースコアライブ更新表示してみた - じんじろげのジロジロモニタ
最近のアクセス傾向
あいかわらずRaspberryPiが人気。特に監視カメラが人気みたいですね。ありがとうございます。
あとは、Pebbleも徐々にアクセスが増えてるみたい。
RaspberryPiにいろいろつないでみた
この記事は書きかけです
RaspberryPiを
にすることを目的にいろいろつなげるだけつないでみた。
RaspberryPiに
をつないでみた。
RaspberryPiにつないだArduino(ATMega328P-PU)に
をつないでみた。
RaspberryPiとArduino(ATMega328P-PU)の間は、SPI(スケッチ書き込み用)とシリアル通信でつないでみた。
各種デバイスをRaspberryPi, Arduinoのどっちにつなぐかはかなり適当です。
当初は、5V系デバイスはArduino, 3.3V系はRaspberryPiにするつもりでしたが必ずしもそうはなってないです。
GPIOでArduinoへスケッチ書き込み
ArduinoというかATMega328への書き込みと言った方が正確かも。
Gertboard | Arduino IDE Installation (ISP) | Gordons Projects
を実施
シリアル通信でArduinoと接続
ちょっとはまった。
何か送信できるけどうまく取り込めない。3.3V(RaspberryPi) <-> 5V(ATMega328)変換で結線ミスかPullUpが弱いのかと思って悩んだ。が、結局は、Getboard(という評価ボード)が12MHzなので、16MHzでATMega328を動かす場合は設定ファイルを書き換える必要があった。
以下を変更。
5V電源はGPIOから供給
RaspberryPiにつないだATMega328P-PUにサーボモータをつないでいるので、RaspberryPiの5V電源で十分な電流が流せる必要がある。
が、microUSB経由だとポリフューズがあるので700mAまでしか流せない(実際、microUSB電源供給でサーボモータを動かすとすぐ落ちる)。
色々調べるとGPIOの5Vに直結するのが良さそう。
なのでmicroUSBから電源供給しないで5V 2A のAC/DCアダプタをGPIO 5Vに直結することにした。
デジタル温度計
ここを参考に実装。
Raspberry Pi で温度センサ(DS18B20+)を読んでみた - 完全に個人的な備忘録
# 1-wireをarduinoで使えるようにもトライしてみたい気もするが
この記事は書きかけです
Chromecastを買いました
Chromecastを買いました。
Google Chromecast ( クロームキャスト ) Wi-Fi経由 テレビ接続 ストリーミング / HDMI / 802.11b/g/n / 1080p ) GA3A00035A16
- 出版社/メーカー: Google
- メディア: Personal Computers
- この商品を含むブログ (33件) を見る
chromecastに対応したアプリの情報をchromecastに飛ばしてテレビに表示させることができます。
セットアップは、PCをWiFiネットワークにつなげたことがあれば問題なくできると思うので省略します。
chromecastの機能のポイントは、
- chromecastに対応したアプリしかテレビに表示させることができない
- 対応アプリでは、PC/スマホからchromecastに映像を送るのではなく、chromecastがそのコンテンツをインターネットから持ってくる
です。(と、理解している)
ただ、2つ目に関しては、ローカルに保存した動画をPCのchromeブラウザで再生したらTVで見られたので、chromeブラウザで表示できるものはなんでもTVで見れると言う方が正しそうですね。でも、音がたまに途切れたりしたので、コンテンツによっては厳しそう。
全体構成のイメージはこんな感じです。
できることとかをまとめるとこんな感じだと思います。
勘違いがあれば、ご指摘ください。
現在できること
- PC(Windows/Linux。Macはすいませんよく知りません)
- ChromeブラウザにGoogle Cast - Chrome Web Storeをインストールすることで、chromeブラウザの画面を飛ばせるようになります。
- スマホ(android), iPhone/iPad
できないかと思いきやできること
できないこと
DVDをPCで再生してTVでみるコンテンツが自分のPCにしかないものは無理。もちろん、DVDと同じコンテンツがインターネット上から見れるなら話は別です。
手持ちの動画ファイルをPCで再生してTVでみる理由は同上と思っていたのですが、chromeブラウザで再生できるフォーマットだったらTVでみれた
#12/10追記 まだ正式機能ではないようだけど、デスクトップを転送できるので、↑は一応できるみたい。
ちょっと頑張るとできること
今のところのとても満足してます。
ひとつうれしい誤算だった(あんまりちゃんと考えいていなかったところなのです)のは、chromeで再生中のニコ動をchromecastに飛ばしてから、PCで別の作業を初めてもTVではニコ動が表示され続けるってことですね。
サブモニタ的な使い方もできる感じですね。
Pebbleでサッカースコアライブ更新表示してみた
Pebble Smartwatch | Smartwatch for iPhone & AndroidとSimply.jsででなんかできないかなぁと考えてみた。
わたし、サッカーをよく見るのですが、今開催されている試合の結果がリアルタイムで分かったら何か楽しそうなので、作ってみることにしました。
ワールドカップを来月開催されることだし。
まず、サッカースコアのライブ更新しているサイトを探すと以下が良さそう。
LiveScore Soccer : Live Soccer Scores by LiveScore.com
欧州リーグだけでなくJ1,J2,J3(!)もカバーしている。
もちろんワールドカップも。
このサイトから情報を取得するためのスクレイピングは、Javascriptに不慣れなのと、一度使って見たかった簡単にスクレイピングしてWebAPI化してくれるという
kimono : Turn websites into structured APIs from your browser in seconds
を使ってみたかったので、これでいく。
15分くらいで直感的にWebAPIができました。
以下がそのWebAPIで取得できるJ1の試合結果のJSONファイル。
https://www.kimonolabs.com/api/52h5eq42?apikey=664315ac6dd2128d90351faeb721fb63
また、Simply.jsの使い方は
ひとりぶろぐ » 2.0で面白くなったスマートウォッチPebbleを、JavaScriptゴリゴリでネット監視装置として使う
を参考にさせてもらいました。
あと、開発はCloudPebbleを利用してブラウザ上で実施。
ソースはこんな感じ。
ごちゃごちゃ書いてあるけど、やっていることは
#試し試しやっててかなり汚いです
#あと、タイムゾーンがあってないです
var api_uri = 'http://www.kimonolabs.com/api/52h5eq42?apikey=664315ac6dd2128d90351faeb721fb63'; var match_text = ''; //simply.title('J1 League'); //simply.style('small'); simply.scrollable(true); //simply.on('singleClick', function(e) { function refresh(opt) { if( opt.length > 0 ) { var league = opt.match(/kimpath2=(.*)&kimpath3=(.*)/); console.log('league[0]=' + league[0]); console.log('league[1]=' + league[1]); console.log('league[2]=' + league[2]); if( league.length == 3 ) { opt = '&kimpath2=' + league[1] + '&kimpath3=' + league[2]; } else { opt = ''; } } else { opt = ''; } api_uri_opt = api_uri + opt; ajax({ url: api_uri_opt, type: 'json' }, function(data) { var matches = data.results.collection1; var match_days = data.results.collection2; if( league.length == 3 ) { match_text += league[1] + '/' + league[2] + '\n'; } for(var i=0; i < match_days.length; i++) { match_text += match_days[i].match_day + ','; } match_text += '\n'; for(var i=0; i < matches.length; i++ ) { if( matches[i].score == "? - ?" ) { // not live score = ' ' + matches[i].score + ' '; } else { // live score = ' ' + matches[i].score.text + ' '; } match_text += matches[i].match_time + ': ' + matches[i].home_team_name + score + matches[i].away_team_name + '\n\n'; } simply.text({ body : match_text }); match_status = window.localStorage.getItem('match_status'); if( match_status != match_text ) { simply.vibe(); } window.localStorage.setItem('match_status', match_text); }); } simply.begin = function() { try{ var options = window.localStorage.getItem('options').split('/'); if( options.length > 0 ) { for(var i=0; i < options.length - 1; i++) { console.log('opt is = ' + options[i]); refresh(options[i]); } setInterval(refresh, 60000); } }catch(e){ concole.log(e); } }; // https://github.com/pebble-hacks/js-configure-demo/blob/master/src/js/pebble-js-app.js Pebble.addEventListener("showConfiguration", function(e) { console.log("showConfiguration!"); Pebble.openURL('https://dl.dropboxusercontent.com/u/9794530/pebble_soccer_live/config.html'); } ); Pebble.addEventListener("webviewclosed", function(e) { console.log("configuration closed"); // webview closed var options = JSON.parse(decodeURIComponent(e.response)); var opt_str = ''; console.log("Options = " + JSON.stringify(options)); for(var key in options) { if( options[key] == true ) { var path_list = key.split('/'); console.log('&kimpath2=' + path_list[1] + '&kimpath3=' + path_list[2] + '\n'); opt_str += '&kimpath2=' + path_list[1] + '&kimpath3=' + path_list[2] + '/'; } } window.localStorage.setItem('options', opt_str); });
で、Pebbleで表示はできたんだけど1つ問題が。
1分毎にスコアを更新したいのだけど、下記記事によると
Pebble Javascript Tips And Tricks
setInterval(refresh, 60000);
はあまりよくないらしい。
でも、上の記事にあることをやろうとすると、Simply.jsでは力不足で、
WatchAppをCで、SmartPhone側のアプリをJavascriptで書く必要があるみたい。
う~ん。
Raspberry Pi で監視カメラ
Raspberry PiにUSBのWebCameraをつけて室内の監視カメラにしてみました。
WebCameraはこれ
LOGICOOL ウェブカム HD画質 120万画素 C270
- 出版社/メーカー: ロジクール
- 発売日: 2010/08/20
- メディア: Personal Computers
- 購入: 21人 クリック: 267回
- この商品を含むブログ (20件) を見る
アプリは motion.
sudo apt-get install motion
使い方はここを参考に設定しました。
Linux + motion + webcamでライブ監視カメラを設置する
設定ファイルは /etc/motion/motion.conf。
変更した設定はこのあたり。
#この記事を書くために見直していたらtimelapse撮影/動画生成もあるみたい
# 静止画(JPEG)はbest shotのみ保存。 output_normal best # 別PCからWebCamera映像を見れるように webcam_localhost off # 制御は別PCからできるけどuser/passwordで制限をつける control_localhost off control_authentication user_name:password
これで
http://192.168.0.2:8081/ とかでWebCameraの映像が見れるようになります。
ただ、監視カメラの目的が自分が不在時の部屋の監視なので、自分が家にいるときは撮影しなくていい。
また、そのうちドメインを取って外部から見れるようにしたいので、なおさら自分が部屋にいるときは撮る必要がない。
# セキュリティ的な見直しは必要だけれども
そこで、「自分が部屋にいるか判定」にスマホのBlueTooth接続の有無で判断するにした。
部屋にいるときは、motion を stop、いないときは motion を start させる。
まず、BlueToothアダプタはこれを購入。
PLANEX Bluetooth USBアダプター Ver.4.0+EDR/LE(省エネ設計)対応 BT-Micro4
- 出版社/メーカー: プラネックス
- 発売日: 2012/02/10
- メディア: Personal Computers
- 購入: 3人 クリック: 9回
- この商品を含むブログを見る
インストールとスマホとのペアリングは、ここを参照して実施。特に問題なく完了。
Raspberry PiでBluetoothを扱う - Programming Log
自分で仕組みを作る前にぐぐってみると、デスクトップをオフ(スクリンセーバーモードに移行?)できるアプリはあった。ただ、今回の目的には使えなさそう。
第267回 Bluetoothデバイスで離席管理する:Ubuntu Weekly Recipe|gihyo.jp … 技術評論社
「自分が部屋にいるか判定」にスマホのBlueTooth接続の有無で判断する
のにどうすれば一番いいかよくわからないけど、
力技で l2ping でスマホのBlueToothから応答があれば、部屋にいると判定して motion のプロセスを止めることにした。こんな感じ。これをrootのcronで適当な間隔で回す。
#!/bin/bash # 実際はスマホのbluetoothアドレスを設定 bt_addr='XX:XX:XX:XX:XX:XX' resp_bt=`l2ping ${bt_addr} -c 1|grep ' 0% loss'` if [ ${#resp_bt} != 0 ]; then echo "bt remote device exist." service motion stop else echo "bt remote device doesn't exist." resp_motion=`ps auxww|grep '^motion.*/usr/bin/motion'` # echo ${#resp_motion} if [ ${#resp_motion} = 0 ]; then echo "motion isn't running." service motion start else echo "motion is aleady running." fi fi
# もっとスマートに書けると思うのだが...
2014/02/01 追記
- if-else文の中身が逆になってた(orz)のを直しました。すいません。
- /var/run/motion/motion.pid ファイルが存在している場合は、motion が起動していると判断する方がセオリーぽい。
2014/04/29 追記
- l2pingだとなぜか反応がないことがあるのでhcitool nameに変更。自分の環境ではこっちの方が安定動作しています。
- motionの起動チェックは、/var/run/motion/motion.pidの存在チェックに変更
#!/bin/bash # 実際はスマホのbluetoothアドレスを設定 bt_addr='XX:XX:XX:XX:XX:XX' #resp_bt=`l2ping ${bt_addr} -c 1|grep ' 0% loss'` resp_bt=`hcitool name ${bt_addr}` #echo ${#resp_bt} if [ ${#resp_bt} != 0 ]; then echo "bt remote device exist." service motion stop else echo "bt remote device doesn't exist." # resp_motion=`ps auxww|grep '^motion.*/usr/bin/motion'` # echo ${#resp_motion} if [ -e /var/run/motion/motion.pid ]; then echo "motion is aleady running." else echo "motion isn't running now." service motion start fi fi