Couple of days ago when I came back home I found out that I forgot to take the main door keys. And it took more than 2 hours before my wife was back home and I could go in. while waiting for her to come I was wishing if I could open my garage door via phone :) . So I decided to setup some basic stuff so that I can open my garage door remotely

I have a Merlin 230T garage door opener, almost all the garage doors have manual open option. Did a simple test with a wire by connecting the manual endpoints. All I needed in hardware was a raspberry pi, a relay and some wire connectors.

Software solution is really simple, Raspberry has a node.js app running which listens to a topic hosted on AWS IoT. There is an API endpoint in AWS which triggers a lambda function which publishes to the same AWS IoT topic. Once a message is received in AWS IoT it notifies the node.js app and that app then triggers the garage opening circuit to toggle the garage state

AWS IoT Diagram

Raspberry PI circuit, just a relay connected to GPIO

Raspberry PI Garage Opener

Here is how the final solution looks like, I will post the code to my github account

Raspberry PI Merlin Garage Opener

Yay now I can open my garage door remotely from anywhere

My son who is type-1 diabetic is turning 5 next week. He is really excited to join school. We are excited too but at the same time worried about his diabetes management. We are already using Abott FreeStyle Libre, it is not generally available in New Zealand, getting it through YouShop UK. I had heard about some awesome open source work being done in this space specially OpenAPS and NightScout. Its time to set this up for my son. The process was quite easy but might be little bit tricky for non-technical people. Here I am listing the steps for a non-technical person.

  1. Signup for an account at Github if you dont have already one Signing up is easy, go to Github and enter some of your details and choose the free plan

  2. Signup for an account at Heroku. You can select Node.js as primary development language

  3. If you want notifications
    • Signup for an account at Pushover.
    • Once logged in go to home page and note your user key, we will use that later on.

      Pushover User Key

    • Click Create New Application link (https://pushover.net/apps/build) and submit the form after entering the new app name. Note the app key.
  4. Go to Nightscout repository and click fork Forking Nightscout

  5. Go to forked repository and click on deploy to Heroku link Deploy to Heroku Link

    • Enter app name, the nightscout url depends on that, URL after deployment will be https://{app-name}.herokuapp.com/
    • Enter API Secret, remember this because that is needed in Glimp
    • In enable tab enter “cors careportal”
    • Enter pushover_api_token (app key) and pushover_user_key (user key)
    • Click the deploy button
    • Go to https://{app-name}.herokuapp.com/
  6. In glimp settings (remote monitoring) , enter the herokuapp url and API secret. Test the connection.

Now when freestyle libre is scanned, you should be able to see in realtime the readings on your nightscout website. More on how to modify different settings in next post :). Setting this up by usually would not take more than 1 hour and everything is free. Thanks Nightscout contributors for making T1s life easy.

Automapper currently provides a static class Mapper to do different operations, Mapper is just another wrapper on IMappingEngine, IConfiguration and IConfigurationProvider. So by dependency injecting these interfaces along with few others the Mapper static class can be avoided. This can be done by any of the IOC container, Jimmy has written a nice post on how to do it in StructureMap, the code below shows how to do it in Autofac

builder.RegisterType<TypeMapFactory>().As<ITypeMapFactory>();
builder.RegisterType<ConfigurationStore>()
       .As<ConfigurationStore>()
       .WithParameter("mappers", MapperRegistry.Mappers)
       .SingleInstance();
 
builder.Register((ctx, t) => ctx.Resolve<ConfigurationStore>())
       .As<IConfiguration>()
       .As<IConfigurationProvider>();
 
builder.RegisterType<MappingEngine>().As<IMappingEngine>();

Note that ConfigurationStore is registered as singleton as there will be only one configuration object in single app domain. MappingEngine can be registered as singleton also but it does not really matter as it is fairly lightweight class.

The configuration can be unit test using following unit test

var container = GetAutofacContainer();
const int expectedValue = 15;

var configuration1 = container.Resolve<IConfiguration>();
var configuration2 = container.Resolve<IConfiguration>();
Assert.AreSame(configuration1,configuration2);

var configurationProvider = container.Resolve<IConfigurationProvider>();
Assert.AreSame(configurationProvider,configuration1);

var configuration = container.Resolve<ConfigurationStore>();
Assert.AreSame(configuration,configuration1);

configuration1.CreateMap<Source, Destination>();

var engine = container.Resolve<IMappingEngine>();

var destination = engine.Map<Source, Destination>(new Source { Value = expectedValue });

Assert.AreEqual(expectedValue,destination.Value);

Thats all we need to remove the dependency on Mapper static class using Autofac

The concept of first class functions and higher order functions is really important to use the modern programming languages effectively and we should take maximum benefit from the functional programming support in c#. Though its not a truly functional programming language but still you can do lot of functional programming in c#.

First-Class Functions: The ability of a programming language in which functions can be assigned to a variable and can be treated just like other variables is called first class functions support. Immediately few questions should come to your mind like Is this something new? Does c++ support first class functions? The answer is that this is not something new and c++ support first class functions as well in the form of function pointers. C# also support first class functions and one way to do is that through delegates.

Higher Order Functions: The functions that take function as an argument or return functions as return value are called higher order functions. So the languages that support first class functions generally support higher order functions. c++ and c# both support higher order functions through various mechanisms which I am going to discuss in detail in future posts .

I was just deploying my first app in an on premises sharepoint installation and deploying failed with following error in the output

Error occurred in deployment step ‘Install app for SharePoint’: Apps are disabled on this site

I got to know that this is something expected as in sharepoint 2013 you have to create isolated app domain for development of apps, which can be created by following powershell script as taken from a technet article.


net start spadminv4
net start sptimerv4
Set-SPAppDomain "your app domain here"
Get-SPServiceInstance | where{$_.GetType().Name -eq "AppManagementServiceInstance" -or $_.GetType().Name -eq "SPSubscriptionSettingsServiceInstance"} | Start-SPServiceInstance
Get-SPServiceInstance | where{$_.GetType().Name -eq "AppManagementServiceInstance" -or $_.GetType().Name -eq "SPSubscriptionSettingsServiceInstance"}
$account = Get-SPManagedAccount "your managed account here" 
$appPoolSubSvc = New-SPServiceApplicationPool -Name SettingsServiceAppPool -Account $account
$appPoolAppSvc = New-SPServiceApplicationPool -Name AppServiceAppPool -Account $account
$appSubSvc = New-SPSubscriptionSettingsServiceApplication –ApplicationPool $appPoolSubSvc –Name SettingsServiceApp –DatabaseName SettingsServiceDB 
$proxySubSvc = New-SPSubscriptionSettingsServiceApplicationProxy –ServiceApplication $appSubSvc
$appAppSvc = New-SPAppManagementServiceApplication -ApplicationPool $appPoolAppSvc -Name AppServiceApp -DatabaseName AppServiceDB
$proxyAppSvc = New-SPAppManagementServiceApplicationProxy -ServiceApplication $appAppSvc
Set-SPAppSiteSubscriptionName -Name "app" -Confirm:$false

Important Note please replace the place holders “your app domain here” and “your managed account here” with appropriate values , app domain can be any arbitarary app domain like apps.myorg.com as sharepoint adds this in hosts file so no dns entry is required this is something to take care of in production. In managed account specify a managed account if you have not created one you can create one in central administration in security options.