Click here to Skip to main content
15,881,757 members
Articles / Hosted Services / Azure

Electric Appliance Automation - An IoT Project using Windows Azure

Rate me:
Please Sign up or sign in to vote.
3.86/5 (4 votes)
5 Mar 2015CPOL3 min read 27.9K   14   4
Control home appliance from anywhere in the world

This article is an entry in our Microsoft Azure IoT Contest. Articles in this section are not required to be full articles so care should be taken when voting.

AIM

To control home appliances from anywhere in the world

HARDWARE & SOFTWARE REQUIREMENTS

  1. Mini PC- We can use the Arduino board / Rasphberry pi / Minix neo z64 mini PC

    Image 1 Photo by Nick Hubbard / CC BY

    Image 2 Image Credits: Minix.com.hk
  2. Insteon-compatible home automation devices
    1. Insteon 2413U or 2413S module
    2. Insteon 2635-222 On/Off module

    Image 3 Image Credits: tech69.net
     
  3. Speakers
  4. Azure Cloud hosting subscription
  5. Internet connection
  6. Visual Studio 2010

INTRODUCTION

In this article we’ll have look at controlling home appliances remotely over HTTP using a small API toolset we’ll create using ASP.NET MVC. On top of that we’ll push the current device status to the client in real time with SignalR(windows service hosted)

We will Control following home appliances through windows service:

1. FAN - on/off, Speed adjust

2. Lights - on/off

3. Air Conditioner - on/off, Temperature Control

4. Speakers – on/off, Play/Pause/Stop song

THE PLAN

Image 4

We will create a windows service for controlling Insteon devices, then we will build a SignalR web service which will interact with the windows service and finally we will build a mobile application to send commands to the web service so that we can control the devices from anywhere on the web

Part I Building windows service for controlling Insteon devices

Part II Building remote control service for sending commands to windows service from ASP.NET MVC and SignalR

Part III Building mobile web application for interacting with web api service

IMPLEMENTATION

To start up with we will implement just controlling of lights on & off

Part I Building windows service for controlling Insteon devices

1. Create new .NET 4.0 console application project in visual studio & add reference of TopShelf to it using NuGet package manager(With topshelf we can build easily debuggable windows service)

Image 5

Image 6

2. Add reference to the FluenDwelling API dll file, Programmatical interaction with Insteon hardware devices is easy because some great souls on the Internet have managed to create the API structure. I came across a great project called as FluentDwelling:
http://soapboxautomation.com/products/fluentdwelling/

3. We will host the signalR client in the windows service,
In the NuGet package manager console type following command:

Install-Package Microsoft.AspNet.SignalR.Client -Version 1.2.2

4. Add new class called as "InsteonService.cs" to the windows service project

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using Microsoft.AspNet.SignalR.Client;
using SoapBox.FluentDwelling;
using Topshelf;

namespace IoT.WindowsService
{
    public class InsteonService : ServiceControl
    {
        private static string ServiceUri;
        private static Connection connection;

        //Insteon related
        private static Plm plm = new Plm("COM4");

        public bool Start(HostControl hostControl)
        {
            ServiceUri = ConfigurationManager.AppSettings["ServiceUri"];

            connection = new Connection(ServiceUri, "name=Client");
            connection.Received += connection_Received;
            connection.StateChanged += connection_StateChanged;
            Console.WriteLine("Connecting...");
            connection.Start().Wait();
            string inputMsg;
            while (!string.IsNullOrEmpty(inputMsg = Console.ReadLine()))
            {
                connection.Send(inputMsg).Wait();
            }
            connection.Stop();

            return true;
        }

        static void connection_StateChanged(StateChange state)
        {
            if (state.NewState == ConnectionState.Connected)
            {
                Console.WriteLine("Connected.");
            }
        }
        static void connection_Received(string data)
        {
            //Parse the commands
            //Format: 
            //Name,Command,DeviceName(optional),Port(optional)
            string[] command = data.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            if (command.Length > 0)
                if (command[0].Equals("Server", StringComparison.InvariantCultureIgnoreCase))
                {
                    string commandName = command[1].ToLower();
                    if (command.Length > 2)
                    {
                        string deviceid = command[2];
                        switch (commandName)
                        {
                            case "turnoff":
                                {
                                    plm.Network.X10
                                            .House("A")
                                            .Unit(2)
                                            .Command(X10Command.Off);
                                }
                                break;
                            case "turnon":
                                {
                                    plm.Network.X10
                                            .House("A")
                                            .Unit(2)
                                            .Command(X10Command.On);
                                }
                                break;
                        }
                    }
                    else
                    {
                        switch (commandName)
                        {
                            case "getlist"://not tested
                                {
                                    var database = plm.GetAllLinkDatabase();
                                    string devices = "";
                                    if (!plm.Error)
                                    {
                                        foreach (var record in database.Records)
                                        {
                                            devices += record.DeviceId.ToString();
                                        }
                                    }
                                    else
                                    {
                                        devices += "Error";
                                    }

                                    connection.Send(devices).Wait();
                                }
                                break;
                        }
                    }
                }
        }

        public bool Stop(HostControl hostControl)
        {
            if (connection.State == ConnectionState.Connected)
                connection.Stop();
            return true;
        }
    }
}

5. In "Program.cs" write following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Topshelf;
using Topshelf.HostConfigurators;
using Topshelf.ServiceConfigurators;

namespace IoT.WindowsService
{
    class Program
    {
        static void Main(string[] args)
        {
            var host = HostFactory.New(ConfigureHost);
            host.Run();
        }

        private static void ConfigureHost(HostConfigurator x)
        {
            x.Service<insteonservice>(ConfigureService);
            x.SetDisplayName("Insteon Service");
            x.SetDescription("Insteon Controller Service");
            x.SetInstanceName("Insteon");
            x.SetServiceName("Insteon");
            x.StartAutomatically();
            x.RunAsPrompt();
        }

        private static void ConfigureService(ServiceConfigurator<insteonservice> sc)
        {
            sc.ConstructUsing(() => new InsteonService());

            // the start and stop methods for the service
            sc.WhenStarted((s, hostControl) => s.Start(hostControl));
            sc.WhenStopped((s, hostControl) => s.Stop(hostControl));
        }
    }
}

</insteonservice></insteonservice>

6. Finally in the "App.config" file in the "AppSettings" section we need to add following lines of code

<add key="ServiceUri" value="http://insteoniot.azurewebsites.net/echo"/>

 

Part II Building remote control service for sending commands to windows service from ASP.NET MVC and SignalR.

1. We will host the signalR service in asp.net mvc4 web application.

2. Create a new asp.net MVC4 project in visual studio:

Image 7

Image 8

3. Install SignalR server in the project using package manager console

Install-Package Microsoft.AspNet.SignalR -Version 1.2.2

4. Create new folder "SignalR" in the project and add a class called as "MyConnection.cs" to the project

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.SignalR;

namespace IoT.Mobile.SignalR
{
    public class MyConnection : PersistentConnection 
    {
        protected override Task OnConnected(IRequest request, string connectionId)
        {
            return Connection.Broadcast(string.Empty);
        }
        protected override Task OnReceived(IRequest request, string connectionId, string data)
        {
            // Broadcast data to all clients
            string msg = string.Format(
                "{0},{1}", request.QueryString["name"], data);
            return Connection.Broadcast(msg);
        }
    }
}

above class simply broadcasts all the messages recieved to the client.

Part III Building mobile web application for interacting with web api service

1. In previously created MVC4 web application we will create a controller called as "HomeController" and then add a view "Index.cshtml",

Image 9

the view "Index.cshtml" contains radio buttons for turning the lights on and off and the code for calling signalR service.

@{
    ViewBag.Title = "Control Home - IoT Azure";
}
<table class="ui-widget ui-widget-content">
    <tr>
    <td colspan="2" class="ui-widget-header">@ViewBag.Title</td>
    <tr>
        <td style="padding:10px">
            Lights:
        </td>
        <td style="padding:10px">
            <div id="radio">
                <input type="radio" class="radio" id="radio1" name="radio"><label for="radio1">On</label>
                <input type="radio" class="radio" id="radio2" name="radio" checked="checked"><label for="radio2">Off</label>
            </div>
        </td>
    </tr>
</table>
<br/>
<br/>
Debug info:
<ul id="messages"></ul>
@section scripts
{
    <script type="text/javascript">
        function htmlEncode(value) {
            return $("<div/>").text(value).html();
        }

        function addMsg(msg) {
            if (msg != "") {
                $("#messages").append("<li>" + htmlEncode(msg) + "</li>");
            }
        }

        $(function() {
            var connection = $.connection("/echo", "name=Server", true);;

            connection.received(function(data) {
                addMsg(data);
            });
            connection.error(function(err) {
                addMsg("Error: " + err);
            });

            addMsg("Connecting...");
            connection.start(function() {
                addMsg("Connected.");
            });

            //UI
            $("#radio").buttonset();
            $('#radio').change(function () {                
                var $this = $('.radio:checked');

                if ($this.attr("id")=="radio1") {
                    connection.send("turnon,com4");
                } else {
                    connection.send("turnoff,com4");
                }
            });
        });
    </script>

}

 

<add key="ServiceUri" value="http://insteoniot.azurewebsites.net/echo"></add>

HARDWARE/SOFTWARE SETUP

1. Connect the insteon 2413U with Minix neo z64 windows mini PC using USB cable

2. Install windows service on the Minix Neo z64 windows mini pc using command line

IoT.WindowsService.exe install

3. Host the mobile app in cloud using Windows Azure Cloud Hosting,

4. The site is published at: http://insteoniot.azurewebsites.net

REFERENCES

1. FluentDwelling: http://soapboxautomation.com/products/fluentdwelling/

2. SignalR Tutorial: http://www.codeproject.com/Articles/633378/ASP-NET-SignalR-Basis-Step-by-Step-Part

3. Minix Neo Z64: http://www.minix.com.hk/Products/MINIX-NEO-Z64-WIN-PC.html

4. Insteon 2413U: http://www.amazon.com/Insteon-2413U-PowerLinc-Dual-Band-Interface/dp/B002XA8XNQ

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionHow to use our own server rather than Azure Pin
Syed umair shah21-Oct-16 20:56
Syed umair shah21-Oct-16 20:56 
QuestionFeaturing this project on #idevthis Pin
Member 115791666-Apr-15 9:14
Member 115791666-Apr-15 9:14 
AnswerRe: Featuring this project on #idevthis Pin
Nitin S10-Apr-15 2:41
professionalNitin S10-Apr-15 2:41 
AdminThanks for entering! Pin
Kevin Priddle19-Mar-15 9:45
professionalKevin Priddle19-Mar-15 9:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.