Home Automation with Windows Workflow

Sign in to queue


  There are some pretty good Home Automation packages out there on the market. Some of these are made for installers – and are thus closed to easy customization by the end user. Then there are packages that are made for hobbyists. These have good core automation systems, and provide some add-in points for customization. There are very few good “toolkits” for home automation enthusiasts who like to Code4Fun, so I decided to build one.

Difficulty: Intermediate
Time Required: 3-6 hours
Cost: $50-$100
Software: Windows Workflow Foundation
Hardware: Z-Wave devices
Download: Download

     For me, home automation ranks near the top of the list of ultimate computer geek hobbies. You get to channel your inner “Scotty/Geordi” by playing with cool hardware, and you can channel your inner “Spock/Data” by playing with cool software. It doesn’t take much hardware to get started. A simple kit such as the ControlThink Z-Wave PC SDK or one of the myriad others will get you going. And you can add more bits and pieces such as motion detectors, alarm controllers, etc. - as you go.

Enter Workflow

Many people think of Windows Workflow Foundation as being useful only for rule-driven, line of business applications, systems management, or one of several other “enterprise business application” uses. These are all good things, but what about using workflow for something a little more fun? After all, Windows Workflow Foundation has features like a cool graphical designer, an awesome rules engine, a robust persistence model, and an extensible service model just to name a few. Somehow, my thoughts about workflow and my thoughts about home automation converged. I wondered: “Can I use workflow to turn on a light?” Yeah, you know like that switch in the refrigerator that costs a few pennies. I wanted to use workflow for turning the light in my pantry on or off. The pantry door has a hardwired contact switch that connects to my Automation/Alarm system – an Elk M1G. My lights are controlled via several Z-Wave controllers including the USB stick that ships with the ControlThink SDK mentioned above. The problem was to get these two pieces of hardware talking so that I could have a workflow that looks like this:


The idea is that the PantryDoorChange activity and the PantryLightOn/Off shapes would be instances of custom workflow activities. PantryDoorChange would monitor the Elk M1G waiting for the door’s contact switch to open or close. PantryLightOn/Off would send the appropriate Z-Wave command for turning the light on/off.

First Order of Business

Before we can get to the custom activities, we have to think about the services behind them, and how we’re going to communicate with the various devices. Communicating with the Z-Wave devices is made extremely easy with the rockin’ ControlThink Z-Wave SDK, so let’s leave that one aside for a moment.

Elk Products, Inc. publishes a protocol that allows application developers to write code to interact with the Elk-M1G. This protocol is accessible via serial port or TCP/IP. I opted for TCP/IP which requires the optional Elk Ethernet module. In either case, the code is fairly straightforward. You can send the Elk-M1G an ASCII request message and it will either carry out an action, reply asynchronously with a response message, or both. You can also set some “global settings” on the Elk-M1G to instruct it to send unsolicited messages whenever events occur.

I started by creating the Elk class. This is a component that implements a .NET interface into the Elk-M1G protocol. The class is a derived from the Component class which makes it easy to use in a Windows Forms application, but it can also be used in any other .NET application. The current implementation only supports a fraction of the request and response messages available within the Elk-M1G. The message that we care about for the above workflow is the ZC – zone status change. This message will tell us when the zone changes status and that that status is. The various status values are given by:

 1: [Serializable]
 2: public enum ZoneStatus : byte
 3: {
 4: NormalUnconfigured,
 5: NormalOpen,
 6: NormalEOL,
 7: NormalShort,
 8: notused1,
 9: TroubleOpen,
 10: TroubleEOL,
 11: TroubleShort,
 12: notused2,
 13: ViolatedOpen,
 14: ViolatedEOL,
 15: ViolatedShort,
 16: notused3,
 17: BypassedOpen,
 18: BypassedEOL,
 19: BypassedShort
 20: }

The documentation for the Elk-M1G serial port protocol describes these values in detail. For us, the key is to find out whether a zone – e.g., the contact switch on my pantry door, is open or closed. The Elk component will listen on the socket for an incoming zone change message – ASCII string ZC followed by zone information – and raise a .NET event when the zone change is received. The .NET event contains the following event arguments:

 1: [Serializable]
 2: public class ZoneStatusChangeEventArgs : EventArgs
 3: {
 4: public ZoneStatusChangeEventArgs(byte zone, ZoneStatus status)
 5: {
 6: this.zone = zone;
 7: this.status = status;
 8: }
 10: private byte zone;
 12: public byte Zone
 13: {
 14: get { return zone; }
 15: }
 17: private ZoneStatus status;
 19: public ZoneStatus Status
 20: {
 21: get { return status; }
 22: }
 23: }

I’ve implemented only a few of the many functions available on the Elk-M1G. Following the patterns in the code, it should be fairly easy to implement the remaining features thus opening up the possibility for much more advanced applications than why I have here.

Workflow Services

The next step in this process is to create the actual services and the Workflow Activities which they serve. I designed two services for my application. The ElkService will funnel Elk-M1G events into a workflow activity and allow a workflow activity to send command messages to the Elk-M1G. The ZWaveService allows activities to send ZWave commands and monitor devices for status changes. As with the Elk component class, these have the basic features implemented, but can easily be extended to support the full range of features offered by their respective SDKs.

Both the ElkService and the ZWaveService serve events to EventActivity derived classes. In order to make life a tad simpler, I wrote the EventActivity base class. The class definition looks like this:

 1: public abstract class EventActivity: 
 2: Activity, 
 3: IEventActivity, 
 4: IActivityEventListener<QueueEventArgs> {…}

This class is similar to the InputActivity class found in the custom activity framework sample code at http://wf.netfx3.com/. I needed to make a few tweaks because my services support multiple different event activity types, but the concepts are the same.

There are three custom event driven activities in the current ElkWorkflow library. They are ZoneChange, TaskChange, and OutputChange. These activities will listen for zone, task, and output changes and will wake up when their respective events occur. If you look at the properties of these activities in the Workflow designer, you’ll see that you can set a Filter property to limit which zone, task or output to monitor. If the filter value is non-zero, the event will only be triggered when the corresponding zone, task, or output is triggered, otherwise all zone, task, or output changes will trigger the event.

There is also an activity called ActivateTask that will activate one of the “automation” tasks on the Elk-M1G. These are essentially flags that can trigger events that are programmed into the Elk-M1G directly using its scripting capabilities. ActivateTask demonstrates how to write a shape that will allow you to send commands to the Elk-M1G.

The ZWaveWorkflow library implements a basic ZWave service that currently supports basic dimmer switch capabilities. The Dimmer activity can set the dim/on/off level of a Z-Wave light. There are lots of additional capabilities that can be added to the ZWaveService including capturing device level changes, scene activations, and so on. The ControlThink Z-Wave SDK makes adding new capabilities extremely simple.

Not Done Yet

Here’s a laundry list of some of the things that are left to do. I’m sure there are many things that are not on the list!

1. Better design time experience. This includes the mundane things like better graphics for the custom shapes, and more important things like having the designer show a list of device names rather than having to use device I.D. numbers.

2. More features in the services. Both the ElkService and the ZWaveService can be expanded quite a bit. Features like retrieving the state of devices on startup would make state machine workflows easier to program.

3. A real workflow host. Hosting the workflow in a console application is fine for experimentation, but a windows service might be a better choice for a real home automation system.

4. Dynamic update of in-progress workflows. You don’t want to have to shut down your home automation system every time you need to make a change to a workflow. Windows Workflow Foundation makes it easy to do this in several different ways. Probably the most effective way in the home automation scenario is to create a mechanism for the host to suspend the workflow of interest, and allow the user to edit the workflow design and restart it.

I hope that I’ve shown the fun side of Windows Workflow Foundation. I also hope this is a good start on a home automation toolkit for people who like Coding4Fun.

The Discussion

  • User profile image

    You've been kicked (a good thing) - Trackback from DotNetKicks.com

  • User profile image
    Paul Andrew

    Check out this use of Windows Workflow Foundation. https://blogs.msdn.com/coding4fun/archive/2007/10/05/5296972.asp

  • User profile image

    ok, while I appreciate the use of Win Workflow, here my "green"  question.  Doesn't it take more power to run a computer that monitors your lights than you would save if you left them on and didn't have the computer running?

  • User profile image

    My computer is always running for other reasons. It's a media center, it runs my sprinkler system, my security system, and a few other things. It also shuts off the monitor and drives when thery're not in use, so it doesn't draw much power.

  • User profile image
    Connected Systems Chilled Out Blog

    Workflow: Just for a change a fun workflow project

  • User profile image
    Connecting Systems the Microsoft Way

    Home Automation with Windows Workflow Published 05 October 07 10:58 AM | Coding4Fun There are some pretty...

  • User profile image

    >>It's a media center, it runs my sprinkler system, my security system, and a few other things.

    And what if it decides to BSOD you?

  • User profile image

    Typically we think of robots as machines from science fiction or as industrial robots such as those that

  • User profile image
    Russian Coding 4 Fun

    Обычно мы представляем себе роботов как машины из научно-фантастической литературы или промышленные устройства

  • User profile image

    This looks like a very interesting project. Quite a bit of time has passed since the article was written and I was wondering if any additional development has been done particularly with the Elk class. Has anyone expanded the Elk class to allow use of the RS232 port? If not I may attempt to modify the code to allow for RS232 serial communication since I have an Elk M1G but do not have the ethernet option. I did see the robotics article, but thought I might keep things simple and use straight vb.net (or C# if I am not able to convert the code from C# to vb.net). I had been thinking about trying to write some vb.net code to talk to the Elk when I ran across this code that might be a good jump start for my home automation project.

  • User profile image


    Thanks for your response.

    I have not started yet, so I am not sure if I will have a problem or not. I was just curious if others had tried this project and if so, how well did it work out for them.


  • User profile image

    @Brian I'd imagine getting it to work on a serial port is pretty straight forward.  What is your exact problem?

Add Your 2 Cents