THE TECHTROID BOX 2 〜システム概要
●動作の流れ
人感センサとQRコード
モニタへ映された携帯からのアクセス情報
CDトレイが向かい側のイジェクトボタンを押す |
A. 人感センサにより、人が近づくと動作開始。 1. 人が接近 ↓ 2. 人感センサが反応 ↓ 3. 電源ON ↓ 4. CDドライブのイジェクトボタンと同じ働きをするリレースイッチがON ↓ 5. 最下部のCDドライブのトレイが開く ↓ 6. CDドライブトレイが開く力で、向かい側のCDイジェクトボタンを押す ↓ 7. それを繰り返すことによって、CDドライブトレイが連続して開く
B. 携帯電話よりQRコードを読み取ることで動作開始。 1. QRコードを読み取る ↓ 2. 会場外サーバ:携帯サイトへ接続 ↓ 3. 会場外サーバ:携帯からのアクセス情報をXMLで書き出し ↓ 4. 会場内サーバ:携帯アクセス情報XMLを取得、モニタへ表示 ↓ 5. 会場内サーバ:CDトレイイジェクト命令 ↓ 6. 最下部のCDドライブのトレイが開く ↓ 7. CDドライブトレイが開く力で、向かい側のCDイジェクトボタンを押す ↓ 8. それを繰り返すことによって、CDドライブトレイが連続して開く
|
●QRコードからアクセスする携帯サイト(会場外サーバ)のプログラム
・トップページ(HTML部は省略)
[codesyntax lang="php" title="index.php"]
<?php include "log_writer.php"; include "analyze.php"; include "outdata.php"; print $last_record; ?>
[/codesyntax]
・アクセスログ記録
[codesyntax lang="php" title="log_writer.php"]
<?php //現在の日付を取得 $time1 = gmdate("Y/m/d",time()+60*60*9); //現在の時刻を取得 $time2 = gmdate("H:i",time()+60*60*9); //日付の取得 $time3 = date("D",time()+60*60*9); //カウンタ値取得、書き込み $counter_file = 'counter.txt'; $counter_lenght = 8; $fp = fopen($counter_file, 'r+'); if ($fp){ if (flock($fp, LOCK_EX)){ $counter = fgets($fp, $counter_lenght); $counter++; rewind($fp); if (fwrite($fp, $counter) === FALSE){ print('ファイル書き込みに失敗しました'); } flock($fp, LOCK_UN); } } fclose($fp); //アクセス解析ログ記録 $log_file = 'log.cgi'; $log = $counter."\t".$time1."\t".$time2."\t".htmlspecialchars(getenv('REMOTE_ADDR'))."\t".htmlspecialchars(getenv('REMOTE_HOST'))."\t".htmlspecialchars(getenv('HTTP_USER_AGENT'))."\n"; $last_record = "<b>Count:</b>".$counter."<br><b>Date:</b>".$time1." ".$time2."<br><b>RemoteAddr:</b>".htmlspecialchars(getenv('REMOTE_ADDR'))."<br><b>RemoteHost:</b>".htmlspecialchars(getenv('REMOTE_HOST'))."<br><b>UserAgent:</b>".htmlspecialchars(getenv('HTTP_USER_AGENT'))."<br>"; $fp = fopen($log_file,"a+"); if (!$fp) { print("ファイルポインタのオープンに失敗しました。\n"); exit; } //ファイルの排他ロック if (!flock($fp,2)) { print("ファイルロックに失敗しました。\n"); exit; } //ファイルに書き込み fseek($fp,SEEK_SET); if (!fputs($fp,$log)) { print("書き込みに失敗しました。\n"); exit; } //ファイルのロック解放 if (!flock($fp,3)) { print("ファイルロックの解放に失敗しました。\n"); exit; } fclose($fp); ?>
[/codesyntax]
・携帯キャリア解析
[codesyntax lang="php" title="analyze.php"]
<?php $log_file = 'log.cgi'; $fp = fopen($log_file,"r"); $row = 5; $num = 0; while (!feof($fp)) { $line = fgets($fp); $num++; } fclose($fp); if($num - $row >= $row){ $row = $num - $row; } //////// ACCESS LOG //////// $num = 0; $log =""; $other=0;$softbank=0;$docomo=0;$au =0;$ddi=0;$willcom=0;$ipod=0;$iphone=0;$mac=0;$windows=0; $fp = fopen($log_file,"r"); while (!feof($fp)) { $line = fgets($fp); if($line==""){ break; } if(preg_match("/Macintosh/is", $line)){ $mac++; }elseif(preg_match("/Windows/is", $line)){ $windows++; }elseif(preg_match("/iPod/is", $line)){ $ipod++; }elseif(preg_match("/iPhone/is", $line)){ $iphone++; }elseif(preg_match("/DoCoMo/is", $line)){ $docomo++; }elseif(preg_match("/J-PHONE/is", $line)){ $softbank++; }elseif(preg_match("/Vodafone/is", $line)){ $softbank++; }elseif(preg_match("/SoftBank/is", $line)){ $softbank++; }elseif(preg_match("/KDDI/is", $line)){ $au++; }elseif(preg_match("/UP.Browser/is", $line)){ $au++; }elseif(preg_match("/DDIPOCKET/is", $line)){ $ddi++; }elseif(preg_match("/WILLCOM/is", $line)){ $willcom++; }elseif(preg_match("/PDA/is", $line)){ $pda++; }elseif(preg_match("/Mozilla/is", $line)){ $other++; }else{ $other++; } list($o_count,$o_day,$o_time,$o_ip,$o_host,$o_ua) = explode("\t",$line); if($num >= $row-1){ $log = $log.$o_day." ".$o_time."\r".$o_ip."\r".$o_host."\r".$o_ua.""."*************************************\r"; } $num++; } fclose($fp); //////// Carrier / OS //////// if($docomo>0){$carrier = "DoCoMo : ".$docomo."\r";} if($softbank>0){$carrier = $carrier."SoftBank : ".$softbank."\r";} if($au>0){$carrier = $carrier."AU : ".$au."\r";} if($willcom>0){$carrier = $carrier."Willcom : ".$willcom."\r";} if($ddi>0){$carrier = $carrier."DDI Pocket : ".$ddi."\r";} if($ipod>0){$carrier = $carrier."iPod : ".$ipod."\r";} if($iphone>0){$carrier = $carrier."iPhone : ".$iphone."\r";} if($pda>0){$carrier = $carrier."PDA : ".$pda."\r";} if($windows>0){$carrier = $carrier."Windows : ".$windows."\r";} if($mac>0){$carrier = $carrier."MacOS : ".$mac."\r";} if($other>0 ){$carrier = $carrier."Other : ".$other."\r";} ?>
[/codesyntax]
・アクセスログ
[codesyntax lang="text" title="log.cgi"]
494 2010/02/22 17:01 124.146.175.15 proxyag015.docomo.ne.jp DoCoMo/2.0 N904i(c100;TB;W30H20) 495 2010/02/22 17:38 126.250.158.168 pw126250158168.10.tss.panda-world.ne.jp Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0_1 like Mac OS X; ja-jp) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A400 Safari/528.16 496 2010/02/22 17:39 126.250.158.168 pw126250158168.10.tss.panda-world.ne.jp Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0_1 like Mac OS X; ja-jp) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A400 Safari/528.16 497 2010/02/22 17:41 210.153.84.118 proxy1164.docomo.ne.jp DoCoMo/2.0 N904i(c100;TB;W30H20) 498 2010/02/23 07:50 66.249.71.218 crawl-66-249-71-218.googlebot.com Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) 499 2010/02/23 10:51 114.148.27.178 p4178-ipbf2404souka.saitama.ocn.ne.jp Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_1; ja-jp) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9 500 2010/02/23 11:27 219.108.157.78 wb47proxy06.ezweb.ne.jp KDDI-KC38 UP.Browser/6.2.0.11.1.2.2e (GUI) MMP/2.0 501 2010/02/23 11:39 222.5.63.230 wb22proxy09.ezweb.ne.jp KDDI-SA36 UP.Browser/6.2.0.10.2.1 (GUI) MMP/2.0 502 2010/02/23 13:13 210.153.84.100 proxy1108.docomo.ne.jp DoCoMo/2.0 F02B(c500;TB;W24H16) 503 2010/02/23 17:41 123.108.237.25 w11.jp-t.ne.jp SoftBank/1.0/930SH/SHJ001/SN353689020294206 Browser/NetFront/3.4 Profile/MIDP-2.0 Configuration/CLDC-1.1 504 2010/02/23 17:41 123.108.237.26 w12.jp-t.ne.jp SoftBank/1.0/930SH/SHJ001/SN353689020294206 Browser/NetFront/3.4 Profile/MIDP-2.0 Configuration/CLDC-1.1 505 2010/02/23 17:41 210.153.84.21 proxy1161.docomo.ne.jp DoCoMo/2.0 SH705i(c100;TB;W24H16) 506 2010/02/23 17:42 210.153.84.108 proxy1144.docomo.ne.jp DoCoMo/2.0 SH705i(c100;TB;W24H16) 507 2010/02/23 19:11 59.135.38.143 wb32proxy03.ezweb.ne.jp KDDI-ST34 UP.Browser/6.2.0.13.2 (GUI) MMP/2.0 508 2010/02/24 10:19 210.153.86.120 proxya148.docomo.ne.jp DoCoMo/2.0 SH705i2(c100;TB;W30H20) 509 2010/02/24 10:29 114.148.27.178 p4178-ipbf2404souka.saitama.ocn.ne.jp Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_1; ja-jp) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9 510 2010/02/24 11:07 210.136.161.164 proxy180.docomo.ne.jp DoCoMo/2.0 P906i(c100;TB;W30H19) 511 2010/02/24 13:40 210.153.84.2 proxy1102.docomo.ne.jp DoCoMo/2.0 P906i(c100;TB;W30H19) 512 2010/02/24 14:15 124.146.175.54 proxyag046.docomo.ne.jp DoCoMo/2.0 N904i(c100;TB;W30H20) 513 2010/02/24 14:22 210.136.161.111 proxy1135.docomo.ne.jp DoCoMo/2.0 N904i(c100;TB;W30H20) 514 2010/02/24 15:26 124.146.175.17 proxyag017.docomo.ne.jp DoCoMo/2.0 N904i(c100;TB;W30H20) 515 2010/02/24 15:44 210.153.84.110 proxy1148.docomo.ne.jp DoCoMo/2.0 N904i(c100;TB;W30H20) 516 2010/02/24 15:46 210.153.84.11 proxy1141.docomo.ne.jp DoCoMo/2.0 N904i(c100;TB;W30H20) 517 2010/02/24 15:53 210.136.161.168 proxy188.docomo.ne.jp DoCoMo/2.0 N904i(c100;TB;W30H20) 518 2010/02/24 15:55 123.108.237.27 w21.jp-t.ne.jp SoftBank/1.0/921P/PJP21/SN353701020103293 Browser/NetFront/3.4 Profile/MIDP-2.0 Configuration/CLDC-1.1 519 2010/02/24 16:09 210.136.161.163 proxy179.docomo.ne.jp DoCoMo/2.0 N904i(c100;TB;W30H20) 520 2010/02/24 16:22 123.108.237.3 w52.jp-t.ne.jp SoftBank/1.0/921P/PJP21/SN353701020103293 Browser/NetFront/3.4 Profile/MIDP-2.0 Configuration/CLDC-1.1 521 2010/02/24 16:24 123.108.237.30 w32.jp-t.ne.jp SoftBank/1.0/921P/PJP21/SN353701020103293 Browser/NetFront/3.4 Profile/MIDP-2.0 Configuration/CLDC-1.1
[/codesyntax]
・アクセスログをXMLへ整形出力
[codesyntax lang="php" title="outdata.php"]
<?php $outdata = <<<XML <?xml version="1.0" encoding="UTF-8"?> <data> <item> <title>log</title> <value>$log</value> </item> <item> <title>count</title> <value>$o_count</value> </item> <item> <title>carrier</title> <value>$carrier</value> </item> </data> XML; $fp = fopen('outdata.xml', 'w'); if ($fp){ if (flock($fp, LOCK_EX)){ fputs($fp, $outdata); flock($fp, LOCK_UN); } } fclose($fp); ?>
[/codesyntax]
・出力されたXMLファイル
[codesyntax lang="xml" title="outdata.xml"]
<?xml version="1.0" encoding="UTF-8"?> <data> <item> <title>log</title> <value> 2010/05/05 08:45 2010/02/24 15:53 210.136.161.168 proxy188.docomo.ne.jp DoCoMo/2.0 N904i(c100;TB;W30H20) ************************************* 2010/02/24 15:55 123.108.237.27 w21.jp-t.ne.jp SoftBank/1.0/921P/PJP21/SN353701020103293 Browser/NetFront/3.4 Profile/MIDP-2.0 Configuration/CLDC-1.1 ************************************* 2010/02/24 15:55 210.136.161.163 proxy179.docomo.ne.jp DoCoMo/2.0 N904i(c100;TB;W30H20) ************************************* 2010/02/24 15:55 123.108.237.3 123.108.237.3 w52.jp-t.ne.jp SoftBank/1.0/921P/PJP21/SN353701020103293 Browser/NetFront/3.4 Profile/MIDP-2.0 Configuration/CLDC-1.1 ************************************* 2010/02/24 15:55 123.108.237.30 w32.jp-t.ne.jp SoftBank/1.0/921P/PJP21/SN353701020103293 Browser/NetFront/3.4 Profile/MIDP-2.0 Configuration/CLDC-1.1 ************************************* </value> </item> <item> <title>count</title> <value>530</value> </item> <item> <title>carrier</title> <value>DoCoMo : 112 SoftBank : 13 AU : 25 iPhone : 7 Windows : 81 MacOS : 176 Other : 8 </value> </item> </data>
[/codesyntax]
・携帯からのアクセスの有無をチェック
アクセスログと同時に更新されるアクセスカウンタの値が増えていたら「1」を返す。会場内サーバと会場外サーバとの通信量を減らすため、数秒おきに会場内サーバの「check2.pl」が以下の「check.php」へアクセスし、「1」を返した場合のみ上記XML化したログファイルをダウンロードする。
[codesyntax lang="php" title="check.php"]
<?php $fp0 = fopen('counter0.txt', 'r'); $counter0 = fgets($fp0); fclose($fp0); $fp = fopen('counter.txt', 'r'); $counter = fgets($fp); fclose($fp); if ($counter - $counter0 > 0 ){ print "1"; $fp1 = fopen('counter0.txt', 'w'); fputs($fp1, $counter); fclose($fp1); }else{ print "0"; } $fp2 = fopen('last_access.txt', 'w'); fputs($fp2, date("m/d H:i:s")); fclose($fp2); ?>
[/codesyntax]
●会場内サーバのプログラム
・会場内サーバメインプログラム
会場内サーバはWindowsノートPCを使用した。回線はUQ WIMAX。ActivePerlで下記のプログラム「main.pl」を動かし、数秒おきに会場外サーバと通信させた。会場外サーバの「check.php」が「1」を返せば、ログファイルである「outdata.xml」をダウンロードする。
当初は、会場外サーバにあるプログラムもすべて会場内サーバで動かし、携帯から直接会場内サーバへアクセスすることを考えていたが、UQ WIMAXの性質上、常時接続でIPアドレスの固定が難しい。今回採用した方式ならば、多少のタイムラグはあるが、会場内サーバのIPアドレスが変化しても問題ない。また、パケット代節約にもなる。
CDトレイのオープンは、Windowsプログラムの「eject-nt.exe」を「main.pl」から実行する。
[codesyntax lang="perl" title="main.pl"]
#!usr/bin/perl use LWP::Simple; use File::Copy; $url_1 = "http://techtroid.xii.jp/m/mixart/check.php"; $url_2 = "http://techtroid.xii.jp/m/mixart/outdata.xml"; $file_2 = 'outdata.xml'; $Interval = 5; $loop = int(131000/$Interval); $count = 0; while(1){ #last if($count > $loop); #タイマ処理 my $t_before = time; sleep ($Interval); my $t_after = time; my $t_offset = $t_after - $t_before; my ($b_ss, $b_MM, $b_hh, $b_dd, $b_mm, $b_yy) = (localtime($t_before))[0..5]; my ($a_ss, $a_MM, $a_hh, $a_dd, $a_mm, $a_yy) = (localtime($t_after))[0..5]; $b_yy += 1900; $b_mm++; $a_yy += 1900; $a_mm++; print $t_offset*$count."sec\n"; $count++; print $count."\n"; #アクセス時の処理 if(get($url_1) == "1"){ #ページ更新 print get($url_2)."\n"; open (FILE, ">$file_2") or die "$!"; print(FILE get($url_2)) or die($!); close (FILE); print "アクセスがありました!\n"; #CDイジェクト print "トレイをオープンします\n"; print "-------\n\n"; print `eject-nt`; print `eject-nt -t`; }elsif(get($url_1) == "0"){ print "-------\n\n"; print `eject-nt -t`; }else{} }
[/codesyntax]
・アクセス状況をモニタへ表示
最新のアクセスログは、ダウンロードされたログファイル「outdata.xml」をFlashへロードし、モニタへ表示させる。