Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

Home Automation with some help from jQuery Mobile, MVC and Netduino

Today's Hardware Friday provides us with a number of things to see in action. Mobile app, jQuery, MVC and some Netduino too...And it's just kind of funny.

Using jQuery Mobile with MVC and Netduino for Home Automation

This article is great for anybody learning jQuery Mobile or building mobile applications with MVC3. I built a remote control for my phone to control a squirt gun for my pool, open my garage door, water the garden and control for my gas fireplace using jQuery Mobile with MVC and a Netduino

How often do you lose your remote control? I hate looking for the remote and family members always seem to hide it from me. I decided to turn my smartphone into the universal remote control for the house which is perfect for me because I'm almost always an arm's length away from it. My wife does not feel the same way about her phone so I had to build external controls as well for our home automation. So far my home automation includes remote controlling a squirt gun for my pool, opening my garage door, watering the garden and I just added control for my gas fireplace! Be sure to see my article entitled Home Automation with Netduino and Kinect for more information and code examples.

My first attempts at building mobile apps for my home automation projects involved building native apps for Windows Phone 7 and Android. The apps served their purpose, but other than the backend web services there was no reuse of the code between the apps written for the different mobile operating systems. The problem was compounded because each family member had their own favorite mobile device with different mobile operating systems. jQuery Mobile and HTML5 solved the problem of making the remote work across a wide variety of devices. Now I have one codebase that works on iOS, Android, Windows Phone, and most of the relevant mobile devices.

Talking to the Hardware

With my jQuery Mobile app, most of the code is running locally on the device. I wrote a MVC controller method that runs on the server to talk to the Netduino called SendMessageToNetduino. The method is called using Ajax from the mobile device.

public ContentResult SendMessageToNetduino(string message, string status)
{
    bool sendToNetduino = bool.Parse(WebConfigurationManager.AppSettings["SendToNetduino"]);
    if (sendToNetduino)
    {
        CommunicateWithNetduino.GetInstance().SendMessage(message);
    }

    return Content(status);
}

The method is a simple pass-through that takes a message sent from Ajax from the mobile device over the internet, and then relays the message behind the firewall over the local network to the Netduino .net microcontroller. The Netduino Plus is a microcontroller that runs C# in the .Net Micro Framework. The Netduino Plus has a built in Ethernet adapter for network communication. For more information and code examples of how to talk with the microcontroller, please read my article entitled Home Automation with Netduino and Kinect.

image

The above image shows the communication between the jQuery Mobile app and the Netduino microcontroller. Note that the same jQuery Mobile app runs on multiple devices with different mobile operating systems.

I wrote a MVC Razor @helper method to encapsulate the logic required to talk to the Netduino.

@helper NetduinoButton(string buttonText, string netduinoMessage, string statusMessage, string dataIcon, AjaxHelper ajax) {
    @ajax.ActionLink(buttonText, "SendMessageToNetduino", "Home",
        new {
            message = netduinoMessage,
            status = statusMessage
        },
        new AjaxOptions {
            UpdateTargetId = "serverMessage",
            InsertionMode = InsertionMode.Replace,
            HttpMethod = "Get"
        },
        new { 
            data_role = "button", 
            rel = "external", 
            data_icon = dataIcon,
            data_theme ="a"
        })
}

With my NetduinoButton @helper method, adding a button to control a device can be done in view by adding a simple line of code. The code below adds a button the open the garage door.

@Content.NetduinoButton("Garage", "C", "Garage Door.", "", Ajax)

...

With jQuery Mobile and HTML5 you can build mobile websites and applications that work on most of the relevant mobile operating systems and devices. The MVC framework works well with jQuery Mobile to keep you from writing duplicate code. The Razor view engine enables better code reuse and also facilitates more readable code. jQuery Mobile allows you to theme your mobile websites/apps to look great like native apps.

Here's the Solution;

image

Here's a snip of code from the project;

public class CommunicateWithNetduino
  {
      private static CommunicateWithNetduino _communicateWithNetduino;
      private Socket _clientSocket = null;
      private Thread _listeningThread;
      private int _port = 80;
      private string _netduinoAddress = null;
      private ISynchronizeInvoke _callingThreadContextToInvoke;

      //Enforce that this class is a singleton that other classes can’t instantiate 
      private CommunicateWithNetduino()
      {
      }
      public int Port
      {
          set { _port = value; }
          get { return _port; }
      }
      public string NetduinoAddress
      {
          set { _netduinoAddress = value; }
          get { return _netduinoAddress; }
      }

      public event EventHandler<MessageEventArgs> EventHandlerMessageReceived;
      public event EventHandler<MessageEventArgs> EventHandlerStatusUpdate;

      //Singleton factory method to load and get the single instance
      public static CommunicateWithNetduino GetInstance()
      {
          if (_communicateWithNetduino == null)
          {
              _communicateWithNetduino = new CommunicateWithNetduino();
              _communicateWithNetduino.Port = 8000;
              _communicateWithNetduino.NetduinoAddress = "192.168.40.100";  //IP Address Must be valid for your network

          }

          return _communicateWithNetduino;
      }

      public void StartListening(ISynchronizeInvoke CallingThreadContextToInvoke)
      {
          _listeningThread = new Thread(new ThreadStart(ReceiveSocketsInBackgroundThread));
          _listeningThread.IsBackground = true;
          _listeningThread.Start();
          _callingThreadContextToInvoke = CallingThreadContextToInvoke;
      }

      public void SendMessage(string message)
      {
          if (_netduinoAddress != null && _port > 0)
          {
              using (System.Net.Sockets.Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
              {
                  IPAddress address = IPAddress.Parse(_netduinoAddress);
                  IPEndPoint endpoint = new IPEndPoint(address, _port);

                  try
                  {
                      socket.Connect(endpoint);
                      socket.Send(Encoding.UTF8.GetBytes(message));
                      socket.Close();
                  }
                  catch (SocketException se)
                  {
                      RaiseEvent(EventHandlerStatusUpdate, "Socket Exception! Probably bad ip or netduino not ready?");
                  }
              }
          }
      }

Tags:

Follow the Discussion

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.