developer's diary

最近はc#のエントリが多いです

raspberry pi イジリ 起動時に勝手にログインしてバーコード読み取りプログラムを起動

f:id:mitsugi-bb:20150910021415j:plain

クラウド+Raspberry pi の組み合わせで簡単なタイムレコーダーのプロトタイプを作ってみてるところ。

Raspberry piが起動したら、あとはバーコードを読み取るだけ!みたいな部分を作成。

肝心なタイムレコーダ部分はサーバ側で記録するのでシンプルなC/Sモデルで作ってます。

Raspberry piが起動した際に、自動でログインする状態に

/etc/inittab ファイルを修正

1:2345:respawn:/sbin/getty 38400 tty1
↓
#1:2345:respawn:/sbin/getty 38400 tty1
1:2345:respawn:/bin/login -f pi tty1 </dev/tty1>/dev/tty1 2>&1

ログイン後に起動するプログラムの作成

バーコードの読み取り結果をHTTPでPOSTするプログラムを記述。 単純にバーコードを読み取ると、キーボード入力で値を受け取れるので、その値をpostするだけという簡単仕様

#!/usr/bin/ruby

require 'net/http'

while str = STDIN.gets
  http = Net::HTTP.new('mitsugeek.net') #接続先ドメイン
  response = http.post('/test.php', 'barcode='+str.strip) #接続先パスとPOSTパラメータ
  if response.body = "OK" then
    system('aplay -D plughw:0,0 -q ok.wav') #結果に問題なかった場合スピーカーで音声出力
  end
end

ログイン後にプログラムが起動するように設定

piユーザでログイン時に起動するプログラムとして、.bash_profile に記述

aplay -D plughw:0,0 -q init.wav #システム起動の音声出力
ruby barcode.rb #バーコード読み取りプログラムを起動

そしてreboot

起動した際に、起動音声が出力される。 起動音声や、バーコード読み取り時に出力する音声は、Open JTalkで、 「システムを起動しました」とか「読み取りました」みたいな音声ファイルを作成してみた。

バーコードを読み取ると、バーコードの読み取った値がサーバにPOSTされて、「読み取りました」の音声ファイルが再生される。

感想

クラウド+Raspberry pi の組み合わせはプロトタイプの作成にものすごく相性がよさそう。

今回はバーコードを利用したタイムレコーダーのプロトタイプだけども、

タイムカードの機械を買うより安上がりだったりする。

本格的に利用するとなると、セキュリティ部分が要になるのでこのままだと使えないけども。

通信の暗号化とか。アクセスキーとか。

参考

http://raspi.noob.jp/howto/auto-login/raspi.noob.jp

アマノ タイムカード タイムレコーダー ホワイト BX2000

アマノ タイムカード タイムレコーダー ホワイト BX2000

  • 発売日: 1996/07/01
  • メディア: オフィス用品

「秋の京都で MobiRuby をつつく会 in はてな」に参加した時を思い出しメモ

MobiRubyの勉強会に参加して内容をブログに書こうとしていたんだけれども、下書きのままでした。なんだか気持ち悪いので、まとまりないけれども公開します。

参加した勉強会:http://atnd.org/events/33550

その時につぶやいた自分のtwitterをまとめながらメモする。

id:ninjinkun さんのプレゼンの途中から参加しました。アプリの開発という内容。電車のなかで、リーン・スタートアップを読んでいたのでちょっとびっくり。

  • iPhoneアプリ開発で、PhoneGap利用した
  • ネイティブだとイテレーションが長くなるので、ピボット(方向転換)しにくい。
  • HTMLベースのアプリだとイテレーションのサイクルを短くできるので、UIが固まっていない場合はWEBベースのほうが向いている。
  • アップストアもWEBベースみたい。リンク切れがあったり。
  • Facebookアプリがネイティブに移行したのは、HTML5でUIを固めることができたからかもしれない。

続いて@masuidriveさんの MobiRuby 。

  • rubyでiPhoneアプリ開発できる→実際にアップストアにsamegameを公開
  • MIT Licese
  • ネイティブ関数は呼べる

  • rubyがISO/IEC 30170になったことで、mrubyをまつもとゆきひろさんが作った。
  • 組込向けのため、メモリ使用量が減った
  • ソースコード一人でもなんとか追いかけれる量?

  • POSIXなOSでなくても動く
  • c99のみで作られてる

初めて知った <=> UFO演算子。

ruby-listのMLで若干話題*1になっていました。<=>(UFO演算子)

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/47414

UFO演算子って何?

A <=> B とすると、
A < Bならば負の数を返し、
A > Bならば正の数を返し、
AとBが等しければ0を返します。

UFO演算子はてんびんみたいなもの

Comparableモジュール

比較演算を許すクラスのための Mix-in。このモジュールをインクルー ドするクラスは、基本的な比較演算子である <=> 演算子を定義してい る必要があります。他の比較演算子はその定義を利用して派生できます。

module Comparable

Comparableを入れるとどうなるか。

下記のようなことができる。

ary = []
ary << Book.new(.....)
ary << Book.new(.....)
ary << Book.new(.....)
ary.sort.each{ |book|
【ここで本の情報を出力】
}

OOPってすごい。。

*1:Gmailのスレッドがわーってなってました

mechanizeを使って、Yahooブリーフケースのファイルを一括ダウンロードする。


yahooブリーフケースを一括でダウンロードするツールを探したのですが、見つからないので作ってみました。<追記_20081027>
yahooがブリーフケースの有料化によって無料でダウンロードが2009年2月1日までしかできないようです。

Yahoo!プレミアム、Yahoo! BBに会員登録いただいていない方は、2009年2月1日までの間に、お手数ですがYahoo!ブリーフケースにアップロードされているデータを、ご自分のパソコンにダウンロードしていただくか、Yahoo!プレミアム/Yahoo! BBへのご登録をお願いいたします。

プログラムとか苦手な人にでもわかるようにid:t_ash20さんが解説を書いてくれました。rubyが入ってない方はid:t_ash20さんの解説を見てがんばってみてください。Yahoo!ブリーフケースから一括ダウンロード その2 - perspective

少し修正しました。

続きを読む

mechanizeを使って、Yahooブリーフケースのファイルを一括ダウンロードする。(ちょっと修正)

「もしかしたらバグ」を修正してみました。

もしかしたらwindowsのファイル名に使用できない文字が入ってるからエラーが起きるのかもしれない!
と考え、windowsで使用できない文字( "<>|:*?\/ ) を全角に変換しちゃう仕様に修正してみました。

DLに失敗した方。もしかしたら動くかもしれないです。

報告お待ちしてます」(__)L

class YahooBriefcase

  require 'rubygems'
  require 'mechanize'
  require 'Kconv'
  require 'uri'

  BRIEFCASE_LOGIN_URL = "https://login.yahoo.co.jp/config/login?.src=bc&.done=http%3a//briefcase.yahoo.co.jp/&.intl=jp&.linkdone=http%3a//briefcase.yahoo.co.jp/"
  BRIEFCASE_LOGOUT_URL = "http://login.yahoo.co.jp/config/login?logout=1&.src=bc&.intl=jp&.done=http://briefcase.yahoo.co.jp"
  BRIEFCASE_URL = "http://briefcase.yahoo.co.jp/"

  def initialize(id=nil, password=nil, user_agent='Mechanize')

    @agent = WWW::Mechanize.new
    set_user_agent_alias(user_agent)
    briefcase_login(id,password) if id && password
  end

public

  # @param[in] user_agent ユーザエージェント
  def set_user_agent_alias(user_agent)
    @agent.user_agent_alias = user_agent
  end

  # @param[in] id Yahoo!のID
  # @param[in] password Yahoo!のパスワード
  def briefcase_login(id,password)
    @agent.post(BRIEFCASE_LOGOUT_URL)
    @agent.post(BRIEFCASE_LOGIN_URL, "login" => id, "passwd" => password)
  end


  # @param[in] dir ダウンロード先のディレクトリ
  # @param[in] url ダウンロード元のURL
  def all_get(dir, url=BRIEFCASE_URL)
    FileUtils.mkdir_p(dir)
    briefcase(dir,url,@agent)
  end

private

  def briefcase(name,url,agent)

    #fileが存在するurlの正規表現
    file_regexp = Regexp.new('^http://proxy')
    #ディレクトリのurlの正規表現
    dir_regexp = Regexp.new('&.order=&.view=l&.src=bc&.done=')

    infileArr = Array.new

    #現在の階層に存在するurlを取得
    page = agent.get(url)

    #取得したurlを回す。
    page.links.each do |link|

      #urlがディレクトリの場合
      if link.href =~ dir_regexp

        #ディレクトリの位置をinfileArrに入れる
        dirname = Kconv.tosjis(link.to_s).sub(/\n/,"").sub(/^ */,"")
        infileArr << { dirname => link.href }

        #urlがファイルの場合
      elsif link.href =~ file_regexp

        #ファイルの位置をinfileArrに入れる
        filename = Kconv.tosjis(URI.decode(link.href.to_s.sub(/\n/,"").to_s.sub(/\?.*$/,"").reverse.scan(/^(.*?)\//).to_s.reverse))
        infileArr << { filename => link.href }
      end
    end

    #現在の階層に存在するリンクを回す。
    infileArr.each do |dirhash|
      #リンクに対する名前、urlを取得(1回しか回らない)
      dirhash.each do |name2, url2|

        name2 = name2.sub(/"/,"").sub(/</,"").sub(/>/,"").sub(/\|/,"").sub(/:/,"")
        name2 = name2.sub(/\*/,"").sub(/\?/,"").sub(/\\/,"").sub(/\//,"")

        #urlがディレクトリの場合
        if url2 =~ dir_regexp then

          #ダウンロード先のディレクトリが存在しない場合は作成
          FileUtils.mkdir_p("#{name}/#{name2}")

          #再起呼び出し
          briefcase("#{name}/#{name2}",url2,agent)
          next
        end

        #urlがファイルの場合
        if url2 =~ file_regexp

          #ファイルを取得
          file = agent.get(url2)
          filename = Kconv.tosjis(name2).sub(/\n/,"")
          File.open("#{name}/#{name2}","w+b") do |line|
            line << file.body
          end
  
          #取得したファイル名を出力する。
          puts "#{name}/#{name2}"
        end
      end
    end
  end
end

秀丸からRubyを実行する。〜秀丸からの連投を目指して〜

とりあえず、5月17日のRuby勉強会で、ujihisaさんが紹介していた、WWW::Mechanizeを使用してみる。

とりあえずインストール。

gem install mechanize

EeePCでは、メモリが足りないとか怒られてインストールできなかったので、
デスクトップPCに、インストール。

うまくいきました。*1

早速RubyScraping - Mechanizeで紹介しているソースを実行して試してみる。
施行

使用例

自動google検索。

require 'rubygems'
require 'mechanize'

agent = WWW::Mechanize.new                     # インスタンス生成
agent.user_agent_alias = 'Mac Safari'          #  User-Agentの設定
page = agent.get('http://www.google.com/')     # ページ取得
search_form = page.forms.with.name('f').first  #  "f"という名前のフォームを探す
search_form.q = 'Hello'                        #  テキストボックス"q"に"Hello"を入力
search_results = agent.submit(search_form)     # フォームのsubmitボタンを押す
puts search_results.body                       # 結果の取得

RubyScraping - Mechanize

を秀丸で実行したのですが。。。。


とエラーが。

Buffer overrun error at LocalUnlock (986) <font size=-1><input type=text name=q size=41 maxlength=2048 value="Hello" ti
\util.cpp(1195) error = 0
ご面倒でなければこのエラーの再現手順を書き添えて、秀丸エディタをインストールしたフォルダ(またはマイドキュメント)にあるdump.txtの内容を作者に連絡ください。また、秀丸エディタは早めに終了させてください。

コマンドプロントより実行した場合は問題なく動きます。

だんだんとWindowsが嫌いになっていく。。。。

しかし、懲りずにもう少し進めよう。

秀まるおのホームページ(サイトー企画)−RubyEval for 秀丸マクロ Ver.0.02で、動かしてみようと思い。
下記ソースで実験。

url = $RUBY_EVAL_INSTR

require 'rubygems'
require 'mechanize'

agent = WWW::Mechanize.new # インスタンス生成
agent.user_agent_alias = 'Mac Safari'
page = agent.get(url)
$RUBY_EVAL_INSTR = page.title

と、こんどは下記エラー。。。

#<SocketError: c:/ruby/lib/ruby/1.8/net/http.rb:564:in `initialize': getaddrinfo: non-recoverable failure in name resolution.>


ちなみに、エラーが指している564行目は、

      s = timeout(@open_timeout) { TCPSocket.open(conn_address(), conn_port()) }

です。

*1:EeePCでもできるようにがんばろう。

秀丸からRubyを実行する。〜秀丸からの連投を目指して〜

昨日の日記で、紹介した、
秀まるおのホームページ(サイトー企画)−RubyEval for 秀丸マクロ Ver.0.02を入れたんですが、[Rubyスクリプトメニュー.mac]ってのがあったので、起動したら、下記エラー

早速、google:DengakuDLL.dllしてみる。
M. Sugiura Personal Web Page [Root]というサイトより頂戴いたしました。

Rubyスクリプトメニュー.macをショートカットに登録して。

さぁ実行。

左クリックで選択した箇所をどのRubyで処理するか選択できるなんて。
なかなかすばらしいです。

ちなみに、マクロファイルの中の下記行の、

$newstr = dllfuncstr("rubyEval", currentmacrodirectory + "\\RubyEval\\toupper.rb", $str);

"\\RubyEval\\toupper.rb"の部分を自作のRubyスクリプトに変更すれば、呼び出せます。

そして、左クリックで選択した箇所が、Rubyソースの

$RUBY_EVAL_INSTR

に入っています。
で最後にreturnされたものが、左クリックで選択した箇所に上書きされます。

サンプルの、toupper.rbは、

$RUBY_EVAL_INSTR.upcase

とだけしてあるみたいですね。

秀丸からRubyを実行する。〜秀丸からの連投を目指して〜

秀丸エディタでRubyをマクロにして使う - Rubyの魔神 - はてな?Rubyグループで紹介されているのを見て知りました。

秀丸からも、Rubyが実行できる。

が、日本語の一部で文字化けが起きたので、マクロを一部を修正

run "ruby " + $ruby_file + " > con";

の"ruby "の部分を

run "ruby -Ks " + $ruby_file + " > con";

に変更して使用しています。

このマクロはものすごく愛用しております。

多分irbよりも使用しています。

作者のおざきはじめさんに感謝です。


さらに、秀丸エディタのRuby起動マクロ - Rubyの魔神 - はてな?Rubyグループで紹介していたマクロは、左クリックで選択した箇所をRubyのスクリプトに渡せるようになっているみたいです。

この秀まるおのホームページ(サイトー企画)−RubyEval for 秀丸マクロ Ver.0.02を利用して、連投アプリを作成しようと思います。

が、それより先に作りたいマクロが沢山出てきたのでそちらを先に。。。