ESP8266とalexaで家電を制御する fauxmoESP編 〜TVを音声コントロール〜

前回までの記事で、ESP8266で家電を制御する為にESP8266をarduinoで利用できる手順やIRremotoという赤外線ライブラリの使い方、さらにalexaでESP8266を認識して制御できるようにするWemoEmulatorライブラリを紹介しましたが、2019年7月の段階で第三世代alexaではESP8266 WemoEmulatorを認識はしますが、サーバーエラーとなり家電を音声制御する事ができませんでした。

 

ですので、今回はalexaとESP8266の連携ライブラリをESP8266WemoEmulatorからfauxmoESPというライブラリに変更して家電を音声制御します。

2020年1月1日 FaumoESPを使ったプログラムでalexa側でデバイスが3つ以上になると検索できなくなる現象がありますが、書き込み時にある事をすると解消されます。詳細はこちらで書いてます。

 

前提条件ですが、arduinoIDEでESP8266を利用する手順やESP8266で赤外線を利用するライブラリのIRremoteの導入手順やプログラムのしかたなどは同様です。

最初から学びたい方はこちらから

HiLetgoの激安ESP8266を使う

激安ESP8266(alexa経由で)で家電を音声操作してみる ~赤外線解析編~

激安ESP8266を用いてアレクサ経由で家電コントロール(第2世代のalexaまで可能) 〜プログラム編その①〜

 

 

fauxmoESPライブラリの導入

導入もむっちゃ簡単です。

fauxmoESPのホームページからライブラリをZIP形式でダウンロードします。

↑ダウンロードする場所ですが、赤丸のESPAsyncTCPというライブラリもどうやらいるようですのでこれと、

もう一つは画面の左の”ダウンロード”からfauxmoEXPをダウンロードしまう。

 

下の画像がダウンロードできるgithubのページです。

いずれもダウンロードする場合はZIP形式で保存します。

 

ダウンロード場所は任意の場所に保存します。

 

 

arduinoIDEにライブラリをインストールする

fauxmoEXPとESPAsyncTCPライブラリはarduinoを開いてスケッチ→ライブラリをインクルード→.zip形式のライブラリをインストールと進んでダウンロードしたファイルを選択すると自動的にライブラリを導入できます。

 

これだけです。

むっちゃ簡単です。

 

 

fauxmoESPの使い方

ESPAsyncTCPはなんの役にたつのかわからないのですがとりあえず、このライブラリもいるよってreadmeに書いてあったので、、、、

それでは実際にfauxmoESPの使い方についてご紹介いたします。

基本的にはライブラリ上のプログラム例があるのでそれを自分なりに変更して使うのが手っ取り早いです。

とりあえずarduinoIDE上のスケッチ例→fauxmoESP→fauxmoESP_basicを選べば間違いありません。

 

スクラッチ例が開くと・・↓

デフォルトのプログラムですが二つのファイルの構成になっています。

 

下の図は二つのファイルのうちの一つです。

何を規定しているのかというとESP8266がwifiに繋がる時のSSIDとパスワードを入れる設定です。

ここに自宅のwifiの設定を記入します。

実際のプログラムについて

実際にのスケッチ例として記載されているのが下のコードになります。

  1. #include <Arduino.h>
  2. #ifdef ESP32
  3.     #include <WiFi.h>
  4. #else
  5.     #include <ESP8266WiFi.h>
  6. #endif
  7. #include “fauxmoESP.h”
  8. // Rename the credentials.sample.h file to credentials.h and
  9. // edit it according to your router configuration
  10. #include “credentials.h”
  11. fauxmoESP fauxmo;
  12. // —————————————————————————–
  13. //このへんまでは触る必要なし
  14. #define SERIAL_BAUDRATE 115200
  15. //#define でESP8266のポート番号に名前を規定しています。
  16. #define LED_YELLOW 4 //たとえばここでは4番ポートの名前はLED_YELLOWです
  17. #define LED_GREEN 5
  18. #define LED_BLUE 0
  19. #define LED_PINK 2
  20. #define LED_WHITE 15
  21. //この下の設定でalexaに表示される名前を規定しまいます。alexa”yellow lamp”をつけてとかいう使い方
  22. #define ID_YELLOW “yellow lamp”
  23. #define ID_GREEN “green lamp”
  24. #define ID_BLUE “blue lamp”
  25. #define ID_PINK “pink lamp”
  26. #define ID_WHITE “white lamp”
  27. // —————————————————————————–
  28. // —————————————————————————–
  29. // Wifi  ここからwifiの設定 まったくいじる必要なし
  30. // —————————————————————————–
  31. void wifiSetup() {
  32.     // Set WIFI module to STA mode
  33.     WiFi.mode(WIFI_STA);
  34.     // Connect
  35.     Serial.printf(“[WIFI] Connecting to %s “, WIFI_SSID);
  36.     WiFi.begin(WIFI_SSID, WIFI_PASS);
  37.     // Wait
  38.     while (WiFi.status() != WL_CONNECTED) {
  39.         Serial.print(“.”);
  40.         delay(100);
  41.     }
  42.     Serial.println();
  43.     // Connected!
  44.     Serial.printf(“[WIFI] STATION Mode, SSID: %s, IP address: %s\n”, WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());
  45. }
  46. void setup() {
  47.     // Init serial port and clean garbage
  48.     Serial.begin(SERIAL_BAUDRATE);
  49.     Serial.println();
  50.     Serial.println();
  51.     // LEDs ここでESP8266のピンの設定です。全てoutput に設定、要は出力です。
  52.     pinMode(LED_YELLOW, OUTPUT);
  53.     pinMode(LED_GREEN, OUTPUT);
  54.     pinMode(LED_BLUE, OUTPUT);
  55.     pinMode(LED_PINK, OUTPUT);
  56.     pinMode(LED_WHITE, OUTPUT);
  57.     digitalWrite(LED_YELLOW, LOW);
  58.     digitalWrite(LED_GREEN, LOW);
  59.     digitalWrite(LED_BLUE, LOW);
  60.     digitalWrite(LED_PINK, LOW);
  61.     digitalWrite(LED_WHITE, LOW);
  62.     // Wifi wifiをつなぎます このへんも特に触る必要なし
  63.     wifiSetup();
  64.     // By default, fauxmoESP creates it’s own webserver on the defined port
  65.     // The TCP port must be 80 for gen3 devices (default is 1901)
  66.     // This has to be done before the call to enable()
  67.     fauxmo.createServer(true); // not needed, this is the default value
  68.     fauxmo.setPort(80); // This is required for gen3 devices
  69.     // You have to call enable(true) once you have a WiFi connection
  70.     // You can enable or disable the library at any moment
  71.     // Disabling it will prevent the devices from being discovered and switched
  72.     fauxmo.enable(true);
  73.     // You can use different ways to invoke alexa to modify the devices state:
  74.     // “Alexa, turn yellow lamp on”
  75.     // “Alexa, turn on yellow lamp
  76.     // “Alexa, set yellow lamp to fifty” (50 means 50% of brightness, note, this example does not use this functionality)
  77.     // Add virtual devices alexa側での仮想デバイスを設定しています。
  78.     fauxmo.addDevice(ID_YELLOW);
  79.     fauxmo.addDevice(ID_GREEN);
  80.     fauxmo.addDevice(ID_BLUE);
  81.     fauxmo.addDevice(ID_PINK);
  82.     fauxmo.addDevice(ID_WHITE);
  83. //ここからが音声制御したときのESP8266の動作を決める部分です。
  84.     fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) {
  85.         
  86.         // Callback when a command from Alexa is received.
  87.         // You can use device_id or device_name to choose the element to perform an action onto (relay, LED,…)
  88.         // State is a boolean (ON/OFF) and value a number from 0 to 255 (if you say “set kitchen light to 50%” you will receive a 128 here).
  89.         // Just remember not to delay too much here, this is a callback, exit as soon as possible.
  90.         // If you have to do something more involved here set a flag and process it in your main loop.
  91.         
  92.         Serial.printf(“[MAIN] Device #%d (%s) state: %s value: %d\n”, device_id, device_name, state ? “ON” : “OFF”, value);
  93.         // Checking for device_id is simpler if you are certain about the order they are loaded and it does not change.
  94.         // Otherwise comparing the device_name is safer.
  95. //ここから下を変更すれば様々な制御が可能です。
  96. //下のプログラムはdevice_nameがID_YELLOWと同じならLED_YELLOWをHIGHにそうでなければLOWにという設定です。
  97. //少し複雑かもしれませんがよく確認すれば簡単です。
  98.         if (strcmp(device_name, ID_YELLOW)==0) {
  99.             digitalWrite(LED_YELLOW, state ? HIGH : LOW);
  100.         } else if (strcmp(device_name, ID_GREEN)==0) {
  101.             digitalWrite(LED_GREEN, state ? HIGH : LOW);
  102.         } else if (strcmp(device_name, ID_BLUE)==0) {
  103.             digitalWrite(LED_BLUE, state ? HIGH : LOW);
  104.         } else if (strcmp(device_name, ID_PINK)==0) {
  105.             digitalWrite(LED_PINK, state ? HIGH : LOW);
  106.         } else if (strcmp(device_name, ID_WHITE)==0) {
  107.             digitalWrite(LED_WHITE, state ? HIGH : LOW);
  108.         }
  109.     });
  110. }
  111. void loop() {
  112.     // fauxmoESP uses an async TCP server but a sync UDP server
  113.     // Therefore, we have to manually poll for UDP packets
  114.     fauxmo.handle();
  115.     // This is a sample code to output free heap every 5 seconds
  116.     // This is a cheap way to detect memory leaks
  117.     static unsigned long last = millis();
  118.     if (millis() – last > 5000) {
  119.         last = millis();
  120.         Serial.printf(“[MAIN] Free heap: %d bytes\n”, ESP.getFreeHeap());
  121.     }
  122.     // If your device state is changed by any other means (MQTT, physical button,…)
  123.     // you can instruct the library to report the new state to Alexa on next request:
  124.     // fauxmo.setState(ID_YELLOW, true, 255);
  125. }

 

とりあえず上記のようなプログラムを変更して自分なりのものに変更していきます。

スポンサードリンク

ちなみに私はテレビの赤外線を操作するので、IRremoteライブラリをいれて赤外線LEDを出力とするプログラム変更を行いました。

ご参考に以下にご紹介します。

 

  1. #include <Arduino.h>
  2. #ifdef ESP32
  3.     #include <WiFi.h>
  4. #else
  5.     #include <ESP8266WiFi.h>
  6. #endif
  7. #include “fauxmoESP.h”
  8. // Rename the credentials.sample.h file to credentials.h and
  9. // edit it according to your router configuration
  10. #include “kazunet.h”
  11. //IRremoteESP8266で赤外線信号の送信設定
  12. #include <Arduino.h>
  13. #include <IRremoteESP8266.h>
  14. #include <IRsend.h>
  15. //4番ピンを赤外線送信pinに設定 ESP8266ではD2になる
  16. const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2).
  17. IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message.
  18. fauxmoESP fauxmo;
  19. // —————————————————————————–
  20. #define SERIAL_BAUDRATE 115200
  21. #define ID_tv “tv”
  22. #define ID_chA “chA”
  23. #define ID_chB “chB”
  24. #define ID_chC “chC”
  25. #define ID_chD “chD”
  26. #define ID_sound “sound”
  27. #define ID_chchange “chchange”
  28. // —————————————————————————–
  29. // —————————————————————————–
  30. // Wifi
  31. // —————————————————————————–
  32. void wifiSetup() {
  33.     // Set WIFI module to STA mode
  34.     WiFi.mode(WIFI_STA);
  35.     // Connect
  36.     Serial.printf(“[WIFI] Connecting to %s “, WIFI_SSID);
  37.     WiFi.begin(WIFI_SSID, WIFI_PASS);
  38.     // Wait
  39.     while (WiFi.status() != WL_CONNECTED) {
  40.         Serial.print(“.”);
  41.         delay(100);
  42.     }
  43.     Serial.println();
  44.     // Connected!
  45.     Serial.printf(“[WIFI] STATION Mode, SSID: %s, IP address: %s\n”, WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());
  46. }
  47. void setup() {
  48.     // Init serial port and clean garbage
  49.     Serial.begin(SERIAL_BAUDRATE);
  50.     Serial.println();
  51.     Serial.println();
  52.     
  53.     //赤外線リモートのライブラリをスタート
  54.     irsend.begin();
  55.     
  56.     // Wifi
  57.     wifiSetup();
  58.     
  59.    
  60.     // By default, fauxmoESP creates it’s own webserver on the defined port
  61.     // The TCP port must be 80 for gen3 devices (default is 1901)
  62.     // This has to be done before the call to enable()
  63.     fauxmo.createServer(true); // not needed, this is the default value
  64.     fauxmo.setPort(80); // This is required for gen3 devices
  65.     // You have to call enable(true) once you have a WiFi connection
  66.     // You can enable or disable the library at any moment
  67.     // Disabling it will prevent the devices from being discovered and switched
  68.     fauxmo.enable(true);
  69.     // You can use different ways to invoke alexa to modify the devices state:
  70.     // “Alexa, turn yellow lamp on”
  71.     // “Alexa, turn on yellow lamp
  72.     // “Alexa, set yellow lamp to fifty” (50 means 50% of brightness, note, this example does not use this functionality)
  73.     // Add virtual devices
  74.     fauxmo.addDevice(ID_tv);
  75.     fauxmo.addDevice(ID_chA);
  76.     fauxmo.addDevice(ID_chB);
  77.     fauxmo.addDevice(ID_chC);
  78.     fauxmo.addDevice(ID_chD);
  79.     fauxmo.addDevice(ID_sound);
  80.     fauxmo.addDevice(ID_chchange);
  81.     
  82.     fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) {
  83.         
  84.         // Callback when a command from Alexa is received.
  85.         // You can use device_id or device_name to choose the element to perform an action onto (relay, LED,…)
  86.         // State is a boolean (ON/OFF) and value a number from 0 to 255 (if you say “set kitchen light to 50%” you will receive a 128 here).
  87.         // Just remember not to delay too much here, this is a callback, exit as soon as possible.
  88.         // If you have to do something more involved here set a flag and process it in your main loop.
  89.         
  90.         Serial.printf(“[MAIN] Device #%d (%s) state: %s value: %d\n”, device_id, device_name, state ? “ON” : “OFF”, value);
  91.         // Checking for device_id is simpler if you are certain about the order they are loaded and it does not change.
  92.         // Otherwise comparing the device_name is safer.
  93.      
  94.             //digitalWrite(LED_YELLOW, state ? HIGH : LOW);
  95.             if (strcmp(device_name, ID_tv)==0) {
  96.             //digitalWrite(LED_GREEN, state ? HIGH : LOW);
  97.             if(state==true){
  98.               //tvOn
  99.               irsend.sendNEC(0x002FD48B7,32);
  100.               }else{
  101.               //tvOff
  102.               irsend.sendNEC(0x002FD48B7,32);
  103.                 }
  104.            
  105.                 
  106.             
  107.         } else if (strcmp(device_name, ID_chA)==0) {
  108.             //digitalWrite(LED_PINK, state ? HIGH : LOW);
  109.             if(state==true){
  110.               //ch1
  111.               irsend.sendNEC(0x002FD807F,32);
  112.               }else{
  113.               //ch2
  114.               irsend.sendNEC(0x002FD40BF,32);
  115.                 }
  116.             
  117.         } else if (strcmp(device_name, ID_chB)==0) {
  118.             //digitalWrite(LED_WHITE, state ? HIGH : LOW);
  119.             if(state==true){
  120.               //ch3
  121.               irsend.sendNEC(0x002FD20DF,32);
  122.               }else{
  123.               //ch4
  124.               irsend.sendNEC(0x002FDA05F,32);
  125.                 }
  126.             
  127.         }else if (strcmp(device_name, ID_chC)==0) {
  128.             //digitalWrite(LED_WHITE, state ? HIGH : LOW);
  129.             if(state==true){
  130.               //ch5
  131.               irsend.sendNEC(0x002FD609F,32);
  132.               }else{
  133.               //ch6
  134.               irsend.sendNEC(0x002FD10EF,32);
  135.                 }
  136.             
  137.         }else if (strcmp(device_name, ID_chD)==0) {
  138.             //digitalWrite(LED_WHITE, state ? HIGH : LOW);
  139.             if(state==true){
  140.               //ch7
  141.               irsend.sendNEC(0x002FDD02F,32);
  142.               }else{
  143.               //ch8
  144.               irsend.sendNEC(0x002FDD02F,32);
  145.               }
  146.             
  147.         }else if (strcmp(device_name, ID_sound)==0) {
  148.             //digitalWrite(LED_WHITE, state ? HIGH : LOW);
  149.             if(state==true){
  150.               //sounUp
  151.               irsend.sendNEC(0x002FD58A7,32);
  152.               }else{
  153.               //soundDown
  154.               irsend.sendNEC(0x002FD7887,32);
  155.                 }
  156.             
  157.         }else if (strcmp(device_name, ID_chchange)==0) {
  158.             //digitalWrite(LED_WHITE, state ? HIGH : LOW);
  159.             if(state==true){
  160.               //chUP
  161.               //↓で赤外線出力
  162.               irsend.sendNEC(0x002FDD827,32);
  163.               }else{
  164.               //chDown
  165.               irsend.sendNEC(0x002FDF807,32);
  166.                 }
  167.             
  168.         }
  169.     });
  170. }
  171. void loop() {
  172.     // fauxmoESP uses an async TCP server but a sync UDP server
  173.     // Therefore, we have to manually poll for UDP packets
  174.     fauxmo.handle();
  175.     
  176.               
  177.     // This is a sample code to output free heap every 5 seconds
  178.     // This is a cheap way to detect memory leaks
  179.     static unsigned long last = millis();
  180.     if (millis() – last > 5000) {
  181.         last = millis();
  182.         Serial.printf(“[MAIN] Free heap: %d bytes\n”, ESP.getFreeHeap());
  183.     }
  184.     // If your device state is changed by any other means (MQTT, physical button,…)
  185.     // you can instruct the library to report the new state to Alexa on next request:
  186.     // fauxmo.setState(ID_YELLOW, true, 255);
  187. }

こんな簡単なプログラムでalexaを簡単音声操作できます。

これでESP8266がうまくwifiにつながれば同一ネットワークに繋がる携帯からalexaアプリを起動してデバイスの追加でプログラム上のデバイス名が検索されたら難関突破です

その後は定型アクションでどう動かしたいかを(どう話しかければどれがどう反応するか)決めて完了です。

一番参考になったのはここのサイトです。ただ、ここのサイトは第3世代alexaでは動かないWemoEmuratorを利用している点に注意です。

ぜひ試してみてください。

スポンサードリンク
カテゴリー: 制作事例 パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください