LINE bot で外出先から家電操作　　中編

前回の続きです。
https://qiita.com/llight/items/35c762179826c31b827f

今回は
⑶ 物理スイッチを作成して鍵の施錠を行う
です。


# TL;DR
私の場合は賃貸なので施錠する必要がある場所は2つ。
(A)建物
　こちらは部屋番号を受付で押して、家にある施錠ボタンをラズパイにつなげたモーターで施錠します。
![IMG_9718 3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264607/1c0fd0f2-d633-a9de-1836-c15fc1109564.jpeg)


(B)部屋
　こちらはESP３２を使用して、サーバーを立てて、モータの強いトルクで回転させます。
![IMG_9719.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264607/5a4612ee-d90e-ed68-58fc-ff65bd1bd5b1.jpeg)


# 必要なもの

|                             　　 |       説明　　　　 |    URL                                   |
|:-----------------|------------------------------------------------------------:|:------------------:|
| SG９０         |             建物の施錠のため。ボタンを押す程度の出力があれば大丈夫なので |      https://www.amazon.co.jp/gp/product/B00VUJYNWG/ref=as_li_tl?ie=UTF8&tag=mmatrainy-22&camp=247&creative=1211&linkCode=as2&creativeASIN=B00VUJYNWG&linkId=639bd66898d30c88cde6a6d435bbb928          |
| ESP32           |          玄関施錠のため。ラズパイが玄関に近いなら買わなくてもよい。 |       https://www.amazon.co.jp/gp/product/B07R87Z178/ref=as_li_tl?ie=UTF8&tag=mmatrainy-22&camp=247&creative=1211&linkCode=as2&creativeASIN=B07R87Z178&linkId=604fd637c52582e207cbdf148c942326      |
| MG996R             |             玄関の鍵を回せるくらいのトルクが必要になるため　|        https://www.amazon.co.jp/gp/product/B010SLRAAS/ref=as_li_tl?ie=UTF8&tag=mmatrainy-22&camp=247&creative=1211&linkCode=as2&creativeASIN=B010SLRAAS&linkId=42e52e13e937b5aac73671ff2881c33a    |
| ACアダプタ               |               ESP32では電源不足のため |        https://www.amazon.co.jp/gp/product/B017M9IFLM/ref=as_li_tl?ie=UTF8&tag=mmatrainy-22&camp=247&creative=1211&linkCode=as2&creativeASIN=B017M9IFLM&linkId=ddc85e877774d9ceb0bfb57823faca71        |
| DC変換プラグ             |             DC電源を直接回路につなぐため |       https://www.amazon.co.jp/gp/product/B017M9IFLM/ref=as_li_tl?ie=UTF8&tag=mmatrainy-22&camp=247&creative=1211&linkCode=as2&creativeASIN=B017M9IFLM&linkId=63361303cd6e85041cea736fad059e23     |
| ブレッドボード          |           ESP32用 |     https://www.amazon.co.jp/gp/product/B009ALRR9M/ref=as_li_tl?ie=UTF8&tag=mmatrainy-22&camp=247&creative=1211&linkCode=as2&creativeASIN=B009ALRR9M&linkId=73ef351b55705c9278253d1330e6d8a3      |
|      ユニバーサルプレート    |          ESP32を固定するため |      https://www.amazon.co.jp/gp/product/B009ALRR9M/ref=as_li_tl?ie=UTF8&tag=mmatrainy-22&camp=247&creative=1211&linkCode=as2&creativeASIN=B009ALRR9M&linkId=73ef351b55705c9278253d1330e6d8a3      |      |



# 建物の施錠
(a)ラズパイ上にサーボモータを動かすプログラムmotor.pyを作成
(b)前回の記事で書いたラズパイのサーバーでmotor.pyを実行する。

参考までにソースコード

```python:motor.py
# coding: utf-8
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
gp_out = 24 #ここでPWMに使用するGPIOを指定
GPIO.setup(gp_out, GPIO.OUT)

#GPIO.PWM( [ピン番号] , [周波数Hz] )
#SG92RはPWMサイクル:20ms(=50Hz), 制御パルス:0.5ms〜2.4ms, (=2.5%〜12%)。
servo = GPIO.PWM(gp_out, 50)

#パルス出力開始。　servo.start( [デューティサイクル 0~100%] )
#とりあえずゼロ指定だとサイクルが生まれないので特に動かないっぽい？
servo.start(0)
#time.sleep(1)
#デューティサイクルの値を変更することでサーボが回って角度が変わる。

servo.ChangeDutyCycle(2.5) #-90度
time.sleep(0.5)
servo.ChangeDutyCycle(12) # 90度
time.sleep(0.5)
       

servo.stop()
GPIO.cleanup() #ラズパイのwsgiで実行するにはos.system('sudo python3 motor.py')とかで大丈夫。
```

# 部屋の施錠

ESP32をArudino IDEで書き込む。
以下参考に

```c++:motor_server.cpp
#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiClient.h>
#include <ESP32Servo.h>
const char* ssid = ""      //ここはご自身の環境で。ちなみに２．４ghzしか対応していません。
const char* password = ""   
//Servo
Servo servo;
int servoPin = 2;
int pos = 0;      // position in degrees


// TCP server at port 80 will respond to HTTP requests
WiFiServer server(80);

void setup(void)
{  
    Serial.begin(115200);

    // Connect to WiFi network
    WiFi.begin(ssid, password);
    Serial.println("");

    // Wait for connection
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.print("Connected to ");
    Serial.println(ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());

    // Set up mDNS responder:
    // - first argument is the domain name, in this example
    //   the fully-qualified domain name is "esp8266.local"
    // - second argument is the IP address to advertise
    //   we send our IP address on the WiFi network
    if (!MDNS.begin("esp32")) {
        Serial.println("Error setting up MDNS responder!");
        while(1) {
            delay(1000);
        }
    }
    Serial.println("mDNS responder started");

    // Start TCP (HTTP) server
    server.begin();
    Serial.println("TCP server started");

    // Add service to MDNS-SD
    MDNS.addService("http", "tcp", 80);

    //Servo
    servo.setPeriodHertz(50);      // Standard 50hz servo
    servo.attach(servoPin);
}

void loop(void)
{
    // Check if a client has connected
    WiFiClient client = server.available();
    if (!client) {
        return;
    }
    Serial.println("");
    Serial.println("New client");

    // Wait for data from client to become available
    while(client.connected() && !client.available()){
        delay(1);
    }

    // Read the first line of HTTP request
    String req = client.readStringUntil('\r');

    // First line of HTTP request looks like "GET /path HTTP/1.1"
    // Retrieve the "/path" part by finding the spaces
    int addr_start = req.indexOf(' ');
    int addr_end = req.indexOf(' ', addr_start + 1);
    if (addr_start == -1 || addr_end == -1) {
        Serial.print("Invalid request: ");
        Serial.println(req);
        return;
    }
    req = req.substring(addr_start + 1, addr_end);
    Serial.print("Request: ");
    Serial.println(req);

    String s;
 if( req == "/O"){
      if (servo.read() == 0){　
        servo.write(90);  //90度に回転
        delay(20000);　　　// ２０秒後に
        servo.write(0);　 //  オートロック
        delay(2000); 
        s = "END";
      }else{
        servo.write(0);
        delay(2000);
        s = "RETURN";
      }
    }
    else
    {
        Serial.println("Sending 404");
        Serial.println("N");
    }
    Serial.println(s);
    client.print(s);
    client.stop();
    Serial.println("Done with client");
}
```


これでhttp://esp32.local/O
にアクセスするとサーボが動きます。
ラズパイ側のwsgiでwget http://esp32.loacal/Oを実行させればおｋ
一応ESP32のDNSサーバに問い合わせるため時間が少しかかります。
直接http://ESP３２にローカルIP/O
としたほうが私の環境では５秒速かったです。

配線は
DC電源（＋）→MG９９６R（VCC)
DC電源（-)→MG996R(GND) →　ESP３２（GND)　（ブレッドボードで直列につないでください）
ESP３２（D2)　→　MG９９６R（PWM）




# 次回

⑷ エアコンの信号を解析してエアコンも操作