レオリモコンとアレクサを連携させる[レオリモコン操作編]
前回の概要編に引き続き,レオリモコンとアレクサの連携についてです.今回はいきなり最終端のレオリモコン操作部分について書きたいと思います.アレクサに出した指示は,めぐりめぐってこの部分を実行することになります.
概要編で触れたとおり,レオリモコンはIRemoconWifiと同様にtelnet経由で操作することができます.IRemoconはレオリモコンに比べればずっとメジャーなので,すでに実装されている方はちらほらいるみたいです.
node-iRemocon つくった - 凹みTips
様のjava script版など.
正直この完成度を超えられる気はしないのですが,勉強も兼ねて使い慣れたPythonで書いてみました.
import telnetlib import traceback class LeoRemoconController: def __init__(self,targetIP,port=51013): self.targetIP=targetIP self.__PORT=port def testConnection(self): rets=self.sendCommand("*au") if(rets[0] != "ok"): raise ValueError(rets) def sendCommand(self,cmd,*values): self.tn.write(cmd.encode('ascii')) for value in values: self.tn.write(b';' + value.encode("ascii")) self.tn.write(b"\r\n") timeout=1 if cmd=="*ic": timeout=60 result,values=self.waitUntilReturn(timeout=timeout) #if cc command succeed, returns previous command(ic)'s result. #So read and waste it. if cmd=="*cc" and ret[0]=="ok": self.waitUntilReturn() return result,values def waitUntilReturn(self,timeout=1): retTupple = self.tn.expect([b'(ok.*|err.*)\r\n'],timeout) if(retTupple[0] == -1): raise ConnectionError() ret = retTupple[1].group(1).decode('ascii') result,*values=ret.split(";") return result,values def openTelnet(self): self.tn = telnetlib.Telnet(self.targetIP,self.__PORT) def closeTelnet(self): self.tn.close() #executes at start of "with" syntax def __enter__(self): try: self.openTelnet() self.testConnection() except: traceback.print_exc() self.closeTelnet() raise ConnectionError() return self #executes at end of "with" syntax def __exit__(self,type,balue,traceback): self.closeTelnet()
で,これを次のように呼んで使います.
if __name__ == "__main__": print("test LeoRemocon") ip="10.151.224.48" #set your LeoRemocon's IP address with LeoRemoconController(ip) as lrc: result,values = lrc.sendCommand("*ic","lightOn") #set command print(result)
with構文でtelnetのopenとcloseを管理しているのが地味なこだわりポイントですね.
レオリモコンへのアクセスはローカルセグメント内に限定されているため基本タイムアウトを1秒に設定していますが,icコマンド(信号の登録)のみ60秒に設定しています.またレオリモコンからの応答はリストにして返しているのですが,ccコマンドだけ応答の形が異なるためif文で逃がしています.この辺りはゴミコード感がすごいですね.
エラー番号の意味についてはマニュアルを参照するしかありませんが,先の
node-iRemocon つくった - 凹みTips
様のコードの中にエラーコードとエラー内容の対応mapがありますので,これを使わせていただくとエラー内容の取得がはかどりそうです.ありがとうございます.
このままでは使いにくいので,レオリモコンへの信号の登録や実行などをブラウザからできるようにWebページを作ろうとは思っているのですが,Webについてはど素人なのでそこそこ時間がかかりそうです.そちらについては形になり次第また書きたいと思います.