https://qiita.com/ABK28/items/0681be13afca40687dff
で作った、お風呂スイッチですが、fauxmoESPがalexaで応答しなくなりました。
とても困って、espalexaに置き換えてみたり、いろいろやってみたんですが、直りません。
そこで、思い切って、ラズパイを購入し、Node-REDを使って、Node-REDスキル経由でAlexaに接続することにしました。
ラズパイの構築
前記事のこれ↓です。
https://qiita.com/ABK28/items/d4d4b766fef03d50027b
Node-REDのインストール
VNCでつないだラズパイの画面でNode-REDをインストールしました。
[ラズベリーメニュー]->[設定]->[Recommended Software]
[Programming]の中の[Node-RED]にチェックしてインストールしました。
ちょっと時間かかります。
[ラズベリーメニュー]->[プログラミング]->[Node-RED]で、起動します。
下記コマンドで、自動実行するようにしておきます。
$ sudo su
# systemctl enable nodered.service
これで、Node-REDが使える状態になりました。
ラズパイは、mDNS化していますので、パソコンのブラウザから下記で、接続できます。
http://raspberrypi.local:1880/
Node-RED Alexa Home Skill Bridge に登録
下記にアクセスして、デバイスを作ります。
https://alexa-node-red.bm.hardill.me.uk/
ログインしたら、
[Devices]タブを押して、デバイスを登録します。
これだけでOK。
Alexaスキル「Node-RED」の登録
スマホのAlexaアプリのスキルメニューで、「Node-RED」を登録します。
「有効」にすると、ログイン画面が出ますので、「Node-RED Alexa Home Skill Bridge」で登録したアカウントでログインします。
デバイスの検索で、「お風呂」をみつけます。
あ、さきに、前に登録した動かないデバイスは消しておきます。
これだけでOK。
Node-REDのフローの作成
先ず、Alexaのノードを使えるようにします。
右上のメニューから「パレットの管理」を選びます。
「alexa」とかいれて検索し、「node-red-contrib-alexa-home-skill」を追加します。
一番左のノードは、上記でAlexaを追加したことにより、選択できるノードです。
ダブルクリックすると編集画面になるので、
「アカウント」に「Node-RED Alexa Home Skill Bridge」で登録したアカウントを設定します。
名前は、「お風呂」にしました。
ESP8266で作っていたお風呂スイッチのスケッチでは、WEB画面で操作できるようになっていましたので、これをHTTPリクエストで呼ぶことでスイッチのON/OFFをします。
そのURLをここに書き込みます。
できたら「デプロイ」します。
Node-REDのフローは、これだけで完成です。
びっくりするくらい簡単です。
使ってみる。
「アレクサ! お風呂をつけて!」
動いたー。
おまけでスケッチのシンプル化
使わなくなった、fauxmoESPのコードを削除して、改めてESP8266に書き込んでおきました。
# include <ESP8266WiFi.h>
# include <ESP8266WebServer.h>
# include <Servo.h>
# include <ESP8266HTTPClient.h>
# include <DNSServer.h>
# include <WiFiManager.h>
# include <ESP8266mDNS.h>
# include <WiFiClient.h>
# define SERIAL_SPEED 115200
// mDNS
static const char* mdns_name = "ofro-sw";
// Servo
Servo servo;
const int servoIni = 90;
const int servoOn = 120;
int flag = 0;
int deg;
// Pin No
const int ServoPin = 12;
const int GreenLEDPin = 13;
const int BlueLEDPin = 15;
// Web page (Port 8080)
ESP8266WebServer server(8080);
static const char* cpResponse200 = "<HTML>"
"<BODY style='background-color:#ffffde;font-family:sans-serif;font-size:40px;'>"
"OFRO-SW WEB<br/><br/>"
"<a href=/cmd?POS=zero>Zero Position</a><br/>"
"<a href=/cmd?POS=push>Push!</a><br/>"
"<a href=/cmd?POS=PLUS10>PLUS 10</a><br/>"
"<a href=/cmd?POS=MINUS10>MINUS 10</a><br/>"
"<br/>"
"<a href=/cmd?POS=reset>Reset WiFi Setting.</a><br/>"
"</BODY></HTML>\r\n";
void setup() {
Serial.begin(SERIAL_SPEED);
Serial.println("");
// LED
pinMode(GreenLEDPin, OUTPUT);
pinMode(BlueLEDPin, OUTPUT);
digitalWrite(GreenLEDPin, LOW);
digitalWrite(BlueLEDPin, LOW);
// WiFi
//WiFiManager
WiFiManager wifiManager;
digitalWrite(BlueLEDPin, HIGH);
wifiManager.setBreakAfterConfig(true);
if (!wifiManager.autoConnect("Auto Connect AP", "password")) {
Serial.println("failed to connect, we should reset as see if it connects");
delay(3000);
digitalWrite(BlueLEDPin, LOW);
ESP.reset();
delay(5000);
}
digitalWrite(BlueLEDPin, LOW);
Serial.println("");
Serial.println("WiFi Connected.");
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Serial.println("");
Serial.println("");
digitalWrite(GreenLEDPin, HIGH);
// Set up mDNS responder:
if (!MDNS.begin(mdns_name)) {
Serial.println("Error setting up MDNS responder!");
while (1) {
delay(1000);
}
}
Serial.println("mDNS responder started");
Serial.println("");
// WebServer
server.on("/cmd", WebCommand);
server.begin();
Serial.println("Web Server started");
Serial.println("0:deg=" +String(deg) );
deg=servoIni; //スタート位置
servo.write(deg);
Serial.println("1:deg=" +String(deg) );
// Add service to MDNS-SD
MDNS.addService("http", "tcp", 8080);
}
void WebCommand() {
String cmd = server.arg("POS");
if (cmd == "zero") { deg=0; servomove(deg); }
else if (cmd == "push") livingOn();
else if (cmd == "PLUS10") { if ((deg+=10)>180) deg=180; servomove(deg);}
else if (cmd == "MINUS10") { if ((deg-=10)<0) deg=0; servomove(deg);}
else if (cmd == "reset") {
WiFiManager wifiManager;
digitalWrite(GreenLEDPin, LOW);
digitalWrite(BlueLEDPin, LOW);
delay(1000);
Serial.println("");
Serial.println("WiFi Reset !");
Serial.println("");
for(int i=0;i<3;i++) {
digitalWrite(BlueLEDPin, HIGH);
delay(250);
digitalWrite(BlueLEDPin, LOW);
delay(250);
}
wifiManager.resetSettings();
delay(3000);
digitalWrite(BlueLEDPin, HIGH);
delay(250);
digitalWrite(BlueLEDPin, LOW);
ESP.reset();
}
Serial.print("deg=" +String(deg) );
Serial.println(" cmd=" + cmd);
server.send(200, "text/html", cpResponse200);
}
void loop() {
MDNS.update();
server.handleClient();
delay(1);
}
void livingOn() {
digitalWrite(BlueLEDPin, HIGH);
servo.attach(ServoPin);
delay(300);
servo.write(servoOn);
delay(500);
servo.write(servoIni);
delay(300);
servo.detach();
digitalWrite(BlueLEDPin, LOW);
Serial.println("Switch turn on ...");
}
void livingOff() {
digitalWrite(BlueLEDPin, HIGH);
servo.attach(ServoPin);
delay(300);
servo.write(servoOn);
delay(500);
servo.write(servoIni);
delay(300);
servo.detach();
digitalWrite(BlueLEDPin, LOW);
Serial.println("Switch turn off ...");
}
void servomove(int d) {
digitalWrite(BlueLEDPin, HIGH);
servo.attach(ServoPin);
servo.write(d);
delay(100);
servo.detach();
digitalWrite(BlueLEDPin, LOW);
}
String ipToString(uint32_t ip){
String result = "";
result += String((ip & 0xFF), 10);
result += ".";
result += String((ip & 0xFF00) >> 8, 10);
result += ".";
result += String((ip & 0xFF0000) >> 16, 10);
result += ".";
result += String((ip & 0xFF000000) >> 24, 10);
return result;
}
おしまい。
めでたしめでたし。