コンテンツへスキップ

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;
	}
}

 

LINE通知のみはこちら

Use Case(ユースケース)

Nature Remoの室温室温センサーが30℃を超えた時点で、LINEに通知およびPCのシャットダウンを行う。

前提条件

  • Nature Remoがセットアップ済み
  • (Raspberry Piの)PHPが動作するWEBサーバがセットアップされている
  • (Raspberry Piの)WEBサーバの公開設定が終わっている
  • IFTTTサービスの利用登録が実施済みである
  • IFTTTサービスにおいて、Webhooksが利用可能である IFTTT(イフト)でWebhooksの利用
  • IFTTTサービスにおいて、LINE Notifyの利用設定を実施している
  • シャットダウン対象のPCにSSHサーバがインストールされている必要があります Raspberry Pi 3 B +にPHPのSSH2インストール

全体の流れ

  1. IFTTTのNature Remoより室温30℃以上をトリガートリガー登録
  2. IFTTTのWebhooksで天候変化時のアクションを実行(Raspberry PiのWEB APIへ発信)
  3. WEB APIよりLINEへメッセージ送信
  4. WEB APIよりPCをシャットダウン(SSH2経由でシャットコマンドを実行)

トリガー

トリガー(this)にNature Remoをを選択し「Temperature rises above」(室温上昇)のトリガーを選択します。
トリガーは以下が準備されております。

  • Temperature rises above : 室温上昇
  • Temperature drops below : 室温低下
  • Humidity rises above : 湿度上昇
  • Humidity drops below : 湿度低下
  • Becomes brighter : 部屋の照度上昇
  • Becomes darker : 部屋の照度低下

対象のNature Remoデバイスを選択

what value でトリガー対象の室温を設定します。今回は、30℃を指定しています。

アクション

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="室温が{{ThresholdValue}}を超えます。現在の {{CreatedAt}}の室温は、 {{Value}}です。"
APIKEY=apikey&KEY=TemperatureWarn&TEXT=室温が{{ThresholdValue}}を超えます。現在の {{CreatedAt}}の室温は、 {{Value}}です。

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

//@HOME_API_LOG_NAME@ ログファイル名、書き込み権限が必要です
//@HOME_API_KEY@ POST受信時の簡易的なAPI-KEYのトークン確認を行います
//@IFTTT_POST_API_KEY@ IFTTTのWebhooks用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@");
//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");
//Windows PC
define("WINDOWS_IP","@WINDOWS_IP@");
define("WINDOWS_USER","@WINDOWS_USER@");
define("WINDOWS_PASS","@WINDOWS_PASS@");

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 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) {
	if(isset($_POST['TEXT'])){
		$text = $_POST['TEXT'];
	}
	switch ($_POST['KEY']) {
	case 'TemperatureWarn':
		logger("Start TemperatureWarn","INFO");
		//Over 30
		pushLine('【リビング室温警告】',$text);
		shutdownPC(WINDOWS_IP, WINDOWS_USER, WINDOWS_PASS);
		break;
}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のグループにも送信することが出来ます。

アクション2

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

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;
	}
}

 

前提条件

  • (Raspberry Piの)PHPが動作するWEBサーバがセットアップされている
  • (Raspberry Piの)WEBサーバの公開設定が終わっている
    今回は、WEBリクエストの受信は行わないので、必須ではないです。

  • IFTTTサービスの利用登録が実施済みである
  • IFTTTサービスにおいて、Webhooksが利用可能である IFTTT(イフト)でWebhooksの利用
  • IFTTTサービスにおいて、LINE Notifyの利用設定を実施している 参考サイト

全体の流れ

  1. Raspberry PiでLINE送信をIFTTTのWebhooksにトリガー {event}:pushLINE
  2. IFTTTのWebhooksでLINE送信のトリガーを受信
  3. IFTTTのアクションでLINEを送信

トリガー

Raspberry PiよりIFTTTのWebhooksにトリガーを送信

IFTTT(イフト)でWebhooksの利用

PHPのサンプルコードを載せておきます。
アクセスキーなどの初期設定値は、IFTTTより取得して下さい。

//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;
}

$test = "テストメッセージです。";
pushLine('【テスト】',$test);

IFTTTでのトリガー


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

アクション


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

実行結果

今回のPHPを実行結果は、以下のようなLINEメッセージを受信出来ます。

以上です。色々簡単に使えそうですね。

PCをリモート起動するためにWOL導入

Wake On LAN とは、ネットワーク経由でパソコンの電源をオンにする機能のことです。よく、WOLと省略されます。

Wake on LANについては、パソコンのBIOS やWindowsの設定が必要で、Wake on LANに対応したパソコンやマザーボードが必要となります。
他のパソコンからの起動を命じる信号(Magic Packet)を、LAN経由で接続されたWake On LANに対応したネットワークアダプタを装着しているパソコンが受信するとこのMagic Packetを受信したほうのパソコンの電源がオンとなります。

Raspberry PiよりMagic Packetを送信するために「etherwake」をインストール

以下のコマンドで「etherwake」をインストール

$ sudo apt-get update
$ sudo apt-get install etherwake
$ which etherwake
/usr/sbin/etherwake

以下、インストール時のコンソールです。

@raspberrypi:~ $ apt-cache search wake on lan
between - game about consciousness and isolation
crossroads - open source load balance and fail over utility for TCP based services
desktop-autoloader - Accelerate Diskless Workstation systems by pre-loading a dummy Desktop Session
etherwake - tool to send magic Wake-on-LAN packets
fusioninventory-for-glpi - FusionInventory Server embedded as a plugin into GLPI
golang-github-danwakefield-fnmatch-dev - Updated clone of kballard’s fnmatch(3) implementation for Go
gwakeonlan - wakes up your machines using Wake on LAN
shutdown-at-night - System to shut down clients at night, and wake them in the morning
wakeonlan - Sends 'magic packets' to wake-on-LAN enabled ethernet adapters
@raspberrypi:~ $ sudo apt-get update
@raspberrypi:~ $ sudo apt-get install etherwake

パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています 
状態情報を読み取っています... 完了
以下の追加パッケージがインストールされます:
wakeonlan
以下のパッケージが新たにインストールされます:
etherwake wakeonlan
アップグレード: 0 個、新規インストール: 2 個、削除: 0 個、保留: 19 個。
19.6 kB のアーカイブを取得する必要があります。
この操作後に追加で 42.0 kB のディスク容量が消費されます。
続行しますか? [Y/n] y
取得:1 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian buster/main armhf etherwake armhf 1.09-4 [9,112 B]
取得:2 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian buster/main armhf wakeonlan all 0.41-12 [10.5 kB]
19.6 kB を 2秒 で取得しました (12.4 kB/s)
以前に未選択のパッケージ etherwake を選択しています。
(データベースを読み込んでいます ... 現在 145425 個のファイルとディレクトリがインストールされています。)
.../etherwake_1.09-4_armhf.deb を展開する準備をしています ...
etherwake (1.09-4) を展開しています...
以前に未選択のパッケージ wakeonlan を選択しています。
.../wakeonlan_0.41-12_all.deb を展開する準備をしています ...
wakeonlan (0.41-12) を展開しています...
wakeonlan (0.41-12) を設定しています ...
etherwake (1.09-4) を設定しています ...
man-db (2.8.5-2) のトリガを処理しています ...
@raspberrypi:~ $ which etherwake
/usr/sbin/etherwake
@raspberrypi:~ $ etherwake -u
usage: etherwake [-i <ifname>] [-p aa:bb:cc:dd[:ee:ff]] 00:11:22:33:44:55

PHPよりetherwakeコマンドを実行

参考URL:GoogleHome で PCを起動( IFTTT / Webhook / Wake-on-LAN)

PHPを実行するapacheユーザーからsudoパスワード無しに、etherwakeが実行可能となりように設定します。

$ sudo visudo

apache ALL=(ALL) NOPASSWD: /usr/sbin/etherwake
www-data ALL=(root) NOPASSWD: ALL

以下が、「etherwake」を実行する際のPHPソースコードとなります。
関数として準備し、引数でLANカードのMACアドレスを引数で渡すようにしております。

function powerOn($MAC) {
	$cmd = 'sudo /usr/sbin/etherwake '.$MAC;
	$output =  shell_exec($cmd);
}

//powerOn実行
powerON("xx:xx:xx:xx:xx:xx");

 

PHPのSSH2インストール

Raspberry Piで以下のSSH2を利用するスクリプトを実行した際に、エラーが出ました。
[Sat Jul 06 17:32:35.669744 2019] [php7:error] PHP Fatal error: Uncaught Error: Call to undefined function ssh2_connect() in /var/www/

Call to undefined function ssh2_connect()とあったので、「php-ssh2」をインストールすることで、PHPでSSH2を利用できます。

$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);
以下、実際の操作ログです。
Apache経由で利用する際は、apacheの再起動を実施後、利用してください。
@raspberrypi:~ $ sudo apt-cache search libss
[sudo]スワード:
cl-plus-ssl - Common Lisp interface to OpenSSL
dcmtk - OFFIS DICOM toolkit command line utilities
dlang-openssl - D version of the C headers for openssl
lib32gcc-6-dev-amd64-cross - GCC support library (32 bit development files)
lib32gcc-6-dev-mips64el-cross - GCC support library (32 bit development files)
lib32gcc-6-dev-s390x-cross - GCC support library (32 bit development files)
lib32gcc-8-dev-amd64-cross - GCC support library (32 bit development files)
lib32gcc-8-dev-mips64-cross - GCC support library (32 bit development files)
lib32gcc-8-dev-mips64el-cross - GCC support library (32 bit development files)
lib32gcc-8-dev-mips64r6-cross - GCC support library (32 bit development files)
lib32gcc-8-dev-mips64r6el-cross - GCC support library (32 bit development files)
lib32gcc-8-dev-ppc64-cross - GCC support library (32 bit development files)
lib32gcc-8-dev-s390x-cross - GCC support library (32 bit development files)
lib32gcc-8-dev-sparc64-cross - GCC support library (32 bit development files)
lib32gcc-8-dev-x32-cross - GCC support library (32 bit development files)
lib64gcc-6-dev-i386-cross - GCC support library (64bit development files)
lib64gcc-6-dev-mips-cross - GCC support library (64bit development files)
lib64gcc-6-dev-mipsel-cross - GCC support library (64bit development files)
lib64gcc-8-dev-i386-cross - GCC support library (64bit development files)
lib64gcc-8-dev-mips-cross - GCC support library (64bit development files)
lib64gcc-8-dev-mipsel-cross - GCC support library (64bit development files)
lib64gcc-8-dev-mipsr6-cross - GCC support library (64bit development files)
lib64gcc-8-dev-mipsr6el-cross - GCC support library (64bit development files)
lib64gcc-8-dev-powerpc-cross - GCC support library (64bit development files)
lib64gcc-8-dev-x32-cross - GCC support library (64bit development files)
libdcmtk-dev - OFFIS DICOM toolkit development libraries and headers
libdcmtk14 - OFFIS DICOM toolkit runtime libraries
libgcc-4.9-dev - GCC support library (development files)
libgcc-5-dev - GCC support library (development files)
libgcc-6-dev - GCC support library (development files)
libgcc-6-dev-amd64-cross - GCC support library (development files)
libgcc-6-dev-arm64-cross - GCC support library (development files)
libgcc-6-dev-armel-cross - GCC support library (development files)
libgcc-6-dev-armhf-cross - GCC support library (development files)
libgcc-6-dev-i386-cross - GCC support library (development files)
libgcc-6-dev-mips-cross - GCC support library (development files)
libgcc-6-dev-mips64el-cross - GCC support library (development files)
libgcc-6-dev-mipsel-cross - GCC support library (development files)
libgcc-6-dev-ppc64el-cross - GCC support library (development files)
libgcc-6-dev-s390x-cross - GCC support library (development files)
libgcc-7-dev - GCC support library (development files)
libgcc-8-dev - GCC support library (development files)
libgcc-8-dev-alpha-cross - GCC support library (development files)
libgcc-8-dev-amd64-cross - GCC support library (development files)
libgcc-8-dev-arm64-cross - GCC support library (development files)
libgcc-8-dev-armel-cross - GCC support library (development files)
libgcc-8-dev-armhf-cross - GCC support library (development files)
libgcc-8-dev-hppa-cross - GCC support library (development files)
libgcc-8-dev-i386-cross - GCC support library (development files)
libgcc-8-dev-m68k-cross - GCC support library (development files)
libgcc-8-dev-mips-cross - GCC support library (development files)
libgcc-8-dev-mips64-cross - GCC support library (development files)
libgcc-8-dev-mips64el-cross - GCC support library (development files)
libgcc-8-dev-mips64r6-cross - GCC support library (development files)
libgcc-8-dev-mips64r6el-cross - GCC support library (development files)
libgcc-8-dev-mipsel-cross - GCC support library (development files)
libgcc-8-dev-mipsr6-cross - GCC support library (development files)
libgcc-8-dev-mipsr6el-cross - GCC support library (development files)
libgcc-8-dev-powerpc-cross - GCC support library (development files)
libgcc-8-dev-powerpcspe-cross - GCC support library (development files)
libgcc-8-dev-ppc64-cross - GCC support library (development files)
libgcc-8-dev-ppc64el-cross - GCC support library (development files)
libgcc-8-dev-riscv64-cross - GCC support library (development files)
libgcc-8-dev-s390x-cross - GCC support library (development files)
libgcc-8-dev-sh4-cross - GCC support library (development files)
libgcc-8-dev-sparc64-cross - GCC support library (development files)
libgcc-8-dev-x32-cross - GCC support library (development files)
libn32gcc-6-dev-mips-cross - GCC support library (n32 development files)
libn32gcc-6-dev-mips64el-cross - GCC support library (n32 development files)
libn32gcc-6-dev-mipsel-cross - GCC support library (n32 development files)
libn32gcc-8-dev-mips-cross - GCC support library (n32 development files)
libn32gcc-8-dev-mips64-cross - GCC support library (n32 development files)
libn32gcc-8-dev-mips64el-cross - GCC support library (n32 development files)
libn32gcc-8-dev-mips64r6-cross - GCC support library (n32 development files)
libn32gcc-8-dev-mips64r6el-cross - GCC support library (n32 development files)
libn32gcc-8-dev-mipsel-cross - GCC support library (n32 development files)
libn32gcc-8-dev-mipsr6-cross - GCC support library (n32 development files)
libn32gcc-8-dev-mipsr6el-cross - GCC support library (n32 development files)
libnet-ssh2-perl - Perl module for the SSH 2 protocol
librust-libgit2-sys+libssh2-sys-dev - Native bindings to the libgit2 library - feature "libssh2-sys"
librust-libssh2-sys-dev - Native bindings to the libssh2 library - Rust source code
libss2 - command-line interface parsing library
libss7-2.0 - Signalling System 7 (ss7) library
libss7-dev - Signalling System 7 (ss7) development files
libsscm-dev - Development library for sigscheme Scheme interpreter
libsscm3 - Shared library for sigscheme Scheme interpreter
libssh-4 - tiny C SSH library (OpenSSL flavor)
libssh-dev - tiny C SSH library - Development files (OpenSSL flavor)
libssh-doc - tiny C SSH library - Documentation files
libssh-gcrypt-4 - tiny C SSH library (gcrypt flavor)
libssh-gcrypt-dev - tiny C SSH library - Development files (gcrypt flavor)
libssh2-1 - SSH2 client-side library
libssh2-1-dev - SSH2 client-side library (development headers)
libssl-dev - Secure Sockets Layer toolkit - development files
libssl-doc - Secure Sockets Layer toolkit - development documentation
libssl-ocaml - OCaml bindings for OpenSSL (runtime)
libssl-ocaml-dev - OCaml bindings for OpenSSL
libssl-utils-clojure - library for SSL certificate management on the JVM
libssl1.0-dev - Secure Sockets Layer toolkit - development files
libssl1.0.2 - Secure Sockets Layer toolkit - shared libraries
libssl1.1 - Secure Sockets Layer toolkit - shared libraries
libssm-bin - macromolecular superposition library - binaries
libssm-dev - macromolecular superposition library - development files
libssm2 - macromolecular superposition library - runtime
libsss-certmap-dev - Certificate mapping library for SSSD -- development files
libsss-certmap0 - Certificate mapping library for SSSD
libsss-idmap-dev - ID mapping library for SSSD -- development files
libsss-idmap0 - ID mapping library for SSSD
libsss-nss-idmap-dev - SID based lookups library for SSSD -- development files
libsss-nss-idmap0 - SID based lookups library for SSSD
libsss-simpleifp-dev - SSSD D-Bus responder helper library -- development files
libsss-simpleifp0 - SSSD D-Bus responder helper library
libsss-sudo - Communicator library for sudo
libx32gcc-6-dev-amd64-cross - GCC support library (x32 development files)
libx32gcc-6-dev-i386-cross - GCC support library (x32 development files)
libx32gcc-8-dev-amd64-cross - GCC support library (x32 development files)
libx32gcc-8-dev-i386-cross - GCC support library (x32 development files)
perl-openssl-defaults - version compatibility baseline for Perl OpenSSL packages
php-ssh2 - Bindings for the libssh2 library
python-libssh2 - Python binding for libssh2 library
python-libsss-nss-idmap - Python bindings for the SID lookups library
python3-libsss-nss-idmap - Python3 bindings for the SID lookups library
r-cran-openssl - GNU R toolkit for encryption, signatures and certificates based on OpenSSL
ssh-audit - tool for ssh server auditing
tcode - create a Java file from an associated LaTex file
@raspberrypi:~ $ sudo apt-get update
@raspberrypi:~ $ sudo apt-get install php-ssh2
@raspberrypi:~ $ sudo service apache2 restart