絖綛 N@i.jp  昨日:00036563
 今日:00024716
 総計:00075593
keywords
管理者専用
  Post   Add link   Control Panel 































新しいトピック
最新:04/16 19:55


新しいコメント
最新:07/28 16:47






管理人へMAIL

プライバシーポリシー

Raspberry Pi から IRKitを操作する。三歩め

Bug Fixと少し機能追加


 今週は少し遅い夏休みだったのだけど、夏休みに入ったとたん天気が不安定になり、W台風まで発生。体調まで少しおかしくなり、おかげで何処にも出掛けられないまま明日で夏休みが終わってしまう。あ〜ぁ・・・


 何ともノロノロとしたペースでしか進まないIRKitを操作するプログラムですが、バグ修正と少しだけ機能追加しました。

  • 初回起動時などのIRKitの情報が保存されていない("~/.irkit.d/irkit.save" ファイルが存在しない)状態で赤外線信号の取得(GET)を行うと、必ずNo dataになる不具合の修正。
    この修正のため、"~/.irkit.d/irkit.save" ファイルに保存する内容が変わってしまったので、一旦削除しておく必要があります。
  • MacのIRLauncherで取得、保存した赤外線信号ファイルを使えるようにしました。
    Raspberry Piで赤外線信号を一つ一つ取得せずとも、IRLauncherが "~/.irkit.d/signals/" 配下に作成した赤外線信号の.jsonファイルをRaspberry Piにコピーして使えます。(逆は試してないので分かりません^^;)
    赤外線信号ファイルの保存場所をIRLauncherと同じ "~/.irkit.d/signals/" 配下にしてあったのは、これが狙いなのでした。
  • 保存してある赤外線信号ファイルを削除するdeleteサブコマンドを追加しました。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
import urllib.request
from resolve_irkit import resolve_irkits
from socket import gethostbyname
import json
import argparse

save_dir = os.environ['HOME'] + '/' + '.irkit.d'    # Getした赤外線信号の保存先ディレクトリ名
make_filename = lambda signal_name: save_dir + '/signals/' + signal_name + '.json'

parser = argparse.ArgumentParser(description='Control IRKit')
parser.add_argument('-v', '--version', action='version', version='%(prog)s 0.2.0')
parser.add_argument('-V', '--verbose', action='store_true', default=False, help='verbose mode')
subparsers = parser.add_subparsers(dest='command')
# create the parser for the "get" command
parser_get = subparsers.add_parser('get', aliases=['read'], help='GET command')
parser_get.add_argument('ir_signal_name', action='store', help='IR signal name')
parser_get.add_argument('-a', '--address', nargs=1, action='store', default=None, dest='host',
                        metavar='address', help='IP address of IRKit device')
# create the parser for the "post" command
parser_post = subparsers.add_parser('post', aliases=['send'], help='POST command')
parser_post.add_argument('ir_signal_name', action='store', help='IR signal name')
parser_post.add_argument('-a', '--address', nargs=1, action='store', default=None, dest='host',
                         metavar='address', help='IP address of IRKit device')
# create the parser for the "show" command
parser_show = subparsers.add_parser('show', aliases=['view'], help='Show IR signal data')
parser_show.add_argument('ir_signal_name', action='store', help='IR signal name')
# create the parser for the "list" command
parser_list = subparsers.add_parser('list', help='Print list saved IR signal')
# create the parser for the "delete" command
parser_delete = subparsers.add_parser('delete', aliases=['remove'], help='Delete saved IR signal')
parser_delete.add_argument('ir_signal_name', action='store', help='IR signal name')
#
args = parser.parse_args()
verbose = args.verbose


class IRKit:
    '''Irkit class'''
    def __init__(self, host, port):
        self.url = 'http://' + host + ':' + port + '/messages'

    def get(self):
        '''最も新しい受信した赤外線信号を返す。'''
        with urllib.request.urlopen(url=self.url) as self.f:
            return self.f.read().decode('utf-8')

    def post(self, json_data):
        '''赤外線信号を送信する。'''
        with urllib.request.urlopen(url=self.url, data=json_data.encode('utf-8')):
            pass

def check_dir(path):
    '''pathディレクトリの有無を調べ、無い場合は作成する'''
    if os.path.exists(path):
        assert os.path.isdir(path), path + ' is not directory.'
    else:
        os.mkdir(path)

def search_irkit():
    '''BonjourでIRKitを探し、見つかったIRKitの情報を返却する'''
    irkits = resolve_irkits()
    assert irkits, 'No IRKit device'
    irkit = irkits[0]    # 最初に見つかったIRKit
    host    = irkit[0]
    address = gethostbyname(host)
    port    = str(irkit[1])
    return {'Host':host, 'IPaddress':address, 'Port':port}

def get_irkit_info():
    '''IRKit の情報辞書(IPアドレス,ポート番号,サーバ名)を返す'''
    save_file = save_dir + '/irkit.save'
    try:
        with open(save_file, mode='rt', encoding='utf-8') as f:
            irkit_info = json.load(f)
    except:
        irkit_info = search_irkit()
        with open(save_file, mode='wt', encoding='utf-8') as f:
            json.dump(irkit_info, f)
    else:
        # Check IRKit info.
        if irkit_info['IPaddress'] != gethostbyname(irkit_info['Host']):
            # IP address has changed
            irkit_info = search_irkit()
            with open(save_file, mode='wt', encoding='utf-8') as f:
                json.dump(irkit_info, f)
    if verbose:
        print('IRKit device: {0}'.format(irkit_info))
    return irkit_info

def get(address, port, signal_name):
    '''GET sub-command'''
    irkit = IRKit(address, port)
    data = irkit.get()
    if data:
        ir_data = json.loads(data)
        file_name = make_filename(signal_name)
        if verbose:
            print('{0} <= {1}'.format(file_name, ir_data))
        with open(file_name, mode='wt', encoding='utf-8') as f:
            json.dump(ir_data, f, indent=2, separators=(',', ': '))
    else:
        print('No data', file=sys.stderr)

def post(address, port, signal_name):
    '''POST sub-command'''
    file_name = make_filename(signal_name)
    with open(file_name, mode='rt', encoding='utf-8') as f:
        ir_data = json.load(f)
        if verbose:
            print('{0} => {1}'.format(file_name, ir_data))
        irkit = IRKit(address, port)
        irkit.post(json.dumps(ir_data))

def show(signal_name):
    '''Show sub-command'''
    file_name = make_filename(signal_name)
    with open(file_name, mode='rt', encoding='utf-8') as f:
        print('{0} = {1}'.format(file_name, json.load(f)))

def list(dir):
    '''List sub-command'''
    for file in os.listdir(dir):
        print(file.rstrip('.json'))    # ←ここバグってます

def delete(signal_name):
    '''Delete sub-command'''
    file_name = make_filename(signal_name)
    assert os.path.exists(file_name), 'The IR signal ' + signal_name + ' does not exist.'
    if verbose:
        print('delete '+file_name)
    os.remove(file_name)


def main():
    check_dir(save_dir)
    check_dir(save_dir + '/signals')

    if args.command == 'get' or args.command == 'read':
        if args.host:
            address, port = args.host[0], '80'
        else:
            info = get_irkit_info()
            address, port = info['IPaddress'], info['Port']
        get(address, port, args.ir_signal_name)
    elif args.command == 'post' or args.command == 'send':
        if args.host:
            address, port = args.host[0], '80'
        else:
            info = get_irkit_info()
            address, port = info['IPaddress'], info['Port']
        post(address, port, args.ir_signal_name)
    elif args.command == 'show' or args.command == 'view':
        show(args.ir_signal_name)
    elif args.command == 'list':
        list(save_dir + '/signals')
    elif args.command == 'delete' or args.command == 'remove':
        delete(args.ir_signal_name)
    else:
        pass

if __name__ == '__main__':
    main()

 勉強のため色々と試行錯誤している最中なので、まだまだバグがあります。(因にlistサブコマンドはバグってます。)少しずつPythonにも慣れてきましたので、もうちょっと洗練したプログラムにできるかも?


< 過去の記事 [ 8月の 全てのカテゴリ リスト ] 新しい記事 >

2015 calendar
8月
1
2345678
9101112131415
16171819202122
23242526272829
3031


掲示板
最新:08/15 17:19


GsBlog was developed by GUSTAV, Copyright(C) 2003, Web Application Factory All Rights Reserved.