設備改造不要! obnizとサーボでスマートロック&壁スイッチ


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/d0356847-4830-6146-da94-311ec0ed4ed0.png)


#1.はじめに
###リモコンもついてない改造もできない訳あり設備のドアの施錠と照明を、既設設備を傷つけることなく自動化してみた案件です。
部屋を空けるたびに個別に消灯や施錠がめんどいというのが発端。
普通に考えたら赤外線リモコンをスマートスピーカーなんかで操作。。。となるのだが、いかんせん設備が古くてリモコンなんてついてない。今時の機器に交換や改造していいか設備管理部門に問い合わせてみたが、秒で拒否られてしまった。
そこで、既設設備を傷つけずにドアロックと壁の照明スイッチを操作するIoTの仕組みを作るというのが今回のお題です。ということなので、見た目はとてもスマートではないビジュアルですが、なかなか実用的な物に仕上がりました。
###obnizを使って、設備にそお～っとサーボモータを取り付けて制御しました。

#2.こんな感じで動いてます
###①運用の様子
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/obniz?src=hash&amp;ref_src=twsrc%5Etfw">#obniz</a> ベタですが、既設設備加工不要のスマートロック&amp;スマートスイッチ自作してみた。 <a href="https://t.co/hVnBdVbO3m">pic.twitter.com/hVnBdVbO3m</a></p>&mdash; Google Homer (@google_homer_) <a href="https://twitter.com/google_homer_/status/1340509153714786307?ref_src=twsrc%5Etfw">December 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

###②スマートロック部の動作
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/obniz?src=hash&amp;ref_src=twsrc%5Etfw">#obniz</a> スマートロック <a href="https://t.co/dTOVcFoY6H">pic.twitter.com/dTOVcFoY6H</a></p>&mdash; Google Homer (@google_homer_) <a href="https://twitter.com/google_homer_/status/1340509579147264001?ref_src=twsrc%5Etfw">December 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
###③スマートスイッチ部の動作
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/obniz?src=hash&amp;ref_src=twsrc%5Etfw">#obniz</a> スマートスイッチ <a href="https://t.co/jV8aal2uXd">pic.twitter.com/jV8aal2uXd</a></p>&mdash; Google Homer (@google_homer_) <a href="https://twitter.com/google_homer_/status/1340510020241223682?ref_src=twsrc%5Etfw">December 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

##3.システム構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/02ee2b1a-8abe-3af1-d401-621a7c700165.png)

##4.壁スイッチへのサーボモータの組み付け方法
①②壁スイッチのプレートのネジを緩め、結束バンドを通します。
③3つのスイッチを同時に操作したかったので、プラスチックの板を両面テープで貼り付け連動するようにします。
④サーボホーンの両端を少しカットし、サーボモータ(SG92R)にネジ止めします。
⑤サーボモータを両面テープでプレートに貼りつけ、結束バンドできつく締め付けて固定します。
⑥⑦スイッチON/OFF状態で、サーボホーンの左/右端が軽く接している当たりが組み付けのポイント。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/30cacc1e-a9b4-dd32-187d-a860fa26fa85.png)


##5.ドアノブへのサーボモータの組み付け方法
①②ドアノブの施錠用ツバに、結束バンドでいい感じにサーボホーンをくくり付けます。
③④コーヒーなんかのアルミ缶をハサミでカットし、内側の底にサーボをネジ止めします。
⑤サーボの回転軸をサーボホーンに差し込みます。
⑥ドアノブとアルミ缶を、適当にビニールテープなんかでぐるぐる巻きにして完成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/475d69d9-50f4-d02e-895f-10af178d6c8f.png)

##6.obnizコード全文
```html
<!-- HTML Example -->
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">  
    <script src="https://unpkg.com/obniz@3.11.0/obniz.js" crossorigin="anonymous"></script>
</head>

<body>
<font size="5">M208_コントローラ</font>
<br><br>
<button id="ON" class="btn btn-primary"><font size="3">ON</font></button>
<button id="OFF" class="btn btn-primary"><font size="3">OFF</font></button>
<button id="OPEN" class="btn btn-primary"><font size="3">OPEN</font></button>
<button id="CLOSE" class="btn btn-primary"><font size="3">CLOSE</font></button>

<script>
var obniz = new Obniz("xxxx-XXXX");
var STOP_ANGLE = 102;                 //照明スイッチサーボ 水平角度
var ON_ANGLE = STOP_ANGLE+30;         //照明スイッチサーボ ON角度 
var OFF_ANGLE = STOP_ANGLE-25;        //照明スイッチサーボ OFF角度
var OPEN_ANGLE = 80;                  //ドアの鍵サーボ　開錠角度
var CLOSE_ANGLE = 0;                  //ドアの鍵サーボ  施錠角度
obniz.onconnect = async function () {
  //サーボ定義
   Servo_light = obniz.wired("ServoMotor" , {signal:0,vcc:1,gnd:2} );   //照明操作
   Servo_door = obniz.wired("ServoMotor" , {signal:3,vcc:4,gnd:5} );    //ドアの鍵操作
   obniz.io4.output(false); 

   if (typeof done === "function"){ 
//----------------------------------------------------------
//  Webhookモードで起動された場合 
//----------------------------------------------------------  
      if (typeof req === "object") {
         if ( req.query.open ){
           await DOOR_OPEN();                //鍵OPEN
           await LIGHT_ON();                 //照明ON
         }
         if ( req.query.close ){
           await DOOR_CLOSE();               //鍵CLOSE
           await LIGHT_OFF();                //照明OFF      
         }
         if ( req.query.on  ){
           await LIGHT_ON();                 //照明ON
         }
         if ( req.query.off ){
           await LIGHT_OFF();                //照明OFF
         }
         obniz.close();  
      }
      obniz.close();
   } else {
//----------------------------------------------------------
//  HTML画面モードで起動された場合 
//----------------------------------------------------------    
      $("#OPEN").click(async function () {   //鍵OPEN
        await DOOR_OPEN(); 
      })
      $("#CLOSE").click(async function () {  //鍵CLOSE
        await DOOR_CLOSE();
      })
      $("#ON").click(async function () {    //照明ON
        await LIGHT_ON();
      })
      $("#OFF").click(async function () {   //照明OFF
        await LIGHT_OFF();
      })
   }
   //鍵　OPEN
   async function DOOR_OPEN(){
     await obniz.io4.output(true); 
     await Servo_door.angle(OPEN_ANGLE);
     await obniz.wait(500);
     await obniz.io4.output(false);
   }
   //鍵　CLOSE
   async function DOOR_CLOSE(){
     await obniz.io4.output(true); 
     await Servo_door.angle(CLOSE_ANGLE);
     await obniz.wait(500);
     await obniz.io4.output(false); 
   } 
   //照明 ON
   async function LIGHT_ON(){
     await Servo_light.angle(ON_ANGLE);
     await obniz.wait(500);
     await Servo_light.angle(STOP_ANGLE); 
     await obniz.wait(500);            
   }
   //照明OFF
   async function LIGHT_OFF(){
     await Servo_light.angle(OFF_ANGLE); 
     await obniz.wait(500);
     await Servo_light.angle(STOP_ANGLE); 
     await obniz.wait(500);
   }
   if (typeof done === "function") { done(); }
}
</script>
</body>
</html>
```

##7.obnizコードのポイント解説
###①壁スイッチのニュートラルポジションの設定
システムが使えなくなった場合に手動でもスイッチをON/OFFできるよう、サーボでON/OFFした後はサーボをニュートラルの位置(STOP_ANGLE)に戻すようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/002552af-4f68-c369-c076-d9a7de4967a6.png)

```html
  //照明 ON
   async function LIGHT_ON(){
     await Servo_light.angle(ON_ANGLE);
     await obniz.wait(500);
     await Servo_light.angle(STOP_ANGLE); 
     await obniz.wait(500);            
   }
   async function LIGHT_OFF(){
     await Servo_light.angle(OFF_ANGLE); 
     await obniz.wait(500);
     await Servo_light.angle(STOP_ANGLE); 
     await obniz.wait(500);
   }
```
###②ドアの鍵のサーボの電源OFF
サーボの電源がONのままだとモータがロックされた状態となっていて、手動でドアの開け閉めができなくなるので、サーボの電源端子(io4.output)を動的にON(true)/OFF(false)するようにしました。

```html
   //鍵　OPEN
   async function DOOR_OPEN(){
     await obniz.io4.output(true); 
     await Servo_door.angle(OPEN_ANGLE);
     await obniz.wait(500);
     await obniz.io4.output(false);
   }
   //鍵　CLOSE
   async function DOOR_CLOSE(){
     await obniz.io4.output(true); 
     await Servo_door.angle(CLOSE_ANGLE);
     await obniz.wait(500);
     await obniz.io4.output(false); 
   } 
```

###③IFTTT障害に備えて画面からも操作できるようにしました
```html
   if (typeof done === "function"){ 
//----------------------------------------------------------
//  Webhookモードで起動された場合 
//----------------------------------------------------------  
  　　 ～ほげほげ～
   } else {
//----------------------------------------------------------
//  HTML画面モードで起動された場合 
//----------------------------------------------------------    
　　　～ほげほげ～
   }
   if (typeof done === "function") { done(); }
}
```
###④サーボの回転角の調整
各サーボの回転角度は、実際の組み付け状況に応じて調整して下さい。

```html
var STOP_ANGLE = 102;                 //照明スイッチサーボ 水平角度
var ON_ANGLE = STOP_ANGLE+30;         //照明スイッチサーボ ON角度 
var OFF_ANGLE = STOP_ANGLE-25;        //照明スイッチサーボ OFF角度
var OPEN_ANGLE = 80;                  //ドアの鍵サーボ　開錠角度
var CLOSE_ANGLE = 0;                  //ドアの鍵サーボ  施錠角度
```

##8.IFTTT設定の例
Google Assistant(音声)からobnizにWebhookをかける部分のAppletの例です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/6814fbd7-818b-a96a-e3f6-2f26fbebb049.png)

##9.感想とまとめ
***なめてかかってました。***初期バージョンはとても運用に耐えられるものではなく、半年間コツコツ改良を加え、やっといい感じに仕上がりました。手動と自動の併用運用、動かなかった場合のコンテンジェンシー機能など、***ベタな作品ですがとても勉強になりました。***
建付けがゆるくサーボが空振りする事がたまにあるので、制御結果のフィードバック機能を追加した方がよいかも。また、便利にはなったのですが、講義用の教材を両手で抱えていてスマホを取り出す事自体もメンドイ場面もあるので、AIカメラやニアフィールドの個体認証で動作する仕組みなんかも検討して行きたいと思っています。