前回の記事では、「スマートホーム」システムを教えて、私たちが言ったことを認識し、Googleを使用して音声応答を合成することができました。
今日は、Webインターフェースを介してシステムへのアクセスを整理する方法を説明します。
技術
ご存知のように、「スマートホーム」を管理するための
perlソフトウェアを作成します。 最新の情報システムは、データベースなしではほとんど考えられません。 私たちも傍観するつもりはなく、
MySQL DBMSを使用してデータを保存します。 Webサーバーを実装するために、サードパーティのソフトウェアではなく、perl-
HTTP :: Server :: Simpleのモジュール、特に
-HTTP :: Server :: Simple :: CGIを使用することにしました 。 なぜこれをしたのですか? ほとんどの場合、興味のために;)しかし、理論的には、Apache / mod_perl複合体を積み上げることなく、HTTPリクエスト/レスポンスの低レベル処理にアクセスできます。 一般的に、望みと十分な時間があれば、プロジェクトをApacheに移動することを妨げるものは何もありません。
データベース
まず、MySQL DBMSをインストールし、db.sqlのテーブルを使用してデータベースを作成します。 リストは次のとおりです。
CREATE DATABASE ion; USE ion;
必要なアクションを実行します。
nix@nix-boss:~$ sudo apt-get install mysql-server
nix@nix-boss:~$ mysql -uroot -ppassword < db.sql
コードを修正する
次に、
lib 、
htmlおよび
configフォルダー(
データフォルダーの横)を作成する必要があります。
libフォルダーに、Webサーバーの実装とHTTPリクエストの処理を担当するモジュールを配置します。
srv.plスクリプトを
少し調整する必要があり
ます 。 初期化ブロックに追加します。
our %cfg = readCfg("common.cfg"); our $dbh = dbConnect($cfg{'dbName'}, $cfg{'dbUser'}, $cfg{'dbPass'});
初期化ブロックの下に、HTTPサーバーの起動を担当する行を追加します。
ここで、不足している関数をファイルの最後に追加します。
sub readCfg { my $file = shift; my %cfg; open(CFG, "<config/$file") || die $!; my @cfg = <CFG>; foreach my $line (@cfg) { next if $line =~ /^\#/; if ($line =~ /(.*?) \= \"(.*?)\"\;/) { chomp $2; $cfg{$1} = $2; } } close(CFG); return %cfg; }
関数の名前からわかるように、dbConnect()はDBMSへの接続を担当し、logSystem()はログを記録し、readCfg()は構成をロードします。 さらに詳しく見ていきましょう。 設定は、configディレクトリにある単純なテキストファイルです。 この例では、
common.cfgと呼ばれ
ます 。 次のようになります。
## daemonMode = "undef"; logSystem = "1"; logUser = "1"; dbName = "ion"; dbUser = "root"; dbPass = "password"; camNumber = "4"; camMotionDetect = "1"; httpPort = "16100"; httpHost = "localhost"; telnetPort = "16000"; telnetHost = "localhost"; micThreads = "5";
その中のいくつかの行は後で使用されます。 これまでのところ、
dbプレフィックスで始まる行にのみ関心があります。 ご覧のとおり、これらはデータベースに接続するための設定です。
次に、複数のコマンドの実行を克服する方法について説明します。 関数
checkcmd()を編集します。
sub checkcmd { my $text = shift; chomp $text; $text =~ s/ $//g; print "+OK - Got command \"$text\" (Length: ".length($text).")\n"; if($text =~ //) {
4秒間隔で実行された最後のコマンドを選択し、現在のコマンドと一致する場合は、関数を終了します。 ご覧のとおり、前回の記事で説明した機能と比較して、いくつかのコマンドを追加しました。 最も興味深いのは天気です。 彼女のデータ取得の実装はわずかに低くなります。
HTTP.pmモジュール
組み込みHTTPサーバーの実装に戻ります。
libディレクトリに
HTTP.pmファイルを作成します。 そこで次のコードを記述します。
package lib::HTTP; use HTTP::Server::Simple::CGI; use LWP::UserAgent; use URI::Escape; use base qw(HTTP::Server::Simple::CGI); use Template;
内容をさらに詳しく分析しましょう。
%ディスパッチハッシュでは、URLと呼び出される関数を照合します。 このハッシュに記載されていない他のすべてのURLは、
404ページを返します。
強力で柔軟な
Template Toolkitライブラリーがテンプレートエンジンになります。 次の行で初期化します。
our $tt = Template->new();
親クラスの
handle_request()関数をオーバーロードすると、HTTPサーバーへのリクエストの処理を制御できます。 ブラウザに静的コンテンツ(png、gif、jpg、css、xml、swf)を提供するには、ブロックを使用します。
if ($path =~ qr{^/(.*\.(?:png|gif|jpg|css|xml|swf))}) { my $url = $1; print "HTTP/1.0 200 OK\n"; print "Content-Type: text/css\r\n\n" if $url =~ /css/; print "Content-Type: image/jpeg\r\n\n" if $url =~ /jpg/; print "Content-Type: image/png\r\n\n" if $url =~ /png/; print "Content-Type: image/gif\r\n\n" if $url =~ /gif/; print "Content-Type: text/xml\r\n\n" if $url =~ /xml/; print "Content-Type: application/x-shockwave-flash\r\n\n" if $url =~ /swf/; open(DTA, "<$url") || die "ERROR: $! - $url"; binmode DTA if $url =~ /jpg|gif|png|swf/; my @dtast = <DTA>; foreach my $line (@dtast) { print $line; } close(DTA); return; }
いくつかのMIMEタイプを取得したので、少しヒンズー教を書きました;)
次に、特定のURLのコンテンツを生成する機能があります。 これまでのところ、インデックスとカメラ付きのページの2つしかありません。
インデックスでは、ビデオやオーディオのキャプチャなどのサブシステムが機能するかどうかを確認できます。 別の行は次のとおりです。
my %w = checkWeather();
この関数は、都市の現在の天気データを含むハッシュを返します。これはページに表示されます。 そのような小さな素敵なパン;)
近くで、「スマートホーム」に対して最後に受信および認識されたコマンドを出力します。
次の関数
goCamers()は、インデックスと同じ機能を実行しますが、サブシステムのステータスに関する情報を表示する代わりに、カメラからの画像を表示し、「スマートホーム」によって合成および音声化されるテキストを書くことができます。
すべてのページは、
htmlフォルダー内のテンプレートに基づいています。 ここにリストをアップロードするのは
不便なので 、アーカイブへのリンク
-html.zipを提供します。
合計
すべての変更後、ポート
16100で適切に機能するWebインターフェースを取得します。これにより、「スマートホーム」サブシステムのステータス、Webカメラからのデータ、入力したテキストの音声表示が可能になります。 将来的には、さらに重要な機能を追加します。
次の記事では、
X10デバイスを操作し、それらをスマートホームシステムに統合する方法について説明します。
upd :
続き