コンテンツへスキップ

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

 

実現したいこと

  • Nature Remoに搭載されているセンサ情報の蓄積
  • Nature Remo Cloud APIを用いたPHPからのセンサ情報取得
  • Googleデータポータルでの表示

前提条件

  • Nature Remoの設置が完了している
  • SynologyのDBサーバがセットアップされている(Maria DB)
    DB作成時にphpMyAdminが導入されていると便利です(Synologyパッケージマネージャよりインストール可能です)
  • SynologyでPHPがインストールされていること
  • Synologyの外部公開設定が終わっている (GoogleデータポータルからSynologyのDBへアクセスする場合)
    • DNSで名前解決ができる、固定IPやダイナミックDNSを利用
    • ルーターのNAT / Port Foward / Virtual Serverの設定が出来ており、インタネットからSynologyのMaria DB(デフォルトポート:3307)にアクセスできる

構築手順

Nature Remo API利用時のアクセストークン発行

Nature Remo Cloud APIへアクセスし、OAUTH2認証用のアクセストークンを発行します。APIを利用する際には、HTTPヘッダに以下を指定します。

Authorization: Bearer {TOKEN}

自分のアクセストークンは、home.nature.globalより新規発行します。

Nature Remo Cloud APIのサンプルレスポンス。

[
  {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "name": "string",
    "temperature_offset": 0,
    "humidity_offset": 0,
    "created_at": "2019-06-29T01:47:23.111Z",
    "updated_at": "2019-06-29T01:47:23.111Z",
    "firmware_version": "string",
    "mac_address": "string",
    "serial_number": "string",
    "newest_events": {
      "te": {
        "value": 0,
        "created_at": "2019-06-29T01:47:23.111Z"
      },
      "hu": {
        "value": 0,
        "created_at": "2019-06-29T01:47:23.111Z"
      },
      "il": {
        "value": 0,
        "created_at": "2019-06-29T01:47:23.111Z"
      }
    }
  }
]

Maria DBの準備

SynologyのMaria DBで、データ蓄積用のDBとテーブルを作成します。
データ取得時間記録カラムとTE(室温)、HU(湿度)、IL(照度)を格納するカラムを作成します。また、データ蓄積時のユーザーとDB参照用のユーザーを作成しておきます。

NatureRemo蓄積DB構成
NatureRemo室温湿度照度蓄積DBの構成

PHPスクリプトの準備

簡単なスクリプトサンプルを載せておきます。
取得したアクセストークン、設定したDB関係のパラメーターを設定すれば動作すると思います。

<?php
/*************************************************************************
 * home-api (History of Nature Remo Senser)
 * Home Tools for private. Using IFTTT and Google Home etc
 *
 * PHP 5 or later
 *
 * @category  Home IoT
 * @author    Miki
 * @url       https://www.miki-ie.com/
 * @copyright 2019 (c) MIKI-IE All rights Reserved.
 * @license   https://opensource.org/licenses/mit-license.html MIT License
 * @version   1.0
*************************************************************************/
//Nature Remo API情報
$token = '@NatureRemoApiToken@'; // tokenを設定
$header = [
	    'Authorization: Bearer '.$token,  // 前準備で取得したtokenをヘッダに含める
		    'Content-Type: application/json',
		];
$base_url = 'https://api.nature.global/1/';

//DB情報
$host_name = '127.0.0.1:3307'; //DB
$user_name = '@DB_USER@';
$password = '@DB_PASS@';
$database_name ='@DB_NAME@';
$table_name = '@DB_TABLE@';

$mysqli = new mysqli($host_name, $user_name, $password, $database_name);

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $base_url.'devices');
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_HEADER, true);
$response = curl_exec($curl);

// ステータスコード取得
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
echo 'HTTP_CODE:'.$code."\n";
// header & body 取得
$header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
echo 'HEADER_SIZE:'.$header_size."\n";
$header = substr($response, 0, $header_size);
$body = substr($response, $header_size);
$result = json_decode($body, true);

echo 'te: '.$result[0]["newest_events"]["te"]["val"]."\n";
echo 'hu: '.$result[0]["newest_events"]["hu"]["val"]."\n";
echo 'il: '.$result[0]["newest_events"]["il"]["val"]."\n";

$te = $result[0]["newest_events"]["te"]["val"]."\n";
$hu = $result[0]["newest_events"]["hu"]["val"]."\n";
$il = $result[0]["newest_events"]["il"]["val"]."\n";
$datetime = date("Y/m/d H:i:s");

curl_close($curl);

// SQL(INSERT)を作成
$sql = "INSERT INTO $table_name (
	DATETIME, TE, HU, IL
	) VALUES (
	'$datetime', $te, $hu, $il
		)";
echo $sql."\n";

$mysqli->query($sql);
$mysqli->close();

?>

コマンドラインより動作確認します。定期実行を設定する際にフルパスで実行指定をしたいので、動作確認もフルパス指定で実行確認を行います。
「/usr/local/bin/php72 /var/services/homes/php/Remo.php」
phpMyAdminなどで、登録されたレコードを確認することもおすすめします。

@Synology:~$ /usr/local/bin/php72 /var/services/homes/php/Remo.php
HTTP_CODE:200
HEADER_SIZE:574
te: 24.6
hu: 60
il: 249.39
INSERT INTO living (
	DATETIME, TE, HU, IL
	) VALUES (
	'2019/06/29 11:01:46', 24.6
, 60
, 249.39

		)
@Synology:~$

スクリプトの定期実行登録

Synologyのタスク スケジューラーでスクリプトの定期実行を登録します。

Googleデータポータル(データスタジオ)

Googleデータポータル

Googleデータポータルにアクセスし、レポートを作成します。

  1. データソース追加。GoogleコネクタのMySQLを選択し、接続情報を登録しSynologyのDBとの接続設定を行います。
  2. レポートやData Studio Explorer (Labs)を用いて、Viewを作成します。

以下にGit Hubのgistへ登録したソースコードも載せておきます。