ADRSIRでボタン登録できるのは10個なので操作したい機器が増えてくると直ぐにパンクする。必然的に、それぞれの機器のリモコンデータを保持して、その中から任意のコマンドを実行したくなってくる。そこで、機器毎のリモコンデータ保持とコマンド送信ができるプログラムを作ってみた。
フォルダ構成はプログラムフォルダをルートとして、kiki、macro、utilsのサブフォルダを作成する前提で以下の例やコードを記述している。
(プログラムフォルダ)
kiki
macro
utils
【リモコンデータの保持方法】
各機器のリモコンデータ保持はyaml形式で保持することにした。
書式は下記の通り。
機能名:リモコンコード
※リモコンコードはIR-remocon02-commandline.pyで読み込みコマンドで出力したコード。
メーカー提供の「赤外線データ20171225.csv」から作成してもいいか。
例)
kiki/tv.yaml このように機器毎にyamlファイルを用意する。
#
# テレビのリモコンデータ
#
電源: "0001A1001900130017003C001700140018003B001700130017003C001700140017003C0017003C001700140017003C001700130017003C001700140017003C0017001300170014001700130017003C0018003B0018003C0017001300170014001700130017003C0017003C0017001400170013001700140017003C0017003C0017003C001700CD034801A1001900130017003C001700140018003B001700130017003C001700140017003C0017003C001700130018003C001700130017003C001700140017003C0017001300170014001700130018003B0018003B0018003C0018001200170014001800120017003C0017003C0017001400170013001700140017003C0017003C0017003C001700CD034801A1001900130017003C001700140017003C001700130017003C001700140016003D0017003C001700130018003C001700130017003C001700140017003C0017001300170014001700130017003C0017003C0018003C0017001300170014001700130017003C0017003C0017001400170013001700140017003C0017003C0017003C001700CD034801A1001900130017003C001700140017003C001700130017003C001700140017003C0017003C001700130018003C001800120017003C001700140017003C0017001300170014001700130017003C0017003C0017003D0017001300170014001700130017003C0017003C0017001400170013001700140017003C0017003C0017003C001600CE034801A1001800140017003C001700140017003C001700130017003C001700140017003C0017003C001700130018003C001700130017003C001700140017003C0017001300170014001700130017003C0017003C0019003B0017001300170014001700130017003C0017003C0017001400170013001700140017003C0017003C0017003C0017004205"
【リモコンデータ管理プログラム】
要求のあった機器のリモコンデータ(yaml形式)を取得するプログラムは下記のようにした。
utils/cmdsbinder.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# 各種機器のリモコンデータ管理プログラム
#
import yaml, codecs, os, inspect
# インストールルートディレクトリ取得
irdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# リモコンデータ格納ディレクトリ
kakunop = '/kiki/'
# リモコンデータ拡張子
ext = '.yaml'
# リモコンデータのロード
def load_remocon_data():
# 呼び出し元の関数名をリモコンデータ名とする
mname = inspect.currentframe().f_back.f_code.co_name
return load_remocon_data_internal(mname)
# リモコンデータのロード
def load_remocon_data_internal(kiki):
with codecs.open(irdir + kakunop + kiki + ext, 'r', 'utf-8') as fs:
rdata = yaml.load(fs)
return rdata
# 機器コード指定してリモコン情報取得
def get_rdata(kiki):
return load_remocon_data_internal(kiki)
# テレビリモコン情報取得
def tv():
return load_remocon_data()
# アンプリモコン情報取得
def amp():
return load_remocon_data()
# ビデオ1リモコン情報取得
def video1():
return load_remocon_data()
# ビデオ2リモコン情報取得
def video2():
return load_remocon_data()
# HDMI切替器リモコン情報取得
def hdmik():
return load_remocon_data()
【リモコンコマンド送信プログラム】
リモコンコマンドを送信するプログラムは下記のようにした。
IR-remocon02-commandline.pyの送信部分のみ切り出した。
utils/remocon.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# リモコン送信プログラム
#
import smbus
# コネクションオブジェクトを取得
bus = smbus.SMBus(1)
# スレーブアドレス
SLAVE_ADDRESS = 0x52
# コマンド
# 送信データ長の書き込み
W2_data_num_write = 0x29
# 送信データの書き込み
W3_data_write = 0x39
# 送信データの送信開始
T1_trans_start = 0x59
# リモコンコマンド送信
def command_soshin(soshin_data):
# 送信データ整形
str_tmp = ""
int_tmp = []
for i in range(int(len(soshin_data) / 2)):
str_tmp = soshin_data[i * 2] + soshin_data[i * 2 + 1]
int_tmp.append(int(str_tmp, 16))
# 送信データ長の書き込み
data_num = int(len(int_tmp) / 4)
data_numHL = [0x31, 0x32] # 初期化
data_numHL[0] = int(data_num / 256)
data_numHL[1] = int(data_num % 256)
bus.write_i2c_block_data(SLAVE_ADDRESS, W2_data_num_write, data_numHL)
# 送信データの書き込み
data = [0x31, 0x32, 0x33, 0x34] # 初期化
for i in range(data_num):
data[0] = int_tmp[i * 4 + 0]
data[1] = int_tmp[i * 4 + 1]
data[2] = int_tmp[i * 4 + 2]
data[3] = int_tmp[i * 4 + 3]
bus.write_i2c_block_data(SLAVE_ADDRESS, W3_data_write, data)
# 送信データのリモコン送信開始
null_data = [0x00] # ダミー
bus.write_i2c_block_data(SLAVE_ADDRESS, T1_trans_start, null_data)
【マクロプログラム】
上の2つのプログラム利用したリモコンマクロ。
下記の例はテレビ、アンプ、ビデオをオンするマクロ。
これをNode-REDなどから呼び出して利用する。
状態をもったり細かい制御がしたくなったらこちらを利用していく予定。
今のところ下記の汎用のものでまかなえている。
例)
macro/m01_v1on.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# ビデオ1系のオン/オフ マクロ
#
from time import sleep
import sys, os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from utils import cmdsbinder, remocon
# リモコン情報取得
tv = cmdsbinder.tv()
amp = cmdsbinder.amp()
video1 = cmdsbinder.video1()
hdmik = cmdsbinder.hdmik()
# ビデオ1とテレビとアンプを付け、切替器を入力1へ
remocon.command_soshin(tv['電源'])
sleep(0.5)
remocon.command_soshin(amp['電源'])
sleep(0.5)
remocon.command_soshin(video1['電源'])
sleep(0.5)
remocon.command_soshin(hdmik['入力1へ'])
【汎用コマンド送信プログラム】
こちらはNode-REDからの引数で任意のリモコンコマンドを送信する目的で作成したプログラム。
シェルとかから呼んでも問題ないはず。
特にプログラムで細かな制御をする必要のないものはマクロを作成するのではなく、これを利用すればいい。
utils/commander.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# 汎用コマンド処理
#
# 引数を解釈して0.5秒おきにコマンドを送信する
#
# 引数は機器、コマンド、機器、コマンドと並んでいる前提
#
from time import sleep
import sys, os
import cmdsbinder, remocon
args = sys.argv
rdatas = {} # リモコン情報キャッシュ
for i in range(1, len(args) - 1, 2):
# 対応するリモコン情報取得
kiki = args[i]
if kiki in rdatas:
rdata = rdatas[kiki]
else:
rdata = cmdsbinder.get_rdata(kiki)
rdatas[kiki] = rdata
# 対応するリモコン信号送信
remocon.command_soshin(rdata[args[i + 1]])
# 待機
sleep(0.5)
・Node-REDから利用する場合
先ずは、injectノードを以下のようなJSON形式で作成する。
JSONの内容は機器(kiki)とコマンド(cmd)を持ったオブジェクトの配列。
例)
[
{
"kiki": "video1",
"cmd": "電源"
},
{
"kiki": "hdmik",
"cmd": "入力1へ"
}
]
次にfunctionノードを以下のようにして、上のJSONから引数生成する。
例)
var cmds = msg.payload;
var hikisu = "";
for(i = 0; i < cmds.length; i++){
hikisu = hikisu + " '" + cmds[i].kiki + "'";
hikisu = hikisu + " '" + cmds[i].cmd + "'";
}
msg.payload = hikisu;
return msg;
最後にexecノードでコマンドをutils/commander.py、引数をmsg.payloadにして実行すれば、上のJSONで指定したコマンドがリモコン送信される。
これを作って操作ボタンはそれほど利用する必要がなくなったので、7~10のボタンはリモコンデータ収集用のフリーのボタンとして位置付けるようになった。
各機器のリモコンデータを管理し、それらの中から任意のコマンドを実行できる仕組みを作らないと真の学習リモコンとはいえない。やっと学習リモコンらしくなってきた。改善したい点は、機器毎のyamlをもう少し簡単に対話形式で作成する機能を作ってみたい。
このページはこれらの動作を保証するものではありません。同様のことをトライされる場合は自己責任でお願致します。