Nature Remoに存在しないボタンを登録する
我が家の照明は、リモコンで操作できる。 なので、Nature Remoからももちろん操作できるのだが、リモコンにあるボタンはON/OFFを切り替えるボタンしかない。 そのため、明示的にONにしたり、OFFにしたりすることはできない。 しかし、同じメーカーの他の照明リモコンを見てみるとONのボタンとOFFのボタンが存在している。 これは推測だが、おそらくプロトコル上、実装上存在しているが、廉価なモデルのリモコンのため省略されていると考えられる。 そこで、Nature RemoのAPIを駆使し、物理的に存在しないが、プロトコル上、実装上存在していると考えられるONボタンとOFFボタンを調査し、Nature Remoから照明のONとOFFを操作できるようにする。

Nature RemoのIPアドレスを調べる
IPアドレスがわからないと、Local APIを叩けないので調べる。
まず、Nature Remoと同じネットワーク(LAN)につなぐ。
つぎに、mDNSでサービスタイプから、インスタンス名を引く。
$ dns-sd -B _remo._tcp
Browsing for _remo._tcp
DATE: ---Sat 12 Jan 2019---
13:33:50.261 ...STARTING...
Timestamp A/R Flags if Domain Service Type Instance Name
13:33:50.413 Add 3 5 local. _remo._tcp. Remo-4A8BDD
13:33:50.413 Add 2 5 local. _remo._tcp. Remo-9086AB
リビングルームとダイニングルームのNature Remoが見つけられる。
最後に、mDNSでインスタンス名からIPv4アドレスを引く。
$ dns-sd -G v4 Remo-4A8BDD.local
DATE: ---Sat 12 Jan 2019---
13:40:19.941 ...STARTING...
Timestamp A/R Flags if Hostname Address
TTL
13:40:19.942 Add 2 5 Remo-4A8BDD.local. 192.168.0.18 120
これでリビングルームのNature RemoのIPアドレスがわかった。
受信した信号を見る
Nature Remoに対して、照明リモコンのON/OFFボタンを押して、赤外線信号を送信する。
Nature Remo Local APIのmessage APIで、Nature Remoが受信した信号を見る。
$ curl -s -X GET 'http://192.168.0.4/messages' -H 'X-Requested-With: curl'
{"format":"us","freq":37,"data":[4675,2627,564,959,572,1850,563,1863,562,958,564,1860,571,1849,566,956,575,949,564,959,571,1849,574,1850,575,952,571,1850,570,1854,572,1849,564,961,571,1847,568,1859,568,951,566,955,573,951,565,955,564,965,562,1854,576,948,567,956,565,957,572,950,571,951,571,953,570,950,572,945,572,16480,4670,2633,565,959,562,1860,572,1848,574,952,571,1849,573,1851,573,949,573,950,564,956,575,1849,576,1850,562,959,575,1848,572,1853,562,1857,566,959,572,1848,567,1859,570,951,571,953,563,956,565,959,570,951,567,1858,571,949,573,951,564,957,572,949,575,949,564,955,574,948,574,944,566,16484,4682,2624,571,951,564,1859,564,1858,572,952,571,1849,569,1855,573,951,571,949,566,960,562,1857,577,1849,570,951,565,1861,569,1850,574,1849,576,946,575,1849,573,1850,571,953,565,955,573,950,574,947,575,946,574,1852,570,953,570,949,566,959,563,956,573,952,563,959,564,960,569,943,574]}
data配列の各要素は、赤外線ONの期間、OFFの期間、ONの期間、OFFの期間、、、、を表している。 厳密には、これは38kHzの変調をデコードしたあとの結果である。実際にはONの期間は38kHzの変調信号になっている。
プロトコルの詳細は書きを参照されたい。
そして、この結果を、ぱっと見た感じ、
NECフォーマット
T=560us
リーダーコード: ON:4T, OFF:8T,
ビット0: ON: 1T, 1.7T
ビット1: ON: 1T, 3.4T
であることがわかる。
プログラムに噛ませて赤外線信号を16進4バイトのデータにデコードする。
$ cat decode.py
import sys
import json
obj_txt = sys.stdin.read()
obj = json.loads(obj_txt)
bit_array = [int(not x < 1100) for x in obj['data'] if 900 < x < 2000]
byte_array = [sum([x<<i for (i, x) in enumerate(x)]) for x in zip(*[iter(bit_array)]*8)]
print(' '.join(["{:02x}".format(x) for x in byte_array]))
$ curl -s -X GET 'http://192.168.0.4/messages' -H 'X-Requested-With: curl' | python decode.py
36 76 83 00 36 76 83 00 36 76 83 00
これで、データがわかった。これをすべてのボタンに対して行い、ボタンに対応するデータの一覧を得る。
(ch1)
Button | Data |
---|---|
豆球 | 36 76 48 00 |
オフタイマー60 | 36 76 80 00 |
オフタイマー30 | 36 76 82 00 |
ON/OFF | 36 76 84 00 |
明るく | 36 76 86 00 |
暗く | 36 76 88 00 |
(ch2)
Button | Data |
---|---|
豆球 | 36 76 47 00 |
オフタイマー60 | 36 76 8f 00 |
オフタイマー30 | 36 76 81 00 |
ON/OFF | 36 76 83 00 |
明るく | 36 76 85 00 |
暗く | 36 76 87 00 |
これらの結果から、おそらく3バイト目が照明の各ボタンの操作に対応していると推察できる。 これから、この3バイト目を書き換えて、赤外線を送信し、ONとOFFに対応するデータを探す。
受信した信号を見る
プログラムに噛ませて16進4バイトのデータを赤外線信号にデコードする。 そして、Nature Remo Local APIのmessage APIで、照明に対して赤外線を送信する。
$ cat encode.py
import sys
import json
byte_array = [int(x, 16) for x in sys.stdin.read().split(' ')]
data = [4668,2636]
for x in byte_array:
for i in range(8):
b = (x>>i)&1
if b == 1:
data += [562, 1877]
else:
data += [562, 951]
data += [548, 16504]
obj = {
'format': 'us',
'freq': 37,
'data': data,
}
obj_txt = json.dumps(obj)
sys.stdout.write(obj_txt)
$ echo "36 76 83 00" | python encode.py | curl -X POST 'http://192.168.0.4/messages' -H 'X-Requested-With: curl' -d @-
無事照明が点いた(消えていたのでON/OFFボタンで点灯した)。
3バイト目を書き換えてみて、動作するボタンと、動作内容の一覧を得る。
(ch1)
Button | Data |
---|---|
ON | 36 76 42 00 |
OFF | 36 76 4a 00 |
(ch2)
Button | Data |
---|---|
ON | 36 76 41 00 |
OFF | 36 76 49 00 |
41がON、49がOFFに対応していることがわかった。 これから、Nature Remo Cloud APIを使って、Nature Remoにボタンを登録する。
信号を登録する
まず、Nature Remo Global APIのアクセス用のトークンを生成し、取得する。以降トークンはXXXX(伏せ字)と表す。
次に、Nature Remo Global APIののappliances APIで、機器の一覧を見る。
$ curl -s -X GET "https://api.nature.global/1/appliances" -H "Authorization: Bearer XXXX" | python -mjson.tool
(snip)
{
"id": "YYYY",
"device": {
"name": "Living Room",
"id": "XXXX",
(snip)
},
"model": null,
"type": "IR",
"nickname": "Living Room Light",
"image": "ico_light",
"settings": null,
"aircon": null,
"signals": [
(snip)
]
},
(snip)
機器のIDがわかる。以降機器のIDはYYYY(伏せ字)とする。
最後に、Nature Remo Global APIののsignals APIで、赤外線信号を登録する。
$ echo "36 76 41 00" | python encode.py | urlencode
%7B%22format%22%3A%20%22us%22%2C%20%22freq%22%3A%2037%2C%20%22data%22...5D%7D
$ curl -s -X POST "https://api.nature.global/1/appliances/YYYY/signals" -H "Authorization: Bearer XXXX" -d "message=ZZZZ&image=ico_on&name=ON"
{"id":"XXXX","name":"ON","image":"ico_on"}
$ echo "36 76 49 00" | python encode.py | urlencode
%7B%22format%22%3A%20%22us%22%2C%20%22freq%22%3A%2037%2C%20%22data%22...5D%7D
$ curl -s -X POST "https://api.nature.global/1/appliances/YYYY/signals" -H "Authorization: Bearer XXXX" -d "message=ZZZZ&image=ico_off&name=OFF"
{"id":"XXXX","name":"OFF","image":"ico_off"}
無事、ONのボタンと、OFFのボタンが登録された。
ぱちぱちぱち