amBX lights met TFS 2010, een Deja Vu

Eind 2009 (het was de nacht voor kerstmis, je ziet de kerstboom op de achtergrond) heb ik een artikeltje geplaatst over het aansturen van ledverlichting met Team Foundation Service 2008. Het was een ludieke actie rond eenzelfde oplossing van een collega (gebaseerd op een dure electronica) maar ik gebruikte gewoon een lampensetje van 25 euro gekocht bij een computerzaak tesamen met een gratis DLL. (https://sandervandevelde.wordpress.com/tag/ambx-lights/ )

Deze oplossing was gebaseerd op het aanpassen van het buildscript en wat handig omgaan met WCF. Ik heb destijds nog gekeken of ik het ook aan de praat kreeg met TFS 2010 maar de buildscripts waren inmiddels door Workflow Foundation (WF4) vervangen en het paste dus niet meer op mijn laptopschermpje.

Vandaag heb ik mijn amBX setje uit het vet gehaald voor een ander klusje waarbij de lampen ook hun opwachting mogen maken. Ik kreeg mijn setje zelfs aan de praat op Windows 7 64 bits. Het kan nog steeds in combinatie met de oude 1.10 drivers! En dus dacht ik, er staat nog een klusje open…

Maar nu hebben we de Team Foundation Service API. Haal het even op… Na installatie staan er een hoop assemblies in C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0

Onderstaande oplossing werkt prima. Ik start de app even op en zie de status in de lampen terug.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using amBXLibrary;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Common;

namespace TfsBuildNotify
{
  internal class Program
  {
    private static int Main(string[] args)
    {
      try
      {
        string uri = "http:// s erver. c om:8080/tfs/prd";
        string teamProjectName = "teamprojectname";
        string buildDefinitionName = "builddefinitionname";
        string userName = "username";
        string password = "password";
        string domain = "domainname";
        bool readKey = true;
        using (var TeamProjectCollection =
          new TfsTeamProjectCollection(new Uri(uri),
          new NetworkCredential(userName, password, domain)))
        {
        TeamProjectCollection.Connect(ConnectOptions.IncludeServices);
        TeamProjectCollection.EnsureAuthenticated();
        IBuildServer buildServer =
          (IBuildServer)TeamProjectCollection.GetService(typeof(IBuildServer));
        var buildDefinitions = buildServer.QueryBuildDefinitions(teamProjectName);
        IBuildDefinition myBuildDefinition = null;
        foreach (var buildDefinition in buildDefinitions)
        {
          if (buildDefinition.Name == buildDefinitionName)
          {
            Console.WriteLine(buildDefinition.Name);
            myBuildDefinition = buildDefinition;
            break;
          }
        }
        if (myBuildDefinition != null)
        {
          var builds = buildServer.QueryBuilds(myBuildDefinition);
          // find current build in progress
          IBuildDetail myBuild = (from build in builds
            where build.Status == BuildStatus.InProgress
            select build).FirstOrDefault();
          if (myBuild == null)
          {
            // find last build started
            myBuild = (from build in builds
              orderby build.StartTime descending
              select build).FirstOrDefault();
          }
          if (myBuild != null)
          {
            // Check state of found build
            try
            {
              switch (myBuild.Status)
              {
                case BuildStatus.Failed:
                  amBXWrapper.PlayRed(200, 10);
                  break;
                case BuildStatus.InProgress:
                  amBXWrapper.PlayWhite(200, 10);
                  break;
                case BuildStatus.PartiallySucceeded:
                  amBXWrapper.PlayRed(1000, 5);
                  break;
                case BuildStatus.Stopped:
                  amBXWrapper.PlayRed(1800, 5);
                  break;
                case BuildStatus.Succeeded:
                  amBXWrapper.PlayGreen(1800, 5);
                  break;
                }

                Console.WriteLine("State: " + myBuild.Status.ToString());
              }
              catch (Exception ex)
              {
                throw new ArgumentException("amBX error: " + ex.Message);
              }
            }
            else
            {
              // no build found
              amBXWrapper.PlayWhite(1800, 5);
              Console.WriteLine("Found: None");
            }
          }
          if (readKey)
          {
            Console.ReadKey();
          }
        }
        return 0;
      }
      catch (Exception ex)
      {
        Console.WriteLine("Error: " + ex.Message);
        Console.ReadKey();
        return 1;
      }
    }
  }
}

Eerst haal ik de TeamProjectCollection van de server via mijn credentials. Mocht je tegen de beveiliging van TFS aanlopen, kijk dan eens naar deze blog . Daar staat prima uitgelegd hoe je met de credentials moet omgaan.

Vervolgens haal ik via de buildServer de BuildDefinitions voor ons teamproject op. Hierbij wil ik er speciaal eentje uitpikken…

En van die definitie probeer ik de meest recente build te achterhalen. Eerst kijk ik of er een build “in progress” is. Indien dit niet het geval is, probeer ik de laatst gestarte build te achterhalen.

Achteraf stuur ik de lampen aan nav. de status van de gevonden build. Het is dus een simpele oplossing voor een simpel probleem. De Build class ondersteunt ook events maar daar ben ik niet verder op in gegaan. Ook kan, indien je voldoende rechten hebt, een build beïnvloed worden (start/stop) of zelfs volledig met code aangemaakt worden.

Succes met je eigen builds.