これは何?
Ratocの家電リモコンwfirexシリーズを、PythonからIFTTT経由でコントロールする方法です。
リモコンコードを直接Pythonから送信するので、IFTTT側で用意するアプレットは1つで済みます。(実質2つですが。)
リモコンコードは、スマホの家電リモコンアプリからエクスポートしてきたデータを使用します。
IFTTTのRatocの赤外線コマンド送信機能を利用していますが、以下のような注意点が記載されています
【注意】
このアクションは、メンテナンス用として残されているものです。
将来予告なしに削除される予定です。
ご使用される場合は、お客様の自己責任でお使いください。
また、使用方法や設定値についてのご質問には回答できません。
サポート外であることを予めご了承ください。
準備
IFTTTのWebhooksのkeyを取得
IFTTT上のWebhooksのページにある「Documentation」をクリックすると表示されます。
後で必要になりますので、メモしておいてください。
IFTTTのアプレットを作成
IFFFTで、「Webhooks --> Ratoc赤外線コマンド送信」というアプレットを2種類作成します。
家電リモコンの制御コードには、非ソニータイプとソニータイプがあり、IFTTTのRatoc赤外線コマンド送信は個別に準備が必要です。
最後の赤外線データの欄は、Add ingredientから、Value1を選択してください。
こうすることで、PythonからWebhook経由でリモコンコードを受け取る事ができます。
ソニーの機器でなくてもソニータイプの制御コードを使用していることがありますので、アプレットは2種類作成するようにしてください。
ここでは、
- living_send0(非ソニー用)
- living_send1(ソニー用)
という2つのイベントを作成しました。2つのイベント名をメモメモ
家電リモコンの制御コード取り出し
スマホの家電リモコンアプリで、制御したいwfirexを選択、「リモコンデータ受け渡し」を選択して、「エクスポート」を選択、「メールで送信」を選択して、自分宛てに送信します。
届いたメールに添付されている、export.xmlをPythonコードと同じフォルダにコピーしておきます。
複数台のwfirexがある場合は、xmlのファイル名が重複しないように変更しておきます。
保存したxmlファイル名をメモ
Pythonの準備
実行環境
Raspberry PI Zero WのPython3.5で動作を確認しています。
print文などを書き換えればPython2でも動くのではないでしょうか。
requestsはpipで取得してください。
python3のpipを実行する場合は、sudo python3 -m pip install requestsなどとしてください。(venvなどを使っていない場合)
Pythonコード
ここまででメモしておいた情報を、下記のPythonコードの「wfirex = Wfirex(〜」行の各パラメータに置き換えます。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import requests
class Wfirex:
def __init__(self, xml_filename, eventid0, eventid1, ifttt_key):
self.filename = xml_filename
self._read_xml(self.filename)
self._eventid0 = eventid0
self._eventid1 = eventid1
self._ifttt_key = ifttt_key
def _read_xml(self, filename):
self.tree = ET.parse(filename)
self.root = self.tree.getroot()
def reload_xml(self):
self._read_xml(self.filename)
def enum_remocon(self):
ret_list = []
for child in self.root:
for child2 in child:
for child3 in child2:
if child3.tag == "remoconname":
ret_list.append(child3.text)
return ret_list
def enum_button(self, remocon_name):
ret_list = []
for child in self.root:
skip_node = None
for child2 in child:
if skip_node == True:
break
for child3 in child2:
if child3.tag == "remoconname":
if child3.text == remocon_name:
skip_node = False
else:
skip_node = True
break
if skip_node == False:
for child4 in child3:
if child4.tag == "buttonname":
ret_list.append(child4.text)
return ret_list
def get_code(self, remocon_name, button_name):
for child in self.root:
skip_node = None
for child2 in child:
if skip_node == True:
break
for child3 in child2:
if child3.tag == "remoconname":
found_button = None
if child3.text == remocon_name:
skip_node = False
else:
skip_node = True
break
if skip_node == False:
for child4 in child3:
if child4.tag == "buttonname":
if child4.text == button_name:
found_button = True
else:
found_button = False
if child4.tag == "format":
if found_button == True:
format = child4.text
if child4.tag == "code":
if found_button == True:
code = child4.text
return {'format': format, 'code': code}
logging.info("code not found.")
return None
def send_ifttt(self, remocon_name, button_name):
ret = self.get_code(remocon_name, button_name)
if ret is not None:
payload = {"value1": ret["code"]}
eventid = self._eventid0 if ret["format"] == "0" else self._eventid1
url = "https://maker.ifttt.com/trigger/" + eventid + "/with/key/" + self._ifttt_key
response = requests.post(url, data=payload)
return response
return None
def main():
#事前に準備した、xmlファイル名、IFTTTイベント名(2種類)、IFTTT key名を設定する。
wfirex = Wfirex("export.xml", "living_send0", "living_send1", "your IFTTT key")
#リモコン名、ボタン名でsend_iftttをコールすると、数秒後にwfirexから信号が発信されます。
ret = wfirex.send_ifttt("エアコンリビング", "運転停止")
print(ret)
sys.exit()
if __name__ == '__main__':
main()
使い方と注意点
send_iftttをコールしている行の、リモコン名とボタン名を実行したい制御に書き換えて実行します。
コマンドライン引数を受け取るように変更して、CLIツールにしてシェルスクリプトから呼び出したり、
APIサーバ化すると便利ではないでしょうか。こちらではMQTTと組み合わせています。
エアコンはボタン名がスマホ上の家電リモコンアプリでの表示と異なるようなので、xmlをツールやブラウザ読むか、enum_button("リモコン名称")を実行してボタン名を確認してみてください。未検証ですが、エアコンの動作温度別のボタンも定義されているようです。
反省点
xmlのデータ検索のやり方がかっこ悪いです。findも試したけれど、しっくりきませんでした。
もしくは、xmlのデータ検索に若干時間がかかるので、サーバ化するなら読み込み時に辞書型に変換してしまった方が良いかも。