たねやつの木

Photos and Programming

【Node.js】スマートプラグ + Raspberry Piで水槽周りの電源管理(tp-link HS105)

こんばんは、たねやつです。

スマートアクアリウムに関しては結構久しぶりの更新になるのではないでしょうか??(笑)

CO2点火装置などに使用しているタイマー付きコンセントを流行りのIoTコンセント(スマートプラグ)に置き換えてRaspberry Piからオンオフを管理するようにしました。管理するといっても昼間にオンにして夜中はオフにするだけという単純なものです。

アクアリウム用だけでなくほかの家電制御にも割と汎用的に使える内容になっていると思います😎

前の記事

関連性はアクアリウム関係というだけですが前回は水温の取得ができるまでを進めました。

正直言って、tp-linkが配布しているマネジメント用のアプリを使うことで簡単に(Raspberry Pi無しで)スマートプラグの電源の管理やスケジューリングは行うことができます。しかし管理環境をRaspberry Pi上に集約することによって保守しやすくなると思います。

使用するもの

Raspberry Pi

どのバージョンでも大丈夫ですがRaspberry Pi Zero Wで動作確認しています。

秋葉原などの実店舗などで買うほうが安いです😏

tp-link HS105

ルーターやハブでtp-linkの他製品を使用している、Node.jsもモジュールを使用できるという点でこれを選択しました。今回は2つ使う(日中用電源、夜間用電源)のでセットのものを購入しました。日中だけでOKな場合は1つでも大丈夫です。

結構頻繁にセールを行っているので安いときに買うとお得です。

Node.js

今回はNode.jsで動作するモジュールを使用してスマートプラグの管理を行います。ので少しだけNode.jsとJavaScriptの知識が必要となるかもしれません。

Node.jsをRaspberry Piにインストールする方法は以下の私の記事でも紹介しています。

タイトルはZero用となっていますが普通の3BなどでもOKです!

構成

今回は二つのスマートプラグを使用します。なぜ2つ必要かというと日中用と夜間用で電源のオンオフを切り分けるためです。日中用のほうにはエアレーションCO2添加装置(電磁弁)水流用のポンプを接続し、夜間用にはエアレーションを接続します。

スマートプラグでは電源への配線を気にしなくてよい(というかそれ自体が電源)ので配置を考えるのは簡単ですね!今既に稼働しているプラグにそのままポンとつけるだけでほぼほぼ完了するかと思います。

一点注意が、おそらくほとんどの国内のタコ足配線ではHS105を二つ連続して挿すことができません(説明書にも注意書きとして書いてあります)。ので一つ置きに挿したりして工夫する必要があります。間のプラグは細いものであれば使用できます。

また、まずは純正のアプリを利用してWi-Fiの電波をつかむ必要があります。付属の手順に従って自宅のネットワークに参加させておいてください。(本末転倒な感じがしますが。。。(笑))

プログラム作成

プロジェクト作成

前回まで使用しているディレクトリを使用してもいいかもしれませんが、Node.jsのプロジェクトとして新たに作成します。

$ mkdir aqua
$ cd aqua
$ npm init

最初にプロジェクト名を聞かれます。今回は例としてaquaというプロジェクト名で進めていきます。その他の選択肢はデフォルトのまま進めていきます。

node-cron

スマートプラグのオンオフを定期的に実行させるために使用します。名前の通りLinuxのcronと同じようなことができます。先ほど作成したプロジェクト内に移動して、インストールを実行します。

$ npm install node-cron --save

--saveオプションを指定することによって、package.jsonというnpmプロジェクト管理用のファイルに「node-cronを使用している」という情報が追加されます。これによりgithubなどからcloneしてきたときにnpm installというコマンドを実行するだけでnode-cronをインストールすることができます。

tplink-smarthome-api

tplink-smarthome-apiというモジュールを使用して開発を進めていきます。これもnode-cronと同じ方法でインストーしておきます。

$ npm install tplink-smarthome-api --save

node-cronの動作確認

公式ドキュメントに簡単な実行例があるのでそれを参考にしてコマンドライン上で実行してみます。

$ node
> const cron = require('node-cron');
> cron.schedule('* * * * * *', () => console.log('test'));
test
test
...

二個目のコマンドを実行すると一秒ごとにtestと表示されます。日時の指定方法もcronと変わりないのでそのまま使えますね。複数のジョブも一つの処理にまとめても大丈夫そうです。

const cron = require('node-cron');
cron.schedule('* * * * * *', () => console.log('1'));
cron.schedule('*/2 * * * * *', () => console.log('2'));

これを実行するとコンソール上には112112112...と表示されます。

tplink-smarthome-apiの動作確認

コチラも公式の例を参考にして実行してみます。プロジェクト内に.jsのファイルを作成して内容を以下のようにします。

const { Client } = require('tplink-smarthome-api');

const ip = '';  // プラグのIPアドレスを指定

const client = new Client();
client.getDevice({host:ip}).then((device) => {
    device.getSysInfo().then(console.log);
    device.setPowerState(true);
});

そのあとにコンソール上でnode ファイル名で実行できます。成功すればログとスマートプラグの電源がオンになります。setPowerState(false)とすれば電源をオフにすることができます。

これで一通り必要な処理は完成しています。

二つをくっつける

この二つの処理をくっつけて、昼と夜で2つのスマートプラグのオンオフを切り替えるようにしたものが以下になります。新しくjsファイルを作成してそこに記述します。

const cron = require('node-cron');
const { Client } = require('tplink-smarthome-api');

/*
 * ┌────────────── second (optional)
 * │ ┌──────────── minute
 * │ │ ┌────────── hour
 * │ │ │ ┌──────── day of month
 * │ │ │ │ ┌────── month
 * │ │ │ │ │ ┌──── day of week
 * *  *  *  *  *  *
 */

const client = new Client();

const host = {
    daytime : '192.168.xx.xx',
    night   : '192.168.yy.yy',
};

// 日中
cron.schedule('0,10,20,30,40,50 * * * * *', () => {
    client.getDevice({host: host.daytime}).then((dev) => dev.setPowerState(true));
    client.getDevice({host: host.night}).then((dev) => dev.setPowerState(false));
});

// 夜間
cron.schedule('5,15,25,35,45,55 * * * * *', () => {
    client.getDevice({host: host.daytime}).then((dev) => dev.setPowerState(false));
    client.getDevice({host: host.night}).then((dev) => dev.setPowerState(true));
});

clientオブジェクトを使いまわしたりコールバック関数とPromiseが混在していますがとりあえず問題なく動いています。起動するにはnode [作成したファイル名]で起動します。

スマートプラグのIPアドレスは無線LANルーターなどから固定しておく必要があります。

この状態だと5秒おきに二つのスマートプラグのオンオフが入れ替わります。例えば08:00~18:00の間は日中用のプラグ、それ以外の時間には夜間用のプラグをオンにするのであれば、

// 日中
cron.schedule('0 0 8 * * *', () => { });

// 夜間
cron.schedule('0 0 18 * * *', () => { });

とします。これで一通り完了です!

後はデータベースへの状態を登録したりほかの処理と連携させることができます。スマートプラグ毎に処理を切り分けてコマンドラインからオンオフできるようにしてもいいかもしれません。

foreverでデーモン化

foreverというコマンドを利用することでバックグラウンドで実行し停止時に自動で再起動などしてくれます。以下のコマンドでインストール、起動できます。

$ sudo npm install -g forever
$ forever start [作成したファイル名]
もしくは
$ forever start --minUptime 1000 --spinSleepTime 1000 [作成したファイル名]

Raspberry Piの起動時と同時に実行する方法については以下の記事で紹介しています。

次の記事

スマートアクアリウム関係は未定ですがまだもう少し続くと思いますのでお楽しみに😎