Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
13
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@morinokami

Nature Remo を Python から操作する

はじめに

Nature Remo のデバイスは、APIを通じて操作することが可能です。最近 Nature Remo の第3世代を入手したため、これをプログラムやコマンドラインから操作したいと思い、Python 向けにライブラリを書きました。

nature-remo

ここではこのライブラリの使い方について解説していきます。Remo で遊ぶ上での選択肢の一つとしていただければ幸いです。

インストール

サポートしている Python のバージョンは 3.8 です。インストールは pip からおこないます:

$ pip install -U nature-remo

なお、動作確認は Ubuntu と macOS にておこないました。

使い方

API を使用する前提として、

にてアクセストークンを発行しておいてください。

アクセストークンを入手したら、それを用いてクライアントを初期化します:

>>> from remo import NatureRemoAPI
>>> api = NatureRemoAPI('access_token')

生成したクライアントには、各 API に対応するメソッドが備わっています。たとえば、自分のアカウントに関連付けられた Nature Remo のデバイスのリストを取得したければ、api.get_devices メソッドを実行します:

>>> devices = api.get_devices()
>>> devices
[Device(id='device-id', name='Remo', temprature_offset=0, humidity_offset=0, created_at=datetime.datetime(2020, 7, 23, 3, 10, 21, tzinfo=datetime.timezone.utc), updated_at=datetime.datetime(2020, 8, 8, 11, 4, 17, tzinfo=datetime.timezone.utc), firmware_version='Remo/1.0.23', mac_address='ab:cd:ef:12:34:56', serial_number='1W000000000000', newest_events={'hu': {'val': 54.0, 'created_at': datetime.datetime(2020, 8, 9, 6, 24, 19, tzinfo=datetime.timezone.utc)}, 'il': {'val': 0.0, 'created_at': datetime.datetime(2020, 8, 9, 6, 31, 46, tzinfo=datetime.timezone.utc)}, 'mo': {'val': 1.0, 'created_at': datetime.datetime(2020, 8, 8, 11, 4, 17, tzinfo=datetime.timezone.utc)}, 'te': {'val': 27.636597, 'created_at': datetime.datetime(2020, 8, 9, 6, 29, 19, tzinfo=datetime.timezone.utc)}})]

devicesDevice モデルのリストです。Device モデルのインスタンスは、idname など、対応する Remo デバイスの情報をアトリビュートとして保持しています。たとえばデバイスのセンサーが取得した湿度や温度は、次のようにしてアクセスすることができます:

>>> d.newest_events
{'hu': SensorValue(val=54.0, created_at=datetime.datetime(2020, 8, 9, 7, 57, 28, tzinfo=datetime.timezone.utc)), 'il': SensorValue(val=21.0, created_at=datetime.datetime(2020, 8, 9, 7, 55, 21, tzinfo=datetime.timezone.utc)), 'mo': SensorValue(val=1.0, created_at=datetime.datetime(2020, 8, 8, 11, 4, 17, tzinfo=datetime.timezone.utc)), 'te': SensorValue(val=27.485535, created_at=datetime.datetime(2020, 8, 9, 7, 49, 28, tzinfo=datetime.timezone.utc))}
>>> d.newest_events['hu'].val # 湿度
54.0
>>> d.newest_events['te'].val # 温度
27.485535

他にも、get_userget_appliances などのメソッドにより、ユーザーや家電の情報を取得することが可能です。

もちろん、情報を取得するだけでなく、家電の操作をおこなうことも可能です。たとえば、エアコンの設定を変更したい場合は、エアコンの ID を取得した上で、update_aircon_settings メソッドを実行します:

>>> appliances = api.get_appliances()
>>> appliances[0].type # 家電のタイプを確認
'AC'
>>> # 26度の冷房に設定
>>> api.update_aircon_settings(appliances[0].id, operation_mode='cool', temperature=26)

同様の流れで、テレビの操作なども可能です:

>>> appliances[1].type # 家電のタイプを確認
'TV'
>>> appliances[1].tv.buttons # 登録されているボタンを確認
[Button(name='power', image='ico_io', label='TV_power'), ...]
>>> api.send_tv_infrared_signal(appliances[1].id, 'power') # 電源ボタンを押す

API を使用すると、クライアントのアトリビュートに Rate Limit (呼び出し制限) の状況がセットされます:

>>> api.get_user()
User(id='user-id', nickname='Foo Bar')
>>> api.rate_limit.limit, api.rate_limit.remaining # リミットと残りの呼び出し可能回数
(30, 28)

この他にも、api.rate_limit.reset から制限がリセットされるタイミングを知ることなどが可能です。

また、クライアントの作成時に debugTrue とすることで、実際におこなわれている通信の様子を確認することもできます:

>>> api = NatureRemoAPI('access_token', debug=True)
>>> api.get_user()
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.nature.global:443
send: b'GET /1/users/me HTTP/1.1\r\nHost: api.nature.global\r\nUser-Agent: nature-remo/0.3.1 (https://github.com/morinokami/nature-remo)\r\nAccept-Encoding: gzip, deflate\r\nAccept: application/json\r\nConnection: keep-alive\r\nAuthorization: Bearer access_token\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Date: Mon, 27 Jul 2020 15:53:12 GMT
header: Content-Type: application/json; charset=utf-8
header: Content-Length: 72
header: Connection: keep-alive
header: Access-Control-Allow-Origin: *
header: Cache-Control: no-cache, no-store, must-revalidate, private, max-age=0
header: Expires: Thu, 01 Jan 1970 00:00:00 UTC
header: Pragma: no-cache
header: Strict-Transport-Security: max-age=86400
header: Vary: Accept-Encoding
header: X-Accel-Expires: 0
header: X-Content-Type-Options: nosniff
header: X-Frame-Options: SAMEORIGIN
header: X-Rate-Limit-Limit: 30
header: X-Rate-Limit-Remaining: 29
header: X-Rate-Limit-Reset: 1595865300
header: X-Xss-Protection: 1; mode=block
DEBUG:urllib3.connectionpool:https://api.nature.global:443 "GET /1/users/me HTTP/1.1" 200 72
User(id='user_id', nickname='your_nickname')

以上のように、クライアントのインスタンスを生成し対応するメソッドを呼び出すことで、簡単に API を利用することができるようになっています。なお、API とメソッドの対応は次のようになっています (下記はすべて実装されていますが、POST /1/detectapplianceなど、僕も動作確認できていないものがあることは述べておきます):

HTTP Method Endpoint API
GET /1/users/me get_user
POST /1/users/me update_user
GET /1/devices get_devices
POST /1/detectappliance detect_appliance
GET /1/appliances get_appliances
POST /1/appliances create_appliance
POST /1/appliance_orders update_appliance_orders
POST /1/appliances/{appliance}/delete delete_appliance
POST /1/appliances/{appliance} update_appliance
POST /1/appliances/{appliance}/aircon_settings update_aircon_settings
POST /1/appliances/{appliance}/tv send_tv_infrared_signal
POST /1/appliances/{appliance}/light send_light_infrared_signal
GET /1/appliances/{appliance}/signals get_signals
POST /1/appliances/{appliance}/signals create_signal
POST /1/appliances/{appliance}/signal_orders update_signal_orders
POST /1/signals/{signal} update_signal
POST /1/signals/{signal}/delete delete_signal
POST /1/signals/{signal}/send send_signal
POST /1/devices/{device} update_device
POST /1/devices/{device}/delete delete_device
POST /1/devices/{device}/temperature_offset update_temperature_offset
POST /1/devices/{device}/humidity_offset update_humidity_offset

各メソッドに与える引数などは、Python の help 関数などにより確認できます。

また、Local API 用のクライアントを生成するためには、Remo デバイスのローカルIPアドレスを調べた上で、それを引数として NatureRemoLocalAPI クラスに与えます:

>>> from remo import NatureRemoLocalAPI
>>> local_api = NatureRemoLocalAPI('ip_addr')

対応している API は以下のようになります:

HTTP Method Endpoint API
GET /messages get_ir_signal
POST /messages send_ir_signal

CLI

nature-remopip によりインストールすると、各 API をコマンドから実行することも可能となります。背後では、上で紹介した Python クライアントが動いています。

各コマンドは、次のような形式で実行します:

$ remo [操作対象] [操作内容] [引数やオプション]

操作対象には、appliancedevicelocalsignaluser のいずれかを指定します。各捜査対象に対応する操作内容は、--help を指定することで確認することができます:

$ remo device --help
Usage: remo device [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  delete                     Delete Remo.
  get                        Fetch the list of Remo devices the user has...
  update                     Update Remo.
  update_humidity_offset     Update humidity offset.
  update_temperature_offset  Update temperature offset.

上の表示内容から、たとえばデバイスのリストを得るためには、get を指定すればよいことがわかります。

操作対象が appliancedevicesignaluser のいずれかである場合にはアクセストークンを指定する必要がありますが、CLI では環境変数とオプションのいずれかでアクセストークンを指定します。環境変数で指定する場合は、$ export REMO_ACCESS_TOKEN=<access_token> のように、REMO_ACCESS_TOKEN に値をセットしておきます。また、オプションで指定する場合は次のようにします:

$ remo device get --token <access_token>
[{"created_at": "2020-07-23T03:10:21+00:00", ...}]

また、更新や削除など、操作内容によっては引数を与える必要がありますが、それについても --help により確認することができます:

remo device update --help
Usage: remo device update [OPTIONS] ID NAME

  Update Remo.

  ID: Device ID. NAME: Device name.

Options:
  --token TEXT
  --debug
  --help        Show this message and exit.

上の表示内容から、デバイスの名前を変更するためには、$ remo device update <device-id> <device-name> とコマンドを実行すればよいことがわかります。他のコマンドに関しても、同様の手順で実行に必要な情報を確認することが可能です。

各コマンドと API の完全な対応表は次のようになります:

Command Nature Remo API
remo user get GET /1/users/me
remo user update POST /1/users/me
remo device get GET /1/devices
remo device update POST /1/devices/{device}
remo device delete POST /1/devices/{device}/delete
remo device update_temperature_offset POST /1/devices/{device}/temperature_offset
remo device update_humidity_offset POST /1/devices/{device}/humidity_offset
remo appliance detect POST /1/detectappliance
remo appliance create POST /1/appliances
remo appliance get GET /1/appliances
remo appliance update POST /1/appliances/{appliance}
remo appliance delete POST /1/appliances/{appliance}/delete
remo appliance update_orders POST /1/appliance_orders
remo appliance update_aircon_settings POST /1/appliances/{appliance}/aircon_settings
remo appliance send_tv_infrared_signal POST /1/appliances/{appliance}/tv
remo appliance send_light_infrared_signal POST /1/appliances/{appliance}/light
remo signal create /1/appliances/{appliance}/signals
remo signal get GET /1/appliances/{appliance}/signals
remo signal update POST /1/signals/{signal}
remo signal delete /1/signals/{signal}/delete
remo signal send /1/signals/{signal}/send
remo signal update_orders /1/appliances/{appliance}/signal_orders

まとめ

Nature Remo の API にアクセスするための Python ライブラリを紹介しました。Remo の単純な操作をするには公式アプリが一番便利だと思いますが、プログラムから気軽に API を叩けることで、より柔軟に Remo を操作できるようになるはずです。Enjoy!🦖

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
13
Help us understand the problem. What are the problem?