見出し画像

現実世界における侵入検知システムを作った話 その3

前回(こちら)、センサー部を作りました。
今回はセンサーから送られてきた情報を集約するサーバ側を作っていきたいと思います。

材料

今回はサーバとしてRaspberryPi(以下RPi)を使用します。
また、TWELiteの親機としてUSB型のTWELiteを使うことにします。


設計

TWELiteはRPi側とUSBシリアル接続されます。
TWELiteの親機は子機たちからステータス情報を受信しますが、受信した情報はシリアル越しに1行のテキスト情報として取得することができます。
そこで、今回はRPiのシリアルポートを読んでそれを解釈するプログラムを作成することにします。

実装

シリアルポートからデータを読み出すプログラムを作ってみます。
実際のシリアルテキストのフォーマットについては公式サイトを参照ください。
例えば、以下のようなテキストとなります。

:0181150190810E36FC000004000C1C1D000C621D3334C50B
:0181150190810E36FC000007000C321D010C451833058B7D
:0181150196810E36FC000009000C321D000D47192710C03C
:0181150193810E36FC00000D000C191D010D410E200FA787
:0181150196810E36FC000011000C271D000D3A111E10B766
:018115019C810E36FC000015000C2B1D010D351A280A58AF
:018115019C810E36FC000019000C2B1D000D37192C06DF23
:018115019C810E36FC00001D000C2E1D000D460B290B4EAA
:018115019C810E36FC000021000C2B1D000D550D2B0D984A
:0181150199810E36FC000025000C271D010D530F2610F7F1
:0181150199810E36FC000027000C271D000D560E3209637B
:0181150190810E36FC00002C000C271D010D580D2F0C39A9
:0181150190810E36FC00802D000C271D0002580D2F0C3931
:018115015A810E36FC00003C000BFF1D010F40111F0AF95C
:018115018D810E36FC000040000BFF1D010F41092009EC39
:0181150190810E36FC000044000C271D010F3D0B27071ED4

このデータのうち、今回は「子機のID」・「現在の電池容量」・「開閉状態」の3つを取得することにします。

今回はRuby を使って書いてみます。

require 'serialport'
require 'optparse'
# structure for Sensor Packet.
SensorPacket = Struct.new(:id, :mv, :status)
def line_parser(line)
  return nil unless line =~ /^:/
  # 0:deviceID, 1:mV,  2:'00'=close '01'=open
  SensorPacket.new(*line.chomp.match(/^:(\h{2})\h{24}(\h{4})\h{2}(\h{2})/).captures)
end
# parsing options
params = ARGV.getopts('d:')
unless params['d']
  puts '-d required.'
  exit 1
end
serial_device = params['d']
serial = SerialPort.new(serial_device, 115_200, 8, 1, 0)
loop do
  next unless sp = line_parser(serial.gets)
  p sp
  #=> #<struct SensorPacket id="0A", mv="0C56", status="01">
end

これを実行すると、以下の様な出力になります。

#<struct SensorPacket id="01", mv="0C1C", status="01">
#<struct SensorPacket id="01", mv="0C32", status="01">
#<struct SensorPacket id="01", mv="0C32", status="01">
#<struct SensorPacket id="01", mv="0C19", status="01">
#<struct SensorPacket id="01", mv="0C27", status="01">
#<struct SensorPacket id="01", mv="0C2B", status="01">

エラー処理が入っていませんが、メインの処理としてはこんな感じになります。

これで各扉のセンサーから状態をRPi側に集約する準備ができました。

各扉から状態を収集できるようになったので、次回はこれらを利用して行きたいと思います。