yeomanを使って ionic アプリを作り plugin を追加して テストを書いて動かすところまで勉強のためにやってみる。
github: https://github.com/motokazu/yoionicibeacon
事前に準備しておくこと
node , npm , gem , (nvm)
コマンドの羅列!メモ。
$ nvm install v0.10.33
$ nvm use v0.10.33
$ npm install -g lodash
$ npm install -g grunt-cli
$ npm install -g bower
$ npm install -g cordova
$ npm install -g yo
$ npm install -g generator-angular
$ npm install -g generator-ionic
$ npm install -g ios-sim
$ npm install -g ios-deploy
$ yo ionic
...
$ bower install
$ grunt platform:add:ios
$ grunt build:ios
$ grunt run:ios
うん、動いた。
pluginを追加してみる
Controller名は "Ctrl"という文字を後ろにつけてくれるようなので、上ではCtrlとはつけずに実行する。
ちなみに、beaconstate.js の中にかかれている module名はどこから取っているのだろう?
angular.module('ionicApp')
.controller('BeaconstateCtrl', function ($scope) {
http://stackoverflow.com/questions/17168131/yeoman-yo-where-does-yo-scaffolding-pickup-the-name-of-the-angular-module
ここらしい?
bower.json
表示はできたので、 beacon の信号を受け取るところを plugin で実装する
beaconのスタートは、アプリ起動時がいい. Serviceを作る
$ yo angular:service ibeacon
angular.module('ionicApp')
.service('Ibeacon', function () {
あれ、、Serviceって factory(... ) で定義するのではないの??
http://stackoverflow.com/questions/14324451/angular-service-vs-angular-factory
書き方は二通りあるみたい. stackoverflowによれば、factory の方が柔軟ということだけど、ここは generator に従って service で進めてみることにする
動かない...
と思ったら, cordova.plugin が初期化される前に、動かそうとして失敗していたことが判明. $ionicPlatform.ready の中で初期化関連を実施するように修正.
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.locationManager){
Ibeacon.init();
}
});
github: https://github.com/motokazu/yoionicibeacon
事前に準備しておくこと
node , npm , gem , (nvm)
コマンドの羅列!メモ。
$ nvm install v0.10.33
$ nvm use v0.10.33
$ npm install -g lodash
$ npm install -g grunt-cli
$ npm install -g bower
$ npm install -g cordova
$ npm install -g yo
$ npm install -g generator-angular
$ npm install -g generator-ionic
$ npm install -g ios-sim
$ npm install -g ios-deploy
$ sudo gem install compass
$ yo ionic
...
$ bower install
$ grunt platform:add:ios
$ grunt build:ios
$ grunt run:ios
うん、動いた。
pluginを追加してみる
$ grunt plugin:add:https://github.com/petermetz/cordova-plugin-ibeacon.git
画面を作る
app/index.html に追加
Controllerを作る
$ yo angular:controller beaconstate
create app/scripts/controllers/beaconstate.js
create test/spec/controllers/beaconstate.js
Controller名は "Ctrl"という文字を後ろにつけてくれるようなので、上ではCtrlとはつけずに実行する。
ちなみに、beaconstate.js の中にかかれている module名はどこから取っているのだろう?
angular.module('ionicApp')
.controller('BeaconstateCtrl', function ($scope) {
http://stackoverflow.com/questions/17168131/yeoman-yo-where-does-yo-scaffolding-pickup-the-name-of-the-angular-module
ここらしい?
bower.json
{"name": "Ionic",
違う名前だ. Appってのはどこから? 1文字目も小文字になっているし。
せっかくなので, generator-angular を読む
このあたりだ. : ~/.npm/generator-angular/0.10.0/package/script-base.js
--
try {
this.appname = require(path.join(process.cwd(), 'bower.json')).name;
} catch (e) {
this.appname = path.basename(process.cwd());
}
this.appname = this._.slugify(this._.humanize(this.appname));
this.scriptAppName = this._.camelize(this.appname) + angularUtils.appName(this);
--
bower.j son があればそこから、なければ パスからということで。
Appがつく。ってことが判明. 変更する場合は コマンドラインに " --app-suffix "をつける
~/.npm/generator-angular/0.10.0/package/util.js
--
function appName (self) {
var counter = 0, suffix = self.options['app-suffix'];
// Have to check this because of generator bug #386
process.argv.forEach(function(val) {
if (val.indexOf('--app-suffix') > -1) {
counter++;
}
});
if (counter === 0 || (typeof suffix === 'boolean'&& suffix)) {
suffix = 'App';
}
--
試してみた.
$ yo angular:controller beaconstate --app-suffix=A
angular.module('ionicA')
.controller('BeaconstateCtrl', function ($scope) {
確かに。
とりあえず今回は ionicApp でいい。
app.js に追加して読み込んでもらう.
angular.module('Ionic', ['ionic', 'config', 'ionicApp'])
beaconのスタートは、アプリ起動時がいい. Serviceを作る
$ yo angular:service ibeacon
angular.module('ionicApp')
.service('Ibeacon', function () {
あれ、、Serviceって factory(... ) で定義するのではないの??
http://stackoverflow.com/questions/14324451/angular-service-vs-angular-factory
書き方は二通りあるみたい. stackoverflowによれば、factory の方が柔軟ということだけど、ここは generator に従って service で進めてみることにする
動かない...
と思ったら, cordova.plugin が初期化される前に、動かそうとして失敗していたことが判明. $ionicPlatform.ready の中で初期化関連を実施するように修正.
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.locationManager){
Ibeacon.init();
}
});
ビーコンを送る側はmacbookを使う
uuidは $ uuidgen で生成可能とのこと。
動かしてみる!
macbook側の senderを起動
$ cat sender.js
$ node sender.js
何も表示されない..
debugモードするときは、以下のように実行できる
BLEがサポートされているかはシステムレポートからLMPバージョンが0x6であること。
http://www.imore.com/how-tell-if-your-mac-has-bluetooth-40
本当に動いているのかを確認するには、detectorも作った方がわかりやすい。
http://shiitakeo.hatenablog.jp/entry/2014/11/04/021844
アプリ起動
起動OK
beacons の中に何か入ってくるのではなかったのか...。
detectorも全く検出せず.
おかしいと思ったがこれではなかろうか...
http://dev.classmethod.jp/smartphone/iphone/mac-beacon/
Yosemiteでは動かないらしい
試しにUbuntu on VMware Fusionでやってみる
こちらを参考にセットアップしてみた
http://qiita.com/yuiseki/items/24f37474e1a4cedb9388
うごいた!
ちなみに advertising を行う場合は Fusion に Bluetooth デバイスを占有させる必要があるのと、sudo で動かす必要があるようです.
ユーザーで起動すると、以下のようなメッセージが出ました.
$ node sender.js
noble warning: adapter state unauthorized, please run as root or with sudo
bleno warning: adapter state unauthorized, please run as root or with sudo
デバイスのログ方見てみよう
お。入って来た。
Viewに反映させるために callback で$scopeに反映.
$scope.beacon.proximity = beacon.proximity;
...
しかし、画面に反映されない!
外部ライブラリなどのコールバックの中で $scope の変数を変更してもviewに反映されないことがあるみたい. $scope.$apply(); する必要がらるらしい。
http://yutawatanabe.hatenablog.com/entry/angularjs-scope-apply
$scope.apply() を追加.
きた. 完成.
macbook側の senderを起動
$ cat sender.js
var Bleacon = require('bleacon');
var uuid = 'AD4E161D-50BA-40CF-9A4B-8E5E9DB02416';
var major = 1;
var minor = 2;
var measuredPower = -59;
Bleacon.startAdvertising(uuid, major, minor, measuredPower);
$ node sender.js
何も表示されない..
debugモードするときは、以下のように実行できる
$ DEBUG=bleacon node sender.js
bleacon startAdvertising: uuid = AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE, major = 1, minor = 2, measuredPower = -59 +0ms
なんか出た!
http://www.imore.com/how-tell-if-your-mac-has-bluetooth-40
本当に動いているのかを確認するには、detectorも作った方がわかりやすい。
http://shiitakeo.hatenablog.jp/entry/2014/11/04/021844
$ cat detector.js
var Bleacon = require('bleacon');
Bleacon.on('discover', function(bleacon) {
console.log(bleacon);
});
Bleacon.startScanning();
アプリ起動
起動OK
2014-12-14 11:15:07.375 Ionic[1092:60b] [DOM] didRangeBeaconsInRegion: {"eventType":"didRangeBeaconsInRegion","beacons":[],"region":{"major":1,"minor":2,"uuid":"AD4E161D-50BA-40CF-9A4B-8E5E9DB02416","identifier":"beaconOnTheMacBooksShelf","typeName":"BeaconRegion"}}
beacons の中に何か入ってくるのではなかったのか...。
detectorも全く検出せず.
おかしいと思ったがこれではなかろうか...
http://dev.classmethod.jp/smartphone/iphone/mac-beacon/
Yosemiteでは動かないらしい
試しにUbuntu on VMware Fusionでやってみる
こちらを参考にセットアップしてみた
http://qiita.com/yuiseki/items/24f37474e1a4cedb9388
うごいた!
ユーザーで起動すると、以下のようなメッセージが出ました.
$ node sender.js
noble warning: adapter state unauthorized, please run as root or with sudo
bleno warning: adapter state unauthorized, please run as root or with sudo
デバイスのログ方見てみよう
2014-12-14 15:20:00.336 Ionic[1276:60b] [DOM] didRangeBeaconsInRegion: {"eventType":"didRangeBeaconsInRegion","beacons":[{"major":1,"minor":2,"uuid":"AD4E161D-50BA-40CF-9A4B-8E5E9DB02416","accuracy":0.27,"rssi":-48,"proximity":"ProximityNear"}],"region":{"major":1,"minor":2,"uuid":"AD4E161D-50BA-40CF-9A4B-8E5E9DB02416","identifier":"beaconOnTheMacBooksShelf","typeName":"BeaconRegion"}}
お。入って来た。
Viewに反映させるために callback で$scopeに反映.
$scope.beacon.proximity = beacon.proximity;
...
しかし、画面に反映されない!
外部ライブラリなどのコールバックの中で $scope の変数を変更してもviewに反映されないことがあるみたい. $scope.$apply(); する必要がらるらしい。
http://yutawatanabe.hatenablog.com/entry/angularjs-scope-apply
$scope.apply() を追加.
きた. 完成.
次は、D3を使って色で表現してみよう
$ bower install d3 --save
view用にdirectiveを作る
view用にdirectiveを作る
$ yo angular:directive d3bar
create app/scripts/directives/d3bar.js
create test/spec/directives/d3bar.js
restrict: 'A', にする.
rssi の値によって色を変化させるようなイメージで作成
directiveを設定
<div class="item"d3bar>
Rssi: {{beacon.rssi}}
</div>
directive側では値の変更をwatchして、変化したらその値を使ってD3で描画する
scope.$watchCollection('beacon', function(data){
var val = data.rssi;
var color = d3.scale.linear().domain([-90,-20]).range(['white','red']);
var d = d3.select(element[0]);
d.data([val])
.transition()
.style('background', color(val));
色変わってます。domainの値は実測値から、適当な範囲を当てはめています。
今回はテストを書けていないので、次はテストの勉強する.