Raspberry PiとNatureRemoで「Nature(大自然)な目覚まし時計」を作ってみた話


背景と概要

先日、「たまにはモルディブの海辺で朝日を浴びながら目覚めてみたい
という無茶振りなお声をいただきました。

これを穏便に、自宅にいながら少ないお金で実現するべく
Raspberry Piで動画による目覚まし機能を実装し、
NatureRemoでIoT化したプロジェクターを媒体に「Natureな目覚まし時計」というのを作ってみました。

※目覚めるとこの視界が映るイメージ

用意したもの

NatureRemoの設定

「Nature Remo スマートリモコン」アプリでプロジェクターのリモコンを機器登録します。Android版, iOS版

Raspberry Piの設定

今回は「就寝前にラズパイを起動しておき、指定時間にプロジェクターをNatureRemoのAPIで起動、接続しているラズパイから動画が流れる」という方針で実装します。
(ラズパイの自動起動は他モジュールが必要など、ハードルが高く感じたため断念)

1. NatureRemoのPythonライブラリを使えるまで

「nature-remo」というPython用のライブラリがあるので、こちらをインストールします。
日本語ドキュメントとしてもわかりやくコチラにまとまっています。

しかし、何も考えずにpip install nature-remoしたところ下記のエラーが出ました。

エラーの理由は、mashmallowというライブラがpython 3.5以上を要求していますが
RaspberryPiのデフォルト設定が2.Xとなっていたためでした。
参考:
marshmallow 3.10.0
marshmallow – 複雑なオブジェクトを単純なPythonデータ型との間で変換するための軽量ライブラリ

回避するにはPythonのデフォルトバージョンを3.Xに切り替えるか、下記コマンドで乗り切れます。
参考:Raspberry Pi の Python デフォルトバージョンを 2系 から 3系 に切り替える

$ pip3 install nature-remo

2. Pythonで家電に信号を送る

2-1. NatureRemoのaccessToken取得

はじめに、自分のNatureRemoデバイスにアクセスするため、アクセストークンの取得を行います。
手順はログインサイトにNatureRemoアカウントでログインし、Generate access tokenボタンを押すだけで発行できます。
下記の表示が出るのでメモしておきます。忘れて画面から移動した場合でも、再取得可能なので問題ありません。

2-2. 登録家電情報を取得してみる

ここで少しNatureRemoのAPI仕様を深掘りしてみます。(詳細はこちら
NatureRemoで扱う情報は大きく分けて3つあります。

名称 NatureRemoでの扱い
user アカウント情報
device NatureRemoデバイスの情報
appliance NatureRemoに登録された家電情報

基本的にはapplianceの情報がメインとなりそうなので
まずは下記スクリプトで家電情報を確認します。

# conding: utf-8
from remo import NatureRemoAPI
api = NatureRemoAPI('accessToken')

appliance = api.get_appliances()
print(appliance)

上記で、自身で登録した全ての家電機器について
どの家電がどのIDを持ってどういった操作が登録されているか、
Listの中で何番目のデバイスなのか等を知ることができます。
例えば1つ目に登録されている家電が照明の場合、下記のように指定するとそのapplianceのみ照会できます。

appliance = api.get_appliances()[0]

実際に取得してみた照明のapplianceデータも情報マスクして載せます。

applianceのデータ詳細
Appliance(
    id='appliance_id',
    device=Device(id='device_id',
        name='寝室のRemo',
        temprature_offset=0,
        humidity_offset=0,
        created_at=datetime.datetime(2021, 3, 23, 10, 0, 0, tzinfo=datetime.timezone.utc), 
        updated_at=datetime.datetime(2021, 3, 23, 10, 0, 0, tzinfo=datetime.timezone.utc),
        firmware_version='remo',
        mac_address='mac_address',
        serial_number='serial_no'
    ),
    model=ApplianceModel(id='appaliance_id',
    manufacturer='Panasonic',
    remote_name='light',
    name='Panasonic LIGHT',
    image='ico_light'),
    nickname='寝室の照明',
    image='ico_light',
    type='LIGHT',
    settings=None,
    aircon=None,
    signals=[],
    tv=None,
    light=Light(
        state=LightState(brightness='100',
            power='on',
            last_button='on-100'
        ),
        buttons=[
            Button(
                name='on',
                image='ico_on',
                label='Light_on'
            ),
            Button(
                name='off',
                image='ico_off',
                label='Light_off'
            ),
            Button(
                name='on-100',
                image='ico_light_all',
                label='Light_all'
            ),
            Button(
                name='on-favorite',
                image='ico_light_favorite',
                label='Light_favorite'
            ),
            Button(
                name='onoff',
                image='ico_io',
                label='Light_onoff'
            ),
            Button(
                name='bright-up',
                image='ico_arrow_top',
                label='Light_bright'
            ),
            Button(
                name='bright-down',
                image='ico_arrow_bottom',
                label='Light_dark'
            )
        ]
    )
)

注目したのは、スマートリモコンの各ボタンの情報がLightオブジェクトで管理されているところです。
これは家電の種類によって異なり、こちらも3種類ありました。

オブジェクト名称 デバイスの種類
TV テレビ関連の機器
Light 照明関連の機器
Signals それ以外?の機器

今回は照明とプロジェクター、2種類の機器を扱うことにしましたが
照明はLightでプロジェクターはSignalsオブジェクト内にボタンの情報があります。
ここの違いが、後述のAPIを呼び出す際に影響しますので確認が必要です。

そのため、この作業項目ではget_appliances()の内容を確認して
API操作したい対象の下記ポイントを把握することがゴールとなります。

  1. 登録家電リストの中で何番目の家電か
  2. 対象家電のボタン情報はどのオブジェクトタイプか
  3. 操作したいボタン情報がどれか(idやnameを確認する)

2-3. Pythonで家電操作スクリプト作成

家電操作する場合に呼び出すAPIは、前述のオブジェクトタイプによって異なります。
今回は実装ポイントだけを簡単にまとめてみますが
APIで使用する引数の情報は、個人的にはGithubを直接参考されることをお勧めします。

Github:https://github.com/morinokami/nature-remo/blob/master/remo/api.py

オブジェクトタイプ 信号送信のAPI 引数の値
Light send_light_infrared_signal(self, appliance: str, button: str) appliance IDとbutton name
Signals send_signal(self, signal: str) signal ID

上記の内容を踏まえて、下記2つのスクリプトを作成しました。
それぞれ部屋の照明On/Offとプロジェクターの電源の信号を飛ばすスクリプト
(添字等は適当に変更しています)

light.py
# conding: utf-8
from remo import NatureRemoAPI
api = NatureRemoAPI('accessToken')

appliance = api.get_appliances()[0]

api.send_light_infrared_signal(appliance.id,appliance.light.buttons[0].name)
projector.py
# conding: utf-8
from remo import NatureRemoAPI
api = NatureRemoAPI('accessToken')

projector = api.get_appliances()[1]
projectorPower = api.get_signals(projector.id)[0]

api.send_signal(projectorPower.id)

大きく違いはありませんが、Signalsではget_signals()という
対象applianceのボタン情報をまとめて取得するAPIが利用できるので
applianceの情報から地道に辿らずに操作ボタンの情報が取得可能、という一例です。

3. 動画再生のスクリプト作成

動画再生用のスクリプトは、下記サイト様の内容を全面的に使わせていただきました。
Raspberry Pi 4を動画再生機(mp4プレーヤー)にした話
今回はSDカードメディアではなく、無料素材を下記からローカルに保存しておきました。
高品質なフリー動画素材

4. cron設定

最後に、作成したスクリプト群をcronで実行してもらうようスケジューリングします。

$ crontab -e

月曜から金曜まで設定する場合、下記のような形で設定しておきます。

7 30 * * 1-5 python3 projector.py
7 30 * * 1-5 python3 moviePlay.py
8 00 * * 1-5 python3 light.py

まとめ

これで起床時間になるとプロジェクターが起動し
壁一面に海やリゾート地の風景動画を輝かせながら朝を迎えることができました!
NatureRemoのAPI仕様など、色々知見が広まったのもありますが
何よりこんなに簡単にできたということが感動的でした。
IoT DIYの入門として大変楽しめました、NatureRemo万歳!

ご自宅のIoT化をやってみたい、けど何からやったものかと悩んでいる方々や
QoL(Quality of Life)を上げてみたい!と思っている方々に響けば大変幸いです。

また長文となり大変申し訳ございません。ご一読いただいた皆様に感謝です。

やってみた感想

  • リゾート地の映像が美しくて最高!
  • 音ではなく光によって自然に起こしてもらえる感
  • 動画で起こしてくれるので、スヌーズ機能や二度寝防止の複数アラームが鳴ることによるイライラ解消
  • 逆に寝る時の睡眠導入用にも応用できそう など

副次的効果もあって結構評判良く安心しました。
動画は好みで変更可能なので、別の楽しみ方ができそうと、ワクワク感もありました。