チラシのうら

レゴとか、工作とか。

IRKitってすばらしい! その3

注意

過去の記憶を遡って記載しています。20150625記

スマホアプリ

Android版、作りました。
f:id:tetunori_lego:20150625064936j:plain

仕様

  • BD Player、電気、テレビ、オーディオエアコンの全コマンド実行可能。
  • タブビュー&縦スクロールで快適な操作性を実現。
  • 各種マクロ対応
    • おやすみスイッチ
    • おでかけスイッチ
    • オーディオ向け、簡単Bluetoothペアリング
  • (バグ有り)Widget対応
  • (未実装)NFCシールにスマホかざしたら任意のコマンド発行。

画面仕様

BD Player

f:id:tetunori_lego:20150625065705j:plain
早送りとかは、タップ操作だとキツイです(笑)

電気

f:id:tetunori_lego:20150625065752j:plain
楽しくて、わざわざ寝室の布団の中から消す(そして、リビングを覗いて、電気が消えたか確認する)ブームが家族内で発生。

テレビ

f:id:tetunori_lego:20150625065908j:plain
f:id:tetunori_lego:20150625070147j:plain
家のテレビはネットワーク越しのリモコンに対応していますが、スマホ上での認識に、数秒かかります。IRKitは一瞬でコマンド発行できるので便利。

オーディオ

f:id:tetunori_lego:20150625070204j:plain
家のオーディオは、NFC搭載しておらず、スマホタブレットの音を出したいときは、少し面倒。リモコン経由でBluetoothのペアリングを開始できるだけですごい便利。

エアコン

f:id:tetunori_lego:20150625070223j:plain
これだけはクセモノでした。
毎回のコマンド発行時に、温度・湿度・時間設定などをのせているようで、ほんとんど解析出来ず。幾つかの決めうち設定しか出来ませんでした。

マクロ

f:id:tetunori_lego:20150625070234j:plain 自分で作っておいてなんですが、めっちゃ便利。
一見、使えそうなNFC機能は未実装です。

Widget

f:id:tetunori_lego:20150625073855j:plain
Widget設定すると、
f:id:tetunori_lego:20150625074254j:plain
のようにホーム画面から直接リモコンコマンドを発行出来ます。

詳細

アイコン

このイケているアイコンは全て さんからダウンロードしました!
iOS向け?のアイコンを多用しています。

つまずいた所

Android上でのBonjour

APIはあります。NsdManager
言われた通りにやってはいるのですが、OSのせいなのか端末のせいなのか、10回やったら1回は失敗しました。 これに失敗すると、IRKit側がハマる事が多く、電源抜き差しが必要となり、使い物になりません。

というわけで、毎回の機器検索はあきらめて、初回起動時に設定値として覚えることにしました。
凝りに凝った機器検索UIは、ほとんど使われませんでした…
f:id:tetunori_lego:20150625074715j:plain
数百msec位表示されますけど…

コードはこちら

さすがに量が多くて、全部はのせられないので、IRKit制御回りのコードを一部だけ。

IRKitManager.java

package IRKit;

import android.content.Context;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;

import android.util.Log;

public class IRKitManager {
    // For log
    private final static String TAG = IRKitManager.class.getSimpleName();

    // For Bonjour communication
    private NsdManager.DiscoveryListener discoveryListener;
    private NsdManager.ResolveListener resolveListener;
    private NsdManager mNsdManager;
    private static final String DNS_TYPE = "_irkit._tcp";
    
    // For IRKit
    private IRKitDiscoveryListner mListner = null;
    private IRKitDevice mIRKitDevice;
    
    // Others
    private Context mContext;
    
    // Constructor
    public IRKitManager( Context context ){
        Log.d(TAG, "IRKitManager constructor");
        this.mContext = context;
        setUpIRKitDiscoveryInfo();      
    }

    // Start Discovery IRKit
    public void startDiscoverIRKit( IRKitDiscoveryListner listner ){
        mListner = listner;
        if(mNsdManager!=null){
            mNsdManager.discoverServices(DNS_TYPE, NsdManager.PROTOCOL_DNS_SD, discoveryListener);
        }
    }

    // Stop Discovery IRKit
    public void stopDiscoverIRKit(){
        mListner = null;
        if(mNsdManager != null){
            mNsdManager.stopServiceDiscovery(discoveryListener);
        }
    }

    // Setup IRKit Discovery Information
    private void setUpIRKitDiscoveryInfo() {
        Log.d(TAG, "Setting up Bonjour");
        discoveryListener = new NsdManager.DiscoveryListener() {
 
            @Override
            public void onStopDiscoveryFailed(String serviceType, int errorCode) {
                // TODO Auto-generated method stub
 
            }
 
            @Override
            public void onStartDiscoveryFailed(String serviceType, int errorCode) {
                // TODO Auto-generated method stub
 
            }
 
            @Override
            public void onServiceLost(NsdServiceInfo serviceInfo) {
                // TODO Auto-generated method stub
 
            }
 
            @Override
            public void onServiceFound(NsdServiceInfo serviceInfo) {
                Log.d(TAG, "Service resolved: " + serviceInfo.getServiceName() + " host:" + serviceInfo.getHost() + " port:"
                        + serviceInfo.getPort() + " type:" + serviceInfo.getServiceType());
                mNsdManager.resolveService(serviceInfo, resolveListener);
            }
 
            @Override
            public void onDiscoveryStopped(String serviceType) {
                // TODO Auto-generated method stub
 
            }
 
            @Override
            public void onDiscoveryStarted(String serviceType) {
                // TODO Auto-generated method stub
 
            }
        };
        
        mNsdManager = (NsdManager) mContext.getSystemService(Context.NSD_SERVICE);
        
        resolveListener = new NsdManager.ResolveListener() {

            @Override
            public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
            }

            @Override
            public void onServiceResolved(NsdServiceInfo serviceInfo) {
                Log.d(TAG, "IRKit is detected! IP Address is [" + serviceInfo.getHost().getHostAddress() + "].");
                mIRKitDevice = new IRKitDevice( serviceInfo.getHost().getHostAddress(), serviceInfo.getServiceName() );
                if( mListner != null ){
                    mListner.onIRKitDiscovered( mIRKitDevice );
                }else{
                    Log.e(TAG, "mListner is null!");
                }
            }
        };
        
    }
    
    public interface IRKitDiscoveryListner{
        public void onIRKitDiscovered( IRKitDevice irkit_dev );
    }
    
}

IRKitDevice.java

package IRKit;

import java.io.IOException;
import android.util.Log;

public class IRKitDevice {
    // For log
    private final static String TAG = IRKitManager.class.getSimpleName();

    private String m_ip_addr = "";
    private String m_dev_name = "";
    
    public IRKitDevice( String ip_addr, String dev_name ){
        m_ip_addr = ip_addr;
        m_dev_name = dev_name;
    }
    
    public String learn() {
        return "";
    };
    
    public int send( final String send_data ){
        Log.d(TAG, "send is called.");
        new Thread() {

            @Override
            public void run() {
                String responseJson = "NULL";
                
                try {
                    // Log.d(TAG, "send_data: " + send_data);
                    responseJson = IRKitHttpClient.httpPost("http://" + m_ip_addr + "/messages", send_data);  // 読み替えてね。
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                
                Log.d(TAG, "Response: " + responseJson);
            }
            
        }.start();
        
        return 0;
    };
    
    public String getIPAddress(){ return m_ip_addr; }
    public String getDevName(){ return m_dev_name; }
    
}