.net core, Cake, IOT, nuget, Raspberry Pi 3

Deploying a .NET Core 2 app to a Raspberry Pi with Cake and PuTTY saved sessions

I’ve written previously about creating a .NET Core 2 template for a simple IoT application which can be deployed to the Raspberry Pi. Recently I was asked if this could be extended to use PuTTY saved sessions, which I thought was an interesting challenge.

I’ve used Cake to help me deploy my .NET Core 2 code – you can see the build.cake file up on GitHub for my template – and this script uses an add-in called Cake.PuTTY to allow me to deploy cross platform .NET Code from my Windows development machine to the Linux based Raspbian Jessie system running on my Raspberry Pi.

I’ve always just supplied my Raspberry Pi’s IP address and username through configurable parameters in the build.cake script, as shown below.

///////////////////////////////////////////////////////////////////////
// ARGUMENTS (WITH DEFAULT PARAMETERS FOR LINUX (Ubuntu 16.04, Raspbian Jessie, etc)
///////////////////////////////////////////////////////////////////////
var runtime = Argument("runtime""linux-arm");
var destinationIp = Argument("destinationPi""192.168.1.73");
var destinationDirectory = Argument("destinationDirectory"@"/home/pi/DotNetConsoleApps/RaspbianTest");
var username = Argument("username""pi");
var executableName = Argument("executableName""HelloRaspbian");

And these are used in the Cake build script in the “Deploy” target – I’ve pasted a snippet of code below which does a few things I’ve listed below the code:

var destination = destinationIp + ":" + destinationDirectory;
var fileArray = files.Select(m => m.ToString()).ToArray();
Pscp(fileArray, destination, new PscpSettings
                                    { 
                                        SshVersion = SshVersion.V2, 
                                        User = username 
                                    }
);
 
var plinkCommand = "chmod u+x,o+x " + destinationDirectory + "/" + executableName;
Plink(username + "@" + destination, plinkCommand);
  • First, it uses the PSCP function (which securely copies files) and supplies the destination in the format of an IP address, then a colon, then the directory that I want to copy files to on the remote machine – as shown below:
"192.168.1.73:/home/pi/DotNetConsoleApps/RaspbianTest"
  • The snippet also supplies the username “pi” to the PSCP function – I supplied this username in the configurable parameter section described earlier.
  • Finally it uses the Plink function to run a custom linux command on remote files – in this case, I change the permissions of the file I need to run to make it executable. Again, here I need to specify a username, and IP address and a location in the format below:
"pi@192.168.1.73:/home/pi/DotNetConsoleApps/RaspbianTest"

So my existing mechanism to deploy a file is really tightly coupled to knowing the username and the destination IP address in the code.

Can we do better with a saved PuTTY session?

I plugged my IP address and username into PuTTY, and saved them as a session named “Raspbian”. I’ve included a couple of screenshots below showing where I entered key bits of data. The first one shows the IP address, and where I name the saved session as “Raspbian”.

Putty saved session with IP address

The second one shows where I enter the username that I’d like to log on with:

Putty saved session with username

Once this “Raspbian” session was saved, I needed to find out how to use it with PSCP and Plink tools.

Using PSCP with Cake.PuTTY

This turned out to be pretty easy – instead of passing the destination IP address, I just passed in the session name. So now instead of:

"192.168.1.73:/home/pi/DotNetConsoleApps/RaspbianTest"

I’ve got:

"Raspbian:/home/pi/DotNetConsoleApps/RaspbianTest"

And I don’t need to pass the username in the settings anymore, so my code in the Cake build script for PSCP looks like this:

var destination = sessionname + ":" + destinationDirectory;
var fileArray = files.Select(m => @"""" + m.ToString() + @"""").ToArray();
Pscp(fileArray, destination, new PscpSettings
                                    { 
                                        SshVersion = SshVersion.V2 
                                    }
);

Using Plink

This turned out to be a little harder – but not too much. I couldn’t get the Cake.PuTTY plugin to work for this, but fortunately I’m able to use the StartProcess C# method with Cake to just run a Plink command.

The command I’d like to run looks like:

plink -load Raspbian [[insert a custom linux command here]]

And the C# code for this, where sessionname = “Raspbian”, is pasted below:

var plinkCommand = "chmod u+x,o+x " + destinationDirectory + "/" + executableName;
 
StartProcess("plink"new ProcessSettings {
        Arguments = new ProcessArgumentBuilder()
            .Append(@"-load")
	    .Append(sessionname)
            .Append(plinkCommand)
        }
);

So now that I can deploy with a saved session, I create a new configurable parameter in my build.cake script called “sessionname”, and leave the username and IP address fields blank.

///////////////////////////////////////////////////////////////////////
// ARGUMENTS (WITH DEFAULT PARAMETERS FOR LINUX (Ubuntu 16.04, Raspbian Jessie, etc)
///////////////////////////////////////////////////////////////////////
var runtime = Argument("runtime""linux-arm");
var destinationIp = Argument("destinationPi""<<safe to leave blank>>");
var destinationDirectory = Argument("destinationDirectory"@"/home/pi/DotNetConsoleApps/RaspbianTest");
var username = Argument("username""<<safe to leave blank>>");
var sessionname = Argument("sessionname""Raspbian");
var executableName = Argument("executableName""HelloRaspbian");

And use the target “DeployWithPuTTYSession”, which is detailed below:

Task("DeployWithPuTTYSession")
    .IsDependentOn("Publish")
    .Does(() =>
    {
        var files = GetFiles("./publish/*");
        
		var destination = sessionname + ":" + destinationDirectory;
		var fileArray = files.Select(m => @"""" + m.ToString() + @"""").ToArray();
		Pscp(fileArray, destination, new PscpSettings
					{ 
						SshVersion = SshVersion.V2 
					}
		);
 
		var plinkCommand = "chmod u+x,o+x " + destinationDirectory + "/" + executableName;
 
		StartProcess("plink"new ProcessSettings {
        		Arguments = new ProcessArgumentBuilder()
            		.Append(@"-load")
			.Append(sessionname)
            		.Append(plinkCommand)
        }
);

Updating the open source code, and how to use it

I’ve updated the source code on Github and also updated the NuGet package – you can check out my previous post on how to install this .NET Core template, and there are instructions on the project ReadMe, but the short version is that you can run the command below at a command prompt:

 dotnet new -i RaspberryPi.Template::*

And then you can create a new RaspberryPi IoT project (I called mine HelloRaspbian, yours can obviously be different) with the command:

dotnet new coreiot -n HelloRaspbian

From the generated project, run the command in the ReadMe.txt file to generate a build.ps1 file so we can run Cake:

Invoke-WebRequest http://cakebuild.net/download/bootstrapper/windows -OutFile build.ps1

Now open the build.cake file and update the parameters you want to use – the focus of this post is on a PuTTY session, and now we can update the sessionname parameter. Then in the project folder, run the command:

.\build.ps1 -target DeployWithPuTTYSession

This command will use your saved PuTTY session when deploying from a Windows machine to a Raspberry Pi running Linux, and allow you to deploy without specifying a username or IP address in your build.cake file.

Wrapping up

I’ve extended my RaspberryPi.Template for .NET Core to allow users to deploy to their Pi using a saved PuTTY session. Hopefully this small extension makes the template easier for the community to use.

nuget

Fixing rogue behaviour in NuGet by clearing the caches

I’ve been posting some of my code to GitHub and creating NuGet packages to make it easy to grab my code.

Typically my process is to create a C# project which contains only interfaces. Then I create another C# project which contains an implementation of this interface, and references the first project. By doing this it’s easy for me to swap out the implementation later and keep the same interface.

Creating NuGet packages for these library projects helps me conveniently include libraries in other projects, and manage versioning through Visual Studio.

I create NuGet packages using the NuGet package explorer (with the source code on GitHub) and there’s instructions on how to do this here.

Usually this is a simple process – I create my nupkg files and host them locally for testing. When I’m happy that the nupkg file does what I want, I’ll publish NuGet packages to https://www.nuget.org/, using the NuGet package explorer with the secret key I got by registering at that site.

However, a few nights ago when I was creating some servo packages, I started to notice some very strange behaviour. When I tried to install a package in VS2015, the behaviour of the library that was installed was definitely not what I had packaged up. I spent a long time seeing strange behaviour and getting increasingly frustrated by it, until I found the reason – NuGet caches files in a selection of locations across my hard drive.

How to find where NuGet caches files

I used the nuget executable to find where the NuGet caches were hidden – I downloaded it from here. At the time of writing, the downloadable executable is version 2.8.60717.93 which is quite old – but fortunately, you can use nuget to upgrade nuget using the command:

nuget update -self

This takes the version to 3.4.3.

There’s a very simple command to list all the places that NuGet caches files:

nuget locals all -list

And I found that it caches files in four separate locations.

C:\NuGet>nuget locals all -list
http-cache: C:\Users\Jeremy\AppData\Local\NuGet\v3-cache
packages-cache: C:\Users\Jeremy\AppData\Local\NuGet\Cache
global-packages: C:\Users\Jeremy\.nuget\packages\
temp: C:\Users\Jeremy\AppData\Local\Temp\NuGetScratch

Given NuGet caches in so many places, it didn’t surprise me that I started to have problems. And fortunately, there’s a simple command to clear these caches using NuGet.

nuget locals all -clear

This clears all the caches.

C:\NuGet>nuget locals all -clear
Clearing NuGet HTTP cache: C:\Users\Jeremy\AppData\Local\NuGet\v3-cache
Clearing NuGet cache: C:\Users\Jeremy\AppData\Local\NuGet\Cache
Clearing NuGet global packages cache: C:\Users\Jeremy\.nuget\packages\
Local resources cleared.

After I cleared this, the NuGet started to behave much more consistently.

.net, Clean Code, Making, nuget, Raspberry Pi 3, UWP

A servo library in C# for Raspberry Pi – Part #2: Designing the interface, IServoController

Last time I posted an article describing a proof of concept for how to control a servo using a Raspberry Pi 3. This time, I want to improve the code so it’s better than just a rough proof of concept – I’d prefer to write a re-usable library. So the first step of my design is to build an interface through which I can talk to the servo.

There were a few principles that I wanted to adhere to:
1. Make the interface fluent (where it was sensible to do so);
2. Make the interface as small as possible;
3. Add public properties so this could be used for servos which have slightly different profiles.

Finally, I wanted to implement the IDisposable interface – this would be useful to close any connections if that was necessary.

Connecting to the servo

There are a couple of things that need to be done when setting up the servo:
1. Specify the GPIO pin on the Raspberry Pi which is going to output a PWM signal;

int ServoPin { getset; }

2. Once we have specified the pin, we need to open a connection. I knew from my proof of concept code that this used asynchronous methods, so I needed the return type to be a Task (as asynchronous methods cannot return void in C#).

Task Connect();

Moving the servo wiper

The first and most obvious thing to tell a servo to do is move to a particular rotational position. This position would be most commonly measured in degrees.

However, one issue is that the source program has no means of knowing when the servo’s blade has reached position. In Arduino code, I’ve seen this handled by just putting a delay in after the instruction to move to a particular position.

I liked the idea of a chain of commands, which would tell the servo the position to move to, specify the amount of time allowed to move to this position, and then go.

// This moves to 45 degrees, allowing 500ms to reach that position
servo.SetPosition(45).AllowTimeToMove(500).Go();

So this ideal chain told me that I needed to have the methods:

void Go();
 
IServoController SetPosition(int degree);
 
IServoController AllowTimeToMove(int pauseInMs);

Altering frequency duty cycle properties

My research told me that servos usual expected duty cycles of 5% to 10% to sweep from 0 to 180 degrees. However, I also found some people who found these are idealised figures – in fact, with my own servos, I found that a better range of duty cycle went from 3% to 12%. So I realised that any servo controller probably needed to have public properties to set frequency, and minimum and maximum duty cycle values.

int Frequency { getset; }
 
double MaximumDutyCycle { getset; }
 
double MinimumDutyCycle { getset; }

The finished interface

So that described what I wanted my servo controller interface to look like – I’ve pasted the code for this below.

public interface IServoController : IDisposable
{
    int Frequency { getset; }
 
    double MaximumDutyCycle { getset; }
 
    double MinimumDutyCycle { getset; }
 
    int ServoPin { getset; }
 
    Task Connect();
 
    void Go();
 
    IServoController SetPosition(int degree);
 
    IServoController AllowTimeToMove(int pauseInMs);
}

Publishing the interface as a library

The final step I wanted to take was to publish this interface to NuGet. I decided to publish the interface in a separate package to the implementation, so that it would be easy to swap out the implementation if necessary.

Presently this interface is available here, and it can be downloaded from NuGet using the command:

Install-Package Magellanic.ServoController.Interfaces -Pre

It’s presently in an alpha (pre-release) status so the “-Pre” switch is needed for the moment.

Next time, I’ll write about how to implement this interface, and I’ll write a simple UWP app to test this.

.net, C# tip, nuget, Visual Studio, Visual Studio Plugin

What’s the link between C# 6.0 language specifications, .NET Frameworks and Visual Studios?

My current work project uses the .NET framework v4.5, and we’re developing using Visual Studio 2013. I’ve been reading about the new language features of C# 6.0 for a while, and I’m really interested in finding a way to use them.

I used Bing/Google to identify what the new language features are, read some blogs and fired up my personal copy of Visual Studio 2015 to try out a few examples. The one I was really interested in was Primary Constructors, but there were a list of new features I wanted to try:

  • Primary Constructors
  • Import of static type members into namespace
  • Auto property initializers
  • Default values for getter-only properties
  • String interpolation
  • nameof operator
  • Dictionary initializer
  • Null propagator

This isn’t a comprehensive list of the new features, they’re just the ones that I think I would use most in my day-to-day coding.

The first feature I decided to try was creating a Primary Constructor…but when I wrote the code in VS2015 and .NET 4.6, it showed the dreaded red squiggly line and didn’t compile. What went wrong?

After some more research, I found that the Primary Constructor feature has been removed (at least temporarily). So those articles (for example, this one) showing me how to do this are, for now, wrong.

This made me sit back and think a bit more.

  • When I look at the dropdown list of available .NET frameworks in Visual Studio 2015, there’s quite a few (at least in my system). Which one should I be using to compile C# 6.0 language features?
  • And what does C# 6.0 actually mean? Should I be assuming that .NET Framework 4.6 necessarily corresponds to C# 6.0?
  • Can I make Visual Studio 2013 compile code written using C# 6.0 language features?
  • And where does Roslyn fit into all of this?

Some Sample Code for C# language features

I wrote a simple class which contains each of the C# 6.0 features that I listed above (except Primary Constructors, obviously). It’s a bit of a silly example, but hopefully it illustrates the point. I’ve commented each of the features, and put some of the most relevant code in bold font.

namespace CSharp6SampleApplication
{
    using System;
    using System.Collections.Generic;
    using static System.Console;

    public class SuperCar
    {
        // Dictionary initializer
        private static readonly Dictionary<string, DateTime> _specialDates =
            new Dictionary<string, DateTime>
            {
                ["past"] = new DateTime(1985, 10, 26),
                ["current"] = new DateTime(1985, 11, 5),
                ["future"] = new DateTime(2015, 10, 21)
            };

        // Auto property initializers
        public string Manufacturer { get; set; } = "DeLorean";

        // Auto property initializers
        public int TopSpeed { get; set; } = 88;

        // Default values for getter-only properties - no need to specify a private setter;
        public double Power { get; }

        public Engine Engine { get; set; }

        public SuperCar()
        {
            // Default values for getter-only properties - possible to set in the constructor only
            Power = 1.21;
        }

        public override string ToString()
        {
            // String interpolation
            return $"Made by {Manufacturer}, Top Speed = {TopSpeed}";
        }
    }

    public class Engine
    {
        public string Manufacturer { get; set; }

        public bool IsEfficient(string engineType)
        {
            // nameof operator
            if (engineType == null)
            {
                throw new ArgumentNullException(nameof(engineType));
            }

            if (engineType == "Mr. Fusion")
            {
                return true;
            }

            return false;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var car = new SuperCar();

            // Import of static type members into namespace
            WriteLine(car.ToString());

            // Null propagator
            WriteLine(car.Engine?.Manufacturer ?? "No engine type specified yet");
        }
    }
}

How it works

There’s a difference between a language specification and the version of the framework that supports it.

C# 6.0 is a language specification that is supported by the Roslyn compiler for the .NET platform. This compiler ships by default with Visual Studio 2015 – however, Roslyn doesn’t ship with Visual Studio 2013 (obviously, because this came out before Roslyn).

So all of the above code will compile and works out of the box in Visual Studio 2015, and it works for .NET framework versions 2.0, 3, 3.5, 4, 4.5, 4.5.1, 4.5.2, and 4.6 (I just haven’t included version 1.0 and 1.1 because I don’t have them installed on my machine). It doesn’t matter about the framework – it’s the compiler that matters.

Can it work in VS2013?

I think the answer to this is “partly but not really”.

When I try the above code in VS2013, the environment looks like the screenshot below, with more of the red-squiggly lines and a bunch of compiler errors.

vs2013_code

But it’s possible to compile C# 6.0 features with Visual Studio 2013 – you just need to install a nuget package. Run the code below from the package manager console.

Install-Package Microsoft.Net.Compilers -Version 1.1.1

This will now compile, but the VS2013 development environment still thinks there’s a problem – it leaves the red squiggly lines and reports the errors in the Error List window. This is because Visual Studio 2013’s real-time compiler hasn’t been replaced, and the development environment doesn’t understand the new language features. So this isn’t really a long term workable solution to develop in VS2013 with C# 6.0 language features. But you can make the code compile if you need to.

.net, C# tip, Clean Code, MVC, nuget, Solid Principles, WebActivatorEx

MVC Tip – Use WebActivatorEx to clean up your boot-strapping logic

The code snippet below shows the Application_Start method inside Global.asax.cs for a default MVC4 implementation.

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
 
    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    AuthConfig.RegisterAuth();
}

In the default implementation, it looks alright – not too messy. But I’ve seen some implementations of this method which are much longer – code to manage NInject registrations, Automapper, and View Engines. So I’ve learned to see this method as somewhere that quickly starts to violate the Single Responsibility Principle.

WebActivatorEx

It’s actually really easy to keep your code clean using WebActivatorEx. This is available as a nuget package that allows a class to be called either just before (or just after) application start-up.

You can install it to your project using the command in the Package Manager Console:

Install-Package WebActivatorEx 

Let’s look at de-coupling Application_Start from the reference to AuthConfig.RegisterAuth(). If we prefix the namespace with a call to WebActivatorEx (as shown below) this method will be called before the Application_Start method.

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(MvcApplication1.AuthConfig), "RegisterAuth")]
namespace MvcApplication1
{
    public static class AuthConfig
    {
        public static void RegisterAuth()
        {
            // ...authorization logic here...
        }
    }
}

I love this pattern because it means that the logic for calling the method at start-up is contained within the same method’s class. We don’t need to call it from the Application_Start method, so we’ve cleanly de-coupled two the classes from each other.