コンテンツへスキップ

NVIDIA Jetson NanoへのGoogle Home Notifier導入は、  こちら

google-tts-apiからHOYA社のVoice Text Web APIへ

Google Home Notifierは、テキストをgoogle-tts-apiを用いて、音声変換を実施しております。十分に内容は把握できますし、実利用には支障はないのですが、HOYA社より優れたWeb APIが公開されているので、HOYA社のVoice Text Web APIを用いた音声に変更を実施します。HOYA株式会社 VoiceText Web API

  1. HOYA社Voice Text Web APIの利用登録
  2. 「voicetext」のインストール
  3. google-home-notifierソースコード修正

前提条件

導入手順

1.HOYA社Voice Text Web APIの利用登録

HOYA株式会社 VoiceText Web APIの「無料利用登録」より利用登録を実施して下さい。利用登録後に、API KEYがメールで送付されて来ます。

2.「voicetext」のインストール

以下のコマンドで、「voicetext」をインストールします。

root@jetson:~# cd google-home-notifier/
root@jetson:~/google-home-notifier# npm update
root@jetson:~/google-home-notifier# npm install voicetext
npm WARN deprecated superagent@0.18.2: Please note that v5.0.1+ of superagent removes User-Agent header by default, therefore you may need to add it yourself (e.g. GitHub blocks requests without a User-Agent header).  This notice will go away with v5.0.2+ once it is released.
google-home-notifier@1.2.0 /root/google-home-notifier
└── voicetext@0.0.7  extraneous

npm WARN google-home-notifier@1.2.0 No repository field.
root@jetson:~/google-home-notifier# npm install -g npm
/usr/local/bin/npm -> /usr/local/lib/node_modules/npm/bin/npm-cli.js
/usr/local/bin/npx -> /usr/local/lib/node_modules/npm/bin/npx-cli.js
/usr/local/lib
├── ansi-regex@2.1.1
├── aproba@2.0.0
├── aws4@1.8.0
├── bin-links@1.1.3
├── bluebird@3.5.5
├── byte-size@5.0.1
├── cacache@12.0.3
├── call-limit@1.1.1
├── chownr@1.1.2

3.google-home-notifierソースコード修正

「google-home-notifier.js」ファイルの修正

以下を参考に2箇所追加および1箇所コメントアウト(削除)を実施します。

var Client = require('castv2-client').Client;
var DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver;
var mdns = require('mdns');
var browser = mdns.createBrowser(mdns.tcp('googlecast'));
var deviceAddress;
var language;

//Add (((((((((((
var VoiceTextWriter = require('./VoiceTextWriter');
var voiceTextWriter = new VoiceTextWriter();
//Add ))))))))))

var device = function(name, lang = 'en') {
    device = name;
    language = lang;
    return this;
};

var ip = function(ip, lang = 'en') {
  deviceAddress = ip;
  language = lang;
  return this;
}

var googletts = require('google-tts-api');
var googlettsaccent = 'us';
var accent = function(accent) {
  googlettsaccent = accent;
  return this;
}

var notify = function(message, callback) {
  if (!deviceAddress){
    browser.start();
    browser.on('serviceUp', function(service) {
      console.log('Device "%s" at %s:%d', service.name, service.addresses[0], service.port);
      if (service.name.includes(device.replace(' ', '-'))){
        deviceAddress = service.addresses[0];
        getSpeechUrl(message, deviceAddress, function(res) {
          callback(res);
        });
      }
      browser.stop();
    });
  }else {
    getSpeechUrl(message, deviceAddress, function(res) {
      callback(res);
    });
  }
};

var play = function(mp3_url, callback) {
  if (!deviceAddress){
    browser.start();
    browser.on('serviceUp', function(service) {
      console.log('Device "%s" at %s:%d', service.name, service.addresses[0], service.port);
      if (service.name.includes(device.replace(' ', '-'))){
        deviceAddress = service.addresses[0];
        getPlayUrl(mp3_url, deviceAddress, function(res) {
          callback(res);
        });
      }
      browser.stop();
    });
  }else {
    getPlayUrl(mp3_url, deviceAddress, function(res) {
      callback(res);
    });
  }
};

var getSpeechUrl = function(text, host, callback) {
//Delete ((((((((((
//  googletts(text, language, 1, 1000, googlettsaccent).then(function (url) {
//    onDeviceUp(host, url, function(res){
//      callback(res)
//    });
//  }).catch(function (err) {
//    console.error(err.stack);
//  });
//Delete )))))))))
//Add (((((((((
	voiceTextWriter.convertToText(text).then(function(result, reject){
        onDeviceUp(host, result, function(res){
            callback(res)
        });
    }).catch(function onRejected(error){
		console.error(error);
	});
//Add )))))))))
};

var getPlayUrl = function(url, host, callback) {
    onDeviceUp(host, url, function(res){
      callback(res)
    });
};

var onDeviceUp = function(host, url, callback) {
  var client = new Client();
  client.connect(host, function() {
    client.launch(DefaultMediaReceiver, function(err, player) {

      var media = {
        contentId: url,
        contentType: 'audio/mp3',
        streamType: 'BUFFERED' // or LIVE
      };
      player.load(media, { autoplay: true }, function(err, status) {
        client.close();
        callback('Device notified');
      });
    });
  });

  client.on('error', function(err) {
    console.log('Error: %s', err.message);
    client.close();
    callback('error');
  });
};

exports.ip = ip;
exports.device = device;
exports.accent = accent;
exports.notify = notify;
exports.play = play;

「VoiceTextWriter.js」ファイルの新規作成

  • 「@APIKEY@」を利用登録時に受信したAPIKEYに変更
  • 「@WEBPAHT@」にWEBサーバの公開フォルダに格納する音声ファイルを指定
    例:/var/www/html/voice-text.wav
  • 「@URL@」にWEBサーバの音声ファイルへアクセスする際のURLを指定
    例:http://192.168.0.200/voice-text.wav
var fs = require('fs');
var VoiceText = require('voicetext');
var voice = new VoiceText('@APIKEY@');
var OUT_PATH = '@WEBPAHT@';
var OUTPUT_URL = '@URL@';

class VoiceTextWriter{

	convertToText(text){
	return new Promise(function(resolve,reject){
	voice
	.speaker(voice.SPEAKER.HIKARI)
	.emotion(voice.EMOTION.HAPPINESS)
//	.emotion_level(voice.EMOTION_LEVEL.HIGH)
	.emotion_level(2)
        .speed(100)
	.volume(120)
	.speak(text, function(e, buf){
	    if(e){
	      console.error(e);
	      reject(e);

	    }else{
	   	 fs.writeFileSync(OUT_PATH, buf, 'binary');
	  	 resolve(OUTPUT_URL);
	    }
	  });
	});
	}
}
module.exports = VoiceTextWriter;

VoiceText Web APIマニュアルを参考に、speedやvolumeなどのオプション指定を変更して、好みの音声に変更して下さい。設定ファイル変更時には、Google Home Notifierの再起動が必要となります。

created by Rinker
NVIDIA
¥19,000 (2021/08/19 16:46:56時点 Amazon調べ-詳細)

Google Home Notifier導入準備

Google Home Notifier導入に向けてNode.jsとnpmをインストールします。

root@jetson:~# apt update
root@jetson:~# apt upgrade -y
root@jetson:~# apt install nodejs npm -y
root@jetson:~# npm cache clean
root@jetson:~# npm install npm n -g
root@jetson:~# npm -v
3.5.2

google-home-notifierインストール

@raspberrypi $ curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
@raspberrypi$ sudo apt-get install nodejs
@raspberrypi $ sudo apt-get install git-core libnss-mdns libavahi-compat-libdnssd-dev

apt install libavahi-compat-libdnssd-dev

root@jetson:~# git clone https://github.com/noelportugal/google-home-notifier
Cloning into 'google-home-notifier'...
remote: Enumerating objects: 155, done.
remote: Total 155 (delta 0), reused 0 (delta 0), pack-reused 155
Receiving objects: 100% (155/155), 26.28 KiB | 48.00 KiB/s, done.
Resolving deltas: 100% (84/84), done.
root@jetson:~# cd google-home-notifier/
root@jetson:~/google-home-notifier# npm install

GoogleTTSの仕様変更対応

GoogleTTSの新バージョンがリリースされており、このままでは、うまく動作しません。この手順を実施していないと、以下のエラーメッセージが表示されます。

Error: get key failed from google
at /root/google-home-notifier/node_modules/google-tts-api/lib/key.js:27:13
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)

GitHubでクローンしたレポジトリのとオプフォルダーにある、package.jsonのバージョン情報を変更。(0.0.2から0.0.4に変更)

root@jetson:~/google-home-notifier# vi package.json
"keywords": [
"google home",
"notifications",
"notifier"
],
"license": "MIT",
"dependencies": {
"body-parser": "^1.15.2",
"castv2-client": "^1.1.2",
"express": "^4.14.0",
"google-tts-api": "0.0.4",// ここを0.0.4に書き換える
"mdns": "^2.3.3",
"ngrok": "^2.2.4"
},

pakage.jason変更後に、google-tts-apiのアップデートを実施。

root@jetson:~/google-home-notifier# npm update google-tts-api
google-home-notifier@1.2.0 /root/google-home-notifier
└── google-tts-api@0.0.4

Webhook(WEBリクエスト)形式での運用準備

google-home-notifierフォルダにあるexample.jsを流用して、以下の形式でのリクエストによりGoogleホームより音声出力を実現します。以下のコマンドで、WEBアクセスの待ち状態となります。

root@jetson:~/google-home-notifier# nodejs example.js

起動時に以下のWARNINGが出るのですが、ほかの方もWARNINGが出たまま運用しているようです。(WARNINGを消す情報は見つけられませんでした)

*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/blog/projects/avahi-compat.html>
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/blog/projects/avahi-compat.html>Endpoints:

google-home-notifierフォルダにあるexample.jsをコピーして、実際に利用するスクリプトを準備します。

  • serverPort:NVIDIA Jetson Nanoの受付ポート番号
  • deviceName:Google Homeのニックネーム
  • ip:Google HomeのIPアドレス
  • 言語設定を2か所 'ja' に変更します。
const serverPort = @PORT_NUM@; // default port

var deviceName = 'Google-Home-2F';
var ip = '192.168.xxx.xxx'; // Google-Home-IP


var language = 'ja'; // default language code

今回は3台分のGoogle Home Miniを運用したいので、example.jsを3個コピーして、3個のスクリプトを起動する方式にしました。

  • Google-Home-1:192.168.xxx.81:ポート番号9081
    http://192.168.xxx.xxx:9081/google-home-notifier?text=Hello+Google+Home
  • Google-Home-2:192.168.xxx.82:ポート番号9082
    http://192.168.xxx.xxx:9082/google-home-notifier?text=Hello+Google+Home
  • Google-Home3:192.168.xxx.83:ポート番号9083
    http://192.168.xxx.xxx:9083/google-home-notifier?text=Hello+Google+Home

forever導入による常時起動化とサーバー再起動時の自動起動

foreverモジュールの導入方法

root@jetson:~/google-home-notifier# npm install -g forever

起動時のコマンドは、以下となります。

/usr/local/bin/forever start /home/user/google-home-notifier/google-home-1.js

再起動時にスクリプトが自動起動するようにクーロン登録します。

root@jetson:~/google-home-notifier# crontab -e

以下を登録します。

@reboot /usr/local/bin/forever start /home/user/google-home-notifier/google-home-1.js
@reboot /usr/local/bin/forever start /home/user/google-home-notifier/google-home-2.js
@reboot /usr/local/bin/forever start /home/user/google-home-notifier/google-home-3.js

foreverコマンドは、「stop」「restart」がそれぞれ停止と再起動となります。
「list」では、foreverで実行しているNode.jsアプリのパスや実行時間、ログファイルの保存場所などの詳細情報を出力します。

雨が降り出す前に通知①Google Homeスピーカーとライン通知

Use Case(ユースケース)

約2−3週間利用してみてのベストプラクティスです。

YahooのYOLP(地図)気象情報APIを利用し、緯度経度で指定した地点の10分間隔の天気予報を定期的にチェックし、トリガーとします。(日本ならではの細かなWEBサービスを利用します)
天候が「Rain(雨)」に変化した際に、Webhooks経由でトリガーを受け、LINEに通知および、トリガー発生時間(日中)を判定しGoogle Homeスピーカーで雨が降り出す旨のアナウンスを実行します。Google Homeスピーカーは就寝時間などには音声を出させたくないので、時間判定を入れました。

前提条件

  • Yahoo! JAPANのアプリケーションID Yahoo!JAPANアプリケーションの管理
    アプリケーションIDはYahoo! JAPAN IDをお持ちの方ならどなたでも登録できます。アプリケーションIDは、各リクエスト送信時に必要で、開発者自身ではなく、アプリケーションを特定します。
  • (Raspberry Piの)Google Home Notifier導入が終わっている「google-home-notifier」導入
  • (Raspberry Piの)PHPが動作するWEBサーバがセットアップされている
  • (Raspberry Piの)WEBサーバの公開設定が終わっている
  • IFTTTサービスの利用登録が実施済みである
  • IFTTTサービスにおいて、Webhooksが利用可能である IFTTT(イフト)でWebhooksの利用
  • IFTTTサービスにおいて、LINE Notifyの利用設定を実施している

全体の流れ

  1. Weather.phpファイルの準備
  2. Weather.phpの定期実行設定、雨を検知した時点でWEB APIへトリガー
  3. WEB APIよりLINEへメッセージ送信
  4. Google Homeスピーカーでアナウンス(Google Home Notifier経由)

Weather.phpファイルの準備

こちらのページを参照して下さい。

Weather.phpの定期実行

Synologyの「コントロールパネル」「タスクスケジューラー」で10分毎の実行で、以下のコマンドラインを登録して、定期実行しております。

/usr/local/bin/php72 /var/services/homes/user/weather.php

トリガー

Weather.phpよりRaspberry PiのWEB APIへ直接トリガーされます。3つのパラメータを設定します。

    • APIKEY=apikey
    • KEY=Weather
    • text="$text"
APIKEY=apikey&KEY=Weather&text="$text"

アクション

以下が、準備したサンプルのPHPスクリプトとなります。

//@HOME_API_LOG_NAME@ ログファイル名、書き込み権限が必要です
//@HOME_API_KEY@ POST受信時の簡易的なAPI-KEYのトークン確認を行います
//@IFTTT_POST_API_KEY@ IFTTTのWebhooks用API-KEY
//@GOOGLE_HOME_1@ http://192.168.0.200:9081 などgoogle home notifier向けのURL
//@GOOGLE_HOME_2@ google home notifier向けのURL
//@GOOGLE_HOME_3@ google home notifier向けのURL

//各種設定
//ログのファイル名
define("HOME_API_LOG_NAME","@HOME_API_LOG_NAME@");
//home-api-key
define("HOME_API_KEY","@HOME_API_KEY@");
//IFTTT用webhookパラメータ
define("IFTTT_POST_API_KEY","/with/key/@IFTTT_POST_API_KEY@");
define("IFTTT_POST_API_BASE","https://maker.ifttt.com/trigger/");
//IFTTT用puchLINE
define("IFTTT_LINE_KEY","pushLINE");

//google-home-notifier
define("GOOGLE_HOME_1",'@GOOGLE_HOME_1@');
define("GOOGLE_HOME_2",'@GOOGLE_HOME_2@');
define("GOOGLE_HOME_3",'@GOOGLE_HOME_3@');

function checkTime($startTime, $endTime) {
	$currentTime = date('H:i');
	if(strtotime($startTime) <= strtotime($currentTime) and strtotime($currentTime) <= strtotime($endTime)) {
		return true;
	}else{
		return false;
	}
}

function pushLINE($value1, $value2) {
	logger("Start pushLINE value1={$value1},value2={$value2}","INFO");
	$url = IFTTT_POST_API_BASE.IFTTT_LINE_KEY.IFTTT_POST_API_KEY;
	$data = array(
		'value1' => $value1,
		'value2' => $value2
	);
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

function announce($api_url, $text) {
	logger("Start announce target={$api_url},text={$text}","INFO");
	$message = 'text='.$text;
	$data = array(
		'text' => "$text"
	);
	$path = '/google-home-notifier';
	$url = $api_url.$path;
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  // curl_execの結果を文字列で返す
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

function logger($text, $level) {
	$datetime = date('Y-m-d H:i:s');
	$date = date('Ym');
	$file_name = __DIR__ . "/log/log-home-{$date}.log";
	$text = "{$datetime} [{$level}] {$text}" . PHP_EOL;
	echo $text;
	if(!(file_exists($file_name))){
		touch($file_name);
		chmod($file_name, 0777);
	}
	return error_log(print_r($text, TRUE), 3, $file_name);
}

logger("Start API","INFO");

if(isset($_POST['KEY']) && strcmp($_POST['APIKEY'], HOME_API_KEY) == 0) {
	logger("KEY : ".$_POST['KEY'],"INFO");
	logger("TEXT : ".$_POST['TEXT'],"INFO");
	$text = $_POST['TEXT'];
	switch ($_POST['KEY']) {
	case 'Weather':
		logger("Start Weather","INFO");
		//Rain alert
		pushLine('【天気情報】',$text);
		if(checkTime('7:00','19:00')) {
			announce(GOOGLE_HOME_2, $text);
			announce(GOOGLE_HOME_3, $text);
		}
		if(checkTime('6:00','23:00')) {
			announce(GOOGLE_HOME_1, $text);
		}
		break;
	default:
		logger("This is private API. (in Default)","ERROR");
	}
}else{
	logger("This is private API. (in else)","ERROR");
}

アクション1

LINE送信のアクションを設定します。すでに、他ユースケースなどでIFTTT側にLINE送信のレシピを導入されている方は、アクション2の定義に進んで下さい。

アクション1:トリガー

アクセスキーなどの初期設定値は、IFTTTより取得して下さい。

IFTTT(イフト)でWebhooksの利用

//IFTTT用webhookパラメータ
define("IFTTT_POST_API_KEY","/with/key/アクセスキー");
define("IFTTT_POST_API_BASE","https://maker.ifttt.com/trigger/");
//IFTTT用puchLINE
define("IFTTT_LINE_KEY","pushLINE");

function pushLINE($value1, $value2) {
	$url = IFTTT_POST_API_BASE.IFTTT_LINE_KEY.IFTTT_POST_API_KEY;
	$data = array(
		'value1' => $value1,
		'value2' => $value2
	);
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

アクション1:IFTTTでのトリガー


Webhooksを{event}:pushLINEで設定します。

アクション1:アクション


LINE送信のアクションを定義します。
Recipientでラインの送付先を指定します。すでに作成しているLINEのグループにも送信することが出来ます。
Message部分は、自由に変更出来ます。今回は、PHPより2つの引数を渡しているので、2つの引数をMessageに入れております。pushLine('【テスト】',$text);

アクション2

Google Home Notifier経由で、Google Homeからアナウンスを流します。「google-home-notifier」導入

//@GOOGLE_HOME_1@ http://192.168.0.200:9081 などgoogle home notifier向けのURL
define("GOOGLE_HOME_1",'@GOOGLE_HOME_1@');

function announce($api_url, $text) {
	logger("Start announce target={$api_url},text={$text}","INFO");
	$message = 'text='.$text;
	$data = array(
		'text' => "$text"
	);
	$path = '/google-home-notifier';
	$url = $api_url.$path;
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  // curl_execの結果を文字列で返す
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

announce(GOOGLE_HOME_1, $text);

時間判定について checkTime関数

対象時間の開始と終了を指定して、true, falseを戻り値とする関数を準備しました。
日付を跨る設定などは考慮しておりません。

checkTime('6:00','23:00')とすれば、朝6時から夜23時まで「True」となります。
このチェック関数を用いて、Google Homeのアナウンス対象時間か否かを確認しています。

function checkTime($startTime, $endTime) {
	$currentTime = date('H:i');
	if(strtotime($startTime) <= strtotime($currentTime) and strtotime($currentTime) <= strtotime($endTime)) {
		return true;
	}else{
		return false;
	}
}

 

Use Case(ユースケース)

Yahoo Japan防災速報の情報を利用します。YahooのIoTプラットフォームである「myThings」の利用も考えたのですが、トリガー登録の単位が細かすぎたりと煩雑だったので、防災速報のメール登録を行い、メール受信をトリガーにライン通知とGoogle Homeからのアナウンスを実現しております。Yahooからの防災速報メールの着信監視とメールの簡単な加工はMicrosoft Flowを利用しております。

前提条件

  • (Raspberry Piの)Google Home Notifier導入が終わっている「google-home-notifier」導入
  • (Raspberry Piの)PHPが動作するWEBサーバがセットアップされている
  • (Raspberry Piの)WEBサーバの公開設定が終わっている
  • IFTTTサービスの利用登録が実施済みである
  • IFTTTサービスにおいて、Webhooksが利用可能である IFTTT(イフト)でWebhooksの利用
  • IFTTTサービスにおいて、LINE Notifyの利用設定を実施している
  • Microsoft Flowの利用登録が実施済みである (YahooJapan防災速報メール受信をトリガー出来たらば別の方法で問題ないです)

全体の流れ

  1. Yahoo Japan防災速報のメール版に登録
    「通知先の設定(メールアドレス)」「地域の設定」および「通知する情報を選択」
  2. 今回は、GoogleのGmailを用いたので、Microsoft Flowを用いて、Yahoo Japan防災速報のメールをトラップします
  3. Yahoo Japan防災速報のメールタイトルのみを自分自身の防災速報専用のツイッタアカウントに発信します
  4. IFTTTのTwitterで自分自身の発信した防災速報情報をトラップし、防災速報情報受信時のアクションを実行(Raspberry PiのWEB APIへ発信)
  5. WEB APIよりLINEへメッセージ送信
  6. Google Homeスピーカーでアナウンス(Google Home Notifier経由)

トリガー

Yahoo Japan防災速報のメールをトラップし、Twitterで発信

MicrosoftFlowのGmailで準備されている「新しいメールが届いたとき」のトリガーに、「開始」にYahoo Japan防災速報が送付されてくるメールアドレスを登録します。
「alerts-emg@mail.yahoo.co.jp」
メールにはID情報などが含まれているため、メールの件名をツイートします。

Tweetをトリガーに設定

トリガー(this)に自分のTweetを受信した際をトリガーとします。「New tweet by you」のトリガーを選択します。

アクション

IFTTTのWebhooksよりRaspberry PiのWEB APIへPUSH通知

IFTTT(イフト)でWebhooksの利用

  • URL:準備したAPIのURLを指定します。外部からWEBアクセス可能なURLを指定する必要があります。また、APIトークンを送信するので、https:// での指定を強くオススメします。
  • Method:今回は、POST受信に対応したPHPを用いるので、POSTを指定します。
  • Content Type:application/x-www-form-urlencoded: キーと値は、その間に '=' がある形でキーと値の組になり、 '&' で区切られてエンコードされます。キーや値の英数字以外の文字は、パーセントエンコーディングされます。
  • Body:準備したPHPの仕様に合わせて、3つのパラメータを設定します。
    • APIKEY=apikey
    • KEY=Weather
    • text=" {{Text}}"
APIKEY=apikey&KEY=UrgentInfo&TEXT=" {{Text}}"

以下が、準備したサンプルのPHPスクリプトとなります。

//@HOME_API_LOG_NAME@ ログファイル名、書き込み権限が必要です
//@HOME_API_KEY@ POST受信時の簡易的なAPI-KEYのトークン確認を行います
//@IFTTT_POST_API_KEY@ IFTTTのWebhooks用API-KEY
//@GOOGLE_HOME_1@ http://192.168.0.200:9081 などgoogle home notifier向けのURL
//@GOOGLE_HOME_2@ google home notifier向けのURL
//@GOOGLE_HOME_3@ google home notifier向けのURL

//各種設定
//ログのファイル名
define("HOME_API_LOG_NAME","@HOME_API_LOG_NAME@");
//home-api-key
define("HOME_API_KEY","@HOME_API_KEY@");
//IFTTT用webhookパラメータ
define("IFTTT_POST_API_KEY","/with/key/@IFTTT_POST_API_KEY@");
define("IFTTT_POST_API_BASE","https://maker.ifttt.com/trigger/");
//IFTTT用puchLINE
define("IFTTT_LINE_KEY","pushLINE");

//google-home-notifier
define("GOOGLE_HOME_1",'@GOOGLE_HOME_1@');
define("GOOGLE_HOME_2",'@GOOGLE_HOME_2@');
define("GOOGLE_HOME_3",'@GOOGLE_HOME_3@');

function checkTime($startTime, $endTime) {
	$currentTime = date('H:i');
	if(strtotime($startTime) <= strtotime($currentTime) and strtotime($currentTime) <= strtotime($endTime)) {
		return true;
	}else{
		return false;
	}
}

function pushLINE($value1, $value2) {
	logger("Start pushLINE value1={$value1},value2={$value2}","INFO");
	$url = IFTTT_POST_API_BASE.IFTTT_LINE_KEY.IFTTT_POST_API_KEY;
	$data = array(
		'value1' => $value1,
		'value2' => $value2
	);
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

function announce($api_url, $text) {
	logger("Start announce target={$api_url},text={$text}","INFO");
	$message = 'text='.$text;
	$data = array(
		'text' => "$text"
	);
	$path = '/google-home-notifier';
	$url = $api_url.$path;
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  // curl_execの結果を文字列で返す
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

function logger($text, $level) {
	$datetime = date('Y-m-d H:i:s');
	$date = date('Ym');
	$file_name = __DIR__ . "/log/log-home-{$date}.log";
	$text = "{$datetime} [{$level}] {$text}" . PHP_EOL;
	echo $text;
	if(!(file_exists($file_name))){
		touch($file_name);
		chmod($file_name, 0777);
	}
	return error_log(print_r($text, TRUE), 3, $file_name);
}

logger("Start API","INFO");

if(isset($_POST['KEY']) && strcmp($_POST['APIKEY'], HOME_API_KEY) == 0) {
	logger("KEY : ".$_POST['KEY'],"INFO");
	logger("TEXT : ".$_POST['TEXT'],"INFO");
	$text = $_POST['TEXT'];
	switch ($_POST['KEY']) {
	case 'UrgentInfo':
		logger("Start info from tweet","INFO");
		pushLine('【緊急通知】',$text);
		if(checkTime('7:00','19:00')) {
			announce(GOOGLE_HOME_2, $text);
			announce(GOOGLE_HOME_3, $text);
		}
		if(checkTime('6:00','23:00')) {
			announce(GOOGLE_HOME_1, $text);
		}
		break;
	default:
		logger("This is private API. (in Default)","ERROR");
	}
}else{
	logger("This is private API. (in else)","ERROR");
}

アクション1

LINE送信のアクションを設定します。すでに、他ユースケースなどでIFTTT側にLINE送信のレシピを導入されている方は、アクション2の定義に進んで下さい。

アクション1:トリガー

アクセスキーなどの初期設定値は、IFTTTより取得して下さい。

IFTTT(イフト)でWebhooksの利用

//IFTTT用webhookパラメータ
define("IFTTT_POST_API_KEY","/with/key/アクセスキー");
define("IFTTT_POST_API_BASE","https://maker.ifttt.com/trigger/");
//IFTTT用puchLINE
define("IFTTT_LINE_KEY","pushLINE");

function pushLINE($value1, $value2) {
	$url = IFTTT_POST_API_BASE.IFTTT_LINE_KEY.IFTTT_POST_API_KEY;
	$data = array(
		'value1' => $value1,
		'value2' => $value2
	);
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

アクション1:IFTTTでのトリガー


Webhooksを{event}:pushLINEで設定します。

アクション1:アクション


LINE送信のアクションを定義します。
Recipientでラインの送付先を指定します。すでに作成しているLINEのグループにも送信することが出来ます。
Message部分は、自由に変更出来ます。今回は、PHPより2つの引数を渡しているので、2つの引数をMessageに入れております。pushLine('【テスト】',$text);

アクション2

Google Home Notifier経由で、Google Homeからアナウンスを流します。「google-home-notifier」導入

//@GOOGLE_HOME_1@ http://192.168.0.200:9081 などgoogle home notifier向けのURL
define("GOOGLE_HOME_1",'@GOOGLE_HOME_1@');

function announce($api_url, $text) {
	logger("Start announce target={$api_url},text={$text}","INFO");
	$message = 'text='.$text;
	$data = array(
		'text' => "$text"
	);
	$path = '/google-home-notifier';
	$url = $api_url.$path;
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  // curl_execの結果を文字列で返す
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

announce(GOOGLE_HOME_1, $text);

時間判定について checkTime関数

対象時間の開始と終了を指定して、true, falseを戻り値とする関数を準備しました。
日付を跨る設定などは考慮しておりません。

checkTime('6:00','23:00')とすれば、朝6時から夜23時まで「True」となります。
このチェック関数を用いて、Google Homeのアナウンス対象時間か否かを確認しています。

function checkTime($startTime, $endTime) {
	$currentTime = date('H:i');
	if(strtotime($startTime) <= strtotime($currentTime) and strtotime($currentTime) <= strtotime($endTime)) {
		return true;
	}else{
		return false;
	}
}

 

Use Case(ユースケース)

Google音声コマンド経由で別のGoogle Homeデバイスにメッセージ送信を行います。(Google Home Notifier経由)

前提条件

  • (Raspberry Piの)Google Home Notifier導入が終わっている「google-home-notifier」導入
  • (Raspberry Piの)PHPが動作するWEBサーバがセットアップされている
  • (Raspberry Piの)WEBサーバの公開設定が終わっている
  • IFTTTサービスの利用登録が実施済みである
  • IFTTTサービスにおいて、Webhooksが利用可能である IFTTT(イフト)でWebhooksの利用

全体の流れ

  1. IFTTTのGoogle Assistantより指定スピーカーへの音声コマンドをトリガートリガー登録
  2. IFTTTのWebhooksでPCシャットダウン時の音声コマンド受領時のアクションを実行(Raspberry PiのWEB APIへ発信)
  3. Google Homeスピーカーでアナウンス(Google Home Notifier経由)

トリガー

トリガー(this)にGoogle Assistantを選択し「Say a phrase with a text ingredient」のトリガーを選択します。これで、コマンドに加えて、不定形のテキストメッセージを追加出来ます。

音声コマンドを登録します。
「リビングにアナウンス $」
「リビングに連絡 $」などを登録します。
$部分が、不定形のテキスト部分となります。

コマンド受付時のGoogle Homeからのレスポンスも登録します。
「リビングにアナウンスします」

Lanuguage(言語)は、Japanese(日本語)を選択します。

アクション

IFTTTのWebhooksよりRaspberry PiのWEB APIへPUSH通知

IFTTT(イフト)でWebhooksの利用

  • URL:準備したAPIのURLを指定します。外部からWEBアクセス可能なURLを指定する必要があります。また、APIトークンを送信するので、https:// での指定を強くオススメします。
  • Method:今回は、POST受信に対応したPHPを用いるので、POSTを指定します。
  • Content Type:application/x-www-form-urlencoded: キーと値は、その間に '=' がある形でキーと値の組になり、 '&' で区切られてエンコードされます。キーや値の英数字以外の文字は、パーセントエンコーディングされます。
  • Body:準備したPHPの仕様に合わせて、3つのパラメータを設定します。
    • APIKEY=apikey
    • KEY=ExecAnnounce1 3台のスピーカーがあり、リビングを1としています。ExecAnnounce2を子供1、ExecAnnounce3を子供2としているので、それぞれ別のレシピとして登録します。
    • text={{TextField}} 不定形テキスト「$」部分となります。
APIKEY=apikey&KEY=ExecAnnounce1&text= {{TextField}}

以下が、準備したサンプルのPHPスクリプトとなります。

//@HOME_API_LOG_NAME@ ログファイル名、書き込み権限が必要です
//@HOME_API_KEY@ POST受信時の簡易的なAPI-KEYのトークン確認を行います
//@IFTTT_POST_API_KEY@ IFTTTのWebhooks用API-KEY
//@GOOGLE_HOME_1@ http://192.168.0.200:9081 などgoogle home notifier向けのURL
//@GOOGLE_HOME_2@ google home notifier向けのURL
//@GOOGLE_HOME_3@ google home notifier向けのURL

//各種設定
//ログのファイル名
define("HOME_API_LOG_NAME","@HOME_API_LOG_NAME@");
//home-api-key
define("HOME_API_KEY","@HOME_API_KEY@");

//google-home-notifier
define("GOOGLE_HOME_1",'@GOOGLE_HOME_1@');
define("GOOGLE_HOME_2",'@GOOGLE_HOME_2@');
define("GOOGLE_HOME_3",'@GOOGLE_HOME_3@');

function checkTime($startTime, $endTime) {
	$currentTime = date('H:i');
	if(strtotime($startTime) <= strtotime($currentTime) and strtotime($currentTime) <= strtotime($endTime)) {
		return true;
	}else{
		return false;
	}
}

function announce($api_url, $text) {
	logger("Start announce target={$api_url},text={$text}","INFO");
	$message = 'text='.$text;
	$data = array(
		'text' => "$text"
	);
	$path = '/google-home-notifier';
	$url = $api_url.$path;
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  // curl_execの結果を文字列で返す
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

function logger($text, $level) {
	$datetime = date('Y-m-d H:i:s');
	$date = date('Ym');
	$file_name = __DIR__ . "/log/log-home-{$date}.log";
	$text = "{$datetime} [{$level}] {$text}" . PHP_EOL;
	echo $text;
	if(!(file_exists($file_name))){
		touch($file_name);
		chmod($file_name, 0777);
	}
	return error_log(print_r($text, TRUE), 3, $file_name);
}


logger("Start API KEY=".$_POST['KEY'],"INFO");

if(isset($_POST['KEY']) && strcmp($_POST['APIKEY'], HOME_API_KEY) == 0) {
	if(isset($_POST['TEXT'])){
		$text = $_POST['TEXT'];
	}
	switch ($_POST['KEY']) {
	case 'ExecAnnounce1': //Living
		logger("Start ExecAnnounce1","INFO");
		if(checkTime('6:00','22:00')) {
			announce(GOOGLE_HOME_1, $text);
		}
		break;
	case 'ExecAnnounce2': //Son
		logger("Start ExecAnnounce2","INFO");
		if(checkTime('6:00','22:00')) {
			announce(GOOGLE_HOME_2, $text);
		}
		break;
	case 'ExecAnnounce3': //Doughter
		logger("Start ExecAnnounce3","INFO");
		if(checkTime('6:00','22:00')) {
			announce(GOOGLE_HOME_3, $text);
		}
		break;
	default:
		logger("This is private API. (in Default)","ERROR");
	}
}else{
	logger("This is private API. (in else)","ERROR");
}

アクション

準備したPHPファイルより「@GOOGLE_HOME_1@ http://192.168.0.200:9081 などgoogle home notifier向けのURL」に設定したgoogle home notifier経由で対象スピーカーよりアナウンスを実施します。
夜間に音を出したくないので、checkTime($startTime, $endTime)関数を用いて、実行時の時間を確認しています。

Use Case(ユースケース)

ツイッターで電車の運行情報をトリガーとして、LINEに通知および、トリガー発生時間(日中)を判定しGoogle Homeスピーカーで雨が降り出す旨のアナウンスを実行します。Google Homeスピーカーは就寝時間などには音声を出させたくないので、時間判定を入れました。

前提条件

  • (Raspberry Piの)Google Home Notifier導入が終わっている「google-home-notifier」導入
  • (Raspberry Piの)PHPが動作するWEBサーバがセットアップされている
  • (Raspberry Piの)WEBサーバの公開設定が終わっている
  • IFTTTサービスの利用登録が実施済みである
  • IFTTTサービスにおいて、Webhooksが利用可能である IFTTT(イフト)でWebhooksの利用
  • IFTTTサービスにおいて、LINE Notifyの利用設定を実施している
  • IFTTTサービスにおいて、Twitterの利用設定を実施している

全体の流れ

  1. IFTTTのTwitterサービスで列車遅延情報をトリガー
  2. IFTTTのWebhooksで列車遅延情報取得時のアクションを実行(Raspberry PiのWEB APIへ発信)
  3. WEB APIよりLINEへメッセージ送信
  4. Google Homeスピーカーでアナウンス(Google Home Notifier経由)

トリガー

トリガー(this)にTwitterを選択します。

Twitterサービスには、多くのトリガーが準備されています。ここでは、New tweet from search(ツイートの検索)をトリガーとしています。

Twitterで検索するSearchワードを登録します。
「From:JRE_F_Tokaido 東海道線:『遅延』」
この例では、JR東海の東海道線に関するツイートより、更に東海道線の遅延情報に絞ってトリガーとして登録しています。

アクション

IFTTTのWebhooksよりRaspberry PiのWEB APIへPUSH通知

IFTTT(イフト)でWebhooksの利用

  • URL:準備したAPIのURLを指定します。外部からWEBアクセス可能なURLを指定する必要があります。また、APIトークンを送信するので、https:// での指定を強くオススメします。
  • Method:今回は、POST受信に対応したPHPを用いるので、POSTを指定します。
  • Content Type:application/x-www-form-urlencoded: キーと値は、その間に '=' がある形でキーと値の組になり、 '&' で区切られてエンコードされます。キーや値の英数字以外の文字は、パーセントエンコーディングされます。
  • Body:準備したPHPの仕様に合わせて、3つのパラメータを設定します。
    • APIKEY=apikey
    • KEY=TransportationInfo
    • text={{Text}}
APIKEY=apikey&KEY=TransportationInfo&TEXT={{Text}}

以下が、準備したサンプルのPHPスクリプトとなります。

//@HOME_API_LOG_NAME@ ログファイル名、書き込み権限が必要です
//@HOME_API_KEY@ POST受信時の簡易的なAPI-KEYのトークン確認を行います
//@IFTTT_POST_API_KEY@ IFTTTのWebhooks用API-KEY
//@GOOGLE_HOME_1@ http://192.168.0.200:9081 などgoogle home notifier向けのURL
//@GOOGLE_HOME_2@ google home notifier向けのURL

//各種設定
//ログのファイル名
define("HOME_API_LOG_NAME","@HOME_API_LOG_NAME@");
//home-api-key
define("HOME_API_KEY","@HOME_API_KEY@");
//IFTTT用webhookパラメータ
define("IFTTT_POST_API_KEY","/with/key/@IFTTT_POST_API_KEY@");
define("IFTTT_POST_API_BASE","https://maker.ifttt.com/trigger/");
//IFTTT用puchLINE
define("IFTTT_LINE_KEY","pushLINE");

//google-home-notifier
define("GOOGLE_HOME_1",'@GOOGLE_HOME_1@');
define("GOOGLE_HOME_2",'@GOOGLE_HOME_2@');

function checkTime($startTime, $endTime) {
	$currentTime = date('H:i');
	if(strtotime($startTime) <= strtotime($currentTime) and strtotime($currentTime) <= strtotime($endTime)) {
		return true;
	}else{
		return false;
	}
}

function pushLINE($value1, $value2) {
	logger("Start pushLINE value1={$value1},value2={$value2}","INFO");
	$url = IFTTT_POST_API_BASE.IFTTT_LINE_KEY.IFTTT_POST_API_KEY;
	$data = array(
		'value1' => $value1,
		'value2' => $value2
	);
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

function announce($api_url, $text) {
	logger("Start announce target={$api_url},text={$text}","INFO");
	$message = 'text='.$text;
	$data = array(
		'text' => "$text"
	);
	$path = '/google-home-notifier';
	$url = $api_url.$path;
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  // curl_execの結果を文字列で返す
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

function logger($text, $level) {
	$datetime = date('Y-m-d H:i:s');
	$date = date('Ym');
	$file_name = __DIR__ . "/log/log-home-{$date}.log";
	$text = "{$datetime} [{$level}] {$text}" . PHP_EOL;
	echo $text;
	if(!(file_exists($file_name))){
		touch($file_name);
		chmod($file_name, 0777);
	}
	return error_log(print_r($text, TRUE), 3, $file_name);
}

logger("Start API KEY=".$_POST['KEY'],"INFO");
if(isset($_POST['KEY']) && strcmp($_POST['APIKEY'], HOME_API_KEY) == 0) {
	if(isset($_POST['TEXT'])){
		$text = $_POST['TEXT'];
	}
	switch ($_POST['KEY']) {
	case 'TransportationInfo':
		logger("Start TransportatioknInfo","INFO");
		//Delay warning
		$text = mb_substr($text,0,mb_strpos($text,'#',0,"UTF-8"),"UTF-8");
		pushLine('【公共交通機関情報】',$text);
		if(checkTime('6:00','22:00')) {
			announce(GOOGLE_HOME_1, $text);
		}
		if(checkTime('6:00','8:00')) {
			announce(GOOGLE_HOME_2, $text);
		}
		break;
	default:
		logger("This is private API. (in Default)","ERROR");
	}
}else{
	logger("This is private API. (in else)","ERROR");
}

ここでのポイントは、ツイート内容からハッシュタグ以降のURLリンクなどを切り取っている部分です。Twitterから取得したメッセージを、LINE送信やアナウンスに必要な部分に切り取って、次の処理に渡すとGoogle Homeからのアナウンスなどがスマートになります。

$text = mb_substr($text,0,mb_strpos($text,'#',0,"UTF-8"),"UTF-8");

アクション1

LINE送信のアクションを設定します。すでに、他ユースケースなどでIFTTT側にLINE送信のレシピを導入されている方は、アクション2の定義に進んで下さい。

アクション1:トリガー

アクセスキーなどの初期設定値は、IFTTTより取得して下さい。

IFTTT(イフト)でWebhooksの利用

//IFTTT用webhookパラメータ
define("IFTTT_POST_API_KEY","/with/key/アクセスキー");
define("IFTTT_POST_API_BASE","https://maker.ifttt.com/trigger/");
//IFTTT用puchLINE
define("IFTTT_LINE_KEY","pushLINE");

function pushLINE($value1, $value2) {
	$url = IFTTT_POST_API_BASE.IFTTT_LINE_KEY.IFTTT_POST_API_KEY;
	$data = array(
		'value1' => $value1,
		'value2' => $value2
	);
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

アクション1:IFTTTでのトリガー


Webhooksを{event}:pushLINEで設定します。

アクション1:アクション


LINE送信のアクションを定義します。
Recipientでラインの送付先を指定します。すでに作成しているLINEのグループにも送信することが出来ます。
Message部分は、自由に変更出来ます。今回は、PHPより2つの引数を渡しているので、2つの引数をMessageに入れております。pushLine('【テスト】',$text);

アクション2

Google Home Notifier経由で、Google Homeからアナウンスを流します。「google-home-notifier」導入

//@GOOGLE_HOME_1@ http://192.168.0.200:9081 などgoogle home notifier向けのURL
define("GOOGLE_HOME_1",'@GOOGLE_HOME_1@');

function announce($api_url, $text) {
	logger("Start announce target={$api_url},text={$text}","INFO");
	$message = 'text='.$text;
	$data = array(
		'text' => "$text"
	);
	$path = '/google-home-notifier';
	$url = $api_url.$path;
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  // curl_execの結果を文字列で返す
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

announce(GOOGLE_HOME_1, $text);

時間判定について checkTime関数

対象時間の開始と終了を指定して、true, falseを戻り値とする関数を準備しました。
日付を跨る設定などは考慮しておりません。

checkTime('6:00','23:00')とすれば、朝6時から夜23時まで「True」となります。
このチェック関数を用いて、Google Homeのアナウンス対象時間か否かを確認しています。

function checkTime($startTime, $endTime) {
	$currentTime = date('H:i');
	if(strtotime($startTime) <= strtotime($currentTime) and strtotime($currentTime) <= strtotime($endTime)) {
		return true;
	}else{
		return false;
	}
}

 

google-tts-apiからHOYA社のVoice Text Web APIへ

Google Home Notifierは、テキストをgoogle-tts-apiを用いて、音声変換を実施しております。十分に内容は把握できますし、実利用には支障はないのですが、HOYA社より優れたWeb APIが公開されているので、HOYA社のVoice Text Web APIを用いた音声に変更を実施します。HOYA株式会社 VoiceText Web API

  1. HOYA社Voice Text Web APIの利用登録
  2. 「voicetext」のインストール
  3. google-home-notifierソースコード修正

参考サイト

前提条件

  • (Raspberry Piの)Google Home Notifier導入が終わっている「google-home-notifier」導入
  • (Raspberry Piの)PHPが動作するWEBサーバがセットアップされている

導入手順

1.HOYA社Voice Text Web APIの利用登録

HOYA株式会社 VoiceText Web APIの「無料利用登録」より利用登録を実施して下さい。利用登録後に、API KEYがメールで送付されて来ます。

2.「voicetext」のインストール

以下のコマンドで、「voicetext」をインストールします。

@raspberrypi:~ $ cd google-home-notifier/
@raspberrypi:~/google-home-notifier $ sudo npm update
@raspberrypi:~/google-home-notifier $ sudo npm install voicetext
npm WARN deprecated superagent@0.18.2: Please note that v5.0.1+ of superagent removes User-Agent header by default, therefore you may need to add it yourself (e.g. GitHub blocks requests without a User-Agent header). This notice will go away with v5.0.2+ once it is released.
+ voicetext@0.0.7
updated 1 package and audited 293 packages in 5.994s
found 8 vulnerabilities (3 low, 3 moderate, 2 high)
run `npm audit fix` to fix them, or `npm audit` for details

╭────────────────────────────────────────────────────────────────╮
│ │
│ New minor version of npm available! 6.9.0 → 6.10.0 │
│ Changelog: https://github.com/npm/cli/releases/tag/v6.10.0 │
│ Run npm install -g npm to update! │
│ │
╰────────────────────────────────────────────────────────────────╯

@raspberrypi:~/google-home-notifier $ sudo npm install -g npm
/usr/local/bin/npm -> /usr/local/lib/node_modules/npm/bin/npm-cli.js
/usr/local/bin/npx -> /usr/local/lib/node_modules/npm/bin/npx-cli.js
+ npm@6.10.0
added 14 packages from 10 contributors, removed 5 packages and updated 17 packages in 30.759s

3.google-home-notifierソースコード修正

「google-home-notifier.js」ファイルの修正

以下を参考に2箇所追加および1箇所コメントアウト(削除)を実施します。

var Client = require('castv2-client').Client;
var DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver;
var mdns = require('mdns');
var browser = mdns.createBrowser(mdns.tcp('googlecast'));
var deviceAddress;
var language;

//Add (((((((((((
var VoiceTextWriter = require('./VoiceTextWriter');
var voiceTextWriter = new VoiceTextWriter();
//Add ))))))))))

var device = function(name, lang = 'en') {
    device = name;
    language = lang;
    return this;
};

var ip = function(ip, lang = 'en') {
  deviceAddress = ip;
  language = lang;
  return this;
}

var googletts = require('google-tts-api');
var googlettsaccent = 'us';
var accent = function(accent) {
  googlettsaccent = accent;
  return this;
}

var notify = function(message, callback) {
  if (!deviceAddress){
    browser.start();
    browser.on('serviceUp', function(service) {
      console.log('Device "%s" at %s:%d', service.name, service.addresses[0], service.port);
      if (service.name.includes(device.replace(' ', '-'))){
        deviceAddress = service.addresses[0];
        getSpeechUrl(message, deviceAddress, function(res) {
          callback(res);
        });
      }
      browser.stop();
    });
  }else {
    getSpeechUrl(message, deviceAddress, function(res) {
      callback(res);
    });
  }
};

var play = function(mp3_url, callback) {
  if (!deviceAddress){
    browser.start();
    browser.on('serviceUp', function(service) {
      console.log('Device "%s" at %s:%d', service.name, service.addresses[0], service.port);
      if (service.name.includes(device.replace(' ', '-'))){
        deviceAddress = service.addresses[0];
        getPlayUrl(mp3_url, deviceAddress, function(res) {
          callback(res);
        });
      }
      browser.stop();
    });
  }else {
    getPlayUrl(mp3_url, deviceAddress, function(res) {
      callback(res);
    });
  }
};

var getSpeechUrl = function(text, host, callback) {
//Delete ((((((((((
//  googletts(text, language, 1, 1000, googlettsaccent).then(function (url) {
//    onDeviceUp(host, url, function(res){
//      callback(res)
//    });
//  }).catch(function (err) {
//    console.error(err.stack);
//  });
//Delete )))))))))
//Add (((((((((
	voiceTextWriter.convertToText(text).then(function(result, reject){
        onDeviceUp(host, result, function(res){
            callback(res)
        });
    }).catch(function onRejected(error){
		console.error(error);
	});
//Add )))))))))
};

var getPlayUrl = function(url, host, callback) {
    onDeviceUp(host, url, function(res){
      callback(res)
    });
};

var onDeviceUp = function(host, url, callback) {
  var client = new Client();
  client.connect(host, function() {
    client.launch(DefaultMediaReceiver, function(err, player) {

      var media = {
        contentId: url,
        contentType: 'audio/mp3',
        streamType: 'BUFFERED' // or LIVE
      };
      player.load(media, { autoplay: true }, function(err, status) {
        client.close();
        callback('Device notified');
      });
    });
  });

  client.on('error', function(err) {
    console.log('Error: %s', err.message);
    client.close();
    callback('error');
  });
};

exports.ip = ip;
exports.device = device;
exports.accent = accent;
exports.notify = notify;
exports.play = play;

「VoiceTextWriter.js」ファイルの新規作成

  • 「@APIKEY@」を利用登録時に受信したAPIKEYに変更
  • 「@WEBPAHT@」にWEBサーバの公開フォルダに格納する音声ファイルを指定
    例:/var/www/html/voice-text.wav
  • 「@URL@」にWEBサーバの音声ファイルへアクセスする際のURLを指定
    例:http://192.168.0.200/voice-text.wav
var fs = require('fs');
var VoiceText = require('voicetext');
var voice = new VoiceText('@APIKEY@');
var OUT_PATH = '@WEBPAHT@';
var OUTPUT_URL = '@URL@';

class VoiceTextWriter{

	convertToText(text){
	return new Promise(function(resolve,reject){
	voice
	.speaker(voice.SPEAKER.HIKARI)
	.emotion(voice.EMOTION.HAPPINESS)
//	.emotion_level(voice.EMOTION_LEVEL.HIGH)
	.emotion_level(2)
        .speed(100)
	.volume(120)
	.speak(text, function(e, buf){
	    if(e){
	      console.error(e);
	      reject(e);

	    }else{
	   	 fs.writeFileSync(OUT_PATH, buf, 'binary');
	  	 resolve(OUTPUT_URL);
	    }
	  });
	});
	}
}
module.exports = VoiceTextWriter;

VoiceText Web APIマニュアルを参考に、speedやvolumeなどのオプション指定を変更して、好みの音声に変更して下さい。設定ファイル変更時には、Google Home Notifierの再起動が必要となります。

Use Case(ユースケース)

Google音声コマンド経由でPCのシャットダウンを行います。

前提条件

全体の流れ

  1. IFTTTのGoogle AssistantよりPCシャットダウン時の音声コマンドをトリガートリガー登録
  2. IFTTTのWebhooksでPCシャットダウン時の音声コマンド受領時のアクションを実行(Raspberry PiのWEB APIへ発信)
  3. WEB APIよりPCをシャットダウン(SSH2経由でシャットコマンドを実行)

トリガー

トリガー(this)にGoogle Assistantを選択し「Say a simple phrase」のトリガーを選択します。

音声コマンドを登録します。
「パソコンをシャットダウンして」
「パソコンの電源を切って」などを登録します。

コマンド受付時のGoogle Homeからのレスポンスも登録します。
「パソコンをシャットダウンします」

Lanuguage(言語)は、Japanese(日本語)を選択します。

アクション

IFTTTのWebhooksよりRaspberry PiのWEB APIへPUSH通知

IFTTT(イフト)でWebhooksの利用

  • URL:準備したAPIのURLを指定します。外部からWEBアクセス可能なURLを指定する必要があります。また、APIトークンを送信するので、https:// での指定を強くオススメします。
  • Method:今回は、POST受信に対応したPHPを用いるので、POSTを指定します。
  • Content Type:application/x-www-form-urlencoded: キーと値は、その間に '=' がある形でキーと値の組になり、 '&' で区切られてエンコードされます。キーや値の英数字以外の文字は、パーセントエンコーディングされます。
  • Body:準備したPHPの仕様に合わせて、3つのパラメータを設定します。
    • APIKEY=apikey
    • KEY=shutdownPC
APIKEY=apikey&KEY=shutdownPC

以下が、準備したサンプルのPHPスクリプトとなります。

//@HOME_API_LOG_NAME@ ログファイル名、書き込み権限が必要です
//@HOME_API_KEY@ POST受信時の簡易的なAPI-KEYのトークン確認を行います
//@WINDOWS_IP@ WindowsのIPアドレス
//@WINDOWS_USER@ Windowsのユーザー名
//@WINDOWS_PASS@ Windowsのパスワード

//各種設定
//ログのファイル名
define("HOME_API_LOG_NAME","@HOME_API_LOG_NAME@");
//home-api-key
define("HOME_API_KEY","@HOME_API_KEY@");
//Windows PC
define("WINDOWS_IP","@WINDOWS_IP@");
define("WINDOWS_USER","@WINDOWS_USER@");
define("WINDOWS_PASS","@WINDOWS_PASS@");

function shutdownPC($target_ip, $target_user, $target_pass) {
	logger("Start shutdown target_ip:".$target_ip." target_user:".$target_user,"INFO");
	$shutdown_time = 60;
	$comment = "シャットダウン開始します。キャンセル「-a」";
	$cmd = 'shutdown /s /f /t '.$shutdown_time.' /c '.$comment;
	$connection = ssh2_connect($target_ip);
	ssh2_auth_password($connection, $target_user, $target_pass);
    $stream = ssh2_exec($connection, $cmd);
    $errorstream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
    stream_set_blocking($stream, true);
    stream_set_blocking($errorstream, true);
    $ok =  stream_get_contents($stream);
   $ng =  stream_get_contents($errorstream); //エラーがあれば表示
   echo $ok;
   echo $ng;
}

function logger($text, $level) {
	$datetime = date('Y-m-d H:i:s');
	$date = date('Ym');
	$file_name = __DIR__ . "/log/log-home-{$date}.log";
	$text = "{$datetime} [{$level}] {$text}" . PHP_EOL;
	echo $text;
	if(!(file_exists($file_name))){
		touch($file_name);
		chmod($file_name, 0777);
	}
	return error_log(print_r($text, TRUE), 3, $file_name);
}

logger("Start API KEY=".$_POST['KEY'],"INFO");

if(isset($_POST['KEY']) && strcmp($_POST['APIKEY'], HOME_API_KEY) == 0) {
	switch ($_POST['KEY']) {
	case 'shutdownPC':
		logger("Start shutdownPC","INFO");
		shutdownPC(WINDOWS_IP, WINDOWS_USER, WINDOWS_PASS);
		break;
	default:
		logger("This is private API. (in Default)","ERROR");
	}
}else{
	logger("This is private API. (in else)","ERROR");
}

アクション

準備したPHPファイルより「@WINDOWS_IP@:WindowsのIPアドレス、 @WINDOWS_USER@:Windowsのユーザー名、@WINDOWS_PASS@:Windowsのパスワード 」に設定したPCへSSH2用いてPCへログインし、シャットダウンコマンドを実行します。

 

Use Case(ユースケース)

Google音声コマンド経由でPCの起動を行います。

前提条件

  • (Raspberry Piの)PHPが動作するWEBサーバがセットアップされている
  • (Raspberry Piの)WEBサーバの公開設定が終わっている
  • (Raspberry Piの)WEBサーバより「etherwake」が利用可能
  • IFTTTサービスの利用登録が実施済みである
  • IFTTTサービスにおいて、Webhooksが利用可能である IFTTT(イフト)でWebhooksの利用
  • 起動対象のPCをWOL経由で起動出来るように設定されている必要があります

全体の流れ

  1. IFTTTのGoogle AssistantよりPC起動時の音声コマンドをトリガートリガー登録
  2. IFTTTのWebhooksでPC起動時の音声コマンド受領時のアクションを実行(Raspberry PiのWEB APIへ発信)
  3. WEB APIよりPC起動(etherwake)

トリガー

トリガー(this)にGoogle Assistantを選択し「Say a simple phrase」のトリガーを選択します。

音声コマンドを登録します。
「パソコンを起動して」
「パソコンの電源を入れて」などを登録します。

コマンド受付時のGoogle Homeからのレスポンスも登録します。
「パソコンを起動します」

Lanuguage(言語)は、Japanese(日本語)を選択します。

アクション

IFTTTのWebhooksよりRaspberry PiのWEB APIへPUSH通知

IFTTT(イフト)でWebhooksの利用

  • URL:準備したAPIのURLを指定します。外部からWEBアクセス可能なURLを指定する必要があります。また、APIトークンを送信するので、https:// での指定を強くオススメします。
  • Method:今回は、POST受信に対応したPHPを用いるので、POSTを指定します。
  • Content Type:application/x-www-form-urlencoded: キーと値は、その間に '=' がある形でキーと値の組になり、 '&' で区切られてエンコードされます。キーや値の英数字以外の文字は、パーセントエンコーディングされます。
  • Body:準備したPHPの仕様に合わせて、3つのパラメータを設定します。
    • APIKEY=apikey
    • KEY=WakeupPC
APIKEY=apikey&KEY=WakeupPC

以下が、準備したサンプルのPHPスクリプトとなります。

//@HOME_API_LOG_NAME@ ログファイル名、書き込み権限が必要です
//@HOME_API_KEY@ POST受信時の簡易的なAPI-KEYのトークン確認を行います
//@WINDOWS_MAC@ WindowsのMACアドレス

//各種設定
//ログのファイル名
define("HOME_API_LOG_NAME","@HOME_API_LOG_NAME@");
//home-api-key
define("HOME_API_KEY","@HOME_API_KEY@");
//Windows PC
define("WINDOWS_MAC","@WINDOWS_MAC@");

function WakeupPC($MAC) {
	logger("Start powerOn","INFO");
	$cmd = 'sudo /usr/sbin/etherwake '.$MAC;
	$output =  shell_exec($cmd);
}

function logger($text, $level) {
	$datetime = date('Y-m-d H:i:s');
	$date = date('Ym');
	$file_name = __DIR__ . "/log/log-home-{$date}.log";
	$text = "{$datetime} [{$level}] {$text}" . PHP_EOL;
	echo $text;
	if(!(file_exists($file_name))){
		touch($file_name);
		chmod($file_name, 0777);
	}
	return error_log(print_r($text, TRUE), 3, $file_name);
}

logger("Start API KEY=".$_POST['KEY'],"INFO");

if(isset($_POST['KEY']) && strcmp($_POST['APIKEY'], HOME_API_KEY) == 0) {
	switch ($_POST['KEY']) {
	case 'WakeupPC':
			logger("Start wakeupPC","INFO");
			WakeupPC(WINDOWS_MAC);
			break;
	default:
		logger("This is private API. (in Default)","ERROR");
	}
}else{
	logger("This is private API. (in else)","ERROR");
}

アクション

準備したPHPファイルより「WINDOWS_MAC」に設定したMACアドレスへ「etherwake」コマンドを用いてPC起動を行います。

Use Case(ユースケース)

Weather Undergroundサービスを用いて、天候変化をトリガーとします。
天候が「Rain(雨)」に変化した際に、Webhooks経由でトリガーを受け、LINEに通知および、トリガー発生時間(日中)を判定しGoogle Homeスピーカーで雨が降り出す旨のアナウンスを実行します。Google Homeスピーカーは就寝時間などには音声を出させたくないので、時間判定を入れました。

前提条件

全体の流れ

  1. IFTTTのWeather Undergroundサービスで天候変化「Rain」をトリガー
  2. IFTTTのWebhooksで天候変化時のアクションを実行(Raspberry PiのWEB APIへ発信)
  3. WEB APIよりLINEへメッセージ送信
  4. Google Homeスピーカーでアナウンス(Google Home Notifier経由)

トリガー

トリガー(this)にWeather Undergroundを選択します。

今日の天気レポート、明日の天気レポート、気温変化などたくさんのトリガーが準備されています。今回は、「Current condition chages to」気象条件の変化を選択します。

どの状態に変化した際のトリガーにするかを選択します。「Rain(雨)」「Snow(雪)」「Cloudy(くもり)」「Clear(晴れ)」より「Rain(雨)」を選びます。

また、ターゲットとするロケーションを地図または住所で指定し、天候変化のトリガーとしたい地点の選択を行います。

アクション

IFTTTのWebhooksよりRaspberry PiのWEB APIへPUSH通知

IFTTT(イフト)でWebhooksの利用

  • URL:準備したAPIのURLを指定します。外部からWEBアクセス可能なURLを指定する必要があります。また、APIトークンを送信するので、https:// での指定を強くオススメします。
  • Method:今回は、POST受信に対応したPHPを用いるので、POSTを指定します。
  • Content Type:application/x-www-form-urlencoded: キーと値は、その間に '=' がある形でキーと値の組になり、 '&' で区切られてエンコードされます。キーや値の英数字以外の文字は、パーセントエンコーディングされます。
  • Body:準備したPHPの仕様に合わせて、3つのパラメータを設定します。
    • APIKEY=apikey
    • KEY=Weather
    • text=" {{CheckTime}}確認、雨が降り出しそうです。"
APIKEY=apikey&KEY=Weather&text=" {{CheckTime}}確認、雨が降り出しそうです。"

以下が、準備したサンプルのPHPスクリプトとなります。

//@HOME_API_LOG_NAME@ ログファイル名、書き込み権限が必要です
//@HOME_API_KEY@ POST受信時の簡易的なAPI-KEYのトークン確認を行います
//@IFTTT_POST_API_KEY@ IFTTTのWebhooks用API-KEY
//@GOOGLE_HOME_1@ http://192.168.0.200:9081 などgoogle home notifier向けのURL
//@GOOGLE_HOME_2@ google home notifier向けのURL
//@GOOGLE_HOME_3@ google home notifier向けのURL

//各種設定
//ログのファイル名
define("HOME_API_LOG_NAME","@HOME_API_LOG_NAME@");
//home-api-key
define("HOME_API_KEY","@HOME_API_KEY@");
//IFTTT用webhookパラメータ
define("IFTTT_POST_API_KEY","/with/key/@IFTTT_POST_API_KEY@");
define("IFTTT_POST_API_BASE","https://maker.ifttt.com/trigger/");
//IFTTT用puchLINE
define("IFTTT_LINE_KEY","pushLINE");

//google-home-notifier
define("GOOGLE_HOME_1",'@GOOGLE_HOME_1@');
define("GOOGLE_HOME_2",'@GOOGLE_HOME_2@');
define("GOOGLE_HOME_3",'@GOOGLE_HOME_3@');

function checkTime($startTime, $endTime) {
	$currentTime = date('H:i');
	if(strtotime($startTime) <= strtotime($currentTime) and strtotime($currentTime) <= strtotime($endTime)) {
		return true;
	}else{
		return false;
	}
}

function pushLINE($value1, $value2) {
	logger("Start pushLINE value1={$value1},value2={$value2}","INFO");
	$url = IFTTT_POST_API_BASE.IFTTT_LINE_KEY.IFTTT_POST_API_KEY;
	$data = array(
		'value1' => $value1,
		'value2' => $value2
	);
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

function announce($api_url, $text) {
	logger("Start announce target={$api_url},text={$text}","INFO");
	$message = 'text='.$text;
	$data = array(
		'text' => "$text"
	);
	$path = '/google-home-notifier';
	$url = $api_url.$path;
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  // curl_execの結果を文字列で返す
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

function logger($text, $level) {
	$datetime = date('Y-m-d H:i:s');
	$date = date('Ym');
	$file_name = __DIR__ . "/log/log-home-{$date}.log";
	$text = "{$datetime} [{$level}] {$text}" . PHP_EOL;
	echo $text;
	if(!(file_exists($file_name))){
		touch($file_name);
		chmod($file_name, 0777);
	}
	return error_log(print_r($text, TRUE), 3, $file_name);
}

logger("Start API","INFO");

if(isset($_POST['KEY']) && strcmp($_POST['APIKEY'], HOME_API_KEY) == 0) {
	logger("KEY : ".$_POST['KEY'],"INFO");
	logger("TEXT : ".$_POST['TEXT'],"INFO");
	$text = $_POST['TEXT'];
	switch ($_POST['KEY']) {
	case 'Weather':
		logger("Start Weather","INFO");
		//Rain alert
		pushLine('【天気情報】',$text);
		if(checkTime('7:00','19:00')) {
			announce(GOOGLE_HOME_2, $text);
			announce(GOOGLE_HOME_3, $text);
		}
		if(checkTime('6:00','23:00')) {
			announce(GOOGLE_HOME_1, $text);
		}
		break;
	default:
		logger("This is private API. (in Default)","ERROR");
	}
}else{
	logger("This is private API. (in else)","ERROR");
}

アクション1

LINE送信のアクションを設定します。すでに、他ユースケースなどでIFTTT側にLINE送信のレシピを導入されている方は、アクション2の定義に進んで下さい。

アクション1:トリガー

アクセスキーなどの初期設定値は、IFTTTより取得して下さい。

IFTTT(イフト)でWebhooksの利用

//IFTTT用webhookパラメータ
define("IFTTT_POST_API_KEY","/with/key/アクセスキー");
define("IFTTT_POST_API_BASE","https://maker.ifttt.com/trigger/");
//IFTTT用puchLINE
define("IFTTT_LINE_KEY","pushLINE");

function pushLINE($value1, $value2) {
	$url = IFTTT_POST_API_BASE.IFTTT_LINE_KEY.IFTTT_POST_API_KEY;
	$data = array(
		'value1' => $value1,
		'value2' => $value2
	);
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

アクション1:IFTTTでのトリガー


Webhooksを{event}:pushLINEで設定します。

アクション1:アクション


LINE送信のアクションを定義します。
Recipientでラインの送付先を指定します。すでに作成しているLINEのグループにも送信することが出来ます。
Message部分は、自由に変更出来ます。今回は、PHPより2つの引数を渡しているので、2つの引数をMessageに入れております。pushLine('【テスト】',$text);

アクション2

Google Home Notifier経由で、Google Homeからアナウンスを流します。「google-home-notifier」導入

//@GOOGLE_HOME_1@ http://192.168.0.200:9081 などgoogle home notifier向けのURL
define("GOOGLE_HOME_1",'@GOOGLE_HOME_1@');

function announce($api_url, $text) {
	logger("Start announce target={$api_url},text={$text}","INFO");
	$message = 'text='.$text;
	$data = array(
		'text' => "$text"
	);
	$path = '/google-home-notifier';
	$url = $api_url.$path;
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_POST, TRUE);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  // curl_execの結果を文字列で返す
	curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信
	$response = curl_exec($curl);
	$result = json_decode($response, true);
	curl_close($curl);
	return $result;
}

announce(GOOGLE_HOME_1, $text);

時間判定について checkTime関数

対象時間の開始と終了を指定して、true, falseを戻り値とする関数を準備しました。
日付を跨る設定などは考慮しておりません。

checkTime('6:00','23:00')とすれば、朝6時から夜23時まで「True」となります。
このチェック関数を用いて、Google Homeのアナウンス対象時間か否かを確認しています。

function checkTime($startTime, $endTime) {
	$currentTime = date('H:i');
	if(strtotime($startTime) <= strtotime($currentTime) and strtotime($currentTime) <= strtotime($endTime)) {
		return true;
	}else{
		return false;
	}
}