5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

M5Stick-C+IR UnitとEspalexaでエアコンの電源をON/OFFさせるAlexaデバイスを作る

Last updated at Posted at 2021-03-31

はじめに

エアコンに限らず、家電は電源を落とすときに音声で操作できると便利なんだよなといつも思っている。
テレビは実現できている。電気も実現できている。残りはエアコンだけ。でもスマートリモコンを買うほどではなかったので、家にあった M5Stick-C でリモコンを作成することにした。

やりたいこと

エアコンのON/OFFを音声で操作したい。
だけど電子工作とかは得意じゃないので、パーツを組み合わせてちょこっとプログラムを書く感じで、手軽にお安くリモコンを作りたい。

image.png

必要なモノ

    1. Amazon
    • Echoデバイス
    • Alexaアプリ
    1. M5Stack
    • M5Stick-C
    • IR Unit
    1. IDE
    • Arduino IDE
    • IRremoteESP8266ライブラリ
    • Espalexaライブラリ

使用したスケッチ例

No スケッチ例 用途 備考
1. IRremoteESP8266: IRrecvDumpV2 赤外線受信 一時的に使用するだけ
2. IRremoteESP8266: IRsendDemo 赤外線送信
3. Espalexa: EspalexaBasic Alexa連携

IRrecvDumpV2 は赤外線信号をゲットするためだけに使用する。IRrecvDumpV3でもできると思うけど、ずっとV2を使ってるので今回もそのままV2を使用した。

Alexaと連携するリモコンはIRsendDemoEspalexaBasicを組合せて作る。

IRremoteESP8266 とは

IRremoteESP8266は、IRremoteという赤外線のライブラリをESP8266またはESP32に特化させたもの。これを使うと簡単に赤外線信号を送受信することができる。

Espalexa とは

EspalexaはPhilips hueのエミュレーター。正確には、SSDPプロトコルとPhilips hue APIの一部をエミュレートしているとのこと。なので、Alexaで操作可能なデバイスとして検出ができて、そして制御ができる。

Alexaから見たらM5Stick-CではなくPhilips hueに見えるということ。こんな感じで、セットアップするデバイスを選択 で 右上のPhilips Hueのアイコンをクリックしていくと、エアコンのリモコンがライトとして検出される。

アレクサアプリでデバイスを検索する Philips hueのデバイスを検索する エアコンがライトとして検出される

ライトのON/OFFと、エアコンの電源ON/OFFをマッピングさせることでエアコンを制御する仕組み。

作成の流れ

    1. エアコンの赤外線信号を取得する
    1. スケッチの骨格を作成する
    • Espalexa: EspalexaBasic を開く
    • Wi-Fiの設定
    • コールバック関数の作成
    1. スケッチに赤外線送信部分を追加する
    • 赤外線送信部分の追加
    1. Alexaに認識させる
    • アレクサアプリでデバイスとして認識させる
    1. 定型アクションを作成する
    • 電源ON
    • 電源OFF

1. エアコンの赤外線信号を取得する

エアコンの赤外線信号を取得する。
まずは スケッチ例 から IRrecvDumpV2を開く。

image.png

以下の2ヵ所を変更して書き込めば IR Unit で赤外線が受信できるようになる。

No 変更前 変更後
1. #include <Arduino.h> #include <M5StickC.h>
2. const uint16_t kRecvPin = 14; const uint16_t kRecvPin = 33;

書き込めたら IR Unit に向かってリモコンのボタンをポチポチ押すと、シリアルモニタに以下のような情報が表示れさる。

14:20:10.550 -> IRrecvDump is now running and waiting for IR input on Pin 33
14:20:25.463 -> if in 
14:20:25.463 -> 
14:20:25.463 -> Timestamp : 000201.408
14:20:25.463 -> Library   : v2.7.11
14:20:25.463 -> 
14:20:25.463 -> Protocol  : FUJITSU_AC
14:20:25.463 -> Code      : 0x1463001010FE0930C101A414002038FE (128 Bits)
14:20:25.463 -> Mesg Desc.: Model: 5 (ARRY4), Power: On, Mode: 1 (Cool), Temp: 28C, Fan: 4 (Quiet), Clean: Off, Filter: On, Swing: 2 (Swing(H)), Command: N/A
14:20:25.463 -> uint16_t rawData[259] = {3304, 1584,  466, 358,  440, 378,  464, 1166,  442, 378,  442, 1194,  442, 376,  440, 378,  442, 376,  442, 1190,  440, 1192,  444, 388,  468, 350,  442, 378,  468, 1168,  466, 1172,  442, 380,  440, 388,  440, 380,  464, 356,  442, 380,  466, 356,  442, 380,  440, 378,  442, 374,  442, 376,  440, 376,  442, 382,  466, 352,  442, 1192,  442, 376,  440, 382,  440, 380,  442, 380,  440, 380,  442, 378,  440, 382,  440, 1194,  442, 376,  442, 376,  440, 380,  440, 380,  440, 1220,  440, 1194,  466, 1168,  442, 1190,  464, 1168,  466, 1172,  440, 1198,  442, 1188,  442, 380,  440, 380,  442, 1190,  442, 380,  440, 378,  442, 380,  442, 380,  466, 350,  442, 382,  470, 376,  440, 380,  438, 1192,  440, 1194,  442, 378,  440, 386,  464, 1168,  442, 382,  440, 380,  440, 382,  442, 384,  436, 378,  440, 1192,  440, 1192,  440, 1198,  440, 382,  442, 378,  440, 382,  440, 382,  440, 384,  440, 378,  438, 378,  440, 380,  440, 380,  440, 1192,  442, 376,  440, 380,  440, 1190,  440, 378,  468, 1200,  440, 380,  440, 378,  442, 1194,  464, 354,  464, 1168,  440, 382,  438, 382,  440, 380,  440, 384,  464, 354,  440, 378,  440, 382,  442, 378,  440, 378,  440, 382,  440, 378,  464, 354,  440, 380,  440, 378,  440, 378,  460, 380,  440, 1200,  440, 380,  440, 380,  438, 380,  464, 356,  440, 384,  442, 1192,  442, 1192,  440, 1198,  440, 380,  440, 380,  440, 382,  440, 1194,  440, 1192,  442, 1192,  440, 1196,  440, 1196,  440, 1192,  440, 1192,  440};  // FUJITSU_AC
14:20:25.603 -> uint8_t state[16] = {0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30, 0xC1, 0x01, 0xA4, 0x14, 0x00, 0x20, 0x38, 0xFE};
14:20:25.603 -> 
14:20:25.603 -> 
14:20:27.191 -> if in 
14:20:27.191 -> 
14:20:27.191 -> Timestamp : 000203.157
14:20:27.191 -> Library   : v2.7.11
14:20:27.191 -> 
14:20:27.191 -> Protocol  : FUJITSU_AC
14:20:27.191 -> Code      : 0x1463001010FE0930C104A414002038FB (128 Bits)
14:20:27.239 -> Mesg Desc.: Model: 5 (ARRY4), Power: On, Mode: 4 (Heat), Temp: 28C, Fan: 4 (Quiet), Clean: Off, Filter: On, Swing: 2 (Swing(H)), Command: N/A
14:20:27.239 -> uint16_t rawData[259] = {3326, 1562,  440, 380,  440, 376,  440, 1196,  442, 382,  440, 1192,  440, 378,  440, 380,  440, 382,  438, 1194,  440, 1194,  440, 386,  438, 378,  464, 356,  438, 1192,  440, 1196,  440, 382,  440, 380,  440, 380,  442, 380,  440, 382,  442, 382,  440, 378,  440, 378,  440, 376,  442, 376,  440, 378,  438, 380,  440, 378,  440, 1196,  464, 354,  440, 382,  440, 380,  440, 378,  440, 380,  440, 378,  440, 376,  440, 1190,  442, 376,  464, 354,  440, 376,  440, 386,  440, 1208,  442, 1190,  440, 1192,  442, 1192,  442, 1192,  440, 1194,  440, 1194,  440, 1192,  464, 356,  440, 378,  440, 1196,  440, 380,  438, 380,  440, 382,  440, 384,  440, 382,  442, 378,  492, 352,  440, 376,  466, 1168,  440, 1196,  440, 378,  462, 356,  440, 1192,  442, 384,  438, 382,  440, 384,  438, 382,  440, 380,  438, 1192,  440, 1194,  440, 384,  438, 382,  440, 1196,  440, 380,  466, 352,  440, 382,  442, 378,  440, 376,  440, 376,  442, 378,  440, 1194,  440, 380,  440, 386,  440, 1196,  464, 358,  490, 1180,  440, 380,  440, 380,  438, 1194,  440, 378,  464, 1170,  440, 382,  440, 384,  440, 382,  440, 376,  466, 356,  464, 356,  440, 382,  440, 380,  438, 380,  438, 378,  438, 378,  440, 382,  438, 382,  440, 384,  440, 384,  440, 380,  440, 1196,  440, 380,  440, 376,  442, 378,  438, 378,  440, 378,  438, 1198,  440, 1196,  440, 1194,  440, 378,  440, 386,  440, 1194,  440, 1194,  440, 384,  440, 1198,  440, 1194,  442, 1192,  440, 1194,  440, 1194,  464};  // FUJITSU_AC
14:20:27.333 -> uint8_t state[16] = {0x14, 0x63, 0x00, 0x10, 0x10, 0xFE, 0x09, 0x30, 0xC1, 0x04, 0xA4, 0x14, 0x00, 0x20, 0x38, 0xFB};

上段が冷房 ボタンを押した時の情報で、下段が停止ボタンを押した時の情報。
uint16_t rawData の部分を使用する。抜き出したのが以下。この2行を使用する。

// 電源ON
uint16_t rawData[259] = {3304, 1584,  466, 358,  440, 378,  464, 1166,  442, 378,  442, 1194,  442, 376,  440, 378,  442, 376,  442, 1190,  440, 1192,  444, 388,  468, 350,  442, 378,  468, 1168,  466, 1172,  442, 380,  440, 388,  440, 380,  464, 356,  442, 380,  466, 356,  442, 380,  440, 378,  442, 374,  442, 376,  440, 376,  442, 382,  466, 352,  442, 1192,  442, 376,  440, 382,  440, 380,  442, 380,  440, 380,  442, 378,  440, 382,  440, 1194,  442, 376,  442, 376,  440, 380,  440, 380,  440, 1220,  440, 1194,  466, 1168,  442, 1190,  464, 1168,  466, 1172,  440, 1198,  442, 1188,  442, 380,  440, 380,  442, 1190,  442, 380,  440, 378,  442, 380,  442, 380,  466, 350,  442, 382,  470, 376,  440, 380,  438, 1192,  440, 1194,  442, 378,  440, 386,  464, 1168,  442, 382,  440, 380,  440, 382,  442, 384,  436, 378,  440, 1192,  440, 1192,  440, 1198,  440, 382,  442, 378,  440, 382,  440, 382,  440, 384,  440, 378,  438, 378,  440, 380,  440, 380,  440, 1192,  442, 376,  440, 380,  440, 1190,  440, 378,  468, 1200,  440, 380,  440, 378,  442, 1194,  464, 354,  464, 1168,  440, 382,  438, 382,  440, 380,  440, 384,  464, 354,  440, 378,  440, 382,  442, 378,  440, 378,  440, 382,  440, 378,  464, 354,  440, 380,  440, 378,  440, 378,  460, 380,  440, 1200,  440, 380,  440, 380,  438, 380,  464, 356,  440, 384,  442, 1192,  442, 1192,  440, 1198,  440, 380,  440, 380,  440, 382,  440, 1194,  440, 1192,  442, 1192,  440, 1196,  440, 1196,  440, 1192,  440, 1192,  440};  // FUJITSU_AC

// 電源OFF
uint16_t rawData[259] = {3326, 1562,  440, 380,  440, 376,  440, 1196,  442, 382,  440, 1192,  440, 378,  440, 380,  440, 382,  438, 1194,  440, 1194,  440, 386,  438, 378,  464, 356,  438, 1192,  440, 1196,  440, 382,  440, 380,  440, 380,  442, 380,  440, 382,  442, 382,  440, 378,  440, 378,  440, 376,  442, 376,  440, 378,  438, 380,  440, 378,  440, 1196,  464, 354,  440, 382,  440, 380,  440, 378,  440, 380,  440, 378,  440, 376,  440, 1190,  442, 376,  464, 354,  440, 376,  440, 386,  440, 1208,  442, 1190,  440, 1192,  442, 1192,  442, 1192,  440, 1194,  440, 1194,  440, 1192,  464, 356,  440, 378,  440, 1196,  440, 380,  438, 380,  440, 382,  440, 384,  440, 382,  442, 378,  492, 352,  440, 376,  466, 1168,  440, 1196,  440, 378,  462, 356,  440, 1192,  442, 384,  438, 382,  440, 384,  438, 382,  440, 380,  438, 1192,  440, 1194,  440, 384,  438, 382,  440, 1196,  440, 380,  466, 352,  440, 382,  442, 378,  440, 376,  440, 376,  442, 378,  440, 1194,  440, 380,  440, 386,  440, 1196,  464, 358,  490, 1180,  440, 380,  440, 380,  438, 1194,  440, 378,  464, 1170,  440, 382,  440, 384,  440, 382,  440, 376,  466, 356,  464, 356,  440, 382,  440, 380,  438, 380,  438, 378,  438, 378,  440, 382,  438, 382,  440, 384,  440, 384,  440, 380,  440, 1196,  440, 380,  440, 376,  442, 378,  438, 378,  440, 378,  438, 1198,  440, 1196,  440, 1194,  440, 378,  440, 386,  440, 1194,  440, 1194,  440, 384,  440, 1198,  440, 1194,  442, 1192,  440, 1194,  440, 1194,  464};  // FUJITSU_AC

2. スケッチの骨格を作成する

EspalexaBasic をベースにして修正していく。

Espalexa: EspalexaBasic を開く

スケッチ例 から EspalexaBasic を開く。開いたら名前をつけて保存するで別ファイルとして保存しておく。

image.png

上記のスケッチ例に表示されない場合はライブラリマネージャEspalexaをインストールする。

image.png

Wi-Fiの設定

ssid と password に 自身のSSIDとパスワードを設定する。

// Change this!!
const char* ssid = "...";
const char* password = "wifipassword";

コールバック関数の作成

今回は以下の設定で作成する。

No 項目 設定値 備考
1. 関数名 airconPowerOnOff
2. デバイス表示名 FUJITSU AC うちのエアコンが富士通製なので
3. デバイスタイプ EspalexaDeviceType::onoff

サンプルスケッチには予め firstLightChanged secondLightChanged thirdLightChanged の3つのコールバック関数が記載されているが、この3つは削除して airconPowerOnOff 関数を記述していく。基本的には以下の3カ所を変更していく。

関数を定義する。

// Callback Functions
void airconPowerOnOff(EspalexaDevice* dev);

関数を登録する。今回は電源のオン/オフがやりたいのでEspalexaDeviceType::onoffを設定した。Espalexaがサポートしているデバイスタイプは、Espalexa(GitHub)を参照。

// Define your devices here. 
espalexa.addDevice("FUJITSU AC", airconPowerOnOff, EspalexaDeviceType::onoff);

関数の本体を作成する。

// our callback functions
void airconPowerOnOff(EspalexaDevice *d) {
    if (d == nullptr) return;
    Serial.println(d->getValue());
    if (d->getValue()) {
        Serial.println("Power On");
    } else {
        Serial.println("Power Off");
    }
}

ちなみに、d->getValue()で取得できる値の意味は以下だけど、今回は、電源ON/OFFしかしないので 2550 のどちらかになる。

No 状態
1. 0 OFF
2. 1 - 254 Dimmed
3. 255 ON

3. スケッチに赤外線送信部分を追加する

スケッチ例 から IRsendDemo を開き、これを参考にして必要な部分を追加していく。

image.png

赤外線送信部分の追加

今回は、M5Stick-C の内臓IRではなく、IR Unit のIRを使用するため以下のようにpin番号を変更する。
M5Stick-C 以外のものを使用する場合は、pin番号が32とは限らないので注意。

const uint16_t kIrLed = 32;
IRsend irsend(kIrLed);
uint16_t rawData_on[259]  = {3336, 1556,  470, 354,  470, 376,  448, 1188,  448, 370,  448, 1184,  448, 348,  466, 374,  446, 348,  470, 1160,  472, 1162,  470, 388,  446, 352,  470, 372,  448, 1162,  468, 1166,  472, 372,  448, 346,  470, 372,  448, 372,  448, 348,  446, 400,  448, 372,  444, 374,  448, 346,  470, 370,  448, 346,  472, 354,  472, 350,  472, 1184,  448, 348,  472, 346,  472, 374,  450, 346,  472, 372,  448, 370,  448, 374,  448, 1186,  448, 346,  474, 350,  472, 348,  470, 348,  472, 1220,  446, 1164,  474, 1162,  472, 1162,  474, 1158,  472, 1162,  474, 1158,  472, 1164,  474, 348,  470, 350,  472, 1162,  472, 374,  448, 344,  474, 368,  450, 368,  450, 370,  450, 350,  500, 350,  474, 346,  474, 1158,  474, 1160,  474, 344,  474, 344,  472, 1160,  474, 348,  474, 348,  476, 350,  474, 350,  474, 348,  476, 1158,  474, 1158,  472, 1160,  474, 350,  474, 344,  472, 354,  472, 342,  476, 342,  474, 348,  474, 368,  450, 342,  476, 344,  474, 1156,  476, 348,  474, 346,  474, 1160,  476, 346,  502, 1166,  476, 346,  474, 1158,  474, 1162,  474, 342,  474, 1160,  474, 344,  474, 348,  502, 350,  474, 346,  474, 346,  476, 344,  476, 346,  476, 344,  476, 350,  474, 346,  474, 344,  474, 372,  450, 344,  476, 346,  474, 1162,  474, 1160,  474, 344,  476, 346,  476, 344,  476, 344,  474, 346,  474, 348,  474, 1162,  472, 1160,  474, 1162,  474, 350,  476, 348,  474, 352,  474, 348,  474, 1158,  474, 346,  474, 348,  474, 346,  476, 346,  474, 346,  474};  // FUJITSU_AC
uint16_t rawData_off[115] = {3264, 1624,  438, 380,  404, 422,  404, 1230,  434, 382,  428, 1206,  404, 418,  404, 422,  402, 420,  402, 1230,  404, 1230,  404, 418,  402, 416,  402, 416,  404, 1228,  406, 1230,  428, 396,  404, 416,  402, 416,  404, 422,  402, 418,  404, 416,  402, 418,  402, 418,  402, 416,  402, 420,  402, 414,  404, 414,  402, 414,  404, 1230,  404, 418,  404, 418,  428, 426,  402, 420,  402, 414,  404, 416,  402, 416,  434, 1196,  402, 418,  434, 384,  402, 418,  426, 392,  402, 1228,  404, 414,  402, 418,  404, 418,  402, 416,  402, 418,  402, 418,  402, 1230,  402, 420,  434, 1196,  404, 1230,  404, 1228,  404, 1230,  404, 1230,  436, 1198,  404};  // FUJITSU_AC

作成済みの関数 void airconPowerOnOff(EspalexaDevice *d) に赤外線送信部分を追加する。

    // 電源ON
    irsend.sendRaw(rawData_on, 259, 38);
    // 電源OFF
    irsend.sendRaw(rawData_off, 115, 38);

※ソースコードは下記に掲載。

4. Alexaに認識させる

作成したデバイス FUJITSU AC を Alexaに認識させる。

アレクサアプリでデバイスとして認識させる

デバイスの追加 その他 デバイスの検出

デバイス検出中 検出・接続済み

5. 定型アクションを作成する

電源ONと電源OFFの2つの定型アクションを作成する。

電源ON

項目 設定値 備考
定型アクション名 富士通エアコン電源オン ※任意
実行条件 Alexaのおしゃべり
└アレクサ、エアコンをつけて
※任意
アクション スマートホーム
└照明
 └FUJITSU AC
  └電源
   └オン

定型アクション設定 定型アクション 電源オン

電源OFF

項目 設定値 備考
定型アクション名 富士通エアコン電源オフ ※任意
実行条件 Alexaのおしゃべり
└アレクサ、エアコンを消して
※任意
アクション スマートホーム
└照明
 └FUJITSU AC
  └電源
   └オフ

定型アクション設定 定型アクション 電源オン

完成。

完成

動作確認

動作確認

本体が赤く点滅するのは、ただの飾り。
動いてる感を出したかっただけ。

ソースコード

動いているのでいいんじゃないかと思ってる。

#include <Arduino.h>
#include <M5StickC.h>

// IR Remote
#include <IRremoteESP8266.h>
#include <IRsend.h>

// Espalexa
#ifdef ARDUINO_ARCH_ESP32
#include <WiFi.h>
#else
#include <ESP8266WiFi.h>
#endif
#include <Espalexa.h>

// Wi-Fi Configuration
boolean connectWifi();
boolean wifiConnected = false;
const char* ssid = "...";
const char* password = "wifipassword";

// Callback Functions
void airconPowerOnOff(EspalexaDevice* dev);

// IR  ( M5Stick-C 9 pin / Serial 32 pin )
const uint16_t IR_LED_PIN = 32;
IRsend irsend(IR_LED_PIN);

// LED ( M5Stick-C 10 pin )
const uint16_t LED_PIN = 10;

// Air conditioner power on
uint16_t rawData_on[259]  = {3336, 1556,  470, 354,  470, 376,  448, 1188,  448, 370,  448, 1184,  448, 348,  466, 374,  446, 348,  470, 1160,  472, 1162,  470, 388,  446, 352,  470, 372,  448, 1162,  468, 1166,  472, 372,  448, 346,  470, 372,  448, 372,  448, 348,  446, 400,  448, 372,  444, 374,  448, 346,  470, 370,  448, 346,  472, 354,  472, 350,  472, 1184,  448, 348,  472, 346,  472, 374,  450, 346,  472, 372,  448, 370,  448, 374,  448, 1186,  448, 346,  474, 350,  472, 348,  470, 348,  472, 1220,  446, 1164,  474, 1162,  472, 1162,  474, 1158,  472, 1162,  474, 1158,  472, 1164,  474, 348,  470, 350,  472, 1162,  472, 374,  448, 344,  474, 368,  450, 368,  450, 370,  450, 350,  500, 350,  474, 346,  474, 1158,  474, 1160,  474, 344,  474, 344,  472, 1160,  474, 348,  474, 348,  476, 350,  474, 350,  474, 348,  476, 1158,  474, 1158,  472, 1160,  474, 350,  474, 344,  472, 354,  472, 342,  476, 342,  474, 348,  474, 368,  450, 342,  476, 344,  474, 1156,  476, 348,  474, 346,  474, 1160,  476, 346,  502, 1166,  476, 346,  474, 1158,  474, 1162,  474, 342,  474, 1160,  474, 344,  474, 348,  502, 350,  474, 346,  474, 346,  476, 344,  476, 346,  476, 344,  476, 350,  474, 346,  474, 344,  474, 372,  450, 344,  476, 346,  474, 1162,  474, 1160,  474, 344,  476, 346,  476, 344,  476, 344,  474, 346,  474, 348,  474, 1162,  472, 1160,  474, 1162,  474, 350,  476, 348,  474, 352,  474, 348,  474, 1158,  474, 346,  474, 348,  474, 346,  476, 346,  474, 346,  474};  // FUJITSU_AC
// Air conditioner power off 
uint16_t rawData_off[115] = {3264, 1624,  438, 380,  404, 422,  404, 1230,  434, 382,  428, 1206,  404, 418,  404, 422,  402, 420,  402, 1230,  404, 1230,  404, 418,  402, 416,  402, 416,  404, 1228,  406, 1230,  428, 396,  404, 416,  402, 416,  404, 422,  402, 418,  404, 416,  402, 418,  402, 418,  402, 416,  402, 420,  402, 414,  404, 414,  402, 414,  404, 1230,  404, 418,  404, 418,  428, 426,  402, 420,  402, 414,  404, 416,  402, 416,  434, 1196,  402, 418,  434, 384,  402, 418,  426, 392,  402, 1228,  404, 414,  402, 418,  404, 418,  402, 416,  402, 418,  402, 418,  402, 1230,  402, 420,  434, 1196,  404, 1230,  404, 1228,  404, 1230,  404, 1230,  436, 1198,  404};  // FUJITSU_AC

Espalexa espalexa;

// ----------------------------------------------------------------------------
void setup() {
  irsend.begin();
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  // Initialise wifi connection ★サンプルのロジックをちっとだけ変えた。
  while (!wifiConnected) {
      wifiConnected = connectWifi();
      if(wifiConnected){
          Serial.println("Successful connection!");
          // Define the required devices. 
          espalexa.addDevice("FUJITSU AC", airconPowerOnOff, EspalexaDeviceType::onoff); 
          espalexa.begin();
      } else {
          Serial.println("Cannot connect to WiFi. Please check data and reset the ESP.");
          delay(2500);
      }
  }
}

void loop() {
   espalexa.loop();
   delay(1);
}

// Function to turn on / off the power of the air conditioner
void airconPowerOnOff(EspalexaDevice *d) {
    if (d == nullptr) return;
    Serial.println(d->getValue());
    if (d->getValue()) {
        Serial.println("Power On");
        irsend.sendRaw(rawData_on, 259, 38);
        blinkBuiltinLED();
    } else {
        Serial.println("Power Off");
        irsend.sendRaw(rawData_off, 115, 38);
        blinkBuiltinLED();
    }
}

// Blink the built-in LED
void blinkBuiltinLED() {
    digitalWrite(LED_PIN, LOW);
    delay(500);
    digitalWrite(LED_PIN, HIGH);
}

// connect to wifi – returns true if successful or false if not
boolean connectWifi(){
  boolean state = true;
  int i = 0;
  
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");
  Serial.println("Connecting to WiFi");

  // Wait for connection
  Serial.print("Connecting...");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    if (i > 20){
      state = false; break;
    }
    i++;
  }
  Serial.println("");
  if (state){
    Serial.print("Connected to ");
    Serial.println(ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  } else {
    Serial.println("Connection failed.");
  }
  return state;
}

おわりに

実はこれを完成させるまでに半年ぐらいかかっている。何度やっても赤外線が反応してくれなくて諦めていた時期もあったんだけど、オチは IR Unit が故障していただけだったという...

IR Unit 新しく買ってきて、もう一度やりなおしたらめちゃくちゃ簡単にできた。
電源ON/OFFぐらいで良いのであればこれで十分だと思う。夏前に完成させることができてよかった。

参考

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?