読者です 読者をやめる 読者になる 読者になる

がりらぼ

WindowsRuntimeの応援ブログ

はてなブログからWordpressに移行しました

日常

たぶんこのブログはもう書かないと思います。

なんでやめるのかというと、別にはてなブログがダメなわけじゃないくて、*1

garicchi.comの方にアクセスを一括化したいという気持ちがあったので今後ブログを書くときはgaricchi.comに書きたい所存です。

garicchi.comの一応ブログカテゴリーに今後は雑記がここに書かれていくと思います。

ブログ | garicchi.com

というわけで今後はgaricchi.comをよろしくお願いします!*2

garicchi.com

*1:むしろブログとしてははてなブログが強い

*2:RSS登録もよろしく!

Nugetでパッケージインストール時に中のファイルのビルドアクションを変更する

PowerShell

Nugetでパッケージ内にビルドアクションを「コンテンツ」とか出力ディレクトリにコピーを「常にコピーする」とかに自動で設定しておきたいファイルをおきたいときがあります。

そういうときはNugetパッケージのToolsフォルダ内のinstall.ps1というスクリプトを置いて、スクリプトからファイルプロパティをいじります。

パッケージはこんな感じで今回はipagithic.fntファイルのビルドアクションをコンテンツにします。

f:id:garicchi:20150601185016p:plain

install.ps1はこんな感じ

param($installPath, $toolsPath, $package, $project)
function Recurse($dir){
    foreach($i in $dir)
    {
        Recurse($i.ProjectItems)
        if($i.Name -eq "ipagothic.fnt")
        {
            $i.Properties.Item("BuildAction").Value = [int]2
            $i.Properties.Item("CopyToOutputDirectory").Value = [int]2
        }
    }
}

Recurse($project.ProjectItems);

ProjectItemの階層をたどって、目的のファイルがみつかったときにプロパティを変更します。

これでパッケージインストール時に自動でファイルのビルドアクションを変更できるようになりました。

MonoGameのWindowsDesktopプロジェクトでGamePadの認識するときに例外がでるやつ

MonoGame

例外で

'xinput1_3.dll' を読み込めません

とでます。

xinput1_3.dllはDirectXエンドユーザーランタイムに入っているのでDirectXをインストールすれば解決しました。

ここからインストールしましょう。

Download DirectX エンド ユーザー ランタイム Web インストーラ from Official Microsoft Download Center

自宅にVPNを張ったら世界が変わった

日常

f:id:garicchi:20150520004053j:plain この間、えろい人(@ichi_sien)にBUFFALOのルーターをもったんですが、このルーターPPTPプロトコルVPNに対応していたので自宅にVPNを張ってみることにしました。

VPNの設定は意外と簡単で、ルーターの設定をちょこっと変えるだけでできました。

でも、どうやらVPN接続のために割り当てられているグローバルIPアドレスは不定期で変わるらしいのでDDNS(Dynamic Domain Name System)を使うらしい。が、BAFFALO公式のやつに契約すると年間3500円ぐらい取られるらしいです。固定IPだともっとかかるのかな?

というわけでフリーのDDNSサービスを利用して、IPアドレスを定期的に更新することにしました。

使ったサービスはmydns

ここはAPIを提供していてHTTP GetするだけでIPを更新できます。

というわけで電気代も心配なのでラズベリーパイwgetをつかってAPIを叩くスクリプトをcronで6時間ごとに走らせることにしました。*1

garicchi.hatenablog.jp

あとはお名前.comのほうから、CNAMEで hogehoge.garicchi.com→mogemoge.mydns.jpと割り当ててやれば、hogehoge.garicchi.comに向かってVPNアクセスすれば固定アドレスにアクセス可能となりました。

これで研究室にいてもおうちネットワークに接続できるぞヤッターって感じだったのですが、思ったより便利で感動しました。

モバイルマシンで高スペックな性能を出すことができる

自宅では常にかずきさん(@okazuki)から格安で買ったCore i7VAIO DUO11が常に起動してるのでVPNを張ることでいつでもそこにリモートデスクトップできます。*2

やっぱりいつでもアクセスするだけで中断している作業を継続できるのは便利ですね。

f:id:garicchi:20150528225719j:plain

Windows8インチタブレットCore i7並のスペックをだすことができるのはやはり魅力的です。

OSを選ばずにVisualStudioが使える

研究室ではUbuntuを、外出時はMacBook Proを、という感じで現在すごしているのですが様々なOSでも、VPN接続してリモートデスクトップするだけでVisualStudioが使えます。

Macの場合は日本語入力切替が面倒ですが(Ctrl+1に割り当ててる)

ネットワークさえあれば端末のスペックが少し低くても端末自体のCPUリソースはあまり食いません。

リモートデバッグができる

VPN張った一番の利点はこれだと思うのですが、VisualStudioのリモートデバッグを、VPNアクセスしてる端末をリモート先として利用することができます。

例えばWindowsストアアプリの場合、

  1. Windows8.1マシンでVPNリモートデスクトップアクセス
  2. リモートデバッグ先のIPアドレスVPNアクセスしてるマシンのIPアドレスにする
  3. VPNアクセスしてるマシンでアプリをデバッグできる

という流れが実現できます。

つまりリモートデスクトップでストアアプリのデバッグがしずらい場合、今もっている端末でデバッグできるという超便利機能ができます。

f:id:garicchi:20150528225446j:plain

もちろんブレークポイントを設定すればブレークも可能です。

これはWindowsストアアプリだけでなく、Xamarin Build Hostに対しても同様のことが言えます。

Macリモートデスクトップ→VisualStudioでコードを書く→MacでBuild Hostを立ち上げてiOSシミュレータでデバッグ

が手持ち端末としてはMac1台で完結させることができます。

もし同様のことをMac1台でやろうとすると、Macの上に仮想マシンWindowsを実行しなければいけないですが、VPNを張ればMacのスペックが低くても、VisualStudioでXamarin.iOSのプログラムを書いてMacの上でデバッグが1台で完結します。 f:id:garicchi:20150520191928j:plain

Macのスペックが低くて仮想マシンを立ち上げることができない僕にとっては非常にありがたいです。

とりあえず、おうちVPNを張ると、予想以上に便利なことがたくさんあったので開発がより便利になりました。

どう世界が変わったか?→ずっと研究室にいることが可能になった(吐血)

*1:冷静に考えて常に起動してるWindowsマシンあるからDiceでもよかった

*2:RDP用のポートを開けてもできる

Arduinoで室温を計測してAzure上でAPIとして公開する

ASP.Net Arduino MicrosoftAzure

de:code2015SNR-003「Windows Phone/iOS/Android アプリ同時開発のススメ」のデータ計測とWebAPI作成をお手伝いさせて頂いてました。

この記事ではArduinoによるデータ計測からAzure上でWebAPIを公開するまでどのように作成できるかをご紹介します。

概要

全体的な構成図はこのようになります。 f:id:garicchi:20150522163930p:plain

コンポーネントとその役割はこのようになります。

テクノロジー名 役割
LM61biz 温度センサー
Arduino UNO & Ethernet Sield 温度計測&アップロード用マイコン
Azure Web Apps データ受信と送信のためのWeb API
Azure SQL Databse 計測データ蓄積のためのデータベース

流れとしてはこのようになります。

  1. 温度センサーで室温計測
  2. Arduino UNOでAzure WebAppsにアップロード
  3. Azure WebAppsからAzure SQL Databaseに蓄積
  4. Azure WebAppsにリクエストがあった場合はSQL Databaseからデータを取得しレスポンス

温度計測部

回路図はこのようになります。

LM61biz温度センサーで受け取った値をArduinoのA0ピンへと入力します。

f:id:garicchi:20150522155940p:plain

回路はブレッドボードとジャンパー線を使って作成し、ArduinoにはEthernet SieldをつけてインターネットにつながるLANに接続しておきます。

f:id:garicchi:20150301140659j:plain

Arduinoソースコードはこのようになります。

#include <SPI.h>
#include <Ethernet.h>

//your ethernet sield mac address
byte mac[] = { 0x**, 0x**, 0x**, 0x**, 0x**, 0x** };

//your server name
const char *server = "http://******.azurewebsites.net/api/temp";
//your server hostname
const char *host = "******.azurewebsites.net";

//your input pin
int tempPin=A0;

EthernetClient client;

unsigned long prevTime=0;
 
void send_request(float value)
{
  char buffer[256];
  char value_str[64];
  
  if (client.connect(host, 80)) {

    sprintf(buffer, "POST %s HTTP/1.1", "/api/temp");
    client.println(buffer);
    sprintf(buffer, "Host: %s", host);
    client.println(buffer);
 
    client.println("Content-Type: application/json");
 
    dtostrf(value,5,2,value_str);  //Arduinoではsprintfで小数をあつかうことができないのでこれ
    sprintf(buffer, "%s",value_str);
 
    client.print("Content-Length: ");
    client.println(strlen(buffer));
    
    client.println();
 
    client.println(buffer);
    Serial.println(buffer);
  }
  
}

void read_response()
{
  bool print = true;
  
  while (client.available()) {
    
    char c = client.read();
    // Print only until the first carriage return
    if (c == '\n')
      print = false;
    if (print)
      Serial.println(c);
  }
}
 
void setup()
{
  Serial.begin(9600);
  Ethernet.begin(mac);
  prevTime=0;
  delay(1000);
}

void loop()
{
  //send hourly <-- 100millisec * 60 seconds * 60minutes
  if((millis()-prevTime)>(unsigned long)(3600000)){
    int val = analogRead(tempPin);
    
    
    float temp=(float)val*500/1024-60;
    
    send_request(temp);
    read_response();
    client.stop();
    
   
    prevTime=millis();
    delay(1000);
    
  }
   
  
  
}

変更点としてはMacAddress、ServerName、ServerHostName、Pin番号の4つです。 f:id:garicchi:20150522162113p:plain

このコードではloop関数内で1時間ごとにデータを送信するようにしています。

millis()関数がミリセカンドの単位で時間を計測できるので、1時間=3600000ミリセカンド経過したらデータを送信するという形にしています。

アナログ入力を受け取ると電圧値から温度へとデータ変換をおこないます。データ変換に関してはこちらを参照してください。

f:id:garicchi:20150522164133p:plain

send_request関数ではPOSTリクエストを作成してデータを送信しています。

データ蓄積部

Arduinoから送信されたデータは、AzureWebApps上にホスティングされたASP.Net WebAPIを通し、Azure SQL Databaseへと送信されます。

まずAzure WebAppsとAzure SQL Databaseのインスタンスを作りましょう。

Azureでのインスタンスの作り方は以下を参考にしてください。

Azure アプリ サービスでの ASP.NET Web アプリの作成

Get started with SQL Database

次にSQL Databaseにテーブルを作りましょう。今回は以下のようにしました。

テーブル名 Temperature

カラム

カラム名 内容
Id 一意なID int
RegisterDate 日付 datetime
Temp 気温 float

続いてASP.Net WebAPIでGetとPostメソッドを作ります。

ASP.Net Web APIについてはこちらを参考にしてください。

Insider.NET > 連載:ASP.NET Web API 入門 - @IT

PostメソッドArduinoからのデータ受信用、Getメソッドはモバイルアプリへのデータ返却用に使用します。

public class TempController : ApiController
{
    //モバイルアプリからGetリクエストをうけたとき
    public IEnumerable<Temperature> Get([FromUri]DateTime from,DateTime to)
    {
        var tempList = new List<Temperature>();
        //SQL接続
        var connectionStr = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
        using (var connection = new SqlConnection(connectionStr))
        {
            connection.Open();
            //クエリ引数にある指定の日付を条件にSQLクエリを作る
            var sql = string.Format("select * from dbo.Temperature where RegisterDate >= '{0}' and RegisterDate < '{1}' order by RegisterDate",
                from,to);

            //SQL発行
            using (var command = new SqlCommand(sql, connection))
            {
                using(var reader = command.ExecuteReader())
                {
                    //取得した結果をコレクションに入れる
                    while (reader.Read())
                    {
                        var date = reader.GetDateTime(1);
                        var val = reader.GetDouble(2);

                        tempList.Add(new Temperature
                        {
                            RegisterDate = date,
                            Value = (float)val
                        });
                        
                    }
                }
                
            }
            connection.Close();
        }

        //結果返却
        return tempList;
    }

    //ArduinoからデータがPostされたとき
    public HttpResponseMessage Post()
    {
        //stringとしてPostの内容を読む
        var content = this.Request.Content.ReadAsStringAsync().Result;
        //float変換
        var t = float.Parse(content);
        //データを挿入するSQLクエリの作成
        //時間に関しては世界標準時を取得できるので+9
        var sql = string.Format("insert into dbo.Temperature values('{0}','{1}')",
        DateTime.Now.AddHours(9), t);

        //SQL接続
        var connectionStr = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
        using (var connection = new SqlConnection(connectionStr))
        {
            connection.Open();

            using (var command = new SqlCommand(sql, connection))
            {
                //SQL発行
                command.ExecuteNonQuery();
            }
            
            connection.Close();
        }
        //レスポンスを返す
        var result = new HttpResponseMessage();
        result.Content = new StringContent("OK");
        result.StatusCode = HttpStatusCode.OK;
        return result;
    }


}

作成したASP.net APIのWeb.configファイルのSQLDatabase接続文字列を編集します。

今回はDefaultConnectionという名前を使うのでconnectionStringタグを編集します。

<connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=tcp:{server hostname},1433;Initial Catalog={databasename};User Id={user id};Password={pass};" providerName="System.Data.SqlClient" />
    
</connectionStrings>

接続文字列は管理ポータルからも見ることができます。 f:id:garicchi:20150526131655p:plain

WebAPIができたらAzure Web Appsへとデプロイします。

Azure Web Appsへのデプロイには発行プロファイルを利用すると便利です。

MSDN Blogs

あとはデプロイしたサイトに向かってHttpアクセスをすると、溜まった気温データを取得することができます。

クエリ引数にはfromとtoにDateTimeに変換できる文字列を入れると、fromとto間の気温データを取得することができます。 f:id:garicchi:20150526132248p:plain

VisualStudioでも入っているデータを閲覧することができます。

f:id:garicchi:20150526132725p:plain

以上でArduinoで計測したデータをAzureにアップロードし、WebAPIとして公開することができました。

decode2015ではさらにWebAPIをXamarin Formから利用してグラフ化するのでぜひ、いろんなプラットフォームでこのようなAzureを利用したIoTシステムを構築してみるといいと思います。 *

Minecraft買ってもらった

日常

かずきさん@okazukiからMinecraftのお誘いがあったのでルンルン気分でダウンロードしようと思ったらこれフリーソフトじゃないんですね...

3000円買いきりですが今の僕には3000円すら惜しいレベルなので諦めてたら可知さん@Kazuki_Kachiさんが買ってくれました!!

なんという海のように広い心...!!!学生の僕は感動しすぎて兄貴!!!一生ついていきます!!って感じでした。

せっかくかって頂いたので精一杯遊ぼうと思います!

そういえばVisualStudioと連携できるだどったらこったら発表があったのでそこらへんたのしみですね!