ほのぼのぼのぼの

ひよっこエンジニアのほのぼの記録

Raspberry Pi と交通系ICカードを使ったポイントシステム(ソフトウェア編)

ポイントシステムをつくる

概要図はこんな感じ。 f:id:u9bo:20160626215531p:plain raspi+カードリーダでIDを読み取り、ID情報をサーバへ送信して集計します。 raspiはクライアントとして利用します。そうすることで、今後のraspi増設にも対応できそうです。

もろもろ開発

まずは、nfcpyをpathの通っている場所へ移動します。

$ sudo mv /root/nfcpy /usr/local/lib/nfcpy

こんなプログラムnfctest.pyを作成します。 ライブラリにpygameurllib2を使用しています。 Python初心者なのでもっと良い書き方あるかも。

import binascii
import nfc
import urllib
import urllib2
from urllib2 import Request, urlopen, URLError
from pygame import mixer


class MyCardReader(object):
    def __init__(self):
        mixer.init()
        self.alert = mixer.Sound('./beep.wav')
    
    def on_connect(self, tag):
        print "touched"
        self.idm = binascii.hexlify(tag.idm)
        return True

    def read_id(self):
        clf = nfc.ContactlessFrontend('usb')
        try:
            clf.connect(rdwr={'on-connect': self.on_connect})
        finally:
            clf.close()

    def put_http(self):
        url = 'http://hogehoge.com/nfc.php'
        values = {'id':self.idm}
        data = urllib.urlencode(values)
        req = urllib2.Request(url,data)
        try:
            response = urllib2.urlopen(req)
            self.httpres = response.read()
        except URLError, e:
            if hasattr(e, 'reason'):
                print 'We failed to reach a server.'
                print 'Reason: ', e.reason
            elif hasattr(e, 'code'):
                print 'The server couldn\'t fulfill the request.'
                print 'Error code: ', e.code
        else:
           print self.httpres

    def playsound(self):
        self.alert.play()

if __name__ == '__main__':
    cr = MyCardReader()
    while True:
        print "touch card:"
        cr.read_id()
        print "released"
        print cr.idm
        cr.put_http()
        cr.playsound()

プログラムの概要を説明すると、

  1. ICカード読み込み
  2. カードIDを集計サーバのhttp://hogehoge.com/nfc.phpへ送信

  3. 情報を送信したら./beep.wavを再生

といった感じです。 平文でIDを送信するのはなんだか怖いので、本格的に利用する場合は暗号化など考慮する必要がありそうです。

集計サーバのhttp://hogehoge.com/nfc.phpはこんな感じ。

<?php
$id = $_POST['id'];
if (!empty($id)) {
    date_default_timezone_set('Asia/Tokyo');
    $fp = fopen("./nfclog.txt", "a");
    $str = date('Y-m-d H:i:s')."\t".$id."\n";
    echo $str;
    fwrite($fp, $str);
    fclose($fp);
} else {
    echo "id未指定¥n";
}

$_POST['id']./nfclog.txtに記録しているだけです。 本格的に使う場合は、DBへ登録するようにしたらよいですね。

動かしてみた

うごかしてみました。

$ sudo python nfctest.py 
touch card:
touched
released
xxxxxxxxxxxxxx
2016-06-26 18:25:40 xxxxxxxxxxxxxx

こんな感じで、

  • 読み取ったID
  • サーバのレスポンス(タイムスタンプとID)

が表示されます。

今後の予定

  • プログラムnfctest.pyのデーモン化
  • 集計システムの開発

qiita.com

blog.shibayan.jp

Raspberry Pi と交通系ICカードを使ったポイントシステム(環境構築編)

はじめに

前回は、RaspberryPi(raspi)のセットアップをしました。 9bo.hateblo.jp 今回は、ICカードを読み取るための環境構築をします。

開発環境

開発メモ

ソフトウェアのインストール

まずは、NFCカードリーダで、カードを読み取るところまでやってみます。 今回はnfcpyというPythonのライブラリを使用しました。 Pythonは標準で入っているようなので、pipとbzrをインストール

yum install bzr python-pip

nfcpyの導入

公式ドキュメントを参考に導入します。

Getting started — nfcpy latest documentation

$ pip install libusb1 pyserial
$ mkdir ~/nfcpy
$ cd ~/nfcpy
$ bzr branch lp:nfcpy trunk

NFCカードリーダを接続して、raspi上で認識されているか確認

$ lsusb
Bus 001 Device 004: ID xxxx:xxxx Sony Corp. 

認識されていますね。

では、サンプルプログラムを動かしてみましょう。 pythonでUSB機器を操作する場合には、sudoで動かす必要があることに注意してください。

$cd ~/trunk
$sudo python examples/tagtool.py show
[nfc.clf] searching for reader on path usb
[nfc.clf] using SONY RC-S380/P NFC Port-100 v1.11 at usb:001:004
** waiting for a tag **
Type3Tag 'FeliCa Standard (RC-S???)' ID=xxxxxxx PMM=xxxxx SYS=0003

tagtool.pyを起動して、適当なICカードをタッチすると、固有IDが読み取れていることが確認できます。

次回は、今回作成した環境を用いて、ソフトウェアを作成します。

参考文献

qiita.com

blog.shibayan.jp

Raspberry Pi と交通系ICカードを使ったポイントシステム

SuicaPasmo などの交通系ICカード電子マネーとしての用途以外に、最近では電子錠やタイムカードなどにも利用されるようになりました。 これらはそれぞれのカード固有の番号(ID)を使って、システムやサービスを実現しています。

一人1枚は持っているこのご時世、ICカードを使って何かシステムを作れたら夢が広がりそうです。 例えば、みんなでタッチしてポイントを貯めるとか。簡易タイムカードとして使うとか。 朝8:00までにタッチしたら2ポイント、8:30までにタッチしたら1ポイントなどと個人ごとにポイントを競い合うシステムなんてものも作れそうです。

今回は、ICカードリーダとRaspberry Piを使ってポイントシステムを制作してみます。

Raspberry Pi のセットアップ

VNCを利用したNOOBS操作

セットアップには最低でもキーボードとディスプレイが必要ですが、今回はVNCを使って、別のPCからセットアップしてみました。 NOOBSをダウンロードして、recovery.cmdlineを次のように書き換えます。 変更前

runinstaller quiet ramdisk_size=32768 root=/dev/ram0 init=/init vt.cur_default=1 elevator=deadline

変更後

runinstaller vncinstall ramdisk_size=32768 root=/dev/ram0 init=/init vt.cur_default=1 elevator=deadline

つまり、quitを削除してvncinstallを追加します。

参考文献

www.slideshare.net 自動インストールなどもできるそうな。

qiita.com

OSインストール

では、Raspberry Pi を起動し、VNCで接続してみます。 今回は、VNC ViewerでRaspberry Pi のipアドレス:5900にアクセスします。 f:id:u9bo:20160612213929p:plain こんな感じでアクセスできました。

OSは、Debian系のRASPBIANではなくFedoraに近いpidoraにしました。

今回はここまで。 次回は、ICカードリーダを使う設定などを進めます。

余談

手元のノートPCからサーバマシンなど操作する需要は(個人的には)結構あって、 キーボード・ディスプレイ・マウスの3点セットをノートPC上で実現するKVMコンソールにあこがれます。 tsuchinoko.dmmlabs.com

はじめてのSQL

とても個人的な備忘録なのですが、初めてのSQLを触った自分がこの先も覚えておこう(でも忘れそう)と思ったコマンドたち。 殴り書きなので、表現の間違えなどご容赦ください。

テーブルを探す

9boを含むテーブルを探す場合

SHOW TABLES LIKE '%9bo%'

テーブルのコメント

SELECT 
    table_name, 
    table_comment 
FROM 
    information_schema.tables 
WHERE
    table_name='テーブル名'

カラムのコメント

show full columns from テーブル名

カラム構成

desc テーブル名;

テーブルの構成

show create table テーブル名

参考になりそうなページ

MySQL :: MySQL 5.6 リファレンスマニュアル

Linuxbrew で始める Go 言語

Golangを勉強してみたくて、前回構築した開発環境*1にインストールしてみました。

WindowsだとZipアーカイブあるいは、MSIインストーラを使った方法が用意されていますが*2、 どのソフトウェアに対してもほぼ言えることですが、アップデートがやっかいです*3。 Linuxbrewを使うと簡単にインストールできます。

インストール

$ brew update
$ brew install go

Macのときと同じぐらい簡単です。

インストールできたか確認

$ which go
~/.linuxbrew/bin/go
$ go version
go version go1.6 linux/amd64

実行してみましょう!

おなじみのプログラムを書きます。

package main
import "fmt"

func main() {
    fmt.Printf("Hello, world!\n")
}

では、実行してみましょう。

$ go run test.go
Hello, world!

動きました! Golangを使える環境が整いました!これから設定など進めていきます。

*1:Mac ユーザが Fedora 23 で開発できるようになるまで。 - ほのぼのぼのぼの

*2:Go言語のインストール - golang.jp

*3:Windowsにインストールされたapache+PHPのアップデートがとても辛かった経験があります。二度とやりたくない。ぷんぷん。

Mac ユーザが Fedora 23 で開発できるようになるまで。

そこに Windows マシンがあったので、 仮想環境に Linux をインストールして、Mac のときと同様の開発環境を用意してみました。

Windowsで MS-Office は使えるわ Linux コマンド使えるわで実は便利なのかもしれない。*1

作業手順

仮想環境は、VMware でも VirtualBox でも Hyper-V でもお好きなものをどうぞ。

OS のインストール

Debian でも Ubuntu でも CentOS でもいいのですが、今回は Fedora 23 にしてみました。

インストールはなんだかとっても簡単で、パッケージを指定する隙もなく、気がついたら完了していました。

アップデート

おなじみのアップデート。最近はyumではなく、dnfなのですね。

sudo dnf update

日本語入力の設定

Google 日本語入力(Mozc)をインストールします。

$ sudo dnf  install ibus-mozc
  1. 「設定」→「地域と言語」→「入力ソース」に「日本語(Mozc)」を追加。
  2. 「日本語」を削除(-)
  3. キーボードレイアウトの変更 /usr/share/ibus/component/mozc.xmlを適当なテキストエディタで開いて、<layout>を次のように変更
<layout>jp</layout>

参考:Fedora 23 で日本語入力する【iBus】【Mozc】

ホームディレクトリ内のディレクトリ名を英語表記する

標準では、ホームディレクトリのディレクトリ名が次のように日本語で表示されます。

$ ls ~
デスクトップ ドキュメント ダウンロード ...

これだと、ターミナルで使いづらいので英語表記にします。

$ LANG=C xdg-user-dirs-gtk-update

参考:Linuxホームのディレクトリ名を英語化する

Google Chrome のインストール

標準では Firefox が入っていますが、Google のサービスをよく使うので Chrome をインストールします。

$ wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
$ sudo dnf install ./google-chrome-stable_current_x86_64.rpm 

rpm からのインストールはdnf installで大丈夫みたいです。

Linuxbrew のインストール

Mac ユーザにはおなじみ、パッケージマネージャ Homebrew を Linux 環境でも使えるようにしたものです。

Linuxbrew by Linuxbrew

メリットは Homebrew と同じです。root 権限を必要とせずにホームディレクトリにいろいろなツールをインストールできます。

必要なパッケージのインストール

$ sudo yum groupinstall 'Development Tools' && sudo yum install curl git irb python-setuptools ruby

Linuxbrewのインストール

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/linuxbrew/go/install)"

.bashrc の設定

.bashrcを適当なテキストエディタで開いて以下を追記します。

export PATH="$HOME/.linuxbrew/bin:$PATH"
export MANPATH="$HOME/.linuxbrew/share/man:$MANPATH"
export INFOPATH="$HOME/.linuxbrew/share/info:$INFOPATH"

最後にインストールが正しく行われたことを確認します。

$ source ~/.bashrc
$ brew --version
Homebrew 0.9.8 (git revision eec50; last commit 2016-04-26)
Homebrew/homebrew-core N/A
$ brew doctor
Your system is ready to brew.

brew コマンドが使えるようになりました!これで Mac のときと同様にいろいろなパッケージを試せますね!

それでは、素敵な Linux ライフを!

*1:かつてのMS-OfficeでWindows版とMac OS版の互換が完璧でなくて、泣かされた経験があります。