Geo-fence Garage Door Using Raspberry Pi, Azure, C#, and Windows Phone
Part Five

In part four, we created Azure Mobile Services, we added a table that keeps track of the garage door status, and our Raspberry Pi program will open/close the garage door when the status of the garage changes.
In part five, we will create a background task and a Windows Phone application that will update the garage door status and give us a feedback via toast notification.
Open your GaragePi.NET project and add new project. Select Windows Runtime Component, name the new project GarageBGTask, and click OK.
Backgrond Task Project

Right click on the new project and click Manage NuGet Packages. Search for WindowsAzure.MobileServices, select it and click Install. Close NuGet manager, after installation.
NuGet Package

Rename the class from class1 to GarageStatusTask and add the below using statements
using Windows.Devices.Geolocation.Geofencing;
using Microsoft.WindowsAzure.MobileServices;
using Windows.ApplicationModel.Background;
using Windows.UI.Notifications;
using Windows.Data.Xml.Dom;
using Windows.Devices.Geolocation;

Inherit from IBackgroundTask and implement interface. Your GarageStatusTask class will now look like the image below.
Background Task Class

In the GaragePi.NET project, locate the GarageDoor Class and drag it to the GarageBGTask project.
Copy Class

Open the GarageDoor class you just copied, mark the class as sealed, change the namespace to GarageBGTask, and safe your changes.
Change Namespace

Go to the GarageStatusTask and add the below Mobile Service information. Remember to use your Mobile Service information. MobileService is private this time.
private static MobileServiceClient MobileService =
new MobileServiceClient("https://xxxxxxx.azure-mobile.net/", "xxxxxxxxxxxxxxxxxxxxxxxx");

Add below code to the Run method, replacing the exception. This code will help us wait for the asynchronous calls we will make. Our code will go between the GetDeferral and Completed method calls.
BackgroundTaskDeferral deferral = taskInstance.GetDeferral();

deferral.Complete();

Deferral Completed

Make the Run method async and add the below code just before the call to deferral.Complete(). Read the comments in the code for more information.
//Get Geofence status changes. 
var reports = GeofenceMonitor.Current.ReadReports();

//Go through all reports
foreach (var report in reports)
{
//Get the garage door from Azure.
var garageDoors = await MobileService.GetTable().Where(l => l.Name == "Home Garage").ToListAsync();

//Take the first item. Remember we only have item in our Garage Door table.
var door = garageDoors.FirstOrDefault();

//Set the StateChanged to true. The Raspberry Pi program will open/close the garage door, when the statchaged value is true.
door.StateChanged = true;

//Update the table so the Raspberry Pi can get the current garage door status.
await MobileService.GetTable().UpdateAsync(door);

//Create Toast Template.
ToastTemplateType toastTemplate = ToastTemplateType.ToastText01;
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);

//Check if the Geofence fired because of enterence or exit
if (report.NewState == GeofenceState.Entered)
{
//Create the Toast Notification text that will be shown when the garage door is opening.
//We don't really know if the garage door is opening or closing.
//In the future, we can add a sensor that will tell us if the garage door is open or closed.
XmlNodeList toatTextElemens = toastXml.GetElementsByTagName("text");
toatTextElemens[0].AppendChild(toastXml.CreateTextNode("Opening " + report.Geofence.Id + ", Welcome!"));
}
else if (report.NewState == GeofenceState.Exited)
{
//Create the Toast Notification text that will be shown when the garage door is closing.
XmlNodeList toatTextElemens = toastXml.GetElementsByTagName("text");
toatTextElemens[0].AppendChild(toastXml.CreateTextNode("Closing " + report.Geofence.Id + ", Bye Bye!"));
}

//Create Toast Notification
ToastNotification toast = new ToastNotification(toastXml);

//Show the Toast Notification
ToastNotificationManager.CreateToastNotifier().Show(toast);
}

Background Task Logic

Add a method that will create a Geofence and add it to the current Geofences.
public async static void AddFence()
{
//Calling GetGeopositionAsync() will ensure that the application has permission to use GeoLocation.
Geolocator loc = new Geolocator();
var current = await loc.GetGeopositionAsync();

//Get the Geofence if it exists
var existingFence = GeofenceMonitor.Current.Geofences.Where(f => f.Id == "Home Garage Door").FirstOrDefault();

//Check if already have this Geofence
if (existingFence != null)
{
//Remove the existing Geofence.
GeofenceMonitor.Current.Geofences.Remove(existingFence);
}

//Here is where my garage door is located. Change this location with your location.
//You can get your current location by calling (var current = await loc.GetGeopositionAsync();)
var center = new BasicGeoposition()
{
Altitude = 0.0,
Latitude = 38.8611580633949,
Longitude = -104.67043238239815
};
//Geofence needs to know the GeoShape of your Geofence. Circle is the only shape available now.
//Build GeoCircle and set the radius to 20 meters.
var circle = new Geocircle(center, 20);

//Create Geofence.
//We are naming our Geofence Home Garage Door.
//Our GeoShape is the Circle we created
//We want to know when the Geofence is entered or exited.
//Our Geofence is not single use Geofence.
//We are setting dwell time to 0. We want the garage door do open/close as soon as we enter/exit the Geofence
Geofence geofence = new Geofence("Home Garage Door", circle,
MonitoredGeofenceStates.Entered | MonitoredGeofenceStates.Exited,
false, TimeSpan.FromMilliseconds(0));

//Add the Geofence to the current Geofences.
GeofenceMonitor.Current.Geofences.Add(geofence);
}

Build the project and make sure it builds successfully. The Background Task is now ready.
Right click on the solution and add new project. Select Blank App (Windows Phone), name the project GarageDoor.WP and click OK.
Create Windows Phone App

Right click, open NuGet Package Manager and install Windows Azure Mobile Services NuGet package. We need this because the BackGround Task is using it.
NuGet Package

Open Package.appmanifest, and from the Application tab, set Toast Capable to Yes.
Toast Capable

Select the Capabilities tab, and select Location.
Location Capable

Select the Declarations tab, from the available declarations select Background Tasks, and click Add.
Declare Background Task

Check the Location checkbox and enter GarageBGTask.GarageStatusTask in the Entry Point textbox. This is the Background Task project name and the Background Task class name.
Location Background Task

Right click the Windows Phone project and add reference to the Background Task project (GarageBGTask).
Reference Background Task Project

Open the MainPage.xaml.cs page and add the below using statements.
using Windows.ApplicationModel.Background;
using GarageBGTask;
using System.Threading.Tasks;

Add the below method to MainPage.xaml.cs. This method will register the Background Task, see the comments in the code.
private void RegisterBackgroundTasks()
{
bool alreadyRegistered = false;
string taskName = "HomeAreaTask";

//Check all existing Background Tasks.
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
//Check if the Background Task already exists.
if (task.Value.Name == taskName)
{
//Set already exiting to true and exit the loop.
alreadyRegistered = true;
break;
}
}

//if the Background Task is new.
if (alreadyRegistered == false)
{
//create Background Task builder.
var builder = new BackgroundTaskBuilder();
//Create Geofence Location Trigger Type.
var trigger = new LocationTrigger(LocationTriggerType.Geofence);

//Set the name of the Background Task.
builder.Name = taskName;

//Set the Background Task Entry Point.
builder.TaskEntryPoint = typeof(GarageStatusTask).FullName;

//Set the Trigger.
builder.SetTrigger(trigger);

//Register the Background Task
var taskRegistration = builder.Register();
}
}

Mark the on Navigated to method as async method and call AddFence(), RequestAccessAsync(), and RegisterBackgroundTasks() as shown below.
GarageStatusTask.AddFence();
await BackgroundExecutionManager.RequestAccessAsync();
RegisterBackgroundTasks();

Call Methods from OnNavigatedTo

Build the solution and make sure it builds successfully.
Power up your Raspberry Pi, and give it a minute to get started. Start PuTTY and login to your Raspberry Pi.
Warning! Your garage door will open or close. Run the GargePi.NET program on the Pi.
sudo mono Debug/GaragePi.NET.exe

Run Program

The program will call Azure and check the garage door status.
Program Checking Azure

Hookup your Windows Phone to your computer, via USB. Go back to Visual Studio, set the Windows Phone project as startup project, select Device and click Run.
Run Windows Phone App

The Windows Phone application will create a Geofence and ask the Background Task to monitor it. The Background Task will get notification when the Geofence status changes. The Background Task will first update the garage door information and then send appropriate Toast Notification (closing Toast Notification or opening Toast Notification).
Toast Notification

The Raspberry Pi will notice the change to the garage door information in Azure and open/close the garage door.
Raspberry Pi Program Open/Close Garage Door

Next time you leave or come home, the Raspberry Pi will close or open the garage door for you.
DO NOT leave the program running, this is because we don’t have a way to know if the garage door is open or closed – yet.
;