IoTでトイレ使用状況を通知&分析するぜ MONOSTICK のデータを Ruby で分析編
今回はMONOSTICKでTWELITEの送信しているデータを読みとってみます。
sshでRaspberry PIに接続したら、MONOSTICKをUSBで接続しておきます。
Raspberry PI から MONOSTICK が受信しているデータを読みとるにはシリアル通信を行えばできます。そのためのソフトをインストールします。
$ sudo apt-get install cu
MONOSTICKがUSBに正しく接続されているか?は ls コマンドで確認できます。
$ ls /dev/ttyUSB0
/dev/ttyUSB0
接続を確認できたら実行してみます。
$ cu -s 115200 -l /dev/ttyUSB0
:7D8115019F810E27130002ED000BED1C00800E0016008954
:7D811501A8810E27130002F4000BED1B00800D0016008A45
:7D8115019F810E27130002FB000BEA1B00800D0016008B49
:7D8115019F810E2713000302000BEA1B00800D001700BA11
:7D8115019F810E2713000309000BEA1B00800D001600B90C
:7D8115019F810E2713000310000BEA1C00800C0016009F1F
:7D8115019C810E2713000317000BEA1B00800E001600A910
:7D81150199810E271300031E000BEA1B00800D001600FABC
:7D81150196810E2713000325000BED1B00800D001400AB06
:7D8115019F810E271300032C000BEA1B00800D001400BBE9
:7D8115019C810E2713000333000BEA1C008012001700A8EF
このようにデータが流れてきます。終了するには、 ~~. (ちるだ・ちるだ・どっと)をゆっくり入力すれば終了できます。
人間には読みづらいですが、この文字列が何を意味しているかは公式ページに乗っています。
かなりスパルタンですが、この16進数文字列の何バイト目を切り取って数値化すればトイレの明るさ(アナログ電圧)がわかります。他にも電圧(電池の残り)がわかったりします。
これをプログラミング言語Rubyで人間が読める形にしてみます。まずはインストールしましょう。今回私が用意したRubyのコードをダウンロードするためにwgetもインストールしておきます。
$ sudo apt-get install ruby wget
wget コマンドで私のコードをダウンロードします。
$ wget https://raw.githubusercontent.com/PharaohKJ/wc/master/twelite_serial_data.rb
Rubyはライブラリの管理にgemというツールを使います。シリアル通信のためのライブラリをインストールします。
$ sudo gem install serialport
これで準備ができました。Rubyを対話形式で実行できる irb で確認してみます。
$ irb
irb(main):001:0>
こんな画面になったらもうここではRubyを実行することができます。カーソルが > のあとにあると思うので p 'Hello World' と打ち込んでEnterを押します。
irb(main):001:0> p 'Hello World'
"Hello World"
=> "Hello World"
irb(main):002:0>
実行されました。Rubyのお勉強はがんばってやるとして、とりあえず先ほど読んだデータを解析、表示してみます。まず先程wgetでダウンロードした私のファイルを読み込んで準備し、流れてきたデータを渡して解析、表示させてみます。
irb(main):002:0> require './twelite_serial_data.rb'
=> true
irb(main):003:0> TweliteSerialData.new(':7D8115019F810E27130002ED000BED1C00800E0016008954')
=> #<TweliteSerialData:0x00007fa34804b058 @original=":7D8115019F810E27130002ED000BED1C00800E0016008954", @data={:header=>":", :from_device_id=>"7D", :data_type=>"81", :packet_id=>"15", :protocol_version=>"01", :quality=>"9F", :hardware_id=>"810E2713", :logical_id=>"00", :timestamp=>"02ED", :relay=>"00", :voltage=>"0BED", :not_use=>"1C", :digital_in=>"00", :digital_change=>"80", :analog_in1=>228, :analog_in2=>0, :analog_in3=>352, :analog_in4=>0, :analog_corrector=>"89", :checksum=>"54"}>
irb(main):004:0>
require行でダウンロードしたものを取り込んでいます。そうすると私の作った解析用クラス TweliteSerialData が使えるようになるのでそれに先程取得できた文字列を解析させています。
ではトイレの明るさ、analog1はどれだけでしょうか?
irb(main):006:0> data = TweliteSerialData.new(':7D8115019F810E27130002ED000BED1C00800E0016008954')
=> #<TweliteSerialData:0x00007fa3482a96b0 @original=":7D8115019F810E27130002ED000BED1C00800E0016008954", @data={:header=>":", :from_device_id=>"7D", :data_type=>"81", :packet_id=>"15", :protocol_version=>"01", :quality=>"9F", :hardware_id=>"810E2713", :logical_id=>"00", :timestamp=>"02ED", :relay=>"00", :voltage=>"0BED", :not_use=>"1C", :digital_in=>"00", :digital_change=>"80", :analog_in1=>228, :analog_in2=>0, :analog_in3=>352, :analog_in4=>0, :analog_corrector=>"89", :checksum=>"54"}>
irb(main):007:0> data[:analog_in1]
=> 228
irb(main):008:0>
228なようです。読めるのがわかったので自動で MONOSTICK を読み取って、読み取るたびに表示するようにしてみましょう。
irb(main):008:0> require 'serialport'
=> true
irb(main):009:0> sp = SerialPort.new('/dev/ttyUSB0', 115_200, 8, 1, 0)
=> #<SerialPort:fd 9>
irb(main):010:0> loop do
irb(main):011:1* begin
irb(main):012:2* line = sp.gets # read
irb(main):013:2> p TweliteSerialData.new(sp.gets.strip)[:analog_in1]
irb(main):014:2> rescue => e
irb(main):015:2> p e
irb(main):016:2> end
irb(main):017:1> end
これを実行すれば、MONOSTICK でデータを受信するたびに解析結果が表示されます。TWELITE側のCdSに光を当てたり、指で光を遮ったりして、表示される値に変化があることを確認できれば大成功です。
これでRaspberry PIで読み出すことまではできたので、次はこの状況をインターネットに送り出すようにしてみます。