自作IoTデバイスをつくろう--.NET Micro Frameworkと.NET Gadgeterを使いこなす技術者ルポ

builder by ZDNet Japan Ad Special
2014-03-05 11:00:00
  • このエントリーをはてなブックマークに追加

いよいよインターネットにつながろう

 最後に、洗濯が終わったときにメールを送れるようにしよう。まずは、メールを送信するプログラムコードのみを、単体のプロジェクトとして作成しよう。

 ネットワーク関係の機能を使うためには、アセンブリ参照を追加する必要がある。Visual Studioの右ペインに表示されているソリューションエクスプローラーの「参照設定」を右クリックし、「参照の追加」をクリックすると、アセンブリ参照を追加できるダイアログが開くので、「System」を探し、OKをクリックする。

capture

 メールを送るためのプログラムコードは次の通り。

 まず、DHCPからIPアドレスを取得し、次にSMTPサーバーに接続し、メールを送信する。SendMailメソッドの中で定義しているSMTPサーバーの情報と、送り元、送付先のアドレスは、自分の情報に変更しよう。

 適当なSMTPサーバーがない場合は、SendGrid (日本語版はこちら)を使うのがおすすめだ。WebAPIの他、SMTPサーバーも使え、1日に200通までは無料でメールを送付できるプランもある。

 また今回は、限られたメモリを有効に使いたい関係上、直接SMTPサーバーに対して、コマンドを発行するコードを実装しているが、メモリに余裕のあるボードを使う場合、SMTP機能を持つ.NET Micro Framework Toolboxµ PLibraryなどといった.Net Micro Framework用のライブラリを使うのもいいだろう。

Program.cs

using System;

using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

// 参照に「System」を追加する 
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace SmtpSample
{
     public partial class Program 
     {
          // This method is run when  the mainboard is powered up or reset.   
          void ProgramStarted()
          {
          // Use Debug.Print to show  messages in Visual Studio's "Output" window during debugging. 
          DebugInfo("Program Started");

           // ネットワーク初期化 
          InitNetwork();

          // メールの送信 
          SendMail();
          }

     // ネットワーク初期化 
     private void InitNetwork()
     {
     DebugInfo("Initializing  Network");

     Microsoft.SPOT.Net.NetworkInformation.NetworkInterface netif
     =  Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0];

          /* Static IPを使うときはこちらのコードを使う */ 
          /* 
          netif.EnableStaticIP( 
          "192.168.1.100",  // IPアドレス 
          "255.255.255.0",  // サブネットマスク 
          "192.168.1.1"     // デフォルトゲートウェイ 
          ); 
          netif.EnableStaticDns(new[] {  "192.168.1.1" }); // DNS 
          */ 

           /* DHCPからIPを取得 */ 

          // DHCPがオフになっていればオンにする
          if (netif.IsDhcpEnabled == false)
          {
          netif.EnableDhcp();
          } 

           // DHCPからIPを取得(最大30秒待つ) 
          for (int i = 0; i < 30; i++)
          {
               DebugInfo("Waiting DHCP ..  " + (i +  1).ToString());

               netif =  Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0];
               if (netif.IPAddress != "0.0.0.0")
               {
               break;
               }
          Thread.Sleep(1000);
      }
     if (netif.IPAddress == "0.0.0.0")
     {
          // DHCPからIPを取得失敗 
          throw new SystemException();
     } 

     DebugInfo(
          "Network  ready.\n" 
          + "IP Address is " + netif.IPAddress,
          1500
          );
     }

     private void SendMail()
     {
     const string server    = "smtp.sendgrid.net";           // SMTPサーバーのホスト 
     const int    port      = 2525;                          // SMTPサーバーのポート 
     const string username  = "this_account_is_temporary";   // SMTPサーバーのユーザー名を設定する 
     const string password  = "this_password_is_temporary";  // SMTPサーバーのパスワードを設定する 
     const string mail_from = "example@example.com";
     const string mail_to   = "example@example.com";

      try 
     {
     using (Socket socket = SmtpConnect(server,  port))
     {
     SmtpReadLine(socket); 

     SmtpSendCommand(socket, "EHLO Ziddy");
     SmtpSendCommand(socket, "AUTH LOGIN");
     SmtpSendCommand(socket, Convert.ToBase64String(Encoding.UTF8.GetBytes(username)));
     SmtpSendCommand(socket, Convert.ToBase64String(Encoding.UTF8.GetBytes(password)));
     SmtpSendCommand(socket, "MAIL FROM: <" + mail_from + ">");
     SmtpSendCommand(socket, "RCPT TO: <" + mail_to + ">");

     string msg = "From: "+ mail_from + "\r\n" 
          + "To: " + mail_to + "\r\n" 
          + "Subject: Hello from  your washing machine\r\n" 
          + "\r\n" 
          + "Finished the  laundry!\r\n" 
          + ".";

          SmtpSendCommand(socket, "DATA");
          SmtpSendCommand(socket, msg);
          SmtpSendCommand(socket, "QUIT");
     }
}
     catch (Exception ex)
     {
     DebugInfo("err : " + ex.Message);
     }
     finally 
     {
     }
}

 // SMTPサーバーに接続 
private Socket SmtpConnect(string server, int port)
{
     try 
     {
          DebugInfo("Connecting SMTP  server");
          IPHostEntry hostEntry = Dns.GetHostEntry(server);

          Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
          socket.Connect(new IPEndPoint(hostEntry.AddressList[0],  port));

          DebugInfo("Connected SMTP  server");

          return socket;
}
     catch (Exception ex)
     {
          DebugInfo("err : " + ex.Message);
     }
     finally{
     }

     return null;
}

// SMTPサーバーからデータ受信 
private string SmtpReadLine(Socket socket){

     Byte[] buffer = new Byte[1024];

     string result = "";
     while (socket.Poll(30 * 1000000, SelectMode.SelectRead))
     {
     Array.Clear(buffer, 0,  buffer.Length);
     Int32 bytesRead =  socket.Receive(buffer);

     if (bytesRead == 0) break;

      string rec = new string(UTF8Encoding.UTF8.GetChars(buffer));
      result = result + rec;

      if (result.LastIndexOf("\r\n") > 0)
     {
          DebugInfo(result, 1500);
          return result;
     }
     }
     return "";
     }

     // SMTPサーバーにコマンド送信
     private string SmtpSendCommand(Socket socket, string command)
     {
          string request = command + "\r\n";
          DebugInfo(request, 1500);
          Byte[] bytesToSend = Encoding.UTF8.GetBytes(request);
          socket.Send(bytesToSend,  bytesToSend.Length, 0);
          Byte[] buffer = new Byte[1024];

          string result =  SmtpReadLine(socket);
          DebugInfo(result, 1500);

           return result;
          }

           // デバッグメッセージ
          private void DebugInfo(string msg, int sleep = 0)
          {
               Debug.Print(msg);
               display_N18.SimpleGraphics.Clear();
               display_N18.SimpleGraphics.DisplayTextInRectangle(msg, 0, 0, 128, 50,  GT.Color.White, Resources.GetFont(Resources.FontResources.NinaB), GTM.Module.DisplayModule.SimpleGraphicsInterface.TextAlign.Left, GTM.Module.DisplayModule.SimpleGraphicsInterface.WordWrap.Wrap, GTM.Module.DisplayModule.SimpleGraphicsInterface.Trimming.WordEllipsis, GTM.Module.DisplayModule.SimpleGraphicsInterface.ScaleText.None);
               if (sleep > 0)
               {
                    Thread.Sleep(sleep);
               }
          }
     }
}

実行結果

  • コメント(1件)
#1 ZDちゃんファン   2014-07-07 22:05:05
Ziddyちゃんは楕円描画でできてるとは!
このサイトでは、利用状況の把握や広告配信などのために、Cookieなどを使用してアクセスデータを取得・利用しています。 これ以降ページを遷移した場合、Cookieなどの設定や使用に同意したことになります。
Cookieなどの設定や使用の詳細、オプトアウトについては詳細をご覧ください。
[ 閉じる ]