make the smart speaker smarter 14

01/24

Index

TP-Link HS105

2020/11/09追記
いつのことからか、このライブラリでエラーが出るようになったので現在は使用していない。

今回は新たなガジェットを購入したのでその話
乾燥肌を少しでも緩和させようと加湿器を購入した。
そんなに高くないもので、電源を入れたら加湿が始まる
非常に単純なもの。

ふと思いつく。部屋にいるときにラズパイが湿度を
定期的にチェックして、30%を下回ったら

乾燥してますね。加湿器を入れましょう。
カチッ
シャワワーー

みたいなの便利だなと。
なので早速やってみる。

以前よりヨドバシカメラで見て気になっていた
スマートプラグTP-Link HS105を購入。
3,000円ちょっとだったと思う。
これはWiFi通信による電源のリモート操作ができるIoT製品。
専用のスマホアプリからリモコンできるのだが
APIが公開されているため自分でスマートホームの一部として
カスタマイズが可能。

本当素晴らしい製品だ。

TPLink.js

さて早速、npmで公開されているか調べたら
やっぱり有志の方が用意してくださっていた。
なんと素晴らしいことか。
tplink-smarthome-apiというモジュールを
インストールして早速クラスを作ってみる。

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

class TPLink {

    constructor(options){
        this.options = options;
        this.client = new Client();
        this.device = {};
    }

    start(){
        return new Promise((resolve, reject) => {
            this.client.startDiscovery(this.options).on('device-new', (device) => {
                this.device=device;
                resolve(this.device);
            });
        });
    }

    getSystemInfo(){
        return new Promise((resolve, reject) => {
            this.device.getSysInfo().then((sysobj, err) => {
                if(err)reject(false);
                console.log(sysobj);
                resolve(sysobj);
            });
        });
    }

    getState(){
        return new Promise((resolve, reject) => {
            this.device.getPowerState().then((state, err) => {
                if(err)state=false;
                this.options.state=state;  
                resolve(this.options);
            });
        });
    }

    setPower(cmd){
        return new Promise((resolve, reject) => {
            this.device.setPowerState(cmd).then((ret, err) => {
                if(err)reject(false);
                resolve(ret);
            });
        });
    }

    setPowerOn(){
        return this.setPower(true);  
    }

    setPowerOff(){
        return this.setPower(false); 
    }

    stop(){
        return new Promise((resolve, reject) => {
            this.client.stopDiscovery(this.options);
            resolve(true);
        });
    }

}
module.exports=TPLink;

こんな感じ。これをTPLink.jsってファイルにする。
使い方は、

const TPLink=require('./TPLink');

var setBulbOn=async ()=>{
    let options={
        'macaddress': [ 'TP-Linkのマックアドレス' ],
        'devices': ['セットアップしたときのホスト名'],
    };
    const tplclient=new TPLink(options);
    tplclient.start().then(()=>{
        tplclient.setPowerOn().then(()=>{
            tplclient.stop();
        });
    });
};
setBulbOn();

こんな感じかな?
これだと返り値がわからないが
電源入/切がtrue/falseで返ってくるようになっているため
最近気になっているDirect Actionに対応させるためには
JSONでのやり取りを想定してさらにWrapperクラスを用意
する予定。
これでREST APIでsync、query、execといった
やり取りをActions on Google側とできるので
今度やってみようかなと。

今回は簡易的にDialogflowを使って
レシピを書いて、あとはapplication server側に
上記のAPIを実装してみた。

あと、これは我が家のルールとして
LAN内のデバイスはすべてスーパーロボットの
名前からとっている。
アクロバンチやバルディオス、ヴォルトロン
ビスマルクというホスト名にしている。
んで今回このデバイス名はガルビオンに決定。

Result

試してみる。

私:ドクターパイアールにつないで
スピーカー:はい、ドクターパイ アールのテストバージョンです。
スピーカー:こんにちは。
私:湿度は
スピーカー:湿度は23%です。
私:加湿器をつけて
スピーカー:電源を入れます。
カチッ
シャワワー
スピーカー:Galvionは稼働中です。
私:キャンセル

ここまではできるようになった。
ホスト名をgalvionとしてみたけど
一応ガルビオンとは発音してくれている。
ただスマホから同じことをしたら

スマホ:Galvion(ギャルボン)は稼働中です。

と答えた。ギャルボンて、、、。
確かに読めなくはないよな。
なら正確にはどうやって書けばいいのか。
Guarvionかな?ガーヴィオンだと変か。
Ghalvionかな?Hが要るような気がする。
ま、いいか。

Next

次回はThresholdを設けて
それを下回ったらなんかさせるってのを
やってみようかな。


コメント: