CentOS + Pear mail mime + PHP + postfix + シリアル通信プログラム = ?
プログラミングは手段?目的?俺は両方だだだだああ
プログラミングは楽しい。やってれば面白いわけで、それは将来につながるだろう。
難しいことはわかんないけど、面白いからいいや。
今日のお題、メールとマイコンを組み合わせたい。
まぁマイコンにTCPIPプロトコル実装するのもいいけど、イーサネットIC買うのだるいし。
実装もだるいし。自分の技術じゃ多分どうにもならない。
ということで、常時稼動の自宅サーバー機を犠牲に話を展開させよう。
※自宅サーバーに対していろいろな事をやった記録です。忘備録。
1.空メール自動返答システム構築した
仕組み。postfix(MTA)との連携プレーで、PHPを叩いてメールの自動返答。これは非常に美味しい。
以下、作業ログ。
1.Apache + PHP のインストール
2.postfixのインストール
3.pearで、mail mimeをインストール。
(自分は警告が出てきてインストールに失敗したので、強制インストールの為に-fオプション追加した。)
4.エイリアス設定
/etc/aliasesに以下の内容を書きこむ。(環境に応じて変更すること)
この場合、ahaha@ドメイン名に対して送られてきたメールを指定されたphpプログラムに引数として渡して実行する。PHP側でメールの内容を解析して、返信するわけだが、その為に必要なのが先程のPHPのパッケージであるMail Mime。(別に自前のメールデコードプログラムがあれば、PHPを使う必要性もないが、自分の本当の目的の為に必要)
5.PHP側プログラムの用意。
<?php //Mail Mimeを使うのでインクルード require_once("Mail/mimeDecode.php"); //標準入力でメールを受信 $source = file_get_contents("php://stdin"); if(!$source) { exit(); } //----------------------------------------// // 引数として渡されたメールデータをデコード(解析) //----------------------------------------// $params['include_bodies'] = true; $params['decode_bodies'] = true; $params['decode_headers'] = true; $decoder = new Mail_mimeDecode($source); $structure = $decoder->decode($params); $from = mb_convert_encoding(mb_decode_mimeheader($structure->headers['from']), mb_internal_encoding(), "auto"); //----------------------------------------// // さっき解析したデータをもとに、メールの送り主に返信 //----------------------------------------// $to = $from; $title = "タイトル。"; $body = "あはーん"; $from = "From: hogehoge@hogehogehoge.hogehoge.com"; mb_internal_encoding("UTF-8"); mb_language("japanese"); mb_send_mail($to, $title, $body, $from); ?>
http://my-server.homelinux.com/emptymail.phpにあったプログラムを自分なりに編集してしまったもの。
このサイトのサンプルでは、文字化けしてしまった為、エンコーディングをUTF-8にしてある。
文字化けを治すために、ずっとphp.iniのmbstring関連項目を疑ってたかが、エンコーディングをUTF-8にしたら治った。本当にこれで良いかは謎。
# postalias /etc/aliases
エイリアスの更新(再構築)。これによって、先ほどつくったエイリアスが適用される。
このコマンドを実行しても、結果は表示されないが問題ない。
mimeDecode.phpは、pearのMail_Mimeと同じパッケージにはないらしいので手動で導入。
他の解説サイトには書いていないが、自分の場合はこれで解決。
7.指定したエイリアス宛でメールを送ってみよう。
成功ならば、自動返信される。失敗の場合は、メールデーモンからエラーメッセージとともにかえってくる。
エラーメッセージを読めば、ここ直せーとか書いてあるからある程度はそれで出来るはず。
さて、別にメールを自動返信するだけのシステムだが、これをどのように応用するか。
データの処理にPHPを介している。自動返信するまえに、PHPの様々な関数を使ってデータ処理が可能だ。
そのため、ただ単にメール自動返答だけではなく、携帯電話からサーバーに対してリモートでコードが実行だとか、様々な事に応用できる。
2.秋月電子のUSB-シリアル変換モジュールを接続
http://akizukidenshi.com/catalog/g/gM-00720/で売られている変換ケーブルをCentOS機に接続。
# dmesg
usb 3-1: new full speed USB device using uhci_hcd and address 2
usb 3-1: configuration #1 chosen from 1 choice
usbcore: registered new driver usbserial
drivers/usb/serial/usb-serial.c: USB Serial support registered for generic
usbcore: registered new driver usbserial_generic
drivers/usb/serial/usb-serial.c: USB Serial Driver core
drivers/usb/serial/usb-serial.c: USB Serial support registered for pl2303
pl2303 3-1:1.0: pl2303 converter detected
usb 3-1: pl2303 converter now attached to ttyUSB0
usbcore: registered new driver pl2303
drivers/usb/serial/pl2303.c: Prolific PL2303 USB to serial adaptor driver
どうやら、無難に認識したようだ。ドライバー関連でトラブルだろうと予想していたが、あっさり。
今更だがPL2303系のICが使われているようだ。無事、ttyUSB0にマウントも成功してる。
動作確認のため、秋月電子のGPSモジュールを接続。ただ、シリアル通信をモニターするプログラムがないため、cuを用いて動作確認・・・したかったのだが、yum install cuでインストールできなかった。
ネットで調べたところ、UUCPと呼ばれるパッケージの中に入っているそうだ。サイズは1MBぐらいだったと思う。
# yum install UUCP
これで、cuは導入できたはず。
続いて、cuを実行し動作確認。
[root@localhost ~]# cu -s 9600 -l /dev/ttyUSB0
Connected.
$GSU-50 : Position Co.,Ltd.2003
$Firmware Checksum: 4d50
$TOW: 0
$WK: 1612
$POS: 6378137 0 0
$CLK: 96000
$CHNL:12
$Baud rate: 9600 System clock: 12.277MHz
$HW Type: S2AM
$Asic Version: 0x23
$Clock Source: GPSCLK
$Internal Beacon: None
$PSRF150,1,*12
$GPGGA,235948.000,3600.0000,N,13600.0000,E,0,00,99.9,00000.0,M,0000.0,M,000.0,0000*4A
あーデータ着てる着てるw
ここまで、CentOSの操作は全てSSHプロトコルを介して無線LAN経由でMacBOOKでやっている。
そのため、他のPCに接続したGPSモジュールのデータを読んでいる状態。
ここから、実際にシリアル通信を行うプログラムの作成。Windowsでは、COMポートをファイルとして扱う事で、一応シリアル通信の送受信はできた。ただし、Linuxではまだやった事が無いので、サンプルプログラムを探したらあったのでこれでテスト。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <termios.h> #include <time.h> #define DEV_NAME "/dev/ttyUSB0" // デバイスファイル名 #define BAUD_RATE B9600 // RS232C通信ボーレート #define BUFF_SIZE 4096 // 適当 // シリアルポートの初期化 void serial_init(int fd) { struct termios tio; memset(&tio,0,sizeof(tio)); tio.c_cflag = CS8 | CLOCAL | CREAD; tio.c_cc[VTIME] = 100; // ボーレートの設定 cfsetispeed(&tio,BAUD_RATE); cfsetospeed(&tio,BAUD_RATE); // デバイスに設定を行う tcsetattr(fd,TCSANOW,&tio); } int main(int argc,char *argv[]){ int fd; fd = open(DEV_NAME,O_RDWR); if(fd<0){ perror(argv[1]); exit(1); } serial_init(fd); while(1){ int i; int len; unsigned char buffer[BUFF_SIZE]; len=read(fd,buffer,BUFF_SIZE); if(len==0){ continue; } if(len<0){ printf("%s: ERROR\n",argv[0]); perror(""); exit(2); } for(i=0; i<len; i++){ printf("%c",buffer[i]); } } }
プログラムは、http://www.si-linux.co.jp/wiki/cat/index.php?%A5%B7%A5%EA%A5%A2%A5%EB%A5%DD%A1%BC%A5%C8%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0からお借りした。分かりやすい丁寧なコメントがされていたが、一部省かせていただいた。またこのサンプルプログラムでは、16進数で受信データを吐き出しているが、%cで文字で出すように変更。これでシリアル通信のモニタープログラム完成。
3.次なる野望
この自動メール返答とシリアル通信プログラムを使って、メールでマイコンからデータが取れるようにしたい。
具体的に、自宅サーバーに空メールを送りつけることによって部屋の温度、湿度、サーバーの稼働状況、部屋の写真、各家電製品の状況、遠隔操作・・・なんてことができたらいいなーと。
前に、HTTP経由で動かせるウェブカメラを開発した。(サーボモーターにWebカメラ付けて、PHPでexe叩いてサーボを動かし、Pythonでwebカメラの写真撮影してJpegをHTML出力ってだけ。)
その次なる野望として、メールを使ったちょっとユビキタスなもんをつくってみたいなーっていうのが俺の願い。