IToTの覚え書き

マイクロビット、アルドゥイーノ、ラズベリーパイなどで楽しい道具を作る趣味のサイトです。 基本的に自分用の覚え書きです。

2021年03月

IFTTT有料化対処法をもうひとつ考えました。おもにgoogle home miniに音楽や語学のCDトラックをmp3化した物を口頭でかけてもらうためのものです。

「OKグーグルCD中国語14」というと「CD中国語のトラック14をかけます ポロン」と言ってサーバの中国語フォルダの014.mp3をかけてくれます。
「OKグーグルCD竹内まりや1」というと「CD竹内まりやのトラック1をかけます ポロン」と言ってサーバの竹内まりやフォルダの001.mp3をかけてくれます。

1.グーグルスプレッドシートを新規に作ります。
シート:
A1セル:空白
A2セル:=SUBSTITUTE(SUBSTITUTE(A1," ","")," ","")
A3セル:空白
A4セル:=Right("00"&A3,3)
A5セル:="http://211.132.114.***:50011/?mp3=http://192.168.1.2/"&A2&"/"&A4&".mp3"
// 211.132.114.***:50011はgoogle home notifierのグローバルIPアドレス
// 192.168.1.2は音声フォルダを入れたweb serverのローカルIPアドレス

マクロ:
function doPost(e) {
var jsonString = e.postData.getDataAsString();//IFTTTからJSON形式で変数を受け取る
var data = JSON.parse(jsonString);//配列に分解
var NumberField = data.NumberField;//数字#を変数NumberFieldに
var TextField = data.TextField;//文字列$を変数TextFieldに
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
sheet.getRange("A1").setValue(TextField);//A1セルに変数TextFieldを
sheet.getRange("A3").setValue(NumberField);//A3セルに変数NumberFieldを
var url = sheet.getRange("A5").getValue();//A5セルの計算されたurlを変数urlに
UrlFetchApp.fetch(url);//urlを開く
}

これを「公開」…「web applicationとして導入」します。
このマクロを実行するurlアドレスが
https://script.google.com/macros/s/AKfycbxy6d8ii9MluRbNTmXRWpwLDTIG-anTE0CK***/exec
などと表示されますので、コピーしておきます。

2.IFTTTを新規に作ります。
IF(トリガー):google assistant
Say a phrase with both a number and a text ingredient
What do you want to say?:「CD $ # 」
What do you want the Assistant to say in response?:「CD $ トラック # をかけます」
Language:Japanese

THEN(アクション):web hooks
URL:先ほどコピーしたアドレス
Method:POST
Content Type:application/JSON
Body:{"NumberField": "{{NumberField}}", "TextField": " {{TextField}}" }

コンテンツを増やしたいときもサーバにフォルダを作ってmp3ファイルを入れるだけです。
IFTTTもグーグルスプレッドシートもスクリプト(GAS)も一度作れば何もいじらなくて大丈夫です。
これで先の方法とあわせてIFTTT2つで無料で十分やっていけそうです。


WeMos D1 Mini

Arduino UNOと互換のD1 miniカードの最大の違いはWiFi機能が搭載されていることです。
WiFi機能は IoT(Internet of Things) には必要な機能です。
IoTの中心となるGoogle Home miniなどのスマートスピーカーとの連動をする準備をまとめます。
※この記事は2年前の記事を2021/03/05最新版にリニューアルしたものです。

1.D1 miniカードを買います。
 Arduino UNO R3互換、ESP8266搭載のWiFi 開発ボード、WeMos D1 miniを入手します。
アマゾンで買えます
(D1 miniにはピンがハンダ付けされていないものがあります。自分でハンダ付けが面倒なら少し大きくなりますがD1カードを買っても設定は同じです。)

2.USBドライバをインストールします。
 D1ボードのUSBドライバをダウンロードしてインストールします。

3.Arduino IDE をインストールします。
 ソフト開発環境(IDE)はArduino IDE が使える点が有り難い。無料で使いやすく情報が豊富です。
最新のArduino 1.8.13 をDOWNLOAD OPTIONS のWIndows win7 and newer からJUST DOWNLOADしてインストールします。

4.Arduino IDEを設定します。
 1)Arduino IDEを起動して、
ファイル>環境設定>追加のボードマネジャのURL で、
http://arduino.esp8266.com/stable/package_esp8266com_index.json
と入れてOKをクリックします。
 2)ツール>ボード>ボードマネージャ…で空欄に esp8266 と入れて、
esp8266 by ESP8266 communityの最新バージョン2.7.4をインストール します。
 3)ツールからボード設定します。
ボード>LOLIN(Wemos) D1 R2 & mini
Upload Speed: 115200
CPU Frequency: 160MHz
シリアルポート: COM3(←コントロールパネル>システム>デバイスマネージャ>ポートで実際にD1ボードが刺さっているCOMポートを調べる)
 4)スケッチ>ライブラリをインクルード>ライブラリを管理で空欄に esp8266-google と入れて、esp8266-google-home-notifier 1.0.7 と esp8266-google-tts 1.1.0 をインストールします。

5.google home miniを用意します。
間違って格安の中古を買ったときは、必ず裏面のボタンを長押しして初期状態にリセットして下さい。手を離せと少し脅されますが離さなければリセットされます。
Android 6.0以上のタブレットに google home アプリをインストールして、google home mini を設定します。
設定はiOSでもできますがPCではできません。(googleはMicrosoftに塩を送りません)

6.google home notifier を用意します。
日本人のhorihiroさんがgoogle home miniに自分の言葉を喋らせることのできるgoogle home notifierをD1 miniカードでも動くように全力で移植してesp8266-google-home-notifier を作ってくれました。多謝。
D1 mini カードに esp8266-google-home-notifier を入れると、google home mini に好きな言葉を喋らせることができて便利です。
ファイル>スケッチ例>esp8266-google-home-notifier>esp8266>SimpleUsage を開いて SSID やpassword、google home mini名 などを自分の環境に変更して、保存後、「→」ボタンをクリックしてマイコンボードに書き込みます。コンパイルが成功し、書き込みが100%になれば成功です。
D1 mini カードのリセットボタンを押すと google home mini が「hello world」と喋るはずです。後はスケッチを自分の用途に改造します。
(google home mini名はリビングルームのときは続いていますが、ダイニング ルームのときは半角スペースが入ります。気をつけてください)

7.googleスプレッドシート を用意します。
googleスプレッドシート は google アカウントがあれば https://docs.google.com/spreadsheets/ から作成できます。
表計算式は Excel に似ていて簡単です。
マクロは GoogleAppsScript(GAS) と言って JavaScript に似ていて慣れやすいです。GoogleAppsScript の本もたくさんあります。
googleスプレッドシート のメニュー>ツール>スクリプトエディタで doPost(e) という関数を作り、
公開>ウェブアプリケーションとして導入…すると URL を教えてくれるので、それを IFTTT の設定に使います。

<< googleスプレッドシートのマクロ例>>

function doPost(e) {
var jsonString = e.postData.getDataAsString();//IFTTTからのデータを受け取る
var data = JSON.parse(jsonString);//JSONだと日本語もOK
var value1 = data.value1; //IFTTTからの番号#をvalue1に
var value2 = data.value2; //IFTTTからの文字$をvalue2に
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName(value1);
sheet.getRange("A1").setValue(value2);//IFTTTからの文字$がA1セルに入る
url = sheet.getRange("A3").getValue();//表計算式でurlを計算してA3に入れておく
UrlFetchApp.fetch(url); //家のD1 miniカードに指示を出す
}

上記例では google home mini に喋った言葉が IFTTT 経由で A1セルに入りますが、勝手にスペースが入ることがありますので、A2セルは =SUBSTITUTE(SUBSTITUTE(A1," ","")," ","") と計算してスペースを抜きます。
A3セルは A2を使って url を計算して入るようにしておきます。


8.IFTTT(イフト)と連携します。
 1)IoT には IFTTT が必須ではないでしょうか?例えば室外からのスマホでの遠隔操作などに WebHook 機能をつかいます。
まだでしたらIFTTTの登録をおすすめします。
IFTTT を使えば直接家電製品の電源を操作したり、赤外線を出して家電製品を操作したり、google-home-notifier 経由で google home mini に喋らせたりできます。
 2)しかし、IFTTT は毎月約4ドルを支払うと無制限に使えますが、無料なら3個までしか使えません。
そこで、いったん使用者が google home mini に発した言葉を IFTTT経由で googleスプレッドシートに飛ばし、それから家の D1 mini カードを様々に指示します。
1手間増えますがそうすればIFTTT1個でシート100枚まで操作でき、100倍に使えます。

<< IFTTTの設定>>

IF(トリガー)
google assistantからSay a phrase with both a number and a text ingredient
What do you want to say?: ナンバー # $
What do you want the Assistant to say in response?: ナンバー # $ ですね?
Language: Japanese

Then(アクション)
WebHooksからMake a web request
URL: https://script.google.com/macros/s/-----------------/exec(先ほどgoogle スプレッドシートのマクロをウェブアプリとして公開したURL)
Method: POST
Content Typ: application/json
Body: {"value1": "{{NumberField}}", "value2": " {{TextField}}"}


これで準備完了です。
あとはファイル>スケッチの例>からいろいろ試して見るといいでしょう。
スケッチのコンパイルおよびボードへの転送はメニューバー下の→(右矢印)ボタンでできます。

これでできることは、
1.Google home miniから、IFTTTを使って家の電気をつけたり消したりできます。
(赤外線を使った家電製品もコントロールできます。家の外からスマホを使ってもできます)
2.Google home miniから、IFTTTを使ってGoogle Spredsheetに各種データを保存できます。
3.esp8266-google-home-notifierを使って、Google home miniに好きな言葉を喋らせることができます。

2020年末にIFTTTが有料化して毎月4ドル支払わないと3個までしかアプリが使えなくなりました。
今まで30個くらい作っていたので困りました。毎月4ドルでもちりも積もれば山です。

しかしこれはIFTTTの番号#と文字$を両方使うことで対応できました。
「OK グーグル ナンバー # $」です。
たとえばナンバー99はgoogle spleadsheetのシート名99に相当します。
料理のレシピですので覚えやすく99(クック)にしました。

これで、たとえば「OK グーグル No.99 肉じゃが」といえばシート名99「料理レシピ」が開き、C1セルに「肉じゃが」と入ります。C2~C5までに表から肉じゃがのレシピを検索し、計算式で加工して最終的にC6にnotifier boardに送るurlを作ります。すると「肉じゃがのレシピは卵1、水1/2、小麦粉60g、片栗粉30gです」とgoogle home miniが喋ってくれます。

ほかに分別ごみをシート名53に作って「OK グーグル No.53 明日」といえばC1セルの「明日」という文字から表計算の式が計算してC4セルに「燃えないごみ」、C5セルに「明日は燃えないごみの日です」を算出し、それからC6セルにurlを作ります。セルの各式はExcelに似ていて簡単に作れます。
これでIFTTT1個のアプリでgoogle spleadsheetが許す100シート分まで使え、3個なら300シートまで無料で使えます。

悪いことばかりでなくいいこともありました。今までGASでUrlFetchApp.fetch(url)するときにurlは日本語はダメでurlコードに変換する必要がありました。そこで今まではecl.jsをgoogle spredsheet内でライブラリ化して
var url = ecl.EscapeSJIS(value);
としていましたが、google spleadsheetは賢くなって日本語のままでfetchできるようになりました。

参考までに私の作ったGAS(GoogleAppsScript←googleの作ったJavaScriptみたいなやつ)はこれ1個だけです。
これでIFTTTからJSONで送られてきた番号#と文字$からシートを移動し、表のデータを検索し結果を、家のD1 miniカードのesp8266-google-home-notifier経由で、google home miniに喋らせることができます。
function doPost(e) {
var jsonString = e.postData.getDataAsString();//JSONでないと文字化けする
var data = JSON.parse(jsonString);
var value1 = data.value1; //NumberField(#)の中身
var value2 = data.value2; //TextField($)の中身
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName(value1);
sheet.getRange("C1").setValue(value2);//IFTTからの文字をC1に入れて検索
url = sheet.getRange("C6").getValue();//C6までにurlを作る
UrlFetchApp.fetch(url); //notifierにデータを送る
}


これと補完する数字#と文字列$を入れ替えたようなもう一つの方法もあります。

2021年になって、久しぶりにアイデアが湧いてさわってみたら、esp8266-google-home-notifierが喋らなくなっていました。

アイデアとは台所で立ったまま料理名をいえば、自分の料理レシピをgoogle home mini が言ってくれるというもの。例えば「OKグーグル 私のレシピ 野菜炒め」というと、「野菜炒めのレシピは水大2、酒大1、塩こしょう、醤油、オイスターソース、片栗粉各小1です」と言ってくれるもの。

esp8266-google-home-notifier作者のhorihiro(Hirofumi Horikawa)さんの情報を調べてみたら、google側の小変更があったが、esp8266-google-ttsバージョンアップで対応済みとのこと。
(horihiroさんありがとう!あなたはいい人です)
さっそくesp8266-google-ttsのバージョンアップをしましたが喋りませんでした。そこで、
Windows Xp → Windows 7
Arduino IDE 1.6.5 → 1.8.13
Board Maneger で、esp8266 Board 2.4.1 → 2.7.4
Library Maneger で、esp8266-google-home-notifier 1.0.7 → 1.0.7
Library Maneger で、esp8266-google-tts 1.0.7 → 1.1.0

と全て最新にバージョンアップしました。それでも喋りませんでした。

horihiroさんの所は喋るのに私の所が喋らないのはソフトのせいじゃないはず。ハードかな?試しにボードを今まで使っていたもの(Wemos D1ミニ開発ボード ESP8285)から、別なもの(D1 Mini ESP8266)に変えてみたら、喋りました。何かの仕様が変わってESP8285ははずされたんですね。

なんとか無事に2021/03/03にesp8266-google-home-notifierが復活しました。

ところがもう一つ問題が起きました。IFTTTが有料化したのです。→IFTTT有料化対処法


↑このページのトップヘ