カワリモノ息子の技術メモ的な~

カワリモノ息子とその母の技術メモ的な〜

学校が苦手な息子くんの作品とその母の作品、はたまた日常などいろいろを在宅エンジニア母が綴る

息子くんAlexaスマートプラグをハックしてプログラムから制御できるようにした

Alexaスマートプラグ

 我が家にはAIスピーカーのAmazon Echo Show 5(Alexa)とその純正スマートプラグがあります。


 ▲ お天気を教えてくれているAmazon Echo Show(右)と純正スマートプラグ(左)

 このスマートプラグはAmazon Echo ShowやスマホのAlexaアプリから、ON/OFFをすることができます。
 我が家では扇風機などとコンセントの間にこれを挟ませて、声かけすることでつけたり消したりしています。

 とても便利なものなのですが、いかんせんAlexaなしには実行ができません。
 自分が書くプログラムからこの操作できたらいいのになーと言ってましたら、息子くんが「やってみよう」とその気になってくれました。

通信をハッキング

 ノートパソコンをルーターに置き換えて通信をハックしていました。
 「悪意ある人がこういう形で公衆WiFiから他の人の通信を覗くのね〜」ということがわかりましたw

 そして丸2日かけて調べてみて色々なことがわかったようでした。

そして作ったライブラリ

 調査開始から3日目、ライブラリを作成して公開してました。
github.com

 npmでもインストールできるようnpmにも公開したとのことでした。
www.npmjs.com

 使い方は上記どちらとものリンクに使用方法が記載されています。

 ちょっと面倒ですが、Cookieの情報が必要ということでChromeからの開発者ツールによる情報の取り方も書いています。

https://camo.githubusercontent.com/92a525e8d3a1b5c91534ec4ed3d94603f26b83ba4df001bd005b82032b705969/68747470733a2f2f692e696d6775722e636f6d2f717775475578432e706e67

 文章苦手な息子くんなのですが、ちゃんと書いて偉い!
 ただ全部英語ですけどね・・(日本語では書けないらしい)

使ってみた

 こんなふうに書くと使えます。JavaScriptです。
(GitHubの中にtestのプログラムもあります)

import AlexaController from "alexa-smart-plug";

const COOKIE = '※コピった内容';
const AMAZON = 'amazon.co.jp';

// const alexa = new AlexaController(COOKIE, AMAZON);
// IPアドレスを設定すること(変更履歴2022/10/17参照)
const alexa = new AlexaController(COOKIE, AMAZON, { alexaIP: 'xx.xx.xxx.xx' });

const plug = await alexa.getAllDevices();

const controller = plug[0].getController();

controller.setState(true);

 上記ではAlexaのプラグのうち1つ目のものについてONにするという処理になっています。

 ▼ プログラムを実行して光らせた息子くんのパトランプ

ぜひ使ってみてください

 我が家(というか私のアカウント)では使えていますが、他の人は試したことがないので是非試してみてうまく動作するかどうかご連絡をいただけたらとても嬉しいです。

追記:変更履歴

2022/10/17

 うまく動作しない状況が発生。
 息子くんの調査によると、どうやら同じAlexa(Amazon)のホスト名でもDNS切り替えにより接続先のサーバー違うことがあり、Cookieを取得した時に繋がっているサーバーとプログラムから繋ぎに行こうとするサーバーが異なる時に繋がらない模様とのこと。

 下記のようにサーバーのIPアドレスを指定できるように修正しました。
 ChromeのF12や右クリック→検証で開くDevTools(デベロッパーツール)の中のNetworkタブを開いて確認できる通信からCookieの情報を取得していると思いますが、サーバーのIPアドレスはそこのRequestヘッダの「Remote Address」がそれにあたります。

const alexa = new AlexaController(COOKIE, AMAZON, { alexaIP: '18.65.112.15' });