When your clone is several commits behind the master

Once in a while, I clone a project just to check out the code, have it compiled or even to request a pull for an update.

That’s ok.

But what if my clone gets stale? What if it is several commits behind the original repository? You see a message like this:

git1

How do you fix it? Is there a hidden button somewhere in the GitHub portal?

Doorgaan met het lezen van “When your clone is several commits behind the master”

Advertenties

Visualize Azure IoT Edge device routes as a flowchart in Asp.Net MVC

If you look at the routes page in Azure IoT Edge configuration wizard, what do you prefer?

The current notation:

Or do you prefer a flow chart like this:

The routes in Azure IoT edge are a clever solution to describe how messages from one module are sent to another. But the JSON notation can become less readable once you add more (up to twenty) modules. That could end up eg. nineteen routes or more!

Just as an experiment I was thinking about how the ease the experience using a graphical interface.

I prefer the second solution, probably just like you.

So let’s look at how you can create the same experience with your routes of your IoT Edge device.

Doorgaan met het lezen van “Visualize Azure IoT Edge device routes as a flowchart in Asp.Net MVC”

Create your own local Azure IoT Edge dashboard

Earlier this year, when Azure IoT Edge was still in Public Preview, I wrote a couple of blogs about Visualizing Azure IoT Edge using local dashboard.

Back then, I had to do some magic with both a C# IoT Edge module, a custom NodeJS docker container, and a Docker network to get it running.

Since then, a lot has changed. Microsoft already released a ton of new features. a And there is still more to come regarding the Azure IoT platform.

But that awkward local dashboard solution was nagging me. A few months ago, Microsoft introduced a NodeJS module as a first-class citizen for IoT Edge modules.

So it was time to pick up the gauntlet and use NodeJS for this awesome local IoT Edge dashboard:

#tldr;  If you like to dig into the code, zip it, clone it, extend it or even make a pull request, I made this project open source. If you only want to use it the easy-going way, pull it from docker eg. ‘svelde/localdashboard:1.0.1-amd64′.

At this moment, only Linux containers are supported. It is tested both on Windows and Ubuntu as host OS.

Interested in this module? Let’s see how you can use it.

Doorgaan met het lezen van “Create your own local Azure IoT Edge dashboard”

Cheap Arduino mesh using RF24 radio modules

Communication between devices is key when you want to combine one or more devices. In my previous blog, I used I2C, Bluetooth and RF24 modules. The latter ones, the RF24 have a few advantages: they are cheap and do not need pairing. In my previous blog, I used them for a peer-to-peer (or better: Master-Slave) communication. This time, we will look at a mesh network using these devices.

Doorgaan met het lezen van “Cheap Arduino mesh using RF24 radio modules”

Getting IP-Address in Win 10 IoT Core

I was working on a new pet project for Windows 10 IoT Core.

At this moment Win10 IoT Core is not supporting the Wi-pi Wi-Fi dongle. So I am using a Dlink 505 mobile companion to attach my Raspberry Pi b2 to my local network. This works great although Visual Studio has some trouble detecting the device.

But because the default app (yes, this is just an app) on the Pi shows the current IP-address, I can simply submit that address when deploying (in the project settings).

pack1

So far so good.

But when I deployed my own app I ran into a little problem. My Pi gets the current IP-address dynamically so at one point my deployment was not working anymore. The device had a new IP-address….

And this address is also needed for RDP so it is rather important.

I wanted to read the current IP address in C# code so I could show it in my own app. This seems a bit trivial, but Google was not helping me this time. All examples were based on System.Net so that was not working.

Then I was thinking, could it be that the default app is just open sourced? That way I could look in the code MSFT provided.

And yes it is! Just go to the github location.

And there I found the code to read the IP4 address (now a bit modified):

public static string GetCurrentIpv4Address()
{
  var icp = NetworkInformation.GetInternetConnectionProfile();
  if (icp != null
        && icp.NetworkAdapter != null
        && icp.NetworkAdapter.NetworkAdapterId != null)
  {
    var name = icp.ProfileName;

    var hostnames = NetworkInformation.GetHostNames();

    foreach (var hn in hostnames)
    {
      if (hn.IPInformation != null
          && hn.IPInformation.NetworkAdapter != null
          && hn.IPInformation.NetworkAdapter.NetworkAdapterId
                                                     != null
          && hn.IPInformation.NetworkAdapter.NetworkAdapterId
                      == icp.NetworkAdapter.NetworkAdapterId
          && hn.Type == HostNameType.Ipv4)
      {
        return hn.CanonicalName;
      }
    }
  }

  return "---";
}

Resolve the namespaces if needed…

So thank you MSFT for making the code available.

jsTreeview in ASP.NET MVC gevuld met Json action

Op dit moment heeft jQuery UI nog geen treeview control. Als alternatief zijn er enkele andere aanbieders van Treeview controls. In het verleden heb ik al eens bericht over de Telerik controls. Deze kan ik zonder meer aanbevelen maar helaas zijn de gratis extensies alleen voor open source projecten toe te passen.

Een andere treeview is de jsTreeview. Deze is heel aardig (ondersteunt ajax, de jQuery themes en bv. ook checkboxes). Helaas is de deocumentatie nogal fragmentarisch. Daarom geef ik hier een opstap hoe jsTreeview is toe te passen in ASP.NET MVC. We maken hierbij gebruik van Json actions om de kinderen op te vragen vanuit de controller.

Stap 1: Bestanden plaatsen

Haal eerst de laatste versie op vanaf http://www.jstree.com/ . Dit is de versie pre 1.0 fix 2.

Plaats in het ASP.NET MVC4 project de jquery.jstree.js in de \Scripts map.

Plaats d.gif (voor ie6 gebruik), d.png, styles.css en throbber.gif in \Scripts\themes\treeview map.

Stap 2: bundles aanpassen

Vul de bundles aan in de BundleConfig.cs:

bundles.Add(new StyleBundle("~/Scripts/themes/treeview").Include(
                         "~/Scripts/themes/treeview/style.css"));
bundles.Add(new ScriptBundle("~/bundles/jqueryplugins").Include(
                        [skip other plugins],
                        "~/Scripts/jquery.jstree.js"));

En deze bundles moeten op de _Layout.cshtml aangeroepen worden:

…
 @Styles.Render("~/Scripts/themes/treeview")
…
</head>
<body>
…
 @Scripts.Render("~/bundles/jquery", "~/bundles/jqueryui", "~/bundles/jqueryplugins")
…

Stap 3: HTML placeholder

Plaats een placeholder op de _Layout.cshtml

<div id="treeviewEdit"> Tree view placeholder</div>

Stap 4: JavaScript

Plaats daarna het volgende  script onder aan de _Layout.cshtml pagina  om te worden uitgevoerd als de pagina laadt (dit moet dus in een javascript blok):

$(function () {
    $("#treeviewEdit").jstree({
        "json_data": {
            "ajax": {
                "url": "/Home/FillEditTree",
                "data": function (n) {
                    return { id: n.attr ? n.attr("id") : 0 };
                }
            }
        },
        "themes": {
            dots: false,
            icons: true
        },
        "plugins": ["themes", "json_data"]

    });
});

Deze jQuery functie zal op de treeview div losgelaten worden om het treeview tekenen te forceren.

Stap 5: de (view) modellen

We praten straks in Json formaat met de treeview, maar we willen dit in typed classes samenstellen. Voeg dus de volgende viewmodellen toe:

jstreeview1

De code wordt dan:

public class JsTreeModel
{
    public JsTreeData data { get; set; }

    public JsTreeAttribute attr { get; set; }

    // "open" or "closed" or null (not available for ajax)
    public string state { get; set; }

    public List<JsTreeModel> children { get; set; }
}
public class JsTreeAttribute
{
    public string id { get; set; }
}
public class JsTreeData
{
    public string title { get; set; }

    public JsTreeDataAttribute attr { get; set; }

    // "folder"  or "/" for no icon thus file
    public string icon { get; set; }
}
public class JsTreeDataAttribute
{
    public string href { get; set; }
}

Laatste stap 6: Controller action

Voeg de volgende action toe aan de controller. Deze geeft ter demonstratie als antwoord altijd de opgevraagde node met daaronder twee kinderen. De eerste keer wordt node 0 opgevraagd. het eerste kind heeft zelf ook kinderen (niet meegestuurd in deze aanroep) en de tweede heeft geen kinderen:

public ActionResult FillEditTree(int id)
{
    // just to show some nodes
    var rootId = id + 2;

    var children = new List<JsTreeModel>();

    // first child containing one or more children
    children.Add(
        new JsTreeModel
            {
                attr = new JsTreeAttribute { id = (rootId + 1).ToString() },
                data = new JsTreeData
                        {
                            title = "Child " + (rootId + 1).ToString(),
                            attr =
                                new JsTreeDataAttribute
                                    {
                                        href =
                                            @"\home\edit\"
                                            + (rootId + 1).ToString()
                                    }
                        },
                state = "closed",
            });

    // second child containing NO children
    children.Add(
        new JsTreeModel
            {
                attr = new JsTreeAttribute { id = (rootId + 2).ToString() },
                data = new JsTreeData { icon = "/", title = "Child " + (rootId + 2).ToString(), },
            });

    // de ‘root’
    var requestedSubTree = new List<JsTreeModel>();

    requestedSubTree.Add(
            new JsTreeModel()
            {
                attr = new JsTreeAttribute { id = rootId.ToString() },
                state = "open",
                data =
                    new JsTreeData
                        {
                            title = "Title " + rootId.ToString(),
                            attr =
                                new JsTreeDataAttribute { href = @"\home\edit\23" }
                        },
                children = children
            });

    return Json(requestedSubTree, JsonRequestBehavior.AllowGet);
}

Dit geeft het volgende plaatje (na enkele keren kinderen opvragen):

jstreeview2

Er zijn een aantal zaken die opvallen:

  • De ‘root’ moet standaard de state geopend (“open”) krijgen
  • Je moet dus onderzoeken of de getoonde kinderen op hun beurt ook kinderen hebben
    • De kinderen moeten standaard de state te openen (“closed”) krijgen als deze op hun beurt kinderen hebben.
    • Een kind zonder kinderen moet geen state krijgen (dus null). Dan komt er ook geen ajax call mogelijkheid.

Bonus stap 7: jQuery Thema

Als laatste in het rijtej plugins kan “themeroller” toevoegen worden.  Deze kan je toepassen als alternatief voor thema:

$(function () {
    $("#treeviewEdit").jstree({
        [skip],
        "themes": {
            dots: false,
            icons: true
        },
        "plugins": ["json_data", "themeroller"]
    });
});

Dit geeft een aardige uitbreiding op het standaard aanwezige thema:

jstreeview3

Bonus stap 8: cookies

Je kunt ook plugin “cookies” toepassen. Dan wordt bij een F5 de selectie bewaard en niet opnieuw opgevraagd. Maar de laatste kan ook op de server in de sessie onthouden worden en bij de initiële aanroep (node id is 0) toegepast kunnen worden.

Conclusie 

Deze plugin is heel aardig om voor weinig geld en snel een treeview toe te passen in ASP.NET MVC.

Seeing anything you like? Google translate does not work out? Drop me a note and I will translate this post.

“Don’t shoot me, I’m just the In Process messenger”

In need of an English translation? Please drop me a note.

Voor ons huidige project zochten we naar een goed ontkoppeling tussen de user interface en de communicatie met hardware. Omdat het een WPF applicatie is en we gebruik maken van MVVM draait alles in hetzelfde applicatie.  De hardware willen we real time uitlezen en reageren op het gedrag.

Er werd dus nagedacht over het gebruik van Events. Dat is een prima oplossing voor “Loose coupling”. Maar hierbij is de ontkoppeling maar één kant op. De ‘luisteraar’ kent de verstrekker van de gebeurtenissen want hij moet zich daarop abonneren.

Omdat we MVVMLight gebruiken kregen we de mogelijkheid om nog verder te gaan met ontkoppeling. MVVMLight bezit namelijk ook een Messagebus.

De messagebus kennen we vooral vanuit SOA en Enterprise architectuur:

Maar hier hebben we te maken met messsages die In Process verstuurd worden. Hierbij zijn de volgende klassen te herkennen:

  1. De boodschap, de Message
  2. Diegene die ‘m verstuurt, de Sender
  3. Diegene die zich abonneert op dit type bericht, de Target of algemener, de Receiver
  4. De Messenger

Bij MVVMLight is dit opgelost met een aantal objecten die globaal beschikbaar zijn en via locking threadsafe zijn gemaakt. Hierdoor wordt het mogelijk om overal in de applicatie boodschappen te verzenden en eventueel te ontvangen.

Een boodschap is in het algemeen een overerving  van MessageBase, een standaard klasse beschikbaar in MVVMLight:

public class DeviceMessage : MessageBase
{
  public DeviceMessage(string message)
  {
    Message = message;
  }

  public string Message { get; private set; }

  public override string ToString()
  {
    return "Device message: " + Message;
  }
}

Hier hebben we een DeviceMessage die één property genaamd Message bezit.
Een message wordt verstuurd via de Send methode op de static Messenger:

Messenger.Default.Send<DeviceMessage>
    (new DeviceMessage("Time on device: " + DateTime.Now.ToString()));

Meer is er niet nodig om een boodschap op de Messagebus te zetten. In dit voorbeeld kan ik berichten met een datum/tijd verwachten. Zo kan ik ook vanuit een ViewModel juist een start- of stopcommando doorgeven aan een bepaald apparaat (of beter: een instanciering van iets wat de interface van dat apparaat implementeert). Ik heb geen kennis van de luisteraar, ik weet niet eens of die wel bestaat.

Hoe wordt het bericht ontvangen? Via een constructor of initialisatie heeft een andere partij zich geabonneerd op deze berichten:

Messenger.Default.Register<DeviceMessage>
  (this, true, m => {   Message = m.Message; });

In dit geval wordt de boodschap in op een ViewModel de m.Message uitgelezen en op het scherm getoond (via een bindable property).

Maar er is ook een bonus. De MessageBus is globaal beschikbaar en iedereen kan zich abonneren op berichten. MVVMLight biedt de mogelijkheid om met een Message ook een filtertoken op te nemen.

Messenger.Default.Send<SwitchMessage>
  (new SwitchMessage(this, "AnotherDevice"), "DeviceSwitchToken");

In dit geval kunnen meerdere partijen zich abonneren op een SwitchMessage. Maar door de meegestuurde “DeviceSwitchToken” zal wellicht niet iedereen de SwitchMessage verwerken, ze wachten op zo’n bericht vergezeld met een ander token.

En het is ook mogelijk om zich juist op een scala van berichten te abonneren. Het is mogelijk om alle overervingen van een baseclass te ontvangen:

public class LogProvider : ILogProvider
{
  public void Initialize()
  {
    // log all messages
    Messenger.Default.Register<MessageBase>(this, true, m =>
    {
      Debug.WriteLine(
        String.Format(
           "At {0} we received: {1}", DateTime.Now.ToShortTimeString(), m));
    });
  }
}

Hier heb ik een logger geabonneerd op alle overervingen van MessageBase.

Door de totale ontkoppeling van de zenders en ontvangers kan je het overzicht verliezen. Maar juist door deze logger heb ik een mooie tijdslijn van wat er onderling verstuurd is en kan ik analyseren wat er mis is gegaan. Daarom implementeer ik ook de ToString() zodat ik de messages hun eigen te loggen boodschap kan laten beschrijven.

Ik kan ook als een soort van watchdog een pulse afgeven. Als ik niet de gewenste antwoorden ontvang kan ik ‘alarm slaan’. En dit kan ik doen zonder dat ik de daadwerkelijke implementatie van de te controleren instanties niet ken.

Er zijn in MVVMLight nog een aantal andere boodschappen mogelijk. Ik wil er nog één aanstippen.

MVVMLight kent ook een generic message. Deze bevat standaard een Content property waarin een andere klasse gestopt kan worden. In bovenstaande voorbeelden is steeds gebruik gemaakt van een MessageBase overerving met extra properties. Met de generic oplossing kunnen die properties in de Content geplaatst worden. De Content zier er dan zo uit:

public class SwitchContent
{
  public SwitchContent(int id, string message)
  {
    ID = id;
    Message = message;
  }

  public int ID { get; private set; }

  public string Message { get; private set; }
}

De message wordt een stuk eenvoudiger:

public class GenericSwitchMessage : GenericMessage<SwitchContent>
{
  public GenericSwitchMessage(SwitchContent switchParameter)
        : base(switchParameter)
  {
  }

  public override string ToString()
  {
    return String.Format(
      "Switch message: sender{0}; target={1}", Sender, Target);
  }
}

Het te verzenden bericht wordt nu gecombineerd met de context:

Messenger.Default.Send<GenericSwitchMessage>
  (new GenericSwitchMessage(new SwitchContent (1, "Hallo")));

En het uitluisten ziet er ook wat rustiger uit:

public class LogProvider : ILogProvider
{
  public void Initialize()
  {
    // log all messages
    Messenger.Default.Register<GenericSwitchMessage>(this, true, m =>
    {
      // m.Content.ID
      // m.Content.Message
    });
  }
}

Conclusie:

De MVVMLight Messenger biedt een fraaie oplossing voor de totale ontkoppeling. Er zijn ook andere implementaties beschikbaar (iedere MVVM implementatie lijkt er wel één te bieden) dus het is eenvoudig om er aan te komen en om het eens uit te proberen.