LoginSignup
1
2

More than 5 years have passed since last update.

GoogleHome/AmazonEcho に電車遅延情報を喋ってもらう(Bluetoothスピーカー編)

Posted at

はじめに

image.png

前回、GoogleHome の goole-home-notifier を使った場合を書きましたが、Bluetoothスピーカー接続でやったらいいんじゃない?と思いやってみました。これなら AmazonEcho も同じBluetoothスピーカーなので。

構成

image.png

RaspberryPiで定刻になったらYahoo路線情報ページをスクレイピングして正常運行以外ならば Bluetooth接続されたスピーカーにしゃべってもらいます。音声は VoiceText を使用します。

ハード

  • GoogleHome (私のはminiです)
  • AmazonEcho (私のはDotです)
  • RaspberryPi (今回は3B)
  • 母艦(Windowsマシン。何でも良い)

ソフト

  • raspbian (今回は 2017-09-07-raspbian-stretch を使いました)
  • nodejs (v9.8.0)
  • npm (v6.4.1)
  • VoiceText

中心となるソフトウェアは上記です。
raspbian、nodejs、npm は設定済み前提です。

Bluetoothスピーカー

RaspberryPi に接続されているスピーカーがあればなんでも良いです。
GoogleHome/AmazonEcho が市民権を得ているご家庭が多くなってきたんではないでしょうか?

GoogleHome/AmazonEchoのBluetooth接続は以前に行いましたのでそちらを参考ください。
「GoogleHome/AmazonEco を RaspberryPi の Bluetooth スピーカーにする」

VoiceText Web API

Bluetooth スピーカーに出力する音声は「VoiceText」を使います
VoiceTextとはなんぞやというと、文字列を合成音に変えてくれるTTS(TextToSpeech)エンジンです。

VoiceText は無料ですがAPIキーが必要です。取得しましょう。
VoiceText Web API
メールアドレスだけで取得できます。APIキーを控えておいてください。

VoiceText のインストール

作業ディレクトリ(trainfo)を作成して npm でインストールします。
再生ライブラリは、node-aplay を使いますのでこれもインストールします。

$ mkdir ~/trainfo
$ cd ~/trainfo
$ npm install voicetext
$ npm install node-aplay

VoiceText のテスト

一旦ここで、VoiceText が動くかのテストを行います。
下記のスクリプトを作成します。<VoiceTextのAPIキー>は 「VoiceText Web API」にユーザ登録したときに取得したものです。
話者(voice.SPEAKER.HIKARI)は SHOW,HARUKA,HIKARI,TAKERU,SANTA,BEAR などが使えますよ。替えてみてください。

~/trainfo/voicetext-sample.js
var VoiceText = require('voicetext');
var Sound = require('node-aplay');
var fs = require('fs');

var voice = new VoiceText('<VoiceTextのAPIキー>');
var OUT_PATH = '/home/pi/trainfo/_temp.wav'

voice
    .speaker(voice.SPEAKER.HIKARI) // SHOW,HARUKA,HIKARI,TAKERU,SANTA,BEAR
    .emotion(voice.EMOTION.HAPPINESS)
    .emotion_level(voice.EMOTION_LEVEL.HIGH)
    .volume(150)
    .speak("こんにちは、ラズベリーパイのテストです", function (e, buf) {
        if (e) {
            console.error(e);
        } else {
            fs.writeFileSync(OUT_PATH, buf, 'binary');
            new Sound(OUT_PATH).play();
            console.log("write done.");
        }
    });

無事に声が聞こえてきたら成功です。次行きましょう。

Yahoo路線情報ページをスクレイピング

スクレイピングには cheerio-httpcli を使いますのでインストールします。

$ npm install cheerio-httpcli

下記のソースでは、3路線の情報を取得しています。適宜変更して使ってください。
「平常運転」のときは何もしゃべりませんので、まずは遅延があるところでテストしてみてください。

Yahoo路線情報(https://transit.yahoo.co.jp/traininfo/top)

~/trainfo/trainfo-bt.js
const client = require('cheerio-httpcli');
const Sound = require('node-aplay');
var VoiceText = require('voicetext');
var fs = require('fs');

var voice = new VoiceText('<VoiceTextのAPIキー>');
const msg = [];
const OUT_PATH = '/home/pi/trainfo/_temp.wav'

client.fetch('https://transit.yahoo.co.jp/traininfo/detail/148/0/') // 江ノ島電鉄線
    .then(function (result) {
        check(result);
        return client.fetch('https://transit.yahoo.co.jp/traininfo/detail/29/0/'); // 横須賀線
    })
    .then(function (result) {
        check(result);
        return client.fetch('https://transit.yahoo.co.jp/traininfo/detail/125/0/'); // 相鉄本線
    })
    .then(function (result) {
        check(result);
    })
    .catch(function (err) {
        console.log(err);
    })
    .finally(function () {
        var text = msg.join();
        if (text.length > 0) {
            voice
                .speaker(voice.SPEAKER.HIKARI)
                .emotion(voice.EMOTION.HAPPINESS)
                .emotion_level(voice.EMOTION_LEVEL.HIGH)
                .volume(150)
                .speak(text, function (e, buf) {
                    if (e) {
                        console.error(e);
                    } else {
                        fs.writeFileSync(OUT_PATH, buf, 'binary');
                        new Sound(OUT_PATH).play();
                        console.log("write done.");
                    }
                });
        }
    });

function check(result) {
    if (!result.error) {
        var $ = result.$;
        var ti = $('h1.title').text().trim();
        var sv = $('#mdServiceStatus > dl > dt').text().trim();
        var tr = $('#mdServiceStatus > dl > dd.trouble').text().trim();
        if (!sv.match('平常運転')) {
            msg.push(ti + tr);
        }
        console.log(ti);
        console.log(sv);
        console.log(tr);
    }
}

実行

$ node trainfo-bt.js
江ノ島電鉄線
[!]列車遅延
混雑の影響で、列車に遅れが出ています。(11月23日 14時15分掲載)
横須賀線
[○]平常運転
相鉄本線
[○]平常運転
write done.

ちゃんと音声が出ましたでしょうか?
ここまでくればあともう少し!
※「平常運転」のときは、なにもしゃべりません。

cron

朝にしゃべってもらわないといけないのでスケジュールします。

$ crontab -l
#Bluetooth接続が切れているかもしれないので再接続
59 6 * * 1-5 /usr/local/bin/connect-bluetooth.sh
#平日7:00から15分ごとに運行情報プログラムを実行する
0,15,30 7 * * 1-5 node /home/pi/trainfo/trainfo-bt.js

以上です。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2