R筋

プログラミング、金融、育児

raspberry pi でローカルDNSサーバを作る

最近仕事で社内向けDNSサーバの設定を変えることがあり、実用性はあまりないんだけど、勉強を兼ねて、家でも内部DNSサーバを作ってみることにした。

毎度お馴染み、持っててよかったraspberry piにBINDを入れて運用することにする。
すでに報告してくれている方々がおり、参考にさせていただきました。
wordpress.zenmai.org
www.kotemaru.org

そもそも、家に内部DNSを置くメリットはなにかというと、こんなところだろう。
・前記事で作ったウェブページにIPアドレスではなく、自分で設定した名前「http://~」でアクセスできる。
NASの共有フォルダへもIPアドレスではなく「\\~」でアクセスできる。
・外部DNSを自分で設定できるので、プロバイダのDNSサーバでブロッキングが行われても回避できる。
DNSの仕組みについて詳しくなり、インターネットの根幹を支えるDNSという技術に感謝する心が生まれる。

思うに一番最後はすごく重要だろう。
「www.yahoo.co.jp」と「183.79.250.251」はどっちをアドレスバーに入れても、ヤフーのトップページにつながるにもかかわらず、それぞれgoogleで検索してみると、検索結果は、約 672,000,000 件と3,420 件 という差が生まれる。
この差、196,491倍!これはもはやDNSサーバが我々の生活を196,491倍便利にしたと言える(謎理論)
従来比約20万倍の恩恵をもたらしたにもかかわらず、DNSサーバは世間一般にはほとんどその存在が知られておらず、誰からも感謝されることはない。
家庭内に内部DNSサーバを作ること、それはその道程においてDNSサーバに感謝するという行為である。

とはいえここから先は自分用のメモなので、全然参考にならないと思う。
やりたい人は上のページを参考にしたほうがいいだよ。

→etc/bind/named.confの設定

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";

named.confはBINDの基本設定ファイルである。
includeにより詳細設定のファイル、named.conf.optionsとnamed.conf.localを読み込む。

→etc/bind/named.conf.optionsの設定
これはconfの各種オプションを設定するファイル。

options {
        directory "/var/cache/bind";

         forwarders {
              1.1.1.1;
        };
	//このゾーンで名前解決出来ないときは、1.1.1.1に問い合わせ
	listen-on-v6 { none; };
	//IP6は無効
};

→/etc/bind/named.conf.localの設定
実際にゾーンをここで定義する。

//ホスト名myhome.jpの設定
zone "myhome.jp" {
    // Master DNS Serverであることを明示
    type master;
    // 設定ファイル名を記載
    file "/etc/bind/myhome.db";
};

// 192.168.100.* の逆引きの設定
zone "100.168.192.in-addr.arpa" {
    // Master DNS Serverであることを明示
    type master;
    // 設定ファイル名
    file "/etc/bind/100.168.192.db";
};

→myhome.dbの設定
正引きの設定を記載

$TTL 86400

@      IN SOA ns.myhome.jp.    root.myhome.jp. (          //最後に「.」を忘れない
                                      2018010204 ; Serial //更新時に値を増やす
                                      28800      ; Refresh
                                      14400      ; Retry
                                      3600000    ; Expire
                                      86400      ; Minimum TTL
)

@       IN NS ns.myhome.jp. ; 
ns      IN A 192.168.100.130  ;
raspi2  IN A 192.168.100.125  ;
NAS     IN A 192.168.100.101 ;

→100.168.192.dbの設定
逆引きの定義を記載

$TTL 86400    ;

@   IN SOA ns.myhome.jp.    root.myhome.jp. (
                        2011102301 ; Serial
                        3H         ; Refresh
                        1H         ; Retry
                        1W         ; Expire
                        1D )       ; Minimum

    IN NS  ns.myhome.jp.     ; //Name Server を指定
    IN PTR myhome.jp.        ; //解決するドメインを指定
    IN A 255.255.255.0 ; //サブネットマスクを指定

130     IN PTR ns.myhome.jp.
125     IN PTR raspi2.myhome.jp.
101     IN PTR NAS.myhome.jp.

設定後は、

sudo named-checkconf

で、設定ファイルが正しいか確認できる。問題なければ再起動

/etc/init.d/bind9 restart

確認は、linuxの場合は、named.confに書いてあるDNSサーバを変更。
windowsはコンパネで使用するDNSサーバを指定。
もしくはDHCPサーバで配信するDNSサーバを変更。
等の方法で、raspberry pi上のDNSサーバが正しく動いているかを調べるとよい。

raspberry piでWEBサーバを立ててブラウザから部屋の気温・湿度・気圧を確認する。

朝からダルくて一切のやる気が出ない日が周期的にやってくるわけだが、この「周期的に」というのが重要で、僕がダメ人間だったら常にやる気がないはずで、何らかの外部要因が影響していて、僕のやる気を奪っている可能性が高い。つまりこの外部要因を特定できれば、僕は悪くないということが証明されるわけだ。

実際、外部要因として、低気圧だと頭痛になったり、湿度が高いと「水毒」でダルくなるということはあるそうだ。
www.alsok.co.jp

この辺を知っていると、役立つことは多いだろう。例えば、会社を早退したいときも
「なんかダリーんで帰りますチョッチョチョリーッス」
「私梅雨の時期は、湿度・気圧の変化によって全身疲労・倦怠感を覚え、業務へ支障をきたす可能性があるため、本日は大事をとって、お休みさせていただきます」
という感じで、知っている人と知らない人ではここまで印象が違う。

そういうわけで、気温・湿度・気圧と体調の相関を常日頃から意識しておくといいことがあるんじゃないかと考え、ブラウザから取得できるボタンを作成した。
だるいなと思ったら、このボタンを押して、原因が外気にないかチェックすることにしよう!


上下にあるボタンは別途記事にするので気にしないでね。

仕組みは前の記事と同じで、ブラウザからPOSTされたら、センサーを実行させる。
anpontan382.hatenablog.com

結果はajaxによってブラウザに返させるようにして、結果が来るまでは「通信中」と表示する。
ajax部分はこんな感じ。

$(function(){
        $(document).on('click', '#env', function(){
            $('#env p').html("Last valid date:通信中<br>Temperature:通信中<br>Humidity:通信中<br>Pressure:通信中")
            $.ajax({
                url:"/env",
                type:"POST",
                success:function(res){
                            $('#env p').html(res);
                        },
                error:function(){
                            window.alert('error')
                        }
            })
    });
});

id=envのボタンがクリックされると、pタグ内を「通信中」に変更する。
ajax通信では「/env」をPOSTし、通信が成功したら、受信した内容でpタグないを書き換える。
通信失敗時はエラーのアラートを表示させる。

サーバではポストを受け取り、センサーを実行させる。
実行するセンサーは2つあり、湿度を取得するDHT11と、気温、気圧を取得するBMP180だ。この辺を参考にそれぞれを取得できるスクリプトを作成した。

qiita.com
qiita.com

取得した値は次のように改行でつないで出力する。

Last valid date:2018/06/15 22:36:11<br>
Temperature: 23.60 C<br>
Humidity: 79%<br>
Pressure:1010.75 hPa

これを、サーバから返せば、ウェブページ上で表示される。

app.post('/env',function(req,res){
    console.log('env');
    const result2 =  execSync('sudo python env.py').toString();
    res.send(result2);   
});

ちなみに今日はこんな感じ。
f:id:anpontan382:20180615225623p:plain
不快指数は71。湿度は高いけど、気温が低いからそこまででもないですね。
いわれてみると確かに今日は気分もぼちぼちだな。

raspberry piでWEBサーバを立ててプリンタのON/OFFを操作する

僕や妻は仕事の書類や子供の写真などで何かとプリンタで印刷することが多い。
だが、印刷しようと思ってから、実際に印刷が完了するまでは、
プリンタの前に行く→プリンタの電源を起動する→パソコンに戻る→プリンタがネットワークに繋がりオンラインになる→印刷する→プリンタへ印刷物を取りに行く→プリンタの電源を切る
というプロセスが発生しており、時間にして2~3分を要する作業である。

これは大変な無駄である。育児と仕事で超絶多忙を極める我々とっての3分の損失は、現在の時間価値で3分の損失である。
私が幸いにして有する超絶最先端技術の知見を駆使することがこの大問題を解決できる微かな光明と言われており、私が可及的速やかにこの問題解決に取り組むことは全人類の渇望するところとなっていた。

そんなわけで完成したのがこれだ。


システム構成図はこんなカンジ
f:id:anpontan382:20180611223608p:plain

処理の流れ順に説明すると、まずHTMLでスイッチを作成する。
「HTML スイッチ おしゃれ」などで検索するといろいろとスタイリッシュなスイッチが出てくるので、その中でこちらを参考にCSSを作成した。
blog.manaten.net

豊富なサンプルのおかげでセンスがない人もそれっぽいものが作れるのでありがたいなぁ。
f:id:anpontan382:20180611223824p:plain

スイッチができたら、サーバにPOSTするjqueryを書く。

    $(document).on('change', '#switch', function(){
            $.post('/printer','printer');
    });
//id=switchで指定したフォームがchngeしたときに「/printer」というurlをPOSTする。

これをstaticフォルダにindex.htmlとして保存する。

次はPOSTを受け取るサーバサイドを作る。
app.jsに以下を記述する。
express.jsを使用するので事前にインストールしておこう。

const execSync = require('child_process').execSync;
const express = require('express');
const app = express();

//staticフォルダのindex.htmlを読み込みport3333で表示
app.use(express.static('static'));
app.listen(3333,function(){
    console.log('server start')
});

//"/printer"がポストされた場合受け取る
app.post('/printer',function(req,res){
    console.log('POSTED')
 //pythonの実行を同期処理で行う
    const result =  execSync('sudo python servo_printer.py').toString();
});

次はサーボモータをプリンタに取り付ける。
サーボモータはSG-90という定番商品があり、一個400円で購入。
http://akizukidenshi.com/catalog/g/gM-08761/
微調整を重ねながら、ゼムクリップ2個でうまいことスイッチに当たる位置で固定することに成功。
f:id:anpontan382:20180611222502p:plain

続いてservo_printer.pyに実際にservoモータを動かすスクリプトを作成する。
コードは以下を参考にした。

import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
gp_out = 17
GPIO.setup(gp_out, GPIO.OUT)
servo = GPIO.PWM(gp_out, 50)
servo.start(0)
servo.ChangeDutyCycle(7)
time.sleep(0.5)
servo.ChangeDutyCycle(15)
time.sleep(0.5)
servo.stop()
GPIO.cleanup()

ChangeDutyCycle()に指定した値で、回転して止まる場所が変わるので、いろいろと値を変更させながら、ちょうど良く押す→戻すができる数値を探す。

各ファイルをこんな構成にしてraspberry piに保存。
www
|-app.js
|-servo_printer.py
|-static
-|-index.html

raspberry piでapp.jsを実行し、コンソールに「server start!」が表示されたら、準備OK。
ブラウザから「192.168.(raspberry piのアドレス):3333」を開きお気に入りに登録すればいつでもスマホやPCでプリンタの電源を入れられるようになった!
いやいや、そろそろ印刷しようかなーって言うときに、ブラウザ開いてボタン押しておけばすぐにプリンタが使えるわけだから意外と便利だと思うよ、うん。

今後の課題としては、webページのON/OFFは必ずしもプリンタのON/OFFとリンクしていないので、うまく電源が入らないときは、それらがズレてきてしまう問題の修正が必要だろう。
プリンタは電源が入ればネットワークに必ずつながるので、raspberry piでプリンタのIPアドレスを常時監視して、一定期間ごとにwebページのON/OFFを実際のプリンタのON/OFFと連動させるとよりスイッチらしくなるだろう。

が、プリンタのON/OFF如きにそこまでこだわれる情熱を持っていないため、やらない。
直接プリンタ見りゃいい話だし。←それを言ったらON/OFFも直接押せやという話になるが。

Raspberry pi + google homeで最近やったこと

結局ハマっちゃうわけです。楽しいから仕方ないことですね。

・現在のマーケット情報を確認する。

f:id:anpontan382:20180424220732p:plain
コマンド実行時に日経新聞社の世界の市況ページをスクレイピングし、読み上げる仕組みだ。
www.nikkei.com
概要はこちら。
f:id:anpontan382:20180424221027p:plain
朝の時間に準備しながら、世界中の通貨や指数をたれ流したかったのだが、google-home-notifierで読み上げられる文字数は100文字程度が上限のようで、指数にして3~4つが限界だった。
また、「+」「ー」をカタカナに、「-」を「から」に置換する等、読み上げをする上で自然になるよう置換が必要である。
スクレイピング部分のコードを載せておく。

var client = require('cheerio-httpcli')
var URL = 'https://www.nikkei.com/markets/worldidx/'

var data = [];
var data2 = [];
var target =["日経平均(円)","ドル・円","NYダウ工業株30種(ドル)","米10年国債"];
var str =""
//抽出対象の銘柄
client.fetch(URL,function(err,$,res){
    if(err){console.log(err);return;}

var table = $('.cmn-table_style1 tr')
//tr内を取り出す

    for(var i=0,l=table.length;i<l;i++){
        var cells=table.eq(i).children();
        data[i]=[];
        for( var j=0,m=cells.length;j<m-1;j++ ){//m-1とすると最終列(時間帯)は含めない
            data[i][j] = cells.eq(j).text();//i行目j列の文字列を取得
           }
           data2[i]=data[i].join('。')//列を結合
           data2[i]=data2[i].replace("+","プラス")//置換
           data2[i]=data2[i].replace("-","マイナス")        
           data2[i]=data2[i].replace("-","マイナス")
           data2[i]=data2[i].replace("-","から")
           data2[i]=data2[i].replace("(","ポイント。")
           data2[i]=data2[i].replace(")","")
           data2[i]=data2[i].replace("※","")
           //console.log(data2[i])
           for(var k=0,n=target.length;k<n;k++){
                if(data2[i].indexOf(target[k])==0){//targetに該当する行を取り出す
                    str+=data2[i]+"\n"
                } 
           }   
    }

    str=str.replace("?","")
    console.log(str)
   
googlehome.notify(str, function(res) {
    console.log(res);
  })
})
}

出来上がったのはこちら。
日経新聞のページに表示されている値なのでマーケットがオープン中なら現在値、クローズ後なら終値が読まれる。


この声での数字の読み上げはなんか頭に入ってこない…
それと、元から「日経平均は?」「ドル円は?」等へは解答してくれるので、全指数をまとめて読み上げることが文字数の制限で無理な時点で実装する意味があんまない機能でした。

NASの音楽ファイルを再生する。

f:id:anpontan382:20180424225100p:plain
NASに置いた音楽ファイルをランダムに再生してくれる。
概要はマーケットとほぼ同じ。
f:id:anpontan382:20180424225303p:plain
NASのマウントはこちらを参考に実施。
www.mana-cat.com
NAS上に音楽フォルダを作成し、その中に音楽ファイルを格納する。
後はパスを指定してgoogle-home-notifierに送ればいいのかと思いきや、google-home-notifierのファイルパスではなくhttp:~のURLを指定しないといけない。
そのため、音楽フォルダでミュージックサーバを立てる。
参考にしたのは次のサイト。
scrapbox.io
プログラムの流れは以下の通りとなる、①と②はnohupで常に実行しておく。
①nodeでミュージックサーバを立てる。
②firebaseのDBの更新があったら③を実行する
③ミュージックサーバの各ファイルへのURLをランダムに取得しGoogle homeで再生する。
①は上記サイト、②は過去の記事を参照。
anpontan382.hatenablog.com
③のコードはこんな感じで出来た。全体を関数としてexportしている。

exports.playmusic=function(){

var fs = require('fs');
const googlehome = require('google-home-notifier');
const language = 'ja';
googlehome.device("Google-Home", language);
googlehome.ip("192.168.***.***");//googlehomeのIPアドレス

fs.readdir('/home/pi/nas/music', function(err, fileList){
    if (err) throw err;
   
    //console.log(fileList);
    randomfile = fileList[Math.floor(Math.random() * fileList.length)];
    url ='http://192.168.***.***:3000/music/' + randomfile;
    //ラズパイのIPアドレス+ポート+ミュージックサーバのパス+NASからランダム
 //に取得した音楽ファイル

    console.log(url);

googlehome.play(url, function(res) {
  console.log(res);
});

僕は現在300曲程をNASに保存しているが、「再生」というとランダムにgooglehomeが再生してくれる。
曲が多すぎて聞きたい曲が流れることはない。そのため、今後の改良としてはフォルダ毎にプレイリストを作り「〇〇(フォルダ名)を再生」と言うと、フォルダ内の曲だけが流れるようにできるとより音楽プレイヤーとしての利用が捗りそう。

Raspberry piでGoogle Homeに話をさせていたら気づいた大切なこと

目次

今回作ったのはこれだ


ずっとほしいなぁと思っていたんだけど、いよいよ禁断症状が出てきて会社帰りに秋葉原で買ってしまったraspberry pi zero!!このLINEに書いた内容を喋らせるヤツ、ブログでいくつか開発している記事を仕事中に見るにつけて、やりたくてやりたくて仕事が手につかなかったもんだから仕方がないことですね。

rassberry pi初期設定

初心者なので色々なものが入っているこちらのスターターキットを買いました。
Raspberry Pi Zero W スターターキット--在庫限り - スイッチサイエンス
まずはセッティング。スターターキットに色々と変換アダプタが入っているので簡単にはじめられる。電源アダプタを入れると自動的に起動してしまうので、他の接続を先に済ませて最後に電源をつなげよう。
f:id:anpontan382:20180302233900p:plain
また、本来はmicroSDの中に公式サイトからダウンロードしたOSを入れてから差さないといけないのだが、スタータキットにはすでにOSがmicroSDにコピー済みのため差し込むだけで準備完了だ。
f:id:anpontan382:20180302234515p:plain
電源を入れて少し待つとこんなかんじの起動画面になる。
OSが起動したら、いくつかの初期設定を行う。amazon ultimatedで無料で読めるので、この本を参考にした。

設定内容は次の通り。
wi-fi接続
SSH、I2Cを使用可
③ログインパスワードの変更
タイムゾーン
これだけで、ネットサーフィンもできる普通のPCとして使用できる状態になる。だが、512MBのメモリではネットサーフィンなどはめちゃくちゃ重たく、実用性はほぼないだろう。基本的に遠隔でログインして操作することになる。
そのために必要な
SSHの設定
FTPサーバの設定
IPアドレスの固定
の作業があるがこれも上記書籍を参考にした。
加えて、LAN外からもアクセスできるようネットワークの設定も変更した。
anpontan382.hatenablog.com
外部からのアクセスにするため、
①ポート番号をデフォルトから変更
②公開鍵認証
を設定している。
これによって、普段使っているwindowsPCから、teratermFFFTPでrasberry piを操作できるようになった。
f:id:anpontan382:20180303002812p:plain

google-home-notifierの設定

続いて、googleHomeに喋らせるために必要なパッケージをインストールする。
コマンドは、こちらを参考にした。
GoogleHomeスピーカーに外部からプッシュして自発的に話してもらいます - Qiita
必要なパッケージは次の通り
・node.js→javascriptを実行する環境
・npm→node.jsで使うパッケージを管理するツール
・nvm→node.jsのバージョンを管理するツール
google-home-notifier→javascriptgoogle homeを動かすためのパッケージ

ハマった場所をメモしておこう。
google-home-notifierのインストールで次のエラーが出た。

pi@raspberrypi:~/google-home-notifier $ npm install -g google-home-notifier
npm WARN package.json google-home-notifier@1.2.0 No repository field.
\
> mdns@2.3.4 install /home/pi/google-home-notifier/node_modules/mdns
> node-gyp rebuild

make: Entering directory '/home/pi/google-home-notifier/node_modules/mdns/build'
  CXX(target) Release/obj.target/dns_sd_bindings/src/dns_sd.o
In file included from ../src/mdns.hpp:12:0,
                 from ../src/dns_sd.cpp:1:
../node_modules/nan/nan.h:324:47: error: ‘REPLACE_INVALID_UTF8’ is not a member of ‘v8::String ’
   static const unsigned kReplaceInvalidUtf8 = v8::String::REPLACE_INVALID_UTF8;
…

この解決方法は、こちらあった。
Raspbianでのnpm install leveldownではまったメモ - Qiita
nodeのバージョンが問題とのことで、nvmでバージョンを変えようとしたが、nvmもエラーが出る。(
gitを使ったnvm(node version manager)のインストールから複数バージョンのnode.jsインストール及びその切替え手順のご紹介です。
これによると、nvmは最初無効化されているため、有効化するコマンド

source ~/.nvm/nvm.sh

が必要だそう。

そんなこんなで、必要なパッケージが揃った。先程の記事を参考にテストコードを記載。

const googlehome = require('google-home-notifier');
const language = 'ja';
googlehome.device("Google-Home", language);
googlehome.ip("192.168.100.112");
googlehome.notify('わっちゃん、おはよう', function(res) {
  console.log(res);
});

わっちゃんというのは息子の名前である。これを実行してみると、

$ node test.js
events.js:183
throw er; // Unhandled 'error' event
^
Error: getaddrinfo -3008
…

残念まだエラー。
npm|yarnで怒られたエラー集まとめ。WARN[deprecated,unmet dependency,peerDependencies,EPEERINVALID,engine]ERR![missing,invalid],throw er; // Unhandled &#39;error&#39; eventの解決方法。(2019/3/8更新) - Qiita
どうやら複数プロセスが動いていると起こるみたい。

$ ps aux | grep node
pi 20091 2.6 7.2 124928 32236 pts/0 Tl 21:23 0:05 node
pi@raspberrypi:~/googlehome $ sudo kill -9 20091

としたら、喋りだした!

cronで実行

ついでに「おはよう」なので毎朝7時に喋るようにセットしておくことにした。cronという定時に自動実行する機能に登録をする。
決まった時間に処理する | Make.
ここを参考にcronをスタートさせ、

$ crontab -e

へ次のコマンドを登録。

*/2 * * * * /home/pi/.nvm/versions/node/v8.9.4/bin/node /home/pi/googlehome/ohayo.js

・ 「****」とすると1分毎に実行だが、タイミングによってはうまくいかないこともあるため、「*/2 * * * *」として2分毎の実行登録がいいそうだ。
・実行させるnodeはフルパスにしておく。
、、、しかしエラー、ログを見てみる。

$ cat /var/log/syslog
Feb 28 22:22:01 raspberrypi CRON[20756]: (CRON) info (No MTA installed, discarding output)

システムログのエラーでググると同じ事象が見つかった。
Raspberry Piでcronを使った時の話し - Qiita
cronは実行されるとメールが飛ぶ仕組みであるためpostfixを入れておかないと行けないようだ。デフォでは「var/mail」に届く。
これでcronは解決。「00 7 * * * 」とすれば毎日7時に「わっちゃんおはよー」とgoogleHomeが話しかけるようになったとさ。

LINE通知から実行

そして本来やりたかったLINE通知から喋らせるヤツはこのふたつを参考にした。
Google Homeで子供の朝支度を促してみる - Qiita
Google HomeにLINEのメッセージを読み上げさせる(LINE BOT+Webhook+Firebase+Node.js) - メガロドンblog
データの流れはこんな感じ。
f:id:anpontan382:20180303091057p:plain
①LINE messageAPI → ②firebase → ③rassberry pi → ④google home

まず②のfirebaseへの登録を行う。上記記事を参考に、googleアカウントでログインし、googlehome用のデータベースを作成した。
firebaseっていうのは、webアプリなどを作る際に役立つ便利な機能が色々とあるサービス。従来自分でサーバを構築しないと出来なかったことが、簡単にできるようになる。今回はこのリアルタイムデータベース機能で、LINEからの通知を受け取る。

続いて①のLINE messageAPIへ登録する。これはお店などでよくあるBOTを作れるサービスだが、相手から通知を受けた時に、それに対応できるようにもなっており、webhockにデータを送ることができる。これをfirebase宛に設定することで、LINEの通知をfirebaseに届けることができる。

最後に③のrassberry piでfirebaseの更新を受け取れるようにする。
firebaseのパッケージをインストール。

npm install firebase

firebaseの更新を監視し、更新があればgoogleHomeに送るスクリプトを作ります。

const googlehome = require('google-home-notifier');
const language = 'ja';
googlehome.device("Google-Home", language);
googlehome.ip("192.168.100.112");

var firebase = require("firebase");
var config = {
  apiKey: "********",
  authDomain: "***********.frebaseapp.com",
  databaseURL: "https://********.firebaseio.com",
  projectId: "******",
  storageBucket: "",
  messagingSenderId: "*************"
};
//firebaseの設定画面で確認

firebase.initializeApp(config);
var db = firebase.database()
var receivedlineRef = db.ref( '/line/mes');

receivedlineRef.on("child_added", function(snap) {
  var linemessage = snap.val();
  snap.ref.remove(); //Delete child in firebase
  var textmain = linemessage.events[0].message.text;
  googlehome.notify(textmain, function(res) {
    console.log(textmain);
  });

nohup~&で実行すると、SSHを切断しても実行し続ける。

nohup node firebase.js &

完成!

今後の展開

なんだかんだで手間がかかったが、使ってみると色々アイデアが出てきてワクワクしてくる。
親が言っても聞かないときに、こっそりLINEで「わっちゃんもう寝ようね」と送って、googleHomeに話させる。「ほら天才googleHome様もそういってるから寝ようよ」みたいな感じで、しつけを代わりにやってもらうこともできる。
他にも、現在は日本語を読み上げる設定になっているが、英語を話させるのも楽しそう。LINEには翻訳BOTがあるので、親が考えた日本語を英語に翻訳させてgoogleHomeに話させれば親の英語力によらず英語教育が可能だ。
LINE以外にもfirebaseの更新でgoogleHomeを話させることができるわけだから、WEBをスクレイピングして「今日はひな祭りの日で、雛人形を飾ります」みたいな教養が取れれば、親の教養力によらず教養ある人間が育つだろう。

本当の今後の展開

いやはや機械が仕事を奪うってよく言われているが、これをやっていると子育ても奪われかねない。
いやまて、すでに僕は「息子に楽しんでもらうぞ~」という大義名分のもと、夜な夜なパソコンに齧りついてプログラムを書いているわけだが、すでに機械に子育ての機会を奪われている状況ではないか。
google Homeが自分から話をする機能はいずれgoogleが提供してくれるだろう。僕がわざわざしなくてもいいのではないか。
僕がgoogle Home開発をしている間、妻は祖父母に近況報告の手紙を書いていた。
f:id:anpontan382:20180303095210j:plain
人間ができること、すべきことむしろこれなのではないか!!

真理に到達した僕は、rassberry piからgoogle Homeを爆発させるコマンドを打ち込み、エンターキーをズッターン!と叩き、燃え上がるgoogle Homeを背に、寝ている息子のもとへ向かった(嘘)

でもホントは僕もわかっている。もう少し日々の子育てや家事をしたほうが、家族みんなにとって良いし、他にも6月にある重要な資格の勉強しなきゃいけないってこと。プログラムやブログを書いている場合じゃないことは確かなんだってこと。

buffaloルータでポートを開放するときの注意点

raspberry piに外部からアクセスできるようポートを解放しようとしたときに家のネットワーク設定で一部ハマったところを自分用メモに残しておく。

以前の記事で書いたが、僕の家のLANはwimaxルータ→buffalo社ルータ→PCという順でつながっている。
buffalo社のルータには、ルーターモード、ブリッジモード及びルーターモードとブリッジモードを自動切換するオートモードがあるのだが、ルーターモードにするとややこしいことになるというのが今回の話。
公式サイトの図が分かりやすいが(http://faq.buffalo.jp/app/answers/detail/a_id/16000
buffalo社ルータの上位機器(プロバイダーから提供される機器)にルーター機能がある場合はブリッジモード、ない場合はルーターモードにするのが一般的である。おそらくデフォルトはオートモードになっており、自動的に判別がおこなわれるはずだったが、なぜかルータモードになっていたため、2重でルータが接続される状態になっていた。
これについては、一般的な利用の中では問題はなかったが、外部からLANにアクセスする必要があると、複数ルータでポートを解放する必要が生じ、大変複雑な作業が必要となる。(https://www.akakagemaru.info/port/tracert-2.html
現状buffalo社ルータをルーターモードにする必要がないため、ブリッジモードへ固定することにした。

しかしブリッジモードへ固定すると、buffaloルータのアドレス「192.168.11.100」が自動的に割り振られる。
これはwimaxルータのDHCPが設定する「192.168.100.~」の範囲から外れてしまう為
・「192.168.100.~」が振られたPCから管理画面へログインができない
・buffaloルータへ接続したNASへアクセスできない
という問題が生じる。
そのため、wimaxルータが割り振るアドレスのセグメントに変更するという手順(http://faq.buffalo.jp/app/answers/detail/a_id/15978)を行う。これは、外部からアクセスできるようポートを解放する手順まで含めているが、LAN内だけでNASを使う場合は、上記リンクの手順1/4まで完了する。

僕の躓きポイントとして「2つ以上のネットワーク機器が接続されています」というエラーが起きた。
まず、エアステーション管理ツールで、現在のbuffaloルータのIPアドレスを取得する必要があるが、検索を実行すると「2つ以上のネットワーク機器が接続されています」というエラーが出た。
これについては、仮想OSで使用していたネットワークアダプタがあったため、
「コントロールパネル」「ネットワークと共有センター」「アダプター設定の変更」からbuffaloルータへ接続しているwifiアダプタ以外を無効にしておく必要がある。

上記手順が完了したら、「エクスプローラー」「PC]「ネットワークドライブの割り当て」で「\\buffaloルータに設定したIPアドレス」を入力すると、NASへアクセスができるようになるし、ウェブブラウザのアドレス欄にbuffaloルータに設定したIPアドレスを入力すると管理画面へログインできるようになる。

ここまでくればwimaxルータでの設定だけだ。
まず、wimaxルータへグローバルIPを設定する(http://www.uqwimax.jp/plan/wimax/option/global_ip/
そして管理画面で対象の機器のポートを解放すれば完了だ(https://www.akakagemaru.info/port/w04-portfw.html

対象機器(Rasberry Pi)側での作業についてはこちらを参考にした(https://qiita.com/3no3_tw/items/4b5975a9f3087edf4e20
SSHするポートについても標準から変更しておとセキュリティが向上する。(https://qiita.com/mukoya/items/606c6cfbdf2f5065e0e4

よし準備はととのったぁ!何しようかなぁ!
f:id:anpontan382:20180228224505p:plain