FruitHAP – Part 1

In this series of posts I will describe my own C# based Home Automation platform FruitHAP

What is FruitHAP

FruitHAP is my home-made home automation system, designed to run on a Raspberry Pi.
The name stands for Fruit Home Automation Platform and is a pun on the Raspberry Pi (since you all know that a raspberry is fruit). Also ‘Fruithap(je)’ in Dutch is the word for a plate of mashed fruit you give to a baby; something like the picture below.

Logo

Why did you make your own system, since there are already lot of other HA solutions

I have a house with an attic and since this my ‘man-cave’ i sit/work there a lot. The only problem is that I often can’t hear the doorbell ring, especially if the washing machine is also turned on (it’s on the attic as well and it’s noisy).

So I came up with an idea to make something that delivers a notification to my cellphone when someone rings the frontdoor bell.
Oh, and maybe it’s also convenient to put an image of the person standing there in the notification, so I can decide if it’s worthwhile to go downstairs and answer the door.

Then I bought a Raspberry PI, a wireless doorbell, a camera and some other stuff. Now I needed some software to make this setup work. I looked first at some existing HA platforms but decided that they didn’t put up to my expectations, so i decided to build my own. (it is a lot more fun too 🙂 )

Requirements

I came up with some requirements for my platform:

  • Extensible
    I heard that automating your house is addicting. It shoulde be easy to add different sensors and sensor types, since there are a lot of standards of sensors out there.
  • Accessibilty of sensor data
    It should be easy to access sensor data from other systems/apps. Maybe you want more than only notifications on your phone, maybe you want to have a dashboard with all your sensor data or log
    your energy consumption to a database to perform some analysis on it (BIG data is hot these days)
  • Should run on a Raspberry Pi
  • Open source

General overview of the platform

A high level overview of the platform is in the diagram below. I will explain it a bit in more detail.

fruithap_overview

Engine

The main part of the system is called the Engine. This is a daemon that runs on the Raspberry Pi and acts as the gateway between the actual physical sensors and the ‘outside’ world.
The engine communicates with the outside world by means of a message queue, so external applications can easily interact with the system by reading/writing into this queue, through a publish/subscribe mechanism or
request/response mechanism. (RPC calls)

For example, when the doorbell rings, the event goes from the doorbell through the engine and finally got published in the message queue. An app running on a phone can listen (subscribe) to this event on the queue and send a
notification when this event is fired.

An example of request/response is when an external application wants to read the temperature of a certain sensor. It sends a request to the message queue which the engine handles by retrieving the value from the sensor concerned
and sends it back (through the queue) to the external application.

The idea is that all the configuration of the engine and the other components will also be exposed in this way to make it easier to make a nice web interface for configuring everything, but that’s another story for another time.

Controllers

The ‘lowest’ layer is the controller layer. This layer handles all nitty-gritty low level hardware protocol stuff.
It communicates directly with the sensor hardware or through another hardware controller, such as a zWave or a 433 mhz controller.

Sensors

The sensor layer is the most important layer and is considered the core of the platform. These contain virtual representations of the physical sensors/actuators and use the controllers to communicate with the actual sensors
so that all hardware/protocol specifics are abstracted away (only the configuration for a sensor exposes some of the specifics).

For example one of the actuators supported is a KaKu button. KaKu stands for KlikAanKlikUit and consists a whole range of actuators/sensors/device with a specific communication protocol. Each device has an unique device ID and some more specific settings.
These have to be set only in the sensor configuration with an unique name and for the rest of the system and the outside world it is known as a button with that particular name, which can be ‘pressed’.

Sounds difficult? No worries, in the next post when I will describe my setup it will all come together.

Also it’s possible to have ‘aggregate’ sensors, a sensor that combines the input 2 or more separate physical sensors in a way and use this as one value. This is comparable with some of the Android ‘logical sensors’.
An example is a ButtonCamera, it combines a Button and a Camera, so when the button is pressed an image from the camera is retrieved and is sent along with the button pressed event as if it was one physical sensor.

Actions

An action is actually the interface between the sensor(s) and the message queue. Its input(s) is/are coming from either the sensors or from the outside (messages from the queue) and its
outputs are requests for sensors or other parts of the system (configuration!) or messages that are bound for the queue. Basically is this a rule engine where you can implement all kinds of scenarios for your home automation needs.
A standard action is for example to send a message to a queue every time a sensor updates. These actions can also have specific configuration.

Phew.. that was a lot of reading

This is just a short description of the system. If you have any remarks or comments about this post please let me know.
Next time I will show you an example of how this thing works. The example is actually my live doorbell setup.
When the doorbell rings FruitHAP is picking this up and a notification with a image from a camera is sent through Pushbullet to my phone.
More details about this in the next post..

See you next time!

Since FruitHap is open source, here is a link to the source.
If you can’t wait to try this thing (and you have the right equipment) you can also find here a quick setup with a complete Raspberry Pi image.

A hardware monitor in C# 4.0 with the Task Parallel Library – Part 2 – Exception handling

Welcome back at part 2 in this series. In the last part I described the basic framework for the hardware monitor. In this part I will add some exception handling to the monitor and also a way to provide the monitor with extra configuration parameters.

The code can be found here, in the “Part 2” folder.

Exception handling

We would like to stop the main task when an exception is thrown and log the information.
Remember the continuation task we defined earlier to handle the main task cancellation. We can extend this that it also handles exceptions.

 this.readerTask.ContinueWith(t =>
 {
     if (t.IsFaulted)
     {
        t.Exception.Handle((x) =>
        {
           Console.WriteLine("Exception in task: {0}", x);
           return true;
        });

        try
        {
           CleanUp();
        }
        catch (Exception ex)
        {
           Console.WriteLine("Cleanup exception: {0}", ex.Message);
        }
    }
   //Notify everyone that we stopped
   OnStatusChanged(MonitorStatus.STOPPED);
   Console.WriteLine("Reader task stopped");
},TaskContinuationOptions.NotOnRanToCompletion);

When an exception in a Task is thrown, the status of the task is set to IsFaulted. So our continuation task should also be executed if the main task is in the faulted state. We accomplish this by changing the TaskContinuationOptions to TaskContinuationOptions.NotOnRanToCompletion, so that it executes when the main task is cancelled or is in the faulted state.

All exceptions thrown in a Task are collected by the TPL and put in one exception of type AggregateException (see here).
The Exception property of a Task contains this AggregateException. It exposes also a Handle method which has a delegate as parameter.
This delegate is executed for every exception in the AggregateException. In this delegate you can put your exception handling code, for example write it to log file or in the snippet above, write it to the console. (the X is the parameter to the delegate and is the current exception being processed) It should return True to indicate that this particular exception is handled, if it returns false the exception is further thrown down the stack.

After handling the exceptions, the CleanUp() method is called to ensure the monitor can be started again in a correct way.

Configuration parameters

It is not unthinkable that you want to pass some configuration parameters to your monitor, like baudrates, communication ports etc.
To add this functionality we have to change the interface a little bit:

public interface IDeviceMonitor<TConfigData, TDeviceData> : IDisposable
{
  void Start(TConfigData configData);
  ...
}

An extra type parameter (TConfigData) is added which represents a class (or even just an int or double or whatever)  that defines the configuration data you want to use.
When calling the Start method you pass an instance of this class.

Our base class also changes a bit, because, obviously, you want to work with the configuration data in your derived class:

public abstract class DeviceMonitorBase<TConfigData, TDeviceData> : IDeviceMonitor<TConfigData, TDeviceData>
{
  ..
  protected TConfigData configData;    
  public void Start(TConfigData configData)    
  {    
      this.configData = configData;
 ..

Example

I improved the example implementation a bit. I added a second timer monitor (TimerMonitorWithException) which throws an exception when the number of seconds is equal to an user specified number. You can pass this number as an argument to the Start() method. It therefore demonstrates the exception handling AND the use of configuration parameters.

I also extended the original timer monitor so that it uses a configuration parameter. Here you can adjust the interval of  printing the current time to the console.

This was part 2 of this series.  I hope you enjoyed reading this as much as you enjoyed the first part.

Happy coding and until next time!

A hardware monitor in C# 4.0 with the Task Parallel Library – Part 1 – The basics

Sometimes you need to continuously and in the background retrieve and process data from an external device connected to your system (for example a GPS receiver or you want to monitor your ethernet connection). The external device has maybe a low level driver/interface which only has the possibility to retrieve its data synchronously. I designed a small framework in C# 4.0 that makes a nice threaded abstraction layer around this. The multithreaded part is implemented with the help of the Task Parallel Library.
In this and following posts I will try to describe it step by step. The complete code can be found here and all code snippets below refer to the Part 1 project in the solution

[Disclaimer] I don’t pretend that this is the ONLY and/or MOST EFFICIENT way to implement this. It just works for me. If you have any remarks or suggestions for improvement or bugs, please leave them in the comments below [/Disclaimer]

Ok, after this introduction, LET’S GET STARTED!

Interface

First we start by defining an interface. Obviously we want to start and stop the retrieval/monitoring and since the monitor will be run on a background thread we define an event that is going to be fired when new data arrives.

public interface IDeviceMonitor<TDeviceData> : IDisposable
{
    void Start();
    void Stop();
    event EventHandler<MonitorStatusEventArgs> MonitorStatusChanged
    event EventHandler<DataReceivedEventArgs<TDeviceData>> DataReceived;
}

The generic parameter TDeviceData defines a class in which you can put the data your hardware/device makes available. An instance of this
class is passed along with the event. Since hardware communication may involve access to unmanaged resources we make it IDisposable as well.
We also define an event that is fired when the state of the monitor changes (e.g. from started to stopped or vice versa).

Base class

Then we define a base class in which we put all the TPL stuff and other plumbing code so that they are hidden away nicely from the actual implementations. (those implementations contain probably a lot of low level hardware interaction, and we don’t want to get all this plumbing code in the way.)

public abstract class DeviceMonitorBase<TDeviceData> : IDeviceMonitor<TDeviceData>

Here we define a couple of life cycle methods which can (or must) be overridden in a derived class.

protected virtual void Initialize() { }
protected abstract TDeviceData ReadData();
protected virtual void CleanUp() { }
public virtual void Dispose() { }

Initialize() is called after the monitor is started before entering it’s main event loop. You can put optional initialization code in here, like opening ports, setting baudrates and other stuff.

ReadData()  is called in the main event loop and is the method in which it all happens, reading the data from a device, and must be (obviously) overridden in a derived class.

CleanUp() is called after the monitor receives the request to stop. Here you can put clean up code like closing ports etc. N.B. It’s not recommended to put here ‘expensive’ operations like freeing memory or freeing device handles, put this code in the Dispose() method.  The purpose of this method is to put the monitor in a sort of ‘sleeping’ state so that it can be started again quickly.
The same principle counts for the Initialize method, don’t put there any memory allocation or other ‘heavy’ operation, since this will be executed every time when the monitor is started. You can put those heavy operations in the constructor of your derived class.

TPL stuff

The whole process is executed in a  Task (see this msdn link for more information) with a continuation task which handles the case when the main task is canceled after a call to the Stop() method.

The main task (readerTask) is created in the Start() method and its operations are defined in a lambda expression. The comments explain what is happening.

void Start()
{
    this.ctSource = new CancellationTokenSource();
    CancellationToken ct = ctSource.Token;

    this.readerTask = new Task(() =>
    {
         //Are we cancelled yet?
         ct.ThrowIfCancellationRequested();

         //Notify everyone that we started
         OnStatusChanged(MonitorStatus.STARTED);

         //Do initialization work
         Initialize();

         //This is our main loop and reads data until this task is cancelled
         while (true)
         {
             if (ct.IsCancellationRequested)
             {
                 //Cancel it
                 CleanUp();
                 ct.ThrowIfCancellationRequested();
             }

             //Read the data from the device
             TDeviceData data = ReadData();

             //Fire event
             OnDataReceived(data);
         }

    }, ct);
...
}

One further remark: In case you don’t already know, but cancellation of a task is accomplished with CancellationTokens that are created from a CancellationTokenSource. In the Stop() method actual cancellation is done by calling the Cancel() method on the CancellationTokenSource from which the CancellationToken is created. In the task an exception will be thrown which actually cancels and stops the task. See here for more info about task cancellation.

The continuation task executes only when its predecessor (our readerTask) has been cancelled. In this case a message is printed to the console, but you can write this message to a log file or event log or whatever. It also notifies all the subscribers that the monitor has stopped

 this.readerTask.ContinueWith(t =>
 {
   Console.WriteLine("Read task stopped");
   OnStatusChanged(MonitorStatus.STOPPED);
 }, TaskContinuationOptions.OnlyOnCanceled);

Example implementation

I made a sample implementation to put the theory from above in practice. You can find it in the TimerMonitor class. It’s just an amazingly unwieldy way to display the current time, but hey I just want to show a simple example.
I created also a sample console application which runs the TimerMonitor.

Well, I hope you have learned from this post and found it useful. Stay tuned for Part 2 of this series in which I add exception handling.
You can have a sneak preview when you look at the Part 2 project in the solution

Happy coding!