Rubyでスマートホームを作ろう！

## はじめに
こんにちは！[Life is Tech！#1 Advent Calendar](https://qiita.com/advent-calendar/2020/life-is-tech)の16日目を担当します、Webサービスプログラミングコースメンターのみずです！ よろしくお願いします！

この記事ではRubyを使ってスマートホームを作る方法について書きたいと思います！

## スマートホームってなんだ？
日本ではまだあまりメジャーになっていない気もしますが、スマートホームとは「IoT」や「AI」を使ってより住みやすくなった家のことです。
スマートスピーカー（Google Home、Amazon Alexa、HomePodなど）も、従来のスピーカーにIoT/AIが備わってより便利になったものとしてスマートホームの一部だと言えるでしょう。

この記事では、スマートフォンやスマートスピーカーを使って家電をコントロールできるようにしてみたいと思います！

## どの技術を使おう？（技術選定）
さて、やることは決まりました。今ある家電の制御です。
ではどんな技術を使いましょうか。

スマートスピーカーを使ってコントロールしたいので、以下のような選択肢が出てくると思います。

- Amazon Echo
- Google Home
- Apple HomePod
- LINE Clova

いずれも家電の制御に対応しています。僕は身の回りにApple製品が多いのでAppleのHomePodで制御出来るようにしてみたいと思います！

HomePodはHomeKitと呼ばれる仕組みを使って家電をコントロールします。このHomeKitは仕組みが公開されていて、誰でも作る事ができます。
Life is Tech ! のWebサービスプログラミングコースではRubyを使ったプログラミングをしています。なので、Rubyを使って実際にHomeKitを実装していきましょうー！

## 開発環境について

今回この記事ではMacで開発する事を前提に進めています。WindowsやLinuxでも開発できるかとは思いますが、手順が異なると思うので各自で挑戦してみてほしいです。

## 下準備

ターミナルで以下のコマンドを打って準備しましょう。

```bash
$ mkdir <プロジェクト名> # フォルダ作成
$ cd <プロジェクト名> # フォルダに移動
$ bundle init # Gemfileを作るコマンド
$ code . # VS Codeを開くコマンド
```

さて、これでVS Codeが起動します。（上手く起動しない場合はVS Codeを起動して先程作ったフォルダを開きましょう。フォルダはユーザーフォルダの中にあるはずです！）

今回は`ruby_home`というライブラリを使用したいのでGemfileに以下を追記しましょう。

```ruby
gem 'ruby_home'
```

追記できたらVS Codeのターミナルでbundleコマンドを実行してライブラリをインストールします。

```bash
$ bundle
```

これで開発の準備は完了です！！

## 試しに照明を作ってみよう

app.rbというファイルを作り、以下のコードを書いてみます。

```ruby:app.rb
require 'ruby_home'

accessory_information = RubyHome::ServiceFactory.create(:accessory_information)
fan = RubyHome::ServiceFactory.create(:lightbulb)

fan.on.after_update do |status|
  if status
    puts "照明がオンになりました"
  else
    puts "照明がオフになりました"
  end
end

RubyHome.run
```

`ruby app.rb`コマンドで実行してみると以下のように表示されるはずです！

```bash
$ ruby app.rb
Please enter this code with your HomeKit app on your iOS device to pair with RubyHome
                       
    ┌────────────┐     
    │ 766-75-746 │    
    └────────────┘     

```

iPhoneのHomeアプリを起動してアクセサリを追加してみましょう。

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672451/b7603eda-c812-325e-c311-58b36b1783cd.png">

このように出てくるので「コードがないか、スキャンできません」を押しましょう。

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672451/dbf47568-24fa-8df2-828e-5617f4324dfb.png">

すると、同じWi-Fiにつながっている対応デバイスを見つけてきてくれます。RubyHomeをタップしましょう！

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672451/bebeb616-a049-c3fa-ff08-8b0f587f3ff8.png">

アラートが出てきますが気にせず進めます。

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672451/2fa5d39c-fb73-107e-b368-49a51a2d67f6.png">

ここからは続けるボタンを繰り返せばOKです！

無事追加出来たら電球マークのRubyHomeをタップしてみましょう！

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672451/3aa1b751-80fb-d20d-30f8-991d1cfe8e82.jpeg">

このようにオンになりましたか？ターミナルを見てみるとこのようにオンオフが表示されているはずです。

```bash
$ ruby app.rb
Please enter this code with your HomeKit app on your iOS device to pair with RubyHome
                       
    ┌────────────┐     
    │ 766-75-746 │    
    └────────────┘     
                       
照明がオンになりました
照明がオフになりました
照明がオンになりました
照明がオフになりました
```

### コード説明

コメントに説明を書いたので読んでみてください。

```ruby
require 'ruby_home' # ライブラリ読み込み

accessory_information = RubyHome::ServiceFactory.create(:accessory_information) # アクセサリだよ！と言う為に必要な機能を追加
fan = RubyHome::ServiceFactory.create(:lightbulb) # 照明機能を追加

fan.on.after_update do |status| # 照明のオンオフが変更された時
  if status # onだったらTrue、offだったらFalse
    puts "照明がオンになりました"
  else
    puts "照明がオフになりました"
  end
end

RubyHome.run # 起動
```

このようにかなり短いコードで実現する事が出来ます！
この中のif文の中に実際に照明を制御するコードを書けばスマートホームが作れるわけです！

## 実際の照明と連携してみる

さて、ここからは照明を制御していきましょう。ごく一部APIが使えるような照明もあるようですが、うちの家の照明は至って普通の照明なので赤外線でコントロールすることにします。

というわけでこんな感じのモジュールを作りました。ESP32というチップ（の開発ボード）をベースにした赤外線信号を発信出来るデバイスです。USBで通信しても良かったのですが、部屋の好きなところに置きたかったのでWi-Fiに接続し、API経由で赤外線を発信できるようにしてみました。

<img width="600px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672451/4c3104b9-69f9-b3b6-6ca5-3d5e01d8d546.jpeg">

基本的には以下のようなコードになっています。赤外線によるコントロールは機器によって大きく方法が変わるので各自で調べて実装することをおすすめします！
https://gist.github.com/mizucoffee/912bb2032e21568821b8ddedda13d99d

```ruby:app.rb
require 'ruby_home'
require 'net/http'
require 'uri'

on = "p344A9034A4"
off = "p344A90F464"

def send_ir(code) # APIを呼び出すコード
  uri = URI.parse('http://192.168.101.200/send?data=' + code)
  req = Net::HTTP::Post.new(uri)
  http = Net::HTTP.new(uri.host, uri.port)
  http.request(req)
end

accessory_information = RubyHome::ServiceFactory.create(:accessory_information)
fan = RubyHome::ServiceFactory.create(:lightbulb)

fan.on.after_update do |status|
  if status
    puts "照明がオンになりました"
    send_ir on # オンにする信号を送るコード
  else
    puts "照明がオフになりました"
    send_ir off # オンにする信号を送るコード
  end
end

RubyHome.run
```

さて、準備は出来ました！実際に動かしてみましょう！

![IMG_0625.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672451/d689c71f-9b96-37cb-8c82-79b5568e6f4b.gif)

こんな感じで動きました！！

## おわりに

この記事ではRubyを使ってHomeKitに対応したアプリを実際に開発し、照明をコントロールしてみました。結構簡単だったのではないでしょうか！
対応したデバイスを購入してスマートホームを作るのも良いですが、自分の力で作り上げてみるのもオツなものです。

ここからは自分の話になりますが、僕は普段「身近な面倒を快適に！」というモットーで開発をしています。
これには自分はもちろん、家族や友達、それこそメンターやメンバーのみんなも含まれています！
今回のスマートホームは主に自分用ですが、家族に一緒に使ってもらうことも出来るし、もしかしたらオフィスにだって導入出来るかもしれませんね。

いままで、家族の介護用にベッドから降りたことを通知するセンサーを作ったり、Twitterのフォロー・フォロワーをバックアップするサービスを作ったりしてきたのですが、ある程度開発する力があればこうやって周りを幸せにすることが出来たりします！

人それぞれ開発をする目的は違うと思いますが、ぜひぜひ自分や周りの人が嬉しくなるような開発にもチャレンジしてみてほしいです！

最後まで読んでいただきまして、ありがとうございました！
明日は[つっちー（@taznica）](https://qiita.com/taznica)が何か書いてくれるようです！お楽しみにー！！

## 追記: カーテンも作ってみました
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">カーテンも作ってみた <a href="https://t.co/qBQmeRlejE">pic.twitter.com/qBQmeRlejE</a></p>&mdash; みず@LiT! (@lit_mizu) <a href="https://twitter.com/lit_mizu/status/1342022740765626368?ref_src=twsrc%5Etfw">December 24, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>