curious4dev

中国旅行、Arduinoなどを使った電子工作、その他色々。

*

上司の離着席状態をクラウドに飛ばし、スマホで見れるようにした。

 

お疲れ様です。高橋です。

前回ブレッドボード上に構築した上司離着席検知システムですが、ユニバーサル基板上に作りなおしました。

さらに、受け付けた離着席状態をAmazonのクラウドに飛ばし、どこからでも上司の離着席状態を参照出来るようにしました。

全体の流れ

  1. 上司座席付近に設置したデバイスが離着席状態を部下デバイスに送信
  2. 部下デバイスは離着席状態をLEDの色で表現すると共に、PCにも離着席状態を送信
  3. PC側で離着席状態を受け取ると、直前に受け取った離着席状態と差があった場合、AWSに送信
  4. AWS側では受け取った離着席状態と日時をDBに蓄積し続ける
  5. 「今の状態を知る」用のwebページを開くと、直近の状態が表示される
  6. 「今までの状態を知る」用のwebページを開くと、今までの時系列推移が表示される

デバイス

デバイスは、上司の座席付近にこっそり設置する物と、そこからの離着席状態を受け付けて、LEDを点灯させつつ、Amazonのクラウド(EC2)に状態を飛ばす物と、2つあります。

上司デバイス(上司の座席付近にこっそり設置する物)

この左側の測距センサーで離着席を検知します。

IMG_6308

部下デバイス(離着席状態を受け付ける物)

上司が着席していると青、離席しているとピンクが点灯します。

IMG_6307

動作イメージ

左側が、上司デバイスで、右側が部下デバイスです。今は上司デバイス上空に何も障害が無いので、部下デバイスには怪しげなピンク色のLEDが点灯しています。

IMG_6309

ここに手をかざすと「上司着席」モードとなり、青色LEDが点灯します。

IMG_6310

※LED

前に使っていた赤色LEDが謎の(というより過負荷による)損傷によってリタイアしてしまいましたので、適当なLEDを挿してみたのですが、これがまた怪しいピンクのLED。素敵な色です。

IMG_6311

離着席状態をサーバに飛ばす

離着席状態をサーバに飛ばすには、部下デバイスからシリアル送信される離着席状態をPC側で受け付ける必要があります。部下デバイスは100msec毎にLED点灯の判断を行ってますが、そのまま100msec毎にPCにも情報を送るようにしてます。しかしPC側で100msec毎に受け付けて、しかもそれをそのままクラウドに垂れ流したら、あまり意味のないデータが大量に生成される事になります。そのため、「直前にクラウドに送信した離着席状態と差があった場合のみ送る」というように細工を行います。

部下デバイスからクラウド側にデータを送るためのjavaプログラムが下記の通りです。URLは実際のものでは無いです。

package serialTest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.util.TooManyListenersException;

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

public class serial implements SerialPortEventListener {
    public static String strComPort = "COM8";
    public static int intBPS = 9600;
    public String strBeforeStatus = "";
    private SerialPort port;
    private static BufferedReader reader;

    serial() {
        try {
            // Serial port initialize
            CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(strComPort);
            port = (SerialPort) portId.open("serial", 2000);

            port.setSerialPortParams(intBPS,
                    SerialPort.DATABITS_8,
                    SerialPort.STOPBITS_1,
                    SerialPort.PARITY_NONE
            );
            port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);

            reader = new BufferedReader(new InputStreamReader(port.getInputStream()));

            try {
                port.addEventListener(this);
                port.notifyOnDataAvailable(true);
            } catch (TooManyListenersException e) {
                System.out.println("Error: " + e);
            }

        } catch (Exception e) {
            System.out.println("Error: " + e);
            System.exit(1);
        }
    }

    public void run() {
        try {
            InputStreamReader isr = new InputStreamReader(System.in);
            BufferedReader br = new BufferedReader(isr);
            OutputStream out = port.getOutputStream();
            boolean flagQuit = false;
            while (!flagQuit) {
                String input = br.readLine();
                if (input.length() > 0) {
                    if (input.equals(":quit")) break;
                    input += "\r";
                    out.write(input.getBytes("US-ASCII"));
                }

            }

            port.close();

        } catch (Exception e) {
            System.out.println("Error: " + e);
        }
    }

    public void serialEvent(SerialPortEvent event) {
        if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
            String buffer = null;
            try {
                while (reader.ready()) {
                    try {
                        buffer = reader.readLine();
                    } catch (IOException ex2) {

                    }
                    if (strBeforeStatus.equals(buffer) == false) {
                        System.out.println(buffer);
                        // post to AWS
                        URL url = new URL("http://curious4dev.mydns.jp/hogehoge.php?status=" + buffer);

                        Object content = url.getContent();
                        if (content instanceof InputStream) {
                            BufferedReader bf = new BufferedReader(new InputStreamReader((InputStream) content));
                            String line;
                            while ((line = bf.readLine()) != null) {
                                System.out.println(line);
                            }
                        }
                        strBeforeStatus = buffer;
                    }
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    public static void main(String arg[]) {
        serial serial = new serial();
        serial.run();
    }

}

要は、部下デバイスからシリアルのCOM8で何か来たら、直前に送信したデータと比較して異なっていたら、クラウド側にデータを送る。という事を無限ループさせているだけです。

クラウド側で受け付ける

クラウド側に「hogehoge.php」という、データを受け付けてDBに蓄積するためのプログラムを作っておきます。db接続周りは適当に変えてください。

// get requestparam
$status = htmlspecialchars($_GET['status']);

// initialize
$db_host = 'host';
$db_user = 'user';
$db_pass = 'pass';
$db_name = 'db_name';

$sql_insert = 'insert into richakuseki (status, insert_date) values(:status, now());';

// conenct to mysql
$pdo = new PDO("mysql:dbname=" . $db_name, $db_user, $db_pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET CHARACTER SET `utf8`"));

// insert db
$statement = $pdo->prepare($sql_insert);
$statement->bindParam(':status', $status, PDO::PARAM_STR);
$statement->execute();

今の状態をスマホで知る

直近の状態を知りたい時に開くのが下記の通りです。now.phpとでも命名しておきましょう。

// initialize
$db_host = 'host';
$db_user = 'user';
$db_pass = 'pass';
$db_name = 'db_name';

$sql_select= 'select status, insert_date from richakuseki order by insert_date desc limit 1;';

// conenct to mysql
$pdo = new PDO("mysql:dbname=" . $db_name, $db_user, $db_pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET CHARACTER SET `utf8`"));

// insert db
$statement = $pdo->prepare($sql_select);
$statement->execute();
$row = $statement->fetch();
$status = $row[0];
$time = $row[1];
if($row[0] == "10") {
$status = "着席してる";
} else {
$status = "着席してない";
}
echo $time . "時点、" . $status;

利用イメージ

スマホでnow.phpを開くと、

IMG_6313

こんな感じで、ぶっきらぼうではありますが、現時点の状態を確認する事が出来ます。もっとフワフワしたイラストやら、上司が実際に着席している写真、離席している写真なんかを、状態に応じて表示することも出来ます。

 

 

 

以上、よろしくお願い致します。

 - 電子工作

  関連記事

【完成】PCからシリアル通信でEEPROM書き込み

お疲れ様です。高橋です。 PCからシリアル通信を介して楽曲データをEEPROMに …

電子オルゴール 基板実装 #2 ~ワイヤストリッパー~

お疲れ様です。高橋です。 先日秋葉原でワイヤーストリッパーを買ってきました。 被 …

満員電車内でのオナラと検知 #4

お疲れ様です。高橋です。 硫化水素センサーが到着しました。結構前に到着していたの …

マウスを分解してみた(リベンジ)

お疲れ様です。高橋です。 壊れたマウスを貰った 本日、壊れたマウスを貰いました。 …

耳コピを簡単にするミキサー構想

お疲れ様です。高橋です。 私が普段耳コピをする時は、iPhoneで音楽を鳴らしな …

bluetoothモジュールHC-06とAndroid

お疲れ様です。高橋です。 先日AliExpressで購入したbluetoothモ …

上司離着席検知システムの開発

お疲れ様です。高橋です。 下記、フィクションでイメージです。 背景 何かしらの相 …

音階LED表示器の実体配線図を書いてみた。

お疲れ様です。高橋です。 前に「音階に合わせてLEDを光らせてみた。」で実験した …

YMZ294のMIDI音源化と、YMZのピン数圧縮

お疲れ様です。高橋です。 YMZで使うピン数を11本から6本に減らす事によって、 …

MIDI INの実験

お疲れ様です。高橋です。 Arduino+YMZをMIDI化するための第一歩の実 …