Grow up

生活とプログラミング

Arduinoでフロートスイッチ(定水位スイッチ)を使ってみた

f:id:knkomko:20190921215526p:plain:w450

はじめに

前回は水位センサーを使いました。
knkomko.hatenablog.com

豆苗の水位を検知する目的で水位センサーを購入したのですが、しばらく使ってみると青い沈殿物が発生し油まで浮いてきたため使用を止めました。
f:id:knkomko:20190921215046j:plain:w250

今回は豆苗に使うことを考えて食品衛生法適合のフロートスイッチを使用します。
www.monotaro.com

フロートスイッチ

磁石の付いた浮きが上下する事で出力値が大きく変化するので、しきい値を使って変化を検知します。
www.youtube.com

配線

実際の配線図
f:id:knkomko:20190921210706p:plain:w350

半固定抵抗器を使いフロートスイッチの値をArduinoで読み込みます。
半固定抵抗器は真ん中の部品を右に回すことで抵抗量を増やすことができます。
抵抗量を最小にすると値の変化が無くなり、水位の変化も検知できませんでした。
今回は分かり易いように抵抗量を最大にして値の変化量を増やしています。
f:id:knkomko:20190921225041j:plain:w350

半固定抵抗器の左端子はArduinoの3.3Vに繋がり、右端子はフロートスイッチに繋がっています。
半固定抵抗器の右端子にArduinoの3.3Vを繋ぐとセンサー値が変化しなかったので配線を間違えないように注意してください。

しきい値の確認

センサーによって値の変化量が変わるため確認します。
私の場合は赤線から下に浮きが沈む事で値が0から706に変わりました。
f:id:knkomko:20190921221848j:plain:w350

ソースコード
int watorLevel = 0;     // holds the wator level value
int watorLevelPin = A0; // wator level sensor pin used

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9800);
}

void loop() {
  // put your main code here, to run repeatedly:
  // read wator level
  watorLevel = analogRead(watorLevelPin);
  Serial.println("Wator Level: Empty(" + String(watorLevel) + ")");
  if(watorLevel > 700) {
    Serial.println("水が空になりそうだよ (" + String(watorLevel) + ")");
  }
  delay(2000);
}

ArduinoでIFTTTを使ってツイートする方法

f:id:knkomko:20190920232259p:plain

はじめに

前回はTweetライブラリを使用してツイートしていました。
knkomko.hatenablog.com

今回は「IoT技術テキスト」で紹介されていたIFTTT (イフト) というアプリ連携サービスを使ってツイートしてみます。

IoT技術テキスト -MCPC IoTシステム技術検定 対応-

IoT技術テキスト -MCPC IoTシステム技術検定 対応-

1日にIFTTTを使用してツイート可能な回数は100回までのようです。


IFTTT とは

IFTTT(イフト)は、「レシピ」と呼ばれる個人作成もしくは公に共有しているプロフィールを使って数あるWebサービスFacebookEvernote、Weather、Dropboxなど)同士で連携することができるWebサービスである。
IFTTT - Wikipedia

Webhooks サービスの追加

Webhooks サービスはPOSTリクエストをトリガーとして別のサービスを実行する事が出来ます。

以下のIFTTT公式サイトにアクセスします。
Every thing works better together - IFTTT

右上の[Sign up]を左クリック。
f:id:knkomko:20190920234551p:plain:w350

右上の[人物アイコン]を左クリック。
f:id:knkomko:20190920234733p:plain:w350

表示されたメニューから[Create]を左クリック。
f:id:knkomko:20190920234915p:plain:w350

IfとThisの間にある[+]を左クリック。
f:id:knkomko:20190920235020p:plain:w350

検索窓に「Webhooks」と入力して表示されたアイコンを左クリック。
f:id:knkomko:20190920235153p:plain:w350

画面に表示されている[Receive a web request]を左クリック。
f:id:knkomko:20190920235314p:plain:w350

「Event Name」を入力したら[Create trigger]を左クリック。
f:id:knkomko:20190920235514p:plain:w350

Twitter サービスの追加

POSTリクエストによりWebhooksで受け取ったJSONをツイートするように設定します。

ThenとThatの間にある[+]を左クリック。
f:id:knkomko:20190920235701p:plain:w350

検索窓に「Twitter」と入力して表示されたアイコンを左クリック。
f:id:knkomko:20190920235801p:plain:w350

[Connect]ボタンを左クリック。
f:id:knkomko:20190920235845p:plain:w350

Arduinoからツイートするアカウントでログイン。
f:id:knkomko:20190920235948p:plain:w350

[Post a tweet]を左クリック。
f:id:knkomko:20190921000034p:plain:w350

Tweet text」欄に入力されている内容を消します。
f:id:knkomko:20190921000131p:plain:w350

[Add ingredient]から表示されたメニューの[Value1]を左クリック。
f:id:knkomko:20190921000437p:plain:w350

Tweet text欄に「Value1」の入力がされた事を確認して[Create action]を左クリック。
f:id:knkomko:20190921000651p:plain:w350

「Receive notifications when this applet runs」は必要に応じて選択します。
f:id:knkomko:20190921011519p:plain:w350

Webhooks と Twitter の連携確認

右上の「人物アイコン」を左クリックします。
f:id:knkomko:20190921011549p:plain:w350

表示されたメニューから[My services]を左クリックします。
f:id:knkomko:20190921011614p:plain:w350

[Webhooks]を左クリック。
f:id:knkomko:20190921001511p:plain:w350

表示されている Twitter アイコンを左クリック。
f:id:knkomko:20190921001552p:plain:w350

灰色で塗りつぶしている文字列はユーザーごと一意の情報です。
「Your key is : ~」のキーはArduinoからツイートする際に使用します。
f:id:knkomko:20190921002539p:plain:w350

また、こちらの画面でツイートの確認が出来るので試しておきましょう。
1.「Make a POST or GET of request to: ~」のURLにEvent Nameを入力。
2.「With an optional JSON body of: ~」のValue1にツイートしたい文字列を入力。
3. [Test it]を左クリック。
f:id:knkomko:20190921002539p:plain:w350

Value1に指定していた文字列がツイートされます。
f:id:knkomko:20190921003839p:plain:w350

Ethernet2 ライブラリのインストール

スケッチの[ツール] → [ライブラリの管理]を左クリック。
f:id:knkomko:20190921004055p:plain:w350

Ethernet2 のライブラリをインストールします。
f:id:knkomko:20190921004152p:plain:w350

ソースコード

requestHead1で指定している[EventName]と[YourKey]はWebhooksの情報を入力します。

#include <Ethernet2.h>

byte mac[] = { 0xA8, 0x61, 0x0A, 0xAE, 0x50, 0x49 }; // Your Ethernet Shield MAC Address
IPAddress ip(192, 168, 0, 15);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
EthernetClient client;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Trying to get an IP address using DHCP");
  if (Ethernet.begin(mac) == 0)
  {
    Serial.println("Failed to configure Ethernet using DHCP");
    Ethernet.begin(mac, ip, gateway, subnet);
  }
  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());
  Serial.println ();
}

void loop() {
  // put your main code here, to run repeatedly:
  for(int i=10; i>0; i--)
  {
    Serial.println(i);
    delay(1000);
  }
  
  if ( client.connect("maker.ifttt.com", 80) )
  {
    Serial.println("connected");
    // POST request
    String requestBody = String("{\"value1\":\"Hello, World!\"}");
    int bodyLength = requestBody.length();
    String requestHead1 = "POST /trigger/[EventName]/with/key/[YourKey] HTTP/1.1\r\n" +
                          String("Host: maker.ifttt.com\r\n") +
                          "Content-Type: application/json\r\n";
    String requestHead2 = "Content-Length: " + String(bodyLength) + "\r\n" + "\r\n";
    client.print(requestHead1 + requestHead2 + requestBody);
    delay( 1000 );
    Serial.println("--- request ---");
    Serial.println(requestHead1 + requestHead2 + requestBody);
    Serial.println("---------------");
    Serial.println("Sent message");
  }
  else
  {
    Serial.println("Error: Could not make a TCP connection");
  }
  Serial.println("--- response ---");
  while (client.available())
  {
    char c = client.read();
    Serial.print(c);
  }
  Serial.println("----------------");
  if (!client.connected())
  {
    client.stop();
  }
}

Arduinoで水位センサーを使ってみた

f:id:knkomko:20190918052239j:plain:w450


前回はArduinoから温湿度のツイートをしました。
knkomko.hatenablog.com

今回は水位センサーを使ってみます。
www.amazon.co.jp

ただこの水位センサーを10分くらい使うと泡と青色の液体が出てきました。
植物の水位をツイートしようと思いましたが、害がありそうなので保留中です。
f:id:knkomko:20190918060610j:plain:w250

配線

実際の配線図
f:id:knkomko:20190918055412j:plain:w350

ソースコード
int watorLevel = 0;     // holds the wator level value
int watorLevelPin = A0; // wator level sensor pin used

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  watorLevel = analogRead(watorLevelPin);

  if(watorLevel <= 100) {
    Serial.println("Wator Level: Empty(" + String(watorLevel) + ")");
  }
  else if(watorLevel > 100  && watorLevel <= 200) {
    Serial.println("Wator Level: Low(" + String(watorLevel) + ")");
  }
  else if(watorLevel > 200 && watorLevel <= 260) {
    Serial.println("Wator Level: Medium(" + String(watorLevel) + ")");
  }
  else if(watorLevel > 260) {
    Serial.println("Wator Level: High(" + String(watorLevel) + ")");
  }
  delay(1000);
}
センサーの値を調べる

水位を知る為の値はセンサーごとに違うようです。
実際に値を調べて変更をしてください。

センサーの値が約100の水位
f:id:knkomko:20190918060004j:plain:w350

センサーの値が約200の水位
f:id:knkomko:20190918060015j:plain:w350

Arduinoから温湿度をツイートする方法

f:id:knkomko:20190916223514p:plain:w450

ツイートする

まずはArduinoから使用するアカウントのトークンを取得します。
以下のサイトにアクセスします。
arduino-tweet.appspot.com

トークンの役割についてはOAuth認証の仕組みをご確認ください。
一番分かりやすい OAuth の説明 - Qiita

1.トークンの取得

Get a token to post a message using OAuth. を左クリック。
f:id:knkomko:20190916233653p:plain:w350

Twitterのアカウント情報を入力して[Authrize app]を左クリック。
f:id:knkomko:20190916233842p:plain:w350

Twitterアカウントに対応したトークンが発行されます。
表示された文字列をプログラム内で使用します。
f:id:knkomko:20190916233951p:plain:w350

2. Stewitter ライブラリをインクルード

OAuth認証を使ってツイートを行う為にライブラリをインクルードします。
以下の記事を参考にしました。
Arduinoで遊ぼう - OAuthを使って安全につぶやくライブラリ「Stewitter」 - なんでも作っちゃう、かも。

以下のリポジトリにアクセスします。
github.com

[Download ZIP]を左クリック。
f:id:knkomko:20190916234810p:plain:w350

スケッチの[ZIP形式のライブラリをインストール]を左クリック。
f:id:knkomko:20190916234914p:plain:w350

ダウンロードしていたStewitterのライブラリを開いてインクルードします。
f:id:knkomko:20190916235027p:plain:w350

3. ソースコード

Tweet Library for Arduino にあるStep3のサンプルが動きませんでした。
変更点は Ethernet.begin(mac); でIPアドレスの指定を無くしています。
問題解決には以下の記事が参考になりました。
forum.arduino.cc

"Hello, World"とツイートします。

#if defined(ARDUINO) && ARDUINO > 18   // Arduino 0019 or later
#include <SPI.h>
#endif
#include <Ethernet.h>
#include <Twitter.h>

// Arduino イーサネットシールドのMACアドレス
byte mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
// Tweet Library for Arduino で発行したトークンをYourTokenに入力
Twitter twitter("YourToken");

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Ethernet.begin(mac);
  String message = "Hello, World!";
  char* msg = message.c_str();
  Serial.print("connecting ...");
  if (twitter.post(msg)) {
    int status = 0;
    status = twitter.wait();
    if (status == 200) {
      Serial.println("OK.");
    } else {
      Serial.print("failed : code ");
      Serial.println(status);
    }
  } else {
    Serial.println("connection failed.");
  }
}

void loop() {
  // put your main code here, to run repeatedly:
}
温湿度を読み込む

今回はスターターキットに付属していたDHT11を使用します。
f:id:knkomko:20190917010928j:plain:w250

1. 配線する

配線については以下の記事を参考にしました。
Arduino 入門 Lesson 11 【温湿度センサ編】 | おもろ家

実際の配線図
f:id:knkomko:20190917005153p:plain:w350

2. DHT ライブラリのインクルード

スケッチの[ライブラリの管理]を左クリック。
f:id:knkomko:20190917005648p:plain:w350

DHT Sensor Library をインストールします。
f:id:knkomko:20190917005802p:plain:w350

3. ソースコード

湿度、温度、不快指数を出力します。

#include "DHT.h" //ライブラリインクルード
#define DHT_Pin 8 //DHT11DATAピンを定義
#define DHT_Type DHT11 //センサの型番定義 DHT11,DHT22など

DHT dht(DHT_Pin, DHT_Type); //センサ初期化
float humidity = 0.0f; //湿度
float tempC = 0.0f; //摂氏温度
float discomfortIndex = 0.0f; //不快指数

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("DHT11"); //画面に表示
  dht.begin(); //温湿度センサー開始
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(2000); //2秒待つ データの読み出し周期1秒以上必要。
  humidity = dht.readHumidity(); //湿度の読み出し
  tempC = dht.readTemperature(); //温度の読み出し 摂氏
  /* 読み取れたかどうかのチェック */
  if (isnan(humidity) || isnan(tempC) || isnan(tempF)) {
  Serial.println("Read failure!");
  }
  /* 不快指数計算 */
  discomfortIndex = 0.81f * tempC + 0.01f * humidity * (0.99f * tempC - 14.3f) + 46.3f;
  /* 以下読み取り値の表示 */
  Serial.print("Humidity:" + String(humidity) + "%");
  Serial.print("Temperature:" + String(tempC) + "*C");
  Serial.print("Discomfort index:" + String(discomfortIndex));
}
4. 温湿度をツイートするソースコード
// Tweet
#if defined(ARDUINO) && ARDUINO > 18   // Arduino 0019 or later
#include <SPI.h>
#endif
#include <Ethernet.h>
#include <Twitter.h>
// 温度計
#include "DHT.h" //ライブラリインクルード
#define DHT_Pin 8 //DHT11DATAピンを定義
#define DHT_Type DHT11 //センサの型番定義 DHT11,DHT22など
// Tweet
byte mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
Twitter twitter("YourToken");
// 温度計
DHT dht(DHT_Pin, DHT_Type); //センサ初期化
float humidity = 0.0f; //湿度
float tempC = 0.0f; //摂氏温度
float discomfortIndex = 0.0f; //不快指数

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  delay(1000);
  for(int i=5; i>0; i--)
  {
    Serial.println(i);
    delay(1000);
  }
  // 温度計 
  Serial.println("DHT11"); //画面に表示
  dht.begin(); //温湿度センサー開始
  // Tweet
  Ethernet.begin(mac);
}

void loop() {
  // put your main code here, to run repeatedly:
  // 2分に1回ツイートする
  for(int i=0; i<2; i++)
  {
    delay(30000);
    Serial.println(i);
  }
  // 温度計
  delay(2000); //2秒待つ データの読み出し周期1秒以上必要。
  humidity = dht.readHumidity(); //湿度の読み出し
  tempC = dht.readTemperature(); //温度の読み出し 摂氏
  /* 読み取れたかどうかのチェック */
  if (isnan(humidity) || isnan(tempC) || isnan(tempF)) {
  Serial.println("Read failure!");
  }
  /* 不快指数計算 */
  discomfortIndex = 0.81f * tempC + 0.01f * humidity * (0.99f * tempC - 14.3f) + 46.3f;
  /* 以下読み取り値の表示 */
  Serial.print("Humidity:" + String(humidity) + "%");
  Serial.print("Temperature:" + String(tempC) + "*C");
  Serial.print("Discomfort index:" + String(discomfortIndex));
  // Tweet
  String message = "湿度: " + String(humidity) + "% %0D気温: " + String(tempC) + "°C %0D不快度指数: " + String(discomfortIndex);
  char* msg = message.c_str();
  Serial.print("connecting ...");
  if (twitter.post(msg)) {
    int status = 0;
    status = twitter.wait();
    if (status == 200) {
      Serial.println("OK.");
    } else {
      Serial.print("failed : code ");
      Serial.println(status);
    }
  } else {
    Serial.println("connection failed.");
  }
}
まとめ

接触不良に悩まされハードウェアの難しさを感じました。
とりあえずArduinoは窓際の植物の傍に置いて動作の様子見です。
f:id:knkomko:20190917011441j:plain:w250

VisualStudio 2019 インストーラの作成方法

f:id:knkomko:20190914235200p:plain:w150

VisualStudio2019で配布用のインストーラを作成します。
ツールは VisualStudio Instller を使用します。

1. Installer Project のダウンロード

インストーラを作成するプロジェクトの[拡張機能の管理(M)]を開きます。
f:id:knkomko:20190914235621p:plain:w350

オンラインの項目を選択して検索欄に「Installer Projects」と入力します。
表示されたMicrosoft Visual Studio Installer Projectsの[ダウンロード]を左クリック。
f:id:knkomko:20190915000244p:plain:w350

VisualStudioの終了を促されるので開いているプロジェクトを閉じます。
f:id:knkomko:20190915000321p:plain:w350

VisualStudioを終了するとウィンドウが起動するので[Modify]を左クリック。
f:id:knkomko:20190915000443p:plain:w350

以下のウィンドウが表示されたらダウンロードの完了です。
f:id:knkomko:20190915000553p:plain:w350

2. Installer Project の作成

インストーラを作成するプロジェクトを再度開きます。
プロジェクト名を右クリックして[追加] → [新しいプロジェクト(N)]を左クリック。
f:id:knkomko:20190915000931p:plain:w350

検索欄に「Installer」と入力して表示された[Setup Project]を選択して[次へ(N)]を左クリック。
f:id:knkomko:20190915001132p:plain:w350

必要に応じて名前を変更してから[作成(C)]を左クリック。
今回は「Setup1」のままとします。
f:id:knkomko:20190915032915p:plain:w350

「Setup1」プロジェクトが作成されます。
f:id:knkomko:20190915001520p:plain:w350

3. インストーラー発行元の情報を入力

Setup1プロジェクトを左クリック。
f:id:knkomko:20190915001520p:plain:w350

「Author」「Manufacture」「ProductName」「Title」を入力します。
今回はインストール時にどの項目が表示されるのか識別できるように項目名を入力します。
f:id:knkomko:20190915024040p:plain:w350

4. ProgramFiles にコピーするアプリケーションファイルの指定

Setup1を右クリックして[View] → [ファイルシステム]を左クリック。
f:id:knkomko:20190915001949p:plain:w350

表示されたFile System内の[Application Folder]を右クリックして[Add]→[プロジェクトの出力(P)]を左クリック。
f:id:knkomko:20190915002356p:plain:w350

一覧から[プライマリ出力]を選択し、構成は「Release Any CPU」を選択して[OK]を左クリック。
プライマリ出力にはプロジェクト内の dll や exe が含まれています。
f:id:knkomko:20190915002429p:plain:w350

Application Folder に「プライマリ出力」のファイルが作成されます。
f:id:knkomko:20190915003213p:plain:w350

5. デスクトップに表示するショートカットファイルの指定

[User's Desktop]を選択した状態で右側の白い背景を右クリックします。
表示されたメニューの[新しいショートカットの作成]を左クリック。
f:id:knkomko:20190915003906p:plain:w350

Lock in に「Application Folder」を選択して表示された[プライマリ出力]を選択して[OK]を左クリック。
f:id:knkomko:20190915004554p:plain:w350

User's Desktop に[プライマリ出力]が作成されます。
f:id:knkomko:20190915004822p:plain:w350

User's Desktop の[プライマリ出力]を右クリックして表示されたメニューから[プロパティ ウィンドウ]を左クリック。
f:id:knkomko:20190915010327p:plain:w350

Name にショートカットアイコンの名称を入力します。
f:id:knkomko:20190915005614p:plain:w350

User's Desktop の[プライマリ出力]だったショートカットの名前が変更されます。
f:id:knkomko:20190915010921p:plain:w350

ショートカットの名前に青い波線が引かれている事に気づくと思います。
User's Desktop の Always Create が False (初期値)のままだと最後のインストーラ作成時に以下の様なエラーになるため True に変更します。

すべてのリビルド開始: プロジェクト:InstallerSample, 構成: Release Any CPU ------
1>  InstallerSample -> C:\Users\user\source\repos\InstallerSample\InstallerSample\bin\Release\InstallerSample.exe
------ Starting pre-build validation for project 'Setup1' ------ 
------ Starting pre-build validation for project 'Setup1' ------ 
ERROR: The target of shortcut 'InstallerSample' is invalid.  The 'AlwaysCreate' property of folder 'User's Desktop' must be set to 'True'
ERROR: The target of shortcut 'InstallerSample' is invalid.  The 'AlwaysCreate' property of folder 'User's Desktop' must be set to 'True'
------ Pre-build validation for project 'Setup1' completed ------
------ Pre-build validation for project 'Setup1' completed ------
2>------ すべてのリビルド開始: プロジェクト:Setup1, 構成: Release ------
2>------ すべてのリビルド開始: プロジェクト:Setup1, 構成: Release ------
========== すべてリビルド: 1 正常終了、1 失敗、0 スキップ ==========

User's Desktop を右クリックして[プロパティ ウィンドウ]を左クリック。
f:id:knkomko:20190915011248p:plain:w350

AlwaysCreate を True に変更します。
f:id:knkomko:20190915011322p:plain:w350

6. デスクトップのショートカットにアイコンを指定

ショートカットに使用するアイコンファイルをプロジェクトに取り込みます。
プロジェクト名を右クリックして[プロパティ]を左クリック。
f:id:knkomko:20190915004301p:plain:w350

[リソース]の[▼]から[既存ファイルの追加(E)]を左クリック。
f:id:knkomko:20190915012007p:plain:w350

ショートカットに表示したいアイコンを取り込みます。
今回は cat.ico というファイルを使用します。
取り込まれたファイルはResourcesフォルダに保存されます。
f:id:knkomko:20190915012305p:plain:w350

取り込んだアイコンファイルをショートカットに指定します。
User's Desktop のショートカットを選択した状態でInstallSampleを右クリック。
表示されたメニューの[プロパティ ウィンドウ(W)]を左クリック。
f:id:knkomko:20190915012541p:plain:w350

Icon の[Brows]を左クリック。
f:id:knkomko:20190915013629p:plain:w350

[Brows]を左クリック。
f:id:knkomko:20190915014017p:plain:w350

Lock in は[Application Folder]を選択して[Add File]からプロジェクトのResourcesフォルダにあるアイコンファイルを追加します。
追加するとファイル名が表示されるので選択して[OK]を左クリック。
f:id:knkomko:20190915014118p:plain:w350

追加したアイコンが表示されるので選択して[OK]を左クリック。
f:id:knkomko:20190915014743p:plain:w350

ショートカットに指定したアイコンファイルはSetup1の中に保存されます。
またUser's DesktopのショートカットのIconは[Icon]となります。
f:id:knkomko:20190915014832p:plain:w350

7. スタートメニューに表示するファイルの指定

Redmeなど必要なファイルがあれば表示できるのですが今回はデスクトップと同じショートカットを表示します。

User's Programs Menu を右クリックして[Add] → [Folder]を左クリック。
今回は InstallerSample と名前を付けます。
f:id:knkomko:20190915015708p:plain:w350

作成したフォルダを選択した状態で右側の白背景を右クリック。
表示されたメニューから[新しいショートカットの作成(C)]を左クリック。
f:id:knkomko:20190915020031p:plain:w350

Lock in は[Application Folder]を選択して表示された[プライマリ出力]を選択して[OK]を左クリック。
f:id:knkomko:20190915021002p:plain:w350

User's Programs Menu の Installer Sample に [Shortcut to プライマリ出力]が表示されます。
f:id:knkomko:20190915021208p:plain:w350

Shortcut toプライマリ出力を右クリックして[プロパティウィンドウ]を左クリック。
f:id:knkomko:20190915021656p:plain:w350

Name にショートカットアイコンの名称を入力します。
f:id:knkomko:20190915021856p:plain:w350

User's Program Menu のショートカットアイコンの名前が変更されています。
f:id:knkomko:20190915022208p:plain:w350

8. スタートメニューのショートカットにアイコンを指定

新たにアイコンを追加して使用する場合は 6. デスクトップのショートカットにアイコンを指定 と同じようにResourceにファイルを取り込む必要があります。
今回はデスクトップのショートカットと同じアイコンを使用します。

Shortcut toプライマリ出力を右クリックして[プロパティウィンドウ]を左クリック。
f:id:knkomko:20190915021656p:plain:w350

Icon の[Brows]を左クリック。
f:id:knkomko:20190915013629p:plain:w350

Setup1にアイコンファイルが保存されている場合は Lock in を選択するとファイル名が表示されます。
ファイル名を選択して[OK]を左クリック。
f:id:knkomko:20190915020345p:plain:w350

User's Program Menu のショートカットのIconは[Icon]となります。
f:id:knkomko:20190915023033p:plain:w350

9. インストーラの作成

Setup1を右クリックして[リビルド]を左クリックします。
f:id:knkomko:20190915024408p:plain:w350

出力が「すべてリビルド: 2正常終了、0失敗、0スキップ」となれば完了です。
[f:id:knkomko:20190915033214p:plain;w350]

プロジェクトフォルダ内のSetup1に「Setup.exe」「Setup1.msi」が作成されます。
f:id:knkomko:20190915024707p:plain:w350

10. インストーラの実行

発行元の情報の入力がどのように表示されているのか表示の確認を行います。
f:id:knkomko:20190915025758p:plain:w350

f:id:knkomko:20190915025943p:plain:w350

f:id:knkomko:20190915030040p:plain:w350

インストールの完了です。
f:id:knkomko:20190915030057p:plain:w350

コントロールパネルのアプリケーション名は ProductName となっていました。
f:id:knkomko:20190915030142p:plain:w350

スタートメニューにショートカットアイコンが作成されています。
f:id:knkomko:20190915030126p:plain:w250

デスクトップにも同様にショートカットアイコンが作成されています。
f:id:knkomko:20190915030213p:plain:w350

まとめ

操作性はInstallSheildに劣りますが無料で使える事を考えると十分な内容です。
オープンソースのツールも幾つかありますが VisualStudio Installer はMicrosoftがサポートしているため安心して使用できます。
今回はインストーラの基本的な使い方を確認しました。
次回は多言語、NuGetパッケージを利用した場合の使い方を確認したいと考えています。

.Net Core MVC を使った初めてのWebアプリ開発 #2

f:id:knkomko:20190912123325p:plain:w500

はじめに

#1 ではWebアプリの仕組みとMVCの設計についてまとめました。
knkomko.hatenablog.com

#2からWebアプリの開発についてソースコードを用いて説明します。
ソースコードASP.NET Core MVC の概要 | Microsoft Docsを参考にしています。

目次

1.Webアプリの作成
2.コントローラの追加
3.ルーティング
4.パラメータの指定

1. Webアプリの作成

[新しいプロジェクトの作成]を左クリックします。
f:id:knkomko:20190911214147p:plain:w350

プロジェクト名に「MvcMovie」と入力して[作成(C)]を左クリックします。
f:id:knkomko:20190911213945p:plain:w350

[Webアプリケーション (モデル ビュー コントローラー)]を左クリックします。
f:id:knkomko:20190911214411p:plain:w350

MVCの設計を使用したサンプルプログラムが自動で作成されます。
MVCに対応するControllers、Models、Viewsのフォルダがあります。
それぞれのフォルダにプログラムを作成していきます。
f:id:knkomko:20190911215253p:plain:w350

●wwwroot
ブラウザ上で処理を行うjQueryやデザインで使用するBootstrapなどのライブラリ(機能を提供するプログラム群)が保存されています。
使いたいライブラリがあればこちらに保存して参照する事で使用が可能です。

●依存関係
Webサーバー上で処理を行う.Net Coreで利用するライブラリが保存されています。
Nuget(にゅーげっと)と呼ばれるパッケージマネージャからライブラリをインストールすると依存関係に保存されます。

●Controllers
MVCのコントローラーのプログラムを保存します。

●Models
MVCのモデルのプログラムを保存します。

●Views
MVCのビューのプログラムを保存します。

●appsettings.json
プログラムから読み出す設定値を保存するファイルが保存されています。
json形式のテキストファイルなので後で値を変更する場合に使用します。

●Program.cs
一番はじめに実行されるプログラムが記述されています。

●Startup.cs
Program.csのMain()によって呼び出されWebアプリケーションの設定を行うプログラムが記述されています。
ログイン機能の開発でクッキー認証を利用する場合など、必要に応じて使用します。

2. コントローラの追加

Controllersフォルダを右クリックして表示されたメニューから[コントローラー]を左クリックします。
f:id:knkomko:20190911230216p:plain:w350

[MVC コントローラー - 空]を選択して[追加]を左クリックします。
f:id:knkomko:20190911230838p:plain:w350

コントローラー名を「HelloWorldController」として[追加]を左クリックします。
コントローラーを作る際には名前の末尾に「Controller」の記載が必要です。
f:id:knkomko:20190911231020p:plain:w350

作成した「HelloWorldController」を開きます。
f:id:knkomko:20190911231729p:plain:w350

HelloWorldControllerにWelcomeアクションメソッドを追加します。

using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;

namespace MvcMovie.Controllers
{
    public class HelloWorldController : Controller
    {
        // 
        // GET: /HelloWorld/
        public string Index()
        {
            return "This is my default action...";
        }

        // 
        // GET: /HelloWorld/Welcome/ 
        public string Welcome()
        {
            return "This is the Welcome action method...";
        }
    }
}

URLからコントローラを呼び出してWebページを表示してみます。
後ほど説明をしますがURLとコントローラの対応は以下のようになっています。
https://localhost:[ポート番号]/[コントローラ]/[アクションメソッド]

Webアプリケーションを実行した状態で以下のどちらかのURLにアクセスするとHelloWorldControllerのIndex()が呼び出されます。
https://localhost:44370/HelloWorld/
https://localhost:44370/HelloWorld/Index
数字部分のポート番号は実行環境で変わるので実行時の番号に合わせてください。
f:id:knkomko:20190911233805p:plain:w450

以下のURLにアクセスするとHelloWorldControllerのWelcome()が呼び出されます。
https://localhost:44370/HelloWorld/welcome
f:id:knkomko:20190911234214p:plain:w450

https://localhost:44370/HelloWorld/にアクセスした時は図のような動作です。
現在はコントローラーのみが動作しています。
f:id:knkomko:20190911234944p:plain:w450

3. ルーティング

URLとコントローラを結びつけることをルーティングと呼びます。
ルーティングはStartup.csファイルのConfigureメソッドで行われています。
f:id:knkomko:20190911234504p:plain:w450

https://localhost:44370/HelloWorld/のようにIndexを省略してもhttps://localhost:44370/HelloWorld/Indexと同じ動作となるのは、Indexというアクションメソッドを省略した場合はIndexを規定値として呼び出すようにルーティングの設定が行われているためです。

ルーティングは以下のように設定されています。
赤はコントローラー、青はアクションメソッドの設定になります。
f:id:knkomko:20190912002209p:plain:w450

ルーティングのイコールで指定している部分が省略した時の規定値になります。
https://localhost:44370/ではHomeController(コントローラの規定値)のIndex(アクションメソッドの規定値)が呼び出されます。
f:id:knkomko:20190912004202p:plain:w450

4. パラメータの指定

アクションメソッドに引数をもたせる事でパラメータを受け取ることができます。
HelloWorldController のWlcomeに name と numTimes の引数を追加します。
welcomeのアクションメソッドでは引数で与えられた name と numtimes を表示します。

        // GET: /HelloWorld/Welcome/ 
        // Requires using System.Text.Encodings.Web;
        public string Welcome(string name, int numTimes = 1)
        {
            return HtmlEncoder.Default.Encode($"Hello {name}, NumTimes is: {numTimes}");
        }

using System.Text.Encodings.Web; を追記して HtmlEncoder を使用します。
HtmlEncoderではパラメータにJavaScriptを入力された場合に無意味な文字列に変換(エスケープ)します。
URLからJavaScriptを実行することをXXS(クロスサイトスクリプティング)と言って悪意のある攻撃として使われるため、フレームワーク上にエスケープする機能が用意されています。

赤下線が追加する記述になります。
f:id:knkomko:20190914023207p:plain:w450

以下の様にnameとnumtimesの引数に値を入力することでパラメータを渡します。
https://localhost:44370/HelloWorld/welcome?name=makoto&numtimes=4

上記URLにアクセスした結果は画像のようになります。
f:id:knkomko:20190914022640p:plain:w450

まとめ

#2ではWebアプリの作成、コントローラーの追加、ルーティング、パラメータの指定についてまとめました。
#3ではコントローラーからビューを呼び出します。

.Net Core MVC を使った初めてのWebアプリ開発 #1

はじめに

私はRailsからWebアプリの基礎を学び、現在は.Net Coreで開発をしています。

Webアプリを学ぶ機会を得たのは社外の勉強会に参加した事がきっかけでした。
liberal-arts-beginners.connpass.com

Webアプリ開発が未経験で.Net Core MVC を使ってもよく分からなかったので、
未経験の人でも分かり易いようにWebアプリ開発について解説します。

1つの記事では開発まで収まらなかったため#1では仕組みについてまとめます。
#2からソースコードを用いて開発について解説をしていきます。

Webアプリケーションの仕組み

f:id:knkomko:20190907002020p:plain:w550

Webアプリケーションはクライアント(要求する側)とWebサーバ(要求に応える側)によって構成されています。

● ブラウザ
Webサーバにリクエストを送り、処理結果となるHTMLを表示します。
例:Microsoft Edge, GoogleChrome, FireFox など

● Webサーバソフトウェア
HTML, CSS, 画像をネットワーク上に公開する事ができます。
例:IIS, Nginx, Apach など

● Webアプリケーションサーバ
アプリケーションの実行環境です。開発言語によって変わります。
例:Kestrel (.Net Core), Tomcat (Java), Unicorn (Ruby) など
  ※括弧内には開発言語を表記しています。

● Webアプリケーション
Webアプリケーションには"静的なWebページ"と"動的なWebページ"があります。
静的なWebページでは、URLに登録されている内容をそのまま返します。
動的なWebページでは、ブラウザの入力内容を処理した結果を返します。
例: .Net Core, Java, Ruby など

● データベース
SQL言語でアクセス可能なデータをハードディスクに保存します。
例:SQL Server, Oracle, MySQL など

Model-View-Controller (MVC)

f:id:knkomko:20190907030801p:plain:w350

.Net Core MVC ではMVCの設計に基づいて開発を行います。
MVCを使用すると データを扱う処理 データを表示する処理 を分離できます。
処理を分離して独立性を高めることで修正による他への影響を最小限に抑え、ソフトウェアの品質や生産性を向上させています。
Java, PHP, Ruby, Python などでフレームワークを使った開発でもMVCの設計は利用されています。

● Model
Webアプリケーションのデータを保存します。

● View
WebアプリケーションのUI(ユーザーインターフェース)になります。

● Controller
モデルからデータの取得や、モデルのデータをビューに提供して表示します。
コントローラーではユーザーがブラウザに入力した内容や操作を処理します。

まとめ

Webアプリケーションの仕組みとMVCの設計について説明しました。
#2 ではMVCの設計に基づいてWebアプリケーションの開発について説明していきます。
ASP.NET Core MVC の概要 | Microsoft Docsを参考に説明を行います。

参考資料

インフラエンジニアの教科書2 スキルアップに効く技術と知識

インフラエンジニアの教科書2 スキルアップに効く技術と知識

改訂3版 これからはじめるプログラミング 基礎の基礎

改訂3版 これからはじめるプログラミング 基礎の基礎

オブジェクト指向でなぜつくるのか 第2版

オブジェクト指向でなぜつくるのか 第2版

docs.microsoft.com