Laurent Ellerbach

Ce blog est principalement destiné à publier des informations relatives à Microsoft, à ses technologies, aux outils Visual Studio et à ses versions Express notamment Visual Basic

  • Laurent Ellerbach

    Creating dynamically a web page using .NET Micro framework

    • 0 Comments

    In a previous post, I’ve explain how to read a file using .NET Microframework, how to create a setup file and load it (and write it also), how to implement a web server using HTTP and managing dynamically web pages and parameters. This post will explain how to generate dynamically a page using files and code. So more or less the same idea but using all components this time.

    And the project is about lighting my Lego city. The idea is to be able to click on an image and a led will switch on or off in the Lego city. I’ll show in this post how to generate dynamically using files and code the page containing the overlay images from this post.

    HttpListenerRequest request = context.Request;
    HttpListenerResponse response = context.Response;
    // decode params
    string strParam = request.RawUrl;
    ParamPage MyParamPage = new ParamPage();
    bool bLight = false;
    int iID= -1;
    Param[] Params = decryptParam(strParam);
    if (Params != null)
        for (int i = 0; i < Params.Length; i++)
        {
            //on cherche le paramètre strMonth
            int j = Params[i].Name.ToLower().IndexOf(MyParamPage.id);
            if (j == 0)
            {
                Convert.ToInt(Params[i].Value, out iID);
            }
            j = Params[i].Name.ToLower().IndexOf(MyParamPage.lg);
            if (j == 0)
            {
                Convert.ToBool(Params[i].Value, out bLight);
            }
        }

    This first part of the code is very similar to what I’ve explained in this post. The page parameters are analyzed, they are converted into real values. Here, each light has an id and a status. They can be on or off. Again, more information in some of my previous posts here.

    // if the ID value is valid, just light up the light :-)
    if ((iID != -1) && (iID < myLegoLight.Count))
    {
        ((LegoLight)myLegoLight[iID]).Light = bLight;
    }

    As it’s a web page and anyone can access it, there are a minimum of integrity to do Sourire I just check if the id is in the limit and load the object. More information on the LegoLight class here.

    string strResp = "<HTML><BODY>netduino Lego City<p>";
    
    // Print requested verb, URL and version.. Adds information from the request.
    strResp += "HTTP Method: " + request.HttpMethod + "<br> Requested URL: \"" + request.RawUrl +
        "<br> HTTP Version: " + request.ProtocolVersion + "\"<p>";
    strResp = OutPutStream(response, strResp);
    //send first part of the HTML File
    SendFile(response, strDefaultDir + "\\page1.ht");

    I create a string with the first part of the HTML page and for debug purpose, I add couple of information and send the string to the response object. Again, everything is explained there.

    The SendFile function is the one described in the post explaining how to read a file. Details here. strDefaultDir contains the directory where the file page1.ht is located. In the emulator it’s WINFS and in the netduino it’s SD. I change it “manually” depending on the environment I’m in. No real need to write code for this. Remember we are running an embedded application, no one will change it!! So things like this one can be written in the marble Sourire

    Page1.ht contains the following:

    <script langague="Javascript">
      // You don't need to worry about this
      function findTop(iobj) { ttop = 0; while (iobj) 
    { ttop += iobj.offsetTop; iobj = iobj.offsetParent; } return ttop; } function findLeft(iobj) { tleft = 0; while (iobj)
    { tleft += iobj.offsetLeft; iobj = iobj.offsetParent; } return tleft; } //This is all you need: //findTop(doucment.all.MyImage); </script> <p> Click the lamp to switch on or off </p>

    As expected, it’s just HTML code Sourire and if you want to understand what is the javascript in the page doing, read this post. By the way, I don’t like javascript, I truly prefer C/C++, C#, VB or even real Java (I say I prefer Java over javascript but it’s far far away from the 3 others Sourire).

    //build array of Span
    LegoLight mLegoLight;
    for (int i = 0; i < myLegoLight.Count; i++)
    {
        mLegoLight = (LegoLight)myLegoLight[i];
        strResp += "<span style='position:absolute;margin-left:" + mLegoLight.PosX +
    "px; margin-top:" + mLegoLight.PosY + "px;width:26px;height:45px;
    top:findTop(document.all.MyImage); left:findLeft(document.all.MyImage);'>"
    ; strResp += "<a href='/" + MyParamPage.pageDefault + ParamStart+ MyParamPage.id +
    ParamEqual + i + ParamSeparator + MyParamPage.lg + ParamEqual + !mLegoLight.Light + "'>"; strResp = OutPutStream(response, strResp); if (mLegoLight.Light) SendFile(response, strDefaultDir + "\\imgon.ht"); else SendFile(response, strDefaultDir + "\\imgoff.ht"); strResp += "</a></span>"; strResp = OutPutStream(response, strResp); }

    The next part of the code displays as a span over the main image all LegoLight object and depending if the state of the light is on or off send a different file. in one case it’s imgon.ht and in the other imgoff.ht. Both code are very similar:

    <img border=0 width=26 height=45 src="/WINFS/lampon.png">
    <img border=0 width=26 height=45 src="/WINFS/lampoff.png">

    Of course the /WINFS here reference the emulator path. In the reality it will be /SD as content will be in an SD card in the real word.

    And to finish, couple of lines:

    //send rest of the file
    SendFile(response, strDefaultDir + "\\page2.ht");
    
    strResp += "</BODY></HTML>";
    strResp = OutPutStream(response, strResp);

    They basically send the rest of the page. page2.ht just contains the image:

    <img alt="" src="/WINFS/ville.jpg" /></p>
    

    Again, here I’m using the emulator. In order to make it work, /WINFS need to be change to /SD to work on the Netduino.

    And you are done, here is a simple example that mix file and dynamic generated code to produce a web page in .NET Microframework Sourire Enjoy the beauty of the code Sourire

  • Laurent Ellerbach

    Dynamically watermark a picture in a ASP.NET page

    • 0 Comments

    In a previous post, I’ve explain how to use generic ASP.NET handlers to display a picture. The concept is easy to use and perfect to manipulate any kind of document you want to output in your web server. There equivalent of this in technologies like PHP or Java but it’s so easy to do using ASP.NET. In my previous post, I’ve used VB, so I’ll continue with VB Sourire Don’t worry, it’s as easy to do in C#!

    The overall code to watermark an image dynamically using the generic handler and the minimum manipulation code is here:

    <%@ WebHandler Language="VB" Class="Image" %>
    
    Imports System
    Imports System.Web
    Imports System.Net
    Imports System.IO
    Imports System.Drawing
    Imports System.Drawing.Imaging
    Imports System.Drawing.Drawing2D
    
    Public Class Image : Implements IHttpHandler
        
        Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
            context.Response.ContentType = "image/jpeg"
            context.Response.AddHeader("Cache-Control", "private,must-revalidate,post-check=1,pre-check=2,no-cache")
                    
            Dim instanceHTTP As New WebClient
            Dim MaCamera As New Camera
            Dim MyUri As New Uri("file://c:/Temp/image.jpg")
            Dim returnValue As Stream
            
            Try
                
                returnValue = instanceHTTP.OpenRead(MyUri)
                
                Dim MyImage As System.Drawing.Image = System.Drawing.Image.FromStream(returnValue)
                
                Dim MyText As String = Now.ToString("yyy-MM-dd HH-mm")
                Dim MyGraphics As Graphics = Graphics.FromImage(MyImage)
                Dim MyFont As Font = New Font(FontFamily.GenericSerif, 12)
                MyGraphics.DrawString(MyText, MyFont, Brushes.White, 100, 100)
                            
                MyImage.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)
                MyGraphics.Dispose()
                MyImage.Dispose()
                
            Catch ex As Exception
                context.Response.Write("Error")
            End Try
            
        End Sub
     
        Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
            Get
                Return False
            End Get
        End Property
    
    End Class
    

    I will not explain again what I’ve explain in the previous post on the way handlers are working. So I’ll just concentrate on the image manipulation and how to write text in an image dynamically.

    returnValue = instanceHTTP.OpenRead(MyUri)
    
    Dim MyImage As System.Drawing.Image = System.Drawing.Image.FromStream(returnValue)
    
    Dim MyText As String = Now.ToString("yyy-MM-dd HH-mm")
    Dim MyGraphics As Graphics = Graphics.FromImage(MyImage)
    Dim MyFont As Font = New Font(FontFamily.GenericSerif, 12)
    MyGraphics.DrawString(MyText, MyFont, Brushes.White, 100, 100)
                
    MyImage.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)
    MyGraphics.Dispose()
    MyImage.Dispose()

    I first open a URI which contains an image. In my case a static image sitting on the hard drive but the idea here is to take it from a webcam for example. The URI is open as a stream and passed to an Image object.

    The idea here is to watermark the image with the date. So I create a simple string containing the date and time in a dedicated formatting. I like this formatting "yyy-MM-dd HH-mm" as it’s easy to sort especially with files. It does return a text like “2011-11-24 10-47”.

    Then I create a graphics object pointing on the image. This object is directly link to the image we have loaded and any modification made on the graphics object will impact the image. It’s the basic concept of pointers used here.

    In order to write text, you’ll have to choose a font. Again, nothing complicated here, choose your preferred font and the size. A good Serif and a 12 size will be enough in my example.

    And let the magic work using the DrawString method to draw in the graphics, so in the image your text. The 100 and 100 params are the X and Y starting point where to write the text. It starts on the upper left corner of the image. You can also use predefined points. But for the example, I keep it very simple.

    And as explain in the previous post, you just have to save your watermarked picture into the output stream and you’re done. Or almost done, don’t forget to dispose the graphics objects, better to do it especially if you want to scale up. The garbage collector will thank you Sourire

    Final result will look like that:

    image

    And of course, you can do more, much more using this handler. You can add shapes, transform the color schemas, apply filters, etc. .NET is full or very efficient graphics manipulations. so just use them! In my case I use it to tag pictures with date and time as in this example but also to control when I can access an image on some webcam. I do not expose them directly to the web. They are only accessible thru handlers like this. And only to specific persons (with a login and password) and on specific time. Maybe more in a next example!

    As always, feedback welcome Sourire The code and blog post written in a plane from Paris to Zagreb Sourire

  • Laurent Ellerbach

    Writing a generic ASP.NET handler to return an image and control the image

    • 1 Comments

    In one of my project, I want to integrate the picture from an IP camera to a web site. The idea is to be able to put a IP camera in my Lego room and see it for real. Especially to be able to control it. this project is linked to the one to light my Lego city. Instead of having the static image of the city, I want to be able to show the real time image. For this project, I’m using a netduino and .NET Microframework.

    Most IP camera do propose a simple URL where you can get the image. So it is very easy to integrate. But what if you want to control when to display the picture? Let say you don’t want to display the picture over night or just in small period of time? Or you want to dynamically add something to the picture like a layer? Well, IP camera are not smart enough to do it. So you’ll have to write some code.

    In ASP.NET you cant easily write a generic handler with the .ashx extension. that’s what I’ll do. And I’ll do it in VB.NET, that will change from my previous post that I did in C#. And no, I won’t do it in C++, php or Java Tire la langue. Yes, I do love VB too. Not only C#. As started developing a very long ago when the only thing you had on a PC was BASICA, the BASIC that was implemented in the IBM PC ROM. My father had a PC at home he was using for his own business.I was allow to use it but as I did not get any floppy disk, the only thing I was able to do was coding. And that’s at this time at 10 I started to code… in BASIC. and since then I never stopped coding Sourire 

    The simple code is the following one:

    <%@ WebHandler Language="VB" Class="Image" %>
    
    Imports System
    Imports System.Web
    Imports System.Net
    Imports System.IO
    Imports System.Drawing
    Imports System.Drawing.Imaging
    Imports System.Drawing.Drawing2D
    
    Public Class Image : Implements IHttpHandler
        
        Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
            context.Response.ContentType = "image/jpeg"
            context.Response.AddHeader("Cache-Control", 
    "private,must-revalidate,post-check=1,pre-check=2,no-cache") Dim instanceHTTP As New WebClient Dim MyUri As New Uri("http://yourcameraurl/image.jpg") Dim returnValue As Stream Try returnValue = instanceHTTP.OpenRead(MyUri) Dim MyImage As System.Drawing.Image = System.Drawing.Image.FromStream(returnValue) MyImage.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg) MyImage.Dispose() Catch ex As Exception context.Response.Write("Error") End Try End Sub Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable Get Return False End Get End Property End Class

    On top the page, you have to declare that it’s a WebHandler and implement IHttpHandler. When you’ve done that, add the ProcessRequest function as following:

    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

    And also the read only property IsReusable. This function basically allow you to control if you want the ProcessRequest function to be reusable without executing the code or not. Here, the idea is to refresh the image each time the function is called so the property will return false.

    The ProcessRequest function gives you a HttpContext object. This object allow you to get many information like the brower type, the IP request address and more. But it also allow you to write in the response object. And that’s what interest us here as we want to send back an image.

    context.Response.ContentType = "image/jpeg"
    context.Response.AddHeader("Cache-Control", "private,must-revalidate,post-check=1,pre-check=2,no-cache")

    Those 2 just set the content type as an image so the browser will know how to interpret the content before having it at all. It does this interpretation automatically based on the extension of the file usually even if the type is not set. But here, it is mandatory to define as the extension of you file is .ASHX. And is it not interpreted as an image by any browser Sourire and the .ASHX can virtually return anything, it can be images, text, videos, PowerPoint, Excel file, Word docs, zip or whatever you want. So don’t forget this line! Still the browser (at least Internet Explorer Sourire) is smart enough to figure out that when you are in the “Error” returned in the stream is text and not a jpg…

    the second line is about adding a header. Here, I’m not really sure I do it correctly but I try to specify that the browser can’t cache the image as I want always a fresh image.

            Dim instanceHTTP As New WebClient
            Dim MyUri As New Uri("http://yourcameraurl/image.jpg")
            Dim returnValue As Stream

    The instanceHTTP variable will be used to download the image from the web cam. It’s a WebClient which allow to do this kind of operation. It can be done synchronously or asynchronously.

    The MyURI is used to create the URI that will be used to download the picture. So put in the string the address of your webcam. It is quite easy to find, just open your webcam in a browser, usually it display a page which includes the picture of your image. Right click on the image and you get the URL.

    Then we will need a stream object to put the image in and resend to the response object. that’s what returnValue is.

            Try
                returnValue = instanceHTTP.OpenRead(MyUri)
                
                Dim MyImage As System.Drawing.Image = System.Drawing.Image.FromStream(returnValue)
                            
                MyImage.Save(context.Response.OutputStream, 
    System.Drawing.Imaging.ImageFormat.Jpeg)MyImage.Dispose() Catch ex As Exception context.Response.Write("Error") End Try

    I know you are a good developer so I know when you are trying to access critical resources or resources that may not be present that you are using a try catch section. Good, you are a great developer Sourire. The fact is that trying to download a picture from a webcam may not work. The webcam may be down, your kids may have switch it off or your cat or your mother or whatever can happen.

    returnValue = instanceHTTP.OpenRead(MyUri)

    The 3 variables created previously are used in this line of code. It does open a stream (returnValue) from the WebClient (instanceHTTP) which has a URI (MyURI). That’s done, we are ready to download the picture from the camera.

    Dim MyImage As System.Drawing.Image = System.Drawing.Image.FromStream(returnValue)

    So I create an Image object which I get from the camera thru the function FromStream. On this image, I can do whatever I want. Add text, change the size, colors or do any manipulation.

    MyImage.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)

    Here, I just save the image as a jpeg in the Response object. And I don’t forget to dispose the image as I don’t need it anymore.

    And that’s it! And you can image returning video or file you have created on the flight. Or pages or whatever you want. It is as simple to use handlers in ASP.NET. This implementation as it is as not really a usage. It is much simple to directly use the address of the camera. The only usage you can see is to secure your internal network and the access to the camera. By doing this you are impersonalizing the access to the camera. It is view as a black box from your web server.

    I’ll try to do couple of more post to show examples on how you can create thumbnails on the flight using this technic or maybe how you can restrict access regarding hours. I’m just a marketing guy with a technical background doing code in planes and enjoying it Sourire So any feedback on the code an those articles is welcome. And I see in my stats you are more and more to read them!

  • Laurent Ellerbach

    Read a setup file in .NET Microframework

    • 0 Comments

    In my previous post, I’ve explain how to read the content of a file in .NET Microframework. The idea now is to read a setup file. I want to store the position of the lamp icon I’d like to display on my Lego city map. More information on what I want to do in this post.

    First I’d like to explain the final structure of object I want to setup with my file. I have created a class which will contain a name, a position, the information if the light is on or not. The class is very simple, here is the code:

    public class LegoLight
    {
        private string myName = "";
        private int myPosX = 0;
        private int myPosY = 0;
        private byte myNetwork = 0;
        private bool myLight = false;
    
        public string Name
        {
            get { return myName; }
            set { myName = value; }
        }
        public int PosX
        {
            get { return myPosX; }
            set { myPosX = value; }
        }
        public int PosY
        {
            get { return myPosY; }
            set { myPosY = value; }
        }
        public byte Network
        {
            get { return myNetwork; }
            set { myNetwork = value; }
        }
        public bool Light
        {
            get { return myLight; }
            set { myLight = value; }
        }
    }

    Then I create an Array to store all the LegoLight objects. The good news with array is that you can easily add, remove, search in the array. The main problem is that the object you are adding are just objects. so you need a cast to force the kind of object you want to play with. But as you are the developer, you know what you’ve put in your array Sourire or if you don’t know, just guess Tire la langue

    static ArrayList myLegoLight = new ArrayList();

    I decided to create a simple setup file with the name, network and both position saved in the file. The concept of network is to be able to display all lights that are part of a network at the same time. The position is the position in pixel on the main image of the led to display. The name will be able to be displayed in the alt attribute of the file but also to be able to display the information on a regular page and not on the map. And I don’t save the state of the light, by default, it will be off.

    There is no serialization implemented in netduino so to store a save and read a file, you’ll have to do it manually. You have basically 2 options. First is to save the binary state of your object. That’s approximately what the serialize function is doing and the second is to do like the old ini files readable by a human. I will go for the second option just because I’m a human and it will be easiest for me to create the setup file. I can do it easily with notepad.

    So I have decided to use the following format: name(string);network(number in a string);PosX(number in a string); PosY(number in a string)\r

    As an example, it gives for one LegoLight object: mairie;1;158;59
    and for an array:

    mairie;1;158;59
    station;1;208;300
    train;1;10;10
    rue;1;700;550

    Now the challenge is to read a file like this. The code I wrote is the following (ParamSeparator = ‘;’, strDefaultDir and strFileSetup contains the path of the file and the name):

    LegoLight mLegoLight = new LegoLight();
    FileStream fileToRead = null;
    try
    {
        fileToRead = new FileStream(strDefaultDir+"\\"+strFileSetup, FileMode.Open, FileAccess.Read);
        long fileLength = fileToRead.Length;
        // Send HTTP headers. Content lenght is ser
        Debug.Print("File length " + fileLength);
        // Now loops sending all the data.
    
        //file length has to be less than 1024 otherwise, it will raise an exception
        byte[] buf = new byte[fileLength];
        string mySetupString="";
        
        // Reads the data.
        fileToRead.Read(buf, 0, (int)fileLength);
        // convert the read into a string
        mySetupString = new String(Encoding.UTF8.GetChars(buf));
        //find "\r"
        int i = mySetupString.IndexOf("\r");
        string mySubstring = "";
        string[] myParam;
        int j=0;
        while ((i < mySetupString.Length) && (i != -1))
        { 
            //split the substring in 3
            mySubstring = mySetupString.Substring(j, i - j);
            myParam = mySubstring.Split(ParamSeparator);
            mLegoLight = new LegoLight();
            mLegoLight.Name = myParam[0];
            int myint = 0;
            Convert.ToInt(myParam[1], out myint);
            mLegoLight.Network = (byte)myint;
            Convert.ToInt(myParam[2], out myint);
            mLegoLight.PosX = myint;
            Convert.ToInt(myParam[3], out myint);
            mLegoLight.PosY = myint;
            myLegoLight.Add(mLegoLight);
    
            //next string
            j = i+1;
            if (j < mySetupString.Length)
                i = mySetupString.IndexOf("\r", j);
            else
                i = -1;
            
        }
        fileToRead.Close();
    }
    catch (Exception e)
    {
        if (fileToRead != null)
        {
            fileToRead.Close();
        }
        throw e;
    }

    First, it create the LegoLight array and a file stream. Then, in a try catch, it starts to open and read the content of the file. See the previous post for most details on how to read a file on a SD. Please note here that the file as to be smaller than the max size of the buffer. For the netduino it is 1024. So the total length of the setup file has to be smaller than 1K. 1 LegoLight is about 35o so it allow to store about 30 objects. Which is quite enough for my needs. I did not test it in my code. I’m the only user of the solution and if I distribute it, I’ll have to do couple of additional check. But as we are in a try catch section, the code will just raise an exception and it will continue to work anyway.

    The second part is more interesting as it is where the parameters will be read and converted. First the buffer is converted into a string. the mySetupString now contains strings that’s has to be analyzed. I had 2 ways to do it there. The first one was to split the string using mySubstring.Split function with the "’\r’ and then for each object in the string, split it again finding the ‘;’. I did it for the first part in the “old way” with a simple while loop and finding the next occurrence of the ‘\r’. That is basically what the Split function is doing anyway to produce the array of strings.

    mySetupString = new String(Encoding.UTF8.GetChars(buf));
    //find "\r"
    int i = mySetupString.IndexOf("\r");
    string mySubstring = "";
    string[] myParam;
    int j=0;
    while ((i < mySetupString.Length) && (i != -1))
    { 
        //split the substring in 3
        mySubstring = mySetupString.Substring(j, i - j);
        myParam = mySubstring.Split(ParamSeparator);
        mLegoLight = new LegoLight();
        mLegoLight.Name = myParam[0];
        int myint = 0;
        Convert.ToInt(myParam[1], out myint);
         mLegoLight.Network = (byte)myint;
        Convert.ToInt(myParam[2], out myint);
        mLegoLight.PosX = myint;
        Convert.ToInt(myParam[3], out myint);
        mLegoLight.PosY = myint;
        myLegoLight.Add(mLegoLight);
    
        //next string
        j = i+1;
        if (j < mySetupString.Length)
            i = mySetupString.IndexOf("\r", j);
        else
            i = -1;
        
    }

    When a line of parameters like “station;1;208;300” is in the myParam string array, the first param contains “station”, the second one “1”, the third one “208” and the last one “300”. As the numbers are in a string format, they need to be converted into real numeric numbers. In a previous post, I’ve created couple of functions that allow an easy conversion, that’s the job of the Convert.ToInt function. The LegoLight object is then added to the array.

    This is an easy and cheap way in terms of memory print to read a setup file and restore the state of objects. For biggest objects or file, you’ll may have to store the binary representation of the data and read by chunk. that should be as efficient but use less memory print. And ob course, avoid XML format they are too big and too costly in foot print. Remember, you have very limited resources, you need to tune them and make sure you are using them very carefully.

    If you want to save your parameters, here is the code (in the previous code, ParamSeparator = ‘;’). Nothing really complicated, it just create a string with all the parameters, add the separators and finally saved them in a file.

    string strSer = "";
    LegoLight mLegoLight;
    for(int i=0; i<myLegoLight.Count; i++)
    {
        mLegoLight=(LegoLight)myLegoLight[i];
        strSer += mLegoLight.Name + ";" 
    + mLegoLight.Network.ToString() + ";"
    + mLegoLight.PosX.ToString() + ";"
    + mLegoLight.PosY.ToString() + '\r'; } File.WriteAllBytes(strDefaultDir + "\\" + strFileSetup, Encoding.UTF8.GetBytes(strSer));

    If you do it in your code, don’t forget the try catch section and make sure you do not exceed the capacity of the memory for string objects. Remember it is 1024 char in netduino. So the build string has to be smallest. If not, you’ll have to write the file by small write up to the end. You’ll need to open the file before the loop, and write each stream in the file each time and finally close the file. And again, don’t forget the try catch. You never know what can happen. And as you are designing an embedded system, it has to work and just work!

    So I hope I’ve shown you the basic method to read a setup file and save it. Nothing really complicated there. I’m just a marketing director writing code mainly in planes and testing back home Sourire

  • Laurent Ellerbach

    Reading file in .NET Microframework

    • 0 Comments

    For the one reading my articles, you know I’m developing in .NET Microframework an application to be able to switch on and off led in my Lego City. In the past post, I’ve explain how to setup a web server with HTTP, generate dynamic pages, handle parameters. And in the last one I show how to overlay 2 images and make the one on top clickable. In this article, I’ll explain how to read a file from the file system. I need this to be able to store images on an SD card for example and push them thru HTTP on the client. But I also want to have a setup file with the position of the led to display on the map.

    .NET Microframework offer basic IO with basic file system. It has to be a FAT format sitting on SD or equivalent. For the netduino, you have the netduino plus version which offers a SD card reader. And the basic IO are already implemented. So you can easily read and write a file. I have to admit I get couple of problems with SD card and have hard time to find one which was working all the time. Also, it looks like there is an hardware/firmware problem with SD card. But it’s about to be fixed. I never get too many problems to read the SD card but mainly to write on it. Here, my need is about reading and not writing.

    In the HTTP Server example, there is a good example of how to read a file and send it over HTTP. Here is the function (a bit modified from the original sample for my own purpose):

    static void SendFile(HttpListenerResponse response, string strFilePath)
     {
         FileStream fileToServe = null;
         try
         {
             fileToServe = new FileStream(strFilePath, FileMode.Open, FileAccess.Read);
             long fileLength = fileToServe.Length;
             // Once we know the file length, set the content length.
             //response.ContentLength64 = fileLength;
             // Send HTTP headers. Content lenght is ser
             Debug.Print("File length " + fileLength);
             // Now loops sending all the data.
    
             byte[] buf = new byte[BUFFER_SIZE];
             for (long bytesSent = 0; bytesSent < fileLength; )
             {
                 // Determines amount of data left.
                 long bytesToRead = fileLength - bytesSent;
                 bytesToRead = bytesToRead < BUFFER_SIZE ? bytesToRead : BUFFER_SIZE;
                 // Reads the data.
                 fileToServe.Read(buf, 0, (int)bytesToRead);
                 // Writes data to browser
                 response.OutputStream.Write(buf, 0, (int)bytesToRead);
    
                 System.Threading.Thread.Sleep(50);
                 // Updates bytes read.
                 bytesSent += bytesToRead;
             }
             fileToServe.Close();
         }
         catch (Exception e)
         {
             if (fileToServe != null)
             {
                 fileToServe.Close();
             }
             throw e;
         }
     }

    The function takes the HTTP response object and the file name of the file to send over HTTP.

    Then the code is quite simple. It first create a FileStream. And as it is well developed, you have a nice try catch Sourire. When you try to access files or resources, always use a try catch. You never know what can happen. You may have the user removing the support on where the file are like the SD card, the file may be corrupted, already access by another thread, etc.

    The file is open on readonly so if there is any other thread which want to access it also in read only, it is possible:

    fileToServe = new FileStream(strFilePath, FileMode.Open, FileAccess.Read);
    long fileLength = fileToServe.Length;

    The size of the file is stored into a variable. It will be necessary because the size of the memory in a netduino is very limited and you can’t open the file totally, put it in memory and send it as you’ll probably do a regular OS like Windows or Linux. Here, there is no operating system, no page file, and very very limited resources to only couple of kilo bytes. Yes, kilo bytes, not mega and far away giga!

    byte[] buf = new byte[BUFFER_SIZE];
    for (long bytesSent = 0; bytesSent < fileLength; )
    {
        // Determines amount of data left.
        long bytesToRead = fileLength - bytesSent;
        bytesToRead = bytesToRead < BUFFER_SIZE ? bytesToRead : BUFFER_SIZE;
        // Reads the data.
        fileToServe.Read(buf, 0, (int)bytesToRead);
        // Writes data to browser
        response.OutputStream.Write(buf, 0, (int)bytesToRead);
    
        System.Threading.Thread.Sleep(50);
        // Updates bytes read.
        bytesSent += bytesToRead;

    Reading the file will be done by slice. We are creating a buffer of the BUFFER_SIZE size. Here in netduino the maximum size is 1024. So the file will be read by slide of 1K and send over the response object. the loop is simple, it just read the file up to the end by slice of 1024 bytes.

    and to allow the system to do something else, it is paused couple of miliseconds. So be aware sending large file over HTTP in a netduino and any other .NET Microframework environment will require lot of loop like this and will take time.

    The rest of the code is just about closing the file. if you are sure your file will be less than 1K, you don’t need the loop, you’ll just need to create a buffer of the right size and read all.

    So we’ve seen the basic of reading a file in .NET Microframework. In a next post we will see how to use this to read a setup file.

  • Laurent Ellerbach

    Display overlay images in HTML and javascript with .NET Microframework

    • 1 Comments

    In my current project of lighting my Lego city, I’m working on a simple web interface that will allow thru a HTTP web page to display an image and small lamp icons on overlay. In my previous project on automate my sprinklers, I’ve implemented a HTTP web server in my netduino. It’s working like any Apache or IIS with kind of dynamic pages like ASP, php or Java. of course the implementation is much smaller and do cover only the very basic functions like GET request and sending file over.

    So as for the sprinkler project, I started with the HTTP Server example provided in the .NET Microframework SDK. I’ve removed what I did not need (same as for the Sprinkler project) and added couple of features like conversion, GET parameter management. Now I have the base, I was looking at a way to display images on overlap. my HTML bases are quite old, last time I did a page by hand was for the sprinkler project but not really with images. So of course, I remember the <img> tag and the map attribute to create an image that can bi clicked in multiple areas but that was not really what I wanted. I wanted multiple real images to be displayed on top of each other and having the ability to click on them.

    I rapidly found the <span> tag which allow to display anything on anyplace on top of HTML code. So it was looking perfect for my usage. The way to use it is to create an area and place HTML code inside with a position on the page. As an example:

    <span style='position:
    absolute;margin-left:158px; margin-top:59px; width:55px;
    height:44px; top:20px; left:50px;'><a href="/"><img border=0 width=55 height=44
    src="lampoff.png"></a></span>
    

    This span will be positioned in an absolute position on the page, starting from 158 pixels from the left side of the page and 59 from the top. Then you have to add another 20 pixels from the top and 50 from the left. The size of this span will be 55 pixels width and 44 pixels height. And it will contain an <a> tag with an image. The size of the image is 55 pixels width and 44 pixels height. the question you may ask is why is the span control taking 2 parameters for each position? one called margin-left + left and for vertical positioning margin-top + top. So good question Sourire the idea there is to allow to position first the span based on a control on the page and then offer the possibility to add an offset. the top/left is the first positioning and the margin-top/margin-left the second one. You want a real example? OK, so lets go with my final page which looks like this:

    image

    As you can see, I’ve positioned some lamps on the main image. And on top of the image there is some text. Imagine than in my code, I want to add more text before, of change the font size. It will change the position of the main picture. So the position of the lamp icons will change too. If I hard code the position of those lamp icons with absolute numbers, I’ll have to change all of them if I do a modification on the page.

    Now, If I can get dynamically the position of the main image and then use the possibility to use the margin to adjust the position on the main image, the only thing I have to care of is really the position on the picture. Well, the bad news there is that in HTML there is no other way than doing javascript to get a position of an object. So I had to code in javascript, 2 functions. 1 which will give me the absolute top position of the image and one for the left position. I have to admit I did not write javascript for such a long time… And I also have to admit, it’s not a language I like very much. No strong typing, no real way to debug correctly, no real language structure and less productivity than with languages like C#, VB, Java, C/C++. But I did it, and here is the result:

    <script langague="Javascript">
            // function to return the absolute Top and Left position
            function findTop(iobj) { ttop = 0; while (iobj) 
    { ttop += iobj.offsetTop; iobj = iobj.offsetParent; }
    return ttop; } function findLeft(iobj) { tleft = 0; while (iobj)
    { tleft += iobj.offsetLeft; iobj = iobj.offsetParent; }
    return tleft; } //to use it if the id of your image is MyImage //findTop(document.all.MyImage); </script>

    The function findTop will take the object you want the top position in argument. In HTML you can have imbricated objects so you have to take care of this to get the real position of an object. So I did a very simple recursive loop to sum the top position of all the parents objects up to the point there won’t be any object. And I simply return the sum of those positions. I did the exact same function for the left position. Now question is: how to use it? well, that’s very simple Sourire Taking the previous example, it will be:

    <span style='position:
    absolute;margin-left:158px; margin-top:59px; width:55px;
    height:44px; top:findTop(document.all.MyImage); 
    left:findLeft(document.all.MyImage);'><a href="/">
    <
    img border=0 width=55 height=44 src="lampoff.png"></a></span>

    So rather than have a number after the left and top attributes, I just call the functions. It assume that the name of the picture is MyImage. To give a name to an object, just use the id attribute:

    <img alt="Map of the city" id=MyImage src="ville.jpg" />
    

    and that’s it! the overall code for the page I generate automatically looks like:

    <HTML><BODY>netduino Lego City
    <p>HTTP Method: GET<br>
    Requested URL: "/default.aspx?id=0;lg=True<br>
    HTTP Version: 1.1"<p>
    <
    script langague="Javascript"> // You don't need to worry about this function findTop(iobj) { ttop = 0; while (iobj)
    { ttop += iobj.offsetTop; iobj = iobj.offsetParent; }
    return ttop; } function findLeft(iobj) { tleft = 0; while (iobj)
    { tleft += iobj.offsetLeft; iobj = iobj.offsetParent; }
    return tleft; } </script> <p> Click the lamp to switch on or off </p><span style='position:absolute;margin-left:158;
    margin-top:59;width:26px;height:45px; top:findTop(document.all.MyImage);
    left:findLeft(document.all.MyImage);'>
    <
    a href='/default.aspx?id=0;lg=False'>
    <
    img border=0 width=26 height=45 src="/WINFS/lampon.png"></a></span>
    <
    span style='position:absolute;margin-left:208;
    margin-top:300;width:26px;height:45px; top:findTop(document.all.MyImage);
    left:findLeft(document.all.MyImage);'>
    <
    a href='/default.aspx?id=1;lg=True'>
    <
    img border=0 width=26 height=45 src="/WINFS/lampoff.png"></a></span>
    <
    span style='position:absolute;margin-left:10;
    margin-top:10;width:26px;height:45px; top:findTop(document.all.MyImage);
    left:findLeft(document.all.MyImage);'>
    <
    a href='/default.aspx?id=2;lg=True'>
    <
    img border=0 width=26 height=45 src="/WINFS/lampoff.png"></a></span>
    <
    span style='position:absolute;margin-left:700;
    margin-top:550;width:26px;height:45px; top:findTop(document.all.MyImage);
    left:findLeft(document.all.MyImage);'>
    <
    a href='/default.aspx?id=3;lg=True'>
    <
    img border=0 width=26 height=45 src="/WINFS/lampoff.png"></a></span>
    <
    img alt="" src="/WINFS/ville.jpg" /></p></BODY></HTML>

    The /WINFS/ path is due to the fact I was running this sample thru the emulator. If you run it on the netduino board, then the SD path is /SD/.

    So I have created all what I need to display an image, put some other pictures as overlap, have the possibility to click on them. Now the next step is about generating dynamically this page from the netduino which I did and I will post explanations in a next post. Of course, there is the possibility to do all this with CSS. It’s working exactly the same way. My need is very simple so I won’t use CSS there but maybe to make my page very sexy in the future. Enjoy this code and post written in a plane Rire

  • Laurent Ellerbach

    Lighting my Lego city using .NET Microframework

    • 4 Comments

    Now I have created a software to pilot sprinklers, I want to be able to pilot my Lego city and light it. I know my sprinkler project is not over as I still need to work on the hardware. I will do it over the winter and try to find someone to help me. This new project looks simpler for me as it will basically only be couple of led. So it can be directly plugged to the netduino board.

    I have quite a big Lego city as you can see in this picture with 2 trains, a modern city, an old city, an airport, couple of rail stations.

    For those who may not have guess, I’m a Lego fan, I have more than 650 official Lego sets from 1970+ to now. Not all are build, some are just used for spare parts to build other kind of constructions. And I have also hundreds of kilos of brick at home which allow me to build whatever I want. You can have a look at part of the collection here.

    Same as for the sprinkler project, the idea is to be able to switch some part on automatically, at night for example, and switch them on and off also manually. In order to reuse the work I’ve done, I will create a similar project with and http web server (like IIS or Apache running on Windows or Linux), dynamic pages (like ASP.NET, php or Java) with parameters. I’ve already develop a web server I will be able to reuse and the management for dynamic input.

    My idea this time is to be able to display a web page with pictures of the city and specific points on the pictures that will represent the light to switch on and off. clicking on them will change the color of the points and switch the light accordingly.

    In a longer term, I will try to pilot also the train lights and the rail switch. That will need a bit more electronic but is very easy to do in term of code. So probably that the code will exist before the electronic as for the sprinkler project. I will try also in this project to use the SD card to store the picture of the city and the points coordinate to be displayed. So a kind of setup file. I’ve already try to play with the SD card but with limited success. I don’t know from where the problem is coming from. I use couple of different cards and I always get errors but never the same. So I think the problem is coming from the hardware.

    So let see where this project will go Sourire

  • Laurent Ellerbach

    Creating and launching timer in .NET Microframework

    • 1 Comments

    In previous posts, I had the occasion to show how to implement a web server using HTTP and handling web request (in my example GET requests) with parameters URL like in a real Windows or Linux server running Internet Information Server (IIS) or Apache with a generated HTML page like for ASP.NET, PHP or Java. Of course in couple of Kilo bits of memory, you just can’t do the same as IIS or Apache. Of course, security is very limited, capacity to cache non existent and many functions does just not exist! But at least you can do what you want and you just can focus on creating web page by hands with real C# code using the standard HTML language Sourire for those of my age who have started to write web pages in 1993 or so remember that it’s not very complicated and notepad was your best friend. Youngest one using tools like Visual Studio, Eclipse or others just don’t know Clignement d'œil Ok, I’m probably a bit polemic there but they may be less comfortable doing it than people of my age or people who developed couple of ISAPI filters.

    So read first this post on the web server implementation, then how to setup the time and date, this one on how to generate a calendar then this one on how to create programs. All done? Good! now, we will create couple of timers to launch the sprinklers. the good news is that in .NET Microframework, there is all what you need to do that. the only thing you have to do is to add a line like that in your initialization phase. I’ve added it in the StartHttpServer function:

    Timer MyTimer = new Timer(new TimerCallback(ClockTimer_Tick), null, 30000, 30000);

    So we have created a Time object that will call a function ClockTimer_Tick every 30 seconds in 30 seconds. The ClockTimer_Tick function looks like:

    static void ClockTimer_Tick(object sender)
    {
        DateTime now = DateTime.Now;
        Debug.Print(now.ToString("MM/dd/yyyy hh:mm:ss"));
        //do we have a Sprinkler to open?
        for (int i = 0; i < SprinklerPrograms.Count; i++)
        { 
            SprinklerProgram MySpr = (SprinklerProgram)SprinklerPrograms[i];
            if ((now.Year == MySpr.DateTimeStart.Year) && (now.Month == MySpr.DateTimeStart.Month) && (now.Day == MySpr.DateTimeStart.Day)
                && (now.Hour == MySpr.DateTimeStart.Hour) && (now.Minute >= MySpr.DateTimeStart.Minute))
            { // this is the time to open a sprinkler
                Debug.Print("Sprinkling " + i + " date time " + now.ToString("MM/dd/yyyy hh:mm:ss"));
                Springlers[MySpr.SprinklerNumber].Manual = false;
                Springlers[MySpr.SprinklerNumber].Open = true;
                // it will close all sprinkler in the desired time of sprinkling. Timer will be called only once.
                Timer MyTime = new Timer(new TimerCallback(ClockStopSprinkler), null, (int)MySpr.Duration.Ticks/10000, 0);
                SprinklerPrograms.RemoveAt(i);
            }
        }
    }            
    

    It starts by creating a DateTime object that take the actual date time. It will be used to see if there are programs to launch. The loop just go thru all the programs. Programs are contained into an ArrayList SprinklerPrograms and contains objects that are SprinklerProgram. All this is describe in this post.

    So what it does is just testing if the program is the right year, right month, right day, right hour and if the minute to start is pasted. As the function is called every 30 seconds, a sprinkler will be started during the minute it was planned. To open the sprinkler, the Sprinkler function Open from the Sprinkler class is called. The code for the class looks like:

    static private OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
    public class Sprinkler
    {
        private bool MySpringlerisOpen = false;
        private int MySprinklerNumber;
        private bool MyManual = false;
    
        public Sprinkler(int SprNum)
        {
            MySprinklerNumber = SprNum;
            //need hardware here
        }
    
        // open or close a sprinkler
        public bool Open
        {
            get { return MySpringlerisOpen; }
            set
            {
                MySpringlerisOpen = value;
                //do harware here
                if (MySpringlerisOpen)
                    led.Write(true);
                else
                    led.Write(false);
            }
        }
        public bool Manual
        {   get { return MyManual; }
            set { MyManual = value; }
        }
            
    
        //read only property
        public int SprinklerNumber
        {
            get { return MySprinklerNumber; }
        }
    }

    This class does not include the real hardware work. It just light on the embedded led when a sprinkler is open and switch it of when closed. As there are multiple sprinklers sharing the same internal led, the led object as to be declare as a static object in the main class to be kept alive and shared by all the sprinklers.

    Here come the specific of the netduino. The internal led is an OutputPort and use a specific port. It can be found in the definition of the enum:

    public const Cpu.Pin ONBOARD_LED = 55;

    The sprinkler class contains the number of the sprinkler, if it is open and if it is a manual open or an automatic opening. The only way to create a sprinkler class is to give it a number. It is done as behind there will be some hardware initialization and all objects will need to be unique. When I’ll have done the hardware work, I’ll come back to post the necessary code Clignement d'œil

    So back to the launch of the program, the code will set the opening to manual and open it in the sprinkler:

    Springlers[MySpr.SprinklerNumber].Manual = false;
    Springlers[MySpr.SprinklerNumber].Open = true;
    // it will close all sprinkler in the desired time of sprinkling. Timer will be called only once.
    Timer MyTime = new Timer(new TimerCallback(ClockStopSprinkler), null, (int)MySpr.Duration.Ticks/10000, 0);
    SprinklerPrograms.RemoveAt(i);

    Then it will create a new timer that will be called after the duration specified to sprinkle. The Ticks member return a number of ticks. 10000 ticks represent 1 second. So the ClockStopSprinkler will be called after the right duration and only 1 time. The function is quite simple, it just reset all sprinklers to close. I’ve decided to do this as I feel it is much more secure. I just can’t run anyway 2 sprinklers at the same time as I don’t have enough water pressure to run more than once a time.

    static void ClockStopSprinkler(object sender)
    {
        Debug.Print("Stop sprinkling " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss"));
        //close all sprinklers if automatic mode
        for (int i = 0; i < NUMBER_SPRINKLERS; i++)
        {
            if (Springlers[i].Manual == false)
                Springlers[i].Open = false; 
        }
    }

    If the mode is manual, no reason to stop a sprinkler. The manual mode can be run in another page. I’ll describe this into a future post.

    So quite easy code here to open and close the sprinklers when needed. Just use simple timers! I hope you’ve also enjoyed this post. Coding makes you feel better Sourire and that’s just a marketing guy telling you this Clignement d'œil

  • Laurent Ellerbach

    Program a date time and duration for a sprinkler in .NET Microframework and netduino

    • 0 Comments

    In my previous posts, I’ve explained that I wanted to be able to program sprinklers in my garden day by day thru the Internet when I was not at home to save energy and water. No need to use a sprinkler when it has rained all night but need to use them when it has been very dry and sunny all day and no forecast for rain in the coming days. So I choose to use a netduio, it’s a system on chip simple board, using no OS so no Windows, no Linux, no DOS or any anything else than .NET Microframework (in one word and not Micro framework). I use C# to develop on it but it’s also possible since recently to use Visual Basic (VB.NET).

    So to summarize, after couple of post, I’ve created a web server to handle http requests like any Windows, Linux server running IIS, Apache or any other web server and being able to handle request in the URL like for ASP.NET, PHP or Java, see this post. I already manage to display a calendar. So now it’s time to add programs!

    As for the calendar, I start by decoding the URL, this time URL looks like program.aspx?year=2011;month=9;day=10;hour=21;minute=2;duration=20;spr=0

    There are 7 parameters. I pass to the URL the year, month, day, start hour, start minute and duration of the program on a specific sprinkler. I made it clear in the parameters to be understandable by a human Sourire In the production version and if I need to get more free space and to improve performance, I’ll reduce the length of the parameters name and URL name. I will save footprint but also time processing and bandwidth when generating the URL. As I did program with clean code, I just need to change couple of strings in a single class for the overall code. All is explained in a previous post.

    I have decided (that’s the chance to be the developer Clignement d'œil) to reset a program when I set the duration to 0. In this case, I just need to have a valid year, month and sprinkler number. So this code will do the job:

    if (intDuration == 0)
    {
        for (int i = 0; i < SprinklerPrograms.Count; i++)
        {
            // case the date already exist => update the hour, minute and duration for the given Sprinkler
            if ((intYear == ((SprinklerProgram)SprinklerPrograms[i]).DateTimeStart.Year)
                && (intMonth == ((SprinklerProgram)SprinklerPrograms[i]).DateTimeStart.Month)
                && (intDay == ((SprinklerProgram)SprinklerPrograms[i]).DateTimeStart.Day)
                && (intSprinklerNumber == ((SprinklerProgram)SprinklerPrograms[i]).SprinklerNumber))
            {
    
                SprinklerPrograms.RemoveAt(i);
                strResp += "Deleting Sprinkler " + intSprinklerNumber + " for " + intYear + " " 
    + intMonth + " " + intDay + ". <br>"; strResp += "<a href='/" + MyParamPage.pageSprinkler + "'>Back to main page</a>"; strResp = OutPutStream(response, strResp); } } }
    As you can see, there a SprinklerPrograms variable. So what is this? It’s an array define like this:
    public static ArrayList SprinklerPrograms = new ArrayList()

    Good news with .NET Microframework is that like for the real .NET framework or even Java or PHP, there is a minimum to manage array and lists. This ArrayList is smart enough to take any object in the array, up to 1024 elements (that’s the limit of netduino platform). And there is function to add, remove, find specific objects.

    intYear == ((SprinklerProgram)SprinklerPrograms[i]).DateTimeStart.Year

    I do test to see if there is an existing element with the same date (year, month, day) and sprinkler. And If I found one, I just remove it. If nothing if found, nothing will be done and no message display. In a normal usage, this page is called from other page. Of course, as it’s just a web page, it can be called by anyone with crappy elements in the URL. It’s just a choice as in a normal usage, it should not happen.

    I also cast an element of the ArrayList to a SprinklerProgam class. This class is created to store a single program for a sprinkler.

    public class SprinklerProgram
    {
        private DateTime myDateTimeStart;
        private TimeSpan myDuration;
        private int mySprinklerNumber;
    
        public SprinklerProgram(DateTime mDT, TimeSpan mTS, int mSN)
        {
            myDateTimeStart = mDT;
            myDuration = mTS;
            mySprinklerNumber = mSN;
        }
    
        public DateTime DateTimeStart
        {
            get { return myDateTimeStart; }
            set { myDateTimeStart = value; }
        }
        public TimeSpan Duration
        {
            get { return myDuration; }
            set { myDuration = value;  }
        }
    
        public int SprinklerNumber
        {
            get { return mySprinklerNumber; }
            set { mySprinklerNumber = value; }
        }
    
    }

    Nothing really complicated there, it’s just about storing the start date, time, duration and sprinkler number. And I do test the year, month, day and sprinkler with a casting.

    So next, the idea is to see if the date and time are valid, create a DateTime object and check if it is today or not. If it is today, only part of the time will be displayed as the idea is not to be able to program a past day. Then after couple of test, either there is a program existing for a sprinkler and it just need to be updated, either it has to be created.

    else if ((intYear > 1900) && (intMonth > 0) && (intMonth < 13) && (intHour >= 0) 
    && (intHour < 24) && (intMinute >= 0) && (intMinute < 60)) { MyDate = new DateTime(intYear, intMonth, intDay, intHour, intMinute, 0); bool TodayIsToday = false; if ((intYear == tmpNow.Year) && (intMonth == tmpNow.Month) && (intDay == tmpNow.Day)) TodayIsToday = true; // Is the program in the future or today! if ((MyDate >= tmpNow) || (TodayIsToday)) { bool updated = false; // is the duration the right one? with an existing sprinkler? if ((intDuration > 0) && (intDuration < 1440) && (intSprinklerNumber >= 0)
    && (intSprinklerNumber < NUMBER_SPRINKLERS)) { MySpanDuration = new TimeSpan(0, intDuration, 0); // is it a new program for a day a just an update (only 1 program per day available) for (int i = 0; i < SprinklerPrograms.Count; i++) { // case the date already exist => update the hour, minute and duration for the given Sprinkler if ((MyDate.Year == ((SprinklerProgram)SprinklerPrograms[i]).DateTimeStart.Year) && (MyDate.Month == ((SprinklerProgram)SprinklerPrograms[i]).DateTimeStart.Month) && (MyDate.Day == ((SprinklerProgram)SprinklerPrograms[i]).DateTimeStart.Day) && (intSprinklerNumber == ((SprinklerProgram)SprinklerPrograms[i]).SprinklerNumber) && (updated == false)) { ((SprinklerProgram)SprinklerPrograms[i]).DateTimeStart = MyDate; ((SprinklerProgram)SprinklerPrograms[i]).Duration = MySpanDuration; updated = true; strResp += "Updating Sprinkler " + intSprinklerNumber + " for "
    + MyDate.ToString("yyyy MMM d") + " to start at " + MyDate.ToString("HH:mm") + " and duration of "
    + MySpanDuration.Minutes + " minutes. <br>"; strResp = OutPutStream(response, strResp); } } // does not exist, then will need to create it if (updated == false) { SprinklerPrograms.Add(new SprinklerProgram(MyDate, MySpanDuration, intSprinklerNumber)); strResp += "Adding Sprinkler " + intSprinklerNumber + " for "
    + MyDate.ToString("yyyy MMM d") + " to start at " + MyDate.ToString("HH:mm") + " and duration of "
    + MySpanDuration.Minutes + " minutes. <br>"; updated = true; strResp = OutPutStream(response, strResp); } } if (updated == false) { //create a timeline to select hour and minutes strResp += "<br>Select your starting time.<br>"; strResp += "<table border=1>"; //in case it's Today, allow programation for the next hour int StartTime = 0; if (TodayIsToday) StartTime = intHour+1; strResp = OutPutStream(response, strResp); for (int i = StartTime; i < 24; i++) { for (int j = 0; j < 2; j++) { strResp += "<tr><td>"; DateTime tmpDateTime = new DateTime(intYear, intMonth, intDay, i, j * 30, 0); strResp += tmpDateTime.ToString("HH:mm"); strResp += "</td><td>"; strResp += "<a href='" + MyParamPage.pageProgram + ParamStart
    + MyParamPage.year + ParamEqual + tmpDateTime.Year + ParamSeparator + MyParamPage.month + ParamEqual
    + tmpDateTime.Month + ParamSeparator + MyParamPage.day + ParamEqual + tmpDateTime.Day + ParamSeparator
    + MyParamPage.hour + ParamEqual + i + ParamSeparator + MyParamPage.minute + ParamEqual + j * 15
    + ParamSeparator + MyParamPage.duration + ParamEqual + "20" + ParamSeparator + MyParamPage.spr
    + ParamEqual + intSprinklerNumber + "'>20 minutes</a>"; strResp += "</td>"; strResp = OutPutStream(response, strResp); strResp = "</tr>"; } } strResp += "</table>"; } else { // something has been updated so redirect to the main page strResp += "<a href='/" + MyParamPage.pageSprinkler + "'>Back to main page<a><br>"; strResp += "<a href='/" + MyParamPage.pageCalendar + ParamStart + MyParamPage.year
    + ParamEqual + intYear + ParamSeparator + MyParamPage.month + ParamEqual + intMonth + ParamSeparator
    + MyParamPage.spr + ParamEqual + intSprinklerNumber + "'>Proram this month</a>"; strResp = OutPutStream(response, strResp); } } else { strResp += "Date must be in the future"; } }

    In the case, a new program has to be added, the code is really simple as we are using an ArrayList:

    SprinklerPrograms.Add(new SprinklerProgram(MyDate, MySpanDuration, intSprinklerNumber));

    Just use the Add member to add a new object. As explain, the only object that are added are SprinklerProgam. In the case, it has to be updated, it just search the list, compare the dates and update the information in the object for hour, minute and duration.

    And finally, if nothing has been update, it display a simple table containing the start hour and the duration. Here by default, it’s 20 minutes but it can of course be different. It’s hard coded here as an example. Best way is to use a constant of a variable that can be set in a different page.

    In case an update or an add has been done, it displays the ability to return to the main page or program another day. The smart thing with this code is that this page just point on itself. I mean by this that this page either display the list of hour and duration or either add, remove or update the information regarding a program. So it is quite efficient as many tests has already be done and are common anyway.

    And last but not least, when a date is not correct, or a time or anything else, it just display a gentle and simple message telling something is wrong. No real benefit here to do more detailed as it should not be displayed when clicking on the normal link. It may only happen when URL are type like this or called from another code or generated by another code.

    Now we have programs for sprinkler the question is how we will be able to launch those programs! See the answer in the next post Sourire and enjoy .NET Microframework! As for the last post, my code is far to be perfect, I’m just a marketing director writing code! Code is life Sourire

  • Laurent Ellerbach

    Displaying a calendar in a web page using .NET Microframework

    • 0 Comments

    As I want to program sprinklers I need to be able to select a date. In my previous posts, I’ve already explained how I’ve setup a Web Server using .NET Microframework, my netduino with Visual Studio using C# and all the magic of code Rire. My implementation allow me to pass parameters in a URL. And I want to create a page to display a calendar. Using PHP, Java or ASP.NET is so easy as you don’t have to do anything, just call a date time picker class, object, widget or whatever extension it can be. Here, there is just nothing Triste

    So all is to be done manually. and it’s not very easy as we will need to determine the number of day in a month, display them in a nice table, add links on the days to call another page. So quite a bit of work. And also the need to go back in the past HTML docs… Well, lets start somewhere Sourire I choose to start with a function to return the number of days in a month. I did not find it in the framework.

    static int NumberDaysPerMonth(int Month, int Year)
            {
                if ((Month <= 0) || (Month >= 13))
                    return 0;
                if ((Year % 4 == 0 && Year % 100 != 0) || Year % 400 == 0)
                {
                    int[] NbDays = new int[] {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
                    return NbDays[Month-1];
                } else {
                    int[] NbDays = new int[] {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
                    return NbDays[Month-1];
            }

    Basically there are year with month of February that change every 4 years, with the exception of century years and every 400 years. In this case, you have 29 days, in all other cases only 28. The rest of the months stay constant. To be very efficient, I’ve just created tables of 12 elements representing each month, and I return the number of days. I’ll be very proud if my netduino board will be still used to pilot my sprinklers in the next century… but anyway, it’s always better to have as clean code as possible!

    In my previous post, you’ll find the first part of the code for this function. The first part analyze the URL and get the year and month of the sprinkler to program.

    So here is the second part of the code. Pretty long but I’ll explain all parts later on:

        string strResp = "<HTML><BODY>netduino sprinkler<p>";
    
        // Print requested verb, URL and version.. Adds information from the request.
        strResp += "HTTP Method: " + request.HttpMethod + "<br> Requested URL: \"" + request.RawUrl +
            "<br> HTTP Version: " + request.ProtocolVersion + "\"<p>";
        response.ContentType = "text/html";
        response.StatusCode = (int)HttpStatusCode.OK;
        if ((intMonth > 0) && (intMonth<13) && (intYear > 2009) && (intYear <2200))
        {
            //are we in the future?
            DateTime tmpDT = new DateTime(intYear, intMonth, 1);
            DateTime tmpNow = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            if (tmpDT >= tmpNow)
            {
    
                for (int i = 0; i < NUMBER_SPRINKLERS; i++)
                    if (i != intSprinkler)
                        strResp += "Calendar for <a href='" + MyParamPage.pageCalendar + ParamStart + MyParamPage.year + ParamEqual + intYear + ParamSeparator + MyParamPage.month + ParamEqual + intMonth + ParamSeparator + MyParamPage.spr + ParamEqual + i + "'>sprinkler " + i + "</a><br>";
                strResp = OutPutStream(response, strResp); 
                strResp += "Month: " + intMonth + "<br>";
                strResp += "Year: " + intYear + "<br>";
                // Display some previous and next.
                // is it the first month? (case 1rst of January of the year to program but in the future year so month =12 and 1 less year)
                if ((intMonth == 1) && (intYear > DateTime.Now.Year))
                    strResp += "<a href='" + MyParamPage.pageCalendar + ParamStart + MyParamPage.year + ParamEqual + (intYear - 1) + ParamSeparator + MyParamPage.month + ParamEqual + "12" + ParamSeparator + MyParamPage.spr + ParamEqual + intSprinkler + "'>Previous month</a>&nbsp&nbsp&nbsp";
                else if ((intMonth > DateTime.Now.Month) && (intYear == DateTime.Now.Year)) // (other cases
                    strResp += "<a href='" + MyParamPage.pageCalendar + ParamStart + MyParamPage.year + ParamEqual + intYear + ParamSeparator + MyParamPage.month + ParamEqual + (intMonth - 1) + ParamSeparator + MyParamPage.spr + ParamEqual + intSprinkler + "'>Previous month</a>&nbsp&nbsp&nbsp";
                else if(intYear > DateTime.Now.Year)
                    strResp += "<a href='" + MyParamPage.pageCalendar + ParamStart + MyParamPage.year + ParamEqual + intYear + ParamSeparator + MyParamPage.month + ParamEqual + (intMonth - 1) + ParamSeparator + MyParamPage.spr + ParamEqual + intSprinkler + "'>Previous month</a>&nbsp&nbsp&nbsp";
                // next month //case december
                strResp = OutPutStream(response, strResp); 
                if (intMonth == 12)
                    strResp += "<a href='" + MyParamPage.pageCalendar + ParamStart + MyParamPage.year + ParamEqual + (intYear + 1) + ParamSeparator + MyParamPage.month + ParamEqual + "1" + ParamSeparator + MyParamPage.spr + ParamEqual + intSprinkler + "'>Next month</a>";
                else // (other cases
                    strResp += "<a href='" + MyParamPage.pageCalendar + ParamStart + MyParamPage.year + ParamEqual + intYear + ParamSeparator + MyParamPage.month + ParamEqual + (intMonth + 1) + ParamSeparator + MyParamPage.spr + ParamEqual + intSprinkler + "'>Next month</a>";
                // display and build a calendar :)
                strResp += "<p>";
                strResp += "<table BORDER='1'><tr>";
                for (int i = 0; i < days.Length; i++)
                    strResp += "<td>" + days[i] + "</td>";
                strResp += "</tr><tr>";
                int NbDays = NumberDaysPerMonth(intMonth, intYear);
                DateTime dt = new DateTime(intYear, intMonth, 1);
                for (int i = 0; i < (int)dt.DayOfWeek; i++)
                    strResp += "<td></td>";
                strResp = OutPutStream(response, strResp); 
                for (int i = 1; i <= NbDays; i++)
                {
                    if ((intMonth == DateTime.Now.Month) && (intYear == DateTime.Now.Year) && (i < DateTime.Now.Day))
                    { // don't add a link to program a past day
                        strResp += "<td>" + i + "</td>";
                    }
                    else
                    {
                        strResp += "<td><a href='" + MyParamPage.pageProgram + ParamStart + MyParamPage.year + ParamEqual + intYear + ParamSeparator + MyParamPage.month + ParamEqual + intMonth + ParamSeparator + MyParamPage.day + ParamEqual + i + ParamSeparator + MyParamPage.hour + ParamEqual + DateTime.Now.Hour + ParamSeparator + MyParamPage.minute + ParamEqual + DateTime.Now.Minute + ParamSeparator + MyParamPage.spr + ParamEqual + intSprinkler + "'>" + i + "</a></td>";
                    }
                    if ((i + (int)dt.DayOfWeek) % 7 == 0)
                        strResp += "</tr><tr>";
                    strResp = OutPutStream(response, strResp);
                }
                strResp += "</tr></table>";
            }
            else
            {
                strResp += "Not in the future, please select a valid month and year, <a href='calendar.aspx?Year=" + DateTime.Now.Year + ";Month=" + DateTime.Now.Month + ";Spr=" + intSprinkler + "'>click here</a> to go to the actual month";
            }
        }
        strResp += "</BODY></HTML>";
        strResp = OutPutStream(response, strResp);
    }

    The first line of code are here to create the HTML page, I use it also to show the URL and the parameters as a debugging point of view. No real rocket science there.

    Then I test if the date is in the future. I setup a maximum date for 2200. I think I can live perfectly up to this date Clignement d'œil and if needed, at this time, I’ll modify the code again Tire la langue. That said, this validation is not enough. We must know if we are in a future month or the actual or not.

    //are we in the future?
    DateTime tmpDT = new DateTime(intYear, intMonth, 1);
    DateTime tmpNow = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
    if (tmpDT >= tmpNow)

    Those 3 lines of code will give us the answer. If we are not in the future, no need to program a sprinkler. It’s quite necessary to do as the page can be called by almost anyone with almost any parameter. And the number of element is a table is limited to 1024. So no need to use unnecessary space in the memory. Embedded is about optimization. every single line of code has to have a usage. Otherwise, just remove it. If you can do something in 5 lines of code rather than 10, choose the 5 lines! And if 7 is the best compromise for speed/memory print, use the 7 lines. Resources are limited, don’t forget it. There are so limited that the strResp string value is limited to 1024 characters. And 1024 characters in HTML is reach very soon!

    I have to admit the first page I did I totally forget this limit. And guess what, first run with couple of HML worked perfectly and then it just raise an out of memory exception. And at this time, I just realize string were limited… That’s why in the code, you’ll find the following function and lines:

    private static string OutPutStream(HttpListenerResponse response, string strResponse)
            {
                byte[] messageBody = Encoding.UTF8.GetBytes(strResponse);
                response.OutputStream.Write(messageBody, 0, messageBody.Length);                 
                return "";
            }

    and the call is simple:

    strResp = OutPutStream(response, strResp);

    All what this function does is emptying the string and put it into the output stream to be displayed in the browser. As we are building our own page, it’s quite easy to know when the string will be close to 1024 characters and empty it. So you’ll see this line of code very regularly.

    The function return an empty string which I remap to the strResp string. All what the function does is convert the string into an array of bytes, and put it into the output stream and initialize again strResp to an empty string.

    I have N sprinklers to program and want to be able to change from a sprinkler to another. So the following line of code will create the right links:

    for (int i = 0; i < NUMBER_SPRINKLERS; i++)
                            if (i != intSprinkler)
                                strResp += "Calendar for <a href='" + MyParamPage.pageCalendar 
    + ParamStart + MyParamPage.year + ParamEqual + intYear + ParamSeparator + MyParamPage.month 
    + ParamEqual + intMonth + ParamSeparator + MyParamPage.spr + ParamEqual + i + "'>sprinkler " + i + "</a><br>";

    As you can see, the URL is build based on a class that returns string and couple of chars. All that is explain in a previous post.

    intYear and intMonth has been decoded from a URL like “calendar.aspx?year=2011;month=9;spr=0”. And the code generate URL like this Sourire

    Now, I want to add a “Previous” and “Next” month in my page. Again, usually using automatic component in a high level PHP, Java or ASP.NET on a Windows or Linux box is very easy. Everything is done automatically with high level framework. Here you have to do all the cases by hand. There is the case of the first month (January) where you’ll have to decrease for 1 year and change the month to 12 (December) to go on the previous month. There is the case of December where it’s the opposite to go on the next month. And as I want to allow only future current and future month, I need to make sure, I will not display any previous when it’s in the past.

    // Display some previous and next.
    // is it the first month? (case 1rst of January of the year to program but in the future year so month =12 and 1 less year)
    if ((intMonth == 1) && (intYear > DateTime.Now.Year))
        strResp += "<a href='" + MyParamPage.pageCalendar + ParamStart + MyParamPage.year + ParamEqual + (intYear - 1) + ParamSeparator + MyParamPage.month + ParamEqual + "12" + ParamSeparator + MyParamPage.spr + ParamEqual + intSprinkler + "'>Previous month</a>&nbsp&nbsp&nbsp";
    else if ((intMonth > DateTime.Now.Month) && (intYear == DateTime.Now.Year)) // (other cases
        strResp += "<a href='" + MyParamPage.pageCalendar + ParamStart + MyParamPage.year + ParamEqual 
    + intYear + ParamSeparator + MyParamPage.month + ParamEqual + (intMonth - 1) + ParamSeparator
    + MyParamPage.spr + ParamEqual + intSprinkler + "'>Previous month</a>&nbsp&nbsp&nbsp"; else if(intYear > DateTime.Now.Year) strResp += "<a href='" + MyParamPage.pageCalendar + ParamStart + MyParamPage.year + ParamEqual
    + intYear + ParamSeparator + MyParamPage.month + ParamEqual + (intMonth - 1) + ParamSeparator
    + MyParamPage.spr + ParamEqual + intSprinkler + "'>Previous month</a>&nbsp&nbsp&nbsp"; // next month //case december strResp = OutPutStream(response, strResp); if (intMonth == 12) strResp += "<a href='" + MyParamPage.pageCalendar + ParamStart + MyParamPage.year + ParamEqual
    + (intYear + 1) + ParamSeparator + MyParamPage.month + ParamEqual + "1" + ParamSeparator
    + MyParamPage.spr + ParamEqual + intSprinkler + "'>Next month</a>"; else // (other cases strResp += "<a href='" + MyParamPage.pageCalendar + ParamStart + MyParamPage.year + ParamEqual
    + intYear + ParamSeparator + MyParamPage.month + ParamEqual + (intMonth + 1) + ParamSeparator
    + MyParamPage.spr + ParamEqual + intSprinkler + "'>Next month</a>";

    OK, we do have our “Previous” and Next” links now Sourire. Not rocket science code but efficient and easy to write. Let go for the calendar itself!

    // display and build a calendar :)
    strResp += "<p>";
    strResp += "<table BORDER='1'><tr>";
    for (int i = 0; i < days.Length; i++)
        strResp += "<td>" + days[i] + "</td>";
    strResp += "</tr><tr>";
    int NbDays = NumberDaysPerMonth(intMonth, intYear);
    DateTime dt = new DateTime(intYear, intMonth, 1);
    for (int i = 0; i < (int)dt.DayOfWeek; i++)
        strResp += "<td></td>";
    strResp = OutPutStream(response, strResp); 
    for (int i = 1; i <= NbDays; i++)
    {
        if ((intMonth == DateTime.Now.Month) && (intYear == DateTime.Now.Year) && (i < DateTime.Now.Day))
        { // don't add a link to program a past day
            strResp += "<td>" + i + "</td>";
        }
        else
        {
            strResp += "<td><a href='" + MyParamPage.pageProgram + ParamStart + MyParamPage.year 
    + ParamEqual + intYear + ParamSeparator + MyParamPage.month + ParamEqual + intMonth + ParamSeparator
    + MyParamPage.day + ParamEqual + i + ParamSeparator + MyParamPage.hour + ParamEqual + DateTime.Now.Hour
    + ParamSeparator + MyParamPage.minute + ParamEqual + DateTime.Now.Minute + ParamSeparator
    + MyParamPage.spr + ParamEqual + intSprinkler + "'>" + i + "</a></td>"; } if ((i + (int)dt.DayOfWeek) % 7 == 0) strResp += "</tr><tr>"; strResp = OutPutStream(response, strResp); } strResp += "</tr></table>";

    In order to display a month, we will need 7 columns and as many row as necessary. We will only display the number of the day where it has to be. So the code starts with creating a table with a simple border.

    strResp += "<table BORDER='1'><tr>";
    for (int i = 0; i < days.Length; i++)
        strResp += "<td>" + days[i] + "</td>";
    strResp += "</tr><tr>";

    The days table is the following:

    static string[] days = new string[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday"
    , "Friday", "Saturday" };

    Of course, you can get this from resources, make it localizable, etc. In my case, English will perfectly work for me and I need to use a minimum space in the netduino Sourire The DateTime class has an interesting feature as it gives you the day of the week you are.

    int NbDays = NumberDaysPerMonth(intMonth, intYear);
    DateTime dt = new DateTime(intYear, intMonth, 1);
    for (int i = 0; i < (int)dt.DayOfWeek; i++)
        strResp += "<td></td>";
    strResp = OutPutStream(response, strResp); 

    Used as in the example, it will give the first day of the month. And we know that we can fill the first values of the table with nothing as we are not at the first day. So as an example, if the first day is Monday, it will fill Sunday with nothing else than the <td></td>. DayOfWeek will be equal to 1. If it’s a Saturday, it will return 7 and the 6 first cells of the table will just be empty <td></td>. Now, we just can doo a loop up to the number of days in the month and don’t forget to add a <tr> tag after every Saturday Sourire

    for (int i = 1; i <= NbDays; i++)
    {
        if ((intMonth == DateTime.Now.Month) && (intYear == DateTime.Now.Year) && (i < DateTime.Now.Day))
        { // don't add a link to program a past day
            strResp += "<td>" + i + "</td>";
        }
        else
        {
            strResp += "<td><a href='" + MyParamPage.pageProgram + ParamStart + MyParamPage.year + ParamEqual + intYear + ParamSeparator + MyParamPage.month + ParamEqual + intMonth + ParamSeparator + MyParamPage.day + ParamEqual + i + ParamSeparator + MyParamPage.hour + ParamEqual + DateTime.Now.Hour + ParamSeparator + MyParamPage.minute + ParamEqual + DateTime.Now.Minute + ParamSeparator + MyParamPage.spr + ParamEqual + intSprinkler + "'>" + i + "</a></td>";
        }
        if ((i + (int)dt.DayOfWeek) % 7 == 0)
            strResp += "</tr><tr>";
        strResp = OutPutStream(response, strResp);
    }
    strResp += "</tr></table>";

    There is still a case here where we won’t add a link to program a past day when it’s the current month as we only allow program for future dates and not past dates. Of course, there will be an interesting case for the actual day but we will see that in a coming post. Pure HTML guys who want to validate the result code in a special HTML validator will tell me that I should add couple of more <td></td> to finalize the table. Fact is that it’s not really needed as all browsers interpret it correctly. Couple of lines of code less Sourire

    Rest of code is there just to empty the strResp buffer and output the stream in the response object. Final result looks like this (if we are the 7th of September 2011):

    netduino sprinkler 

    HTTP Method: GET
    Requested URL: "/calendar.aspx?year=2011;month=9;spr=0
    HTTP Version: 1.1"

    Calendar for sprinkler 1
    Calendar for sprinkler 2
    Month: 9
    Year: 2011
    Next month

    Sunday Monday Tuesday Wednesday Thursday Friday Saturday
    1 2 3
    4 5 6 7 8 9 10
    11 12 13 14 15 16 17
    18 19 20 21 22 23 24
    25 26 27 28 29 30

    And of course you can navigate with the “previous” (not here as it’s the current month) and “next” month links. When clicking on a day, it calls a page to program a sprinkler. We will see this in a next post.

    I hope you’ve enjoy this post. I did enjoy a lot creating this calendar. It’s so strange to do it by hand! As usual, feedback welcome, I’m just a marketing director doing code Sourire

  • Laurent Ellerbach

    Setup a time and date using .NET Microframework

    • 0 Comments

    In theory, .NET Microframework implement a class to get the time from a time server. It never worked for me using my netduino board. You’ll find more info on this board in my previous post. And also I’ve implemented a Web Server with the possibility to decrypt a parameter URL.

    netduino has no BIOS and no way when it’s off to keep a date and time. So each time you boot it, you have to setup the time and date yourself. Normally in order to do that, you can use the TimeService class.It looks like it’s not implemented on this board. The forum is very active and very useful. So as I needed the right time on my board and not in a very precise way (second and even minutes were ok), I get the idea of requesting a web page on my server that will return a date and time value.

    In terms of code on an IIS server, it’s very very very very simple:

    <%@ Page Title="Home Page" Language="C#" 
        CodeBehind="Default.aspx.cs" Inherits="DateHeure._Default" %><html><head></head>
    <body><% Response.Write(DateTime.Now.ToString("u")); %></body></html>
    Nothing else is needed! the “u” formatting return a date time like “2011/09/15 15:20:30Z”. So the return code from the server will be: <html><head></head><body>2011/09/15 15:20:30Z</body></html>

    On the client side on the netduino board, I needed to have an HTTP client and then decrypt the date and time. I found the HTTP Client in the sample and just simply it. So I’ve created a function that take a URL to request the page and return a date.

    public static DateTime ReadDateTime(string url)
     {
         // Create an HTTP Web request.
         HttpWebRequest request =
             HttpWebRequest.Create(url) as HttpWebRequest;
    
         // Set request.KeepAlive to use a persistent connection. 
         request.KeepAlive = true;
    
         // Get a response from the server.
         WebResponse resp = null;
         DateTime MyDateTime = DateTime.Now;
    
         try
         {
             resp = request.GetResponse();
         }
         catch (Exception e)
         {
             Debug.Print("Exception in HttpWebRequest.GetResponse(): " +
                 e.ToString());
         }
    
         // Get the network response stream to read the page data.
         if (resp != null)
         {
             Stream respStream = resp.GetResponseStream();
             string page = null;
             byte[] byteData = new byte[1024];
             char[] charData = new char[1024];
             int bytesRead = 0;
             Decoder UTF8decoder = System.Text.Encoding.UTF8.GetDecoder();
             int totalBytes = 0;
    
             // allow 5 seconds for reading the stream
             respStream.ReadTimeout = 5000;
    
             // If we know the content length, read exactly that amount of 
             // data; otherwise, read until there is nothing left to read.
             if (resp.ContentLength != -1)
             {
    
                 Thread.Sleep(500);
                 bytesRead =
                     respStream.Read(byteData, 0, byteData.Length);
                 if (bytesRead == 0)
                 {
                     return MyDateTime;
                 }
    
                 // Convert from bytes to chars, and add to the page 
                 // string.
                 int byteUsed, charUsed;
                 bool completed = false;
                 totalBytes += bytesRead;
                 UTF8decoder.Convert(byteData, 0, bytesRead, charData, 0,
                     bytesRead, true, out byteUsed, out charUsed,
                     out completed);
                 page = page + new String(charData, 0, charUsed);
    
                 // Display the page download status.
                 Debug.Print("Bytes Read Now: " + bytesRead +
                     " Total: " + totalBytes);
    
                 page = new String(
                     System.Text.Encoding.UTF8.GetChars(byteData));
             }
    
             // Display the page results.
             Debug.Print(page);
    
             // Close the response stream.  For Keep-Alive streams, the 
             // stream will remain open and will be pushed into the unused 
             // stream list.
             resp.Close();
             if (page.Length > 0)
             {
                 int start = page.IndexOf("<body>");
                 int end = page.IndexOf("</body>");
                 if ((start >= 0) && (end >= 0))
                 {
                     String strDateHeure = page.Substring(start + 6, end - start - 7);
                     if (strDateHeure.Length > 0)
                     {
                         int year = -1;
                         int month = -1;
                         int day = -1;
                         int hour = -1;
                         int minute = -1;
                         Convert.ToInt(strDateHeure.Substring(0, 4), out year);
                         Convert.ToInt(strDateHeure.Substring(5, 2), out month);
                         Convert.ToInt(strDateHeure.Substring(8, 2), out day);
                         Convert.ToInt(strDateHeure.Substring(11, 2), out hour);
                         Convert.ToInt(strDateHeure.Substring(14, 2), out minute);
                         if ((year != -1) && (month != -1) && (day != -1) && (hour != -1) && (minute != -1))
                             MyDateTime = new DateTime(year, month, day, hour, minute, 0);
                     }
                 }
             }
         }
    
         return MyDateTime;
     }
    First part of the code is the one form the sample. I’ve just modify the size of the buffer to fit with the max size in the netduino. Second part if the analyze of the return page. It does just keep what is between the <body> and </body> tags, remove the Z and basically convert the string to int using the convert class I’ve developed and expose in my previous post. I did not convert the second as I don’t need to be very precise. And of course, I’m checking if values are correct. I should have check also a range for year, month, day, hours and minutes. I did not and if something goes wrong I may get an exception when creating the DateTime class. I take the risk here.

    Now, I initialize the date and time when starting the HTTP server like this:

    DateTime TodayIs = new DateTime(2011, 8, 14, 10, 0, 0);
    Utility.SetLocalTime(TodayIs);
    Debug.Print(TodayIs.ToString());
    TodayIs = ReadDateTime(MyTimeServer);
    Utility.SetLocalTime(TodayIs);
    Debug.Print(TodayIs.ToString());

    MyTimeServer is a string with the URL of my date time page. Be careful as you’ll need a full URL including the name of the page. In my case the URL is http://www.ellerbach.net/DateHeure/default.aspx.

    By following the debug trace, you’ll see the date and time changing.

    It took about 1 hour to create this function and implement it in real Sourire I love this very cool netduino and .NET Microframework. The marketing guy doing development. Sourire

  • Laurent Ellerbach

    Implementing a simple HTTP server in .NET Microframework

    • 4 Comments

    To follow my previous posts, I’ve started to implement a simple HTTP server in my netduino using .NET Microfamework. I have to admit it was quite easy as there is a HTTP Server example in the samples. I was very impressed that with no OS so no Windows, no Linux, no Mac or any DOS or whatever OS, you can do high level code, create a Web Server in about 2 hours. I haven’t seen something comparable using Java, native C or other languages. There may be ways but here, all the framework is designed to be able to handle any kind of networking, there is even multithreading. I’ll use multithreading in a future post to show how to handle periodic calls.

    As I would not use all the functions, I’ve started to simplify the code and kept only what I needed.

    So I just kept couple of functions:

    • public static void StartHttpServer()
    • internal static void RunServer(string prefix)
    • static private string GetPathFromURL(string URL)
    • private static void ProcessClientGetRequest(HttpListenerContext context)
    • static void SendFileOverHTTP(HttpListenerResponse response, string strFilePath)
    • class PrefixKeeper

    I will not used any post method, so I removed it from the code. I removed also the certificate part because I won’t use HTTPS and removed the secure part as I won’t also use it. It needs to clean a bit the code but nothing really too complicated.

    I wanted to use parameter in the URL. So have requests like http://siteweb/page.ext?param1=value1;param2=value2

    In order to do that, I’ve created a very simple class which associate on parameter and one value. Nothing really to comment here, it’s a very classic class. I let the set and get properties in this class as it may be use in read and write. Both parameters and values are string.

    public class Param
            {
                private string myName = "";
                private string myValue = "";
    
                public string Name
                {
                    get { return myName; }
                    set { myName = value; }
                }
    
                public string Value
                {
                    get { return myValue; }
                    set { myValue = value; }
                }
    
                public Param()
                {
                    myName = "";
                    myValue = "";
                }
            }

    In the sample, there is nothing to decrypt such a URL. So I’ll need to function to decrypt the URL and return a table with parameters and the associated values.

    As I want to have clean code (or as clean as possible Sourire), I’ve defined 3 chars constant for the various separators.

    const char ParamSeparator = ';';
    const char ParamStart = '?';
    const char ParamEqual = '=';

    private static Param[] decryptParam(String Parameters)
    {
        Param[] retParams = null;
        int i = Parameters.IndexOf(ParamStart);
        int j = i;
        int k;
        if ( i> 0) 
        {
            //look at the number of = and ;
            
            while ((i < Parameters.Length) || (i == -1))
            {
                j = Parameters.IndexOf(ParamEqual, i);
                if (j > i)
                {
                    //first param!
                    if (retParams == null)
                    {
                        retParams = new Param[1];
                        retParams[0] = new Param();
                    }
                    else
                    {
                        Param[] rettempParams = new Param[retParams.Length+1];
                        retParams.CopyTo(rettempParams, 0);
                        rettempParams[rettempParams.Length-1] = new Param();
                        retParams = new Param[rettempParams.Length];
                        rettempParams.CopyTo(retParams, 0);
                    }
                    k = Parameters.IndexOf(ParamSeparator, j);
                    retParams[retParams.Length - 1].Name = Parameters.Substring(i + 1, j - i - 1);
                    //case'est la fin et il n'y a rien
                    if (k == j)
                    {
                        retParams[retParams.Length - 1].Value = "";
                    } // cas normal
                    else if (k > j)
                    {
                        retParams[retParams.Length - 1].Value = Parameters.Substring(j + 1, k - j - 1);
                    } //c'est la fin
                    else
                    {
                        retParams[retParams.Length - 1].Value = Parameters.Substring(j + 1, Parameters.Length - j - 1);
                    }
                    if (k > 0)
                        i = Parameters.IndexOf(ParamSeparator, k);
                    else
                        i = Parameters.Length;
                }
            }
        }
        return retParams;
    }

    The code here is not very complex. It looks first at the start parameter. Here, it’s the question mark (? ParamStart) then it finds the separator equal mark (= ParamEqual) and it finished by the separator (; ParamSeparator). Couple of cases if we are at the end for example as there is usually no separator.

    I’m not sure it’s the smartes way to do it but it’s working, it’s pretty robust and it’s been working with many various URL and cases. I’ve chosen to return a table as it’s easy to implement and easy to use. It’s pretty simple in .NET Microframework.

    You just has to be careful as depending on the platform you are using the size of the tables are limited. In the case of netduino, it’s a maximum 1024 elements. That’s also the limit size for strings. No impact here as we can consider (never consider anything in code Sourire) that a URL will be less than 1024 parameters as the string used will of course of a maximum of 1024 characters.

    In order to have clean code, I’ve also define couple of parameters and page names in a read only class.

    public class ParamPage {
        public string year { get { return "year"; } }
        public string month { get { return "month"; } }
        public string day { get { return "day"; } }
        public string hour { get { return "hour"; } }
        public string minute { get { return "minute"; } }
        public string duration { get { return "duration"; } }
        public string spr { get { return "spr"; } }
        public string pageProgram { get { return "program.aspx"; } }
        public string pageListPrgm { get { return "listprg.aspx"; } }
        public string pageCalendar { get { return "calendar.aspx"; } }
        public string pageSprinkler { get { return "sprinkler.aspx"; } }
    }

    It defines all my parameters, name of the pages I’ll use. So in code, I’ll use this class to make sure I’ll always use the right element and don’t mix up my parameters. It will also be the same name use for all pages when needed.

    As you’ve seen, the decrypt parameter function return a string value. In your code, you may want to convert it to int, float, bool or other numeric values. .NET Microframework does not provide any convert class as the full framework. So you’ll to do it by hand Sourire Not quite hard and you’ll be able to keep this class for other development.

    public class Convert
     {
         public static bool ToFloat(string s, out float result)
         {
             bool success = true;
             int decimalDiv = 0;
             result = 0;
             try
             {
                 for (int i = 0; i < s.Length; i++)
                 {
                     if (s[i] == '.' && decimalDiv == 0)
                         decimalDiv = 1;
                     else if (s[i] < '0' || s[i] > '9')
                         success = false;
                     else
                     {
                         result = result * 10;
                         decimalDiv = decimalDiv * 10;
                         result += (int)(s[i] - '0');
                     }
                 }
                 result = (float)result / decimalDiv;
             }
             catch
             {
                 success = false;
             }
             return success;
         }
    
         public static bool ToInt(string s, out int result)
         {
             bool success = true;
             result = 0;
             try
             {
                 for (int i = 0; i < s.Length; i++)
                 {
                         result = result * 10;
                         result += (int)(s[i] - '0');
                 }
             }
             catch
             {
                 success = false;
             }
             return success;
         }
    
         public static bool ToBool(string s, out bool result)
         { 
             bool success = true;
             result = false;
             try
             {
                 if ((s == "1") || (s.ToLower() == "true"))
                     result = true;
             }
             catch
             {
                 success = false;
             }
             return success;
         }
     
     }

    The code is very simple too. I’ve prefer to handle in the class a try catch and return a success value. I feel more comfortable coding like that but if you want to make it more simpler and faster, just don’t use a try catch and handle it in a higher level. The conversion for int will return funky numbers if you don’t have only decimal in the string and same for float. I’m not looking first if all are numeric if the min and max values are correct. It’s just fast and easy way to convert.

    For the bool conversion, I’ve decided to only validate the true which can be represented as 1 or true. Anything else will just be false. So here false is anything but true.

    Now to use the decrypt function and associate couple of values, here is a complete example. with the request.RawUrl you can get the URL so a string like calendar.aspx?year=2011;month=9;spr=0

    HttpListenerRequest request = context.Request;
    HttpListenerResponse response = context.Response;
    // decode params
    string strParam = request.RawUrl;
    ParamPage MyParamPage = new ParamPage();
    int intMonth = -1;
    int intYear = -1;
    int intSprinkler = -1;
    Param[] Params = decryptParam(strParam);

    Here you’ll get Params as a table of 3 elements. First couple will be year and 2011, second month and 9 and third spr and 0. All as strings. Now you’ll have to convert those string into values and then use them in your code.

    if (Params !=null)
        for (int i = 0; i < Params.Length; i++)
        {
            //on cherche le paramètre strMonth
            int j = Params[i].Name.ToLower().IndexOf(MyParamPage.month);
            if (j == 0)
            {
                Convert.ToInt(Params[i].Value, out intMonth);
            }
            j = Params[i].Name.ToLower().IndexOf(MyParamPage.year);
            if (j == 0)
            {
                Convert.ToInt(Params[i].Value, out intYear);
            }
            j = Params[i].Name.ToLower().IndexOf(MyParamPage.spr);
            if (j == 0)
            {
                Convert.ToInt(Params[i].Value, out intSprinkler);
            }
        }

    At the end, you’ll get intMonth = 9, intYear = 2011 and intSprinkler = 0.

    Last but not least, to call a function with a name and parameters you’ll need to do it in the private static void ProcessClientGetRequest(HttpListenerContext context) function from the sample.

    HttpListenerRequest request = context.Request;
    HttpListenerResponse response = context.Response;
    
    ParamPage MyParamPage = new ParamPage();
    
    string strFilePath = GetPathFromURL(request.RawUrl);
    
    string strCalendar = "\\" + MyParamPage.pageCalendar;
    // if page calendar.aspx
     if (strFilePath.Length >= strCalendar.Length)
     {
         if (strFilePath.Substring(0, strCalendar.Length).ToLower() == strCalendar)
         {
             ProcessCalendar(context);
             return;
         }
     }

    So basically, the idea is to see if the name of the page is the one used at the beginning of the URL string. If yes, it calls a specific function and gives it the context object. From there, you can use the previous code to decode your URL and analyze your parameters.

    So to summarize, with couple of more functions, you are now able to pass parameters un a URL and decrypt them. For me, that’s what I wanted to do as it’s very easy to use to generate URL but also call specific URL in code. If you have better way to do all of this, just let me know, I’m just a marketing guy doing code Sourire

  • Laurent Ellerbach

    netduino board: geek tool for .NET Microframework

    • 0 Comments

    In the past, long time ago, I’ve been a developer. I loved to develop low level code like drivers. And I love embedded and robots and all those stuff. So I have a natural attraction for .NET Microframework. Of course I know it was existing but I never really touch it. And discussing with Pierre Cauchois, he told me he bought a netduino board and automate his cooler!

    I had a look at it and just figure that was exactly what I needed to start my automation sprinkler project! So I bought the netduino plus version with the micro sd card reader and the network connection. So 50€ later and couple of days I’ve received this gadget Sourire

    What I love with netduino is that it’s an open source design, really simple and efficient, the community is really active and it has all what I needed in terms of IO. And of course, I’ll be able to reuse my .NET C# skills. OK, last time I’ve coded in C# was 1 year ago to automate my CANON EOS and be able to control it. But after 2 hours of code, C# skills come back very fast Sourire And good news with .NET Microframework is that the number of class is quite small! so it’s very easy to understand, very efficient classes and pretty much all what you need.

    So I’ve started by downloading and installing all the SDK (I’m using Visual Studio Ultimate but it’s working with express versions). and downloaded the first example to make the embedded led blinking. And é minutes later, it was working Sourire At this time I was an happy geek Rire

    So I started to look at other samples that are available and played with the HHTPServer one. And decided to derive from this project to build my own pages and program my sprinklers. On the other side, I’ve done quite a bit retro engineering on my sprinklers (Gardena model). they are bi stable electro valve using 9V small impulsions. So I know I have to use 2 digital output to pilot open and close for each sprinkler. And I’ll first concentrate and the soft and then on the hardware. By the way, the hardware question is still open, so if anyone want help, I’ll appreciate it.

    When searching if someone already did this, I found Mike Linnen  who has done an amazing integration with Windows Azure and Windows Phone 7. check it, it’s really cool!

    In the next post, I’ll go thru couple of lines of code!

  • Laurent Ellerbach

    Re opening this blog

    • 0 Comments

    I’m re opening this blog. It’s been too long since I’ve posted anything on this blog.

    And as I’m developing a bit again, I’ve decided to share it more broadly. Well, that may be a bit specific as I’m developing on .NET Microframework but it may interest couple of people. My main goal is to be able to control my sprinklers at home over the Internet. For the moment, the only thing I can do is to select a program for a duration and a specific period on them. So when it’s raining or it’s too warm and I’m far away, I can’t adjust or make it adjust itself automatically.

    So I bought a netduino plus http://www.netduino.com/netduinoplus/specs.htm and started to develop a web interface on it and an hardware interface Sourire So I’ll post about this story.

    I love to be a marketing director doing dev. Dev is like sport, it’s good for your health Sourire

  • Laurent Ellerbach

    MSDN et formation

    • 0 Comments

    CIF, DIF, APR… Vous connaissez ? Et si je vous dis Congé individuel de formation, Droit individuel à la formation, Action préparatoire au recrutement ???

    La formation est un des points noirs de la satisfaction des développeurs (Etude ANIF 2007 sur le moral des informaticiens).

    Pour vous permettre de prendre en main votre formation, d’être pro-actif, nous avons réalisé un dossier sur MSDN sur le sujet. Les principaux dispositifs pour les salariés et les demandeurs d’emploi sont donc présentés, avec des liens utiles pour aller plus loin : http://msdn2.microsoft.com/fr-fr/bb980893.aspx

  • Laurent Ellerbach

    MSDN France vous souhaite un Joyeux Noël

    • 1 Comments

    Je profite d'une pause dans le marathon infernal de ces fêtes de fin d'année pour pointer une super vidéo où l'équipe de MSDN France vous souhaite une bonne année :


    Video: Joyeux Noël aux développeurs de la part d'MSDN

    A ne pas rater :-) Surtout le vrai Père Noël :-) Philippe a raté sa carrière. Il aurait dû faire acteur :-)

    Je vous laisse retourner à vos dindes, poissons, crustacés, fois gras et autres bûches.

  • Laurent Ellerbach

    IIS rattrape Apache comme serveur Web

    • 2 Comments

    Ca faisait déjà un moment qu’IIS progressait et cela continue. La source est l’étude Netcraft qui fait référence depuis plus de 10 ans sur le marché des serveurs Web.

    “This continues the strong gains seen last month, a rate of over 5% monthly growth, with MySpace, Microsoft Live.com, and Google's Blogger each gained over 1 million sites this month. Benefitting from the gains at MySpace and Microsoft Live, Microsoft-IIS now hosts over 50 million sites.”

    Le graphique est d’ailleurs intéressant à suivre : Market Share for Top Servers Across All Domains August 1995 - October 2007clip_image002

    Source : http://news.netcraft.com/archives/2007/10/11/october_2007_web_server_survey.html

  • Laurent Ellerbach

    Pour les étudiants : des Webcasts sur les carrières dans l'informatique

    • 1 Comments

    Sur le site Etudiants, qui a été dernièrement un peu relooké, nous lançons une nouvelle initiative d’échanges en live sur le net entre les étudiants et les employés de Microsoft pour les aider à mieux connaître les métiers des nouvelles technologies.

    Pour commencer cette série de rencontre live, Jérémy Fain, tout jeune responsable des partenariats avec les éditeurs de logiciels émergents, aura la chance de partager sa jeune expérience et de répondre aux  questions des étudiants  le mercredi 24 octobre à 18h.

    clip_image001

    Retrouvez  le programme des rencontres live avec les employés de Microsoft et les enregistrements des anciens webcasts sur le site Etudiants !

  • Laurent Ellerbach

    Apprendre .NET avec la Saga .NET

    • 2 Comments

    Mieux que Dalas, la Saga .NET, réalisée par Pascal Belaud, va vous permettre de vous mettre à .NET. C’est un cursus de cours de 10 épisodes complets avec des vidéos, les codes sources associés et de quoi refaire les exercices.

    Ce que j’aime particulièrement chez Pascal, c’est sa pédagogie, les explications qu’il donne sont toujours claires et les exemples parlent bien.

    image

    La série sera complétée par d’autres épisodes si nous en avons la demande. Aussi, n’hésitez pas à réagir en m’envoyant un mail ou dans les commentaires.

    Ca se passe ici : http://www.microsoft.com/france/vision/saga-dot-net/

  • Laurent Ellerbach

    Frogz : elle arrive le 8 octobre

    • 1 Comments

    Ca se passe sur http://www.frogz.fr

    J'adore :-)

    Il faut vraiment aller voir !

  • Laurent Ellerbach

    Fréquence MSDN, vous connaissez ?

    • 2 Comments

    C'est un nouveau concept que nous lançons. Une émission de radio diffusée en live avec roundtalbe (donc plutôt de la TV avec vision 360° du plateau) à partir du 10 octobre.

    L'objectif est de pouvoir revenir sur l'actialité des quelques semaines passées, décortiquer des annonces et aussi répondre à vos questions en direct. Vous pourrez en effet poser des questions en direct.

    Nous vous réservons également quelques surprises et un peu de fun :-)

    Nous avons prévu 1 heure pour la première émission. Si le concept plait, alors on remettra ça avec d'autres émissions.

    Pour s'inscrire, c'est là que ça passe :

    http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032354930&Culture=fr-FR

  • Laurent Ellerbach

    Grandes écoles, universités et innovations

    • 0 Comments

    Je vous recommande la lecture du billet d'Olivier Ezratty sur le sujet des grandes écoles et l'innovation. Il analyse et ajoute des commentaires personnels au livre de Pierre Veltz: "Faut-il sauver les grandes écoles". A voir aussi les commentaires du billet dans lesquels il y a aussi quelques liens complémentaires.

    La réforme des grandes écoles et des universités est un sujet qui m'intéresse depuis longtemps. Je suis clairement en phase avec la plupart des points. Et je livre ici quelques pensées purement personnelles et qui ne saurait engager Microsoft.

    Ce qui m'attriste le plus dans notre système d'enseignement supérieur c'est le manque de réactivité. La plupart des problèmes ne sont pas nouveaux et personne ne semble vouloir changer les choses à un niveau politique suffisamment élevé. Et quand au niveau d'une école un directeur courageux avec ses enseignants décident de changer les choses, le soutient des étudiants s'en va et celui de l'administration avec. Dur de voir tous les étudiants dans la rue dès que l'on touche aux frais de scolarité et à quoi que ce soit. Dur de voir que ceux qui sont sensés être les plus ouverts et progressistes sont dans la grande majorité les moins à même de bouger.

    Je suis triste également de voir ces entités microscopiques que sont les grandes écoles se battre entre elles et se livrer la guerre sur le territoire français alors que la guerre des talents est internationale. Ce n'est pas Centrale contre Mines ou Arts et Métiers, c'est la France contre les Etats-Unis, la Chine, l'Inde et tous les autres pays. Que vaut un des diplômes de ces grandes écoles à l'international ? Rien. Personne ne connait. Comment attirer les talents alors ? En se regroupant, en arrêtant la guéguerre entre écoles et entre écoles et université.

    Triste aussi de voir la diversité disparaître. De voir de moins en moins d'étudiants issus de milieux défavorisés arriver dans ces écoles. Pourquoi notre système présenté par nos intellectuels littéraires comme le meilleur et le plus égalitaire du monde est-il devenu le plus inégalitaire du monde (ou presque) ? Le tout avec des études qui ne coûtent rien. Tout simplement parce que des lois économiques sont là pour le rappeler régulièrement, quand on n'a pas de moyen, on ne fait rien. Et ce n'est pas l'état qui va encore donner plus, c'est plutôt aux étudiants (à travers des empreints pour financer des études payantes) et des fonds d'entreprises (à condition que cela rapporte un minimum en recherche, recrutement ou autre) que l'on arrivera à avoir plus d'argent. Dur de voir que les étudiants issus du milieu ouvrier sont passés de 25% il y a 15 ans dans les grandes écoles à moins de 5% aujourd'hui...

    Et il y a encore plein d'autres choses qui m'attristent mais arrêtons là :-)

    C'est clairement tout un système qu'il faut avoir le courage de remettre à plat et de revoir.

    Je suis d'autant plus à l'aise à critiquer ce système que j'ai fait l'ENSAM (Arts et Métiers) que je suis issus d'un milieu classe moyenne et que mes parents m'ont financés une partie de mes études. Pour le reste, j'ai bossé quand j'étais étudiant, pendant mon temps libre et mes congés pour me payer le reste. J'ai continué mes études et j'ai fait un master en marketing et communication à l'ESCP. Pour le financer, j'ai fais un empreint à ma banque. J'ai aussi passé 4 mois à l'université polytechnique de Montréal et 2 mois de stages dans la Silicon Valley. Au final, je ne me plains pas.

    Bonne chance à tous ceux qui voudront réformer tout cela. Et pour finir sur une notre positive, je salue les réformes en cours au sein de l'Université Paris VI (Jussieu) pour remettre à plat tous les enseignements, jouer la carte LMD à fond et la compétition mondiale. Il y a de la motivation, de l'envie et clairement une vision. Encore beaucoup de freins mais les choses bougent.

    Alors bravo à tous ceux qui fond bouger les choses dans le bon sens.

  • Laurent Ellerbach

    Halo 3 : encore plus loin dans le réalisme

    • 1 Comments

    C'est aujourd'hui que sort officiellement Halo 3. Et avec ce nouveau volet, c'est encore plus de rouabilité et d'immertion qui arrivent. C'est aussi ce tpe de technologies qui nous fait prograsser dans les interfaces homme-machine. Beaucoup d'innovations sont venues du monde du jeu.

    Les graphismes sont venus de là avec les premières consoles, la démocratisation des consoles portables avec Nintendo et a donc facilité l'arrivée des terminaux mobiles que l'on connait aujourd'hui.

    Ce sont aussi des innovations comme celles apportées par les consoles modernes de Sony et Microsoft qui ont réussit à pousser les limites du réalisme, de l'immertion.

    Ce serait oublier la WII avec sa manète vraiment révolutionnaire qui va certainement beaucoup apporter dans d'autres domaines dans le domaine des interaction homme-machine.

    Bref, Halo 3, dans la continuité des innovations passées va certainement apporté sa pierre aux interfaces homme-machine. En totu cas, une chose est sûr, en full HD, son DTS 5.1, on s'y croit ! Hallucinant. Envoutant.

    Pour se faire plaisir, le trailer :-)

    no more video there :-)

    Je sens qu'il va y avoir perte de productivité quand je vais craquer pour m'acheter le jeu...

  • Laurent Ellerbach

    La CNJE : Révélateur d'esprit d'entreprise a un blog

    • 2 Comments

    Voilà maintenant plus de 4 ans que Microsoft est partenaire de la Confédération  Nationale des Juniors Entreprises (CNJE). La CNJE est une association qui regroupe toutes les Junior Entreprises (JE) de France. Une JE, c'est une association d'étudiants à but pédagogique qui fonctionne comme une entreprise et propose du service (du vrai) aux entreprises à tarif étudiants.

    Je fais parti des personnes qui sont à l'origine de la signature de ce partenariat. Je suis intéressé par tout ce qui touche à l'aide que l'on peut apporter aux entrepreneurs et aux jeunes pour leur donner envie d'entreprendre.

    Et j'en viens donc au sujet de ce post qui est l'ouverture d'un blog sur l'esprit d'entreprendre animé par les membres de la CNJE :

    http://blog.junior-entreprises.com/

    Je vais l'ajouter à mes flux !

  • Laurent Ellerbach

    Quiksilver : du Silverlight qui déchire :-)

    • 2 Comments

    Quiksilver en partenariat avec Microsoft a développé un super player pour suivre la compétition Quiksilver Pro France.

    Ca se passe ici : http://premium.quiksilverlive.com/

    Au menu :

    • les lives quand il y a des vagues, là, y'en n'a pas :-(
    • les replays de toutes les meilleurs vagues
    • les scores
    • les stats
    • la possibilité de noter des vagues
    • une gallerie de photo
    • le tout en HD pour ceux qui veullent !
    • et quelques bonus en plus :-)

    Faut vraiment aller voir pour se donner une idée de ce que l'on peut faire avec Silverlight.

Page 2 of 5 (122 items) 12345