音声認識による赤外線機器の操作 その 3【赤外線操作編】
どうも,筆者です.
音声認識も終わり,やっと赤外線操作ができる.ただし,ここで説明するのは,ADRSIR に向けた解説になるため,他の機器を使っている人は別サイトを参考にしてほしい.
以下のサイトを参考にさせていただいた.
Amazon Echoから赤外線リモコン機器(テレビ、照明など)をコントロールする(ラズベリー・パイ専用 学習リモコン基板 ADRSIRを使って) - Qiita
また,前回までの記事は以下にある.
workspacememory.hatenablog.com
前提
ここからは,プログラミングを行っていく.利用するライブラリが Python で書かれているため,Python を利用する.C 言語で開発しても良かったが,ライブラリを自分で作成するのは手間であるため,Python を利用することにした.
準備
まず,Raspberry Pi の電源を落とし,ADRSIR を GPIO ピンに接続する.利用するピンは決まっているため,他にも利用したいピンがある場合,ブレッドボードなどを用いて配線する. 筆者は,特に用途がなかった為,そのまま全部のピンを埋める形で接続した.
Raspberry Pi を起動後,以下のサイトから,「リモコンコードリスト(CSV)」をダウンロードする.また,有志の方が作成したライブラリを GitHub からダウンロードする.
http://bit-trade-one.co.jp/support/download/
GitHub - you0708/adrsir: 赤外線学習リモコン基板 ADRSIR 関連スクリプト
# GitHub からダウンロードする
git clone https://github.com/you0708/adrsir.git
ダウンロードした「リモコンコードリスト(CSV)」は,adrsir に保存する.今後は,adrsir ディレクトリで作業する.
赤外線信号の作成
ADRSIR を利用して赤外線信号を登録する.ただ,筆者の環境の場合,テレビと電気は「リモコンコードリスト(CSV)」内にあったため,そのまま利用した.
ただ,どれがどれに対応するか分からなかったため,会社と対象機器の動作で grep をかけて,順番に試した.その手順を示す.ここでは,「ソニーのテレビ」を対象とする.また,「リモコンコードリスト(CSV)」は,「infrared_data_0171225.csv」という名前に変更して扱っている.
対象データの抽出
まず,ソニーのテレビに対し,対象機器の動作として,「電源」を抽出する.
~/adrsir $ cat infrared_data_0171225.csv | grep "ソニー" | grep "デジタルテレビ" | grep "電源" # === 出力結果 === # "ソニー","デジタルテレビ1","電源","..." # "ソニー","デジタルテレビ2","電源","..." # "ソニー","デジタルテレビ3","電源","..."
データをファイルへ書き込む
次に,抽出したリストから赤外線信号を取り出し,ファイルに保存する Shell Script を作成する.ここでのファイル名は createIrDataToFile.sh とした.
#!/bin/bash # createIrDataToFile.sh count=1 cat infrared_data_0171225.csv | grep "ソニー" | \ grep "デジタルテレビ" | grep "電源" | sed -e 's|"||g' | -e "s|,| |g" \ while read a b c d; do outName=machine${count}.dat echo ${b} "->" ${outName} echo ${d} > ${outName} count=$(expr ${count} \+ 1) done
Python スクリプトの実行
後は,作成した Shell Script を実行し,生成されたファイルを順に Python スクリプトで実行する.以下に例を示す.
~/adrsir $ chmod +x createIrDataToFile.sh ~/adrsir $ ./createIrDataToFile.sh ~/adrsir $ python3 ir_control.py send machine1.dat ~/adrsir $ python3 ir_control.py send machine2.dat ~/adrsir $ python3 ir_control.py send machine3.dat
筆者は実行も面倒だったため,createIrDataToFile.sh を exeIrData.sh として作成した.スクリプトの中身も以下のように変更した.
#!/bin/bash # exeIrData.sh corpName="ソニー" machine="デジタルテレビ" operation="電源" outName=tmp.$$ cat infrared_data_0171225.csv | grep "${corpName}" | \ grep "${machine}" | grep "${operation}" | sed -e 's|"||g' | -e "s|,| |g" \ while read a b c d; do echo ${b} "->" ${outName} echo ${d} > ${outName} python3 ir_control.py send ${outName} sleep 3 done rm -f ${outName}
JSON ファイルの生成
対象機器が分かれば,後は関連する信号をすべて出力すればよい.ただ,「ir_control.py」をそのまま利用するとファイル数が膨大になるため,JSON 形式でまとめることにした.
まず,「リモコンコードリスト(CSV)」から対象機器の信号一覧を取得する.ここでは,「ソニーのデジタルテレビ2」を利用する場合を考える.処理自体は難しくなく,grep コマンドで該当のものをすべて抽出すればよい.
cat infrared_data_0171225.csv | grep "ソニー" | grep "デジタルテレビ2" | sed -e 's|"||g' > ret.data
次に,抽出したデータをコマンドとして扱えるように名前を付ける.手間ではあるが,日本語をそのまま扱うのは後々辛そうであるため,ここで変換しておく.例えば,「電源」は「power」,「音量」は「volume」というように名前を付ける.
最後に,以下のような Python スクリプトを作成し,JSON 形式に変換する.ここで,スクリプト名は createJson.py とした.
#!/usr/bin/python3 #coding: utf-8 # createJson.py import json import sys, os def createDictData(filename): listData = [] for line in open(filename): data = line.replace('\n', '').split(',') listData.append((data[2], data[3])) return dict(listData) if __name__ == "__main__": argv = sys.argv argc = len(argv) if argc < 2: print('Usage: {0} [infra red data file]'.format(argv[0])) else: filename = argv[1] rootName, _ = os.path.splitext(filename) dicData = createDictData(filename) with open(rootName + '.json', 'w') as fout: json.dump(dicData, fout)
変換方法
python3 createJson.py ret.data # ret.json が生成される
この JSON ファイルは,名前(power や volume)をキー(key)とし,赤外線信号を値(val)として持つ.Python で読み込めば,連想配列として利用できる.
赤外線信号の送信
JSON 形式で保存したファイルを用いて,赤外線を送信する.そのための Python スクリプトを以下に示す.ファイル名は irControl.py とした.
#!/usr/bin/python3 #coding: utf-8 # irControl.py import adrsirlib import sys, json # =============== # display command # =============== def display_list(jsonFile): try: with open(jsonFile, 'r') as fin: dictData = json.load(fin) print("print json file data") listData = [key for key, _ in dictData.items()] for i, key in enumerate(sorted(listData)): print("No.{0:03d}: {1}".format(i, key)) except json.JSONDecodeError as e: print('JSONDecodeError: ', e) # ===== # Usage # ===== def usage(): print("\nUsage: {0} <send|list> [json file] [options...]\n".format(__file__)) print(" command") print(" send : send data to ADRSIR") print(" ex) {0} send [json file] [send command]".format(__file__)) print(" list : print json file data") print(" ex) {0} list [json file] all".format(__file__)) # =========== # execute cmd # =========== def executeCmd(jsonFile, cmd): retVal = 1 try: with open(jsonFile, 'r') as fin: jsonData = json.load(fin) try: adrsirlib.write(jsonData[sendCmd]) retVal = 0 except: print('command not found') except json.JSONDecodeError as e: print('JSONDecodeError: ', e) if __name__ == '__main__': argv = sys.argv argc = len(argv) if argc < 4: usage() else: command = argv[1] jsonFile = argv[2] if command == 'send': sendCmd = argv[3] executeCmd(jsonFile, sendCmd) elif command == 'list': display_list(jsonFile) else: usage()
実行方法
python3 irControl.py list ret.json all # コマンドの一覧表示 python3 irControl.py send ret.json power # 電源ボタンの赤外線信号を送信
以上で,赤外線機器の操作ができるようになった.後は,音声認識結果と組み合わせればよい.次回以降で,組み合わせ方を解説する.