iBeacon メモ

iOS7で導入された、位置&近接の検出技術。

  • iBeacon は Bluetooth Low Energy を利用している
  • 通信は単方向

ビーコンが発信できる識別情報は、設定したUUID, major, minor。

  • 16ビットの major, minor の使い方は自由。
  • major を店舗、minor を売り場を表す番号に割り当てるなど
  • major, minor は省略可能。省略したらワイルドカード扱い。

対応OS, 機種

できること

  • 近づいたことを検出。
  • おおまかな距離測定。
    • 1m, 10m かを判別できる程度。
    • 障害物、人が間に立つなどで電波は弱まる。
    • 電波の強さによって最大 50m くらいまで検知可能。
  • iOS7.1から アプリがサスペンド状態でも検出可能。

できないこと

  • 方向検知
  • 正確な距離の検知

ビーコンのコピーは簡単

  • Androidアプリなどで簡単に拾って、おなじ電波を出すことが可能
  • 不正は簡単という認識をもっておく。

iOS での Advertise は フォアグラウンド時のみ可能

After advertising your app as a beacon, your app must continue running in the foreground to broadcast the needed Bluetooth signals. If the user quits the app, the system stops advertising your device as a peripheral.

参考

Java - 日本語で曜日を表示

自前で曜日配列から組み立ててるコード見かけてしまった。 ググっても似たようなことをやってるサンプルコードがたくさん出てくる。

それ SimpleDateFormat で簡単にできるよ。

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class Main {

    public static void main(String[] args) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 E曜日", Locale.JAPAN);
        Date now = new Date();

        System.out.println(formatter.format(now)); // -> 2014年05月22日 木曜日
    }
}

Kibana + Elasticsearch + ダミーデータ をインストール on Mac OSX

5分でMac上に構築 & ダミーデータ込み。

環境

  • Mac OS X 10.8.5
  • Kibana v3.0.1
  • Elasticsearch v1.1.1

手順

作業ディレクトリの用意

mkdir -p ~/sandbox
cd ~/sandbox

Kibanaのインストール

wget https://download.elasticsearch.org/kibana/kibana/kibana-3.0.1.tar.gz -P /tmp
tar xvf /tmp/kibana-3.0.1.tar.gz -C .

※ 展開した kibana のソースは httpd のDocumentRoot 以下に配置する。

Elasticsearch のインストール

wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.1.1.tar.gz -P /tmp
tar xvf /tmp/elasticsearch-1.1.1.tar.gz -C .

起動

./elasticsearch-1.1.1/bin/elasticsearch

ダミーデータの入力 (データはこちらのを使わさせていただきます。https://github.com/stormpython/Elasticsearch-datasets)

wget https://github.com/stormpython/Elasticsearch-datasets/archive/88a36cd9600d56ae2ee24ede607db04e9f35fa08.tar.gz -O /tmp/elasticsearch_dummy_data.tar.gz
tar xvf /tmp/elasticsearch_dummy_data.tar.gz -C .

cd Elasticsearch-datasets-88a36cd9600d56ae2ee24ede607db04e9f35fa08
curl -X POST 'localhost:9200/nfl'
curl -X PUT 'localhost:9200/nfl/2013/_mapping' -d @mappings/nfl_mapping.json
curl -X POST 'localhost:9200/nfl/2013/_bulk?pretty' --data-binary @datasets/nfl_2013.json

あとは、localhost ひらく。

f:id:potato777:20140515174815p:plain

PlayFramework - play dist を一行で25%高速化する方法

scaladocの生成を無効化したら 185秒が138秒になった。
build.sbt に以下を追加しただけ。

playScalaSettings ++ Seq(doc in Compile <<= target.map(_ / "none"))

参考: https://groups.google.com/forum/#!msg/play-framework/vXLwW2EvzmQ/NTf_NfmtR8oJ

若手が進行役をすると意見が出やすい

意見しやすい空気づくりの一つです。

偉い人やベテランの場合。一部の人は遠慮してしまったり、「あの人が言うのだから間違いないだろう」という危険な集団心理に陥いったりしてしまうケースがある。

逆に若手の進行だと、他の若手も意見しやすかったり、進行役を任すことで若手の成長にもなる。

少なくとも議事録取らせるだけより能動的な能力が育つ。

PlayFramework - DBセッションを提供する Action を作る

この記事は Play Framework 2.x Scala Advent Calendar 2013 の21日目の記事です。

こんにちわ。

師走で忙しい中、忘れてはならない大掃除の時期です。
こういうとき慌てないためにも、日頃から細かいところを掃除することは大切ですね。

とういことで21日目。
Play Framework 2.2 から用意された ActionBuilder を利用して Action の定型コードを綺麗にする。という内容です。

アクションで現れる定型コード

Slickを利用した例です。

  class SampleController extends Controller {

    def sampleAction1 = Action { request =>
      DB.withSession { implicit session =>
        UserRepository.findAll() // ここでDBアクセスの処理したりする
        ???
      }
    }

    def sampleAction2 = Action { request =>
      DB.withSession { implicit session =>
        ???
      }
    }

    def sampleAction3 = Action { request =>
      DB.withSession { implicit session =>
        ???
      }
    }
  }

煩わしいですね。
DBセッションを得るために DB.withSession を毎回呼んでしまってます。
ここは、簡潔にし見通しを良くしたいです。

ActionBuilder を利用して DB.withSession を毎回呼んでくれる Action を作る

ActionBuilder は Play Framework 2.2 から用意された カスタムアクション を作る機能です。 公式ドキュメント

そして、今回は最低限の実装のサンプルを用意しました。

trait CustomController extends Controller {
  implicit def dbSession(implicit requestContext: CustomRequest[_]): Session = requestContext.dbSession
}

class CustomRequest[A](request: Request[A]) extends WrappedRequest[A](request) {
  var dbSession: Session = null
}

object CustomAction extends ActionBuilder[CustomRequest] {

  // リクエスト毎に呼ばれる
  def invokeBlock[A](request: Request[A], block: (CustomRequest[A]) => Future[SimpleResult]) = {
    val requestContext = new CustomRequest[A](request) // DBセッションを保持できるように拡張した Requestクラス
    requestContext.dbSession = DB.createSession() // DBセッションを取得し、Requestクラスに紐づけてます

    try {
      block(requestContext) // アクションのブロックを実行します
    } finally {
      requestContext.dbSession.close() // リクエストの終わりにセッション開放します
    }
  }
}

サンプルの説明

CustomActionクラス
ActionBuilder で作った今回の主役です。
invokeBlockメソッドがリクエスト毎に呼ばれます。
中で呼んでいる block(requestContext) が Action に渡した 処理です。

CustomControllerクラス
DBセッションの暗黙的パラメータ を持ったコントローラです。
アクションがDBセッションを必要なタイミングで、Requestクラスが持つDBセッションを返してます。

利用の例

class SampleController extends CustomController {

  def sampleAction = CustomAction { implicit request => // 暗黙的パラメータにする必要があります

    // ReadOnly なセッションは暗黙的に CustomController#dbSession から取ってる
    val res = UserRepository.findAll().mkString

    // トランザクションスコープは明示的に指定したいので、従来通り
    DB.withTransaction {
      ???
    }

    Ok(res)
  }

}

object UserRepository extends Repository {
  def findAll()(implicit session: Session): Seq[User] = ??? // セッション使ってDBにアクセスする処理
}

簡単ですが、21日目の記事でした。
ActionBuilder は 今回の例に限らず、広く応用できると思います。
なにか思いついた人は年越しまでにちょっと綺麗にしてみてはいかがでしょうか?

以上。 まだまだ経験も浅く、拙い内容で畏れ入りますが、
ツッコミなどありましたらよろしくお願いします。

さて、明日の22日目はー。(きっとだれかが埋めてくれる)

PlayFramework にて build.sbt に scalaVersion 指定しない理由が分かった

気がする。

通常の sbt プロジェクトでは、開発者の環境に依存してしまうので build.sbt に scalaVersion を指定する意味は大きい。

しかし、PlayFramework では PlayScalaSettings がデフォルトで指定してくれている。
これで開発者の環境に依存する件は解決していた。


※ただし、意識していないと意図していないバージョンを使っているということにはなる。


関連記事: sbt 使うなら必ずScala, sbtのバージョンを指定する