2018年2月24日土曜日

Raspberry pi zero Wでgoogle-home-notifier

2021/11/22追記 現在はGoogleHome側の仕様変更により、下記の方法ではうまく動かないようです。


GoogleHomeにしゃべらせたくてラズベリーパイ ( Raspberry pi zero W ) を買いました。

ラズパイもnode.jsも触ったことがありませんが、有益なことを公開してくださっている皆様の情報をたよりに進めます。

私は中身が何もわかってないので以下の情報は間違っているかもしれません。

(1) Raspberry pi zero Wのセットアップ
(2) google-home-notifierのセットアップ
(3)外部からRaspberry piにリクエストを送ってGoogleHomeがしゃべる


@mascii様の
Raspberry PiにNode.jsとnpmの最新版をインストールする
を参考にnode.jsのセットアップしました。
以下引用:
sudo apt-get update
sudo apt-get install -y nodejs npm
sudo npm cache clean
sudo npm install npm n -g
sudo n stable

@ktetsuo
Raspberry PiからGoogle Homeを喋らせる
を参考にgoogle-home-notifierをセットアップしました。
以下引用:
sudo apt-get install libavahi-compat-libdnssd-dev
npm install google-home-notifier

しゃべるだけなら下記を実行すればしゃべります。簡単すぎてビックリします。
以下引用
ファイル名:main2.js
const googlehome = require('google-home-notifier');
const language = 'ja';
googlehome.device("Google-Home", language);
googlehome.ip("192.168.xxx.xxx");
googlehome.notify('こんにちは。私はグーグルホームです。', function(res) {
  console.log(res);
});

node main2.js (パスは適宜追加してください)

次は
次に下記のファイルを編集して
/home/(ユーザー名)/node_modules/google-home-notifier/example.js

以下引用:
ファイル名:example.js
(略)
var ip = '192.168.1.10'; // default IP      //ここにIPを記載
(略)
  var language = 'ja'; // default language code   //ここに「ja」を記載
  if (req.query.language) {
    language;
  }
(略)
  if (req.query.ip) {
     ip = req.query.ip;
  }
  var language = 'ja'; // default language code     //ここに「ja」を記載
  if (req.query.language) {
    language;
  }
(略)

下記で実行
node /home/(ユーザー名)/node_modules/google-home-notifier/example.js

/etc/rc.localに下記を追記すると電源をオフにしても自動で起動します。
forever start /home/(ユーザー名)/node_modules/google-home-notifier/example.js

ラズベリーパイ上のコンソールから

curl -X POST -d "text=テスト" http://(RaspberryPiのIP):(ポート番号)/google-home-notifier

でしゃべると思います。

esp32からでも
下記のスケッチで無事しゃべりました。

#include
#include

const char* ssid     = "(SSID)";
const char* password = "(パスワード)";
const char URL[] = "http://(ラズパイのID):(ポート番号)/google-home-notifier";
WiFiServer server(80);

void setup()
{
    Serial.begin(115200);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    server.begin();
}

void loop() {
  HTTPClient http;
  http.begin(URL);
  String requestBody = "text=テストです";
  http.addHeader("Content-Type", "application/x-www-form-urlencoded");
  int httpCode = http.POST(requestBody);

  Serial.printf("Response: %d", httpCode);
  Serial.println();
  if (httpCode == HTTP_CODE_OK) {
    String body = http.getString();
    Serial.print("Response Body: ");
    Serial.println(body);
  }

  delay(10000);
}


上記のやり方でなくても、Raspberry piとGoogle homeをBluetoothで接続してBluetoothスピーカとして鳴らすという手段もあると思います。
(スマホからは普通にBluetoothスピーカとしてGoogle homeに音を出せました。)


2018年2月18日日曜日

Google homeとESP32+Blynkで家電制御

Google Homeを購入しました。

【2021/11/22追記】
現在は赤外線リモコンやUSBのon/offは行っていません。
リモコンはラトックシステムの家電リモコンを使っています。
ESP32はシャッターと給湯の制御のみに使用しています。
Wi-fiが切れたときに再接続できずオフラインのままになる対策を入れました。(下のほう参照)

ESP32やM5シリーズを使う場合、GoogleHomeで使おうとするとBlynkやIFTTTを使わないといけませんが、アレクサなら単体でデバイスとして認識するらしいのでアレクサと組み合わせたほうが良いみたいです。いつかアレクサを買ったらまたいろいろやってみたいです。

【2021/5/19 追記】
IFTTTが3つまでしか使えなくなってしまったため、現在は大幅に構成を見直しました。
また機会があれば記事を書きたいと思います。

やったこと
・赤外線リモコンによる家電の操作 (照明、エアコン、TVの操作)
・USB機器(ドライブレコーダ)の電源ON/OFF
・HA機器(電動シャッター、エコキュート)の制御(JEM-A端子)
・スマートコンセントによる100V機器のオン/オフ (ホットカーペット、ゲーム機)

使ったもの
・Google Home mini
・ESP32-DevkitC (ESP-WROOM-32)
 今回の用途の場合、Wi-Fi内蔵のArduinoと考えて問題ありません。
しかも今回の用途の場合、前モデルのESP-WROOM-02 (ESP8266)をつかった方が赤外線送受信ライブラリ等がそろっていて便利です。

・IFTTT Google Homeと連携するwebサービスです
・Blynk Arduinoをスマホから操作するwebサービスです


セットアップ関係についてはmgo-tec様で詳細に説明されているので、特に説明することはないです。

「mgo-tec電子工作」
Google Home Mini を使って、声で ESP32 の LED を光らせてみた
https://www.mgo-tec.com/blog-entry-esp32-googlehome-ifttt-webhooks-blynk.html


回路図は以下の通り。動作を保証するものではありません。あくまでも自己責任で。

赤外線リモコンの方は、webを調べるとLEDの電圧ドロップを1.2Vとしているものがたくさん出てきますが、SE303A-Cという赤外線LEDのデータシートによると、定格1.25V@50mA、パルス2.1V@1.0Aとなっていますので、今回使った赤外LEDがどうかは知りませんが、パルスで大電流を流した時はもっと電圧ドロップが大きくなるようです。
今回は適当に設定してしまいました。
メモ書きが間違っていて、ESP32-DevkitCの5V端子はUSB電源からダイオードで電圧ドロップしてから出てきているので4.5V程度、想定電流が0.7Aだと、抵抗で2.3V、LEDで1.9V、Trで0.3Vくらい。
書き忘れましたが、パルス電流の供給用に5Vの端子とGNDの間に10uFの電解コンデンサを入れています。電荷が足りているかの検討は全くしていません。無責任で申し訳ない。

赤外線の送受信は下記のサイトを参考に信号をキャプチャしました。
送信もほぼ下記サイトそのままですが、delayMicrosecondsの値が7と8だと、エアコン以外が動作しませんでした。9と17に変更することで照明も動作するようになりましたが、TVは動作しません。38kHzになってないのだと思います。

「ソースに絡まるエスカルゴ」
http://rikoubou.hatenablog.com/entry/2017/06/12/142227


USB機器のオン/オフは参考にできるサイトが探せず、適当に作ってしまいました。
電圧がギリギリですし、GND電位が浮くので注意が必要です。
p-chのMOSか何かを使った方が良いように思います。

赤外線送受信とカメラのオン/オフのスケッチ(メモ書きの1号のほう)は下記になりました。
==========================
#define BLYNK_PRINT Serial
#include
#include
#include

char auth[] = "(Blynkから送られてきたメール内にある Auth コード)";
char ssid[] = "(ご自宅のWi-FiのSSID)";
char pass[] = "(ご自宅のWi-Fiのパスワード)";

// 送信データ
unsigned int TVon[] = {(キャプチャした赤外線のコード)};
unsigned int TVof[] =  {(キャプチャした赤外線のコード)};

・(以下好きなだけ列挙)


const int IR_SEND_PIN = 33; // 赤外線LEDのピン
const int LED1_PIN = 27;

void setup()
{
    Serial.begin(115200);
  pinMode(IR_SEND_PIN, OUTPUT);
  pinMode(LED1_PIN, OUTPUT);
    delay(10);

    // We start by connecting to a WiFi network

    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

  Blynk.begin(auth, ssid, pass);

//  sigmaDeltaSetup(0, 312500);
//  sigmaDeltaAttachPin(LED_pin, 0);
//  sigmaDeltaWrite(0, 0); // LED OFF ( level 0 )
}

int value = 0;

void loop(){
    Blynk.run();
}

// dataの赤外線信号を送信
void sendSignalP(unsigned int dataP[], unsigned int dataSize) {
  for (int cnt = 0; cnt < dataSize; cnt++) {
    unsigned long len = dataP[cnt]*10;
    unsigned long us = micros();
    do {
      digitalWrite(IR_SEND_PIN, 1 - (cnt&1));
      delayMicroseconds(9);
      digitalWrite(IR_SEND_PIN, 0);
      delayMicroseconds(17);
    } while (long(us + len - micros()) > 0); // 送信時間に達するまでループ
  }
}

BLYNK_WRITE(V4){
  //スマホ側 Blynk アプリで設定したスライダー値の受信
int cmd1 = param[0].asInt();
  switch (cmd1) {
    case 0:
      sendSignalP(TVon, sizeof(TVon) / sizeof(TVon[0]));
      break;
    case 1:
      sendSignalP(TVof, sizeof(TVof) / sizeof(TVof[0]));
      break;
  }

}

BLYNK_WRITE(V5){
  //USB機器の電源ON/OFF
int cmd1 = param[0].asInt();
  switch (cmd1) {
    case 0:
      digitalWrite(LED1_PIN, HIGH);
      break;
    case 1:
      digitalWrite(LED1_PIN, LOW);
      break;
  }
}
==========================

上記とは別にもう一台ESP32-DevkitC を使って、赤外線リモコンで動作しない機器をHA端子(JEM-A端子)を使って制御しています。
(2018/3/25追記 1か月くらい運用したところ、数時間~数日でWi-Fiが切断してしまうようになりました。3/25にもう1台作り直して再投入しています。初号機との違いは5V端子-GND間に25V 100uFの電解コンデンサ追加、フォトカプラの入力端子間に100kΩ追加の2点です。)

それぞれの機器の場所が近くて、1台で全部接続できればそれが一番良いのですが、我が家の場合はカメラ(ドライブレコーダ)とHA機器の場所が離れており、2台体制になりました。

そもそも聞きなれないHA端子について。
日立のエアコンハンドブックの説明がわかりやすかったです。

オン/オフの制御を4ピンの共通端子で行えるようです。搭載機器は電気錠、エアコン、電動シャッター、インターホン、エコキュートなどの給湯関係くらいのようです。

まずコネクタですが、XHコネクタの4Pになるようです。
秋月電子で下記2点を購入し、アセンブリしました。難しかったです。
XHコネクタハウジング 4P XHP-4
XHコネクタハウジング用コンタクト SXH-001T-P0.6

たぶんパソコンの内蔵CDドライブに昔ついていたオーディオケーブル等が使えると思います。
フォトカプラ、ダイオード、抵抗で簡単な回路を作ってケーブル、コネクタと接続します。
回路は簡単なのですが、壁についている電動シャッターの制御ユニットの裏
(壁の中)に設置しなければならず、電源5Vの確保が大変でした。

スケッチは下記。信号オンオフをせめてサブルーチンにすればよかっのですが、面倒でコピペしてしまいました。

V6ピンは
0: シャッター開く
1:シャッター閉じる
2:お風呂オフ
3:お風呂オン
です。

オンもオフも同じ信号なので、モニタ信号で現在の状態を見て、
動作が必要なときのみ信号を送るようになっています。

2021/11/22追記
WIfiが切れたときに再接続できずずっとオフラインになるので下記を追記しました。
void loop()に入れてよいのかわかりませんでしたが、とりあえず様子を見ます。

    while(!Blynk.connected()) {
      Blynk.begin(auth, ssid, pass);
      delay(1000);
    }

================================
#define BLYNK_PRINT Serial
#include
#include
#include

char auth[] = "(Blynkから送られてきたメール内にある Auth コード)";
char ssid[] = "(ご自宅のWi-FiのSSID)";
char pass[] = "(ご自宅のWi-Fiのパスワード)";

void setup()
{
    Serial.begin(115200);
    pinMode(33, OUTPUT);      //シャッター制御
    pinMode(34, INPUT);      // シャッターモニタ
    pinMode(26, OUTPUT);      // お風呂制御
    pinMode(27, INPUT);      // お風呂モニタ
    delay(10);

    // We start by connecting to a WiFi network
    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);
  Blynk.begin(auth, ssid, pass);
}

int value = 0;

void loop(){
    Blynk.run();
    
    while(!Blynk.connected()) {
      Blynk.begin(auth, ssid, pass);
      delay(1000);
    }
}


BLYNK_WRITE(V6){
  //スマホ側 Blynk アプリで設定したスライダー値の受信
int cmd1 = param[0].asInt();
  switch (cmd1) {
    case 0:
       if (digitalRead(34) ==0) {
          digitalWrite(33, HIGH); 
          delay(200);
          digitalWrite(33, LOW); 
        }                  
       break;
    case 1:
      if (digitalRead(34) ==1) {
        digitalWrite(33, HIGH);
        delay(200);
        digitalWrite(33, LOW);         
      }
      break;
    case 2:
       if (digitalRead(27) ==0) {
        digitalWrite(26, HIGH);  
        delay(200);
        digitalWrite(26, LOW); 
      }                  
      break;
    case 3:
      if (digitalRead(27) ==1) {
        digitalWrite(26, HIGH); 
        delay(200);
        digitalWrite(26, LOW); 
      }
      break;
  }
}
================================

このほか、スマートコンセント(Wifiスマートプラグ)という製品を2個購入し、ホットカーペットとWiiUの主電源オン/オフをGoogle homeから行っています。
1台1500円と、そんなに安くはありませんが、100V系を扱うならこちらも大変便利です。
========

おまけ
三和シャッター操作HY-800ユニット背面
〇で囲んだ端子がHA端子です。ピン配置は適当に調べてください。






2017年12月11日月曜日

Javardry やる夫が狂王の試練に挑戦するようです

Javardry やる夫が狂王の試練に挑戦するようですの攻略メモとマップです。

本家Wizardry#1のままなので特に価値はないと思いますが一応載せておきます。

特徴としてはランダムエンカウントの確立がかなり高めに設定されています。
最初は気になりましたが、これもアリかなと思いました。
ただし、悪だと友好的な敵といちいち戦わないといけないので相当負担になります。

武器や防具も数字が出ませんが、これもWizardry#1準拠だとおもいますのでいくらでもwebに情報があると思います。

戦戦僧盗魔魔でスタートして、最終的には戦 戦 戦、 魔→盗、 僧→魔、 魔→僧になりました。アイテムが出ず上級職はなし。クリアレベルは前衛がLV14~12でした。
レアアイテムは唯一手裏剣が出ました。

MAP
B1
 B2
 B3
 B4


B9

B10


2017年11月28日火曜日

Javardry Gunzardry

Javardry Gunzardryの攻略メモとマップです。

ポイントが15固定なのでオレラから上級職への転職になる。
最初のパラメータの割り振りで上級職を意識して割り振る。
前衛は一刻も早く上級職に転職したほうが良い。
悪専用の武器や防具があり、悪が有利に感じた。
あと、麻痺の呪文が結構効くのでお世話になった。
Ore,Ore,Ore,Uta,Dre,Crfでスタート、最終的にAnk,Sam,Ojo,Nin,But,Mai
LV7の攻撃呪文が最終版まで3回しか使えず苦戦。
罠解除は呪文で識別すればNinやButでもなんとかなる(?)

敵の魔法攻撃やブレスを抑える手段がないので装備の組み合わせで炎、冷、雷の耐性はつけておきたい。
自分はHPがなかなか上がらず、後半はレベルアップの選別をした。

8F,9Fで急にドロップ品の質が上がるので飛躍的に戦闘能力が上がる。
ムラマサブレード、シュリケンを入手でき、今までの苦戦がうそのように敵を倒せるようになった。

3Fの小部屋と6Fのシュートで心が折れそうになったけどなんとか乗り切った。

裏ボスは戦ってない。

群馬に行ってみたくなった

MAP
1F
B1
お墓ゾーンは後で来るので無理に回らない。
 2F
 3F
 4F
 5F
 6F
 7F
 8F
 9F


2017年11月23日木曜日

Javardry Simple Dungeon#1 キンドルの挑戦

Javardry Simple Dungeon#1 キンドルの挑戦の攻略メモとマップです。

配布ページに下記の記述があるが、Javardry Class Fileはjarファイルに統合されているようなので最新版のjavardryからJavardry.jarやlibフォルダをコピーした。

JavardryからJavardry Class File Ver.0.261をダウンロードし、classFileフォルダを差し換えてください。

おそらく壁のグラフィックファイルか何かが不足して、デフォルトでは真っ黒しか映らなかったが、自分はワイヤフレーム派なのでjavardry画面の左上Option-render-Dungeon : Wire Frameでワイヤフレームにしたところ、ワイヤフレームは普通に表示された。

ゲーム自体はテンポがよく、とても楽しく遊べた。
CoCの直後だったので攻撃呪文の豊富さがとてもうれしかった。
(もちろんCoCもとても面白い。)

経験値ポイントもうれしかった。

一点だけ注意点。鍵のかかった扉はアイテムの鍵を拾うのではなく、サブメニューからこじ開ける。

自分は戦 闘 僧 盗 魔 賢でやった。闘は中立で作っておけば道の者に転職できたけど残念ながら自分は善で作ってしまった。
珍しく前衛に僧侶を置いたけど、戦闘力的にまったく問題なかった。
いつも賢を入れないので回復呪文に困っていたけど、今回は賢者がいたし、成長も早かったので進めやすかった。種族のせいだと思うけど、賢者はHPが高くとてもよかった。

MAP
B1
 B2
 B3
 B4
 B5
 B6
 B7
 B8
 B9
 B10

2017年11月18日土曜日

Javardry 剣匠王の試練場

Javardry 剣匠王の試練場の攻略メモとマップです。

特に問題もないはず。
ラスボスがちょっとだけ強いので最後に少しレベリングが必要かも。

B1
 B2
 B3
 B4
 B5
 B6
 B7
 B8
 B9
 B10

2017年10月30日月曜日

Jvardry CoC

Jvardry CoCの攻略メモとマップです。Ver0.6だったはずです

リドル含めてネタバレ上等なので、いろんな意味で絶望して、
もう投げ出そうとしている人向けです。

・初期パーティに商人(鑑定用)とADV(将来的な脱出用)を入れたほうが良い
・AMURET of MITER 僧侶の呪文を全部習得

とても評価の高いシナリオです。
5人パーティや、序盤の容赦なさ含めて非常に個性が強いながらも、マップや仕掛けの作りこみは非常に魅力的です。
おそらく敵ごとに戦略を変えて戦わないといけないのだと思うのですが、自分はグループ攻撃魔法が1種類しかないのがつらかったです。


MAP
街道

真ん中上の部屋から左の広間にいく隠し扉があります。
三姉妹の言うことを全部やっても何が起こるのかわかりませんでした。
羊皮紙の使い方、ぐるぐる回るイベントのヒント等なのかもしれませんし、
言ってることと反対のことをするとか、私のわからなかったイベントがあるかもしれません。
右の真ん中やや上の小さくなるキノコは1個持って廃城まで行ってください。


商店で酸素ボンベを買ってくれば先に進めるのかもしれませんが私はやってません。

山脈


商人の石を拾ってあげると装備が買える
シャドウキーは山頂で使うらしい

 影 おおっす
スイッチを探しなおしたりするといいらしいけど、不明。
死骸は称号関係のイベントかな?やってません。
城下町跡
右下で騎士団イベントしてから右上の少女、そしてまた騎士団。
街道で戦ってない場合は戻ってやっつけてくる。

廃城
 1F
 2F
 B1F
ルルイエの書はInsaneの称号でPIEが上がってHPがLV1並みに減った。
自分は慌ててlordに転職してしまったけど、普通にレベルが上がればHPは戻るのかも。
グリモアは一人で戦う。呪文が強化。
Mountains!
 B2F
 B3
4つ角のボスを倒せばB4に進めるのかもしれないけど、自分はエレベータで先にB4に行ってしまったので微妙になってしまいました。
右下で魔剣士イベント。
 B4
羊でB5への近道が開く。
 B5
ここのボスつよい。少しレベリング必要かも。
右上は盗まれたアイテムが戻ってくる?
女性一人でいくイベントはやってません。
称号関係のイベント?戻れなくなったりするのかな。
左下で粉をかぶる。見破る粉をかぶって3体のボスを順番にたおすのかな。
結局意味がわからないまま適当に何度か順番を変えて倒したら行けました。
別の粉で魔剣士イベント。
金の粉は何だろう。
ここは縦になっていて衝撃を受けました。発想がすごい。

B8

両耳を閉ざせ 己を見失うな
目を見開け 全てを導とせよ

もの 赤
道  青
そむけば監獄

4-1赤 
右手 西に3南に0
東に1南に1
求めるもの 東に3北に1 飽き足らず掘り進む東に3南に2
西4南1
東0北4 利を棄てなお理を求めるもの東4北0
西2北3
東2北1
もう一つの志、もう一つの始まり
心なお砕けじ かれの見つめる先は
十夜を待ちわびどもいまだ君と見えず 思慮浅き者はいずれ石の中
賢者はその身を焼きて火を知り 愚者は我が身を惜しみて辿らず 魔道の頂を目指すものよ死の知識は黄泉で尋ねよ




2-3青
東3南2
西4
東4北4
西2南1
最も近く親しいもの
鼠どもは失せ 後に鳥の出入りも無し
導きの終わり すなわちその意味を示せ 信ずること七度 遂には籠の外

 B9
基本的にトークンを泉に入れるといろいろ起こる。
隼のトークン(中央左の隠し部屋)でエレベータが起動する。
杖のトークンは捨てたけど、二度と手に入らなかった。

 B10
真実の粉みたいなやつをかぶっていると0-19で女の子の亡霊がつく
上真ん中の2つの扉の間のかくし扉から武器やに入れる
武器防具の中ボスを倒していくと、中央のボスが弱体化していくような雰囲気

 B11


それは天秤のつり合い
それは田畑の土を均すに等しく
それは貧と富の差を埋めるもの  平等 石化
もし汝がそれを願うならば我の前で高らかに声挙げよ


それは心の安らぎ
それは一人では決して得られず
それは心地よく語らうひと時 団欒 さわがしくなる

右上
それは汝らが一番望むもの
それは探索の終わりを意味し
それは旅路と対となりて不可欠  帰還

真ん中
それは成長と順応の証
それは後世に紡ぐ手段であり
それは人が人でなくなること 進化 B12

かわいい