# スマホから猫と遊ぶ技術 ## これを作りたい HPにボタンを設置し、オフィスのラズパイに信号を送り、サーボを制御するというものです。 https://www.youtube.com/watch?v=UA4ztZSOPIw ![](https://i.imgur.com/5ydSgo5.jpg) ## 手法の検討 ### 通信手段の検討 HPから社内LANにつながるラズパイにアクセスするには、何かしらの通信をする必要があります。 WEBサイトの通信というと、HTTP/HTTPS通信、websocket通信などが挙げられます。 * HTTP/HTTPS通信 webサーバとブラウザ間でよく使われている通信です。HTTPSの方は、暗号化されてよりセキュアな通信ができます。 * WebSocket通信 HTTP通信を簡略化した通信です。HTTPよりも低コストでの通信が可能です。 以上2つの通信方法を検討しましたが、HPを作成したWiXというツールではWebSocketもHTTPも非対応であったあため、**HTTPS通信を採用**しました。 WiXではWebSocketの使用を想定されておらず、HTTPはセキュリティ上の都合でNG、とのことでした。 ### 通信経路の検討 以下のようなシステムにて構築します。 |![](https://i.imgur.com/3zZKXvw.png)| |:-:| ユーサがLefixeaのHPにアクセスし、「点灯」ボタンを押すとHTTPS通信で信号がインターネット経由でLefixea社内に到達します。信号を受けたモデムはラズパイに受け渡し、ラズパイが信号を検出するとライトを点灯させるしくみです。 </br> </br> ## ラズパイwebサーバの構築 クライアントであるユーザのPCに表示されたホームページからの信号に応答するためには、何かしらのWEBサーバを設置する必要があります。例えばGoogleのサービスもWEBサーバとのやりとりによって成立しています。今回も例外ではなく、HPからの点灯ボタンに応答する処理を行うWEBサーバが必要です。 サーバの設置場所としては 1. ラズパイがあるLAN内に設置する方法 2. ラズパイ自体をWEBサーバとしてしまう方法 の2種類を検討しました。今回はただ単にラズパイのGPIOを操作するだけのため負荷は軽いだろうと考え、ラズパイ自体をWEBサーバとしてしまう方法を採りました。 ### ラズパイにwebサーバ設置 WEBサーバ構築には、apache2を用います。オープンソースの有名なWEBサーバーソフトです。 |![](https://i.imgur.com/wyxvIEs.png =300x)| |:-:| ``` $ sudo apt-get update $ sudo apt-get upgrade -y $ sudo apt-get install apache2 ``` apacheのインストールが完了したら、WEBサーバ構築完了! 同じLAN内にあるPCなどから、ブラウザで 192.168.x.x(ラズパイのIP) を入力してapacheサーバにアクセスしてみましょう。IPは、 `$ ifconfig` の「inet」の192.168.~~の項目です。私は192.168.1.25に固定しています。 apacheの導入が成功していれば、「It works!」と表示されます。 ![](https://i.imgur.com/w85AGNb.png) 続いて、サーバーサイドでよく使われる言語であるPHPをインストールします。 `$ sudo apt-get install php7.1` 続いて、apacheでphpを使えるように設定します。 `sudo nano /etc/apache2/mods-available/mime.conf` で開いて、以下3行を追記します。 > AddType application/x-httpd-php .php > AddType application/x-httpd-php-source .phps > : > : > AddHandler cgi-script .cgi .php `$ sudo nano /var/www/html/index.php` に以下のphpプログラムを記入します。 ``` <?php phpinfo(); ?> ``` apache2を再起動します。 `systemctl reload apache2` ブラウザから http://192.168.1.25/index.php にアクセスし、 ![](https://i.imgur.com/DLtwzwA.png) こんな表示が出たら成功です。 </br> </br> ## プログラムの配置 次に、実際に動作するプログラム類を作成、配置していきます。 ### HP側のHTMLファイル HPに配置するボタンを作成します。 ボタンを押すと、「neko」というデータがPOSTでactionの宛先(ラズパイWEBサーバ)に送信されます。 ```html <html> <body> <form method="POST" action="https://lefipi.hopto.org/sample.php"> <input type="hidden" name="text1" value=neko> <input type="submit" name="btn1" value="ねこじゃらしボタン"> </form> </body> </html> ``` ![](https://i.imgur.com/jyL5R1z.png) こんな感じの表示になります。 ### サーバ側のPHPファイル ねこじゃらしボタンから送信されたデータを受け取り、ねこじゃらしを動かすためのpythonコマンドを実行します。 データを受け取ってpythonを実行したあとは、ボタンを再度表示させるためにHTML形式でprintしています。これで、何度でもボタンを押せるようになります。 /var/www/html/sample.php ```php <?php $input_data = (int)$_POST['text1']; if ($input_data == neko){ $command='sudo /usr/bin/python /home/pi/Documents/servo.py'; exec($command,$output,$state);//コマンド実行 print('<form method="POST" action="https://lefipi.hopto.org/sample.php">'); print('<input type="hidden" name="text1" value=neko>'); print('<input type="submit" name="btn1" value="ねこじゃらしボタン">'); print('</form>'); } else{ } a?> ``` ### サーバ側のpythonファイル pythonファイルを作成します。自動ねこじゃらしはこのpythonファイルを用いて動作させます。 サーボを1回振るだけの単純なプログラムです。 /home/pi/Documents/servo.py ```python import RPi.GPIO as GPIO import time def servo_move(): PIN = 21 GPIO.setmode(GPIO.BCM) GPIO.setup(PIN, GPIO.OUT) servo = GPIO.PWM(PIN, 50) # GPIO.PWM(PIN, [周波数(Hz)]) val = [2.5,3.6875,4.875,6.0625,7.25,8.4375,9.625,10.8125,12] # サーボ動かすプログラム servo.start(0.0) servo.ChangeDutyCycle(val[0]) time.sleep(0.5) servo.ChangeDutyCycle(val[3]) time.sleep(0.5) servo.ChangeDutyCycle(val[0]) time.sleep(0.5) servo.stop(0.0) if __name__ == "__main__": servo_move() ``` </br> ## ネットワーク環境の整備 通信のためのネットワーク設定を行っていきます。 ### DDNSサービスを利用してグローバルIPが変化してもOKな状態にする まずは、DDNSサービスを用いてグローバルIPが変化してもドメインと紐いてくれるように設定します。 #### 説明 少し説明します。 IPアドレスには「グローバルIP」と「プライベートIP」の2種類があります。 グローバルIPはインターネット上でのIPで、プライベートIPはLAN内でのIPです。 回線契約時に「固定IP」サービスに加入していない場合(普通は加入しない)、グローバルIPが度々変化します。グローバルIPはインターネット上からサーバの場所を特定するために必要な情報ですので、グローバルIPが変化するとサーバの場所を特定できなくなります。つまり、ラズパイWEBサーバーにアクセスできなくなります。 IP固定サービスに加入してIPを固定してもいいのですが、月額500~1000円程度かかります。 そこで、DDNSサービスを利用することでグローバルIPが変化してもDDNSに登録したドメインに紐付けてくれるのです。 DDNSサービスは色々ありますが、今回はNO-IPというサービスを利用しました。無料ですが、月1回NO-IPにサインインしないとIP紐付機能を停止されます。無料なので仕方ないです。 #### 利用手順 NO-IPのサイトにて、アカウント作成(Sign Up)を行います。 その後メールが届きますので、アカウントを有効化してください。 https://www.noip.com/ ![](https://i.imgur.com/oR5mHV6.png) ラズパイにnoipディレクトリを作成 `mkdir /home/pi/noip` noipディレクトリに移動 `cd /home/pi/noip` noipクライアントをダウンロード `wget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz` ダウンロードしたクライアントを解凍 `tar vzxf noip-duc-linux.tar.gz` クライアントソフトの中に移動 `cd noip-2.1.9-1` インストール `sudo make` 設定 `sudo make install` #### 自動起動の設定 ``` $ sudo cp debian.noip2.sh /etc/init.d/noip2 $ sudo chmod +x /etc/init.d/noip2 $ sudo vi /etc/rc.lcal 以下の1行を追加します /etc/init.d/noip2 start ``` #### 設定 ``` $ sudo /etc/init.d/noip2 stop $ sudo /usr/local/bin/noip2 -C # 再度設定 $ sudo /etc/init.d/noip2 start # 起動 ``` #### 確認 `$ sudo /usr/local/bin/noip2 -S` </br> ### HTTP→HTTPS化する 今のままでもWEBサーバとしての機能は発揮できるのですが、WiXと通信するにはもうひと手間加える必要があります。 WiXではhttp通信を用いるのはセキュリティの観点から推奨されていないため、HTTPS通信でWiXとラズパイの通信を行います。 HTTPS通信は暗号化された通信で、第三者はこの通信内容を見ることができません。一方HTTP通信は暗号化されておらず、簡単に通信内容を傍受できます。 現在HTTPサーバであるapacheサーバに、SSL証明書を発行してHTTPS化を行います。 HTTPS化は、 1. 自己署名証明書によるもの(オレオレ証明書) 2. 第三者認証局の証明書によるもの があります。 1のオレオレ証明書は、SSL証明書を認証局から取得せずに、自分で証明書を発行する方法です。 2の第三者認証局を使ったほうがWEBサーバの信頼性が上がるのは言うまでもないですが、通常は料金がかかります。 ただし、認証局からの証明書発行にもグレードがあり、無料のものも存在します。 今回は、無料で利用できる認証局からのSSl証明書を用いてHTTPS化を行います。 #### Let’s EncryptでSSl取得 参考:https://www.miki-ie.com/network/raspberry-pi-certificate-ssl-lets-encrypt/ 下記コマンドでパッケージをインストールし、 sudo apt-get install certbot sudo apt-get install python-certbot-apache 下記コマンドでSSL証明書の取得を行います。 sudo certbot --apache > Saving debug log to /var/log/letsencrypt/letsencrypt.log > Plugins selected: Authenticator apache, Installer apache > > Which names would you like to activate HTTPS for? > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > 1: www.domain.com > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > Select the appropriate numbers separated by commas and/or spaces, or leave input > blank to select all options shown (Enter 'c' to cancel): 1 > Obtaining a new certificate > Deploying Certificate to VirtualHost /etc/apache2/sites-enabled/aaa.domain2-ssl.conf > Created an SSL vhost at /etc/apache2/sites-available/domain2-le-ssl.conf > Deploying Certificate to VirtualHost /etc/apache2/sites-available/domain2-le-ssl.conf > Enabling available site: /etc/apache2/sites-available/domain2-le-ssl.conf > > Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > 1: No redirect - Make no further changes to the webserver configuration. > 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for > new sites, or if you're confident your site works on HTTPS. You can undo this > change by editing your web server's configuration. > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2 > Redirecting vhost in /etc/apache2/sites-enabled/aaa.domain2.conf to ssl vhost in /etc/apache2/sites-enabled/aaa.domain2-ssl.conf > Redirecting vhost in /etc/apache2/sites-enabled/domain2.conf to ssl vhost in /etc/apache2/sites-available/domain2-le-ssl.conf > > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > Congratulations! You have successfully enabled https://aaa.domain.com and > https://www.domain.com > > You should test your configuration at: > https://www.ssllabs.com/ssltest/analyze.html?d=aaa.domain.com > https://www.ssllabs.com/ssltest/analyze.html?d=www.domain.com > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > > IMPORTANT NOTES: > - Congratulations! Your certificate and chain have been saved at: > /etc/letsencrypt/live/aaa.domain.com/fullchain.pem > Your key file has been saved at: > /etc/letsencrypt/live/aaa.domain.com/privkey.pem > Your cert will expire on 2019-12-03. To obtain a new or tweaked > version of this certificate in the future, simply run certbot again > with the "certonly" option. To non-interactively renew *all* of > your certificates, run "certbot renew" > - If you like Certbot, please consider supporting our work by: > > Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate > Donating to EFF: https://eff.org/donate-le エラーがでなければこれで完了です。 </br> ### ポート開放 ポート開放をして、LAN外からHPにアクセスできるようにします。 ルータによって設定方法が異なりますが、今回はNTTのモデム兼ルータのRX-600KIでのポート開放を行います。 192.168.1.1にアクセスし、ログインして管理画面を参照します。 「静的マスカレード設定」にて、編集ボタンを押します。 |![](https://i.imgur.com/WvvrAqs.png)| |:-:| |![](https://i.imgur.com/RzKFMHA.png)| |:-:| プロトコル:TCP 対象ポート:443 IPアドレス:(ラズパイのIP) ポート:443 入力し、「設定」を押します。まだ終わりではありません。 |![](https://i.imgur.com/K3fGGuj.png)| |:-:| この画面で先程入力した行のチェックを入れ、設定ボタンを押します。 これで設定完了です。 </br> </br> ## 動作確認 HPにボタンを追加して、いざ動作テストです。 |![](https://i.imgur.com/Fw8cE1B.png)| |:-:| HTMLでボタンを埋め込み、 ![](https://i.imgur.com/rbdon2Z.png) ボタンを押すと...ねこじゃらしが動きました! ↓で試せますので、皆さんもボタンを押してみてください。 https://www.lefixea.com/iot </br> ## うまくできない時は 以下を確認してください。 **2重ルータになっていないこと**  確認方法:windowsPCのコマンドプロンプトで「tracert 8.8.8.8」と入力。先頭2行がプライベートIPであれば2重ルータになっている。 **ファイヤウォールでブロックされていないこと**  確認方法:ラズパイで「sudo ufw status」と打って443がALLOWになっているか確認。パッケージが見つからなければラズパイにファイヤウォールは入っていない。 **ポート開放ができていること**  確認方法:ポート開放確認サイトにてドメイン名orグローバルIPと、確認するポート番号(443)を入力。し、開放できれいるか確認。https://www.cman.jp/network/support/port.html ## おわりに ラズパイでWEBサーバを構築して外出先からねこじゃらしを振ることができました。 このしくみを応用すれば、もっと面白そうなことができそうですね。 以上、スマホから猫と遊ぶ技術の解説を終了します。