コンテンツへスキップ

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

Raspberry Pi 4概要

SoC(システムオンチップ)の変更。Cortex-A72アーキテクチャ(64ビットのクアッドコアARMv8が1.5GHz)を採用。

  • H.265のハードウェアビデオデコーディング
  • 基本モデルは1GBのRAM、2GBと4GBのRAMを搭載するモデルをラインナップ
  • メモリ規格がLPDDR2からLPDDR4に更新
  • Gigabit Ethernet搭載(Gigabit Ethernet over USB 2.0からの変更)
  • USB 3.0×2とUSB 2.0×2
  • 電源用USB-Cポート装備
  • Bluetoothも、4.2から5.0にアップデート
  • 2つのmicro-HDMIポート(フルサイズのHDMIポートからの変更)
  • 2つの4Kディスプレイを、60fpsで接続可能

Raspberry Piの正規販売店によって米国時間6月23日に発売された。メモリが1GBのベースモデルの価格は35ドル。RAMが2GBのモデルは45ドル、4GBのモデルは55ドル。

Raspberry Pi 4 BとRaspberry Pi 3 B +比較

海外サイトで見つけたベンチマーク結果です。
個人的に気にしていた消費電力ですが、想定以上の優秀な結果。導入しても良いかなと思える結果です。

テスト項目Raspberry Pi 3 B +Raspberry Pi 4 B差分
起動時間39.941.74.51%
アイドル状態(消費電力)0.5050.68435.45%
ピーク状態(消費電力)1.141.12-1.75%
CPUベンチマーク(1スレッド)317.7250.4-21.18%
CPUベンチマーク(4スレッド)86.262.8-27.15%
RAMベンチマーク14202983110.07%
OpenGL30.935.815.86%
Ethernet332933181.02%
WiFi 2.4Ghz38.639.62.59%
WiFi 5Ghz98.61078.52%
USB Drive Write35155342.86%
USB Drive Read32233628.13%

大幅な入出力の増強。発熱は少し気になるものの、魅力ある製品だと思います。
また、イノベーションと呼べるモデルチェンジだと思います。

Webhooksの利用

Webhooksは、WEB APIとなります。
Webhook(Webコールバック、HTTPプッシュAPIなど)はあるアプリケーションから別のアプリケーションに対してリアルタイムな情報提供を実現するための仕組みです。
Web/URLアクセスを行います。
Webhooksは、WEB受信とWEB送信側の機能を実現出来ます。

  1. SynologyやRaspberry PiからのURLアクセスを受け付けるWebhook
  2. WebhookからSynologyやRaspberry PiへアクセスするWebhook

の2つの利用形態があります。

IFTTTは、「if(もし) this(この状態) then(の場合は) that(それをする)」なので、
Synologyなどが、IFTTT処理の実行を開始させたい場合は、SynologyよりWebhookを実行します。(SynologyよりWebhookにURLアクセスします)

IFTTT処理でアクションさせたい処理がSynology側などにある場合は、WebhookよりSynologyへURLアクセスさせます。

トリガー(That)

外部よりWebhookにURLアクセスする必要があります。
その際のアクセスするURLや、アクセスに必要なアクセスキーは、Webhooksの「Documation」画面より入手可能です。
{event}はトリガーごとに設定するので、IFTTTでレシピを作成する際に指定します。

実際にThis部分を指定する画面は以下となります。
Event Nameを設定する部分があり、ここで、設定した文字列がURL部分{event}となります。

例:https://maker.ifttt.com/trigger/test/with/key/XXXXXXXXXXXXXXXXXXXXXX
トリガーアクセス時に変数を加える場合は、GETやPOSTで変数を与えます。

アクション(This)

 

Webhookより外部にURLアクセスを実施します。
その際のアクセスするURLや、自分がSynologyなどに準備したPHPファイルなどのWEBコンテンツとなります。
アクセスURLにWEBアクセス方法GETやPOSTなど、そしてコンテンツタイプおよびBodyに変数を指定します。
日本語を扱う場面も多いと思うので、URLエンコードされたコンテンツの送信をオススメします。

 

前提条件

  • Synologyのサーバの公開設定が終わっている
    • ルーターのNAT / Port Foward / Virtual Serverの設定が出来ており、インタネットからサーバーにアクセスできる

DDNS(Dynamic DNS)ダイナミックDNS/動的DNS

インターネットを利用する際に必要となる、パブリックIPアドレス(インターネットにおける世界で一意なアドレス)。
ドメイン(miki-ie.comなど)は、人にもわかりやすい表札や屋号のようなもの。
DNS(Domain Name Serivce)は、ドメインとIPアドレスの割り当てを行います。

DDNSとは、IPアドレスが頻繁に変わるホストに固定的にドメイン名を割り当て、アドレス変更に即座に追随してDNS情報を更新するシステム。 また、その仕組みを利用して提供される動的なDNSサービス。

企業向けなどには固定IPアドレスが利用され、DNS(Domain Name System)運用においてもIPアドレスとドメイン名を固定的に長期間結びつけた運用となる。
個人宅など、一般のインターネットプロバイダ(ISP)を利用した際は、インターネットプロバイダより、一時的なIPアドレスが割り当てられる。

よって、通常の自宅環境でドメインを運用した際は、利用するIPアドレスに合わせてDNSレコードを変更する必要があります。
www.miki-ie.com(不変に利用を続けたい) ⇔ Public IPアドレス(ISP接続毎に変わる)

独自ドメイン取得

DDNS向けに無料でドメインを貸してくれるWEBサービスもありますが、永続的な無料での利用などが約束されているわけでもなく、WEBサイトなどを運営する際は、独自ドメインを利用するのも悪くないと考えています。

VALUE-DOMAIN(バリュードメイン)

  • 500種類以上の独自ドメインを取り扱い。
  • 自動更新設定、一括ドメイン取得・更新など運用がしやすい
  • ネームサーバー/DNSレコード設定/Whois代行などドメイン運用の基本機能も標準装備
  • 「バリューサーバー」「コアサーバー」「XREA」などのホスティングとの連携が容易



VALUE-DOMAINでのDDNS利用時のIP更新方法

VALUE-DOMAINで本設定を行う際は、VALUE-DOMAINのポータルサイトよりIP更新時に用いるドメインのパスワードを取得する必要があります。
参考URL:https://www.value-domain.com/ddns.php?action=howto

ツールなどからのアクセス先(HTTP GET/POSTリクエスト)

https://dyn.value-domain.com/cgi-bin/dyn.fcg?d=ドメイン名&p=パスワード&h=ホスト名&i=IPアドレス

パラメータ説明
d更新するドメインを指定します。
例:value-domain.com
p更新するドメインのパスワードを指定します。
例: 1234
h更新するドメインのホスト名を指定します。DNSレコード編集画面のホスト名と全く同じ仕様です。
例: *(全ホスト)、www、指定なしはホスト名なし
i更新するドメインのIPアドレスを指定します。指定しない場合は、自動的に接続者のIPアドレスが設定されます。
aaaaレコードが存在し、IPアドレスがIPv6フォーマットの場合、aaaaレコードのホストがアップデートされます。

SynologyへVALUE-DOMAINのDDNS更新を設定

SynologyへVALUE-DOMAIN向けのプロバイダ登録を実施

「コントロールパネル」「外部アクセス」「DDNS」「カスタマイズ」よりDDNSプロバイダを新規登録します。
Query URLへは、以下を登録し、一部はSynologyの設定画面で設定する設定値を利用するために、準備されている変数を利用します。

  • ユーザー名:__USERNAME__ d=ドメイン名
  •  パスワード:__PASSWORD__ p=パスワード
  •  ホスト名:__HOSTNAME__ 利用しない
  • 外部アドレス:__MYIP__ i=IPアドレス

※ ホスト名(h=ホスト名)は、「 *(全ホスト)」を固定指定。

 

https://dyn.value-domain.com/cgi-bin/dyn.fcg?d=__USERNAME__&p=__PASSWORD__&h=*&i=__MYIP__

SynologyへVALUE-DOMAIN向けDDNS更新を設定

「コントロールパネル」「外部アクセス」「DDNS」「追加」より作成したサービス・プロバイダVALUE-DOMAINに必要な情報をINPUTします。
※ ホスト名は何を設定しても、実際には「*」となります。このフォームに「*」のしては不可能な仕様となっておりました。



API連携プラットフォーム概要(Overview)

ラズベリーパイ(Raspberry Pi)とNAS(Synology)の使い分け

記載済み記事

ネットワーク構成

SynologyのWEBサーバとRaspberry PiのWEB APIを外部公開にする必要があります。
SynologyとRaspberry Piの両方をWEBサーバーとして、外部公開します。
通常WEBサービスでは、ポート80(http://)と443(https://)が利用されます。
家庭向けの製品では、パケットの到着ポートで、アクセスURLを見て、パケット送付先を振り分けることは出来ないので、2台のWEBサーバを公開する際は、1台を別ポートで運用します。

NAT / Port Forward / Virtual Server設定

インターネット側IP+Port を ローカルネット側IP+Port の転送ルールを設定します。この技術や機能名がNAT、Port ForwardやVirtual Serverと呼ばれております。

パブリック側プライベート側
(グローバルIP)Port:80(Synology プライベートIP)Port:80
(グローバルIP)Port:443(Synology プライベートIP)Port:443
(グローバルIP)Port:8443(Raspberry PiプライベートIP)Port:443

この際に、グローバル側からのRaspberry Piへのアクセス方法は、「https://www.miki.-ie.com:8443」とポート番号を指定したアドレスとなります。

複数DOMAIN(ドメイン)の運用

複数の独自ドメインでWEBサーバを運用します。これは、WEBサーバのVirtual Server機能で実現します。Synologyでは、簡単に設定が可能ですので、設定方法などは割愛します。

常時電源が入っているマシンが2台。
1台がベストなのですが、現時点のベストプラクティスは2台構成
・Synology DiskStation DS218j:サーバー機能、NAS機能、バックアップスペース など
・Raspberry Pi 3 modelB +:各種プログラム動作環境

SynologyとRaspberry Pi

CPUの性能など詳細な比較は、別のサイトを参考にして下さい。
私の現時点(2019年7月時点)の答えは、両方導入。

Synology DiskStation DS218j

Raspberry Pi 3 modelB +

HDDはRAID化によりデータ保全性や製品の特性上高信頼な24時間運転が期待できます。
SSHなどでコンソールログインできるものの、自由度は低いです。
また、GUIで提供されている機能の完成度が高いので、個別なカスタマイズなしで運用な範囲をすべてSynologyで運用が基本方針です。
やはり製品寿命が気になります。
ただし自由度が高い。
新規技術が容易。
(コードさえかければ、今世の中にあるオープンソフトはほとんど動くのでは?)よって、日次バックアップで復旧可能な範囲でのデータ格納。
  • パブリック公開
  • WEBサーバー
  • DBサーバー
  • Node.js関係の開発スピードが速いプラットフォーム
  • OSコマンド

SynologyとRaspberry Piの利用方針

「カスタマイズなしで運用できるものはSynology、Synologyで運用出来ないものをRaspberry Pi」

システムオーバービュー

トリガーとアクション、そしてロジック

トリガー

    • 音声コマンド(Google Home / Google Home mini など)
    • 物理ボタンやスマホのボタン押下
    • 時間 (定期的なスケジュール実行など)
    • メール受信
    • ツイッター (特定情報発信者や特定キーワード)
    • 雨が、降ってきた
    • 室温上昇
    • 人感センサー

アクション

    • Google homeより音声発信発信 Notification
    • メール送信
    • ライン送信
    • 家電操作(テレビ、照明、エアコン)
    • パソコン操作

IFTTT(イフト)If This Then That

IFTTT(イフト)とは“if this then that”の略で、「こうなったら(if this)」「こうする(then that)」という 簡単なルール設定で連携させることができます。
  • [こうなったら]:トリガー
  • [こうする]アクション
多くのサービスなりが連携されており、トリガー部分にもアクション部分にも利用できます。詳しい紹介サイト:https://www.atmarkit.co.jp/ait/spv/1711/22/news031.html

ロジックの利便性

IFTTTは基本的にトリガーとアクションが1:1になります。条件判断などにも対応しておりません。1:1アクションには、基本的にIFTTTのレシピで完結するようにします。
Google Homeで標準で対応できない、グーグールホームとNATURE REMO 連携での、テレビのチャンネル変更や音量変更など。
また、一部ロジック定義が出来るサービスもありますが、トリガーもアクションも品不足で、トリガーの一部利用に止まります。
ここでは、一つのトリガーで複数のアクションや時間によって異なるアクションなどを、自宅サーバーで実現します。

全体API連携時のシステムアーキテクチャ

トリガーロジック
home-api on Raspberry Pi
アクション
IFTTT

  • Google Home音声入力
  • Twitter監視
  • メール監視
  • 天気トリガー など

IFTTT以外

  • タスクスケジューラーやCron実行
  • 他WEBサービス
トリガーに対してアクションをキック。

時間判定によるアクション内容変更

複数条件判定によるアクション実施の決定

IFTTT

  • ライン送信
  • メール送信

IFTTT以外

  • Google Home音声発信(google-home-notifier)
  • PC操作
  • 他WEBサービスへのAPI発行(Spotifyなど)

アーキテクチャオーバービュー(Architecture Overview)、IFTTT、LINE、Google Home、Twitter、Nature Remo、Raspberry Pi

実現したいこと

  • 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へ登録したソースコードも載せておきます。

Webサイトは常時SSLが必須となってきました。
しかも、簡単なSSL証明書は、無料で簡単に作成できるようになりました。Synology無料SSL証明書導入

httpからhttpsへのリダイレクト(転送)

「https://www.miki-ie.com」で運用してきたWebサイトを、「https://www.miki-ie.com」に転送します。
httpでWEBアクセスした場合が、暗号化なしでWEBアクセスをした場合となり、
httpsでWEBアクセスした場合は、インターネット通信がSSL証明書(SSL/TLSでの暗号化)により暗号化された通信となります。
一昔前は、WEBショッピングや会員サイトなど、個人情報などを扱う、機密性のあるサイトのみが利用していました。
特にSSL証明書は、年間数万のコストが発生していました。

利用しているサーバーをSSL化したとしても、今までの運用によって、
既に登録されたブックマークやほかサイトからのリンクや、Google等の検索エンジンからはhttp経由の古いURLにアクセスされる可能性があります。
検索エンジンの検索結果(検索順位)において、不利な場合もあるので、すべてのサイトアクセスをSSL経由に統一する設定は実施しておきたい内容です。

www無しからwww有りへのリダイレクト(転送)

「https://www.miki-ie.com」でアクセスしてきたWEBサイトを、「https://www.miki-ie.com」に転送します。
サイト運営時に、特に意識してURLを統一していても、他サイトから被リンクを受けた場合などは、
他サイトオーナー様のリンク作成方法に依存してしまうので、
www無しのURLアクセスも、www有りのURLアクセスへ自サーバーで転送する設定をおすすめします。
(www無し、有りは好みとなります。どちらかに統一できれば良いと思います)
このURL不統一も検索エンジンの検索結果(検索順位)に影響する場合があります。運用するURLアドレスの統一は是非実施しておきたい内容です。

URL転送設定「mod_rewrite」

URL転送には、Apache(Webサーバー)の、mod_rewriteという機能を使い転送を行います。
今回は下記の転送を設定します。

転送対象のURL

  1. https://www.miki-ie.com
  2. https://www.miki-ie.com
  3. https://www.miki-ie.com

転送先のURL

  1. https://www.miki-ie.com

通常WEBサーバのWEBコンテンツを公開しているフォルダーのトップページに
「.htaccess」ファイルを作成する方法で設定します。
その他、phpでプログラム的に実現や、同様の設定内容をhttpd.confなどWEBサーバ自体の設定で実現することも可能です。

.htaccessファイル編集

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
 
# httpからhttpsへのリダイレクト(転送)
RewriteCond %{HTTPS} off
RewriteRule ^(.*$) https://www.miki-ie.com/$1 [R=301,L]

# www無しからwww有りへのリダイレクト(転送)
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^miki-ie.com$
RewriteRule ^(.*)$ https://www.miki-ie.com/$1 [R=301,L]

www無しからwww有りへのリダイレクト(転送)の記載方法ですが、
すべてwww有りでアクセスさせたいので、以下の記載方法が個人的には好きです。
www無しやwww以外(ftp, mail, nsなど)からのアクセスをhttps://www.へリダイレクト(転送)
ただ、Virtual Serverで運用している場合には、既にwwwありのみホームページが表示される設定かもしれません。
(Virtual Server設定で、「https://www.miki-ie.com」アクセスを設定した公開フォルダ(「/volume1/web/wordpress」など)とマッピング。)

転送対象のURLを拡大(RewriteCond %{HTTP_HOST} !^www.)

  1. https://www.miki-ie.com
  2. https://www.miki-ie.com
  3. https://www.miki-ie.com
  4. http://www2.miki-ie.com
  5. https://ns.miki-ie.com
  6. https://hogehoge.miki-ie.com
    などなど

# www以外からwww有りへのリダイレクト(転送)

# www以外からwww有りへのリダイレクト(転送)
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} !^www.
RewriteRule ^(.*)$ https://www.miki-ie.com/$1 [R=301,L]

変更前「.htaccess」

@Synology$ cat /volume1/web/wordpress/.htaccess
# Synology PHP
AddHandler default-handler .htm .html .shtml
AddHandler php-fastcgi .php
AddType text/html .php
Action php-fastcgi /php56-fpm-handler.fcgi
# Synology PHP

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

変更後「.htaccess」

@Synology$ cat /volume1/web/wordpress/.htaccess
# Synology PHP
AddHandler default-handler .htm .html .shtml
AddHandler php-fastcgi .php
AddType text/html .php
Action php-fastcgi /php56-fpm-handler.fcgi
# Synology PHP

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

# httpからhttpsへのリダイレクト(転送)
RewriteCond %{HTTPS} off
RewriteRule ^(.*$) https://www.miki-ie.com/$1 [R=301,L]

# www以外からwww有りへのリダイレクト(転送)
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} !^www.
RewriteRule ^(.*)$ https://www.miki-ie.com/$1 [R=301,L]

</IfModule>

# END WordPress