MENU

Raspberry Pi + OpenECHOでECHOENT Lite機器を自作する【完全版】その②

前回の続きで、Raspberry PiのGPIOを制御するコードを追加していきます。

以下では、前回作成したプロジェクトのコピー(EchoDevicePi)を使って進めていきます。もちろん前回のプロジェクト(EchoDevice)にそのまま追記していく形で進めてもらってOKです。個人的に分けて残しておきたかっただけなので。

では早速。

JavaからRaspberry PiのGPIOを制御するためのライブラリPi4Jをここからもってきます。とりあえず、pi4j-1.0-SNAPSHOT.zipを使うことにします。

“pi4j-1.0-SNAPSHOT/lib/pi4j-core.jar”をEchoDevicePiの下にコピーしてきて、ビルドパスに追加します。

あとはMain.javaとLightEmulator.javaを修正します。

package jp.weblike.makemuda.echodevice;

import java.io.IOException;

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
import com.sonycsl.echo.Echo;
import com.sonycsl.echo.eoj.device.DeviceObject;
import com.sonycsl.echo.processing.defaults.DefaultNodeProfile;

import jp.weblike.makemuda.echodevice.devices.*;

public class Main {
    public static GpioController gpio;
    public static GpioPinDigitalOutput lightStatusPin;
    public static GpioPinDigitalOutput lightOperationPin;

    static private LightEmulator light;

    public static void main(String[] args) {
        Echo.addEventListener(new Echo.Logger(System.out)); // ログ出力

        gpio = GpioFactory.getInstance();
        lightStatusPin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_00, "LightStatusLED", PinState.HIGH);
        lightOperationPin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_02, "LightOperationLED", PinState.LOW);

        Main mainThread = new Main();
        mainThread.exec();
    }

    void exec() {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                lightStatusPin.low();
                lightOperationPin.low();
                gpio.shutdown();
                System.out.println("Quit ECHONET Lite Program.");
                System.out.flush();
            }
        });

        try {
            light = new LightEmulator();
            Echo.start(new DefaultNodeProfile(), new DeviceObject[] { light });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
package jp.weblike.makemuda.echodevice.devices;

import java.io.IOException;

import jp.weblike.makemuda.echodevice.Main;

import com.sonycsl.echo.eoj.device.housingfacilities.GeneralLighting;

public class LightEmulator extends GeneralLighting {
    byte[] mStatus = { 0x31 };           // 電源状態を格納する変数です。デフォルトは OFF と仮定します。
    byte[] mLocation = { 0x00 };         // 機器の置き場所を格納する変数です。
    byte[] mFaultStatus = { 0x42 };      // 機器に問題が発生した時に、そのコードを格納します。
    byte[] mManufacturerCode = { 0, 0, 0 }; // ベンダー固有のメーカーコードです。

    @Override
    protected boolean setOperationStatus(byte[] edt) {
        mStatus[0] = edt[0]; //電源状態が変化したことを他のノードに通知します

        try {
            // --------------------------------------------------
            // この部分に、実際に照明を点灯/消灯させるためのコードを書く。
            if (mStatus[0] == 0x30) {
                System.out.println("Light ON!");
                Main.lightOperationPin.high();
                inform().reqInformOperationStatus().send();
            } else if (mStatus[0] == 0x31) {
                System.out.println("Light OFF!");
                Main.lightOperationPin.low();
                inform().reqInformOperationStatus().send();
            } else {
                System.out.println("Parameter Error: Can NOT operate status");
            }
            // --------------------------------------------------
        } catch (IOException e) {
            e.printStackTrace();
        }

        return true;
    }

    @Override
    protected byte[] getOperationStatus() {
        return mStatus;
    }

    @Override
    protected byte[] getLightingModeSetting() {
        // TODO 自動生成されたメソッド・スタブ
        return null;
    }

    @Override
    protected boolean setLightingModeSetting(byte[] arg0) {
        // TODO 自動生成されたメソッド・スタブ
        return false;
    }

    @Override
    protected byte[] getFaultStatus() {
        // TODO 自動生成されたメソッド・スタブ
        return mFaultStatus;
    }

    @Override
    protected byte[] getInstallationLocation() {
        // TODO 自動生成されたメソッド・スタブ
        return mLocation;
    }

    @Override
    protected byte[] getManufacturerCode() {
        // TODO 自動生成されたメソッド・スタブ
        return mManufacturerCode;
    }

    @Override
    protected boolean setInstallationLocation(byte[] edt) {
        mLocation[0] = edt[0];

        try {
            inform().reqInformInstallationLocation().send();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return true;
    }
}

lightStatusPinは、プログラムが動作していることを示すためのLEDを光らせておくための制御ピンです。プログラムの開始と同時に点灯、終了と同時に消灯します。lightOperationPinは、ECHONET LiteのON/OFF操作で実際に照明代わりのLEDのON/OFF操作をするための制御ピンです。

ということで、このプログラムは2つのLEDに接続して使うことを想定しています。

Main.javaでスレッドを利用している理由は、Raspberry Pi上でjavaを実行させた後、Ctrl+Cで強制終了させるときにGPIO関係の後始末をさせたかったからです。

プログラムを修正したあとは、実行可能なjarファイルとしてエクスポートして、あとはRaspberry Piに持っていって実行するだけ!…とやれればスマートでカッコ良かったのですが、やってみた結果、プログラムは動くものの、なぜかGPIOの制御がきかず。。。仕方がないので、ソース(Main.javaとLightEmulator.java)とライブラリ(echo.jarとpi4j-core.jar)をRaspberry Piに持ってきて、Rsapberry Pi上でコンパイルして実行することにします。ああ、カッコ悪い。。。ライブラリの参照とかの問題なのだろうけれど。

Raspberry Piは事前にJavaを使えるようにしておいてください。自分はこのあたりを参考にJDKを入れましたが、少し時間が経っているので、他にもっとわかりやすい解説サイトがあるかもしれません。

Raspberry Pi上に、適当に”echonet”とかのフォルダを作って、その中に、以下のようにファイルを持ってきます。手段はscpでもsambaでも何でもOKです。

  • Main.java
  • LightEmulator.java
  • lib/echo.java
  • lib/pi4j-core.java

javaファイルにパッケージ云々の記述があると実行時に失敗するので、javacでコンパイルする前に、Raspberry Piに持ってきたMain.javaの1行目と14行目、LightEmulator.javaの1行目と5行目はコメントアウトしておいてください。ああカッコ悪い。。。

ファイルを置いたディレクトリに移動してきたら、javacでコンパイルします。

$ javac -cp lib/echo.jar:lib/pi4j-core.jar Main.java LightEmulator.java

日本語のコメント関係でエラーが出てくるようであれば、eclipseのテキストのエンコードがUTF-8になっている確認してください。

無事にclassファイルが生成されたら、以下で実行です。

$ sudo java -cp .:lib/echo.jar:lib/pi4j-core.jar Main

特に問題なければ、PCで実行したときと同じようなログが出力されるはずです。Raspberry PiとAndroid端末を同じローカルネットに繋いでいれば、Kadecotで新しいGeneralLightingが発見されます。

こんな感じで配線してもらえたら、プログラムの開始と同時に赤色LEDが点灯し、KadecotからのON/OFF操作で緑色LEDが点灯/消灯するはずです。Ctrl+Cで強制終了すると、両LED共に消灯します。

思ったよりつまづいた上に、大変カッコ悪い進め方になってしまいました。。。完全版をうたっておきながら。

とりあえず使えるものをつくるため、ラスト、Raspberry Piの電源ONで、このプログラムが自動スタートするようにしたいと思います。

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメント一覧 (1件)

コメントする

目次