家に大きめの信楽焼のタヌキが送られてきたので、Raspberry Pi仕込んでRails&Herokuでしゃべるタヌキにしたお話。

#（ありがとうございます。）参考にさせていただきました。
引っ越し祝いに大きめのエジプト神像を送りつけられたのでラズパイを仕込んで喋れるようにした
http://qiita.com/sngazm/items/c27b7745fb68139213c2


# こんな感じ
### 定刻イベント(毎時00分にランダムに登録されたメッセージを読み上げます。)
マザーテレサからのメッセージ
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/yMN7C4EnRXI/0.jpg)](http://www.youtube.com/watch?v=yMN7C4EnRXI)

### 定刻イベント(毎時00分にランダムに登録されたメッセージを読み上げます。)
ドラえもんからのメッセージ
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/C7dyOcGa2MM/0.jpg)](http://www.youtube.com/watch?v=C7dyOcGa2MM)


### 朝７：００に天気予報を読み上げる
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/76CLacVh8Lw/0.jpg)](http://www.youtube.com/watch?v=76CLacVh8Lw)

### お掃除音楽　夜８：００にドリフ盆回しを爆音で。（本体は３０分ループです。）
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/XFPbAV2cMww/0.jpg)](http://www.youtube.com/watch?v=XFPbAV2cMww)


# 1:準備したハードウェア
タヌキの中身
![IMG_6033.JPG](https://qiita-image-store.s3.amazonaws.com/0/128165/5fc9ceb1-711e-7d78-1f95-b832cac39c28.jpeg)


・Raspberry Pi 2 Model B
・USBドングル(wifi)
・USBマウス（家にあるもの）
・UBSキーボード（家にあった）
・スピーカー
・MicroSDカード（16GB）
・HDMIケーブル
・Micro USBケーブル
新しく買ったものは、ラズパイとUSBドングルくらいでしたので、制作費としては、８０００円くらいでした。全部Amazonで買えました。

## １−２：ハードウェアのセットアップ
以下のサイトを参考にし、そのまま実行しました。動くようになりましたが、セットアップは時間がかかります。また注意事項としてMicroSDにNOOBSを入れてスロットに入れておかないと立ち上がりません。

・参考にしたサイト：https://liginc.co.jp/261317
・NOOBS（インストーラ）：https://www.raspberrypi.org/downloads/noobs/

インストールに際し、特に苦慮したことはありませんでした。モニタは自宅のテレビを使用しました。（HDMI付）電源はIphoneとかの充電器を利用しましたが、一応規格が２．１A以上を推奨しているようなので要確認です。私は確認せずにテレビのUSBケーブルから給電してました。


# ２：仕組み
ラズパイ自体に色々仕込もうかと思いましたが、更新性がある方が面白いのでRailsで作って、Herokuに上げてそれをインターネットに接続されたラズパイが見に行く仕組みにしました。


![TNK.png](https://qiita-image-store.s3.amazonaws.com/0/128165/5eeebb59-9418-664a-d412-903a2901362f.png)


# ３:しゃべる仕組み(Open Jtalk)を作ろう
ホルス神像様と同じくOpen Jtalkを採用させていただきました。

私はRubyを使うので、それで動く仕組みを組めないかと思いましたが、すでに先人が作ってくださいました。ありがとうございます。

open_jtalk-ruby	
https://github.com/sunny4381/open_jtalk-ruby/blob/master/README.md

これをRailsのコントローラーに仕込みますと以下のような感じ。

```ruby:posts/show.html.erb
<p>
  <%= @post.name %>
</p>

<p>
  <%= @post.body %>
</p>

<%= audio_tag("/a#{@post.id}.wav", :autoplay => true, :controls => true) %>
```

```ruby:posts_controller.rb
def show


    time = Time.zone.now

    require 'open_jtalk'


    text ="どうもたぬきです。お便りのご紹介の時間だたぬ。"+@post.name+"さんからのメッセージです。"+@post.body+
    "　　　以上です。どうぞよろしくお願いいたぬます。"

      OpenJtalk.load(OpenJtalk::Config::Mei::NORMAL) do |openjtalk|
      header, data = openjtalk.synthesis(openjtalk.normalize_text(text))



      OpenJtalk::WaveFileWriter.save("public/a#{@post.id}.wav", header, data)




    end
```

うむしゃべる。

# 4-1：タイムスケジュールでしゃべるようにつくろう。
とりあえずはタイムスケジュールを組み時間になったらしゃべるようにします。
以下の感じで。

![rate.png](https://qiita-image-store.s3.amazonaws.com/0/128165/7a91ffeb-5207-a365-13c7-2607f07a55bf.png)


私は定刻に飲む薬があるので、時間になったら教えてくれると助かります。
あと、子供が片付けをする時間にお片づけの曲を流したいので、それをセットします。その他はひとまず００分になったら、なんかしゃべるようにします。

まあ、この辺はほとんど鳩時計みたいなものですね。

#4-2 使用したライブラリ
JAVASCRIPT で CRON ちっくに指定時間で実行
http://yurubu.org/javascript-cron/

これをルートのページに設置して、時間になったらメッセージ読み上げページに
移動する仕組みとしました。


```ruby:posts/index.html.erb
script>


    var jsCron = {
        items:[],
        interval: null,
        parse: function(strUnix) {
            return strUnix.match(/^(\d+|\*) (\d+|\*) (\d+|\*) (\d+|\*) (\d|\*) +(\w+)/);
        },
        check: function() {
            var hoy = new Date();
            var test = [new Date(), hoy.getMinutes(), hoy.getHours(), hoy.getDate(), hoy.getMonth(), hoy.getDay()];

            for (var i in this.items) {
                var exec = 0;
                var t = this.parse(this.items[i][1]);
                for (var x in t)
                    if (t[x] && (t[x] == test[x] || t[x] == "*"))exec++;
                if (exec == 5 && this.items[i][0] == 0) {
                    eval(t[6]).call();
                    this.items[i][0] = 1;
                } else if (exec < 5 && this.items[i][0] == 1) {
                    this.items[i][0] = 0;
                }
            }
        },
        set: function(strUnix) {
            if (!/^(\d+|\*) (\d+|\*) (\d+|\*) (\d+|\*) (\d|\*) +(\w+)/.test(strUnix)) return new Error("Formato invalido");
            this.items.push([0, strUnix]);
        },
        init: function(seg) {
            var seg = seg || 1000;
            this.interval = setInterval("jsCron.check()", seg);
        }
    };
    jsCron.init();



    function nEffect() {
        audioElem = new Audio();
        audioElem.src = "/we.wav";
        audioElem.play();

    }
    // イベントの作成 (定刻メッセージ読み上げページへ移動)

    function mEffect() {
        { window.location.href = "/posts/<%=@randpost.id%>" ; };


    }

    // イベントの作成 (お天気予報読み上げページへ移動)

    function wEffect() {
        { window.location.href = "/posts/weather_news" ; };


    }

    // イベントの作成 (お薬アラーム読み上げページへ移動)

    function dEffect() {
        { window.location.href = "/posts/drug" ; };


    }

    // イベントの作成 (お掃除アラーム読み上げページへ移動)

    function cEffect() {
        { window.location.href = "/posts/clean_up" ; };


    }

//この辺で時間を指定してページを移動(分：時)

    jsCron.set("00 05 * * * mEffect()");
    jsCron.set("00 06 * * * mEffect()");
    jsCron.set("00 07 * * * wEffect()");
    jsCron.set("00 08 * * * mEffect()");
    jsCron.set("00 09 * * * mEffect()");
    jsCron.set("30 09 * * * mEffect()");
    jsCron.set("00 10 * * * mEffect()");
    jsCron.set("00 11 * * * mEffect()");
    jsCron.set("00 12 * * * mEffect()");
    jsCron.set("00 13 * * * mEffect()");
    jsCron.set("00 14 * * * mEffect()");
    jsCron.set("00 15 * * * mEffect()");
    jsCron.set("00 16 * * * mEffect()");
    jsCron.set("00 17 * * * mEffect()");
    jsCron.set("00 18 * * * mEffect()");
    jsCron.set("00 19 * * * mEffect()");
    jsCron.set("00 20 * * * mEffect()");
    jsCron.set("45 20 * * * cEffect()");
    jsCron.set("00 21 * * * mEffect()");
    jsCron.set("30 21 * * * dEffect()");
    jsCron.set("18 23 * * * mEffect()");
</script>
```

あまりニーズがあるかどうかはわからないので、ざっくりとメモ程度に作成しました。
もしご質問など頂けましたら回答させていただきます。

随時追記させていただきます。どうぞよろしくお願いいたします。