Table of Contents
IoTにおける"制御"は難しい
例えば、弊社オフィスのエアコンをIoT化したいとします。
温度が高いときは自動的にエアコンをOFFに、低いときは自動的にエアコンをONにする簡単なシステムです。この場合、温度は温度センサーを使うことで計測ができます。
一方、エアコンのON/OFFはどのように実現できるでしょうか?ちなみに、弊社のエアコンはこのようなコントローラからしか制御できません。赤外線リモコンもありません。
SwitchBotで「スイッチを押す」を実現する
そんな時に役立つのがSwitchBotです。この製品は粘着テープでスイッチに設置して使います。
スマホアプリからスイッチを押すと...
このようにスイッチを押してくれます。
AlexaやIFTTTとも連携可能なので、これだけで簡単なIoTシステムを実現できます。
SwitchBotをM5Stackで制御する
SwitchBotをオフィスのあらゆるスイッチに設置する場合、1台1台スマホアプリと連携するのは手間です。また、連携できるサービスも限られるので、少々不便です。
そこで、M5Stackを使ってスマホアプリを使わずにSwitchBotを制御してみることにしました。
SwitchBotはBLEで制御できる
SwitchBotとスマホアプリはBLEで通信しています。GithubにPythonのライブラリが公開されているので、これを読んで通信部分の仕様を理解します。
SwitchBotがBLEのAdvertiseをしているのでそれをスキャンして、 CBA20002-224D-11E6-9FB8-0002A5D5C51B
というCharacteristicに 570100
というコマンドを書き込むことで制御できるようです。
最終的にM5Stackのプログラムは以下となりました。
#include "BLEDevice.h"
#include "Free_Fonts.h"
#include <M5Stack.h>
static BLEUUID serviceUUID("CBA20D00-224D-11E6-9FB8-0002A5D5C51B");
static BLEUUID characteristicUUID("CBA20002-224D-11E6-9FB8-0002A5D5C51B");
static BLEAdvertisedDevice* myDevice;
static uint8_t cmdPress[3] = {0x57, 0x01, 0x00};
void pressSwitchBot() {
BLEClient* pClient = BLEDevice::createClient();
M5.Lcd.fillScreen(TFT_RED);
M5.Lcd.setTextColor(TFT_WHITE, TFT_RED);
M5.Lcd.drawString("Connecting...", 160, 120, GFXFF);
pClient->connect(myDevice);
BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr) {
pClient->disconnect();
return;
}
BLERemoteCharacteristic* pCharacteristic = pRemoteService->getCharacteristic(characteristicUUID);
if (pCharacteristic == nullptr) {
pClient->disconnect();
return;
}
pCharacteristic->writeValue(cmdPress, sizeof(cmdPress), false);
pClient->disconnect();
M5.Lcd.fillScreen(TFT_BLUE);
M5.Lcd.setTextColor(TFT_WHITE, TFT_BLUE);
M5.Lcd.drawString("Pressed.", 160, 120, GFXFF);
delay(2000);
M5.Lcd.fillScreen(TFT_GREEN);
M5.Lcd.setTextColor(TFT_WHITE, TFT_GREEN);
M5.Lcd.drawString("Push button.", 160, 120, GFXFF);
}
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {
BLEDevice::getScan()->stop();
myDevice = new BLEAdvertisedDevice(advertisedDevice);
}
}
};
void setup() {
M5.begin();
M5.Power.begin();
M5.Lcd.setTextDatum(MC_DATUM);
M5.Lcd.setFreeFont(FF44);
M5.Lcd.fillScreen(TFT_RED);
M5.Lcd.setTextColor(TFT_WHITE, TFT_RED);
M5.Lcd.drawString("Searching...", 160, 120, GFXFF);
BLEDevice::init("");
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setInterval(1349);
pBLEScan->setWindow(449);
pBLEScan->setActiveScan(true);
pBLEScan->start(5, false);
M5.Lcd.fillScreen(TFT_GREEN);
M5.Lcd.setTextColor(TFT_WHITE, TFT_GREEN);
M5.Lcd.drawString("Push button.", 160, 120, GFXFF);
}
void loop() {
if (myDevice == NULL) {
return;
}
M5.update();
if (M5.BtnA.wasReleased()) {
pressSwitchBot();
}
}
SwitchBotをM5Stackから制御
M5StackのAボタン(一番左のボタン)を押してみます。
SwitchBotが動きました!!!
まとめ
M5StackからSwitchBotを制御できたことで、IoTシステムにレトロフィットな制御を簡単に組み込めます。例えばこんな活用方法が想定されます。
- Alexaと連携してオフィスの照明や空調を一斉にON/OFFしたい
- 会議室に人が入退出したタイミングで、照明をON/OFFしたい
- Webアプリやモバイルアプリでスイッチ付きのデバイスをON/OFFしたい
みなさんもぜひお試しください。