2017年10月27日金曜日

Unity : VRプログラム(2)

今回は街並みを走るプログラムを作成します。
(1) 街並みプログラム作成
プロジェクト名:VR02
今回街並みの設定は次を利用させてもらいます。
http://many.chu.jp/Unity/TekitouCityGenerator/
これをダウンロードして、Assetにインポートします。
Sample1を利用します(ダブルクリック)。下のようなシーンが出て来ます。
 試しに動かしてみると、面白いものが出て来ます。
せっかくなのでVRとしてみてみます。GoogleVRをインポートしておきます。
前回と同様なやり方でAndroid端末に転送します。
変更する必要があればCameraの位置を調整します。



(2) Unity Chanの配置
今回は回転は止めておきます。Camera->Add Rotation Script のチェックを外します。
Unity Chanを配置します。利用規約に同意してデータを持って来ます。
http://unity-chan.com/download/releaseNote.php?id=UnityChan
これをAssetに取り込みます。
この中からUnityChan->Prefabs->unitychan_dynamic -> for Locomotion -> unitychan_dynamic_locokotion を取り込みます。

unitychanの目線に合わせ、Cameraを変更します。Camera -> Add component -> Followというスクリプトを作ります。
targetを指定しておきます。
これで動かしてみると、下に落ちていくかもです。そのため、Planeを加えておきます。
unity chanがうまく動くように調整します。例えばちょっと高さを調整します。Planeも広くしておきます。

(3) 街中で人探し
もう一人、unitychan(動かない)を配置して、探してみます。
for locomotion -> unitychan を持って来ます。
探すと、いました。

参考
https://www.slideshare.net/kinneko/part3-unityvr
https://github.com/unity3d-jp/FirstTutorial/wiki/3.%E3%82%AB%E3%83%A1%E3%83%A9%E3%82%92%E5%8B%95%E3%81%8B%E3%81%99
https://qiita.com/gahaq/items/cec28c764eebbc9bae0b

2017年10月25日水曜日

Unity : VRプログラム(1)

Unityを利用してVRプログラムを作成します。ターゲットはAndroidとします。
環境設定(Unity, Android SDK, JDK、GoogleVR)は設定してあるとします。
VRの環境設定は、
https://developers.google.com/vr/unity/get-started
を参考にします。 この中にもリンクはありますが、GoogleVRは
https://github.com/googlevr/gvr-unity-sdk/releases
からダウンロードしておきます。
注意点として、AndroidStudio2.3.3では
/Users/mizuno/Library/Android/sdk/tools
このtoolsの構造が変更されたらしく、Unityでアクセスできなかったので、toolsをダウンロードしてフォルダごと置き換える必要があります。僕はtools_r25.2.5-macosx.zipをダウンロードして置き換えました。

(1) プロジェクト作成
今回はVR01というプロジェクトにします。
プリミティブオブジェクトを用意していきます。
Planeを用意
GameObject->3DObject->Plane

 次にCubeを持ってきます。
同様にSphereを持ってきます。
この2つに色をつけるためのスクリプトを作成します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class changeColorScript : MonoBehaviour {
// Use this for initialization
void Start () {
Renderer rend = GetComponent<Renderer>();
rend.material.shader = Shader.Find("Object");
rend.material.SetColor("_Object",Color.red);
}
// Update is called once per frame
void Update () {
}
}


これをAdd Component -> Script -> changeColorScript.cs を選択しておきます。

次に、もう一つPlaneを持ってきて設定します(PhotoPlane)。




Project -> Assets -> Materials に画像ファイルを置いておき、PhotoPlaneに適用します。



(2) VRの設定

Assetを右クリックして、import package -> cunsom Package -> VRファイルを選択
全てをインポートします。
Game Object -> Create Emptyで作成したオブジェクトの名前をVREyeとします。
この中にMain Cameraを入れて値をリセットします。
 さらにAssete -> GoogleVR -> Prefabs -> GvrEditorEmulatorを入れます。







(3) VRのAndrtoid転送
File -> Build Setting でAndroidを選択し、Switch Platformを押します。
次にPlayer Settingで次のように設定します。


これでAndroid端末に転送し、確認します。

2017年10月22日日曜日

CISCO MERAKI APIの利用(2)

CISCO MERAKI APIを使ってデータベース化してみます。
Organization -> Network -> Device -> Client の順で作成します。

(1) テーブルの作成
organizations, networks, terminals, clientsテーブルを作成します。
organizationsテーブル
CREATE TABLE IF NOT EXISTS `organizations` (
`id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


networksテーブル
CREATE TABLE IF NOT EXISTS `networks` (
`id` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`organization_id` int(11) NOT NULL,
`timeZone` varchar(255) DEFAULT NULL,
`tags` varchar(255) DEFAULT NULL,
`type` varchar(255) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


terminalsテーブル
CREATE TABLE IF NOT EXISTS `terminals` (
`id` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`network_id` varchar(255) NOT NULL,
`lanip` varchar(255) DEFAULT NULL,
`mac` varchar(255) DEFAULT NULL,
`lat` double DEFAULT NULL,
`lng` double DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
`model` varchar(255) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


clientsテーブル
CREATE TABLE IF NOT EXISTS `clients` (
`id` varchar(255) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`terminal_id` varchar(255) NOT NULL,
`mdnsName` varchar(255) DEFAULT NULL,
`dhcpHostname` varchar(255) DEFAULT NULL,
`mac` varchar(255) DEFAULT NULL,
`ip` varchar(255) DEFAULT NULL,
`vlan` varchar(255) DEFAULT NULL,
`sent` int(11) DEFAULT NULL,
`recv` int(11) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


(2) API関数群の作成
API関数については、関数名をapiテーブル名としてAppControllerの中に作成します。
 
public function apiOrganization(){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://dashboard.meraki.com/api/v0/organizations/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: application / json",
"postman-token: 328a4947-4d6d-4152-0042-3c95b79f541a",
"x-cisco-meraki-api-key: naisyo"
),
CURLOPT_FOLLOWLOCATION => TRUE
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
/*
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
*/
$res = json_decode($response);
return $res;
}
public function apiNetwork($organization_id = NULL){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://dashboard.meraki.com/api/v0/organizations/".$organization_id."/networks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: application / json",
"postman-token: 5a044421-38e9-58d1-5c1b-344513ee9bb2",
"x-cisco-meraki-api-key: naisyo"
),
CURLOPT_FOLLOWLOCATION => TRUE
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
$res = json_decode($response);
return $res;
}
public function apiTerminal($network_id = NULL){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://dashboard.meraki.com/api/v0/networks/".$network_id."/devices",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: application / json",
"postman-token: 75399286-ba00-ddcf-8037-959e7db17ff6",
"x-cisco-meraki-api-key: naisyo"
),
CURLOPT_FOLLOWLOCATION => TRUE
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
$res = json_decode($response);
return $res;
}
public function apiClient($terminal_id = NULL){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://dashboard.meraki.com/api/v0/devices/".$terminal_id."/clients?timespan=600",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: application / json",
"postman-token: 9b62c72d-46ba-615b-0426-2f790551fbb1",
"x-cisco-meraki-api-key: naisyo"
),
CURLOPT_FOLLOWLOCATION => TRUE
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
$res = json_decode($response);
return $res;
}
}
~
view raw AppController hosted with ❤ by GitHub


apiOrganization関数呼び出しをします。OrganizationsControllerに記述します。
public function getOrganization() {
$this->Organization->recursive = 0;
$this->set('organizations', $this->Paginator->paginate());
$result = $this->apiOrganization();
$data = array(
'id' => $result[0]->id,
'name' => $result[0]->name,
);
$this->Organization->save($data);
return $this->redirect(array('action' => 'index'));
}
view raw getOrganization hosted with ❤ by GitHub


次にネットワークを取得します。これもOrganizationsControllerに記述します。
public function getNetwork($id = null) {
if (!$this->Organization->exists($id)) {
throw new NotFoundException(__('Invalid organization'));
}
$options = array('conditions' => array('Organization.' . $this->Organization->primaryKey => $id));
$this->set('organization', $this->Organization->find('first', $options));
APP::import('Model','Network');
$this->Network = new Network;
$results = $this->apiNetwork($id);
foreach($results as $result){
$data = array(
'id' => $result->id,
'name' => $result->name,
'organization_id' => $result->organizationId,
'timeZone' => $result->timeZone,
'tags' => $result->tags,
'type' => $result->type
);
$this->Network->save($data);
}
return $this->redirect(array('controller' => 'networks','action' => 'index'));
}
view raw getNetwork hosted with ❤ by GitHub


次にデバイスを取得します。これはNetworksControllerに記述します。
public function getTerminal($id = null) {
if (!$this->Network->exists($id)) {
throw new NotFoundException(__('Invalid network'));
}
$options = array('conditions' => array('Network.' . $this->Network->primaryKey => $id));
$this->set('network', $this->Network->find('first', $options));
APP::import('Model','Terminal');
$this->Terminal = new Terminal;
$results = $this->apiTerminal($id);
foreach($results as $result){
$data = array(
'id' => $result->serial,
'name' => $result->name,
'network_id' => $result->networkId,
'lanip' => $result->lanIp,
'mac' => $result->mac,
'lat' => $result->lat,
'lng' => $result->lng,
'address' => $result->address,
'model' => $result->model,
);
$this->Terminal->save($data);
}
return $this->redirect(array('controller' => 'terminals','action' => 'index'));
}
view raw getTerminal hosted with ❤ by GitHub


次にクライアント情報を取得します。これはTerminalsControllerに記述します。
public function getClient($id = null) {
if (!$this->Terminal->exists($id)) {
throw new NotFoundException(__('Invalid terminal'));
}
$options = array('conditions' => array('Terminal.' . $this->Terminal->primaryKey => $id));
$this->set('terminal', $this->Terminal->find('first', $options));
APP::import('Model','Client');
$this->Client = new Client;
$results = $this->apiClient($id);
foreach($results as $result){
$data = array(
'id' => $result->id,
'name' => $result->description,
'terminal_id' => $id,
'mdnsName' => $result->mdnsName,
'dhcpHostname' => $result->dhcpHostname,
'mac' => $result->mac,
'ip' => $result->ip,
'vlan' => $result->vlan,
'sent' => $result->usage->sent,
'recv' => $result->usage->recv,
);
$this->Client->save($data);
}
return $this->redirect(array('controller' => 'clients','action' => 'index'));
}
view raw getClient hosted with ❤ by GitHub

これで情報を取得できました。

(3) Client情報の自動化
Client APIでは時刻がありません。取得した時刻を利用時刻とみなしてやってみます。
Client情報は随時更新されるので、5分に一度取得するようにします。
Shellを作成します。
app]$ vi Console/Command/MerakiShell.php
<?php
class MerakiShell extends Shell {
function main () {
App::import('Model','Terminal');
$this->Terminal = new Terminal;
$this->Terminal->recursive = 0;
$terminals = $this->Terminal->find('all');
APP::import('Model','Client');
$this->Client = new Client;
foreach($terminals as $terminal){
$results = $this->apiClient($terminal['Terminal']['id']);
foreach($results as $result){
$data = array(
'id' => $result->id,
'name' => $result->description,
'terminal_id' => $terminal['Terminal']['id'],
'mdnsName' => $result->mdnsName,
'dhcpHostname' => $result->dhcpHostname,
'mac' => $result->mac,
'ip' => $result->ip,
'vlan' => $result->vlan,
'sent' => $result->usage->sent,
'recv' => $result->usage->recv,
);
$this->Client->save($data);
}
}
}
public function apiClient($terminal_id = NULL){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://dashboard.meraki.com/api/v0/devices/".$terminal_id."/clients?timespan=600",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: application / json",
"postman-token: 9b62c72d-46ba-615b-0426-2f790551fbb1",
"x-cisco-meraki-api-key: naisyo"
),
CURLOPT_FOLLOWLOCATION => TRUE
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
$res = json_decode($response);
return $res;
}
}
?>
view raw MerakiShell.php hosted with ❤ by GitHub


シェルスクリプトを作成
app]$ vi Vendor/MerakiShell.sh
#!/bin/bash

cd /home/ms000/www/oc/app
Console/cake meraki

権限を与えておきます。
app]$ chmod +x Vendor/MerakiShell.sh

cronに登録します。
app]$ crontab -e
0-59/5 * * * * /home/ms000/www/oc/app/Vendor/MerakiShell.sh

これでクライアント情報が自動で取得できるようになりました。

CISCO MERAKI APIの利用(1)

CISCO MERAKI APIの利用をしてみます。
(1) APIの内容
https://dashboard.meraki.com/api_docs
上記のリンクにAPIの説明があります。
この中で、Organizationsを見てみると、curlで取ってきているようです。
これを実施すると、OrganizationIDを取得できます。このOrganizationIDは他のAPIでも使うので最初にやるのが良さそうです。順番としては
Organizations -> Networks -> Devices -> Clients が良さそうです。

(2) Meraki DashboardでのAPI Keyの取得
Meraki Dashboard -> Profile -> API Access からAPIキーを生成しておきます。

(3) POSTMANの利用
Meraki APIを利用する時に、確認しやすいツールがPOSTMANです。
https://www.getpostman.com/apps
からダウンロードして起動します。 または
https://documenter.getpostman.com/view/897512/meraki-dashboard-prov-api/2To9xm#16dcb4fa-30f3-6ca5-d85a-0988c486eeef
でやってみます。
Organizations APIを利用する場合、
Getの部分:https://dashboard.meraki.com/api/v0/organizations/
Headersの部分
Key : X-Cisco-Meraki-API-Key   Value : (2)で取得したもの
Key : Content-Type                  Value : application / json
Sendを押して、値を取得してみると結果が取得できます。
画面の右側にあるCodeを押すと、プログラムコードを取得できます。今回はPHPのcURLで取得しておきます。




(4) PHPから利用してみる
PHPでapiOrganization関数を作成します。
public function apiOrganization(){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://dashboard.meraki.com/api/v0/organizations/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: application / json",
"postman-token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"x-cisco-meraki-api-key: yyyyyyyyyyyyyyyyyyyyyyyyyyy"
),
CURLOPT_FOLLOWLOCATION => TRUE
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
/*
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
*/
$res = json_decode($response);
return $res;
}
view raw apiOrganization hosted with ❤ by GitHub

POSTMANで作成されたコードに
CURLOPT_FOLLOWLOCATION => TRUE 

を追加しておきます。
参考
https://stackoverflow.com/questions/6077133/using-curl-and-avoiding-being-redirected-to-the-base-url

これをgetOrganization関数から呼び出し、処理をします。
public function getOrganization() {
$this->Organization->recursive = 0;
$this->set('organizations', $this->Paginator->paginate());
$result = $this->apiOrganization();
$data = array(
'id' => $result[0]->id,
'name' => $result[0]->name,
);
$this->Organization->save($data);
return $this->redirect(array('action' => 'index'));
}
view raw getOrganization hosted with ❤ by GitHub

これでAPIで取得できたデータを処理できました。

2017年10月16日月曜日

Eclipse : GIthubの利用

EclipseからGithubを利用し、ソースをアップロードします。
(1) Githubアカウントの作成
https://github.com/
にアクセスし、アカウントを作成、ログインします。
ログイン後、New Repositoryからtest01というリポジトリを作成します。
作成されたページの
Quick setup — if you’ve done this kind of thing before
は後で必要なのでページをそのままにしておきます。

(2) Eclipseからアップロード
Eclipseで作成したTest01プロジェクトをアップロードします。
プロジェクトを右クリックし、Team -> Share Projectをクリック
Use or Create ... にチェックを入れ、Test01プロジェクトをクリックして下のCreate Repositoryをクリック
フォルダやファイルに?がつきます。
プロジェクトを右クリックして、Team -> Commitをクリック
まだcommitの対象を指定していないので、Team -> Add Index をクリック
Commit Messageを入れておきます。
Commit and Pushをクリックすると、Location -> URIの部分にリポジトリ情報から入れておきます。
ユーザ認証をします。
github側で確認してみると、アップロードされていることが確認できます。

参考
https://qiita.com/cotrpepe/items/7cafaacb538425a78f1f